@@ -463,38 +463,35 @@ static void
463463print_class (FILE * f , PCRE2_SPTR code , const uint8_t * char_lists_end , BOOL utf ,
464464 const char * before , const char * after )
465465{
466- BOOL printmap , invertmap ;
466+ BOOL printmap , negated ;
467467PCRE2_SPTR ccode ;
468468int i ;
469469
470- fprintf (f , "%s[" , before );
471-
472- /* Negative XCLASS has an inverted map whereas the original opcodes have
473- already done the inversion. */
474- invertmap = FALSE;
470+ /* Negative XCLASS and NCLASS both have a bitmap indicating which characters
471+ are accepted. For clarity we print this inverted and prefixed by "^". */
475472if (* code == OP_XCLASS )
476473 {
477474 ccode = code + LINK_SIZE + 1 ;
478475 printmap = (* ccode & XCL_MAP ) != 0 ;
479- if ((* ccode & XCL_NOT ) != 0 )
480- {
481- invertmap = TRUE;
482- fprintf (f , "^" );
483- }
476+ negated = (* ccode & XCL_NOT ) != 0 ;
484477 ccode ++ ;
485478 }
486479else /* CLASS or NCLASS */
487480 {
488481 printmap = TRUE;
482+ negated = * code == OP_NCLASS ;
489483 ccode = code + 1 ;
490484 }
491485
486+ fprintf (f , "%s[%s" , before , negated ? "^" : "" );
487+
492488/* Print a bit map */
493489if (printmap )
494490 {
491+ BOOL first = TRUE;
495492 uint8_t inverted_map [32 ];
496493 const uint8_t * map = (const uint8_t * )ccode ;
497- if (invertmap )
494+ if (negated )
498495 {
499496 /* Using 255 ^ instead of ~ avoids clang sanitize warning. */
500497 for (i = 0 ; i < 32 ; i ++ ) inverted_map [i ] = 255 ^ map [i ];
@@ -507,13 +504,15 @@ if (printmap)
507504 int j ;
508505 for (j = i + 1 ; j < 256 ; j ++ )
509506 if ((map [j /8 ] & (1u << (j & 7 ))) == 0 ) break ;
510- if (i == '-' || i == ']' ) fprintf (f , "\\" );
507+ if (i == '-' || i == '\\' || i == ']' || (first && i == '^' ))
508+ fprintf (f , "\\" );
511509 if (PRINTABLE (i )) fprintf (f , "%c" , i );
512510 else fprintf (f , "\\x%02x" , i );
511+ first = FALSE;
513512 if (-- j > i )
514513 {
515514 if (j != i + 1 ) fprintf (f , "-" );
516- if (j == '-' || j == ']' ) fprintf (f , "\\" );
515+ if (j == '-' || j == '\\' || j == ' ]' ) fprintf (f , "\\" );
517516 if (PRINTABLE (j )) fprintf (f , "%c" , j );
518517 else fprintf (f , "\\x%02x" , j );
519518 }
@@ -580,7 +579,7 @@ if (*code == OP_XCLASS)
580579 }
581580
582581/* Indicate a non-UTF class which was created by negation */
583- fprintf (f , "]%s%s" , ( * code == OP_NCLASS )? " (neg)" : " " , after );
582+ fprintf (f , "]%s" , after );
584583}
585584
586585
@@ -842,7 +841,7 @@ for(;;)
842841 case OP_NOT :
843842 fprintf (f , " %s [^" , flag );
844843 extra = print_char (f , code + 1 , utf );
845- fprintf (f , "]" );
844+ fprintf (f , "] (not) " );
846845 break ;
847846
848847 case OP_NOTSTARI :
@@ -868,7 +867,7 @@ for(;;)
868867 case OP_NOTPOSQUERY :
869868 fprintf (f , " %s [^" , flag );
870869 extra = print_char (f , code + 1 , utf );
871- fprintf (f , "]%s" , OP_names [* code ]);
870+ fprintf (f , "]%s (not) " , OP_names [* code ]);
872871 break ;
873872
874873 case OP_NOTEXACTI :
@@ -890,6 +889,7 @@ for(;;)
890889 if (* code == OP_NOTMINUPTO || * code == OP_NOTMINUPTOI ) fprintf (f , "?" );
891890 else
892891 if (* code == OP_NOTPOSUPTO || * code == OP_NOTPOSUPTOI ) fprintf (f , "+" );
892+ fprintf (f , " (not)" );
893893 break ;
894894
895895 case OP_RECURSE :
0 commit comments