aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2019-10-29 05:20:35 +0100
committerCharles <sircharlesaze@gmail.com>2019-10-29 05:20:35 +0100
commit66ed3290deb97057875aa7372741595e3fa290a6 (patch)
treec2123744a3775f274a07bab24841690498e36fad
parent87bce91050b56915dcf5964f6f66d5f47299e7f3 (diff)
downloadft_printf-66ed3290deb97057875aa7372741595e3fa290a6.tar.gz
ft_printf-66ed3290deb97057875aa7372741595e3fa290a6.tar.bz2
ft_printf-66ed3290deb97057875aa7372741595e3fa290a6.zip
String conversion refactor, malloc protection
-rw-r--r--ft_printf.c4
-rw-r--r--header.h10
-rw-r--r--main.c12
-rw-r--r--parse.c10
-rw-r--r--printer.c126
-rwxr-xr-xtestbin20308 -> 20748 bytes
6 files changed, 88 insertions, 74 deletions
diff --git a/ft_printf.c b/ft_printf.c
index 5a57a23..5bfd2e8 100644
--- a/ft_printf.c
+++ b/ft_printf.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/10/29 00:15:28 by cacharle #+# #+# */
-/* Updated: 2019/10/29 00:16:41 by cacharle ### ########.fr */
+/* Updated: 2019/10/29 05:17:55 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -38,7 +38,7 @@ int ft_printf(const char *format, ...)
write(STDOUT_FILENO, format + i, 1);
continue ;
}
- str = convert_to_str(format_list->content, ap);
+ str = convert(format_list->content, ap);
if (str == NULL)
{
list_destroy(&format_list);
diff --git a/header.h b/header.h
index 359bff9..72108ab 100644
--- a/header.h
+++ b/header.h
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/10/29 00:06:46 by cacharle #+# #+# */
-/* Updated: 2019/10/29 00:10:16 by cacharle ### ########.fr */
+/* Updated: 2019/10/29 05:01:00 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -80,9 +80,11 @@ t_pformat *parse_reduced(char *fmt);
** printer.c
*/
-void handle_padding(t_pformat *pformat, char *str);
-char *convert_to_str(t_pformat *pformat, va_list ap);
-void handle_precision(t_pformat *pformat, char *str);
+char *convert(t_pformat *pformat, va_list ap);
+char *convert_type(t_conversion conversion, va_list ap);
+char *handle_padding(t_pformat *pformat, char *str);
+char *handle_precision(t_pformat *pformat, char *str);
+char *add_address_prefix(char *addr);
/*
** utils.c
diff --git a/main.c b/main.c
index 2b04c77..c869075 100644
--- a/main.c
+++ b/main.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/10/28 04:25:09 by cacharle #+# #+# */
-/* Updated: 2019/10/29 00:04:49 by cacharle ### ########.fr */
+/* Updated: 2019/10/29 05:18:05 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -55,9 +55,11 @@ int main()
ft_printf("overwrite neg |%*-1d|\n", 0, 43);
printf("overwrite neg |%*-1d|\n", 0, 43);
- /* ft_printf("pointer field width |%15p|\n", &test); */
- /* printf("pointer field width |%15p|\n", &test); */
- /* ft_printf("pointer precision |%.15p|\n", &test); */
- /* printf("pointer precision |%.15p|\n", &test); */
+ ft_printf("pointer field width |%15p|\n", &test);
+ printf("pointer field width |%15p|\n", &test);
+ ft_printf("pointer precision |%.15p|\n", &test);
+ printf("pointer precision |%.15p|\n", &test);
+ ft_printf("pointer precision/width |%20.15p|\n", &test);
+ printf("pointer precision/width |%20.15p|\n", &test);
return 0;
}
diff --git a/parse.c b/parse.c
index 83a7d55..6738566 100644
--- a/parse.c
+++ b/parse.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/10/29 00:11:33 by cacharle #+# #+# */
-/* Updated: 2019/10/29 00:11:50 by cacharle ### ########.fr */
+/* Updated: 2019/10/29 05:19:00 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -36,6 +36,7 @@ t_flist *parse(char *format)
if ((tmp = list_new(parsed)) == NULL)
return (list_destroy(&format_list));
list_push_front(&format_list, tmp);
+ format += format_list->content->len;
}
return (list_reverse(format_list));
}
@@ -44,14 +45,16 @@ t_pformat *parse_reduced(char *fmt)
{
t_pformat *pformat;
int i;
+ char *start;
i = 0;
while (strrchr_index(CONVERSIONS_STR, fmt[i]) == -1)
i++;
- if ((fmt = ft_strndup(fmt, i + 1)) == NULL)
+ if ((start = ft_strndup(fmt, i + 1)) == NULL)
return (NULL);
if ((pformat = (t_pformat*)malloc(sizeof(t_pformat))) == NULL)
return (NULL);
+ fmt = start;
pformat->precision = -1;
pformat->min_width = -1;
pformat->flags = 0;
@@ -60,6 +63,7 @@ t_pformat *parse_reduced(char *fmt)
fmt[pformat->len - 1] = '\0';
fmt = extract_standalone_flags(pformat, fmt);
fmt = extract_min_width(pformat, fmt);
- fmt = extract_precision(pformat, fmt);
+ extract_precision(pformat, fmt);
+ free(start);
return (pformat);
}
diff --git a/printer.c b/printer.c
index 2bc0116..62c00eb 100644
--- a/printer.c
+++ b/printer.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/10/28 23:19:24 by cacharle #+# #+# */
-/* Updated: 2019/10/29 00:13:53 by cacharle ### ########.fr */
+/* Updated: 2019/10/29 05:20:14 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -15,17 +15,15 @@
#include <stdarg.h>
#include "header.h"
-#define ITOA_DEC(x) (ft_itoa_base(x, "0123456789"))
#define ITOA_HEX_LOWER(x) (ft_itoa_base(x, "0123456789abcdef"))
#define ITOA_HEX_UPPER(x) (ft_itoa_base(x, "0123456789ABCDEF"))
-char *convert_to_str(t_pformat *pformat, va_list ap)
+#define IN_STR(str, c) (ft_strchr(str, c) != NULL)
+
+char *convert(t_pformat *pformat, va_list ap)
{
char *str;
- t_conversion conversion;
- conversion = pformat->conversion;
- str = NULL;
if (pformat->flags & FLAG_MIN_WIDTH_WILDCARD)
{
if (pformat->flags & FLAG_MIN_WIDTH_OVERWRITE)
@@ -40,63 +38,57 @@ char *convert_to_str(t_pformat *pformat, va_list ap)
}
if (pformat->flags & FLAG_PRECISION_WILDCARD)
pformat->precision = va_arg(ap, int);
- if (conversion == CONVERSION_CHAR)
+ if ((str = convert_type(pformat->conversion, ap)) == NULL)
+ return (NULL);
+ if ((str = handle_precision(pformat, str)) == NULL)
+ return (NULL);
+ if (pformat->conversion == 'p')
+ if ((str = add_address_prefix(str)) == NULL)
+ return (NULL);
+ if ((str = handle_padding(pformat, str)) == NULL)
+ return (NULL);
+ return (str);
+}
+
+char *convert_type(t_conversion conversion, va_list ap)
+{
+ char *str;
+
+ str = NULL;
+ if (conversion == 'c')
{
if ((str = ft_strnew(2)) == NULL)
return (NULL);
str[0] = (char)va_arg(ap, int);
}
- else if (conversion == CONVERSION_STR)
+ else if (conversion == 's')
str = ft_strdup(va_arg(ap, char*));
- else if (conversion == CONVERSION_PTR)
- {
- // handle 0x with and without zero padding
- ft_putstr("0x");
- str = ft_strnew(2);
- str[0] = 'b';
- str[1] = 0;
+ else if (conversion == 'p')
str = ITOA_HEX_LOWER((long int)va_arg(ap, void*));
- }
- else if (conversion == CONVERSION_DECIMAL || conversion == CONVERSION_INT)
- str = ITOA_DEC(va_arg(ap, int));
- else if (conversion == CONVERSION_UINT)
- str = ITOA_DEC(va_arg(ap, unsigned int));
- else if (conversion == CONVERSION_HEX_LOWER)
+ else if (conversion == 'd' || conversion == 'i')
+ str = ft_itoa(va_arg(ap, int));
+ else if (conversion == 'u')
+ str = ft_itoa(va_arg(ap, unsigned int));
+ else if (conversion == 'x')
str = ITOA_HEX_LOWER(va_arg(ap, unsigned int));
- else if (conversion == CONVERSION_HEX_UPPER)
+ else if (conversion == 'X')
str = ITOA_HEX_UPPER(va_arg(ap, unsigned int));
- else if (conversion == CONVERSION_PERCENT)
- {
- if ((str = ft_strnew(2)) == NULL)
- return (NULL);
- str[0] = '%';
- }
- handle_precision(pformat, str);
- handle_padding(pformat, str);
+ else if (conversion == '%')
+ str = ft_strdup("%");
return (str);
}
-void handle_padding(t_pformat *pformat, char *str)
+char *handle_padding(t_pformat *pformat, char *str)
{
char *tmp;
int len;
int i;
- if (pformat->min_width == -1)
- return;
if ((len = ft_strlen(str)) >= pformat->min_width)
- return;
- //protect this
- tmp = (char*)malloc(sizeof(char) * (pformat->min_width + 1));
- if (!(pformat->flags & FLAG_LEFT_ADJUSTED))
- {
- i = 0;
- while (i <= pformat->min_width - len)
- tmp[i++] = pformat->flags & FLAG_ZERO_PADDING ? '0' : ' ';
- ft_strcpy(tmp + i - 1, str);
- ft_strcpy(str, tmp);
- }
- else
+ return (str);
+ if ((tmp = (char*)malloc(sizeof(char) * (pformat->min_width + 1))) == NULL)
+ return (NULL);
+ if (pformat->flags & FLAG_LEFT_ADJUSTED)
{
ft_strcpy(tmp, str);
i = len;
@@ -104,29 +96,30 @@ void handle_padding(t_pformat *pformat, char *str)
tmp[i++] = ' ';
ft_strcpy(str, tmp);
}
+ else
+ {
+ i = 0;
+ while (i <= pformat->min_width - len)
+ tmp[i++] = pformat->flags & FLAG_ZERO_PADDING ? '0' : ' ';
+ ft_strcpy(tmp + i - 1, str);
+ ft_strcpy(str, tmp);
+ }
free(tmp);
+ return (str);
}
-void handle_precision(t_pformat *pformat, char *str)
+char *handle_precision(t_pformat *pformat, char *str)
{
- int len;
- char *tmp;
- t_conversion conv;
+ int len;
+ char *tmp;
- if (pformat->precision == -1)
- return ;
len = ft_strlen(str);
- conv = pformat->conversion;
- if (conv == CONVERSION_STR)
+ if (pformat->conversion == 's' && pformat->precision < len)
str[pformat->precision] = '\0';
- else if (conv == CONVERSION_DECIMAL || conv == CONVERSION_INT
- || conv == CONVERSION_UINT || conv == CONVERSION_HEX_LOWER
- || conv == CONVERSION_HEX_UPPER)
+ else if (IN_STR("diuxXp", pformat->conversion) && len < pformat->precision)
{
- if (len >= pformat->precision)
- return ;
- // protect this
- tmp = (char*)malloc(sizeof(char) * (pformat->precision + 1));
+ if ((tmp = (char*)malloc(sizeof(char) * (pformat->precision + 1))) == NULL)
+ return (NULL);
ft_strcpy(tmp + pformat->precision - len, str);
pformat->precision -= len;
while (pformat->precision-- > 0)
@@ -134,4 +127,17 @@ void handle_precision(t_pformat *pformat, char *str)
ft_strcpy(str, tmp);
free(tmp);
}
+ return (str);
+}
+
+char *add_address_prefix(char *addr)
+{
+ char *tmp;
+
+ if ((tmp = ft_strdup(addr)) == NULL)
+ return (NULL);
+ if ((addr = ft_strjoin("0x", addr)) == NULL)
+ return (NULL);
+ free(tmp);
+ return (addr);
}
diff --git a/test b/test
index 36cc5a3..c8410da 100755
--- a/test
+++ b/test
Binary files differ