From 1dd0f25ff8dbedb199c65e91d66cd6fb3a20740c Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sun, 12 Apr 2020 21:11:37 -0300 Subject: [PATCH] Added script that automatically generates code for code coverage --- autogen.py | 112 +++++++++++++++++++++++++++++++ tests/codecov/src/bidimap.c | 10 ++- tests/codecov/src/deque.c | 4 +- tests/codecov/src/hashmap.c | 10 ++- tests/codecov/src/hashset.c | 10 ++- tests/codecov/src/heap.c | 4 +- tests/codecov/src/intervalheap.c | 10 ++- tests/codecov/src/linkedlist.c | 4 +- tests/codecov/src/list.c | 4 +- tests/codecov/src/multimap.c | 10 ++- tests/codecov/src/multiset.c | 10 ++- tests/codecov/src/queue.c | 4 +- tests/codecov/src/sortedlist.c | 4 +- tests/codecov/src/stack.c | 4 +- tests/codecov/src/treemap.c | 4 +- tests/codecov/src/treeset.c | 4 +- 16 files changed, 145 insertions(+), 63 deletions(-) create mode 100644 autogen.py diff --git a/autogen.py b/autogen.py new file mode 100644 index 0000000..9bea336 --- /dev/null +++ b/autogen.py @@ -0,0 +1,112 @@ +# A script that automatically expands the macros for code coverage + +import os +import re +import time +import subprocess + +# Compiler settings +CC = 'gcc' +INCLUDE = '-I ./src' +# -E Only preprocessor +# -P No linemarkers +# -C Keep comments, except those inside macros (for UNIQUE_FLAG) +FLAGS = '-E -P -C' + +# Used to delimiter where the actual code starts and ends +# Used by regex +# Needs to be a valid C comment +UNIQUE_FLAG = '// C_MACRO_COLLECTIONS_CODE' + +# Temporary file used to expand the macros +TMP_FILE = 'main.c' + +# Output directory +OUTPUT_DIR = './tests/codecov/src' + +collections = [ + # type, header, pfx, sname, key, val + {'t': 'BIDIMAP', 'h': '"cmc/bidimap.h"', 'pfx': 'bm', 'sname': 'bidimap', 'key': 'size_t', 'val': 'size_t'}, + {'t': 'DEQUE', 'h': '"cmc/deque.h"', 'pfx': 'd', 'sname': 'deque', 'key': '', 'val': 'size_t'}, + {'t': 'HASHMAP', 'h': '"cmc/hashmap.h"', 'pfx': 'hm', 'sname': 'hashmap', 'key': 'size_t', 'val': 'size_t'}, + {'t': 'HASHSET', 'h': '"cmc/hashset.h"', 'pfx': 'hs', 'sname': 'hashset', 'key': '', 'val': 'size_t'}, + {'t': 'HEAP', 'h': '"cmc/heap.h"', 'pfx': 'h', 'sname': 'heap', 'key': '', 'val': 'size_t'}, + {'t': 'INTERVALHEAP', 'h': '"cmc/intervalheap.h"', 'pfx': 'ih', 'sname': 'intervalheap', 'key': '', 'val': 'size_t'}, + {'t': 'LINKEDLIST', 'h': '"cmc/linkedlist.h"', 'pfx': 'll', 'sname': 'linkedlist', 'key': '', 'val': 'size_t'}, + {'t': 'LIST', 'h': '"cmc/list.h"', 'pfx': 'l', 'sname': 'list', 'key': '', 'val': 'size_t'}, + {'t': 'MULTIMAP', 'h': '"cmc/multimap.h"', 'pfx': 'mm', 'sname': 'multimap', 'key': 'size_t', 'val': 'size_t'}, + {'t': 'MULTISET', 'h': '"cmc/multiset.h"', 'pfx': 'ms', 'sname': 'multiset', 'key': '', 'val': 'size_t'}, + {'t': 'QUEUE', 'h': '"cmc/queue.h"', 'pfx': 'q', 'sname': 'queue', 'key': '', 'val': 'size_t'}, + {'t': 'SORTEDLIST', 'h': '"cmc/sortedlist.h"', 'pfx': 'sl', 'sname': 'sortedlist', 'key': '', 'val': 'size_t'}, + {'t': 'STACK', 'h': '"cmc/stack.h"', 'pfx': 's', 'sname': 'stack', 'key': '', 'val': 'size_t'}, + {'t': 'TREEMAP', 'h': '"cmc/treemap.h"', 'pfx': 'tm', 'sname': 'treemap', 'key': 'size_t', 'val': 'size_t'}, + {'t': 'TREESET', 'h': '"cmc/treeset.h"', 'pfx': 'ts', 'sname': 'treeset', 'key': '', 'val': 'size_t'} +] + +# Create output directory +if not os.path.exists(OUTPUT_DIR): + os.makedirs(OUTPUT_DIR) + +for data in collections: + file = open(TMP_FILE, 'w') + + file.write( + f''' + #include {data['h']} + + {UNIQUE_FLAG} + + CMC_GENERATE_{data['t']}({data['pfx']}, {data['sname']}, {f'{data["key"]}, {data["val"]}' if data['key'] != '' else data['val']}) + + {UNIQUE_FLAG} + ''') + + file.flush() + file.close() + + result = subprocess.run(f'{CC} {FLAGS} {INCLUDE} {TMP_FILE}', stdout=subprocess.PIPE).stdout.decode('utf-8') + + # (?s) makes '.' match anything, even '\n' + match = re.search(fr'(?s){UNIQUE_FLAG}(?P.+){UNIQUE_FLAG}', result) + + if match is None: + os.remove(TMP_FILE) + print('Didn\'t match FLAG. Probably because compilation failed.') + exit(1) + + file = open(f'{OUTPUT_DIR}/{data["sname"]}.c', 'w') + + file.write(f'#include {data["h"]}\n{match.group("code")}') + + file.flush() + file.close() + + print(f'Generated {data["h"]: >20} -> {OUTPUT_DIR}/{data["sname"]}.c') + +# This seemed to be crashing +# subprocess.run(f'clang-format --style=file -i {OUTPUT_DIR}/*.c') + +# So I guess... it will have to be called from a temp Makefile... ugh +TMP_MAKE = 'temp_makefile' + +data = ''' +.PHONY: codecov FORCE + +codecov: FORCE +\tclang-format --style=file -i $(OUTPUT_DIR)/*.c + +FORCE: + +''' + +print(f'Creating temporary Makefile as {TMP_MAKE}') + +file = open(TMP_MAKE, 'w') +file.write(data) +file.flush() +file.close() + +subprocess.call(f'make -f {TMP_MAKE} codecov OUTPUT_DIR={OUTPUT_DIR} --always-make') + +os.remove(TMP_FILE) +os.remove(TMP_MAKE) diff --git a/tests/codecov/src/bidimap.c b/tests/codecov/src/bidimap.c index 5ed8ccc..ca182e7 100644 --- a/tests/codecov/src/bidimap.c +++ b/tests/codecov/src/bidimap.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_BIDIMAP(bm, bidimap, size_t, size_t) +#include "cmc/bidimap.h" struct bidimap { @@ -120,7 +118,7 @@ struct bidimap *bm_new(size_t capacity, double load, struct cmc_alloc_node *alloc = &cmc_alloc_node_default; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); - if (capacity >= 0xffffffffffffffff * load) + if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); @@ -156,7 +154,7 @@ struct bidimap *bm_new_custom(size_t capacity, double load, { if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); - if (capacity >= 0xffffffffffffffff * load) + if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); @@ -483,7 +481,7 @@ _Bool bm_resize(struct bidimap *_map_, size_t capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; - if (capacity >= 0xffffffffffffffff * _map_->load) + if (capacity >= 0xffffffffffffffffULL * _map_->load) { _map_->flag = cmc_flags.ERROR; return 0; diff --git a/tests/codecov/src/deque.c b/tests/codecov/src/deque.c index fca5eae..a7ca48b 100644 --- a/tests/codecov/src/deque.c +++ b/tests/codecov/src/deque.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_DEQUE(d, deque, size_t) +#include "cmc/deque.h" struct deque { diff --git a/tests/codecov/src/hashmap.c b/tests/codecov/src/hashmap.c index 3b7c22d..a68019f 100644 --- a/tests/codecov/src/hashmap.c +++ b/tests/codecov/src/hashmap.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_HASHMAP(hm, hashmap, size_t, size_t) +#include "cmc/hashmap.h" struct hashmap { @@ -111,7 +109,7 @@ struct hashmap *hm_new(size_t capacity, double load, struct cmc_alloc_node *alloc = &cmc_alloc_node_default; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); - if (capacity >= 0xffffffffffffffff * load) + if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); @@ -145,7 +143,7 @@ struct hashmap *hm_new_custom(size_t capacity, double load, { if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); - if (capacity >= 0xffffffffffffffff * load) + if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); @@ -462,7 +460,7 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; - if (capacity >= 0xffffffffffffffff * _map_->load) + if (capacity >= 0xffffffffffffffffULL * _map_->load) { _map_->flag = cmc_flags.ERROR; return 0; diff --git a/tests/codecov/src/hashset.c b/tests/codecov/src/hashset.c index af0f9b9..6643b11 100644 --- a/tests/codecov/src/hashset.c +++ b/tests/codecov/src/hashset.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_HASHSET(hs, hashset, size_t) +#include "cmc/hashset.h" struct hashset { @@ -101,7 +99,7 @@ struct hashset *hs_new(size_t capacity, double load, struct cmc_alloc_node *alloc = &cmc_alloc_node_default; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); - if (capacity >= 0xffffffffffffffff * load) + if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_val) return ((void *)0); @@ -133,7 +131,7 @@ struct hashset *hs_new_custom(size_t capacity, double load, { if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); - if (capacity >= 0xffffffffffffffff * load) + if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_val) return ((void *)0); @@ -367,7 +365,7 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity) goto success; if (_set_->capacity > capacity / _set_->load) goto success; - if (capacity >= 0xffffffffffffffff * _set_->load) + if (capacity >= 0xffffffffffffffffULL * _set_->load) { _set_->flag = cmc_flags.ERROR; return 0; diff --git a/tests/codecov/src/heap.c b/tests/codecov/src/heap.c index d60d9a3..9ec2186 100644 --- a/tests/codecov/src/heap.c +++ b/tests/codecov/src/heap.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_HEAP(h, heap, size_t) +#include "cmc/heap.h" struct heap { diff --git a/tests/codecov/src/intervalheap.c b/tests/codecov/src/intervalheap.c index f8ca2c8..846bccb 100644 --- a/tests/codecov/src/intervalheap.c +++ b/tests/codecov/src/intervalheap.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_INTERVALHEAP(ih, intervalheap, size_t) +#include "cmc/intervalheap.h" struct intervalheap { @@ -87,7 +85,7 @@ struct intervalheap *ih_new(size_t capacity, struct intervalheap_ftab_val *f_val) { struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || capacity == 0xffffffffffffffff) + if (capacity == 0 || capacity == 0xffffffffffffffffULL) return ((void *)0); if (!f_val) return ((void *)0); @@ -117,7 +115,7 @@ struct intervalheap *ih_new_custom(size_t capacity, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { - if (capacity == 0 || capacity == 0xffffffffffffffff) + if (capacity == 0 || capacity == 0xffffffffffffffffULL) return ((void *)0); if (!f_val) return ((void *)0); @@ -414,7 +412,7 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity) _heap_->flag = cmc_flags.INVALID; return 0; } - if (capacity == 0xffffffffffffffff) + if (capacity == 0xffffffffffffffffULL) { _heap_->flag = cmc_flags.ERROR; return 0; diff --git a/tests/codecov/src/linkedlist.c b/tests/codecov/src/linkedlist.c index c98b89a..30a564a 100644 --- a/tests/codecov/src/linkedlist.c +++ b/tests/codecov/src/linkedlist.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_LINKEDLIST(ll, linkedlist, size_t) +#include "cmc/linkedlist.h" struct linkedlist { diff --git a/tests/codecov/src/list.c b/tests/codecov/src/list.c index 6d9760d..92ea43c 100644 --- a/tests/codecov/src/list.c +++ b/tests/codecov/src/list.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_LIST(l, list, size_t) +#include "cmc/list.h" struct list { diff --git a/tests/codecov/src/multimap.c b/tests/codecov/src/multimap.c index 11c240f..90e135a 100644 --- a/tests/codecov/src/multimap.c +++ b/tests/codecov/src/multimap.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_MULTIMAP(mm, multimap, size_t, size_t) +#include "cmc/multimap.h" struct multimap { @@ -118,7 +116,7 @@ struct multimap *mm_new(size_t capacity, double load, struct cmc_alloc_node *alloc = &cmc_alloc_node_default; if (capacity == 0 || load <= 0) return ((void *)0); - if (capacity >= 0xffffffffffffffff * load) + if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); @@ -153,7 +151,7 @@ struct multimap *mm_new_custom(size_t capacity, double load, { if (capacity == 0 || load <= 0) return ((void *)0); - if (capacity >= 0xffffffffffffffff * load) + if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); @@ -632,7 +630,7 @@ _Bool mm_resize(struct multimap *_map_, size_t capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; - if (capacity >= 0xffffffffffffffff * _map_->load) + if (capacity >= 0xffffffffffffffffULL * _map_->load) { _map_->flag = cmc_flags.ERROR; return 0; diff --git a/tests/codecov/src/multiset.c b/tests/codecov/src/multiset.c index 67945b5..f96a0e4 100644 --- a/tests/codecov/src/multiset.c +++ b/tests/codecov/src/multiset.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_MULTISET(ms, multiset, size_t) +#include "cmc/multiset.h" struct multiset { @@ -116,7 +114,7 @@ struct multiset *ms_new(size_t capacity, double load, struct cmc_alloc_node *alloc = &cmc_alloc_node_default; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); - if (capacity >= 0xffffffffffffffff * load) + if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_val) return ((void *)0); @@ -149,7 +147,7 @@ struct multiset *ms_new_custom(size_t capacity, double load, { if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); - if (capacity >= 0xffffffffffffffff * load) + if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_val) return ((void *)0); @@ -449,7 +447,7 @@ _Bool ms_resize(struct multiset *_set_, size_t capacity) goto success; if (_set_->capacity > capacity / _set_->load) goto success; - if (capacity >= 0xffffffffffffffff * _set_->load) + if (capacity >= 0xffffffffffffffffULL * _set_->load) { _set_->flag = cmc_flags.ERROR; return 0; diff --git a/tests/codecov/src/queue.c b/tests/codecov/src/queue.c index 46bfc2c..dde7ec5 100644 --- a/tests/codecov/src/queue.c +++ b/tests/codecov/src/queue.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_QUEUE(q, queue, size_t) +#include "cmc/queue.h" struct queue { diff --git a/tests/codecov/src/sortedlist.c b/tests/codecov/src/sortedlist.c index 76f1558..f3c9d00 100644 --- a/tests/codecov/src/sortedlist.c +++ b/tests/codecov/src/sortedlist.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_SORTEDLIST(sl, sortedlist, size_t) +#include "cmc/sortedlist.h" struct sortedlist { diff --git a/tests/codecov/src/stack.c b/tests/codecov/src/stack.c index b136c32..21ad368 100644 --- a/tests/codecov/src/stack.c +++ b/tests/codecov/src/stack.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_STACK(s, stack, size_t) +#include "cmc/stack.h" struct stack { diff --git a/tests/codecov/src/treemap.c b/tests/codecov/src/treemap.c index 458b60f..eb552da 100644 --- a/tests/codecov/src/treemap.c +++ b/tests/codecov/src/treemap.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_TREEMAP(tm, treemap, size_t, size_t) +#include "cmc/treemap.h" struct treemap { diff --git a/tests/codecov/src/treeset.c b/tests/codecov/src/treeset.c index b54ac6c..1a348c2 100644 --- a/tests/codecov/src/treeset.c +++ b/tests/codecov/src/treeset.c @@ -1,6 +1,4 @@ -#include - -// CMC_GENERATE_TREESET(ts, treeset, size_t) +#include "cmc/treeset.h" struct treeset {