remove calloc calls
[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>
92fc2c44 15#include <unistd.h>
5f83300c 16
c84ea202
LM
17#include "fprintf.h"
18
19int _fdout = STDOUT_FILENO;
20int _fderr = STDERR_FILENO;
21
b40343bc 22inline unsigned int nextpow (unsigned int x, int base) {
5f83300c
LM
23 unsigned int n = 0;
24 while (x) {
25 n++;
b40343bc 26 x = x / base;
5f83300c
LM
27 }
28 return (n == 0) ? 1 : n;
29}
30
31/* simple fprintf function */
32
92fc2c44 33int fdprintf (int fd, const char *fmt, ...)
5f83300c
LM
34{
35 char buffer[1024 + 1] = { 0 };
36 char *str = buffer;
37
38 va_list ap;
39 va_start (ap, fmt);
40 while (*fmt) {
41 char *s;
42 int d = 0;
43 unsigned int u;
5f83300c
LM
44 char c = *fmt++;
45
46 /* copy standard char */
47 if (c != '%') {
48 *str++ = c;
49 } else {
50 int t = 0;
b40343bc 51 char w = '0';
92fc2c44 52 int i, sz = 0;
b40343bc
LM
53 void *p = NULL;
54
55 /* stamp */
56 if ((*fmt == ' ') || (*fmt == '0')) {
57 w = *fmt++;
58 }
59
60 /* size */
61 if ((*fmt >= '1') && (*fmt <= '9')) {
62 sz = *fmt++ - '0';
63 }
5f83300c
LM
64
65 /* process format char */
66 switch (*fmt++) {
67 case 'c': /* char */
68 c = (char) va_arg (ap, int);
69 *str++ = c;
70 break;
71 case 'd': /* int */
72 d = va_arg (ap, int);
73 if (d < 0) {
74 *str++ = '-';
75 d = -d;
76 }
77 t = 1;
78 /* fall through */
79 case 'u': /* unsigned int */
80 u = (t) ? (unsigned int)d : va_arg (ap, unsigned int);
b40343bc 81 for (i = nextpow (u, 10), s = str; i > 0; i--, s++) {
5f83300c
LM
82 str[i - 1] = '0' + (u % 10);
83 u /= 10;
84 }
85 str = s;
86 break;
87 case 'p': /* pointer */
5f83300c
LM
88 *str++ = '0';
89 *str++ = 'x';
b40343bc
LM
90 w = '0';
91 sz = sizeof (void *) * 2;
92 p = va_arg (ap, void *);
93 /* fall through */
94 case 'x': /* integer hexa */
95 if (!p) {
96 u = va_arg (ap, unsigned int);
97 p = (void *)u;
98 if (sz == 0) {
99 sz = nextpow (u, 16);
100 }
101 }
102 for (i = sz, t = 1; i > 0; i--) {
5f83300c 103 char x = (char)(((uintptr_t)p >> (i * 4 - 4)) & 0xf);
b40343bc
LM
104 if ((t == 1) && (x == 0)) {
105 *str++ = w;
106 } else {
107 *str++ = (x > 9) ? 'a' + x - 10 : '0' + x;
108 t = 0;
109 }
5f83300c
LM
110 }
111 break;
112 case 's': /* string */
113 s = va_arg (ap, char *);
114 while (s && *s)
115 *str++ = *s++;
116 break;
117 default:
118 *str++ = '?';
119 }
120 }
121 }
122 va_end (ap);
123
124 /* output string */
92fc2c44
LM
125 int n = str - buffer;
126 if (n < (int)sizeof (buffer) - 1) {
127 write (fd, buffer, n);
5f83300c
LM
128 return n;
129 }
130 return 0;
131}
132
b40343bc 133/* vim: set ts=4 sw=4 et: */