ox 2.14.13 → 2.14.15

Sign up to get free protection for your applications and to get access to all the features.
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