diff options
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | ft_printf.c | 75 | ||||
| -rw-r--r-- | ft_printf.h | 23 | ||||
| -rw-r--r-- | header.h | 92 | ||||
| -rw-r--r-- | list.c | 54 | ||||
| -rw-r--r-- | parse.c | 58 | ||||
| -rw-r--r-- | printer.c | 4 | ||||
| -rw-r--r-- | utils.c | 99 |
8 files changed, 344 insertions, 65 deletions
@@ -4,9 +4,9 @@ CCFLAGS = -Wall -Wextra #-Werror RM = rm -f NAME = ft_printf -SRC = ft_printf.c utils.c printer.c parse.c +SRC = ft_printf.c utils.c printer.c parse.c list.c OBJ = $(SRC:.c=.o) -INCLUDE = ft_printf.h +INCLUDE = header.h all: $(NAME) diff --git a/ft_printf.c b/ft_printf.c index c7bc473..1c0d8ea 100644 --- a/ft_printf.c +++ b/ft_printf.c @@ -1,55 +1,45 @@ #include <unistd.h> #include <stdlib.h> #include <stdarg.h> -#include "ft_printf.h" +#include "header.h" int ft_printf(const char *format, ...) { int i; va_list ap; - /* char *convertions_flags; */ - - /* convertions_flags = "cspdiuxX%"; */ + t_list *format_list; + t_conversion conv; + if ((format_list = parse(format)) == NULL) + return (-1); va_start(ap, format); i = -1; while (format[++i]) { if (format[i] == '%') { - switch (format[++i]) - { - case 'c': - ft_putchar(va_arg(ap, char)); - break; - case 's': - ft_putstr(va_arg(ap, char*)); - break; - case 'p': - ft_putstr("0x"); - PUTXNBR(va_arg(ap, int)); - break; - case 'd': - ft_putnbr(va_arg(ap, int)); - break; - case 'i': - ft_putnbr(va_arg(ap, int)); - break; - case 'u': - ft_putunbr(va_arg(ap, unsigned int)); - break; - case 'x': - ft_putstr("0x"); - PUTXNBR(va_arg(ap, int)); - break; - case 'X': - ft_putstr("0x"); - PUTXMAJNBR(va_arg(ap, int)); - break; - case '%': - ft_putchar('%'); - break; - } + conv = format_list->data->conversion; + if (conv == CONVERSION_CHAR) + ft_putchar(va_arg(ap, char)); + else if (conv == CONVERSION_STR) + ft_putstr(va_arg(ap, char*)); + else if (conv == CONVERSION_PTR) + { + ft_putstr("0x"); + PUTXNBR(va_arg(ap, long unsigned int)); + } + else if (conv == CONVERSION_DECIMAL || conv == CONVERSION_INT) + ft_putnbr(va_arg(ap, int)); + else if (conv == CONVERSION_UINT) + ft_putunbr(va_arg(ap, unsigned int)); + else if (conv == CONVERSION_HEX_LOWER) + PUTXNBR(va_arg(ap, unsigned int)); + else if (conv == CONVERSION_HEX_UPPER) + PUTXMAJNBR(va_arg(ap, unsigned int)); + else if (conv == CONVERSION_PERCENT) + ft_putchar('%'); + i += format_list->data->len; + list_pop_front(&format_list); } else write(STDOUT_FILENO, format + i, 1); @@ -60,6 +50,15 @@ int ft_printf(const char *format, ...) int main() { - ft_printf("b%conjo %X ur%p\n", 'r', 0xec54, NULL); + 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"); return 0; } diff --git a/ft_printf.h b/ft_printf.h deleted file mode 100644 index b755f91..0000000 --- a/ft_printf.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef FT_PRINTF_H -# define FT_PRINTF_H - -#define PUTXNBR(nb) (ft_putxnbr(nb, "0123456789abcdef")) -#define PUTXMAJNBR(nb) (ft_putxnbr(nb, "0123456789ABCDEF")) - -/* -** ft_printf.c -*/ - -int ft_printf(const char *format, ...); - -/* -** utils.c -*/ - -void ft_putchar(char c); -void ft_putstr(char *str); -void ft_putnbr(int nb); -void ft_putxnbr(unsigned int n, char *hex_symbols); -void ft_putunbr(unsigned int n); - -#endif diff --git a/header.h b/header.h new file mode 100644 index 0000000..3c8aba9 --- /dev/null +++ b/header.h @@ -0,0 +1,92 @@ +#ifndef HEADER_H +# define HEADER_H + +# define TRUE 1 +# define FALSE 0 + +# define HEX_SYMBOLS "0123456789abcdef" +# define HEX_MAJ_SYMBOLS "0123456789ABCDEF" + +# define PUTXNBR(nb) (ft_putxnbr(nb, HEX_SYMBOLS)) +# define PUTXMAJNBR(nb) (ft_putxnbr(nb, HEX_MAJ_SYMBOLS)) + +# define CONVERSIONS_STR "cspdiuxX%" + +typedef enum +{ + CONVERSION_CHAR = 0, + CONVERSION_STR, + CONVERSION_PTR, + CONVERSION_DECIMAL, + CONVERSION_INT, + CONVERSION_UINT, + CONVERSION_HEX_LOWER, + CONVERSION_HEX_UPPER, + CONVERSION_PERCENT +} t_conversion; + +typedef int t_bool; + +typedef struct +{ + int arg_position; + t_bool left_adjusted; + t_bool zero_padding; + // * and . flags + int min_field_width; + t_conversion conversion; + int len; +} t_pformat; + +typedef struct s_list +{ + struct s_list *next; + t_pformat *data; +} t_list; + +/* +** ft_printf.c +*/ + +int ft_printf(const char *format, ...); + +/* +** parse.c +*/ + + +t_list *parse(const char *format); +char *isolate_conversion(const char *conversion_start); +t_pformat *parse_conversion(char *conversion); + +/* +** printer.c +*/ + +void ft_putchar(char c); +void ft_putstr(char *str); +void ft_putnbr(int nb); +void ft_putxnbr(long unsigned int n, char *hex_symbols); +void ft_putunbr(unsigned int n); + +/* +** utils.c +*/ + +int ft_atoi(const char *str); +char *ft_strndup(const char *s1, int n); +char *ft_strrchr(const char *s, int c); +int strrchr_index(const char *s, char c); +int ft_strlen(char *str); + +/* +** list.c +*/ + +t_list *list_new(t_pformat *data); +t_list *list_destroy(t_list *list); +void list_push_front(t_list **list, t_list *new_front); +void list_push_back(t_list **list, t_list *new_back); +void list_pop_front(t_list **list); + +#endif @@ -0,0 +1,54 @@ +#include <stdlib.h> +#include "header.h" + +t_list *list_new(t_pformat *data) +{ + t_list *list; + + if ((list = (t_list*)malloc(sizeof(t_list))) == NULL) + return NULL; + list->data = data; + list->next = NULL; + return (list); +} + +t_list *list_destroy(t_list *list) +{ + while (list != NULL) + list_pop_front(&list); + return (NULL); +} + + +void list_push_front(t_list **list, t_list *new_front) +{ + new_front->next = *list; + *list = new_front; +} + +void list_push_back(t_list **list, t_list *new_back) +{ + t_list *cursor; + + if (*list == NULL) + { + *list = new_back; + return ; + } + cursor = *list; + while (cursor->next != NULL) + cursor = cursor->next; + cursor->next = new_back; +} + +void list_pop_front(t_list **list) +{ + t_list *tmp; + + if (*list == NULL) + return ; + tmp = (*list)->next; + free((*list)->data); + free(*list); + *list = tmp; +} @@ -0,0 +1,58 @@ +#include <stdlib.h> +#include "header.h" + +#define STRRCHR_CONVERSIONS(c) (ft_strrchr(CONVERSIONS_STR, c)) + +t_list *parse(const char *format) +{ + t_list *format_list; + t_list *tmp; + t_pformat *parsed; + + format_list = NULL; + while (*format) + { + if (*format != '%') + { + format++; + continue; + } + format++; + if ((parsed = parse_conversion(isolate_conversion(format))) == NULL) + return (list_destroy(format_list)); + if ((tmp = list_new(parsed)) == NULL) + return (list_destroy(format_list)); + list_push_back(&format_list, tmp); + } + return (format_list); +} + +char *isolate_conversion(const char *conversion_start) +{ + int i; + + i = 0; + while (strrchr_index(CONVERSIONS_STR, conversion_start[i]) == -1) + i++; + return (ft_strndup(conversion_start, i + 1)); +} + +t_pformat *parse_conversion(char *conversion) +{ + int i; + t_pformat *pformat; + + if (conversion == NULL) + return (NULL); + if ((pformat = (t_pformat*)malloc(sizeof(t_pformat))) == NULL) + return (NULL); + i = ft_strlen(conversion) - 1; + pformat->conversion = strrchr_index(CONVERSIONS_STR, conversion[i]); + i--; + pformat->arg_position = 0; + pformat->left_adjusted = FALSE; + pformat->zero_padding = FALSE; + pformat->min_field_width = -1; + pformat->len = 1; + return (pformat); +} @@ -1,5 +1,5 @@ #include <unistd.h> -#include "ft_printf.h" +#include "header.h" void ft_putchar(char c) { @@ -27,7 +27,7 @@ void ft_putnbr(int n) ft_putchar(p_n % 10 + '0'); } -void ft_putxnbr(unsigned int n, char *hex_symbols) +void ft_putxnbr(long unsigned int n, char *hex_symbols) { if (n > 15) ft_putxnbr(n / 16, hex_symbols); @@ -1 +1,100 @@ +#include <stdlib.h> +#include "header.h" +#define MIN_INT (1 << 31) +#define MAX_INT (~(1 << 31)) + +static int precheck(const char **str) +{ + int is_negative; + + while (**str == ' ' || **str == '\t' || **str == '\n' + || **str == '\v' || **str == '\f' || **str == '\r') + (*str)++; + is_negative = 0; + if (**str == '-' || **str == '+') + { + if (**str == '-') + is_negative = 1; + (*str)++; + } + return (is_negative); +} + +int ft_atoi(const char *str) +{ + unsigned int nb; + int i; + int is_negative; + + is_negative = precheck(&str); + i = 0; + nb = 0; + while (str[i] >= '0' && str[i] <= '9') + { + if (!is_negative && nb > (unsigned int)MAX_INT) + return (-1); + else if (nb > (unsigned int)MIN_INT) + return (0); + nb *= 10; + nb += str[i] - '0'; + i++; + } + return ((int)(is_negative ? -nb : nb)); +} + +char *ft_strndup(const char *s1, int n) +{ + char *clone; + int i; + + if ((clone = (char*)malloc(sizeof(char) * (n + 1))) == NULL) + return (NULL); + i = 0; + while (i < n) + { + clone[i] = s1[i]; + i++; + } + clone[i] = '\0'; + return (clone); +} + +char *ft_strrchr(const char *s, int c) +{ + int i; + + i = ft_strlen(s) - 1; + while (s[i] != (char)c) + { + if (i == 0) + return (NULL); + i--; + } + return ((char*)s + i); +} + +int strrchr_index(const char *s, char c) +{ + int i; + + i = ft_strlen(s) - 1; + while (s[i] != c) + { + if (i == 0) + return (-1); + i--; + } + return (i); + +} + +int ft_strlen(char *str) +{ + int counter; + + counter = 0; + while (str[counter]) + counter++; + return (counter); +} |
