annotate printf.c @ 0:e3088565a6b8 default tip

*: initial commit kinda dumb, but wifi was out and I was bored. most of this code is shit.
author Paper <paper@tflc.us>
date Wed, 03 Dec 2025 03:04:39 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1 /**
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
2 * "Portable" printf implementation
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
3 *
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
4 * Copyright (c) 2025 Paper
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
5 * Copyright (c) 2005-2012 Rich Felker
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
6 *
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
7 * Permission is hereby granted, free of charge, to any person obtaining
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
8 * a copy of this software and associated documentation files (the
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
9 * "Software"), to deal in the Software without restriction, including
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
10 * without limitation the rights to use, copy, modify, merge, publish,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
11 * distribute, sublicense, and/or sell copies of the Software, and to
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
12 * permit persons to whom the Software is furnished to do so, subject to
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
13 * the following conditions:
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
14 *
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
15 * The above copyright notice and this permission notice shall be
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
16 * included in all copies or substantial portions of the Software.
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
17 *
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
25 *
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
26 * NOTE: Floating point support is very scuffed, and doesn't
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
27 * work for many numbers. It also depends on math.h. If you don't
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
28 * care or don't want floating point support, toggle the #define
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
29 * to disable it.
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
30 *
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
31 * EXTRA NOTE: You don't need malloc() if you turn off wide character
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
32 * support :)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
33 **/
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
34
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
35 #include "printf.h"
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
36
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
37 /* Since C89, but optional because locale shit sucks */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
38 #define HAVE_WCTOMB 1
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
39
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
40 /* strlen has been here since the beginning... */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
41 #define HAVE_STRLEN 1
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
42 /* ... but strnlen is a POSIX invention, added in C23. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
43 /*#define HAVE_STRNLEN 1*/
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
44
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
45 #define HAVE_FLOATING_POINT 1
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
46 #define HAVE_INTMAX_T 1
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
47 #define HAVE_LONG_LONG 1
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
48 #define HAVE_UINTPTR_T 1
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
49 #define HAVE_SIZE_T 1
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
50 #define HAVE_PTRDIFF_T 1
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
51 #define HAVE_LONG_DOUBLE 1
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
52
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
53 /* #define to use sprintf for floats. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
54 #define MY_PRINTF_USE_SPRINTF 1
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
55
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
56 #include <stdarg.h>
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
57 #include <stdio.h> /* stdout, FILE */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
58 #include <limits.h>
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
59 #if defined(HAVE_STRLEN) || defined(HAVE_STRNLEN)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
60 # include <string.h>
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
61 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
62 #ifdef HAVE_WCTOMB
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
63 # include <stdlib.h>
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
64 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
65 #ifdef HAVE_INTMAX_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
66 # include <stdint.h>
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
67 typedef intmax_t my_printf_intmax;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
68 typedef uintmax_t my_printf_uintmax;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
69 #elif defined(HAVE_LONG_LONG)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
70 typedef long long my_printf_intmax;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
71 typedef unsigned long long my_printf_uintmax;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
72 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
73 typedef long my_printf_intmax;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
74 typedef unsigned long my_printf_uintmax;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
75 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
76 #ifdef HAVE_WCTOMB
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
77 # include <wchar.h>
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
78 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
79 #ifdef HAVE_FLOATING_POINT
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
80 # include <math.h> /* fmod */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
81 # include <float.h>
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
82 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
83 #ifdef HAVE_UINTPTR_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
84 # include <stdint.h>
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
85 typedef uintptr_t my_printf_uintptr;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
86 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
87 /* uintmax can probably hold a pointer?? hopefully :) */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
88 typedef my_printf_uintmax my_printf_uintptr;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
89 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
90 #ifdef HAVE_SIZE_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
91 # include <stddef.h>
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
92 typedef size_t my_printf_size;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
93 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
94 typedef my_printf_uintptr my_printf_size;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
95 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
96
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
97 #ifdef HAVE_LONG_DOUBLE
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
98 /* Everything is long double */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
99 typedef long double floatmax;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
100
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
101 # define frexpm frexpl
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
102 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
103 typedef double floatmax;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
104
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
105 # define frexpm frexp
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
106 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
107
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
108 #ifdef HAVE_STRNLEN
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
109 # define my_strnlen strnlen
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
110 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
111 static my_printf_size my_strnlen(const char *s, my_printf_size maxlen)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
112 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
113 my_printf_size len;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
114 for (len = 0; len < maxlen && *s; len++, s++);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
115 return len;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
116 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
117 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
118
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
119 #ifdef HAVE_STRLEN
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
120 # define my_strlen strlen
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
121 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
122 static my_printf_size my_strlen(const char *s)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
123 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
124 my_printf_size len;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
125 for (len = 0; *s; len++, s++);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
126 return len;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
127 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
128 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
129
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
130 #ifdef TEST_MEMORY
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
131 static int my_mem_counter = 0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
132
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
133 /* Make sure our memory allocation code still works,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
134 * even in out of memory conditions */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
135 static void *my_realloc(void *x, my_printf_size sz)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
136 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
137 if (my_mem_counter++ > 4)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
138 return NULL;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
139
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
140 return realloc(x, sz);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
141 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
142
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
143 static void *my_calloc(my_printf_size sz, my_printf_size c)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
144 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
145 if (my_mem_counter++ > 4)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
146 return NULL;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
147
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
148 return calloc(sz, c);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
149 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
150
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
151 static void *my_malloc(my_printf_size sz)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
152 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
153 if (my_mem_counter++ > 4)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
154 return NULL;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
155
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
156 return malloc(sz);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
157 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
158 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
159 # define my_realloc realloc
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
160 # define my_calloc calloc
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
161 # define my_malloc malloc
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
162 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
163
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
164 void my_free(void *x)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
165 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
166 if (x) free(x);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
167 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
168
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
169 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
170 /* ERRORS */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
171
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
172 const char *my_strerror(int err)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
173 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
174 static const char *errs[] = {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
175 "Out of memory",
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
176 "Invalid format string",
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
177 "Invalid or incomplete multibyte or wide character",
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
178 "Value too large to be stored in data type",
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
179 };
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
180
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
181 err = abs(err) - 1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
182
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
183 if (err < 0 || err >= sizeof(errs))
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
184 return NULL;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
185
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
186 return errs[err];
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
187 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
188
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
189 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
190 /* FLAGS */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
191
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
192 enum flags {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
193 FLAG_JUSTIFY_LEFT = 0x01,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
194 FLAG_PLUS = 0x02,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
195 FLAG_SPACE = 0x04,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
196 FLAG_HASH = 0x08,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
197 FLAG_ZERO = 0x10
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
198 };
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
199
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
200 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
201 /* CONVERT SIZE_T TO SIGNED
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
202 * - this is required for handling %zd correctly on odd systems
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
203 * - basically any compiler ever (besides msvc) will do dead code removal
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
204 * because sizeof() is a compile time constant
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
205 * - we cannot do this in the preprocessor unless SIZE_MAX is defined... */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
206
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
207 #ifdef HAVE_SIZE_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
208 static my_printf_intmax my_size_t_sign(size_t x)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
209 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
210 #define IF(type) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
211 if (sizeof(size_t) == sizeof(type)) { \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
212 union { type s; size_t ss; } u; \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
213 u.ss = x; \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
214 return u.s; \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
215 } else \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
216
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
217 IF(signed char)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
218 IF(signed short)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
219 IF(signed int)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
220 IF(signed long)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
221 #ifdef HAVE_LONG_LONG
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
222 IF(signed long long)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
223 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
224 #ifdef HAVE_PTRDIFF_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
225 IF(ptrdiff_t)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
226 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
227 /* hope this works */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
228 return (my_printf_intmax)x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
229 #undef IF
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
230 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
231 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
232
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
233 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
234 /* CHAR PRINTING */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
235
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
236 static void print_chars(put_spec put,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
237 void *opaque, my_printf_uintmax *pnum, unsigned char c, unsigned long width)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
238 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
239 *pnum += width;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
240 while (width-- > 0)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
241 put(opaque, c);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
242 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
243
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
244 #define print_spaces(a,b,c,d) print_chars(a,b,c,' ',d)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
245
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
246 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
247 /* STRING PRINTING */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
248
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
249 static void putstring(put_spec put, void *opaque, const char *s,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
250 my_printf_size len, my_printf_uintmax *num, my_printf_uintmax width, int justify_left)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
251 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
252 my_printf_size i;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
253
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
254 /* Handle width */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
255 if (!justify_left && width > len)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
256 print_spaces(put, opaque, num, width - len);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
257
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
258 for (i = 0; i < len; i++)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
259 put(opaque, s[i]);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
260 *num += len;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
261
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
262 if (justify_left && width > len)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
263 print_spaces(put, opaque, num, width - len);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
264 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
265
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
266 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
267 /* NUMBER PRINTING */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
268
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
269 static my_printf_uintmax my_numput_width(my_printf_uintmax d, int radix)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
270 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
271 my_printf_uintmax x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
272 my_printf_uintmax width;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
273
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
274 /* ... */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
275 for (width = 0, x = d; x >= 1; width++, x /= radix);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
276 width--; /* ;) */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
277
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
278 return width;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
279 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
280
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
281 static void my_numput_ex(put_spec put,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
282 void *opaque, my_printf_uintmax d, int radix, const char trans[36],
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
283 my_printf_uintmax *num)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
284 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
285 /* This is terrible but it doesn't need a intermediate buffer */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
286 my_printf_uintmax x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
287 my_printf_uintmax width, i;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
288
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
289 /* ... */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
290 width = my_numput_width(d, radix);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
291
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
292 for (i = 0, x = 1; i < width; x *= radix, i++);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
293
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
294 while (x >= 1) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
295 put(opaque, trans[d / x]);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
296 ++*num;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
297 d %= x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
298 x /= radix;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
299 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
300 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
301
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
302 /* note: for radix 2-10, the translation table doesn't actually matter. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
303 static void my_numput_lower(put_spec put,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
304 void *opaque, my_printf_uintmax d, int radix, my_printf_uintmax *num)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
305 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
306 static const char trans[36] = "0123456789abcdefghijklmnopqrstuvwxyz";
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
307 my_numput_ex(put, opaque, d, radix, trans, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
308 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
309
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
310 static void my_numput_upper(put_spec put,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
311 void *opaque, my_printf_uintmax d, int radix, my_printf_uintmax *num)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
312 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
313 static const char trans[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
314 my_numput_ex(put, opaque, d, radix, trans, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
315 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
316
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
317 static void my_numput(put_spec put,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
318 void *opaque, my_printf_uintmax d, int radix, my_printf_uintmax *num,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
319 int hash, const char *hash_str, my_printf_size hash_strlen,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
320 my_printf_uintmax width, int justify_left, int zero,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
321 int upper)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
322 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
323 if (hash) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
324 putstring(put, opaque, hash_str, hash_strlen, num, 0, 0);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
325 if (width >= 2) width -= 2;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
326 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
327
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
328 if (width > 0) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
329 my_printf_uintmax len;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
330
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
331 /* This is disgusting. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
332 len = my_numput_width(d, 16);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
333
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
334 if ((!justify_left && !zero) && len + 1 < width)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
335 print_chars(put, opaque, num, ' ', width - len - 1);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
336
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
337 if (zero && len + 1 < width)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
338 print_chars(put, opaque, num, '0', width - len - 1);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
339
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
340
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
341 (upper ? my_numput_upper : my_numput_lower)(put, opaque, d, radix, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
342
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
343 if ((justify_left) && len + 1 < width)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
344 print_spaces(put, opaque, num, width - len - 1);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
345 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
346 (upper ? my_numput_upper : my_numput_lower)(put, opaque, d, radix, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
347 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
348 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
349
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
350 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
351 /* FLOATING POINT
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
352 *
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
353 * The following code was taken from musl libc. I won't even pretend to
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
354 * understand it. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
355
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
356 #ifdef HAVE_FLOATING_POINT
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
357 # ifndef isnan
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
358 static int isnan(floatmax d)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
359 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
360 return (d != d);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
361 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
362 # endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
363
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
364 # ifndef isfinite
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
365 static int isfinite(floatmax d)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
366 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
367 return !(d >= HUGE_VAL);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
368 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
369 # endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
370
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
371 # ifndef signbit
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
372 static int signbit(floatmax d)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
373 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
374 /* NOTE: this doesn't work for -NAN */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
375 return (d < 0.0 || d == -0.0);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
376 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
377 # endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
378
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
379 #define MARK_POS FLAG_PLUS
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
380 #define PAD_POS FLAG_SPACE
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
381 #define ALT_FORM FLAG_HASH
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
382 #define LEFT_ADJ FLAG_JUSTIFY_LEFT
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
383 #define ZERO_PAD FLAG_ZERO
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
384
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
385 #define MIN(x,y) ((x)<(y)?(x):(y))
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
386 #define MAX(x,y) ((x)>(y)?(x):(y))
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
387 #define CONCAT2(x,y) x ## y
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
388 #define CONCAT(x,y) CONCAT2(x,y)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
389
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
390 static const char xdigits[16] = {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
391 "0123456789ABCDEF"
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
392 };
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
393
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
394 static void out(put_spec put, void *opaque, const char *s, size_t l, my_printf_uintmax *num)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
395 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
396 putstring(put, opaque, s, l, num, 0, 0);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
397 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
398
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
399 static void pad(put_spec put, void *opaque, char c, int w, int l, enum flags fl,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
400 my_printf_uintmax *num)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
401 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
402 char pad[256];
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
403 if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
404 l = w - l;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
405 memset(pad, c, l>sizeof pad ? sizeof pad : l);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
406 for (; l >= sizeof pad; l -= sizeof pad)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
407 out(put, opaque, pad, sizeof pad, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
408 out(put, opaque, pad, l, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
409 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
410
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
411 static char *fmt_u(uintmax_t x, char *s)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
412 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
413 unsigned long y;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
414 for ( ; x>ULONG_MAX; x/=10) *--s = '0' + x%10;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
415 for (y=x; y; y/=10) *--s = '0' + y%10;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
416 return s;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
417 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
418
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
419 static int my_floatput(put_spec put, void *opaque, floatmax y,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
420 int w, int p, enum flags fl, my_printf_uintmax *num, int t)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
421 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
422 /* Floating point implementation borrowed from musl libc */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
423 uint32_t big[(LDBL_MAX_EXP+LDBL_MANT_DIG)/9+1];
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
424 uint32_t *a, *d, *r, *z;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
425 int e2=0, e, i, j, l;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
426 char buf[9+LDBL_MANT_DIG/4], *s;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
427 const char *prefix="-0X+0X 0X-0x+0x 0x";
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
428 int pl;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
429 char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
430
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
431 pl=1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
432 if (signbit(y)) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
433 y=-y;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
434 } else if (fl & MARK_POS) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
435 prefix+=3;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
436 } else if (fl & PAD_POS) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
437 prefix+=6;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
438 } else prefix++, pl=0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
439
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
440 if (!isfinite(y)) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
441 char *s;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
442 if (isnan(y)) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
443 s = (t & 32) ? "nan" : "NAN";
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
444 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
445 s = (t & 32) ? "inf" : "INF";
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
446 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
447 pad(put, opaque, ' ', w, 3+pl, fl&~ZERO_PAD, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
448 out(put, opaque, prefix, pl, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
449 out(put, opaque, s, 3, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
450 pad(put, opaque, ' ', w, 3+pl, fl^LEFT_ADJ, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
451 return MAX(w, 3+pl);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
452 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
453
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
454 y = frexpm(y, &e2) * 2;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
455 if (y) e2--;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
456
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
457 if ((t|32)=='a') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
458 long double round = 8.0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
459 int re;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
460
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
461 if (t&32) prefix += 9;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
462 pl += 2;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
463
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
464 if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
465 else re=LDBL_MANT_DIG/4-1-p;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
466
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
467 if (re) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
468 while (re--) round*=16;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
469 if (*prefix=='-') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
470 y=-y;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
471 y-=round;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
472 y+=round;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
473 y=-y;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
474 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
475 y+=round;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
476 y-=round;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
477 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
478 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
479
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
480 estr=fmt_u(e2<0 ? -e2 : e2, ebuf);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
481 if (estr==ebuf) *--estr='0';
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
482 *--estr = (e2<0 ? '-' : '+');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
483 *--estr = t+('p'-'a');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
484
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
485 s=buf;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
486 do {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
487 int x=y;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
488 *s++=xdigits[x]|(t&32);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
489 y=16*(y-x);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
490 if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.';
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
491 } while (y);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
492
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
493 if (p && s-buf-2 < p)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
494 l = (p+2) + (ebuf-estr);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
495 else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
496 l = (s-buf) + (ebuf-estr);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
497
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
498 pad(put, opaque, ' ', w, pl+l, fl, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
499 out(put, opaque, prefix, pl, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
500 pad(put, opaque, '0', w, pl+l, fl^ZERO_PAD, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
501 out(put, opaque, buf, s-buf, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
502 pad(put, opaque, '0', l-(ebuf-estr)-(s-buf), 0, 0, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
503 out(put, opaque, estr, ebuf-estr, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
504 pad(put, opaque, ' ', w, pl+l, fl^LEFT_ADJ, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
505 return MAX(w, pl+l);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
506 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
507 if (p<0) p=6;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
508
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
509 if (y) y *= 0x1p28, e2-=28;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
510
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
511 if (e2<0) a=r=z=big;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
512 else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
513
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
514 do {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
515 *z = y;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
516 y = 1000000000*(y-*z++);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
517 } while (y);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
518
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
519 while (e2>0) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
520 uint32_t carry=0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
521 int sh=MIN(29,e2);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
522 for (d=z-1; d>=a; d--) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
523 uint64_t x = ((uint64_t)*d<<sh)+carry;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
524 *d = x % 1000000000;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
525 carry = x / 1000000000;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
526 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
527 if (!z[-1] && z>a) z--;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
528 if (carry) *--a = carry;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
529 e2-=sh;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
530 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
531 while (e2<0) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
532 uint32_t carry=0, *b;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
533 int sh=MIN(9,-e2);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
534 for (d=a; d<z; d++) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
535 uint32_t rm = *d & (1<<sh)-1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
536 *d = (*d>>sh) + carry;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
537 carry = (1000000000>>sh) * rm;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
538 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
539 if (!*a) a++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
540 if (carry) *z++ = carry;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
541 /* Avoid (slow!) computation past requested precision */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
542 b = (t|32)=='f' ? r : a;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
543 if (z-b > 2+p/9) z = b+2+p/9;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
544 e2+=sh;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
545 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
546
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
547 if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
548 else e=0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
549
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
550 /* Perform rounding: j is precision after the radix (possibly neg) */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
551 j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
552 if (j < 9*(z-r-1)) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
553 uint32_t x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
554 /* We avoid C's broken division of negative numbers */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
555 d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
556 j += 9*LDBL_MAX_EXP;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
557 j %= 9;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
558 for (i=10, j++; j<9; i*=10, j++);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
559 x = *d % i;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
560 /* Are there any significant digits past j? */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
561 if (x || d+1!=z) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
562 long double round = CONCAT(0x1p,LDBL_MANT_DIG);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
563 long double small;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
564 if (*d/i & 1) round += 2;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
565 if (x<i/2) small=0x0.8p0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
566 else if (x==i/2 && d+1==z) small=0x1.0p0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
567 else small=0x1.8p0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
568 if (pl && *prefix=='-') round*=-1, small*=-1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
569 *d -= x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
570 /* Decide whether to round by probing round+small */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
571 if (round+small != round) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
572 *d = *d + i;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
573 while (*d > 999999999) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
574 *d--=0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
575 (*d)++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
576 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
577 if (d<a) a=d;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
578 for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
579 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
580 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
581 if (z>d+1) z=d+1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
582 for (; !z[-1] && z>a; z--);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
583 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
584
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
585 if ((t|32)=='g') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
586 if (!p) p++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
587 if (p>e && e>=-4) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
588 t--;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
589 p-=e+1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
590 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
591 t-=2;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
592 p--;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
593 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
594 if (!(fl&ALT_FORM)) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
595 /* Count trailing zeros in last place */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
596 if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
597 else j=9;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
598 if ((t|32)=='f')
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
599 p = MIN(p,MAX(0,9*(z-r-1)-j));
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
600 else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
601 p = MIN(p,MAX(0,9*(z-r-1)+e-j));
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
602 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
603 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
604 l = 1 + p + (p || (fl&ALT_FORM));
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
605 if ((t|32)=='f') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
606 if (e>0) l+=e;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
607 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
608 estr=fmt_u(e<0 ? -e : e, ebuf);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
609 while(ebuf-estr<2) *--estr='0';
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
610 *--estr = (e<0 ? '-' : '+');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
611 *--estr = t;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
612 l += ebuf-estr;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
613 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
614
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
615 pad(put, opaque, ' ', w, pl+l, fl, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
616 out(put, opaque, prefix, pl, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
617 pad(put, opaque, '0', w, pl+l, fl^ZERO_PAD, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
618
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
619 if ((t|32)=='f') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
620 if (a>r) a=r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
621 for (d=a; d<=r; d++) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
622 char *s = fmt_u(*d, buf+9);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
623 if (d!=a) while (s>buf) *--s='0';
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
624 else if (s==buf+9) *--s='0';
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
625 out(put, opaque, s, buf+9-s, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
626 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
627 if (p || (fl&ALT_FORM)) out(put, opaque, ".", 1, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
628 for (; d<z && p>0; d++, p-=9) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
629 char *s = fmt_u(*d, buf+9);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
630 while (s>buf) *--s='0';
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
631 out(put, opaque, s, MIN(9,p), num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
632 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
633 pad(put, opaque, '0', p+9, 9, 0, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
634 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
635 if (z<=a) z=a+1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
636 for (d=a; d<z && p>=0; d++) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
637 char *s = fmt_u(*d, buf+9);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
638 if (s==buf+9) *--s='0';
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
639 if (d!=a) while (s>buf) *--s='0';
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
640 else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
641 out(put, opaque, s++, 1, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
642 if (p>0||(fl&ALT_FORM)) out(put, opaque, ".", 1, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
643 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
644 out(put, opaque, s, MIN(buf+9-s, p), num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
645 p -= buf+9-s;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
646 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
647 pad(put, opaque, '0', p+18, 18, 0, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
648 out(put, opaque, estr, ebuf-estr, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
649 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
650
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
651 pad(put, opaque, ' ', w, pl+l, fl^LEFT_ADJ, num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
652
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
653 return MAX(w, pl+l);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
654 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
655 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
656
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
657 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
658 /* NUMBER PARSER */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
659
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
660 static void parse_num(my_printf_uintmax *pnum, const char **pfmt)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
661 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
662 /* Width */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
663 (*pnum) = 0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
664 while (**pfmt >= '0' && **pfmt <= '9') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
665 /* Parse width */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
666 (*pnum) *= 10;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
667 (*pnum) += **pfmt - '0';
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
668
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
669 (*pfmt)++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
670 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
671 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
672
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
673 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
674
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
675 /* required for extrmeely scuffed %ls handling */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
676 int my_iprintf(put_spec put, void *opaque, const char *format, ...);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
677
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
678 int my_viprintf(put_spec put, void *opaque, const char *format, va_list ap)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
679 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
680 const char *fmt = format;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
681 my_printf_uintmax num;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
682
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
683 num = 0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
684
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
685 while (*fmt) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
686 if (fmt[0] == '%' && fmt[1] == '%') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
687 put(opaque, '%');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
688 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
689 fmt += 2;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
690 } else if (*fmt == '%') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
691 my_printf_uintmax width, precision;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
692 int have_precision;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
693 enum flags flags = 0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
694 enum {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
695 TYPE_NONE,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
696 TYPE_hh,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
697 TYPE_h,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
698 TYPE_ll,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
699 TYPE_l,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
700 TYPE_j,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
701 TYPE_z,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
702 TYPE_t,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
703 TYPE_L
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
704 } type = TYPE_NONE;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
705
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
706 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
707
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
708 /* Flags */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
709 while (*fmt) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
710 int end = 0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
711
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
712 switch (*fmt) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
713 case '-':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
714 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
715 flags |= FLAG_JUSTIFY_LEFT;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
716 /* Left justify (unimplemented) */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
717 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
718 case '+':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
719 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
720 flags |= FLAG_PLUS;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
721 /* Forces plus/minus sign */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
722 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
723 case ' ':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
724 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
725 /* If no negative sign, add a space */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
726 flags |= FLAG_SPACE;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
727 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
728 case '#':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
729 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
730 /* For hex and octal specifiers, this prepends with
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
731 * the C literal notation (such as 0x08 for "%#x", 8) */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
732 flags |= FLAG_HASH;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
733 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
734 case '0':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
735 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
736 /* Left-pads the number with zeroes */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
737 flags |= FLAG_ZERO;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
738 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
739 default:
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
740 end = 1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
741 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
742 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
743
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
744 if (end) break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
745 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
746
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
747 /* Width */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
748 parse_num(&width, &fmt);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
749
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
750 /* Precision */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
751 if (*fmt == '.') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
752 have_precision = 1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
753 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
754 if (*fmt == '*') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
755 /* Precision is in the va_list */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
756 precision = va_arg(ap, int);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
757 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
758 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
759 /* NOTE this was not intentional, but we actually handle this right.
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
760 *
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
761 * "If the period is specified without an explicit value for precision,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
762 * 0 is assumed." */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
763 parse_num(&precision, &fmt);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
764 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
765 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
766 have_precision = 0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
767 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
768
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
769 /* Length specifier (could be condensed to a switch) */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
770 switch (*fmt) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
771 case 'h':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
772 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
773 if (*fmt == 'h') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
774 /* char */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
775 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
776 type = TYPE_hh;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
777 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
778 /* short */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
779 type = TYPE_h;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
780 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
781 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
782 case 'l':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
783 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
784 if (*fmt == 'l') {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
785 /* long long */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
786 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
787 type = TYPE_ll;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
788 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
789 /* long, wint_t (c), and wchar_t * (s) */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
790 type = TYPE_l;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
791 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
792 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
793 case 'j':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
794 /* intmax_t */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
795 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
796 type = TYPE_j;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
797 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
798 case 'z':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
799 /* size_t */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
800 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
801 type = TYPE_z;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
802 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
803 case 't':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
804 /* ptrdiff_t */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
805 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
806 type = TYPE_t;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
807 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
808 case 'L':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
809 /* long double */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
810 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
811 type = TYPE_L;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
812 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
813 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
814
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
815 #define TYPE_CASE(TYPE, SIGN, T, X) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
816 case TYPE: \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
817 d = (T)va_arg(ap, X); \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
818 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
819
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
820 #ifdef HAVE_LONG_LONG
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
821 # define LONG_LONG_CASE(sign) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
822 TYPE_CASE(TYPE_ll, sign, sign long long, long long)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
823 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
824 # define LONG_LONG_CASE(sign)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
825 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
826
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
827 #ifdef HAVE_INTMAX_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
828 # define INTMAX_T_CASE(sign) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
829 TYPE_CASE(TYPE_j, sign, intmax_t, intmax_t)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
830 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
831 # define INTMAX_T_CASE(sign)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
832 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
833
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
834 #ifdef HAVE_SIZE_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
835 # define SIZE_T_CASE(sign) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
836 case TYPE_z: \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
837 d = my_size_t_sign(va_arg(ap, size_t)); \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
838 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
839 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
840 # define SIZE_T_CASE(sign)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
841 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
842
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
843 #ifdef HAVE_PTRDIFF_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
844 # define PTRDIFF_T_CASE(sign) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
845 TYPE_CASE(TYPE_t, sign, ptrdiff_t, ptrdiff_t)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
846 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
847 # define PTRDIFF_T_CASE(sign)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
848 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
849
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
850 /* For numbers, these are basically all the same besides the sign.
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
851 * Note that we always(-ish) interpret numbers as signed, to prevent
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
852 * signed integer overflow (which is undefined behavior). The problem
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
853 * here is that if we, say, pass a size_t, there is no signed equivalent.
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
854 * If someone were to pass a size_t that's bigger than INTMAX_MAX, then
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
855 * we'll be in big trouble. But who's even going to use %zd anyway??
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
856 *
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
857 * NOTE: ubsan doesn't scream at us when we do that. So I think it's
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
858 * probably fine. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
859 #define TYPE_SWITCH(sign) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
860 switch (type) { \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
861 TYPE_CASE(TYPE_hh, sign, sign char, int) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
862 TYPE_CASE(TYPE_h, sign, sign short, int) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
863 TYPE_CASE(TYPE_NONE, sign, sign int, int) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
864 TYPE_CASE(TYPE_l, sign, sign long, long) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
865 LONG_LONG_CASE(sign) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
866 INTMAX_T_CASE(sign) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
867 PTRDIFF_T_CASE(sign) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
868 SIZE_T_CASE(sign) \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
869 default: \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
870 /* Bad type specifier */ \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
871 return MY_EINVAL; \
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
872 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
873
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
874 switch (*fmt) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
875 case 'd': {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
876 /* Need special handling for some signed shit, so we can't
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
877 * do my_numput exactly.
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
878 *
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
879 * This is also the only place this needs to be... */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
880 my_printf_intmax d;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
881 my_printf_uintmax ad;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
882 my_printf_uintmax len;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
883
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
884 TYPE_SWITCH(signed)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
885
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
886 /* TODO handle width specifiers */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
887
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
888 /* inline llabs with defined behavior for LLONG_MIN */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
889 ad = (d < 0) ? (~(my_printf_uintmax)d + 1) : d;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
890
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
891 if (width > 0) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
892 len = my_numput_width(ad, 10);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
893
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
894 if ((d < 0) || (flags & FLAG_PLUS) || (flags & FLAG_SPACE))
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
895 len++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
896
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
897 if (!(flags & (FLAG_JUSTIFY_LEFT|FLAG_ZERO)) && len + 1 < width) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
898 print_chars(put, opaque, &num, ' ', width - len - 1);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
899 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
900
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
901 if (d < 0) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
902 put(opaque, '-');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
903 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
904 } else if (flags & FLAG_PLUS) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
905 put(opaque, '+');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
906 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
907 } else if (flags & FLAG_SPACE) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
908 put(opaque, ' ');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
909 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
910 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
911
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
912 if ((flags & FLAG_ZERO) && len + 1 < width)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
913 print_chars(put, opaque, &num, '0', width - len - 1);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
914
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
915 my_numput_lower(put, opaque, ad, 10, &num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
916
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
917 if ((flags & FLAG_JUSTIFY_LEFT) && len + 1 < width) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
918 print_spaces(put, opaque, &num, width - len - 1);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
919 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
920 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
921 /* Faster */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
922 if (d < 0) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
923 put(opaque, '-');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
924 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
925 } else if (flags & FLAG_PLUS) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
926 put(opaque, '+');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
927 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
928 } else if (flags & FLAG_SPACE) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
929 put(opaque, ' ');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
930 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
931 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
932
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
933 my_numput_lower(put, opaque, ad, 10, &num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
934 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
935
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
936 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
937
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
938 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
939 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
940 case 'u': {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
941 my_printf_uintmax d;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
942 TYPE_SWITCH(unsigned)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
943 my_numput(put, opaque, d, 10, &num, 0, NULL, 0,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
944 width, flags & FLAG_JUSTIFY_LEFT, flags & FLAG_ZERO, 0);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
945 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
946 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
947 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
948 case 'x': {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
949 my_printf_uintmax d;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
950 TYPE_SWITCH(unsigned)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
951
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
952 /* stinky */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
953 my_numput(put, opaque, d, 16, &num, flags & FLAG_HASH, "0x", 2,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
954 width, flags & FLAG_JUSTIFY_LEFT, flags & FLAG_ZERO, 0);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
955
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
956 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
957 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
958 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
959 case 'X': {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
960 my_printf_uintmax d;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
961 TYPE_SWITCH(unsigned)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
962
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
963 /* stinky */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
964 my_numput(put, opaque, d, 16, &num, flags & FLAG_HASH, "0X", 2,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
965 width, flags & FLAG_JUSTIFY_LEFT, flags & FLAG_ZERO, 1);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
966
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
967 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
968 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
969 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
970 case 'o': {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
971 my_printf_uintmax d;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
972 TYPE_SWITCH(unsigned)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
973 /* stinky */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
974 my_numput(put, opaque, d, 8, &num, flags & FLAG_HASH, "0", 1,
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
975 width, flags & FLAG_JUSTIFY_LEFT, flags & FLAG_ZERO, 0);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
976 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
977 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
978 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
979
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
980 #undef TYPE_CASE
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
981 #undef LONG_LONG_CASE
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
982 #undef INTMAX_T_CASE
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
983 #undef SIZE_T_CASE
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
984 #undef PTRDIFF_T_CASE
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
985 #undef TYPE_SWITCH
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
986
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
987 #ifdef HAVE_FLOATING_POINT
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
988 case 'a': case 'A': case 'e': case 'E':
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
989 case 'G': case 'g': case 'F': case 'f': {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
990 /* balls */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
991 floatmax d;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
992 switch (type) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
993 #ifdef HAVE_LONG_DOUBLE
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
994 case TYPE_L:
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
995 d = va_arg(ap, long double);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
996 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
997 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
998 case TYPE_NONE:
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
999 d = va_arg(ap, double);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1000 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1001 default:
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1002 /* Invalid */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1003 return MY_EINVAL;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1004 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1005 if (!have_precision) precision = 6;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1006 my_floatput(put, opaque, d, width, precision, flags, &num, *fmt);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1007 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1008 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1009 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1010 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1011 case 's': {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1012 switch (type) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1013 case TYPE_l: {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1014 wchar_t *s;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1015 s = va_arg(ap, wchar_t *);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1016
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1017 /* This stinks and isn't right for width nor precision */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1018 while (*s && (!have_precision || precision-- > 0)) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1019 my_iprintf(put, opaque, "%lc", *(s++));
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1020 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1021 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1022
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1023 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1024 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1025 case TYPE_NONE: {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1026 char *s;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1027 my_printf_size len;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1028
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1029 s = va_arg(ap, char *);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1030
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1031 if (width > 0) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1032 if (have_precision) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1033 /* Use strnlen to avoid overflow */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1034 len = my_strnlen(s, precision);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1035 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1036 len = my_strlen(s);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1037 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1038
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1039 putstring(put, opaque, s, len, &num, width, !!(flags & FLAG_JUSTIFY_LEFT));
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1040 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1041 /* Simpler implementation (only one pass of the string) */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1042 if (have_precision) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1043 while (*s && precision-- > 0) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1044 put(opaque, *(s++));
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1045 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1046 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1047 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1048 while (*s) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1049 put(opaque, *(s++));
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1050 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1051 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1052 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1053 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1054 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1055 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1056 default:
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1057 /* Invalid */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1058 return MY_EINVAL;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1059 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1060
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1061 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1062 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1063 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1064 case 'c': {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1065 switch (type) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1066 #ifdef HAVE_WCTOMB
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1067 case TYPE_l: {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1068 /* XXX this doesn't work on Windows. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1069 char *c;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1070
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1071 /* TODO would make more sense to move the full buffer
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1072 * handling stuff out of here, instead of having it all
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1073 * intermixed like this */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1074 c = my_calloc(MB_CUR_MAX + 1, 1);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1075 if (!c)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1076 return MY_ENOMEM;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1077
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1078 /* handle wide char -> multi byte */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1079 if (wctomb(c, va_arg(ap, wint_t)) == -1) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1080 my_free(c);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1081 return MY_EENCOD;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1082 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1083 putstring(put, opaque, c, my_strlen(c), &num, width, !!(flags & FLAG_JUSTIFY_LEFT));
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1084 my_free(c);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1085 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1086 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1087 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1088 case TYPE_NONE: {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1089 /* Balls simple */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1090 char c = (char)va_arg(ap, int);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1091 putstring(put, opaque, &c, 1, &num, width, !!(flags & FLAG_JUSTIFY_LEFT));
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1092 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1093 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1094 default:
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1095 /* Invalid type */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1096 return MY_EINVAL;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1097 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1098
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1099 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1100 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1101 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1102 case 'n': {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1103 #define STORE(TYPE, type) case TYPE: *va_arg(ap, type *) = num; break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1104
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1105 switch (type) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1106 STORE(TYPE_hh, signed char)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1107 STORE(TYPE_h, short)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1108 STORE(TYPE_NONE, int)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1109 STORE(TYPE_l, long)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1110 #ifdef HAVE_LONG_LONG
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1111 STORE(TYPE_ll, long long)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1112 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1113 #ifdef HAVE_INTMAX_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1114 STORE(TYPE_j, intmax_t)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1115 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1116 #ifdef HAVE_SIZE_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1117 STORE(TYPE_z, size_t)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1118 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1119 #ifdef HAVE_PTRDIFF_T
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1120 STORE(TYPE_t, ptrdiff_t)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1121 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1122 default:
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1123 return -1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1124 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1125 #undef STORE
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1126
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1127 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1128 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1129 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1130 case 'p': {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1131 /* This can pretty much be whatever we want, but I'm going to replicate
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1132 * the glibc result. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1133 void *x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1134
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1135 x = va_arg(ap, void *);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1136
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1137 put(opaque, '0');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1138 put(opaque, 'x');
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1139 num += 2;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1140
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1141 my_numput_lower(put, opaque, (my_printf_uintptr)x, 16, &num);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1142 fmt++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1143 break;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1144 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1145 default:
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1146 /* Invalid/unknown selector */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1147 return MY_EINVAL;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1148 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1149 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1150 /* Just append the character. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1151 put(opaque, *(fmt++));
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1152 num++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1153 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1154 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1155
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1156 if (num > (my_printf_uintmax)INT_MAX)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1157 return MY_EOVERFLOW;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1158
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1159 return num;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1160 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1161
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1162 int my_iprintf(put_spec put, void *opaque, const char *format, ...)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1163 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1164 va_list ap;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1165 int r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1166
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1167 va_start(ap, format);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1168 r = my_viprintf(put, opaque, format, ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1169 va_end(ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1170
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1171 return r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1172 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1173
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1174 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1175 /* vsnprintf */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1176
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1177 struct put_vsnprintf_data {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1178 char *out;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1179 my_printf_size n;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1180 int c;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1181 };
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1182
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1183 static void put_vsnprintf(void *opaque, unsigned char c)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1184 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1185 struct put_vsnprintf_data *d = opaque;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1186
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1187 if (d->out && d->c < d->n)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1188 d->out[d->c] = c;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1189
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1190 d->c++;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1191 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1192
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1193 int my_vsnprintf(char *out, my_printf_size n, const char *fmt, va_list ap)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1194 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1195 int r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1196 struct put_vsnprintf_data d;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1197
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1198 d.out = out;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1199 d.n = n;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1200 d.c = 0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1201
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1202 r = my_viprintf(put_vsnprintf, &d, fmt, ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1203
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1204 /* case: returned size is smaller than buffer. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1205 put_vsnprintf(&d, 0);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1206
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1207 /* case: returned size is larger than buffer.
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1208 * we still have to NUL terminate. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1209 if (out && n > 0)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1210 out[n-1] = 0; /* NUL terminate */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1211
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1212 if (r < 0)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1213 return r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1214
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1215 /* subtract one because of NUL termination above */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1216 return d.c - 1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1217 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1218
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1219 int my_snprintf(char *out, my_printf_size n, const char *fmt, ...)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1220 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1221 int r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1222 va_list ap;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1223
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1224 va_start(ap, fmt);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1225 r = my_vsnprintf(out, n, fmt, ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1226 va_end(ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1227
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1228 return r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1229 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1230
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1231 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1232 /* vasprintf
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1233 * we do this in one pass, instead of two (like the usual vsnprintf impl)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1234 * why? well, it's a bit easier to implement, and doesn't require va_copy. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1235
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1236 struct put_vasprintf_data {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1237 char *x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1238 my_printf_size len;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1239 my_printf_size alloc;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1240
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1241 int dead;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1242 };
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1243
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1244 static void put_vasprintf(void *opaque, unsigned char c)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1245 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1246 struct put_vasprintf_data *d = opaque;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1247
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1248 if (d->dead)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1249 return;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1250
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1251 if (!d->x || d->len >= d->alloc) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1252 char *old;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1253
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1254 /* make a guesstimate */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1255 if (!d->alloc) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1256 #ifdef TEST
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1257 /* Stress test reallocation */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1258 d->alloc = 2;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1259 #else
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1260 d->alloc = 128;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1261 #endif
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1262 } else {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1263 d->alloc *= 2;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1264 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1265
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1266 old = d->x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1267 d->x = my_realloc(old, d->alloc);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1268 if (!d->x) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1269 my_free(old);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1270 d->dead = 1;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1271 return;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1272 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1273 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1274
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1275 d->x[d->len++] = c;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1276 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1277
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1278 int my_vasprintf(char **out, const char *fmt, va_list ap)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1279 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1280 int r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1281 struct put_vasprintf_data d;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1282
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1283 d.x = NULL;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1284 d.len = 0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1285 d.alloc = 0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1286 d.dead = 0;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1287
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1288 r = my_viprintf(put_vasprintf, &d, fmt, ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1289
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1290 if (d.dead) /* memory allocation failed, punt */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1291 return MY_ENOMEM;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1292
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1293 /* Add NUL terminator */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1294 put_vasprintf(&d, 0);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1295
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1296 if (d.x) {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1297 /* Trim the fat
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1298 * Even if the realloc calls fails, this is still okay
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1299 * because we still have the original allocation */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1300 void *x = my_realloc(d.x, d.len);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1301 if (x)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1302 d.x = x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1303 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1304
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1305 if (r >= 0)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1306 *out = d.x;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1307
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1308 return r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1309 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1310
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1311 int my_asprintf(char **out, const char *fmt, ...)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1312 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1313 int r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1314 va_list ap;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1315
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1316 va_start(ap, fmt);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1317 r = my_vasprintf(out, fmt, ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1318 va_end(ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1319
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1320 return r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1321 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1322
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1323 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1324 /* Finally, functions for outputting to stdio. */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1325
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1326 static void put_fprintf(void *opaque, unsigned char c)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1327 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1328 putc(c, opaque);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1329 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1330
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1331 int my_vfprintf(FILE *f, const char *fmt, va_list ap)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1332 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1333 return my_viprintf(put_fprintf, f, fmt, ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1334 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1335
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1336 int my_fprintf(FILE *f, const char *fmt, ...)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1337 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1338 int r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1339 va_list ap;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1340
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1341 va_start(ap, fmt);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1342 r = my_viprintf(put_fprintf, f, fmt, ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1343 va_end(ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1344
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1345 return r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1346 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1347
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1348 /* ------------------------------------------------------------------------ */
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1349
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1350 int my_vprintf(const char *fmt, va_list ap)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1351 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1352 return my_vfprintf(stdout, fmt, ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1353 }
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1354
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1355 int my_printf(const char *fmt, ...)
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1356 {
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1357 int r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1358 va_list ap;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1359
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1360 va_start(ap, fmt);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1361 r = my_vprintf(fmt, ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1362 va_end(ap);
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1363
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1364 return r;
e3088565a6b8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1365 }