@@ -572,7 +572,7 @@ static size_t jl_show_svec(JL_STREAM *out, jl_svec_t *t, const char *head, const
572
572
JL_DLLEXPORT int jl_id_start_char (uint32_t wc ) JL_NOTSAFEPOINT ;
573
573
JL_DLLEXPORT int jl_id_char (uint32_t wc ) JL_NOTSAFEPOINT ;
574
574
575
- JL_DLLEXPORT int jl_is_identifier (char * str ) JL_NOTSAFEPOINT
575
+ JL_DLLEXPORT int jl_is_identifier (const char * str ) JL_NOTSAFEPOINT
576
576
{
577
577
size_t i = 0 ;
578
578
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
655
655
return 0 ;
656
656
}
657
657
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
659
659
{
660
660
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
+ }
666
675
}
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
+ }
670
698
}
671
- n += jl_printf (out , "%s" , sn );
672
- if (hidden ) {
699
+ if (wrap )
673
700
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 );
674
716
}
675
717
return n ;
676
718
}
@@ -788,11 +830,6 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
788
830
// Types are printed as a fully qualified name, with parameters, e.g.
789
831
// `Base.Set{Int}`, and function types are printed as e.g. `typeof(Main.f)`
790
832
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 ;
796
833
if (dv -> name == jl_tuple_typename ) {
797
834
if (dv == jl_tuple_type )
798
835
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
825
862
return n ;
826
863
}
827
864
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 );
829
866
}
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 ;
830
872
if (globfunc ) {
831
873
n += jl_printf (out , "typeof(" );
832
874
}
@@ -839,7 +881,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
839
881
quote = 1 ;
840
882
}
841
883
}
842
- n += jl_static_show_x_sym_escaped (out , sym );
884
+ n += jl_static_show_symbol (out , sym );
843
885
if (globfunc ) {
844
886
n += jl_printf (out , ")" );
845
887
if (quote ) {
@@ -908,9 +950,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
908
950
n += jl_printf (out , "nothing" );
909
951
}
910
952
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 );
914
954
}
915
955
else if (v == jl_bottom_type ) {
916
956
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
959
999
n += jl_printf (out , ")" );
960
1000
n += jl_printf (out , "<:" );
961
1001
}
962
- n += jl_static_show_x_sym_escaped (out , var -> name );
1002
+ n += jl_static_show_symbol (out , var -> name );
963
1003
if (showbounds && (ub != (jl_value_t * )jl_any_type || lb != jl_bottom_type )) {
964
1004
// show type-var upper bound if it is defined, or if we showed the lower bound
965
1005
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
977
1017
n += jl_static_show_x (out , (jl_value_t * )m -> parent , depth , ctx );
978
1018
n += jl_printf (out , "." );
979
1019
}
980
- n += jl_printf (out , "%s" , jl_symbol_name ( m -> name ) );
1020
+ n += jl_static_show_symbol (out , m -> name );
981
1021
}
982
1022
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 );
992
1025
}
993
1026
else if (vt == jl_ssavalue_type ) {
994
1027
n += jl_printf (out , "SSAValue(%" PRIuPTR ")" ,
995
1028
(uintptr_t )((jl_ssavalue_t * )v )-> id );
996
1029
}
997
1030
else if (vt == jl_globalref_type ) {
998
1031
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 );
1001
1038
}
1002
1039
else if (vt == jl_gotonode_type ) {
1003
1040
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
1031
1068
else if (vt == jl_expr_type ) {
1032
1069
jl_expr_t * e = (jl_expr_t * )v ;
1033
1070
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 );
1035
1072
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 );
1037
1074
}
1038
1075
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 );
1042
1079
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 );
1045
1082
}
1046
1083
n += jl_printf (out , ")" );
1047
1084
}
@@ -1128,7 +1165,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
1128
1165
}
1129
1166
}
1130
1167
1131
- n += jl_static_show_x_sym_escaped (out , sym );
1168
+ n += jl_static_show_symbol (out , sym );
1132
1169
1133
1170
if (globfunc ) {
1134
1171
if (quote ) {
@@ -1164,8 +1201,14 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
1164
1201
jl_value_t * names = isnamedtuple ? jl_tparam0 (vt ) : (jl_value_t * )jl_field_names (vt );
1165
1202
for (; i < tlen ; i ++ ) {
1166
1203
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 , "=" );
1169
1212
}
1170
1213
size_t offs = jl_field_offset (vt , i );
1171
1214
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
1300
1343
if ((jl_nparams (ftype ) == 0 || ftype == ((jl_datatype_t * )ftype )-> name -> wrapper ) &&
1301
1344
((jl_datatype_t * )ftype )-> name -> mt != jl_type_type_mt &&
1302
1345
((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 );
1304
1347
}
1305
1348
else {
1306
1349
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,
1399
1442
}
1400
1443
jl_printf (str , "\n@ " );
1401
1444
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 );
1403
1446
}
1404
1447
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 );
1406
1449
}
1407
1450
jl_printf (str , ":" );
1408
1451
jl_static_show (str , line );
0 commit comments