#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include #include #include "cmaybe.h" MAYBE_TYPE(voidptr, void *); MAYBE(voidptr) strchr_maybe(const void *s, int c) { ENABLE_RETURN(voidptr); void *location = strchr(s, c); if (location == NULL) { RETURN_NOTHING(); } else { RETURN_VALUE(location); } } MAYBE(voidptr) malloc_maybe(size_t size) { ENABLE_RETURN(voidptr); void *allocation = malloc(size); if(allocation == NULL && size != 0) { RETURN_NOTHING(); } else { RETURN_VALUE(allocation); } } MAYBE(voidptr) realloc_maybe(void *old, size_t size) { ENABLE_RETURN(voidptr); void *allocation = realloc(old, size); if(allocation == NULL && size != 0) { RETURN_NOTHING(); } else { RETURN_VALUE(allocation); } } MAYBE_TYPE(intmax_t, intmax_t); MAYBE(intmax_t) str2int(const char *string) { ENABLE_RETURN(intmax_t); char *endptr; intmax_t num = strtoimax(string, &endptr, 10); if (*endptr == '\0' && string[0] != '\0') { RETURN_VALUE(num); } else { RETURN_NOTHING(); } } struct intmax_t_array { intmax_t *data; size_t length; size_t alloc_size; }; MAYBE_TYPE(intmax_t_array, struct intmax_t_array); MAYBE(intmax_t_array) create_array(void) { ENABLE_RETURN(intmax_t_array); ENABLE_TRY(); TRY_TYPE(voidptr); struct intmax_t_array array; array.length = 0; array.alloc_size = sizeof(intmax_t); array.data = TRY(voidptr, malloc_maybe(array.alloc_size)); RETURN_VALUE(array); } MAYBE(intmax_t_array) resize_array(struct intmax_t_array array, size_t length) { ENABLE_RETURN(intmax_t_array); ENABLE_TRY(); TRY_TYPE(voidptr); struct intmax_t_array resized_array = {array.data, length, array.alloc_size}; if(resized_array.alloc_size / sizeof(intmax_t) < resized_array.length) { if(SIZE_MAX / 2 < resized_array.alloc_size) { RETURN_NOTHING(); } resized_array.alloc_size *= 2; resized_array.data = TRY(voidptr, realloc_maybe(resized_array.data, resized_array.alloc_size)); } RETURN_VALUE(resized_array); } MAYBE(intmax_t_array) convert_to_numbers(char *line) { ENABLE_RETURN(intmax_t_array); ENABLE_TRY(); TRY_TYPE(intmax_t); TRY_TYPE(intmax_t_array); struct intmax_t_array numbers = TRY(intmax_t_array, create_array()); FREE_ON_TRY_FAIL(numbers.data); char *strtok_saveptr = NULL; for (;;) { char *num_str; if (strtok_saveptr == NULL) { num_str = strtok_r(line, " ", &strtok_saveptr); } else { num_str = strtok_r(NULL, " ", &strtok_saveptr); } if (num_str == NULL) { break; } intmax_t num = TRY(intmax_t, str2int(num_str)); size_t index = numbers.length; void *old_ptr = numbers.data; numbers = TRY(intmax_t_array, resize_array(numbers, numbers.length + 1)); TRY_HOF_REPLACE(old_ptr, numbers.data); numbers.data[index] = num; } RETURN_VALUE(numbers); } int main(void) { size_t line_size = 0; char *line = NULL; ssize_t line_len; while ((line_len = getline(&line, &line_size, stdin)) > 0) { MAYBE(voidptr) newline = strchr_maybe(line, '\n'); IS_VALUE(newline) { *(char*)VALUE(newline) = '\0'; } MAYBE(intmax_t_array) numbers = convert_to_numbers(line); IS_VALUE(numbers) { for (size_t i = 0; i < VALUE(numbers).length; i++) { printf("%jd ", VALUE(numbers).data[i]); } printf("\n"); } else { printf("Error in conversion\n"); } } return 0; }