@@ -461,38 +461,35 @@ static void
461461print_class (FILE * f , PCRE2_SPTR code , const uint8_t * char_lists_end , BOOL utf ,
462462 const char * before , const char * after )
463463{
464- BOOL printmap , invertmap ;
464+ BOOL printmap , negated ;
465465PCRE2_SPTR ccode ;
466466int i ;
467467
468- fprintf (f , "%s[" , before );
469-
470- /* Negative XCLASS has an inverted map whereas the original opcodes have
471- already done the inversion. */
472- invertmap = FALSE;
468+ /* Negative XCLASS and NCLASS both have a bitmap indicating which characters
469+ are accepted. For clarity we print this inverted and prefixed by "^". */
473470if (* code == OP_XCLASS )
474471 {
475472 ccode = code + LINK_SIZE + 1 ;
476473 printmap = (* ccode & XCL_MAP ) != 0 ;
477- if ((* ccode & XCL_NOT ) != 0 )
478- {
479- invertmap = TRUE;
480- fprintf (f , "^" );
481- }
474+ negated = (* ccode & XCL_NOT ) != 0 ;
482475 ccode ++ ;
483476 }
484477else /* CLASS or NCLASS */
485478 {
486479 printmap = TRUE;
480+ negated = * code == OP_NCLASS ;
487481 ccode = code + 1 ;
488482 }
489483
484+ fprintf (f , "%s[%s" , before , negated ? "^" : "" );
485+
490486/* Print a bit map */
491487if (printmap )
492488 {
489+ BOOL first = TRUE;
493490 uint8_t inverted_map [32 ];
494491 const uint8_t * map = (const uint8_t * )ccode ;
495- if (invertmap )
492+ if (negated )
496493 {
497494 /* Using 255 ^ instead of ~ avoids clang sanitize warning. */
498495 for (i = 0 ; i < 32 ; i ++ ) inverted_map [i ] = 255 ^ map [i ];
@@ -505,13 +502,15 @@ if (printmap)
505502 int j ;
506503 for (j = i + 1 ; j < 256 ; j ++ )
507504 if ((map [j /8 ] & (1u << (j & 7 ))) == 0 ) break ;
508- if (i == '-' || i == ']' ) fprintf (f , "\\" );
505+ if (i == '-' || i == '\\' || i == ']' || (first && i == '^' ))
506+ fprintf (f , "\\" );
509507 if (PRINTABLE (i )) fprintf (f , "%c" , i );
510508 else fprintf (f , "\\x%02x" , i );
509+ first = FALSE;
511510 if (-- j > i )
512511 {
513512 if (j != i + 1 ) fprintf (f , "-" );
514- if (j == '-' || j == ']' ) fprintf (f , "\\" );
513+ if (j == '-' || j == '\\' || j == ' ]' ) fprintf (f , "\\" );
515514 if (PRINTABLE (j )) fprintf (f , "%c" , j );
516515 else fprintf (f , "\\x%02x" , j );
517516 }
@@ -584,7 +583,7 @@ if (*code == OP_XCLASS)
584583 }
585584
586585/* Indicate a non-UTF class which was created by negation */
587- fprintf (f , "]%s%s" , ( * code == OP_NCLASS )? " (neg)" : " " , after );
586+ fprintf (f , "]%s" , after );
588587}
589588
590589
@@ -846,7 +845,7 @@ for(;;)
846845 case OP_NOT :
847846 fprintf (f , " %s [^" , flag );
848847 extra = print_char (f , code + 1 , utf );
849- fprintf (f , "]" );
848+ fprintf (f , "] (not) " );
850849 break ;
851850
852851 case OP_NOTSTARI :
@@ -872,7 +871,7 @@ for(;;)
872871 case OP_NOTPOSQUERY :
873872 fprintf (f , " %s [^" , flag );
874873 extra = print_char (f , code + 1 , utf );
875- fprintf (f , "]%s" , OP_names [* code ]);
874+ fprintf (f , "]%s (not) " , OP_names [* code ]);
876875 break ;
877876
878877 case OP_NOTEXACTI :
@@ -894,6 +893,7 @@ for(;;)
894893 if (* code == OP_NOTMINUPTO || * code == OP_NOTMINUPTOI ) fprintf (f , "?" );
895894 else
896895 if (* code == OP_NOTPOSUPTO || * code == OP_NOTPOSUPTOI ) fprintf (f , "+" );
896+ fprintf (f , " (not)" );
897897 break ;
898898
899899 case OP_RECURSE :
0 commit comments