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/builder.c CHANGED
@@ -4,41 +4,42 @@
4
4
  */
5
5
 
6
6
  #include <errno.h>
7
- #include <stdlib.h>
8
7
  #include <stdio.h>
8
+ #include <stdlib.h>
9
9
  #include <string.h>
10
10
 
11
+ #include "buf.h"
12
+ #include "err.h"
13
+ #include "ox.h"
11
14
  #include "ruby.h"
12
15
  #include "ruby/encoding.h"
13
16
  #include "ruby/version.h"
14
- #include "ox.h"
15
- #include "buf.h"
16
- #include "err.h"
17
17
 
18
- #define MAX_DEPTH 128
18
+ #define MAX_DEPTH 128
19
19
 
20
20
  typedef struct _element {
21
- char *name;
22
- char buf[64];
23
- long len;
24
- bool has_child;
25
- bool non_text_child;
21
+ char *name;
22
+ char buf[64];
23
+ long len;
24
+ bool has_child;
25
+ bool non_text_child;
26
26
  } *Element;
27
27
 
28
28
  typedef struct _builder {
29
- struct _buf buf;
30
- int indent;
31
- char encoding[64];
32
- int depth;
33
- FILE *file;
34
- struct _element stack[MAX_DEPTH];
35
- long line;
36
- long col;
37
- long pos;
29
+ struct _buf buf;
30
+ int indent;
31
+ char encoding[64];
32
+ int depth;
33
+ FILE *file;
34
+ struct _element stack[MAX_DEPTH];
35
+ long line;
36
+ long col;
37
+ long pos;
38
38
  } *Builder;
39
39
 
40
- static VALUE builder_class = Qundef;
41
- static const char indent_spaces[] = "\n "; // 128 spaces
40
+ static VALUE builder_class = Qundef;
41
+ static const char indent_spaces[] = "\n "
42
+ " "; // 128 spaces
42
43
 
43
44
  // The : character is equivalent to 10. Used for replacement characters up to
44
45
  // 10 characters long such as '&#x10FFFF;'. From
@@ -57,7 +58,7 @@ static const char xml_friendly_chars[257] = "\
57
58
 
58
59
  // From 2.3 of the XML 1.1 spec. All over 0x20 except <&", > also. Builder
59
60
  // uses double quotes for attributes.
60
- static const char xml_attr_chars[257] = "\
61
+ static const char xml_attr_chars[257] = "\
61
62
  :::::::::11::1::::::::::::::::::\
62
63
  11611151111111111111111111114141\
63
64
  11111111111111111111111111111111\
@@ -68,7 +69,7 @@ static const char xml_attr_chars[257] = "\
68
69
  11111111111111111111111111111111";
69
70
 
70
71
  // From 3.1 of the XML 1.1 spec. All over 0x20 except <&, > also.
71
- static const char xml_element_chars[257] = "\
72
+ static const char xml_element_chars[257] = "\
72
73
  :::::::::11::1::::::::::::::::::\
73
74
  11111151111111111111111111114141\
74
75
  11111111111111111111111111111111\
@@ -78,152 +79,134 @@ static const char xml_element_chars[257] = "\
78
79
  11111111111111111111111111111111\
79
80
  11111111111111111111111111111111";
80
81
 
