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