Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Ticket #1042: patch.1

File patch.1, 8.9 kB (added by fawzi, 5 months ago)

slightly cleaned up patch

Line 
1 Index: Layout.d
2 ===================================================================
3 --- Layout.d    (revision 3447)
4 +++ Layout.d    (working copy)
5 @@ -51,6 +51,71 @@
6          alias void* ArgList;
7          }
8  
9 +version(GNU) {
10 +    /+
11 +     + Template to get arbitrary structures out of va_arg
12 +     + assumes that all argument of the same size are treated in the same way
13 +     + this is needed due to the bad implementation of va_arg in gdc see
14 +     +
15 +     +/
16 +    private const int maxStore=64;
17 +    private struct StoreEl{byte[maxStore] st;};
18 +   
19 +    private va_list dummy;
20 +    static if (is(typeof(dummy.ptr))){
21 +    /+ ugly workaround for the missing way to pass inout va_list on X86-64 +/
22 +    void *dynGetArgT(int s1,int s2)(in TypeInfo ti, va_list argptr,out StoreEl el){
23 +        const int m = (s1+s2)/2;
24 +        static if (s1 < s2){
25 +            if (ti.tsize > m) {
26 +                return dynGetArgT!(m+1,s2)(ti,argptr,el);
27 +            } else {
28 +                return dynGetArgT!(s1,m)(ti,argptr,el);
29 +            }
30 +        }
31 +        else{
32 +            if (ti.tsize == m)
33 +            {
34 +                struct ms{byte[m] mse;};
35 +                ms *st=cast(ms*)&el;
36 +                *st=va_arg!(ms)(argptr);
37 +                return cast(void *)st;
38 +            } else {
39 +                throw new Exception("hit max size of dyn_va_argT increase maxStore");
40 +            }
41 +        }
42 +    }
43 +    void *dynGetArg(in TypeInfo ti, va_list argptr,out StoreEl el){
44 +        return dynGetArgT!(1,maxStore)(ti,argptr,el);
45 +    }
46 +    }else{
47 +    void *dynGetArgT(int s1,int s2)(in TypeInfo ti,inout va_list argptr,out StoreEl el){
48 +        const int m = (s1+s2)/2;
49 +        static if (s1 < s2){
50 +            if (ti.tsize > m) {
51 +                return dynGetArgT!(m+1,s2)(ti,argptr,el);
52 +            } else {
53 +                return dynGetArgT!(s1,m)(ti,argptr,el);
54 +            }
55 +        }
56 +        else{
57 +            if (ti.tsize == m)
58 +            {
59 +                struct ms{byte[m] mse;};
60 +                ms *st=cast(ms*)&el;
61 +                *st=va_arg!(ms)(argptr);
62 +                return cast(void *)st;
63 +            } else {
64 +                throw new Exception("hit max size of dyn_va_argT increase maxStore");
65 +            }
66 +        }
67 +    }
68 +    void *dynGetArg(in TypeInfo ti, inout va_list argptr,out StoreEl el){
69 +        return dynGetArgT!(1,maxStore)(ti,argptr,el);
70 +    }
71 +    }   
72 +}
73 +
74  /*******************************************************************************
75  
76          Contains methods for replacing format items in a string with string
77 @@ -184,77 +249,45 @@
78          version (GNU)
79                  {
80                  Arg[64] arglist = void;
81 -                int[64] intargs = void;
82 -                byte[64] byteargs = void;
83 -                long[64] longargs = void;
84 -                short[64] shortargs = void;
85 -                void[][64] voidargs = void;
86                  real[64] realargs = void;
87                  float[64] floatargs = void;
88                  double[64] doubleargs = void;
89 -
90 +                StoreEl[64] bigargs = void;
91 +               
92                  foreach (i, arg; arguments)
93 -                        {
94 -                        static if (is(typeof(args.ptr)))
95 -                            arglist[i] = args.ptr;
96 -                        else
97 -                            arglist[i] = args;
98 -                        /* Since floating point types don't live on
99 -                         * the stack, they must be accessed by the
100 -                         * correct type. */
101 -                        bool converted = false;
102 -                        switch (arg.classinfo.name[9])
103 -                               {
104 -                               case TypeCode.FLOAT:
105 -                                    floatargs[i] = va_arg!(float)(args);
106 -                                    arglist[i] = &floatargs[i];
107 -                                    converted = true;
108 -                                    break;
109 +                    {
110 +                            /* Since floating point types don't live on
111 +                             * the stack, they must be accessed by the
112 +                             * correct type. */
113 +                            bool converted = false;
114 +                            switch (arg.classinfo.name[9])
115 +                                   {
116 +                                   case TypeCode.FLOAT:
117 +                                        floatargs[i] = va_arg!(float)(args);
118 +                                        arglist[i] = &floatargs[i];
119 +                                        converted = true;
120 +                                        break;
121  
122 -                               case TypeCode.DOUBLE:
123 -                                    doubleargs[i] = va_arg!(double)(args);
124 -                                    arglist[i] = &doubleargs[i];
125 -                                    converted = true;
126 -                                    break;
127 +                                   case TypeCode.DOUBLE:
128 +                                        doubleargs[i] = va_arg!(double)(args);
129 +                                        arglist[i] = &doubleargs[i];
130 +                                        converted = true;
131 +                                        break;
132  
133 -                               case TypeCode.REAL:
134 -                                    realargs[i] = va_arg!(real)(args);
135 -                                    arglist[i] = &realargs[i];
136 -                                    converted = true;
137 -                                    break;
138 +                                   case TypeCode.REAL:
139 +                                        realargs[i] = va_arg!(real)(args);
140 +                                        arglist[i] = &realargs[i];
141 +                                        converted = true;
142 +                                        break;
143  
144 -                               default:
145 -                                    break;
146 +                                   default:
147 +                                        break;
148                                  }
149 -                        if (! converted)
150 -                           {
151 -                           switch (arg.tsize)
152 -                                  {
153 -                                  case 1:
154 -                                       byteargs[i] = va_arg!(byte)(args);
155 -                                       arglist[i] = &byteargs[i];
156 -                                       break;
157 -                                  case 2:
158 -                                       shortargs[i] = va_arg!(short)(args);
159 -                                       arglist[i] = &shortargs[i];
160 -                                       break;
161 -                                  case 4:
162 -                                       intargs[i] = va_arg!(int)(args);
163 -                                       arglist[i] = &intargs[i];
164 -                                       break;
165 -                                  case 8:
166 -                                       longargs[i] = va_arg!(long)(args);
167 -                                       arglist[i] = &longargs[i];
168 -                                       break;
169 -                                  case 16:
170 -                                       voidargs[i] = va_arg!(void[])(args);
171 -                                       arglist[i] = &voidargs[i];
172 -                                       break;
173 -                                  default:
174 -                                       assert (false, "Unknown size: " ~ Integer.toString (arg.tsize));
175 -                                  }
176 -                           }
177 -                        }
178 +                            if (! converted)
179 +                               {
180 +                                   arglist[i] = dynGetArg(arg,args,bigargs[i]);
181 +                               }
182 +                      }
183                  }
184               else
185                  {
186 @@ -815,7 +848,8 @@
187          assert( Formatter( "d{{0}d", "<string>" ) == "d{0}d");
188          assert( Formatter( "d{{{0}d", "<string>" ) == "d{<string>d");
189          assert( Formatter( "d{0}}d", "<string>" ) == "d<string>}d");
190 -
191 +        assert( Formatter( "{} {} {} {} {:x}",1.3f,cast(bool)1,1.4,cast(bool)1, 0xafe0000 ) == "1.30 true 1.40 true afe0000" );
192 +        assert( Formatter( "{} {} {} {} {:x}",0.0f,cast(bool)1,0.0,cast(bool)1, 0xafe0000 ) == "0.00 true 0.00 true afe0000" );
193          assert( Formatter( "{0:x}", 0xafe0000 ) == "afe0000" );
194          // todo: is it correct to print 7 instead of 6 chars???
195          assert( Formatter( "{0:x7}", 0xafe0000 ) == "afe0000" );
196 @@ -891,6 +925,7 @@
197          assert( Formatter( "{:x}", a ) == "[ 33, 34, 35, 36, 37 ]" );
198          assert( Formatter( "{,-4}", a ) == "[ 51  , 52  , 53  , 54  , 55   ]" );
199          assert( Formatter( "{,4}", a ) == "[   51,   52,   53,   54,   55 ]" );
200 +        assert( Formatter( "{} {}", a,cast(byte)21 ) == "[ 51, 52, 53, 54, 55 ] 21" );
201          int[][] b = [ [ 51, 52 ], [ 53, 54, 55 ] ];
202          assert( Formatter( "{}", b ) == "[ [ 51, 52 ], [ 53, 54, 55 ] ]" );
203