@@ -591,7 +591,7 @@ static size_t jl_show_svec(JL_STREAM *out, jl_svec_t *t, const char *head, const
591591JL_DLLEXPORT  int  jl_id_start_char (uint32_t  wc ) JL_NOTSAFEPOINT ;
592592JL_DLLEXPORT  int  jl_id_char (uint32_t  wc ) JL_NOTSAFEPOINT ;
593593
594- JL_DLLEXPORT  int  jl_is_identifier (char  * str ) JL_NOTSAFEPOINT 
594+ JL_DLLEXPORT  int  jl_is_identifier (const   char  * str ) JL_NOTSAFEPOINT 
595595{
596596    size_t  i  =  0 ;
597597    uint32_t  wc  =  u8_nextchar (str , & i );
@@ -674,22 +674,64 @@ static int is_globfunction(jl_value_t *v, jl_datatype_t *dv, jl_sym_t **globname
674674    return  0 ;
675675}
676676
677- static  size_t  jl_static_show_x_sym_escaped (JL_STREAM  * out , jl_sym_t   * name ) JL_NOTSAFEPOINT 
677+ static  size_t  jl_static_show_string (JL_STREAM  * out , const   char   * str ,  size_t   len ,  int   wrap ) JL_NOTSAFEPOINT 
678678{
679679    size_t  n  =  0 ;
680- 
681-     char  * sn  =  jl_symbol_name (name );
682-     int  hidden  =  0 ;
683-     if  (!(jl_is_identifier (sn ) ||  jl_is_operator (sn ))) {
684-         hidden  =  1 ;
680+     if  (wrap )
681+         n  +=  jl_printf (out , "\"" );
682+     if  (!u8_isvalid (str , len )) {
683+         // alternate print algorithm that preserves data if it's not UTF-8 
684+         static  const  char  hexdig [] =  "0123456789abcdef" ;
685+         for  (size_t  i  =  0 ; i  <  len ; i ++ ) {
686+             uint8_t  c  =  str [i ];
687+             if  (c  ==  '\\'  ||  c  ==  '"'  ||  c  ==  '$' )
688+                 n  +=  jl_printf (out , "\\%c" , c );
689+             else  if  (c  >= 32  &&  c  <  0x7f )
690+                 n  +=  jl_printf (out , "%c" , c );
691+             else 
692+                 n  +=  jl_printf (out , "\\x%c%c" , hexdig [c >>4 ], hexdig [c & 0xf ]);
693+         }
685694    }
686- 
687-     if  (hidden ) {
688-         n  +=  jl_printf (out , "var\"" );
695+     else  {
696+         int  special  =  0 ;
697+         for  (size_t  i  =  0 ; i  <  len ; i ++ ) {
698+             uint8_t  c  =  str [i ];
699+             if  (c  <  32  ||  c  ==  0x7f  ||  c  ==  '\\'  ||  c  ==  '"'  ||  c  ==  '$' ) {
700+                 special  =  1 ;
701+                 break ;
702+             }
703+         }
704+         if  (!special ) {
705+             jl_uv_puts (out , str , len );
706+             n  +=  len ;
707+         }
708+         else  {
709+             char  buf [512 ];
710+             size_t  i  =  0 ;
711+             while  (i  <  len ) {
712+                 size_t  r  =  u8_escape (buf , sizeof (buf ), str , & i , len , "\"$" , 0 );
713+                 jl_uv_puts (out , buf , r  -  1 );
714+                 n  +=  r  -  1 ;
715+             }
716+         }
689717    }
690-     n  +=  jl_printf (out , "%s" , sn );
691-     if  (hidden ) {
718+     if  (wrap )
692719        n  +=  jl_printf (out , "\"" );
720+     return  n ;
721+ }
722+ 
723+ static  size_t  jl_static_show_symbol (JL_STREAM  * out , jl_sym_t  * name ) JL_NOTSAFEPOINT 
724+ {
725+     size_t  n  =  0 ;
726+     const  char  * sn  =  jl_symbol_name (name );
727+     int  quoted  =  !jl_is_identifier (sn ) &&  !jl_is_operator (sn );
728+     if  (quoted ) {
729+         n  +=  jl_printf (out , "var" );
730+         // TODO: this is not quite right, since repr uses String escaping rules, and Symbol uses raw string rules 
731+         n  +=  jl_static_show_string (out , sn , strlen (sn ), 1 );
732+     }
733+     else  {
734+         n  +=  jl_printf (out , "%s" , sn );
693735    }
694736    return  n ;
695737}
@@ -807,11 +849,6 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
807849        // Types are printed as a fully qualified name, with parameters, e.g. 
808850        // `Base.Set{Int}`, and function types are printed as e.g. `typeof(Main.f)` 
809851        jl_datatype_t  * dv  =  (jl_datatype_t * )v ;
810-         jl_sym_t  * globname ;
811-         int  globfunc  =  is_globname_binding (v , dv ) &&  is_globfunction (v , dv , & globname );
812-         jl_sym_t  * sym  =  globfunc  ? globname  : dv -> name -> name ;
813-         char  * sn  =  jl_symbol_name (sym );
814-         size_t  quote  =  0 ;
815852        if  (dv -> name  ==  jl_tuple_typename ) {
816853            if  (dv  ==  jl_tuple_type )
817854                return  jl_printf (out , "Tuple" );
@@ -844,8 +881,13 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
844881            return  n ;
845882        }
846883        if  (ctx .quiet ) {
847-             return  jl_printf (out , "%s" ,  jl_symbol_name ( dv -> name -> name ) );
884+             return  jl_static_show_symbol (out , dv -> name -> name );
848885        }
886+         jl_sym_t  * globname ;
887+         int  globfunc  =  is_globname_binding (v , dv ) &&  is_globfunction (v , dv , & globname );
888+         jl_sym_t  * sym  =  globfunc  ? globname  : dv -> name -> name ;
889+         char  * sn  =  jl_symbol_name (sym );
890+         size_t  quote  =  0 ;
849891        if  (globfunc ) {
850892            n  +=  jl_printf (out , "typeof(" );
851893        }
@@ -858,7 +900,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
858900                quote  =  1 ;
859901            }
860902        }
861-         n  +=  jl_static_show_x_sym_escaped (out , sym );
903+         n  +=  jl_static_show_symbol (out , sym );
862904        if  (globfunc ) {
863905            n  +=  jl_printf (out , ")" );
864906            if  (quote ) {
@@ -927,9 +969,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
927969        n  +=  jl_printf (out , "nothing" );
928970    }
929971    else  if  (vt  ==  jl_string_type ) {
930-         n  +=  jl_printf (out , "\"" );
931-         jl_uv_puts (out , jl_string_data (v ), jl_string_len (v )); n  +=  jl_string_len (v );
932-         n  +=  jl_printf (out , "\"" );
972+         n  +=  jl_static_show_string (out , jl_string_data (v ), jl_string_len (v ), 1 );
933973    }
934974    else  if  (v  ==  jl_bottom_type ) {
935975        n  +=  jl_printf (out , "Union{}" );
@@ -978,7 +1018,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
9781018                n  +=  jl_printf (out , ")" );
9791019            n  +=  jl_printf (out , "<:" );
9801020        }
981-         n  +=  jl_static_show_x_sym_escaped (out , var -> name );
1021+         n  +=  jl_static_show_symbol (out , var -> name );
9821022        if  (showbounds  &&  (ub  !=  (jl_value_t * )jl_any_type  ||  lb  !=  jl_bottom_type )) {
9831023            // show type-var upper bound if it is defined, or if we showed the lower bound 
9841024            int  ua  =  jl_is_unionall (ub );
@@ -996,27 +1036,24 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
9961036            n  +=  jl_static_show_x (out , (jl_value_t * )m -> parent , depth , ctx );
9971037            n  +=  jl_printf (out , "." );
9981038        }
999-         n  +=  jl_printf (out , "%s" ,  jl_symbol_name ( m -> name ) );
1039+         n  +=  jl_static_show_symbol (out , m -> name );
10001040    }
10011041    else  if  (vt  ==  jl_symbol_type ) {
1002-         char  * sn  =  jl_symbol_name ((jl_sym_t * )v );
1003-         int  quoted  =  !jl_is_identifier (sn ) &&  jl_operator_precedence (sn ) ==  0 ;
1004-         if  (quoted )
1005-             n  +=  jl_printf (out , "Symbol(\"" );
1006-         else 
1007-             n  +=  jl_printf (out , ":" );
1008-         n  +=  jl_printf (out , "%s" , sn );
1009-         if  (quoted )
1010-             n  +=  jl_printf (out , "\")" );
1042+         n  +=  jl_printf (out , ":" );
1043+         n  +=  jl_static_show_symbol (out , (jl_sym_t * )v );
10111044    }
10121045    else  if  (vt  ==  jl_ssavalue_type ) {
10131046        n  +=  jl_printf (out , "SSAValue(%"  PRIuPTR  ")" ,
10141047                       (uintptr_t )((jl_ssavalue_t * )v )-> id );
10151048    }
10161049    else  if  (vt  ==  jl_globalref_type ) {
10171050        n  +=  jl_static_show_x (out , (jl_value_t * )jl_globalref_mod (v ), depth , ctx );
1018-         char  * name  =  jl_symbol_name (jl_globalref_name (v ));
1019-         n  +=  jl_printf (out , jl_is_identifier (name ) ? ".%s"  : ".:(%s)" , name );
1051+         jl_sym_t  * name  =  jl_globalref_name (v );
1052+         n  +=  jl_printf (out , "." );
1053+         if  (jl_is_operator (jl_symbol_name (name )))
1054+             n  +=  jl_printf (out , ":(%s)" , jl_symbol_name (name ));
1055+         else 
1056+             n  +=  jl_static_show_symbol (out , name );
10201057    }
10211058    else  if  (vt  ==  jl_gotonode_type ) {
10221059        n  +=  jl_printf (out , "goto %"  PRIuPTR , jl_gotonode_label (v ));
@@ -1050,17 +1087,17 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
10501087    else  if  (vt  ==  jl_expr_type ) {
10511088        jl_expr_t  * e  =  (jl_expr_t * )v ;
10521089        if  (e -> head  ==  jl_assign_sym  &&  jl_array_nrows (e -> args ) ==  2 ) {
1053-             n  +=  jl_static_show_x (out , jl_exprarg (e ,0 ), depth , ctx );
1090+             n  +=  jl_static_show_x (out , jl_exprarg (e ,  0 ), depth , ctx );
10541091            n  +=  jl_printf (out , " = " );
1055-             n  +=  jl_static_show_x (out , jl_exprarg (e ,1 ), depth , ctx );
1092+             n  +=  jl_static_show_x (out , jl_exprarg (e ,  1 ), depth , ctx );
10561093        }
10571094        else  {
1058-             char   sep   =   ' ' ;
1059-             n  +=  jl_printf (out , "Expr(:%s" ,  jl_symbol_name ( e -> head ) );
1095+             n   +=   jl_printf ( out ,  "Expr(" ) ;
1096+             n  +=  jl_static_show_x (out , ( jl_value_t * ) e -> head ,  depth ,  ctx );
10601097            size_t  i , len  =  jl_array_nrows (e -> args );
10611098            for  (i  =  0 ; i  <  len ; i ++ ) {
1062-                 n  +=  jl_printf (out , ",%c"  ,  sep );
1063-                 n  +=  jl_static_show_x (out , jl_exprarg (e ,i ), depth , ctx );
1099+                 n  +=  jl_printf (out , ", "  );
1100+                 n  +=  jl_static_show_x (out , jl_exprarg (e ,  i ), depth , ctx );
10641101            }
10651102            n  +=  jl_printf (out , ")" );
10661103        }
@@ -1195,7 +1232,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
11951232            }
11961233        }
11971234
1198-         n  +=  jl_static_show_x_sym_escaped (out , sym );
1235+         n  +=  jl_static_show_symbol (out , sym );
11991236
12001237        if  (globfunc ) {
12011238            if  (quote ) {
@@ -1231,8 +1268,14 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
12311268            jl_value_t  * names  =  isnamedtuple  ? jl_tparam0 (vt ) : (jl_value_t * )jl_field_names (vt );
12321269            for  (; i  <  tlen ; i ++ ) {
12331270                if  (!istuple ) {
1234-                     jl_value_t  * fname  =  isnamedtuple  ? jl_fieldref_noalloc (names , i ) : jl_svecref (names , i );
1235-                     n  +=  jl_printf (out , "%s=" , jl_symbol_name ((jl_sym_t * )fname ));
1271+                     jl_sym_t  * fname  =  (jl_sym_t * )(isnamedtuple  ? jl_fieldref_noalloc (names , i ) : jl_svecref (names , i ));
1272+                     if  (fname  ==  NULL  ||  !jl_is_symbol (fname ))
1273+                         n  +=  jl_static_show_x (out , (jl_value_t * )fname , depth , ctx );
1274+                     else  if  (jl_is_operator (jl_symbol_name (fname )))
1275+                         n  +=  jl_printf (out , "(%s)" , jl_symbol_name (fname ));
1276+                     else 
1277+                         n  +=  jl_static_show_symbol (out , fname );
1278+                     n  +=  jl_printf (out , "=" );
12361279                }
12371280                size_t  offs  =  jl_field_offset (vt , i );
12381281                char  * fld_ptr  =  (char * )v  +  offs ;
@@ -1367,7 +1410,7 @@ size_t jl_static_show_func_sig_(JL_STREAM *s, jl_value_t *type, jl_static_show_c
13671410    if  ((jl_nparams (ftype ) ==  0  ||  ftype  ==  ((jl_datatype_t * )ftype )-> name -> wrapper ) && 
13681411            ((jl_datatype_t * )ftype )-> name -> mt  !=  jl_type_type_mt  && 
13691412            ((jl_datatype_t * )ftype )-> name -> mt  !=  jl_nonfunction_mt ) {
1370-         n  +=  jl_printf (s , "%s" ,  jl_symbol_name ((( jl_datatype_t * )ftype )-> name -> mt -> name ) );
1413+         n  +=  jl_static_show_symbol (s , (( jl_datatype_t * )ftype )-> name -> mt -> name );
13711414    }
13721415    else  {
13731416        n  +=  jl_printf (s , "(::" );
@@ -1466,10 +1509,10 @@ void jl_log(int level, jl_value_t *module, jl_value_t *group, jl_value_t *id,
14661509        }
14671510        jl_printf (str , "\n@ " );
14681511        if  (jl_is_string (file )) {
1469-             jl_uv_puts (str , jl_string_data (file ), jl_string_len (file ));
1512+             jl_static_show_string (str , jl_string_data (file ), jl_string_len (file ),  0 );
14701513        }
14711514        else  if  (jl_is_symbol (file )) {
1472-             jl_printf (str , "%s" ,  jl_symbol_name ((jl_sym_t * )file ));
1515+             jl_static_show_string (str , jl_symbol_name (( jl_sym_t * ) file ),  strlen ( jl_symbol_name ((jl_sym_t * )file )),  0 );
14731516        }
14741517        jl_printf (str , ":" );
14751518        jl_static_show (str , line );
0 commit comments