-
Notifications
You must be signed in to change notification settings - Fork 0
Konstantin Makarov #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
2f96fd4
b616dbb
5743621
81c1208
8567d9e
1d29408
048941a
6e5d2ae
62bf86d
ac48875
b36ccad
8214a99
ce8ba93
2c13d9a
4aa1cf6
433534f
5d74d99
ec6a61c
4e22e4b
488b92d
4eadb04
a7edeed
a4e24ef
7c60054
9a8146e
e24400b
3e094de
2af6ce0
53c15d4
5c4dea8
dec995f
b0aafc7
6187b68
f1150bb
ef810cc
6255319
235d2af
bc0f203
cfec9ee
5e5c8b2
16e9b6f
5fed38c
b86982c
8676232
5761143
9808d05
7124f47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| name: testing_library | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ master ] | ||
| pull_request: | ||
| branches: [ master ] | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Install gtest manually | ||
| run: sudo apt-get install libgtest-dev && sudo apt-get install libgmock-dev && cd /usr/src/gtest && sudo cmake CMakeLists.txt && sudo make && sudo cp lib/*.a /usr/lib && sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a && sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a && sudo ln -s /usr/lib/libgmock.a /usr/local/lib/libgmock.a && sudo ln -s /usr/lib/libgmock_main.a /usr/local/lib/libgmock_main.a | ||
| - uses: actions/checkout@v1 | ||
| - name: configure | ||
| run: mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug .. | ||
| - name: make | ||
| run: cd build && make | ||
| - name: Run Test | ||
| run: /home/runner/work/prosoft-c-stack/prosoft-c-stack/build/cstack_test |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,42 +1,182 @@ | ||
| #include "cstack.h" | ||
|
|
||
| #include <stddef.h> | ||
| #include <stdlib.h> | ||
| #include <string.h> | ||
|
|
||
|
|
||
| // *** LIBRARY SETTINGS *** | ||
|
|
||
| #define STACK_TABLE_HANDLER 12 | ||
| #define UNUSED(VAR) (void)(VAR) | ||
|
|
||
| // ======================== | ||
|
|
||
| #pragma pack(1) | ||
| typedef struct node | ||
| { | ||
| void* data; | ||
| struct node* prev; | ||
| unsigned int size; | ||
| } node_t; | ||
| #pragma pack() | ||
|
|
||
| #pragma pack(1) | ||
| typedef struct stack | ||
| { | ||
| struct node* entry; | ||
| } stack_t; | ||
| #pragma pack() | ||
|
|
||
| #pragma pack(1) | ||
| typedef struct stack_entries_table | ||
| { | ||
| stack_t* stacks[STACK_TABLE_HANDLER]; | ||
| int count; | ||
| } stack_entries_table_t; | ||
| #pragma pack() | ||
|
|
||
| stack_entries_table_t g_table = {.stacks = NULL, .count = 0 }; | ||
|
|
||
| hstack_t stack_new(void) | ||
| { | ||
| return -1; | ||
| if(g_table.count == STACK_TABLE_HANDLER - 1) | ||
| { | ||
| return -1; | ||
| } | ||
|
|
||
| stack_t* _stack = (stack_t*)malloc(sizeof(stack_t)); | ||
|
|
||
| if (_stack == NULL) | ||
| { | ||
| return -1; | ||
| } | ||
|
|
||
| _stack->entry = NULL; | ||
| g_table.stacks[g_table.count] = _stack; | ||
|
Mako-D marked this conversation as resolved.
|
||
|
|
||
| return g_table.count++; | ||
| } | ||
|
|
||
| void stack_free(const hstack_t hstack) | ||
| { | ||
| UNUSED(hstack); | ||
| if (stack_valid_handler(hstack)) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| stack_t* _ptrStack = g_table.stacks[hstack]; | ||
|
|
||
| if (_ptrStack->entry != NULL) | ||
| { | ||
| node_t* _nextTopNode = (node_t*)NULL; | ||
| for (int _i = 0, _s = stack_size(hstack); _i < _s; ++_i) | ||
| { | ||
| _nextTopNode = _ptrStack->entry->prev; | ||
|
|
||
| free(_ptrStack->entry->data); | ||
| free(_ptrStack->entry); | ||
|
|
||
| _ptrStack->entry = _nextTopNode; | ||
| } | ||
|
|
||
| free(_ptrStack->entry); | ||
| } | ||
|
|
||
| free(_ptrStack); | ||
| g_table.stacks[hstack] = (stack_t*)NULL; | ||
| --g_table.count; | ||
| } | ||
|
|
||
| int stack_valid_handler(const hstack_t hstack) | ||
| { | ||
| UNUSED(hstack); | ||
| return 1; | ||
| if ((hstack < 0) || | ||
|
|
||
| (hstack >= STACK_TABLE_HANDLER) || | ||
|
|
||
| (g_table.stacks[hstack] == NULL)) | ||
| { | ||
| return 1; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| unsigned int stack_size(const hstack_t hstack) | ||
| { | ||
| UNUSED(hstack); | ||
| return 0; | ||
| if (stack_valid_handler(hstack)) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| int _i = 0; | ||
|
|
||
| for (node_t* _node = g_table.stacks[hstack]->entry; _node != (node_t*)NULL; _node = _node->prev) | ||
| { | ||
| ++_i; | ||
| } | ||
| return _i; | ||
| } | ||
|
|
||
| void stack_push(const hstack_t hstack, const void* data_in, const unsigned int size) | ||
| { | ||
| UNUSED(hstack); | ||
| UNUSED(data_in); | ||
| UNUSED(size); | ||
| if ((stack_valid_handler(hstack)) || | ||
|
|
||
| (data_in == NULL || size == 0)) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| node_t* _ptr = (node_t*)malloc(sizeof(node_t)); | ||
|
|
||
| if (_ptr == NULL) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| _ptr->size = size; | ||
| _ptr->data = malloc(size); | ||
|
|
||
| if (_ptr->data == NULL) | ||
| { | ||
| free(_ptr); | ||
| return; | ||
| } | ||
|
|
||
| #ifdef _MSC_VER | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Такие вещи обычно выносят в макрос или макро-функцию, пример: #ifdef _MSC_VER
#define CSTACK_MEMCPY(D, DZ, S, SZ) memspy_s(D, DZ, S, SZ)
#else
#define CSTACK_MEMCPY(D, DZ, S, SZ) memcpy(D, S, SZ)
#endif
CSTACK_MEMCPY(_ptr->data, _ptr->size, data_in, size);и пользуются дальше сколько угодно)
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Но вообще, насколько это хорошая или плохая практика так делать? По сути, здесь в зависимости от компилятора, на котором будет собрана библиотека, можно ожидать немного разное поведение от программы. Такие вещи в принципе допустимы?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если можно избежать макро-магии и прибивания гвоздями кода к платформе/компилятору/ОС/etc — стоит избегать. Конкретно в этом случае игра свеч все таки не стоит. Но иногда этого не избежать. |
||
| memcpy_s(_ptr->data, _ptr->size, data_in, size); | ||
| #else | ||
| memcpy(_ptr->data, data_in, size); | ||
| #endif | ||
|
|
||
| _ptr->prev = g_table.stacks[hstack]->entry; | ||
| g_table.stacks[hstack]->entry = _ptr; | ||
| } | ||
|
|
||
| unsigned int stack_pop(const hstack_t hstack, void* data_out, const unsigned int size) | ||
| { | ||
| UNUSED(hstack); | ||
| UNUSED(data_out); | ||
| UNUSED(size); | ||
| return 0; | ||
| if ((stack_valid_handler(hstack)) || | ||
|
|
||
| (data_out == NULL || size == 0) || | ||
|
|
||
| (g_table.stacks[hstack]->entry == NULL) || | ||
|
|
||
| (g_table.stacks[hstack]->entry->size > size)) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| #ifdef _MSC_VER | ||
| memcpy_s(data_out, size, g_table.stacks[hstack]->entry->data, g_table.stacks[hstack]->entry->size); | ||
| #else | ||
| memcpy(data_out, g_table.stacks[hstack]->entry->data, size); | ||
| #endif | ||
|
|
||
| node_t* _nextTopNode = g_table.stacks[hstack]->entry->prev; | ||
|
|
||
| free(g_table.stacks[hstack]->entry->data); | ||
| free(g_table.stacks[hstack]->entry); | ||
|
|
||
| g_table.stacks[hstack]->entry = _nextTopNode; | ||
| return size; | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.