From d144ab9af005a6731753747bdfe00953753c195a Mon Sep 17 00:00:00 2001 From: Oluwatobi Oladoye Date: Sun, 12 Nov 2023 22:30:37 +0000 Subject: [PATCH] Parse format string Additions: - parse_format function - handle_percent function - code refactoring - stop va_list iteration Removal - print_error source code --- _printf.c | 29 ++++++++++--------- main.h | 8 ++++-- parser.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ print_literals.c | 1 - 4 files changed, 92 insertions(+), 18 deletions(-) create mode 100644 parser.c diff --git a/_printf.c b/_printf.c index 86177f3..b68567d 100644 --- a/_printf.c +++ b/_printf.c @@ -1,5 +1,3 @@ -#include -#include #include "main.h" /** @@ -11,24 +9,26 @@ */ int _printf(const char *format, ...) { - int char_count = 0; + int char_count = 0, fmt_status; va_list ap; - va_start(ap, format); - if (!(*format)) - write(1, "User input is needed", 21); + return (char_count); + fmt_status = parse_format(format); - while (*format) + if (fmt_status == 1) { - if (*format == '%') - char_count += p_func(ap, *++format); - else - char_count += write(1, format, 1); - - ++format; + va_start(ap, format); + while (*format) + { + if (*format == '%') + char_count += p_func(ap, *++format); + else + char_count += write(1, format, 1); + ++format; + } + va_end(ap); } - return (char_count); } @@ -55,6 +55,5 @@ int p_func(va_list ap, char specifier) char_count += write(1, "%", 1); break; } - return (char_count); } diff --git a/main.h b/main.h index 4d68fee..9bd144f 100644 --- a/main.h +++ b/main.h @@ -1,11 +1,15 @@ #ifndef MAIN_H #define MAIN_H + +#include #include +#include int _printf(const char *format, ...); +int parse_format(const char *); +int handle_percent(char, char); +int p_func(va_list, char); int print_char(va_list); int print_string(va_list); -int p_func(va_list, char); -void print_error(char *); #endif diff --git a/parser.c b/parser.c new file mode 100644 index 0000000..b8d479d --- /dev/null +++ b/parser.c @@ -0,0 +1,72 @@ +#include "main.h" + +/** + * parse_format - parse format string + * @fmt - Format string to parse + * Description: Determines if the format string + * contains valid format specifiers. + * Return: 1 (valid) or 0 (invalid). + */ +int parse_format(const char *fmt) +{ + int i = 0, ret_val, len = strlen(fmt) - 1; + + while (i <= len) + { + if (fmt[i] == '%') + { + if (i + 1 > len) /* fmt[i] is the last char of *fmt */ + { + ret_val = 0; + break; + } + /* char fmt[i] does not denote allowed specifier */ + if (fmt[i + 1] != 'c' && fmt[i + 1] != 's' && fmt[i + 1] + != '%') + { + ret_val = 0; + break; + } + if (fmt[i + 1] == '%') /* % was escaped */ + { + /* Returns (0) when last char is % */ + if ((i + 2) == len && fmt[i + 2] == '%') + { + ret_val = 0; + break; + } + /*Fast forward check to determine next-2 chars*/ + if ((i + 2) < len) + { + ret_val = (handle_percent(fmt[i + 2], fmt[i + + 3])); + if (ret_val == 0) + break; + } + } + i += 2; /* skip determined fmt specifier */ + } + else + { + ret_val = 1; + i++; + } + } + return (ret_val); +} + +/** + * handle_percent - fast forward check + * @nxt2: Third char of *fmt + * @nxt3: Fourth char of *fmt + * Description: Fast forward check the next + * two chars of %. + * Return: 1 (valid) or 0 (invalid) + */ +int handle_percent(char nxt2, char nxt3) +{ + if (nxt2 == '%') + if (nxt3 != 'c' && nxt3 != 's' && nxt3 != '%') + return (0); + return (1); +} diff --git a/print_literals.c b/print_literals.c index 4970d60..77a77bb 100644 --- a/print_literals.c +++ b/print_literals.c @@ -1,4 +1,3 @@ -#include #include "main.h" /**