aboutsummaryrefslogtreecommitdiff
path: root/7.3
diff options
context:
space:
mode:
authorsinanmohd <sinan@firemail.cc>2023-05-11 21:10:32 +0530
committersinanmohd <sinan@firemail.cc>2023-05-12 15:50:08 +0530
commit8a00a65c66914b7dbbf7c3c594d94698f11629dc (patch)
treecec9a5fa9550ef4cbc6b3c281bea90bc718dc812 /7.3
parentf481f43596073d7f5cee231da901fb43d6af8366 (diff)
7.3: initial commit, no printf was abused in the process
fractional number support is not complete, but most things should work.
Diffstat (limited to '7.3')
-rw-r--r--7.3/Makefile12
-rw-r--r--7.3/main.c9
-rw-r--r--7.3/mprintf.c165
-rw-r--r--7.3/mprintf.h1
4 files changed, 187 insertions, 0 deletions
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 <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <stdarg.h>
+#include <ctype.h>
+#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, ...);