ox 2.14.14 → 2.14.16

Sign up to get free protection for your applications and to get access to all the features.
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,48 @@ 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;
336
+ volatile VALUE v;
360
337
 
361
- rb_check_type(*argv, T_HASH);
362
- if (Qnil != (v = rb_hash_lookup(*argv, ox_indent_sym))) {
338
+ rb_check_type(*argv, T_HASH);
339
+ if (Qnil != (v = rb_hash_lookup(*argv, ox_indent_sym))) {
363
340
  #ifdef RUBY_INTEGER_UNIFICATION
364
- if (rb_cInteger != rb_obj_class(v)) {
341
+ if (rb_cInteger != rb_obj_class(v)) {
365
342
  #else
366
- if (rb_cFixnum != rb_obj_class(v)) {
343
+ if (rb_cFixnum != rb_obj_class(v)) {
367
344
  #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))) {
345
+ rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
346
+ }
347
+ indent = NUM2INT(v);
348
+ }
349
+ if (Qnil != (v = rb_hash_lookup(*argv, ox_size_sym))) {
373
350
  #ifdef RUBY_INTEGER_UNIFICATION
374
- if (rb_cInteger != rb_obj_class(v)) {
351
+ if (rb_cInteger != rb_obj_class(v)) {
375
352
  #else
376
- if (rb_cFixnum != rb_obj_class(v)) {
353
+ if (rb_cFixnum != rb_obj_class(v)) {
377
354
  #endif
378
- rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
379
- }
380
- buf_size = NUM2LONG(v);
381
- }
355
+ rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
356
+ }
357
+ buf_size = NUM2LONG(v);
358
+ }
382
359
  }
383
360
  b->file = NULL;
384
361
  init(b, 0, indent, buf_size);
385
362
 
386
363
  if (rb_block_given_p()) {
387
- volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b);
364
+ volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b);
388
365
 
389
- rb_yield(rb);
390
- bclose(b);
366
+ rb_yield(rb);
367
+ bclose(b);
391
368
 
392
- return to_s(b);
369
+ return to_s(b);
393
370
  } else {
394
- return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
371
+ return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
395
372
  }
396
373
  }
397
374
 
@@ -404,56 +381,55 @@ builder_new(int argc, VALUE *argv, VALUE self) {
404
381
  * - +:indent+ (Fixnum) indentaion level, negative values excludes terminating newline
405
382
  * - +:size+ (Fixnum) the initial size of the string buffer
406
383
  */
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;
384
+ static VALUE builder_file(int argc, VALUE *argv, VALUE self) {
385
+ Builder b = ALLOC(struct _builder);
386
+ int indent = ox_default_options.indent;
387
+ long buf_size = 0;
388
+ FILE *f;
413
389
 
414
390
  if (1 > argc) {
415
- rb_raise(ox_arg_error_class, "missing filename");
391
+ rb_raise(ox_arg_error_class, "missing filename");
416
392
  }
417
393
  Check_Type(*argv, T_STRING);
418
394
  if (NULL == (f = fopen(StringValuePtr(*argv), "w"))) {
419
- xfree(b);
420
- rb_raise(rb_eIOError, "%s\n", strerror(errno));
395
+ xfree(b);
396
+ rb_raise(rb_eIOError, "%s\n", strerror(errno));
421
397
  }
422
398
  if (2 == argc) {
423
- volatile VALUE v;
399
+ volatile VALUE v;
424
400
 
425
- rb_check_type(argv[1], T_HASH);
426
- if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) {
401
+ rb_check_type(argv[1], T_HASH);
402
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) {
427
403
  #ifdef RUBY_INTEGER_UNIFICATION
428
- if (rb_cInteger != rb_obj_class(v)) {
404
+ if (rb_cInteger != rb_obj_class(v)) {
429
405
  #else
430
- if (rb_cFixnum != rb_obj_class(v)) {
406
+ if (rb_cFixnum != rb_obj_class(v)) {
431
407
  #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))) {
408
+ rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
409
+ }
410
+ indent = NUM2INT(v);
411
+ }
412
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) {
437
413
  #ifdef RUBY_INTEGER_UNIFICATION
438
- if (rb_cInteger != rb_obj_class(v)) {
414
+ if (rb_cInteger != rb_obj_class(v)) {
439
415
  #else
440
- if (rb_cFixnum != rb_obj_class(v)) {
416
+ if (rb_cFixnum != rb_obj_class(v)) {
441
417
  #endif
442
- rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
443
- }
444
- buf_size = NUM2LONG(v);
445
- }
418
+ rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
419
+ }
420
+ buf_size = NUM2LONG(v);
421
+ }
446
422
  }
447
423
  b->file = f;
448
424
  init(b, fileno(f), indent, buf_size);
449
425
 
450
426
  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;
427
+ volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b);
428
+ rb_yield(rb);
429
+ bclose(b);
430
+ return Qnil;
455
431
  } else {
456
- return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
432
+ return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
457
433
  }
458
434
  }
459
435
 
@@ -466,57 +442,55 @@ builder_file(int argc, VALUE *argv, VALUE self) {
466
442
  * - +:indent+ (Fixnum) indentaion level, negative values excludes terminating newline
467
443
  * - +:size+ (Fixnum) the initial size of the string buffer
468
444
  */
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;
445
+ static VALUE builder_io(int argc, VALUE *argv, VALUE self) {
446
+ Builder b = ALLOC(struct _builder);
447
+ int indent = ox_default_options.indent;
448
+ long buf_size = 0;
449
+ int fd;
450
+ volatile VALUE v;
476
451
 
477
452
  if (1 > argc) {
478
- rb_raise(ox_arg_error_class, "missing IO object");
453
+ rb_raise(ox_arg_error_class, "missing IO object");
479
454
  }
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.");
455
+ if (!rb_respond_to(*argv, ox_fileno_id) || Qnil == (v = rb_funcall(*argv, ox_fileno_id, 0)) ||
456
+ 0 == (fd = FIX2INT(v))) {
457
+ rb_raise(rb_eIOError, "expected an IO that has a fileno.");
484
458
  }
485
459
  if (2 == argc) {
486
- volatile VALUE v;
460
+ volatile VALUE v;
487
461
 
488
- rb_check_type(argv[1], T_HASH);
489
- if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) {
462
+ rb_check_type(argv[1], T_HASH);
463
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) {
490
464
  #ifdef RUBY_INTEGER_UNIFICATION
491
- if (rb_cInteger != rb_obj_class(v)) {
465
+ if (rb_cInteger != rb_obj_class(v)) {
492
466
  #else
493
- if (rb_cFixnum != rb_obj_class(v)) {
467
+ if (rb_cFixnum != rb_obj_class(v)) {
494
468
  #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))) {
469
+ rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
470
+ }
471
+ indent = NUM2INT(v);
472
+ }
473
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) {
500
474
  #ifdef RUBY_INTEGER_UNIFICATION
501
- if (rb_cInteger != rb_obj_class(v)) {
475
+ if (rb_cInteger != rb_obj_class(v)) {
502
476
  #else
503
- if (rb_cFixnum != rb_obj_class(v)) {
477
+ if (rb_cFixnum != rb_obj_class(v)) {
504
478
  #endif
505
- rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
506
- }
507
- buf_size = NUM2LONG(v);
508
- }
479
+ rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
480
+ }
481
+ buf_size = NUM2LONG(v);
482
+ }
509
483
  }
510
484
  b->file = NULL;
511
485
  init(b, fd, indent, buf_size);
512
486
 
513
487
  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;
488
+ volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b);
489
+ rb_yield(rb);
490
+ bclose(b);
491
+ return Qnil;
518
492
  } else {
519
- return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
493
+ return Data_Wrap_Struct(builder_class, NULL, builder_free, b);
520
494
  }
521
495
  }
522
496
 
@@ -527,65 +501,64 @@ builder_io(int argc, VALUE *argv, VALUE self) {
527
501
  * - +decl+ - (String) 'xml' expected
528
502
  * - +options+ - (Hash) version or encoding
529
503
  */
530
- static VALUE
531
- builder_instruct(int argc, VALUE *argv, VALUE self) {
532
- Builder b = (Builder)DATA_PTR(self);
504
+ static VALUE builder_instruct(int argc, VALUE *argv, VALUE self) {
505
+ Builder b = (Builder)DATA_PTR(self);
533
506
 
534
507
  i_am_a_child(b, false);
535
508
  append_indent(b);
536
509
  if (0 == argc) {
537
- buf_append_string(&b->buf, "<?xml?>", 7);
538
- b->col += 7;
539
- b->pos += 7;
510
+ buf_append_string(&b->buf, "<?xml?>", 7);
511
+ b->col += 7;
512
+ b->pos += 7;
540
513
  } 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;
514
+ volatile VALUE v;
515
+
516
+ buf_append_string(&b->buf, "<?", 2);
517
+ b->col += 2;
518
+ b->pos += 2;
519
+ append_sym_str(b, *argv);
520
+ if (1 < argc && rb_cHash == rb_obj_class(argv[1])) {
521
+ int len;
522
+
523
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_version_sym))) {
524
+ if (rb_cString != rb_obj_class(v)) {
525
+ rb_raise(ox_parse_error_class, ":version must be a Symbol.\n");
526
+ }
527
+ len = (int)RSTRING_LEN(v);
528
+ buf_append_string(&b->buf, " version=\"", 10);
529
+ buf_append_string(&b->buf, StringValuePtr(v), len);
530
+ buf_append(&b->buf, '"');
531
+ b->col += len + 11;
532
+ b->pos += len + 11;
533
+ }
534
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_encoding_sym))) {
535
+ if (rb_cString != rb_obj_class(v)) {
536
+ rb_raise(ox_parse_error_class, ":encoding must be a Symbol.\n");
537
+ }
538
+ len = (int)RSTRING_LEN(v);
539
+ buf_append_string(&b->buf, " encoding=\"", 11);
540
+ buf_append_string(&b->buf, StringValuePtr(v), len);
541
+ buf_append(&b->buf, '"');
542
+ b->col += len + 12;
543
+ b->pos += len + 12;
544
+ strncpy(b->encoding, StringValuePtr(v), sizeof(b->encoding));
545
+ b->encoding[sizeof(b->encoding) - 1] = '\0';
546
+ }
547
+ if (Qnil != (v = rb_hash_lookup(argv[1], ox_standalone_sym))) {
548
+ if (rb_cString != rb_obj_class(v)) {
549
+ rb_raise(ox_parse_error_class, ":standalone must be a Symbol.\n");
550
+ }
551
+ len = (int)RSTRING_LEN(v);
552
+ buf_append_string(&b->buf, " standalone=\"", 13);
553
+ buf_append_string(&b->buf, StringValuePtr(v), len);
554
+ buf_append(&b->buf, '"');
555
+ b->col += len + 14;
556
+ b->pos += len + 14;
557
+ }
558
+ }
559
+ buf_append_string(&b->buf, "?>", 2);
560
+ b->col += 2;
561
+ b->pos += 2;
589
562
  }
