@@ -310,7 +310,8 @@ public static void Run()
310310 var sourceCode = File . ReadAllText ( csFile ) ;
311311 var processedCode = ProcessFile ( sourceCode , definedSymbols ) ;
312312
313- // Remove empty/whitespace lines and normalize newlines to \r\n
313+ // Remove empty conditional blocks, empty lines, and normalize newlines to \r\n
314+ processedCode = RemoveEmptyConditionalBlocks ( processedCode ) ;
314315 processedCode = RemoveEmptyLines ( processedCode ) ;
315316 processedCode = NormalizeNewlines ( processedCode ) ;
316317
@@ -329,6 +330,75 @@ public static string RemoveEmptyLines(string text)
329330 return string . Join ( "\n " , nonEmptyLines ) ;
330331 }
331332
333+ /// <summary>
334+ /// Removes empty conditional blocks (e.g., #if X followed directly by #endif with no content).
335+ /// Handles nested cases by repeatedly removing until no more empty blocks exist.
336+ /// </summary>
337+ public static string RemoveEmptyConditionalBlocks ( string text )
338+ {
339+ var lines = text . Split ( '\n ' ) . Select ( l => l . TrimEnd ( '\r ' ) ) . ToList ( ) ;
340+ bool changed ;
341+
342+ do
343+ {
344+ changed = false ;
345+ var result = new List < string > ( ) ;
346+
347+ for ( var i = 0 ; i < lines . Count ; i ++ )
348+ {
349+ var line = lines [ i ] ;
350+ var trimmed = line . TrimStart ( ) ;
351+
352+ // Check if this is an #if or #elif that is immediately followed by #endif, #else, or #elif
353+ if ( trimmed . StartsWith ( "#if " ) || trimmed . StartsWith ( "#if(" ) ||
354+ trimmed . StartsWith ( "#elif " ) || trimmed . StartsWith ( "#elif(" ) )
355+ {
356+ // Look ahead to find the matching #endif, #else, or #elif
357+ if ( i + 1 < lines . Count )
358+ {
359+ var nextTrimmed = lines [ i + 1 ] . TrimStart ( ) ;
360+ if ( nextTrimmed == "#endif" || nextTrimmed == "#else" ||
361+ nextTrimmed . StartsWith ( "#elif " ) || nextTrimmed . StartsWith ( "#elif(" ) )
362+ {
363+ // This #if/#elif has no content, skip it
364+ // If next is #endif, skip both
365+ if ( nextTrimmed == "#endif" )
366+ {
367+ i ++ ; // Skip the #endif too
368+ changed = true ;
369+ continue ;
370+ }
371+ // If next is #else or #elif, just skip this #if/#elif line
372+ changed = true ;
373+ continue ;
374+ }
375+ }
376+ }
377+
378+ // Check if this is an #else immediately followed by #endif
379+ if ( trimmed == "#else" )
380+ {
381+ if ( i + 1 < lines . Count )
382+ {
383+ var nextTrimmed = lines [ i + 1 ] . TrimStart ( ) ;
384+ if ( nextTrimmed == "#endif" )
385+ {
386+ // Empty #else block, skip just the #else (keep the #endif to close the #if)
387+ changed = true ;
388+ continue ;
389+ }
390+ }
391+ }
392+
393+ result . Add ( line ) ;
394+ }
395+
396+ lines = result ;
397+ } while ( changed ) ;
398+
399+ return string . Join ( "\n " , lines ) ;
400+ }
401+
332402 /// <summary>
333403 /// Normalizes all newlines to \r\n.
334404 /// </summary>
@@ -374,6 +444,19 @@ public string Process()
374444 var state = new Stack < ConditionalState > ( ) ;
375445 var i = 0 ;
376446
447+ // Helper to check if we're inside an outer False branch
448+ bool IsInsideFalseBranch ( )
449+ {
450+ foreach ( var s in state )
451+ {
452+ if ( ! s . BranchTaken )
453+ {
454+ return true ;
455+ }
456+ }
457+ return false ;
458+ }
459+
377460 while ( i < _lines . Count )
378461 {
379462 var line = _lines [ i ] ;
@@ -384,6 +467,9 @@ public string Process()
384467 var expression = ExtractExpression ( trimmed , "#if" ) ;
385468 var evalResult = EvaluateExpression ( expression ) ;
386469
470+ // Check if we're inside a False branch BEFORE pushing the new state
471+ var insideFalseBranch = IsInsideFalseBranch ( ) ;
472+
387473 state . Push ( new ConditionalState
388474 {
389475 OriginalExpression = expression ,
@@ -392,10 +478,11 @@ public string Process()
392478 BranchTaken = evalResult == TriState . True || evalResult == TriState . Unknown ,
393479 HasElse = false ,
394480 ElseEvalResult = null ,
395- Line = i
481+ Line = i ,
482+ InsideExcludedBranch = insideFalseBranch
396483 } ) ;
397484
398- if ( evalResult == TriState . Unknown )
485+ if ( evalResult == TriState . Unknown && ! insideFalseBranch )
399486 {
400487 // Keep the directive but with simplified expression
401488 var simplified = SimplifyExpression ( expression ) ;
@@ -420,20 +507,22 @@ public string Process()
420507 {
421508 // Previous branch was taken, this elif becomes else-false
422509 current . BranchTaken = false ;
423- if ( current . EvalResult == TriState . Unknown )
510+ if ( current . EvalResult == TriState . Unknown && evalResult == TriState . Unknown && ! current . InsideExcludedBranch )
424511 {
512+ // Only output elif if it has unknown symbols and we're not inside an excluded branch
425513 var simplified = SimplifyExpression ( expression ) ;
426514 var indent = line . Substring ( 0 , line . Length - trimmed . Length ) ;
427515 _outputLines . Add ( $ "{ indent } #elif { simplified } ") ;
428516 }
517+ // If elif condition is definitely true or false, don't output it
429518 }
430519 else if ( current . EvalResult == TriState . False )
431520 {
432521 // Previous branch was not taken, check this one
433522 current . EvalResult = evalResult ;
434523 current . BranchTaken = evalResult == TriState . True || evalResult == TriState . Unknown ;
435524
436- if ( evalResult == TriState . Unknown )
525+ if ( evalResult == TriState . Unknown && ! current . InsideExcludedBranch )
437526 {
438527 var simplified = SimplifyExpression ( expression ) ;
439528 var indent = line . Substring ( 0 , line . Length - trimmed . Length ) ;
@@ -442,11 +531,14 @@ public string Process()
442531 }
443532 else
444533 {
445- // Unknown state - keep the elif
446- var simplified = SimplifyExpression ( expression ) ;
447- var indent = line . Substring ( 0 , line . Length - trimmed . Length ) ;
448- _outputLines . Add ( $ "{ indent } #elif { simplified } ") ;
534+ // Unknown state - keep the elif only if it has unknown symbols
449535 current . BranchTaken = evalResult == TriState . True || evalResult == TriState . Unknown ;
536+ if ( evalResult == TriState . Unknown && ! current . InsideExcludedBranch )
537+ {
538+ var simplified = SimplifyExpression ( expression ) ;
539+ var indent = line . Substring ( 0 , line . Length - trimmed . Length ) ;
540+ _outputLines . Add ( $ "{ indent } #elif { simplified } ") ;
541+ }
450542 }
451543 }
452544 else if ( trimmed == "#else" )
@@ -473,10 +565,13 @@ public string Process()
473565 }
474566 else
475567 {
476- // Unknown - keep the else
568+ // Unknown - keep the else only if not inside an excluded branch
477569 current . ElseEvalResult = TriState . Unknown ;
478570 current . BranchTaken = true ;
479- _outputLines . Add ( line ) ;
571+ if ( ! current . InsideExcludedBranch )
572+ {
573+ _outputLines . Add ( line ) ;
574+ }
480575 }
481576 }
482577 else if ( trimmed == "#endif" )
@@ -488,9 +583,10 @@ public string Process()
488583
489584 var current = state . Pop ( ) ;
490585
491- // Only output #endif if we had an unknown condition
492- if ( current . EvalResult == TriState . Unknown ||
493- ( current . HasElse && current . ElseEvalResult == TriState . Unknown ) )
586+ // Only output #endif if we had an unknown condition and not inside an excluded branch
587+ if ( ! current . InsideExcludedBranch &&
588+ ( current . EvalResult == TriState . Unknown ||
589+ ( current . HasElse && current . ElseEvalResult == TriState . Unknown ) ) )
494590 {
495591 _outputLines . Add ( line ) ;
496592 }
@@ -554,6 +650,7 @@ class ConditionalState
554650 public bool HasElse { get ; set ; }
555651 public TriState ? ElseEvalResult { get ; set ; }
556652 public int Line { get ; init ; }
653+ public bool InsideExcludedBranch { get ; init ; }
557654 }
558655}
559656
0 commit comments