@@ -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