Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
6972f075
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6972f075
编写于
9月 01, 2011
作者:
B
Brian Anderson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make #fmt and #ifmt synonymous. Issue #855
上级
fc45eb78
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
598 addition
and
166 deletion
+598
-166
src/comp/rustc.rc
src/comp/rustc.rc
+1
-1
src/comp/syntax/ext/base.rs
src/comp/syntax/ext/base.rs
+3
-1
src/comp/syntax/ext/fmt.rs
src/comp/syntax/ext/fmt.rs
+12
-12
src/lib/extfmt.rs
src/lib/extfmt.rs
+429
-0
src/lib/extifmt.rs
src/lib/extifmt.rs
+1
-1
src/lib/std.rc
src/lib/std.rc
+1
-0
src/test/compile-fail/extfmt-unsigned-plus.rs
src/test/compile-fail/extfmt-unsigned-plus.rs
+1
-1
src/test/compile-fail/extfmt-unsigned-space.rs
src/test/compile-fail/extfmt-unsigned-space.rs
+1
-1
src/test/run-pass/syntax-extension-fmt.rs
src/test/run-pass/syntax-extension-fmt.rs
+149
-149
未找到文件。
src/comp/rustc.rc
浏览文件 @
6972f075
...
...
@@ -63,7 +63,7 @@ mod syntax {
mod
base
;
mod
expand
;
mod
i
fmt
;
mod
fmt
;
mod
env
;
mod
simplext
;
mod
concat_idents
;
...
...
src/comp/syntax/ext/base.rs
浏览文件 @
6972f075
...
...
@@ -22,7 +22,9 @@
// AST nodes into full ASTs
fn
syntax_expander_table
()
->
hashmap
<
istr
,
syntax_extension
>
{
let
syntax_expanders
=
new_str_hash
::
<
syntax_extension
>
();
syntax_expanders
.insert
(
~
"ifmt"
,
normal
(
ext
::
ifmt
::
expand_syntax_ext
));
syntax_expanders
.insert
(
~
"fmt"
,
normal
(
ext
::
fmt
::
expand_syntax_ext
));
// FIXME: Transitional. Remove
syntax_expanders
.insert
(
~
"ifmt"
,
normal
(
ext
::
fmt
::
expand_syntax_ext
));
syntax_expanders
.insert
(
~
"env"
,
normal
(
ext
::
env
::
expand_syntax_ext
));
syntax_expanders
.insert
(
~
"macro"
,
macro_defining
(
ext
::
simplext
::
add_new_extension
));
...
...
src/comp/syntax/ext/
i
fmt.rs
→
src/comp/syntax/ext/fmt.rs
浏览文件 @
6972f075
/*
* The compiler code necessary to support the #
i
fmt extension. Eventually this
* The compiler code necessary to support the #fmt extension. Eventually this
* should all get sucked into either the standard library extfmt module or the
* compiler syntax extension plugin interface.
*/
...
...
@@ -10,7 +10,7 @@
import
std
::
option
;
import
std
::
option
::
none
;
import
std
::
option
::
some
;
import
std
::
ext
i
fmt
::
ct
::
*
;
import
std
::
extfmt
::
ct
::
*
;
import
base
::
*
;
import
codemap
::
span
;
export
expand_syntax_ext
;
...
...
@@ -22,15 +22,15 @@ fn expand_syntax_ext(cx: &ext_ctxt, sp: span, arg: @ast::expr,
ast
::
expr_vec
(
elts
,
_
)
{
elts
}
_
{
cx
.span_fatal
(
sp
,
~
"#
i
fmt requires arguments of the form `[...]`."
)
sp
,
~
"#fmt requires arguments of the form `[...]`."
)
}
};
if
vec
::
len
::
<@
ast
::
expr
>
(
args
)
==
0u
{
cx
.span_fatal
(
sp
,
~
"#
i
fmt requires a format string"
);
cx
.span_fatal
(
sp
,
~
"#fmt requires a format string"
);
}
let
fmt
=
expr_to_str
(
cx
,
args
[
0
],
~
"first argument to #
i
fmt must be a "
~
"first argument to #fmt must be a "
+
~
"string literal."
);
let
fmtspan
=
args
[
0
]
.span
;
log
"Format string:"
;
...
...
@@ -106,8 +106,8 @@ fn compiling_std(cx: &ext_ctxt) -> bool {
ret
str
::
find
(
cx
.crate_file_name
(),
~
"std.rc"
)
>=
0
;
}
if
compiling_std
(
cx
)
{
ret
[
~
"ext
i
fmt"
,
~
"rt"
,
ident
];
}
else
{
ret
[
~
"std"
,
~
"ext
i
fmt"
,
~
"rt"
,
ident
];
}
ret
[
~
"extfmt"
,
~
"rt"
,
ident
];
}
else
{
ret
[
~
"std"
,
~
"extfmt"
,
~
"rt"
,
ident
];
}
}
fn
make_rt_path_expr
(
cx
:
&
ext_ctxt
,
sp
:
span
,
ident
:
&
istr
)
->
@
ast
::
expr
{
...
...
@@ -151,7 +151,7 @@ fn make_count(cx: &ext_ctxt, sp: span, cnt: &count) -> @ast::expr {
let
count_is_args
=
[
count_lit
];
ret
make_call
(
cx
,
sp
,
count_is_path
,
count_is_args
);
}
_
{
cx
.span_unimpl
(
sp
,
~
"unimplemented #
i
fmt conversion"
);
}
_
{
cx
.span_unimpl
(
sp
,
~
"unimplemented #fmt conversion"
);
}
}
}
fn
make_ty
(
cx
:
&
ext_ctxt
,
sp
:
span
,
t
:
&
ty
)
->
@
ast
::
expr
{
...
...
@@ -205,7 +205,7 @@ fn is_signed_type(cnv: conv) -> bool {
_
{
ret
false
;
}
}
}
let
unsupported
=
~
"conversion not supported in #
i
fmt string"
;
let
unsupported
=
~
"conversion not supported in #fmt string"
;
alt
cnv
.param
{
option
::
none
.
{
}
_
{
cx
.span_unimpl
(
sp
,
unsupported
);
}
...
...
@@ -217,14 +217,14 @@ fn is_signed_type(cnv: conv) -> bool {
if
!
is_signed_type
(
cnv
)
{
cx
.span_fatal
(
sp
,
~
"+ flag only valid in "
+
~
"signed #
i
fmt conversion"
);
~
"signed #fmt conversion"
);
}
}
flag_space_for_sign
.
{
if
!
is_signed_type
(
cnv
)
{
cx
.span_fatal
(
sp
,
~
"space flag only valid in "
+
~
"signed #
i
fmt conversions"
);
~
"signed #fmt conversions"
);
}
}
flag_left_zero_pad
.
{
}
...
...
@@ -329,7 +329,7 @@ fn log_conv(c: conv) {
n
+=
1u
;
if
n
>=
nargs
{
cx
.span_fatal
(
sp
,
~
"not enough arguments to #
i
fmt "
+
~
"not enough arguments to #fmt "
+
~
"for the given format string"
);
}
log
"Building conversion:"
;
...
...
src/lib/extfmt.rs
0 → 100644
浏览文件 @
6972f075
/* The 'fmt' extension is modeled on the posix printf system.
*
* A posix conversion ostensibly looks like this:
*
* %[parameter][flags][width][.precision][length]type
*
* Given the different numeric type bestiary we have, we omit the 'length'
* parameter and support slightly different conversions for 'type':
*
* %[parameter][flags][width][.precision]type
*
* we also only support translating-to-rust a tiny subset of the possible
* combinations at the moment.
*/
import
option
::
none
;
import
option
::
some
;
/*
* We have a 'ct' (compile-time) module that parses format strings into a
* sequence of conversions. From those conversions AST fragments are built
* that call into properly-typed functions in the 'rt' (run-time) module.
* Each of those run-time conversion functions accepts another conversion
* description that specifies how to format its output.
*
* The building of the AST is currently done in a module inside the compiler,
* but should migrate over here as the plugin interface is defined.
*/
// Functions used by the fmt extension at compile time
mod
ct
{
tag
signedness
{
signed
;
unsigned
;
}
tag
caseness
{
case_upper
;
case_lower
;
}
tag
ty
{
ty_bool
;
ty_str
;
ty_char
;
ty_int
(
signedness
);
ty_bits
;
ty_hex
(
caseness
);
ty_octal
;
// FIXME: More types
}
tag
flag
{
flag_left_justify
;
flag_left_zero_pad
;
flag_space_for_sign
;
flag_sign_always
;
flag_alternate
;
}
tag
count
{
count_is
(
int
);
count_is_param
(
int
);
count_is_next_param
;
count_implied
;
}
// A formatted conversion from an expression to a string
type
conv
=
{
param
:
option
::
t
<
int
>
,
flags
:
[
flag
],
width
:
count
,
precision
:
count
,
ty
:
ty
};
// A fragment of the output sequence
tag
piece
{
piece_string
(
istr
);
piece_conv
(
conv
);
}
type
error_fn
=
fn
(
&
istr
)
->
!
;
fn
parse_fmt_string
(
s
:
&
istr
,
error
:
error_fn
)
->
[
piece
]
{
let
pieces
:
[
piece
]
=
[];
let
lim
=
str
::
byte_len
(
s
);
let
buf
=
~
""
;
fn
flush_buf
(
buf
:
&
istr
,
pieces
:
&
mutable
[
piece
])
->
istr
{
if
str
::
byte_len
(
buf
)
>
0u
{
let
piece
=
piece_string
(
buf
);
pieces
+=
[
piece
];
}
ret
~
""
;
}
let
i
=
0u
;
while
i
<
lim
{
let
curr
=
str
::
substr
(
s
,
i
,
1u
);
if
str
::
eq
(
curr
,
~
"%"
)
{
i
+=
1u
;
if
i
>=
lim
{
error
(
~
"unterminated conversion at end of string"
);
}
let
curr2
=
str
::
substr
(
s
,
i
,
1u
);
if
str
::
eq
(
curr2
,
~
"%"
)
{
i
+=
1u
;
}
else
{
buf
=
flush_buf
(
buf
,
pieces
);
let
rs
=
parse_conversion
(
s
,
i
,
lim
,
error
);
pieces
+=
[
rs
.piece
];
i
=
rs
.next
;
}
}
else
{
buf
+=
curr
;
i
+=
1u
;
}
}
buf
=
flush_buf
(
buf
,
pieces
);
ret
pieces
;
}
fn
peek_num
(
s
:
&
istr
,
i
:
uint
,
lim
:
uint
)
->
option
::
t
<
{
num
:
uint
,
next
:
uint
}
>
{
if
i
>=
lim
{
ret
none
;
}
let
c
=
s
[
i
];
if
!
(
'0'
as
u8
<=
c
&&
c
<=
'9'
as
u8
)
{
ret
option
::
none
;
}
let
n
=
c
-
(
'0'
as
u8
)
as
uint
;
ret
alt
peek_num
(
s
,
i
+
1u
,
lim
)
{
none
.
{
some
({
num
:
n
,
next
:
i
+
1u
})
}
some
(
next
)
{
let
m
=
next
.num
;
let
j
=
next
.next
;
some
({
num
:
n
*
10u
+
m
,
next
:
j
})
}
};
}
fn
parse_conversion
(
s
:
&
istr
,
i
:
uint
,
lim
:
uint
,
error
:
error_fn
)
->
{
piece
:
piece
,
next
:
uint
}
{
let
parm
=
parse_parameter
(
s
,
i
,
lim
);
let
flags
=
parse_flags
(
s
,
parm
.next
,
lim
);
let
width
=
parse_count
(
s
,
flags
.next
,
lim
);
let
prec
=
parse_precision
(
s
,
width
.next
,
lim
);
let
ty
=
parse_type
(
s
,
prec
.next
,
lim
,
error
);
ret
{
piece
:
piece_conv
({
param
:
parm
.param
,
flags
:
flags
.flags
,
width
:
width
.count
,
precision
:
prec
.count
,
ty
:
ty
.ty
}),
next
:
ty
.next
};
}
fn
parse_parameter
(
s
:
&
istr
,
i
:
uint
,
lim
:
uint
)
->
{
param
:
option
::
t
<
int
>
,
next
:
uint
}
{
if
i
>=
lim
{
ret
{
param
:
none
,
next
:
i
};
}
let
num
=
peek_num
(
s
,
i
,
lim
);
ret
alt
num
{
none
.
{
{
param
:
none
,
next
:
i
}
}
some
(
t
)
{
let
n
=
t
.num
;
let
j
=
t
.next
;
if
j
<
lim
&&
s
[
j
]
==
'$'
as
u8
{
{
param
:
some
(
n
as
int
),
next
:
j
+
1u
}
}
else
{
{
param
:
none
,
next
:
i
}
}
}
};
}
fn
parse_flags
(
s
:
&
istr
,
i
:
uint
,
lim
:
uint
)
->
{
flags
:
[
flag
],
next
:
uint
}
{
let
noflags
:
[
flag
]
=
[];
if
i
>=
lim
{
ret
{
flags
:
noflags
,
next
:
i
};
}
// FIXME: This recursion generates illegal instructions if the return
// value isn't boxed. Only started happening after the ivec conversion
fn
more_
(
f
:
flag
,
s
:
&
istr
,
i
:
uint
,
lim
:
uint
)
->
@
{
flags
:
[
flag
],
next
:
uint
}
{
let
next
=
parse_flags
(
s
,
i
+
1u
,
lim
);
let
rest
=
next
.flags
;
let
j
=
next
.next
;
let
curr
:
[
flag
]
=
[
f
];
ret
@
{
flags
:
curr
+
rest
,
next
:
j
};
}
let
more
=
bind
more_
(
_
,
s
,
i
,
lim
);
let
f
=
s
[
i
];
ret
if
f
==
'-'
as
u8
{
*
more
(
flag_left_justify
)
}
else
if
f
==
'0'
as
u8
{
*
more
(
flag_left_zero_pad
)
}
else
if
f
==
' '
as
u8
{
*
more
(
flag_space_for_sign
)
}
else
if
f
==
'+'
as
u8
{
*
more
(
flag_sign_always
)
}
else
if
f
==
'#'
as
u8
{
*
more
(
flag_alternate
)
}
else
{
{
flags
:
noflags
,
next
:
i
}
};
}
fn
parse_count
(
s
:
&
istr
,
i
:
uint
,
lim
:
uint
)
->
{
count
:
count
,
next
:
uint
}
{
ret
if
i
>=
lim
{
{
count
:
count_implied
,
next
:
i
}
}
else
if
s
[
i
]
==
'*'
as
u8
{
let
param
=
parse_parameter
(
s
,
i
+
1u
,
lim
);
let
j
=
param
.next
;
alt
param
.param
{
none
.
{
{
count
:
count_is_next_param
,
next
:
j
}
}
some
(
n
)
{
{
count
:
count_is_param
(
n
),
next
:
j
}
}
}
}
else
{
let
num
=
peek_num
(
s
,
i
,
lim
);
alt
num
{
none
.
{
{
count
:
count_implied
,
next
:
i
}
}
some
(
num
)
{
{
count
:
count_is
(
num
.num
as
int
),
next
:
num
.next
}
}
}
};
}
fn
parse_precision
(
s
:
&
istr
,
i
:
uint
,
lim
:
uint
)
->
{
count
:
count
,
next
:
uint
}
{
ret
if
i
>=
lim
{
{
count
:
count_implied
,
next
:
i
}
}
else
if
s
[
i
]
==
'.'
as
u8
{
let
count
=
parse_count
(
s
,
i
+
1u
,
lim
);
// If there were no digits specified, i.e. the precision
// was ".", then the precision is 0
alt
count
.count
{
count_implied
.
{
{
count
:
count_is
(
0
),
next
:
count
.next
}
}
_
{
count
}
}
}
else
{
{
count
:
count_implied
,
next
:
i
}
};
}
fn
parse_type
(
s
:
&
istr
,
i
:
uint
,
lim
:
uint
,
error
:
error_fn
)
->
{
ty
:
ty
,
next
:
uint
}
{
if
i
>=
lim
{
error
(
~
"missing type in conversion"
);
}
let
tstr
=
str
::
substr
(
s
,
i
,
1u
);
// TODO: Do we really want two signed types here?
// How important is it to be printf compatible?
let
t
=
if
str
::
eq
(
tstr
,
~
"b"
)
{
ty_bool
}
else
if
str
::
eq
(
tstr
,
~
"s"
)
{
ty_str
}
else
if
str
::
eq
(
tstr
,
~
"c"
)
{
ty_char
}
else
if
str
::
eq
(
tstr
,
~
"d"
)
||
str
::
eq
(
tstr
,
~
"i"
)
{
ty_int
(
signed
)
}
else
if
str
::
eq
(
tstr
,
~
"u"
)
{
ty_int
(
unsigned
)
}
else
if
str
::
eq
(
tstr
,
~
"x"
)
{
ty_hex
(
case_lower
)
}
else
if
str
::
eq
(
tstr
,
~
"X"
)
{
ty_hex
(
case_upper
)
}
else
if
str
::
eq
(
tstr
,
~
"t"
)
{
ty_bits
}
else
if
str
::
eq
(
tstr
,
~
"o"
)
{
ty_octal
}
else
{
error
(
~
"unknown type in conversion: "
+
tstr
)
};
ret
{
ty
:
t
,
next
:
i
+
1u
};
}
}
// Functions used by the fmt extension at runtime. For now there are a lot of
// decisions made a runtime. If it proves worthwhile then some of these
// conditions can be evaluated at compile-time. For now though it's cleaner to
// implement it this way, I think.
mod
rt
{
tag
flag
{
flag_left_justify
;
flag_left_zero_pad
;
flag_space_for_sign
;
flag_sign_always
;
flag_alternate
;
// FIXME: This is a hack to avoid creating 0-length vec exprs,
// which have some difficulty typechecking currently. See
// comments in front::extfmt::make_flags
flag_none
;
}
tag
count
{
count_is
(
int
);
count_implied
;
}
tag
ty
{
ty_default
;
ty_bits
;
ty_hex_upper
;
ty_hex_lower
;
ty_octal
;
}
// FIXME: May not want to use a vector here for flags;
// instead just use a bool per flag
type
conv
=
{
flags
:
[
flag
],
width
:
count
,
precision
:
count
,
ty
:
ty
};
fn
conv_int
(
cv
:
&
conv
,
i
:
int
)
->
istr
{
let
radix
=
10u
;
let
prec
=
get_int_precision
(
cv
);
let
s
=
int_to_str_prec
(
i
,
radix
,
prec
);
if
0
<=
i
{
if
have_flag
(
cv
.flags
,
flag_sign_always
)
{
s
=
~
"+"
+
s
;
}
else
if
have_flag
(
cv
.flags
,
flag_space_for_sign
)
{
s
=
~
" "
+
s
;
}
}
ret
pad
(
cv
,
s
,
pad_signed
);
}
fn
conv_uint
(
cv
:
&
conv
,
u
:
uint
)
->
istr
{
let
prec
=
get_int_precision
(
cv
);
let
rs
=
alt
cv
.ty
{
ty_default
.
{
uint_to_str_prec
(
u
,
10u
,
prec
)
}
ty_hex_lower
.
{
uint_to_str_prec
(
u
,
16u
,
prec
)
}
ty_hex_upper
.
{
str
::
to_upper
(
uint_to_str_prec
(
u
,
16u
,
prec
))
}
ty_bits
.
{
uint_to_str_prec
(
u
,
2u
,
prec
)
}
ty_octal
.
{
uint_to_str_prec
(
u
,
8u
,
prec
)
}
};
ret
pad
(
cv
,
rs
,
pad_unsigned
);
}
fn
conv_bool
(
cv
:
&
conv
,
b
:
bool
)
->
istr
{
let
s
=
if
b
{
~
"true"
}
else
{
~
"false"
};
// run the boolean conversion through the string conversion logic,
// giving it the same rules for precision, etc.
ret
conv_str
(
cv
,
s
);
}
fn
conv_char
(
cv
:
&
conv
,
c
:
char
)
->
istr
{
ret
pad
(
cv
,
str
::
from_char
(
c
),
pad_nozero
);
}
fn
conv_str
(
cv
:
&
conv
,
s
:
&
istr
)
->
istr
{
// For strings, precision is the maximum characters
// displayed
// FIXME: substr works on bytes, not chars!
let
unpadded
=
alt
cv
.precision
{
count_implied
.
{
s
}
count_is
(
max
)
{
if
max
as
uint
<
str
::
char_len
(
s
)
{
str
::
substr
(
s
,
0u
,
max
as
uint
)
}
else
{
s
}
}
};
ret
pad
(
cv
,
unpadded
,
pad_nozero
);
}
// Convert an int to string with minimum number of digits. If precision is
// 0 and num is 0 then the result is the empty string.
fn
int_to_str_prec
(
num
:
int
,
radix
:
uint
,
prec
:
uint
)
->
istr
{
ret
if
num
<
0
{
~
"-"
+
uint_to_str_prec
(
-
num
as
uint
,
radix
,
prec
)
}
else
{
uint_to_str_prec
(
num
as
uint
,
radix
,
prec
)
};
}
// Convert a uint to string with a minimum number of digits. If precision
// is 0 and num is 0 then the result is the empty string. Could move this
// to uint: but it doesn't seem all that useful.
fn
uint_to_str_prec
(
num
:
uint
,
radix
:
uint
,
prec
:
uint
)
->
istr
{
ret
if
prec
==
0u
&&
num
==
0u
{
~
""
}
else
{
let
s
=
uint
::
to_str
(
num
,
radix
);
let
len
=
str
::
char_len
(
s
);
if
len
<
prec
{
let
diff
=
prec
-
len
;
let
pad
=
str_init_elt
(
'0'
,
diff
);
pad
+
s
}
else
{
s
}
};
}
fn
get_int_precision
(
cv
:
&
conv
)
->
uint
{
ret
alt
cv
.precision
{
count_is
(
c
)
{
c
as
uint
}
count_implied
.
{
1u
}
};
}
// FIXME: This might be useful in str: but needs to be utf8 safe first
fn
str_init_elt
(
c
:
char
,
n_elts
:
uint
)
->
istr
{
let
svec
=
vec
::
init_elt
::
<
u8
>
(
c
as
u8
,
n_elts
);
ret
str
::
unsafe_from_bytes
(
svec
);
}
tag
pad_mode
{
pad_signed
;
pad_unsigned
;
pad_nozero
;
}
fn
pad
(
cv
:
&
conv
,
s
:
&
istr
,
mode
:
pad_mode
)
->
istr
{
let
uwidth
;
alt
cv
.width
{
count_implied
.
{
ret
s
;
}
count_is
(
width
)
{
// FIXME: Maybe width should be uint
uwidth
=
width
as
uint
;
}
}
let
strlen
=
str
::
char_len
(
s
);
if
uwidth
<=
strlen
{
ret
s
;
}
let
padchar
=
' '
;
let
diff
=
uwidth
-
strlen
;
if
have_flag
(
cv
.flags
,
flag_left_justify
)
{
let
padstr
=
str_init_elt
(
padchar
,
diff
);
ret
s
+
padstr
;
}
let
might_zero_pad
=
false
;
let
signed
=
false
;
alt
mode
{
pad_nozero
.
{
// fallthrough
}
pad_signed
.
{
might_zero_pad
=
true
;
signed
=
true
;
}
pad_unsigned
.
{
might_zero_pad
=
true
;
}
}
fn
have_precision
(
cv
:
&
conv
)
->
bool
{
ret
alt
cv
.precision
{
count_implied
.
{
false
}
_
{
true
}
};
}
let
zero_padding
=
false
;
if
might_zero_pad
&&
have_flag
(
cv
.flags
,
flag_left_zero_pad
)
&&
!
have_precision
(
cv
)
{
padchar
=
'0'
;
zero_padding
=
true
;
}
let
padstr
=
str_init_elt
(
padchar
,
diff
);
// This is completely heinous. If we have a signed value then
// potentially rip apart the intermediate result and insert some
// zeros. It may make sense to convert zero padding to a precision
// instead.
if
signed
&&
zero_padding
&&
str
::
byte_len
(
s
)
>
0u
{
let
head
=
s
[
0
];
if
head
==
'+'
as
u8
||
head
==
'-'
as
u8
||
head
==
' '
as
u8
{
let
headstr
=
str
::
unsafe_from_bytes
([
head
]);
let
bytelen
=
str
::
byte_len
(
s
);
let
numpart
=
str
::
substr
(
s
,
1u
,
bytelen
-
1u
);
ret
headstr
+
padstr
+
numpart
;
}
}
ret
padstr
+
s
;
}
fn
have_flag
(
flags
:
&
[
flag
],
f
:
flag
)
->
bool
{
for
candidate
:
flag
in
flags
{
if
candidate
==
f
{
ret
true
;
}
}
ret
false
;
}
}
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
src/lib/extifmt.rs
浏览文件 @
6972f075
// FIXME: Transitional. Remove me
/* The 'fmt' extension is modeled on the posix printf system.
*
...
...
src/lib/std.rc
浏览文件 @
6972f075
...
...
@@ -85,6 +85,7 @@ mod sort;
mod sha1;
mod ebml;
mod ufind;
mod extfmt;
mod extifmt;
mod box;
mod getopts;
...
...
src/test/compile-fail/extfmt-unsigned-plus.rs
浏览文件 @
6972f075
// error-pattern:only valid in signed #
i
fmt conversion
// error-pattern:only valid in signed #fmt conversion
fn
main
()
{
// Can't use a sign on unsigned conversions
...
...
src/test/compile-fail/extfmt-unsigned-space.rs
浏览文件 @
6972f075
// error-pattern:only valid in signed #
i
fmt conversion
// error-pattern:only valid in signed #fmt conversion
fn
main
()
{
// Can't use a space on unsigned conversions
...
...
src/test/run-pass/syntax-extension-fmt.rs
浏览文件 @
6972f075
...
...
@@ -8,10 +8,10 @@ fn test(actual: &istr, expected: &istr) {
}
fn
main
()
{
test
(
#
i
fmt
[
~
"hello %d friends and %s things"
,
10
,
~
"formatted"
],
test
(
#
fmt
[
~
"hello %d friends and %s things"
,
10
,
~
"formatted"
],
~
"hello 10 friends and formatted things"
);
test
(
#
i
fmt
[
~
"test"
],
~
"test"
);
test
(
#
fmt
[
~
"test"
],
~
"test"
);
// a quadratic optimization in LLVM (jump-threading) makes this test a
// bit slow to compile unless we break it up
...
...
@@ -26,192 +26,192 @@ fn main() {
fn
part1
()
{
// Simple tests for types
test
(
#
i
fmt
[
~
"%d"
,
1
],
~
"1"
);
test
(
#
i
fmt
[
~
"%i"
,
2
],
~
"2"
);
test
(
#
i
fmt
[
~
"%i"
,
-
1
],
~
"-1"
);
test
(
#
i
fmt
[
~
"%u"
,
10u
],
~
"10"
);
test
(
#
i
fmt
[
~
"%s"
,
~
"test"
],
~
"test"
);
test
(
#
i
fmt
[
~
"%b"
,
true
],
~
"true"
);
test
(
#
i
fmt
[
~
"%b"
,
false
],
~
"false"
);
test
(
#
i
fmt
[
~
"%c"
,
'A'
],
~
"A"
);
test
(
#
i
fmt
[
~
"%x"
,
0xff_u
],
~
"ff"
);
test
(
#
i
fmt
[
~
"%X"
,
0x12ab_u
],
~
"12AB"
);
test
(
#
i
fmt
[
~
"%o"
,
10u
],
~
"12"
);
test
(
#
i
fmt
[
~
"%t"
,
0b11010101_u
],
~
"11010101"
);
test
(
#
fmt
[
~
"%d"
,
1
],
~
"1"
);
test
(
#
fmt
[
~
"%i"
,
2
],
~
"2"
);
test
(
#
fmt
[
~
"%i"
,
-
1
],
~
"-1"
);
test
(
#
fmt
[
~
"%u"
,
10u
],
~
"10"
);
test
(
#
fmt
[
~
"%s"
,
~
"test"
],
~
"test"
);
test
(
#
fmt
[
~
"%b"
,
true
],
~
"true"
);
test
(
#
fmt
[
~
"%b"
,
false
],
~
"false"
);
test
(
#
fmt
[
~
"%c"
,
'A'
],
~
"A"
);
test
(
#
fmt
[
~
"%x"
,
0xff_u
],
~
"ff"
);
test
(
#
fmt
[
~
"%X"
,
0x12ab_u
],
~
"12AB"
);
test
(
#
fmt
[
~
"%o"
,
10u
],
~
"12"
);
test
(
#
fmt
[
~
"%t"
,
0b11010101_u
],
~
"11010101"
);
// 32-bit limits
test
(
#
i
fmt
[
~
"%i"
,
-
2147483648
],
~
"-2147483648"
);
test
(
#
i
fmt
[
~
"%i"
,
2147483647
],
~
"2147483647"
);
test
(
#
i
fmt
[
~
"%u"
,
4294967295u
],
~
"4294967295"
);
test
(
#
i
fmt
[
~
"%x"
,
0xffffffff_u
],
~
"ffffffff"
);
test
(
#
i
fmt
[
~
"%o"
,
0xffffffff_u
],
~
"37777777777"
);
test
(
#
i
fmt
[
~
"%t"
,
0xffffffff_u
],
~
"11111111111111111111111111111111"
);
test
(
#
fmt
[
~
"%i"
,
-
2147483648
],
~
"-2147483648"
);
test
(
#
fmt
[
~
"%i"
,
2147483647
],
~
"2147483647"
);
test
(
#
fmt
[
~
"%u"
,
4294967295u
],
~
"4294967295"
);
test
(
#
fmt
[
~
"%x"
,
0xffffffff_u
],
~
"ffffffff"
);
test
(
#
fmt
[
~
"%o"
,
0xffffffff_u
],
~
"37777777777"
);
test
(
#
fmt
[
~
"%t"
,
0xffffffff_u
],
~
"11111111111111111111111111111111"
);
}
fn
part2
()
{
// Widths
test
(
#
i
fmt
[
~
"%1d"
,
500
],
~
"500"
);
test
(
#
i
fmt
[
~
"%10d"
,
500
],
~
" 500"
);
test
(
#
i
fmt
[
~
"%10d"
,
-
500
],
~
" -500"
);
test
(
#
i
fmt
[
~
"%10u"
,
500u
],
~
" 500"
);
test
(
#
i
fmt
[
~
"%10s"
,
~
"test"
],
~
" test"
);
test
(
#
i
fmt
[
~
"%10b"
,
true
],
~
" true"
);
test
(
#
i
fmt
[
~
"%10x"
,
0xff_u
],
~
" ff"
);
test
(
#
i
fmt
[
~
"%10X"
,
0xff_u
],
~
" FF"
);
test
(
#
i
fmt
[
~
"%10o"
,
10u
],
~
" 12"
);
test
(
#
i
fmt
[
~
"%10t"
,
0xff_u
],
~
" 11111111"
);
test
(
#
i
fmt
[
~
"%10c"
,
'A'
],
~
" A"
);
test
(
#
fmt
[
~
"%1d"
,
500
],
~
"500"
);
test
(
#
fmt
[
~
"%10d"
,
500
],
~
" 500"
);
test
(
#
fmt
[
~
"%10d"
,
-
500
],
~
" -500"
);
test
(
#
fmt
[
~
"%10u"
,
500u
],
~
" 500"
);
test
(
#
fmt
[
~
"%10s"
,
~
"test"
],
~
" test"
);
test
(
#
fmt
[
~
"%10b"
,
true
],
~
" true"
);
test
(
#
fmt
[
~
"%10x"
,
0xff_u
],
~
" ff"
);
test
(
#
fmt
[
~
"%10X"
,
0xff_u
],
~
" FF"
);
test
(
#
fmt
[
~
"%10o"
,
10u
],
~
" 12"
);
test
(
#
fmt
[
~
"%10t"
,
0xff_u
],
~
" 11111111"
);
test
(
#
fmt
[
~
"%10c"
,
'A'
],
~
" A"
);
// Left justify
test
(
#
i
fmt
[
~
"%-10d"
,
500
],
~
"500 "
);
test
(
#
i
fmt
[
~
"%-10d"
,
-
500
],
~
"-500 "
);
test
(
#
i
fmt
[
~
"%-10u"
,
500u
],
~
"500 "
);
test
(
#
i
fmt
[
~
"%-10s"
,
~
"test"
],
~
"test "
);
test
(
#
i
fmt
[
~
"%-10b"
,
true
],
~
"true "
);
test
(
#
i
fmt
[
~
"%-10x"
,
0xff_u
],
~
"ff "
);
test
(
#
i
fmt
[
~
"%-10X"
,
0xff_u
],
~
"FF "
);
test
(
#
i
fmt
[
~
"%-10o"
,
10u
],
~
"12 "
);
test
(
#
i
fmt
[
~
"%-10t"
,
0xff_u
],
~
"11111111 "
);
test
(
#
i
fmt
[
~
"%-10c"
,
'A'
],
~
"A "
);
test
(
#
fmt
[
~
"%-10d"
,
500
],
~
"500 "
);
test
(
#
fmt
[
~
"%-10d"
,
-
500
],
~
"-500 "
);
test
(
#
fmt
[
~
"%-10u"
,
500u
],
~
"500 "
);
test
(
#
fmt
[
~
"%-10s"
,
~
"test"
],
~
"test "
);
test
(
#
fmt
[
~
"%-10b"
,
true
],
~
"true "
);
test
(
#
fmt
[
~
"%-10x"
,
0xff_u
],
~
"ff "
);
test
(
#
fmt
[
~
"%-10X"
,
0xff_u
],
~
"FF "
);
test
(
#
fmt
[
~
"%-10o"
,
10u
],
~
"12 "
);
test
(
#
fmt
[
~
"%-10t"
,
0xff_u
],
~
"11111111 "
);
test
(
#
fmt
[
~
"%-10c"
,
'A'
],
~
"A "
);
}
fn
part3
()
{
// Precision
test
(
#
i
fmt
[
~
"%.d"
,
0
],
~
""
);
test
(
#
i
fmt
[
~
"%.u"
,
0u
],
~
""
);
test
(
#
i
fmt
[
~
"%.x"
,
0u
],
~
""
);
test
(
#
i
fmt
[
~
"%.t"
,
0u
],
~
""
);
test
(
#
i
fmt
[
~
"%.d"
,
10
],
~
"10"
);
test
(
#
i
fmt
[
~
"%.d"
,
-
10
],
~
"-10"
);
test
(
#
i
fmt
[
~
"%.u"
,
10u
],
~
"10"
);
test
(
#
i
fmt
[
~
"%.s"
,
~
"test"
],
~
""
);
test
(
#
i
fmt
[
~
"%.x"
,
127u
],
~
"7f"
);
test
(
#
i
fmt
[
~
"%.o"
,
10u
],
~
"12"
);
test
(
#
i
fmt
[
~
"%.t"
,
3u
],
~
"11"
);
test
(
#
i
fmt
[
~
"%.c"
,
'A'
],
~
"A"
);
test
(
#
i
fmt
[
~
"%.0d"
,
0
],
~
""
);
test
(
#
i
fmt
[
~
"%.0u"
,
0u
],
~
""
);
test
(
#
i
fmt
[
~
"%.0x"
,
0u
],
~
""
);
test
(
#
i
fmt
[
~
"%.0t"
,
0u
],
~
""
);
test
(
#
i
fmt
[
~
"%.0d"
,
10
],
~
"10"
);
test
(
#
i
fmt
[
~
"%.0d"
,
-
10
],
~
"-10"
);
test
(
#
i
fmt
[
~
"%.0u"
,
10u
],
~
"10"
);
test
(
#
i
fmt
[
~
"%.0s"
,
~
"test"
],
~
""
);
test
(
#
i
fmt
[
~
"%.0x"
,
127u
],
~
"7f"
);
test
(
#
i
fmt
[
~
"%.0o"
,
10u
],
~
"12"
);
test
(
#
i
fmt
[
~
"%.0t"
,
3u
],
~
"11"
);
test
(
#
i
fmt
[
~
"%.0c"
,
'A'
],
~
"A"
);
test
(
#
i
fmt
[
~
"%.1d"
,
0
],
~
"0"
);
test
(
#
i
fmt
[
~
"%.1u"
,
0u
],
~
"0"
);
test
(
#
i
fmt
[
~
"%.1x"
,
0u
],
~
"0"
);
test
(
#
i
fmt
[
~
"%.1t"
,
0u
],
~
"0"
);
test
(
#
i
fmt
[
~
"%.1d"
,
10
],
~
"10"
);
test
(
#
i
fmt
[
~
"%.1d"
,
-
10
],
~
"-10"
);
test
(
#
i
fmt
[
~
"%.1u"
,
10u
],
~
"10"
);
test
(
#
i
fmt
[
~
"%.1s"
,
~
"test"
],
~
"t"
);
test
(
#
i
fmt
[
~
"%.1x"
,
127u
],
~
"7f"
);
test
(
#
i
fmt
[
~
"%.1o"
,
10u
],
~
"12"
);
test
(
#
i
fmt
[
~
"%.1t"
,
3u
],
~
"11"
);
test
(
#
i
fmt
[
~
"%.1c"
,
'A'
],
~
"A"
);
test
(
#
fmt
[
~
"%.d"
,
0
],
~
""
);
test
(
#
fmt
[
~
"%.u"
,
0u
],
~
""
);
test
(
#
fmt
[
~
"%.x"
,
0u
],
~
""
);
test
(
#
fmt
[
~
"%.t"
,
0u
],
~
""
);
test
(
#
fmt
[
~
"%.d"
,
10
],
~
"10"
);
test
(
#
fmt
[
~
"%.d"
,
-
10
],
~
"-10"
);
test
(
#
fmt
[
~
"%.u"
,
10u
],
~
"10"
);
test
(
#
fmt
[
~
"%.s"
,
~
"test"
],
~
""
);
test
(
#
fmt
[
~
"%.x"
,
127u
],
~
"7f"
);
test
(
#
fmt
[
~
"%.o"
,
10u
],
~
"12"
);
test
(
#
fmt
[
~
"%.t"
,
3u
],
~
"11"
);
test
(
#
fmt
[
~
"%.c"
,
'A'
],
~
"A"
);
test
(
#
fmt
[
~
"%.0d"
,
0
],
~
""
);
test
(
#
fmt
[
~
"%.0u"
,
0u
],
~
""
);
test
(
#
fmt
[
~
"%.0x"
,
0u
],
~
""
);
test
(
#
fmt
[
~
"%.0t"
,
0u
],
~
""
);
test
(
#
fmt
[
~
"%.0d"
,
10
],
~
"10"
);
test
(
#
fmt
[
~
"%.0d"
,
-
10
],
~
"-10"
);
test
(
#
fmt
[
~
"%.0u"
,
10u
],
~
"10"
);
test
(
#
fmt
[
~
"%.0s"
,
~
"test"
],
~
""
);
test
(
#
fmt
[
~
"%.0x"
,
127u
],
~
"7f"
);
test
(
#
fmt
[
~
"%.0o"
,
10u
],
~
"12"
);
test
(
#
fmt
[
~
"%.0t"
,
3u
],
~
"11"
);
test
(
#
fmt
[
~
"%.0c"
,
'A'
],
~
"A"
);
test
(
#
fmt
[
~
"%.1d"
,
0
],
~
"0"
);
test
(
#
fmt
[
~
"%.1u"
,
0u
],
~
"0"
);
test
(
#
fmt
[
~
"%.1x"
,
0u
],
~
"0"
);
test
(
#
fmt
[
~
"%.1t"
,
0u
],
~
"0"
);
test
(
#
fmt
[
~
"%.1d"
,
10
],
~
"10"
);
test
(
#
fmt
[
~
"%.1d"
,
-
10
],
~
"-10"
);
test
(
#
fmt
[
~
"%.1u"
,
10u
],
~
"10"
);
test
(
#
fmt
[
~
"%.1s"
,
~
"test"
],
~
"t"
);
test
(
#
fmt
[
~
"%.1x"
,
127u
],
~
"7f"
);
test
(
#
fmt
[
~
"%.1o"
,
10u
],
~
"12"
);
test
(
#
fmt
[
~
"%.1t"
,
3u
],
~
"11"
);
test
(
#
fmt
[
~
"%.1c"
,
'A'
],
~
"A"
);
}
fn
part4
()
{
test
(
#
i
fmt
[
~
"%.5d"
,
0
],
~
"00000"
);
test
(
#
i
fmt
[
~
"%.5u"
,
0u
],
~
"00000"
);
test
(
#
i
fmt
[
~
"%.5x"
,
0u
],
~
"00000"
);
test
(
#
i
fmt
[
~
"%.5t"
,
0u
],
~
"00000"
);
test
(
#
i
fmt
[
~
"%.5d"
,
10
],
~
"00010"
);
test
(
#
i
fmt
[
~
"%.5d"
,
-
10
],
~
"-00010"
);
test
(
#
i
fmt
[
~
"%.5u"
,
10u
],
~
"00010"
);
test
(
#
i
fmt
[
~
"%.5s"
,
~
"test"
],
~
"test"
);
test
(
#
i
fmt
[
~
"%.5x"
,
127u
],
~
"0007f"
);
test
(
#
i
fmt
[
~
"%.5o"
,
10u
],
~
"00012"
);
test
(
#
i
fmt
[
~
"%.5t"
,
3u
],
~
"00011"
);
test
(
#
i
fmt
[
~
"%.5c"
,
'A'
],
~
"A"
);
test
(
#
fmt
[
~
"%.5d"
,
0
],
~
"00000"
);
test
(
#
fmt
[
~
"%.5u"
,
0u
],
~
"00000"
);
test
(
#
fmt
[
~
"%.5x"
,
0u
],
~
"00000"
);
test
(
#
fmt
[
~
"%.5t"
,
0u
],
~
"00000"
);
test
(
#
fmt
[
~
"%.5d"
,
10
],
~
"00010"
);
test
(
#
fmt
[
~
"%.5d"
,
-
10
],
~
"-00010"
);
test
(
#
fmt
[
~
"%.5u"
,
10u
],
~
"00010"
);
test
(
#
fmt
[
~
"%.5s"
,
~
"test"
],
~
"test"
);
test
(
#
fmt
[
~
"%.5x"
,
127u
],
~
"0007f"
);
test
(
#
fmt
[
~
"%.5o"
,
10u
],
~
"00012"
);
test
(
#
fmt
[
~
"%.5t"
,
3u
],
~
"00011"
);
test
(
#
fmt
[
~
"%.5c"
,
'A'
],
~
"A"
);
// Bool precision. I'm not sure if it's good or bad to have bool
// conversions support precision - it's not standard printf so we
// can do whatever. For now I'm making it behave the same as string
// conversions.
test
(
#
i
fmt
[
~
"%.b"
,
true
],
~
""
);
test
(
#
i
fmt
[
~
"%.0b"
,
true
],
~
""
);
test
(
#
i
fmt
[
~
"%.1b"
,
true
],
~
"t"
);
test
(
#
fmt
[
~
"%.b"
,
true
],
~
""
);
test
(
#
fmt
[
~
"%.0b"
,
true
],
~
""
);
test
(
#
fmt
[
~
"%.1b"
,
true
],
~
"t"
);
}
fn
part5
()
{
// Explicit + sign. Only for signed conversions
test
(
#
i
fmt
[
~
"%+d"
,
0
],
~
"+0"
);
test
(
#
i
fmt
[
~
"%+d"
,
1
],
~
"+1"
);
test
(
#
i
fmt
[
~
"%+d"
,
-
1
],
~
"-1"
);
test
(
#
fmt
[
~
"%+d"
,
0
],
~
"+0"
);
test
(
#
fmt
[
~
"%+d"
,
1
],
~
"+1"
);
test
(
#
fmt
[
~
"%+d"
,
-
1
],
~
"-1"
);
// Leave space for sign
test
(
#
i
fmt
[
~
"% d"
,
0
],
~
" 0"
);
test
(
#
i
fmt
[
~
"% d"
,
1
],
~
" 1"
);
test
(
#
i
fmt
[
~
"% d"
,
-
1
],
~
"-1"
);
test
(
#
fmt
[
~
"% d"
,
0
],
~
" 0"
);
test
(
#
fmt
[
~
"% d"
,
1
],
~
" 1"
);
test
(
#
fmt
[
~
"% d"
,
-
1
],
~
"-1"
);
// Plus overrides space
test
(
#
i
fmt
[
~
"% +d"
,
0
],
~
"+0"
);
test
(
#
i
fmt
[
~
"%+ d"
,
0
],
~
"+0"
);
test
(
#
fmt
[
~
"% +d"
,
0
],
~
"+0"
);
test
(
#
fmt
[
~
"%+ d"
,
0
],
~
"+0"
);
// 0-padding
test
(
#
i
fmt
[
~
"%05d"
,
0
],
~
"00000"
);
test
(
#
i
fmt
[
~
"%05d"
,
1
],
~
"00001"
);
test
(
#
i
fmt
[
~
"%05d"
,
-
1
],
~
"-0001"
);
test
(
#
i
fmt
[
~
"%05u"
,
1u
],
~
"00001"
);
test
(
#
i
fmt
[
~
"%05x"
,
127u
],
~
"0007f"
);
test
(
#
i
fmt
[
~
"%05X"
,
127u
],
~
"0007F"
);
test
(
#
i
fmt
[
~
"%05o"
,
10u
],
~
"00012"
);
test
(
#
i
fmt
[
~
"%05t"
,
3u
],
~
"00011"
);
test
(
#
fmt
[
~
"%05d"
,
0
],
~
"00000"
);
test
(
#
fmt
[
~
"%05d"
,
1
],
~
"00001"
);
test
(
#
fmt
[
~
"%05d"
,
-
1
],
~
"-0001"
);
test
(
#
fmt
[
~
"%05u"
,
1u
],
~
"00001"
);
test
(
#
fmt
[
~
"%05x"
,
127u
],
~
"0007f"
);
test
(
#
fmt
[
~
"%05X"
,
127u
],
~
"0007F"
);
test
(
#
fmt
[
~
"%05o"
,
10u
],
~
"00012"
);
test
(
#
fmt
[
~
"%05t"
,
3u
],
~
"00011"
);
// 0-padding a string is undefined but glibc does this:
test
(
#
i
fmt
[
~
"%05s"
,
~
"test"
],
~
" test"
);
test
(
#
i
fmt
[
~
"%05c"
,
'A'
],
~
" A"
);
test
(
#
i
fmt
[
~
"%05b"
,
true
],
~
" true"
);
test
(
#
fmt
[
~
"%05s"
,
~
"test"
],
~
" test"
);
test
(
#
fmt
[
~
"%05c"
,
'A'
],
~
" A"
);
test
(
#
fmt
[
~
"%05b"
,
true
],
~
" true"
);
// Left-justify overrides 0-padding
test
(
#
i
fmt
[
~
"%-05d"
,
0
],
~
"0 "
);
test
(
#
i
fmt
[
~
"%-05d"
,
1
],
~
"1 "
);
test
(
#
i
fmt
[
~
"%-05d"
,
-
1
],
~
"-1 "
);
test
(
#
i
fmt
[
~
"%-05u"
,
1u
],
~
"1 "
);
test
(
#
i
fmt
[
~
"%-05x"
,
127u
],
~
"7f "
);
test
(
#
i
fmt
[
~
"%-05X"
,
127u
],
~
"7F "
);
test
(
#
i
fmt
[
~
"%-05o"
,
10u
],
~
"12 "
);
test
(
#
i
fmt
[
~
"%-05t"
,
3u
],
~
"11 "
);
test
(
#
i
fmt
[
~
"%-05s"
,
~
"test"
],
~
"test "
);
test
(
#
i
fmt
[
~
"%-05c"
,
'A'
],
~
"A "
);
test
(
#
i
fmt
[
~
"%-05b"
,
true
],
~
"true "
);
test
(
#
fmt
[
~
"%-05d"
,
0
],
~
"0 "
);
test
(
#
fmt
[
~
"%-05d"
,
1
],
~
"1 "
);
test
(
#
fmt
[
~
"%-05d"
,
-
1
],
~
"-1 "
);
test
(
#
fmt
[
~
"%-05u"
,
1u
],
~
"1 "
);
test
(
#
fmt
[
~
"%-05x"
,
127u
],
~
"7f "
);
test
(
#
fmt
[
~
"%-05X"
,
127u
],
~
"7F "
);
test
(
#
fmt
[
~
"%-05o"
,
10u
],
~
"12 "
);
test
(
#
fmt
[
~
"%-05t"
,
3u
],
~
"11 "
);
test
(
#
fmt
[
~
"%-05s"
,
~
"test"
],
~
"test "
);
test
(
#
fmt
[
~
"%-05c"
,
'A'
],
~
"A "
);
test
(
#
fmt
[
~
"%-05b"
,
true
],
~
"true "
);
}
fn
part6
()
{
// Precision overrides 0-padding
test
(
#
i
fmt
[
~
"%06.5d"
,
0
],
~
" 00000"
);
test
(
#
i
fmt
[
~
"%06.5u"
,
0u
],
~
" 00000"
);
test
(
#
i
fmt
[
~
"%06.5x"
,
0u
],
~
" 00000"
);
test
(
#
i
fmt
[
~
"%06.5d"
,
10
],
~
" 00010"
);
test
(
#
i
fmt
[
~
"%06.5d"
,
-
10
],
~
"-00010"
);
test
(
#
i
fmt
[
~
"%06.5u"
,
10u
],
~
" 00010"
);
test
(
#
i
fmt
[
~
"%06.5s"
,
~
"test"
],
~
" test"
);
test
(
#
i
fmt
[
~
"%06.5c"
,
'A'
],
~
" A"
);
test
(
#
i
fmt
[
~
"%06.5x"
,
127u
],
~
" 0007f"
);
test
(
#
i
fmt
[
~
"%06.5X"
,
127u
],
~
" 0007F"
);
test
(
#
i
fmt
[
~
"%06.5o"
,
10u
],
~
" 00012"
);
test
(
#
fmt
[
~
"%06.5d"
,
0
],
~
" 00000"
);
test
(
#
fmt
[
~
"%06.5u"
,
0u
],
~
" 00000"
);
test
(
#
fmt
[
~
"%06.5x"
,
0u
],
~
" 00000"
);
test
(
#
fmt
[
~
"%06.5d"
,
10
],
~
" 00010"
);
test
(
#
fmt
[
~
"%06.5d"
,
-
10
],
~
"-00010"
);
test
(
#
fmt
[
~
"%06.5u"
,
10u
],
~
" 00010"
);
test
(
#
fmt
[
~
"%06.5s"
,
~
"test"
],
~
" test"
);
test
(
#
fmt
[
~
"%06.5c"
,
'A'
],
~
" A"
);
test
(
#
fmt
[
~
"%06.5x"
,
127u
],
~
" 0007f"
);
test
(
#
fmt
[
~
"%06.5X"
,
127u
],
~
" 0007F"
);
test
(
#
fmt
[
~
"%06.5o"
,
10u
],
~
" 00012"
);
// Signed combinations
test
(
#
i
fmt
[
~
"% 5d"
,
1
],
~
" 1"
);
test
(
#
i
fmt
[
~
"% 5d"
,
-
1
],
~
" -1"
);
test
(
#
i
fmt
[
~
"%+5d"
,
1
],
~
" +1"
);
test
(
#
i
fmt
[
~
"%+5d"
,
-
1
],
~
" -1"
);
test
(
#
i
fmt
[
~
"% 05d"
,
1
],
~
" 0001"
);
test
(
#
i
fmt
[
~
"% 05d"
,
-
1
],
~
"-0001"
);
test
(
#
i
fmt
[
~
"%+05d"
,
1
],
~
"+0001"
);
test
(
#
i
fmt
[
~
"%+05d"
,
-
1
],
~
"-0001"
);
test
(
#
i
fmt
[
~
"%- 5d"
,
1
],
~
" 1 "
);
test
(
#
i
fmt
[
~
"%- 5d"
,
-
1
],
~
"-1 "
);
test
(
#
i
fmt
[
~
"%-+5d"
,
1
],
~
"+1 "
);
test
(
#
i
fmt
[
~
"%-+5d"
,
-
1
],
~
"-1 "
);
test
(
#
i
fmt
[
~
"%- 05d"
,
1
],
~
" 1 "
);
test
(
#
i
fmt
[
~
"%- 05d"
,
-
1
],
~
"-1 "
);
test
(
#
i
fmt
[
~
"%-+05d"
,
1
],
~
"+1 "
);
test
(
#
i
fmt
[
~
"%-+05d"
,
-
1
],
~
"-1 "
);
test
(
#
fmt
[
~
"% 5d"
,
1
],
~
" 1"
);
test
(
#
fmt
[
~
"% 5d"
,
-
1
],
~
" -1"
);
test
(
#
fmt
[
~
"%+5d"
,
1
],
~
" +1"
);
test
(
#
fmt
[
~
"%+5d"
,
-
1
],
~
" -1"
);
test
(
#
fmt
[
~
"% 05d"
,
1
],
~
" 0001"
);
test
(
#
fmt
[
~
"% 05d"
,
-
1
],
~
"-0001"
);
test
(
#
fmt
[
~
"%+05d"
,
1
],
~
"+0001"
);
test
(
#
fmt
[
~
"%+05d"
,
-
1
],
~
"-0001"
);
test
(
#
fmt
[
~
"%- 5d"
,
1
],
~
" 1 "
);
test
(
#
fmt
[
~
"%- 5d"
,
-
1
],
~
"-1 "
);
test
(
#
fmt
[
~
"%-+5d"
,
1
],
~
"+1 "
);
test
(
#
fmt
[
~
"%-+5d"
,
-
1
],
~
"-1 "
);
test
(
#
fmt
[
~
"%- 05d"
,
1
],
~
" 1 "
);
test
(
#
fmt
[
~
"%- 05d"
,
-
1
],
~
"-1 "
);
test
(
#
fmt
[
~
"%-+05d"
,
1
],
~
"+1 "
);
test
(
#
fmt
[
~
"%-+05d"
,
-
1
],
~
"-1 "
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录