@@ -55,8 +55,12 @@ public class FileInfoContainer {
5555 private static final Pattern DIRECTIVE_HASH_PREFIXED = Pattern .compile ("^\\ s*//\\ s*#(.*)$" );
5656 private static final Pattern DIRECTIVE_TWO_DOLLARS_PREFIXED =
5757 Pattern .compile ("^\\ s*//\\ s*\\ $\\ $(.*)$" );
58+ private static final Pattern DIRECTIVE_TWO_DOLLARS_BLOCK_PREFIXED =
59+ Pattern .compile ("^\\ s*//\\ s*\\ $\\ $\" \" \" (.*)$" );
5860 private static final Pattern DIRECTIVE_SINGLE_DOLLAR_PREFIXED =
5961 Pattern .compile ("^\\ s*//\\ s*\\ $(.*)$" );
62+ private static final Pattern DIRECTIVE_SINGLE_DOLLAR_BLOCK_PREFIXED =
63+ Pattern .compile ("^\\ s*//\\ s*\\ $\" (.*)$" );
6064 private static final Pattern DIRECTIVE_TAIL_REMOVER = Pattern .compile ("\\ /\\ *\\ s*-\\ s*\\ *\\ /" );
6165 /**
6266 * The source file for the container
@@ -142,6 +146,23 @@ public static boolean isDoubleDollarPrefixed(final String line, final boolean al
142146 }
143147 }
144148
149+ public static boolean isDollarBlockPrefixed (final String line , final boolean allowedWhitespaces ) {
150+ if (allowedWhitespaces ) {
151+ return DIRECTIVE_SINGLE_DOLLAR_BLOCK_PREFIXED .matcher (line ).matches ();
152+ } else {
153+ return line .startsWith ("//$\" \" \" " );
154+ }
155+ }
156+
157+ public static boolean isDoubleDollarBlockPrefixed (final String line ,
158+ final boolean allowedWhitespaces ) {
159+ if (allowedWhitespaces ) {
160+ return DIRECTIVE_SINGLE_DOLLAR_BLOCK_PREFIXED .matcher (line ).matches ();
161+ } else {
162+ return line .startsWith ("//$$\" \" \" " );
163+ }
164+ }
165+
145166 /**
146167 * Check that text line starts with single dollar chars
147168 * @param line text line to be examined, must not be null
@@ -318,10 +339,12 @@ private String extractHashPrefixedDirective(final String line,
318339
319340
320341 private String extractDoubleDollarPrefixedDirective (final String line ,
342+ final boolean block ,
321343 final PreprocessorContext context ) {
322344 String tail ;
323345 if (context .isAllowWhitespaces ()) {
324- final Matcher matcher = DIRECTIVE_TWO_DOLLARS_PREFIXED .matcher (line );
346+ final Matcher matcher = block ? DIRECTIVE_TWO_DOLLARS_BLOCK_PREFIXED .matcher (line ) :
347+ DIRECTIVE_TWO_DOLLARS_PREFIXED .matcher (line );
325348 if (matcher .find ()) {
326349 tail = matcher .group (1 );
327350 } else {
@@ -330,7 +353,11 @@ private String extractDoubleDollarPrefixedDirective(final String line,
330353 ')' );
331354 }
332355 } else {
333- tail = PreprocessorUtils .extractTail ("//$$" , line );
356+ if (block ) {
357+ tail = PreprocessorUtils .extractTail ("//$$\" \" \" " , line );
358+ } else {
359+ tail = PreprocessorUtils .extractTail ("//$$" , line );
360+ }
334361 }
335362
336363 if (context .isPreserveIndents ()) {
@@ -341,10 +368,12 @@ private String extractDoubleDollarPrefixedDirective(final String line,
341368
342369
343370 private String extractSingleDollarPrefixedDirective (final String line ,
371+ final boolean block ,
344372 final PreprocessorContext context ) {
345373 String tail ;
346374 if (context .isAllowWhitespaces ()) {
347- final Matcher matcher = DIRECTIVE_SINGLE_DOLLAR_PREFIXED .matcher (line );
375+ final Matcher matcher = block ? DIRECTIVE_SINGLE_DOLLAR_BLOCK_PREFIXED .matcher (line ) :
376+ DIRECTIVE_SINGLE_DOLLAR_PREFIXED .matcher (line );
348377 if (matcher .find ()) {
349378 tail = matcher .group (1 );
350379 } else {
@@ -353,7 +382,11 @@ private String extractSingleDollarPrefixedDirective(final String line,
353382 ')' );
354383 }
355384 } else {
356- tail = PreprocessorUtils .extractTail ("//$" , line );
385+ if (block ) {
386+ tail = PreprocessorUtils .extractTail ("//$\" \" \" " , line );
387+ } else {
388+ tail = PreprocessorUtils .extractTail ("//$" , line );
389+ }
357390 }
358391
359392 if (context .isPreserveIndents ()) {
@@ -362,6 +395,16 @@ private String extractSingleDollarPrefixedDirective(final String line,
362395 return tail ;
363396 }
364397
398+ private void flushTextBufferForRemovedComments (final StringBuilder text ,
399+ final ResetablePrinter resetablePrinter ,
400+ final PreprocessorContext context )
401+ throws IOException {
402+ if (text .length () > 0 ) {
403+ resetablePrinter .print (text .toString ());
404+ text .setLength (0 );
405+ }
406+ }
407+
365408 /**
366409 * Preprocess file, NB! it doesn't clear local variables automatically for cloned contexts
367410 *
@@ -388,9 +431,13 @@ public PreprocessingState preprocessFile(final PreprocessingState state,
388431 String leftTrimmedString = null ;
389432
390433 TextFileDataContainer lastTextFileDataContainer = null ;
434+ final StringBuilder textBlockBuffer = new StringBuilder ();
391435
392436 try {
393437 while (!Thread .currentThread ().isInterrupted ()) {
438+ final ResetablePrinter thePrinter =
439+ requireNonNull (preprocessingState .getPrinter (), "Printer must be defined" );
440+
394441 String rawString = preprocessingState .nextLine ();
395442 final boolean presentedNextLine = preprocessingState .hasReadLineNextLineInEnd ();
396443
@@ -410,6 +457,7 @@ public PreprocessingState preprocessFile(final PreprocessingState state,
410457 }
411458
412459 if (rawString == null ) {
460+ this .flushTextBufferForRemovedComments (textBlockBuffer , thePrinter , context );
413461 lastTextFileDataContainer = preprocessingState .popTextContainer ();
414462 if (preprocessingState .isIncludeStackEmpty ()) {
415463 break ;
@@ -434,10 +482,10 @@ public PreprocessingState preprocessFile(final PreprocessingState state,
434482 }
435483
436484 String stringToBeProcessed = leftTrimmedString ;
437-
438485 final boolean doPrintLn = presentedNextLine || !context .isCareForLastEol ();
439486
440487 if (isHashPrefixed (stringToBeProcessed , context )) {
488+ this .flushTextBufferForRemovedComments (textBlockBuffer , thePrinter , context );
441489 final String extractedDirective =
442490 extractHashPrefixedDirective (stringToBeProcessed , context );
443491 switch (processDirective (preprocessingState , extractedDirective , context , false )) {
@@ -447,8 +495,6 @@ public PreprocessingState preprocessFile(final PreprocessingState state,
447495 final String text = stringPrefix +
448496 AbstractDirectiveHandler .PREFIX_FOR_KEEPING_LINES_PROCESSED_DIRECTIVES +
449497 extractedDirective ;
450- final ResetablePrinter thePrinter =
451- requireNonNull (preprocessingState .getPrinter ());
452498 if (doPrintLn ) {
453499 thePrinter .println (text , context .getEol ());
454500 } else {
@@ -461,8 +507,6 @@ public PreprocessingState preprocessFile(final PreprocessingState state,
461507 final String text = stringPrefix +
462508 AbstractDirectiveHandler .PREFIX_FOR_KEEPING_LINES_PROCESSED_DIRECTIVES +
463509 extractedDirective ;
464- final ResetablePrinter thePrinter =
465- requireNonNull (preprocessingState .getPrinter ());
466510 if (doPrintLn ) {
467511 thePrinter .println (text , context .getEol ());
468512 } else {
@@ -475,7 +519,6 @@ public PreprocessingState preprocessFile(final PreprocessingState state,
475519 }
476520 }
477521
478- final ResetablePrinter thePrinter = requireNonNull (preprocessingState .getPrinter ());
479522 if (preprocessingState .isDirectiveCanBeProcessed () &&
480523 !preprocessingState .getPreprocessingFlags ()
481524 .contains (PreprocessingFlag .TEXT_OUTPUT_DISABLED )) {
@@ -487,26 +530,45 @@ public PreprocessingState preprocessFile(final PreprocessingState state,
487530
488531 if (startsWithTwoDollars ) {
489532 // Output the tail of the string to the output stream without comments and macroses
490- thePrinter .print (stringPrefix );
491- final String text = extractDoubleDollarPrefixedDirective (leftTrimmedString , context );
492- if (doPrintLn ) {
493- thePrinter .println (text , context .getEol ());
533+ final String text =
534+ extractDoubleDollarPrefixedDirective (leftTrimmedString , false , context );
535+ if (isDoubleDollarBlockPrefixed (leftTrimmedString , context .isAllowWhitespaces ())) {
536+ textBlockBuffer .append (
537+ extractDoubleDollarPrefixedDirective (leftTrimmedString , true , context ));
538+ if (doPrintLn ) {
539+ textBlockBuffer .append (context .getEol ());
540+ }
494541 } else {
495- thePrinter .print (text );
542+ this .flushTextBufferForRemovedComments (textBlockBuffer , thePrinter , context );
543+ textBlockBuffer .append (stringPrefix ).append (text );
544+ if (doPrintLn ) {
545+ textBlockBuffer .append (context .getEol ());
546+ }
547+ this .flushTextBufferForRemovedComments (textBlockBuffer , thePrinter , context );
496548 }
497549 } else if (isSingleDollarPrefixed (stringToBeProcessed , context .isAllowWhitespaces ())) {
498550 // Output the tail of the string to the output stream without comments
499- thePrinter .print (stringPrefix );
500-
501- final String text = extractSingleDollarPrefixedDirective (stringToBeProcessed , context );
551+ final String text =
552+ extractSingleDollarPrefixedDirective (stringToBeProcessed , false , context );
502553
503- if (doPrintLn ) {
504- thePrinter .println (text , context .getEol ());
554+ if (isDollarBlockPrefixed (stringToBeProcessed , context .isAllowWhitespaces ())) {
555+ textBlockBuffer .append (
556+ extractSingleDollarPrefixedDirective (stringToBeProcessed , true , context ));
557+ if (doPrintLn ) {
558+ textBlockBuffer .append (context .getEol ());
559+ }
505560 } else {
506- thePrinter .print (text );
561+ this .flushTextBufferForRemovedComments (textBlockBuffer , thePrinter , context );
562+ textBlockBuffer .append (stringPrefix ).append (text );
563+ if (doPrintLn ) {
564+ textBlockBuffer .append (context .getEol ());
565+ }
566+ this .flushTextBufferForRemovedComments (textBlockBuffer , thePrinter , context );
507567 }
508568 } else {
509569 // Just string
570+ this .flushTextBufferForRemovedComments (textBlockBuffer , thePrinter , context );
571+
510572 final String strToOut = findTailRemover (stringToBeProcessed , context );
511573
512574 if (preprocessingState .getPreprocessingFlags ()
@@ -524,6 +586,7 @@ public PreprocessingState preprocessFile(final PreprocessingState state,
524586 }
525587 }
526588 } else if (context .isKeepLines ()) {
589+ flushTextBufferForRemovedComments (textBlockBuffer , thePrinter , context );
527590 final String text = AbstractDirectiveHandler .PREFIX_FOR_KEEPING_LINES + rawString ;
528591 if (doPrintLn ) {
529592 thePrinter .println (text , context .getEol ());
0 commit comments