Skip to content

Commit eae43be

Browse files
CopilotJohnAmadis
andcommitted
Fix configure_section_drivers to use dmini_generate_string instead of direct file I/O
Replace Dmod_FileOpen/Dmod_FileReadLine with dmini_generate_string so that section enumeration works from the already-parsed in-memory dmini context rather than re-reading the raw config file from disk. This is the intended usage as described in the issue: use the dmini API (dmini_set_active_section) to restrict context scope, not a hand-rolled file parser. - Remove config_path parameter from configure_section_drivers (no longer needed) - Remove unused INI_LINE_BUFFER_SIZE define - Add whitespace trimming for robustness when parsing section names - Use dmini_generate_string to obtain INI content from in-memory context Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
1 parent f5590c7 commit eae43be

1 file changed

Lines changed: 86 additions & 65 deletions

File tree

src/dmdevfs.c

Lines changed: 86 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#define DMDEVFS_CONTEXT_MAGIC 0x444D4456 // 'DMDV'
2424
#define ROOT_DIRECTORY_NAME "/"
2525
#define MAX_PATH_LENGTH (DMOD_MAX_MODULE_NAME_LENGTH + 20)
26-
#define INI_LINE_BUFFER_SIZE 256
2726
#define INI_MAIN_SECTION "main"
2827

