diff options
| author | Charles <sircharlesaze@gmail.com> | 2019-10-15 13:02:53 +0200 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2019-10-15 13:02:53 +0200 |
| commit | fa4bf89263e897695dbf48061369a23d695fef8b (patch) | |
| tree | 0c1bd50114f49adac07bd2fabda5d7a5ea74e88e | |
| parent | 60733a2298c7a93fe681f78af9b69e1639a791b5 (diff) | |
| download | ft_printf-fa4bf89263e897695dbf48061369a23d695fef8b.tar.gz ft_printf-fa4bf89263e897695dbf48061369a23d695fef8b.tar.bz2 ft_printf-fa4bf89263e897695dbf48061369a23d695fef8b.zip | |
Parsing rewrite
- 4 extraction functions which parse some format attributes
and remove them.
- Not handling wildcard yet
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | extract.c | 62 | ||||
| -rw-r--r-- | ft_printf.c | 48 | ||||
| -rw-r--r-- | header.h | 16 | ||||
| -rw-r--r-- | parse.c | 97 | ||||
| -rw-r--r-- | printer.c | 175 | ||||
| -rw-r--r-- | utils.c | 100 |
7 files changed, 219 insertions, 281 deletions
@@ -4,7 +4,7 @@ CCFLAGS = -Wall -Wextra #-Werror RM = rm -f NAME = ft_printf -SRC = ft_printf.c utils.c printer.c parse.c list.c +SRC = ft_printf.c utils.c printer.c parse.c list.c extract.c OBJ = $(SRC:.c=.o) INCLUDE = header.h @@ -1,3 +1,4 @@ +#include <stdlib.h> #include "header.h" char *extract_ap_index(t_pformat *pformat, char *fmt) @@ -27,44 +28,46 @@ char *extract_standalone_flags(t_pformat *pformat, char *fmt) int i; char *fmt_dup; - i = -1; - while (IS_STANDALONE_FLAG(fmt[++i])) + i = 0; + while (IS_STANDALONE_FLAG(fmt[i])) { if (!pformat->zero_padding) pformat->zero_padding = fmt[i] == '0'; if (!pformat->left_adjusted) pformat->left_adjusted = fmt[i] == '-'; + i++; } fmt_dup = ft_strdup(&fmt[i]); free(fmt); - return (fmt_dup); + return (fmt_dup); } char *extract_min_width(t_pformat *pformat, char *fmt) { int i; int tmp; - char fmt_dup; + char *fmt_dup; i = 0; - if (*fmt == '*') - { - pformat->min_width->wildcard->exist = TRUE; - i++; - } + /* if (*fmt == '*') */ + /* { */ + /* pformat->min_width.wildcard.exist = TRUE; */ + /* i++; */ + /* } */ if (ft_isdigit(fmt[i])) { - tmp = ft_atoi(fmt[i]); + tmp = ft_atoi(&fmt[i]); while (ft_isdigit(fmt[i])) i++; - if (fmt[i] == '$') - pformat->min_width->wildcard->ap_index = tmp; - else - { - pformat->min_width->hardcoded = tmp; - pformat->min_width->wildcard->exist = FALSE; - } + /* printf("%d\n", tmp); */ + /* if (fmt[i] == '$') */ + /* pformat->min_width.wildcard.ap_index = tmp; */ + /* else */ + /* { */ + pformat->min_width.hardcoded = tmp; + pformat->min_width.wildcard.exist = FALSE; + /* } */ } fmt_dup = ft_strdup(&fmt[i]); free(fmt); @@ -74,25 +77,26 @@ char *extract_min_width(t_pformat *pformat, char *fmt) char *extract_precision(t_pformat *pformat, char *fmt) { int i; + int tmp; char *fmt_dup; if (*fmt != '.') return (fmt); i = 1; - if (fmt[i] == '*') - { - pformat->precision->wildcard->exist = TRUE; - i++; - } - else if (!ft_isdigit(fmt[i])) - pformat->precision->hardcoded = 0; - tmp = ft_atoi(fmt[i]); + /* if (fmt[i] == '*') */ + /* { */ + /* pformat->precision.wildcard.exist = TRUE; */ + /* i++; */ + /* } */ + /* else if (!ft_isdigit(fmt[i])) */ + /* pformat->precision.hardcoded = 0; */ + tmp = ft_atoi(&fmt[i]); while (ft_isdigit(fmt[i])) i++; - if (pformat->precision->wildcard->exist && fmt[i] == '$') - pformat->precision->wilcard->ap_index = tmp; - else - pformat->precision->hardcoded = tmp; + /* if (pformat->precision.wildcard.exist && fmt[i] == '$') */ + /* pformat->precision.wildcard.ap_index = tmp; */ + /* else */ + pformat->precision.hardcoded = tmp; fmt_dup = ft_strdup(&fmt[i]); free(fmt); return (fmt); diff --git a/ft_printf.c b/ft_printf.c index beabcd7..3ae03c0 100644 --- a/ft_printf.c +++ b/ft_printf.c @@ -48,32 +48,36 @@ int ft_printf(const char *format, ...) return (print_len); } +#ifndef TESTING + 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"); + /* int test; */ - ft_printf("precision |%.10d|\n", 43); - ft_printf("string precision |%.1s|\n", "bonjour"); - ft_printf("min width |%9d|\n", 43); - ft_printf("zero padding |%09d|\n", 43); - ft_printf("left adjusted |%-9d|\n", 43); - ft_printf("string padding |%9s|\n", "bon"); + /* 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("width wildcard |%*d|\n", 5, 43); - ft_printf("precision wildcard |%.*d|\n", 5, 43); - ft_printf("precision/width wildcard |%*.*d|\n", 5, 3, 43); - ft_printf("left adjusted |%*d|\n", -5, 43); + ft_printf("precision |%.9d|\n", 43); + ft_printf("string precision |%.9s|\n", "jesuisbonjourbonjour"); + ft_printf("min width |%9d|\n", 43); + ft_printf("zero padding |%09d|\n", 43); + ft_printf("left adjusted |%-9d|\n", 43); + ft_printf("string padding |%9s|\n", "bon"); - ft_printf("overwrite |%*3d|\n", 5, 43); - ft_printf("overwrite |%*-1d|\n", 0, 43); + /* ft_printf("width wildcard |%*d|\n", 5, 43); */ + /* ft_printf("precision wildcard |%.*d|\n", 5, 43); */ + /* ft_printf("precision/width wildcard |%*.*d|\n", 5, 3, 43); */ + /* ft_printf("left adjusted |%*d|\n", -5, 43); */ + /* */ + /* ft_printf("overwrite |%*3d|\n", 5, 43); */ + /* ft_printf("overwrite |%*-1d|\n", 0, 43); */ return 0; } + +#endif @@ -9,8 +9,7 @@ # 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 IS_STANDALONE_FLAG(c) (c == '0' || c == '-') # define CONVERSIONS_STR "cspdiuxX%" @@ -69,19 +68,13 @@ int ft_printf(const char *format, ...); t_list *parse(const char *format); char *isolate_conversion(const char *conversion_start); -t_pformat *parse_conversion(char *conversion); -char *parse_arg_position(char *conversion, t_pformat *pformat); +t_pformat *parse_reduced(char *fmt); /* ** printer.c */ void ft_putstr(char *str); -int nbrlen_radix(int nbr, int radix); -char *ft_itoa(int n); -char *ft_strnew(int size); -char *ft_strdup(char *s); -char *ft_strcpy(char *dest, const char *src); 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); @@ -96,6 +89,11 @@ char *ft_strrchr(const char *s, int c); int strrchr_index(const char *s, char c); int ft_strlen(char *str); t_bool ft_isdigit(char c); +int nbrlen_radix(long int nbr, int radix); +char *ft_itoa_base(long int n, char *base); +char *ft_strnew(int size); +char *ft_strdup(char *s); +char *ft_strcpy(char *dest, const char *src); /* ** extract.c @@ -2,12 +2,12 @@ #include "header.h" #define STRRCHR_CONVERSIONS(c) (ft_strrchr(CONVERSIONS_STR, c)) -#define IS_STANDALONE_FLAG(c) (c == '0' || c == '-') /* ** %(?:\d+\$)?[-]?(?:[0]|'.{1})?-?\d*(?:\.\d+)?[cdusxX] */ +#include <stdio.h> t_list *parse(const char *format) { t_list *format_list; @@ -23,7 +23,7 @@ t_list *parse(const char *format) continue; } format++; - if ((parsed = parse_conversion(isolate_conversion(format))) == NULL) + if ((parsed = parse_reduced(isolate_conversion(format))) == NULL) return (list_destroy(format_list)); if ((tmp = list_new(parsed)) == NULL) return (list_destroy(format_list)); @@ -42,100 +42,25 @@ char *isolate_conversion(const char *conversion_start) return (ft_strndup(conversion_start, i + 1)); } - -t_pformat *parse_reduced_fmt(char *fmt) +t_pformat *parse_reduced(char *fmt) { t_pformat *pformat; - if (conversion == NULL) + if (fmt == NULL) return (NULL); if ((pformat = (t_pformat*)malloc(sizeof(t_pformat))) == NULL) return (NULL); pformat->ap_index = -1; pformat->left_adjusted = FALSE; pformat->zero_padding = FALSE; - pformat->min_width->wildcard->exist = FALSE; - pformat->precision->wildcard->exist = FALSE; - fmt = extrac_ap_index(pformat, fmt); - fmt = extrac_standalone_flags(pformat, fmt); + pformat->min_width.wildcard.exist = FALSE; + pformat->precision.wildcard.exist = FALSE; + pformat->precision.hardcoded = -1; + pformat->len = ft_strlen(fmt); + pformat->conversion = strrchr_index(CONVERSIONS_STR, fmt[pformat->len - 1]); + fmt[pformat->len - 1] = 0; + fmt = extract_standalone_flags(pformat, fmt); fmt = extract_min_width(pformat, fmt); fmt = extract_precision(pformat, fmt); return (pformat); } - -// %[position][dollar][flags][width][.precision][length]type -t_pformat *parse_conversion(char *conversion) -{ - int i; - char *start; - 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->len = i + 1; - pformat->conversion = strrchr_index(CONVERSIONS_STR, conversion[i]); - i--; - if ((conversion = parse_arg_position(conversion, pformat)) == NULL) - return (NULL); - start = conversion; - pformat->zero_padding = FALSE; - pformat->left_adjusted = FALSE; - while (IS_STANDALONE_FLAG(*start)) - { - if (!pformat->zero_padding) - pformat->zero_padding = *start == '0'; - if (!pformat->left_adjusted) - pformat->left_adjusted = *start == '-'; - start++; - } - pformat->min_field_width_wildcard = FALSE; - pformat->min_field_width = -1; - if (*start == '*') - { - pformat->min_field_width_wildcard = TRUE; - start++; - } - if (ft_isdigit(*start)) - { - /* pformat->min_field_width_wildcard = FALSE; */ - pformat->min_field_width = ft_atoi(start); - while (ft_isdigit(*start)) - start++; - } - pformat->precision = -1; - pformat->precision_wildcard = FALSE; - if (*start == '.') - { - start++; - if (*start == '*') - pformat->precision_wildcard = TRUE; - else - { - pformat->precision = ft_atoi(start); - while (ft_isdigit(*start)) - start++; - } - } - return (pformat); -} - -char *parse_arg_position(char *conversion, t_pformat *pformat) -{ - if (strrchr_index(conversion, '$') != -1) - { - if ((pformat->ap_index = ft_atoi(conversion)) == 0) - { - free(pformat); - return (NULL); - } - while (ft_isdigit(*conversion)) - conversion++; - conversion++; - } - else - pformat->ap_index = -1; - return (conversion); -} @@ -4,8 +4,8 @@ #include "header.h" #define ITOA_DEC(x) (ft_itoa_base(x, "0123456789")) -#define ITOA_HEX_LOWER(x) (ft_itoa_base(x, "abcdef0123456789")) -#define ITOA_HEX_UPPER(x) (ft_itoa_base(x, "ABCDEF0123456789")) +#define ITOA_HEX_LOWER(x) (ft_itoa_base(x, "0123456789abcdef")) +#define ITOA_HEX_UPPER(x) (ft_itoa_base(x, "0123456789ABCDEF")) void ft_putstr(char *str) { @@ -13,127 +13,28 @@ void ft_putstr(char *str) write(STDOUT_FILENO, str++, 1); } -int nbrlen_radix(int nbr, int radix) -{ - int counter; - 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(int n, char *base) -{ - char *str; - int len; - int is_negative; - int radix; - 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'; - is_negative = 0; - u_nbr = n; - if (n < 0) - { - is_negative = 1; - str[0] = '-'; - u_nbr = -n; - } - len--; - while (len >= (is_negative ? 1 : 0)) - { - str[len] = base[u_nbr % radix]; - u_nbr /= radix; - len--; - } - return (str); -} - -char *ft_strnew(int size) -{ - char *str; - - if ((str = (char*)malloc(sizeof(char) * (size + 1))) == NULL) - return (NULL); - str[size] = '\0'; - while (size-- > 0) - str[size] = '\0'; - return (str); -} - -char *ft_strdup(char *s) -{ - char *clone; - size_t i; - size_t len; - - len = ft_strlen(s); - if ((clone = (char*)malloc(sizeof(char) * (len + 1))) == NULL) - return (NULL); - i = 0; - while (i < len) - { - clone[i] = s[i]; - i++; - } - clone[i] = '\0'; - return (clone); -} - -char *ft_strcpy(char *dest, const char *src) -{ - int i; - - i = 0; - while (src[i]) - { - dest[i] = src[i]; - i++; - } - dest[i] = '\0'; - return (dest); -} - char *convert_to_str(t_pformat *pformat, va_list ap) { char *str; t_conversion conversion = pformat->conversion; str = NULL; - if (pformat->min_width.wildcard.exist) - { - if (pformat->min_width != -1) - va_arg(ap, int); - else - { - pformat->min_width = va_arg(ap, int); - if (pformat->min_width < 0) - { - pformat->left_adjusted = TRUE; - pformat->min_width = -pformat->min_width; - } - } - } - if (pformat->precision_wildcard) - pformat->precision = va_arg(ap, int); + /* if (pformat->min_width.wildcard.exist) */ + /* { */ + /* if (pformat->min_width.hardcoded != -1) */ + /* va_arg(ap, int); */ + /* else */ + /* { */ + /* pformat->min_width.hardcoded = va_arg(ap, int); */ + /* if (pformat->min_width.hardcoded < 0) */ + /* { */ + /* pformat->left_adjusted = TRUE; */ + /* pformat->min_width.hardcoded *= -1; */ + /* } */ + /* } */ + /* } */ + /* if (pformat->precision.wildcard.exist) */ + /* pformat->precision.hardcoded = va_arg(ap, int); */ if (conversion == CONVERSION_CHAR) { if ((str = ft_strnew(2)) == NULL) @@ -145,16 +46,20 @@ char *convert_to_str(t_pformat *pformat, va_list ap) else if (conversion == CONVERSION_PTR) { // handle 0x with and without zero padding - str = ITOA_HEX_UPPER(va_arg(ap, int)); + ft_putstr("0x"); + str = ft_strnew(2); + str[0] = 'b'; + str[1] = 0; + 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, int)); + str = ITOA_DEC(va_arg(ap, unsigned int)); else if (conversion == CONVERSION_HEX_LOWER) - str = ITOA_HEX_LOWER(va_arg(ap, int)); + str = ITOA_HEX_LOWER(va_arg(ap, unsigned int)); else if (conversion == CONVERSION_HEX_UPPER) - str = ITOA_HEX_UPPER(va_arg(ap, int)); + str = ITOA_HEX_UPPER(va_arg(ap, unsigned int)); else if (conversion == CONVERSION_PERCENT) { if ((str = ft_strnew(2)) == NULL) @@ -172,15 +77,15 @@ void handle_padding(t_pformat *pformat, char *str) int len; int i; - if (pformat->min_width == -1) + if (pformat->min_width.hardcoded == -1) return; - if ((len = ft_strlen(str)) >= pformat->min_width) + if ((len = ft_strlen(str)) >= pformat->min_width.hardcoded) return; - tmp = (char*)malloc(sizeof(char) * (pformat->min_width + 1)); + tmp = (char*)malloc(sizeof(char) * (pformat->min_width.hardcoded + 1)); if (!pformat->left_adjusted) { i = 0; - while (i <= pformat->min_width - len) + while (i <= pformat->min_width.hardcoded - len) tmp[i++] = pformat->zero_padding ? '0' : ' '; ft_strcpy(tmp + i - 1, str); ft_strcpy(str, tmp); @@ -189,37 +94,39 @@ void handle_padding(t_pformat *pformat, char *str) { ft_strcpy(tmp, str); i = len; - while (i < pformat->min_width) + while (i < pformat->min_width.hardcoded) tmp[i++] = ' '; ft_strcpy(str, tmp); } free(tmp); } +/* #include <stdio.h> */ void handle_precision(t_pformat *pformat, char *str) { int len; char *tmp; t_conversion conv; - if (pformat->precision == -1) + /* printf("\n%d\n", pformat->precision.hardcoded); */ + if (pformat->precision.hardcoded == -1) return ; len = ft_strlen(str); conv = pformat->conversion; if (conv == CONVERSION_STR) - str[pformat->precision] = '\0'; + str[pformat->precision.hardcoded] = '\0'; else if (conv == CONVERSION_DECIMAL || conv == CONVERSION_INT || conv == CONVERSION_UINT || conv == CONVERSION_HEX_LOWER || conv == CONVERSION_HEX_UPPER) { - if (len >= pformat->precision) + if (len >= pformat->precision.hardcoded) return ; - tmp = (char*)malloc(sizeof(char) * (pformat->precision + 1)); - ft_strcpy(tmp + pformat->precision - len, str); + tmp = (char*)malloc(sizeof(char) * (pformat->precision.hardcoded + 1)); + ft_strcpy(tmp + pformat->precision.hardcoded - len, str); /* printf("\n>%s< %d %d\n", str, len, pformat->precision); */ - pformat->precision -= len; - while (pformat->precision-- > 0) - tmp[pformat->precision] = '0'; + pformat->precision.hardcoded -= len; + while (pformat->precision.hardcoded-- > 0) + tmp[pformat->precision.hardcoded] = '0'; ft_strcpy(str, tmp); free(tmp); } @@ -103,3 +103,103 @@ t_bool ft_isdigit(char c) { return (c >= '0' && c <= '9'); } + +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 int n, char *base) +{ + char *str; + int len; + int is_negative; + int radix; + 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'; + is_negative = 0; + u_nbr = n; + if (n < 0) + { + is_negative = 1; + str[0] = '-'; + u_nbr = -n; + } + len--; + while (len >= (is_negative ? 1 : 0)) + { + str[len] = base[u_nbr % radix]; + u_nbr /= radix; + len--; + } + return (str); +} + +char *ft_strnew(int size) +{ + char *str; + + if ((str = (char*)malloc(sizeof(char) * (size + 1))) == NULL) + return (NULL); + str[size] = '\0'; + while (size-- > 0) + str[size] = '\0'; + return (str); +} + +char *ft_strdup(char *s) +{ + char *clone; + size_t i; + size_t len; + + len = ft_strlen(s); + if ((clone = (char*)malloc(sizeof(char) * (len + 1))) == NULL) + return (NULL); + i = 0; + while (i < len) + { + clone[i] = s[i]; + i++; + } + clone[i] = '\0'; + return (clone); +} + +char *ft_strcpy(char *dest, const char *src) +{ + int i; + + i = 0; + while (src[i]) + { + dest[i] = src[i]; + i++; + } + dest[i] = '\0'; + return (dest); +} + |
