@@ -572,7 +572,7 @@ static size_t jl_show_svec(JL_STREAM *out, jl_svec_t *t, const char *head, const
572572JL_DLLEXPORT  int  jl_id_start_char (uint32_t  wc ) JL_NOTSAFEPOINT ;
573573JL_DLLEXPORT  int  jl_id_char (uint32_t  wc ) JL_NOTSAFEPOINT ;
574574
575- JL_DLLEXPORT  int  jl_is_identifier (char  * str ) JL_NOTSAFEPOINT 
575+ JL_DLLEXPORT  int  jl_is_identifier (const   char  * str ) JL_NOTSAFEPOINT 
576576{
577577    size_t  i  =  0 ;
578578    uint32_t  wc  =  u8_nextchar (str , & i );
@@ -655,22 +655,64 @@ static int is_globfunction(jl_value_t *v, jl_datatype_t *dv, jl_sym_t **globname
655655    return  0 ;
656656}
657657
658- static  size_t  jl_static_show_x_sym_escaped (JL_STREAM  * out , jl_sym_t   * name ) JL_NOTSAFEPOINT 
658+ static  size_t  jl_static_show_string (JL_STREAM  * out , const   char   * str ,  size_t   len ,  int   wrap ) JL_NOTSAFEPOINT 
659659{
660660    size_t  n  =  0 ;
661- 
662-     char  * sn  =  jl_symbol_name (name );
663-     int  hidden  =  0 ;
664-     if  (!(jl_is_identifier (sn ) ||  jl_is_operator (sn ))) {
665-         hidden  =  1 ;
661+     if  (wrap )
662+         n  +=  jl_printf (out , "\"" );
663+     if  (!u8_isvalid (str , len )) {
664+         // alternate print algorithm that preserves data if it's not UTF-8 
665+         static  const  char  hexdig [] =  "0123456789abcdef" ;
666+         for  (size_t  i  =  0 ; i  <  len ; i ++ ) {
667+             uint8_t  c  =  str [i ];
668+             if  (c  ==  '\\'  ||  c  ==  '"'  ||  c  ==  '$' )
669+                 n  +=  jl_printf (out , "\\%c" , c );
670+             else  if  (c  >= 32  &&  c  <  0x7f )
671+                 n  +=  jl_printf (out , "%c" , c );
672+             else 
673+                 n  +=  jl_printf (out , "\\x%c%c" , hexdig [c >>4 ], hexdig [c & 0xf ]);
674+         }
666675    }
667- 
668-     if  (hidden ) {
669-         n  +=  jl_printf (out , "var\"" );
676+     else  {
677+         int  special  =  0 ;
678+         for  (size_t  i  =  0 ; i  <  len ; i ++ ) {
679+             uint8_t  c  =  str [i ];
680+             if  (c  <  32  ||  c  ==  0x7f  ||  c  ==  '\\'  ||  c  ==  '"'  ||  c  ==  '$' ) {
681+                 special  =  1 ;
682+                 break ;
683+             }
684+         }
685+         if  (!special ) {
686+             jl_uv_puts (out , str , len );
687+             n  +=  len ;
688+         }
689+         else  {
690+             char  buf [512 ];
691+             size_t  i  =  0 ;
692+             while  (i  <  len ) {
693+                 size_t  r  =  u8_escape (buf , sizeof (buf ), str , & i , len , "\"$" , 0 );
694+                 jl_uv_puts (out , buf , r  -  1 );
695+                 n  +=  r  -  1 ;
696+             }
697+         }
670698    }
671-     n  +=  jl_printf (out , "%s" , sn );
672-     if  (hidden ) {
699+     if  (wrap )
673700        n  +=  jl_printf (out , "\"" );
701+     return  n ;
702+ }
703+ 
704+ static  size_t  jl_static_show_symbol (JL_STREAM  * out , jl_sym_t  * name ) JL_NOTSAFEPOINT 
705+ {
706+     size_t  n  =  0 ;
707+     const  char  * sn  =  jl_symbol_name (name );
708+     int  quoted  =  !jl_is_identifier (sn ) &&  !jl_is_operator (sn );
709+     if  (quoted ) {
710+         n  +=  jl_printf (out , "var" );
711+         // TODO: this is not quite right, since repr uses String escaping rules, and Symbol uses raw string rules 
712+         n  +=  jl_static_show_string (out , sn , strlen (sn ), 1 );
713+     }
714+     else  {
715+         n  +=  jl_printf (out , "%s" , sn );
674716    }
675717    return  n ;
676718}
@@ -788,11 +830,6 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
788830        // Types are printed as a fully qualified name, with parameters, e.g. 
789831        // `Base.Set{Int}`, and function types are printed as e.g. `typeof(Main.f)` 
790832        jl_datatype_t  * dv  =  (jl_datatype_t * )v ;
791-         jl_sym_t  * globname ;
792-         int  globfunc  =  is_globname_binding (v , dv ) &&  is_globfunction (v , dv , & globname );
793-         jl_sym_t  * sym  =  globfunc  ? globname  : dv -> name -> name ;
794-         char  * sn  =  jl_symbol_name (sym );
795-         size_t  quote  =  0 ;
796833        if  (dv -> name  ==  jl_tuple_typename ) {
797834            if  (dv  ==  jl_tuple_type )
798835                return  jl_printf (out , "Tuple" );
@@ -825,8 +862,13 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
825862            return  n ;
826863        }
827864        if  (ctx .quiet ) {
828-             return  jl_printf (out , "%s" ,  jl_symbol_name ( dv -> name -> name ) );
865+             return  jl_static_show_symbol (out , dv -> name -> name );
829866        }
867+         jl_sym_t  * globname ;
868+         int  globfunc  =  is_globname_binding (v , dv ) &&  is_globfunction (v , dv , & globname );
869+         jl_sym_t  * sym  =  globfunc  ? globname  : dv -> name -> name ;
870+         char  * sn  =  jl_symbol_name (sym );
871+         size_t  quote  =  0 ;
830872        if  (globfunc ) {
831873            n  +=  jl_printf (out , "typeof(" );
832874        }
@@ -839,7 +881,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
839881                quote  =  1 ;
840882            }
841883        }
842-         n  +=  jl_static_show_x_sym_escaped (out , sym );
884+         n  +=  jl_static_show_symbol (out , sym );
843885        if  (globfunc ) {
844886            n  +=  jl_printf (out , ")" );
845887            if  (quote ) {
@@ -908,9 +950,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
908950        n  +=  jl_printf (out , "nothing" );
909951    }
910952    else  if  (vt  ==  jl_string_type ) {
911-         n  +=  jl_printf (out , "\"" );
912-         jl_uv_puts (out , jl_string_data (v ), jl_string_len (v )); n  +=  jl_string_len (v );
913-         n  +=  jl_printf (out , "\"" );
953+         n  +=  jl_static_show_string (out , jl_string_data (v ), jl_string_len (v ), 1 );
914954    }
915955    else  if  (v  ==  jl_bottom_type ) {
916956        n  +=  jl_printf (out , "Union{}" );
@@ -959,7 +999,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
959999                n  +=  jl_printf (out , ")" );
9601000            n  +=  jl_printf (out , "<:" );
9611001        }
962-         n  +=  jl_static_show_x_sym_escaped (out , var -> name );
1002+         n  +=  jl_static_show_symbol (out , var -> name );
9631003        if  (showbounds  &&  (ub  !=  (jl_value_t * )jl_any_type  ||  lb  !=  jl_bottom_type )) {
9641004            // show type-var upper bound if it is defined, or if we showed the lower bound 
9651005            int  ua  =  jl_is_unionall (ub );
@@ -977,27 +1017,24 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
9771017            n  +=  jl_static_show_x (out , (jl_value_t * )m -> parent , depth , ctx );
9781018            n  +=  jl_printf (out , "." );
9791019        }
980-         n  +=  jl_printf (out , "%s" ,  jl_symbol_name ( m -> name ) );
1020+         n  +=  jl_static_show_symbol (out , m -> name );
9811021    }
9821022    else  if  (vt  ==  jl_symbol_type ) {
983-         char  * sn  =  jl_symbol_name ((jl_sym_t * )v );
984-         int  quoted  =  !jl_is_identifier (sn ) &&  jl_operator_precedence (sn ) ==  0 ;
985-         if  (quoted )
986-             n  +=  jl_printf (out , "Symbol(\"" );
987-         else 
988-             n  +=  jl_printf (out , ":" );
989-         n  +=  jl_printf (out , "%s" , sn );
990-         if  (quoted )
991-             n  +=  jl_printf (out , "\")" );
1023+         n  +=  jl_printf (out , ":" );
1024+         n  +=  jl_static_show_symbol (out , (jl_sym_t * )v );
9921025    }
9931026    else  if  (vt  ==  jl_ssavalue_type ) {
9941027        n  +=  jl_printf (out , "SSAValue(%"  PRIuPTR  ")" ,
9951028                       (uintptr_t )((jl_ssavalue_t * )v )-> id );
9961029    }
9971030    else  if  (vt  ==  jl_globalref_type ) {
9981031        n  +=  jl_static_show_x (out , (jl_value_t * )jl_globalref_mod (v ), depth , ctx );
999-         char  * name  =  jl_symbol_name (jl_globalref_name (v ));
1000-         n  +=  jl_printf (out , jl_is_identifier (name ) ? ".%s"  : ".:(%s)" , name );
1032+         jl_sym_t  * name  =  jl_globalref_name (v );
1033+         n  +=  jl_printf (out , "." );
1034+         if  (jl_is_operator (jl_symbol_name (name )))
1035+             n  +=  jl_printf (out , ":(%s)" , jl_symbol_name (name ));
1036+         else 
1037+             n  +=  jl_static_show_symbol (out , name );
10011038    }
10021039    else  if  (vt  ==  jl_gotonode_type ) {
10031040        n  +=  jl_printf (out , "goto %"  PRIuPTR , jl_gotonode_label (v ));
@@ -1031,17 +1068,17 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
10311068    else  if  (vt  ==  jl_expr_type ) {
10321069        jl_expr_t  * e  =  (jl_expr_t * )v ;
10331070        if  (e -> head  ==  jl_assign_sym  &&  jl_array_len (e -> args ) ==  2 ) {
1034-             n  +=  jl_static_show_x (out , jl_exprarg (e ,0 ), depth , ctx );
1071+             n  +=  jl_static_show_x (out , jl_exprarg (e ,  0 ), depth , ctx );
10351072            n  +=  jl_printf (out , " = " );
1036-             n  +=  jl_static_show_x (out , jl_exprarg (e ,1 ), depth , ctx );
1073+             n  +=  jl_static_show_x (out , jl_exprarg (e ,  1 ), depth , ctx );
10371074        }
10381075        else  {
1039-             char   sep   =   ' ' ;
1040-             n  +=  jl_printf (out , "Expr(:%s" ,  jl_symbol_name ( e -> head ) );
1041-             size_t  i , len  =  jl_array_len (e -> args );
1076+             n   +=   jl_printf ( out ,  "Expr(" ) ;
1077+             n  +=  jl_static_show_x (out , ( jl_value_t * ) e -> head ,  depth ,  ctx );
1078+             size_t  i , len  =  jl_array_nrows (e -> args );
10421079            for  (i  =  0 ; i  <  len ; i ++ ) {
1043-                 n  +=  jl_printf (out , ",%c"  ,  sep );
1044-                 n  +=  jl_static_show_x (out , jl_exprarg (e ,i ), depth , ctx );
1080+                 n  +=  jl_printf (out , ", "  );
1081+                 n  +=  jl_static_show_x (out , jl_exprarg (e ,  i ), depth , ctx );
10451082            }
10461083            n  +=  jl_printf (out , ")" );
10471084        }
@@ -1128,7 +1165,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
11281165            }
11291166        }
11301167
1131-         n  +=  jl_static_show_x_sym_escaped (out , sym );
1168+         n  +=  jl_static_show_symbol (out , sym );
11321169
11331170        if  (globfunc ) {
11341171            if  (quote ) {
@@ -1164,8 +1201,14 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
11641201            jl_value_t  * names  =  isnamedtuple  ? jl_tparam0 (vt ) : (jl_value_t * )jl_field_names (vt );
11651202            for  (; i  <  tlen ; i ++ ) {
11661203                if  (!istuple ) {
1167-                     jl_value_t  * fname  =  isnamedtuple  ? jl_fieldref_noalloc (names , i ) : jl_svecref (names , i );
1168-                     n  +=  jl_printf (out , "%s=" , jl_symbol_name ((jl_sym_t * )fname ));
1204+                     jl_sym_t  * fname  =  (jl_sym_t * )(isnamedtuple  ? jl_fieldref_noalloc (names , i ) : jl_svecref (names , i ));
1205+                     if  (fname  ==  NULL  ||  !jl_is_symbol (fname ))
1206+                         n  +=  jl_static_show_x (out , (jl_value_t * )fname , depth , ctx );
1207+                     else  if  (jl_is_operator (jl_symbol_name (fname )))
1208+                         n  +=  jl_printf (out , "(%s)" , jl_symbol_name (fname ));
1209+                     else 
1210+                         n  +=  jl_static_show_symbol (out , fname );
1211+                     n  +=  jl_printf (out , "=" );
11691212                }
11701213                size_t  offs  =  jl_field_offset (vt , i );
11711214                char  * fld_ptr  =  (char * )v  +  offs ;
@@ -1300,7 +1343,7 @@ size_t jl_static_show_func_sig_(JL_STREAM *s, jl_value_t *type, jl_static_show_c
13001343    if  ((jl_nparams (ftype ) ==  0  ||  ftype  ==  ((jl_datatype_t * )ftype )-> name -> wrapper ) && 
13011344            ((jl_datatype_t * )ftype )-> name -> mt  !=  jl_type_type_mt  && 
13021345            ((jl_datatype_t * )ftype )-> name -> mt  !=  jl_nonfunction_mt ) {
1303-         n  +=  jl_printf (s , "%s" ,  jl_symbol_name ((( jl_datatype_t * )ftype )-> name -> mt -> name ) );
1346+         n  +=  jl_static_show_symbol (s , (( jl_datatype_t * )ftype )-> name -> mt -> name );
13041347    }
13051348    else  {
13061349        n  +=  jl_printf (s , "(::" );
@@ -1399,10 +1442,10 @@ void jl_log(int level, jl_value_t *module, jl_value_t *group, jl_value_t *id,
13991442        }
14001443        jl_printf (str , "\n@ " );
14011444        if  (jl_is_string (file )) {
1402-             jl_uv_puts (str , jl_string_data (file ), jl_string_len (file ));
1445+             jl_static_show_string (str , jl_string_data (file ), jl_string_len (file ),  0 );
14031446        }
14041447        else  if  (jl_is_symbol (file )) {
1405-             jl_printf (str , "%s" ,  jl_symbol_name ((jl_sym_t * )file ));
1448+             jl_static_show_string (str , jl_symbol_name (( jl_sym_t * ) file ),  strlen ( jl_symbol_name ((jl_sym_t * )file )),  0 );
14061449        }
14071450        jl_printf (str , ":" );
14081451        jl_static_show (str , line );
0 commit comments