@@ -731,14 +731,29 @@ readstat_error_t sav_parse_very_long_string_record(void *data, int count, sav_ct
731
731
{
732
732
varlookup_t * found = bsearch (temp_key , table , var_count , sizeof (varlookup_t ), & compare_key_varlookup );
733
733
if (found ) {
734
- ctx -> varinfo [found -> index ]-> string_length = temp_val ;
735
- ctx -> varinfo [found -> index ]-> write_format .width = temp_val ;
736
- ctx -> varinfo [found -> index ]-> print_format .width = temp_val ;
734
+ // See logic above; we need to apply this to all matching variables since ghost variable
735
+ // names may conflict with real variable names.
736
+ varlookup_t * first_match = found , * last_match = found ;
737
+ varlookup_t * iter_match = found - 1 ;
738
+ while (iter_match >= table && strcmp (iter_match -> name , temp_key ) == 0 ) {
739
+ first_match = iter_match ;
740
+ iter_match -- ;
741
+ }
742
+ iter_match = found + 1 ;
743
+ while (iter_match - table < var_count && strcmp (iter_match -> name , temp_key ) == 0 ) {
744
+ last_match = iter_match ;
745
+ iter_match ++ ;
746
+ }
747
+ for (iter_match = first_match ; iter_match <=last_match ; iter_match ++ ) {
748
+ ctx -> varinfo [iter_match -> index ]-> string_length = temp_val ;
749
+ ctx -> varinfo [iter_match -> index ]-> write_format .width = temp_val ;
750
+ ctx -> varinfo [iter_match -> index ]-> print_format .width = temp_val ;
751
+ }
737
752
}
738
753
}
739
754
break ;
740
755
case 4 :
741
- #line 202 "src/spss/readstat_sav_parse.rl"
756
+ #line 217 "src/spss/readstat_sav_parse.rl"
742
757
{
743
758
if ((* p ) != '\0' ) {
744
759
unsigned char digit = (* p ) - '0' ;
@@ -751,10 +766,10 @@ readstat_error_t sav_parse_very_long_string_record(void *data, int count, sav_ct
751
766
}
752
767
break ;
753
768
case 5 :
754
- #line 213 "src/spss/readstat_sav_parse.rl"
769
+ #line 228 "src/spss/readstat_sav_parse.rl"
755
770
{ temp_val = 0 ; }
756
771
break ;
757
- #line 758 "src/spss/readstat_sav_parse.c"
772
+ #line 773 "src/spss/readstat_sav_parse.c"
758
773
}
759
774
}
760
775
@@ -775,21 +790,36 @@ readstat_error_t sav_parse_very_long_string_record(void *data, int count, sav_ct
775
790
{
776
791
varlookup_t * found = bsearch (temp_key , table , var_count , sizeof (varlookup_t ), & compare_key_varlookup );
777
792
if (found ) {
778
- ctx -> varinfo [found -> index ]-> string_length = temp_val ;
779
- ctx -> varinfo [found -> index ]-> write_format .width = temp_val ;
780
- ctx -> varinfo [found -> index ]-> print_format .width = temp_val ;
793
+ // See logic above; we need to apply this to all matching variables since ghost variable
794
+ // names may conflict with real variable names.
795
+ varlookup_t * first_match = found , * last_match = found ;
796
+ varlookup_t * iter_match = found - 1 ;
797
+ while (iter_match >= table && strcmp (iter_match -> name , temp_key ) == 0 ) {
798
+ first_match = iter_match ;
799
+ iter_match -- ;
800
+ }
801
+ iter_match = found + 1 ;
802
+ while (iter_match - table < var_count && strcmp (iter_match -> name , temp_key ) == 0 ) {
803
+ last_match = iter_match ;
804
+ iter_match ++ ;
805
+ }
806
+ for (iter_match = first_match ; iter_match <=last_match ; iter_match ++ ) {
807
+ ctx -> varinfo [iter_match -> index ]-> string_length = temp_val ;
808
+ ctx -> varinfo [iter_match -> index ]-> write_format .width = temp_val ;
809
+ ctx -> varinfo [iter_match -> index ]-> print_format .width = temp_val ;
810
+ }
781
811
}
782
812
}
783
813
break ;
784
- #line 785 "src/spss/readstat_sav_parse.c"
814
+ #line 815 "src/spss/readstat_sav_parse.c"
785
815
}
786
816
}
787
817
}
788
818
789
819
_out : {}
790
820
}
791
821
792
- #line 221 "src/spss/readstat_sav_parse.rl"
822
+ #line 236 "src/spss/readstat_sav_parse.rl"
793
823
794
824
795
825
if (cs < 11 || p != pe ) {
0 commit comments