|
23 | 23 | #define DMDEVFS_CONTEXT_MAGIC 0x444D4456 // 'DMDV' |
24 | 24 | #define ROOT_DIRECTORY_NAME "/" |
25 | 25 | #define MAX_PATH_LENGTH (DMOD_MAX_MODULE_NAME_LENGTH + 20) |
| 26 | +#define INI_LINE_BUFFER_SIZE 256 |
| 27 | +#define INI_MAIN_SECTION "main" |
26 | 28 |
|
27 | 29 | /** |
28 | 30 | * @brief Type definition for path strings |
@@ -73,6 +75,7 @@ struct dmfsi_context |
73 | 75 | // ============================================================================ |
74 | 76 | static int configure_drivers(dmfsi_context_t ctx, const char* driver_name, const char* config_path); |
75 | 77 | 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); |
76 | 79 | static int unconfigure_drivers(dmfsi_context_t ctx); |
77 | 80 | static bool is_file(const char* path); |
78 | 81 | static bool is_driver( const char* name); |
@@ -851,19 +854,27 @@ static int configure_drivers(dmfsi_context_t ctx, const char* driver_name, const |
851 | 854 | continue; |
852 | 855 | } |
853 | 856 |
|
854 | | - driver_node_t* driver_node = configure_driver(module_name, config_ctx); |
855 | | - dmini_destroy(config_ctx); |
856 | | - if (driver_node == NULL) |
| 857 | + // Section-specific driver_name entries take priority over the file/directory |
| 858 | + // derived driver name. Only configure the main driver when no section-level |
| 859 | + // drivers are present in the file. |
| 860 | + int section_drivers_added = configure_section_drivers(ctx, config_ctx, full_path); |
| 861 | + if (section_drivers_added == 0) |
857 | 862 | { |
858 | | - DMOD_LOG_ERROR("Failed to configure driver: %s\n", module_name); |
859 | | - continue; |
860 | | - } |
861 | | - if(!dmlist_push_back(ctx->drivers, driver_node)) |
862 | | - { |
863 | | - DMOD_LOG_ERROR("Failed to add driver to list: %s\n", module_name); |
864 | | - Dmod_Free(driver_node); |
865 | | - continue; |
| 863 | + driver_node_t* driver_node = configure_driver(module_name, config_ctx); |
| 864 | + if (driver_node != NULL) |
| 865 | + { |
| 866 | + if(!dmlist_push_back(ctx->drivers, driver_node)) |
| 867 | + { |
| 868 | + DMOD_LOG_ERROR("Failed to add driver to list: %s\n", module_name); |
| 869 | + Dmod_Free(driver_node); |
| 870 | + } |
| 871 | + } |
| 872 | + else |
| 873 | + { |
| 874 | + DMOD_LOG_ERROR("Failed to configure driver: %s\n", module_name); |
| 875 | + } |
866 | 876 | } |
| 877 | + dmini_destroy(config_ctx); |
867 | 878 | } |
868 | 879 | else |
869 | 880 | { |
@@ -944,6 +955,96 @@ static driver_node_t* configure_driver(const char* driver_name, dmini_context_t |
944 | 955 | return driver_node; |
945 | 956 | } |
946 | 957 |
|
| 958 | +/** |
| 959 | + * @brief Configure drivers for non-main sections that contain a driver_name key |
| 960 | + * |
| 961 | + * Scans the config file line by line for INI section headers. For each section |
| 962 | + * other than "main" that contains a driver_name key, a new driver is configured |
| 963 | + * with the INI context restricted to that section via dmini_set_active_section, |
| 964 | + * so the driver only sees the keys belonging to its own section. |
| 965 | + * |
| 966 | + * Returns the number of section-specific drivers that were successfully added. |
| 967 | + * A non-zero return value signals to the caller that the file is a multi-driver |
| 968 | + * config and no fallback main driver should be configured. |
| 969 | + */ |
| 970 | +static int configure_section_drivers(dmfsi_context_t ctx, dmini_context_t config_ctx, const char* config_path) |
| 971 | +{ |
| 972 | + void* file = Dmod_FileOpen(config_path, "r"); |
| 973 | + if (file == NULL) |
| 974 | + { |
| 975 | + DMOD_LOG_ERROR("Failed to open config file for section scan: %s\n", config_path); |
| 976 | + return 0; |
| 977 | + } |
| 978 | + |
| 979 | + int num_added = 0; |
| 980 | + char line[INI_LINE_BUFFER_SIZE]; |
| 981 | + while (Dmod_FileReadLine(line, sizeof(line), file) != NULL) |
| 982 | + { |
| 983 | + // Skip lines that don't start with '[' (ignore leading whitespace) |
| 984 | + char* p = line; |
| 985 | + while (*p == ' ' || *p == '\t') p++; |
| 986 | + if (*p != '[') continue; |
| 987 | + |
| 988 | + // Find closing bracket |
| 989 | + char* end = strchr(p, ']'); |
| 990 | + if (end == NULL || end <= p) continue; |
| 991 | + |
| 992 | + // Extract section name |
| 993 | + size_t name_len = (size_t)(end - p - 1); |
| 994 | + if (name_len == 0 || name_len >= DMOD_MAX_MODULE_NAME_LENGTH) continue; |
| 995 | + |
| 996 | + char section_name[DMOD_MAX_MODULE_NAME_LENGTH]; |
| 997 | + strncpy(section_name, p + 1, name_len); |
| 998 | + section_name[name_len] = '\0'; |
| 999 | + |
| 1000 | + // Trim trailing whitespace from section name |
| 1001 | + size_t slen = strlen(section_name); |
| 1002 | + while (slen > 0 && (section_name[slen - 1] == ' ' || section_name[slen - 1] == '\t')) |
| 1003 | + { |
| 1004 | + slen--; |
| 1005 | + } |
| 1006 | + section_name[slen] = '\0'; |
| 1007 | + |
| 1008 | + // Skip empty section names and the "main" section (handled by existing logic) |
| 1009 | + if (slen == 0 || strcmp(section_name, INI_MAIN_SECTION) == 0) continue; |
| 1010 | + |
| 1011 | + // Check if this section has a driver_name key |
| 1012 | + if (!dmini_has_key(config_ctx, section_name, "driver_name")) continue; |
| 1013 | + |
| 1014 | + const char* drv_name = dmini_get_string(config_ctx, section_name, "driver_name", NULL); |
| 1015 | + if (drv_name == NULL) continue; |
| 1016 | + |
| 1017 | + char module_name[DMOD_MAX_MODULE_NAME_LENGTH]; |
| 1018 | + strncpy(module_name, drv_name, sizeof(module_name)); |
| 1019 | + module_name[sizeof(module_name) - 1] = '\0'; |
| 1020 | + |
| 1021 | + // Restrict the INI context to this section and configure the driver. |
| 1022 | + // Token 0 means no owner-token protection (context was created with dmini_create). |
| 1023 | + dmini_set_active_section(config_ctx, section_name, 0); |
| 1024 | + driver_node_t* driver_node = configure_driver(module_name, config_ctx); |
| 1025 | + dmini_clear_active_section(config_ctx, 0); |
| 1026 | + |
| 1027 | + if (driver_node == NULL) |
| 1028 | + { |
| 1029 | + DMOD_LOG_ERROR("Failed to configure driver for section [%s]: %s\n", section_name, module_name); |
| 1030 | + continue; |
| 1031 | + } |
| 1032 | + |
| 1033 | + if (!dmlist_push_back(ctx->drivers, driver_node)) |
| 1034 | + { |
| 1035 | + DMOD_LOG_ERROR("Failed to add driver to list: %s\n", module_name); |
| 1036 | + Dmod_Free(driver_node); |
| 1037 | + } |
| 1038 | + else |
| 1039 | + { |
| 1040 | + num_added++; |
| 1041 | + } |
| 1042 | + } |
| 1043 | + |
| 1044 | + Dmod_FileClose(file); |
| 1045 | + return num_added; |
| 1046 | +} |
| 1047 | + |
947 | 1048 | /** |
948 | 1049 | * @brief Unconfigure and unload all drivers |
949 | 1050 | */ |
|
0 commit comments