adding v and d printf AND made private header

This commit is contained in:
hugogogo
2026-05-02 21:23:52 +02:00
parent 954b7eb9d8
commit b64ede50af
10 changed files with 336 additions and 361 deletions

View File

@@ -108,10 +108,12 @@ SRCS = ft_memset.c \
ft_concat_free.c \ ft_concat_free.c \
\ \
ft_printf.c \ ft_printf.c \
ft_next_word.c \ pf_next_word.c \
ft_convert.c \ pf_convert.c \
ft_flag_transform.c \ pf_flag_transform.c \
ft_flag_transform_bonus.c \ pf_flag_transform_bonus.c \
pf_utils.c \
\
ft_abs.c \ ft_abs.c \
ft_greater.c \ ft_greater.c \
ft_smaller.c \ ft_smaller.c \
@@ -121,25 +123,6 @@ SRCS = ft_memset.c \
\ \
ft_arrint.c ft_arrint.c
# deleted : \
ft_lstnew.c \
ft_lstadd_front.c \
ft_lstsize.c \
ft_lstlast.c \
ft_lstadd_back.c \
ft_lstdelone.c \
ft_lstclear.c \
ft_lstiter.c \
ft_lstmap.c \
\
ft_putstr.c \
ft_putchar.c \
ft_putendl.c \
ft_putnbr.c \
ft_putnbrendl.c \
ft_putnbrendl_fd.c \
ft_putendl_fd.c \
ODIR = ./builds ODIR = ./builds
OBJS = $(SRCS:%.c=$(ODIR)/%.o) OBJS = $(SRCS:%.c=$(ODIR)/%.o)

View File

@@ -11,52 +11,15 @@
/* ************************************************************************** */ /* ************************************************************************** */
#ifndef FT_PRINTF_H #ifndef FT_PRINTF_H
# define FT_PRINTF_H #define FT_PRINTF_H
# include <stdarg.h> // to use va_arg #include <stdarg.h> // to use va_arg
/* /*
** ft_printf.c ** ft_printf.c
*/ */
char *specifier(char *s); int ft_dprintf(int fd, const char *string, ...);
int ft_expand_star(int nbr, char **string); int ft_printf(const char *string, ...);
int ft_put_word(char *s, char *type, int size); int ft_vdprintf(int fd, const char *string, va_list ap);
char *convert_with_flags(char *s, va_list ap, char *type, int *size);
int ft_printf(char *string, ...);
/*
** ft_next_word.c
*/
int width_precision(char *s);
int word_length(char *s);
char *next_word(char **s);
/*
** ft_convert.c
*/
char *conv_i(char c, long int i);
char *conv_u(char c, unsigned long int i);
char *ft_convert(va_list ap, char *type, char **s);
/*
** ft_flag_transform.c
*/
char *precision_int(char *print, int precision);
char *ft_precision(char *s, char *print, char *type);
char *width_flags(char *print, char *s, int width, int zero);
char *ft_width(char *s, char *print, int *size, char *type);
char *ft_flag_transform(char *s, char *print, char *type, int *size);
/*
** ft_flag_transform_bonus.c
*/
char *ft_plus(char *s, char *print, char *type);
char *ft_sharp(char *s, char *print, char *type);
char *ft_sharp_again(char *s, char *print, char *type);
char *ft_space(char *s, char *print, char *type, int *size);
#endif #endif

View File

