Can consume input

This commit is contained in:
Miguel M 2023-04-21 19:39:21 +01:00
parent 6e1af9c863
commit 709bc6f8c0
1 changed files with 59 additions and 23 deletions

View File

@ -19,10 +19,12 @@ typedef struct
// The data is organized as <string length> <chars...>, such that the `char`s
// are casted to `int_fast32_t` to allow for the mixed types.
grid_data_t *data_head;
// Array of pointers to the start of each entry string.
grid_data_t **entries_head;
// Number of elements.
// Array of indices in `data_head` of the start of each string.
size_t *entries_head;
// Number of bytes.
size_t data_len;
// Number of entries.
size_t entries_len;
} grid_t;
// Parameters for `increase_input_buffers`.
@ -30,15 +32,54 @@ typedef struct
{
size_t data_cap;
grid_data_t *data_head;
grid_data_t **entries_head;
size_t *entries_head;
} increase_input_buffers_params_t;
// Prints a debug view of a `grid_t` to standard output.
void debug_print_grid(grid_t *grid)
{
printf("Grid { row_len: %zu, data_head: %p, entries_head: %p, data_len: %zu }",
(grid->row_len), (void*)(grid->data_head), (void*)(grid->entries_head),
(grid->data_len));
printf("Grid ( row_len: %zu, data_head: %p, entries_head: %p, data_len: %zu, entries_len: %zu ) { ",
(grid->row_len), (void *)(grid->data_head), (void *)(grid->entries_head),
(grid->data_len), (grid->entries_len));
printf("data: [");
size_t str_counter = 0;
for (size_t i = 0; i < grid->data_len; i++)
{
if (i > 0)
{
printf(", ");
}
else
{
printf(" ");
}
_Bool is_char = 1;
if (grid->entries_len > 0 && str_counter < grid->entries_len) {
if ((grid->entries_head)[str_counter] == i) {
is_char = 0;
str_counter += 1;
}
}
if (is_char) {
printf("'%c'", (char)((grid->data_head)[i]));
} else {
printf("%" PRIgridDATA, (grid->data_head)[i]);
}
}
printf("], entries: [");
for (size_t i = 0; i < grid->entries_len; i++)
{
if (i > 0)
{
printf(", ");
}
else
{
printf(" ");
}
printf("%zu", (grid->entries_head)[i]);
}
printf("] }\n");
}
// Increases the data buffers used in `parse_input`.
@ -84,13 +125,13 @@ grid_t parse_input(void)
size_t data_cap = 32; // Initial value is arbitrary.
size_t data_len = 0; // Number of characters written so far.
size_t str_len = 0; // Number of strings written so far.
size_t entries_len = 0; // Number of strings written so far.
grid_data_t *data_head = malloc(data_cap * sizeof(grid_data_t));
size_t *entries_head = malloc(data_cap * sizeof(size_t));
_Bool spaces = 1;
char scanned;
while ((scanned = scanf("%c", &scanned)) != EOF)
while (scanf("%c", &scanned) != EOF)
{
if (isspace(scanned))
{
@ -99,26 +140,21 @@ grid_t parse_input(void)
else
{
// A little input sanitization.
if (scanned == '+')
{
// We can ignore plus signs, assuming we have (\+|\-)?\d+(\.\d+)?(E\d+)?
continue;
}
if (!(isdigit(scanned) || (scanned == '-') || (scanned == '.')))
{
printf(
"Foreign character %c found when processing input, aborting.",
scanned);
"Foreign character %c (%x) found when processing input, aborting.",
scanned, scanned);
exit(EXIT_FAILURE);
}
if (spaces)
{
// New row
str_len += 1;
// New string
entries_len += 1;
data_len += 1; // The byte for the string length
// data_head[data_len] is already correctly initialized to 0.
entries_head[str_len - 1] = data_len - 1;
entries_head[entries_len - 1] = data_len - 1;
}
spaces = 0;
@ -143,18 +179,17 @@ grid_t parse_input(void)
data_head[data_len - 1] = scanned;
// Increase the length of current string
grid_data_t *cur_len = entries_head[str_len - 1];
*cur_len += 1;
data_head[entries_head[entries_len - 1]] += 1;
}
} // End of scan loop
// Input sanitization: confirm that the number of entries read is a multiple
// of the number of entries in a row.
if (!((str_len % row_len) == 0))
if (!((entries_len % row_len) == 0))
{
printf("Number of entries is not consistent with provided row length. "
"Got row length of %zu, and read %zu entries. Aborting.",
row_len, str_len);
row_len, entries_len);
// No need to free the buffers.
exit(EXIT_FAILURE);
}
@ -164,6 +199,7 @@ grid_t parse_input(void)
.data_head = data_head,
.entries_head = entries_head,
.data_len = data_len,
.entries_len = entries_len,
};
return grid;