Skip to content

Commit d46bb2c

Browse files
brsongraydon
authored andcommitted
---
yaml --- r: 1483 b: refs/heads/master c: 012c2d1 h: refs/heads/master i: 1481: 7971721 1479: 7743b24 v: v3
1 parent 3d194b9 commit d46bb2c

File tree

2 files changed

+90
-8
lines changed

2 files changed

+90
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 4bc9052e135c25c79d4fa8556c44876e620ba1f7
2+
refs/heads/master: 012c2d18d04f27ad52322a1a7673a14817c7d291

trunk/src/comp/front/extfmt.rs

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ fn expand_syntax_ext(vec[@ast.expr] args,
8181
}
8282

8383
auto fmt = expr_to_str(args.(0));
84+
85+
log "Format string:";
86+
log fmt;
87+
8488
auto pieces = parse_fmt_string(fmt);
8589
auto args_len = _vec.len[@ast.expr](args);
8690
auto fmt_args = _vec.slice[@ast.expr](args, 1u, args_len - 1u);
@@ -170,7 +174,7 @@ fn peek_num(str s, uint i, uint lim) -> option.t[tup(uint, uint)] {
170174
fn parse_conversion(str s, uint i, uint lim) -> tup(piece, uint) {
171175
auto parm = parse_parameter(s, i, lim);
172176
auto flags = parse_flags(s, parm._1, lim);
173-
auto width = parse_width(s, flags._1, lim);
177+
auto width = parse_count(s, flags._1, lim);
174178
auto prec = parse_precision(s, width._1, lim);
175179
auto ty = parse_type(s, prec._1, lim);
176180
ret tup(piece_conv(rec(param = parm._0,
@@ -192,22 +196,100 @@ fn parse_parameter(str s, uint i, uint lim) -> tup(option.t[int], uint) {
192196
ret tup(none[int], i);
193197
}
194198
case (some[tup(uint, uint)](?t)) {
195-
fail;
199+
auto n = t._0;
200+
auto j = t._1;
201+
if (j < lim && s.(j) == '$' as u8) {
202+
ret tup(some[int](n as int), j + 1u);
203+
}
204+
else {
205+
ret tup(none[int], i);
206+
}
196207
}
197208
}
198209
}
199210

200211
fn parse_flags(str s, uint i, uint lim) -> tup(vec[flag], uint) {
201-
let vec[flag] flags = vec();
202-
ret tup(flags, i);
212+
let vec[flag] noflags = vec();
213+
214+
if (i >= lim) {
215+
ret tup(noflags, i);
216+
}
217+
218+
fn more_(flag f, str s, uint i, uint lim) -> tup(vec[flag], uint) {
219+
auto next = parse_flags(s, i + 1u, lim);
220+
auto rest = next._0;
221+
auto j = next._1;
222+
let vec[flag] curr = vec(f);
223+
ret tup(curr + rest, j);
224+
}
225+
226+
auto more = bind more_(_, s, i, lim);
227+
228+
auto f = s.(i);
229+
if (f == ('-' as u8)) {
230+
ret more(flag_left_justify);
231+
} else if (f == ('0' as u8)) {
232+
ret more(flag_left_zero_pad);
233+
} else if (f == (' ' as u8)) {
234+
ret more(flag_left_space_pad);
235+
} else if (f == ('+' as u8)) {
236+
ret more(flag_plus_if_positive);
237+
} else if (f == ('#' as u8)) {
238+
ret more(flag_alternate);
239+
} else {
240+
ret tup(noflags, i);
241+
}
203242
}
204243

205-
fn parse_width(str s, uint i, uint lim) -> tup(count, uint) {
206-
ret tup(count_implied, i);
244+
fn parse_count(str s, uint i, uint lim) -> tup(count, uint) {
245+
if (i >= lim) {
246+
ret tup(count_implied, i);
247+
}
248+
249+
// FIXME: These inner functions are just to avoid a rustboot
250+
// "Unsatisfied precondition constraint" bug with alts nested in ifs
251+
fn parse_star_count(str s, uint i, uint lim) -> tup(count, uint) {
252+
auto param = parse_parameter(s, i + 1u, lim);
253+
auto j = param._1;
254+
alt (param._0) {
255+
case (none[int]) {
256+
ret tup(count_is_next_param, j);
257+
}
258+
case (some[int](?n)) {
259+
ret tup(count_is_param(n), j);
260+
}
261+
}
262+
}
263+
264+
fn parse_count_(str s, uint i, uint lim) -> tup(count, uint) {
265+
auto num = peek_num(s, i, lim);
266+
alt (num) {
267+
case (none[tup(uint, uint)]) {
268+
ret tup(count_implied, i);
269+
}
270+
case (some[tup(uint, uint)](?num)) {
271+
ret tup(count_is(num._0 as int), num._1);
272+
}
273+
}
274+
}
275+
276+
if (s.(i) == ('*' as u8)) {
277+
ret parse_star_count(s, i, lim);
278+
} else {
279+
ret parse_count_(s, i, lim);
280+
}
207281
}
208282

209283
fn parse_precision(str s, uint i, uint lim) -> tup(count, uint) {
210-
ret tup(count_implied, i);
284+
if (i >= lim) {
285+
ret tup(count_implied, i);
286+
}
287+
288+
if (s.(i) == '.' as u8) {
289+
ret parse_count(s, i + 1u, lim);
290+
} else {
291+
ret tup(count_implied, i);
292+
}
211293
}
212294

213295
fn parse_type(str s, uint i, uint lim) -> tup(ty, uint) {

0 commit comments

Comments
 (0)