summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-11-26 12:19:52 +0800
committerJohn Hodge <tpg@mutabah.net>2016-11-26 12:19:52 +0800
commit2fc13a07c606005ab9e89ba85cd347e622a76a15 (patch)
treee293c11cf4d00b4e80818f03890550f95d64f0c6 /src
parent6697029a0d71a886538caac6eaf1ebdaa7cf0fb3 (diff)
downloadmrust-2fc13a07c606005ab9e89ba85cd347e622a76a15.tar.gz
Expand/format_args! - Handle named argument for width
Diffstat (limited to 'src')
-rw-r--r--src/expand/format_args.cpp43
1 files changed, 36 insertions, 7 deletions
diff --git a/src/expand/format_args.cpp b/src/expand/format_args.cpp
index 6881e19a..9f4eaa93 100644
--- a/src/expand/format_args.cpp
+++ b/src/expand/format_args.cpp
@@ -157,10 +157,10 @@ namespace {
}
// Debugging: A view of the formatting fragment
- //const char* s2 = s;
- //while(*s2 && *s2 != '}')
- // s2 ++;
- //auto fmt_frag_str = string_view { s, s2 };
+ const char* s2 = s;
+ while(*s2 && *s2 != '}')
+ s2 ++;
+ auto fmt_frag_str = string_view { s, s2 };
unsigned int index = ~0u;
const char* trait_name;
@@ -271,6 +271,31 @@ namespace {
//args.width_is_arg = false;
}
}
+ else if( ::std::isalpha(*s) ) {
+ // Parse an ident and if the next character is $, convert to named
+ // - Otherwise keep the ident around for the formatter
+
+ const char* start = s;
+ while( isalnum(*s) || *s == '_' || (*s < 0 || *s > 127) ) {
+ s ++;
+ }
+ if( *s == '$' )
+ {
+ ::std::string ident { start, s };
+ auto it = named.find(ident);
+ if( it == named.end() )
+ ERROR(sp, E0000, "Named argument '"<<ident<<"' not found");
+ args.width = n_free + it->second;
+ args.width_is_arg = true;
+
+ s ++;
+ }
+ else {
+ s = start;
+ }
+ }
+ else {
+ }
// Precision
if( *s == '.' ) {
s ++;
@@ -283,7 +308,7 @@ namespace {
args.prec = next_free + n_named;
next_free ++;
}
- else {
+ else if( ::std::isdigit(*s) ) {
unsigned int val = 0;
while( ::std::isdigit(*s) )
{
@@ -301,12 +326,15 @@ namespace {
//args.prec_is_arg = false;
}
}
+ else {
+ // Wut?
+ }
}
// Parse ident?
// - Lazy way is to just handle a single char and ensure that it is just a single char
if( s[0] != '}' && s[0] != '\0' && s[1] != '}' ) {
- TODO(sp, "Parse formatting fragment at \"" << s << "\" (long type)");
+ TODO(sp, "Parse formatting fragment at \"" << fmt_frag_str << "\" (long type)");
}
switch(s[0])
@@ -399,6 +427,7 @@ class CFormatArgsExpander:
if( !format_string_np ) {
ERROR(sp, E0000, "format_args! requires a string literal - got " << *n);
}
+ const auto& format_string_sp = format_string_np->span();
const auto& format_string = format_string_np->m_value;
::std::map< ::std::string, unsigned int> named_args_index;
@@ -441,7 +470,7 @@ class CFormatArgsExpander:
// - Parse the format string
::std::vector< FmtFrag> fragments;
::std::string tail;
- ::std::tie( fragments, tail ) = parse_format_string(sp, format_string, named_args_index, free_args.size());
+ ::std::tie( fragments, tail ) = parse_format_string(format_string_sp, format_string, named_args_index, free_args.size());
bool is_simple = true;
for(unsigned int i = 0; i < fragments.size(); i ++)