@@ -1,75 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_flag_transform_bonus.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/03/12 22:30:50 by hulamy #+# #+# */
/* Updated: 2020/03/12 22:30:57 by hulamy ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_plus(char *s, char *print, char *type)
{
if (!ft_strchrset(type, "di"))
return (print);
if (ft_strchr(s, '+') && !ft_strchr(print, '-'))
print = ft_concat_free(ft_strdup("+"), print);
return (print);
}
char *ft_sharp(char *s, char *print, char *type)
{
if (ft_strchr(s, '#'))
{
if (ft_strchr(type, 'x'))
print = ft_concat_free(ft_strdup("0x"), print);
else
print = ft_concat_free(ft_strdup("0X"), print);
}
return (print);
}
char *ft_sharp_again(char *s, char *print, char *type)
{
char *tmp;
if (!ft_strchr(s, '#'))
return (print);
if (print[0] == '0' && print[1] == '0' && ft_strchrset(type, "xX"))
{
tmp = ft_strchrset("xX", print);
print[1] = tmp[0];
tmp[0] = '0';
}
return (print);
}
char *ft_space(char *s, char *print, char *type, int *size)
{
int i;
i = 0;
if (print[0] == ' ' || !ft_strchr(s, ' ') || !ft_strchrset(type, "diuxX"))
return (print);
while (print[i] == ' ')
i++;
if (print[i] == '-' || print[i] == '+')
return (print);
if (ft_strchr(s, '.') || (i == 0 && print[i] != '0'))
{
print = ft_concat_free(ft_strdup(" "), print);
*size += 1;
}
else
print[i] = ' ';
if (ft_strchr(s, '-') && print[*size - 1] == ' ')
{
print[*size] = '\0';
*size -= 1;
}
return (print);
}

View File

@@ -1,162 +1,81 @@
/* ************************************************************************** */ /* ft_printf.c */
/* */
/* ::: :::::::: */
/* ft_printf.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/03/12 22:31:29 by hulamy #+# #+# */
/* Updated: 2020/06/30 00:41:35 by hulamy ### ########.fr */
/* */
/* ************************************************************************** */
#include "pf_private_header.h"
#include "libft.h" #include "libft.h"
/*
** SPECIFIER :
** receive a word as a string, check if it start by '%', and return the
** specifier (diuxXspefgn) and the length (h hh l ll)
** -if s is a string, or is a single '%'
** return NULL (to print is as a string)
** -if s is a double '%%', remove one '%', and
** return NULL (to print is as a string)
** -then s is a conversion, go to the length and specifier
** -copy them in 'string'
** -and remove them from s
** -return the length and specifier in a string
*/
char *specifier(char *s)
{
char *string;
int i;
if (s[0] != '%' || s[1] == '\0')
return (NULL);
if (s[1] == '%')
{
s[1] = '\0';
return (NULL);
}
i = 1;
while (ft_strchr("#0- +'0123456789.*", s[i]) != NULL)
i++;
string = ft_strdup(s + i);
while (s[i] != '\0')
{
s[i] = '\0';
i++;
}
return (string);
}
/*
** -receive 'i' the number in which '*' will expand
** -turn it into a string
** -calculate the total lentgh of the string '%...' for nbr replacing '*'
** -allocate a new string with this length
** -copy the original str with first '*' expanded into it's corresponding nbr
*/
int ft_expand_star(int nbr, char **string)
{
char *s;
char *n;
int i;
int j;
int k;
n = ft_itoa(nbr);
if (!(s = ft_memalloc(sizeof(char) * (ft_strlen(n) + ft_strlen(*string)))))
return (0);
i = -1;
j = 0;
k = 0;
while ((*string)[++i] != '\0')
{
s[j] = (*string)[i];
if (s[j] == '*')
while (n[k] != '\0')
s[j++] = n[k++];
else
j++;
}
free(n);
free(*string);
*string = s;
return (1);
}
/*
** print the string
** because of lake of space, it also free 'type'
*/
int ft_put_word(char *s, char *type, int size)
{
int i;
i = 0;
while (i < size)
write(1, &(s[i++]), 1);
free(type);
free(s);
return (i);
}
/*
** because of lake of space...
** -1 expand the specifier according to its type and its length
** and put in a string 'print'
** -2 transform 'print' according to the flags
*/
char *convert_with_flags(char *s, va_list ap, char *type, int *size)
{
char *print;
if (!(print = ft_convert(ap, type, &s)))
return (NULL);
if (!(print = ft_flag_transform(s, print, type, size)))
return (NULL);
free(s);
return (print);
}
/* /*
** -printf receive a string to print with a variadic number of arguments ** -printf receive a string to print with a variadic number of arguments
** -it will go in a loop through each 'words' ** -it will go in a loop through each 'words'
** -a word is either a string containing no '%' or a conversion starting by '%' ** -a word is either a string containing no '%' or a conversion starting by '%'
** -if it's a string it's printed right away ** -if it's a string it's printed right away
** -if it's a conversion it will call convert_with_flags for some actions : ** -if it's a conversion it will call pf_convert_with_flags for some actions :
** -1 expand the specifier according to its type and its length ** -1 expand the specifier according to its type and its length
** and put in a string 'print' ** and put in a string 'print'
** -2 transform 'print' according to the flags ** -2 transform 'print' according to the flags
*/ */
int ft_printf(const char *string, ...)
int ft_printf(char *string, ...)
{ {
char *s; va_list ap;
char *type; int ret;
int length;
int size; va_start(ap, string);
va_list ap; ret = ft_vdprintf(STDOUT_FILENO, string, ap);
va_end(ap);
return (ret);
}
/*
** ft_dprintf : prints formatted output to a file descriptor
** @param fd : the file descriptor to write to (e.g., STDOUT_FILENO, STDERR_FILENO)
** @param string: the format string (see ft_printf for format specifiers)
** @param ... : variadic arguments for the format string
** @return : the number of characters printed, or -1 on error
** @note : this is the file descriptor equivalent of ft_printf.
** Use this when you need to print to a specific file descriptor,
** such as STDERR_FILENO or a custom file descriptor from open().
*/
int ft_dprintf(int fd, const char *string, ...)
{
va_list ap;
int ret;
va_start(ap, string);
ret = ft_vdprintf(fd, string, ap);
va_end(ap);
return (ret);
}
/*
** ft_vdprintf : core implementation of formatted output to a file descriptor
** @param fd : the file descriptor to write to
** @param string : the format string (see ft_printf for format specifiers)
** @param ap : va_list containing the variadic arguments for the format string
** @return : the number of characters printed, or -1 on error
** @note : this is the va_list version of ft_dprintf.
** It processes the format string and variadic arguments,
** then writes the result to the file descriptor `fd`.
** This function is used internally by ft_dprintf and ft_printf.
*/
int ft_vdprintf(int fd, const char *string, va_list ap)
{
char *s;
char *type;
int length;
int size;
length = 0; length = 0;
va_start(ap, string); while ((s = pf_next_word(&string)) != NULL)
while ((s = next_word(&string)) != NULL)
{ {
if ((type = specifier(s)) == NULL) if ((type = pf_specifier(s)) == NULL)
length += ft_put_word(s, type, ft_strlen(s)); length += pf_put_word(fd, s, type, ft_strlen(s));
else else
{ {
size = 0; size = 0;
if (!(s = convert_with_flags(s, ap, type, &size))) if (!(s = pf_convert_with_flags(s, ap, type, &size)))
return (-1); return (-1);
length += ft_put_word(s, type, size); length += pf_put_word(fd, s, type, size);
} }
} }
free(s); free(s);
va_end(ap);
return (length); return (length);
} }

