ox 1.9.0 → 1.9.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ox might be problematic. Click here for more details.

Files changed (5) hide show
  1. data/README.md +4 -0
  2. data/ext/ox/sax.c +80 -33
  3. data/lib/ox/sax.rb +2 -2
  4. data/lib/ox/version.rb +1 -1
  5. metadata +2 -2
data/README.md CHANGED
@@ -34,6 +34,10 @@ A fast XML parser and Object marshaller as a Ruby gem.
34
34
 
35
35
  ## <a name="release">Release Notes</a>
36
36
 
37
+ ### Release 1.9.1
38
+
39
+ - Fixed the line numbers to be the start of the elements in the sax parser.
40
+
37
41
  ### Release 1.9.0
38
42
 
39
43
  - Added a new feature to Ox::Element.locate() that allows filtering by node Class.
@@ -143,6 +143,20 @@ sax_drive_get(SaxDrive dr) {
143
143
  return *dr->cur++;
144
144
  }
145
145
 
146
+ static inline void
147
+ backup(SaxDrive dr) {
148
+ dr->cur--;
149
+ dr->col--; // should reverse wrap but not worth it
150
+ }
151
+
152
+ static inline void
153
+ reset_reader(SaxDrive dr, char *cur, int line, int col) {
154
+ dr->cur = cur;
155
+ dr->line = line;
156
+ dr->col = col;
157
+ }
158
+
159
+
146
160
  /* Starts by reading a character so it is safe to use with an empty or
147
161
  * compacted buffer.
148
162
  */
