ox 2.14.14 → 2.14.15

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/sax.c CHANGED
@@ -761,17 +761,19 @@ CB:
761
761
  * code.
762
762
  */
763
763
  static char read_element_start(SaxDrive dr) {
764
- const char *ename = 0;
764
+ const char *ename = NULL;
765
+ char ebuf[128];
765
766
  size_t nlen;
766
- volatile VALUE name = Qnil;
767
+ volatile VALUE name = Qnil;
767
768
  char c;
768
- int closed;
769
769
  long pos = (long)(dr->buf.pos);
770
770
  long line = (long)(dr->buf.line);
771
771
  long col = (long)(dr->buf.col);
772
772
  Hint h = NULL;
773
773
  int stackless = 0;
774
774
  Nv parent = stack_peek(&dr->stack);
775
+ bool closed;
776
+ bool efree = false;
775
777
 
776
778
  if ('\0' == (c = read_name_token(dr))) {
777
779
  return '\0';
@@ -827,7 +829,7 @@ static char read_element_start(SaxDrive dr) {
827
829
  if (0 != top_nv) {
828
830
  char msg[256];
829
831
 
830
- if (!h->nest && NestOverlay != h->overlay && 0 == strcasecmp(top_nv->name, h->name)) {
832
+ if (!h->nest && NestOverlay != h->overlay && nv_same_name(top_nv, h->name, true)) {
831
833
  snprintf(msg,
832
834
  sizeof(msg) - 1,
833
835
  "%s%s can not be nested in a %s document, closing previous.",
@@ -844,7 +846,7 @@ static char read_element_start(SaxDrive dr) {
844
846
  int ok = 0;
845
847
 
846
848
  for (p = h->parents; 0 != *p; p++) {
847
- if (0 == strcasecmp(*p, top_nv->name)) {
849
+ if (nv_same_name(top_nv, *p, true)) {
848
850
  ok = 1;
849
851
  break;
850
852
  }
@@ -855,7 +857,7 @@ static char read_element_start(SaxDrive dr) {
855
857
  "%s%s can not be a child of a %s in a %s document.",
856
858
  INV_ELEMENT,
857
859
  h->name,
858
- top_nv->name,
860
+ nv_name(top_nv),
859
861
  dr->options.hints->name);
860
862
  ox_sax_drive_error(dr, msg);
861
863
  }
@@ -864,6 +866,16 @@ static char read_element_start(SaxDrive dr) {
864
866
  }
865
867
  }
866
868
  name = str2sym(dr, dr->buf.str, nlen, &ename);
869
+ if (NULL == ename) {
870
+ if (sizeof(ebuf) <= nlen) {
871
+ ename = strndup(dr->buf.str, nlen);
872
+ efree = true;
873
+ } else {
874
+ memcpy(ebuf, dr->buf.str, nlen);
875
+ ebuf[nlen] = '\0';
876
+ ename = ebuf;
877
+ }
878
+ }
867
879
  if (dr->has_start_element && 0 >= dr->blocked &&
868
880
  (NULL == h || ActiveOverlay == h->overlay || NestOverlay == h->overlay)) {
869
881
  VALUE args[1];
@@ -875,9 +887,9 @@ static char read_element_start(SaxDrive dr) {
875
887
  rb_funcall2(dr->handler, ox_start_element_id, 1, args);
876
888
  }
877
889
  if ('/' == c) {
878
- closed = 1;
890
+ closed = true;
879
891
  } else if ('>' == c) {
880
- closed = 0;
892
+ closed = false;
881
893
  } else {
882
894
  buf_protect(&dr->buf);
883
895
  c = read_attrs(dr, c, '/', '>', 0, 0, h);
@@ -906,11 +918,14 @@ static char read_element_start(SaxDrive dr) {
906
918
  } else {
907
919
  stack_push(&dr->stack, ename, nlen, name, h);
908
920
  }
921
+ if (efree) {
922
+ free((char *)ename);
923
+ }
909
924
  if ('>' != c) {
910
925
  ox_sax_drive_error(dr, WRONG_CHAR "element not closed");
911
926
  return c;
912
927
  }
913
- dr->buf.str = 0;
928
+ dr->buf.str = NULL;
914
929
 
915
930
  return buf_get(&dr->buf);
916
931
  }
@@ -919,7 +934,7 @@ static Nv stack_rev_find(SaxDrive dr, const char *name) {
919
934
  Nv nv;
920
935
 
921
936
  for (nv = dr->stack.tail - 1; dr->stack.head <= nv; nv--) {
922
- if (0 == (dr->options.smart ? strcasecmp(name, nv->name) : strcmp(name, nv->name))) {
937
+ if (nv_same_name(nv, name, dr->options.smart)) {
923
938
  return nv;
924
939
  }
925
940
  }
@@ -944,7 +959,7 @@ static char read_element_end(SaxDrive dr) {
944
959
  // c should be > and current is one past so read another char
945
960
  c = buf_get(&dr->buf);
946
961
  nv = stack_peek(&dr->stack);
947
- if (0 != nv && 0 == (dr->options.smart ? strcasecmp(dr->buf.str, nv->name) : strcmp(dr->buf.str, nv->name))) {
962
+ if (0 != nv && nv_same_name(nv, dr->buf.str, dr->options.smart)) {
948
963
  name = nv->val;
949
964
  h = nv->hint;
950
965
  stack_pop(&dr->stack);
@@ -997,7 +1012,7 @@ static char read_element_end(SaxDrive dr) {
997
1012
  "%selement '%s' close does not match '%s' open",
998
1013
  EL_MISMATCH,
999
1014
  dr->buf.str,
1000
- nv->name);
1015
+ nv_name(nv));
1001
1016
  ox_sax_drive_error_at(dr, msg, pos, line, col);
1002
1017
  for (nv = stack_pop(&dr->stack); match < nv; nv = stack_pop(&dr->stack)) {
1003
1018
  end_element_cb(dr, nv->val, pos, line, col, nv->hint);
@@ -1465,18 +1480,18 @@ int ox_sax_collapse_special(SaxDrive dr, char *str, long pos, long line, long co
1465
1480
  break;
1466
1481
  }
1467
1482
  case '\r':
1468
- s++;
1483
+ s++;
1469
1484
  if ('\n' == *s) {
1470
- continue;
1471
- }
1472
- line++;
1473
- col = 1;
1485
+ continue;
1486
+ }
1487
+ line++;
1488
+ col = 1;
1474
1489
  *b++ = '\n';
1475
- break;
1476
- case '\n':
1477
- line++;
1478
- col = 0;
1479
- // fall through
1490
+ break;
1491
+ case '\n':
1492
+ line++;
1493
+ col = 0;
1494
+ // fall through
1480
1495
  default:
1481
1496
  col++;
1482
1497
  *b++ = *s++;
@@ -1512,7 +1527,7 @@ static Nv hint_try_close(SaxDrive dr, const char *name) {
1512
1527
  return 0;
1513
1528
  }
1514
1529
  for (nv = stack_peek(&dr->stack); 0 != nv; nv = stack_peek(&dr->stack)) {
1515
- if (0 == strcasecmp(name, nv->name)) {
1530
+ if (nv_same_name(nv, name, true)) {
1516
1531
  stack_pop(&dr->stack);
1517
1532
  return nv;
1518
1533
  }
data/ext/ox/sax.h CHANGED
@@ -20,7 +20,7 @@ typedef struct _saxOptions {
20
20
  SkipMode skip;
21
21
  char strip_ns[64];
22
22
  Hints hints;
23
- } * SaxOptions;
23
+ } *SaxOptions;
24
24
 
25
25
  typedef struct _saxDrive {
26
26
  struct _buf buf;
@@ -52,7 +52,7 @@ typedef struct _saxDrive {
52
52
  bool has_start_element;
53
53
  bool has_end_element;
54
54
 
55
- } * SaxDrive;
55
+ } *SaxDrive;
56
56
 
57
57
  extern void ox_collapse_return(char *str);
58
58
  extern void ox_sax_parse(VALUE handler, VALUE io, SaxOptions options);
data/ext/ox/sax_as.c CHANGED
@@ -3,27 +3,26 @@
3
3
  * All rights reserved.
4
4
  */
5
5
 
6
- #include <stdlib.h>
7
6
  #include <errno.h>
8
7
  #include <stdio.h>
8
+ #include <stdlib.h>
9
9
  #include <strings.h>
10
10
  #include <sys/types.h>
11
11
  #if HAVE_SYS_UIO_H
12
12
  #include <sys/uio.h>
13
13
  #endif
14
- #include <unistd.h>
15
14
  #include <time.h>
15
+ #include <unistd.h>
16
16
 
17
+ #include "ox.h"
17
18
  #include "ruby.h"
18
19
  #include "ruby/version.h"
19
- #include "ox.h"
20
20
  #include "sax.h"
21
21
 
22
- static VALUE
23
- parse_double_time(const char *text) {
24
- long v = 0;
25
- long v2 = 0;
26
- const char *dot = 0;
22
+ static VALUE parse_double_time(const char *text) {
23
+ long v = 0;
24
+ long v2 = 0;
25
+ const char *dot = 0;
27
26
  char c;
28
27
 
29
28
  for (; '.' != *text; text++) {
@@ -52,58 +51,57 @@ parse_double_time(const char *text) {
52
51
  }
53
52
 
54
53
  typedef struct _tp {
55
- int cnt;
56
- char end;
57
- char alt;
54
+ int cnt;
55
+ char end;
56
+ char alt;
58
57
  } *Tp;
59
58
 
60
- static VALUE
61
- parse_xsd_time(const char *text) {
62
- long cargs[10];
63
- long *cp = cargs;
64
- long v;
65
- int i;
66
- char c = '\0';
67
- struct _tp tpa[10] = { { 4, '-', '-' },
68
- { 2, '-', '-' },
69
- { 2, 'T', ' ' },
70
- { 2, ':', ':' },
71
- { 2, ':', ':' },
72
- { 2, '.', '.' },
73
- { 9, '+', '-' },
74
- { 2, ':', ':' },
75
- { 2, '\0', '\0' },
76
- { 0, '\0', '\0' } };
77
- Tp tp = tpa;
78
- struct tm tm;
59
+ static VALUE parse_xsd_time(const char *text) {
60
+ long cargs[10];
61
+ long *cp = cargs;
62
+ long v;
63
+ int i;
64
+ char c = '\0';
65
+ struct _tp tpa[10] = {{4, '-', '-'},
66
+ {2, '-', '-'},
67
+ {2, 'T', ' '},
68
+ {2, ':', ':'},
69
+ {2, ':', ':'},
70
+ {2, '.', '.'},
71
+ {9, '+', '-'},
72
+ {2, ':', ':'},
73
+ {2, '\0', '\0'},
74
+ {0, '\0', '\0'}};
75
+ Tp tp = tpa;
76
+ struct tm tm;
79
77
 
80
78
  memset(cargs, 0, sizeof(cargs));
81
79
  for (; 0 != tp->cnt; tp++) {
82
- for (i = tp->cnt, v = 0; 0 < i ; text++, i--) {
80
+ for (i = tp->cnt, v = 0; 0 < i; text++, i--) {
83
81
  c = *text;
84
82
  if (c < '0' || '9' < c) {
85
83
  if ('\0' == c || tp->end == c || tp->alt == c) {
86
84
  break;
87
85
  }
88
- return Qnil;
86
+ return Qnil;
89
87
  }
90
88
  v = 10 * v + (long)(c - '0');
91
89
  }
92
- if ('\0' == c) {
93
- break;
94
- }
90
+ if ('\0' == c) {
91
+ break;
92
+ }
95
93
  c = *text++;
96
94
  if (tp->end != c && tp->alt != c) {
97
- return Qnil;
95
+ return Qnil;
98
96
  }
99
97
  *cp++ = v;
100
98
  }
101
99
  tm.tm_year = (int)cargs[0] - 1900;
102
- tm.tm_mon = (int)cargs[1] - 1;
100
+ tm.tm_mon = (int)cargs[1] - 1;
103
101
  tm.tm_mday = (int)cargs[2];
104
102
  tm.tm_hour = (int)cargs[3];
105
- tm.tm_min = (int)cargs[4];
106
- tm.tm_sec = (int)cargs[5];
103
+ tm.tm_min = (int)cargs[4];
104
+ tm.tm_sec = (int)cargs[5];
107
105
  #if HAVE_RB_TIME_NANO_NEW
108
106
  return rb_time_nano_new(mktime(&tm), cargs[6]);
109
107
  #else
@@ -115,30 +113,24 @@ parse_xsd_time(const char *text) {
115
113
  *
116
114
  * *return* value as an String.
117
115
  */
118
- static VALUE
119
- sax_value_as_s(VALUE self) {
120
- SaxDrive dr = DATA_PTR(self);
121
- VALUE rs;
116
+ static VALUE sax_value_as_s(VALUE self) {
117
+ SaxDrive dr = DATA_PTR(self);
118
+ VALUE rs;
122
119
 
123
120
  if ('\0' == *dr->buf.str) {
124
- return Qnil;
121
+ return Qnil;
125
122
  }
126
123
  if (dr->options.convert_special) {
127
- ox_sax_collapse_special(dr, dr->buf.str, dr->buf.pos, dr->buf.line, dr->buf.col);
124
+ ox_sax_collapse_special(dr, dr->buf.str, dr->buf.pos, dr->buf.line, dr->buf.col);
128
125
  }
129
126
  switch (dr->options.skip) {
130
- case CrSkip:
131
- buf_collapse_return(dr->buf.str);
132
- break;
133
- case SpcSkip:
134
- buf_collapse_white(dr->buf.str);
135
- break;
136
- default:
137
- break;
127
+ case CrSkip: buf_collapse_return(dr->buf.str); break;
128
+ case SpcSkip: buf_collapse_white(dr->buf.str); break;
129
+ default: break;
138
130
  }
139
131
  rs = rb_str_new2(dr->buf.str);
140
132
  if (0 != dr->encoding) {
141
- rb_enc_associate(rs, dr->encoding);
133
+ rb_enc_associate(rs, dr->encoding);
142
134
  }
143
135
  return rs;
144
136
  }
@@ -147,12 +139,11 @@ sax_value_as_s(VALUE self) {
147
139
  *
148
140
  * *return* value as an Symbol.
149
141
  */
150
- static VALUE
151
- sax_value_as_sym(VALUE self) {
152
- SaxDrive dr = DATA_PTR(self);
142
+ static VALUE sax_value_as_sym(VALUE self) {
143
+ SaxDrive dr = DATA_PTR(self);
153
144
 
154
145
  if ('\0' == *dr->buf.str) {
155
- return Qnil;
146
+ return Qnil;
156
147
  }
157
148
  return str2sym(dr, dr->buf.str, strlen(dr->buf.str), 0);
158
149
  }
@@ -161,12 +152,11 @@ sax_value_as_sym(VALUE self) {
161
152
  *
162
153
  * *return* value as an Float.
163
154
  */
164
- static VALUE
165
- sax_value_as_f(VALUE self) {
166
- SaxDrive dr = DATA_PTR(self);
155
+ static VALUE sax_value_as_f(VALUE self) {
156
+ SaxDrive dr = DATA_PTR(self);
167
157
 
168
158
  if ('\0' == *dr->buf.str) {
169
- return Qnil;
159
+ return Qnil;
170
160
  }
171
161
  return rb_float_new(strtod(dr->buf.str, 0));
172
162
  }
@@ -175,31 +165,30 @@ sax_value_as_f(VALUE self) {
175
165
  *
176
166
  * *return* value as an Fixnum.
177
167
  */
178
- static VALUE
179
- sax_value_as_i(VALUE self) {
180
- SaxDrive dr = DATA_PTR(self);
181
- const char *s = dr->buf.str;
182
- long n = 0;
183
- int neg = 0;
168
+ static VALUE sax_value_as_i(VALUE self) {
169
+ SaxDrive dr = DATA_PTR(self);
170
+ const char *s = dr->buf.str;
171
+ long n = 0;
172
+ int neg = 0;
184
173
 
185
174
  if ('\0' == *s) {
186
- return Qnil;
175
+ return Qnil;
187
176
  }
188
177
  if ('-' == *s) {
189
- neg = 1;
190
- s++;
178
+ neg = 1;
179
+ s++;
191
180
  } else if ('+' == *s) {
192
- s++;
181
+ s++;
193
182
  }
194
183
  for (; '\0' != *s; s++) {
195
- if ('0' <= *s && *s <= '9') {
196
- n = n * 10 + (*s - '0');
197
- } else {
198
- rb_raise(ox_arg_error_class, "Not a valid Fixnum.\n");
199
- }
184
+ if ('0' <= *s && *s <= '9') {
185
+ n = n * 10 + (*s - '0');
186
+ } else {
187
+ rb_raise(ox_arg_error_class, "Not a valid Fixnum.\n");
188
+ }
200
189
  }
201
190
  if (neg) {
202
- n = -n;
191
+ n = -n;
203
192
  }
204
193
  return LONG2NUM(n);
205
194
  }
@@ -208,22 +197,20 @@ sax_value_as_i(VALUE self) {
208
197
  *
209
198
  * *return* value as an Time.
210
199
  */
211
- static VALUE
212
- sax_value_as_time(VALUE self) {
213
- SaxDrive dr = DATA_PTR(self);
214
- const char *str = dr->buf.str;
200
+ static VALUE sax_value_as_time(VALUE self) {
201
+ SaxDrive dr = DATA_PTR(self);
202
+ const char *str = dr->buf.str;
215
203
  VALUE t;
216
204
 
217
205
  if ('\0' == *str) {
218
- return Qnil;
206
+ return Qnil;
219
207
  }
220
- if (Qnil == (t = parse_double_time(str)) &&
221
- Qnil == (t = parse_xsd_time(str))) {
222
- VALUE args[1];
208
+ if (Qnil == (t = parse_double_time(str)) && Qnil == (t = parse_xsd_time(str))) {
209
+ VALUE args[1];
223
210
 
224
211
  /*printf("**** time parse\n"); */
225
212
  *args = rb_str_new2(str);
226
- t = rb_funcall2(ox_time_class, ox_parse_id, 1, args);
213
+ t = rb_funcall2(ox_time_class, ox_parse_id, 1, args);
227
214
  }
228
215
  return t;
229
216
  }
@@ -232,8 +219,7 @@ sax_value_as_time(VALUE self) {
232
219
  *
233
220
  * *return* value as an boolean.
234
221
  */
235
- static VALUE
236
- sax_value_as_bool(VALUE self) {
222
+ static VALUE sax_value_as_bool(VALUE self) {
237
223
  return (0 == strcasecmp("true", ((SaxDrive)DATA_PTR(self))->buf.str)) ? Qtrue : Qfalse;
238
224
  }
239
225
 
@@ -241,8 +227,7 @@ sax_value_as_bool(VALUE self) {
241
227
  *
242
228
  * *return* true if the value is empty.
243
229
  */
244
- static VALUE
245
- sax_value_empty(VALUE self) {
230
+ static VALUE sax_value_empty(VALUE self) {
246
231
  return ('\0' == *((SaxDrive)DATA_PTR(self))->buf.str) ? Qtrue : Qfalse;
247
232
  }
248
233
 
@@ -251,15 +236,14 @@ sax_value_empty(VALUE self) {
251
236
  * Values in the SAX callbacks. They can be converted to various different
252
237
  * types. with the _as_x()_ methods.
253
238
  */
254
- void
255
- ox_sax_define() {
239
+ void ox_sax_define() {
256
240
  #if 0
257
241
  ox = rb_define_module("Ox");
258
242
  #if RUBY_API_VERSION_CODE >= 30200
259
243
  sax_module = rb_define_class_under(ox, "Sax", rb_cObject);
260
244
  #endif
261
245
  #endif
262
- VALUE sax_module = rb_const_get_at(Ox, rb_intern("Sax"));
246
+ VALUE sax_module = rb_const_get_at(Ox, rb_intern("Sax"));
263
247
 
264
248
  ox_sax_value_class = rb_define_class_under(sax_module, "Value", rb_cObject);
265
249
  #if RUBY_API_VERSION_CODE >= 30200