diff options
Diffstat (limited to 'prism/extension.c')
-rw-r--r-- | prism/extension.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/prism/extension.c b/prism/extension.c index fd2281fd79..3eccb20e5a 100644 --- a/prism/extension.c +++ b/prism/extension.c @@ -21,6 +21,8 @@ VALUE rb_cPrismParseError; VALUE rb_cPrismParseWarning; VALUE rb_cPrismParseResult; +VALUE rb_cPrismDebugEncoding; + ID rb_option_id_filepath; ID rb_option_id_encoding; ID rb_option_id_line; @@ -1102,6 +1104,80 @@ format_errors(VALUE self, VALUE source, VALUE colorize) { return result; } +/** + * call-seq: Debug::Encoding.all -> Array[Debug::Encoding] + * + * Return an array of all of the encodings that prism knows about. + */ +static VALUE +encoding_all(VALUE self) { + VALUE encodings = rb_ary_new(); + + for (size_t index = 0; index < PM_ENCODING_MAXIMUM; index++) { + const pm_encoding_t *encoding = &pm_encodings[index]; + + VALUE encoding_argv[] = { rb_str_new_cstr(encoding->name), encoding->multibyte ? Qtrue : Qfalse }; + rb_ary_push(encodings, rb_class_new_instance(2, encoding_argv, rb_cPrismDebugEncoding)); + } + + return encodings; +} + +static const pm_encoding_t * +encoding_find(VALUE name) { + const uint8_t *source = (const uint8_t *) RSTRING_PTR(name); + size_t length = RSTRING_LEN(name); + + const pm_encoding_t *encoding = pm_encoding_find(source, source + length); + if (encoding == NULL) { rb_raise(rb_eArgError, "Unknown encoding: %s", source); } + + return encoding; +} + +/** + * call-seq: Debug::Encoding.width(source) -> Integer + * + * Returns the width of the first character in the given string if it is valid + * in the encoding. If it is not, this function returns 0. + */ +static VALUE +encoding_char_width(VALUE self, VALUE name, VALUE value) { + return ULONG2NUM(encoding_find(name)->char_width((const uint8_t *) RSTRING_PTR(value), RSTRING_LEN(value))); +} + +/** + * call-seq: Debug::Encoding.alnum?(source) -> true | false + * + * Returns true if the first character in the given string is an alphanumeric + * character in the encoding. + */ +static VALUE +encoding_alnum_char(VALUE self, VALUE name, VALUE value) { + return encoding_find(name)->alnum_char((const uint8_t *) RSTRING_PTR(value), RSTRING_LEN(value)) > 0 ? Qtrue : Qfalse; +} + +/** + * call-seq: Debug::Encoding.alpha?(source) -> true | false + * + * Returns true if the first character in the given string is an alphabetic + * character in the encoding. + */ +static VALUE +encoding_alpha_char(VALUE self, VALUE name, VALUE value) { + return encoding_find(name)->alpha_char((const uint8_t *) RSTRING_PTR(value), RSTRING_LEN(value)) > 0 ? Qtrue : Qfalse; +} + +/** + * call-seq: Debug::Encoding.upper?(source) -> true | false + * + * Returns true if the first character in the given string is an uppercase + * character in the encoding. + */ +static VALUE +encoding_isupper_char(VALUE self, VALUE name, VALUE value) { + return encoding_find(name)->isupper_char((const uint8_t *) RSTRING_PTR(value), RSTRING_LEN(value)) ? Qtrue : Qfalse; +} + /******************************************************************************/ /* Initialization of the extension */ /******************************************************************************/ @@ -1182,6 +1258,15 @@ Init_prism(void) { rb_define_singleton_method(rb_cPrismDebug, "inspect_node", inspect_node, 1); rb_define_singleton_method(rb_cPrismDebug, "format_errors", format_errors, 2); + // Next, define the functions that are exposed through the private + // Debug::Encoding class. + rb_cPrismDebugEncoding = rb_define_class_under(rb_cPrismDebug, "Encoding", rb_cObject); + rb_define_singleton_method(rb_cPrismDebugEncoding, "all", encoding_all, 0); + rb_define_singleton_method(rb_cPrismDebugEncoding, "_width", encoding_char_width, 2); + rb_define_singleton_method(rb_cPrismDebugEncoding, "_alnum?", encoding_alnum_char, 2); + rb_define_singleton_method(rb_cPrismDebugEncoding, "_alpha?", encoding_alpha_char, 2); + rb_define_singleton_method(rb_cPrismDebugEncoding, "_upper?", encoding_isupper_char, 2); + // Next, initialize the other APIs. Init_prism_api_node(); Init_prism_pack(); |