2928
/**
@@ -75,7 +74,7 @@ struct dmfsi_context
7574
// ============================================================================
7675
static int configure_drivers(dmfsi_context_t ctx, const char* driver_name, const char* config_path);
7776
static driver_node_t* configure_driver(const char* driver_name, dmini_context_t config_ctx);
78-
static int configure_section_drivers(dmfsi_context_t ctx, dmini_context_t config_ctx, const char* config_path);
77+
static int configure_section_drivers(dmfsi_context_t ctx, dmini_context_t config_ctx);
7978
static int unconfigure_drivers(dmfsi_context_t ctx);
8079
static bool is_file(const char* path);
8180
static bool is_driver( const char* name);
@@ -857,7 +856,7 @@ static int configure_drivers(dmfsi_context_t ctx, const char* driver_name, const
857856
// Section-specific driver_name entries take priority over the file/directory
858857
// derived driver name. Only configure the main driver when no section-level
859858
// drivers are present in the file.
860-
int section_drivers_added = configure_section_drivers(ctx, config_ctx, full_path);
859+
int section_drivers_added = configure_section_drivers(ctx, config_ctx);
861860
if (section_drivers_added == 0)
862861
{
863862
driver_node_t* driver_node = configure_driver(module_name, config_ctx);
@@ -967,90 +966,112 @@ static driver_node_t* configure_driver(const char* driver_name, dmini_context_t
967966
/**
968967
* @brief Configure drivers for non-main sections that contain a driver_name key
969968
*
970-
* Scans the config file line by line for INI section headers. For each section
971-
* other than "main" that contains a driver_name key, a new driver is configured
972-
* with the INI context restricted to that section via dmini_set_active_section,
973-
* so the driver only sees the keys belonging to its own section.
969+
* Uses dmini_generate_string to obtain the full INI content from the
970+
* already-parsed context (avoiding a second read of the config file from
971+
* disk). Each non-main section that contains a driver_name key is configured
972+
* as a separate driver with the INI context restricted to that section via
973+
* dmini_set_active_section, so the driver only sees the keys belonging to its
974+
* own section.
974975
*
975976
* Returns the number of section-specific drivers that were successfully added.
976977
* A non-zero return value signals to the caller that the file is a multi-driver
977978
* config and no fallback main driver should be configured.
978979
*/
979-
static int configure_section_drivers(dmfsi_context_t ctx, dmini_context_t config_ctx, const char* config_path)
980+
static int configure_section_drivers(dmfsi_context_t ctx, dmini_context_t config_ctx)
980981
{
981-
void* file = Dmod_FileOpen(config_path, "r");
982-
if (file == NULL)
982+
// Generate the full INI content from the already-parsed dmini context.
983+
// This avoids re-reading the file from disk; we work entirely with the
984+
// in-memory representation that dmini built during dmini_parse_file.
985+
int content_size = dmini_generate_string(config_ctx, NULL, 0);
986+
if (content_size <= 0)
983987
{
984-
DMOD_LOG_ERROR("Failed to open config file for section scan: %s\n", config_path);
985988
return 0;
986989
}
987990

988-
int num_added = 0;
989-
char line[INI_LINE_BUFFER_SIZE];
990-
while (Dmod_FileReadLine(line, sizeof(line), file) != NULL)
991+
char* ini_content = (char*)Dmod_Malloc((size_t)content_size);
992+
if (ini_content == NULL)
991993
{
992-
// Skip lines that don't start with '[' (ignore leading whitespace)
993-
char* p = line;
994-
while (*p == ' ' || *p == '\t') p++;
995-
if (*p != '[') continue;
996-
997-
// Find closing bracket
998-
char* end = strchr(p, ']');
999-
if (end == NULL || end <= p) continue;
994+
DMOD_LOG_ERROR("Failed to allocate buffer for INI content scan\n");
995+
return 0;
996+
}
1000997

1001-
// Extract section name
1002-
size_t name_len = (size_t)(end - p - 1);
1003-
if (name_len == 0 || name_len >= DMOD_MAX_MODULE_NAME_LENGTH) continue;
998+
if (dmini_generate_string(config_ctx, ini_content, (size_t)content_size) <= 0)
999+
{
1000+
Dmod_Free(ini_content);
1001+
return 0;
1002+
}
10041003

1005-
char section_name[DMOD_MAX_MODULE_NAME_LENGTH];
1006-
strncpy(section_name, p + 1, name_len);
1007-
section_name[name_len] = '\0';
1004+
int num_added = 0;
1005+
const char* p = ini_content;
1006+
while (*p != '\0')
1007+
{
1008+
// Skip leading whitespace on the line
1009+
while (*p == ' ' || *p == '\t') p++;
10081010

1009-
// Trim trailing whitespace from section name
1010-
size_t slen = strlen(section_name);
1011-
while (slen > 0 && (section_name[slen - 1] == ' ' || section_name[slen - 1] == '\t'))
1011+
if (*p == '[')
10121012
{
1013-
slen--;
1014-
}
1015-
section_name[slen] = '\0';
1016-
1017-
// Skip empty section names and the "main" section (handled by existing logic)
1018-
if (slen == 0 || strcmp(section_name, INI_MAIN_SECTION) == 0) continue;
1019-
1020-
// Check if this section has a driver_name key
1021-
if (!dmini_has_key(config_ctx, section_name, "driver_name")) continue;
1013+
// Extract section name between '[' and ']'
1014+
const char* name_start = p + 1;
1015+
const char* name_end = name_start;
1016+
while (*name_end != '\0' && *name_end != ']' && *name_end != '\n') name_end++;
10221017

1023-
const char* drv_name = dmini_get_string(config_ctx, section_name, "driver_name", NULL);
1024-
if (drv_name == NULL) continue;
1025-
1026-
char module_name[DMOD_MAX_MODULE_NAME_LENGTH];
1027-
strncpy(module_name, drv_name, sizeof(module_name));
1028-
module_name[sizeof(module_name) - 1] = '\0';
1018+
if (*name_end == ']')
1019+
{
1020+
// Trim leading whitespace inside the brackets
1021+
while (name_start < name_end && (*name_start == ' ' || *name_start == '\t')) name_start++;
1022+
// Trim trailing whitespace inside the brackets
1023+
while (name_end > name_start && (*(name_end - 1) == ' ' || *(name_end - 1) == '\t')) name_end--;
10291024

1030-
// Restrict the INI context to this section and configure the driver.
1031-
// Token 0 means no owner-token protection (context was created with dmini_create).
1032-
dmini_set_active_section(config_ctx, section_name, 0);
1033-
driver_node_t* driver_node = configure_driver(module_name, config_ctx);
1034-
dmini_clear_active_section(config_ctx, 0);
1025+
size_t name_len = (size_t)(name_end - name_start);
1026+
if (name_len > 0 && name_len < DMOD_MAX_MODULE_NAME_LENGTH)
1027+
{
1028+
char section_name[DMOD_MAX_MODULE_NAME_LENGTH];
1029+
strncpy(section_name, name_start, name_len);
1030+
section_name[name_len] = '\0';
10351031

1036-
if (driver_node == NULL)
1037-
{
1038-
DMOD_LOG_ERROR("Failed to configure driver for section [%s]: %s\n", section_name, module_name);
1039-
continue;
1032+
// Skip the [main] section; it is handled by existing logic
1033+
if (strcmp(section_name, INI_MAIN_SECTION) != 0 &&
1034+
dmini_has_key(config_ctx, section_name, "driver_name"))
1035+
{
1036+
const char* drv_name = dmini_get_string(config_ctx, section_name, "driver_name", NULL);
1037+
if (drv_name != NULL)
1038+
{
1039+
char module_name[DMOD_MAX_MODULE_NAME_LENGTH];
1040+
strncpy(module_name, drv_name, sizeof(module_name));
1041+
module_name[sizeof(module_name) - 1] = '\0';
1042+
1043+
// Restrict the INI context to this section and configure the driver.
1044+
// Token 0 means no owner-token protection (context was created with dmini_create).
1045+
dmini_set_active_section(config_ctx, section_name, 0);
1046+
driver_node_t* driver_node = configure_driver(module_name, config_ctx);
1047+
dmini_clear_active_section(config_ctx, 0);
1048+
1049+
if (driver_node == NULL)
1050+
{
1051+
DMOD_LOG_ERROR("Failed to configure driver for section [%s]: %s\n",
1052+
section_name, module_name);
1053+
}
1054+
else if (!dmlist_push_back(ctx->drivers, driver_node))
1055+
{
1056+
DMOD_LOG_ERROR("Failed to add driver to list: %s\n", module_name);
1057+
Dmod_Free(driver_node);
1058+
}
1059+
else
1060+
{
1061+
num_added++;
1062+
}
1063+
}
1064+
}
1065+
}
1066+
}
10401067
}
10411068

1042-
if (!dmlist_push_back(ctx->drivers, driver_node))
1043-
{
1044-
DMOD_LOG_ERROR("Failed to add driver to list: %s\n", module_name);
1045-
Dmod_Free(driver_node);
1046-
}
1047-
else
1048-
{
1049-
num_added++;
1050-
}
1069+
// Advance to the next line
1070+
while (*p != '\0' && *p != '\n') p++;
1071+
if (*p == '\n') p++;
10511072
}
10521073

1053-
Dmod_FileClose(file);
1074+
Dmod_Free(ini_content);
10541075
return num_added;
10551076
}
10561077

0 commit comments

Comments
 (0)