From 001e3638fe992e8a4db0d3bd964fd045444c9f37 Mon Sep 17 00:00:00 2001 From: Isaac Shoebottom Date: Fri, 17 Nov 2023 12:40:31 -0400 Subject: [PATCH] Initial commit --- .idea/.gitignore | 8 +++ .idea/cmake.xml | 8 +++ .idea/foreach.iml | 2 + .idea/misc.xml | 4 ++ .idea/modules.xml | 8 +++ .idea/vcs.xml | 7 +++ CMakeLists.txt | 7 +++ README.md | 1 + foreach.h | 9 +++ test.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 211 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/cmake.xml create mode 100644 .idea/foreach.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 foreach.h create mode 100644 test.c diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/cmake.xml b/.idea/cmake.xml new file mode 100644 index 0000000..2ad2554 --- /dev/null +++ b/.idea/cmake.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/foreach.iml b/.idea/foreach.iml new file mode 100644 index 0000000..6d70257 --- /dev/null +++ b/.idea/foreach.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..79b3c94 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..84fde23 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..f245aa7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..44205ec --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.22) +project(foreach C) + +set(CMAKE_C_STANDARD 99) + +include_directories(.) +add_executable(foreach test.c) diff --git a/README.md b/README.md new file mode 100644 index 0000000..fd9241c --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Simple foreach C macro \ No newline at end of file diff --git a/foreach.h b/foreach.h new file mode 100644 index 0000000..5e88f6a --- /dev/null +++ b/foreach.h @@ -0,0 +1,9 @@ +#pragma once + +// Will determine the size of an array only if it is declared on the stack +#define foreach(type, item, array) \ + for (type* item = array; item < array + (sizeof(array) / sizeof(type)); item++) + +// Need to pass in the size of the array, since heap allocated arrays don't work with sizeof +#define foreach_p(type, item, array, size) \ + for (type* item = array; item < array + size; item++) diff --git a/test.c b/test.c new file mode 100644 index 0000000..6b0c08c --- /dev/null +++ b/test.c @@ -0,0 +1,157 @@ +// Ignore rand warning +#pragma clang diagnostic push +#pragma ide diagnostic ignored "cert-msc50-cpp" +#pragma ide diagnostic ignored "cert-msc51-cpp" + +#include +#include +#include +#include +#include "foreach.h" + +int rand_range(int min, int max) { + return rand() % (max - min + 1) + min; +} + +bool test_simpleArray() { + int arr[] = {1, 2, 3, 4, 5}; + + int test[5]; + int counter = 0; + foreach(int, item, arr) { + test[counter] = *item; + counter++; + } + + if (memcmp(arr, test, sizeof(arr)) == 0) { + return true; + } else { + return false; + } +} + +bool test_randomNumbers() { + int arr1[10]; + srand(0); + foreach(int, item, arr1) { + *item = rand_range(0, 100); + } + int arr2[10]; + srand(0); + for (int i = 0; i < sizeof(arr2) / sizeof(int); i++) { + arr2[i] = rand_range(0, 100); + } + if (memcmp(arr1, arr2, sizeof(arr1)) == 0) { + return true; + } else { + return false; + } +} + +bool test_simpleString() { + char *str = "Hello, World!"; + + // Plus one for the null terminator + char test[strlen(str) + 1]; + int counter = 0; + foreach_p(char, item, str, strlen(str) + 1) { + test[counter] = *item; + counter++; + } + + if (strcmp(str, test) == 0) { + return true; + } else { + return false; + } +} + + + +bool test_randomNumbersAsPointers() { + int arr1[10]; + srand(0); + foreach_p(int, item, arr1, sizeof(arr1) / sizeof(int)) { + *item = rand_range(0, 100); + } + int arr2[10]; + srand(0); + for (int i = 0; i < sizeof(arr2) / sizeof(int); i++) { + arr2[i] = rand_range(0, 100); + } + + if (memcmp(arr1, arr2, sizeof(arr1)) == 0) { + return true; + } else { + return false; + } +} + +bool test_randomNumbersOnHeap() { + int *arr1 = malloc(sizeof(int) * 10); + srand(0); + foreach_p(int, item, arr1, 10) { + *item = rand_range(0, 100); + } + int *arr2 = malloc(sizeof(int) * 10); + srand(0); + for (int i = 0; i < 10; i++) { + arr2[i] = rand_range(0, 100); + } + + bool result = memcmp(arr1, arr2, 10) == 0; + free(arr1); + free(arr2); + return result; +} + +bool test_stringOnHeap() { + char *str = malloc(sizeof(char) * 14); + strcpy(str, "Hello, World!"); + char *test = malloc(sizeof(char) * 14); + int counter = 0; + foreach_p(char, item, str, 14) { + test[counter] = *item; + counter++; + } + + bool result = strcmp(str, test) == 0; + free(str); + free(test); + return result; +} + +int main() { + void* foreach_functions[] = { + test_simpleArray, + test_randomNumbers, + }; + void* foreach_p_functions[] = { + test_simpleString, + test_randomNumbersAsPointers, + test_randomNumbersOnHeap, + test_stringOnHeap + }; + + printf("Foreach tests\n"); + for (int i = 0; i < sizeof(foreach_functions) / sizeof(void*); i++) { + bool result = ((bool (*)()) foreach_functions[i])(); + if (result) { + printf("Test %d passed\n", i); + } else { + printf("Test %d failed\n", i); + } + } + printf("Foreach_p tests\n"); + for (int i = 0; i < sizeof(foreach_p_functions) / sizeof(void*); i++) { + bool result = ((bool (*)()) foreach_p_functions[i])(); + if (result) { + printf("Test %d passed\n", i); + } else { + printf("Test %d failed\n", i); + } + } + + return EXIT_SUCCESS; +} +#pragma clang diagnostic pop \ No newline at end of file