Skip to content

Commit

Permalink
Merge branch 'pretty_generate-fix' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
ohler55 committed Feb 18, 2022
2 parents a1c56ff + 048cd32 commit 41f4223
Show file tree
Hide file tree
Showing 22 changed files with 184 additions and 125 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,10 @@
# CHANGELOG

## 3.13.12 - <not released>

- Fixed crash on no arguments to pretty_generate. Now raises an exception.
- Register all classes and globals.

## 3.13.11 - 2022-01-05

- Fixed write blocking failures on writes to a slow stream with larger writes.
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Expand Up @@ -21,7 +21,7 @@ task :test_all => [:clean, :compile] do
exitcode = 0
status = 0

cmds = "ruby test/tests.rb && ruby test/tests_mimic.rb && ruby test/tests_mimic_addition.rb"
cmds = "ruby test/tests.rb -v && ruby test/tests_mimic.rb -v && ruby test/tests_mimic_addition.rb -v"
STDOUT.syswrite "\n#{'#'*90}\n#{cmds}\n"
Bundler.with_original_env do
status = system(cmds)
Expand Down
2 changes: 1 addition & 1 deletion ext/oj/circarray.c
Expand Up @@ -3,7 +3,7 @@

#include "circarray.h"

CircArray oj_circ_array_new() {
CircArray oj_circ_array_new(void) {
CircArray ca;

if (0 == (ca = ALLOC(struct _circArray))) {
Expand Down
2 changes: 2 additions & 0 deletions ext/oj/dump.c
Expand Up @@ -635,6 +635,7 @@ void oj_write_obj_to_file(VALUE obj, const char *path, Options copts) {
}
}

#if !IS_WINDOWS
static void write_ready(int fd) {
struct pollfd pp;
int i;
Expand All @@ -649,6 +650,7 @@ static void write_ready(int fd) {
rb_raise(rb_eIOError, "write failed. %d %s.", errno, strerror(errno));
}
}
#endif

void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
char buf[4096];
Expand Down
2 changes: 1 addition & 1 deletion ext/oj/dump_object.c
Expand Up @@ -446,7 +446,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
assure_size(out, size);
name = rb_id2name(*idp);
nlen = strlen(name);
if (0 != *fp) {
if (NULL != *fp) {
v = (*fp)(obj);
} else if (0 == strchr(name, '.')) {
v = rb_funcall(obj, *idp, 0);
Expand Down
7 changes: 5 additions & 2 deletions ext/oj/fast.c
Expand Up @@ -771,7 +771,7 @@ static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) {
pi.doc = doc;
#if IS_WINDOWS
// assume a 1M stack and give half to ruby
pi.stack_min = (void *)((char *)&pi - (512 * 1024));
pi.stack_min = (void *)((char *)&pi - (512L * 1024L));
#else
{
struct rlimit lim;
Expand Down Expand Up @@ -1717,8 +1717,11 @@ static VALUE doc_not_implemented(VALUE self) {
* # Now try again using a path to Oj::Doc.fetch() directly and not using a
* block. doc = Oj::Doc.open(json) doc.fetch('/2/three') #=> 3 doc.close()
*/
void oj_init_doc() {
void oj_init_doc(void) {
oj_doc_class = rb_define_class_under(Oj, "Doc", rb_cObject);
rb_gc_register_address(&oj_doc_class);
rb_undef_alloc_func(oj_doc_class);

rb_define_singleton_method(oj_doc_class, "open", doc_open, 1);
rb_define_singleton_method(oj_doc_class, "open_file", doc_open_file, 1);
rb_define_singleton_method(oj_doc_class, "parse", doc_open, 1);
Expand Down
9 changes: 7 additions & 2 deletions ext/oj/intern.c
Expand Up @@ -86,9 +86,12 @@ static VALUE form_attr(const char *str, size_t len) {
return (VALUE)rb_intern3(buf, len + 1, oj_utf8_encoding);
}

void oj_hash_init() {
void oj_hash_init(void) {
VALUE cache_class = rb_define_class_under(Oj, "Cache", rb_cObject);

rb_gc_register_address(&cache_class);
rb_undef_alloc_func(cache_class);

str_cache = cache_create(0, form_str, true, true);
str_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, str_cache);
rb_gc_register_address(&str_cache_obj);
Expand Down Expand Up @@ -288,8 +291,10 @@ char *oj_strndup(const char *s, size_t len) {
return d;
}

void intern_cleanup() {
/*
void intern_cleanup(void) {
cache_free(str_cache);
cache_free(sym_cache);
cache_free(attr_cache);
}
*/
2 changes: 1 addition & 1 deletion ext/oj/intern.h
Expand Up @@ -9,7 +9,7 @@

struct _parseInfo;

extern void oj_hash_init();
extern void oj_hash_init(void);

extern VALUE oj_str_intern(const char *key, size_t len);
extern VALUE oj_sym_intern(const char *key, size_t len);
Expand Down
8 changes: 7 additions & 1 deletion ext/oj/mimic_json.c
Expand Up @@ -362,6 +362,9 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
struct _out out;
VALUE rstr;

if (0 == argc) {
rb_raise(rb_eArgError, "wrong number of arguments (0))");
}
memset(buf, 0, sizeof(buf));

out.buf = buf;
Expand Down Expand Up @@ -457,9 +460,12 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
// a Hash. I haven't dug deep enough to find out why but using a State
// instance and not a Hash gives the desired behavior.
*rargs = *argv;
if (0 == argc) {
rb_raise(rb_eArgError, "wrong number of arguments (0))");
}
if (1 == argc) {
h = rb_hash_new();
} else {
} else {
h = argv[1];
}
if (!oj_hash_has_key(h, oj_indent_sym)) {
Expand Down
142 changes: 81 additions & 61 deletions ext/oj/odd.c
Expand Up @@ -5,28 +5,27 @@

#include <string.h>

static struct _odd _odds[4]; // bump up if new initial Odd classes are added
static struct _odd *odds = _odds;
static long odd_cnt = 0;
static ID sec_id;
static ID sec_fraction_id;
static ID to_f_id;
static ID numerator_id;
static ID denominator_id;
static ID rational_id;
static VALUE rational_class;
static Odd odds = NULL;
static ID sec_id;
static ID sec_fraction_id;
static ID to_f_id;
static ID numerator_id;
static ID denominator_id;
static ID rational_id;

static void set_class(Odd odd, const char *classname) {
const char **np;
ID * idp;
ID *idp;

odd->classname = classname;
odd->clen = strlen(classname);
odd->clas = rb_const_get(rb_cObject, rb_intern(classname));
odd->classname = classname;
odd->clen = strlen(classname);
odd->clas = rb_const_get(rb_cObject, rb_intern(classname));
rb_gc_register_mark_object(odd->clas);
odd->create_obj = odd->clas;
odd->create_op = rb_intern("new");
odd->is_module = (T_MODULE == rb_type(odd->clas));
odd->raw = 0;
rb_gc_register_mark_object(odd->create_obj);
odd->create_op = rb_intern("new");
odd->is_module = (T_MODULE == rb_type(odd->clas));
odd->raw = 0;
for (np = odd->attr_names, idp = odd->attrs; 0 != *np; np++, idp++) {
*idp = rb_intern(*np);
}
Expand All @@ -45,7 +44,40 @@ static VALUE get_datetime_secs(VALUE obj) {
return rb_funcall(rb_cObject, rational_id, 2, rb_ll2inum(num), rb_ll2inum(den));
}

void oj_odd_init() {
static void print_odd(Odd odd) {
const char **np;
int i;

printf(" %s {\n", odd->classname);
printf(" attr_cnt: %d %p\n", odd->attr_cnt, (void *)odd->attr_names);
printf(" attr_names: %p\n", (void *)*odd->attr_names);
printf(" attr_names: %c\n", **odd->attr_names);
for (i = odd->attr_cnt, np = odd->attr_names; 0 < i; i--, np++) {
printf(" %d %s\n", i, *np);
}
printf(" }\n");
}

void print_all_odds(const char *label) {
Odd odd;
printf("@ %s {\n", label);
for (odd = odds; NULL != odd; odd = odd->next) {
print_odd(odd);
}
printf("}\n");
}

static Odd odd_create(void) {
Odd odd = ALLOC(struct _odd);

memset(odd, 0, sizeof(struct _odd));
odd->next = odds;
odds = odd;

return odd;
}

void oj_odd_init(void) {
Odd odd;
const char **np;

Expand All @@ -55,11 +87,9 @@ void oj_odd_init() {
numerator_id = rb_intern("numerator");
denominator_id = rb_intern("denominator");
rational_id = rb_intern("Rational");
rational_class = rb_const_get(rb_cObject, rational_id);

memset(_odds, 0, sizeof(_odds));
odd = odds;
// Rational
odd = odd_create();
np = odd->attr_names;
*np++ = "numerator";
*np++ = "denominator";
Expand All @@ -68,8 +98,9 @@ void oj_odd_init() {
odd->create_obj = rb_cObject;
odd->create_op = rational_id;
odd->attr_cnt = 2;

// Date
odd++;
odd = odd_create();
np = odd->attr_names;
*np++ = "year";
*np++ = "month";
Expand All @@ -78,8 +109,9 @@ void oj_odd_init() {
*np++ = 0;
set_class(odd, "Date");
odd->attr_cnt = 4;

// DateTime
odd++;
odd = odd_create();
np = odd->attr_names;
*np++ = "year";
*np++ = "month";
Expand All @@ -93,24 +125,23 @@ void oj_odd_init() {
set_class(odd, "DateTime");
odd->attr_cnt = 8;
odd->attrFuncs[5] = get_datetime_secs;

// Range
odd++;
odd = odd_create();
np = odd->attr_names;
*np++ = "begin";
*np++ = "end";
*np++ = "exclude_end?";
*np++ = 0;
set_class(odd, "Range");
odd->attr_cnt = 3;

odd_cnt = odd - odds + 1;
}

Odd oj_get_odd(VALUE clas) {
Odd odd;
const char *classname = NULL;

for (odd = odds + odd_cnt - 1; odds <= odd; odd--) {
for (odd = odds; NULL != odd; odd = odd->next) {
if (clas == odd->clas) {
return odd;
}
Expand All @@ -129,21 +160,20 @@ Odd oj_get_odd(VALUE clas) {
Odd oj_get_oddc(const char *classname, size_t len) {
Odd odd;

for (odd = odds + odd_cnt - 1; odds <= odd; odd--) {
for (odd = odds; NULL != odd; odd = odd->next) {
if (len == odd->clen && 0 == strncmp(classname, odd->classname, len)) {
return odd;
}
if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) &&
':' == classname[odd->clen]) {
if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) && ':' == classname[odd->clen]) {
return odd;
}
}
return 0;
return NULL;
}

OddArgs oj_odd_alloc_args(Odd odd) {
OddArgs oa = ALLOC_N(struct _oddArgs, 1);
VALUE * a;
VALUE *a;
int i;

oa->odd = odd;
Expand All @@ -159,11 +189,10 @@ void oj_odd_free(OddArgs args) {

int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
const char **np;
VALUE * vp;
VALUE *vp;
int i;

for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i;
i--, np++, vp++) {
for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i; i--, np++, vp++) {
if (0 == strncmp(key, *np, klen) && '\0' == *((*np) + klen)) {
*vp = value;
return 0;
Expand All @@ -172,52 +201,43 @@ int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
return -1;
}

void oj_reg_odd(VALUE clas,
VALUE create_object,
VALUE create_method,
int mcnt,
VALUE *members,
bool raw) {
void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw) {
Odd odd;
const char **np;
ID * ap;
ID *ap;
AttrGetFunc *fp;

if (_odds == odds) {
odds = ALLOC_N(struct _odd, odd_cnt + 1);

memcpy(odds, _odds, sizeof(struct _odd) * odd_cnt);
} else {
REALLOC_N(odds, struct _odd, odd_cnt + 1);
}
odd = odds + odd_cnt;
odd = odd_create();
odd->clas = clas;
rb_gc_register_mark_object(odd->clas);
if (NULL == (odd->classname = strdup(rb_class2name(clas)))) {
rb_raise(rb_eNoMemError, "for attribute name.");
rb_raise(rb_eNoMemError, "for class name.");
}
odd->clen = strlen(odd->classname);
odd->create_obj = create_object;
odd->create_op = SYM2ID(create_method);
odd->attr_cnt = mcnt;
odd->is_module = (T_MODULE == rb_type(clas));
odd->raw = raw;
for (ap = odd->attrs, np = odd->attr_names, fp = odd->attrFuncs; 0 < mcnt;
mcnt--, ap++, np++, members++, fp++) {
rb_gc_register_mark_object(odd->create_obj);
odd->create_op = SYM2ID(create_method);
odd->attr_cnt = mcnt;
odd->is_module = (T_MODULE == rb_type(clas));
odd->raw = raw;
for (ap = odd->attrs, np = odd->attr_names, fp = odd->attrFuncs; 0 < mcnt; mcnt--, ap++, np++, members++, fp++) {
*fp = 0;
switch (rb_type(*members)) {
case T_STRING:
if (NULL == (*np = strdup(RSTRING_PTR(*members)))) {
rb_raise(rb_eNoMemError, "for attribute name.");
}
break;
case T_SYMBOL: *np = rb_id2name(SYM2ID(*members)); break;
default:
rb_raise(rb_eArgError, "registered member identifiers must be Strings or Symbols.");
case T_SYMBOL:
// The symbol can move and invalidate the name so make a copy.
if (NULL == (*np = strdup(rb_id2name(SYM2ID(*members))))) {
rb_raise(rb_eNoMemError, "for attribute name.");
}
break;
default: rb_raise(rb_eArgError, "registered member identifiers must be Strings or Symbols."); break;
}
*ap = rb_intern(*np);
}
*np = 0;
*ap = 0;
odd_cnt++;
}

0 comments on commit 41f4223

Please sign in to comment.