@@ -448,6 +462,8 @@ read_children(SaxDrive dr, int first) {
448
462
  int err = 0;
449
463
  int element_read = !first;
450
464
  char c;
465
+ int line;
466
+ int col;
451
467
 
452
468
  while (!err) {
453
469
  dr->str = dr->cur; /* protect the start */
@@ -523,14 +539,19 @@ read_children(SaxDrive dr, int first) {
523
539
  }
524
540
  break;
525
541
  case '/': /* element end */
526
- return ('\0' == read_name_token(dr));
542
+ line = dr->line;
543
+ col = dr->col;
544
+ err = ('\0' == read_name_token(dr));
545
+ dr->line = line;
546
+ dr->col = col;
547
+ return err;
527
548
  break;
528
549
  case '\0':
529
550
  sax_drive_error(dr, "invalid format, document not terminated", 1);
530
551
  err = 1;
531
552
  break;
532
553
  default:
533
- dr->cur--; /* safe since no read occurred after getting last character */
554
+ backup(dr); /* safe since no read occurred after getting last character */
534
555
  if (first && element_read) {
535
556
  sax_drive_error(dr, "invalid format, multiple top level elements", 0);
536
557
  }
@@ -578,6 +599,8 @@ read_instruction(SaxDrive dr) {
578
599
  const char *err;
579
600
  VALUE target = Qnil;
580
601
  int is_xml;
602
+ int line = dr->line;
603
+ int col = dr->col - 1;
581
604
 
582
605
  if ('\0' == (c = read_name_token(dr))) {
583
606
  return -1;
@@ -590,18 +613,20 @@ read_instruction(SaxDrive dr) {
590
613
  VALUE args[1];
591
614
 
592
615
  if (dr->has_line) {
593
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
616
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
594
617
  }
595
618
  if (dr->has_column) {
596
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
619
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
597
620
  }
598
621
  args[0] = target;
599
622
  rb_funcall2(dr->handler, ox_instruct_id, 1, args);
600
623
  }
601
624
  dr->str = dr->cur; /* make sure the start doesn't get compacted out */
625
+ line = dr->line;
626
+ col = dr->col;
602
627
  read_content(dr, content, sizeof(content) - 1);
603
628
  cend = dr->cur;
604
- dr->cur = dr->str;
629
+ reset_reader(dr, dr->str, line, col);
605
630
  if (0 != (err = read_attrs(dr, c, '?', '?', is_xml))) {
606
631
  if (dr->has_text) {
607
632
  VALUE args[1];
@@ -622,15 +647,17 @@ read_instruction(SaxDrive dr) {
622
647
  }
623
648
  #endif
624
649
  if (dr->has_line) {
625
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
650
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
626
651
  }
627
652
  if (dr->has_column) {
628
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
653
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
629
654
  }
630
655
  rb_funcall2(dr->handler, ox_text_id, 1, args);
631
656
  }
632
657
  dr->cur = cend;
633
658
  } else {
659
+ line = dr->line;
660
+ col = dr->col;
634
661
  c = next_non_white(dr);
635
662
  if ('>' != c) {
636
663
  sax_drive_error(dr, "invalid format, instruction not terminated", 1);
@@ -641,10 +668,10 @@ read_instruction(SaxDrive dr) {
641
668
  VALUE args[1];
642
669
 
643
670
  if (dr->has_line) {
644
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
671
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
645
672
  }
646
673
  if (dr->has_column) {
647
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
674
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
648
675
  }
649
676
  args[0] = target;
650
677
  rb_funcall2(dr->handler, ox_end_instruct_id, 1, args);
@@ -659,6 +686,8 @@ read_instruction(SaxDrive dr) {
659
686
  static int
660
687
  read_doctype(SaxDrive dr) {
661
688
  char c;
689
+ int line = dr->line;
690
+ int col = dr->col - 10;
662
691
 
663
692
  dr->str = dr->cur - 1; /* mark the start */
664
693
  while ('>' != (c = sax_drive_get(dr))) {
@@ -672,10 +701,10 @@ read_doctype(SaxDrive dr) {
672
701
  VALUE args[1];
673
702
 
674
703
  if (dr->has_line) {
675
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
704
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
676
705
  }
677
706
  if (dr->has_column) {
678
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
707
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
679
708
  }
680
709
  args[0] = rb_str_new2(dr->str);
681
710
  rb_funcall2(dr->handler, ox_doctype_id, 1, args);
@@ -691,8 +720,10 @@ static int
691
720
  read_cdata(SaxDrive dr) {
692
721
  char c;
693
722
  int end = 0;
723
+ int line = dr->line;
724
+ int col = dr->col - 10;
694
725
 
695
- dr->cur--; /* back up to the start in case the cdata is empty */
726
+ backup(dr); /* back up to the start in case the cdata is empty */
696
727
  dr->str = dr->cur; /* mark the start */
697
728
  while (1) {
698
729
  c = sax_drive_get(dr);
@@ -725,10 +756,10 @@ read_cdata(SaxDrive dr) {
725
756
  }
726
757
  #endif
727
758
  if (dr->has_line) {
728
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
759
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
729
760
  }
730
761
  if (dr->has_column) {
731
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
762
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
732
763
  }
733
764
  rb_funcall2(dr->handler, ox_cdata_id, 1, args);
734
765
  }
@@ -743,6 +774,8 @@ static int
743
774
  read_comment(SaxDrive dr) {
744
775
  char c;
745
776
  int end = 0;
777
+ int line = dr->line;
778
+ int col = dr->col - 5;
746
779
 
747
780
  dr->str = dr->cur - 1; /* mark the start */
748
781
  while (1) {
@@ -779,10 +812,10 @@ read_comment(SaxDrive dr) {
779
812
  }
780
813
  #endif
781
814
  if (dr->has_line) {
782
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
815
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
783
816
  }
784
817
  if (dr->has_column) {
785
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
818
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
786
819
  }
787
820
  rb_funcall2(dr->handler, ox_comment_id, 1, args);
788
821
  }
@@ -801,6 +834,8 @@ read_element(SaxDrive dr) {
801
834
  const char *err;
802
835
  char c;
803
836
  int closed;
837
+ int line = dr->line;
838
+ int col = dr->col - 1;
804
839
 
805
840
  if ('\0' == (c = read_name_token(dr))) {
806
841
  return -1;
@@ -810,10 +845,10 @@ read_element(SaxDrive dr) {
810
845
  VALUE args[1];
811
846
 
812
847
  if (dr->has_line) {
813
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
848
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
814
849
  }
815
850
  if (dr->has_column) {
816
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
851
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
817
852
  }
818
853
  args[0] = name;
819
854
  rb_funcall2(dr->handler, ox_start_element_id, 1, args);
@@ -837,14 +872,16 @@ read_element(SaxDrive dr) {
837
872
  }
838
873
  }
839
874
  if (closed) {
875
+ line = dr->line;
876
+ col = dr->col - 1;
840
877
  if (dr->has_end_element) {
841
878
  VALUE args[1];
842
879
 
843
880
  if (dr->has_line) {
844
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
881
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
845
882
  }
846
883
  if (dr->has_column) {
847
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
884
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
848
885
  }
849
886
  args[0] = name;
850
887
  rb_funcall2(dr->handler, ox_end_element_id, 1, args);
@@ -853,12 +890,16 @@ read_element(SaxDrive dr) {
853
890
  if (0 != read_children(dr, 0)) {
854
891
  return -1;
855
892
  }
893
+ line = dr->line;
894
+ col = dr->col;
895
+ // read_children reads up to the end of the terminating element nameb
896
+ dr->col += dr->cur - dr->str;
856
897
  if (0 != ename && 0 != strcmp(ename, dr->str)) {
857
898
  if (dr->has_line) {
858
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
899
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
859
900
  }
860
901
  if (dr->has_column) {
861
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
902
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
862
903
  }
863
904
  //printf("*** ename: %s close: %s\n", ename, dr->str);
864
905
  sax_drive_error(dr, "invalid format, element start and end names do not match", 1);
@@ -868,10 +909,10 @@ read_element(SaxDrive dr) {
868
909
  VALUE args[1];
869
910
 
870
911
  if (dr->has_line) {
871
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
912
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
872
913
  }
873
914
  if (dr->has_column) {
874
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
915
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col - 2));
875
916
  }
876
917
  args[0] = name;
877
918
  rb_funcall2(dr->handler, ox_end_element_id, 1, args);
@@ -885,6 +926,8 @@ read_element(SaxDrive dr) {
885
926
  static int
886
927
  read_text(SaxDrive dr) {
887
928
  char c;
929
+ int line = dr->line;
930
+ int col = dr->col - 1;
888
931
 
889
932
  /* start marked in read_children */
890
933
  /*dr->str = dr->cur - 1; / * mark the start */
@@ -899,10 +942,10 @@ read_text(SaxDrive dr) {
899
942
  VALUE args[1];
900
943
 
901
944
  if (dr->has_line) {
902
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
945
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
903
946
  }
904
947
  if (dr->has_column) {
905
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
948
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
906
949
  }
907
950
  *args = dr->value_obj;
908
951
  rb_funcall2(dr->handler, ox_value_id, 1, args);
@@ -925,10 +968,10 @@ read_text(SaxDrive dr) {
925
968
  }
926
969
  #endif
927
970
  if (dr->has_line) {
928
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
971
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
929
972
  }
930
973
  if (dr->has_column) {
931
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
974
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
932
975
  }
933
976
  rb_funcall2(dr->handler, ox_text_id, 1, args);
934
977
  }
@@ -941,13 +984,17 @@ static const char*
941
984
  read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml) {
942
985
  VALUE name = Qnil;
943
986
  int is_encoding = 0;
987
+ int line;
988
+ int col;
944
989
 
945
990
  dr->str = dr->cur; /* lock it down */
946
991
  if (is_white(c)) {
947
992
  c = next_non_white(dr);
948
993
  }
949
994
  while (termc != c && term2 != c) {
950
- dr->cur--;
995
+ backup(dr);
996
+ line = dr->line;
997
+ col = dr->col;
951
998
  if ('\0' == c) {
952
999
  return "invalid format, attributes not terminated";
953
1000
  }
@@ -982,10 +1029,10 @@ read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml) {
982
1029
  VALUE args[2];
983
1030
 
984
1031
  if (dr->has_line) {
985
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
1032
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
986
1033
  }
987
1034
  if (dr->has_column) {
988
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
1035
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
989
1036
  }
990
1037
  args[0] = name;
991
1038
  args[1] = dr->value_obj;
@@ -1008,10 +1055,10 @@ read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml) {
1008
1055
  }
1009
1056
  #endif
1010
1057
  if (dr->has_line) {
1011
- rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(dr->line));
1058
+ rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
1012
1059
  }
1013
1060
  if (dr->has_column) {
1014
- rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(dr->col));
1061
+ rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
1015
1062
  }
1016
1063
  rb_funcall2(dr->handler, ox_attr_id, 2, args);
1017
1064
  }
@@ -44,8 +44,8 @@ module Ox
44
44
  # def end_element(name); end
45
45
  #
46
46
  # Initializing @line in the initializer will cause that variable to be updated before each callback with the XML line
47
- # number. The same is true for the @column but it will be updated with the column in the XML file that is the end of
48
- # the element or node just read. Not this is the end not the start of the node, attribute, or text.
47
+ # number. The same is true for the @column but it will be updated with the column in the XML file that is the start of
48
+ # the element or node just read.
49
49
  class Sax
50
50
  # Create a new instance of the Sax handler class.
51
51
  def initialize()
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Ox
3
3
  # Current version of the module.
4
- VERSION = '1.9.0'
4
+ VERSION = '1.9.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ox
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.9.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-25 00:00:00.000000000 Z
12
+ date: 2013-02-27 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! "A fast XML parser and object serializer that uses only standard C
15
15
  lib.\n \nOptimized XML (Ox), as the name implies was written to provide