Add first structure and start work on format specifier parser

This commit is contained in:
2023-05-29 11:40:13 +02:00
commit af27e79678
4 changed files with 178 additions and 0 deletions

134
src/simple-printf.c Normal file
View File

@@ -0,0 +1,134 @@
#include <simple-printf/simple-printf.h>
#include <stddef.h>
#include <stdbool.h>
enum format_specifier_type {
FMT_INVALID = 0,
FMT_INTEGER,
FMT_UNSIGNED,
FMT_STRING,
FMT_HEXUINT_CAPITALIZED,
FMT_HEXUNIT,
FMT_CHAR,
FMT_SIZE,
FMT_PERCENT,
};
struct format_specifier {
enum format_specifier_type specifier;
size_t length; /**< @brief lenght of formatted output.*/
bool zero_pad;
size_t length_of_provided_specifier;
};
static void parse_format_specifier(const char *start, struct format_specifier *result)
{
size_t fmt_len = 1ull;
bool keep_parsing = true;
bool is_in_number = false;
const char *number;
size_t num_len = 0;
result->specifier = FMT_INVALID;
result->zero_pad = 0;
result->length_of_provided_specifier = 0;
result->length = 0;
if (!start)
return;
/* Check if specifier starts with % */
if (*start != '%')
return;
start++;
while (keep_parsing) {
/* Parse the format specifier*/
switch (*start) {
case '0':
if (fmt_len == 1) {
result->zero_pad = 1;
break;
}
/* Fallthru */
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
/* Number */
if (!is_in_number) {
/* Start of number */
is_in_number = true;
number = start;
num_len = 0;
} else {
/* Continue parsing number */
num_len++;
}
break;
case 'c':
result->specifier = FMT_CHAR;
keep_parsing = false;
break;
case 'z':
result->specifier = FMT_SIZE;
keep_parsing = false;
break;
case 'x':
result->specifier = FMT_HEXUNIT;
keep_parsing = false;
break;
case 'X':
result->specifier = FMT_HEXUINT_CAPITALIZED;
keep_parsing = false;
break;
case 's':
result->specifier = FMT_STRING;
keep_parsing = false;
break;
case 'u':
result->specifier = FMT_UNSIGNED;
keep_parsing = false;
break;
case 'i': /* Falltrhu */
case 'd':
result->specifier = FMT_INTEGER;
keep_parsing = false;
break;
case '%':
if (fmt_len == 1) {
result->specifier = FMT_PERCENT;
}
keep_parsing = false;
default:
/* Unrecognized stuff. Abort */
keep_parsing = false;
break;
}
if (keep_parsing == false) {
/* End reached. Check the number */
}
start++;
fmt_len++;
}
}
int simple_snprintf(char *dest, size_t dest_size, const char *fmt, ...)
{
int ret = -1;
if (!dest || !dest_size || !fmt) {
/* Parameter error */
return -1000;
}
return ret;
}