Implement DMOD environment variables manager with context-based API and inheritance#1
Conversation
Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
JohnAmadis
left a comment
There was a problem hiding this comment.
@copilot - sprawdź moje komentarze, popraw kod i dopisz jeszcze skrypty CI dla github. Możesz sprawdzić jak to jest zrobione w dwóch referencyjnych repozytoriach i zrobić tak samo
There was a problem hiding this comment.
@copilot ten plik nie powinien być zacommitowany. Proszę usuń go, zacommituj usunięcie, a następnie dodaj ten katalog do gitignore i zrób drugi commit z tym gitignore.
There was a problem hiding this comment.
Removed in commit 14d33c1. Also added _codeql_build_dir/ and _codeql_detected_source_root to .gitignore to prevent future commits.
| * | ||
| * @return true if initialization is successful, false otherwise. | ||
| */ | ||
| DMOD_BUILTIN_API( dmenv, 1.0, bool , _init, ( void* buffer, size_t size ) ); |
There was a problem hiding this comment.
dobrze by było zrobić to tak jak dmlog - czyli żeby można było stworzyć context, korzystać z niego i jakimś API ustawić jaki context ma byc domyślny. Dzięki temu będzie można tworzyć niezależne contexty - np dla różnych użytkowników. Fajnie by też było, gdyby można było dziedziczyć po kontekście, czyli żeby w jednym kontekście przechowywać też referencje do drugiego. Czyli jako parametr do np dmenv_create podawać inny context jako parent i wtedy jeśli zmiennej nie ma w obecnym kontekście, to sprawdzić w tym rodzicu
There was a problem hiding this comment.
Implemented in commit 4380198. Created context-based API with:
dmenv_create(parent)- create context with optional parent for inheritancedmenv_set_as_default/get_default- default context management- Child contexts search parent recursively when variable not found locally
- All operations now take context as first parameter
| * | ||
| * @return Number of matching variables found. | ||
| */ | ||
| DMOD_BUILTIN_API( dmenv, 1.0, size_t , _find, ( const char* prefix, void (*callback)(const char* name, const char* value, void* user_data), void* user_data ) ); |
There was a problem hiding this comment.
ten callback zdefiniuj typedefem jako typ gdzieś wyżej i tutaj tylko użyj, bo inaczej to mało czytelne jest. Dodaj też dobry opis do tego typu callbacka
There was a problem hiding this comment.
Fixed in commit 4380198. Defined dmenv_find_callback_t typedef with full documentation explaining the callback signature and that it executes under lock.
| * | ||
| * @return true if the variable was set successfully, false otherwise. | ||
| */ | ||
| DMOD_BUILTIN_API( dmenv, 1.0, bool , _set, ( const char* name, const char* value ) ); |
There was a problem hiding this comment.
by się przydał też drugi interfejs na ustawienie i odczytanie wartości jako uint w hex - często coś takiego jest potrzebne i bez tego będzie implementowane ciągle od nowa.
coś na zasadzie:
dmenv_seti( "MY_VAR", 0x2000);
uint32_t my_var = dmenv_geti("MY_VAR");
Oczywiście pod spodem i tak musisz to konwertować na char*, ale niech będzie do tego interfejs upraszczający
There was a problem hiding this comment.
Implemented in commit 4380198. Added:
dmenv_seti(ctx, name, value)- stores uint32_t as hex string (e.g., "0x2000")dmenv_geti(ctx, name, &value)- parses hex or decimal to uint32_t
Both functions are wrappers around dmenv_set/get with automatic conversion.
| /** | ||
| * @brief Helper function to allocate an entry from the buffer | ||
| */ | ||
| static env_entry_t* allocate_entry(void) { |
There was a problem hiding this comment.
Możesz spokojnie używać Dmod_Malloc oraz Dmod_Free - będzie zawsze gotowy przed tym modułem.
There was a problem hiding this comment.
Implemented in commit 4380198. Now using Dmod_MallocEx and Dmod_FreeEx for all dynamic allocations (entries, names, values). Removed static buffer approach entirely.
| #endif | ||
|
|
||
| #ifndef DMENV_MAX_VALUE_LENGTH | ||
| #define DMENV_MAX_VALUE_LENGTH 256 |
There was a problem hiding this comment.
Lepiej alokuj dynamicznie pamięć na wpisy, inaczej dużo pamięci będzie się marnowało
There was a problem hiding this comment.
Fixed in commit 4380198. Now dynamically allocating each entry, name, and value with exact sizes needed. No fixed-size arrays, no wasted memory.
| g_dmenv_context.entry_count = 0; | ||
| g_dmenv_context.used_size = 0; | ||
|
|
||
| DMOD_LOG_INFO("dmenv: Initialized with buffer %p of size %zu", buffer, size); |
There was a problem hiding this comment.
tak jak jest to w innych modułach tak i tutaj powinieneś zalogować wersję modułu w postaci:
== dmenv ver 1.0 ==
There was a problem hiding this comment.
Added in commit 4380198. Version is now logged as "== dmenv ver. 1.0 ==" when creating contexts, matching the style in dmheap/dmlog.
Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
…ions Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
All comments addressed in commits 14d33c1 and 4380198: All 20 unit tests passing with new API. |
Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
JohnAmadis
left a comment
There was a problem hiding this comment.
@copilot popraw prosze to wszystko
|
|
||
| DMOD_INPUT_API_DECLARATION( dmenv, 1.0, bool, _is_valid, ( dmenv_ctx_t ctx ) ) | ||
| { | ||
| return ctx != NULL; |
There was a problem hiding this comment.
@copilot dodaj jakiś magic number, żeby zabezpieczyć się przed pamięcią, która już była zwolniona. Sprawdzaj też w API czy ten context jest poprawny za pomocą dmenv_is_valid
There was a problem hiding this comment.
Fixed in commit ef3bb17. Added DMENV_MAGIC_NUMBER (0x444D454E) to context structure. All API functions now call dmenv_is_valid() to check both NULL pointer and magic number. Magic is cleared on destroy to prevent use-after-free.
| DMOD_INPUT_API_DECLARATION( dmenv, 1.0, bool, _seti, ( dmenv_ctx_t ctx, const char* name, uint32_t value ) ) | ||
| { | ||
| char buffer[32]; | ||
| snprintf(buffer, sizeof(buffer), "0x%X", value); |
There was a problem hiding this comment.
To jest embedded - tutaj nie ma spnprintf
There was a problem hiding this comment.
Fixed in commit ef3bb17. Replaced snprintf with Dmod_SnPrintf for embedded compatibility.
| return true; | ||
| } | ||
|
|
||
| DMOD_INPUT_API_DECLARATION( dmenv, 1.0, size_t, _count, ( dmenv_ctx_t ctx ) ) |
There was a problem hiding this comment.
Brakuje zaimplementowania warunkowego interfejsu DMOD, czyli funkcji Dmod_SetEnv i Dmod_GetEnv - dodałeś na to już zmienną w CMake, ale tutaj nie ma implementacji. Sprawdź jak to jest zrobione w dmlog
There was a problem hiding this comment.
Implemented in commit ef3bb17. Added Dmod_SetEnv and Dmod_GetEnv implementations that use the default context. Both are conditionally compiled with #ifndef DMENV_DONT_IMPLEMENT_DMOD_API, matching dmlog pattern.
…D API Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
|
@copilot jeszcze pipeline Ci failuje na coverage: |
Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
Fixed in commit 5f65f9a. Added --coverage compile and link flags to:
Coverage now working: 86.4% lines, 96.1% functions for dmenv.c. The .gcda files are generated correctly and lcov captures the data. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Addressing PR comments:
All 20 unit tests passing.
Coverage: 86.4% lines, 96.1% functions for dmenv.c
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.