libkernaux/pkgs/ruby/lib/kernaux.rb

236 lines
6.0 KiB
Ruby
Raw Normal View History

2022-01-18 10:20:37 +00:00
# frozen_string_literal: true
require_relative 'kernaux/version'
2022-01-21 21:23:57 +00:00
# Native extensions
require_relative 'kernaux/default'
2022-01-18 10:20:37 +00:00
##
2022-01-30 05:12:40 +00:00
# Binding to libkernaux - auxiliary library for kernel development.
2022-01-18 10:20:37 +00:00
#
module KernAux
2022-01-30 11:29:48 +00:00
# Default callback for assertions.
# @see .assert_cb
2022-01-29 21:17:04 +00:00
DEFAULT_ASSERT_CB = @assert_cb = lambda { |file, line, msg|
raise AssertError, "#{file}:#{line}:#{msg}"
2022-01-20 19:36:36 +00:00
}
2022-01-30 11:29:48 +00:00
# Buffer size for {.sprintf1}.
# @todo Make it dynamic.
2022-01-21 14:38:22 +00:00
SPRINTF1_BUFFER_SIZE = 10_000
2022-01-20 19:36:36 +00:00
2022-01-30 11:29:48 +00:00
# @!scope class
##
# @!attribute [rw] assert_cb
# Panic callback.
#
# @see .panic
# @see .assert_do
##
##
# Raise assertion with implicit file and line, retrieved from `caller`, and
# explicit message.
#
# @param msg [String] any message
# @return [nil]
#
2022-01-30 12:05:01 +00:00
# @raise [AssertError] if {.assert_cb} have not been changed
2022-01-30 11:29:48 +00:00
#
# @see .assert_do Explicit file and line.
#
2022-01-20 19:36:36 +00:00
def self.panic(msg)
file, line = caller(1..1).first.split(':')[0..1]
assert_do file, Integer(line), msg
end
2022-01-30 11:29:48 +00:00
##
# @!method assert_do(file, line, msg)
# Raise assertion with explicit file, line and message.
#
# @param file [String] file name, usually from `__FILE__`
# @param line [Integer] line number, usually from `__LINE__`
# @param msg [String] any message
# @return [nil]
#
2022-01-30 12:05:01 +00:00
# @raise [AssertError] if {.assert_cb} have not been changed
2022-01-30 11:29:48 +00:00
#
2022-01-30 12:05:01 +00:00
# @see .panic Implicit file and line
2022-01-30 11:29:48 +00:00
2022-01-30 12:11:20 +00:00
# @!parse [ruby]
2022-01-30 11:29:48 +00:00
2022-01-23 21:52:42 +00:00
if singleton_class.method_defined? :snprintf1
2022-01-30 12:05:01 +00:00
##
# Typical `printf`.
#
# @param args [Array<String, Array<(String, Object)>>]
# @return [String] formatted output
#
# @example
# KernAux.sprintf 'foo', ['%*s', 5, 'bar'], 'car', ['%d', 123]
# #=> "foo barcar123"
#
2022-01-23 21:52:42 +00:00
def self.sprintf(*args)
args.map do |arg|
if arg.is_a? Array
sprintf1(*arg)
else
arg
end
end.join.freeze
end
2022-01-30 12:05:01 +00:00
##
# `printf` for single formatting parameter.
#
# @param format [String] formatting string
# @return [String] formatted output
#
# @see .sprintf Multiple formatting parameters
#
# @example
# KernAux.sprintf1 '%%' #=> "%"
# KernAux.sprintf1 '%s', 'foo' #=> "foo"
# KernAux.sprintf1 '%5s', 'foo' #=> " foo"
# KernAux.sprintf1 '%*s', 5, 'foo' #=> " foo"
#
def self.sprintf1(format, *args)
snprintf1(SPRINTF1_BUFFER_SIZE, format, *args).first
end
##
# @!method snprintf1(buffer_size, format, ...)
# `printf` for single formatting parameter with manual buffer size.
#
# @param buffer_size [Integer] buffer size (including terminating null
# character)
# @param format [String] formatting string
# @return [String] formatted output
#
# @see .sprintf1 Automatic buffer size
##
2022-01-21 14:52:46 +00:00
end
2022-01-30 12:11:20 +00:00
##
# @!method cmdline(str)
# Parse command line.
#
# @param str [String] command line string
# @return [Array<String>] command line arguments
#
# @raise [CmdlineError] syntax is invalid
# @!parse [ruby]
2022-01-30 12:34:34 +00:00
##
# @!method utoa(number, base)
# Convert `uint64_t` to a string in multiple numeral systems.
#
# Base can be a positive or negative integer between 2 and 36, or a symbol
# which is an alias to a valid integer value. Positive integers and lowercase
# symbols mean lowercase output when base is greater than 10. Negative
# integers and uppercase symbols mean uppercase output when base is greater
2022-01-30 12:37:33 +00:00
# than 10. Aliases are: `:b`, `:B` - 2; `:o`, `:O` - 8; `:d`, `:D` - 10; `:h`,
# `:x` - 16 (lowercase); `:H`, `:X` - -10 (uppercase).
2022-01-30 12:34:34 +00:00
#
2022-01-30 12:37:33 +00:00
# @param number [Integer] a number between 0 and `UINT64_MAX`
2022-01-30 12:34:34 +00:00
# @param base [Integer, Symbol] base of a numeral system
# @return [String]
#
2022-01-30 12:46:22 +00:00
# @raise [RangeError] number is out of range
2022-01-30 12:34:34 +00:00
# @raise [InvalidNtoaBaseError] base is invalid
#
# @see .itoa Convert signed integers
##
2022-01-30 12:37:33 +00:00
##
# @!method itoa(number, base)
# Convert `int64_t` to a string in multiple numeral systems.
#
# Base can be a positive or negative integer between 2 and 36, or a symbol
# which is an alias to a valid integer value. Positive integers and lowercase
# symbols mean lowercase output when base is greater than 10. Negative
# integers and uppercase symbols mean uppercase output when base is greater
# than 10. Aliases are: `:b`, `:B` - 2; `:o`, `:O` - 8; `:d`, `:D` - 10; `:h`,
# `:x` - 16 (lowercase); `:H`, `:X` - -10 (uppercase).
#
# @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
# @param base [Integer, Symbol] base of a numeral system
# @return [String]
#
2022-01-30 12:46:22 +00:00
# @raise [RangeError] number is out of range
2022-01-30 12:37:33 +00:00
# @raise [InvalidNtoaBaseError] base is invalid
#
# @see .utoa Convert unsigned integers
##
2022-01-30 12:40:21 +00:00
##
# @!method utoa10(number)
# Convert `uint64_t` to a decimal string.
#
# @param number [Integer] a number between 0 and `UINT64_MAX`
# @return [String]
2022-01-30 12:46:22 +00:00
#
# @raise [RangeError] number is out of range
2022-01-30 12:40:21 +00:00
##
##
# @!method itoa10(number)
# Convert `int64_t` to a decimal string.
#
# @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
# @return [String]
2022-01-30 12:46:22 +00:00
#
# @raise [RangeError] number is out of range
2022-01-30 12:40:21 +00:00
##
##
# @!method utoa16(number)
# Convert `uint64_t` to a hexadecimal string.
#
# @param number [Integer] a number between 0 and `UINT64_MAX`
# @return [String]
2022-01-30 12:46:22 +00:00
#
# @raise [RangeError] number is out of range
2022-01-30 12:40:21 +00:00
##
##
# @!method itoa16(number)
# Convert `int64_t` to a hexadecimal string.
#
# @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
# @return [String]
2022-01-30 12:46:22 +00:00
#
# @raise [RangeError] number is out of range
2022-01-30 12:40:21 +00:00
##
2022-01-20 19:36:36 +00:00
##
2022-01-20 19:42:48 +00:00
# Our base class for runtime errors.
2022-01-20 19:36:36 +00:00
#
2022-01-20 21:52:43 +00:00
class Error < RuntimeError; end
2022-01-20 19:36:36 +00:00
##
# Raised when assertion has failed or panic has been called.
#
2022-01-21 21:11:28 +00:00
# @see .panic
2022-01-30 11:29:48 +00:00
# @see .assert_do
2022-01-21 21:11:28 +00:00
#
2022-01-20 21:52:43 +00:00
class AssertError < Error; end
2022-01-21 21:23:40 +00:00
##
2022-01-29 22:29:04 +00:00
# Raised when command line parsing goes wrong.
2022-01-21 21:23:40 +00:00
#
# @see .cmdline
#
class CmdlineError < Error; end
2022-01-29 22:12:09 +00:00
##
2022-01-29 22:29:04 +00:00
# Raised when integer base is invalid.
2022-01-29 22:12:09 +00:00
#
# @see .utoa
# @see .itoa
#
class InvalidNtoaBaseError < Error; end
2022-01-18 10:20:37 +00:00
end