diff options
Diffstat (limited to '')
-rw-r--r-- | libft/src/ft_printf_treat_flags.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/libft/src/ft_printf_treat_flags.c b/libft/src/ft_printf_treat_flags.c new file mode 100644 index 0000000..cb60c19 --- /dev/null +++ b/libft/src/ft_printf_treat_flags.c @@ -0,0 +1,147 @@ +/* ************************************************************************** */ +/* LE - / */ +/* / */ +/* ft_printf_treat_flags.c .:: .:/ . .:: */ +/* +:+:+ +: +: +:+:+ */ +/* By: rbousset <marvin@le-101.fr> +:+ +: +: +:+ */ +/* #+# #+ #+ #+# */ +/* Created: 2019/12/31 14:41:01 by rbousset #+# ## ## #+# */ +/* Updated: 2019/12/31 14:41:01 by rbousset ### #+. /#+ ###.fr */ +/* / */ +/* / */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdlib.h> +#include <stdarg.h> + +static int + ft_printf_get_width(va_list arg, t_printflist *pflist) +{ + char *nstr; + char *nstr_ptr; + int ret; + + if (ft_strlchr(pflist->fullflag, '.') >= 0) + nstr = ft_substr(pflist->fullflag, 0, + ft_strlchr(pflist->fullflag, '.')); + else + nstr = ft_strdup(pflist->fullflag); + nstr_ptr = nstr; + nstr = ft_printf_get_width_nstr(nstr, pflist); + ret = ft_printf_fetch_width(arg, nstr, pflist); + ft_memdel(nstr_ptr); + (ret < 0) ? (pflist->isreverse = 1) : 0; + (ret < 0) ? (ret = -ret) : 0; + return (ret); +} + +static int + ft_printf_get_precision(va_list arg, int pos, t_printflist *pflist) +{ + int ret; + char *ptr; + + ptr = pflist->fullflag; + if (pflist->isaz && ft_strlchr(pflist->fullflag, '+') >= 0) + { + pflist->isaplus = 1; + if (ft_strlen(ptr) < pflist->flaglen) + ptr += 1; + } + if (*(ptr + pos + 1) == '*') + { + ret = va_arg(arg, int); + (ret < 0) ? (ret = 0) : 0; + return (ret); + } + else + ret = ft_atoi(ptr + pos + 1); + if (ret == 0) + return (-1); + return (ret); +} + +/* +** Corresponding l ll hh h +** in pflist->lh +** hh = -2 +** h = -1 +** l = 1 +** ll = 2 +*/ + +static void + ft_printf_get_lh(t_printflist *pflist) +{ + int pos; + + if ((pos = ft_strlchr(pflist->fullflag, 'z')) >= 0) + pflist->zflag = 1; + else if ((pos = ft_strlchr(pflist->fullflag, 'l')) >= 0) + { + if (pos + 2 <= (int)pflist->flaglen && + *(pflist->fullflag + pos + 1) == 'l') + pflist->lh = 2; + else + pflist->lh = 1; + } + else if ((pos = ft_strlchr(pflist->fullflag, 'h')) >= 0) + { + if (pos + 2 <= (int)pflist->flaglen && + *(pflist->fullflag + pos + 1) == 'h') + pflist->lh = -2; + else + pflist->lh = -1; + } +} + +static uint8_t + ft_printf_check_z(t_printflist *pflist) +{ + char *ptr; + + ptr = pflist->fullflag; + while (!ft_isdigit(*ptr) && *ptr) + ptr++; + if ((ptr - pflist->fullflag) <= (long)ft_strlen(pflist->fullflag) + && (*ptr == '0') && ft_strlchr(pflist->fullflag, '.') < 0) + return (1); + return (0); +} + +/* +** Uses pflist->fullflag to put +** width and precision in the list +** also l ll hh h +*/ + +void + ft_printf_treat_flags(va_list arg, t_printflist *pflist) +{ + int pos; + char c; + + pflist->flaglen = ft_strlen(pflist->fullflag); + if (((pflist->isaz = ft_printf_check_z(pflist)) == 1 + && ft_strlchr(pflist->fullflag, '.') < 0 + && ft_strlchr(pflist->fullflag, '-') < 0)) + pflist->precision = ft_printf_get_precision(arg, 0, pflist); + else + { + pflist->width = ft_printf_get_width(arg, pflist); + (pflist->isaspace >= 0) ? (pflist->isaspace = 1) : 0; + if ((pos = ft_strlchr(pflist->fullflag, '.')) >= 0) + pflist->precision = ft_printf_get_precision(arg, pos, pflist); + } + (pflist->isaz && pflist->width) ? (pflist->isaz = 0) : 0; + (ft_strlchr(pflist->fullflag, '#') >= 0) ? (pflist->issharp = 1) : 0; + c = pflist->actconv; + if (ft_strlchr(pflist->fullflag, '.') < 0 && pflist->isaz + && pflist->precision < 0 && c != 'c' && c != 's' && c != '%') + { + pflist->precision = 0; + pflist->isaz = 0; + } + ft_printf_get_lh(pflist); +} |