]> Untitled Git - axy/ft/ft_printf.git/commitdiff
Split in multiple files
authorAxy <gilliardmarthey.axel@gmail.com>
Fri, 31 Oct 2025 23:40:57 +0000 (00:40 +0100)
committerAxy <gilliardmarthey.axel@gmail.com>
Fri, 31 Oct 2025 23:40:57 +0000 (00:40 +0100)
Makefile
formats.c [new file with mode: 0644]
ft_printf.c
ft_printf_shared.h [new file with mode: 0644]
libftprintf.h
parse.c [new file with mode: 0644]
scalar.c [new file with mode: 0644]
utils.c [new file with mode: 0644]
utils2.c [new file with mode: 0644]

index ca674accf9b2c68c4b17833ff6b66a938bc34bb1..eb1c7b09a2fbdb5a8b820ce0c574f70f6a92d896 100644 (file)
--- 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 (file)
index 0000000..511345d
--- /dev/null
+++ b/formats.c
@@ -0,0 +1,88 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   formats.c                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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));
+}
index fe4badc515803d762b92860e9362afe85812dc76..000bdd411fb7d5c09a504f79b7c775beafdfc64b 100644 (file)
 /*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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 <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <stdint.h>
 
-/*
-       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 <stdio.h>
-#include <limits.h>
-
-#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 (file)
index 0000000..91bdbf7
--- /dev/null
@@ -0,0 +1,117 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_printf_shared.h                                 :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 <stdbool.h>
+# include <stdint.h>
+
+/*
+       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
index b43b38d8c510bee531e75792d6f511b3532e714d..268fd80faa990927f57870794f6ea41e0f29ed17 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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 (file)
index 0000000..b55d935
--- /dev/null
+++ b/parse.c
@@ -0,0 +1,75 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   parse.c                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 (file)
index 0000000..7a0c87d
--- /dev/null
+++ b/scalar.c
@@ -0,0 +1,85 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   scalar.c                                           :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 (file)
index 0000000..f5b87ed
--- /dev/null
+++ b/utils.c
@@ -0,0 +1,46 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   utils.c                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/11/01 00:09:22 by agilliar          #+#    #+#             */
+/*   Updated: 2025/11/01 00:40:14 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include <unistd.h>
+#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 (file)
index 0000000..5ea7e52
--- /dev/null
+++ b/utils2.c
@@ -0,0 +1,61 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   utils2.c                                           :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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;
+}