summaryrefslogtreecommitdiffstats
path: root/libft/src/ft_printf_treat_flags.c
diff options
context:
space:
mode:
Diffstat (limited to 'libft/src/ft_printf_treat_flags.c')
-rw-r--r--libft/src/ft_printf_treat_flags.c146
1 files changed, 146 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..d7b11a1
--- /dev/null
+++ b/libft/src/ft_printf_treat_flags.c
@@ -0,0 +1,146 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ft_printf_treat_flags.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/02/14 17:06:45 by rbousset #+# #+# */
+/* Updated: 2020/02/14 17:06:45 by rbousset ### ########lyon.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((void**)&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);
+}