@@ -81,6 +81,10 @@ fn expand_syntax_ext(vec[@ast.expr] args,
81
81
}
82
82
83
83
auto fmt = expr_to_str ( args. ( 0 ) ) ;
84
+
85
+ log "Format string:" ;
86
+ log fmt;
87
+
84
88
auto pieces = parse_fmt_string ( fmt) ;
85
89
auto args_len = _vec. len [ @ast. expr ] ( args) ;
86
90
auto fmt_args = _vec. slice [ @ast. expr ] ( args, 1 u, args_len - 1 u) ;
@@ -170,7 +174,7 @@ fn peek_num(str s, uint i, uint lim) -> option.t[tup(uint, uint)] {
170
174
fn parse_conversion ( str s, uint i, uint lim) -> tup ( piece , uint ) {
171
175
auto parm = parse_parameter ( s, i, lim) ;
172
176
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) ;
174
178
auto prec = parse_precision ( s, width. _1 , lim) ;
175
179
auto ty = parse_type ( s, prec. _1 , lim) ;
176
180
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) {
192
196
ret tup ( none[ int] , i) ;
193
197
}
194
198
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 + 1 u) ;
203
+ }
204
+ else {
205
+ ret tup ( none[ int] , i) ;
206
+ }
196
207
}
197
208
}
198
209
}
199
210
200
211
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 + 1 u, 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
+ }
203
242
}
204
243
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 + 1 u, 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
+ }
207
281
}
208
282
209
283
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 + 1 u, lim) ;
290
+ } else {
291
+ ret tup ( count_implied, i) ;
292
+ }
211
293
}
212
294
213
295
fn parse_type ( str s, uint i, uint lim) -> tup ( ty , uint ) {
0 commit comments