Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
2f96fd4
upd: создана наивная реализация push & pop + разработана структура стека
Mako-D Nov 25, 2023
b616dbb
Merge branch 'master' of https://github.com/Mako-D/prosoft-c-stack
Mako-D Nov 25, 2023
5743621
slv: first version of working stack
Mako-D Nov 26, 2023
81c1208
fix: remove capacity in stacks
Mako-D Nov 26, 2023
8567d9e
fix: remove reserved and isFree from stack_t
Mako-D Nov 26, 2023
1d29408
fix: free memory from popped node & remove g_table count check
Mako-D Nov 26, 2023
048941a
Create cmake-single-platform.yml
Mako-D Nov 26, 2023
6e5d2ae
Update cmake-single-platform.yml
Mako-D Nov 26, 2023
62bf86d
Update cmake-single-platform.yml
Mako-D Nov 26, 2023
ac48875
Update cmake-single-platform.yml
Mako-D Nov 26, 2023
b36ccad
Update cmake-single-platform.yml
Mako-D Nov 26, 2023
8214a99
Update cmake-single-platform.yml
Mako-D Nov 26, 2023
ce8ba93
Update cmake-single-platform.yml
Mako-D Nov 26, 2023
2c13d9a
fix: make STACK_TABLE_HANDLER signed int
Mako-D Nov 26, 2023
4aa1cf6
Merge branch 'master' of https://github.com/Mako-D/prosoft-c-stack
Mako-D Nov 26, 2023
433534f
style: init g_table in 1 line
Mako-D Nov 26, 2023
5d74d99
add: c-compiler version into CMakeLists.txt
Mako-D Nov 26, 2023
ec6a61c
fix: gcc isn't compiled
Mako-D Nov 26, 2023
4e22e4b
fix: gcc compile?
Mako-D Nov 27, 2023
488b92d
Update cmake-single-platform.yml
Mako-D Nov 27, 2023
4eadb04
fix: gcc, compile, please
Mako-D Nov 27, 2023
a7edeed
fix: add -Wno-error=missing-braces (gcc bag)
Mako-D Nov 27, 2023
a4e24ef
Update cmake-single-platform.yml
Mako-D Nov 27, 2023
7c60054
Update cmake-single-platform.yml
Mako-D Nov 27, 2023
9a8146e
Update cmake-single-platform.yml
Mako-D Nov 27, 2023
e24400b
Update cmake-single-platform.yml
Mako-D Nov 27, 2023
3e094de
Merge branch 'master' into homework
Mako-D Nov 27, 2023
2af6ce0
upd: comment PushBadArgs test
Mako-D Nov 27, 2023
53c15d4
fix+upd: comment PopBadArgs test
Mako-D Nov 27, 2023
5c4dea8
Merge branch 'homework' of https://github.com/Mako-D/prosoft-c-stack …
Mako-D Nov 28, 2023
dec995f
fix: add size of element of node and check this in pop; uncomment Pop…
Mako-D Nov 28, 2023
b0aafc7
fix+style: delete free(size) in node & put stack_valid_handler in funcs
Mako-D Nov 28, 2023
6187b68
upd: add in cmake -Wno-error=missing-braces
Mako-D Nov 28, 2023
f1150bb
fix: free nodes in stack by stack_free (leak memory)
Mako-D Nov 28, 2023
ef810cc
fix: stack_pop - change checking size of buffer from "strict equal" t…
Mako-D Nov 29, 2023
6255319
style: add _ to internal var in func
Mako-D Nov 30, 2023
235d2af
upd: delete pack wrap from structs
Mako-D Nov 30, 2023
bc0f203
style: add uniform placement of brackets and add some spaces
Mako-D Dec 1, 2023
cfec9ee
refactor+style: remove pointer creation in for; change the validation…
Mako-D Dec 1, 2023
5e5c8b2
fix (stack_size): doesn't create NULL in for
Mako-D Dec 1, 2023
16e9b6f
style: remove 'if-else' in validity check to one 'if'
Mako-D Dec 2, 2023
5fed38c
solve: review
Mako-D Dec 3, 2023
b86982c
fix: change gcc standard to c11
Mako-D Dec 3, 2023
8676232
style: correct test's names and correct stack_free(0) to stack_free(s…
Mako-D Dec 3, 2023
5761143
fix
Mako-D Dec 3, 2023
9808d05
fix
Mako-D Dec 3, 2023
7124f47
fix:: add macros "if" for memcpy and memcpy_s
Mako-D Dec 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/cmake-single-platform.yml
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
37 changes: 18 additions & 19 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
cmake_minimum_required(VERSION 3.22)
cmake_minimum_required(VERSION 3.20)
project(cstack)


enable_testing()

option(WITH_TEST "Build test (GTest library required)" OFF)
option(WITH_TEST "Build test (GTest library required)" ON)

include(FetchContent)

set(CMAKE_C_STANDARD_REQUIRED ON)

# build library
add_library(cstack STATIC cstack.c)

target_compile_features(cstack PUBLIC c_std_11)

# build test
if (WITH_TEST)
enable_testing()
Expand All @@ -28,21 +36,12 @@ if (WITH_TEST)
endif()

# compiler-specific project settings
if (MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(MSVC_FLAGS /Wall /WX)
target_compile_options(cstack PRIVATE ${MSVC_FLAGS})
target_link_options(cstack PRIVATE ${MSVC_FLAGS})
if (WITH_TEST)
target_compile_options(cstack_test PRIVATE /fsanitize=address)
target_compile_definitions(cstack_test PRIVATE _DISABLE_VECTOR_ANNOTATION)
endif()
else()
target_compile_options(cstack PRIVATE -Wall -Wextra -Wformat -Wformat-security -Werror)
set(SANITIZERS_FLAGS -fsanitize=undefined -fsanitize=address)
if (WITH_TEST)
target_compile_options(cstack_test PRIVATE ${SANITIZERS_FLAGS})
target_link_options(cstack_test PRIVATE ${SANITIZERS_FLAGS})
endif()
endif()

target_compile_options(cstack PRIVATE -Wall -Wextra -Wformat -Wformat-security -Werror -Wno-error=missing-braces -Wno-error=implicit-function-declaration)

set(SANITIZERS_FLAGS -fsanitize=undefined -fsanitize=address)

if (WITH_TEST)
target_compile_options(cstack_test PRIVATE ${SANITIZERS_FLAGS})
target_link_options(cstack_test PRIVATE ${SANITIZERS_FLAGS})
endif()
166 changes: 153 additions & 13 deletions cstack.c
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
Comment thread
Mako-D marked this conversation as resolved.
{
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;
Comment thread
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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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);

и пользуются дальше сколько угодно)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Но вообще, насколько это хорошая или плохая практика так делать? По сути, здесь в зависимости от компилятора, на котором будет собрана библиотека, можно ожидать немного разное поведение от программы. Такие вещи в принципе допустимы?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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;
}

Loading