From 8c461db5a99086b402a274e6c786f6d1d6bbdfc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Sat, 11 Aug 2018 12:33:56 +0300 Subject: [PATCH] Implement TRY --- Makefile | 7 ++- cmaybe.h | 85 ++++++++++++++++++++++++++++++++++- convert_to_ints | Bin 0 -> 13592 bytes convert_to_ints.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 198 insertions(+), 4 deletions(-) create mode 100755 convert_to_ints create mode 100644 convert_to_ints.c diff --git a/Makefile b/Makefile index a25cfff..1bf8066 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,12 @@ -all: average +all: average convert_to_ints average: average.c cmaybe.h $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< +convert_to_ints: convert_to_ints.c cmaybe.h + $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< + clean: - rm -f average + rm -f average convert_to_ints .PHONY: all clean diff --git a/cmaybe.h b/cmaybe.h index bdfb824..2c7b806 100644 --- a/cmaybe.h +++ b/cmaybe.h @@ -15,8 +15,89 @@ return __return_value;\ } -#define IS_VALUE(x) if((x).is_value) -#define IS_NOT_VALUE(x) if(!(x).is_value) +#define IS_VALUE(x) if ((x).is_value) +#define IS_NOT_VALUE(x) if (!(x).is_value) #define VALUE(x) (x).value +struct __free_list { + struct __free_list *next; + void *ptr; +}; +#define ENABLE_TRY() \ + struct __free_list *__allocations = NULL, *__free_list_node;\ + void *__allocation, *__old_allocation;\ + jmp_buf __try_fail_jmp_buf;\ + if (setjmp(__try_fail_jmp_buf)) {\ + TRY_FREE_ALL();\ + RETURN_NOTHING();\ + } +#define TRY_TYPE(name) MAYBE(name) __try_tmp_##name +#define TRY(name, maybe_value) (\ + __try_tmp_##name = maybe_value,\ + (__try_tmp_##name.is_value ? 0 :\ + longjmp(__try_fail_jmp_buf, 1)\ + ),\ + __try_tmp_##name.value\ +) + +#define TRY_MEMALLOC(allocator, ...) (\ + __free_list_node = malloc(sizeof(struct __free_list)),\ + (__free_list_node == NULL ? longjmp(__try_fail_jmp_buf, 1) : 0),\ + __allocation = allocator(__VA_ARGS__),\ + (__allocation == NULL ? (\ + free(__free_list_node),\ + longjmp(__try_fail_jmp_buf, 1)\ + ) : (\ + __free_list_node->next = __allocations,\ + __free_list_node->ptr = __allocation,\ + __allocations = __free_list_node\ + )),\ + __allocation\ +) +#define TRY_MALLOC(size) TRY_MEMALLOC(malloc, size) + +void __remove_free_list(struct __free_list **head, void *ptr) { + struct __free_list **current = head; + while (*current != NULL) { + if (current[0]->ptr == ptr) { + *current = current[0]->next; + break; + } + current = ¤t[0]->next; + } +} +#define TRY_FREE(allocation) (\ + free(allocation),\ + __remove_free_list(&__allocations, allocation)\ +) +#define TRY_FREE_ALL() \ + while (__allocations != NULL) {\ + struct __free_list *current = __allocations;\ + free(current->ptr);\ + __allocations = current->next;\ + free(current);\ + } + +void __replace_free_list(struct __free_list **head, void *from, void *to) { + struct __free_list **current = head; + while (*current != NULL) { + if (current[0]->ptr == from) { + current[0]->ptr = to; + break; + } + current = ¤t[0]->next; + } +} +#define TRY_MEMREALLOC(reallocator, old, ...) (\ + __old_allocation = old,\ + __allocation = reallocator(old, __VA_ARGS__),\ + (__allocation == NULL ? (\ + longjmp(__try_fail_jmp_buf, 1)\ + ) : \ + __replace_free_list(&__allocations, __old_allocation, __allocation)\ + ),\ + __allocation\ +) +#define TRY_REALLOC(old, size) TRY_MEMREALLOC(realloc, old, size) + #endif diff --git a/convert_to_ints b/convert_to_ints new file mode 100755 index 0000000000000000000000000000000000000000..1335f0a01a6b4ec7bf604549676d72d4db6cd9eb GIT binary patch literal 13592 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 literal 0 HcmV?d00001 diff --git a/convert_to_ints.c b/convert_to_ints.c new file mode 100644 index 0000000..2094d56 --- /dev/null +++ b/convert_to_ints.c @@ -0,0 +1,110 @@ +#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_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) convert_to_numbers(char *line) { + ENABLE_RETURN(intmax_t_array); + ENABLE_TRY(); + TRY_TYPE(intmax_t); + + struct intmax_t_array numbers; + numbers.length = 0; + numbers.alloc_size = 64 * sizeof(intmax_t); + numbers.data = TRY_MALLOC(numbers.alloc_size * sizeof(intmax_t)); + + 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; + numbers.length++; + if(numbers.alloc_size / sizeof(intmax_t) < numbers.length) { + if(SIZE_MAX / 2 < numbers.alloc_size) { + TRY_FREE(numbers.data); + RETURN_NOTHING(); + } + numbers.alloc_size *= 2; + numbers.data = TRY_REALLOC(numbers.data, numbers.alloc_size); + } + 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; +}