diff --git a/eeschema/sch_file_versions.h b/eeschema/sch_file_versions.h index 5fb7a7c1d8..b6e0a64c25 100644 --- a/eeschema/sch_file_versions.h +++ b/eeschema/sch_file_versions.h @@ -49,4 +49,6 @@ //#define SEXPR_SCHEMATIC_FILE_VERSION 20200608 // Add support for bus and junction properties. -#define SEXPR_SCHEMATIC_FILE_VERSION 20200618 +//#define SEXPR_SCHEMATIC_FILE_VERSION 20200618 // Disallow duplicate field ids. + +#define SEXPR_SCHEMATIC_FILE_VERSION 20200714 diff --git a/eeschema/sch_sexpr_parser.cpp b/eeschema/sch_sexpr_parser.cpp index 8c73ece607..46f85b757a 100644 --- a/eeschema/sch_sexpr_parser.cpp +++ b/eeschema/sch_sexpr_parser.cpp @@ -2166,6 +2166,25 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol() // the field positions are set. field = parseSchField( symbol.get() ); + if( m_requiredVersion <= 20200618 ) + { + // It would appear that at some point we allowed duplicate ids to slip + // through when writing files. We know this happens at least for sheets, + // so we add the patch for it here too (even though we don't know for + // sure if it's necessary). + // + // While no longer used, -1 is still a valid id for user fields and will + // get written out as the next unused number on save. + for( const SCH_FIELD& existing : symbol->GetFields() ) + { + if( existing.GetId() == field->GetId() ) + { + field->SetId( -1 ); + break; + } + } + } + // Set the default symbol reference prefix. if( field->GetId() == REFERENCE ) { @@ -2353,6 +2372,24 @@ SCH_SHEET* SCH_SEXPR_PARSER::parseSheet() field->SetId( SHEETFILENAME ); } + if( m_requiredVersion <= 20200618 ) + { + // It would appear the problem persists past 20200310, but this time with + // the earlier ids being re-used for later (user) fields. The easiest (and + // most complete) solution is to disallow multiple instances of the same id. + // + // While no longer used, -1 is still a valid id for user fields and will + // get written out as the next unused number on save. + for( const SCH_FIELD& existing : fields ) + { + if( existing.GetId() == field->GetId() ) + { + field->SetId( -1 ); + break; + } + } + } + fields.emplace_back( *field ); delete field; break;