From 2bf3cfb1edb5103bbb2cd502f8a2d6ee12efc548 Mon Sep 17 00:00:00 2001 From: Magnus Lundmark Date: Fri, 14 Nov 2025 15:33:19 +0100 Subject: [PATCH] almost working, just need to not evaluate to uuid in escaped expressions --- .gitignore | 1 + common/common.cpp | 73 +++++++++++++++++++++++++++++++------- eeschema/sch_field.cpp | 28 +++++++-------- eeschema/sch_label.cpp | 20 +++++------ eeschema/sch_tablecell.cpp | 22 ++++++------ eeschema/sch_text.cpp | 24 ++++++------- eeschema/sch_textbox.cpp | 20 +++++------ 7 files changed, 114 insertions(+), 74 deletions(-) diff --git a/.gitignore b/.gitignore index 7d7b915f99..9dedaa2e56 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ boost_root /Build* /build* /cmake-build-* +texteval/ common/fp_lib_table_keywords.cpp common/drc_rules_keywords.cpp common/drc_rules_lexer.h diff --git a/common/common.cpp b/common/common.cpp index 7670dec273..6539acbd7b 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -83,6 +83,51 @@ wxString ExpandTextVars( const wxString& aSource, const std::function 0 ) + { + if( aSource[i] == '{' ) + braceCount++; + else if( aSource[i] == '}' ) + braceCount--; + + newbuf.append( aSource[i] ); + i++; + } + i--; // Back up one since the for loop will increment + continue; + } + else if( i + 10 <= sourceLen && aSource.Mid( i, 10 ) == wxT( "<< 0 ) + { + if( aSource[i] == '{' ) + braceCount++; + else if( aSource[i] == '}' ) + braceCount--; + + newbuf.append( aSource[i] ); + i++; + } + i--; // Back up one since the for loop will increment + continue; + } + // Handle escaped variable references: \${...} or \@{...} // Replace with escape markers that won't be expanded by multi-pass loops // The markers will be converted back to ${...} or @{...} only at the final display stage @@ -90,15 +135,15 @@ wxString ExpandTextVars( const wxString& aSource, const std::function 0; ++i ) { @@ -107,10 +152,8 @@ wxString ExpandTextVars( const wxString& aSource, const std::function 0 ) // Don't append the final closing brace - newbuf.append( aSource[i] ); + newbuf.append( aSource[i] ); } - newbuf.append( wxT( ">>>" ) ); // Append closing delimiter i--; // Adjust because loop will increment continue; } @@ -213,13 +256,19 @@ wxString ResolveTextVars( const wxString& aSource, const std::function libSymbolResolver = [&]( wxString* token ) -> bool { LIB_SYMBOL* symbol = static_cast( m_parent ); - return symbol->ResolveTextVar( token, aDepth + 1 ); + return symbol->ResolveTextVar( token, depth + 1 ); }; std::function symbolResolver = [&]( wxString* token ) -> bool { SCH_SYMBOL* symbol = static_cast( m_parent ); - return symbol->ResolveTextVar( aPath, token, aDepth + 1 ); + return symbol->ResolveTextVar( aPath, token, depth + 1 ); }; std::function schematicResolver = [&]( wxString* token ) -> bool @@ -208,7 +211,7 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT return false; if( SCHEMATIC* schematic = Schematic() ) - return schematic->ResolveTextVar( aPath, token, aDepth + 1 ); + return schematic->ResolveTextVar( aPath, token, depth + 1 ); return false; }; @@ -224,10 +227,10 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT SCH_SHEET_PATH path = *aPath; path.push_back( sheet ); - bool retval = sheet->ResolveTextVar( &path, token, aDepth + 1 ); + bool retval = sheet->ResolveTextVar( &path, token, depth + 1 ); if( schematic ) - retval |= schematic->ResolveTextVar( &path, token, aDepth + 1 ); + retval |= schematic->ResolveTextVar( &path, token, depth + 1 ); return retval; }; @@ -238,7 +241,7 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT return false; SCH_LABEL_BASE* label = static_cast( m_parent ); - return label->ResolveTextVar( aPath, token, aDepth + 1 ); + return label->ResolveTextVar( aPath, token, depth + 1 ); }; wxString variantName; @@ -276,20 +279,15 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT return resolved; }; - text = ResolveTextVars( text, &fieldResolver, aDepth ); + text = ResolveTextVars( text, &fieldResolver, depth ); } if( m_id == FIELD_T::SHEET_FILENAME && aAllowExtraText && !IsNameShown() ) text = _( "File:" ) + wxS( " " ) + text; - // Convert escape markers back to literals only at the top level (aDepth == 0) - // This prevents re-expansion when text is used in nested CELL() references - if( aDepth == 0 ) - { - text.Replace( wxT( "<<>>" ), wxT( "}" ) ); - } + // Convert escape markers back to literals (safety fallback - already done in ResolveTextVars) + text.Replace( wxT( "<< textResolver = [&]( wxString* token ) -> bool { - return ResolveTextVar( aPath, token, aDepth + 1 ); + return ResolveTextVar( aPath, token, depth + 1 ); }; - wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth ); + wxString text = EDA_TEXT::GetShownText( aAllowExtraText, depth ); if( HasTextVars() ) - text = ResolveTextVars( text, &textResolver, aDepth ); + text = ResolveTextVars( text, &textResolver, depth ); - // Convert escape markers back to literals only at the top level (aDepth == 0) - // This prevents re-expansion when text is used in nested CELL() references - if( aDepth == 0 ) - { - text.Replace( wxT( "<<>>" ), wxT( "}" ) ); - } + // Convert escape markers back to literals (safety fallback - already done in ResolveTextVars) + text.Replace( wxT( "<<GetShownText( aSettings, aPath, false, aDepth + 1 ); + *token = targetCell->GetShownText( aSettings, aPath, false, depth + 1 ); return true; } else @@ -260,17 +263,17 @@ wxString SCH_TABLECELL::GetShownText( const RENDER_SETTINGS* aSettings, const SC // Fall back to sheet variables if( sheet ) { - if( sheet->ResolveTextVar( aPath, token, aDepth + 1 ) ) + if( sheet->ResolveTextVar( aPath, token, depth + 1 ) ) return true; } return false; }; - wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth ); + wxString text = EDA_TEXT::GetShownText( aAllowExtraText, depth ); if( HasTextVars() ) - text = ResolveTextVars( text, &tableCellResolver, aDepth ); + text = ResolveTextVars( text, &tableCellResolver, depth ); VECTOR2I size = GetEnd() - GetStart(); int colWidth; @@ -283,14 +286,9 @@ wxString SCH_TABLECELL::GetShownText( const RENDER_SETTINGS* aSettings, const SC GetDrawFont( aSettings ) ->LinebreakText( text, colWidth, GetTextSize(), GetEffectiveTextPenWidth(), IsBold(), IsItalic() ); - // Convert escape markers back to literals only at the top level (aDepth == 0) - // This prevents re-expansion when text is used in nested CELL() references - if( aDepth == 0 ) - { - text.Replace( wxT( "<<>>" ), wxT( "}" ) ); - } + // Convert escape markers back to literals (safety fallback - already done in ResolveTextVars) + text.Replace( wxT( "<<( m_parent ) ) { - if( sch_symbol->ResolveTextVar( aPath, token, aDepth + 1 ) ) + if( sch_symbol->ResolveTextVar( aPath, token, depth + 1 ) ) return true; } else if( LIB_SYMBOL* lib_symbol = dynamic_cast( m_parent ) ) { - if( lib_symbol->ResolveTextVar( token, aDepth + 1 ) ) + if( lib_symbol->ResolveTextVar( token, depth + 1 ) ) return true; } if( sheet ) { - if( sheet->ResolveTextVar( aPath, token, aDepth + 1 ) ) + if( sheet->ResolveTextVar( aPath, token, depth + 1 ) ) return true; } return false; }; - wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth ); + wxString text = EDA_TEXT::GetShownText( aAllowExtraText, depth ); if( HasTextVars() ) - text = ResolveTextVars( text, &textResolver, aDepth ); + text = ResolveTextVars( text, &textResolver, depth ); - // Convert escape markers back to literals only at the top level (aDepth == 0) - // This prevents re-expansion when text is used in nested CELL() references - if( aDepth == 0 ) - { - text.Replace( wxT( "<<>>" ), wxT( "}" ) ); - } + // Convert escape markers back to literals (safety fallback - already done in ResolveTextVars) + text.Replace( wxT( "<<ResolveTextVar( aPath, token, aDepth + 1 ) ) + if( sheet->ResolveTextVar( aPath, token, depth + 1 ) ) return true; } return false; }; - wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth ); + wxString text = EDA_TEXT::GetShownText( aAllowExtraText, depth ); if( HasTextVars() ) - text = ResolveTextVars( text, &textResolver, aDepth ); + text = ResolveTextVars( text, &textResolver, depth ); VECTOR2I size = GetEnd() - GetStart(); int colWidth; @@ -272,14 +275,9 @@ wxString SCH_TEXTBOX::GetShownText( const RENDER_SETTINGS* aSettings, const SCH_ GetDrawFont( aSettings ) ->LinebreakText( text, colWidth, GetTextSize(), GetEffectiveTextPenWidth(), IsBold(), IsItalic() ); - // Convert escape markers back to literals only at the top level (aDepth == 0) - // This prevents re-expansion when text is used in nested CELL() references - if( aDepth == 0 ) - { - text.Replace( wxT( "<<>>" ), wxT( "}" ) ); - } + // Convert escape markers back to literals (safety fallback - already done in ResolveTextVars) + text.Replace( wxT( "<<