diff --git a/examples/libc99/libc99.c b/examples/libc99/libc99.c index 6256153..b826b70 100644 --- a/examples/libc99/libc99.c +++ b/examples/libc99/libc99.c @@ -2,27 +2,203 @@ #include #include -Test_struct1* new_test_struct(int c_int, Test_enum c_enum, const char* c_str) -{ - Test_struct1* result = calloc(1, sizeof(Test_struct1)); - if (result) { - result->c_int = c_int; - result->c_enum = c_enum; - if (c_str) { - result->c_str = strdup(c_str); - if (result->c_str == NULL) { - free_test_struct(result); - return NULL; - } - } +C99_C* c99_C_new() +{ + C99_C* ret = calloc(1, sizeof(C99_C)); + return ret; +} + +void c99_C_free(C99_C* c) +{ + if (c) { + free(c->pi); + free(c); + } +} + +C99_B* c99_B_new() +{ + C99_B* result = calloc(1, sizeof(C99_B)); + return result; +} + +void c99_B_free(C99_B* b) +{ + if (b) { + c99_C_free(b->c); + free(b); } +} + +C99_A* c99_A_new() +{ + C99_A* result = calloc(1, sizeof(C99_A)); return result; } -void free_test_struct(Test_struct1* c_struct) +void c99_A_free(C99_A* a) +{ + if (a) { + c99_B_free(a->b); + c99_A_free(a); + } +} + + +// ------------------------------------------------------------------------------------------------- +// USE +// --- +// dont do anything +C99_Status c99_use_basic(int basic) +{ + return OK; +} +C99_Status c99_use_struct(const C99_A* a) +{ + if (!a) { + return ERROR; + } + return OK; +} +C99_Status c99_use_string(const char* c_str) +{ + if (!c_str) { + return ERROR; + } + return OK; +} + + +// SUPPLY +// ------ +// modify value +C99_Status c99_supply_basic(int* basic) +{ + if (!basic) { + return ERROR; + } + + *basic *= 2; + return OK; +} + +// modify struct elem +// Replace object in a struct +C99_Status c99_supply_struct(C99_A* a) { - if (c_struct) { - free(c_struct->c_str); - free(c_struct); + // validate input + if (!a) { + return ERROR; } + if (!a->b) { + return ERROR; + } + if (!a->b->c) { + return ERROR; + } + if (!a->b->c->pi) { + return ERROR; + } + + // get current value + int curr_val = *(a->b->c->pi); + // calculate new value + int new_val = curr_val * 2; + + // replace with new object + c99_B_free(a->b); + a->b = c99_B_new(); + a->b->c = c99_C_new(); + a->b->c->pi = calloc(1, sizeof(int)); + *a->b->c->pi = new_val; + + return OK; +} + +// prepend pEp +C99_Status c99_supply_string(char** c_str) +{ + if (!c_str) { + return ERROR; + } + if (!*c_str) { + return ERROR; + } + + char pEp[] = "pEp"; + size_t pEp_len = strlen(pEp); + size_t c_str_len = strlen(*c_str); + char* new_str = (char*)malloc(c_str_len + pEp_len); + memcpy(new_str, pEp, pEp_len); + memcpy(new_str + pEp_len, *c_str, c_str_len); + free(*c_str); + c_str = &new_str; + return OK; } + +// PROVIDE +// ------- +// dont do anything +C99_Status c99_provide_basic(int basic) +{ + return OK; +} + +// use and free the struct +C99_Status c99_provide_struct(C99_A* a) +{ + if (!a) { + return ERROR; + } + c99_A_free(a); + return OK; +} + +// use and free the string +C99_Status c99_provide_string(char* c_str) +{ + if (!c_str) { + return ERROR; + } + free(c_str); + return OK; +} + +// RETURN +// ------ +// create a new instance and return it +C99_Status c99_return_basic(int** basic) +{ + if (!basic) { + return ERROR; + } + *basic = NULL; + int* new_basic = calloc(1, sizeof(int)); + *basic = new_basic; + return OK; +} + +// create a new instance and return it +C99_Status c99_return_struct(C99_A** a) +{ + if (!a) { + return ERROR; + } + *a = NULL; + C99_A* new_a = c99_A_new(); + *a = new_a; + return OK; +} + +// create a new instance and return it +C99_Status c99_return_string(char** c_str) +{ + if (!c_str) { + return ERROR; + } + + *c_str = NULL; + char* new_str = strdup("pEp"); + *c_str = new_str; + return OK; +} \ No newline at end of file diff --git a/examples/libc99/libc99.h b/examples/libc99/libc99.h index 3437999..74f9d41 100644 --- a/examples/libc99/libc99.h +++ b/examples/libc99/libc99.h @@ -10,31 +10,81 @@ #ifdef __cplusplus extern "C" { #endif + typedef enum + { + OK, + ERROR + } C99_Status; typedef enum { ONE, TWO, THREE - } Test_enum; + } C99_Enum; + + + typedef struct { + int i; + int* pi; + } C99_C; + C99_C* c99_C_new(); + void c99_C_free(C99_C* c); typedef struct { - int c_int; - Test_enum c_enum; - char* c_str; - } Test_struct1; + C99_C* c; + } C99_B; + C99_B* c99_B_new(); + void c99_B_free(C99_B* b); + typedef struct { - int c_int; - Test_enum c_enum; - char* c_str; - Test_struct1* c_struct1; - } Test_struct2; + C99_B* b; + } C99_A; + C99_A* c99_A_new(); + void c99_A_free(C99_A* a); + + + // calling conventions + // ------------------- + // use + // readonly in parm, ownership remains with caller + // create/own a full instance -> operator const T*() + // const T* / T + C99_Status c99_use_basic(int basic); + C99_Status c99_use_struct(const C99_A* a); + C99_Status c99_use_string(const char* c_str); + + // supply + // inout parm, ownership remains with caller + // the function changes the value of the object, but not the object itself + // create/own a full instance -> operator T* + // T* + C99_Status c99_supply_basic(int* basic); + C99_Status c99_supply_struct(C99_A* a); + C99_Status c99_supply_string(char** c_str); + + // provide + // in parm, ownership goes to callee + // same as 'use', but ownership goes to callee + // create/own a full instance -> release ownership -> operator T* + // T / T* (release ownership) + C99_Status c99_provide_basic(int basic); + C99_Status c99_provide_struct(C99_A* a); + C99_Status c99_provide_string(char* c_str); + // return + // out parm, ownership goes to caller + // T** will not be freed by the function, + // create/own an empty instance -> operator T** + // T** (must not point to mem which has to be freed first) + C99_Status c99_return_basic(int** basic); + C99_Status c99_return_struct(C99_A** a); + C99_Status c99_return_string(char** c_str); - Test_struct1* new_test_struct(int c_int, Test_enum c_enum, const char* c_str); + // create + // factory delivers this, ownership goes to caller - void free_test_struct(Test_struct1* c_struct); #ifdef __cplusplus } #endif