From 2a7713bab0b7c2cedd4ff2904cc158bcfd7bec24 Mon Sep 17 00:00:00 2001 From: savalet Date: Sun, 27 Oct 2024 22:16:10 +0100 Subject: [PATCH] add: add buffer --- include/my.h | 50 ++++++++++++++++++++++------------ src/baby/baby_put_nbr.c | 19 +++++++------ src/handler/put_bin.c | 17 +++++------- src/handler/put_count_char.c | 4 +-- src/handler/put_float.c | 39 ++------------------------ src/handler/put_hex.c | 42 ++++++++++++++++------------ src/handler/put_nbr.c | 4 +-- src/handler/put_oct.c | 28 +++++++++++-------- src/handler/put_pointer.c | 13 ++++++--- src/handler/put_unsigned_nbr.c | 4 +-- src/handler/putchar.c | 6 ++-- src/handler/putpercentage.c | 6 ++-- src/handler/putstr.c | 21 ++++++++------ src/parser.c | 43 +++++++++++++++++++++-------- src/str_builder.c | 17 ++++++++++++ tests/main.c | 3 +- 16 files changed, 178 insertions(+), 138 deletions(-) create mode 100644 src/str_builder.c diff --git a/include/my.h b/include/my.h index a9570fb..e45b331 100644 --- a/include/my.h +++ b/include/my.h @@ -8,11 +8,11 @@ #ifndef MY_H_ #define MY_H_ - #include - #include #include + #include #include #include + #include #define EXIT_ERROR -84 #define ERROR_OVERFLOW -2 @@ -20,11 +20,16 @@ #define ARRAY_SIZE(array) ((sizeof array) / (sizeof array[0])) #define TODO(s) // renvoie rin + +typedef struct { + char *str; + int count; +} buff_t; + typedef struct { char *fmt; char spec; va_list args; - char *built_string; int width; int precision; int length; @@ -32,17 +37,27 @@ typedef struct { int count; char flags; int written; + buff_t spec_buff; + buff_t prefix_buff; } flags_t; typedef struct { char flag; - int (*ptr)(flags_t *flags); + void (*ptr)(flags_t *flags); } handler_t; +typedef enum { + FLAGS_ALT_FORM = 1 << 0, + FLAGS_PAD_ZERO = 1 << 1, + FLAGS_SET_SPACE = 1 << 2, + FLAGS_PUT_SIGN = 1 << 3, + FLAGS_PAD_RIGHT = 1 << 4 +} flags_bit_shifts_t; + char *baby_revstr(char *); int baby_getnbr(char const *); -int baby_put_nbr(int); -int baby_put_hex(uintptr_t truc); +int baby_put_nbr(int, flags_t *, int); +int baby_put_hex(size_t nb, flags_t *); int baby_putchar(char); int baby_putstr(char *); int baby_stridx(char const *, char); @@ -51,15 +66,16 @@ size_t baby_intlen(size_t truc, int); int baby_strpnum(char **); int my_printf(char *, ...); int parser(char *, va_list); -int printf_put_float(flags_t *); -int printf_put_hex(flags_t *); -int printf_put_nbr(flags_t *); -int printf_put_oct(flags_t *); -int printf_put_pointer(flags_t *); -int printf_put_unsigned_nbr(flags_t *); -int printf_putchar(flags_t *); -int printf_putpercentage(flags_t *); -int printf_putstr(flags_t *); -int printf_put_bin(flags_t *); -int printf_put_hex_upc(flags_t *); +void printf_put_float(flags_t *); +void printf_put_hex(flags_t *); +void printf_put_nbr(flags_t *); +void printf_put_oct(flags_t *); +void printf_put_pointer(flags_t *); +void printf_put_unsigned_nbr(flags_t *); +void printf_putchar(flags_t *); +void printf_putpercentage(flags_t *); +void printf_putstr(flags_t *); +void printf_put_bin(flags_t *); +void printf_put_hex_upc(flags_t *); +int width_printer(flags_t *, int); #endif /* MY_H_ */ diff --git a/src/baby/baby_put_nbr.c b/src/baby/baby_put_nbr.c index 6e01c39..08792e2 100644 --- a/src/baby/baby_put_nbr.c +++ b/src/baby/baby_put_nbr.c @@ -6,17 +6,20 @@ */ #include "my.h" -int baby_put_nbr(int nb) +int baby_put_nbr(int nb, flags_t *flags, int i) { if (nb < 0) { - baby_putchar('-'); + flags->spec_buff.str[i] = '-'; nb *= -1; + i++; } - if (nb < 10) { - baby_putchar(nb + '0'); - } else { - baby_put_nbr(nb / 10); - baby_putchar(nb % 10 +'0'); + if (nb < 10) + flags->spec_buff.str[i] = nb + '0'; + else { + i = baby_put_nbr(nb / 10, flags, i); + flags->spec_buff.str[i] = nb % 10 + '0'; } - return 0; + i++; + flags->spec_buff.count = i; + return i; } diff --git a/src/handler/put_bin.c b/src/handler/put_bin.c index 4fbd62d..86f04bf 100644 --- a/src/handler/put_bin.c +++ b/src/handler/put_bin.c @@ -6,15 +6,17 @@ */ #include "my.h" -int baby_put_bin(int nb) +void printf_put_bin(flags_t *flags) { + int nb = va_arg(flags->args, int); int result = nb; int len = baby_intlen(nb, 2); char str[baby_intlen(nb, 2)]; if (nb == 0){ - baby_putchar('0'); - return 1; + flags->spec_buff.str = "0"; + flags->spec_buff.count = 1; + return; } for (int i = 0; nb != 0; i++) { result = nb % 2; @@ -23,11 +25,6 @@ int baby_put_bin(int nb) } str[len] = '\0'; baby_revstr(str); - baby_putstr(str); - return len; -} - -int printf_put_bin(flags_t *flags) -{ - return baby_put_bin(va_arg(flags->args, int)); + flags->spec_buff.count = len; + flags->spec_buff.str = str; } diff --git a/src/handler/put_count_char.c b/src/handler/put_count_char.c index f317610..b50f4dd 100644 --- a/src/handler/put_count_char.c +++ b/src/handler/put_count_char.c @@ -7,10 +7,10 @@ #include "my.h" -int printf_count_char(flags_t *flags) +void printf_count_char(flags_t *flags) { int *count = va_arg(flags->args, int *); *count = flags->written; - return *count; + flags->spec_buff.count = *count; } diff --git a/src/handler/put_float.c b/src/handler/put_float.c index 260f8f9..519d661 100644 --- a/src/handler/put_float.c +++ b/src/handler/put_float.c @@ -7,42 +7,7 @@ #include "my.h" -static -void printf_put_float2( - int *decimal, - int x, - int precision, - int entier -) +void printf_put_float(flags_t *flags) { - x += baby_put_nbr(entier); - baby_putchar('.'); - x++; - for (int i = 0; i < precision; i++) - if (decimal[i] != 0) - x += baby_put_nbr(decimal[i]); -} - -int printf_put_float(flags_t *flags) -{ - int x = 0; - float nb = va_arg(flags->args, double); - int entier = (int)nb; - int precision = flags->precision; - int decimal[precision]; - int b = 10; - int tt; - - for (int i = 0; i < precision; i++) { - tt = (int)(nb * b); - decimal[i] = tt % 10; - b = b * 10; - } - if (nb < 0) { - baby_putchar('-'); - nb = nb * -1; - entier = nb; - } - printf_put_float2(decimal, x, precision, entier); - return (0); + return; } diff --git a/src/handler/put_hex.c b/src/handler/put_hex.c index 8278aec..69d4ac5 100644 --- a/src/handler/put_hex.c +++ b/src/handler/put_hex.c @@ -4,20 +4,15 @@ ** File description: ** display an int in hexadecimal format */ -#include + #include "my.h" -#include -int baby_put_hex(size_t nb) +int baby_put_hex(size_t nb, flags_t *flags) { size_t result = (size_t)nb; char str[baby_intlen(nb, 16)]; int len = baby_intlen(nb, 16); - if (nb == 0) { - baby_putchar('0'); - return 1; - } for (int i = 0; nb != 0; i++) { result = nb % 16; if (result < 10) @@ -28,20 +23,17 @@ int baby_put_hex(size_t nb) } str[len] = '\0'; baby_revstr(str); - baby_putstr(str); + flags->spec_buff.str = str; return len; } -int baby_put_hex_upc(size_t nb) +static +int baby_put_hex_upc(size_t nb, flags_t *flags) { size_t result = (size_t)nb; char str[baby_intlen(nb, 16)]; int len = baby_intlen(nb, 16); - if (nb == 0) { - baby_putchar('0'); - return 1; - } for (int i = 0; nb != 0; i++) { result = nb % 16; if (result < 10) @@ -52,16 +44,30 @@ int baby_put_hex_upc(size_t nb) } str[len] = '\0'; baby_revstr(str); - baby_putstr(str); + flags->spec_buff.str = str; return len; } -int printf_put_hex_upc(flags_t *flags) +void printf_put_hex_upc(flags_t *flags) { - return baby_put_hex_upc(va_arg(flags->args, void *)); + size_t nb = (size_t)va_arg(flags->args, void *); + + if (nb == 0) { + flags->spec_buff.str = "0"; + flags->spec_buff.count = 1; + return; + } + baby_put_hex_upc(nb, flags); } -int printf_put_hex(flags_t *flags) +void printf_put_hex(flags_t *flags) { - return baby_put_hex(va_arg(flags->args, void *)); + size_t nb = (size_t)va_arg(flags->args, void *); + + if (nb == 0) { + flags->spec_buff.str = "0"; + flags->spec_buff.count = 1; + return; + } + baby_put_hex(nb, flags); } diff --git a/src/handler/put_nbr.c b/src/handler/put_nbr.c index 5378e03..e96c4ac 100644 --- a/src/handler/put_nbr.c +++ b/src/handler/put_nbr.c @@ -7,7 +7,7 @@ #include "my.h" -int printf_put_nbr(flags_t *flags) +void printf_put_nbr(flags_t *flags) { - return baby_put_nbr(va_arg(flags->args, int)); + baby_put_nbr(va_arg(flags->args, int), flags, 0); } diff --git a/src/handler/put_oct.c b/src/handler/put_oct.c index 962c1d0..6566003 100644 --- a/src/handler/put_oct.c +++ b/src/handler/put_oct.c @@ -4,26 +4,30 @@ ** File description: ** display an int given as parameter in octal format */ + +#include + #include "my.h" -int baby_put_oct(int nb) +int baby_put_oct(int nb, flags_t *flags) { - int result = nb; - int len = baby_intlen(nb, 8); - char str[baby_intlen(nb, 8)]; + size_t result = (size_t)nb; + char str[64]; + int i = 0; - for (int i = 0; nb != 0; i++) { + for (; nb != 0; i++) { result = nb % 8; - str[i] = (result + 48); - nb /= 8; + str[i] = (result + '0'); + nb = nb / 8; } - str[len] = '\0'; + str[i] = '\0'; baby_revstr(str); - baby_putstr(str); - return len; + flags->spec_buff.str = str; + flags->spec_buff.count = i; + return 0; } -int printf_put_oct(flags_t *flags) +void printf_put_oct(flags_t *flags) { - return baby_put_oct(va_arg(flags->args, int)); + baby_put_oct(va_arg(flags->args, int), flags); } diff --git a/src/handler/put_pointer.c b/src/handler/put_pointer.c index de54ade..9eb4525 100644 --- a/src/handler/put_pointer.c +++ b/src/handler/put_pointer.c @@ -5,14 +5,19 @@ ** display the adress given as parameter ** in the hexadecimal format */ + #include + #include "my.h" -int printf_put_pointer(flags_t *flags) +void printf_put_pointer(flags_t *flags) { uintptr_t src = (uintptr_t)va_arg(flags->args, void *); + char *old_spec_buff_str; - baby_putstr("0x"); - baby_put_hex(src); - return 0; + old_spec_buff_str = flags->spec_buff.str; + flags->spec_buff.str = "0x"; + flags->spec_buff.str += 2; + baby_put_hex(src, flags); + flags->spec_buff.str = old_spec_buff_str; } diff --git a/src/handler/put_unsigned_nbr.c b/src/handler/put_unsigned_nbr.c index 97f3b8f..2c844de 100644 --- a/src/handler/put_unsigned_nbr.c +++ b/src/handler/put_unsigned_nbr.c @@ -25,7 +25,7 @@ int baby_put_unsigned_nbr(unsigned int nb) return baby_intlen(nb, 10); } -int printf_put_unsigned_nbr(flags_t *flags) +void printf_put_unsigned_nbr(flags_t *flags) { - return baby_put_unsigned_nbr(va_arg(flags->args, int)); + baby_put_unsigned_nbr(va_arg(flags->args, int)); } diff --git a/src/handler/putchar.c b/src/handler/putchar.c index 03e0fc2..5d57184 100644 --- a/src/handler/putchar.c +++ b/src/handler/putchar.c @@ -7,10 +7,10 @@ #include "my.h" -int printf_putchar(flags_t *flags) +void printf_putchar(flags_t *flags) { int c = va_arg(flags->args, int); - return (write(STDOUT_FILENO, &c, sizeof(char)) == sizeof(char)) - ? (int)(sizeof(char)) : EXIT_ERROR; + flags->spec_buff.str[0] = c; + flags->spec_buff.count = 1; } diff --git a/src/handler/putpercentage.c b/src/handler/putpercentage.c index 303f3b4..3ef68f1 100644 --- a/src/handler/putpercentage.c +++ b/src/handler/putpercentage.c @@ -7,8 +7,10 @@ #include "my.h" -int printf_putpercentage(flags_t *flags) +void printf_putpercentage(flags_t *flags) { (void)flags; - return (write(STDOUT_FILENO, "%", sizeof(char))); + flags->width = 0; + flags->spec_buff.str = "%"; + flags->spec_buff.count = 1; } diff --git a/src/handler/putstr.c b/src/handler/putstr.c index 959894c..56d4e63 100644 --- a/src/handler/putstr.c +++ b/src/handler/putstr.c @@ -13,18 +13,23 @@ static const size_t NULL_LEN = sizeof "(null)" - 1; -int printf_putstr(flags_t *flags) +void printf_putstr(flags_t *flags) { int count = 0; char *str = va_arg(flags->args, char *); - if (str == NULL && (size_t)flags->precision < NULL_LEN) - return write(STDOUT_FILENO, "", sizeof ""), 0; - if (str == NULL) - return write(STDOUT_FILENO, "(null)", NULL_LEN); + if (str == NULL && (size_t)flags->precision < NULL_LEN) { + flags->spec_buff.str = ""; + return; + } + if (str == NULL) { + flags->spec_buff.str = "(null)"; + flags->spec_buff.count = NULL_LEN; + return; + } if (flags->precision == -1) flags->precision = INT_MAX; - for (int i = 0; str[i] && i < flags->precision; i++) - count += write(STDOUT_FILENO, &str[i], sizeof(char)); - return (count); + for (; str[count] && count < flags->precision; count++); + flags->spec_buff.str = str; + flags->spec_buff.count = count; } diff --git a/src/parser.c b/src/parser.c index 295eb70..52bbc99 100644 --- a/src/parser.c +++ b/src/parser.c @@ -5,7 +5,6 @@ ** parser */ -#include #include #include #include @@ -46,26 +45,48 @@ void parse_char_settings(flags_t *flags) } static -bool handle_flags(flags_t *flags) +void parse_precision(flags_t *flags) { - flags->fmt++; - if (*flags->fmt == '\0') - return true; - parse_char_settings(flags); - flags->width = baby_strpnum(&flags->fmt); if (*flags->fmt == '.') { flags->fmt++; flags->precision = baby_strpnum(&flags->fmt); } - if (flags->width == ERROR_OVERFLOW || flags->precision == ERROR_OVERFLOW) - return false; - TODO("add len modifier"); +} + +static +void handle_spec(flags_t *flags) +{ for (size_t i = 0; i < ARRAY_SIZE(HANDLERS); i++) { if (*(flags->fmt) == HANDLERS[i].flag) { flags->spec = *(flags->fmt); - flags->count += HANDLERS[i].ptr(flags); + HANDLERS[i].ptr(flags); + flags->count = flags->spec_buff.count; } } +} + +static +bool handle_flags(flags_t *flags) +{ + static char prefix_buff[4]; + static char spec_buff[64]; + + flags->fmt++; + if (*flags->fmt == '\0') + return true; + parse_char_settings(flags); + flags->width = baby_strpnum(&flags->fmt); + parse_precision(flags); + if (flags->width == ERROR_OVERFLOW || flags->precision == ERROR_OVERFLOW) + return false; + flags->spec_buff = (buff_t){ spec_buff, 0 }; + flags->prefix_buff = (buff_t){ prefix_buff, 0 }; + handle_spec(flags); + if (write(STDOUT_FILENO, flags->spec_buff.str, flags->spec_buff.count) != + flags->spec_buff.count) + return false; + if (flags->flags & FLAGS_PAD_RIGHT) + flags->count += width_printer(flags, flags->spec_buff.count); return true; } diff --git a/src/str_builder.c b/src/str_builder.c new file mode 100644 index 0000000..52a49d0 --- /dev/null +++ b/src/str_builder.c @@ -0,0 +1,17 @@ +/* +** EPITECH PROJECT, 2024 +** printf +** File description: +** string builder +*/ + +#include "my.h" + +int width_printer(flags_t *flags, int printed_count) +{ + int i = 0; + + for (; i < flags->width - printed_count; i++) + write(STDOUT_FILENO, " ", sizeof(char)); + return i; +} diff --git a/tests/main.c b/tests/main.c index 43998f0..caf68fe 100644 --- a/tests/main.c +++ b/tests/main.c @@ -6,6 +6,5 @@ int main(void) { int a = 42; - my_printf("%o \n", 3301); - printf("%o \n", 3301); + my_printf("%o", NULL); }