some fixes to accented characters
[tangerine.git] / rom / dos / vfwritef.c
blob3ec1e8c216bf170d6f15977f8f43b260a6211482
1 /*
2 Copyright © 1995-2008, 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
34 Write a formatted string (with supplied values) to a specified file.
35 The string may be of any length and the routine is buffered.
36 The following format commands may be used (preceded by a '%') a la 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
53 fh -- file to write the output to
54 fmt -- format string
55 argarray -- pointer to an array of formatting values
57 RESULT
59 The number of bytes written or -1 if there was an error.
61 NOTES
63 EXAMPLE
65 BUGS
67 SEE ALSO
69 VFPrintf(), FPutC()
71 INTERNALS
73 *****************************************************************************/
75 AROS_LIBFUNC_INIT
77 #define bLast (sizeof(ULONG)*8/3 + 1)
79 char buffer[bLast + 1];
81 LONG count = 0; /* Number of characters written */
82 CONST_STRPTR format = fmt;
83 const IPTR *args = argarray;
85 STRPTR string;
86 STRPTR wBuf; /* Pointer to first number character in buffer */
87 LONG len;
88 LONG i; /* Loop variable */
89 LONG number;
90 BOOL minus;
91 BOOL quitNow = FALSE; /* Takes care of the case "...%" as format
92 string */
95 while (*format != 0 && !quitNow)
97 if (*format == '%')
99 format++;
101 switch (*format)
103 case 'S': /* Regular c string */
104 case 's':
105 string = (STRPTR)*args;
106 args++;
108 if (string == NULL)
110 return -1;
113 while (*string != 0)
115 FPutC(fh, *string++);
116 count++;
119 break;
121 case 'T': /* BCPL string (possibly filled out) */
122 case 't':
123 format++;
124 len = *format - '0';
126 if (BADDR(*args) == NULL)
128 return -1;
131 for (i = 0; i < AROS_BSTR_strlen((BSTR)*args); i++)
133 FPutC(fh, AROS_BSTR_getchar((BSTR)*args, i));
134 count++;
137 args++;
139 /* If needed, write out spaces to fill field. */
140 for(; i < len; i++)
142 FPutC(fh, ' ');
143 count++;
146 break;
148 case 'C': /* Character */
149 case 'c':
150 FPutC(fh, (char)*args);
151 count++;
152 args++;
153 break;
155 case 'O': /* Octal number */
156 case 'o':
157 count += putNumber(&format, (IPTR **)&args, 8, fh, DOSBase);
158 break;
160 case 'X': /* Hexadecimal number */
161 case 'x':
162 count += putNumber(&format, (IPTR **)&args, 16, fh, DOSBase);
163 break;
165 case 'I': /* Decimal number */
166 case 'i':
167 count += putNumber(&format, (IPTR **)&args, 10, fh, DOSBase);
168 break;
170 case 'N': /* Decimal number (no length restriction) */
171 case 'n':
172 number = *args;
173 args++;
175 if (number < 0)
177 number = -number;
178 minus = TRUE;
180 else
182 minus = FALSE;
185 buffer[bLast] = 0;
187 /* Write decimal number */
188 wBuf = writeNumber(&buffer[bLast], 10, number, minus, DOSBase);
190 while (*wBuf != 0)
192 FPutC(fh, *wBuf++);
193 count++;
196 break;
198 case 'U': /* Unsigned decimal number */
199 case 'u':
200 format++;
201 len = *format - '0';
203 number = *args;
204 args++;
206 wBuf = writeNumber(&buffer[bLast], 10, number, FALSE, DOSBase);
208 for (i = 0; i < len; i++)
210 FPutC(fh, *wBuf++);
211 count++;
213 if (*wBuf == 0)
215 break;
219 break;
221 case '$': /* Skip argument */
222 args++;
223 break;
225 case 0: /* Stupid user... */
226 quitNow = TRUE;
227 break;
229 default: /* Ability to print '%':s */
230 FPutC(fh, *format);
231 count++;
232 break;
235 else
237 /* A regular character */
238 FPutC(fh, *format);
239 count++;
242 format++;
245 return count;
247 AROS_LIBFUNC_EXIT
248 } /* VFWritef */
251 LONG putNumber(CONST_STRPTR *format, IPTR **args, ULONG base, BPTR fh,
252 struct DosLibrary *DOSBase)
254 char buffer[bLast + 1];
255 LONG icount = 0;
256 LONG number;
257 LONG len; /* Maximum width of number (ASCII) */
258 BOOL minus = FALSE;
259 STRPTR aNum;
260 LONG i; /* Loop variable */
262 buffer[bLast] = 0;
264 (*format)++;
265 len = **format - '0';
267 number = **args;
268 (*args)++;
270 if(number < 0)
272 number = -number;
273 minus = TRUE;
276 aNum = writeNumber(&buffer[bLast], base, number, minus, DOSBase);
278 /* Write the textual number to the file */
279 for (i = 0; i < len; i++)
281 FPutC(fh, *aNum++);
282 icount++;
284 if(*aNum == 0)
285 break;
288 return icount;
289 } /* VFWritef */
292 /* Generate a text string from a number */
293 STRPTR writeNumber(char *buffer, ULONG base, ULONG n, BOOL minus,
294 struct DosLibrary *DOSBase)
296 int val;
300 val = n % base;
301 *--buffer = val < 10 ? val + '0' : val - 10 + 'A';
302 n /= base;
303 } while(n != 0);
305 if (minus)
307 *--buffer = '-';
310 return buffer;