From 2ccaaaa1017fa411134648bbaa6fa8f8b875e16d Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Sat, 29 Jul 2023 16:13:52 +0200 Subject: [PATCH] [ruby/yarp] Add simpler exported unescape function to librubyparser * Moves logic from the C extension to librubyparser which can be shared with the Fiddle backend. https://github.com/ruby/yarp/commit/aa48d5e444 --- yarp/extension.c | 28 +++++++--------------------- yarp/unescape.c | 21 ++++++++++++++++++++- yarp/unescape.h | 4 ++++ 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/yarp/extension.c b/yarp/extension.c index 7ede50bb0f..36e9941d64 100644 --- a/yarp/extension.c +++ b/yarp/extension.c @@ -529,30 +529,16 @@ named_captures(VALUE self, VALUE source) { // version. static VALUE unescape(VALUE source, yp_unescape_type_t unescape_type) { - yp_string_t string; - VALUE result; + yp_string_t result; - yp_list_t error_list; - yp_list_init(&error_list); - - const char *start = RSTRING_PTR(source); - size_t length = RSTRING_LEN(source); - - yp_parser_t parser; - yp_parser_init(&parser, start, length, ""); - - yp_unescape_manipulate_string(&parser, start, length, &string, unescape_type, &error_list); - if (yp_list_empty_p(&error_list)) { - result = rb_str_new(yp_string_source(&string), yp_string_length(&string)); + if (yp_unescape_string(RSTRING_PTR(source), RSTRING_LEN(source), unescape_type, &result)) { + VALUE str = rb_str_new(yp_string_source(&result), yp_string_length(&result)); + yp_string_free(&result); + return str; } else { - result = Qnil; + yp_string_free(&result); + return Qnil; } - - yp_string_free(&string); - yp_list_free(&error_list); - yp_parser_free(&parser); - - return result; } // Do not unescape anything in the given string. This is here to provide a diff --git a/yarp/unescape.c b/yarp/unescape.c index 296caf01aa..3f6e70216c 100644 --- a/yarp/unescape.c +++ b/yarp/unescape.c @@ -1,4 +1,4 @@ -#include "yarp/unescape.h" +#include "yarp.h" /******************************************************************************/ /* Character checks */ @@ -528,6 +528,25 @@ yp_unescape_manipulate_string(yp_parser_t *parser, const char *value, size_t len string->as.owned.length = dest_length + ((size_t) (end - cursor)); } +YP_EXPORTED_FUNCTION bool +yp_unescape_string(const char *start, size_t length, yp_unescape_type_t unescape_type, yp_string_t *result) { + bool success; + + yp_list_t error_list; + yp_list_init(&error_list); + + yp_parser_t parser; + yp_parser_init(&parser, start, length, ""); + + yp_unescape_manipulate_string(&parser, start, length, result, unescape_type, &error_list); + success = yp_list_empty_p(&error_list); + + yp_list_free(&error_list); + yp_parser_free(&parser); + + return success; +} + // This function is similar to yp_unescape_manipulate_string, except it doesn't // actually perform any string manipulations. Instead, it calculates how long // the unescaped character is, and returns that value diff --git a/yarp/unescape.h b/yarp/unescape.h index 15e7cf2e17..b76ac9f7a4 100644 --- a/yarp/unescape.h +++ b/yarp/unescape.h @@ -33,6 +33,10 @@ typedef enum { // given unescape mode. YP_EXPORTED_FUNCTION void yp_unescape_manipulate_string(yp_parser_t *parser, const char *value, size_t length, yp_string_t *string, yp_unescape_type_t unescape_type, yp_list_t *error_list); +// Accepts a source string and a type of unescaping and returns the unescaped version. +// The caller must yp_string_free(result); after calling this function. +YP_EXPORTED_FUNCTION bool yp_unescape_string(const char *start, size_t length, yp_unescape_type_t unescape_type, yp_string_t *result); + YP_EXPORTED_FUNCTION size_t yp_unescape_calculate_difference(const char *value, const char *end, yp_unescape_type_t unescape_type, bool expect_single_codepoint, yp_list_t *error_list); #endif