revert between 56095 -> 55830 in arch
[AROS.git] / rom / dos / vfwritef.c
blob2ca826e10c9cc40c93bc61309aa48906ae94cb83
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
8 #include "dos_intern.h"
9 #include <dos/bptr.h>
10 #include <string.h>
12 LONG putNumber(CONST_STRPTR *format, IPTR **args, ULONG base, BPTR fh,
13 struct DosLibrary *DOSBase);
14 STRPTR writeNumber(char *buffer, ULONG base, ULONG n, BOOL minus,
15 struct DosLibrary *DOSBase);
17 /*****************************************************************************
19 NAME */
20 #include <proto/dos.h>
22 AROS_LH3(LONG, VFWritef,
24 /* SYNOPSIS */
25 AROS_LHA(BPTR , fh , D1),
26 AROS_LHA(CONST_STRPTR, fmt , D2),
27 AROS_LHA(const IPTR *, argarray, D3),
29 /* LOCATION */
30 struct DosLibrary *, DOSBase, 58, Dos)
32 /* FUNCTION
33 Write a formatted string (with supplied values) to a specified file.
34 The string may be of any length and the routine is buffered.
35 The following format commands may be used (preceded by a '%') a la
36 printf().
38 S - string (C style)
39 Tx - writes a left justified string padding it to be (at least)
40 x bytes long
41 C - character
42 Ox - octal number; maximum width x characters
43 Xx - hexadecimal number; maximum width x characters
44 Ix - decimal number; maximum width x chararcters
45 N - decimal number; any length
46 Ux - unsigned decimal number; maximum width x characters
47 $ - ignore parameter
49 Note: 'x' above is the character value - '0'.
51 INPUTS
52 fh - file to write the output to
53 fmt - format string
54 argarray - pointer to an array of formatting values
56 RESULT
57 The number of bytes written or -1 if there was an error.
59 NOTES
61 EXAMPLE
63 BUGS
65 SEE ALSO
66 VFPrintf(), FPutC()
68 INTERNALS
70 *****************************************************************************/
72 AROS_LIBFUNC_INIT
74 #define bLast (sizeof(ULONG)*8/3 + 1)
76 char buffer[bLast + 1];
78 LONG count = 0; /* Number of characters written */
79 CONST_STRPTR format = fmt;
80 const IPTR *args = argarray;
82 STRPTR string;
83 STRPTR wBuf; /* Pointer to first number character in buffer */
84 LONG len;
85 LONG i; /* Loop variable */
86 LONG number;
87 BOOL minus;
88 BOOL quitNow = FALSE; /* Takes care of the case "...%" as format
89 string */
92 while (*format != 0 && !quitNow)
94 if (*format == '%')
96 format++;
98 switch (*format)
100 case 'S': /* Regular c string */
101 case 's':
102 string = (STRPTR)*args;
103 args++;
105 if (string == NULL)
107 return -1;
110 while (*string != 0)
112 FPutC(fh, *string++);
113 count++;
116 break;
118 case 'T': /* BCPL string (possibly filled out) */
119 case 't':
120 format++;
121 len = *format - '0';
123 if (BADDR(*args) == NULL)
125 return -1;
128 for (i = 0; i < AROS_BSTR_strlen((BSTR)*args); i++)
130 FPutC(fh, AROS_BSTR_getchar((BSTR)*args, i));
131 count++;
134 args++;
136 /* If needed, write out spaces to fill field. */
137 for(; i < len; i++)
139 FPutC(fh, ' ');
140 count++;
143 break;
145 case 'C': /* Character */
146 case 'c':
147 FPutC(fh, (char)*args);
148 count++;
149 args++;
150 break;
152 case 'O': /* Octal number */
153 case 'o':
154 count += putNumber(&format, (IPTR **)&args, 8, fh, DOSBase);
155 break;
157 case 'X': /* Hexadecimal number */
158 case 'x':
159 count += putNumber(&format, (IPTR **)&args, 16, fh, DOSBase);
160 break;
162 case 'I': /* Decimal number */
163 case 'i':
164 count += putNumber(&format, (IPTR **)&args, 10, fh, DOSBase);
165 break;
167 case 'N': /* Decimal number (no length restriction) */
168 case 'n':
169 number = *args;
170 args++;
172 if (number < 0)
174 number = -number;
175 minus = TRUE;
177 else
179 minus = FALSE;
182 buffer[bLast] = 0;
184 /* Write decimal number */
185 wBuf = writeNumber(&buffer[bLast], 10, number, minus, DOSBase);
187 while (*wBuf != 0)
189 FPutC(fh, *wBuf++);
190 count++;
193 break;
195 case 'U': /* Unsigned decimal number */
196 case 'u':
197 format++;
198 len = *format - '0';
200 number = *args;
201 args++;
203 wBuf = writeNumber(&buffer[bLast], 10, number, FALSE, DOSBase);
205 for (i = 0; i < len; i++)
207 FPutC(fh, *wBuf++);
208 count++;
210 if (*wBuf == 0)
212 break;
216 break;
218 case '$': /* Skip argument */
219 args++;
220 break;
222 case 0: /* Stupid user... */
223 quitNow = TRUE;
224 break;
226 default: /* Ability to print '%':s */
227 FPutC(fh, *format);
228 count++;
229 break;
232 else
234 /* A regular character */
235 FPutC(fh, *format);
236 count++;
239 format++;
242 return count;
244 AROS_LIBFUNC_EXIT
245 } /* VFWritef */
248 LONG putNumber(CONST_STRPTR *format, IPTR **args, ULONG base, BPTR fh,
249 struct DosLibrary *DOSBase)
251 char buffer[bLast + 1];
252 LONG icount = 0;
253 LONG number;
254 LONG len; /* Maximum width of number (ASCII) */
255 BOOL minus = FALSE;
256 STRPTR aNum;
257 LONG i; /* Loop variable */
259 buffer[bLast] = 0;
261 (*format)++;
262 len = **format - '0';
264 number = **args;
265 (*args)++;
267 if(number < 0)
269 number = -number;
270 minus = TRUE;
273 aNum = writeNumber(&buffer[bLast], base, number, minus, DOSBase);
275 /* Write the textual number to the file */
276 for (i = 0; i < len; i++)
278 FPutC(fh, *aNum++);
279 icount++;
281 if(*aNum == 0)
282 break;
285 return icount;
286 } /* VFWritef */
289 /* Generate a text string from a number */
290 STRPTR writeNumber(char *buffer, ULONG base, ULONG n, BOOL minus,
291 struct DosLibrary *DOSBase)
293 int val;
297 val = n % base;
298 *--buffer = val < 10 ? val + '0' : val - 10 + 'A';
299 n /= base;
300 } while(n != 0);
302 if (minus)
304 *--buffer = '-';
307 return buffer;