View File

@@ -1,15 +1,6 @@
/* ************************************************************************** */ /* pf_convert.c */
/* */
/* ::: :::::::: */
/* ft_convert.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/03/12 22:30:05 by hulamy #+# #+# */
/* Updated: 2020/06/30 00:40:49 by hulamy ### ########.fr */
/* */
/* ************************************************************************** */
#include "pf_private_header.h"
#include "libft.h" #include "libft.h"
/* /*
@@ -36,10 +27,9 @@
** -'h' and 'hh', are traited just like regular size because of ** -'h' and 'hh', are traited just like regular size because of
** default promotion, that promote smaller type than int into int ** default promotion, that promote smaller type than int into int
*/ */
static char *pf_conv_i(char c, long int i)
char *conv_i(char c, long int i)
{ {
char *s; char *s;
if (c == 'c') if (c == 'c')
{ {
@@ -52,9 +42,9 @@ char *conv_i(char c, long int i)
return (NULL); return (NULL);
} }
char *conv_u(char c, unsigned long int i) static char *pf_conv_u(char c, unsigned long int i)
{ {
char *s; char *s;
if (c == 's') if (c == 's')
return (i == 0 ? ft_strdup("(null)") : ft_strdup((char *)i)); return (i == 0 ? ft_strdup("(null)") : ft_strdup((char *)i));
@@ -68,6 +58,42 @@ char *conv_u(char c, unsigned long int i)
return (NULL); return (NULL);
} }
/*
** -receive 'i' the number in which '*' will expand
** -turn it into a string
** -calculate the total lentgh of the string '%...' for nbr replacing '*'
** -allocate a new string with this length
** -copy the original str with first '*' expanded into it's corresponding nbr
*/
static int pf_expand_star(int nbr, char **string)
{
char *s;
char *n;
int i;
int j;
int k;
n = ft_itoa(nbr);
if (!(s = ft_memalloc(sizeof(char) * (ft_strlen(n) + ft_strlen(*string)))))
return (0);
i = -1;
j = 0;
k = 0;
while ((*string)[++i] != '\0')
{
s[j] = (*string)[i];
if (s[j] == '*')
while (n[k] != '\0')
s[j++] = n[k++];
else
j++;
}
free(n);
free(*string);
*string = s;
return (1);
}
/* /*
** -first a loop to expand all the stars from width and .precision ** -first a loop to expand all the stars from width and .precision
** they always expand into int type ** they always expand into int type
@@ -81,22 +107,21 @@ char *conv_u(char c, unsigned long int i)
** (because it will never find a 'p' or a 's' if there are 'uxX' already) ** (because it will never find a 'p' or a 's' if there are 'uxX' already)
** or for 'p' and again for 'p', or 's' twice similarly ** or for 'p' and again for 'p', or 's' twice similarly
*/ */
char *pf_convert(va_list ap, char *type, char **s)
char *ft_convert(va_list ap, char *type, char **s)
{ {
char *tmp; char *tmp;
while (ft_strchr(*s, '*')) while (ft_strchr(*s, '*'))
if (!(ft_expand_star(va_arg(ap, int), s))) if (!(pf_expand_star(va_arg(ap, int), s)))
return (NULL); return (NULL);
if ((tmp = ft_strchrset(type, "dic")) && ft_strchr(type, 'l')) if ((tmp = ft_strchrset(type, "dic")) && ft_strchr(type, 'l'))
return (conv_i(tmp[0], va_arg(ap, long int))); return (pf_conv_i(tmp[0], va_arg(ap, long int)));
if ((tmp = ft_strchrset(type, "dic"))) if ((tmp = ft_strchrset(type, "dic")))
return (conv_i(tmp[0], va_arg(ap, int))); return (pf_conv_i(tmp[0], va_arg(ap, int)));
if ((tmp = ft_strchrset(type, "uxXps")) && ft_strchrset(type, "lps")) if ((tmp = ft_strchrset(type, "uxXps")) && ft_strchrset(type, "lps"))
return (conv_u(tmp[0], va_arg(ap, unsigned long int))); return (pf_conv_u(tmp[0], va_arg(ap, unsigned long int)));
if ((tmp = ft_strchrset(type, "uxX"))) if ((tmp = ft_strchrset(type, "uxX")))
return (conv_u(tmp[0], va_arg(ap, unsigned int))); return (pf_conv_u(tmp[0], va_arg(ap, unsigned int)));
if (ft_strchr(type, '%')) if (ft_strchr(type, '%'))
return (ft_strdup("%")); return (ft_strdup("%"));
if (ft_strchrset(type, "efgn")) if (ft_strchrset(type, "efgn"))

View File

@@ -1,26 +1,16 @@
/* ************************************************************************** */ /* pf_flag_transform.c */
/* */
/* ::: :::::::: */
/* ft_flag_transform.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/03/12 22:30:28 by hulamy #+# #+# */
/* Updated: 2020/03/12 22:30:41 by hulamy ### ########.fr */
/* */
/* ************************************************************************** */
#include "pf_private_header.h"
#include "libft.h" #include "libft.h"
/* /*
** -function that modify the string 'print' according to the precision flag : ** -function that modify the string 'print' according to the precision flag :
** if length(s) < precision, add x '0' bfr nbr, but after '-' if negative ** if length(s) < precision, add x '0' bfr nbr, but after '-' if negative
*/ */
static char *pf_precision_int(char *print, int precision)
char *precision_int(char *print, int precision)
{ {
int i; int i;
char *tmp; char *tmp;
i = ft_strlen(print); i = ft_strlen(print);
if (print[0] == '-') if (print[0] == '-')
@@ -60,18 +50,17 @@ char *precision_int(char *print, int precision)
** -0 if .precision is 0 && print is "0": print nothing ** -0 if .precision is 0 && print is "0": print nothing
** -1 if type is s: if length(s) > precision, removes end of 'print' to print ** -1 if type is s: if length(s) > precision, removes end of 'print' to print
** only x chars, with x = precision ** only x chars, with x = precision
** -2 if type is "diouxX": call fonction 'precision_int' that return : ** -2 if type is "diouxX": call fonction 'pf_precision_int' that return :
** if length(s) < precision, add x '0' bfr nbr, but after '-' if negative ** if length(s) < precision, add x '0' bfr nbr, but after '-' if negative
** -3 if type is "aAeEfF": not covered ** -3 if type is "aAeEfF": not covered
** -4 if type is "gG": not covered ** -4 if type is "gG": not covered
** -5 else: error ** -5 else: error
*/ */
static char *pf_precision(char *s, char *print, char *type)
char *ft_precision(char *s, char *print, char *type)
{ {
char *tmp; char *tmp;
int precision; int precision;
int i; int i;
if ((tmp = ft_strchr(s, '.'))) if ((tmp = ft_strchr(s, '.')))
{ {
@@ -90,7 +79,7 @@ char *ft_precision(char *s, char *print, char *type)
print[i] = '\0'; print[i] = '\0';
} }
else if (ft_strchrset(type, "diouxX")) else if (ft_strchrset(type, "diouxX"))
print = precision_int(print, precision); print = pf_precision_int(print, precision);
} }
return (print); return (print);
} }
@@ -100,12 +89,11 @@ char *ft_precision(char *s, char *print, char *type)
** -if flag '0' is present, put extra width as '0' to left of 'print' ** -if flag '0' is present, put extra width as '0' to left of 'print'
** -else, put extra width as ' ' to left of 'print' ** -else, put extra width as ' ' to left of 'print'
*/ */
static char *pf_width_flags(char *print, char *s, int width, int zero)
char *width_flags(char *print, char *s, int width, int zero)
{ {
char *tmp; char *tmp;
char *minus; char *minus;
int len; int len;
len = ft_strlen(print) + zero; len = ft_strlen(print) + zero;
if (!(tmp = ft_strnew(width))) if (!(tmp = ft_strnew(width)))
@@ -141,15 +129,14 @@ char *width_flags(char *print, char *s, int width, int zero)
** otherwise the int 'size' take the value returned by atoi ** otherwise the int 'size' take the value returned by atoi
** in case print isn't changed, 'size' is the length of 'print' ** in case print isn't changed, 'size' is the length of 'print'
** 3 then if the size of the width shield is bigger than the size of print ** 3 then if the size of the width shield is bigger than the size of print
** (plus zero in case print is a (char)0), call 'width_flags' that will ** (plus zero in case print is a (char)0), call 'pf_width_flags' that will
** create a new char* to contain the string to print after transformation ** create a new char* to contain the string to print after transformation
** 4 otherwise 'size' is the length of print + zero ** 4 otherwise 'size' is the length of print + zero
*/ */
static char *pf_width(char *s, char *print, int *size, char *type)
char *ft_width(char *s, char *print, int *size, char *type)
{ {
char *tmp; char *tmp;
int zero; int zero;
tmp = s; tmp = s;
zero = 0; zero = 0;
@@ -165,7 +152,7 @@ char *ft_width(char *s, char *print, int *size, char *type)
*size = ft_atoi(tmp); *size = ft_atoi(tmp);
tmp[0] = '\0'; tmp[0] = '\0';
if ((unsigned int)*size > ft_strlen(print) + zero) if ((unsigned int)*size > ft_strlen(print) + zero)
print = width_flags(print, s, *size, zero); print = pf_width_flags(print, s, *size, zero);
else else
*size = ft_strlen(print) + zero; *size = ft_strlen(print) + zero;
tmp[0] = '1'; tmp[0] = '1';
@@ -181,19 +168,18 @@ char *ft_width(char *s, char *print, int *size, char *type)
** -then p ** -then p
** -the case of 'p' is treated without any subtelness because i don't care ** -the case of 'p' is treated without any subtelness because i don't care
*/ */
char *pf_flag_transform(char *s, char *print, char *type, int *size)
char *ft_flag_transform(char *s, char *print, char *type, int *size)
{ {
print = ft_precision(s, print, type); print = pf_precision(s, print, type);
print = ft_plus(s, print, type); print = pf_plus(s, print, type);
print = ft_sharp(s, print, type); print = pf_sharp(s, print, type);
if (ft_strchr(type, 'p')) if (ft_strchr(type, 'p'))
{ {
print = ft_concat_free(ft_strdup("0x"), print); print = ft_concat_free(ft_strdup("0x"), print);
*size += 2; *size += 2;
} }
print = ft_width(s, print, size, type); print = pf_width(s, print, size, type);
print = ft_sharp_again(s, print, type); print = pf_sharp_again(s, print, type);
print = ft_space(s, print, type, size); print = pf_space(s, print, type, size);
return (print); return (print);
} }

View File

@@ -0,0 +1,66 @@
/* pf_flag_transform_bonus.c */
#include "pf_private_header.h"
#include "libft.h"
char *pf_plus(char *s, char *print, char *type)
{
if (!ft_strchrset(type, "di"))
return (print);
if (ft_strchr(s, '+') && !ft_strchr(print, '-'))
print = ft_concat_free(ft_strdup("+"), print);
return (print);
}
char *pf_sharp(char *s, char *print, char *type)
{
if (ft_strchr(s, '#'))
{
if (ft_strchr(type, 'x'))
print = ft_concat_free(ft_strdup("0x"), print);
else
print = ft_concat_free(ft_strdup("0X"), print);
}
return (print);
}
char *pf_sharp_again(char *s, char *print, char *type)
{
char *tmp;
if (!ft_strchr(s, '#'))
return (print);
if (print[0] == '0' && print[1] == '0' && ft_strchrset(type, "xX"))
{
tmp = ft_strchrset("xX", print);
print[1] = tmp[0];
tmp[0] = '0';
}
return (print);
}
char *pf_space(char *s, char *print, char *type, int *size)
{
int i;
i = 0;
if (print[0] == ' ' || !ft_strchr(s, ' ') || !ft_strchrset(type, "diuxX"))
return (print);
while (print[i] == ' ')
i++;
if (print[i] == '-' || print[i] == '+')
return (print);
if (ft_strchr(s, '.') || (i == 0 && print[i] != '0'))
{
print = ft_concat_free(ft_strdup(" "), print);
*size += 1;
}
else
print[i] = ' ';
if (ft_strchr(s, '-') && print[*size - 1] == ' ')
{
print[*size] = '\0';
*size -= 1;
}
return (print);
}

View File

@@ -1,15 +1,6 @@
/* ************************************************************************** */ /* pf_next_word.c */
/* */
/* ::: :::::::: */
/* next_word.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/10 13:58:30 by hulamy #+# #+# */
/* Updated: 2020/02/26 18:24:04 by hulamy ### ########.fr */
/* */
/* ************************************************************************** */
#include "pf_private_header.h"
#include "libft.h" #include "libft.h"
/* /*
@@ -19,9 +10,9 @@
** for a '.' for the 'precision' flag ** for a '.' for the 'precision' flag
*/ */
int width_precision(char *s) static int width_precision(const char *s)
{ {
int i; int i;
i = 0; i = 0;
if (ft_strchr("*", s[i]) != NULL) if (ft_strchr("*", s[i]) != NULL)
@@ -47,9 +38,9 @@ int width_precision(char *s)
** to save a line (3 with the brackets) ** to save a line (3 with the brackets)
*/ */
int word_length(char *s) static int word_length(const char *s)
{ {
int i; int i;
i = 1; i = 1;
if (s[0] == '\0') if (s[0] == '\0')
@@ -79,11 +70,11 @@ int word_length(char *s)
** but is treated as a '%' here ** but is treated as a '%' here
*/ */
char *next_word(char **string) char *pf_next_word(const char **string)
{ {
char *s; const char *s;
char *word; char *word;
int i; int i;
s = *string; s = *string;
if (*s == '\0') if (*s == '\0')

View File

@@ -0,0 +1,42 @@
/* pf_private_header.h */
#ifndef FT_PF_PRIVATE_H
#define FT_PF_PRIVATE_H
#include <stdarg.h> // to use va_arg
/*
** pf_next_word.c
*/
char *pf_next_word(const char **s);
/*
** pf_convert.c
*/
char *pf_convert(va_list ap, char *type, char **s);
/*
** pf_flag_transform.c
*/
char *pf_flag_transform(char *s, char *print, char *type, int *size);
/*
** pf_flag_transform_bonus.c
*/
char *pf_plus(char *s, char *print, char *type);
char *pf_sharp(char *s, char *print, char *type);
char *pf_sharp_again(char *s, char *print, char *type);
char *pf_space(char *s, char *print, char *type, int *size);
/*
** pf_utils.c
*/
char *pf_specifier(char *s);
int pf_put_word(int fd, char *s, char *type, int size);
char *pf_convert_with_flags(char *s, va_list ap, char *type, int *size);
#endif

View File

@@ -0,0 +1,75 @@
/* pf_utils.c */
#include "pf_private_header.h"
#include "libft.h"
/*
** SPECIFIER :
** receive a word as a string, check if it start by '%', and return the
** specifier (diuxXspefgn) and the length (h hh l ll)
** -if s is a string, or is a single '%'
** return NULL (to print is as a string)
** -if s is a double '%%', remove one '%', and
** return NULL (to print is as a string)
** -then s is a conversion, go to the length and specifier
** -copy them in 'string'
** -and remove them from s
** -return the length and specifier in a string
*/
char *pf_specifier(char *s)
{
char *string;
int i;
if (s[0] != '%' || s[1] == '\0')
return (NULL);
if (s[1] == '%')
{
s[1] = '\0';
return (NULL);
}
i = 1;
while (ft_strchr("#0- +'0123456789.*", s[i]) != NULL)
i++;
string = ft_strdup(s + i);
while (s[i] != '\0')
{
s[i] = '\0';
i++;
}
return (string);
}
/*
** print the string
** because of lake of space, it also free 'type'
*/
int pf_put_word(int fd, char *s, char *type, int size)
{
int i;
i = 0;
while (i < size)
write(fd, &(s[i++]), 1);
free(type);
free(s);
return (i);
}
/*
** because of lake of space...
** -1 expand the specifier according to its type and its length
** and put in a string 'print'
** -2 transform 'print' according to the flags
*/
char *pf_convert_with_flags(char *s, va_list ap, char *type, int *size)
{
char *print;
if (!(print = pf_convert(ap, type, &s)))
return (NULL);
if (!(print = pf_flag_transform(s, print, type, size)))
return (NULL);
free(s);
return (print);
}