aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--convert_char.c13
-rw-r--r--convert_hex_low.c17
-rw-r--r--convert_hex_up.c17
-rw-r--r--convert_int.c47
-rw-r--r--convert_percent.c10
-rw-r--r--convert_ptr.c22
-rw-r--r--convert_str.c15
-rw-r--r--convert_uint.c18
-rw-r--r--extract.c32
-rw-r--r--ft_printf.c4
-rw-r--r--header.h58
-rw-r--r--main.c90
-rw-r--r--parse.c23
-rw-r--r--printer.c117
-rwxr-xr-xtestbin20748 -> 22988 bytes
-rw-r--r--utils.c47
17 files changed, 385 insertions, 151 deletions
diff --git a/Makefile b/Makefile
index 43cbdfd..4e5d46c 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@
# By: cacharle <marvin@42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2019/10/28 17:41:14 by cacharle #+# #+# #
-# Updated: 2019/10/29 02:01:51 by cacharle ### ########.fr #
+# Updated: 2019/10/29 23:00:05 by cacharle ### ########.fr #
# #
# **************************************************************************** #
@@ -22,7 +22,9 @@ LIB = ar rcs
MAKE = make -j4
NAME = libftprintf.a
-SRC = ft_printf.c utils.c printer.c parse.c list.c extract.c
+SRC = ft_printf.c utils.c printer.c parse.c list.c extract.c \
+ convert_int.c convert_uint.c convert_char.c convert_str.c \
+ convert_ptr.c convert_hex_low.c convert_hex_up.c convert_percent.c
OBJ = $(SRC:.c=.o)
INCLUDE = header.h
diff --git a/convert_char.c b/convert_char.c
new file mode 100644
index 0000000..ee30a2c
--- /dev/null
+++ b/convert_char.c
@@ -0,0 +1,13 @@
+#include <stdarg.h>
+#include "header.h"
+
+char *convert_char(va_list ap, t_pformat *pformat)
+{
+ char *str = ft_strnew(2);
+ if (str == NULL)
+ return (NULL);
+ str[0] = va_arg(ap, int);
+ str[1] = '\0';
+ str = handle_padding(pformat, str);
+ return (str);
+}
diff --git a/convert_hex_low.c b/convert_hex_low.c
new file mode 100644
index 0000000..39cc188
--- /dev/null
+++ b/convert_hex_low.c
@@ -0,0 +1,17 @@
+#include <stdarg.h>
+#include "header.h"
+
+char *convert_hex_low(va_list ap, t_pformat *pformat)
+{
+ unsigned int n = va_arg(ap, unsigned int);
+ char *str = ITOA_HEX_LOW(n);
+ str = handle_precision(pformat, str);
+ if (pformat->flags & FLAG_ALTERNATE && n != 0)
+ {
+ char *tmp = ft_strjoin("0x", str);
+ free(str);
+ str = tmp;
+ }
+ str = handle_padding(pformat, str);
+ return (str);
+}
diff --git a/convert_hex_up.c b/convert_hex_up.c
new file mode 100644
index 0000000..7f5e640
--- /dev/null
+++ b/convert_hex_up.c
@@ -0,0 +1,17 @@
+#include <stdarg.h>
+#include "header.h"
+
+char *convert_hex_up(va_list ap, t_pformat *pformat)
+{
+ unsigned int n = va_arg(ap, unsigned int);
+ char *str = ITOA_HEX_UP(n);
+ str = handle_precision(pformat, str);
+ if (pformat->flags & FLAG_ALTERNATE)
+ {
+ char *tmp = ft_strjoin("0X", str);
+ free(str);
+ str = tmp;
+ }
+ str = handle_padding(pformat, str);
+ return (str);
+}
diff --git a/convert_int.c b/convert_int.c
new file mode 100644
index 0000000..d0ef77e
--- /dev/null
+++ b/convert_int.c
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+#include <stdarg.h>
+#include "header.h"
+
+char *convert_int(va_list ap, t_pformat *pformat)
+{
+ char *tmp;
+ int is_neg;
+ long long int n;
+
+ if (pformat->flags & FLAG_SHORT)
+ n = va_arg(ap, short);
+ else if (pformat->flags & FLAG_SHORT_SHORT)
+ n = va_arg(ap, signed char);
+ else if (pformat->flags & FLAG_LONG)
+ n = va_arg(ap, long int);
+ else if (pformat->flags & FLAG_LONG_LONG)
+ n = va_arg(ap, long long int);
+ else
+ n = va_arg(ap, int);
+
+ is_neg = n < 0;
+
+ char *str = ITOA_DEC(n);
+
+ if (is_neg)
+ ft_strcpy(str, str + 1);
+ str = handle_precision(pformat, str);
+ if (pformat->flags & FLAG_ZERO_PADDING)
+ {
+ if (is_neg || pformat->flags & FLAG_SIGNED)
+ pformat->min_width--;
+ str = handle_padding(pformat, str);
+ }
+ if (is_neg)
+ tmp = ft_strjoin("-", str);
+ else if (pformat->flags & FLAG_SIGNED || pformat->flags & FLAG_SPACE)
+ tmp = ft_strjoin(pformat->flags & FLAG_SPACE ? " " : "+", str);
+ else
+ tmp = ft_strdup(str);
+ free(str);
+ str = tmp;
+ if (!(pformat->flags & FLAG_ZERO_PADDING))
+ str = handle_padding(pformat, str);
+ return (str);
+}
+
diff --git a/convert_percent.c b/convert_percent.c
new file mode 100644
index 0000000..2b15340
--- /dev/null
+++ b/convert_percent.c
@@ -0,0 +1,10 @@
+#include <stdarg.h>
+#include "header.h"
+
+char *convert_percent(va_list ap, t_pformat *pformat)
+{
+ char *str = ft_strdup("%");
+
+ str = handle_padding(pformat, str);
+ return (str);
+}
diff --git a/convert_ptr.c b/convert_ptr.c
new file mode 100644
index 0000000..c74222c
--- /dev/null
+++ b/convert_ptr.c
@@ -0,0 +1,22 @@
+#include <stdarg.h>
+#include "header.h"
+
+char *convert_ptr(va_list ap, t_pformat *pformat)
+{
+ char *str = ITOA_HEX_LOW(va_arg(ap, void*));
+
+ str = handle_precision(pformat, str);
+ str = add_hex_prefix(str);
+ str = handle_padding(pformat, str);
+ return (str);
+}
+
+char *add_hex_prefix(char *str)
+{
+ char *tmp;
+
+ if ((tmp = ft_strjoin("0x", str)) == NULL)
+ return (NULL);
+ free(str);
+ return (tmp);
+}
diff --git a/convert_str.c b/convert_str.c
new file mode 100644
index 0000000..dbdf01e
--- /dev/null
+++ b/convert_str.c
@@ -0,0 +1,15 @@
+#include <stdarg.h>
+#include "header.h"
+
+char *convert_str(va_list ap, t_pformat *pformat)
+{
+ char *str = va_arg(ap, char*);
+
+ str = str == NULL ? ft_strdup("(null)") : ft_strdup(str);
+
+ if (pformat->precision != -1 && pformat->precision < ft_strlen(str))
+ str[pformat->precision] = '\0';
+ str = handle_padding(pformat, str);
+
+ return (str);
+}
diff --git a/convert_uint.c b/convert_uint.c
new file mode 100644
index 0000000..bf28679
--- /dev/null
+++ b/convert_uint.c
@@ -0,0 +1,18 @@
+#include <stdarg.h>
+#include "header.h"
+
+char *convert_uint(va_list ap, t_pformat *pformat)
+{
+ unsigned int n;
+
+ if (pformat->flags & FLAG_SHORT)
+ n = va_arg(ap, unsigned short);
+ else if (pformat->flags & FLAG_SHORT_SHORT)
+ n = va_arg(ap, unsigned char);
+ else
+ n = va_arg(ap, unsigned int);
+ char *str = ft_itoa_base(n, "0123456789");
+ str = handle_precision(pformat, str);
+ str = handle_padding(pformat, str);
+ return (str);
+}
diff --git a/extract.c b/extract.c
index 11bff1d..75d4929 100644
--- a/extract.c
+++ b/extract.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/10/29 00:10:36 by cacharle #+# #+# */
-/* Updated: 2019/10/29 18:17:38 by cacharle ### ########.fr */
+/* Updated: 2019/10/30 03:40:28 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -25,8 +25,14 @@ char *extract_standalone_flags(t_pformat *pformat, char *fmt)
pformat->flags |= FLAG_LEFT_ADJUSTED;
if (*fmt == '+')
pformat->flags |= FLAG_SIGNED;
+ if (*fmt == ' ')
+ pformat->flags |= FLAG_SPACE;
+ if (*fmt == '#')
+ pformat->flags |= FLAG_ALTERNATE;
fmt++;
}
+ if (pformat->flags & FLAG_SIGNED)
+ pformat->flags &= ~FLAG_SPACE;
return (fmt);
}
@@ -65,3 +71,27 @@ char *extract_precision(t_pformat *pformat, char *fmt)
fmt++;
return (fmt);
}
+
+char *extract_length_modifier(t_pformat *pformat, char *fmt)
+{
+ if (fmt[0] && fmt[0] == 'l')
+ {
+ if (fmt[1] && fmt[1] == 'l')
+ {
+ pformat->flags |= FLAG_LONG_LONG;
+ return (fmt + 2);
+ }
+ pformat->flags |= FLAG_LONG;
+ return (fmt + 1);
+ }
+ if (fmt[0] && fmt[0] == 'h')
+ {
+ if (fmt[1] && fmt[1] == 'h')
+ {
+ pformat->flags |= FLAG_SHORT_SHORT;
+ return (fmt + 2);
+ }
+ pformat->flags |= FLAG_SHORT;
+ return (fmt + 1);
+ }
+}
diff --git a/ft_printf.c b/ft_printf.c
index fa9ba1d..c51cc22 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 18:28:15 by cacharle ### ########.fr */
+/* Updated: 2019/10/30 02:01:25 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -27,7 +27,7 @@ int ft_printf(const char *format, ...)
if (format == NULL)
return (-1);
str = ft_strdup(format);
- if ((format_list = parse(str)) == NULL)
+ if (!parse(str, &format_list))
return (-1);
free(str);
va_start(ap, format);
diff --git a/header.h b/header.h
index af66bd8..6a5a11c 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 16:09:31 by cacharle ### ########.fr */
+/* Updated: 2019/10/30 03:53:28 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -23,7 +23,7 @@
# define HEX_MAJ_SYMBOLS "0123456789ABCDEF"
# define IN_STR(str, c) (ft_strchr(str, c) != NULL)
-# define IS_STANDALONE_FLAG(c) (IN_STR("0-+", c))
+# define IS_STANDALONE_FLAG(c) (IN_STR("0-+ #", c))
# define CONVERSIONS_STR "cspdiuxX%"
@@ -37,25 +37,34 @@
# define CONVERSION_HEX_UPPER 'X'
# define CONVERSION_PERCENT '%'
-# define FLAG_LEFT_ADJUSTED 0b00000001
-# define FLAG_ZERO_PADDING 0b00000010
-# define FLAG_MIN_WIDTH_WILDCARD 0b00000100
-# define FLAG_PRECISION_WILDCARD 0b00001000
-# define FLAG_MIN_WIDTH_OVERWRITE 0b00010000
-# define FLAG_SIGNED 0b00100000
+# define FLAG_LEFT_ADJUSTED (1 << 0)
+# define FLAG_ZERO_PADDING (1 << 1)
+# define FLAG_MIN_WIDTH_WILDCARD (1 << 2)
+# define FLAG_PRECISION_WILDCARD (1 << 3)
+# define FLAG_MIN_WIDTH_OVERWRITE (1 << 4)
+# define FLAG_SIGNED (1 << 5)
+# define FLAG_SPACE (1 << 6)
+# define FLAG_ALTERNATE (1 << 7)
+# define FLAG_SHORT_SHORT (1 << 8)
+# define FLAG_SHORT (1 << 9)
+# define FLAG_LONG (1 << 10)
+# define FLAG_LONG_LONG (1 << 11)
+
+#define ITOA_HEX_LOW(x) (ft_itoa_base(x, "0123456789abcdef"))
+#define ITOA_HEX_UP(x) (ft_itoa_base(x, "0123456789ABCDEF"))
+#define ITOA_DEC(x) (ft_itoa_base(x, "0123456789"))
#include <stdio.h>
-typedef char t_conversion;
typedef int t_bool;
-typedef unsigned char t_flags;
+typedef short t_flags;
typedef struct
{
int precision;
int min_width;
t_flags flags;
- t_conversion conversion;
+ char type;
int len;
} t_pformat;
@@ -65,6 +74,12 @@ typedef struct s_flist
t_pformat *content;
} t_flist;
+typedef struct
+{
+ char *(*func)(va_list ap, t_pformat *pformat);
+ char type;
+} t_converter;
+
/*
** ft_printf.c
*/
@@ -75,7 +90,7 @@ int ft_printf(const char *format, ...);
** parse.c
*/
-t_flist *parse(char *format);
+int parse(char *format, t_flist **flist);
t_pformat *parse_reduced(char *fmt);
/*
@@ -83,16 +98,17 @@ t_pformat *parse_reduced(char *fmt);
*/
char *convert(t_pformat *pformat, va_list ap);
-char *convert_type(t_conversion conversion, va_list ap);
+char *convert_type(va_list ap, t_pformat *pformat);
char *handle_padding(t_pformat *pformat, char *str);
char *handle_precision(t_pformat *pformat, char *str);
-char *add_address_prefix(char *addr);
+char *add_hex_prefix(char *str);
/*
** utils.c
*/
int strrchr_index(const char *s, char c);
+char *ft_itoa_base(long long int n, char *base);
/*
** extract.c
@@ -112,4 +128,18 @@ void list_push_front(t_flist **lst, t_flist *new);
void list_pop_front(t_flist **lst);
t_flist *list_reverse(t_flist *lst);
+
+/*
+** convert_*.c
+*/
+
+char *convert_char(va_list ap, t_pformat *pformat);
+char *convert_str(va_list ap, t_pformat *pformat);
+char *convert_ptr(va_list ap, t_pformat *pformat);
+char *convert_int(va_list ap, t_pformat *pformat);
+char *convert_uint(va_list ap, t_pformat *pformat);
+char *convert_hex_low(va_list ap, t_pformat *pformat);
+char *convert_hex_up(va_list ap, t_pformat *pformat);
+char *convert_percent(va_list ap, t_pformat *pformat);
+
#endif
diff --git a/main.c b/main.c
index c869075..937b063 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 05:18:05 by cacharle ### ########.fr */
+/* Updated: 2019/10/30 03:15:22 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -18,48 +18,50 @@ int main()
{
int test;
- ft_printf("char: %c\n", 'r');
- ft_printf("string: %s\n", "bonjour");
- ft_printf("pointer: %p\n", &test);
- ft_printf("int: %d or %i\n", 45, 54);
- ft_printf("uint: %u\n", 1 << 31);
- ft_printf("hex lower: %x\n", 0xabcf012);
- ft_printf("hex upper: %X\n", 0xabcf012);
- ft_printf("percent: %%\n");
- ft_printf("multiple stuff: %d %u %d %x %d\n", 1, -2, 3, 0xa, 5);
-
- ft_printf("precision |%.9d|\n", 43);
- printf("precision |%.9d|\n", 43);
- ft_printf("string precision |%.9s|\n", "jesuisbonjourbonjour");
- printf("string precision |%.9s|\n", "jesuisbonjourbonjour");
- ft_printf("min width |%9d|\n", 43);
- printf("min width |%9d|\n", 43);
- ft_printf("zero padding |%09d|\n", 43);
- printf("zero padding |%09d|\n", 43);
- ft_printf("left adjusted |%-9d|\n", 43);
- printf("left adjusted |%-9d|\n", 43);
- ft_printf("string padding |%9s|\n", "bon");
- printf("string padding |%9s|\n", "bon");
-
- ft_printf("width wildcard |%*d|\n", 5, 43);
- printf("width wildcard |%*d|\n", 5, 43);
- ft_printf("precision wildcard |%.*d|\n", 5, 43);
- printf("precision wildcard |%.*d|\n", 5, 43);
- ft_printf("precision/width wildcard |%*.*d|\n", 5, 3, 43);
- printf("precision/width wildcard |%*.*d|\n", 5, 3, 43);
- ft_printf("left adjusted |%*d|\n", -5, 43);
- printf("left adjusted |%*d|\n", -5, 43);
-
- ft_printf("overwrite |%*3d|\n", 5, 43);
- printf("overwrite |%*3d|\n", 5, 43);
- 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 precision/width |%20.15p|\n", &test);
- printf("pointer precision/width |%20.15p|\n", &test);
+ printf("%d\n", ft_printf("%", 4));
+ printf("%d\n", printf("aa%bb", 4));
+ /* ft_printf("char: %c\n", 'r'); */
+ /* ft_printf("string: %s\n", "bonjour"); */
+ /* ft_printf("pointer: %p\n", &test); */
+ /* ft_printf("int: %d or %i\n", 45, 54); */
+ /* ft_printf("uint: %u\n", 1 << 31); */
+ /* ft_printf("hex lower: %x\n", 0xabcf012); */
+ /* ft_printf("hex upper: %X\n", 0xabcf012); */
+ /* ft_printf("percent: %%\n"); */
+ /* ft_printf("multiple stuff: %d %u %d %x %d\n", 1, -2, 3, 0xa, 5); */
+ /* */
+ /* ft_printf("precision |%.9d|\n", 43); */
+ /* printf("precision |%.9d|\n", 43); */
+ /* ft_printf("string precision |%.9s|\n", "jesuisbonjourbonjour"); */
+ /* printf("string precision |%.9s|\n", "jesuisbonjourbonjour"); */
+ /* ft_printf("min width |%9d|\n", 43); */
+ /* printf("min width |%9d|\n", 43); */
+ /* ft_printf("zero padding |%09d|\n", 43); */
+ /* printf("zero padding |%09d|\n", 43); */
+ /* ft_printf("left adjusted |%-9d|\n", 43); */
+ /* printf("left adjusted |%-9d|\n", 43); */
+ /* ft_printf("string padding |%9s|\n", "bon"); */
+ /* printf("string padding |%9s|\n", "bon"); */
+ /* */
+ /* ft_printf("width wildcard |%*d|\n", 5, 43); */
+ /* printf("width wildcard |%*d|\n", 5, 43); */
+ /* ft_printf("precision wildcard |%.*d|\n", 5, 43); */
+ /* printf("precision wildcard |%.*d|\n", 5, 43); */
+ /* ft_printf("precision/width wildcard |%*.*d|\n", 5, 3, 43); */
+ /* printf("precision/width wildcard |%*.*d|\n", 5, 3, 43); */
+ /* ft_printf("left adjusted |%*d|\n", -5, 43); */
+ /* printf("left adjusted |%*d|\n", -5, 43); */
+ /* */
+ /* ft_printf("overwrite |%*3d|\n", 5, 43); */
+ /* printf("overwrite |%*3d|\n", 5, 43); */
+ /* 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 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 6738566..871ff74 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 05:19:00 by cacharle ### ########.fr */
+/* Updated: 2019/10/30 03:41:02 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -19,26 +19,26 @@
** %(?:\d+\$)?[-]?(?:[0]|'.{1})?-?\d*(?:\.\d+)?[cdusxX]
*/
-t_flist *parse(char *format)
+int parse(char *format, t_flist **flist)
{
- t_flist *format_list;
t_flist *tmp;
t_pformat *parsed;
- format_list = NULL;
+ *flist = NULL;
while (*format)
{
format++;
if (format[-1] != '%')
continue;
if ((parsed = parse_reduced(format)) == NULL)
- return (list_destroy(&format_list));
+ return (list_destroy(flist));
if ((tmp = list_new(parsed)) == NULL)
- return (list_destroy(&format_list));
- list_push_front(&format_list, tmp);
- format += format_list->content->len;
+ return (list_destroy(flist));
+ list_push_front(flist, tmp);
+ format += (*flist)->content->len;
}
- return (list_reverse(format_list));
+ *flist = list_reverse(*flist);
+ return (1);
}
t_pformat *parse_reduced(char *fmt)
@@ -59,11 +59,12 @@ t_pformat *parse_reduced(char *fmt)
pformat->min_width = -1;
pformat->flags = 0;
pformat->len = ft_strlen(fmt);
- pformat->conversion = fmt[pformat->len - 1];
+ pformat->type = fmt[pformat->len - 1];
fmt[pformat->len - 1] = '\0';
fmt = extract_standalone_flags(pformat, fmt);
fmt = extract_min_width(pformat, fmt);
- extract_precision(pformat, fmt);
+ fmt = extract_precision(pformat, fmt);
+ extract_length_modifier(pformat, fmt);
free(start);
return (pformat);
}
diff --git a/printer.c b/printer.c
index e002551..34cbd07 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 18:46:48 by cacharle ### ########.fr */
+/* Updated: 2019/10/30 00:56:05 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -15,8 +15,6 @@
#include <stdarg.h>
#include "header.h"
-#define ITOA_HEX_LOWER(x) (ft_itoa_base(x, "0123456789abcdef"))
-#define ITOA_HEX_UPPER(x) (ft_itoa_base(x, "0123456789ABCDEF"))
char *convert(t_pformat *pformat, va_list ap)
{
@@ -36,54 +34,30 @@ char *convert(t_pformat *pformat, va_list ap)
}
if (pformat->flags & FLAG_PRECISION_WILDCARD)
pformat->precision = va_arg(ap, int);
- if ((str = convert_type(pformat->conversion, ap)) == NULL)
- return (NULL);
- if (pformat->flags & FLAG_SIGNED && (pformat->conversion == 'd' || pformat->conversion == 'i')
- && str[0] != '-')
- {
- char *tmp = ft_strjoin("+", str);
- free(str);
- str = tmp;
- }
- 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)
+ if ((str = convert_type(ap, pformat)) == NULL)
return (NULL);
return (str);
}
-char *convert_type(t_conversion conversion, va_list ap)
+char *convert_type(va_list ap, t_pformat *pformat)
{
- 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 == 's')
- {
- char *tmp = va_arg(ap, char*);
- str = tmp == NULL ? ft_strdup("(null)") : ft_strdup(tmp);
- }
- else if (conversion == 'p')
- str = ITOA_HEX_LOWER((long int)va_arg(ap, void*));
- 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 == 'X')
- str = ITOA_HEX_UPPER(va_arg(ap, unsigned int));
- else if (conversion == '%')
- str = ft_strdup("%");
- return (str);
+ if (pformat->type == 'c')
+ return (convert_char(ap, pformat));
+ if (pformat->type == 's')
+ return (convert_str(ap, pformat));
+ if (pformat->type == 'p')
+ return (convert_ptr(ap, pformat));
+ if (pformat->type == 'd' || pformat->type == 'i')
+ return (convert_int(ap, pformat));
+ if (pformat->type == 'u')
+ return (convert_uint(ap, pformat));
+ if (pformat->type == 'x')
+ return (convert_hex_low(ap, pformat));
+ if (pformat->type == 'X')
+ return (convert_hex_up(ap, pformat));
+ if (pformat->type == '%')
+ return (convert_percent(ap, pformat));
+ return (NULL);
}
char *handle_padding(t_pformat *pformat, char *str)
@@ -98,33 +72,38 @@ char *handle_padding(t_pformat *pformat, char *str)
return (NULL);
if (pformat->flags & FLAG_LEFT_ADJUSTED)
{
- ft_strcpy(tmp, str);
i = len;
+ ft_strcpy(tmp, str);
while (i < pformat->min_width)
tmp[i++] = ' ';
tmp[i] = 0;
- ft_strcpy(str, tmp);
}
else
{
- if (IN_STR("+-", str[0]) && pformat->flags & FLAG_ZERO_PADDING)
- {
- tmp[0] = str[0];
- len--;
- i = 1;
- while (i < pformat->min_width - len)
- tmp[i++] = pformat->flags & FLAG_ZERO_PADDING ? '0' : ' ';
- ft_strcpy(tmp + i , str + 1);
- ft_strcpy(str, tmp);
- free(tmp);
- return (str);
- }
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(str);
+ return (tmp);
+}
+
+char *handle_nbr_padding(t_pformat *pformat, char *str)
+{
+ char *tmp;
+ int len = ft_strlen(str);
+ int i;
+
+ if (!(IN_STR("+-", str[0]) && pformat->flags & FLAG_ZERO_PADDING))
+ return (str);
+ tmp[0] = str[0];
+ len--;
+ i = 1;
+ while (i < pformat->min_width - len)
+ tmp[i++] = '0';
+ ft_strcpy(tmp + i , str + 1);
+ ft_strcpy(str, tmp);
free(tmp);
return (str);
}
@@ -137,9 +116,7 @@ char *handle_precision(t_pformat *pformat, char *str)
len = ft_strlen(str);
if (pformat->precision == 0 && str[0] == '0')
return (ft_strdup(""));
- if (pformat->conversion == 's' && pformat->precision < len)
- str[pformat->precision] = '\0';
- else if (IN_STR("diuxXp", pformat->conversion) && len < pformat->precision)
+ else if (IN_STR("diuxXp", pformat->type) && len < pformat->precision)
{
if ((tmp = (char*)malloc(sizeof(char) * (pformat->precision + 1))) == NULL)
return (NULL);
@@ -162,15 +139,3 @@ char *handle_precision(t_pformat *pformat, char *str)
}
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 c8410da..08afd94 100755
--- a/test
+++ b/test
Binary files differ
diff --git a/utils.c b/utils.c
index c018e5a..09b2bd5 100644
--- a/utils.c
+++ b/utils.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/10/29 00:12:40 by cacharle #+# #+# */
-/* Updated: 2019/10/29 00:12:52 by cacharle ### ########.fr */
+/* Updated: 2019/10/30 03:53:16 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -29,3 +29,48 @@ int strrchr_index(const char *s, char c)
}
return (i);
}
+
+static int nbrlen_radix(long int nbr, int radix)
+{
+ int counter;
+ long unsigned int u_nbr;
+
+ if (nbr == 0)
+ return (1);
+ counter = 0;
+ u_nbr = nbr;
+ if (nbr < 0)
+ {
+ counter++;
+ u_nbr = -nbr;
+ }
+ while (u_nbr > 0)
+ {
+ u_nbr /= radix;
+ counter++;
+ }
+ return (counter);
+}
+
+char *ft_itoa_base(long long int n, char *base)
+{
+ char *str;
+ int len;
+ int radix;
+ long long unsigned int u_nbr;
+
+ radix = ft_strlen(base);
+ len = nbrlen_radix(n, radix);
+ if ((str = (char*)malloc(sizeof(char) * (len + 1))) == NULL)
+ return (NULL);
+ str[len] = '\0';
+ u_nbr = n < 0 ? -n : n;
+ if (n < 0)
+ str[0] = '-';
+ while (--len >= (n < 0 ? 1 : 0))
+ {
+ str[len] = base[u_nbr % radix];
+ u_nbr /= radix;
+ }
+ return (str);
+}