diff --git a/Makefile b/Makefile index 2eb6a65..317cca1 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,8 @@ LIBS = $(_LIBS:lib%.a=%) SRCS = ft_printf.c \ ft_next_word.c \ - aside.c \ ft_convert.c \ - ft_width_n_precision.c \ + ft_flag_transform.c \ main.c ODIR = ./builds diff --git a/ft_printf b/ft_printf index a73325a..6b6598d 100755 Binary files a/ft_printf and b/ft_printf differ diff --git a/ft_printf.c b/ft_printf.c index ff0d60c..fa7a265 100644 --- a/ft_printf.c +++ b/ft_printf.c @@ -1,70 +1,131 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: hulamy +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/27 12:01:26 by hulamy #+# #+# */ +/* Updated: 2020/02/27 12:01:30 by hulamy ### ########.fr */ +/* */ +/* ************************************************************************** */ #include "ft_printf.h" /* -** FT_FLAG_TRANSFORM : -** if i = flag_p(&s) | -precision is calculated before width, -** | on str, if < length(str), cuts it, -** print = ft_precision() | on nbr, if > length(nbr), add '0' before, -** | then add '-' if negatif -** | (if precision given with flag '0', it's -** | ignored and cuted from s) -** if i = flag_w(s) | -width is caculated -** if flag_-(&s) | -if flag '-', rm '-' and width from s -** print = ft_rpadd() | -put extra width as ' ' to right, -** else if flag_0(&s) | -if flag '0', rm '0' and width from s -** print = ft_lpadd() | -put extra width as '0' to left -** else | -if just width -** print = ft_lpadd() | put extra width as ' ' to left -** // if flag_+(s) | -** // else if flag_space(s) | -** // if flag_'(s) | -** // if flag_#(s) | -** // print = ft_altfrm() | -** -** int flag_p(char **s); -** char *ft_precision(int i, char *print); -** int flag_w(char *s); -** void flag_-(char **s); -** char *ft_rpadd(int i, char *print); -** char *ft_lpadd(int i, char *print, char c); +** 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 *ft_flag_transform(char *s, char *print, char *type) +char *specifier(char *s) { - print = ft_precision(s, print, type); - print = ft_width(s, print); + char *string; + int i; -// if (flag_+(s)) // -// else if (flag_space(s)) // -// if (flag_'(s)) // -// if (flag_#(s)) // -// print = ft_alternate_form(print) // - return (print); + 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); } /* -** FT_PRINTF : -** va_list ap; -** int length; -** char *print; | -contain the arg converted into a string -** char *type; | -contain the specifier type to use -** | by va_arg -** while s = next_word() | -return the next sequence to be print -** | (either a string, or a conversion) -** type = specifier(s) | -return the type if it's a conversion, or "%", -** | or NULL if it's a string. if it's a -** | single '%' it's considered as a string -** | if convers0, rmvs length & specifier from s -** if !type: ft_put_word() | -print the string if it wasn't a conversion -** else | or if it was a '%%' -** while strchr(s,*) | -for each * present, expand it into s in -** ft_expand_star()| order it appears -** print = ft_convert()| -convert the arg with its type, -** | then trsfm it into a str and rtrn the str -** ft_flag_transform() | -proceed all modification according to flags -** ft_put_word(print) | -print the string fully converted -** return (length) | -return the length of what was printed +** -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 i; + + free(type); + i = ft_strlen(s); + ft_putstr(s); + free(s); + return (i); +} + +/* +** print the string +** because of lake of space, it also free 'type' +*/ + +int length_n_free(int length, char *s) +{ + free(s); + return (length); +} + +/* +** -printf receive a string to print with a variadic number of arguments +** -it will go in a loop through each 'words' +** -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 conversion it will go through some actions : +** -1 expand all the stars from width and .precision +** they always expand into int type +** it's done first because those are the first next args on the va_list +** -2 expand the specifier according to its type and its length +** and put in a string 'print' +** -3 transform 'print' according to the flags */ int ft_printf(char *string, ...) @@ -80,7 +141,7 @@ int ft_printf(char *string, ...) while ((s = next_word(&string)) != NULL) { if ((type = specifier(s)) == NULL) - length += ft_put_word(s); + length += ft_put_word(s, type); else { while (ft_strchr(s, '*')) @@ -90,12 +151,8 @@ int ft_printf(char *string, ...) return (-1); if (!(print = ft_flag_transform(s, print, type))) return (-1); - length += ft_put_word(print); - free(print); + length += ft_put_word(print, type); } - free(s); - free(type); } - free(s); - return (length); + return (length_n_free(length, s)); } diff --git a/ft_printf.h b/ft_printf.h index 9963abd..de62644 100644 --- a/ft_printf.h +++ b/ft_printf.h @@ -8,7 +8,10 @@ # include // ft_printf.c -char *ft_flag_transform(char *s, char *print, char *type); +char *specifier(char *s); +int ft_expand_star(int nbr, char **string); +int ft_put_word(char *s, char *type); +int length_n_free(int length, char *s); int ft_printf(char *string, ...); // ft_next_word.c @@ -16,20 +19,16 @@ int width_precision(char *s); int word_length(char *s); char *next_word(char **s); -// aside.c -char *specifier(char *s); -int ft_put_word(char *s); -int ft_expand_star(int nbr, char **string); - // 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); -// ft_width_n_precision.c +// 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 *tmp, char *s, int width); char *ft_width(char *s, char *print); +char *ft_flag_transform(char *s, char *print, char *type); #endif diff --git a/srcs/aside.c b/srcs/aside.c deleted file mode 100644 index de8394f..0000000 --- a/srcs/aside.c +++ /dev/null @@ -1,101 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* aside.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: hulamy +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/02/19 16:23:01 by hulamy #+# #+# */ -/* Updated: 2020/02/26 17:43:21 by hulamy ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "ft_printf.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); -} - -/* -** print the string -*/ - -int ft_put_word(char *s) -{ - int i; - - i = ft_strlen(s); - ft_putstr(s); - return (i); -} - -/* -** -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); -} diff --git a/srcs/ft_width_n_precision.c b/srcs/ft_flag_transform.c similarity index 91% rename from srcs/ft_width_n_precision.c rename to srcs/ft_flag_transform.c index 4e0724e..3258cb5 100644 --- a/srcs/ft_width_n_precision.c +++ b/srcs/ft_flag_transform.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_width_n_precision.c :+: :+: :+: */ +/* ft_flag_transform.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: hulamy +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2020/02/25 14:48:55 by hulamy #+# #+# */ -/* Updated: 2020/02/26 19:24:18 by hulamy ### ########.fr */ +/* Created: 2020/02/27 11:55:43 by hulamy #+# #+# */ +/* Updated: 2020/02/27 11:55:45 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -154,3 +154,14 @@ char *ft_width(char *s, char *print) return (print); } + +/* +** go through all the transformation flags needs +*/ + +char *ft_flag_transform(char *s, char *print, char *type) +{ + print = ft_precision(s, print, type); + print = ft_width(s, print); + return (print); +}