From 32d555158f021d385d5de96507de368351813006 Mon Sep 17 00:00:00 2001 From: Axy Date: Sat, 1 Nov 2025 00:40:57 +0100 Subject: [PATCH] Split in multiple files --- Makefile | 2 +- formats.c | 88 +++++++++ ft_printf.c | 447 +-------------------------------------------- ft_printf_shared.h | 117 ++++++++++++ libftprintf.h | 2 +- parse.c | 75 ++++++++ scalar.c | 85 +++++++++ utils.c | 46 +++++ utils2.c | 61 +++++++ 9 files changed, 478 insertions(+), 445 deletions(-) create mode 100644 formats.c create mode 100644 ft_printf_shared.h create mode 100644 parse.c create mode 100644 scalar.c create mode 100644 utils.c create mode 100644 utils2.c diff --git a/Makefile b/Makefile index ca674ac..eb1c7b0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ NAME=libftprintf.a -SRCS=ft_printf.c +SRCS=utils2.c formats.c utils.c parse.c ft_printf.c scalar.c OBJS=${SRCS:.c=.o} diff --git a/formats.c b/formats.c new file mode 100644 index 0000000..511345d --- /dev/null +++ b/formats.c @@ -0,0 +1,88 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* formats.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/01 00:11:59 by agilliar #+# #+# */ +/* Updated: 2025/11/01 00:35:04 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf_shared.h" + +int ft_putformat_char(const t_format *format, t_step_arg arg, bool sim) +{ + (void) format; + return (ft_putchar_sim(arg.v_int, sim)); +} + +int ft_putformat_str(const t_format *format, t_step_arg arg, bool sim) +{ + int i; + const char *s; + + i = 0; + s = arg.v_ptr; + if (!s) + s = "(null)"; + while ((!format->enable_precision || format->precision > i) && s[i]) + if (ft_putchar_sim(s[i++], sim) == -1) + return (-1); + return (i); +} + +int ft_putformat_ptr(const t_format *format, t_step_arg arg, bool sim) +{ + int written; + uint64_t val; + + val = (uint64_t) arg.v_ptr; + if (!arg.v_ptr) + { + arg.v_ptr = "(nil)"; + return (ft_putformat_str(format, arg, sim)); + } + if (ft_putprefix(format, sim, val) == -1) + return (-1); + written = ft_put_uint64(ft_uint64_format_new(format), val, sim); + if (written == -1) + return (-1); + return (written + 2); +} + +int ft_putformat_scalar(const t_format *format, t_step_arg arg, bool sim) +{ + int sign; + int prefix; + int core; + int precision; + int zero_pad; + + sign = ft_putsign(format, arg, sim); + if (sign == -1) + return (-1); + prefix = ft_putprefix(format, sim, ft_int_arg_abs(format, arg)); + if (prefix == -1) + return (-1); + core = ft_put_uint64(ft_uint64_format_new(format), + ft_int_arg_abs(format, arg), true); + precision = ft_precision_pad(format, core, sim); + if (precision == -1) + return (-1); + zero_pad = ft_zero_pad(format, sign + prefix + precision + core, sim); + if (zero_pad == -1) + return (-1); + if (ft_put_uint64(ft_uint64_format_new(format), + ft_int_arg_abs(format, arg), sim) == -1) + return (-1); + return (sign + prefix + zero_pad + precision + core); +} + +int ft_putformat_percent(const t_format *format, t_step_arg arg, bool sim) +{ + (void)format; + (void)arg; + return (ft_putchar_sim('%', sim)); +} diff --git a/ft_printf.c b/ft_printf.c index fe4badc..000bdd4 100644 --- a/ft_printf.c +++ b/ft_printf.c @@ -6,277 +6,13 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/10/29 14:24:47 by agilliar #+# #+# */ -/* Updated: 2025/10/31 23:52:32 by agilliar ### ########.fr */ +/* Updated: 2025/11/01 00:21:44 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ #include -#include -#include -#include -#include -/* - Because of variadic argument promotion, - we represent an expected char as an int -*/ -typedef enum e_step -{ - STEP_INT, - STEP_UINT, - STEP_PTR, - STEP_NONE, -} t_step; - -/* - Ditto for t_step -*/ -typedef union u_step_arg -{ - int v_int; - unsigned int v_uint; - void *v_ptr; -} t_step_arg; - -typedef enum e_sign_flag -{ - SIGN_NEG_ONLY, - SIGN_FORCED, - SIGN_SPACE, -} t_sign_flag; - -typedef enum e_justify -{ - JUSTIFY_LEFT, - JUSTIFY_RIGHT, -} t_justify; - -typedef enum e_specifier -{ - SPECIFIER_NONE, - SPECIFIER_CHAR, - SPECIFIER_STR, - SPECIFIER_PTR, - SPECIFIER_INT, - SPECIFIER_UINT, - SPECIFIER_UINT_HEX_LOWER, - SPECIFIER_UINT_HEX_UPPER, - SPECIFIER_PERCENT, -} t_specifier; - -typedef struct s_format -{ - t_specifier specifier; - t_sign_flag sign_flag; - t_justify justify; - bool num_prefix; - int width; - bool zero_pad; - int precision; - bool enable_precision; -} t_format; - -typedef struct s_uint64_format -{ - bool print_zeros; - uint64_t base; - const char *base_s; -} t_uint64_format; - -int ft_putchar_sim(char c, bool sim) -{ - if (!sim && write(STDOUT_FILENO, &c, 1) != 1) - return (-1); - return (1); -} - -int ft_putnchar(char c, int n, bool sim) -{ - int i; - - i = 0; - while (i++ < n) - if (ft_putchar_sim(c, sim) == -1) - return (-1); - return (n); -} - -uint64_t ft_int_abs(int64_t n) -{ - if (n < 0) - return (-n); - return (n); -} - -t_uint64_format ft_uint64_format_new(const t_format *format) -{ - t_uint64_format res; - t_specifier spec; - - res.print_zeros = !format->enable_precision; - spec = format->specifier; - res.base = 16; - res.base_s = "0123456789abcdef"; - if (spec == SPECIFIER_INT || spec == SPECIFIER_UINT) - res.base = 10; - if (spec == SPECIFIER_UINT_HEX_UPPER) - res.base_s = "0123456789ABCDEF"; - return (res); -} - -/* - Prints a uint64_t without prefixes, padding or precision padding -*/ -int ft_put_uint64(t_uint64_format format, uint64_t n, bool sim) -{ - int written; - uint64_t base; - const char *base_s; - - if (!n && !format.print_zeros) - return (0); - format.print_zeros = true; - base = format.base; - base_s = format.base_s; - if (n < base) - written = 0; - else - written = ft_put_uint64(format, n / base, sim); - if (written == -1 || ft_putchar_sim(base_s[n % base], sim) == -1) - return (-1); - return (written + 1); -} - -int ft_putprefix(const t_format *format, bool sim, uint64_t n) -{ - t_specifier spec; - char c; - - if (n == 0) - return ; - spec = format->specifier; - if (!format->num_prefix && spec != SPECIFIER_PTR) - return (0); - if (spec == SPECIFIER_PTR || spec == SPECIFIER_UINT_HEX_LOWER) - c = 'x'; - else if (spec == SPECIFIER_UINT_HEX_UPPER) - c = 'X'; - else - return (0); - if (ft_putchar_sim('0', sim) == -1 - || ft_putchar_sim(c, sim) == -1) - return (-1); - return (2); -} - -int ft_precision_pad(const t_format *format, int written, bool sim) -{ - if (written >= format->precision || !format->enable_precision) - return (0); - return (ft_putnchar('0', format->precision - written, sim)); -} - -int ft_zero_pad(const t_format *format, int written, bool sim) -{ - if (written >= format->width || !format->zero_pad) - return (0); - return (ft_putnchar('0', format->width - written, sim)); -} - -int ft_putformat_char(const t_format *format, t_step_arg arg, bool sim) -{ - (void) format; - return (ft_putchar_sim(arg.v_int, sim)); -} - -int ft_putformat_str(const t_format *format, t_step_arg arg, bool sim) -{ - int i; - const char *s; - - i = 0; - s = arg.v_ptr; - if (!s) - s = "(null)"; - while ((!format->enable_precision || format->precision > i) && s[i]) - if (ft_putchar_sim(s[i++], sim) == -1) - return (-1); - return (i); -} - -int ft_putformat_ptr(const t_format *format, t_step_arg arg, bool sim) -{ - int written; - uint64_t val; - - val = (uint64_t) arg.v_ptr; - if (!arg.v_ptr) - { - arg.v_ptr = "(nil)"; - return (ft_putformat_str(format, arg, sim)); - } - if (ft_putprefix(format, sim, val) == -1) - return (-1); - written = ft_put_uint64(ft_uint64_format_new(format), val, sim); - if (written == -1) - return (-1); - return (written + 2); -} - -uint64_t ft_int_arg_abs(const t_format *format, t_step_arg arg) -{ - if (format->specifier == SPECIFIER_INT) - return (ft_int_abs(arg.v_int)); - return (arg.v_uint); -} - -int ft_putsign(const t_format *format, t_step_arg arg, bool sim) -{ - if (format->specifier != SPECIFIER_INT) - return (0); - if (arg.v_int < 0) - return (ft_putchar_sim('-', sim)); - if (format->sign_flag == SIGN_FORCED) - return (ft_putchar_sim('+', sim)); - if (format->sign_flag == SIGN_SPACE) - return (ft_putchar_sim(' ', sim)); - return (0); -} - -int ft_putformat_scalar(const t_format *format, t_step_arg arg, bool sim) -{ - int sign; - int prefix; - int core; - int precision; - int zero_pad; - - sign = ft_putsign(format, arg, sim); - if (sign == -1) - return (-1); - prefix = ft_putprefix(format, sim, ft_int_arg_abs(format, arg)); - if (prefix == -1) - return (-1); - core = ft_put_uint64(ft_uint64_format_new(format), - ft_int_arg_abs(format, arg), true); - precision = ft_precision_pad(format, core, sim); - if (precision == -1) - return (-1); - zero_pad = ft_zero_pad(format, sign + prefix + precision + core, sim); - if (zero_pad == -1) - return (-1); - if (ft_put_uint64(ft_uint64_format_new(format), - ft_int_arg_abs(format, arg), sim) == -1) - return (-1); - return (sign + prefix + zero_pad + precision + core); -} - -int ft_putformat_percent(const t_format *format, t_step_arg arg, bool sim) -{ - (void)format; - (void)arg; - return (ft_putchar_sim('%', sim)); -} +#include "ft_printf_shared.h" int ft_putformat(const t_format *format, t_step_arg arg) { @@ -307,99 +43,6 @@ int ft_putformat(const t_format *format, t_step_arg arg) return (len + (len < format->width) * (format->width - len)); } -t_format ft_format_default(void) -{ - t_format res; - - res.specifier = SPECIFIER_NONE; - res.sign_flag = SIGN_NEG_ONLY; - res.justify = JUSTIFY_RIGHT; - res.num_prefix = false; - res.width = 0; - res.zero_pad = false; - res.precision = 0; - res.enable_precision = false; - return (res); -} - -int ft_parse_num(const char **s) -{ - int res; - - res = 0; - while (**s >= '0' && **s <= '9') - res = res * 10 + '0' - *((*s)++); - return (res); -} - -/* - norminette doesn't want switch and case? - fine then, poor man's switch -*/ -bool ft_parse_flag(char c, t_format *format) -{ - if (c == '-') - format->justify = JUSTIFY_LEFT; - else if (c == '+') - format->sign_flag = SIGN_FORCED; - else if (c == ' ') - format->sign_flag = SIGN_SPACE; - else if (c == '#') - format->num_prefix = true; - else if (c == '0') - format->zero_pad = true; - else - return (false); - return (true); -} - -void ft_parse_width(const char **s, t_format *format) -{ - while (**s >= '0' && **s <= '9') - format->width = format->width * 10 + *((*s)++) - '0'; -} - -void ft_parse_precision(const char **s, t_format *format) -{ - if (**s != '.') - return ; - (*s)++; - format->enable_precision = true; - while (**s >= '0' && **s <= '9') - format->precision = format->precision * 10 + *((*s)++) - '0'; -} - -/* - really wish there was a language feature to allow doing that in a neater way, - but of course no such thing! -*/ -t_specifier ft_parse_specifier(char c) -{ - if (c == 'c') - return (SPECIFIER_CHAR); - if (c == 's') - return (SPECIFIER_STR); - if (c == 'p') - return (SPECIFIER_PTR); - if (c == 'd' || c == 'i') - return (SPECIFIER_INT); - if (c == 'u') - return (SPECIFIER_UINT); - if (c == 'x') - return (SPECIFIER_UINT_HEX_LOWER); - if (c == 'X') - return (SPECIFIER_UINT_HEX_UPPER); - if (c == '%') - return (SPECIFIER_PERCENT); - return (SPECIFIER_NONE); -} - -void ft_format_normalize(t_format *format) -{ - if (format->enable_precision || format->justify == JUSTIFY_LEFT) - format->zero_pad = false; -} - t_format ft_parse_format(const char **s) { t_format res; @@ -414,7 +57,7 @@ t_format ft_parse_format(const char **s) return (res); } -int ft_print_step(const char **s, t_format *format, t_step_arg arg) +int ft_printf_step(const char **s, t_format *format, t_step_arg arg) { int written; @@ -431,17 +74,6 @@ int ft_print_step(const char **s, t_format *format, t_step_arg arg) return (0); } -t_step specifier_to_step(t_specifier spec) -{ - if (spec == SPECIFIER_NONE || spec == SPECIFIER_PERCENT) - return (STEP_NONE); - if (spec == SPECIFIER_STR || spec == SPECIFIER_PTR) - return (STEP_PTR); - if (spec == SPECIFIER_UINT) - return (STEP_UINT); - return (STEP_INT); -} - int ft_printf(const char *s, ...) { va_list args; @@ -455,7 +87,7 @@ int ft_printf(const char *s, ...) format = ft_format_default(); while (*s || format.specifier != SPECIFIER_NONE) { - written = ft_print_step(&s, &format, arg); + written = ft_printf_step(&s, &format, arg); if (written == -1) return (-1); count += written; @@ -469,74 +101,3 @@ int ft_printf(const char *s, ...) va_end(args); return (count); } - -/* -#include -#include - -#define TEST_PRINTF(...) {int r1 = printf(__VA_ARGS__); fflush(stdout); int r2 = ft_printf(__VA_ARGS__); if (r1 != r2) {fprintf(stderr, "printf failed, r1: %i, r2: %i\n", r1, r2); res = 1;}} - -int main(void) -{ - int res = 0; - const void *test_ptr = "test"; - TEST_PRINTF("this %corks\n", 'w'); - TEST_PRINTF("this %3corks\n", 'w'); - TEST_PRINTF("this %s\n", "is awesome"); - TEST_PRINTF("this %.5s\n", "is awesome"); - TEST_PRINTF("this %2s\n", "is awesome"); - TEST_PRINTF("this %10.6s\n", "is awesome"); - TEST_PRINTF("this %.6s\n", "is awesome"); - TEST_PRINTF("this %1.6s\n", "is awesome"); - TEST_PRINTF("this %.6s\n", NULL); - TEST_PRINTF("this %p\n", NULL); - TEST_PRINTF("this %0p\n", test_ptr); - TEST_PRINTF("this %-24p a\n", test_ptr); - TEST_PRINTF("this %24p a\n", test_ptr); - TEST_PRINTF("this %i a\n", 12); - TEST_PRINTF("this %d a\n", 12); - TEST_PRINTF("this %i a\n", INT_MAX); - TEST_PRINTF("this %d a\n", INT_MIN); - TEST_PRINTF("this %.0i a\n", 0); - TEST_PRINTF("this %5.0d a\n", 0); - TEST_PRINTF("this %#-10i a\n", 12); - TEST_PRINTF("this %#-10.5d a\n", 12); - TEST_PRINTF("this % 10.5i a\n", 12); - TEST_PRINTF("this % 10.5d a\n", -123); - TEST_PRINTF("this % .5i a\n", 12); - TEST_PRINTF("this %+10.5d a\n", 12); - TEST_PRINTF("this %+10.5i a\n", -123); - TEST_PRINTF("this %010.5d a\n", 12); - TEST_PRINTF("this %0-10.5i a\n", 12); - TEST_PRINTF("this %020u a\n", UINT_MAX); - TEST_PRINTF("this %.0u a\n", 0); - TEST_PRINTF("this %-10.0u a\n", 15); - TEST_PRINTF("this %020x a\n", UINT_MAX); - TEST_PRINTF("this %.0x a\n", 0); - TEST_PRINTF("this %-10.0x a\n", 15); - TEST_PRINTF("this %020X a\n", UINT_MAX); - TEST_PRINTF("this %.0X a\n", 0); - TEST_PRINTF("this %-10.0X a\n", 15); - TEST_PRINTF("this %#020u a\n", UINT_MAX); - TEST_PRINTF("this %#.0u a\n", 0); - TEST_PRINTF("this %#-10.0u a\n", 15); - TEST_PRINTF("this %#020x a\n", UINT_MAX); - TEST_PRINTF("this %#.0x a\n", 0); - TEST_PRINTF("this %#-10.0x a\n", 15); - TEST_PRINTF("this %#020X a\n", UINT_MAX); - TEST_PRINTF("this %#.0X a\n", 0); - TEST_PRINTF("this %#-10.0X a\n", 15); - TEST_PRINTF("this %+#020u a\n", UINT_MAX); - TEST_PRINTF("this %+#.0u a\n", 0); - TEST_PRINTF("this %+#-10.0u a\n", 15); - TEST_PRINTF("this %+#020x a\n", UINT_MAX); - TEST_PRINTF("this %+#.0x a\n", 0); - TEST_PRINTF("this %+#-10.0x a\n", 15); - TEST_PRINTF("this %+#020X a\n", UINT_MAX); - TEST_PRINTF("this %+#.0X a\n", 0); - TEST_PRINTF("this %+#-10.0X a\n", 15); - TEST_PRINTF("%% hai %15s%05i\n", "this num is: ", 621); - - return res; -} -*/ diff --git a/ft_printf_shared.h b/ft_printf_shared.h new file mode 100644 index 0000000..91bdbf7 --- /dev/null +++ b/ft_printf_shared.h @@ -0,0 +1,117 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf_shared.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/01 00:07:43 by agilliar #+# #+# */ +/* Updated: 2025/11/01 00:39:45 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PRINTF_SHARED_H +# define FT_PRINTF_SHARED_H + +# include +# include + +/* + Because of variadic argument promotion, + we represent an expected char as an int +*/ +typedef enum e_step +{ + STEP_INT, + STEP_UINT, + STEP_PTR, + STEP_NONE, +} t_step; + +/* + Ditto for t_step +*/ +typedef union u_step_arg +{ + int v_int; + unsigned int v_uint; + void *v_ptr; +} t_step_arg; + +typedef enum e_sign_flag +{ + SIGN_NEG_ONLY, + SIGN_FORCED, + SIGN_SPACE, +} t_sign_flag; + +typedef enum e_justify +{ + JUSTIFY_LEFT, + JUSTIFY_RIGHT, +} t_justify; + +typedef enum e_specifier +{ + SPECIFIER_NONE, + SPECIFIER_CHAR, + SPECIFIER_STR, + SPECIFIER_PTR, + SPECIFIER_INT, + SPECIFIER_UINT, + SPECIFIER_UINT_HEX_LOWER, + SPECIFIER_UINT_HEX_UPPER, + SPECIFIER_PERCENT, +} t_specifier; + +typedef struct s_format +{ + t_specifier specifier; + t_sign_flag sign_flag; + t_justify justify; + bool num_prefix; + int width; + bool zero_pad; + int precision; + bool enable_precision; +} t_format; + +typedef struct s_uint64_format +{ + bool print_zeros; + uint64_t base; + const char *base_s; +} t_uint64_format; + +int ft_putformat_char(const t_format *format, + t_step_arg arg, bool sim); +int ft_putformat_str(const t_format *format, + t_step_arg arg, bool sim); +int ft_putformat_ptr(const t_format *format, + t_step_arg arg, bool sim); +int ft_putformat_scalar(const t_format *format, + t_step_arg arg, bool sim); +int ft_putformat_percent(const t_format *format, + t_step_arg arg, bool sim); + +int ft_putchar_sim(char c, bool sim); +int ft_putnchar(char c, int n, bool sim); +uint64_t ft_int_arg_abs(const t_format *format, t_step_arg arg); + +t_format ft_format_default(void); +t_step specifier_to_step(t_specifier spec); +void ft_format_normalize(t_format *format); +t_uint64_format ft_uint64_format_new(const t_format *format); + +bool ft_parse_flag(char c, t_format *format); +void ft_parse_width(const char **s, t_format *format); +void ft_parse_precision(const char **s, t_format *format); +t_specifier ft_parse_specifier(char c); + +int ft_put_uint64(t_uint64_format format, uint64_t n, bool sim); +int ft_putprefix(const t_format *format, bool sim, uint64_t n); +int ft_precision_pad(const t_format *format, int written, bool sim); +int ft_zero_pad(const t_format *format, int written, bool sim); +int ft_putsign(const t_format *format, t_step_arg arg, bool sim); + +#endif diff --git a/libftprintf.h b/libftprintf.h index b43b38d..268fd80 100644 --- a/libftprintf.h +++ b/libftprintf.h @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/10/29 14:21:01 by agilliar #+# #+# */ -/* Updated: 2025/10/31 23:33:11 by agilliar ### ########.fr */ +/* Updated: 2025/11/01 00:08:24 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..b55d935 --- /dev/null +++ b/parse.c @@ -0,0 +1,75 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/01 00:15:07 by agilliar #+# #+# */ +/* Updated: 2025/11/01 00:40:31 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf_shared.h" + +/* + norminette doesn't want switch and case? + fine then, poor man's switch +*/ +bool ft_parse_flag(char c, t_format *format) +{ + if (c == '-') + format->justify = JUSTIFY_LEFT; + else if (c == '+') + format->sign_flag = SIGN_FORCED; + else if (c == ' ') + format->sign_flag = SIGN_SPACE; + else if (c == '#') + format->num_prefix = true; + else if (c == '0') + format->zero_pad = true; + else + return (false); + return (true); +} + +void ft_parse_width(const char **s, t_format *format) +{ + while (**s >= '0' && **s <= '9') + format->width = format->width * 10 + *((*s)++) - '0'; +} + +void ft_parse_precision(const char **s, t_format *format) +{ + if (**s != '.') + return ; + (*s)++; + format->enable_precision = true; + while (**s >= '0' && **s <= '9') + format->precision = format->precision * 10 + *((*s)++) - '0'; +} + +/* + really wish there was a language feature to allow doing that in a neater way, + but of course no such thing! +*/ +t_specifier ft_parse_specifier(char c) +{ + if (c == 'c') + return (SPECIFIER_CHAR); + if (c == 's') + return (SPECIFIER_STR); + if (c == 'p') + return (SPECIFIER_PTR); + if (c == 'd' || c == 'i') + return (SPECIFIER_INT); + if (c == 'u') + return (SPECIFIER_UINT); + if (c == 'x') + return (SPECIFIER_UINT_HEX_LOWER); + if (c == 'X') + return (SPECIFIER_UINT_HEX_UPPER); + if (c == '%') + return (SPECIFIER_PERCENT); + return (SPECIFIER_NONE); +} diff --git a/scalar.c b/scalar.c new file mode 100644 index 0000000..7a0c87d --- /dev/null +++ b/scalar.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* scalar.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/01 00:10:22 by agilliar #+# #+# */ +/* Updated: 2025/11/01 00:40:38 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf_shared.h" + +/* + Prints a uint64_t without prefixes, padding or precision padding +*/ +int ft_put_uint64(t_uint64_format format, uint64_t n, bool sim) +{ + int written; + uint64_t base; + const char *base_s; + + if (!n && !format.print_zeros) + return (0); + format.print_zeros = true; + base = format.base; + base_s = format.base_s; + if (n < base) + written = 0; + else + written = ft_put_uint64(format, n / base, sim); + if (written == -1 || ft_putchar_sim(base_s[n % base], sim) == -1) + return (-1); + return (written + 1); +} + +int ft_putprefix(const t_format *format, bool sim, uint64_t n) +{ + t_specifier spec; + char c; + + if (n == 0) + return (0); + spec = format->specifier; + if (!format->num_prefix && spec != SPECIFIER_PTR) + return (0); + if (spec == SPECIFIER_PTR || spec == SPECIFIER_UINT_HEX_LOWER) + c = 'x'; + else if (spec == SPECIFIER_UINT_HEX_UPPER) + c = 'X'; + else + return (0); + if (ft_putchar_sim('0', sim) == -1 + || ft_putchar_sim(c, sim) == -1) + return (-1); + return (2); +} + +int ft_precision_pad(const t_format *format, int written, bool sim) +{ + if (written >= format->precision || !format->enable_precision) + return (0); + return (ft_putnchar('0', format->precision - written, sim)); +} + +int ft_zero_pad(const t_format *format, int written, bool sim) +{ + if (written >= format->width || !format->zero_pad) + return (0); + return (ft_putnchar('0', format->width - written, sim)); +} + +int ft_putsign(const t_format *format, t_step_arg arg, bool sim) +{ + if (format->specifier != SPECIFIER_INT) + return (0); + if (arg.v_int < 0) + return (ft_putchar_sim('-', sim)); + if (format->sign_flag == SIGN_FORCED) + return (ft_putchar_sim('+', sim)); + if (format->sign_flag == SIGN_SPACE) + return (ft_putchar_sim(' ', sim)); + return (0); +} diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..f5b87ed --- /dev/null +++ b/utils.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/01 00:09:22 by agilliar #+# #+# */ +/* Updated: 2025/11/01 00:40:14 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include "ft_printf_shared.h" + +int ft_putchar_sim(char c, bool sim) +{ + if (!sim && write(STDOUT_FILENO, &c, 1) != 1) + return (-1); + return (1); +} + +int ft_putnchar(char c, int n, bool sim) +{ + int i; + + i = 0; + while (i++ < n) + if (ft_putchar_sim(c, sim) == -1) + return (-1); + return (n); +} + +uint64_t ft_int_abs(int64_t n) +{ + if (n < 0) + return (-n); + return (n); +} + +uint64_t ft_int_arg_abs(const t_format *format, t_step_arg arg) +{ + if (format->specifier == SPECIFIER_INT) + return (ft_int_abs(arg.v_int)); + return (arg.v_uint); +} diff --git a/utils2.c b/utils2.c new file mode 100644 index 0000000..5ea7e52 --- /dev/null +++ b/utils2.c @@ -0,0 +1,61 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* utils2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/01 00:17:11 by agilliar #+# #+# */ +/* Updated: 2025/11/01 00:34:51 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf_shared.h" + +t_step specifier_to_step(t_specifier spec) +{ + if (spec == SPECIFIER_NONE || spec == SPECIFIER_PERCENT) + return (STEP_NONE); + if (spec == SPECIFIER_STR || spec == SPECIFIER_PTR) + return (STEP_PTR); + if (spec == SPECIFIER_UINT) + return (STEP_UINT); + return (STEP_INT); +} + +t_uint64_format ft_uint64_format_new(const t_format *format) +{ + t_uint64_format res; + t_specifier spec; + + res.print_zeros = !format->enable_precision; + spec = format->specifier; + res.base = 16; + res.base_s = "0123456789abcdef"; + if (spec == SPECIFIER_INT || spec == SPECIFIER_UINT) + res.base = 10; + if (spec == SPECIFIER_UINT_HEX_UPPER) + res.base_s = "0123456789ABCDEF"; + return (res); +} + +t_format ft_format_default(void) +{ + t_format res; + + res.specifier = SPECIFIER_NONE; + res.sign_flag = SIGN_NEG_ONLY; + res.justify = JUSTIFY_RIGHT; + res.num_prefix = false; + res.width = 0; + res.zero_pad = false; + res.precision = 0; + res.enable_precision = false; + return (res); +} + +void ft_format_normalize(t_format *format) +{ + if (format->enable_precision || format->justify == JUSTIFY_LEFT) + format->zero_pad = false; +} -- 2.51.0