2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
5 Internal utility functions.
8 #include <aros/debug.h>
9 #include <aros/system.h>
10 #include "alib_intern.h"
12 /******************************************************************************
15 VOID
GetDataStreamFromFormat (
20 RAWARG dataStream
, ULONG
*dataSize
,
21 ULONG
*indexStream
, ULONG
*indexSize
)
24 Builds an array of parameters which are passed on the stack.
25 This function is used on machines which have compilers which
26 don't pass the arguments to a varargs function unlike the
30 format - Exec/RawDoFmt or Locale/FormatString format string
31 args - This has to be initialized by va_start()
32 (not used if dataStream is NULL)
33 dataStream - data buffer to write to
34 (can be NULL for sizing)
35 dataSize - size of the buffer
36 (can be NULL, or pointer to 0 for sizing)
37 updated to the actual size required at exit.
38 indexStream- array of offsets to the Nth element in the dataStream
39 (can be NULL for sizing)
40 indexSize - size of the index, in bytes
41 (can be NULL, or pointer to 0 for sizing)
42 updated to the actual size required at exit.
45 An array which can be passed to any function which expects the
46 structure or NULL if something failed. This call may fail for
47 different reasons on different systems. On some systems, NULL
48 indicates that there was not enough memory.
51 This structure converts from format types to the following
52 dataStream values in the returned structure. The dataStream
53 is suitable for use by Exec/RawDoFmt or Locale/FormatString,
54 and is packed on WORD alignment. The indexStream is used
55 internally by Locale/FormatString for format repositioning.
57 Format code GET_ARG() type Datastream type
58 ----------- ------------- ---------------
59 %c char (really int) WORD
61 %u/%U unsigned int UWORD
62 %x/%X unsigned int UWORD
67 %ll<cdDuUxX> QUAD QUAD
76 exec.library/RawDoFmt(), locale.library/FormatString()
80 ******************************************************************************/
82 size_t len
= dataSize
? *dataSize
: 0;
83 int ilen
= (indexSize
? *indexSize
: 0) / sizeof(indexStream
[0]);
87 size_t size_force
= 0;
88 BOOL in_format
= FALSE
;
90 size_t vsize
= 0, dsize
= 0;
91 unsigned int argpos
= 0;
93 #define IFLAG_SIGNED (1UL << 31)
94 #define IFLAG_VSIZE(x) ((x) << 16)
95 #define IFLAG_VSIZE_of(x) (((x) >> 16) & 0xf)
96 #define IFLAG_DSIZE(x) ((x) << 0)
97 #define IFLAG_DSIZE_of(x) (((x) >> 0) & 0xf)
98 #define GET_ARG(args, type) (dataStream ? va_arg(args, type) : 0)
100 for (size
= 0; format
&& *format
; format
++) {
102 if (*format
== '%') {
111 if (*format
== '%') {
116 /* Ignore non-argument characters */
117 if ((*format
>= '0' && *format
<= '9')) {
118 argpos
= (argpos
* 10) + (*format
- '0');
132 size_force
= sizeof(IPTR
);
135 if (size_force
>= sizeof(LONG
))
136 size_force
= sizeof(QUAD
);
138 size_force
= sizeof(LONG
);
143 dsize
= sizeof(WORD
);
144 iflags
|= IFLAG_SIGNED
;
147 case 'c': /* char is promoted to int through (fmt, ...) */
152 vsize
= sizeof(unsigned int);
153 dsize
= sizeof(WORD
);
159 vsize
= sizeof(void *);
160 dsize
= sizeof(IPTR
);
165 vsize
= sizeof(BPTR
);
166 dsize
= sizeof(BPTR
);
171 dsize
= sizeof(WORD
);
176 if (in_format
== FALSE
) {
177 D(bug("%s: '%c' l=%d (v=%d, d=%d)\n", __func__
, *format
, size_force
, vsize
, dsize
));
183 iflags
|= IFLAG_VSIZE(vsize
);
184 iflags
|= IFLAG_DSIZE(dsize
);
187 indexStream
[isize
] = iflags
;
196 /* Convert indexStream flags into offsets
197 * into the datastream. If the datastream
198 * is present, assume we have to pull its
199 * data from the va_list.
204 for (i
= 0; i
< imax
&& i
< ilen
; i
++) {
206 CONST_APTR buff
= (CONST_APTR
)((IPTR
)dataStream
+ size
);
207 ULONG iflags
= indexStream
[i
];
209 D(bug("%s: indexStream[%d] = %d\n", __func__
, i
, (int)size
));
210 indexStream
[i
] = size
;
211 size
+= IFLAG_DSIZE_of(iflags
);
216 /* dataStream present - pull its data from the va_list.
218 switch (IFLAG_VSIZE_of(iflags
)) {
220 if (iflags
& IFLAG_SIGNED
)
221 arg_val
= (SIPTR
)va_arg(args
, LONG
);
223 arg_val
= (IPTR
)va_arg(args
, ULONG
);
226 if (iflags
& IFLAG_SIGNED
)
227 arg_val
= (SIPTR
)va_arg(args
, QUAD
);
229 arg_val
= (IPTR
)va_arg(args
, UQUAD
);
232 if (iflags
& IFLAG_SIGNED
)
233 arg_val
= (SIPTR
)va_arg(args
, int);
235 arg_val
= (IPTR
)va_arg(args
, int);
239 D(bug("%s: dataStream len = 0x%x (%d)\n", __func__
, (unsigned int)len
, dataSize
? (int)*dataSize
: -1));
240 D(bug("%s: dataStream + 0x%x (%d) = 0x%p\n", __func__
, (int)((IPTR
)buff
- (IPTR
)dataStream
), IFLAG_DSIZE_of(iflags
), (void *)arg_val
));
242 switch (IFLAG_DSIZE_of(iflags
)) {
244 *((UWORD
*)buff
) = (UWORD
)arg_val
;
247 *((ULONG
*)buff
) = (ULONG
)arg_val
;
250 *((UQUAD
*)buff
) = (UQUAD
)arg_val
;
261 *indexSize
= imax
* sizeof(indexStream
[0]);
262 } /* GetDataStreamFromFormat */