From 8a00a65c66914b7dbbf7c3c594d94698f11629dc Mon Sep 17 00:00:00 2001 From: sinanmohd Date: Thu, 11 May 2023 21:10:32 +0530 Subject: 7.3: initial commit, no printf was abused in the process fractional number support is not complete, but most things should work. --- 7.3/Makefile | 12 +++++ 7.3/main.c | 9 ++++ 7.3/mprintf.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7.3/mprintf.h | 1 + 4 files changed, 187 insertions(+) create mode 100644 7.3/Makefile create mode 100644 7.3/main.c create mode 100644 7.3/mprintf.c create mode 100644 7.3/mprintf.h diff --git a/7.3/Makefile b/7.3/Makefile new file mode 100644 index 0000000..434eecd --- /dev/null +++ b/7.3/Makefile @@ -0,0 +1,12 @@ +objects = main.o mprintf.o +CC = gcc +CFLAGS = -Wvla -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -fsanitize=address + +print : $(objects) + $(CC) $(CFLAGS) -o print $(objects) -lm + +main.o : mprintf.h + +.PHONY : clean +clean : + rm print $(objects) diff --git a/7.3/main.c b/7.3/main.c new file mode 100644 index 0000000..3b58a5c --- /dev/null +++ b/7.3/main.c @@ -0,0 +1,9 @@ +#include "mprintf.h" + +int main(void) +{ + char p = 'c'; + mprintf("%-10s-%3d-%.1f-%x-%p-%o\n", "sneed", 44, 2.4, 0xa7, &p, 023); + + return 0; +} diff --git a/7.3/mprintf.c b/7.3/mprintf.c new file mode 100644 index 0000000..740f395 --- /dev/null +++ b/7.3/mprintf.c @@ -0,0 +1,165 @@ +#include +#include +#include +#include +#include +#include "mprintf.h" + +#define DEFPRES 6 +enum base { OCT = 8, DEC = 10, HEX = 16 }; + +struct flags { + unsigned int fw; + unsigned int pres; + unsigned int fwc; + unsigned int laligne : 1; +} flags; + +void printnum(long long num, struct flags flags, int base); +void printflt(double num, struct flags flags); +void printstr(char *s, struct flags flags); +int reverse(long long *num, int base); + +void mprintf(char *fmt, ...) +{ + va_list ap; + char *p; + int dlim; + + va_start(ap, fmt); + for (p = fmt; *p; ++p) { + if (*p != '%') { + putchar(*p); + continue; + } + + flags.fwc = ' '; + flags.fw = dlim = flags.pres = 0; + while (!isalpha(*++p) && *p != '\0') { + if (isalnum(*p) && !dlim) + flags.fw = flags.fw * 10 + *p - '0'; + else if (isalnum(*p) && dlim) + flags.pres = flags.pres * 10 + *p - '0'; + else if (*p == '.') + dlim = 1; + else if (*p == '-') + flags.laligne = 1; + } + if (!dlim) + flags.pres = DEFPRES; + + switch (*p) { + case 'd': + case 'i': + printnum(va_arg(ap, int), flags, DEC); + break; + case 'o': + printnum(va_arg(ap, int), flags, DEC); + break; + case 'u': + printnum(va_arg(ap, unsigned), flags, DEC); + break; + case 'x': + printnum(va_arg(ap, unsigned), flags, HEX); + break; + case 'c': + putchar(va_arg(ap, unsigned)); + break; + case 'p': + mprintf("0x"); + printnum(va_arg(ap, long long), flags, HEX); + break; + case 'f': + printflt(va_arg(ap, double), flags); + break; + case 's': + printstr(va_arg(ap, char *), flags); + break; + default: + putchar(*p); + break; + } + } + va_end(ap); + + return; +} + +void printstr(char *s, struct flags flags) +{ + int blank; + + blank = flags.fw - strlen(s); + for (; blank > 0 && !flags.laligne; --blank) + putchar(flags.fwc); + + for (; *s; ++s) + putchar(*s); + + for (; blank > 0 && flags.laligne; --blank) + putchar(flags.fwc); +} +void printnum(long long num, struct flags flags, int base) +{ + int temp, blank; + + if (num < 0) { + putchar('-'); + num *= -1; + } + + blank = flags.fw - reverse(&num, base); + for (; blank > 0 && !flags.laligne; --blank) + putchar(flags.fwc); + + for (; num; num /= base) { + switch (temp = num % base) { + case 10: + putchar('a'); + break; + case 11: + putchar('b'); + break; + case 12: + putchar('c'); + break; + case 13: + putchar('d'); + break; + case 14: + putchar('e'); + break; + case 15: + putchar('f'); + break; + default: + putchar(temp + '0'); + break; + } + } + + for (; blank > 0 && flags.laligne; --blank) + putchar(flags.fwc); +} + +void printflt(double num, struct flags flags) +{ + printnum((int) num, flags, DEC); + if (flags.pres) { + flags.fwc = '0'; + putchar('.'); + printnum((long long) ((num - (int) num) * + powl(10, flags.pres)), flags, DEC); + } +} + +int reverse(long long *num, int base) +{ + long long temp = *num; + int len; + + for (*num = len = 0; temp; temp /= base, ++len) + *num = *num * base + temp % base; + + return len; +} diff --git a/7.3/mprintf.h b/7.3/mprintf.h new file mode 100644 index 0000000..a53d2b9 --- /dev/null +++ b/7.3/mprintf.h @@ -0,0 +1 @@ +void mprintf(char *fmt, ...); -- cgit v1.2.3