aboutsummaryrefslogtreecommitdiff
path: root/ft_printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'ft_printf.c')
-rw-r--r--ft_printf.c126
1 files changed, 73 insertions, 53 deletions
diff --git a/ft_printf.c b/ft_printf.c
index da9a14a..c4df9b7 100644
--- a/ft_printf.c
+++ b/ft_printf.c
@@ -6,67 +6,87 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/10/29 00:15:28 by cacharle #+# #+# */
-/* Updated: 2019/11/06 00:01:32 by cacharle ### ########.fr */
+/* Updated: 2019/11/13 08:56:49 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
#include "header.h"
-int ft_printf(const char *format, ...)
+int ft_printf(const char *format, ...)
{
- va_list ap;
- t_flist *flist;
- char *str;
- int print_len;
- int i;
+ t_printf_status status;
if (format == NULL)
- return (-1);
- str = ft_strdup(format);
- if (!parse(str, &flist))
- return (-1);
- free(str);
- va_start(ap, format);
- print_len = 0;
- i = -1;
- while (format[++i])
+ return (STATUS_ERROR);
+ if (!parse(format, &status.flist))
+ return (STATUS_ERROR);
+ va_start(status.ap, format);
+ status.format = format;
+ status.out = NULL;
+ status.out_size = 0;
+ while (*status.format)
{
- if (format[i] != '%')
- {
- write(STDOUT_FILENO, format + i, 1);
- print_len++;
- continue ;
- }
- str = convert(flist->content, ap);
- if (str == NULL && flist->content->specifier == 'n')
- {
- if (flist->content->written != NULL)
- *flist->content->written = print_len;
- i += flist->content->fmt_len;
- list_pop_front(&flist);
- continue;
- }
- if (str == NULL)
- {
- list_destroy(&flist);
- return (-1);
- }
- if (flist->content->specifier == 'c')
- {
- write(1, str, flist->content->size);
- print_len++;
- free(str);
- }
- else
- {
- ft_putstr(str);
- print_len += ft_strlen(str);
- free(str);
- }
- i += flist->content->fmt_len;
- list_pop_front(&flist);
+ if (*status.format == '%'
+ && (status.format =
+ add_conversion(&status, status.flist->content)) == NULL)
+ return (destroy_status_error(&status));
+ else if ((status.format = add_between(&status)) == NULL)
+ return (destroy_status_error(&status));
}
- list_destroy(&flist);
- va_end(ap);
- return (print_len);
+ va_end(status.ap);
+ list_destroy(&status.flist);
+ write(STDOUT_FILENO, status.out, status.out_size);
+ free(status.out);
+ return (status.out_size);
+}
+
+const char *add_conversion(t_printf_status *status, t_pformat *pformat)
+{
+ char *conversion_str;
+
+ conversion_str = convert(pformat, status->ap);
+ if (pformat->specifier == 'n')
+ {
+ if (pformat->written != NULL)
+ *pformat->written = status->out_size;
+ status->format += pformat->fmt_len;
+ list_pop_front(&status->flist);
+ return (status->format + 1);
+ }
+ if (conversion_str == NULL)
+ return (NULL);
+ if (pformat->specifier != 'c')
+ pformat->size = ft_strlen(conversion_str);
+ if ((status->out = ft_memjoin_free(status->out, status->out_size,
+ conversion_str, pformat->size)) == NULL)
+ return (NULL);
+ status->out_size += pformat->size;
+ free(conversion_str);
+ status->format += pformat->fmt_len;
+ list_pop_front(&status->flist);
+ return (status->format + 1);
+}
+
+const char *add_between(t_printf_status *status)
+{
+ int i;
+
+ i = 0;
+ while (status->format[i] && status->format[i] != '%')
+ i++;
+ if ((status->out = ft_memjoin_free(status->out, status->out_size,
+ (void*)status->format, i)) == NULL)
+ return (NULL);
+ status->out_size += i;
+ return (status->format + i);
+}
+
+int destroy_status_error(t_printf_status *status)
+{
+ if (status == NULL)
+ return (STATUS_ERROR);
+ va_end(status->ap);
+ list_destroy(&status->flist);
+ free(status->out);
+ return (STATUS_ERROR);
}