min_array/src/main.c

66 lines
2.3 KiB
C

#include <stdlib.h> /* EXIT_ strtol */
#include <stdio.h> /* FILE fopen fclose fread */
#include <errno.h> /* errno */
#include <ctype.h> /* isdigit */
#include <limits.h> /* LONG_ INT_ _MIN _MAX */
#include <assert.h> /* assert */
#include "min_array.h"
MIN_ARRAY(char, char)
MIN_ARRAY(num, int)
/** Concatenates the contents of `fp` after the file pointer to `string`. The
file pointer is modified. Zeros are preserved, as well as appending a
null-terminator. @return Success, otherwise `string` may have read a partial
read and may not be terminated. @throws[fread, malloc] */
static int cat_fp_to_str(FILE *const fp, struct char_array *const string) {
const size_t granularity = 1024;
size_t nread;
char *cursor;
assert(fp && string);
do {
if(!(cursor = char_array_buffer(string, granularity))) return 0;
char_array_emplace(string, nread = fread(cursor, 1, granularity, fp));
} while(nread == granularity); assert(nread < granularity);
if(ferror(fp) || !(cursor = char_array_new(string))) return 0;
*cursor = '\0';
return 1;
}
int main(void) {
int success = EXIT_FAILURE;
struct char_array str = MIN_ARRAY_IDLE;
struct num_array nums = MIN_ARRAY_IDLE;
int *num;
long big_num;
char *a, *anum = 0;
size_t i;
errno = 0; /* In case we are running it as part of another editor. */
if(!cat_fp_to_str(stdin, &str)) goto catch;
/*printf("<<<%s>>>\n", str.data);*/
/* The first sentinel '\0' it stops, even though it could have more data,
and we could conceivably use the length to continue; it's simple. */
for(a = str.data; a = strpbrk(a, "-0123456789"); ) {
if(*a == '-') { anum = a++; continue; }
if(!(num = num_array_new(&nums))) goto catch;
if(!anum || anum != a - 1) anum = a; /* Wasn't negative. */
big_num = strtol(anum, &a, 0);
if((!big_num || big_num == LONG_MIN || big_num == LONG_MAX) && errno)
goto catch; /* Long conversion failed. */
if(big_num < INT_MIN || big_num > INT_MAX)
{ errno = ERANGE; goto catch; }
*num = (int)big_num; /* Safe now. */
}
for(i = 0; i < nums.size; i++) printf("Extracted %d.\n", nums.data[i]);
success = EXIT_SUCCESS;
goto finally;
catch:
perror("stdin");
finally:
printf("Freeeee!! str %lu, nums %lu\n", str.capacity, nums.capacity);
char_array_(&str);
num_array_(&nums);
printf("yessss.\n");
return success;
}