+++ /dev/null
-/*
- File name : fprintf.c
- Date of creation : 05/12/2022
- Version : 1.0
- Copyright : Soft'n'design
- Author : Laurent Mazet <mazet@softndesign.org>
-
- Description : This file contains embedded printf
-
- History :
- - initial version
-*/
-
-#include <stdarg.h>
-#include <stdint.h>
-#include <unistd.h>
-
-#include "fdprintf.h"
-
-int stdfdin = STDIN_FILENO;
-int stdfdout = STDOUT_FILENO;
-int stdfderr = STDERR_FILENO;
-
-unsigned int nextpow (unsigned int x, int base) {
- unsigned int n = 0;
- while (x) {
- n++;
- x = x / base;
- }
- return (n == 0) ? 1 : n;
-}
-
-char *itoa (char *str, unsigned u, unsigned int sz)
-{
- unsigned int i = (sz == 0 ) ? nextpow (u, 10) : sz;
- char *s = str;
- while (i > 0) {
- str[i - 1] = '0' + (u % 10);
- u /= 10;
- i--;
- s++;
- }
- return s;
-}
-
-double tenpower(int n)
-{
- double t = 1.0;
- int i;
- for (i = 0; i < n; i++) {
- t *= 10;
- }
- for (i = 0; i > n; i--) {
- t /= 10;
- }
- return t;
-}
-
-int getexponant (double *f, int maxexp)
-{
- int exp = 0;
- while (*f > 10) {
- *f /= 10;
- exp++;
- }
- while (*f < 1) {
- *f *= 10;
- exp--;
- }
- *f += tenpower (maxexp - 1);
- if (*f >= 10) {
- *f /= 10;
- exp++;
- }
-
- return exp;
-}
-/* simple fprintf function */
-
-int fdprintf (int fd, const char *fmt, ...)
-{
- char buffer[1024 + 1] = { 0 };
- char *str = buffer;
-
- va_list ap;
- va_start (ap, fmt);
- while (*fmt) {
- char *s;
- double f = 0.0;
- int d = 0;
- unsigned int u;
- char c = *fmt++;
-
- /* copy standard char */
- if (c != '%') {
- *str++ = c;
- } else {
- int t = 0;
- char w = '0';
- int i, sz = 0;
- void *p = NULL;
-
- /* stamp */
- if ((*fmt == ' ') || (*fmt == '0')) {
- w = *fmt++;
- }
-
- /* size */
- if ((*fmt >= '1') && (*fmt <= '9')) {
- sz = *fmt++ - '0';
- }
-
- /* process format char */
- switch (*fmt++) {
- case '%': /* percent */
- *str++ = '%';
- break;
- case 'c': /* char */
- c = (char) va_arg (ap, int);
- *str++ = c;
- break;
- case 'd': /* int */
- d = va_arg (ap, int);
- if (d < 0) {
- *str++ = '-';
- d = -d;
- }
- t = 1;
- /* fall through */
- case 'u': /* unsigned int */
- str = itoa (str, (t) ? (unsigned int)d : va_arg (ap, unsigned int), 0);
- break;
- case 'f': /* float */
- f = va_arg (ap, double);
- if (f == 0) {
- *str++ = '0';
- break;
- }
- if (f < 0) {
- *str++ = '-';
- f = -f;
- }
- if (sz == 0) sz = 6;
- t = getexponant (&f, -sz);
- u = (int)f;
- str = itoa (str, u, 0);
- d = (int)((f - u) * tenpower (sz));
- if (d > 0) {
- *str++ = '.';
- str = itoa (str, d, sz);
- }
- while (*(str - 1) == '0') {
- str--;
- }
- if (t != 0) {
- *str++ = 'e';
- if (t < 0) {
- *str++ = '-';
- t = -t;
- }
- str = itoa (str, t, 0);
- }
- break;
- case 'p': /* pointer */
- *str++ = '0';
- *str++ = 'x';
- w = '0';
- sz = sizeof (void *) * 2;
- p = va_arg (ap, void *);
- /* fall through */
- case 'x': /* integer hexa */
- if (!p) {
- u = va_arg (ap, unsigned int);
- if (sz == 0) {
- sz = nextpow (u, 16);
- }
- } else {
- u = (uintptr_t)p;
- }
- for (i = sz, t = 1; i > 0; i--) {
- char x = (char)((u >> (i * 4 - 4)) & 0xf);
- if ((t == 1) && (x == 0)) {
- *str++ = w;
- } else {
- *str++ = (x > 9) ? 'a' + x - 10 : '0' + x;
- t = 0;
- }
- }
- break;
- case 's': /* string */
- s = va_arg (ap, char *);
- while (s && *s)
- *str++ = *s++;
- break;
- default:
- *str++ = '?';
- }
- }
- }
- va_end (ap);
-
- /* output string */
- int n = str - buffer;
- if (n < (int)sizeof (buffer) - 1) {
- return write (fd, buffer, n);
- }
- return 0;
-}
-
-/* vim: set ts=4 sw=4 et: */