D Paste by Neal Alexander
Description: Compile time printf -> Composite FMT string conversion
Hide line numbers

Create new paste
Post a reply
View replies

Paste:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  

private enum : uint
{
FLdash = 1,
FLplus = 2,
FLspace = 4,
FLhash = 8,
FLlngdbl = 0x20,
FLzpad = 0x40,
FLprecision = 0x80,
}

private  char[] parse(char[] s)
{
    char[] x;
    char[] width, precision;
    char type = '?';
    
    int i;
    uint flags = 0;

    for (i = 1; type == '?'; ++i)
    {
        switch (s[i]){
        case '-': flags |= FLdash; break;
        case '#': flags |= FLhash; break;
        case '0': flags |= FLzpad; break;
        case '+': assert(0); // unsupported
        case ' ': assert(0); // unsupported
        
        default:
        
            if (s[i] == '*')
                assert(0); // unsupported
                
            if (s[i] >= '0' && s[i] <= '9')
            {
                do width ~= s[i++];
                while (s[i] >= '0' && s[i] <= '9');
            }
            
            if (s[i] == '.')
            {
                if (s[++i] == '*')
                    assert(0); // unsupported
                
                else if (s[i] >= '0' && s[i] <= '9')
                {
                    flags |= FLprecision;
                    
                    do precision ~= s[i++];
                    while (s[i] >= '0' && s[i] <= '9');
                }
            }
            
            type = get_type(s[i]);
            
            if (type == '%')
                return "%";
        }
    }
    
    if (flags & FLplus)
        flags &= ~FLspace;
    
    if (flags & FLdash)
        flags &= ~FLzpad;
    
    if (flags & FLhash)
    {
        if (type == 'x' || type == 'X')
            x ~= "0x";

        else if (type == 'o')
            x ~= "0";
            
        // e, E, f, F, g, G decimal not needed?
    }
    
    x ~= "{";
    
    if (width && (flags & FLzpad) == 0)
    {
        x ~= ',';
        
        if (flags & FLdash)
            x ~= '-';
            
        x ~= width;
    }
    
    if (type != 's')
    {
        x ~= ":" ~ type;

        if (flags & FLzpad)
            x ~= width;
        
        if (flags & FLprecision)
            x ~= precision;
    }
    
    x ~= '}';
    
    
    return x;
}

private char get_type(char c)
{
    switch (c){
    case '%': return '%';
    case 'c': return 'c';
    case 'u': return 'u';
    case 'o': return 'o';
    case 'x': return 'x';
    case 'X': return 'X';
    case 's': return 's';
    case 'i':
    case 'd': return 'd';
    case 'e': return 'e';
    case 'E': return 'E';
    case 'f': return 'f';
    case 'F': return 'F';
    case 'g': return 'g';
    case 'G': return 'G';
    case 'p': return 'x';
    case 'a':
    case 'A': assert(0);
    default : return '?';
    }
}

private int skip(char[] s)
{
    int n = 1;
    
    for (char t = '?'; t == '?'; ++n)
        t = get_type(s[n]);
  
    return n;
}

template FMT(char[] s)
{ 
    static if (s.length == 0)
        const char[] FMT = s;
    else
    {
        static if (s[0] == '%')
            const char[] FMT = parse(s) ~ FMT!(s[skip(s) .. $]);
        else
            const char[] FMT = s[0] ~ FMT!(s[1 .. $]);             
    }
}





Replies:

    (some replies deleted)