@@ -731,14 +731,29 @@ readstat_error_t sav_parse_very_long_string_record(void *data, int count, sav_ct
731731 {
732732 varlookup_t * found = bsearch (temp_key , table , var_count , sizeof (varlookup_t ), & compare_key_varlookup );
733733 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+ }
737752 }
738753 }
739754 break ;
740755 case 4 :
741- #line 202 "src/spss/readstat_sav_parse.rl"
756+ #line 217 "src/spss/readstat_sav_parse.rl"
742757 {
743758 if ((* p ) != '\0' ) {
744759 unsigned char digit = (* p ) - '0' ;
@@ -751,10 +766,10 @@ readstat_error_t sav_parse_very_long_string_record(void *data, int count, sav_ct
751766 }
752767 break ;
753768 case 5 :
754- #line 213 "src/spss/readstat_sav_parse.rl"
769+ #line 228 "src/spss/readstat_sav_parse.rl"
755770 { temp_val = 0 ; }
756771 break ;
757- #line 758 "src/spss/readstat_sav_parse.c"
772+ #line 773 "src/spss/readstat_sav_parse.c"
758773 }
759774 }
760775
@@ -775,21 +790,36 @@ readstat_error_t sav_parse_very_long_string_record(void *data, int count, sav_ct
775790 {
776791 varlookup_t * found = bsearch (temp_key , table , var_count , sizeof (varlookup_t ), & compare_key_varlookup );
777792 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+ }
781811 }
782812 }
783813 break ;
784- #line 785 "src/spss/readstat_sav_parse.c"
814+ #line 815 "src/spss/readstat_sav_parse.c"
785815 }
786816 }
787817 }
788818
789819 _out : {}
790820 }
791821
792- #line 221 "src/spss/readstat_sav_parse.rl"
822+ #line 236 "src/spss/readstat_sav_parse.rl"
793823
794824
795825 if (cs < 11 || p != pe ) {
0 commit comments