ox 2.14.14 → 2.14.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/ox/obj_load.c CHANGED
@@ -3,518 +3,470 @@
3
3
  * All rights reserved.
4
4
  */
5
5
 
6
- #include <stdlib.h>
7
6
  #include <errno.h>
7
+ #include <stdarg.h>
8
8
  #include <stdio.h>
9
+ #include <stdlib.h>
9
10
  #include <string.h>
10
- #include <stdarg.h>
11
11
  #include <time.h>
12
12
 
13
- #include "ruby.h"
14
- #include "ruby/encoding.h"
15
-
16
13
  #include "base64.h"
17
- #include "ox.h"
18
14
  #include "intern.h"
15
+ #include "ox.h"
16
+ #include "ruby.h"
17
+ #include "ruby/encoding.h"
19
18
 
20
- static void instruct(PInfo pi, const char *target, Attr attrs, const char *content);
21
- static void add_text(PInfo pi, char *text, int closed);
22
- static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren);
23
- static void end_element(PInfo pi, const char *ename);
24
-
25
- static VALUE parse_time(const char *text, VALUE clas);
26
- static VALUE parse_xsd_time(const char *text, VALUE clas);
27
- static VALUE parse_double_time(const char *text, VALUE clas);
28
- static VALUE parse_regexp(const char *text);
29
-
30
- static ID get_var_sym_from_attrs(Attr a, void *encoding);
31
- static VALUE get_obj_from_attrs(Attr a, PInfo pi, VALUE base_class);
32
- static VALUE get_class_from_attrs(Attr a, PInfo pi, VALUE base_class);
33
- static VALUE classname2class(const char *name, PInfo pi, VALUE base_class);
34
- static unsigned long get_id_from_attrs(PInfo pi, Attr a);
35
- static CircArray circ_array_new(void);
36
- static void circ_array_free(CircArray ca);
37
- static void circ_array_set(CircArray ca, VALUE obj, unsigned long id);
38
- static VALUE circ_array_get(CircArray ca, unsigned long id);
39
-
40
- static void debug_stack(PInfo pi, const char *comment);
41
- static void fill_indent(PInfo pi, char *buf, size_t size);
42
-
43
-
44
- struct _parseCallbacks _ox_obj_callbacks = {
45
- instruct, // instruct,
46
- 0, // add_doctype,
47
- 0, // add_comment,
48
- 0, // add_cdata,
19
+ static void instruct(PInfo pi, const char *target, Attr attrs, const char *content);
20
+ static void add_text(PInfo pi, char *text, int closed);
21
+ static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren);
22
+ static void end_element(PInfo pi, const char *ename);
23
+
24
+ static VALUE parse_time(const char *text, VALUE clas);
25
+ static VALUE parse_xsd_time(const char *text, VALUE clas);
26
+ static VALUE parse_double_time(const char *text, VALUE clas);
27
+ static VALUE parse_regexp(const char *text);
28
+
29
+ static ID get_var_sym_from_attrs(Attr a, void *encoding);
30
+ static VALUE get_obj_from_attrs(Attr a, PInfo pi, VALUE base_class);
31
+ static VALUE get_class_from_attrs(Attr a, PInfo pi, VALUE base_class);
32
+ static VALUE classname2class(const char *name, PInfo pi, VALUE base_class);
33
+ static unsigned long get_id_from_attrs(PInfo pi, Attr a);
34
+ static CircArray circ_array_new(void);
35
+ static void circ_array_free(CircArray ca);
36
+ static void circ_array_set(CircArray ca, VALUE obj, unsigned long id);
37
+ static VALUE circ_array_get(CircArray ca, unsigned long id);
38
+
39
+ static void debug_stack(PInfo pi, const char *comment);
40
+ static void fill_indent(PInfo pi, char *buf, size_t size);
41
+
42
+ struct _parseCallbacks _ox_obj_callbacks = {
43
+ instruct, // instruct,
44
+ 0, // add_doctype,
45
+ 0, // add_comment,
46
+ 0, // add_cdata,
49
47
  add_text,
50
48
  add_element,
51
49
  end_element,
52
50
  NULL,
53
51
  };
54
52
 
55
- ParseCallbacks ox_obj_callbacks = &_ox_obj_callbacks;
53
+ ParseCallbacks ox_obj_callbacks = &_ox_obj_callbacks;
56
54
 
57
- extern ParseCallbacks ox_gen_callbacks;
55
+ extern ParseCallbacks ox_gen_callbacks;
58
56
 
