├── .github └── workflows │ └── c-cpp.yml ├── Makefile ├── README.md ├── TODO ├── docs ├── Makefile ├── array.md ├── char.md ├── comparison.md ├── compiler.md ├── cslist.md ├── debug.md ├── deque.md ├── dlist.md ├── dynamic_array.md ├── dynamic_stack.md ├── exceptions.md ├── generic_x.md ├── hash_table.md ├── math.md ├── meta.md ├── misc.md ├── object_api.md ├── objects.md ├── objects_api.md ├── objects_class.md ├── objects_code.md ├── objects_details.md ├── objects_examples.md ├── objects_implementing.md ├── objects_introduction.md ├── objects_json.md ├── objects_restrictions.md ├── objects_signals.md ├── objects_wobject.md ├── pointer.md ├── pp_char.md ├── pp_math.md ├── seq.md ├── slist.md ├── sorting.md ├── string.md ├── test.md ├── test_x.md └── tree.md ├── examples ├── Makefile ├── array │ ├── Makefile │ ├── array_for_each.c │ ├── array_get_size.c │ ├── deque.c │ ├── dynamic_array.c │ ├── dynamic_stack.c │ ├── hash_table.c │ └── move.c ├── char │ ├── Makefile │ └── to_char.c ├── exceptions │ ├── Makefile │ └── try.c ├── list │ ├── Makefile │ ├── clist.c │ ├── dlist.c │ └── slist.c ├── math │ ├── Makefile │ ├── min.c │ └── sign.c ├── meta │ ├── Makefile │ └── stringize.c ├── objects │ ├── Makefile │ ├── html │ │ ├── Makefile │ │ ├── array.c │ │ ├── array.h │ │ ├── array_class.h │ │ ├── attr_tags.h │ │ ├── classes_declare.h │ │ ├── cond.c │ │ ├── cond.h │ │ ├── cond_class.h │ │ ├── css_elem.c │ │ ├── css_elem.h │ │ ├── css_elem_class.h │ │ ├── css_selector.c │ │ ├── css_selector.h │ │ ├── css_selector_class.h │ │ ├── dom_list.c │ │ ├── dom_list.h │ │ ├── dom_list_class.h │ │ ├── dom_string.c │ │ ├── dom_string.h │ │ ├── dom_string_class.h │ │ ├── html.c │ │ ├── html.h │ │ ├── html_api.h │ │ ├── html_attr.c │ │ ├── html_attr.h │ │ ├── html_attr_class.h │ │ ├── html_class.h │ │ ├── html_elem.c │ │ ├── html_elem.h │ │ ├── html_elem_class.h │ │ ├── html_tags.h │ │ ├── js_elem.c │ │ ├── js_elem.h │ │ ├── js_elem_class.h │ │ ├── model.c │ │ ├── model.h │ │ ├── model_class.h │ │ ├── source │ │ ├── test.c │ │ ├── var_double.c │ │ ├── var_double.h │ │ ├── var_double_class.h │ │ ├── var_int.c │ │ ├── var_int.h │ │ └── var_int_class.h │ ├── point │ │ ├── Makefile │ │ ├── classes.h │ │ ├── classes_declare.h │ │ ├── colored_point.c │ │ ├── colored_point.h │ │ ├── colored_point3d.c │ │ ├── colored_point3d.h │ │ ├── colored_point3d_class.h │ │ ├── colored_point_class.h │ │ ├── owner.c │ │ ├── owner.h │ │ ├── owner_class.h │ │ ├── point.c │ │ ├── point.h │ │ ├── point_class.h │ │ ├── source │ │ ├── test.c │ │ └── uml.h │ ├── signals │ │ ├── Makefile │ │ ├── classes_declare.h │ │ ├── point.c │ │ ├── point.h │ │ ├── point_class.h │ │ ├── source │ │ └── test.c │ └── vechiles │ │ ├── Aircraft.c │ │ ├── Bike.c │ │ ├── Car.c │ │ ├── DieselEngine.c │ │ ├── Engine.c │ │ ├── JetEngine.c │ │ ├── Makefile │ │ ├── MotorVehicle.c │ │ ├── README.md │ │ ├── Vehicle.c │ │ ├── classes.wobject │ │ ├── source │ │ ├── test.c │ │ └── vehicles.h ├── sorting │ ├── Makefile │ └── variadic_testing.c ├── tree │ ├── Makefile │ └── tree.c └── x │ ├── Makefile │ ├── case.c │ ├── colors.h │ ├── enum.c │ ├── string_name.c │ ├── struct.c │ └── value_array.c ├── test ├── Makefile └── wondermacros.c ├── tools ├── api_tool.pl ├── cat.pl ├── stringize.pl └── wobject └── wondermacros ├── README.md ├── all.h ├── array ├── all.h ├── deque.h ├── dynamic_array.h ├── dynamic_stack.h ├── for_each.h ├── for_each_reversed.h ├── get_size.h ├── hash_table.h ├── move_left.h └── move_right.h ├── binding ├── uml.h └── x │ └── uml.h ├── comparison ├── all.h ├── byte_compare.h └── is_any_of.h ├── configs ├── array_collection.h ├── compare.h ├── default_allocation.h └── stack │ ├── README.md │ ├── dynamic_alloca.h │ ├── dynamic_heap_array.h │ └── static_array.h ├── debug └── debug.h ├── exceptions ├── default_policy.h └── exceptions.h ├── functions ├── README.md ├── list_length.h ├── list_reel_to_last.h ├── log2.h └── round_up_pow2.h ├── included └── mp.h ├── list ├── all.h ├── cslist.h ├── dlist.h └── slist.h ├── math ├── abs.h ├── all.h ├── for_ceiling_pow2.h ├── log2.h ├── max.h ├── min.h ├── sign.h └── uint_average.h ├── meta ├── after.h ├── all.h ├── before.h ├── cat.h ├── cat_inner.h ├── cat_outer.h ├── declare.h ├── finally.h ├── id.h ├── label.h ├── pp_pow2.h ├── stringize.h ├── stringize_to_variadic.h ├── stringize_with_comma.h ├── variadic_rest_n.h └── wrap.h ├── misc ├── all.h ├── struct_init.h ├── struct_new.h └── unused.h ├── objects ├── api.h ├── json │ ├── bool.c │ ├── boolean.c │ ├── char.c │ ├── double.c │ ├── dynamic_array_object.c │ ├── float.c │ ├── int.c │ ├── int64.c │ ├── int_array_2.c │ ├── long_double.c │ ├── object.c │ ├── string.c │ ├── types.h │ ├── unsigned.c │ └── unsigned64.c ├── meta.h ├── object.h ├── object_name.h └── x │ ├── README.md │ ├── class_declare.h │ ├── class_end.h │ ├── class_instance.h │ ├── class_start.h │ ├── class_struct.h │ ├── dup.h │ ├── forward_declare.h │ ├── free.h │ ├── instance_struct.h │ ├── method_forward_declares.h │ ├── method_typedefs.h │ ├── new.h │ └── to_json.h ├── pointer ├── all.h ├── byte_offset.h ├── container_of.h ├── for_aligned_ptr.h ├── hidden_of.h ├── ref_void_ptr.h ├── tagged.h ├── values_as_array.h └── variadic_to_refs.h ├── pp_char ├── all.h ├── charseq.h ├── to_char.h ├── to_int.h ├── tolower.h └── toupper.h ├── pp_math ├── all.h ├── decompose.h ├── even.h ├── is_prime.h ├── max.h ├── median.h ├── min.h ├── odd.h └── pow.h ├── seq ├── all.h ├── for_each_combination.h ├── for_each_permutation.h ├── max.h ├── median.h ├── min.h ├── sort.h └── swap.h ├── sorting ├── all.h ├── numeric_cmp.h ├── pp_sort.h ├── swap.h ├── variadic_sort.h └── variadic_testing.h ├── string ├── all.h └── for_string_as_uint.h ├── test └── test.h ├── tree ├── all.h └── for_each.h └── x ├── case.h ├── code.h ├── enum.h ├── string_name.h ├── struct.h ├── struct_fields.h ├── unit_test.h └── value_array.h /.github/workflows/c-cpp.yml: -------------------------------------------------------------------------------- 1 | name: C/C++ CI 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: add boost 17 | run: sudo apt-get install -y libboost-all-dev 18 | - name: make clean 19 | run: make clean 20 | - name: make 21 | run: make 22 | - name: run tests 23 | run: make check 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DESTDIR=/usr/include 2 | 3 | all: 4 | cd examples && make all 5 | cd test && make all 6 | cd docs && make all 7 | 8 | check: 9 | ./test/wondermacros 10 | 11 | install: 12 | cp -r wondermacros $(DESTDIR) 13 | cp -r tools $(DESTDIR)/wondermacros 14 | 15 | clean: 16 | cd examples && make clean 17 | cd test && make clean 18 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | TODO: 2 | ===== 3 | Objects 4 | * Add automatic array dimensions in JSON 5 | * Add W_OBJECT_SET(o,property,string) and W_OBJECT_SET(o,string) 6 | 7 | Data Structures 8 | * Add heap 9 | * Add Avl-tree 10 | 11 | W_HIDDEN_OF 12 | * Fix alignment issues 13 | 14 | Other 15 | * Add full test coverage 16 | * Improve docs 17 | * Add configuration macros to docs 18 | * Add examples 19 | 20 | Tests 21 | * move_right 22 | * for_each 23 | * for_each_reversed 24 | * variadic_testing 25 | * pow 26 | * tolower / toupper 27 | * to_int 28 | * to_char 29 | * charseq_to_string 30 | * charseq_to_int 31 | * charseq_tolower 32 | * charseq_toupper 33 | * variadic_rest 34 | 35 | * remove pp_pow2 (meta) 36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/comparison.md: -------------------------------------------------------------------------------- 1 | ## Comparison 2 | 3 | ### W_BYTE_COMPARE(buf,...) 4 | #### Arguments 5 | ```C 6 | buf a buffer (or a string) to match 7 | ... variadic number of bytes (or characters) 8 | ``` 9 | #### Description 10 | Use W_BYTE_COMPARE to test if a given buffer contains given bytes. If the buffer is not \0-terminated, it must be large enough for testing. 11 | 12 | ### W_IS_ANY_OF(value,...) 13 | #### Arguments 14 | ```C 15 | value a value to be tested 16 | ... variadic number of values 17 | ``` 18 | #### Description 19 | Use W_IS_ANY_OF to test if a given value is equal to any of the given other values. 20 | -------------------------------------------------------------------------------- /docs/compiler.md: -------------------------------------------------------------------------------- 1 | ## Compiler Tools 2 | 3 | ### W_BYTE_OFFSET(ptr1,ptr2) 4 | #### Arguments 5 | ```C 6 | ptr1 a pointer 7 | ptr2 a pointer 8 | ``` 9 | #### Description 10 | Use W_BYTE_OFFSET to count the offset of two pointers. The offset is negative if ptr1 is before ptr2. 11 | 12 | ### W_HIDDEN_CONTAINER_OF(ptr,T) 13 | #### Arguments 14 | ```C 15 | ptr a pointer to a structure having a hidden header. 16 | T type of the hidden header. 17 | ``` 18 | #### Description 19 | Use W_HIDDEN_CONTAINER_OF to get a pointer to the actual container of on object having a hidden header. 20 | 21 | ### W_HIDDEN_OF(ptr,T,member) 22 | #### Arguments 23 | ```C 24 | ptr a pointer to a structure having a hidden header. 25 | T type of the hidden header. 26 | member member field name of the header. 27 | ``` 28 | #### Description 29 | Use W_HIDDEN_OF to get a value of a field in the hidden header of a structure. 30 | 31 | ### W_REF_VOID_PTR(ptr,offset) 32 | #### Arguments 33 | ```C 34 | ptr a pointer A pointer to be referenced by an offset. 35 | offset an offset An offset in bytes. 36 | ``` 37 | #### Description 38 | Use W_REF_VOID_PTR to reference a void pointer using an offset in bytes. 39 | 40 | ### W_UNUSED(id) 41 | #### Arguments 42 | ```C 43 | id identifier name The name of unused identifier. 44 | ``` 45 | #### Description 46 | Use W_UNUSED to kill a warning if an identifier is unused. 47 | -------------------------------------------------------------------------------- /docs/cslist.md: -------------------------------------------------------------------------------- 1 | ## Singly-Linked Circular List 2 | 3 | ### W_CSLIST_FOR_EACH(T,node,list) 4 | #### Arguments 5 | ```C 6 | T a type name (the type of the list nodes) 7 | node a free identifier name 8 | list a list to be traversed 9 | ``` 10 | #### Description 11 | Use W_CSLIST_FOR_EACH to traverse all elements in a circular list. 12 | #### Notes 13 | Redefine W_CSLIST_FIELD_NAME to reset the link name (defaults to 'next'). 14 | 15 | ### W_CSLIST_FOR_EACH_NAMED(T,next,node,list) 16 | #### Arguments 17 | ```C 18 | T a type name (the type of the list nodes) 19 | next a member field name of the next link 20 | node a free identifier name 21 | list a list to be traversed 22 | ``` 23 | #### Description 24 | Use W_CSLIST_FOR_EACH_NAMED to traverse all elements in a circular list. 25 | 26 | ### W_CSLIST_PREPEND(T,self,list) 27 | #### Arguments 28 | ```C 29 | T a type name (the type of the list nodes) 30 | self a list to be modified 31 | list a list to be prepended 32 | ``` 33 | #### Description 34 | Use W_CSLIST_PREPEND to prepend a circular list to another circular list. 35 | 36 | ### W_CSLIST_PREPEND_NAMED(T,self,list) 37 | #### Arguments 38 | ```C 39 | T a type name (the type of the list nodes) 40 | next a member field name of the next link 41 | self a list to be modified 42 | list a list to be prepended 43 | ``` 44 | #### Description 45 | Use W_CSLIST_PREPEND_NAMED to prepend a circular list to another circular list. 46 | 47 | ### W_CSLIST_APPEND(T,self,list) 48 | #### Arguments 49 | ```C 50 | T a type name (the type of the list nodes) 51 | self a list to be modified 52 | list a list to be prepended 53 | ``` 54 | #### Description 55 | Use W_CSLIST_APPEND to append a circular list to another circular list. 56 | 57 | ### W_CSLIST_APPEND_NAMED(T,self,list) 58 | #### Arguments 59 | ```C 60 | T a type name (the type of the list nodes) 61 | next a member field name of the next link 62 | self a list to be modified 63 | list a list to be prepended 64 | ``` 65 | #### Description 66 | Use W_CSLIST_APPEND_NAMED to append a circular list to another circular list. 67 | -------------------------------------------------------------------------------- /docs/debug.md: -------------------------------------------------------------------------------- 1 | ## Debugging 2 | 3 | ### W_DEBUG(fmt,...) 4 | #### Arguments 5 | ```C 6 | fmt a format (like printf) 7 | ... optional arguments 8 | ``` 9 | #### Description 10 | Use W_DEBUG to write a debug message. 11 | #### Notes 12 | Redefine W_DEBUG_FUNC, W_DEBUG_FILE and W_DEBUG_APPEND_NL change the default behaviour. 13 | -------------------------------------------------------------------------------- /docs/dlist.md: -------------------------------------------------------------------------------- 1 | ## Doubly-Linked List 2 | 3 | ### W_DLIST_FOR_EACH(T,node,list) 4 | #### Arguments 5 | ```C 6 | T a type name (the type of the list nodes) 7 | node a free identifier name 8 | list a list to be traversed 9 | ``` 10 | #### Description 11 | Use W_DLIST_FOR_EACH to traverse all elements in a doubly-linked list. 12 | #### Notes 13 | Redefine W_DLIST_FIELD_NEXT and W_DLIST_FIELD_PREV to reset the link name (defaults to 'next'). 14 | 15 | ### W_DLIST_FOR_EACH_NAMED(T,prev,next,node,list) 16 | #### Arguments 17 | ```C 18 | T a type name (the type of the list nodes) 19 | prev a member field name of the previous link 20 | next a member field name of the next link 21 | node a free identifier name 22 | list a list to be traversed 23 | ``` 24 | #### Description 25 | Use W_DLIST_FOR_EACH_NAMED to traverse all elements in a doubly-linked list. 26 | 27 | ### W_DLIST_PREPEND(T,self,list) 28 | #### Arguments 29 | ```C 30 | T a type name (the type of the list nodes) 31 | self a list to be modified 32 | list a list to be prepended 33 | ``` 34 | #### Description 35 | Use W_DLIST_PREPEND to prepend a list to another doubly-linked list. 36 | 37 | ### W_DLIST_PREPEND_NAMED(T,self,list) 38 | #### Arguments 39 | ```C 40 | T a type name (the type of the list nodes) 41 | next a member field name of the next link 42 | self a list to be modified 43 | list a list to be prepended 44 | ``` 45 | #### Description 46 | Use W_DLIST_PREPEND_NAMED to prepend a list to another doubly-linked list. 47 | 48 | ### W_DLIST_APPEND(T,self,list) 49 | #### Arguments 50 | ```C 51 | T a type name (the type of the list nodes) 52 | self a list to be modified 53 | list a list to be prepended 54 | ``` 55 | #### Description 56 | Use W_DLIST_APPEND to append a list to another doubly-linked list. 57 | 58 | ### W_DLIST_APPEND_NAMED(T,self,list) 59 | #### Arguments 60 | ```C 61 | T a type name (the type of the list nodes) 62 | next a member field name of the next link 63 | self a list to be modified 64 | list a list to be prepended 65 | ``` 66 | #### Description 67 | Use W_DLIST_APPEND_NAMED to append a list to another doubly-linked list. 68 | -------------------------------------------------------------------------------- /docs/exceptions.md: -------------------------------------------------------------------------------- 1 | ## Exceptions 2 | 3 | ### W_EXCEPTION_STACK_DECLARE(size) 4 | #### Arguments 5 | ```C 6 | size the size of the exception stack, e.g. 64 7 | ``` 8 | #### Description 9 | Use W_EXCEPTION_STACK_DECLARE to declare an exception stack. Use it in the global scope (outside any function) in a C file. Use also in a header with extern prefix and with emphty size argument. 10 | 11 | ### W_EXCEPTION_RESET_LAST 12 | #### Description 13 | Use W_EXCEPTION_RESET_LAST to clear all data related to last exception. with extern prefix and with emphty size argument. 14 | 15 | ### W_TRY 16 | #### Description 17 | Use W_TRY to run code which may cause exceptions. Use W_THROW to throw an exception inside W_TRY block. Use W_CATCH or W_CATCH_ALL to catch exceptions after W_TRY block. 18 | #### Notes 19 | Exception stack must be declared using W_EXCEPTION_STACK_DECLARE. 20 | 21 | ### W_THROW(err[,...]) 22 | #### Arguments 23 | ```C 24 | err an integer other than zero 25 | ``` 26 | #### Description 27 | Use W_THROW to throw an exception inside W_TRY block. 28 | 29 | ### W_CATCH(err) 30 | #### Arguments 31 | ```C 32 | err an integer other than zero 33 | ``` 34 | #### Description 35 | Use W_CATCH to catch exceptions of a given error class. It will clear the last exception from memory so another catch following will not trigger. 36 | 37 | ### W_CATCH_ALL 38 | #### Description 39 | Use W_CATCH_ALL to catch exceptions of all kinds. It will clear the last exception from memory so another catch following will not trigger. 40 | 41 | ### W_EXCEPTION_FPRINTF(out) 42 | #### Description 43 | Use W_EXCEPTION_FPRINTF to print an error message of latest exception into a file (e.g. stderr). 44 | -------------------------------------------------------------------------------- /docs/hash_table.md: -------------------------------------------------------------------------------- 1 | ## Hash Table 2 | 3 | ### W_HASH_TABLE_GET_SIZE(H) 4 | #### Arguments 5 | ```C 6 | H a pointer to a hash table. 7 | ``` 8 | #### Description 9 | Use W_HASH_TABLE_GET_SIZE to get the number of mappings in a hash table. 10 | 11 | ### W_HASH_TABLE_INIT(H,pow2_size) 12 | #### Arguments 13 | ```C 14 | H a pointer to a hash table. 15 | pow2_size size of the hash table (an exponent of power two) 16 | ``` 17 | #### Description 18 | Use W_HASH_TABLE_FREE to free a hash table. 19 | 20 | ### W_HASH_TABLE_FOR_EACH(T,map,H) 21 | #### Arguments 22 | ```C 23 | T type name of a hash mapping 24 | map a free identifier for mappings 25 | H a pointer to a hash table 26 | ``` 27 | #### Description 28 | Use W_HASH_TABLE_FOR_EACH to iterate all mappings in a hash table. 29 | 30 | ### W_HASH_TABLE_PUSH(T,H,Key,Value) 31 | #### Arguments 32 | ```C 33 | T type name of a hash mapping 34 | H a pointer to a hash table. 35 | Key a key to be mapped 36 | Value a value to be mapped 37 | ``` 38 | #### Description 39 | Use W_HASH_TABLE_FREE to free a hash table. 40 | 41 | ### W_HASH_TABLE_FOR_EACH_MATCH(T,match,H,Key) 42 | #### Arguments 43 | ```C 44 | T type name of a hash mapping 45 | match a free variable 46 | H a pointer to a hash table. 47 | Key key to be matched 48 | ``` 49 | #### Description 50 | Use W_HASH_TABLE_FREE to free a hash table. 51 | 52 | ### W_HASH_TABLE_FREE(H) 53 | #### Arguments 54 | ```C 55 | H a pointer to a hash table. 56 | ``` 57 | #### Description 58 | Use W_HASH_TABLE_FREE to free a hash table. 59 | 60 | ### W_HASH_TABLE_REMOVE(H,Key,matched) 61 | #### Arguments 62 | ```C 63 | H a pointer to a hash table. 64 | Key key to be removed 65 | matched integer variable to be set if a mapping is removed 66 | ``` 67 | #### Description 68 | Use W_HASH_TABLE_FREE to free a hash table. 69 | -------------------------------------------------------------------------------- /docs/math.md: -------------------------------------------------------------------------------- 1 | ## Mathematics 2 | 3 | ### W_ABS(a) 4 | #### Arguments 5 | ```C 6 | a a value 7 | ``` 8 | #### Description 9 | Use W_ABS to get the absolute value. 10 | #### Notes 11 | Redefine W_GE, W_ZERO and W_NEG to change the default operators. 12 | 13 | ### W_FOR_CEILING_POW2(T,pow2,a) 14 | #### Arguments 15 | ```C 16 | T an unsigned type name (e.g. `unsigned` or `uint64_t`) 17 | pow2 a free variable name to be assigned 18 | a a value 19 | ``` 20 | #### Description 21 | Use W_FOR_CEILING_POW2 to round up to next power of two. 22 | 23 | ### W_LOG2(a) 24 | #### Arguments 25 | ```C 26 | a a value (32-bit unsigned) 27 | ``` 28 | #### Description 29 | Use W_LOG2 to get the logarithm of 2. 30 | 31 | ### W_MAX(...) 32 | #### Arguments 33 | ```C 34 | ... values to be compared (from one up to four) 35 | ``` 36 | #### Description 37 | Use W_MAX to get the maximum of given values. 38 | 39 | ### W_MIN(...) 40 | #### Arguments 41 | ```C 42 | ... values to be compared (from one up to four) 43 | ``` 44 | #### Description 45 | Use W_MIN to get the minimum of given values. 46 | #### Notes 47 | Redefine W_LE, W_ZERO and W_COMPARE to change the default operators. 48 | 49 | ### W_SIGN(x) 50 | #### Arguments 51 | ```C 52 | x a numeric value 53 | ``` 54 | #### Description 55 | Use W_SIGN to get the sign of a number, i.g. -1 for negative, 0 for zero, and 1 for positive numbers. 56 | 57 | ### W_UINT_AVERAGE_FLOOR(x, y) 58 | #### Arguments 59 | ```C 60 | x an unsigned numeric value 61 | y an unsigned numeric value 62 | ``` 63 | #### Description 64 | Use W_UINT_AVERAGE_FLOOR to get the average (floor) of two unsigned integers without overflow or division operator. 65 | 66 | ### W_UINT_AVERAGE_CEIL(x, y) 67 | #### Arguments 68 | ```C 69 | x an unsigned numeric value 70 | y an unsigned numeric value 71 | ``` 72 | #### Description 73 | Use W_UINT_AVERAGE_CEIL to get the average (ceil) of two unsigned integers without overflow or division operator. 74 | -------------------------------------------------------------------------------- /docs/misc.md: -------------------------------------------------------------------------------- 1 | ## Misc 2 | 3 | ### W_STRUCT_INIT(T,ptr,...) 4 | #### Arguments 5 | ```C 6 | T a type name 7 | ptr a pointer to newly allocated memory of size T at minimum 8 | ... initial values for the structure (e.g. '.x=1, .y=2' or just '1,2') 9 | ``` 10 | #### Description 11 | Use W_STRUCT_INIT to initialize a newly allocated structure. 12 | 13 | ### W_STRUCT_NEW(T,ptr,...) 14 | #### Arguments 15 | ```C 16 | T a type name 17 | ... initial values for the structure (e.g. '.x=1, .y=2' or just '1,2') 18 | ``` 19 | #### Description 20 | Use W_STRUCT_NEW to allocate and initialize a structure. 21 | 22 | ### W_UNUSED(id) 23 | #### Arguments 24 | ```C 25 | id a name of unused identifier. 26 | ``` 27 | #### Description 28 | Use W_UNUSED to kill a warning if an identifier is unused. 29 | -------------------------------------------------------------------------------- /docs/objects_code.md: -------------------------------------------------------------------------------- 1 | ## How to expand the header file of a class 2 | 3 | What we have now is just the plain definitions of two classes. In order to compile code we need to 4 | get the necessary type definitions and forward declarations in C. And then actually implement the 5 | class. Typically classess refer to each other so they need forward declarations of each other before 6 | the types are actually declared. In our simple example this is not actually needed but we will cover it 7 | here anyway. In order to get the forward declarations we write the following into `classes_declare.h': 8 | 9 | ```C 10 | #ifndef __CLASSES_DECLARE_H 11 | #define __CLASSES_DECLARE_H 12 | 13 | #include "point_class.h" 14 | #include 15 | 16 | #include "colored_point_class.h" 17 | #include 18 | 19 | #endif 20 | ``` 21 | 22 | Next we create `point.h`. 23 | 24 | ```C 25 | #ifndef __POINT_H 26 | #define __POINT_H 27 | 28 | #include "classes_declare.h" 29 | 30 | #include "point_class.h" 31 | #include 32 | 33 | #endif 34 | ``` 35 | 36 | In the subclass's header in `colored_point.h` we must include `point.h`. These header may include 37 | other declarations if they are needed in the implementations. 38 | 39 | ```C 40 | #ifndef __COLORED_POINT_H 41 | #define __COLORED_POINT_H 42 | 43 | #include "classes_declare.h" 44 | 45 | #include "point.h" 46 | 47 | #include "colored_point_class.h" 48 | #include 49 | 50 | #endif 51 | ``` 52 | -------------------------------------------------------------------------------- /docs/objects_examples.md: -------------------------------------------------------------------------------- 1 | ### Source code and other examples 2 | 3 | The source code of the previous example can be found 4 | [here](https://github.com/plainC/wondermacros/tree/master/examples/objects/point). There is 5 | [another example](https://github.com/plainC/wondermacros/tree/master/examples/objects/html) which 6 | implements a simple web content generation classes (HTML elements, HTML attributes, strings and simple string templates). 7 | 8 | See also [Web Elements](https://github.com/plainC/web_elements). 9 | 10 | ```C 11 | int main() 12 | { 13 | int v=42; 14 | double e=2.744; 15 | double* prices = NULL; 16 | int has_prices = 1; 17 | 18 | W_DYNAMIC_ARRAY_PUSH(prices, 2.12, 3.14, 6.32, 4.24, 7.44); 19 | 20 | struct model* model = W_NEW(model); 21 | W_CALL(model,bind_ptr)("has_prices",0,&has_prices); 22 | W_CALL(model,bind_ptr)("a",0,&v); 23 | W_CALL(model,bind_ptr)("e",1,&e); 24 | W_CALL(model,bind_ptr)("prices",1,prices); 25 | 26 | 27 | struct html_elem* doc = DOC( 28 | DOCTYPE, 29 | htmlHTML( attrID(_("FooPoro")), attrLANG(_("fi-FI")), attrDIR(_("LTR")), attrCLASS(_("Public")), 30 | htmlHEAD( 31 | htmlMETA(attrCHARSET(_("utf-8"))), 32 | htmlMETA(attrHTTP_EQUIV(_("X-UA-Compatible")), attrCONTENT(_("IE=Edge,chrome=1"))), 33 | htmlMETA(attrNAME(_("viewport")), attrCONTENT(_("width=device-width, initial-scale=1"))), 34 | htmlBASE(attrHREF(_("https://local.com/"))), 35 | htmlTITLE(_("First page")) 36 | ), 37 | htmlBODY( 38 | css(cssTYPE_SELECTOR("p"),"width:9;"), 39 | ), 40 | INT_VAR("a"), DOUBLE_VAR("e", .format="%.2%%"), COND("has_prices", ARRAY("prices", htmlLI(htmlB(DOUBLE_VAR("@elem", .format="$%.2f"))))) 41 | ) 42 | ); 43 | 44 | 45 | char buffer[1024]; 46 | int pos=0; 47 | 48 | struct view_context context; 49 | context.buffer = buffer; 50 | context.size = 1024; 51 | context.pos = 0; 52 | 53 | W_CALL(doc,to_string)(model, &context); 54 | printf("%s\n", buffer); 55 | } 56 | ``` 57 | 58 | -------------------------------------------------------------------------------- /docs/objects_implementing.md: -------------------------------------------------------------------------------- 1 | ### How to implement a class 2 | 3 | In order to implement the class we will first include the header file of the class, i.g. `point.h`. 4 | The next step is to include the class file `point_class.h` and the X-macro which begins the class 5 | implementation. The implementation is written between two X-macros. The file must end to another 6 | X-macro inclusion. See an example bellow. 7 | 8 | ```C 9 | #ifndef WDEBUG_EXPAND 10 | # include 11 | # include 12 | #endif 13 | 14 | 15 | /* Include class header. */ 16 | #include "point.h" 17 | 18 | /* Begin class implementation. */ 19 | #include "point_class.h" 20 | #include 21 | 22 | 23 | CONSTRUCT(Point) /* self */ 24 | { 25 | W_CALL(self,ping)("constructed"); 26 | W_UNUSED(self); 27 | } 28 | 29 | FINALIZE(Point) /* self */ 30 | { 31 | W_UNUSED(self); 32 | } 33 | 34 | METHOD(Point,private,void,ping,(const char* message)) 35 | { 36 | printf("Message: %s\n", message); 37 | } 38 | 39 | 40 | METHOD(Point,public,int,move_up,(int steps)) 41 | { 42 | if (self->y - steps < 0) { 43 | W_CALL(self,ping)("Hits the wall"); 44 | self->y = 0; 45 | return 1; 46 | } 47 | 48 | self->y -= steps; 49 | return 0; 50 | } 51 | 52 | METHOD(Point,public,int,move_left,(int steps)) 53 | { 54 | self->x -= steps; 55 | return 0; 56 | } 57 | 58 | METHOD(Point,public,void,draw) 59 | { 60 | printf("point at %d,%d\n", self->x, self->y); 61 | } 62 | 63 | 64 | #include 65 | ``` 66 | 67 | A constructor is provided in a block after `CONSTRUCT` macro, and a destructor in a similar manner after 68 | `FINALIZE`. If you need to call the constructor of a superclass, you can use `W_CALL_CONSTRUCT` macro. 69 | For example, to call the constructor of Point in Point3D, add `W_CALL_CONSTRUCT(Point)` into the body 70 | of the constructor of `Point3D`. To call destructor in finalize block, use `W_CALL_FINALIZE(class_name)`. 71 | 72 | If your class does not need a constructor, add `#define NO_CONSTRUCT` into the class definition file. 73 | To notify missing destructor, define `#define NO_DESTRUCT`. 74 | 75 | Each method is implemented using `METHOD` macro. Note that the name of the class must be 76 | repeated in each method. The object in all methods including constructor and destructor can be accessed in `self`. 77 | A method of an object can be called using `W_CALL` or `W_CALL_VOID`. 78 | 79 | -------------------------------------------------------------------------------- /docs/objects_introduction.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | There exists various libraries for object-oriented programming in C, e.g. 4 | [GObject](https://developer.gnome.org/gobject/stable/). There are also 5 | compilers, pre-processors and tools which will build objects for C. In 6 | Wondermacros we will take a different approach. We will use a header file 7 | (e.g. `a_class.h`) which has a fixed-form and specific guidelines 8 | to define a class with properties and methods. Then we will create another 9 | header file (e.g. `a.h`) which includes the first header and an 10 | X-macro, ``. This header may also 11 | have other type definitions and declarations just like all headers if needed. 12 | Then we will implement the methods of the class in a separate C file (e.g. 13 | a.c). This C file also includes the first header (a_class.h) and 14 | an X-macro, ``. This set-up will 15 | give us object-oriented capabilities including: 16 | 17 | * Abstraction: we have class based objects with properties and methods 18 | * Encapsulation: we have public, private and read-only properties, public and private methods 19 | * Inheritance: we have single inheritance 20 | * Polymorphism: method calls lookup the actual method implementation from the class of the object being called 21 | * Introspection: we can study existing objects at runtime 22 | 23 | We also introduce a tool which creates all necessary boilerplate automatically 24 | from [simple class specifications](https://github.com/plainC/wondermacros/blob/master/examples/objects/vechiles/classes.wobject). 25 | 26 | ###### Next: [Defining a Class](https://github.com/plainC/wondermacros/blob/master/docs/objects_class.md) 27 | -------------------------------------------------------------------------------- /docs/objects_restrictions.md: -------------------------------------------------------------------------------- 1 | ### Restrictions 2 | 3 | Do not use the following names when specifing the name of a property. They are reserved for other purposes. 4 | * the name of the class (e.g. `VAR(read,int,Point)` is not valid in `Point` class 5 | * `klass` 6 | * all reserved words in the C language 7 | 8 | Do not use the following names when specifing the name of a method. They are reserved for other purposes. 9 | * `meta` 10 | * `free` 11 | * `to_json` 12 | * `from_json` 13 | * all reserved words in the C language 14 | 15 | -------------------------------------------------------------------------------- /docs/objects_signals.md: -------------------------------------------------------------------------------- 1 | ### Signals 2 | 3 | It is possible to implement observer pattern using build-in signal mechanism 4 | in the O-O framework. To add a signal into a class, use `SIGNAL` macro in the 5 | class file. For instance, to add signal `on_move` to `Point` class we could define it 6 | like this: 7 | 8 | ``` 9 | #define Point__define \ 10 | /* Inherits */ \ 11 | /*none */ \ 12 | \ 13 | METHOD(Point,public,int,move_up,(int steps)) \ 14 | METHOD(Point,public,int,move_left,(int steps)) \ 15 | METHOD(Point,public,void,draw) \ 16 | SIGNAL(on_move, int steps) \ 17 | \ 18 | VAR(read,int,x) \ 19 | VAR(read,int,y) \ 20 | /**/ 21 | ``` 22 | Now to connect a signal into instance of `Point` we can use `W_CONNECT` macro. 23 | For instance, if we have an object `struct Point*` created in `p`, we 24 | can attach a callback `my_cb` to signal `on_move` using the following code: 25 | ``` 26 | W_OBJECT_SIGNAL_TYPE* handle; 27 | 28 | W_CONNECT(p,on_move,my_cb, handle); 29 | ``` 30 | If you also want to bind a data pointer, use `W_CONNECT(p,on_move,(my_cb,data),handle`. 31 | The extra paranthesis must be there. 32 | 33 | The `handle` is needed to deattach the callback later. To unbind a callback, 34 | just use `W_DISCONNECT(handle)`. To unbind all bindings to a signal at once, 35 | use `W_DISCONNECT_ALL(object,signal)`. 36 | 37 | In the class implementation, we can emit signals using `W_EMIT`. For example, 38 | `W_EMIT(self,on_move,steps);` emits `on_move` signal with an argument `steps`. 39 | If the signal does not take any arguments, use `W_EMIT_VOID`. 40 | 41 | Finally, a callback can be implemented like this. Note that the first argument 42 | is the object it self and the second argument is the data pointer which may 43 | be bound with the callback with `W_CONNECT`. 44 | 45 | ``` 46 | void 47 | my_cb(struct Point* self, void* data, int steps) 48 | { 49 | printf(" Moved: %d steps\n",steps); 50 | } 51 | ``` 52 | 53 | The first argument is always the object itself. 54 | 55 | 56 | -------------------------------------------------------------------------------- /docs/objects_wobject.md: -------------------------------------------------------------------------------- 1 | ### wobject Tool 2 | 3 | `wobject` tool helps to skip all steps in maintaining boilerplate code needed 4 | by the O-O framework. It takes a simple class specification and builds the 5 | necessary headers and initial C file, if it does not exist already. The format 6 | is the following: 7 | 8 | ``` 9 | // Define a class ClassName which inherits SuperClassName. It uses Other class 10 | uses Other 11 | class ClassName : SuperClassName 12 | construct // we have a constructor 13 | finalize // we have a destructor 14 | public int x // defines a public property 15 | private int y // defines a private property 16 | public int foo() // defines a method which does not take arguments 17 | public int goo(struct Other* o) // defines a method with an argument 18 | override superfunc // we will override superfunc 19 | ``` 20 | 21 | -------------------------------------------------------------------------------- /docs/string.md: -------------------------------------------------------------------------------- 1 | ## String Handling 2 | 3 | ### W_FOR_STRING_AS_UINT(T,u,str) 4 | #### Arguments 5 | ```C 6 | T an unsigned integer type name 7 | u a free variable name to be assigned 8 | str a string 9 | ``` 10 | #### Description 11 | Use W_FOR_STRING_AS_UINT to convert a string to an unsigned integer. 12 | #### Notes 13 | The string must be null terminated. 14 | If the string is longer than the unsigned type can handle it is truncated. 15 | #### Example 16 | ```C 17 | 'W_FOR_STRING_AS_UINT(uint64_t,x,buffer) printf("%llu", x);' 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/test.md: -------------------------------------------------------------------------------- 1 | ## Unit Testing 2 | 3 | Wondermacros itself has build-in unit tests which use an X-macro based unit tester. 4 | All you need to do is to create a C file, define W_XFILE to include all source code 5 | to be tested, and then include `'. It will expand to a 6 | main program that can be compiled. See an example below. It can also be found 7 | [here](https://github.com/plainC/wondermacros/tree/master/test). 8 | 9 | ```C 10 | #include 11 | #define W_XFILE 12 | #include 13 | ``` 14 | 15 | The tests are written to the header files to be included. The best place is at the 16 | end of the file. There, first test if W_TEST is not defined. If it is not, define 17 | it to expand to nothing. Then add tests separately. See an example below. The 18 | full file is [here](https://github.com/plainC/wondermacros/blob/master/wondermacros/meta/id.h). 19 | 20 | ```C 21 | /*Unit Test*/ 22 | 23 | #ifndef W_TEST 24 | # define W_TEST(...) 25 | #endif 26 | 27 | W_TEST(W_ID, 28 | int W_ID(i) = 42; 29 | W_TEST_ASSERT(W_ID(i) == 42, "Value mismatch"); 30 | ) 31 | ``` 32 | 33 | 34 | ### W_TEST(name,...) 35 | #### Arguments 36 | ```C 37 | name name of the test case 38 | ... statements to be executed 39 | ``` 40 | #### Description 41 | Use W_TEST to add a unit test directly into a header file. It is used with the unit test X-Macro. 42 | 43 | ### W_TEST_ASSERT(cond,...) 44 | #### Arguments 45 | ```C 46 | cond a condition expression, should evaluate to non-zero if test ok 47 | ... format and arguments for error reporting 48 | ``` 49 | #### Description 50 | Use W_TEST_ASSERT to run a test in a unit test. 51 | 52 | ### W_TEST_GROUP(name) 53 | #### Arguments 54 | ```C 55 | name a test group name 56 | ``` 57 | #### Description 58 | Use W_TEST_GROUP to group tests in unit testing. 59 | -------------------------------------------------------------------------------- /docs/test_x.md: -------------------------------------------------------------------------------- 1 | 2 | Wondermacros itself has build-in unit tests which use an X-macro based unit tester. 3 | All you need to do is to create a C file, define W_XFILE to include all source code 4 | to be tested, and then include `'. It will expand to a 5 | main program that can be compiled. See an example below. It can also be found 6 | [here](https://github.com/plainC/wondermacros/tree/master/test). 7 | 8 | ```C 9 | #include 10 | #define W_XFILE 11 | #include 12 | ``` 13 | 14 | The tests are written to the header files to be included. The best place is at the 15 | end of the file. There, first test if W_TEST is not defined. If it is not, define 16 | it to expand to nothing. Then add tests separately. See an example below. The 17 | full file is [here](https://github.com/plainC/wondermacros/blob/master/wondermacros/meta/id.h). 18 | 19 | ```C 20 | /*Unit Test*/ 21 | 22 | #ifndef W_TEST 23 | # define W_TEST(...) 24 | #endif 25 | 26 | W_TEST(W_ID, 27 | int W_ID(i) = 42; 28 | W_TEST_ASSERT(W_ID(i) == 42, "Value mismatch"); 29 | ) 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | cd array && make all 3 | cd char && make all 4 | cd math && make all 5 | cd meta && make all 6 | cd list && make all 7 | cd sorting && make all 8 | cd objects && make all 9 | cd x && make all 10 | 11 | 12 | clean: 13 | cd array && make clean 14 | cd char && make clean 15 | cd math && make clean 16 | cd meta && make clean 17 | cd list && make clean 18 | cd sorting && make clean 19 | cd objects && make clean 20 | cd x && make clean 21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/array/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -I . -I../.. -Wall -Wextra 2 | SRCS = $(wildcard *.c) 3 | PROGS = $(patsubst %.c,%,$(SRCS)) 4 | LIBS = 5 | 6 | all: $(PROGS) 7 | %: %.c 8 | $(CC) $(CFLAGS) -o $@ $< $(LIBS) 9 | 10 | run: $(PROGS) 11 | ./run.sh $(PROGS) 12 | 13 | 14 | clean: 15 | rm -f *~ $(PROGS) 16 | 17 | .PHONY: clean run 18 | -------------------------------------------------------------------------------- /examples/array/array_for_each.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | char foo[] = { 'a', 'b', 'c', 'd', 'e' }; 8 | 9 | W_ARRAY_FOR_EACH(char, ch, foo) { 10 | printf("%d: %c\n", ch_ix, ch); 11 | } 12 | 13 | printf("\nReversed:\n\n"); 14 | 15 | W_ARRAY_FOR_EACH_REVERSED(char, ch, foo) { 16 | printf("%d: %c\n", ch_ix, ch); 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /examples/array/array_get_size.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | char foo[] = { 'a', 'b', 'c' }; 7 | printf("%d\n", W_ARRAY_GET_SIZE(foo)); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /examples/array/deque.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | int main() 7 | { 8 | int* deque = NULL; 9 | W_DEQUE_INIT(deque,3); 10 | for (int i=0; i < 1000; i++) { 11 | if (!W_DEQUE_PUSH_BACK(deque, i)) { 12 | printf("Queue full: %d\n", i); 13 | break; 14 | } 15 | } 16 | 17 | W_DEQUE_FOR_EACH_REVERSED(int, t, deque) 18 | printf("->%d\n", t); 19 | 20 | int x; 21 | while (!W_DEQUE_IS_EMPTY(deque)) { 22 | x = W_DEQUE_POP(deque,x); 23 | printf("%d\n",x); 24 | } 25 | W_DEQUE_FREE(deque); 26 | } 27 | -------------------------------------------------------------------------------- /examples/array/dynamic_array.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | int main() 8 | { 9 | int* array = NULL; 10 | W_DYNAMIC_ARRAY_PUSH(array, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 11 | 12 | W_ARRAY_FOR_EACH(int, elem, array, W_DYNAMIC_ARRAY_GET_SIZE(array)) { 13 | printf("%d\n", elem); 14 | } 15 | 16 | /* Or simply */ 17 | printf("-----\n"); 18 | for (int i=0; i < W_DYNAMIC_ARRAY_GET_SIZE(array); i++) 19 | printf("%d\n", array[i]); 20 | 21 | printf("Last elem=%d (steal it)\n", W_DYNAMIC_ARRAY_STEAL_LAST(array)); 22 | printf("Last elem=%d (using safe version)\n", W_DYNAMIC_ARRAY_PEEK_LAST_SAFE(array,0)); 23 | printf("Remove two elements starting at position 3\n"); 24 | 25 | W_DYNAMIC_ARRAY_REMOVE(array, 3, 2); 26 | for (int i=0; i < W_DYNAMIC_ARRAY_GET_SIZE(array); i++) 27 | printf("%d: %d\n", i, array[i]); 28 | 29 | W_DYNAMIC_ARRAY_FREE(array); 30 | } 31 | -------------------------------------------------------------------------------- /examples/array/dynamic_stack.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | int main() 7 | { 8 | int* stack; 9 | W_DYNAMIC_STACK_INIT(stack, 8); 10 | W_DYNAMIC_STACK_PUSH(stack, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 11 | 12 | while (! W_DYNAMIC_STACK_IS_EMPTY(stack)) 13 | printf("%d\n", W_DYNAMIC_STACK_POP(stack)); 14 | 15 | W_DYNAMIC_STACK_FREE(stack); 16 | } 17 | -------------------------------------------------------------------------------- /examples/array/hash_table.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | int main() 7 | { 8 | struct hash_uint { 9 | unsigned key; 10 | unsigned value; 11 | }; 12 | 13 | struct hash_uint* table = NULL; 14 | 15 | W_HASH_TABLE_INIT(table,1); 16 | 17 | for (unsigned int i=0; i < 50000; i++) 18 | W_HASH_TABLE_PUSH(struct hash_uint, table, i, i); 19 | 20 | 21 | W_HASH_TABLE_FOR_EACH_MATCH(struct hash_uint, map, table, 2) 22 | printf("%u -> %d\n", map->key, map->value); 23 | 24 | int matched; 25 | W_HASH_TABLE_REMOVE(table, 2, matched); 26 | printf("Removed: %d\n", matched); 27 | 28 | W_HASH_TABLE_FOR_EACH_MATCH(struct hash_uint, map, table, 2) 29 | printf("%u -> %d\n", map->key, map->value); 30 | 31 | W_HASH_TABLE_FREE(table); 32 | } 33 | -------------------------------------------------------------------------------- /examples/array/move.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | int array[100] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 8 | 9 | W_ARRAY_MOVE_LEFT(array, 10, 5, 3); 10 | for (int i=0; i < 10-3; i++) 11 | printf("%d: %d\n", i, array[i]); 12 | 13 | printf("---\n"); 14 | int array2[100] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 15 | W_ARRAY_MOVE_RIGHT(array2, 10, 5, 3); 16 | for (int i=0; i < 10+3; i++) 17 | printf("%d: %d\n", i, array2[i]); 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /examples/char/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -I . -I../.. -Wall -Wextra 2 | SRCS = $(wildcard *.c) 3 | PROGS = $(patsubst %.c,%,$(SRCS)) 4 | LIBS = 5 | 6 | all: $(PROGS) 7 | %: %.c 8 | $(CC) $(CFLAGS) -o $@ $< $(LIBS) 9 | 10 | run: $(PROGS) 11 | ./run.sh $(PROGS) 12 | 13 | 14 | clean: 15 | rm -f *~ $(PROGS) 16 | 17 | .PHONY: clean run 18 | -------------------------------------------------------------------------------- /examples/char/to_char.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | char buf[] = { 8 | W_PP_CHAR_TO_CHAR(a), 9 | W_PP_CHAR_TO_CHAR(b), 10 | W_PP_CHAR_TO_CHAR(c), 11 | W_PP_CHAR_TO_CHAR(7), 12 | 0 13 | }; 14 | 15 | printf("%s\n", buf); 16 | } 17 | -------------------------------------------------------------------------------- /examples/exceptions/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -I . -I../.. -Wall -Wextra 2 | SRCS = $(wildcard *.c) 3 | PROGS = $(patsubst %.c,%,$(SRCS)) 4 | LIBS = 5 | 6 | all: $(PROGS) 7 | %: %.c 8 | $(CC) $(CFLAGS) -o $@ $< $(LIBS) 9 | 10 | run: $(PROGS) 11 | ./run.sh $(PROGS) 12 | 13 | 14 | clean: 15 | rm -f *~ $(PROGS) 16 | 17 | .PHONY: clean run 18 | -------------------------------------------------------------------------------- /examples/exceptions/try.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | W_EXCEPTION_STACK_DECLARE(64); 6 | 7 | void foo() 8 | { 9 | W_THROW(2, "Error occured in foo\n"); 10 | } 11 | 12 | int main() 13 | { 14 | #define FILE_ERROR 2 15 | 16 | W_TRY { 17 | char* filename = "not_found"; 18 | FILE* file = fopen(filename,"r"); 19 | if (!file) 20 | W_THROW(FILE_ERROR,"%s was not there", filename); 21 | printf("Does not print\n"); 22 | } 23 | W_CATCH(4) { 24 | printf("Should not print\n"); 25 | } 26 | W_CATCH(FILE_ERROR) { 27 | W_EXCEPTION_FPRINTF(stdout); 28 | } 29 | W_CATCH(FILE_ERROR) { 30 | printf("Should not print since catched already\n"); 31 | } 32 | 33 | 34 | W_TRY { 35 | foo(); 36 | printf("Should not print\n"); 37 | } 38 | W_CATCH_ALL { 39 | W_EXCEPTION_FPRINTF(stdout); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /examples/list/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -I . -I../.. -Wall -Wextra 2 | SRCS = $(wildcard *.c) 3 | PROGS = $(patsubst %.c,%,$(SRCS)) 4 | LIBS = 5 | 6 | all: $(PROGS) 7 | %: %.c 8 | $(CC) $(CFLAGS) -o $@ $< $(LIBS) 9 | 10 | run: $(PROGS) 11 | ./run.sh $(PROGS) 12 | 13 | 14 | clean: 15 | rm -f *~ $(PROGS) 16 | 17 | .PHONY: clean run 18 | -------------------------------------------------------------------------------- /examples/list/clist.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | struct int_list { 7 | int value; 8 | struct int_list* next; 9 | }; 10 | 11 | static inline struct int_list* 12 | new_list(int value) 13 | { 14 | struct int_list* self = malloc(sizeof(struct int_list)); 15 | self->value = value; 16 | self->next = self; 17 | return self; 18 | } 19 | 20 | 21 | int main () 22 | { 23 | struct int_list* list = NULL; 24 | 25 | struct int_list* a = new_list(1); 26 | struct int_list* b = new_list(2); 27 | struct int_list* c = new_list(3); 28 | struct int_list* d = new_list(4); 29 | 30 | struct int_list* x = new_list(7); 31 | struct int_list* y = new_list(8); 32 | 33 | W_CSLIST_PREPEND(struct int_list, list, a); 34 | W_CSLIST_PREPEND(struct int_list, list, b); 35 | W_CSLIST_PREPEND(struct int_list, list, c); 36 | W_CSLIST_PREPEND(struct int_list, list, d); 37 | 38 | W_CSLIST_FOR_EACH(struct int_list, l, list) 39 | printf("%d\n", l->value); 40 | 41 | W_CSLIST_APPEND(struct int_list, x, y); 42 | 43 | printf("\n"); 44 | 45 | W_CSLIST_FOR_EACH(struct int_list, l, x) 46 | printf("%d\n", l->value); 47 | 48 | printf("\n"); 49 | 50 | W_CSLIST_PREPEND(struct int_list, list, x); 51 | 52 | W_CSLIST_FOR_EACH(struct int_list, l, x) 53 | printf("%d\n", l->value); 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /examples/list/dlist.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | struct int_list { 7 | int value; 8 | struct int_list* next; 9 | struct int_list* prev; 10 | }; 11 | 12 | static inline struct int_list* 13 | new_list(int value, struct int_list* prev, struct int_list* next) 14 | { 15 | struct int_list* self = malloc(sizeof(struct int_list)); 16 | self->value = value; 17 | self->next = next; 18 | self->prev = prev; 19 | return self; 20 | } 21 | 22 | 23 | int main () 24 | { 25 | struct int_list* list = NULL; 26 | 27 | struct int_list* a = new_list(1, NULL, NULL); 28 | struct int_list* b = new_list(2, NULL, NULL); 29 | 30 | struct int_list* x = new_list(7, NULL, NULL); 31 | struct int_list* y = new_list(8, NULL, NULL); 32 | 33 | W_DLIST_APPEND(struct int_list, list, a); 34 | W_DLIST_APPEND(struct int_list, list, b); 35 | W_DLIST_APPEND(struct int_list, x, y); 36 | 37 | W_DLIST_FOR_EACH(struct int_list, l, x) 38 | printf("%d\n", l->value); 39 | printf("\n"); 40 | 41 | W_DLIST_PREPEND(struct int_list, list, x); 42 | 43 | W_DLIST_FOR_EACH(struct int_list, l, x) 44 | printf("%d\n", l->value); 45 | 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /examples/list/slist.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | struct int_list { 7 | int value; 8 | struct int_list* next; 9 | }; 10 | 11 | static inline struct int_list* 12 | new_list(int value, struct int_list* next) 13 | { 14 | struct int_list* self = malloc(sizeof(struct int_list)); 15 | self->value = value; 16 | self->next = next; 17 | return self; 18 | } 19 | 20 | 21 | int main () 22 | { 23 | struct int_list* list = NULL; 24 | 25 | struct int_list* a = new_list(1, NULL); 26 | struct int_list* b = new_list(2, NULL); 27 | 28 | struct int_list* x = new_list(7, NULL); 29 | struct int_list* y = new_list(8, NULL); 30 | 31 | W_SLIST_APPEND(struct int_list, list, a); 32 | W_SLIST_APPEND(struct int_list, list, b); 33 | W_SLIST_APPEND(struct int_list, x, y); 34 | 35 | W_SLIST_FOR_EACH(struct int_list, l, x) 36 | printf("%d\n", l->value); 37 | printf("\n"); 38 | 39 | W_SLIST_PREPEND(struct int_list, list, x); 40 | 41 | W_SLIST_FOR_EACH(struct int_list, l, x) 42 | printf("%d\n", l->value); 43 | 44 | return 0; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /examples/math/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -I . -I../.. -Wall -Wextra 2 | SRCS = $(wildcard *.c) 3 | PROGS = $(patsubst %.c,%,$(SRCS)) 4 | LIBS = 5 | 6 | all: $(PROGS) 7 | %: %.c 8 | $(CC) $(CFLAGS) -o $@ $< $(LIBS) 9 | 10 | run: $(PROGS) 11 | ./run.sh $(PROGS) 12 | 13 | 14 | clean: 15 | rm -f *~ $(PROGS) 16 | 17 | .PHONY: clean run 18 | -------------------------------------------------------------------------------- /examples/math/min.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | printf("%d\n", W_MIN(4,6,2,7)); 9 | printf("%d\n", W_MIN(2,6,4,7)); 10 | printf("%d\n", W_MIN(6,2,4,7)); 11 | printf("%d\n", W_MIN(7,6,4,2)); 12 | 13 | printf("%d\n", W_MAX(4,6,2,7)); 14 | printf("%d\n", W_MAX(2,6,4,7)); 15 | printf("%d\n", W_MAX(6,2,4,7)); 16 | printf("%d\n", W_MAX(7,6,4,2)); 17 | } 18 | -------------------------------------------------------------------------------- /examples/math/sign.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | printf(" 2->%d\n", W_SIGN(2)); 8 | printf(" 0->%d\n", W_SIGN(0)); 9 | printf("-2>%d\n", W_SIGN(-2)); 10 | } 11 | -------------------------------------------------------------------------------- /examples/meta/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -I . -I../.. -Wall -Wextra 2 | SRCS = $(wildcard *.c) 3 | PROGS = $(patsubst %.c,%,$(SRCS)) 4 | LIBS = 5 | 6 | all: $(PROGS) 7 | %: %.c 8 | $(CC) $(CFLAGS) -o $@ $< $(LIBS) 9 | 10 | run: $(PROGS) 11 | ./run.sh $(PROGS) 12 | 13 | 14 | clean: 15 | rm -f *~ $(PROGS) 16 | 17 | .PHONY: clean run 18 | -------------------------------------------------------------------------------- /examples/meta/stringize.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | printf("%s\n", W_STRINGIZE(a,b,c,d,e,f)); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /examples/objects/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | cd point && make test 3 | cd html && make test 4 | 5 | clean: 6 | cd point && make clean 7 | cd html && make clean 8 | 9 | -------------------------------------------------------------------------------- /examples/objects/html/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = \ 2 | -I . \ 3 | -I ../../.. \ 4 | -g \ 5 | 6 | 7 | SRCS = \ 8 | model.c \ 9 | \ 10 | var_int.c \ 11 | var_double.c \ 12 | \ 13 | html.c \ 14 | html_elem.c \ 15 | html_attr.c \ 16 | dom_string.c \ 17 | dom_list.c \ 18 | js_elem.c \ 19 | css_elem.c \ 20 | css_selector.c \ 21 | cond.c \ 22 | array.c \ 23 | 24 | CLASSES = $(patsubst %.c,%_class.h,$(SRCS)) 25 | OBJS = $(patsubst %.c,%.o,$(SRCS)) 26 | 27 | test: $(SRCS) $(OBJS) test.c $(CLASSES) html_api.h 28 | cc $(CFLAGS) -o test test.c $(OBJS) 29 | 30 | $(OBJS): $(SRCS) $(CLASSES) 31 | cc -c $(CFLAGS) $^ 32 | 33 | clean: 34 | rm -f test $(OBJS) *.gch 35 | -------------------------------------------------------------------------------- /examples/objects/html/array.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | # include 6 | # include 7 | #endif 8 | 9 | #include "array.h" 10 | 11 | #include "array_class.h" 12 | #include 13 | 14 | 15 | CONSTRUCT(array) 16 | { 17 | } 18 | 19 | FINALIZE(array) 20 | { 21 | } 22 | 23 | METHOD(array,public,int,to_string, 24 | (struct model* model, struct view_context* context)) 25 | { 26 | double* array = W_CALL(model,get)(self->name); 27 | if (array) { 28 | double e; 29 | W_CALL(model,bind_ptr)("@elem",1,&e); 30 | for (int i=0; i < W_DYNAMIC_ARRAY_GET_SIZE(array); i++) { 31 | e = array[i]; 32 | W_CALL(self->child,to_string)(model, context); 33 | } 34 | } 35 | 36 | return 0; 37 | } 38 | 39 | 40 | #include 41 | -------------------------------------------------------------------------------- /examples/objects/html/array.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARRAY_H 2 | #define __ARRAY_H 3 | 4 | #include "classes_declare.h" 5 | 6 | #include "html.h" 7 | 8 | #include "array_class.h" 9 | #include 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /examples/objects/html/array_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS array 2 | 3 | #define array__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | OVERRIDE(array,to_string) \ 8 | \ 9 | VAR(read,char*,name) \ 10 | VAR(read,struct html*,child) \ 11 | /**/ 12 | -------------------------------------------------------------------------------- /examples/objects/html/classes_declare.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLASSES_DECLARE_H 2 | #define __CLASSES_DECLARE_H 3 | 4 | #include "model_class.h" 5 | #include 6 | 7 | 8 | #include "var_int_class.h" 9 | #include 10 | 11 | #include "var_double_class.h" 12 | #include 13 | 14 | 15 | #include "html_class.h" 16 | #include 17 | 18 | #include "html_elem_class.h" 19 | #include 20 | 21 | #include "html_attr_class.h" 22 | #include 23 | 24 | #include "dom_string_class.h" 25 | #include 26 | 27 | #include "css_selector_class.h" 28 | #include 29 | 30 | #include "css_elem_class.h" 31 | #include 32 | 33 | #include "dom_list_class.h" 34 | #include 35 | 36 | #include "js_elem_class.h" 37 | #include 38 | 39 | #include "cond_class.h" 40 | #include 41 | 42 | #include "array_class.h" 43 | #include 44 | 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /examples/objects/html/cond.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | #endif 6 | 7 | #include "cond.h" 8 | 9 | #include "cond_class.h" 10 | #include 11 | 12 | 13 | CONSTRUCT(cond) 14 | { 15 | } 16 | 17 | FINALIZE(cond) 18 | { 19 | } 20 | 21 | METHOD(cond,public,int,to_string, 22 | (struct model* model, struct view_context* context)) 23 | { 24 | int* ptr = W_CALL(model,get)(self->name); 25 | if (ptr) { 26 | if (*ptr) 27 | W_CALL(self->child,to_string)(model, context); 28 | } else 29 | context->pos += sprintf(context->buffer + context->pos, "#NA!"); 30 | 31 | return 0; 32 | } 33 | 34 | 35 | #include 36 | -------------------------------------------------------------------------------- /examples/objects/html/cond.h: -------------------------------------------------------------------------------- 1 | #ifndef __COND_H 2 | #define __COND_H 3 | 4 | #include "classes_declare.h" 5 | 6 | #include "html.h" 7 | 8 | #include "cond_class.h" 9 | #include 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /examples/objects/html/cond_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS cond 2 | 3 | #define cond__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | OVERRIDE(cond,to_string) \ 8 | \ 9 | VAR(read,char*,name) \ 10 | VAR(public,struct html*,child) \ 11 | /**/ 12 | -------------------------------------------------------------------------------- /examples/objects/html/css_elem.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | # include 6 | # include 7 | #endif 8 | 9 | #include "css_elem.h" 10 | #include "css_selector.h" 11 | 12 | #include "css_elem_class.h" 13 | #include 14 | 15 | 16 | CONSTRUCT(css_elem) 17 | { 18 | W_UNUSED(self); 19 | } 20 | 21 | FINALIZE(css_elem) 22 | { 23 | W_UNUSED(self); 24 | } 25 | 26 | METHOD(css_elem,public,int,to_string, 27 | (struct model* model, struct view_context* context)) 28 | { 29 | W_CALL(self->selector,to_string)(model, context); 30 | 31 | context->pos += sprintf(context->buffer + context->pos, 32 | " {%s",self->declarations); 33 | /* 34 | W_ARRAY_FOR_EACH(char*,decl, self->declarations, W_DYNAMIC_ARRAY_GET_SIZE(self->declarations)) { 35 | *pos += sprintf(buffer + *pos, "%s;", decl); 36 | } 37 | */ 38 | context->pos += sprintf(context->buffer + context->pos, "}"); 39 | } 40 | 41 | 42 | #include 43 | -------------------------------------------------------------------------------- /examples/objects/html/css_elem.h: -------------------------------------------------------------------------------- 1 | #ifndef __CSS_ELEM_H 2 | #define __CSS_ELEM_H 3 | 4 | #include "classes_declare.h" 5 | 6 | 7 | #include "html.h" 8 | 9 | #include "css_elem_class.h" 10 | #include 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /examples/objects/html/css_elem_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS css_elem 2 | 3 | #define css_elem__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | OVERRIDE(css_elem,to_string) \ 8 | \ 9 | VAR(read,struct css_selector*,selector) \ 10 | VAR(read,char*,declarations) \ 11 | /**/ 12 | -------------------------------------------------------------------------------- /examples/objects/html/css_selector.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | #endif 6 | 7 | #include "css_selector.h" 8 | 9 | #include "css_selector_class.h" 10 | #include 11 | 12 | 13 | CONSTRUCT(css_selector) 14 | { 15 | W_UNUSED(self); 16 | } 17 | 18 | FINALIZE(css_selector) 19 | { 20 | W_UNUSED(self); 21 | } 22 | 23 | METHOD(css_selector,public,int,to_string, 24 | (struct model* model, struct view_context* context)) 25 | { 26 | context->pos += sprintf(context->buffer + context->pos, "%s", self->elem); 27 | } 28 | 29 | 30 | #include 31 | -------------------------------------------------------------------------------- /examples/objects/html/css_selector.h: -------------------------------------------------------------------------------- 1 | #ifndef __CSS_SELECTOR_H 2 | #define __CSS_SELECTOR_H 3 | 4 | #include "classes_declare.h" 5 | 6 | #include "html.h" 7 | 8 | #include "css_selector_class.h" 9 | #include 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /examples/objects/html/css_selector_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS css_selector 2 | 3 | #define css_selector__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | OVERRIDE(css_selector,to_string) \ 8 | \ 9 | VAR(read,char*,elem) \ 10 | /**/ 11 | -------------------------------------------------------------------------------- /examples/objects/html/dom_list.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | # include 6 | # include 7 | #endif 8 | 9 | #include "dom_list.h" 10 | 11 | #include "dom_list_class.h" 12 | #include 13 | 14 | 15 | CONSTRUCT(dom_list) 16 | { 17 | } 18 | 19 | FINALIZE(dom_list) 20 | { 21 | } 22 | 23 | METHOD(dom_list,public,int,append_child, 24 | (struct html* child)) 25 | { 26 | W_DYNAMIC_ARRAY_PUSH(self->docs, child); 27 | } 28 | 29 | METHOD(dom_list,public,int,to_string, 30 | (struct model* model, struct view_context* context)) 31 | { 32 | W_ARRAY_FOR_EACH(struct html*,doc, self->docs, W_DYNAMIC_ARRAY_GET_SIZE(self->docs)) 33 | W_CALL(doc,to_string)(model, context); 34 | 35 | return 0; 36 | } 37 | 38 | 39 | #include 40 | -------------------------------------------------------------------------------- /examples/objects/html/dom_list.h: -------------------------------------------------------------------------------- 1 | #ifndef __DOM_LIST_H 2 | #define __DOM_LIST_H 3 | 4 | #include "classes_declare.h" 5 | 6 | #include "html.h" 7 | 8 | #include "dom_list_class.h" 9 | #include 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /examples/objects/html/dom_list_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS dom_list 2 | 3 | #define dom_list__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | METHOD(dom_list,public,int,append_child, \ 8 | (struct html* child)) \ 9 | OVERRIDE(dom_list,to_string) \ 10 | \ 11 | VAR(read,struct html**,docs) \ 12 | /**/ 13 | -------------------------------------------------------------------------------- /examples/objects/html/dom_string.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | #endif 6 | 7 | #include "html.h" 8 | #include "dom_string.h" 9 | 10 | #include "dom_string_class.h" 11 | #include 12 | 13 | 14 | CONSTRUCT(dom_string) 15 | { 16 | self->value = strdup(self->value); 17 | } 18 | 19 | FINALIZE(dom_string) 20 | { 21 | free(self->value); 22 | } 23 | 24 | METHOD(dom_string,public,int,to_string, 25 | (struct model* model, struct view_context* context)) 26 | { 27 | context->pos += sprintf(context->buffer + context->pos, "%s", self->value); 28 | 29 | return 0; 30 | } 31 | 32 | 33 | #include 34 | -------------------------------------------------------------------------------- /examples/objects/html/dom_string.h: -------------------------------------------------------------------------------- 1 | #ifndef __DOM_STRING_H 2 | #define __DOM_STRING_H 3 | 4 | #include "classes_declare.h" 5 | 6 | #include "html.h" 7 | 8 | #include "dom_string_class.h" 9 | #include 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /examples/objects/html/dom_string_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS dom_string 2 | 3 | #define dom_string__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | OVERRIDE(dom_string,to_string) \ 8 | \ 9 | VAR(read,char*,value) \ 10 | /**/ 11 | -------------------------------------------------------------------------------- /examples/objects/html/html.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | #endif 5 | 6 | 7 | /* Include class header. */ 8 | #include "html.h" 9 | #include "html_elem.h" 10 | 11 | /* Begin class implementation. */ 12 | #include "html_class.h" 13 | #include 14 | 15 | 16 | CONSTRUCT(html) /* self */ 17 | { 18 | W_UNUSED(self); 19 | } 20 | 21 | FINALIZE(html) /* self */ 22 | { 23 | } 24 | 25 | METHOD(html,public,int,to_string, 26 | (struct model* model, struct view_context* context)) 27 | { 28 | } 29 | 30 | #include 31 | -------------------------------------------------------------------------------- /examples/objects/html/html.h: -------------------------------------------------------------------------------- 1 | #ifndef __HTML_H 2 | #define __HTML_H 3 | 4 | struct view_context { 5 | char* buffer; 6 | size_t size; 7 | int pos; 8 | }; 9 | 10 | #include "classes_declare.h" 11 | #define W_OBJECT_CAST_TO_VOID 12 | 13 | #include "model.h" 14 | 15 | #include "html_class.h" 16 | #include 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /examples/objects/html/html_attr.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | #endif 6 | 7 | #include "html_attr.h" 8 | 9 | #include "html_attr_class.h" 10 | #include 11 | 12 | /**/ 13 | 14 | /* static const char* html_attr_name[] = { }; */ 15 | #define W_NAME html_attr_name 16 | #define W_NAME_INDEX 1 17 | #define W_XFILE "attr_tags.h" 18 | #include 19 | /**/ 20 | 21 | 22 | CONSTRUCT(html_attr) 23 | { 24 | W_UNUSED(self); 25 | } 26 | 27 | FINALIZE(html_attr) 28 | { 29 | W_UNUSED(self); 30 | } 31 | 32 | METHOD(html_attr,public,int,to_string, 33 | (struct model* model, struct view_context* context)) 34 | { 35 | context->pos += sprintf(context->buffer + context->pos, 36 | " %s=\"", html_attr_name[self->tag]); 37 | W_CALL(self->value,to_string)(model, context); 38 | context->pos += sprintf(context->buffer + context->pos, "\""); 39 | } 40 | 41 | 42 | #include 43 | -------------------------------------------------------------------------------- /examples/objects/html/html_attr.h: -------------------------------------------------------------------------------- 1 | #ifndef __HTML_ATTR_H 2 | #define __HTML_ATTR_H 3 | 4 | #include "classes_declare.h" 5 | 6 | /* Define enum html_attr_tag. */ 7 | #define W_NAME html_attr_tag 8 | #define W_XFILE "attr_tags.h" 9 | #include 10 | /**/ 11 | 12 | 13 | 14 | #include "html.h" 15 | 16 | #include "html_attr_class.h" 17 | #include 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /examples/objects/html/html_attr_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS html_attr 2 | 3 | #define html_attr__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | OVERRIDE(html_attr,to_string) \ 8 | \ 9 | VAR(read,enum html_attr_tag,tag) \ 10 | VAR(read,struct html*,value) \ 11 | /**/ 12 | -------------------------------------------------------------------------------- /examples/objects/html/html_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS html 2 | 3 | #define html__define \ 4 | /* Inherits */ \ 5 | /*none */ \ 6 | \ 7 | METHOD(html,public,int,to_string, \ 8 | (struct model* model, struct view_context* context)) \ 9 | \ 10 | /**/ 11 | -------------------------------------------------------------------------------- /examples/objects/html/html_elem.h: -------------------------------------------------------------------------------- 1 | #ifndef __HTML_ELEM_H 2 | #define __HTML_ELEM_H 3 | 4 | #include "classes_declare.h" 5 | 6 | /* Define enum html_elem_tag. */ 7 | #define W_NAME html_elem_tag 8 | #define W_XFILE "html_tags.h" 9 | #include 10 | /**/ 11 | 12 | 13 | 14 | #include "html.h" 15 | 16 | #include "html_elem_class.h" 17 | #include 18 | 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /examples/objects/html/html_elem_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS html_elem 2 | 3 | #define html_elem__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | METHOD(html_elem,public,int,append_child, \ 8 | (struct html* child)) \ 9 | OVERRIDE(html_elem,to_string) \ 10 | \ 11 | VAR(read,enum html_elem_tag,tag) \ 12 | VAR(read,struct html_attr**,attrs) \ 13 | VAR(read,struct html**,next) \ 14 | /**/ 15 | -------------------------------------------------------------------------------- /examples/objects/html/js_elem.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | # include 6 | # include 7 | #endif 8 | 9 | #include "js_elem.h" 10 | 11 | #include "js_elem_class.h" 12 | #include 13 | 14 | 15 | CONSTRUCT(js_elem) 16 | { 17 | W_UNUSED(self); 18 | } 19 | 20 | FINALIZE(js_elem) 21 | { 22 | W_UNUSED(self); 23 | } 24 | 25 | METHOD(js_elem,public,int,to_string, 26 | (struct model* model, struct view_context* context)) 27 | { 28 | W_CALL(self->script,to_string)(model, context); 29 | } 30 | 31 | 32 | #include 33 | -------------------------------------------------------------------------------- /examples/objects/html/js_elem.h: -------------------------------------------------------------------------------- 1 | #ifndef __JS_ELEM_H 2 | #define __JS_ELEM_H 3 | 4 | #include "classes_declare.h" 5 | 6 | 7 | #include "html.h" 8 | 9 | #include "js_elem_class.h" 10 | #include 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /examples/objects/html/js_elem_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS js_elem 2 | 3 | #define js_elem__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | OVERRIDE(js_elem,to_string) \ 8 | \ 9 | VAR(read,struct html*,script) \ 10 | /**/ 11 | -------------------------------------------------------------------------------- /examples/objects/html/model.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | # include 6 | # include 7 | #endif 8 | 9 | 10 | /* Include class header. */ 11 | #include "model.h" 12 | 13 | /* Begin class implementation. */ 14 | #include "model_class.h" 15 | #include 16 | 17 | 18 | CONSTRUCT(model) /* self */ 19 | { 20 | self->variables = NULL; 21 | } 22 | 23 | FINALIZE(model) /* self */ 24 | { 25 | W_ARRAY_FOR_EACH(struct variable*,var, self->variables) { 26 | free((void*) var->name); 27 | free(var); 28 | } 29 | } 30 | 31 | METHOD(model,public,void*,get, 32 | (const char* name)) 33 | { 34 | W_ARRAY_FOR_EACH(struct variable*,var, self->variables, W_DYNAMIC_ARRAY_GET_SIZE(self->variables)) 35 | if (strcmp(var->name, name) == 0) 36 | return var->ptr; 37 | return NULL; 38 | } 39 | 40 | METHOD(model,public,int,bind_ptr, 41 | (const char* name, int type, void* ptr)) 42 | { 43 | struct variable* var = malloc(sizeof(struct variable)); 44 | var->name = strdup(name); 45 | var->type = type; 46 | var->ptr = ptr; 47 | 48 | W_ARRAY_FOR_EACH(struct variable*,v, self->variables, W_DYNAMIC_ARRAY_GET_SIZE(self->variables)) 49 | if (strcmp(v->name, name) == 0) { 50 | free(v); 51 | self->variables[v_ix] = var; 52 | return 1; 53 | } 54 | 55 | W_DYNAMIC_ARRAY_PUSH(self->variables, var); 56 | return 0; 57 | } 58 | 59 | #include 60 | -------------------------------------------------------------------------------- /examples/objects/html/model.h: -------------------------------------------------------------------------------- 1 | #ifndef __MODEL_H 2 | #define __MODEL_H 3 | 4 | struct variable { 5 | const char* name; 6 | int type; 7 | void* ptr; 8 | }; 9 | 10 | #include "classes_declare.h" 11 | 12 | #include "model_class.h" 13 | #include 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/objects/html/model_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS model 2 | 3 | #define model__define \ 4 | /* Inherits */ \ 5 | /*none */ \ 6 | \ 7 | METHOD(model,public,int,bind_ptr, \ 8 | (const char* name, int type, void* ptr)) \ 9 | METHOD(model,public,void*,get, \ 10 | (const char* name)) \ 11 | \ 12 | VAR(private,struct variable**,variables) \ 13 | \ 14 | /**/ 15 | -------------------------------------------------------------------------------- /examples/objects/html/source: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gcc -DWDEBUG_EXPAND=1 -E -P -I . -I ../../.. $1 | indent -l 500 4 | 5 | -------------------------------------------------------------------------------- /examples/objects/html/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef WDEBUG_EXPAND 4 | # include 5 | # define W_OBJECT_CAST_TO_VOID 6 | # include 7 | # include 8 | #endif 9 | 10 | #include "model.h" 11 | 12 | #include "html.h" 13 | #include "html_elem.h" 14 | #include "html_attr.h" 15 | #include "html_api.h" 16 | #include "dom_string.h" 17 | #include "dom_list.h" 18 | #include "css_selector.h" 19 | #include "css_elem.h" 20 | #include "js_elem.h" 21 | #include "cond.h" 22 | #include "array.h" 23 | 24 | #include "var_int.h" 25 | #include "var_double.h" 26 | 27 | 28 | int main() 29 | { 30 | int v=42; 31 | double e=2.744; 32 | double* prices = NULL; 33 | int has_prices = 1; 34 | 35 | W_DYNAMIC_ARRAY_PUSH(prices, 2.12, 3.14, 6.32, 4.24, 7.44); 36 | 37 | struct model* model = W_NEW(model); 38 | W_CALL(model,bind_ptr)("has_prices",0,&has_prices); 39 | W_CALL(model,bind_ptr)("a",0,&v); 40 | W_CALL(model,bind_ptr)("e",1,&e); 41 | W_CALL(model,bind_ptr)("prices",1,prices); 42 | 43 | 44 | struct html_elem* doc = DOC( 45 | DOCTYPE, 46 | htmlHTML( attrID(_("FooPoro")), attrLANG(_("fi-FI")), attrDIR(_("LTR")), attrCLASS(_("Public")), 47 | htmlHEAD( 48 | htmlMETA(attrCHARSET(_("utf-8"))), 49 | htmlMETA(attrHTTP_EQUIV(_("X-UA-Compatible")), attrCONTENT(_("IE=Edge,chrome=1"))), 50 | htmlMETA(attrNAME(_("viewport")), attrCONTENT(_("width=device-width, initial-scale=1"))), 51 | htmlBASE(attrHREF(_("https://local.com/"))), 52 | htmlTITLE(_("First page")) 53 | ), 54 | htmlBODY( 55 | css(cssTYPE_SELECTOR("p"),"width:9;"), 56 | ), 57 | INT_VAR("a"), DOUBLE_VAR("e", .format="%.2%%"), COND("has_prices", ARRAY("prices", htmlLI(htmlB(DOUBLE_VAR("@elem", .format="$%.2f"))))) 58 | ) 59 | ); 60 | 61 | 62 | char buffer[1024]; 63 | int pos=0; 64 | 65 | struct view_context context; 66 | context.buffer = buffer; 67 | context.size = 1024; 68 | context.pos = 0; 69 | 70 | W_CALL(doc,to_string)(model, &context); 71 | printf("%s\n", buffer); 72 | } 73 | -------------------------------------------------------------------------------- /examples/objects/html/var_double.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | #endif 6 | 7 | #include "var_double.h" 8 | 9 | #include "var_double_class.h" 10 | #include 11 | 12 | 13 | CONSTRUCT(var_double) 14 | { 15 | } 16 | 17 | FINALIZE(var_double) 18 | { 19 | } 20 | 21 | METHOD(var_double,public,int,to_string, 22 | (struct model* model, struct view_context* context)) 23 | { 24 | double* ptr = W_CALL(model,get)(self->name); 25 | if (ptr) 26 | context->pos += sprintf(context->buffer + context->pos, 27 | self->format ? self->format : "%g", *ptr); 28 | else 29 | context->pos += sprintf(context->buffer + context->pos, "#NA!"); 30 | 31 | return 0; 32 | } 33 | 34 | 35 | #include 36 | -------------------------------------------------------------------------------- /examples/objects/html/var_double.h: -------------------------------------------------------------------------------- 1 | #ifndef __VAR_DOUBLE_H 2 | #define __VAR_DOUBLE_H 3 | 4 | #include "classes_declare.h" 5 | 6 | #include "html.h" 7 | 8 | #include "var_double_class.h" 9 | #include 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /examples/objects/html/var_double_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS var_double 2 | 3 | #define var_double__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | OVERRIDE(var_double,to_string) \ 8 | \ 9 | VAR(read,char*,name) \ 10 | VAR(read,char*,format) \ 11 | /**/ 12 | -------------------------------------------------------------------------------- /examples/objects/html/var_int.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | #endif 6 | 7 | #include "var_int.h" 8 | 9 | #include "var_int_class.h" 10 | #include 11 | 12 | 13 | CONSTRUCT(var_int) 14 | { 15 | } 16 | 17 | FINALIZE(var_int) 18 | { 19 | } 20 | 21 | METHOD(var_int,public,int,to_string, 22 | (struct model* model, struct view_context* context)) 23 | { 24 | int* ptr = W_CALL(model,get)(self->name); 25 | if (ptr) 26 | context->pos += sprintf(context->buffer + context->pos, "%d", *ptr); 27 | else 28 | context->pos += sprintf(context->buffer + context->pos, "#NA!"); 29 | 30 | return 0; 31 | } 32 | 33 | 34 | #include 35 | -------------------------------------------------------------------------------- /examples/objects/html/var_int.h: -------------------------------------------------------------------------------- 1 | #ifndef __VAR_INT_H 2 | #define __VAR_INT_H 3 | 4 | #include "classes_declare.h" 5 | 6 | #include "html.h" 7 | 8 | #include "var_int_class.h" 9 | #include 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /examples/objects/html/var_int_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS var_int 2 | 3 | #define var_int__define \ 4 | /* Inherits */ \ 5 | html__define \ 6 | \ 7 | OVERRIDE(var_int,to_string) \ 8 | \ 9 | VAR(read,char*,name) \ 10 | /**/ 11 | -------------------------------------------------------------------------------- /examples/objects/point/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = \ 2 | -I ../../.. \ 3 | -g \ 4 | 5 | 6 | SRCS = \ 7 | owner.c \ 8 | point.c \ 9 | colored_point.c \ 10 | colored_point3d.c \ 11 | 12 | CLASSES = \ 13 | owner_class.h \ 14 | point_class.h \ 15 | colored_point_class.h \ 16 | 17 | 18 | OBJS = $(patsubst %.c,%.o,$(SRCS)) 19 | 20 | all: test 21 | 22 | test: $(SRCS) $(OBJS) test.c $(CLASSES) 23 | cc $(CFLAGS) -o test test.c $(OBJS) 24 | 25 | $(OBJS): $(SRCS) $(CLASSES) 26 | cc -c $(CFLAGS) $^ 27 | 28 | uml.png: $(CLASSES) 29 | gcc -o uml.dot -I . -E -P uml.h 30 | dot -T png -o uml.png uml.dot 31 | 32 | clean: 33 | rm -f test $(OBJS) *.gch uml.png uml.dot 34 | -------------------------------------------------------------------------------- /examples/objects/point/classes.h: -------------------------------------------------------------------------------- 1 | #include "owner_class.h" 2 | #include W_XMACRO 3 | #include "point_class.h" 4 | #include W_XMACRO 5 | #include "colored_point_class.h" 6 | #include W_XMACRO 7 | #include "colored_point3d_class.h" 8 | #include W_XMACRO 9 | -------------------------------------------------------------------------------- /examples/objects/point/classes_declare.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLASSES_DECLARE_H 2 | #define __CLASSES_DECLARE_H 3 | 4 | #define USE_T_TYPE_SUFFIX 5 | #include "owner_class.h" 6 | #include 7 | 8 | #include "point_class.h" 9 | #include 10 | 11 | #include "colored_point_class.h" 12 | #include 13 | 14 | #include "colored_point3d_class.h" 15 | #include 16 | 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /examples/objects/point/colored_point.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | #endif 5 | 6 | #include "colored_point.h" 7 | 8 | #include "colored_point_class.h" 9 | #include 10 | 11 | 12 | CONSTRUCT(ColoredPoint) 13 | { 14 | W_CALL_CONSTRUCT(Point); 15 | } 16 | 17 | FINALIZE(ColoredPoint) 18 | { 19 | W_UNUSED(self); 20 | } 21 | 22 | METHOD(ColoredPoint,public,void,draw) 23 | { 24 | printf("%s point at %d,%d\n", self->color, self->x, self->y); 25 | } 26 | 27 | 28 | #include 29 | -------------------------------------------------------------------------------- /examples/objects/point/colored_point.h: -------------------------------------------------------------------------------- 1 | #ifndef __COLORED_POINT_H 2 | #define __COLORED_POINT_H 3 | 4 | #include "classes_declare.h" 5 | 6 | #include "point.h" 7 | 8 | #include "colored_point_class.h" 9 | #include 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /examples/objects/point/colored_point3d.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | #endif 5 | 6 | #include "colored_point3d.h" 7 | 8 | #include "colored_point3d_class.h" 9 | #include 10 | 11 | 12 | CONSTRUCT(ColoredPoint3D) 13 | { 14 | W_UNUSED(self); 15 | } 16 | 17 | FINALIZE(ColoredPoint3D) 18 | { 19 | W_UNUSED(self); 20 | } 21 | 22 | METHOD(ColoredPoint3D,public,void,draw) 23 | { 24 | printf("%s point at %d,%d,%d\n", self->color, self->x, self->y, self->z); 25 | } 26 | 27 | 28 | #include 29 | -------------------------------------------------------------------------------- /examples/objects/point/colored_point3d.h: -------------------------------------------------------------------------------- 1 | #ifndef __COLORED_POINT3D_H 2 | #define __COLORED_POINT3D_H 3 | 4 | #include "classes_declare.h" 5 | 6 | #include "point.h" 7 | #include "colored_point.h" 8 | 9 | #include "colored_point3d_class.h" 10 | #include 11 | 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /examples/objects/point/colored_point3d_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS ColoredPoint3D 2 | #define SUPER ColoredPoint 3 | 4 | #define BUILD_JSON 5 | 6 | #define ColoredPoint3D__define \ 7 | /* Inherits */ \ 8 | ColoredPoint__define \ 9 | \ 10 | OVERRIDE(ColoredPoint3D,draw) \ 11 | \ 12 | VAR(read,int,z,JSON(json_int)) \ 13 | /**/ 14 | -------------------------------------------------------------------------------- /examples/objects/point/colored_point_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS ColoredPoint 2 | #define SUPER Point 3 | 4 | #define BUILD_JSON 5 | 6 | #define ColoredPoint__define \ 7 | /* Inherits */ \ 8 | Point__define \ 9 | \ 10 | OVERRIDE(ColoredPoint,draw) \ 11 | \ 12 | VAR(read,const char*,color,JSON(json_string)) \ 13 | /**/ 14 | -------------------------------------------------------------------------------- /examples/objects/point/owner.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | #endif 5 | 6 | 7 | /* Include class header. */ 8 | #include "owner.h" 9 | 10 | /* Begin class implementation. */ 11 | #include "owner_class.h" 12 | #include 13 | 14 | 15 | #include 16 | -------------------------------------------------------------------------------- /examples/objects/point/owner.h: -------------------------------------------------------------------------------- 1 | #ifndef __OWNER_H 2 | #define __OWNER_H 3 | 4 | #define W_OBJECT_CAST_TO_VOID 5 | #include "classes_declare.h" 6 | 7 | #include "owner_class.h" 8 | #include 9 | 10 | #endif 11 | 12 | -------------------------------------------------------------------------------- /examples/objects/point/owner_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS Owner 2 | 3 | #define NO_CONSTRUCT 4 | #define NO_DESTRUCT 5 | #define BUILD_JSON 6 | 7 | #define Owner__define \ 8 | /* Inherits */ \ 9 | /*none */ \ 10 | \ 11 | \ 12 | VAR(read,int,id,JSON(json_int)) \ 13 | VAR(read,int,number,JSON(json_int)) \ 14 | /**/ 15 | -------------------------------------------------------------------------------- /examples/objects/point/point.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | #endif 5 | 6 | 7 | /* Include class header. */ 8 | #include "point.h" 9 | #include "owner.h" 10 | 11 | /* Begin class implementation. */ 12 | #include "point_class.h" 13 | #include 14 | 15 | CONSTRUCT(Point) 16 | { 17 | self->a = W_NEW(Owner); 18 | } 19 | 20 | METHOD(Point,private,void,ping,(const char* message)) 21 | { 22 | printf("Message: %s\n", message); 23 | } 24 | 25 | METHOD(Point,public,int,move_up,(int steps)) 26 | { 27 | if (self->y - steps < 0) { 28 | W_CALL(self,ping)("Hits the wall"); 29 | self->y = 0; 30 | return 1; 31 | } 32 | 33 | self->y -= steps; 34 | return 0; 35 | } 36 | 37 | METHOD(Point,public,int,move_left,(int steps)) 38 | { 39 | self->x -= steps; 40 | return 0; 41 | } 42 | 43 | METHOD(Point,public,void,draw) 44 | { 45 | printf("point at %d,%d\n", self->x, self->y); 46 | } 47 | 48 | 49 | #include 50 | -------------------------------------------------------------------------------- /examples/objects/point/point.h: -------------------------------------------------------------------------------- 1 | #ifndef __POINT_H 2 | #define __POINT_H 3 | 4 | #define W_OBJECT_CAST_TO_VOID 5 | #include "classes_declare.h" 6 | 7 | #include "point_class.h" 8 | #include 9 | 10 | #endif 11 | 12 | -------------------------------------------------------------------------------- /examples/objects/point/point_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS Point 2 | 3 | #define NO_DESTRUCT 4 | #define BUILD_JSON 5 | 6 | #define Point__define \ 7 | /* Inherits */ \ 8 | /*none */ \ 9 | \ 10 | METHOD(Point,public,int,move_up,(int steps)) \ 11 | METHOD(Point,public,int,move_left,(int steps)) \ 12 | METHOD(Point,private,void,ping,(const char* message)) \ 13 | METHOD(Point,public,void,draw) \ 14 | \ 15 | VAR(read,int,r,Array(2) JSON(json_int_array_2)) \ 16 | VAR(read,int,x,JSON(json_int)) \ 17 | VAR(read,int,y,JSON(json_int)) \ 18 | VAR(read,struct Owner*,a,JSON(json_object)) \ 19 | /**/ 20 | -------------------------------------------------------------------------------- /examples/objects/point/source: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gcc -DWDEBUG_EXPAND=1 -E -P -I . -I ../../.. $1 | indent 4 | 5 | -------------------------------------------------------------------------------- /examples/objects/point/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef WDEBUG_EXPAND 4 | #include 5 | # include 6 | # include 7 | # include 8 | # include 9 | # define W_OBJECT_CAST_TO_VOID 10 | # include 11 | #endif 12 | 13 | #include "point.h" 14 | #include "colored_point.h" 15 | #include "colored_point3d.h" 16 | #include "owner.h" 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | struct w_object_class_map* w_object_classes; 26 | 27 | 28 | int main() 29 | { 30 | Point_t* array[] = { 31 | W_NEW(Point), 32 | W_NEW(ColoredPoint), 33 | W_NEW(ColoredPoint3D, .x=5, .y=2, .z=8, .color="green"), 34 | }; 35 | 36 | printf("meta: %d %d %d\n", w_object_is_subclass_of(array[1],array[0]), 37 | w_object_is_superclass_of(array[0],array[2]), 38 | w_object_is_subclass_of(array[0],array[1])); 39 | 40 | #include 41 | #define VAR(name,value) "\"" # name "\":" W_STRINGIZE(value) 42 | 43 | const char* json = "{" 44 | "\"r\":[1,2]," 45 | VAR(x,12) "," VAR(y,99) ",\"a\": {" VAR(id,77) "," VAR(number,88) " }" 46 | "}," 47 | "{" 48 | VAR(x,1) "," VAR(y,2) "," 49 | VAR(color,"black") 50 | "}"; 51 | 52 | #undef VAR 53 | 54 | const char* end; 55 | /* We will initialize the first two objects from JSON string. */ 56 | printf("%s\n", json); 57 | if (W_CALL(array[0],from_json)(json, &end)) 58 | printf("ERROR: %ld\n", end-json); 59 | 60 | if (W_CALL(array[1],from_json)(end, &end)) 61 | printf("ERROR\n"); 62 | 63 | /* A buffer for JSON output. */ 64 | char buffer[256]; 65 | 66 | for (int i=0; i < 3; i++) { 67 | printf("Round: %d\n", i); 68 | W_ARRAY_FOR_EACH(struct Point*, point, array) { 69 | if (W_CALL(point,to_json)(buffer,256) < 0) 70 | printf("Error\n"); 71 | else 72 | printf("%s\n", buffer); 73 | W_CALL_VOID(point,draw); 74 | W_CALL(point,move_up)(2); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /examples/objects/point/uml.h: -------------------------------------------------------------------------------- 1 | #define W_XFILE "classes.h" 2 | #include 3 | 4 | -------------------------------------------------------------------------------- /examples/objects/signals/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = \ 2 | -I ../../.. \ 3 | -g \ 4 | 5 | 6 | SRCS = \ 7 | point.c \ 8 | 9 | CLASSES = \ 10 | point_class.h \ 11 | 12 | 13 | OBJS = $(patsubst %.c,%.o,$(SRCS)) 14 | 15 | all: test 16 | 17 | test: $(SRCS) $(OBJS) test.c $(CLASSES) 18 | cc $(CFLAGS) -o test test.c $(OBJS) 19 | 20 | $(OBJS): $(SRCS) $(CLASSES) 21 | cc -c $(CFLAGS) $^ 22 | 23 | uml.png: $(CLASSES) 24 | gcc -o uml.dot -I . -E -P uml.h 25 | dot -T png -o uml.png uml.dot 26 | 27 | clean: 28 | rm -f test $(OBJS) *.gch uml.png uml.dot 29 | -------------------------------------------------------------------------------- /examples/objects/signals/classes_declare.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLASSES_DECLARE_H 2 | #define __CLASSES_DECLARE_H 3 | 4 | #define USE_T_TYPE_SUFFIX 5 | #include "point_class.h" 6 | #include 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /examples/objects/signals/point.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | #endif 6 | 7 | 8 | /* Include class header. */ 9 | #include "point.h" 10 | 11 | /* Begin class implementation. */ 12 | #include "point_class.h" 13 | #include 14 | 15 | 16 | 17 | CONSTRUCT(Point) 18 | { 19 | } 20 | 21 | METHOD(Point,private,void,ping,(const char* message)) 22 | { 23 | printf("Message: %s\n", message); 24 | } 25 | 26 | METHOD(Point,public,int,move_up,(int steps)) 27 | { 28 | if (self->y - steps < 0) { 29 | W_CALL(self,ping)("Hits the wall"); 30 | self->y = 0; 31 | W_EMIT(self,on_move,steps); 32 | return 1; 33 | } 34 | 35 | self->y -= steps; 36 | W_EMIT(self,on_move,steps); 37 | return 0; 38 | } 39 | 40 | METHOD(Point,public,int,move_left,(int steps)) 41 | { 42 | self->x -= steps; 43 | return 0; 44 | } 45 | 46 | METHOD(Point,public,void,draw) 47 | { 48 | printf("point at %d,%d\n", self->x, self->y); 49 | } 50 | 51 | 52 | #include 53 | -------------------------------------------------------------------------------- /examples/objects/signals/point.h: -------------------------------------------------------------------------------- 1 | #ifndef __POINT_H 2 | #define __POINT_H 3 | 4 | #define W_OBJECT_CAST_TO_VOID 5 | #include "classes_declare.h" 6 | 7 | #include 8 | #include 9 | 10 | #include "point_class.h" 11 | #include 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /examples/objects/signals/point_class.h: -------------------------------------------------------------------------------- 1 | #define CLASS Point 2 | 3 | #define NO_DESTRUCT 4 | 5 | #define Point__define \ 6 | /* Inherits */ \ 7 | /*none */ \ 8 | \ 9 | METHOD(Point,public,int,move_up,(int steps)) \ 10 | METHOD(Point,public,int,move_left,(int steps)) \ 11 | METHOD(Point,private,void,ping,(const char* message)) \ 12 | METHOD(Point,public,void,draw) \ 13 | SIGNAL(on_move, int steps) \ 14 | \ 15 | VAR(read,int,x) \ 16 | VAR(read,int,y) \ 17 | /**/ 18 | -------------------------------------------------------------------------------- /examples/objects/signals/source: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gcc -DWDEBUG_EXPAND=1 -E -P -I . -I ../../.. $1 | indent 4 | 5 | -------------------------------------------------------------------------------- /examples/objects/signals/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "point.h" 6 | 7 | void 8 | my_cb(struct Point* self, void* data, int steps) 9 | { 10 | printf(" Moved: %d steps\n",steps); 11 | } 12 | 13 | void 14 | my_cb2(struct Point* self, void* data, int steps) 15 | { 16 | printf(" Yes it dit move %d\n",steps); 17 | } 18 | 19 | int main() 20 | { 21 | struct Point* p = W_NEW(Point, .x=3, .y=7); 22 | W_OBJECT_SIGNAL_TYPE* handle; 23 | 24 | W_CONNECT(p,on_move,my_cb, handle); 25 | W_CONNECT(p,on_move,my_cb2, handle); 26 | W_CALL_VOID(p,draw); 27 | W_CALL(p,move_up)(2); 28 | W_CALL_VOID(p,draw); 29 | 30 | W_DISCONNECT(handle); 31 | W_CALL(p,move_up)(1); 32 | 33 | W_CALL_VOID(p,free); 34 | } 35 | 36 | -------------------------------------------------------------------------------- /examples/objects/vechiles/Aircraft.c: -------------------------------------------------------------------------------- 1 | #include "forward_declare.h" 2 | #include "Aircraft.h" 3 | #include "Aircraft_class.h" 4 | #include 5 | 6 | METHOD(Aircraft,public,void,land) 7 | { 8 | } 9 | 10 | METHOD(Aircraft,public,void,fly) 11 | { 12 | } 13 | 14 | /* Override: start */ 15 | METHOD(Aircraft,public,void,start) 16 | { 17 | } 18 | 19 | /* Override: stop */ 20 | METHOD(Aircraft,public,void,stop) 21 | { 22 | } 23 | 24 | /* Override: turn */ 25 | METHOD(Aircraft,public,void,turn,(float angle)) 26 | { 27 | } 28 | 29 | /* Override: add_speed */ 30 | METHOD(Aircraft,public,void,add_speed,(float increment)) 31 | { 32 | } 33 | 34 | #include 35 | -------------------------------------------------------------------------------- /examples/objects/vechiles/Bike.c: -------------------------------------------------------------------------------- 1 | #include "forward_declare.h" 2 | #include "Bike.h" 3 | #include "Bike_class.h" 4 | #include 5 | 6 | /* Override: turn */ 7 | METHOD(Bike,public,void,turn,(float angle)) 8 | { 9 | } 10 | 11 | /* Override: add_speed */ 12 | METHOD(Bike,public,void,add_speed,(float increment)) 13 | { 14 | } 15 | 16 | #include 17 | -------------------------------------------------------------------------------- /examples/objects/vechiles/Car.c: -------------------------------------------------------------------------------- 1 | #include "forward_declare.h" 2 | #include "Car.h" 3 | #include "Car_class.h" 4 | #include 5 | 6 | CONSTRUCT(Car) 7 | { 8 | self->engine = W_NEW(DieselEngine); 9 | self->weight = 2000; 10 | } 11 | 12 | FINALIZE(Car) 13 | { 14 | W_CALL_VOID(self->engine,free); 15 | } 16 | 17 | /* Override: start */ 18 | METHOD(Car,public,void,start) 19 | { 20 | W_CALL_VOID(self->engine,start); 21 | } 22 | 23 | /* Override: stop */ 24 | METHOD(Car,public,void,stop) 25 | { 26 | W_CALL_VOID(self->engine,stop); 27 | } 28 | 29 | /* Override: turn */ 30 | METHOD(Car,public,void,turn,(float angle)) 31 | { 32 | } 33 | 34 | /* Override: add_speed */ 35 | METHOD(Car,public,void,add_speed,(float increment)) 36 | { 37 | if (increment > 0 && !W_CALL_VOID(self->engine,is_running)) 38 | W_CALL_VOID(self,start); 39 | W_CALL(self->engine,add_rotations)(increment); 40 | self->speed = W_CALL(self->engine,get_speed)(self->weight); 41 | printf("Car: Speed set to %f\n", self->speed); 42 | } 43 | 44 | #include 45 | -------------------------------------------------------------------------------- /examples/objects/vechiles/DieselEngine.c: -------------------------------------------------------------------------------- 1 | #include "forward_declare.h" 2 | #include "DieselEngine.h" 3 | #include "DieselEngine_class.h" 4 | #include 5 | 6 | CONSTRUCT(DieselEngine) 7 | { 8 | self->max_rotations=8000; 9 | self->min_rotations=1000; 10 | self->rotations=0; 11 | } 12 | 13 | /* Override: start */ 14 | METHOD(DieselEngine,public,void,start) 15 | { 16 | if (self->is_on) 17 | return; 18 | self->is_on = 1; 19 | self->rotations = self->min_rotations; 20 | printf("Diesel started: rotations=%d\n",self->rotations); 21 | } 22 | 23 | /* Override: stop */ 24 | METHOD(DieselEngine,public,void,stop) 25 | { 26 | if (!self->is_on) 27 | return; 28 | self->is_on = 0; 29 | self->rotations = 0; 30 | printf("Diesel stopped\n"); 31 | } 32 | 33 | #include 34 | -------------------------------------------------------------------------------- /examples/objects/vechiles/Engine.c: -------------------------------------------------------------------------------- 1 | #include "forward_declare.h" 2 | #include "Engine.h" 3 | #include "Engine_class.h" 4 | #include 5 | 6 | METHOD(Engine,public,void,stop) 7 | { 8 | } 9 | 10 | METHOD(Engine,public,int,is_running) 11 | { 12 | return self->is_on; 13 | } 14 | 15 | METHOD(Engine,public,void,start) 16 | { 17 | } 18 | 19 | METHOD(Engine,public,float,get_speed,(int weight)) 20 | { 21 | return ((float)self->rotations - self->min_rotations) / weight * 10.0f; 22 | } 23 | 24 | METHOD(Engine,public,void,add_rotations,(int increment)) 25 | { 26 | if (self->rotations + increment > self->max_rotations) { 27 | printf("Engine: max rotations reached\n"); 28 | self->rotations = self->max_rotations; 29 | } else if (self->rotations + increment < self->min_rotations) { 30 | printf("Engine: min rotations reached\n"); 31 | self->rotations = self->min_rotations; 32 | } else { 33 | self->rotations += increment; 34 | printf("Engine: rotations=%d\n", self->rotations); 35 | } 36 | } 37 | 38 | #include 39 | -------------------------------------------------------------------------------- /examples/objects/vechiles/JetEngine.c: -------------------------------------------------------------------------------- 1 | #include "forward_declare.h" 2 | #include "JetEngine.h" 3 | #include "JetEngine_class.h" 4 | #include 5 | 6 | /* Override: start */ 7 | METHOD(JetEngine,/*FIXME:is public?*/ public,/*FIXME:is void?*/void,start /*FIXME:has args?*/) 8 | { 9 | } 10 | 11 | /* Override: stop */ 12 | METHOD(JetEngine,/*FIXME:is public?*/ public,/*FIXME:is void?*/void,stop /*FIXME:has args?*/) 13 | { 14 | } 15 | 16 | #include 17 | -------------------------------------------------------------------------------- /examples/objects/vechiles/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = \ 2 | -I ../../.. \ 3 | -g \ 4 | 5 | CLASSES = $(wildcard *_class.h) 6 | SRCS = $(patsubst %_class.h,%.c,$(CLASSES)) 7 | HEADERS = $(patsubst %.c,%.h,$(SRCS)) 8 | OBJS = $(patsubst %.c,%.o,$(SRCS)) 9 | 10 | all: build_src 11 | 12 | build_src: classes.wobject 13 | ../../../tools/wobject classes.wobject 14 | echo "\nTo build type 'make test'" 15 | 16 | test: $(OBJS) test.o Vehicle_class.h 17 | cc -o test test.o $(OBJS) 18 | 19 | $(OBJS): $(SRCS) $(HEADERS) $(CLASSES) test.c 20 | cc -c $(CFLAGS) test.c $^ 21 | 22 | clean: 23 | rm -f test test.o $(OBJS) *.gch $(CLASSES) $(HEADERS) classes.h forward_declare.h 24 | -------------------------------------------------------------------------------- /examples/objects/vechiles/MotorVehicle.c: -------------------------------------------------------------------------------- 1 | #include "forward_declare.h" 2 | #include "MotorVehicle.h" 3 | #include "MotorVehicle_class.h" 4 | #include 5 | 6 | METHOD(MotorVehicle,public,void,stop) 7 | { 8 | } 9 | 10 | METHOD(MotorVehicle,public,void,start) 11 | { 12 | } 13 | 14 | #include 15 | -------------------------------------------------------------------------------- /examples/objects/vechiles/README.md: -------------------------------------------------------------------------------- 1 | # An example using wobject tool 2 | 3 | Run `make` to build the source code. `wobject` saves time since no boilerplate 4 | code has to be maintained. Run `make test` to build objects and an executable. 5 | The classes are generated using [this template](https://github.com/plainC/wondermacros/blob/master/examples/objects/vechiles/classes.wobject). 6 | -------------------------------------------------------------------------------- /examples/objects/vechiles/Vehicle.c: -------------------------------------------------------------------------------- 1 | #include "forward_declare.h" 2 | #include "Vehicle.h" 3 | #include "Vehicle_class.h" 4 | #include 5 | 6 | METHOD(Vehicle,public,void,add_speed,(float increment)) 7 | { 8 | } 9 | 10 | METHOD(Vehicle,public,void,turn,(float angle)) 11 | { 12 | } 13 | 14 | #include 15 | -------------------------------------------------------------------------------- /examples/objects/vechiles/classes.wobject: -------------------------------------------------------------------------------- 1 | #include all "vehicles.h" 2 | 3 | guard VEHICLES 4 | 5 | abstract class Engine 6 | public void start() 7 | public void stop() 8 | public int is_running() 9 | public void add_rotations(int increment) 10 | public float get_speed(int weight) 11 | public int is_on 12 | private int max_rotations 13 | private int min_rotations 14 | private int rotations 15 | 16 | class DieselEngine : Engine 17 | construct 18 | override start 19 | override stop 20 | 21 | class JetEngine : Engine 22 | override start 23 | override stop 24 | 25 | abstract class Vehicle 26 | public void turn(float angle) 27 | public void add_speed(float increment) 28 | public float x_pos 29 | public float y_pos 30 | public float speed 31 | public float direction 32 | 33 | uses Engine 34 | abstract class MotorVehicle : Vehicle 35 | public struct Engine* engine 36 | public void start() 37 | public void stop() 38 | 39 | class Bike : Vehicle 40 | override turn 41 | override add_speed 42 | 43 | uses DieselEngine 44 | class Car : MotorVehicle 45 | construct 46 | finalize 47 | override start 48 | override stop 49 | override turn 50 | override add_speed 51 | private int weight 52 | 53 | class Aircraft : MotorVehicle 54 | public void fly() 55 | public void land() 56 | override start 57 | override stop 58 | override turn 59 | override add_speed 60 | 61 | -------------------------------------------------------------------------------- /examples/objects/vechiles/source: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gcc -DWDEBUG_EXPAND=1 -E -P -I . -I ../../.. $1 | indent 4 | 5 | -------------------------------------------------------------------------------- /examples/objects/vechiles/test.c: -------------------------------------------------------------------------------- 1 | #include "vehicles.h" 2 | 3 | int main() 4 | { 5 | struct Vehicle* v1 = W_NEW(Car); 6 | 7 | W_CALL(v1,add_speed)(2500); 8 | W_CALL(v1,add_speed)(1500); 9 | W_CALL(v1,add_speed)(1500); 10 | W_CALL(v1,add_speed)(2500); 11 | W_CALL(v1,add_speed)(3500); 12 | } 13 | -------------------------------------------------------------------------------- /examples/objects/vechiles/vehicles.h: -------------------------------------------------------------------------------- 1 | #ifndef __VEHICLES_H 2 | #define __VEHICLES_H 3 | 4 | #define W_OBJECT_CAST_TO_VOID 5 | 6 | #include 7 | #include 8 | #include 9 | #include "classes.h" 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /examples/sorting/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -I . -I../.. -Wall -Wextra 2 | SRCS = $(wildcard *.c) 3 | PROGS = $(patsubst %.c,%,$(SRCS)) 4 | LIBS = 5 | 6 | all: $(PROGS) 7 | %: %.c 8 | $(CC) $(CFLAGS) -o $@ $< $(LIBS) 9 | 10 | run: $(PROGS) 11 | ./run.sh $(PROGS) 12 | 13 | 14 | clean: 15 | rm -f *~ $(PROGS) 16 | 17 | .PHONY: clean run 18 | -------------------------------------------------------------------------------- /examples/sorting/variadic_testing.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #undef COMPARE 4 | #define COMPARE strcmp 5 | 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | int 12 | main() 13 | { 14 | printf("is in equal: %d\n", W_VARIADIC_IS_EQUAL("a","a","a")); 15 | printf("is in equal: %d\n", W_VARIADIC_IS_EQUAL("a","b","c")); 16 | printf("is in ascending order: %d\n", W_VARIADIC_IS_IN_ASC_ORDER("a","b","c")); 17 | printf("is in ascending order: %d\n", W_VARIADIC_IS_IN_ASC_ORDER("a","c","b")); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /examples/tree/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -I . -I../.. 2 | SRCS = $(wildcard *.c) 3 | PROGS = $(patsubst %.c,%,$(SRCS)) 4 | LIBS = 5 | 6 | all: $(PROGS) 7 | %: %.c 8 | $(CC) $(CFLAGS) -o $@ $< $(LIBS) 9 | 10 | run: $(PROGS) 11 | ./run.sh $(PROGS) 12 | 13 | 14 | clean: 15 | rm -f *~ $(PROGS) 16 | 17 | .PHONY: clean run 18 | -------------------------------------------------------------------------------- /examples/tree/tree.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct bintree { 6 | struct bintree* next[2]; 7 | const char* value; 8 | }; 9 | 10 | static inline struct bintree* 11 | tree_new(const char* value) 12 | { 13 | struct bintree* t = malloc(sizeof(struct bintree)); 14 | 15 | t->value = value; 16 | t->next[0] = t->next[1] = NULL; 17 | return t; 18 | } 19 | 20 | #define LEFT 0 21 | #define RIGHT 1 22 | 23 | int main() 24 | { 25 | struct bintree* a = tree_new("a"); 26 | struct bintree* b = tree_new("b"); 27 | struct bintree* c = tree_new("c"); 28 | struct bintree* d = tree_new("d"); 29 | struct bintree* e = tree_new("e"); 30 | 31 | a->next[LEFT] = b; 32 | a->next[RIGHT] = e; 33 | b->next[LEFT] = c; 34 | c->next[LEFT] = d; 35 | 36 | printf("In preorder:\n"); 37 | W_TREE_FOR_EACH_PREORDER(struct bintree, node, a) 38 | printf("%s\n", node->value); 39 | 40 | printf("In postorder:\n"); 41 | W_TREE_FOR_EACH_POSTORDER(struct bintree, node, a) 42 | printf("%s\n", node->value); 43 | 44 | printf("In levelorder:\n"); 45 | W_TREE_FOR_EACH_LEVELORDER(struct bintree, node, a) 46 | printf("%s\n", node->value); 47 | 48 | W_TREE_FREE(struct bintree, a); 49 | } 50 | 51 | -------------------------------------------------------------------------------- /examples/x/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -I . -I../.. -Wall -Wextra 2 | SRCS = $(wildcard *.c) 3 | PROGS = $(patsubst %.c,%,$(SRCS)) 4 | LIBS = 5 | 6 | all: $(PROGS) 7 | %: %.c 8 | $(CC) $(CFLAGS) -o $@ $< $(LIBS) 9 | 10 | run: $(PROGS) 11 | ./run.sh $(PROGS) 12 | 13 | 14 | clean: 15 | rm -f *~ $(PROGS) 16 | 17 | .PHONY: clean run 18 | -------------------------------------------------------------------------------- /examples/x/case.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define W_XFILE "colors.h" 4 | #include 5 | 6 | #define W_XFILE "colors.h" 7 | #define W_NAME color_name 8 | #include 9 | 10 | void warm(int color) 11 | { 12 | printf("%s is warm\n", color_name[color]); 13 | } 14 | 15 | void cold(int color) 16 | { 17 | printf("%s is cold", color_name[color]); 18 | } 19 | 20 | int main() 21 | { 22 | int color = red; 23 | 24 | switch (color) { 25 | # define W_XFILE "colors.h" 26 | # define W_NAME_INDEX 0 27 | # define W_CODE_INDEX 2 28 | # define W_CODE_PREFIX printf("Let's see\n"); 29 | # define W_CODE_POSTFIX printf("Or is it?\n"); 30 | # include 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/x/colors.h: -------------------------------------------------------------------------------- 1 | XMACRO(blue,490,cold,const char* remarks;) 2 | XMACRO(green,560,warm,int extra;) 3 | XMACRO(red,700,warm,int is_dark;) 4 | XMACRO(violet,450,cold,) 5 | XMACRO(yellow,590,warm,) 6 | -------------------------------------------------------------------------------- /examples/x/enum.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define W_XFILE "colors.h" 4 | #include 5 | 6 | int main() 7 | { 8 | printf("%d %d %d\n", red, green, blue); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /examples/x/string_name.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define W_XFILE "colors.h" 4 | #include 5 | 6 | #define W_XFILE "colors.h" 7 | #define W_NAME color_names 8 | #include 9 | 10 | int main() 11 | { 12 | printf("%s %s %s\n", color_names[red], color_names[green], color_names[blue]); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /examples/x/struct.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define W_XFILE "colors.h" 5 | #define W_NAME color 6 | #define W_PREFIX 7 | #include 8 | 9 | 10 | #define W_XFILE "colors.h" 11 | #define W_NAME_INDEX 0 12 | #define W_CODE_INDEX 3 13 | #define W_COMMON enum color color; int r : 8; int g : 8; int b : 8; 14 | #include 15 | 16 | int main() 17 | { 18 | struct blue* b = malloc(sizeof(struct blue)); 19 | b->color = blue; 20 | b->r = 0; 21 | b->g = 0; 22 | b->b = 255; 23 | 24 | free(b); 25 | } 26 | -------------------------------------------------------------------------------- /examples/x/value_array.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define W_XFILE "colors.h" 4 | #include 5 | 6 | #define W_XFILE "colors.h" 7 | #define W_TYPE int 8 | #define W_NAME wavelength 9 | #define W_NAME_INDEX 1 10 | #include 11 | 12 | int main() 13 | { 14 | printf("%d %d %d\n", wavelength[red], wavelength[green], wavelength[blue]); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -I . -I .. -I ../.. -Wall -Wextra -Wno-unused-value -Wno-unused-variable 2 | SRCS = $(wildcard *.c) 3 | PROGS = $(patsubst %.c,%,$(SRCS)) 4 | LIBS = 5 | 6 | all: $(PROGS) 7 | %: %.c 8 | $(CC) $(CFLAGS) -o $@ $< $(LIBS) 9 | 10 | run: $(PROGS) 11 | ./run.sh $(PROGS) 12 | 13 | 14 | clean: 15 | rm -f *~ $(PROGS) 16 | 17 | .PHONY: clean run 18 | -------------------------------------------------------------------------------- /test/wondermacros.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | # include 5 | # include 6 | # include 7 | #endif 8 | 9 | #define W_XFILE 10 | #include 11 | -------------------------------------------------------------------------------- /tools/api_tool.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | if (defined $ARGV[0]) { 4 | docs($ARGV[0]); 5 | } else { 6 | @files = <*.h>; 7 | foreach $file (@files) { 8 | docs($file); 9 | } 10 | } 11 | 12 | sub docs { 13 | my $file = shift @_; 14 | open IN,$file; 15 | my $in_args = 0; 16 | while () { 17 | if (/\*\*\* Name:\s*(\w+)/) { 18 | $name = $1; 19 | } elsif (/\*\*\* Proto:\s*(\w+)(.*)/) { 20 | $proto_name = $1; 21 | $proto_args = $2; 22 | print "### $1$2\n"; 23 | } elsif (/\*\*\* Arg:\s*([^\s]+)\s+(.*)/) { 24 | if (not $in_args) { 25 | $in_args = 1; 26 | print "#### Arguments\n"; 27 | print "```C\n"; 28 | } 29 | $arg_id = $1; 30 | $arg_description = $2; 31 | printf "%-20s %s\n", $arg_id, $arg_description; 32 | } elsif (/\*\*\* Returns:\s+(.*)/) { 33 | print "#### Return Value\n"; 34 | print "$1\n"; 35 | } elsif (/\*\*\* Notes:\s+(.*)/) { 36 | print "#### Notes\n"; 37 | print "$1\n"; 38 | } elsif (/\*\*\* Example:\s+(.*)/) { 39 | print "#### Example\n"; 40 | print "```C\n"; 41 | print "$1\n"; 42 | print "```\n"; 43 | } elsif (/\*\*\* Description:\s+(.*)/) { 44 | if ($in_args) { 45 | $in_args = 0; 46 | print "```\n"; 47 | } 48 | print "#### Description\n"; 49 | print " $1\n"; 50 | } elsif (/\*\*\*\s+(.*)/) { 51 | print " $1\n"; 52 | } 53 | } 54 | close IN; 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /tools/cat.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $copyright= <<'END_COPYRIGHT'; 4 | /* (C) Copyright 2018 J.P. Iivonen 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation 8 | * files (the "Software"), to deal in the Software without 9 | * restriction, including without limitation the rights to use, 10 | * copy, modify, merge, publish, distribute, sublicense, and/or 11 | * sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following 13 | * conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 23 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | */ 27 | END_COPYRIGHT 28 | 29 | print "$copyright\n"; 30 | print "#include \n\n"; 31 | 32 | my $max = 8; 33 | if (defined $ARGV[0]) { 34 | $max = $ARGV[0]; 35 | } 36 | 37 | print "#define W_CAT(...) BOOST_PP_OVERLOAD(_W_CAT_,__VA_ARGS__)(__VA_ARGS__)\n\n"; 38 | for ($i=1; $i<=$max; $i++) { 39 | print "#define _W_CAT_$i("; 40 | for ($n=1; $n<=$i; $n++) { 41 | if ($n > 1) { 42 | print ","; 43 | } 44 | print "_$n"; 45 | } 46 | print ") "; 47 | for ($n=1; $n<=$i; $n++) { 48 | if ($n > 1) { 49 | print " ## "; 50 | } 51 | print "_$n"; 52 | } 53 | print "\n"; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /tools/stringize.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $copyright= <<'END_COPYRIGHT'; 4 | /* (C) Copyright 2018 J.P. Iivonen 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation 8 | * files (the "Software"), to deal in the Software without 9 | * restriction, including without limitation the rights to use, 10 | * copy, modify, merge, publish, distribute, sublicense, and/or 11 | * sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following 13 | * conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 23 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | */ 27 | END_COPYRIGHT 28 | 29 | print "$copyright\n"; 30 | print "#include \n\n"; 31 | 32 | my $max = 8; 33 | if (defined $ARGV[0]) { 34 | $max = $ARGV[0]; 35 | } 36 | 37 | print "#define W_STRINGIZE(...) BOOST_PP_OVERLOAD(_W_STRINGIZE_,__VA_ARGS__)(__VA_ARGS__)\n\n"; 38 | for ($i=1; $i<=$max; $i++) { 39 | print "#define _W_STRINGIZE_$i("; 40 | for ($n=1; $n<=$i; $n++) { 41 | if ($n > 1) { 42 | print ","; 43 | } 44 | print "_$n"; 45 | } 46 | print ") "; 47 | for ($n=1; $n<=$i; $n++) { 48 | print " # "; 49 | print "_$n"; 50 | } 51 | print "\n"; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /wondermacros/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Meta") 6 | 7 | #include 8 | 9 | 10 | 11 | /**/ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | -------------------------------------------------------------------------------- /wondermacros/array/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Other Array") 6 | 7 | #include 8 | #include 9 | 10 | /**/ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | -------------------------------------------------------------------------------- /wondermacros/array/get_size.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2018 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_ARRAY_GET_SIZE_H 26 | #define __W_ARRAY_GET_SIZE_H 27 | 28 | /*** 29 | *** Name: W_ARRAY_GET_SIZE 30 | *** Proto: W_ARRAY_GET_SIZE(a) 31 | *** 32 | *** Arg: a A static array 33 | *** 34 | *** Description: Use W_ARRAY_GET_SIZE to obtain the allocation size of a static array. 35 | *** Returns: The static allocation size of an array. 36 | *** Example: 'char foo[] = { 'a', 'b', 'c' }; printf("%d", W_ARRAY_GET_SIZE(foo));' prints '3'. 37 | ***/ 38 | #define W_ARRAY_GET_SIZE(a) \ 39 | ((sizeof(a) / sizeof((a)[0]))) 40 | 41 | 42 | /*Unit Test*/ 43 | 44 | #ifndef W_TEST 45 | # define W_TEST(...) 46 | #endif 47 | 48 | W_TEST(W_ARRAY_GET_SIZE, 49 | int array[] = { 1, 2, 3, 4, 5 }; 50 | W_TEST_ASSERT(W_ARRAY_GET_SIZE(array) == 5, "Array size"); 51 | ) 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /wondermacros/array/move_right.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2018 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_ARRAY_MOVE_RIGHT_H 26 | #define __W_ARRAY_MOVE_RIGHT_H 27 | 28 | #include 29 | 30 | /*** 31 | *** Name: W_ARRAY_MOVE_RIGHT 32 | *** Proto: W_ARRAY_MOVE_RIGHT(array,size,pos,offset) 33 | *** Arg: array a pointer to an array 34 | *** Arg: size size of the array 35 | *** Arg: pos start position (index) in the array 36 | *** Arg: offset steps to be moved 37 | *** Description: Use W_ARRAY_MOVE_RIGHT to move items in an array to right by given offset. 38 | ***/ 39 | #define W_ARRAY_MOVE_RIGHT(array,size,pos,offset) \ 40 | do { \ 41 | int W_ID(elems) = (size); \ 42 | int W_ID(step) = (offset); \ 43 | int W_ID(Pos) = (pos); \ 44 | for (int W_ID(i)=W_ID(elems)-1+W_ID(step); W_ID(i) >= W_ID(Pos)+W_ID(step); W_ID(i)--) \ 45 | (array)[W_ID(i)] = (array)[W_ID(i) - W_ID(step)]; \ 46 | } while (0) 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /wondermacros/binding/uml.h: -------------------------------------------------------------------------------- 1 | #define W_XMACRO 2 | 3 | digraph G { 4 | #include W_XFILE 5 | } 6 | 7 | -------------------------------------------------------------------------------- /wondermacros/comparison/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Comparison") 6 | 7 | #include 8 | #include 9 | -------------------------------------------------------------------------------- /wondermacros/configs/array_collection.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2018 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_ARRAY_COLLECTION_H 26 | #define __W_ARRAY_COLLECTION_H 27 | 28 | /* 29 | * Sets W_GET and W_SET macros to access normal C arrays. 30 | */ 31 | 32 | #ifndef W_GET 33 | # define W_GET(array,i) \ 34 | ((array)[i]) 35 | #endif 36 | 37 | #ifndef W_SET 38 | # define W_SET(array,i,val) \ 39 | W_GET(array,i) = (val) 40 | #endif 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /wondermacros/configs/compare.h: -------------------------------------------------------------------------------- 1 | #include "wondermacros/sorting/numeric_cmp.h" 2 | 3 | /* 4 | * By redefining W_COMPARE a different comparison method can be used. Use, for example, 5 | * strcmp for strings, or, W_NUMERIC_CMP_DESC for descending order for numeric types. 6 | */ 7 | #ifndef W_COMPARE 8 | # define W_COMPARE W_NUMERIC_CMP_ASC /* use numeric ascending order by default */ 9 | #endif 10 | 11 | -------------------------------------------------------------------------------- /wondermacros/configs/default_allocation.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef W_MALLOC 3 | # ifndef WDEBUG_EXPAND 4 | # include 5 | # endif 6 | # define W_MALLOC(size) malloc(size) 7 | #endif 8 | 9 | #ifndef W_MALLOC0 10 | # ifndef WDEBUG_EXPAND 11 | # include 12 | # endif 13 | # define W_MALLOC0(size) memset(malloc(size), 0, size) 14 | #endif 15 | 16 | #ifndef W_REALLOC 17 | # define W_REALLOC realloc 18 | #endif 19 | 20 | #ifndef W_FREE 21 | # define W_FREE free 22 | #endif 23 | 24 | #ifndef W_ERROR_ALLOCATION 25 | # define W_ERROR_ALLOCATION \ 26 | do { \ 27 | fprintf(stderr, "Unable to allocate memory.\n"); \ 28 | exit(1); \ 29 | } while (0) 30 | #endif 31 | -------------------------------------------------------------------------------- /wondermacros/configs/stack/README.md: -------------------------------------------------------------------------------- 1 | # Stack options 2 | 3 | Some macros support multiple types of stacks. Simplest stack is static 4 | array which cannot grow but has a check for overflow. Dynamic stack grows 5 | but uses heap (malloc/free). Dynamic alloca stack also grows and uses C 6 | stack with alloca. It may not be available on some systems. 7 | 8 | To choose a stack include the specific stack configuration before including 9 | the macro definitions. 10 | 11 | ## Static array stack 12 | 13 | Use the following include to use static array stack. 14 | 15 | ``` 16 | #include 17 | ``` 18 | 19 | This stack does not grow but has a check for stack overflow. In the case 20 | of overflow, `W_RAISE` is run. 21 | 22 | ## Dynamic stack 23 | 24 | Use the following include to use dynamic stack. 25 | 26 | ``` 27 | #include 28 | ``` 29 | 30 | This stack grows and uses heap allocations (malloc and free). In the case 31 | when allocation fails `W_RAISE` is run. 32 | 33 | ## Dynamic alloca 34 | 35 | Use the following include to use dynamic alloca stack. 36 | 37 | ``` 38 | #include 39 | ``` 40 | 41 | This stack grows and uses C stack with alloca. There is no check for alloca 42 | to fail but system most likely segmentation faults. Typically this is not 43 | an issue for most programs. Note that alloca may not be available on some 44 | systems. 45 | -------------------------------------------------------------------------------- /wondermacros/configs/stack/dynamic_heap_array.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2024 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | 26 | #ifndef WDEBUG_EXPAND 27 | # include 28 | # include 29 | #endif 30 | 31 | 32 | #ifndef WCONF_STACK 33 | # define WCONF_STACK 34 | #endif 35 | 36 | 37 | #undef WCONF_STACK_DECLARE_AND_INIT 38 | #define WCONF_STACK_DECLARE_AND_INIT W_DECLARE(0, void** stack = NULL) 39 | 40 | 41 | #undef WCONF_STACK_FREE 42 | #define WCONF_STACK_FREE W_DYNAMIC_STACK_FREE(stack) 43 | 44 | 45 | #undef WCONF_STACK_PUSH_PTR 46 | #define WCONF_STACK_PUSH_PTR(p) W_DYNAMIC_STACK_PUSH(stack, p) 47 | 48 | 49 | #undef WCONF_STACK_POP_PTR 50 | #define WCONF_STACK_POP_PTR() W_DYNAMIC_STACK_POP(stack) 51 | 52 | 53 | #undef WCONF_STACK_PEEK_PTR 54 | #define WCONF_STACK_PEEK_PTR() W_DYNAMIC_STACK_PEEK(stack) 55 | 56 | 57 | #undef WCONF_STACK_SWAP_PTRS 58 | #define WCONF_STACK_SWAP_PTRS(x, y) W_DYNAMIC_ARRAY_SWAP(void*, stack, x, y) 59 | -------------------------------------------------------------------------------- /wondermacros/exceptions/default_policy.h: -------------------------------------------------------------------------------- 1 | /* (C) is Copyright 2019 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #undef W_ERROR_ALLOCATION 25 | #define W_ERROR_ALLOCATION \ 26 | W_THROW(W_ERROR_CODE_ALLOCATION, "Unable to allocate") 27 | 28 | #ifndef __W_EXCEPTION_DEFAULT_POLICY_H 29 | #define __W_EXCEPTION_DEFAULT_POLICY_H 30 | 31 | #define W_ERROR_CODE_ALLOCATION 1 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /wondermacros/functions/README.md: -------------------------------------------------------------------------------- 1 | # Function helpers 2 | 3 | This directory contains some functions to help writing macros. 4 | In order to write an expression macro which returns a value, 5 | one often would need to use GCC specific extensions. This can 6 | be often avoided by using a helper function. The macro just 7 | provides type independent interface for the function. 8 | 9 | ## w_list_length 10 | 11 | Returns the length of the list. 12 | 13 | ``` 14 | static inline size_t w_list_length(void* list, size_t offset) 15 | ``` 16 | 17 | ## w_list_reel_to_last 18 | 19 | Returns the last item in a list, or NULL, if the list is empty. 20 | 21 | ``` 22 | static inline void* 23 | w_list_reel_to_last(void* list, size_t offset) 24 | ``` 25 | -------------------------------------------------------------------------------- /wondermacros/functions/list_length.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2024 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_LIST_LENGTH_H 26 | #define __W_LIST_LENGTH_H 27 | 28 | #include 29 | 30 | #include 31 | 32 | 33 | static inline size_t 34 | w_list_length(void* list, size_t offset) 35 | { 36 | size_t len = 0; 37 | while( list ) { 38 | list = *((void**) W_REF_VOID_PTR( list, offset )); 39 | len++; 40 | } 41 | return len; 42 | } 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /wondermacros/functions/list_reel_to_last.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2024 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_LIST_REEL_TO_LAST_H 26 | #define __W_LIST_REEL_TO_LAST_H 27 | 28 | #include 29 | 30 | #include 31 | 32 | 33 | static inline void* 34 | w_list_reel_to_last(void* list, size_t offset) 35 | { 36 | if( !list ) 37 | return NULL; 38 | void* next; 39 | while( (next = *((void**) W_REF_VOID_PTR( list, offset ))) ) 40 | list = next; 41 | return list; 42 | } 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /wondermacros/functions/log2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * https://graphics.stanford.edu/%7Eseander/bithacks.html 3 | */ 4 | #pragma once 5 | 6 | #include 7 | 8 | 9 | static inline unsigned 10 | w_log2(unsigned v) 11 | { 12 | const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; 13 | const unsigned int S[] = {1, 2, 4, 8, 16}; 14 | int i; 15 | 16 | register unsigned int r = 0; // result of log2(v) will go here 17 | for (i = 4; i >= 0; i--) { 18 | if (v & b[i]) { 19 | v >>= S[i]; 20 | r |= S[i]; 21 | } 22 | } 23 | return r; 24 | } 25 | -------------------------------------------------------------------------------- /wondermacros/functions/round_up_pow2.h: -------------------------------------------------------------------------------- 1 | #ifndef _W_ROUND_UP_POW2 2 | #define _W_ROUND_UP_POW2 3 | 4 | /* 5 | By Sean Eron Anderson 6 | seander@cs.stanford.edu 7 | Individually, the code snippets here are in the public domain 8 | (unless otherwise noted) — feel free to use them however you 9 | please. The aggregate collection and descriptions are 10 | © 1997-2005 Sean Eron Anderson. The code and descriptions are 11 | distributed in the hope that they will be useful, but WITHOUT 12 | ANY WARRANTY and without even the implied warranty of 13 | merchantability or fitness for a particular purpose. As of 14 | May 5, 2005, all the code has been tested thoroughly. Thousands 15 | of people have read it. Moreover, Professor Randal Bryant, the 16 | Dean of Computer Science at Carnegie Mellon University, has 17 | personally tested almost everything with his Uclid code 18 | verification system. What he hasn't tested, I have checked 19 | against all possible inputs on a 32-bit machine. To the first 20 | person to inform me of a legitimate bug in the code, I'll pay a 21 | bounty of US$10 (by check or Paypal). If directed to a charity, 22 | I'll pay US$20. 23 | 24 | https://graphics.stanford.edu/%7Eseander/bithacks.html#RoundUpPowerOf2 25 | */ 26 | 27 | #include 28 | 29 | 30 | static inline uint32_t 31 | w_round_up_pow2_uint32( uint32_t v ) 32 | { 33 | v--; 34 | v |= v >> 1; 35 | v |= v >> 2; 36 | v |= v >> 4; 37 | v |= v >> 8; 38 | v |= v >> 16; 39 | v++; 40 | return v; 41 | } 42 | 43 | 44 | static inline uint64_t 45 | w_round_up_pow2_uint64( uint64_t v ) 46 | { 47 | v--; 48 | v |= v >> 1; 49 | v |= v >> 2; 50 | v |= v >> 4; 51 | v |= v >> 8; 52 | v |= v >> 16; 53 | v |= v >> 32; 54 | v++; 55 | return v; 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /wondermacros/list/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Linked Lists") 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | -------------------------------------------------------------------------------- /wondermacros/math/abs.h: -------------------------------------------------------------------------------- 1 | /* (C) is Copyright 2015,2018 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_ABS_H 26 | #define __W_ABS_H 27 | 28 | #ifndef W_GE 29 | # define W_GE(a,b) ((a) >= (b)) 30 | #endif 31 | 32 | #ifndef W_ZERO 33 | # define W_ZERO 0 34 | #endif 35 | 36 | #ifndef W_NEG 37 | # define W_NEG(a) (-(a)) 38 | #endif 39 | 40 | /*** 41 | *** Name: W_ABS 42 | *** Proto: W_ABS(a) 43 | *** Arg: a a value 44 | *** Description: Use W_ABS to get the absolute value. 45 | *** Notes: Redefine W_GE, W_ZERO and W_NEG to change the default operators. 46 | ***/ 47 | #define W_ABS(a) (W_GE(a,W_ZERO) ? (a) : W_NEG(a)) 48 | 49 | /*Unit Test*/ 50 | 51 | #ifndef W_TEST 52 | # define W_TEST(...) 53 | #endif 54 | 55 | W_TEST(W_ABS, 56 | W_TEST_ASSERT(W_ABS(-1) == 1, "abs failed"); 57 | W_TEST_ASSERT(W_ABS(1) == 1, "abs failed"); 58 | ) 59 | 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /wondermacros/math/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Math") 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | -------------------------------------------------------------------------------- /wondermacros/math/log2.h: -------------------------------------------------------------------------------- 1 | /* (C) is Copyright 2024 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_LOG2_H 26 | #define __W_LOG2_H 27 | 28 | /*** 29 | *** Name: W_LOG2 30 | *** Proto: W_LOG2(a) 31 | *** Arg: a a value (32-bit unsigned) 32 | *** Description: Use W_LOG2 to get the logarithm of 2. 33 | ***/ 34 | #if __GNUC__ 35 | # define W_LOG2(x) ((x) ? 31-__builtin_clz(x) : 0) 36 | #else 37 | # include 38 | # define W_LOG2(x) (w_log2(x)) 39 | #endif 40 | 41 | /*Unit Test*/ 42 | 43 | #ifndef W_TEST 44 | # define W_TEST(...) 45 | #endif 46 | 47 | W_TEST(W_LOG2, 48 | W_TEST_ASSERT(W_LOG2(0) == 0, "failed"); 49 | W_TEST_ASSERT(W_LOG2(1) == 0, "failed"); 50 | W_TEST_ASSERT(W_LOG2(123) == 6, "failed"); 51 | W_TEST_ASSERT(W_LOG2(1000) == 9, "failed"); 52 | ) 53 | 54 | #endif 55 | 56 | -------------------------------------------------------------------------------- /wondermacros/math/sign.h: -------------------------------------------------------------------------------- 1 | /* (C) is Copyright 2019 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_SIGN_H 26 | #define __W_SIGN_H 27 | 28 | /*** 29 | *** Name: W_SIGN 30 | *** Proto: W_SIGN(x) 31 | *** Arg: x a numeric value 32 | *** Description: Use W_SIGN to get the sign of a number, i.g. -1 for negative, 0 for zero, and 1 for positive numbers. 33 | ***/ 34 | #define W_SIGN(x) (((x) > 0) - ((x) < 0)) 35 | 36 | /*Unit Test*/ 37 | 38 | #ifndef W_TEST 39 | # define W_TEST(...) 40 | #endif 41 | 42 | W_TEST(W_SIGN, 43 | W_TEST_ASSERT(W_SIGN(10) == 1, "sign failed"); 44 | W_TEST_ASSERT(W_SIGN(-12) == -1, "sign failed"); 45 | W_TEST_ASSERT(W_SIGN(0) == 0, "sign failed"); 46 | W_TEST_ASSERT(W_SIGN(-2.1) == -1, "sign failed"); 47 | ) 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /wondermacros/meta/all.h: -------------------------------------------------------------------------------- 1 | #undef W_TEST_SECTION 2 | #define W_TEST_SECTION "Meta" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | -------------------------------------------------------------------------------- /wondermacros/meta/id.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2015 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_ID_H 26 | #define __W_ID_H 27 | 28 | #include 29 | 30 | /*** 31 | *** Name: W_ID 32 | *** Proto: W_ID(id) 33 | *** Arg: id identifier name 34 | *** Description: Use W_ID to provide a more hygienic identifier name to be used in a macro. 35 | *** Returns: Expands to an identifier name. 36 | *** Notes: Uses the line number and a prefix to avoid name conflicts. Since a macro 37 | *** always expands to a single row all expansions will get the same line number. 38 | ***/ 39 | #define W_ID(id) \ 40 | BOOST_PP_CAT(W_ID_ ## id, __LINE__) 41 | 42 | /*Unit Test*/ 43 | 44 | #ifndef W_TEST 45 | # define W_TEST(...) 46 | #endif 47 | 48 | W_TEST(W_ID, 49 | int W_ID(i) = 42; W_TEST_ASSERT(W_ID(i) == 42, "Value mismatch"); 50 | ) 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /wondermacros/meta/label.h: -------------------------------------------------------------------------------- 1 | #ifndef __W_LABEL_H 2 | #define __W_LABEL_H 3 | 4 | /*** 5 | *** Name: W_LABEL 6 | *** Proto: W_LABEL(id1,id2) 7 | *** 8 | *** Arg: id1 label one 9 | *** Arg: id2 label one 10 | *** 11 | *** Description: Use W_LABEL to construct line-unique labels. 12 | ***/ 13 | #define W_LABEL(id1,id2) \ 14 | W_CAT(W_LABEL_ ## id1 ## _ ## id2 ## _, __LINE__) 15 | 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /wondermacros/meta/variadic_rest_n.h: -------------------------------------------------------------------------------- 1 | #ifndef __W_VARIADIC_REST_N_H 2 | #define __W_VARIADIC_REST_N_H 3 | 4 | #define W_VARIADIC_REST_N(n,...) W_CAT(_W_VARIADIC_REST_,n)(__VA_ARGS__) 5 | #define _W_VARIADIC_REST_0(_0,...) __VA_ARGS__ 6 | #define _W_VARIADIC_REST_1(_0,_1,...) __VA_ARGS__ 7 | #define _W_VARIADIC_REST_2(_0,_1,_2,...) __VA_ARGS__ 8 | #define _W_VARIADIC_REST_3(_0,_1,_2,_3,...) __VA_ARGS__ 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /wondermacros/meta/wrap.h: -------------------------------------------------------------------------------- 1 | #ifndef __W_WRAP_H 2 | #define __W_WRAP_H 3 | 4 | /* (C) Copyright 2018 J.P. Iivonen 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation 8 | * files (the "Software"), to deal in the Software without 9 | * restriction, including without limitation the rights to use, 10 | * copy, modify, merge, publish, distribute, sublicense, and/or 11 | * sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following 13 | * conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 23 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | */ 27 | 28 | #include 29 | 30 | /*** 31 | *** Name: W_WRAP 32 | *** Proto: W_WRAP(id,...) 33 | *** Arg: id The name of the macro being wrapped. 34 | *** Arg: ... The code of the macro. 35 | *** Description: Use W_WRAP to construct a macro having multiple statements. 36 | *** Typically such macros are written inside a 'do...while (0)' block. 37 | *** W_WRAP does that and adds the name of the macro to the code (id) in 38 | *** order to help the debugging phase. 39 | ***/ 40 | #define W_WRAP(id,...) \ 41 | do { __VA_ARGS__ } while (0 && BOOST_PP_STRINGIZE(id)) 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /wondermacros/misc/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Misc") 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | -------------------------------------------------------------------------------- /wondermacros/misc/struct_init.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2019 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_STRUCT_INIT_H 26 | #define __W_STRUCT_INIT_H 27 | 28 | /*** 29 | *** Name: W_STRUCT_INIT 30 | *** Proto: W_STRUCT_INIT(T,ptr,...) 31 | *** Arg: T a type name 32 | *** Arg: ptr a pointer to newly allocated memory of size T at minimum 33 | *** Arg: ... initial values for the structure (e.g. '.x=1, .y=2' or just '1,2') 34 | *** Description: Use W_STRUCT_INIT to initialize a newly allocated structure. 35 | ***/ 36 | #define W_STRUCT_INIT(T,ptr,...) \ 37 | memcpy(ptr, &((T) { __VA_ARGS__ }), sizeof(T)) 38 | 39 | 40 | /*Unit Test*/ 41 | 42 | #ifndef W_TEST 43 | # define W_TEST(...) 44 | #endif 45 | 46 | W_TEST(W_STRUCT_INIT, 47 | struct point { 48 | int x; 49 | int y; 50 | int z; 51 | }; 52 | struct point* p = malloc(sizeof(struct point)); 53 | W_STRUCT_INIT(struct point, p, .x=1, .y=2, .z=3); 54 | W_TEST_ASSERT(p->x == 1, "Value mismatch"); 55 | W_TEST_ASSERT(p->y == 2, "Value mismatch"); 56 | W_TEST_ASSERT(p->z == 3, "Value mismatch"); 57 | free(p); 58 | ) 59 | 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /wondermacros/misc/struct_new.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2019 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_STRUCT_NEW_H 26 | #define __W_STRUCT_NEW_H 27 | 28 | 29 | #ifndef W_MALLOC 30 | # define W_MALLOC malloc 31 | #endif 32 | 33 | 34 | /*** 35 | *** Name: W_STRUCT_NEW 36 | *** Proto: W_STRUCT_NEW(T,ptr,...) 37 | *** Arg: T a type name 38 | *** Arg: ... initial values for the structure (e.g. '.x=1, .y=2' or just '1,2') 39 | *** Description: Use W_STRUCT_NEW to allocate and initialize a structure. 40 | ***/ 41 | #define W_STRUCT_NEW(T,...) \ 42 | W_STRUCT_INIT(T,W_MALLOC(sizeof(T)),__VA_ARGS__) 43 | 44 | 45 | /*Unit Test*/ 46 | 47 | #ifndef W_TEST 48 | # define W_TEST(...) 49 | #endif 50 | 51 | W_TEST(W_STRUCT_NEW, 52 | struct point { 53 | int x; 54 | int y; 55 | int z; 56 | }; 57 | struct point* p = W_STRUCT_NEW(struct point, .x=1, .y=2, .z=3); 58 | W_TEST_ASSERT(p->x == 1, "Value mismatch"); 59 | W_TEST_ASSERT(p->y == 2, "Value mismatch"); 60 | W_TEST_ASSERT(p->z == 3, "Value mismatch"); 61 | free(p); 62 | ) 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /wondermacros/misc/unused.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2017 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_UNUSED_H 26 | #define __W_UNUSED_H 27 | 28 | /*** 29 | *** Name: W_UNUSED 30 | *** Proto: W_UNUSED(id) 31 | *** Arg: id a name of unused identifier. 32 | *** Description: Use W_UNUSED to kill a warning if an identifier is unused. 33 | ***/ 34 | #define W_UNUSED(id) \ 35 | do { \ 36 | (void) id; \ 37 | } while (0) 38 | 39 | /*Unit Test*/ 40 | 41 | #ifndef W_TEST 42 | # define W_TEST(...) 43 | #endif 44 | 45 | W_TEST(W_UNUSED, 46 | int unused; 47 | 48 | W_UNUSED(unused); /* should not issue a warning. */ 49 | ) 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /wondermacros/objects/json/bool.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | json_bool_to_string(bool* self, char* buffer, size_t size) 5 | { 6 | char tmp[256]; 7 | int len = sprintf(tmp, "%s", ((char*[]){"false","true"})[*self > 0]); 8 | 9 | if (len >= size) 10 | return -1; 11 | 12 | strncpy(buffer, tmp, len); 13 | 14 | return len; 15 | } 16 | 17 | int 18 | json_bool_from_string(const char* buffer, const char** endptr, const char* type_name, bool* self) 19 | { 20 | if (strncmp(buffer, "true", 4)==0) { 21 | *endptr = buffer + 4; 22 | *self = 1; 23 | } else if (strncmp(buffer, "false", 5)==0) { 24 | *endptr = buffer + 5; 25 | *self = 0; 26 | } else 27 | return 1; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /wondermacros/objects/json/boolean.c: -------------------------------------------------------------------------------- 1 | int 2 | json_boolean_to_string(int* self, char* buffer, size_t size) 3 | { 4 | char tmp[256]; 5 | int len = sprintf(tmp, "%s", ((char*[]){"false","true"})[*self > 0]); 6 | 7 | if (len >= size) 8 | return -1; 9 | 10 | strncpy(buffer, tmp, len); 11 | 12 | return len; 13 | } 14 | 15 | int 16 | json_boolean_from_string(const char* buffer, const char** endptr, const char* type_name, int* self) 17 | { 18 | if (strncmp(buffer, "true", 4)==0) { 19 | *endptr = buffer + 4; 20 | *self = 1; 21 | } else if (strncmp(buffer, "false", 5)==0) { 22 | *endptr = buffer + 5; 23 | *self = 0; 24 | } else 25 | return 1; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /wondermacros/objects/json/char.c: -------------------------------------------------------------------------------- 1 | int 2 | json_char_to_string(char* self, char* buffer, size_t size) 3 | { 4 | char tmp[256]; 5 | int len = sprintf(tmp, "%d", *self); 6 | 7 | if (len >= size) 8 | return -1; 9 | 10 | strncpy(buffer, tmp, len); 11 | 12 | return len; 13 | } 14 | 15 | int 16 | json_char_from_string(const char* buffer, const char** endptr, const char* type_name, char* self) 17 | { 18 | unsigned long value = strtoul(buffer, (char**) endptr, 10); 19 | 20 | if (value > 255) 21 | return 1; 22 | 23 | *self = (char) value; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /wondermacros/objects/json/double.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | json_double_to_string(double* self, char* buffer, size_t size) 5 | { 6 | char tmp[256]; 7 | int len = sprintf(tmp, "%g", *self); 8 | 9 | if (len >= size) 10 | return -1; 11 | 12 | strncpy(buffer, tmp, len); 13 | 14 | return len; 15 | } 16 | 17 | int 18 | json_double_from_string(const char* buffer, const char** endptr, const char* type_name, double* self) 19 | { 20 | double value = strtod(buffer, (char**) endptr); 21 | 22 | if (value == HUGE_VAL) 23 | return 1; 24 | 25 | *self = value; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /wondermacros/objects/json/dynamic_array_object.c: -------------------------------------------------------------------------------- 1 | int 2 | json_dynamic_array_object_to_string(struct Object** self, char* buffer, size_t size) 3 | { 4 | char tmp[4096]; 5 | char* p = tmp; 6 | *p++ = '['; 7 | W_DYNAMIC_ARRAY_FOR_EACH(struct Object*, o, self) { 8 | if (o_ix) 9 | *p++ = ','; 10 | int len = W_CALL(o,to_json)(p, 512); 11 | if (len >= size) 12 | return -1; 13 | p += len; 14 | } 15 | *p++ = ']'; 16 | 17 | return p-tmp; 18 | } 19 | 20 | #define SKIP_WS \ 21 | while (isspace(*p)) \ 22 | p++ 23 | 24 | #define ACCEPT(ch) \ 25 | if (*p++ == (ch)) \ 26 | {} \ 27 | else \ 28 | return 1 29 | 30 | #define READ_OBJECT(obj) \ 31 | do { \ 32 | obj = new_with(NULL); \ 33 | if (W_CALL(obj,from_json)(p,endptr)) \ 34 | return 1; \ 35 | p = *endptr; \ 36 | } while (0) 37 | 38 | 39 | int 40 | json_dynamic_array_object_from_string(const char* buffer, const char** endptr, const char* type_name, struct Object*** self) 41 | { 42 | const char* p = buffer; 43 | struct Object* obj; 44 | 45 | char name[strlen(type_name)]; 46 | strncpy(name,type_name,strlen(type_name)-1); 47 | name[strlen(type_name)-1] = '\0'; 48 | w_object_new_with_func new_with = w_class_lookup_new_by_name(name); 49 | 50 | if (!new_with) 51 | return 1; 52 | 53 | SKIP_WS; 54 | ACCEPT('['); 55 | SKIP_WS; 56 | *self = NULL; 57 | while (1) { 58 | READ_OBJECT(obj); 59 | 60 | W_DYNAMIC_ARRAY_PUSH(*self, obj); 61 | SKIP_WS; 62 | if (*p == ']') 63 | break; 64 | } 65 | 66 | ACCEPT(']'); 67 | SKIP_WS; 68 | *endptr = p; 69 | 70 | return 0; 71 | } 72 | 73 | #undef SKIP_WS 74 | #undef ACCEPT 75 | #undef READ_INT 76 | 77 | 78 | -------------------------------------------------------------------------------- /wondermacros/objects/json/float.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | json_float_to_string(float* self, char* buffer, size_t size) 5 | { 6 | char tmp[256]; 7 | int len = sprintf(tmp, "%g", *self); 8 | 9 | if (len >= size) 10 | return -1; 11 | 12 | strncpy(buffer, tmp, len); 13 | 14 | return len; 15 | } 16 | 17 | int 18 | json_float_from_string(const char* buffer, const char** endptr, const char* type_name, float* self) 19 | { 20 | float value = strtof(buffer, (char**) endptr); 21 | 22 | if (value == HUGE_VALF) 23 | return 1; 24 | 25 | *self = value; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /wondermacros/objects/json/int.c: -------------------------------------------------------------------------------- 1 | int 2 | json_int_to_string(int* self, char* buffer, size_t size) 3 | { 4 | char tmp[256]; 5 | int len = sprintf(tmp, "%d", *self); 6 | 7 | if (len >= size) 8 | return -1; 9 | 10 | strncpy(buffer, tmp, len); 11 | 12 | return len; 13 | } 14 | 15 | int 16 | json_int_from_string(const char* buffer, const char** endptr, const char* type_name, int* self) 17 | { 18 | long value = strtol(buffer, (char**) endptr, 10); 19 | 20 | if (value == LONG_MIN || value == LONG_MAX) 21 | return 1; 22 | 23 | *self = value; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /wondermacros/objects/json/int64.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | json_int64_to_string(int64_t* self, char* buffer, size_t size) 5 | { 6 | char tmp[256]; 7 | int len = sprintf(tmp, "%lld", *self); 8 | 9 | if (len >= size) 10 | return -1; 11 | 12 | strncpy(buffer, tmp, len); 13 | 14 | return len; 15 | } 16 | 17 | int 18 | json_int64_from_string(const char* buffer, const char** endptr, const char* type_name, int64_t* self) 19 | { 20 | int64_t value = strtoll(buffer, (char**) endptr, 10); 21 | 22 | if (value == LLONG_MIN || value == LLONG_MAX) 23 | return 1; 24 | 25 | *self = value; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /wondermacros/objects/json/int_array_2.c: -------------------------------------------------------------------------------- 1 | int 2 | json_int_array_2_to_string(int* self, char* buffer, size_t size) 3 | { 4 | char tmp[256]; 5 | int len = sprintf(tmp, "[%d,%d]", self[0], self[1]); 6 | 7 | if (len >= size) 8 | return -1; 9 | 10 | strncpy(buffer, tmp, len); 11 | 12 | return len; 13 | } 14 | 15 | #define SKIP_WS \ 16 | while (isspace(*p)) \ 17 | p++ 18 | 19 | #define ACCEPT(ch) \ 20 | if (*p++ == (ch)) \ 21 | {} \ 22 | else \ 23 | return 1 24 | 25 | #define READ_INT \ 26 | strtol(p, (char**) endptr, 10); \ 27 | if (!(value == LONG_MIN || value == LONG_MAX)) \ 28 | {p = *endptr;} \ 29 | else \ 30 | return 1 31 | 32 | int 33 | json_int_array_2_from_string(const char* buffer, const char** endptr, const char* type_name, int* self) 34 | { 35 | const char* p = buffer; 36 | long value; 37 | 38 | ACCEPT('['); 39 | SKIP_WS; 40 | value = READ_INT; 41 | self[0] = value; 42 | SKIP_WS; 43 | ACCEPT(','); 44 | SKIP_WS; 45 | value = READ_INT; 46 | self[1] = value; 47 | SKIP_WS; 48 | ACCEPT(']'); 49 | SKIP_WS; 50 | *endptr = p; 51 | 52 | return 0; 53 | } 54 | 55 | #undef SKIP_WS 56 | #undef ACCEPT 57 | #undef READ_INT 58 | 59 | 60 | -------------------------------------------------------------------------------- /wondermacros/objects/json/long_double.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | json_long_double_to_string(long double* self, char* buffer, size_t size) 5 | { 6 | char tmp[256]; 7 | int len = sprintf(tmp, "%Lg", *self); 8 | 9 | if (len >= size) 10 | return -1; 11 | 12 | strncpy(buffer, tmp, len); 13 | 14 | return len; 15 | } 16 | 17 | int 18 | json_long_double_from_string(const char* buffer, const char** endptr, const char* type_name, long double* self) 19 | { 20 | long double value = strtold(buffer, (char**) endptr); 21 | 22 | if (value == HUGE_VALL) 23 | return 1; 24 | 25 | *self = value; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /wondermacros/objects/json/object.c: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | #endif 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | int 10 | json_object_to_string(struct CLASS** self, char* buffer, size_t size) 11 | { 12 | if (!(*self)) { 13 | if (size < 5) 14 | return -1; 15 | strncpy(buffer,"null",4); 16 | buffer+=4; 17 | return 4; 18 | } 19 | 20 | return W_CALL(*self,to_json)(buffer,size); 21 | } 22 | 23 | int 24 | json_object_from_string(const char* buffer, const char** endptr, const char* type_name, struct CLASS** self) 25 | { 26 | /* The constructor of a class is responsible to create an initial empty object. */ 27 | if (!(*self)) { 28 | w_object_new_with_func new_with = w_class_lookup_new_by_name(type_name); 29 | printf("Lookup by: %s\n", type_name); 30 | if (!new_with) 31 | return 0; 32 | *self = new_with(NULL); 33 | if (!(*self)) 34 | return 0; 35 | } 36 | 37 | return W_CALL(*self,from_json)(buffer,endptr); 38 | } 39 | -------------------------------------------------------------------------------- /wondermacros/objects/json/string.c: -------------------------------------------------------------------------------- 1 | int 2 | json_string_to_string(char** self, char* buffer, size_t size) 3 | { 4 | if (!(*self)) { 5 | if (size < 4) 6 | return -1; 7 | else { 8 | strcpy(buffer, "null"); 9 | return 4; 10 | } 11 | } 12 | 13 | int len = strlen(*self); 14 | if (len+2 >= size) 15 | return -1; 16 | 17 | *buffer++ = '\"'; 18 | strncpy(buffer, *self, len); 19 | buffer += len; 20 | *buffer++ = '\"'; 21 | return len+2; 22 | } 23 | 24 | int 25 | json_string_from_string(const char* buffer, const char** endptr, const char* type_name, char** self) 26 | { 27 | const char* p = buffer; 28 | 29 | if (strncmp(p, "null", 4) == 0) { 30 | *self = NULL; 31 | *endptr += 4; 32 | return 0; 33 | } 34 | 35 | if (*p != '\"') 36 | return 1; 37 | ++p; 38 | const char* start = p; 39 | int backslash = 0; 40 | while (*p && (*p != '\"' || backslash)) { 41 | if (*p == '\\') 42 | backslash = !backslash; 43 | ++p; 44 | } 45 | if (*p != '\"') 46 | return 1; 47 | *self = strndup(start, p-start); 48 | *endptr = p+1; 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /wondermacros/objects/json/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __W_OBJECT_JSON_TYPES_H 2 | #define __W_OBJECT_JSON_TYPES_H 3 | 4 | #ifndef WDEBUG_EXPAND 5 | # include 6 | #endif 7 | 8 | struct w_json_class { 9 | int (*to_string)(void* self, char* buffer, size_t size); 10 | int (*from_string)(const char* buffer, const char** endptr, const char* type_name, void* self); 11 | }; 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /wondermacros/objects/json/unsigned.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | json_unsigned_to_string(unsigned* self, char* buffer, size_t size) 5 | { 6 | char tmp[256]; 7 | int len = sprintf(tmp, "%u", *self); 8 | 9 | if (len >= size) 10 | return -1; 11 | 12 | strncpy(buffer, tmp, len); 13 | 14 | return len; 15 | } 16 | 17 | int 18 | json_unsigned_from_string(const char* buffer, const char** endptr, const char* type_name, unsigned* self) 19 | { 20 | unsigned long value = strtoul(buffer, (char**) endptr, 10); 21 | 22 | *self = value; 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /wondermacros/objects/json/unsigned64.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | json_unsigned64_to_string(uint64_t* self, char* buffer, size_t size) 5 | { 6 | char tmp[256]; 7 | int len = sprintf(tmp, "%llu", *self); 8 | 9 | if (len >= size) 10 | return -1; 11 | 12 | strncpy(buffer, tmp, len); 13 | 14 | return len; 15 | } 16 | 17 | int 18 | json_unsigned64_from_string(const char* buffer, const char** endptr, const char* type_name, uint64_t* self) 19 | { 20 | unsigned long long value = strtoull(buffer, (char**) endptr, 10); 21 | 22 | *self = value; 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /wondermacros/objects/object.h: -------------------------------------------------------------------------------- 1 | #ifndef __W_OBJECTS_OBJECT_H 2 | #define __W_OBJECTS_OBJECT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #endif 10 | 11 | -------------------------------------------------------------------------------- /wondermacros/objects/object_name.h: -------------------------------------------------------------------------------- 1 | #undef CLASS 2 | #undef Object_t__define 3 | #undef Object__define 4 | #undef object_t__define 5 | #undef object__define 6 | 7 | #ifndef LOWERCASE_OBJECT 8 | # ifdef USE_T_TYPE_SUFFIX 9 | # define CLASS Object 10 | # define Object__define 11 | # define OBJECT_T Object_t 12 | # define CLASS_T Object__class_t 13 | # else 14 | # define CLASS Object 15 | # define Object__define 16 | # define OBJECT_T struct Object 17 | # define CLASS_T struct Object__class 18 | # endif 19 | #else 20 | # ifdef USE_T_TYPE_SUFFIX 21 | # define CLASS object 22 | # define object__define 23 | # define OBJECT_T object_t 24 | # define CLASS_T object__class_t 25 | # else 26 | # define CLASS object 27 | # define object__define 28 | # define OBJECT_T struct object 29 | # define CLASS_T struct object__class 30 | # endif 31 | #endif 32 | -------------------------------------------------------------------------------- /wondermacros/objects/x/README.md: -------------------------------------------------------------------------------- 1 | # X-macros for Object-oriented Type System 2 | 3 | ## Lower level includes 4 | 5 | ### class_struct.h 6 | 7 | Expands the struct defining the class. This struct holds the meta-data of the class, 8 | constructor, destructor, instance builder and the virtual function table. 9 | 10 | ### instance_struct.h 11 | 12 | Expands the struct defining an instance of the class. This struct holds all properties 13 | of an object and pointer to the class instance. 14 | 15 | ### class_instance.h 16 | 17 | Expands the class instance. Fills in the meta-data and the virtual function table. 18 | 19 | ### new.h 20 | 21 | Expands the object builder for the class. 22 | 23 | ### free.h 24 | 25 | Expands the object finalizer for the class. 26 | 27 | ### dup.h 28 | 29 | Expands the object copy function for the class. 30 | 31 | ### to_json.h 32 | 33 | Expands the object to JSON and from JSON conversion functions for the class. 34 | 35 | ## Higher level includes 36 | 37 | ### forward_declare.h 38 | 39 | Used to forward declare a class. 40 | 41 | ### class_declare.h 42 | 43 | Used to declare a class. 44 | 45 | ### class_start.h 46 | 47 | Used to start the class code. 48 | 49 | ### class_end.h 50 | 51 | Used to end the class code. 52 | -------------------------------------------------------------------------------- /wondermacros/objects/x/class_declare.h: -------------------------------------------------------------------------------- 1 | #define W_CLASS_DECLARE 2 | 3 | #ifdef TO_HEADER 4 | TO_HEADER 5 | #endif 6 | 7 | #ifdef INCLUDE_0 8 | # include INCLUDE_0 9 | #endif 10 | 11 | #ifdef INCLUDE_1 12 | # include INCLUDE_1 13 | #endif 14 | 15 | #ifdef INCLUDE_2 16 | # include INCLUDE_2 17 | #endif 18 | 19 | #ifdef INCLUDE_3 20 | # include INCLUDE_3 21 | #endif 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #ifdef BUILD_JSON 30 | # include 31 | #endif 32 | #include 33 | 34 | extern void* W_CAT(CLASS,__class_instance_ptr); 35 | 36 | #undef W_CLASS_DECLARE 37 | 38 | #undef CLASS 39 | #undef SUPER 40 | #undef ABSTRACT 41 | #undef NO_CONSTRUCT 42 | #undef NO_DESTRUCT 43 | #undef TO_HEADER 44 | #undef INCLUDE_0 45 | #undef INCLUDE_1 46 | #undef INCLUDE_2 47 | #undef INCLUDE_3 48 | 49 | -------------------------------------------------------------------------------- /wondermacros/objects/x/class_end.h: -------------------------------------------------------------------------------- 1 | #undef CONSTRUCT 2 | #undef FINALIZE 3 | 4 | 5 | #undef METHOD 6 | #undef _METHOD 7 | #undef _METHOD_1 8 | #undef _METHOD_2 9 | 10 | #define W_CLASS_GENERATE 11 | #include 12 | #undef W_CLASS_GENERATE 13 | 14 | #undef CLASS 15 | #undef SUPER 16 | #undef ABSTRACT 17 | #undef NO_CONSTRUCT 18 | #undef NO_DESTRUCT 19 | #undef TO_HEADER 20 | #undef INCLUDE_0 21 | #undef INCLUDE_1 22 | #undef INCLUDE_2 23 | #undef INCLUDE_3 24 | -------------------------------------------------------------------------------- /wondermacros/objects/x/class_start.h: -------------------------------------------------------------------------------- 1 | #define W_CLASS_GENERATE 2 | #include 3 | #include 4 | #include 5 | #undef W_CLASS_GENERATE 6 | 7 | #define W_CLASS_DECLARE 8 | #include 9 | #undef W_CLASS_DECLARE 10 | 11 | #define W_CLASS_GENERATE 12 | #include 13 | #include 14 | #include 15 | #ifdef BUILD_JSON 16 | # include 17 | #endif 18 | 19 | #include 20 | #undef W_CLASS_GENERATE 21 | 22 | #define CONSTRUCT(C) \ 23 | void W_CAT(C,___construct)(struct W_CAT(C,__private)* self) 24 | 25 | #define FINALIZE(C) \ 26 | void W_CAT(C,___finalize)(struct W_CAT(C,__private)* self) 27 | 28 | 29 | #define METHOD(C,P,type,...) \ 30 | BOOST_PP_OVERLOAD(_METHOD_,__VA_ARGS__)(C,P,type,__VA_ARGS__) 31 | #define _METHOD_1(C,P,type,name) \ 32 | _METHOD(C,P,type,name, struct W_CAT(C,__private)* self) 33 | #define _METHOD_2(C,P,type,name,args) \ 34 | _METHOD(C,P,type,name, struct W_CAT(C,__private)* self, BOOST_PP_REMOVE_PARENS(args)) 35 | #define _METHOD(C,P,type,name,...) type W_CAT(C,__,name) (__VA_ARGS__) 36 | -------------------------------------------------------------------------------- /wondermacros/objects/x/dup.h: -------------------------------------------------------------------------------- 1 | /* (C) is Copyright 2019 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | 35 | #ifndef CLASS 36 | # error "Macro CLASS is not defined" 37 | #endif 38 | 39 | 40 | 41 | struct CLASS* 42 | W_CAT(CLASS,_dup)(struct CLASS* data, int flags) 43 | #ifdef W_CLASS_DECLARE 44 | ; 45 | #endif 46 | #ifdef W_CLASS_GENERATE 47 | { 48 | struct W_CAT(CLASS,__private)* self = W_MALLOC(sizeof(struct W_CAT(CLASS,__private))); 49 | 50 | if (!self) 51 | W_ERROR_ALLOCATION; 52 | 53 | memcpy(self, data, sizeof(struct W_CAT(CLASS,__private))); 54 | 55 | #ifndef NO_CONSTRUCT 56 | # ifndef ABSTRACT 57 | if (flags & 1) 58 | W_CAT(CLASS,___construct)(self); 59 | # endif 60 | #endif 61 | 62 | return (struct CLASS*) self; 63 | } 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /wondermacros/objects/x/forward_declare.h: -------------------------------------------------------------------------------- 1 | #define W_FORWARD_DECLARE 2 | #include 3 | #include 4 | #undef W_FORWARD_DECLARE 5 | 6 | #undef CLASS 7 | #undef SUPER 8 | #undef ABSTRACT 9 | #undef NO_CONSTRUCT 10 | #undef NO_DESTRUCT 11 | #undef TO_HEADER 12 | #undef INCLUDE_0 13 | #undef INCLUDE_1 14 | #undef INCLUDE_2 15 | #undef INCLUDE_3 16 | 17 | -------------------------------------------------------------------------------- /wondermacros/objects/x/method_forward_declares.h: -------------------------------------------------------------------------------- 1 | /* (C) is Copyright 2019 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | 35 | #ifndef CLASS 36 | # error "Macro CLASS is not defined" 37 | #endif 38 | 39 | # define SIGNAL(...) 40 | # define VAR(...) 41 | # define OVERRIDE(...) 42 | # define METHOD(C,P,type,...) \ 43 | BOOST_PP_OVERLOAD(_METHOD_,__VA_ARGS__)(C,P,type,__VA_ARGS__) 44 | # define _METHOD_1(C,P,type,name) \ 45 | type W_CAT_INNER(CLASS,__,name)(struct W_CAT_INNER(CLASS,__private)* self); 46 | # define _METHOD_2(C,P,type,name,args) \ 47 | type W_CAT_INNER(CLASS,__,name)(struct W_CAT_INNER(CLASS,__private)* self, BOOST_PP_REMOVE_PARENS(args)); 48 | W_CAT(CLASS,__define) 49 | # undef OVERRIDE 50 | # undef METHOD 51 | # undef _METHOD_1 52 | # undef _METHOD_2 53 | # undef VAR 54 | # undef SIGNAL 55 | -------------------------------------------------------------------------------- /wondermacros/pointer/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Pointer Macros") 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | -------------------------------------------------------------------------------- /wondermacros/pointer/byte_offset.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2017 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_BYTE_OFFSET_H 26 | #define __W_BYTE_OFFSET_H 27 | 28 | /*** 29 | *** Name: W_BYTE_OFFSET 30 | *** Proto: W_BYTE_OFFSET(ptr1,ptr2) 31 | *** Arg: ptr1 a pointer 32 | *** Arg: ptr2 a pointer 33 | *** Description: Use W_BYTE_OFFSET to count the offset of two pointers. The offset is negative if ptr1 is before ptr2. 34 | ***/ 35 | #define W_BYTE_OFFSET(ptr1,ptr2) \ 36 | ((size_t) (((char*)(ptr1)) - ((char*)(ptr2)))) 37 | 38 | /*Unit Test*/ 39 | 40 | #ifndef W_TEST 41 | # define W_TEST(...) 42 | #endif 43 | 44 | W_TEST(W_BYTE_OFFSET, 45 | ) 46 | 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /wondermacros/pointer/container_of.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2018 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_CONTAINER_OF_H__ 26 | #define __W_CONTAINER_OF_H__ 27 | 28 | #define W_CONTAINER_OF(ptr,T,member) \ 29 | ( (T*) (((char*) (ptr)) - offsetof(T, member)) ) 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /wondermacros/pointer/hidden_of.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2018 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_HIDDEN_OF_H 26 | #define __W_HIDDEN_OF_H 27 | 28 | #include 29 | 30 | /*** 31 | *** Name: W_HIDDEN_CONTAINER_OF 32 | *** Proto: W_HIDDEN_CONTAINER_OF(ptr,T) 33 | *** Arg: ptr a pointer to a structure having a hidden header. 34 | *** Arg: T type of the hidden header. 35 | *** Description: Use W_HIDDEN_CONTAINER_OF to get a pointer to the actual container of on object having a hidden header. 36 | ***/ 37 | #define W_HIDDEN_CONTAINER_OF(ptr,T) ((T*) W_REF_VOID_PTR(ptr, -sizeof(T))) 38 | 39 | /*** 40 | *** Name: W_HIDDEN_OF 41 | *** Proto: W_HIDDEN_OF(ptr,T,member) 42 | *** Arg: ptr a pointer to a structure having a hidden header. 43 | *** Arg: T type of the hidden header. 44 | *** Arg: member member field name of the header. 45 | *** Description: Use W_HIDDEN_OF to get a value of a field in the hidden header of a structure. 46 | ***/ 47 | #define W_HIDDEN_OF(ptr,T,member) (W_HIDDEN_CONTAINER_OF(ptr,T)->member) 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /wondermacros/pointer/ref_void_ptr.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2017 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_REF_VOID_PTR_H 26 | #define __W_REF_VOID_PTR_H 27 | 28 | /*** 29 | *** Name: W_REF_VOID_PTR 30 | *** Proto: W_REF_VOID_PTR(ptr,offset) 31 | *** Arg: ptr a pointer to be referenced by an offset. 32 | *** Arg: offset an offset in bytes. 33 | *** Description: Use W_REF_VOID_PTR to reference a void pointer using an offset in bytes. 34 | ***/ 35 | #define W_REF_VOID_PTR(ptr,offset) \ 36 | ((void*)((char*) (ptr) + (offset))) 37 | 38 | /*Unit Test*/ 39 | 40 | #ifndef W_TEST 41 | # define W_TEST(...) 42 | #endif 43 | 44 | W_TEST(W_REF_VOID_PTR, 45 | int array[] = { 1, 2, 3 }; 46 | 47 | W_TEST_ASSERT(*((int*) W_REF_VOID_PTR(array,sizeof(int) * 1)) == 2, 48 | "Value mismatch"); 49 | W_TEST_ASSERT(*((int*) W_REF_VOID_PTR(array,sizeof(int) * 2)) == 3, 50 | "Value mismatch"); 51 | ) 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /wondermacros/pointer/values_as_array.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2024 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_VALUES_AS_ARRAY_H 26 | #define __W_VALUES_AS_ARRAY_H 27 | 28 | #include 29 | 30 | 31 | /*** 32 | *** Name: W_VALUES_AS_ARRAY 33 | *** Proto: W_VALUES_AS_ARRAY(T, ...) 34 | *** Arg: T element type of the array 35 | *** Arg: ... variadic number of values 36 | *** Description: Use W_VALUES_AS_ARRAY to get a stack reference to given values without declaring temporary variables. 37 | ***/ 38 | #define W_VALUES_AS_ARRAY(T, ...) \ 39 | ((T[BOOST_PP_VARIADIC_SIZE(__VA_ARGS__)]){__VA_ARGS__}) \ 40 | /**/ 41 | 42 | /*Unit Test*/ 43 | 44 | #ifndef W_TEST 45 | # define W_TEST(...) 46 | #endif 47 | 48 | W_TEST(W_VALUES_AS_ARRAY, 49 | for( int n=0; n<5; n++ ) 50 | W_TEST_ASSERT((W_VALUES_AS_ARRAY(int, 0, 1, 2, 3, 4)[n]) == n, 51 | "Value mismatch"); 52 | ) 53 | 54 | #endif 55 | 56 | -------------------------------------------------------------------------------- /wondermacros/pp_char/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Pre-Processor Strings (char sequences)") 6 | 7 | #include 8 | -------------------------------------------------------------------------------- /wondermacros/pp_math/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Pre-Processor Math Macros") 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | -------------------------------------------------------------------------------- /wondermacros/pp_math/even.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2021 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_PP_EVEN_H 26 | #define __W_PP_EVEN_H 27 | 28 | #include 29 | #include 30 | 31 | /*** 32 | *** Name: W_PP_EVEN 33 | *** Proto: W_PP_EVEN(a) 34 | *** Arg: a a constant integer between 0...255 35 | *** Description: Use W_PP_EVEN to check whether a constant value is even at pre-processing time. 36 | ***/ 37 | #define W_PP_EVEN(a) BOOST_PP_EQUAL(BOOST_PP_MOD(a, 2), 0) 38 | 39 | /*Unit Test*/ 40 | 41 | #ifndef W_TEST 42 | # define W_TEST(...) 43 | #endif 44 | 45 | W_TEST(W_PP_EVEN, 46 | #if W_PP_EVEN(2) == 1 47 | W_TEST_ASSERT(1, "ok"); 48 | #else 49 | W_TEST_ASSERT(0, "failed"); 50 | #endif 51 | 52 | #if W_PP_EVEN(3) == 0 53 | W_TEST_ASSERT(1, "ok"); 54 | #else 55 | W_TEST_ASSERT(0, "failed"); 56 | #endif 57 | ) 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /wondermacros/pp_math/max.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2019,2021,2024 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_PP_MAX_H 26 | #define __W_PP_MAX_H 27 | 28 | #include 29 | 30 | /*** 31 | *** Name: W_PP_MAX 32 | *** Proto: W_PP_MAX(...) 33 | *** Arg: ... a variadic number of integer arguments (up to eight arguments) between 0...255 34 | *** Description: Use W_PP_MAX to get the maximum value of given arguments at pre-processing time. 35 | ***/ 36 | #define W_PP_MAX(...) W_SEQ_MAX(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) 37 | 38 | /*Unit Test*/ 39 | 40 | #ifndef W_TEST 41 | # define W_TEST(...) 42 | #endif 43 | 44 | W_TEST(W_PP_MAX, 45 | #if W_PP_MAX(2,5) == 5 46 | W_TEST_ASSERT(1, "ok"); 47 | #else 48 | W_TEST_ASSERT(0, "failed"); 49 | #endif 50 | 51 | #if W_PP_MAX(8,4) == 8 52 | W_TEST_ASSERT(1, "ok"); 53 | #else 54 | W_TEST_ASSERT(0, "failed"); 55 | #endif 56 | ) 57 | 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /wondermacros/pp_math/median.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2021 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_PP_MEDIAN_H 26 | #define __W_PP_MEDIAN_H 27 | 28 | #include 29 | 30 | /*** 31 | *** Name: W_PP_MEDIAN 32 | *** Proto: W_PP_MEDIAN(...) 33 | *** Arg: ... variadic number of integer arguments (up to eight arguments) between 0...255 34 | *** Description: Use W_PP_MEDIAN to get the median of values of arguments at pre-processing time. The result is a boost sequence. If the given arguments contain even number of arguments, the result sequence has two values, the first one being less or equal to the second. For instance, W_PP_MEDIAN(5,2,7) returns (5) and W_PP_MEDIAN(7,2,4,5) returns (4)(5). 35 | ***/ 36 | #define W_PP_MEDIAN(...) \ 37 | W_SEQ_MEDIAN(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) 38 | 39 | /*Unit Test*/ 40 | 41 | #ifndef W_TEST 42 | # define W_TEST(...) 43 | #endif 44 | 45 | W_TEST(W_PP_MEDIAN, 46 | #if BOOST_PP_SEQ_ELEM(0, W_PP_MEDIAN(5,2,7)) == 5 47 | W_TEST_ASSERT(1, "ok"); 48 | #else 49 | W_TEST_ASSERT(0, "failed"); 50 | #endif 51 | ) 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /wondermacros/pp_math/odd.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2021 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_PP_ODD_H 26 | #define __W_PP_ODD_H 27 | 28 | #include 29 | #include 30 | 31 | /*** 32 | *** Name: W_PP_ODD 33 | *** Proto: W_PP_ODD(a) 34 | *** Arg: a a constant integer between 0...255 35 | *** Description: Use W_PP_ODD to check whether a constant value is odd at pre-processing time. 36 | ***/ 37 | #define W_PP_ODD(a) BOOST_PP_GREATER(BOOST_PP_MOD(a, 2), 0) 38 | 39 | /*Unit Test*/ 40 | 41 | #ifndef W_TEST 42 | # define W_TEST(...) 43 | #endif 44 | 45 | W_TEST(W_PP_ODD, 46 | #if W_PP_ODD(2) == 0 47 | W_TEST_ASSERT(1, "ok"); 48 | #else 49 | W_TEST_ASSERT(0, "failed"); 50 | #endif 51 | 52 | #if W_PP_ODD(3) == 1 53 | W_TEST_ASSERT(1, "ok"); 54 | #else 55 | W_TEST_ASSERT(0, "failed"); 56 | #endif 57 | ) 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /wondermacros/seq/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Pre-Processor Sequence Macros") 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | -------------------------------------------------------------------------------- /wondermacros/seq/max.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2021 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_SEQ_MAX_H 26 | #define __W_SEQ_MAX_H 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | /*** 34 | *** Name: W_SEQ_MAX 35 | *** Proto: W_SEQ_MAX(...) 36 | *** Arg: seq a Boost pre-processor sequence of integer values (up to six values) between 0...255 37 | *** Description: Use W_SEQ_MAX to get the maximum value in a given sequence at pre-processing time. 38 | ***/ 39 | #define W_SEQ_MAX(seq) \ 40 | BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)), W_SEQ_SORT(seq)) 41 | 42 | 43 | /*Unit Test*/ 44 | 45 | #ifndef W_TEST 46 | # define W_TEST(...) 47 | #endif 48 | 49 | W_TEST(W_SEQ_MAX, 50 | #if W_SEQ_MAX((5)(2)(7)(77)) == 77 51 | W_TEST_ASSERT(1, "ok"); 52 | #else 53 | W_TEST_ASSERT(0, "failed"); 54 | #endif 55 | ) 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /wondermacros/seq/min.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2021 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_SEQ_MIN_H 26 | #define __W_SEQ_MIN_H 27 | 28 | #include 29 | #include 30 | 31 | /*** 32 | *** Name: W_SEQ_MIN 33 | *** Proto: W_SEQ_MIN(...) 34 | *** Arg: seq a Boost pre-processor sequence of integer values (up to six values) between 0...255 35 | *** Description: Use W_SEQ_MIN to get the maximum value in a given sequence at pre-processing time. 36 | *** For example, W_SEQ_MIN((5)(2)(0)) expands to 0. 37 | ***/ 38 | #define W_SEQ_MIN(seq) \ 39 | BOOST_PP_SEQ_ELEM(0, W_SEQ_SORT(seq)) 40 | 41 | 42 | /*Unit Test*/ 43 | 44 | #ifndef W_TEST 45 | # define W_TEST(...) 46 | #endif 47 | 48 | W_TEST(W_SEQ_MIN, 49 | #if W_SEQ_MIN((5)(2)(7)(77)) == 2 50 | W_TEST_ASSERT(1, "ok"); 51 | #else 52 | W_TEST_ASSERT(0, "failed"); 53 | #endif 54 | ) 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /wondermacros/sorting/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Sorting") 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | -------------------------------------------------------------------------------- /wondermacros/sorting/pp_sort.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2021 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_PP_SORT_H 26 | #define __W_PP_SORT_H 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | /*** 33 | *** Name: W_PP_SORT 34 | *** Proto: W_PP_SORT(...) 35 | *** Arg: ... Variadic number of integer arguments (between 0 and 255) to be sorted (up to eight arguments). 36 | *** Description: Use W_PP_SORT to sort variadic number of arguments at pre-processing time. For example, W_PP_SORT(5,2,77,0) expands to 0,2,5,77. 37 | ***/ 38 | #define W_PP_SORT(...) BOOST_PP_SEQ_ENUM(W_SEQ_SORT(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))) 39 | 40 | 41 | /*Unit Test*/ 42 | 43 | #ifndef W_TEST 44 | # define W_TEST(...) 45 | #endif 46 | 47 | W_TEST(W_PP_SORT, 48 | #if BOOST_PP_SEQ_ELEM(2, BOOST_PP_VARIADIC_TO_SEQ(W_PP_SORT(5, 2, 0))) == 5 49 | W_TEST_ASSERT(1, "ok"); 50 | #else 51 | W_TEST_ASSERT(0, "failed"); 52 | #endif 53 | ) 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /wondermacros/sorting/swap.h: -------------------------------------------------------------------------------- 1 | /* (C) Copyright 2015 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __W_SWAP_H 26 | #define __W_SWAP_H 27 | 28 | #include 29 | 30 | /*** 31 | *** Name: W_SWAP 32 | *** Proto: W_SWAP(T,a,b) 33 | *** Arg: T type name The type of both a and b. 34 | *** Arg: a a value A value to be swapped 35 | *** Arg: b a value A value to be swapped 36 | *** Description: Use W_SWAP to swap the values of a and b. Neither of them can be constants. 37 | *** Notes: Both a and b are evaluated twice. 38 | ***/ 39 | #define W_SWAP(T, a, b) \ 40 | do { \ 41 | T W_ID(swap) = (a); \ 42 | (a) = (b); \ 43 | (b) = W_ID(swap); \ 44 | } while (0) 45 | 46 | /*Unit Test*/ 47 | 48 | #ifndef W_TEST 49 | # define W_TEST(...) 50 | #endif 51 | 52 | W_TEST(W_SWAP, 53 | int a=1, b=2; 54 | W_SWAP(int, a, b); 55 | W_TEST_ASSERT(a == 2 && b == 1, "Swap failed"); 56 | ) 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /wondermacros/string/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("String Macros") 6 | 7 | #include 8 | -------------------------------------------------------------------------------- /wondermacros/tree/all.h: -------------------------------------------------------------------------------- 1 | #ifndef W_TEST_GROUP 2 | # define W_TEST_GROUP(...) 3 | #endif 4 | 5 | W_TEST_GROUP("Trees") 6 | 7 | #include 8 | 9 | -------------------------------------------------------------------------------- /wondermacros/x/case.h: -------------------------------------------------------------------------------- 1 | /* (C) is Copyright 2019 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | 26 | #ifndef W_CODE_INDEX 27 | # error "W_CODE_INDEX not specified" 28 | #endif 29 | 30 | 31 | /**/ 32 | 33 | #ifndef W_PREFIX 34 | # define W_PREFIX 35 | #endif 36 | 37 | #ifndef W_POSTFIX 38 | # define W_POSTFIX 39 | #endif 40 | 41 | #ifndef W_STATIC 42 | # define W_STATIC 1 43 | #endif 44 | 45 | #ifndef W_NAME_INDEX 46 | # define W_NAME_INDEX 0 47 | #endif 48 | 49 | #ifndef W_CODE_PREFIX 50 | # define W_CODE_PREFIX 51 | #endif 52 | 53 | #ifndef W_CODE_POSTFIX 54 | # define W_CODE_POSTFIX 55 | #endif 56 | 57 | 58 | #ifndef W_CODE 59 | # define W_CODE(tag,code) code(tag); 60 | #endif 61 | 62 | 63 | #define W_CASE(name,code) \ 64 | case W_CAT(W_PREFIX,name,W_POSTFIX): { \ 65 | W_CODE_PREFIX W_CODE(W_CAT(W_PREFIX,name,W_POSTFIX),code) W_CODE_POSTFIX \ 66 | } \ 67 | break; 68 | 69 | 70 | #include 71 | 72 | /**/ 73 | #include W_XFILE 74 | /**/ 75 | 76 | #undef W_NAME 77 | #undef W_NAME_INDEX 78 | #undef W_XFILE 79 | #undef W_PREFIX 80 | #undef W_POSTFIX 81 | #undef W_VALUE 82 | #undef W_TYPE 83 | #undef W_STATIC 84 | #undef XMACRO 85 | -------------------------------------------------------------------------------- /wondermacros/x/struct.h: -------------------------------------------------------------------------------- 1 | /* (C) is Copyright 2019 J.P. Iivonen 2 | * 3 | * Permission is hereby granted, free of charge, to any person 4 | * obtaining a copy of this software and associated documentation 5 | * files (the "Software"), to deal in the Software without 6 | * restriction, including without limitation the rights to use, 7 | * copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following 10 | * conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | 26 | #ifndef W_CODE_INDEX 27 | # error "W_CODE_INDEX not specified" 28 | #endif 29 | 30 | 31 | /**/ 32 | 33 | #ifndef W_PREFIX 34 | # define W_PREFIX 35 | #endif 36 | 37 | #ifndef W_POSTFIX 38 | # define W_POSTFIX 39 | #endif 40 | 41 | #ifndef W_NAME_INDEX 42 | # define W_NAME_INDEX 0 43 | #endif 44 | 45 | #ifndef W_COMMON 46 | # define W_COMMON 47 | #endif 48 | 49 | #ifndef W_CODE 50 | # define W_CODE(name,code) code 51 | #endif 52 | 53 | 54 | #define W_CASE(name,code) \ 55 | struct W_CAT(W_PREFIX,name,W_POSTFIX) { \ 56 | W_COMMON W_CODE(W_CAT(W_PREFIX,name,W_POSTFIX),code) \ 57 | }; 58 | 59 | 60 | #include 61 | 62 | /**/ 63 | #ifdef W_XFILE 64 | # include W_XFILE 65 | #endif 66 | #ifdef W_XMACRO 67 | W_XMACRO 68 | #endif 69 | /**/ 70 | 71 | #undef W_NAME 72 | #undef W_NAME_INDEX 73 | #undef W_XFILE 74 | #undef W_PREFIX 75 | #undef W_POSTFIX 76 | #undef W_VALUE 77 | #undef W_TYPE 78 | #undef XMACRO 79 | -------------------------------------------------------------------------------- /wondermacros/x/unit_test.h: -------------------------------------------------------------------------------- 1 | #ifndef WDEBUG_EXPAND 2 | # include 3 | # include 4 | #endif 5 | 6 | #include 7 | #include 8 | 9 | #ifndef W_XFILE 10 | # error "W_XFILE not defined" 11 | #endif 12 | 13 | 14 | int 15 | main(int argc, char**argv) 16 | { 17 | W_UNUSED(argc); 18 | printf("Unit: %s\n\n", argv[0]); 19 | 20 | #include W_XFILE 21 | 22 | return 0; 23 | } 24 | --------------------------------------------------------------------------------