add private atoi function
[compress.git] / fprintf.c
CommitLineData
5f83300c
LM
1/*
2 File name : fprintf.c
3 Date of creation : 05/12/2022
4 Version : 1.0
5 Copyright : Soft'n'design
6 Author : Laurent Mazet <mazet@softndesign.org>
7
8 Description : This file contains embedded printf
9
10 History :
11 - initial version
12*/
13
14#include <stdarg.h>
15#include <stddef.h>
16#include <stdio.h>
17
18inline unsigned int nextpow10 (unsigned int x) {
19 unsigned int n = 0;
20 while (x) {
21 n++;
22 x = x / 10;
23 }
24 return (n == 0) ? 1 : n;
25}
26
27/* simple fprintf function */
28
29size_t _fprintf (FILE *fid, const char *fmt, ...)
30{
31 char buffer[1024 + 1] = { 0 };
32 char *str = buffer;
33
34 va_list ap;
35 va_start (ap, fmt);
36 while (*fmt) {
37 char *s;
38 int d = 0;
39 unsigned int u;
40 void *p;
41 char c = *fmt++;
42
43 /* copy standard char */
44 if (c != '%') {
45 *str++ = c;
46 } else {
47 int t = 0;
48 size_t i;
49
50 /* process format char */
51 switch (*fmt++) {
52 case 'c': /* char */
53 c = (char) va_arg (ap, int);
54 *str++ = c;
55 break;
56 case 'd': /* int */
57 d = va_arg (ap, int);
58 if (d < 0) {
59 *str++ = '-';
60 d = -d;
61 }
62 t = 1;
63 /* fall through */
64 case 'u': /* unsigned int */
65 u = (t) ? (unsigned int)d : va_arg (ap, unsigned int);
66 for (i = nextpow10 (u), s = str; i > 0; i--, s++) {
67 str[i - 1] = '0' + (u % 10);
68 u /= 10;
69 }
70 str = s;
71 break;
72 case 'p': /* pointer */
73 p = va_arg (ap, void *);
74 *str++ = '0';
75 *str++ = 'x';
76 for (i = sizeof (void *) * 2; i > 0; i--) {
77 char x = (char)(((uintptr_t)p >> (i * 4 - 4)) & 0xf);
78 *str++ = (x > 9) ? 'a' + x - 10 : '0' + x;
79 }
80 break;
81 case 's': /* string */
82 s = va_arg (ap, char *);
83 while (s && *s)
84 *str++ = *s++;
85 break;
86 default:
87 *str++ = '?';
88 }
89 }
90 }
91 va_end (ap);
92
93 /* output string */
94 size_t n = str - buffer;
95 if (n < sizeof (buffer) - 1) {
96 fwrite (buffer, n, 1, fid);
97 return n;
98 }
99 return 0;
100}
101
102/* vim: set ts=4 sw=4 et */