diff --git a/.github/workflows/test_binding_cpp.yml b/.github/workflows/test_binding_cpp.yml new file mode 100644 index 000000000..203062445 --- /dev/null +++ b/.github/workflows/test_binding_cpp.yml @@ -0,0 +1,30 @@ +name: "Binding Tests: C++" + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + + build_clang: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: make + run: | + make CC=clang all + ./build/dice d20 + + build_cpp: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: make + run: | + make cpp diff --git a/Makefile b/Makefile index c8f7adc87..0d8ec2393 100644 --- a/Makefile +++ b/Makefile @@ -2,30 +2,38 @@ CODEDIRS=./src/grammar ./src/grammar/rolls ./src/grammar/util ./src/grammar/oper INCDIRS=./src/grammar CC=cc -OPT=-O3 -std=c99 -Wall -Wextra -Werror -pedantic -Wcast-align \ + +ifeq ($(CC),g++) + STANDARD= -std=c++11 +else ifeq ($(CC),clang++) + STANDARD= -std=c++11 +else + STANDARD= -std=c99 +endif + +OPT=-O3 $(STANDARD) -Wall -Wextra -Werror -pedantic -Wcast-align \ -Wcast-qual -Wdisabled-optimization -Winit-self \ -Wmissing-declarations -Wmissing-include-dirs \ -Wredundant-decls -Wshadow -Wsign-conversion \ - -Wundef -Wno-unused -Wformat=2 + -Wundef -Wno-unused -Wformat=2 + +# -ffast-math # Problematic for Python - # -ffast-math # Problematic for Python +# YACC/LEX fails for the following, so disabled: +# -Wswitch-default -Wstrict-overflow=5 + +# EMCC fails for the following, so disabled: +# -Wlogical-op # === DEBUG OPTIONS ==== DEBUG=0 ifeq ($(DEBUG), 1) OPT=-O0 -g # Valgrind info PARSER_DEBUG:=--debug --verbose -PARSER_DEBUG:= else PARSER_DEBUG:= endif -# YACC/LEX fails for the following, so disabled: -# -Wswitch-default -Wstrict-overflow=5 - -# EMCC fails for the following, so disabled: -# -Wlogical-op - USE_SECURE_RANDOM=0 ifeq ($(USE_SECURE_RANDOM), 1) #$(shell echo "Using Fast, but Cryptographically insecure random fn") @@ -101,7 +109,7 @@ compile: # Shared Lib shared: $(OBJECTS) $(CC) -shared -o build/dice.so $^ $(ARC4RANDOM) - + cp build/dice.so build/libdice.so # Linux mv ./a.out build/dice | true # Windows diff --git a/README.md b/README.md index df4b1a765..de984bd50 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ Many of our notation design decisions are explained in the documentation and com GNOLL was written to be the definitive solution to dice notation. The core has been written in C, but fear not! You can use GNOLL in many other programming languages too. ![C](https://img.shields.io/badge/c-%2300599C.svg?style=for-the-badge&logo=c&logoColor=white) +![C++](https://img.shields.io/badge/c++-%2300599C.svg?style=for-the-badge&logo=c%2B%2B&logoColor=white) ![Go](https://img.shields.io/badge/go-%2300ADD8.svg?style=for-the-badge&logo=go&logoColor=white) ![Java](https://img.shields.io/badge/java-%23ED8B00.svg?style=for-the-badge&logo=java&logoColor=white) ![JavaScript](https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge&logo=javascript&logoColor=%23F7DF1E) diff --git a/src/C++/main.cpp b/src/C++/main.cpp new file mode 100644 index 000000000..8bf53ac84 --- /dev/null +++ b/src/C++/main.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include "shared_header.h" + +int roll_full_options( + char* roll_request, + char* log_file, + int enable_verbosity, + int enable_introspection, + int enable_mocking, + int mocking_type, + int mocking_seed +); + +int main() +{ + const char* fn = "out.dice"; + + remove(fn); + + int err_code = roll_full_options( + strdup("1d20"), + strdup(fn), + 0, + 0, + 0, + 0, + 0 + ); + assert(err_code == 0); + + std::ifstream myfile; + myfile.open(fn); + std::string mystring; + if ( myfile.is_open() ) { + myfile >> mystring; + std::cout << mystring; + }else{ + return 1; + } + return 0; +} diff --git a/src/C++/target.mk b/src/C++/target.mk new file mode 100644 index 000000000..fe28da489 --- /dev/null +++ b/src/C++/target.mk @@ -0,0 +1,4 @@ +CXX?=g++ +cpp: all + $(CXX) src/C++/main.cpp -I src/grammar/ -ldice -Lbuild/ + LD_LIBRARY_PATH=$(PWD)/build/ ./a.out diff --git a/src/grammar/dice.lex b/src/grammar/dice.lex index 5bf33261a..7899f071e 100644 --- a/src/grammar/dice.lex +++ b/src/grammar/dice.lex @@ -23,8 +23,8 @@ /* TODO */ [A-Z_]+ { vec vector; - vector.symbols = safe_malloc(sizeof(char **)); - if(gnoll_errno){yyerror("Malloc Err");} + vector.symbols = (char**)safe_malloc(sizeof(char **)); + if(gnoll_errno){yyerror("Memory Err");} vector.symbols[0] = safe_strdup(yytext); if(gnoll_errno){yyerror("String Err");} @@ -38,7 +38,7 @@ [0-9]+ { vec vector; - vector.content = safe_malloc(sizeof(int)); + vector.content = (int*)safe_malloc(sizeof(int)); if(gnoll_errno){yyerror("Memory Err");} vector.content[0] = fast_atoi(yytext); @@ -71,7 +71,7 @@ d { vec vector; vector.dtype = SYMBOLIC; - vector.symbols = safe_malloc(sizeof(char **) * 6); + vector.symbols = (char**)safe_malloc(sizeof(char **) * 6); if(gnoll_errno){yyerror("Memory Err");} vector.symbols[0] = plus; vector.symbols[1] = zero; @@ -95,7 +95,7 @@ d { vec vector; vector.dtype = SYMBOLIC; - vector.symbols = safe_malloc(sizeof(char **) * 2); + vector.symbols = (char**)safe_malloc(sizeof(char **) * 2); if(gnoll_errno){yyerror("Memory Err");} vector.symbols[0] = plus; vector.symbols[1] = minus; @@ -118,7 +118,7 @@ d { vec vector; vector.dtype = SYMBOLIC; - vector.symbols = safe_malloc(sizeof(char **) * 3); + vector.symbols = (char**)safe_malloc(sizeof(char **) * 3); if(gnoll_errno){yyerror("Memory Err");} vector.symbols[0] = plus; vector.symbols[1] = zero; @@ -192,7 +192,7 @@ c { } u { vec vector; - vector.content = safe_malloc(sizeof(int)); + vector.content = (int*)safe_malloc(sizeof(int)); if(gnoll_errno){yyerror("Memory Err");} vector.content[0] = IS_UNIQUE; vector.dtype = NUMERIC; @@ -218,7 +218,7 @@ o { /* Comparitors */ \!\= { vec vector; - vector.content = safe_malloc(sizeof(int)); + vector.content = (int*)safe_malloc(sizeof(int)); if(gnoll_errno){yyerror("Memory Err");} vector.content[0] = NOT_EQUAL; vector.dtype = NUMERIC; @@ -228,7 +228,7 @@ o { } \=\= { vec vector; - vector.content = safe_malloc(sizeof(int)); + vector.content = (int*)safe_malloc(sizeof(int)); if(gnoll_errno){yyerror("Memory Err");} vector.content[0] = EQUALS; vector.dtype = NUMERIC; @@ -238,7 +238,7 @@ o { } \< { vec vector; - vector.content = safe_malloc(sizeof(int)); + vector.content = (int*)safe_malloc(sizeof(int)); if(gnoll_errno){yyerror("Memory Err");} vector.content[0] = LESS_THAN; vector.dtype = NUMERIC; @@ -248,7 +248,7 @@ o { } \> { vec vector; - vector.content = safe_malloc(sizeof(int)); + vector.content = (int*)safe_malloc(sizeof(int)); if(gnoll_errno){yyerror("Memory Err");} vector.content[0] = GREATER_THAN; vector.dtype = NUMERIC; @@ -258,7 +258,7 @@ o { } \<\= { vec vector; - vector.content = safe_malloc(sizeof(int)); + vector.content = (int*)safe_malloc(sizeof(int)); if(gnoll_errno){yyerror("Memory Err");} vector.content[0] = LESS_OR_EQUALS; vector.dtype = NUMERIC; @@ -268,7 +268,7 @@ o { } \>\= { vec vector; - vector.content = safe_malloc(sizeof(int)); + vector.content = (int*)safe_malloc(sizeof(int)); if(gnoll_errno){yyerror("Memory Err");} vector.content[0] = GREATER_OR_EQUALS; vector.dtype = NUMERIC; @@ -278,7 +278,7 @@ o { } is_even { vec vector; - vector.content = safe_malloc(sizeof(int)); + vector.content = (int*)safe_malloc(sizeof(int)); if(gnoll_errno){yyerror("Memory Err");} vector.content[0] = IF_EVEN; vector.dtype = NUMERIC; @@ -288,7 +288,7 @@ is_even { } is_odd { vec vector; - vector.content = safe_malloc(sizeof(int)); + vector.content = (int*)safe_malloc(sizeof(int)); if(gnoll_errno){yyerror("Memory Err");} vector.content[0] = IF_ODD; vector.dtype = NUMERIC; diff --git a/src/grammar/rolls/dice_logic.c b/src/grammar/rolls/dice_logic.c index f92983632..2e4cb7464 100644 --- a/src/grammar/rolls/dice_logic.c +++ b/src/grammar/rolls/dice_logic.c @@ -86,7 +86,7 @@ int* perform_roll(unsigned int number_of_dice, unsigned int die_sides, int explosion_condition_score = 0; int explosion_count = 0; - int* all_dice_roll = safe_calloc(number_of_dice, sizeof(int)); + int* all_dice_roll = (int*)safe_calloc(number_of_dice, sizeof(int)); if (gnoll_errno) { return 0; } diff --git a/src/grammar/rolls/sided_dice.c b/src/grammar/rolls/sided_dice.c index 82efcead9..57e697a41 100644 --- a/src/grammar/rolls/sided_dice.c +++ b/src/grammar/rolls/sided_dice.c @@ -56,7 +56,7 @@ void roll_symbolic_dice(vec* x, vec* y, vec* result) { rp.dtype = SYMBOLIC; rp.number_of_dice = num_dice; rp.die_sides = y->length; - rp.explode = 0; + rp.explode = (EXPLOSION_TYPE)0; rp.symbol_pool = NULL; // Copy over memory to Symbol Pool for reloading diff --git a/src/grammar/shared_header.h b/src/grammar/shared_header.h index bd5ed5a47..0a0747420 100644 --- a/src/grammar/shared_header.h +++ b/src/grammar/shared_header.h @@ -1,6 +1,11 @@ #ifndef SHARED_YACC_HEADER #define SHARED_YACC_HEADER +#ifdef __cplusplus +extern "C" +{ +#endif + #include "rolls/sided_dice.h" #include "util/vector_functions.h" @@ -20,4 +25,8 @@ int roll_and_write(char* s, char* f); void roll_and_write_R(int* return_code, char** s, char** f ); int mock_roll(char* s, char* f, int mock_value, int mock_const); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/grammar/util/safe_functions.c b/src/grammar/util/safe_functions.c index 1812556f4..bf1ed9dcc 100644 --- a/src/grammar/util/safe_functions.c +++ b/src/grammar/util/safe_functions.c @@ -57,13 +57,13 @@ void safe_copy_2d_chararray_with_allocation(char ***dst, char **src, * @param item * @param max_size */ - *dst = safe_calloc(items, sizeof(char **)); + *dst = (char**)safe_calloc(items, sizeof(char **)); if (gnoll_errno) { return; } for (unsigned int i = 0; i != items; i++) { - (*dst)[i] = safe_calloc(sizeof(char), max_size); + (*dst)[i] = (char*)safe_calloc(sizeof(char), max_size); if (gnoll_errno) { return; } @@ -125,7 +125,7 @@ char *safe_strdup(const char *str1) { } char *result; unsigned int l = strlen(str1) + 1; //+1 for \0 - result = safe_calloc(sizeof(char), l); + result = (char*) safe_calloc(sizeof(char), l); result = strcpy(result, str1); if (result == 0) { gnoll_errno = BAD_STRING; diff --git a/src/grammar/util/vector_functions.c b/src/grammar/util/vector_functions.c index f072e04f0..12f846a3a 100644 --- a/src/grammar/util/vector_functions.c +++ b/src/grammar/util/vector_functions.c @@ -25,10 +25,10 @@ void light_initialize_vector(vec *vector, DIE_TYPE dt, vector->length = number_of_items; if (dt == NUMERIC) { - vector->content = safe_calloc(number_of_items, sizeof(int)); + vector->content = (int*)safe_calloc(number_of_items, sizeof(int)); if (gnoll_errno) return; } else if (dt == SYMBOLIC) { - vector->symbols = safe_calloc(1, sizeof(char **)); + vector->symbols = (char**)safe_calloc(1, sizeof(char **)); } } void initialize_vector(vec *vector, DIE_TYPE dt, unsigned int number_of_items) { @@ -47,14 +47,14 @@ void initialize_vector(vec *vector, DIE_TYPE dt, unsigned int number_of_items) { vector->length = number_of_items; if (dt == NUMERIC) { - vector->content = safe_calloc(number_of_items, sizeof(int)); + vector->content = (int*)safe_calloc(number_of_items, sizeof(int)); if (gnoll_errno) return; } else if (dt == SYMBOLIC) { - vector->symbols = safe_calloc(number_of_items, sizeof(char *)); + vector->symbols = (char**)safe_calloc(number_of_items, sizeof(char *)); if (gnoll_errno) return; for (unsigned int i = 0; i < number_of_items; i++) { - vector->symbols[i] = safe_calloc(MAX_SYMBOL_LENGTH, sizeof(char)); + vector->symbols[i] = (char*)safe_calloc(MAX_SYMBOL_LENGTH, sizeof(char)); if (gnoll_errno) return; } } @@ -218,7 +218,7 @@ void collapse_vector(vec *vector, vec *new_vector) { c += vector->content[i]; } - new_vector->content = safe_calloc(sizeof(int), 1); + new_vector->content = (int*)safe_calloc(sizeof(int), 1); if (gnoll_errno) return; new_vector->content[0] = c; new_vector->length = 1; @@ -248,7 +248,7 @@ void keep_logic(vec *vector, vec *new_vector, unsigned int number_to_keep, } unsigned int available_amount = vector->length; if (available_amount > number_to_keep) { - new_vector->content = safe_calloc(sizeof(int), number_to_keep); + new_vector->content = (int*)safe_calloc(sizeof(int), number_to_keep); if (gnoll_errno) { return; } @@ -266,7 +266,7 @@ void keep_logic(vec *vector, vec *new_vector, unsigned int number_to_keep, m = min_in_vec(arr, length); } new_vector->content[i] = m; - new_arr = safe_calloc(sizeof(int), length - 1); + new_arr = (int*)safe_calloc(sizeof(int), length - 1); if (gnoll_errno) { return; }