81
- inline static size_t
82
- xml_str_len(const unsigned char *str, size_t len, const char *table) {
83
- size_t size = 0;
82
+ inline static size_t xml_str_len(const unsigned char *str, size_t len, const char *table) {
83
+ size_t size = 0;
84
84
 
85
85
  for (; 0 < len; str++, len--) {
86
- size += table[*str];
86
+ size += table[*str];
87
87
  }
88
88
  return size - len * (size_t)'0';
89
89
  }
90
90
 
91
- static void
92
- append_indent(Builder b) {
91
+ static void append_indent(Builder b) {
93
92
  if (0 >= b->indent) {
94
- return;
93
+ return;
95
94
  }
96
95
  if (b->buf.head < b->buf.tail) {
97
- int cnt = (b->indent * (b->depth + 1)) + 1;
96
+ int cnt = (b->indent * (b->depth + 1)) + 1;
98
97
 
99
- if (sizeof(indent_spaces) <= (size_t)cnt) {
100
- cnt = sizeof(indent_spaces) - 1;
101
- }
102
- buf_append_string(&b->buf, indent_spaces, cnt);
103
- b->line++;
104
- b->col = cnt - 1;
105
- b->pos += cnt;
98
+ if (sizeof(indent_spaces) <= (size_t)cnt) {
99
+ cnt = sizeof(indent_spaces) - 1;
100
+ }
101
+ buf_append_string(&b->buf, indent_spaces, cnt);
102
+ b->line++;
103
+ b->col = cnt - 1;
104
+ b->pos += cnt;
106
105
  }
107
106
  }
108
107
 
109
- static void
110
- append_string(Builder b, const char *str, size_t size, const char *table, bool strip_invalid_chars) {
111
- size_t xsize = xml_str_len((const unsigned char*)str, size, table);
108
+ static void append_string(Builder b, const char *str, size_t size, const char *table, bool strip_invalid_chars) {
109
+ size_t xsize = xml_str_len((const unsigned char *)str, size, table);
112
110
 
113
111
  if (size == xsize) {
114
- const char *s = str;
115
- const char *end = str + size;
112
+ const char *s = str;
113
+ const char *end = str + size;
116
114
 
117
- buf_append_string(&b->buf, str, size);
118
- b->col += size;
115
+ buf_append_string(&b->buf, str, size);
116
+ b->col += size;
119
117
  s = strchr(s, '\n');
120
118
  while (NULL != s) {
121
119
  b->line++;
122
120
  b->col = end - s;
123
- s = strchr(s + 1, '\n');
121
+ s = strchr(s + 1, '\n');
124
122
  }
125
- b->pos += size;
123
+ b->pos += size;
126
124
  } else {
127
- char buf[256];
128
- char *end = buf + sizeof(buf) - 1;
129
- char *bp = buf;
130
- size_t i = size;
131
- int fcnt;
132
-
133
- for (; '\0' != *str && 0 < i; i--, str++) {
134
- if ('1' == (fcnt = table[(unsigned char)*str])) {
135
- if (end <= bp) {
136
- buf_append_string(&b->buf, buf, bp - buf);
137
- bp = buf;
138
- }
139
- if ('\n' == *str) {
140
- b->line++;
141
- b->col = 1;
142
- } else {
143
- b->col++;
144
- }
145
- b->pos++;
146
- *bp++ = *str;
147
- } else {
148
- b->pos += fcnt - '0';
149
- b->col += fcnt - '0';
150
- if (buf < bp) {
151
- buf_append_string(&b->buf, buf, bp - buf);
152
- bp = buf;
153
- }
154
- switch (*str) {
155
- case '"':
156
- buf_append_string(&b->buf, "&quot;", 6);
157
- break;
158
- case '&':
159
- buf_append_string(&b->buf, "&amp;", 5);
160
- break;
161
- case '\'':
162
- buf_append_string(&b->buf, "&apos;", 6);
163
- break;
164
- case '<':
165
- buf_append_string(&b->buf, "&lt;", 4);
166
- break;
167
- case '>':
168
- buf_append_string(&b->buf, "&gt;", 4);
169
- break;
170
- default:
171
- // Must be one of the invalid characters.
172
- if (!strip_invalid_chars) {
173
- rb_raise(ox_syntax_error_class, "'\\#x%02x' is not a valid XML character.", *str);
174
- }
175
- break;
176
- }
177
- }
178
- }
179
- if (buf < bp) {
180
- buf_append_string(&b->buf, buf, bp - buf);
181
- bp = buf;
182
- }
125
+ char buf[256];
126
+ char *end = buf + sizeof(buf) - 1;
127
+ char *bp = buf;
128
+ size_t i = size;
129
+ int fcnt;
130
+
131
+ for (; '\0' != *str && 0 < i; i--, str++) {
132
+ if ('1' == (fcnt = table[(unsigned char)*str])) {
133
+ if (end <= bp) {
134
+ buf_append_string(&b->buf, buf, bp - buf);
135
+ bp = buf;
136
+ }
137
+ if ('\n' == *str) {
138
+ b->line++;
139
+ b->col = 1;
140
+ } else {
141
+ b->col++;
142
+ }
143
+ b->pos++;
144
+ *bp++ = *str;
145
+ } else {
146
+ b->pos += fcnt - '0';
147
+ b->col += fcnt - '0';
148
+ if (buf < bp) {
149
+ buf_append_string(&b->buf, buf, bp - buf);
150
+ bp = buf;
151
+ }
152
+ switch (*str) {
153
+ case '"': buf_append_string(&b->buf, "&quot;", 6); break;
154
+ case '&': buf_append_string(&b->buf, "&amp;", 5); break;
155
+ case '\'': buf_append_string(&b->buf, "&apos;", 6); break;
156
+ case '<': buf_append_string(&b->buf, "&lt;", 4); break;
157
+ case '>': buf_append_string(&b->buf, "&gt;", 4); break;
158
+ default:
159
+ // Must be one of the invalid characters.
160
+ if (!strip_invalid_chars) {
161
+ rb_raise(ox_syntax_error_class, "'\\#x%02x' is not a valid XML character.", *str);
162
+ }
163
+ break;
164
+ }
165
+ }
166
+ }
167
+ if (buf < bp) {
168
+ buf_append_string(&b->buf, buf, bp - buf);
169
+ bp = buf;
170
+ }
183
171
  }
184
172
  }
185
173
 
186
- static void
187
- append_sym_str(Builder b, VALUE v) {
188
- const char *s;
189
- long len;
174
+ static void append_sym_str(Builder b, VALUE v) {
175
+ const char *s;
176
+ long len;
190
177
 
191
178
  switch (rb_type(v)) {
192
179
  case T_STRING:
193
- s = StringValuePtr(v);
194
- len = RSTRING_LEN(v);
195
- break;
180
+ s = StringValuePtr(v);
181
+ len = RSTRING_LEN(v);
182
+ break;
196
183
  case T_SYMBOL:
197
- s = rb_id2name(SYM2ID(v));
198
- len = strlen(s);
199
- break;
200
- default:
201
- rb_raise(ox_arg_error_class, "expected a Symbol or String");
202
- break;
184
+ s = rb_id2name(SYM2ID(v));
185
+ len = strlen(s);
186
+ break;
187
+ default: rb_raise(ox_arg_error_class, "expected a Symbol or String"); break;
203
188
  }
204
189
  append_string(b, s, len, xml_element_chars, false);
205
190
  }
206
191
 
207
- static void
208
- i_am_a_child(Builder b, bool is_text) {
192
+ static void i_am_a_child(Builder b, bool is_text) {
209
193
  if (0 <= b->depth) {
210
- Element e = &b->stack[b->depth];
211
-
212
- if (!e->has_child) {
213
- e->has_child = true;
214
- buf_append(&b->buf, '>');
215
- b->col++;
216
- b->pos++;
217
- }
218
- if (!is_text) {
219
- e->non_text_child = true;
220
- }
194
+ Element e = &b->stack[b->depth];
195
+
196
+ if (!e->has_child) {
197
+ e->has_child = true;
198
+ buf_append(&b->buf, '>');
199
+ b->col++;
200
+ b->pos++;
201
+ }
202
+ if (!is_text) {
203
+ e->non_text_child = true;
204
+ }
221
205
  }
222
206
  }
223
207
 
224
- static int
225
- append_attr(VALUE key, VALUE value, VALUE bv) {
226
- Builder b = (Builder)bv;
208
+ static int append_attr(VALUE key, VALUE value, VALUE bv) {
209
+ Builder b = (Builder)bv;
227
210
 
228
211
  buf_append(&b->buf, ' ');
229
212
  b->col++;
@@ -241,100 +224,95 @@ append_attr(VALUE key, VALUE value, VALUE bv) {
241
224
  return ST_CONTINUE;
242
225
  }
243
226
 
244
- static void
245
- init(Builder b, int fd, int indent, long initial_size) {
227
+ static void init(Builder b, int fd, int indent, long initial_size) {
246
228
  buf_init(&b->buf, fd, initial_size);
247
- b->indent = indent;
229
+ b->indent = indent;
248
230
  *b->encoding = '\0';
249
- b->depth = -1;
250
- b->line = 1;
251
- b->col = 1;
252
- b->pos = 0;
231
+ b->depth = -1;
232
+ b->line = 1;
233
+ b->col = 1;
234
+ b->pos = 0;
253
235
  }
254
236
 
255
- static void
256
- builder_free(void *ptr) {
257
- Builder b;
258
- Element e;
259
- int d;
237
+ static void builder_free(void *ptr) {
238
+ Builder b;
239
+ Element e;
240
+ int d;
260
241
 
261
242
  if (0 == ptr) {
262
- return;
243
+ return;
263
244
  }
264
245
  b = (Builder)ptr;
265
246
  buf_cleanup(&b->buf);
266
247
  for (e = b->stack, d = b->depth; 0 < d; d--, e++) {
267
- if (e->name != e->buf) {
268
- free(e->name);
269
- }
248
+ if (e->name != e->buf) {
249
+ free(e->name);
250
+ }
270
251
  }
271
252
  xfree(ptr);
272
253
  }
273
254
 
274
- static void
275
- pop(Builder b) {
276
- Element e;
255
+ static void pop(Builder b) {
256
+ Element e;
277
257
 
278
258
  if (0 > b->depth) {
279
- rb_raise(ox_arg_error_class, "closed too many elements");
259
+ rb_raise(ox_arg_error_class, "closed too many elements");
280
260
  }
281
261
  e = &b->stack[b->depth];
282
262
  b->depth--;
283
263
  if (e->has_child) {
284
- if (e->non_text_child) {
285
- append_indent(b);
286
- }
287
- buf_append_string(&b->buf, "</", 2);
288
- append_string(b, e->name, e->len, xml_element_chars, false);
289
- buf_append(&b->buf, '>');
290
- b->col += e->len + 3;
291
- b->pos += e->len + 3;
292
- if (e->buf != e->name) {
293
- free(e->name);
294
- e->name = 0;
295
- }
264
+ if (e->non_text_child) {
265
+ append_indent(b);
266
+ }
267
+ buf_append_string(&b->buf, "</", 2);
268
+ append_string(b, e->name, e->len, xml_element_chars, false);
269
+ buf_append(&b->buf, '>');
270
+ b->col += e->len + 3;
271
+ b->pos += e->len + 3;
272
+ if (e->buf != e->name) {
273
+ free(e->name);
274
+ e->name = 0;
275
+ }
296
276
  } else {
297
- buf_append_string(&b->buf, "/>", 2);
298
- b->col += 2;
299
- b->pos += 2;
277
+ buf_append_string(&b->buf, "/>", 2);
278
+ b->col += 2;
279
+ b->pos += 2;
300
280
  }
301
281
  }
302
282
 
303
- static void
304
- bclose(Builder b) {
283
+ static void bclose(Builder b) {
305
284
  while (0 <= b->depth) {
306
- pop(b);
285
+ pop(b);
307
286
  }
308
287
  if (0 <= b->indent) {
309
- buf_append(&b->buf, '\n');
288
+ buf_append(&b->buf, '\n');
310
289
  }
311
290
  b->line++;
312
291
  b->col = 1;
313
292
  b->pos++;
314
293
  buf_finish(&b->buf);
315
294
  if (NULL != b->file) {
316
- fclose(b->file);
295
+ fclose(b->file);
317
296
  }
318
297
  }
319
298
 
320
- static VALUE
321
- to_s(Builder b) {
322
- volatile VALUE rstr;
299
+ static VALUE to_s(Builder b) {
300
+ volatile VALUE rstr;
323
301
 
324
302
  if (0 != b->buf.fd) {
325
- rb_raise(ox_arg_error_class, "can not create a String with a stream or file builder.");
303
+ rb_raise(ox_arg_error_class, "can not create a String with a stream or file builder.");
326
304
  }
327
305
  if (0 <= b->indent && '\n' != *(b->buf.tail - 1)) {
328
- buf_append(&b->buf, '\n');
329
- b->line++;
330
- b->col = 1;
331
- b->pos++;
306
+ buf_append(&b->buf, '\n');
307
+ b->line++;
308
+ b->col = 1;
309
+ b->pos++;
332
310
  }
333
- *b->buf.tail = '\0'; // for debugging
334
- rstr = rb_str_new(b->buf.head, buf_len(&b->buf));
311
+ *b->buf.tail = '\0'; // for debugging
312
+ rstr = rb_str_new(b->buf.head, buf_len(&b->buf));
335
313
 
336
314
  if ('\0' != *b->encoding) {
337
- rb_enc_associate(rstr, rb_enc_find(b->encoding));
315
+ rb_enc_associate(rstr, rb_enc_find(b->encoding));
338
316
  }
339
317
  return rstr;
340
318
  }
@@ -349,49 +327,40 @@ to_s(Builder b) {
349
327
  * - +:indent+ (Fixnum) indentaion level, negative values excludes terminating newline
350
328
  * - +:size+ (Fixnum) the initial size of the string buffer
351
329
  */
352
- static VALUE
353
- builder_new(int argc, VALUE *argv, VALUE self) {
354
- Builder b = ALLOC(struct _builder);
355
- int indent = ox_default_options.indent;
356
- long buf_size = 0;
330
+ static VALUE builder_new(int argc, VALUE *argv, VALUE self) {
331
+ Builder b = ALLOC(struct _builder);
332
+ int indent = ox_default_options.indent;
333
+ long buf_size = 0;
357
334
 
358
335
  if (1 == argc) {
359
- volatile VALUE v;
360
-
361
- rb_check_type(*argv, T_HASH);
362
- if (Qnil != (v = rb_hash_lookup(*argv, ox_indent_sym))) {
363
- #ifdef RUBY_INTEGER_UNIFICATION
364
- if (rb_cInteger != rb_obj_class(v)) {
365
- #else
366
- if (rb_cFixnum != rb_obj_class(v)) {
367
- #endif
368
- rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
369
- }
370
- indent = NUM2INT(v);
371
- }
372
- if (Qnil != (v = rb_hash_lookup(*argv, ox_size_sym))) {
373
- #ifdef RUBY_INTEGER_UNIFICATION
374
- if (rb_cInteger != rb_obj_class(v)) {
375
- #else
376
- if (rb_cFixnum != rb_obj_class(v)) {
377
- #endif
378
- rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
379
- }
380
- buf_size = NUM2LONG(v);
381
- }
336
+ volatile VALUE v;
337
+
338
+ rb_check_type(*argv, T_HASH);
339
+ if (Qnil != (v = rb_hash_lookup(*argv, ox_indent_sym))) {
340
+ if (rb_cInteger != rb_obj_class(v)) {
341
+ rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
342
+ }
343
+ indent = NUM2INT(v);
344
+ }
345
+ if (Qnil != (v = rb_hash_lookup(*argv, ox_size_sym))) {
346
+ if (rb_cInteger != rb_obj_class(v)) {
347
+ rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
348
+ }
349
+ buf_size = NUM2LONG(v);
350
+ }
382
351
  }
383
352
  b->file = NULL;
384
353
  init(b, 0, indent, buf_size);
385
354
 
386
355
  if (rb_block_given_p()) {
387
- volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b);
356
+ volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b);
388
357
 
389
- rb_yield(rb);
390
- bclose(b);
358
+ rb_yield(rb);
359
+ bclose(b);
391
360
 
392
- return to_s(b);
361
+ return to_s(b);
393
362
  } else {
394
- return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
363
+ return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
395
364
  }
396
365
  }
397
366
 
@@ -404,56 +373,47 @@ builder_new(int argc, VALUE *argv, VALUE self) {
404
373
  * - +:indent+ (Fixnum) indentaion level, negative values excludes terminating newline
405
374
  * - +:size+ (Fixnum) the initial size of the string buffer
406
375
  */
407
- static VALUE
408
- builder_file(int argc, VALUE *argv, VALUE self) {
409
- Builder b = ALLOC(struct _builder);
410
- int indent = ox_default_options.indent;
411
- long buf_size = 0;
412
- FILE *f;
376
+ static VALUE builder_file(int argc, VALUE *argv, VALUE self) {
377
+ Builder b = ALLOC(struct _builder);
378
+ int indent = ox_default_options.indent;
379
+ long buf_size = 0;
380
+ FILE *f;
413
381
 
414
382
  if (1 > argc) {
415
- rb_raise(ox_arg_error_class, "missing filename");
383
+ rb_raise(ox_arg_error_class, "missing filename");
416
384
  }
417
385
  Check_Type(*argv, T_STRING);
418
386
  if (NULL == (f = fopen(StringValuePtr(*argv), "w"))) {
419
- xfree(b);
420
- rb_raise(rb_eIOError, "%s\n", strerror(errno));
387
+ xfree(b);
388
+ rb_raise(rb_eIOError, "%s\n", strerror(errno));
421
389
  }
422
390
  if (2 == argc) {
423
- volatile VALUE v;
424
-
425
- rb_check_type(argv[1], T_HASH);
426
- if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) {
427
- #ifdef RUBY_INTEGER_UNIFICATION
428
- if (rb_cInteger != rb_obj_class(v)) {
429
- #else
430
- if (rb_cFixnum != rb_obj_class(v)) {
431
- #endif
432
- rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
433
- }
434
- indent = NUM2INT(v);
435
- }
436
- if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) {
437
- #ifdef RUBY_INTEGER_UNIFICATION
438
- if (rb_cInteger != rb_obj_class(v)) {
439
- #else
440
- if (rb_cFixnum != rb_obj_class(v)) {
441
- #endif
442
- rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
443
- }
444
- buf_size = NUM2LONG(v);
445
- }
391
+ volatile VALUE v;
392
+
393
+ rb_check_type(argv[1], T_HASH);
394
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) {
395
+ if (rb_cInteger != rb_obj_class(v)) {
396
+ rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
397
+ }
398
+ indent = NUM2INT(v);
399
+ }
400
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) {
401
+ if (rb_cInteger != rb_obj_class(v)) {
402
+ rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
403
+ }
404
+ buf_size = NUM2LONG(v);
405
+ }
446
406
  }
447
407
  b->file = f;
448
408
  init(b, fileno(f), indent, buf_size);
449
409
 
450
410
  if (rb_block_given_p()) {
451
- volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b);
452
- rb_yield(rb);
453
- bclose(b);
454
- return Qnil;
411
+ volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b);
412
+ rb_yield(rb);
413
+ bclose(b);
414
+ return Qnil;
455
415
  } else {
456
- return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
416
+ return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
457
417
  }
458
418
  }
459
419
 
@@ -466,57 +426,47 @@ builder_file(int argc, VALUE *argv, VALUE self) {
466
426
  * - +:indent+ (Fixnum) indentaion level, negative values excludes terminating newline
467
427
  * - +:size+ (Fixnum) the initial size of the string buffer
468
428
  */
469
- static VALUE
470
- builder_io(int argc, VALUE *argv, VALUE self) {
471
- Builder b = ALLOC(struct _builder);
472
- int indent = ox_default_options.indent;
473
- long buf_size = 0;
474
- int fd;
475
- volatile VALUE v;
429
+ static VALUE builder_io(int argc, VALUE *argv, VALUE self) {
430
+ Builder b = ALLOC(struct _builder);
431
+ int indent = ox_default_options.indent;
432
+ long buf_size = 0;
433
+ int fd;
434
+ volatile VALUE v;
476
435
 
477
436
  if (1 > argc) {
478
- rb_raise(ox_arg_error_class, "missing IO object");
437
+ rb_raise(ox_arg_error_class, "missing IO object");
479
438
  }
480
- if (!rb_respond_to(*argv, ox_fileno_id) ||
481
- Qnil == (v = rb_funcall(*argv, ox_fileno_id, 0)) ||
482
- 0 == (fd = FIX2INT(v))) {
483
- rb_raise(rb_eIOError, "expected an IO that has a fileno.");
439
+ if (!rb_respond_to(*argv, ox_fileno_id) || Qnil == (v = rb_funcall(*argv, ox_fileno_id, 0)) ||
440
+ 0 == (fd = FIX2INT(v))) {
441
+ rb_raise(rb_eIOError, "expected an IO that has a fileno.");
484
442
  }
485
443
  if (2 == argc) {
486
- volatile VALUE v;
487
-
488
- rb_check_type(argv[1], T_HASH);
489
- if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) {
490
- #ifdef RUBY_INTEGER_UNIFICATION
491
- if (rb_cInteger != rb_obj_class(v)) {
492
- #else
493
- if (rb_cFixnum != rb_obj_class(v)) {
494
- #endif
495
- rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
496
- }
497
- indent = NUM2INT(v);
498
- }
499
- if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) {
500
- #ifdef RUBY_INTEGER_UNIFICATION
501
- if (rb_cInteger != rb_obj_class(v)) {
502
- #else
503
- if (rb_cFixnum != rb_obj_class(v)) {
504
- #endif
505
- rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
506
- }
507
- buf_size = NUM2LONG(v);
508
- }
444
+ volatile VALUE v;
445
+
446
+ rb_check_type(argv[1], T_HASH);
447
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) {
448
+ if (rb_cInteger != rb_obj_class(v)) {
449
+ rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
450
+ }
451
+ indent = NUM2INT(v);
452
+ }
453
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) {
454
+ if (rb_cInteger != rb_obj_class(v)) {
455
+ rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
456
+ }
457
+ buf_size = NUM2LONG(v);
458
+ }
509
459
  }
510
460
  b->file = NULL;
511
461
  init(b, fd, indent, buf_size);
512
462
 
513
463
  if (rb_block_given_p()) {
514
- volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b);
515
- rb_yield(rb);
516
- bclose(b);
517
- return Qnil;
464
+ volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b);
465
+ rb_yield(rb);
466
+ bclose(b);
467
+ return Qnil;
518
468
  } else {
519
- return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
469
+ return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
520
470
  }
521
471
  }
522
472
 
@@ -527,65 +477,64 @@ builder_io(int argc, VALUE *argv, VALUE self) {
527
477
  * - +decl+ - (String) 'xml' expected
528
478
  * - +options+ - (Hash) version or encoding
529
479
  */
530
- static VALUE
531
- builder_instruct(int argc, VALUE *argv, VALUE self) {
532
- Builder b = (Builder)DATA_PTR(self);
480
+ static VALUE builder_instruct(int argc, VALUE *argv, VALUE self) {
481
+ Builder b = (Builder)DATA_PTR(self);
533
482
 
534
483
  i_am_a_child(b, false);
535
484
  append_indent(b);
536
485
  if (0 == argc) {
537
- buf_append_string(&b->buf, "<?xml?>", 7);
538
- b->col += 7;
539
- b->pos += 7;
486
+ buf_append_string(&b->buf, "<?xml?>", 7);
487
+ b->col += 7;
488
+ b->pos += 7;
540
489
  } else {
541
- volatile VALUE v;
542
-
543
- buf_append_string(&b->buf, "<?", 2);
544
- b->col += 2;
545
- b->pos += 2;
546
- append_sym_str(b, *argv);
547
- if (1 < argc && rb_cHash == rb_obj_class(argv[1])) {
548
- int len;
549
-
550
- if (Qnil != (v = rb_hash_lookup(argv[1], ox_version_sym))) {
551
- if (rb_cString != rb_obj_class(v)) {
552
- rb_raise(ox_parse_error_class, ":version must be a Symbol.\n");
553
- }
554
- len = (int)RSTRING_LEN(v);
555
- buf_append_string(&b->buf, " version=\"", 10);
556
- buf_append_string(&b->buf, StringValuePtr(v), len);
557
- buf_append(&b->buf, '"');
558
- b->col += len + 11;
559
- b->pos += len + 11;
560
- }
561
- if (Qnil != (v = rb_hash_lookup(argv[1], ox_encoding_sym))) {
562
- if (rb_cString != rb_obj_class(v)) {
563
- rb_raise(ox_parse_error_class, ":encoding must be a Symbol.\n");
564
- }
565
- len = (int)RSTRING_LEN(v);
566
- buf_append_string(&b->buf, " encoding=\"", 11);
567
- buf_append_string(&b->buf, StringValuePtr(v), len);
568
- buf_append(&b->buf, '"');
569
- b->col += len + 12;
570
- b->pos += len + 12;
571
- strncpy(b->encoding, StringValuePtr(v), sizeof(b->encoding));
572
- b->encoding[sizeof(b->encoding) - 1] = '\0';
573
- }
574
- if (Qnil != (v = rb_hash_lookup(argv[1], ox_standalone_sym))) {
575
- if (rb_cString != rb_obj_class(v)) {
576
- rb_raise(ox_parse_error_class, ":standalone must be a Symbol.\n");
577
- }
578
- len = (int)RSTRING_LEN(v);
579
- buf_append_string(&b->buf, " standalone=\"", 13);
580
- buf_append_string(&b->buf, StringValuePtr(v), len);
581
- buf_append(&b->buf, '"');
582
- b->col += len + 14;
583
- b->pos += len + 14;
584
- }
585
- }
586
- buf_append_string(&b->buf, "?>", 2);
587
- b->col += 2;
588
- b->pos += 2;
490
+ volatile VALUE v;
491
+
492
+ buf_append_string(&b->buf, "<?", 2);
493
+ b->col += 2;
494
+ b->pos += 2;
495
+ append_sym_str(b, *argv);
496
+ if (1 < argc && rb_cHash == rb_obj_class(argv[1])) {
497
+ int len;
498
+
499
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_version_sym))) {
500
+ if (rb_cString != rb_obj_class(v)) {
501
+ rb_raise(ox_parse_error_class, ":version must be a Symbol.\n");
502
+ }
503
+ len = (int)RSTRING_LEN(v);
504
+ buf_append_string(&b->buf, " version=\"", 10);
505
+ buf_append_string(&b->buf, StringValuePtr(v), len);
506
+ buf_append(&b->buf, '"');
507
+ b->col += len + 11;
508
+ b->pos += len + 11;
509
+ }
510
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_encoding_sym))) {
511
+ if (rb_cString != rb_obj_class(v)) {
512
+ rb_raise(ox_parse_error_class, ":encoding must be a Symbol.\n");
513
+ }
514
+ len = (int)RSTRING_LEN(v);
515
+ buf_append_string(&b->buf, " encoding=\"", 11);
516
+ buf_append_string(&b->buf, StringValuePtr(v), len);
517
+ buf_append(&b->buf, '"');
518
+ b->col += len + 12;
519
+ b->pos += len + 12;
520
+ strncpy(b->encoding, StringValuePtr(v), sizeof(b->encoding));
521
+ b->encoding[sizeof(b->encoding) - 1] = '\0';
522
+ }
523
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_standalone_sym))) {
524
+ if (rb_cString != rb_obj_class(v)) {
525
+ rb_raise(ox_parse_error_class, ":standalone must be a Symbol.\n");
526
+ }
527
+ len = (int)RSTRING_LEN(v);
528
+ buf_append_string(&b->buf, " standalone=\"", 13);
529
+ buf_append_string(&b->buf, StringValuePtr(v), len);
530
+ buf_append(&b->buf, '"');
531
+ b->col += len + 14;
532
+ b->pos += len + 14;
533
+ }
534
+ }
535
+ buf_append_string(&b->buf, "?>", 2);
536
+ b->col += 2;
537
+ b->pos += 2;
589
538
  }
590
539
  return Qnil;
591
540
  }
@@ -598,45 +547,42 @@ builder_instruct(int argc, VALUE *argv, VALUE self) {
598
547
  * - +name+ - (String) name of the element
599
548
  * - +attributes+ - (Hash) of the element
600
549
  */
601
- static VALUE
602
- builder_element(int argc, VALUE *argv, VALUE self) {
603
- Builder b = (Builder)DATA_PTR(self);
604
- Element e;
605
- const char *name;
606
- long len;
550
+ static VALUE builder_element(int argc, VALUE *argv, VALUE self) {
551
+ Builder b = (Builder)DATA_PTR(self);
552
+ Element e;
553
+ const char *name;
554
+ long len;
607
555
 
608
556
  if (1 > argc) {
609
- rb_raise(ox_arg_error_class, "missing element name");
557
+ rb_raise(ox_arg_error_class, "missing element name");
610
558
  }
611
559
  i_am_a_child(b, false);
612
560
  append_indent(b);
613
561
  b->depth++;
614
562
  if (MAX_DEPTH <= b->depth) {
615
- rb_raise(ox_arg_error_class, "XML too deeply nested");
563
+ rb_raise(ox_arg_error_class, "XML too deeply nested");
616
564
  }
617
565
  switch (rb_type(*argv)) {
618
566
  case T_STRING:
619
- name = StringValuePtr(*argv);
620
- len = RSTRING_LEN(*argv);
621
- break;
567
+ name = StringValuePtr(*argv);
568
+ len = RSTRING_LEN(*argv);
569
+ break;
622
570
  case T_SYMBOL:
623
- name = rb_id2name(SYM2ID(*argv));
624
- len = strlen(name);
625
- break;
626
- default:
627
- rb_raise(ox_arg_error_class, "expected a Symbol or String for an element name");
628
- break;
571
+ name = rb_id2name(SYM2ID(*argv));
572
+ len = strlen(name);
573
+ break;
574
+ default: rb_raise(ox_arg_error_class, "expected a Symbol or String for an element name"); break;
629
575
  }
630
576
  e = &b->stack[b->depth];
631
577
  if (sizeof(e->buf) <= (size_t)len) {
632
- e->name = strdup(name);
633
- *e->buf = '\0';
578
+ e->name = strdup(name);
579
+ *e->buf = '\0';
634
580
  } else {
635
- strcpy(e->buf, name);
636
- e->name = e->buf;
581
+ strcpy(e->buf, name);
582
+ e->name = e->buf;
637
583
  }
638
- e->len = len;
639
- e->has_child = false;
584
+ e->len = len;
585
+ e->has_child = false;
640
586
  e->non_text_child = false;
641
587
 
642
588
  buf_append(&b->buf, '<');
@@ -644,12 +590,12 @@ builder_element(int argc, VALUE *argv, VALUE self) {
644
590
  b->pos++;
645
591
  append_string(b, e->name, len, xml_element_chars, false);
646
592
  if (1 < argc && T_HASH == rb_type(argv[1])) {
647
- rb_hash_foreach(argv[1], append_attr, (VALUE)b);
593
+ rb_hash_foreach(argv[1], append_attr, (VALUE)b);
648
594
  }
649
595
  // Do not close with > or /> yet. That is done with i_am_a_child() or pop().
650
596
  if (rb_block_given_p()) {
651
- rb_yield(self);
652
- pop(b);
597
+ rb_yield(self);
598
+ pop(b);
653
599
  }
654
600
  return Qnil;
655
601
  }
@@ -661,39 +607,37 @@ builder_element(int argc, VALUE *argv, VALUE self) {
661
607
  * - +name+ - (String) name of the element
662
608
  * - +attributes+ - (Hash) of the element
663
609
  */
664
- static VALUE
665
- builder_void_element(int argc, VALUE *argv, VALUE self) {
666
- Builder b = (Builder)DATA_PTR(self);
667
- const char *name;
668
- long len;
610
+ static VALUE builder_void_element(int argc, VALUE *argv, VALUE self) {
611
+ Builder b = (Builder)DATA_PTR(self);
612
+ const char *name;
613
+ long len;
669
614
 
670
615
  if (1 > argc) {
671
- rb_raise(ox_arg_error_class, "missing element name");
616
+ rb_raise(ox_arg_error_class, "missing element name");
672
617
  }
673
618
  i_am_a_child(b, false);
674
619
  append_indent(b);
675
620
  switch (rb_type(*argv)) {
676
621
  case T_STRING:
677
- name = StringValuePtr(*argv);
678
- len = RSTRING_LEN(*argv);
679
- break;
622
+ name = StringValuePtr(*argv);
623
+ len = RSTRING_LEN(*argv);
624
+ break;
680
625
  case T_SYMBOL:
681
- name = rb_id2name(SYM2ID(*argv));
682
- len = strlen(name);
683
- break;
684
- default:
685
- rb_raise(ox_arg_error_class, "expected a Symbol or String for an element name");
686
- break;
626
+ name = rb_id2name(SYM2ID(*argv));
627
+ len = strlen(name);
628
+ break;
629
+ default: rb_raise(ox_arg_error_class, "expected a Symbol or String for an element name"); break;
687
630
  }
688
631
  buf_append(&b->buf, '<');
689
632
  b->col++;
690
633
  b->pos++;
691
634
  append_string(b, name, len, xml_element_chars, false);
692
635
  if (1 < argc && T_HASH == rb_type(argv[1])) {
693
- rb_hash_foreach(argv[1], append_attr, (VALUE)b);
636
+ rb_hash_foreach(argv[1], append_attr, (VALUE)b);
694
637
  }
695
638
  buf_append_string(&b->buf, ">", 1);
696
- b->col++;;
639
+ b->col++;
640
+ ;
697
641
  b->pos++;
698
642
 
699
643
  return Qnil;
@@ -704,9 +648,8 @@ builder_void_element(int argc, VALUE *argv, VALUE self) {
704
648
  * Adds a comment element to the XML string being formed.
705
649
  * - +text+ - (String) contents of the comment
706
650
  */
707
- static VALUE
708
- builder_comment(VALUE self, VALUE text) {
709
- Builder b = (Builder)DATA_PTR(self);
651
+ static VALUE builder_comment(VALUE self, VALUE text) {
652
+ Builder b = (Builder)DATA_PTR(self);
710
653
 
711
654
  rb_check_type(text, T_STRING);
712
655
  i_am_a_child(b, false);
@@ -727,9 +670,8 @@ builder_comment(VALUE self, VALUE text) {
727
670
  * Adds a DOCTYPE element to the XML string being formed.
728
671
  * - +text+ - (String) contents of the doctype
729
672
  */
730
- static VALUE
731
- builder_doctype(VALUE self, VALUE text) {
732
- Builder b = (Builder)DATA_PTR(self);
673
+ static VALUE builder_doctype(VALUE self, VALUE text) {
674
+ Builder b = (Builder)DATA_PTR(self);
733
675
 
734
676
  rb_check_type(text, T_STRING);
735
677
  i_am_a_child(b, false);
@@ -751,25 +693,22 @@ builder_doctype(VALUE self, VALUE text) {
751
693
  * - +text+ - (String) contents of the text field
752
694
  * - +strip_invalid_chars+ - [true|false] strips any characters invalid for XML, defaults to false
753
695
  */
754
- static VALUE
755
- builder_text(int argc, VALUE *argv, VALUE self) {
756
- Builder b = (Builder)DATA_PTR(self);
757
- volatile VALUE v;
758
- volatile VALUE strip_invalid_chars;
696
+ static VALUE builder_text(int argc, VALUE *argv, VALUE self) {
697
+ Builder b = (Builder)DATA_PTR(self);
698
+ volatile VALUE v;
699
+ volatile VALUE strip_invalid_chars;
759
700
 
760
701
  if ((0 == argc) || (argc > 2)) {
761
- rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1..2)", argc);
702
+ rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1..2)", argc);
762
703
  }
763
704
  v = argv[0];
764
705
  if (2 == argc) {
765
- strip_invalid_chars = argv[1];
706
+ strip_invalid_chars = argv[1];
766
707
  } else {
767
- strip_invalid_chars = Qfalse;
708
+ strip_invalid_chars = Qfalse;
768
709
  }
769
710
 
770
- if (T_STRING != rb_type(v)) {
771
- v = rb_funcall(v, ox_to_s_id, 0);
772
- }
711
+ v = rb_String(v);
773
712
  i_am_a_child(b, true);
774
713
  append_string(b, StringValuePtr(v), RSTRING_LEN(v), xml_element_chars, RTEST(strip_invalid_chars));
775
714
 
@@ -781,21 +720,18 @@ builder_text(int argc, VALUE *argv, VALUE self) {
781
720
  * Adds a CDATA element to the XML string being formed.
782
721
  * - +data+ - (String) contents of the CDATA element
783
722
  */
784
- static VALUE
785
- builder_cdata(VALUE self, VALUE data) {
786
- Builder b = (Builder)DATA_PTR(self);
787
- volatile VALUE v = data;
788
- const char *str;
789
- const char *s;
790
- const char *end;
791
- int len;
792
-
793
- if (T_STRING != rb_type(v)) {
794
- v = rb_funcall(v, ox_to_s_id, 0);
795
- }
723
+ static VALUE builder_cdata(VALUE self, VALUE data) {
724
+ Builder b = (Builder)DATA_PTR(self);
725
+ volatile VALUE v = data;
726
+ const char *str;
727
+ const char *s;
728
+ const char *end;
729
+ int len;
730
+
731
+ v = rb_String(v);
796
732
  str = StringValuePtr(v);
797
733
  len = (int)RSTRING_LEN(v);
798
- s = str;
734
+ s = str;
799
735
  end = str + len;
800
736
  i_am_a_child(b, false);
801
737
  append_indent(b);
@@ -808,7 +744,7 @@ builder_cdata(VALUE self, VALUE data) {
808
744
  while (NULL != s) {
809
745
  b->line++;
810
746
  b->col = end - s;
811
- s = strchr(s + 1, '\n');
747
+ s = strchr(s + 1, '\n');
812
748
  }
813
749
  b->pos += len;
814
750
  buf_append_string(&b->buf, "]]>", 3);
@@ -824,21 +760,18 @@ builder_cdata(VALUE self, VALUE data) {
824
760
  *
825
761
  * - +text+ - (String) contents to be added
826
762
  */
827
- static VALUE
828
- builder_raw(VALUE self, VALUE text) {
829
- Builder b = (Builder)DATA_PTR(self);
830
- volatile VALUE v = text;
831
- const char *str;
832
- const char *s;
833
- const char *end;
834
- int len;
835
-
836
- if (T_STRING != rb_type(v)) {
837
- v = rb_funcall(v, ox_to_s_id, 0);
838
- }
763
+ static VALUE builder_raw(VALUE self, VALUE text) {
764
+ Builder b = (Builder)DATA_PTR(self);
765
+ volatile VALUE v = text;
766
+ const char *str;
767
+ const char *s;
768
+ const char *end;
769
+ int len;
770
+
771
+ v = rb_String(v);
839
772
  str = StringValuePtr(v);
840
773
  len = (int)RSTRING_LEN(v);
841
- s = str;
774
+ s = str;
842
775
  end = str + len;
843
776
  i_am_a_child(b, true);
844
777
  buf_append_string(&b->buf, str, len);
@@ -847,7 +780,7 @@ builder_raw(VALUE self, VALUE text) {
847
780
  while (NULL != s) {
848
781
  b->line++;
849
782
  b->col = end - s;
850
- s = strchr(s + 1, '\n');
783
+ s = strchr(s + 1, '\n');
851
784
  }
852
785
  b->pos += len;
853
786
 
@@ -858,8 +791,7 @@ builder_raw(VALUE self, VALUE text) {
858
791
  *
859
792
  * Returns the JSON document string in what ever state the construction is at.
860
793
  */
861
- static VALUE
862
- builder_to_s(VALUE self) {
794
+ static VALUE builder_to_s(VALUE self) {
863
795
  return to_s((Builder)DATA_PTR(self));
864
796
  }
865
797
 
@@ -867,8 +799,7 @@ builder_to_s(VALUE self) {
867
799
  *
868
800
  * Returns the current line in the output. The first line is line 1.
869
801
  */
870
- static VALUE
871
- builder_line(VALUE self) {
802
+ static VALUE builder_line(VALUE self) {
872
803
  return LONG2NUM(((Builder)DATA_PTR(self))->line);
873
804
  }
874
805
 
@@ -877,8 +808,7 @@ builder_line(VALUE self) {
877
808
  * Returns the current column in the output. The first character in a line is at
878
809
  * column 1.
879
810
  */
880
- static VALUE
881
- builder_column(VALUE self) {
811
+ static VALUE builder_column(VALUE self) {
882
812
  return LONG2NUM(((Builder)DATA_PTR(self))->col);
883
813
  }
884
814
 
@@ -886,8 +816,7 @@ builder_column(VALUE self) {
886
816
  *
887
817
  * Returns the indentation level
888
818
  */
889
- static VALUE
890
- builder_get_indent(VALUE self) {
819
+ static VALUE builder_get_indent(VALUE self) {
891
820
  return INT2NUM(((Builder)DATA_PTR(self))->indent);
892
821
  }
893
822
 
@@ -897,14 +826,9 @@ builder_get_indent(VALUE self) {
897
826
  *
898
827
  * - +indent+ (Fixnum) indentaion level, negative values excludes terminating newline
899
828
  */
900
- static VALUE
901
- builder_set_indent(VALUE self, VALUE indent) {
902
- #ifdef RUBY_INTEGER_UNIFICATION
829
+ static VALUE builder_set_indent(VALUE self, VALUE indent) {
903
830
  if (rb_cInteger != rb_obj_class(indent)) {
904
- #else
905
- if (rb_cFixnum != rb_obj_class(indent)) {
906
- #endif
907
- rb_raise(ox_parse_error_class, "indent must be a fixnum.\n");
831
+ rb_raise(ox_parse_error_class, "indent must be a fixnum.\n");
908
832
  }
909
833
 
910
834
  ((Builder)DATA_PTR(self))->indent = NUM2INT(indent);
@@ -915,8 +839,7 @@ builder_set_indent(VALUE self, VALUE indent) {
915
839
  *
916
840
  * Returns the number of bytes written.
917
841
  */
918
- static VALUE
919
- builder_pos(VALUE self) {
842
+ static VALUE builder_pos(VALUE self) {
920
843
  return LONG2NUM(((Builder)DATA_PTR(self))->pos);
921
844
  }
922
845
 
@@ -934,8 +857,7 @@ static VALUE builder_pop(VALUE self) {
934
857
  *
935
858
  * Closes the all elements and the document.
936
859
  */
937
- static VALUE
938
- builder_close(VALUE self) {
860
+ static VALUE builder_close(VALUE self) {
939
861
  bclose((Builder)DATA_PTR(self));
940
862
 
941
863
  return Qnil;
@@ -946,8 +868,7 @@ builder_close(VALUE self) {
946
868
  *
947
869
  * An XML builder.
948
870
  */
949
- void
950
- ox_init_builder(VALUE ox) {
871
+ void ox_init_builder(VALUE ox) {
951
872
  #if 0
952
873
  // Just for rdoc.
953
874
  ox = rb_define_module("Ox");