59
- inline static VALUE
60
- resolve_classname(VALUE mod, const char *class_name, Effort effort, VALUE base_class) {
61
- VALUE clas;
62
- ID ci = rb_intern(class_name);
57
+ inline static VALUE resolve_classname(VALUE mod, const char *class_name, Effort effort, VALUE base_class) {
58
+ VALUE clas;
59
+ ID ci = rb_intern(class_name);
63
60
 
64
61
  switch (effort) {
65
62
  case TolerantEffort:
66
- if (rb_const_defined_at(mod, ci)) {
67
- clas = rb_const_get_at(mod, ci);
68
- } else {
69
- clas = Qundef;
70
- }
71
- break;
63
+ if (rb_const_defined_at(mod, ci)) {
64
+ clas = rb_const_get_at(mod, ci);
65
+ } else {
66
+ clas = Qundef;
67
+ }
68
+ break;
72
69
  case AutoEffort:
73
- if (rb_const_defined_at(mod, ci)) {
74
- clas = rb_const_get_at(mod, ci);
75
- } else {
76
- clas = rb_define_class_under(mod, class_name, base_class);
77
- }
78
- break;
70
+ if (rb_const_defined_at(mod, ci)) {
71
+ clas = rb_const_get_at(mod, ci);
72
+ } else {
73
+ clas = rb_define_class_under(mod, class_name, base_class);
74
+ }
75
+ break;
79
76
  case StrictEffort:
80
77
  default:
81
- // raise an error if name is not defined
82
- clas = rb_const_get_at(mod, ci);
83
- break;
78
+ // raise an error if name is not defined
79
+ clas = rb_const_get_at(mod, ci);
80
+ break;
84
81
  }
85
82
  return clas;
86
83
  }
87
84
 
88
- inline static VALUE
89
- classname2obj(const char *name, PInfo pi, VALUE base_class) {
90
- VALUE clas = classname2class(name, pi, base_class);
85
+ inline static VALUE classname2obj(const char *name, PInfo pi, VALUE base_class) {
86
+ VALUE clas = classname2class(name, pi, base_class);
91
87
 
92
88
  if (Qundef == clas) {
93
- return Qnil;
89
+ return Qnil;
94
90
  } else {
95
- return rb_obj_alloc(clas);
91
+ return rb_obj_alloc(clas);
96
92
  }
97
93
  }
98
94
 
99
- inline static VALUE
100
- structname2obj(const char *name) {
101
- VALUE ost;
102
- const char *s = name;
95
+ inline static VALUE structname2obj(const char *name) {
96
+ VALUE ost;
97
+ const char *s = name;
103
98
 
104
99
  for (; 1; s++) {
105
- if ('\0' == *s) {
106
- s = name;
107
- break;
108
- } else if (':' == *s) {
109
- s += 2;
110
- break;
111
- }
100
+ if ('\0' == *s) {
101
+ s = name;
102
+ break;
103
+ } else if (':' == *s) {
104
+ s += 2;
105
+ break;
106
+ }
112
107
  }
113
108
  ost = rb_const_get(ox_struct_class, rb_intern(s));
114
- #if HAVE_RB_STRUCT_ALLOC_NOINIT
115
109
  return rb_struct_alloc_noinit(ost);
116
- #else
117
- return rb_struct_new(ost);
118
- #endif
119
110
  }
120
111
 
121
- inline static VALUE
122
- parse_ulong(const char *s, PInfo pi) {
123
- unsigned long n = 0;
112
+ inline static VALUE parse_ulong(const char *s, PInfo pi) {
113
+ unsigned long n = 0;
124
114
 
125
115
  for (; '\0' != *s; s++) {
126
- if ('0' <= *s && *s <= '9') {
127
- n = n * 10 + (*s - '0');
128
- } else {
129
- set_error(&pi->err, "Invalid number for a julian day", pi->str, pi->s);
130
- return Qundef;
131
- }
116
+ if ('0' <= *s && *s <= '9') {
117
+ n = n * 10 + (*s - '0');
118
+ } else {
119
+ set_error(&pi->err, "Invalid number for a julian day", pi->str, pi->s);
120
+ return Qundef;
121
+ }
132
122
  }
133
123
  return ULONG2NUM(n);
134
124
  }
135
125
 
136
126
  // 2010-07-09T10:47:45.895826162+09:00
137
- inline static VALUE
138
- parse_time(const char *text, VALUE clas) {
139
- VALUE t;
127
+ inline static VALUE parse_time(const char *text, VALUE clas) {
128
+ VALUE t;
140
129
 
141
- if (Qnil == (t = parse_double_time(text, clas)) &&
142
- Qnil == (t = parse_xsd_time(text, clas))) {
143
- VALUE args[1];
130
+ if (Qnil == (t = parse_double_time(text, clas)) && Qnil == (t = parse_xsd_time(text, clas))) {
131
+ VALUE args[1];
144
132
 
145
- *args = rb_str_new2(text);
146
- t = rb_funcall2(ox_time_class, ox_parse_id, 1, args);
133
+ *args = rb_str_new2(text);
134
+ t = rb_funcall2(ox_time_class, ox_parse_id, 1, args);
147
135
  }
148
136
  return t;
149
137
  }
150
138
 
151
- static VALUE
152
- classname2class(const char *name, PInfo pi, VALUE base_class) {
153
- VALUE *slot;
154
- VALUE clas;
139
+ static VALUE classname2class(const char *name, PInfo pi, VALUE base_class) {
140
+ VALUE *slot;
141
+ VALUE clas;
155
142
 
156
143
  if (Qundef == (clas = slot_cache_get(ox_class_cache, name, &slot, 0))) {
157
- char class_name[1024];
158
- char *s;
159
- const char *n = name;
160
-
161
- clas = rb_cObject;
162
- for (s = class_name; '\0' != *n; n++) {
163
- if (':' == *n) {
164
- *s = '\0';
165
- n++;
166
- if (':' != *n) {
167
- set_error(&pi->err, "Invalid classname, expected another ':'", pi->str, pi->s);
168
- return Qundef;
169
- }
170
- if (Qundef == (clas = resolve_classname(clas, class_name, pi->options->effort, base_class))) {
171
- return Qundef;
172
- }
173
- s = class_name;
174
- } else {
175
- *s++ = *n;
176
- }
177
- }
178
- *s = '\0';
179
- if (Qundef != (clas = resolve_classname(clas, class_name, pi->options->effort, base_class))) {
180
- *slot = clas;
181
- rb_gc_register_address(slot);
182
- }
144
+ char class_name[1024];
145
+ char *s;
146
+ const char *n = name;
147
+
148
+ clas = rb_cObject;
149
+ for (s = class_name; '\0' != *n; n++) {
150
+ if (':' == *n) {
151
+ *s = '\0';
152
+ n++;
153
+ if (':' != *n) {
154
+ set_error(&pi->err, "Invalid classname, expected another ':'", pi->str, pi->s);
155
+ return Qundef;
156
+ }
157
+ if (Qundef == (clas = resolve_classname(clas, class_name, pi->options->effort, base_class))) {
158
+ return Qundef;
159
+ }
160
+ s = class_name;
161
+ } else {
162
+ *s++ = *n;
163
+ }
164
+ }
165
+ *s = '\0';
166
+ if (Qundef != (clas = resolve_classname(clas, class_name, pi->options->effort, base_class))) {
167
+ *slot = clas;
168
+ rb_gc_register_address(slot);
169
+ }
183
170
  }
184
171
  return clas;
185
172
  }
186
173
 
187
- static ID
188
- get_var_sym_from_attrs(Attr a, void *encoding) {
174
+ static ID get_var_sym_from_attrs(Attr a, void *encoding) {
189
175
  for (; 0 != a->name; a++) {
190
- if ('a' == *a->name && '\0' == *(a->name + 1)) {
191
- const char *val = a->value;
176
+ if ('a' == *a->name && '\0' == *(a->name + 1)) {
177
+ const char *val = a->value;
192
178
 
193
- if ('0' <= *val && *val <= '9') {
194
- return INT2NUM(atoi(val));
195
- }
196
- return ox_id_intern(val, strlen(val));
197
- }
179
+ if ('0' <= *val && *val <= '9') {
180
+ return INT2NUM(atoi(val));
181
+ }
182
+ return ox_id_intern(val, strlen(val));
183
+ }
198
184
  }
199
185
  return 0;
200
186
  }
201
187
 
202
- static VALUE
203
- get_obj_from_attrs(Attr a, PInfo pi, VALUE base_class) {
188
+ static VALUE get_obj_from_attrs(Attr a, PInfo pi, VALUE base_class) {
204
189
  for (; 0 != a->name; a++) {
205
- if ('c' == *a->name && '\0' == *(a->name + 1)) {
206
- return classname2obj(a->value, pi, base_class);
207
- }
190
+ if ('c' == *a->name && '\0' == *(a->name + 1)) {
191
+ return classname2obj(a->value, pi, base_class);
192
+ }
208
193
  }
209
194
  return Qundef;
210
195
  }
211
196
 
212
- static VALUE
213
- get_struct_from_attrs(Attr a) {
197
+ static VALUE get_struct_from_attrs(Attr a) {
214
198
  for (; 0 != a->name; a++) {
215
- if ('c' == *a->name && '\0' == *(a->name + 1)) {
216
- return structname2obj(a->value);
217
- }
199
+ if ('c' == *a->name && '\0' == *(a->name + 1)) {
200
+ return structname2obj(a->value);
201
+ }
218
202
  }
219
203
  return Qundef;
220
204
  }
221
205
 
222
- static VALUE
223
- get_class_from_attrs(Attr a, PInfo pi, VALUE base_class) {
206
+ static VALUE get_class_from_attrs(Attr a, PInfo pi, VALUE base_class) {
224
207
  for (; 0 != a->name; a++) {
225
- if ('c' == *a->name && '\0' == *(a->name + 1)) {
226
- return classname2class(a->value, pi, base_class);
227
- }
208
+ if ('c' == *a->name && '\0' == *(a->name + 1)) {
209
+ return classname2class(a->value, pi, base_class);
210
+ }
228
211
  }
229
212
  return Qundef;
230
213
  }
231
214
 
232
- static unsigned long
233
- get_id_from_attrs(PInfo pi, Attr a) {
215
+ static unsigned long get_id_from_attrs(PInfo pi, Attr a) {
234
216
  for (; 0 != a->name; a++) {
235
- if ('i' == *a->name && '\0' == *(a->name + 1)) {
236
- unsigned long id = 0;
237
- const char *text = a->value;
238
- char c;
239
-
240
- for (; '\0' != *text; text++) {
241
- c = *text;
242
- if ('0' <= c && c <= '9') {
243
- id = id * 10 + (c - '0');
244
- } else {
245
- set_error(&pi->err, "bad number format", pi->str, pi->s);
246
- return 0;
247
- }
248
- }
249
- return id;
250
- }
217
+ if ('i' == *a->name && '\0' == *(a->name + 1)) {
218
+ unsigned long id = 0;
219
+ const char *text = a->value;
220
+ char c;
221
+
222
+ for (; '\0' != *text; text++) {
223
+ c = *text;
224
+ if ('0' <= c && c <= '9') {
225
+ id = id * 10 + (c - '0');
226
+ } else {
227
+ set_error(&pi->err, "bad number format", pi->str, pi->s);
228
+ return 0;
229
+ }
230
+ }
231
+ return id;
232
+ }
251
233
  }
252
234
  return 0;
253
235
  }
254
236
 
255
- static CircArray
256
- circ_array_new() {
257
- CircArray ca;
237
+ static CircArray circ_array_new() {
238
+ CircArray ca;
258
239
 
259
- ca = ALLOC(struct _circArray);
240
+ ca = ALLOC(struct _circArray);
260
241
  ca->objs = ca->obj_array;
261
242
  ca->size = sizeof(ca->obj_array) / sizeof(VALUE);
262
- ca->cnt = 0;
243
+ ca->cnt = 0;
263
244
 
264
245
  return ca;
265
246
  }
266
247
 
267
- static void
268
- circ_array_free(CircArray ca) {
248
+ static void circ_array_free(CircArray ca) {
269
249
  if (ca->objs != ca->obj_array) {
270
- xfree(ca->objs);
250
+ xfree(ca->objs);
271
251
  }
272
252
  xfree(ca);
273
253
  }
274
254
 
275
- static void
276
- circ_array_set(CircArray ca, VALUE obj, unsigned long id) {
255
+ static void circ_array_set(CircArray ca, VALUE obj, unsigned long id) {
277
256
  if (0 < id) {
278
- unsigned long i;
279
-
280
- if (ca->size < id) {
281
- unsigned long cnt = id + 512;
282
-
283
- if (ca->objs == ca->obj_array) {
284
- ca->objs = ALLOC_N(VALUE, cnt);
285
- memcpy(ca->objs, ca->obj_array, sizeof(VALUE) * ca->cnt);
286
- } else {
287
- REALLOC_N(ca->objs, VALUE, cnt);
288
- }
289
- ca->size = cnt;
290
- }
291
- id--;
292
- for (i = ca->cnt; i < id; i++) {
293
- ca->objs[i] = Qundef;
294
- }
295
- ca->objs[id] = obj;
296
- if (ca->cnt <= id) {
297
- ca->cnt = id + 1;
298
- }
257
+ unsigned long i;
258
+
259
+ if (ca->size < id) {
260
+ unsigned long cnt = id + 512;
261
+
262
+ if (ca->objs == ca->obj_array) {
263
+ ca->objs = ALLOC_N(VALUE, cnt);
264
+ memcpy(ca->objs, ca->obj_array, sizeof(VALUE) * ca->cnt);
265
+ } else {
266
+ REALLOC_N(ca->objs, VALUE, cnt);
267
+ }
268
+ ca->size = cnt;
269
+ }
270
+ id--;
271
+ for (i = ca->cnt; i < id; i++) {
272
+ ca->objs[i] = Qundef;
273
+ }
274
+ ca->objs[id] = obj;
275
+ if (ca->cnt <= id) {
276
+ ca->cnt = id + 1;
277
+ }
299
278
  }
300
279
  }
301
280
 
302
- static VALUE
303
- circ_array_get(CircArray ca, unsigned long id) {
304
- VALUE obj = Qundef;
281
+ static VALUE circ_array_get(CircArray ca, unsigned long id) {
282
+ VALUE obj = Qundef;
305
283
 
306
284
  if (id <= ca->cnt) {
307
- obj = ca->objs[id - 1];
285
+ obj = ca->objs[id - 1];
308
286
  }
309
287
  return obj;
310
288
  }
311
289
 
312
- static VALUE
313
- parse_regexp(const char *text) {
314
- const char *te;
315
- int options = 0;
290
+ static VALUE parse_regexp(const char *text) {
291
+ const char *te;
292
+ int options = 0;
316
293
 
317
294
  te = text + strlen(text) - 1;
318
295
  #ifdef ONIG_OPTION_IGNORECASE
319
296
  for (; text < te && '/' != *te; te--) {
320
- switch (*te) {
321
- case 'i': options |= ONIG_OPTION_IGNORECASE; break;
322
- case 'm': options |= ONIG_OPTION_MULTILINE; break;
323
- case 'x': options |= ONIG_OPTION_EXTEND; break;
324
- default: break;
325
- }
297
+ switch (*te) {
298
+ case 'i': options |= ONIG_OPTION_IGNORECASE; break;
299
+ case 'm': options |= ONIG_OPTION_MULTILINE; break;
300
+ case 'x': options |= ONIG_OPTION_EXTEND; break;
301
+ default: break;
302
+ }
326
303
  }
327
304
  #endif
328
305
  return rb_reg_new(text + 1, te - text - 1, options);
329
306
  }
330
307
 
331
- static void
332
- instruct(PInfo pi, const char *target, Attr attrs, const char *content) {
308
+ static void instruct(PInfo pi, const char *target, Attr attrs, const char *content) {
333
309
  if (0 == strcmp("xml", target)) {
334
- for (; 0 != attrs->name; attrs++) {
335
- if (0 == strcmp("encoding", attrs->name)) {
336
- pi->options->rb_enc = rb_enc_find(attrs->value);
337
- }
338
- }
310
+ for (; 0 != attrs->name; attrs++) {
311
+ if (0 == strcmp("encoding", attrs->name)) {
312
+ pi->options->rb_enc = rb_enc_find(attrs->value);
313
+ }
314
+ }
339
315
  }
340
316
  }
341
317
 
342
- static void
343
- add_text(PInfo pi, char *text, int closed) {
344
- Helper h = helper_stack_peek(&pi->helpers);
318
+ static void add_text(PInfo pi, char *text, int closed) {
319
+ Helper h = helper_stack_peek(&pi->helpers);
345
320
 
346
321
  if (!closed) {
347
- set_error(&pi->err, "Text not closed", pi->str, pi->s);
348
- return;
322
+ set_error(&pi->err, "Text not closed", pi->str, pi->s);
323
+ return;
349
324
  }
350
325
  if (0 == h) {
351
- set_error(&pi->err, "Unexpected text", pi->str, pi->s);
352
- return;
326
+ set_error(&pi->err, "Unexpected text", pi->str, pi->s);
327
+ return;
353
328
  }
354
329
  if (DEBUG <= pi->options->trace) {
355
- char indent[128];
330
+ char indent[128];
356
331
 
357
- fill_indent(pi, indent, sizeof(indent));
358
- printf("%s '%s' to type %c\n", indent, text, h->type);
332
+ fill_indent(pi, indent, sizeof(indent));
333
+ printf("%s '%s' to type %c\n", indent, text, h->type);
359
334
  }
360
335
  switch (h->type) {
361
336
  case NoCode:
362
337
  case StringCode:
363
- h->obj = rb_str_new2(text);
364
- if (0 != pi->options->rb_enc) {
365
- rb_enc_associate(h->obj, pi->options->rb_enc);
366
- }
367
- if (0 != pi->circ_array) {
368
- circ_array_set(pi->circ_array, h->obj, (unsigned long)pi->id);
369
- }
370
- break;
371
- case FixnumCode:
372
- {
373
- long n = 0;
374
- char c;
375
- int neg = 0;
376
-
377
- if ('-' == *text) {
378
- neg = 1;
379
- text++;
380
- }
381
- for (; '\0' != *text; text++) {
382
- c = *text;
383
- if ('0' <= c && c <= '9') {
384
- n = n * 10 + (c - '0');
385
- } else {
386
- set_error(&pi->err, "bad number format", pi->str, pi->s);
387
- return;
388
- }
389
- }
390
- if (neg) {
391
- n = -n;
392
- }
393
- h->obj = LONG2NUM(n);
394
- break;
395
- }
396
- case FloatCode:
397
- h->obj = rb_float_new(strtod(text, 0));
398
- break;
399
- case SymbolCode:
400
- h->obj = ox_sym_intern(text, strlen(text), NULL);
401
- break;
402
- case DateCode:
403
- {
404
- VALUE args[1];
405
-
406
- if (Qundef == (*args = parse_ulong(text, pi))) {
407
- return;
408
- }
409
- h->obj = rb_funcall2(ox_date_class, ox_jd_id, 1, args);
410
- break;
411
- }
412
- case TimeCode:
413
- h->obj = parse_time(text, ox_time_class);
414
- break;
415
- case String64Code:
416
- {
417
- unsigned long str_size = b64_orig_size(text);
418
- VALUE v;
419
- char *str = ALLOCA_N(char, str_size + 1);
420
-
421
- from_base64(text, (uchar*)str);
422
- v = rb_str_new(str, str_size);
423
- if (0 != pi->options->rb_enc) {
424
- rb_enc_associate(v, pi->options->rb_enc);
425
- }
426
- if (0 != pi->circ_array) {
427
- circ_array_set(pi->circ_array, v, (unsigned long)h->obj);
428
- }
429
- h->obj = v;
430
- break;
431
- }
432
- case Symbol64Code:
433
- {
434
- unsigned long str_size = b64_orig_size(text);
435
- char *str = ALLOCA_N(char, str_size + 1);
436
-
437
- from_base64(text, (uchar*)str);
438
- h->obj = ox_sym_intern(str, strlen(str), NULL);
439
- break;
338
+ h->obj = rb_str_new2(text);
339
+ if (0 != pi->options->rb_enc) {
340
+ rb_enc_associate(h->obj, pi->options->rb_enc);
341
+ }
342
+ if (0 != pi->circ_array) {
343
+ circ_array_set(pi->circ_array, h->obj, (unsigned long)pi->id);
344
+ }
345
+ break;
346
+ case FixnumCode: {
347
+ long n = 0;
348
+ char c;
349
+ int neg = 0;
350
+
351
+ if ('-' == *text) {
352
+ neg = 1;
353
+ text++;
354
+ }
355
+ for (; '\0' != *text; text++) {
356
+ c = *text;
357
+ if ('0' <= c && c <= '9') {
358
+ n = n * 10 + (c - '0');
359
+ } else {
360
+ set_error(&pi->err, "bad number format", pi->str, pi->s);
361
+ return;
362
+ }
363
+ }
364
+ if (neg) {
365
+ n = -n;
366
+ }
367
+ h->obj = LONG2NUM(n);
368
+ break;
369
+ }
370
+ case FloatCode: h->obj = rb_float_new(strtod(text, 0)); break;
371
+ case SymbolCode: h->obj = ox_sym_intern(text, strlen(text), NULL); break;
372
+ case DateCode: {
373
+ VALUE args[1];
374
+
375
+ if (Qundef == (*args = parse_ulong(text, pi))) {
376
+ return;
377
+ }
378
+ h->obj = rb_funcall2(ox_date_class, ox_jd_id, 1, args);
379
+ break;
380
+ }
381
+ case TimeCode: h->obj = parse_time(text, ox_time_class); break;
382
+ case String64Code: {
383
+ unsigned long str_size = b64_orig_size(text);
384
+ VALUE v;
385
+ char *str = ALLOCA_N(char, str_size + 1);
386
+
387
+ from_base64(text, (uchar *)str);
388
+ v = rb_str_new(str, str_size);
389
+ if (0 != pi->options->rb_enc) {
390
+ rb_enc_associate(v, pi->options->rb_enc);
391
+ }
392
+ if (0 != pi->circ_array) {
393
+ circ_array_set(pi->circ_array, v, (unsigned long)h->obj);
394
+ }
395
+ h->obj = v;
396
+ break;
397
+ }
398
+ case Symbol64Code: {
399
+ unsigned long str_size = b64_orig_size(text);
400
+ char *str = ALLOCA_N(char, str_size + 1);
401
+
402
+ from_base64(text, (uchar *)str);
403
+ h->obj = ox_sym_intern(str, strlen(str), NULL);
404
+ break;
440
405
  }
441
406
  case RegexpCode:
442
- if ('/' == *text) {
443
- h->obj = parse_regexp(text);
444
- } else {
445
- unsigned long str_size = b64_orig_size(text);
446
- char *str = ALLOCA_N(char, str_size + 1);
447
-
448
- from_base64(text, (uchar*)str);
449
- h->obj = parse_regexp(str);
450
- }
451
- break;
452
- case BignumCode:
453
- h->obj = rb_cstr_to_inum(text, 10, 1);
454
- break;
455
- case BigDecimalCode:
456
- h->obj = rb_funcall(rb_cObject, ox_bigdecimal_id, 1, rb_str_new2(text));
457
- break;
458
- default:
459
- h->obj = Qnil;
460
- break;
407
+ if ('/' == *text) {
408
+ h->obj = parse_regexp(text);
409
+ } else {
410
+ unsigned long str_size = b64_orig_size(text);
411
+ char *str = ALLOCA_N(char, str_size + 1);
412
+
413
+ from_base64(text, (uchar *)str);
414
+ h->obj = parse_regexp(str);
415
+ }
416
+ break;
417
+ case BignumCode: h->obj = rb_cstr_to_inum(text, 10, 1); break;
418
+ case BigDecimalCode: h->obj = rb_funcall(rb_cObject, ox_bigdecimal_id, 1, rb_str_new2(text)); break;
419
+ default: h->obj = Qnil; break;
461
420
  }
462
421
  }
463
422
 
464
- static void
465
- add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
466
- Attr a;
467
- Helper h;
468
- unsigned long id;
423
+ static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
424
+ Attr a;
425
+ Helper h;
426
+ unsigned long id;
469
427
 
470
428
  if (TRACE <= pi->options->trace) {
471
- char buf[1024];
472
- char indent[128];
473
- char *s = buf;
474
- char *end = buf + sizeof(buf) - 2;
475
-
476
- s += snprintf(s, end - s, " <%s%s", (hasChildren) ? "" : "/", ename);
477
- for (a = attrs; 0 != a->name; a++) {
478
- s += snprintf(s, end - s, " %s=%s", a->name, a->value);
479
- }
480
- *s++ = '>';
481
- *s++ = '\0';
482
- if (DEBUG <= pi->options->trace) {
483
- printf("===== add element stack(%d) =====\n", helper_stack_depth(&pi->helpers));
484
- debug_stack(pi, buf);
485
- } else {
486
- fill_indent(pi, indent, sizeof(indent));
487
- printf("%s%s\n", indent, buf);
488
- }
489
- }
490
- if (helper_stack_empty(&pi->helpers)) { // top level object
491
- if (0 != (id = get_id_from_attrs(pi, attrs))) {
492
- pi->circ_array = circ_array_new();
493
- }
429
+ char buf[1024];
430
+ char indent[128];
431
+ char *s = buf;
432
+ char *end = buf + sizeof(buf) - 2;
433
+
434
+ s += snprintf(s, end - s, " <%s%s", (hasChildren) ? "" : "/", ename);
435
+ for (a = attrs; 0 != a->name; a++) {
436
+ s += snprintf(s, end - s, " %s=%s", a->name, a->value);
437
+ }
438
+ *s++ = '>';
439
+ *s++ = '\0';
440
+ if (DEBUG <= pi->options->trace) {
441
+ printf("===== add element stack(%d) =====\n", helper_stack_depth(&pi->helpers));
442
+ debug_stack(pi, buf);
443
+ } else {
444
+ fill_indent(pi, indent, sizeof(indent));
445
+ printf("%s%s\n", indent, buf);
446
+ }
447
+ }
448
+ if (helper_stack_empty(&pi->helpers)) { // top level object
449
+ if (0 != (id = get_id_from_attrs(pi, attrs))) {
450
+ pi->circ_array = circ_array_new();
451
+ }
494
452
  }
495
453
  if ('\0' != ename[1]) {
496
- set_error(&pi->err, "Invalid element name", pi->str, pi->s);
497
- return;
454
+ set_error(&pi->err, "Invalid element name", pi->str, pi->s);
455
+ return;
498
456
  }
499
- h = helper_stack_push(&pi->helpers, get_var_sym_from_attrs(attrs, (void*)pi->options->rb_enc), Qundef, *ename);
457
+ h = helper_stack_push(&pi->helpers, get_var_sym_from_attrs(attrs, (void *)pi->options->rb_enc), Qundef, *ename);
500
458
  switch (h->type) {
501
- case NilClassCode:
502
- h->obj = Qnil;
503
- break;
504
- case TrueClassCode:
505
- h->obj = Qtrue;
506
- break;
507
- case FalseClassCode:
508
- h->obj = Qfalse;
509
- break;
459
+ case NilClassCode: h->obj = Qnil; break;
460
+ case TrueClassCode: h->obj = Qtrue; break;
461
+ case FalseClassCode: h->obj = Qfalse; break;
510
462
  case StringCode:
511
- // h->obj will be replaced by add_text if it is called
512
- h->obj = ox_empty_string;
513
- if (0 != pi->circ_array) {
514
- pi->id = get_id_from_attrs(pi, attrs);
515
- circ_array_set(pi->circ_array, h->obj, pi->id);
516
- }
517
- break;
463
+ // h->obj will be replaced by add_text if it is called
464
+ h->obj = ox_empty_string;
465
+ if (0 != pi->circ_array) {
466
+ pi->id = get_id_from_attrs(pi, attrs);
467
+ circ_array_set(pi->circ_array, h->obj, pi->id);
468
+ }
469
+ break;
518
470
  case FixnumCode:
519
471
  case FloatCode:
520
472
  case SymbolCode:
@@ -525,361 +477,333 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
525
477
  case ComplexCode:
526
478
  case DateCode:
527
479
  case TimeCode:
528
- case RationalCode: // sub elements read next
529
- // value will be read in the following add_text
530
- h->obj = Qundef;
531
- break;
480
+ case RationalCode: // sub elements read next
481
+ // value will be read in the following add_text
482
+ h->obj = Qundef;
483
+ break;
532
484
  case String64Code:
533
- h->obj = Qundef;
534
- if (0 != pi->circ_array) {
535
- pi->id = get_id_from_attrs(pi, attrs);
536
- }
537
- break;
485
+ h->obj = Qundef;
486
+ if (0 != pi->circ_array) {
487
+ pi->id = get_id_from_attrs(pi, attrs);
488
+ }
489
+ break;
538
490
  case ArrayCode:
539
- h->obj = rb_ary_new();
540
- if (0 != pi->circ_array) {
541
- circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
542
- }
543
- break;
491
+ h->obj = rb_ary_new();
492
+ if (0 != pi->circ_array) {
493
+ circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
494
+ }
495
+ break;
544
496
  case HashCode:
545
- h->obj = rb_hash_new();
546
- if (0 != pi->circ_array) {
547
- circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
548
- }
549
- break;
550
- case RangeCode:
551
- h->obj = rb_ary_new_from_args(3, Qnil, Qnil, Qfalse);
552
- break;
497
+ h->obj = rb_hash_new();
498
+ if (0 != pi->circ_array) {
499
+ circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
500
+ }
501
+ break;
502
+ case RangeCode: h->obj = rb_ary_new_from_args(3, Qnil, Qnil, Qfalse); break;
553
503
  case RawCode:
554
- if (hasChildren) {
555
- h->obj = ox_parse(pi->s, pi->end - pi->s, ox_gen_callbacks, &pi->s, pi->options, &pi->err);
556
- if (0 != pi->circ_array) {
557
- circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
558
- }
559
- } else {
560
- h->obj = Qnil;
561
- }
562
- break;
504
+ if (hasChildren) {
505
+ h->obj = ox_parse(pi->s, pi->end - pi->s, ox_gen_callbacks, &pi->s, pi->options, &pi->err);
506
+ if (0 != pi->circ_array) {
507
+ circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
508
+ }
509
+ } else {
510
+ h->obj = Qnil;
511
+ }
512
+ break;
563
513
  case ExceptionCode:
564
- if (Qundef == (h->obj = get_obj_from_attrs(attrs, pi, rb_eException))) {
565
- return;
566
- }
567
- if (0 != pi->circ_array && Qnil != h->obj) {
568
- circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
569
- }
570
- break;
514
+ if (Qundef == (h->obj = get_obj_from_attrs(attrs, pi, rb_eException))) {
515
+ return;
516
+ }
517
+ if (0 != pi->circ_array && Qnil != h->obj) {
518
+ circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
519
+ }
520
+ break;
571
521
  case ObjectCode:
572
- if (Qundef == (h->obj = get_obj_from_attrs(attrs, pi, ox_bag_clas))) {
573
- return;
574
- }
575
- if (0 != pi->circ_array && Qnil != h->obj) {
576
- circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
577
- }
578
- break;
522
+ if (Qundef == (h->obj = get_obj_from_attrs(attrs, pi, ox_bag_clas))) {
523
+ return;
524
+ }
525
+ if (0 != pi->circ_array && Qnil != h->obj) {
526
+ circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
527
+ }
528
+ break;
579
529
  case StructCode:
580
- h->obj = get_struct_from_attrs(attrs);
581
- if (0 != pi->circ_array) {
582
- circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
583
- }
584
- break;
530
+ h->obj = get_struct_from_attrs(attrs);
531
+ if (0 != pi->circ_array) {
532
+ circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
533
+ }
534
+ break;
585
535
  case ClassCode:
586
- if (Qundef == (h->obj = get_class_from_attrs(attrs, pi, ox_bag_clas))) {
587
- return;
588
- }
589
- break;
536
+ if (Qundef == (h->obj = get_class_from_attrs(attrs, pi, ox_bag_clas))) {
537
+ return;
538
+ }
539
+ break;
590
540
  case RefCode:
591
- h->obj = Qundef;
592
- if (0 != pi->circ_array) {
593
- h->obj = circ_array_get(pi->circ_array, get_id_from_attrs(pi, attrs));
594
- }
595
- if (Qundef == h->obj) {
596
- set_error(&pi->err, "Invalid circular reference", pi->str, pi->s);
597
- return;
598
- }
599
- break;
541
+ h->obj = Qundef;
542
+ if (0 != pi->circ_array) {
543
+ h->obj = circ_array_get(pi->circ_array, get_id_from_attrs(pi, attrs));
544
+ }
545
+ if (Qundef == h->obj) {
546
+ set_error(&pi->err, "Invalid circular reference", pi->str, pi->s);
547
+ return;
548
+ }
549
+ break;
600
550
  default:
601
- set_error(&pi->err, "Invalid element name", pi->str, pi->s);
602
- return;
603
- break;
551
+ set_error(&pi->err, "Invalid element name", pi->str, pi->s);
552
+ return;
553
+ break;
604
554
  }
605
555
  if (DEBUG <= pi->options->trace) {
606
- debug_stack(pi, " -----------");
556
+ debug_stack(pi, " -----------");
607
557
  }
608
558
  }
609
559
 
610
- static void
611
- end_element(PInfo pi, const char *ename) {
560
+ static void end_element(PInfo pi, const char *ename) {
612
561
  if (TRACE <= pi->options->trace) {
613
- char indent[128];
562
+ char indent[128];
614
563
 
615
- if (DEBUG <= pi->options->trace) {
616
- char buf[1024];
564
+ if (DEBUG <= pi->options->trace) {
565
+ char buf[1024];
617
566
 
618
- printf("===== end element stack(%d) =====\n", helper_stack_depth(&pi->helpers));
619
- snprintf(buf, sizeof(buf) - 1, "</%s>", ename);
620
- debug_stack(pi, buf);
621
- } else {
622
- fill_indent(pi, indent, sizeof(indent));
623
- printf("%s</%s>\n", indent, ename);
624
- }
567
+ printf("===== end element stack(%d) =====\n", helper_stack_depth(&pi->helpers));
568
+ snprintf(buf, sizeof(buf) - 1, "</%s>", ename);
569
+ debug_stack(pi, buf);
570
+ } else {
571
+ fill_indent(pi, indent, sizeof(indent));
572
+ printf("%s</%s>\n", indent, ename);
573
+ }
625
574
  }
626
575
  if (!helper_stack_empty(&pi->helpers)) {
627
- Helper h = helper_stack_pop(&pi->helpers);
628
- Helper ph = helper_stack_peek(&pi->helpers);
629
-
630
- if (ox_empty_string == h->obj) {
631
- // special catch for empty strings
632
- h->obj = rb_str_new2("");
633
- } else if (Qundef == h->obj) {
634
- set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
635
- return;
636
- } else if (RangeCode == h->type) { // Expect an array of 3 elements.
637
- const VALUE *ap = RARRAY_PTR(h->obj);
638
-
639
- h->obj = rb_range_new(*ap, *(ap + 1), Qtrue == *(ap + 2));
640
- }
641
- pi->obj = h->obj;
642
- if (0 != ph) {
643
- switch (ph->type) {
644
- case ArrayCode:
645
- rb_ary_push(ph->obj, h->obj);
646
- break;
647
- case ExceptionCode:
648
- case ObjectCode:
649
- if (Qnil != ph->obj) {
650
- if (0 == h->var || NULL == rb_id2name(h->var )) {
651
- set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
652
- return;
653
- }
654
- if (RUBY_T_OBJECT != rb_type(ph->obj)) {
655
- set_error(&pi->err, "Corrupt object encoding", pi->str, pi->s);
656
- return;
657
- }
658
- rb_ivar_set(ph->obj, h->var, h->obj);
659
- }
660
- break;
661
- case StructCode:
662
- if (0 == h->var) {
663
- set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
664
- return;
665
- }
666
- rb_struct_aset(ph->obj, h->var, h->obj);
667
- break;
668
- case HashCode:
669
- // put back h
670
- helper_stack_push(&pi->helpers, h->var, h->obj, KeyCode);
671
- break;
672
- case RangeCode:
673
- if (ox_beg_id == h->var) {
674
- rb_ary_store(ph->obj, 0, h->obj);
675
- } else if (ox_end_id == h->var) {
676
- rb_ary_store(ph->obj, 1, h->obj);
677
- } else if (ox_excl_id == h->var) {
678
- rb_ary_store(ph->obj, 2, h->obj);
679
- } else {
680
- set_error(&pi->err, "Invalid range attribute", pi->str, pi->s);
681
- return;
682
- }
683
- break;
684
- case KeyCode:
685
- {
686
- Helper gh;
687
-
688
- helper_stack_pop(&pi->helpers);
689
- if (NULL == (gh = helper_stack_peek(&pi->helpers)) || Qundef == ph->obj || Qundef == h->obj) {
690
- set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s);
691
- return;
692
- }
693
- rb_hash_aset(gh->obj, ph->obj, h->obj);
694
- }
695
- break;
696
- case ComplexCode:
697
- #ifdef T_COMPLEX
698
- if (Qundef == ph->obj) {
699
- ph->obj = h->obj;
700
- } else {
701
- ph->obj = rb_complex_new(ph->obj, h->obj);
702
- }
703
- #else
704
- set_error(&pi->err, "Complex Objects not implemented in Ruby 1.8.7", pi->str, pi->s);
705
- return;
706
- #endif
707
- break;
708
- case RationalCode: {
709
- if (Qundef == h->obj || RUBY_T_FIXNUM != rb_type(h->obj)) {
710
- set_error(&pi->err, "Invalid object format", pi->str, pi->s);
711
- return;
712
- }
713
- #ifdef T_RATIONAL
714
- if (Qundef == ph->obj) {
715
- ph->obj = h->obj;
716
- } else {
717
- if (Qundef == ph->obj || RUBY_T_FIXNUM != rb_type(h->obj)) {
718
- set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s);
719
- return;
720
- }
576
+ Helper h = helper_stack_pop(&pi->helpers);
577
+ Helper ph = helper_stack_peek(&pi->helpers);
578
+
579
+ if (ox_empty_string == h->obj) {
580
+ // special catch for empty strings
581
+ h->obj = rb_str_new2("");
582
+ } else if (Qundef == h->obj) {
583
+ set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
584
+ return;
585
+ } else if (RangeCode == h->type) { // Expect an array of 3 elements.
586
+ const VALUE *ap = RARRAY_PTR(h->obj);
587
+
588
+ h->obj = rb_range_new(*ap, *(ap + 1), Qtrue == *(ap + 2));
589
+ }
590
+ pi->obj = h->obj;
591
+ if (0 != ph) {
592
+ switch (ph->type) {
593
+ case ArrayCode: rb_ary_push(ph->obj, h->obj); break;
594
+ case ExceptionCode:
595
+ case ObjectCode:
596
+ if (Qnil != ph->obj) {
597
+ if (0 == h->var || NULL == rb_id2name(h->var)) {
598
+ set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
599
+ return;
600
+ }
601
+ if (RUBY_T_OBJECT != rb_type(ph->obj)) {
602
+ set_error(&pi->err, "Corrupt object encoding", pi->str, pi->s);
603
+ return;
604
+ }
605
+ rb_ivar_set(ph->obj, h->var, h->obj);
606
+ }
607
+ break;
608
+ case StructCode:
609
+ if (0 == h->var) {
610
+ set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
611
+ return;
612
+ }
613
+ rb_struct_aset(ph->obj, h->var, h->obj);
614
+ break;
615
+ case HashCode:
616
+ // put back h
617
+ helper_stack_push(&pi->helpers, h->var, h->obj, KeyCode);
618
+ break;
619
+ case RangeCode:
620
+ if (ox_beg_id == h->var) {
621
+ rb_ary_store(ph->obj, 0, h->obj);
622
+ } else if (ox_end_id == h->var) {
623
+ rb_ary_store(ph->obj, 1, h->obj);
624
+ } else if (ox_excl_id == h->var) {
625
+ rb_ary_store(ph->obj, 2, h->obj);
626
+ } else {
627
+ set_error(&pi->err, "Invalid range attribute", pi->str, pi->s);
628
+ return;
629
+ }
630
+ break;
631
+ case KeyCode: {
632
+ Helper gh;
633
+
634
+ helper_stack_pop(&pi->helpers);
635
+ if (NULL == (gh = helper_stack_peek(&pi->helpers)) || Qundef == ph->obj || Qundef == h->obj) {
636
+ set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s);
637
+ return;
638
+ }
639
+ rb_hash_aset(gh->obj, ph->obj, h->obj);
640
+ } break;
641
+ case ComplexCode:
642
+ if (Qundef == ph->obj) {
643
+ ph->obj = h->obj;
644
+ } else {
645
+ ph->obj = rb_complex_new(ph->obj, h->obj);
646
+ }
647
+ break;
648
+ case RationalCode: {
649
+ if (Qundef == h->obj || RUBY_T_FIXNUM != rb_type(h->obj)) {
650
+ set_error(&pi->err, "Invalid object format", pi->str, pi->s);
651
+ return;
652
+ }
653
+ if (Qundef == ph->obj) {
654
+ ph->obj = h->obj;
655
+ } else {
656
+ if (Qundef == ph->obj || RUBY_T_FIXNUM != rb_type(ph->obj)) {
657
+ set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s);
658
+ return;
659
+ }
721
660
  #ifdef RUBINIUS_RUBY
722
- ph->obj = rb_Rational(ph->obj, h->obj);
723
- #else
724
- ph->obj = rb_rational_new(ph->obj, h->obj);
725
- #endif
726
- }
661
+ ph->obj = rb_Rational(ph->obj, h->obj);
727
662
  #else
728
- set_error(&pi->err, "Rational Objects not implemented in Ruby 1.8.7", pi->str, pi->s);
729
- return;
663
+ ph->obj = rb_rational_new(ph->obj, h->obj);
730
664
  #endif
731
- break;
732
- }
733
- default:
734
- set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s);
735
- return;
736
- break;
737
- }
738
- }
665
+ }
666
+ break;
667
+ }
668
+ default:
669
+ set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s);
670
+ return;
671
+ break;
672
+ }
673
+ }
739
674
  }
740
675
  if (0 != pi->circ_array && helper_stack_empty(&pi->helpers)) {
741
- circ_array_free(pi->circ_array);
742
- pi->circ_array = 0;
676
+ circ_array_free(pi->circ_array);
677
+ pi->circ_array = 0;
743
678
  }
744
679
  if (DEBUG <= pi->options->trace) {
745
- debug_stack(pi, " ----------");
680
+ debug_stack(pi, " ----------");
746
681
  }
747
682
  }
748
683
 
749
- static VALUE
750
- parse_double_time(const char *text, VALUE clas) {
751
- long v = 0;
752
- long v2 = 0;
753
- const char *dot = 0;
754
- char c;
684
+ static VALUE parse_double_time(const char *text, VALUE clas) {
685
+ long v = 0;
686
+ long v2 = 0;
687
+ const char *dot = 0;
688
+ char c;
755
689
 
756
690
  for (; '.' != *text; text++) {
757
- c = *text;
758
- if (c < '0' || '9' < c) {
759
- return Qnil;
760
- }
761
- v = 10 * v + (long)(c - '0');
691
+ c = *text;
692
+ if (c < '0' || '9' < c) {
693
+ return Qnil;
694
+ }
695
+ v = 10 * v + (long)(c - '0');
762
696
  }
763
697
  dot = text++;
764
698
  for (; '\0' != *text && text - dot <= 6; text++) {
765
- c = *text;
766
- if (c < '0' || '9' < c) {
767
- return Qnil;
768
- }
769
- v2 = 10 * v2 + (long)(c - '0');
699
+ c = *text;
700
+ if (c < '0' || '9' < c) {
701
+ return Qnil;
702
+ }
703
+ v2 = 10 * v2 + (long)(c - '0');
770
704
  }
771
705
  for (; text - dot <= 9; text++) {
772
- v2 *= 10;
706
+ v2 *= 10;
773
707
  }
774
- #if HAVE_RB_TIME_NANO_NEW
775
708
  return rb_time_nano_new(v, v2);
776
- #else
777
- return rb_time_new(v, v2 / 1000);
778
- #endif
779
709
  }
780
710
 
781
711
  typedef struct _tp {
782
- int cnt;
783
- char end;
784
- char alt;
712
+ int cnt;
713
+ char end;
714
+ char alt;
785
715
  } *Tp;
786
716
 
787
- static VALUE
788
- parse_xsd_time(const char *text, VALUE clas) {
789
- long cargs[10];
790
- long *cp = cargs;
791
- long v;
792
- int i;
793
- char c;
794
- struct _tp tpa[10] = { { 4, '-', '-' },
795
- { 2, '-', '-' },
796
- { 2, 'T', 'T' },
797
- { 2, ':', ':' },
798
- { 2, ':', ':' },
799
- { 2, '.', '.' },
800
- { 9, '+', '-' },
801
- { 2, ':', ':' },
802
- { 2, '\0', '\0' },
803
- { 0, '\0', '\0' } };
804
- Tp tp = tpa;
805
- struct tm tm;
717
+ static VALUE parse_xsd_time(const char *text, VALUE clas) {
718
+ long cargs[10];
719
+ long *cp = cargs;
720
+ long v;
721
+ int i;
722
+ char c;
723
+ struct _tp tpa[10] = {{4, '-', '-'},
724
+ {2, '-', '-'},
725
+ {2, 'T', 'T'},
726
+ {2, ':', ':'},
727
+ {2, ':', ':'},
728
+ {2, '.', '.'},
729
+ {9, '+', '-'},
730
+ {2, ':', ':'},
731
+ {2, '\0', '\0'},
732
+ {0, '\0', '\0'}};
733
+ Tp tp = tpa;
734
+ struct tm tm;
806
735
 
807
736
  for (; 0 != tp->cnt; tp++) {
808
- for (i = tp->cnt, v = 0; 0 < i ; text++, i--) {
809
- c = *text;
810
- if (c < '0' || '9' < c) {
811
- if (tp->end == c || tp->alt == c) {
812
- break;
813
- }
814
- return Qnil;
815
- }
816
- v = 10 * v + (long)(c - '0');
817
- }
818
- c = *text++;
819
- if (tp->end != c && tp->alt != c) {
820
- return Qnil;
821
- }
822
- *cp++ = v;
737
+ for (i = tp->cnt, v = 0; 0 < i; text++, i--) {
738
+ c = *text;
739
+ if (c < '0' || '9' < c) {
740
+ if (tp->end == c || tp->alt == c) {
741
+ break;
742
+ }
743
+ return Qnil;
744
+ }
745
+ v = 10 * v + (long)(c - '0');
746
+ }
747
+ c = *text++;
748
+ if (tp->end != c && tp->alt != c) {
749
+ return Qnil;
750
+ }
751
+ *cp++ = v;
823
752
  }
824
753
  tm.tm_year = (int)cargs[0] - 1900;
825
- tm.tm_mon = (int)cargs[1] - 1;
754
+ tm.tm_mon = (int)cargs[1] - 1;
826
755
  tm.tm_mday = (int)cargs[2];
827
756
  tm.tm_hour = (int)cargs[3];
828
- tm.tm_min = (int)cargs[4];
829
- tm.tm_sec = (int)cargs[5];
830
- #if HAVE_RB_TIME_NANO_NEW
757
+ tm.tm_min = (int)cargs[4];
758
+ tm.tm_sec = (int)cargs[5];
831
759
  return rb_time_nano_new(mktime(&tm), cargs[6]);
832
- #else
833
- return rb_time_new(mktime(&tm), cargs[6] / 1000);
834
- #endif
835
760
  }
836
761
 
837
762
  // debug functions
838
- static void
839
- fill_indent(PInfo pi, char *buf, size_t size) {
840
- size_t cnt;
763
+ static void fill_indent(PInfo pi, char *buf, size_t size) {
764
+ size_t cnt;
841
765
 
842
766
  if (0 < (cnt = helper_stack_depth(&pi->helpers))) {
843
- cnt *= 2;
844
- if (size < cnt + 1) {
845
- cnt = size - 1;
846
- }
847
- memset(buf, ' ', cnt);
848
- buf += cnt;
767
+ cnt *= 2;
768
+ if (size < cnt + 1) {
769
+ cnt = size - 1;
770
+ }
771
+ memset(buf, ' ', cnt);
772
+ buf += cnt;
849
773
  }
850
774
  *buf = '\0';
851
775
  }
852
776
 
853
- static void
854
- debug_stack(PInfo pi, const char *comment) {
855
- char indent[128];
856
- Helper h;
777
+ static void debug_stack(PInfo pi, const char *comment) {
778
+ char indent[128];
779
+ Helper h;
857
780
 
858
781
  fill_indent(pi, indent, sizeof(indent));
859
782
  printf("%s%s\n", indent, comment);
860
783
  if (!helper_stack_empty(&pi->helpers)) {
861
- for (h = pi->helpers.head; h < pi->helpers.tail; h++) {
862
- const char *clas = "---";
863
- const char *key = "---";
864
-
865
- if (Qundef != h->obj) {
866
- VALUE c = rb_obj_class(h->obj);
867
-
868
- clas = rb_class2name(c);
869
- }
870
- if (0 != h->var) {
871
- if (HashCode == h->type) {
872
- VALUE v;
873
-
874
- v = rb_funcall2(h->var, rb_intern("to_s"), 0, 0);
875
- key = StringValuePtr(v);
876
- } else if (ObjectCode == (h - 1)->type || ExceptionCode == (h - 1)->type || RangeCode == (h - 1)->type || StructCode == (h - 1)->type) {
877
- key = rb_id2name(h->var);
878
- } else {
879
- printf("%s*** corrupt stack ***\n", indent);
880
- }
881
- }
882
- printf("%s [%c] %s : %s\n", indent, h->type, clas, key);
883
- }
784
+ for (h = pi->helpers.head; h < pi->helpers.tail; h++) {
785
+ const char *clas = "---";
786
+ const char *key = "---";
787
+
788
+ if (Qundef != h->obj) {
789
+ VALUE c = rb_obj_class(h->obj);
790
+
791
+ clas = rb_class2name(c);
792
+ }
793
+ if (0 != h->var) {
794
+ if (HashCode == h->type) {
795
+ VALUE v;
796
+
797
+ v = rb_String(h->var);
798
+ key = StringValuePtr(v);
799
+ } else if (ObjectCode == (h - 1)->type || ExceptionCode == (h - 1)->type ||
800
+ RangeCode == (h - 1)->type || StructCode == (h - 1)->type) {
801
+ key = rb_id2name(h->var);
802
+ } else {
803
+ printf("%s*** corrupt stack ***\n", indent);
804
+ }
805
+ }
806
+ printf("%s [%c] %s : %s\n", indent, h->type, clas, key);
807
+ }
884
808
  }
885
809
  }