@@ -591,7 +591,7 @@ static size_t jl_show_svec(JL_STREAM *out, jl_svec_t *t, const char *head, const
591
591
JL_DLLEXPORT int jl_id_start_char (uint32_t wc ) JL_NOTSAFEPOINT ;
592
592
JL_DLLEXPORT int jl_id_char (uint32_t wc ) JL_NOTSAFEPOINT ;
593
593
594
- JL_DLLEXPORT int jl_is_identifier (char * str ) JL_NOTSAFEPOINT
594
+ JL_DLLEXPORT int jl_is_identifier (const char * str ) JL_NOTSAFEPOINT
595
595
{
596
596
size_t i = 0 ;
597
597
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
674
674
return 0 ;
675
675
}
676
676
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
678
678
{
679
679
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
+ }
685
694
}
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
+ }
689
717
}
690
- n += jl_printf (out , "%s" , sn );
691
- if (hidden ) {
718
+ if (wrap )
692
719
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 );
693
735
}
694
736
return n ;
695
737
}
@@ -807,11 +849,6 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
807
849
// Types are printed as a fully qualified name, with parameters, e.g.
808
850
// `Base.Set{Int}`, and function types are printed as e.g. `typeof(Main.f)`
809
851
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 ;
815
852
if (dv -> name == jl_tuple_typename ) {
816
853
if (dv == jl_tuple_type )
817
854
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
844
881
return n ;
845
882
}
846
883
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 );
848
885
}
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 ;
849
891
if (globfunc ) {
850
892
n += jl_printf (out , "typeof(" );
851
893
}
@@ -858,7 +900,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
858
900
quote = 1 ;
859
901
}
860
902
}
861
- n += jl_static_show_x_sym_escaped (out , sym );
903
+ n += jl_static_show_symbol (out , sym );
862
904
if (globfunc ) {
863
905
n += jl_printf (out , ")" );
864
906
if (quote ) {
@@ -927,9 +969,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
927
969
n += jl_printf (out , "nothing" );
928
970
}
929
971
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 );
933
973
}
934
974
else if (v == jl_bottom_type ) {
935
975
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
978
1018
n += jl_printf (out , ")" );
979
1019
n += jl_printf (out , "<:" );
980
1020
}
981
- n += jl_static_show_x_sym_escaped (out , var -> name );
1021
+ n += jl_static_show_symbol (out , var -> name );
982
1022
if (showbounds && (ub != (jl_value_t * )jl_any_type || lb != jl_bottom_type )) {
983
1023
// show type-var upper bound if it is defined, or if we showed the lower bound
984
1024
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
996
1036
n += jl_static_show_x (out , (jl_value_t * )m -> parent , depth , ctx );
997
1037
n += jl_printf (out , "." );
998
1038
}
999
- n += jl_printf (out , "%s" , jl_symbol_name ( m -> name ) );
1039
+ n += jl_static_show_symbol (out , m -> name );
1000
1040
}
1001
1041
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 );
1011
1044
}
1012
1045
else if (vt == jl_ssavalue_type ) {
1013
1046
n += jl_printf (out , "SSAValue(%" PRIuPTR ")" ,
1014
1047
(uintptr_t )((jl_ssavalue_t * )v )-> id );
1015
1048
}
1016
1049
else if (vt == jl_globalref_type ) {
1017
1050
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 );
1020
1057
}
1021
1058
else if (vt == jl_gotonode_type ) {
1022
1059
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
1050
1087
else if (vt == jl_expr_type ) {
1051
1088
jl_expr_t * e = (jl_expr_t * )v ;
1052
1089
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 );
1054
1091
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 );
1056
1093
}
1057
1094
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 );
1060
1097
size_t i , len = jl_array_nrows (e -> args );
1061
1098
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 );
1064
1101
}
1065
1102
n += jl_printf (out , ")" );
1066
1103
}
@@ -1195,7 +1232,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
1195
1232
}
1196
1233
}
1197
1234
1198
- n += jl_static_show_x_sym_escaped (out , sym );
1235
+ n += jl_static_show_symbol (out , sym );
1199
1236
1200
1237
if (globfunc ) {
1201
1238
if (quote ) {
@@ -1231,8 +1268,14 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
1231
1268
jl_value_t * names = isnamedtuple ? jl_tparam0 (vt ) : (jl_value_t * )jl_field_names (vt );
1232
1269
for (; i < tlen ; i ++ ) {
1233
1270
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 , "=" );
1236
1279
}
1237
1280
size_t offs = jl_field_offset (vt , i );
1238
1281
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
1367
1410
if ((jl_nparams (ftype ) == 0 || ftype == ((jl_datatype_t * )ftype )-> name -> wrapper ) &&
1368
1411
((jl_datatype_t * )ftype )-> name -> mt != jl_type_type_mt &&
1369
1412
((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 );
1371
1414
}
1372
1415
else {
1373
1416
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,
1466
1509
}
1467
1510
jl_printf (str , "\n@ " );
1468
1511
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 );
1470
1513
}
1471
1514
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 );
1473
1516
}
1474
1517
jl_printf (str , ":" );
1475
1518
jl_static_show (str , line );
0 commit comments