From 9e637ca0a607eb12fc6431a96e973f8f9ce18c4d Mon Sep 17 00:00:00 2001 From: Watson Date: Sun, 1 Sep 2024 06:28:02 +0900 Subject: [PATCH] Use TypedData_Wrap_Struct() macro to suppress deprecated messages When compile ox gem with Ruby 3.4-dev, it show the following deprecated messages: ``` ../../../../ext/ox/builder.c:356:29: warning: 'rb_data_object_wrap_warning' is deprecated: by TypedData [-Wdeprecated-declarations] 356 | volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b); | ^ /Users/watson/.rbenv/versions/3.4-dev/include/ruby-3.4.0+0/ruby/internal/core/rdata.h:199:5: note: expanded from macro 'Data_Wrap_Struct' 199 | rb_data_object_wrap( \ | ^ /Users/watson/.rbenv/versions/3.4-dev/include/ruby-3.4.0+0/ruby/internal/core/rdata.h:363:31: note: expanded from macro 'rb_data_object_wrap' 363 | #define rb_data_object_wrap RUBY_MACRO_SELECT(rb_data_object_wrap_2, RUBY_UNTYPED_DATA_WARNING) | ^ /Users/watson/.rbenv/versions/3.4-dev/include/ruby-3.4.0+0/ruby/internal/core/rdata.h:50:35: note: expanded from macro 'RUBY_MACRO_SELECT' 50 | #define RUBY_MACRO_SELECT(x, y) RBIMPL_MACRO_SELECT(x, y) | ^ /Users/watson/.rbenv/versions/3.4-dev/include/ruby-3.4.0+0/ruby/internal/core/rdata.h:49:35: note: expanded from macro 'RBIMPL_MACRO_SELECT' 49 | #define RBIMPL_MACRO_SELECT(x, y) x ## y | ^ :119:1: note: expanded from here 119 | rb_data_object_wrap_1 | ^ /Users/watson/.rbenv/versions/3.4-dev/include/ruby-3.4.0+0/ruby/internal/core/rdata.h:361:31: note: expanded from macro 'rb_data_object_wrap_1' 361 | #define rb_data_object_wrap_1 rb_data_object_wrap_warning | ^ /Users/watson/.rbenv/versions/3.4-dev/include/ruby-3.4.0+0/ruby/internal/core/rdata.h:277:1: note: 'rb_data_object_wrap_warning' has been explicitly marked deprecated here 277 | RBIMPL_ATTRSET_UNTYPED_DATA_FUNC() | ^ /Users/watson/.rbenv/versions/3.4-dev/include/ruby-3.4.0+0/ruby/internal/core/rdata.h:47:5: note: expanded from macro 'RBIMPL_ATTRSET_UNTYPED_DATA_FUNC' 47 | RBIMPL_ATTR_DEPRECATED(("by TypedData")) | ^ /Users/watson/.rbenv/versions/3.4-dev/include/ruby-3.4.0+0/ruby/internal/attr/deprecated.h:36:53: note: expanded from macro 'RBIMPL_ATTR_DEPRECATED' 36 | # define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg)) | ^ ``` This patch will suppress the deprecated messages. --- ext/ox/builder.c | 93 ++++++++++++++++++++++++++++++++++++------------ ext/ox/cache.c | 17 +++++++-- ext/ox/cache.h | 6 ++-- ext/ox/intern.c | 8 ++--- ext/ox/parse.c | 14 +++++++- ext/ox/sax.c | 13 ++++++- ext/ox/sax.h | 2 ++ ext/ox/sax_as.c | 36 ++++++++++++++----- 8 files changed, 148 insertions(+), 41 deletions(-) diff --git a/ext/ox/builder.c b/ext/ox/builder.c index 97342cde..ef07e37b 100644 --- a/ext/ox/builder.c +++ b/ext/ox/builder.c @@ -17,6 +17,19 @@ #define MAX_DEPTH 128 +static void builder_free(void *ptr); + +static const rb_data_type_t ox_builder_type = { + "Ox/builder", + { + NULL, + builder_free, + NULL, + }, + 0, + 0, +}; + typedef struct _element { char *name; char buf[64]; @@ -353,14 +366,14 @@ static VALUE builder_new(int argc, VALUE *argv, VALUE self) { init(b, 0, indent, buf_size); if (rb_block_given_p()) { - volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b); + volatile VALUE rb = TypedData_Wrap_Struct(builder_class, &ox_builder_type, b); rb_yield(rb); bclose(b); return to_s(b); } else { - return Data_Wrap_Struct(builder_class, NULL, builder_free, b); + return TypedData_Wrap_Struct(builder_class, &ox_builder_type, b); } } @@ -408,12 +421,12 @@ static VALUE builder_file(int argc, VALUE *argv, VALUE self) { init(b, fileno(f), indent, buf_size); if (rb_block_given_p()) { - volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b); + volatile VALUE rb = TypedData_Wrap_Struct(builder_class, &ox_builder_type, b); rb_yield(rb); bclose(b); return Qnil; } else { - return Data_Wrap_Struct(builder_class, NULL, builder_free, b); + return TypedData_Wrap_Struct(builder_class, &ox_builder_type, b); } } @@ -461,12 +474,12 @@ static VALUE builder_io(int argc, VALUE *argv, VALUE self) { init(b, fd, indent, buf_size); if (rb_block_given_p()) { - volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b); + volatile VALUE rb = TypedData_Wrap_Struct(builder_class, &ox_builder_type, b); rb_yield(rb); bclose(b); return Qnil; } else { - return Data_Wrap_Struct(builder_class, NULL, builder_free, b); + return TypedData_Wrap_Struct(builder_class, &ox_builder_type, b); } } @@ -478,8 +491,9 @@ static VALUE builder_io(int argc, VALUE *argv, VALUE self) { * - +options+ - (Hash) version or encoding */ static VALUE builder_instruct(int argc, VALUE *argv, VALUE self) { - Builder b = (Builder)DATA_PTR(self); + Builder b; + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); i_am_a_child(b, false); append_indent(b); if (0 == argc) { @@ -548,11 +562,13 @@ static VALUE builder_instruct(int argc, VALUE *argv, VALUE self) { * - +attributes+ - (Hash) of the element */ static VALUE builder_element(int argc, VALUE *argv, VALUE self) { - Builder b = (Builder)DATA_PTR(self); + Builder b; Element e; const char *name; long len; + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + if (1 > argc) { rb_raise(ox_arg_error_class, "missing element name"); } @@ -608,10 +624,12 @@ static VALUE builder_element(int argc, VALUE *argv, VALUE self) { * - +attributes+ - (Hash) of the element */ static VALUE builder_void_element(int argc, VALUE *argv, VALUE self) { - Builder b = (Builder)DATA_PTR(self); + Builder b; const char *name; long len; + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + if (1 > argc) { rb_raise(ox_arg_error_class, "missing element name"); } @@ -649,8 +667,9 @@ static VALUE builder_void_element(int argc, VALUE *argv, VALUE self) { * - +text+ - (String) contents of the comment */ static VALUE builder_comment(VALUE self, VALUE text) { - Builder b = (Builder)DATA_PTR(self); + Builder b; + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); rb_check_type(text, T_STRING); i_am_a_child(b, false); append_indent(b); @@ -671,8 +690,9 @@ static VALUE builder_comment(VALUE self, VALUE text) { * - +text+ - (String) contents of the doctype */ static VALUE builder_doctype(VALUE self, VALUE text) { - Builder b = (Builder)DATA_PTR(self); + Builder b; + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); rb_check_type(text, T_STRING); i_am_a_child(b, false); append_indent(b); @@ -694,10 +714,12 @@ static VALUE builder_doctype(VALUE self, VALUE text) { * - +strip_invalid_chars+ - [true|false] strips any characters invalid for XML, defaults to false */ static VALUE builder_text(int argc, VALUE *argv, VALUE self) { - Builder b = (Builder)DATA_PTR(self); + Builder b; volatile VALUE v; volatile VALUE strip_invalid_chars; + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + if ((0 == argc) || (argc > 2)) { rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1..2)", argc); } @@ -721,13 +743,15 @@ static VALUE builder_text(int argc, VALUE *argv, VALUE self) { * - +data+ - (String) contents of the CDATA element */ static VALUE builder_cdata(VALUE self, VALUE data) { - Builder b = (Builder)DATA_PTR(self); + Builder b; volatile VALUE v = data; const char *str; const char *s; const char *end; int len; + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + v = rb_String(v); str = StringValuePtr(v); len = (int)RSTRING_LEN(v); @@ -761,13 +785,14 @@ static VALUE builder_cdata(VALUE self, VALUE data) { * - +text+ - (String) contents to be added */ static VALUE builder_raw(VALUE self, VALUE text) { - Builder b = (Builder)DATA_PTR(self); + Builder b; volatile VALUE v = text; const char *str; const char *s; const char *end; int len; + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); v = rb_String(v); str = StringValuePtr(v); len = (int)RSTRING_LEN(v); @@ -792,7 +817,10 @@ static VALUE builder_raw(VALUE self, VALUE text) { * Returns the JSON document string in what ever state the construction is at. */ static VALUE builder_to_s(VALUE self) { - return to_s((Builder)DATA_PTR(self)); + Builder b; + + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + return to_s(b); } /* call-seq: line() @@ -800,7 +828,10 @@ static VALUE builder_to_s(VALUE self) { * Returns the current line in the output. The first line is line 1. */ static VALUE builder_line(VALUE self) { - return LONG2NUM(((Builder)DATA_PTR(self))->line); + Builder b; + + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + return LONG2NUM(b->line); } /* call-seq: column() @@ -809,7 +840,10 @@ static VALUE builder_line(VALUE self) { * column 1. */ static VALUE builder_column(VALUE self) { - return LONG2NUM(((Builder)DATA_PTR(self))->col); + Builder b; + + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + return LONG2NUM(b->col); } /* call-seq: indent() @@ -817,7 +851,10 @@ static VALUE builder_column(VALUE self) { * Returns the indentation level */ static VALUE builder_get_indent(VALUE self) { - return INT2NUM(((Builder)DATA_PTR(self))->indent); + Builder b; + + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + return INT2NUM(b->indent); } /* call-seq: indent=(indent) @@ -827,11 +864,15 @@ static VALUE builder_get_indent(VALUE self) { * - +indent+ (Fixnum) indentaion level, negative values excludes terminating newline */ static VALUE builder_set_indent(VALUE self, VALUE indent) { + Builder b; + + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + if (rb_cInteger != rb_obj_class(indent)) { rb_raise(ox_parse_error_class, "indent must be a fixnum.\n"); } - ((Builder)DATA_PTR(self))->indent = NUM2INT(indent); + b->indent = NUM2INT(indent); return Qnil; } @@ -840,7 +881,10 @@ static VALUE builder_set_indent(VALUE self, VALUE indent) { * Returns the number of bytes written. */ static VALUE builder_pos(VALUE self) { - return LONG2NUM(((Builder)DATA_PTR(self))->pos); + Builder b; + + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + return LONG2NUM(b->pos); } /* call-seq: pop() @@ -848,7 +892,9 @@ static VALUE builder_pos(VALUE self) { * Closes the current element. */ static VALUE builder_pop(VALUE self) { - pop((Builder)DATA_PTR(self)); + Builder b; + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + pop(b); return Qnil; } @@ -858,7 +904,10 @@ static VALUE builder_pop(VALUE self) { * Closes the all elements and the document. */ static VALUE builder_close(VALUE self) { - bclose((Builder)DATA_PTR(self)); + Builder b; + + TypedData_Get_Struct(self, struct _builder, &ox_builder_type, b); + bclose(b); return Qnil; } diff --git a/ext/ox/cache.c b/ext/ox/cache.c index f142a9ff..44121814 100644 --- a/ext/ox/cache.c +++ b/ext/ox/cache.c @@ -54,6 +54,17 @@ typedef struct _cache { bool mark; } *Cache; +const rb_data_type_t ox_cache_type = { + "Ox/Cache", + { + ox_cache_mark, + ox_cache_free, + NULL, + }, + 0, + 0, +}; + static uint64_t hash_calc(const uint8_t *key, size_t len) { const uint8_t *end = key + len; const uint8_t *endless = key + (len & 0xFFFFFFFC); @@ -263,7 +274,8 @@ Cache ox_cache_create(size_t size, VALUE (*form)(const char *str, size_t len), b return c; } -void ox_cache_free(Cache c) { +void ox_cache_free(void *ptr) { + Cache c = (Cache)ptr; uint64_t i; for (i = 0; i < c->size; i++) { @@ -279,7 +291,8 @@ void ox_cache_free(Cache c) { free(c); } -void ox_cache_mark(Cache c) { +void ox_cache_mark(void *ptr) { + Cache c = (Cache)ptr; uint64_t i; #if !HAVE_PTHREAD_MUTEX_INIT diff --git a/ext/ox/cache.h b/ext/ox/cache.h index 1bd78a81..3d372a0a 100644 --- a/ext/ox/cache.h +++ b/ext/ox/cache.h @@ -11,9 +11,11 @@ struct _cache; +extern const rb_data_type_t ox_cache_type; + extern struct _cache *ox_cache_create(size_t size, VALUE (*form)(const char *str, size_t len), bool mark, bool locking); -extern void ox_cache_free(struct _cache *c); -extern void ox_cache_mark(struct _cache *c); +extern void ox_cache_free(void *ptr); +extern void ox_cache_mark(void *ptr); extern VALUE ox_cache_intern(struct _cache *c, const char *key, size_t len, const char **keyp); #endif /* OX_CACHE_H */ diff --git a/ext/ox/intern.c b/ext/ox/intern.c index c4890461..d2b2c11e 100644 --- a/ext/ox/intern.c +++ b/ext/ox/intern.c @@ -74,19 +74,19 @@ void ox_hash_init() { #endif ox_str_cache = ox_cache_create(0, form_str, true, false); - ox_str_cache_obj = Data_Wrap_Struct(cache_class, ox_cache_mark, ox_cache_free, ox_str_cache); + ox_str_cache_obj = TypedData_Wrap_Struct(cache_class, &ox_cache_type, ox_str_cache); rb_gc_register_address(&ox_str_cache_obj); ox_sym_cache = ox_cache_create(0, form_sym, true, false); - ox_sym_cache_obj = Data_Wrap_Struct(cache_class, ox_cache_mark, ox_cache_free, ox_sym_cache); + ox_sym_cache_obj = TypedData_Wrap_Struct(cache_class, &ox_cache_type, ox_sym_cache); rb_gc_register_address(&ox_sym_cache_obj); ox_attr_cache = ox_cache_create(0, form_attr, false, false); - ox_attr_cache_obj = Data_Wrap_Struct(cache_class, ox_cache_mark, ox_cache_free, ox_attr_cache); + ox_attr_cache_obj = TypedData_Wrap_Struct(cache_class, &ox_cache_type, ox_attr_cache); rb_gc_register_address(&ox_attr_cache_obj); ox_id_cache = ox_cache_create(0, form_id, false, false); - ox_id_cache_obj = Data_Wrap_Struct(cache_class, ox_cache_mark, ox_cache_free, ox_id_cache); + ox_id_cache_obj = TypedData_Wrap_Struct(cache_class, &ox_cache_type, ox_id_cache); rb_gc_register_address(&ox_id_cache_obj); } diff --git a/ext/ox/parse.c b/ext/ox/parse.c index 92db8b3f..04e5dd2f 100644 --- a/ext/ox/parse.c +++ b/ext/ox/parse.c @@ -18,6 +18,7 @@ #include "ruby.h" #include "special.h" +static void mark_pi_cb(void *ptr); static void read_instruction(PInfo pi); static void read_doctype(PInfo pi); static void read_comment(PInfo pi); @@ -33,6 +34,17 @@ static char *read_coded_chars(PInfo pi, char *text); static void next_non_white(PInfo pi); static int collapse_special(PInfo pi, char *str); +static const rb_data_type_t ox_wrap_type = { + "Object", + { + mark_pi_cb, + NULL, + NULL, + }, + 0, + 0, +}; + /* This XML parser is a single pass, destructive, callback parser. It is a * single pass parse since it only make one pass over the characters in the * XML document string. It is destructive because it re-uses the content of @@ -140,7 +152,7 @@ ox_parse(char *xml, size_t len, ParseCallbacks pcb, char **endp, Options options // initialize parse info helper_stack_init(&pi.helpers); // Protect against GC - wrap = Data_Wrap_Struct(rb_cObject, mark_pi_cb, NULL, &pi); + wrap = TypedData_Wrap_Struct(rb_cObject, &ox_wrap_type, &pi); err_init(&pi.err); pi.str = xml; diff --git a/ext/ox/sax.c b/ext/ox/sax.c index a45e16bd..9d2d696e 100644 --- a/ext/ox/sax.c +++ b/ext/ox/sax.c @@ -62,6 +62,17 @@ static Nv hint_try_close(SaxDrive dr, const char *name); VALUE ox_sax_value_class = Qnil; +const rb_data_type_t ox_sax_value_type = { + "Ox/Sax/Value", + { + NULL, + NULL, + NULL, + }, + 0, + 0, +}; + static VALUE protect_parse(VALUE drp) { parse((SaxDrive)drp); @@ -256,7 +267,7 @@ static void sax_drive_init(SaxDrive dr, VALUE handler, VALUE io, SaxOptions opti dr->buf.dr = dr; stack_init(&dr->stack); dr->handler = handler; - dr->value_obj = Data_Wrap_Struct(ox_sax_value_class, 0, 0, dr); + dr->value_obj = TypedData_Wrap_Struct(ox_sax_value_class, &ox_sax_value_type, dr); rb_gc_register_address(&dr->value_obj); dr->options = *options; dr->err = 0; diff --git a/ext/ox/sax.h b/ext/ox/sax.h index 19264a16..40054f44 100644 --- a/ext/ox/sax.h +++ b/ext/ox/sax.h @@ -54,6 +54,8 @@ typedef struct _saxDrive { } *SaxDrive; +extern const rb_data_type_t ox_sax_value_type; + extern void ox_collapse_return(char *str); extern void ox_sax_parse(VALUE handler, VALUE io, SaxOptions options); extern void ox_sax_drive_cleanup(SaxDrive dr); diff --git a/ext/ox/sax_as.c b/ext/ox/sax_as.c index a67012a5..7fde7393 100644 --- a/ext/ox/sax_as.c +++ b/ext/ox/sax_as.c @@ -106,9 +106,11 @@ static VALUE parse_xsd_time(const char *text) { * *return* value as an String. */ static VALUE sax_value_as_s(VALUE self) { - SaxDrive dr = DATA_PTR(self); + SaxDrive dr; VALUE rs; + TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr); + if ('\0' == *dr->buf.str) { return Qnil; } @@ -132,7 +134,9 @@ static VALUE sax_value_as_s(VALUE self) { * *return* value as an Symbol. */ static VALUE sax_value_as_sym(VALUE self) { - SaxDrive dr = DATA_PTR(self); + SaxDrive dr; + + TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr); if ('\0' == *dr->buf.str) { return Qnil; @@ -145,7 +149,9 @@ static VALUE sax_value_as_sym(VALUE self) { * *return* value as an Float. */ static VALUE sax_value_as_f(VALUE self) { - SaxDrive dr = DATA_PTR(self); + SaxDrive dr; + + TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr); if ('\0' == *dr->buf.str) { return Qnil; @@ -158,11 +164,14 @@ static VALUE sax_value_as_f(VALUE self) { * *return* value as an Fixnum. */ static VALUE sax_value_as_i(VALUE self) { - SaxDrive dr = DATA_PTR(self); - const char *s = dr->buf.str; + SaxDrive dr; + const char *s; long n = 0; int neg = 0; + TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr); + s = dr->buf.str; + if ('\0' == *s) { return Qnil; } @@ -190,10 +199,13 @@ static VALUE sax_value_as_i(VALUE self) { * *return* value as an Time. */ static VALUE sax_value_as_time(VALUE self) { - SaxDrive dr = DATA_PTR(self); - const char *str = dr->buf.str; + SaxDrive dr; + const char *str; VALUE t; + TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr); + str = dr->buf.str; + if ('\0' == *str) { return Qnil; } @@ -212,7 +224,10 @@ static VALUE sax_value_as_time(VALUE self) { * *return* value as an boolean. */ static VALUE sax_value_as_bool(VALUE self) { - return (0 == strcasecmp("true", ((SaxDrive)DATA_PTR(self))->buf.str)) ? Qtrue : Qfalse; + SaxDrive dr; + + TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr); + return (0 == strcasecmp("true", dr->buf.str)) ? Qtrue : Qfalse; } /* call-seq: empty() @@ -220,7 +235,10 @@ static VALUE sax_value_as_bool(VALUE self) { * *return* true if the value is empty. */ static VALUE sax_value_empty(VALUE self) { - return ('\0' == *((SaxDrive)DATA_PTR(self))->buf.str) ? Qtrue : Qfalse; + SaxDrive dr; + + TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr); + return ('\0' == *dr->buf.str) ? Qtrue : Qfalse; } /* Document-class: Ox::Sax::Value