590
563
  return Qnil;
591
564
  }
@@ -598,45 +571,42 @@ builder_instruct(int argc, VALUE *argv, VALUE self) {
598
571
  * - +name+ - (String) name of the element
599
572
  * - +attributes+ - (Hash) of the element
600
573
  */
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;
574
+ static VALUE builder_element(int argc, VALUE *argv, VALUE self) {
575
+ Builder b = (Builder)DATA_PTR(self);
576
+ Element e;
577
+ const char *name;
578
+ long len;
607
579
 
608
580
  if (1 > argc) {
609
- rb_raise(ox_arg_error_class, "missing element name");
581
+ rb_raise(ox_arg_error_class, "missing element name");
610
582
  }
611
583
  i_am_a_child(b, false);
612
584
  append_indent(b);
613
585
  b->depth++;
614
586
  if (MAX_DEPTH <= b->depth) {
615
- rb_raise(ox_arg_error_class, "XML too deeply nested");
587
+ rb_raise(ox_arg_error_class, "XML too deeply nested");
616
588
  }
617
589
  switch (rb_type(*argv)) {
618
590
  case T_STRING:
619
- name = StringValuePtr(*argv);
620
- len = RSTRING_LEN(*argv);
621
- break;
591
+ name = StringValuePtr(*argv);
592
+ len = RSTRING_LEN(*argv);
593
+ break;
622
594
  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;
595
+ name = rb_id2name(SYM2ID(*argv));
596
+ len = strlen(name);
597
+ break;
598
+ default: rb_raise(ox_arg_error_class, "expected a Symbol or String for an element name"); break;
629
599
  }
630
600
  e = &b->stack[b->depth];
631
601
  if (sizeof(e->buf) <= (size_t)len) {
632
- e->name = strdup(name);
633
- *e->buf = '\0';
602
+ e->name = strdup(name);
603
+ *e->buf = '\0';
634
604
  } else {
635
- strcpy(e->buf, name);
636
- e->name = e->buf;
605
+ strcpy(e->buf, name);
606
+ e->name = e->buf;
637
607
  }
638
- e->len = len;
639
- e->has_child = false;
608
+ e->len = len;
609
+ e->has_child = false;
640
610
  e->non_text_child = false;
641
611
 
642
612
  buf_append(&b->buf, '<');
@@ -644,12 +614,12 @@ builder_element(int argc, VALUE *argv, VALUE self) {
644
614
  b->pos++;
645
615
  append_string(b, e->name, len, xml_element_chars, false);
646
616
  if (1 < argc && T_HASH == rb_type(argv[1])) {
647
- rb_hash_foreach(argv[1], append_attr, (VALUE)b);
617
+ rb_hash_foreach(argv[1], append_attr, (VALUE)b);
648
618
  }
649
619
  // Do not close with > or /> yet. That is done with i_am_a_child() or pop().
650
620
  if (rb_block_given_p()) {
651
- rb_yield(self);
652
- pop(b);
621
+ rb_yield(self);
622
+ pop(b);
653
623
  }
654
624
  return Qnil;
655
625
  }
@@ -661,39 +631,37 @@ builder_element(int argc, VALUE *argv, VALUE self) {
661
631
  * - +name+ - (String) name of the element
662
632
  * - +attributes+ - (Hash) of the element
663
633
  */
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;
634
+ static VALUE builder_void_element(int argc, VALUE *argv, VALUE self) {
635
+ Builder b = (Builder)DATA_PTR(self);
636
+ const char *name;
637
+ long len;
669
638
 
670
639
  if (1 > argc) {
671
- rb_raise(ox_arg_error_class, "missing element name");
640
+ rb_raise(ox_arg_error_class, "missing element name");
672
641
  }
673
642
  i_am_a_child(b, false);
674
643
  append_indent(b);
675
644
  switch (rb_type(*argv)) {
676
645
  case T_STRING:
677
- name = StringValuePtr(*argv);
678
- len = RSTRING_LEN(*argv);
679
- break;
646
+ name = StringValuePtr(*argv);
647
+ len = RSTRING_LEN(*argv);
648
+ break;
680
649
  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;
650
+ name = rb_id2name(SYM2ID(*argv));
651
+ len = strlen(name);
652
+ break;
653
+ default: rb_raise(ox_arg_error_class, "expected a Symbol or String for an element name"); break;
687
654
  }
688
655
  buf_append(&b->buf, '<');
689
656
  b->col++;
690
657
  b->pos++;
691
658
  append_string(b, name, len, xml_element_chars, false);
692
659
  if (1 < argc && T_HASH == rb_type(argv[1])) {
693
- rb_hash_foreach(argv[1], append_attr, (VALUE)b);
660
+ rb_hash_foreach(argv[1], append_attr, (VALUE)b);
694
661
  }
695
662
  buf_append_string(&b->buf, ">", 1);
696
- b->col++;;
663
+ b->col++;
664
+ ;
697
665
  b->pos++;
698
666
 
699
667
  return Qnil;
@@ -704,9 +672,8 @@ builder_void_element(int argc, VALUE *argv, VALUE self) {
704
672
  * Adds a comment element to the XML string being formed.
705
673
  * - +text+ - (String) contents of the comment
706
674
  */
707
- static VALUE
708
- builder_comment(VALUE self, VALUE text) {
709
- Builder b = (Builder)DATA_PTR(self);
675
+ static VALUE builder_comment(VALUE self, VALUE text) {
676
+ Builder b = (Builder)DATA_PTR(self);
710
677
 
711
678
  rb_check_type(text, T_STRING);
712
679
  i_am_a_child(b, false);
@@ -727,9 +694,8 @@ builder_comment(VALUE self, VALUE text) {
727
694
  * Adds a DOCTYPE element to the XML string being formed.
728
695
  * - +text+ - (String) contents of the doctype
729
696
  */
730
- static VALUE
731
- builder_doctype(VALUE self, VALUE text) {
732
- Builder b = (Builder)DATA_PTR(self);
697
+ static VALUE builder_doctype(VALUE self, VALUE text) {
698
+ Builder b = (Builder)DATA_PTR(self);
733
699
 
734
700
  rb_check_type(text, T_STRING);
735
701
  i_am_a_child(b, false);
@@ -751,24 +717,23 @@ builder_doctype(VALUE self, VALUE text) {
751
717
  * - +text+ - (String) contents of the text field
752
718
  * - +strip_invalid_chars+ - [true|false] strips any characters invalid for XML, defaults to false
753
719
  */
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;
720
+ static VALUE builder_text(int argc, VALUE *argv, VALUE self) {
721
+ Builder b = (Builder)DATA_PTR(self);
722
+ volatile VALUE v;
723
+ volatile VALUE strip_invalid_chars;
759
724
 
760
725
  if ((0 == argc) || (argc > 2)) {
761
- rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1..2)", argc);
726
+ rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1..2)", argc);
762
727
  }
763
728
  v = argv[0];
764
729
  if (2 == argc) {
765
- strip_invalid_chars = argv[1];
730
+ strip_invalid_chars = argv[1];
766
731
  } else {
767
- strip_invalid_chars = Qfalse;
732
+ strip_invalid_chars = Qfalse;
768
733
  }
769
734
 
770
735
  if (T_STRING != rb_type(v)) {
771
- v = rb_funcall(v, ox_to_s_id, 0);
736
+ v = rb_funcall(v, ox_to_s_id, 0);
772
737
  }
773
738
  i_am_a_child(b, true);
774
739
  append_string(b, StringValuePtr(v), RSTRING_LEN(v), xml_element_chars, RTEST(strip_invalid_chars));
@@ -781,21 +746,20 @@ builder_text(int argc, VALUE *argv, VALUE self) {
781
746
  * Adds a CDATA element to the XML string being formed.
782
747
  * - +data+ - (String) contents of the CDATA element
783
748
  */
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;
749
+ static VALUE builder_cdata(VALUE self, VALUE data) {
750
+ Builder b = (Builder)DATA_PTR(self);
751
+ volatile VALUE v = data;
752
+ const char *str;
753
+ const char *s;
754
+ const char *end;
755
+ int len;
792
756
 
793
757
  if (T_STRING != rb_type(v)) {
794
- v = rb_funcall(v, ox_to_s_id, 0);
758
+ v = rb_funcall(v, ox_to_s_id, 0);
795
759
  }
796
760
  str = StringValuePtr(v);
797
761
  len = (int)RSTRING_LEN(v);
798
- s = str;
762
+ s = str;
799
763
  end = str + len;
800
764
  i_am_a_child(b, false);
801
765
  append_indent(b);
@@ -808,7 +772,7 @@ builder_cdata(VALUE self, VALUE data) {
808
772
  while (NULL != s) {
809
773
  b->line++;
810
774
  b->col = end - s;
811
- s = strchr(s + 1, '\n');
775
+ s = strchr(s + 1, '\n');
812
776
  }
813
777
  b->pos += len;
814
778
  buf_append_string(&b->buf, "]]>", 3);
@@ -824,21 +788,20 @@ builder_cdata(VALUE self, VALUE data) {
824
788
  *
825
789
  * - +text+ - (String) contents to be added
826
790
  */
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;
791
+ static VALUE builder_raw(VALUE self, VALUE text) {
792
+ Builder b = (Builder)DATA_PTR(self);
793
+ volatile VALUE v = text;
794
+ const char *str;
795
+ const char *s;
796
+ const char *end;
797
+ int len;
835
798
 
836
799
  if (T_STRING != rb_type(v)) {
837
- v = rb_funcall(v, ox_to_s_id, 0);
800
+ v = rb_funcall(v, ox_to_s_id, 0);
838
801
  }
839
802
  str = StringValuePtr(v);
840
803
  len = (int)RSTRING_LEN(v);
841
- s = str;
804
+ s = str;
842
805
  end = str + len;
843
806
  i_am_a_child(b, true);
844
807
  buf_append_string(&b->buf, str, len);
@@ -847,7 +810,7 @@ builder_raw(VALUE self, VALUE text) {
847
810
  while (NULL != s) {
848
811
  b->line++;
849
812
  b->col = end - s;
850
- s = strchr(s + 1, '\n');
813
+ s = strchr(s + 1, '\n');
851
814
  }
852
815
  b->pos += len;
853
816
 
@@ -858,8 +821,7 @@ builder_raw(VALUE self, VALUE text) {
858
821
  *
859
822
  * Returns the JSON document string in what ever state the construction is at.
860
823
  */
861
- static VALUE
862
- builder_to_s(VALUE self) {
824
+ static VALUE builder_to_s(VALUE self) {
863
825
  return to_s((Builder)DATA_PTR(self));
864
826
  }
865
827
 
@@ -867,8 +829,7 @@ builder_to_s(VALUE self) {
867
829
  *
868
830
  * Returns the current line in the output. The first line is line 1.
869
831
  */
870
- static VALUE
871
- builder_line(VALUE self) {
832
+ static VALUE builder_line(VALUE self) {
872
833
  return LONG2NUM(((Builder)DATA_PTR(self))->line);
873
834
  }
874
835
 
@@ -877,8 +838,7 @@ builder_line(VALUE self) {
877
838
  * Returns the current column in the output. The first character in a line is at
878
839
  * column 1.
879
840
  */
880
- static VALUE
881
- builder_column(VALUE self) {
841
+ static VALUE builder_column(VALUE self) {
882
842
  return LONG2NUM(((Builder)DATA_PTR(self))->col);
883
843
  }
884
844
 
@@ -886,8 +846,7 @@ builder_column(VALUE self) {
886
846
  *
887
847
  * Returns the indentation level
888
848
  */
889
- static VALUE
890
- builder_get_indent(VALUE self) {
849
+ static VALUE builder_get_indent(VALUE self) {
891
850
  return INT2NUM(((Builder)DATA_PTR(self))->indent);
892
851
  }
893
852
 
@@ -897,14 +856,13 @@ builder_get_indent(VALUE self) {
897
856
  *
898
857
  * - +indent+ (Fixnum) indentaion level, negative values excludes terminating newline
899
858
  */
900
- static VALUE
901
- builder_set_indent(VALUE self, VALUE indent) {
859
+ static VALUE builder_set_indent(VALUE self, VALUE indent) {
902
860
  #ifdef RUBY_INTEGER_UNIFICATION
903
861
  if (rb_cInteger != rb_obj_class(indent)) {
904
862
  #else
905
863
  if (rb_cFixnum != rb_obj_class(indent)) {
906
864
  #endif
907
- rb_raise(ox_parse_error_class, "indent must be a fixnum.\n");
865
+ rb_raise(ox_parse_error_class, "indent must be a fixnum.\n");
908
866
  }
909
867
 
910
868
  ((Builder)DATA_PTR(self))->indent = NUM2INT(indent);
@@ -915,8 +873,7 @@ builder_set_indent(VALUE self, VALUE indent) {
915
873
  *
916
874
  * Returns the number of bytes written.
917
875
  */
918
- static VALUE
919
- builder_pos(VALUE self) {
876
+ static VALUE builder_pos(VALUE self) {
920
877
  return LONG2NUM(((Builder)DATA_PTR(self))->pos);
921
878
  }
922
879
 
@@ -934,8 +891,7 @@ static VALUE builder_pop(VALUE self) {
934
891
  *
935
892
  * Closes the all elements and the document.
936
893
  */
937
- static VALUE
938
- builder_close(VALUE self) {
894
+ static VALUE builder_close(VALUE self) {
939
895
  bclose((Builder)DATA_PTR(self));
940
896
 
941
897
  return Qnil;
@@ -946,8 +902,7 @@ builder_close(VALUE self) {
946
902
  *
947
903
  * An XML builder.
948
904
  */
949
- void
950
- ox_init_builder(VALUE ox) {
905
+ void ox_init_builder(VALUE ox) {
951
906
  #if 0
952
907
  // Just for rdoc.
953
908
  ox = rb_define_module("Ox");