3 * - By John Hodge (thePowersGang)
6 * - *scanf family of functions
12 #include <acess/sys.h> // debug!
15 typedef void (*printf_putch_t)(void *h, char ch);
18 void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned);
22 * \fn EXPORT void vsnprintf(char *buf, const char *format, va_list args)
23 * \brief Prints a formatted string to a buffer
24 * \param buf Pointer - Destination Buffer
25 * \param format String - Format String
26 * \param args VarArgs List - Arguments
28 EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *format, va_list args)
31 int c, minSize, precision, len;
36 int bLongLong, bPadLeft;
38 _SysDebug("format=%s", format);
40 #define _addchar(ch) do { \
41 putch_cb(putch_h, ch); \
47 while((c = *format++) != 0)
49 // Non-control character
57 if(c == '%') { // Literal %
76 minSize = va_arg(args, size_t);
80 if('1' <= c && c <= '9')
83 while('0' <= c && c <= '9')
96 precision = va_arg(args, size_t);
99 else if('1' <= c && c <= '9')
102 while('0' <= c && c <= '9')
105 precision += c - '0';
111 // Check for long long
121 // Just help things along later
130 if(bLongLong) arg = va_arg(args, int64_t);
131 else arg = va_arg(args, int32_t);
132 itoa(tmp, arg, 10, minSize, pad, 1);
139 if(bLongLong) arg = va_arg(args, uint64_t);
140 else arg = va_arg(args, uint32_t);
141 itoa(tmp, arg, 10, minSize, pad, 0);
150 arg = va_arg(args, intptr_t);
151 itoa(tmp, arg, 16, minSize, pad, 0);
154 // Unsigned Hexadecimal
156 if(bLongLong) arg = va_arg(args, uint64_t);
157 else arg = va_arg(args, uint32_t);
158 itoa(tmp, arg, 16, minSize, pad, 0);
164 if(bLongLong) arg = va_arg(args, uint64_t);
165 else arg = va_arg(args, uint32_t);
166 itoa(tmp, arg, 8, minSize, pad, 0);
172 if(bLongLong) arg = va_arg(args, uint64_t);
173 else arg = va_arg(args, uint32_t);
174 itoa(tmp, arg, 2, minSize, pad, 0);
180 p = va_arg(args, char*);
183 //_SysDebug("vsnprintf: p = '%s'", p);
185 len = strnlen(p, precision);
188 if(bPadLeft) while(minSize > len++) _addchar(pad);
190 if(precision >= 0 && precision -- == 0)
194 if(!bPadLeft) while(minSize > len++) _addchar(pad);
197 // Unknown, just treat it as a character
199 arg = va_arg(args, uint32_t);
209 struct s_sprintf_info {
215 void _vsnprintf_putch(void *h, char ch)
217 struct s_sprintf_info *info = h;
218 if(info->ofs < info->maxlen)
219 info->dest[info->ofs++] = ch;
222 EXPORT int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list __args)
224 struct s_sprintf_info info = {__s, 0, __maxlen};
226 ret = _vcprintf_int(_vsnprintf_putch, &info, __format, __args);
227 _vsnprintf_putch(&info, '\0');
231 EXPORT int snprintf(char *buf, size_t maxlen, const char *format, ...)
235 va_start(args, format);
236 ret = vsnprintf((char*)buf, maxlen, (char*)format, args);
242 EXPORT int vsprintf(char * __s, const char *__format, va_list __args)
244 return vsnprintf(__s, 0x7FFFFFFF, __format, __args);
246 EXPORT int sprintf(char *buf, const char *format, ...)
250 va_start(args, format);
251 ret = vsprintf((char*)buf, (char*)format, args);
256 void _vfprintf_putch(void *h, char ch)
261 EXPORT int vfprintf(FILE *__fp, const char *__format, va_list __args)
263 return _vcprintf_int(_vfprintf_putch, __fp, __format, __args);
266 EXPORT int fprintf(FILE *fp, const char *format, ...)
272 va_start(args, format);
273 ret = vfprintf(fp, (char*)format, args);
279 EXPORT int vprintf(const char *__format, va_list __args)
281 return vfprintf(stdout, __format, __args);
284 EXPORT int printf(const char *format, ...)
290 va_start(args, format);
291 ret = vprintf(format, args);
298 const char cUCDIGITS[] = "0123456789ABCDEF";
300 * \brief Convert an integer into a character string
301 * \param buf Destination Buffer
302 * \param num Number to convert
303 * \param base Base-n number output
304 * \param minLength Minimum length of output
305 * \param pad Padding used to ensure minLength
306 * \param bSigned Signed number output?
308 EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned)
314 if(base > 16 || base < 2) {
319 if(bSigned && (int64_t)num < 0)
326 // Encode into reversed string
327 while(num > base-1) {
328 tmpBuf[pos++] = cUCDIGITS[ num % base ];
329 num = (uint64_t) num / (uint64_t)base; // Shift {number} right 1 digit
332 tmpBuf[pos++] = cUCDIGITS[ num % base ]; // Last digit of {number}
333 if(bSigned) tmpBuf[pos++] = '-'; // Append sign symbol if needed
337 while(minLength-- > 0) buf[i++] = pad;
338 while(pos-- > 0) buf[i++] = tmpBuf[pos]; // Reverse the order of characters