Skip to content

Commit b46bcd2

Browse files
plugin config command
1 parent b620cb6 commit b46bcd2

File tree

3 files changed

+196
-0
lines changed

3 files changed

+196
-0
lines changed

code/logic/common.c

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ static void _show_help(void) {
7575
pizza_io_printf("{cyan} sort Sort tests by specified criteria{reset}\n");
7676
pizza_io_printf("{cyan} shuffle Shuffle tests with optional parameters{reset}\n");
7777
pizza_io_printf("{cyan} color=<mode> Set color mode (enable, disable, auto){reset}\n");
78+
pizza_io_printf("{cyan} config=<file> Specify a configuration file (must be pizza_test.ini){reset}\n");
7879
pizza_io_printf("{cyan} theme=<name> Set the theme (fossil, catch, doctest, etc.){reset}\n");
7980
pizza_io_printf("{cyan} verbose=<level> Set verbosity level (plain, ci, doge){reset}\n");
8081
exit(EXIT_SUCCESS);
@@ -320,6 +321,19 @@ fossil_pizza_pallet_t fossil_pizza_pallet_create(int argc, char** argv) {
320321
if (i + 1 < argc && pizza_io_cstr_compare(argv[i + 1], "--help") == 0) {
321322
_show_subhelp_color();
322323
}
324+
} else if (strncmp(argv[i], "config=", 7) == 0) {
325+
const char* config_file = argv[i] + 7;
326+
if (pizza_io_cstr_compare(config_file, "pizza_test.ini") == 0) {
327+
pallet.config_file = config_file;
328+
} else {
329+
pizza_io_printf("{red}Error: Invalid configuration file name. Must be 'pizza_test.ini'.{reset}\n");
330+
exit(EXIT_FAILURE);
331+
}
332+
} else if (pizza_io_cstr_compare(argv[i], "config") == 0) {
333+
if (i + 1 < argc && pizza_io_cstr_compare(argv[i + 1], "--help") == 0) {
334+
_show_help();
335+
}
336+
323337
} else if (strncmp(argv[i], "theme=", 6) == 0) {
324338
const char* theme_str = argv[i] + 6;
325339
if (pizza_io_cstr_compare(theme_str, "fossil") == 0) {
@@ -371,6 +385,161 @@ fossil_pizza_pallet_t fossil_pizza_pallet_create(int argc, char** argv) {
371385
return pallet;
372386
}
373387

388+
// *****************************************************************************
389+
// INI Parser
390+
// *****************************************************************************
391+
392+
int fossil_pizza_ini_parse(const char *filename, fossil_pizza_pallet_t *pallet) {
393+
if (pizza_io_cstr_compare(filename, "pizza_test.ini") != 0) {
394+
fprintf(stderr, "Error: INI file must be named 'pizza_test.ini'.\n");
395+
return -1;
396+
}
397+
398+
FILE *file = fopen(filename, "r");
399+
if (!file) {
400+
fprintf(stderr, "Error: Unable to open INI file: %s\n", filename);
401+
return -1;
402+
}
403+
404+
char line[256];
405+
char section[64] = "";
406+
while (fgets(line, sizeof(line), file)) {
407+
// Trim whitespace
408+
char *start = line;
409+
while (isspace((unsigned char)*start)) start++;
410+
char *end = start + strlen(start) - 1;
411+
while (end > start && isspace((unsigned char)*end)) *end-- = '\0';
412+
413+
// Skip comments and empty lines
414+
if (*start == ';' || *start == '#' || *start == '\0') continue;
415+
416+
// Handle section headers
417+
if (*start == '[') {
418+
char *close = strchr(start, ']');
419+
if (close) {
420+
*close = '\0';
421+
strncpy(section, start + 1, sizeof(section) - 1);
422+
section[sizeof(section) - 1] = '\0';
423+
}
424+
continue;
425+
}
426+
427+
// Handle key-value pairs
428+
char *equals = strchr(start, '=');
429+
if (equals) {
430+
*equals = '\0';
431+
char *key = start;
432+
char *value = equals + 1;
433+
434+
// Trim whitespace around key and value
435+
while (isspace((unsigned char)*key)) key++;
436+
end = key + strlen(key) - 1;
437+
while (end > key && isspace((unsigned char)*end)) *end-- = '\0';
438+
439+
while (isspace((unsigned char)*value)) value++;
440+
end = value + strlen(value) - 1;
441+
while (end > value && isspace((unsigned char)*end)) *end-- = '\0';
442+
443+
// Handle inline comments
444+
char *comment = strchr(value, ';');
445+
if (!comment) comment = strchr(value, '#');
446+
if (comment) *comment = '\0';
447+
448+
// Trim whitespace again after removing comments
449+
end = value + strlen(value) - 1;
450+
while (end > value && isspace((unsigned char)*end)) *end-- = '\0';
451+
452+
// Populate the pallet structure based on the section and key
453+
if (pizza_io_cstr_compare(section, "general") == 0) {
454+
if (pizza_io_cstr_compare(key, "theme") == 0) {
455+
if (pizza_io_cstr_compare(value, "fossil") == 0) {
456+
pallet->theme = PIZZA_THEME_FOSSIL;
457+
} else if (pizza_io_cstr_compare(value, "catch") == 0) {
458+
pallet->theme = PIZZA_THEME_CATCH;
459+
} else if (pizza_io_cstr_compare(value, "doctest") == 0) {
460+
pallet->theme = PIZZA_THEME_DOCTEST;
461+
} else if (pizza_io_cstr_compare(value, "cpputest") == 0) {
462+
pallet->theme = PIZZA_THEME_CPPUTEST;
463+
} else if (pizza_io_cstr_compare(value, "tap") == 0) {
464+
pallet->theme = PIZZA_THEME_TAP;
465+
} else if (pizza_io_cstr_compare(value, "gtest") == 0) {
466+
pallet->theme = PIZZA_THEME_GOOGLETEST;
467+
} else if (pizza_io_cstr_compare(value, "unity") == 0) {
468+
pallet->theme = PIZZA_THEME_UNITY;
469+
}
470+
} else if (pizza_io_cstr_compare(key, "verbose") == 0) {
471+
if (pizza_io_cstr_compare(value, "plain") == 0) {
472+
pallet->verbose = PIZZA_VERBOSE_PLAIN;
473+
} else if (pizza_io_cstr_compare(value, "ci") == 0) {
474+
pallet->verbose = PIZZA_VERBOSE_CI;
475+
} else if (pizza_io_cstr_compare(value, "doge") == 0) {
476+
pallet->verbose = PIZZA_VERBOSE_DOGE;
477+
}
478+
}
479+
} else if (pizza_io_cstr_compare(section, "test") == 0) {
480+
if (pizza_io_cstr_compare(key, "run.fail_fast") == 0) {
481+
pallet->run.fail_fast = atoi(value);
482+
} else if (pizza_io_cstr_compare(key, "run.only") == 0) {
483+
pallet->run.only = pizza_io_cstr_dup(value);
484+
} else if (pizza_io_cstr_compare(key, "run.repeat") == 0) {
485+
pallet->run.repeat = atoi(value);
486+
} else if (pizza_io_cstr_compare(key, "filter.test_name") == 0) {
487+
pallet->filter.test_name = pizza_io_cstr_dup(value);
488+
} else if (pizza_io_cstr_compare(key, "filter.suite_name") == 0) {
489+
pallet->filter.suite_name = pizza_io_cstr_dup(value);
490+
} else if (pizza_io_cstr_compare(key, "filter.tag") == 0) {
491+
int is_valid_tag = 0;
492+
for (int i = 0; VALID_TAGS[i] != null; i++) {
493+
if (pizza_io_cstr_compare(value, VALID_TAGS[i]) == 0) {
494+
is_valid_tag = 1;
495+
break;
496+
}
497+
}
498+
if (is_valid_tag) {
499+
pallet->filter.tag = pizza_io_cstr_dup(value);
500+
} else {
501+
fprintf(stderr, "Error: Invalid tag '%s'.\n", value);
502+
fclose(file);
503+
return -1;
504+
}
505+
} else if (pizza_io_cstr_compare(key, "sort.by") == 0) {
506+
int is_valid_criteria = 0;
507+
for (int i = 0; VALID_CRITERIA[i] != null; i++) {
508+
if (pizza_io_cstr_compare(value, VALID_CRITERIA[i]) == 0) {
509+
is_valid_criteria = 1;
510+
break;
511+
}
512+
}
513+
if (is_valid_criteria) {
514+
pallet->sort.by = pizza_io_cstr_dup(value);
515+
} else {
516+
fprintf(stderr, "Error: Invalid sort criteria '%s'.\n", value);
517+
fclose(file);
518+
return -1;
519+
}
520+
} else if (pizza_io_cstr_compare(key, "sort.order") == 0) {
521+
pallet->sort.order = pizza_io_cstr_dup(value);
522+
} else if (pizza_io_cstr_compare(key, "shuffle.seed") == 0) {
523+
pallet->shuffle.seed = pizza_io_cstr_dup(value);
524+
} else if (pizza_io_cstr_compare(key, "shuffle.count") == 0) {
525+
pallet->shuffle.count = atoi(value);
526+
} else if (pizza_io_cstr_compare(key, "shuffle.by") == 0) {
527+
pallet->shuffle.by = pizza_io_cstr_dup(value);
528+
}
529+
} else if (pizza_io_cstr_compare(section, "mock") == 0) {
530+
// Add mock-related parsing logic here
531+
} else if (pizza_io_cstr_compare(section, "mark") == 0) {
532+
// Add mark-related parsing logic here
533+
} else if (pizza_io_cstr_compare(section, "sanity") == 0) {
534+
// Add sanity-related parsing logic here
535+
}
536+
}
537+
}
538+
539+
fclose(file);
540+
return 0;
541+
}
542+
374543
// *****************************************************************************
375544
// Host information
376545
// *****************************************************************************

code/logic/fossil/pizza/common.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ typedef enum {
295295

296296
typedef struct {
297297
int dry_run; // Flag for dry run mode
298+
const char* config_file; // Path to the configuration file
298299
struct {
299300
int fail_fast; // Flag for --fail-fast
300301
const char* only; // Value for --only
@@ -345,6 +346,25 @@ extern fossil_pizza_cli_verbose_t G_PIZZA_VERBOSE;
345346
*/
346347
fossil_pizza_pallet_t fossil_pizza_pallet_create(int argc, char** argv);
347348

349+
// *****************************************************************************
350+
// INI Parser
351+
// *****************************************************************************
352+
353+
// INI Parser Implementation
354+
355+
/**
356+
* @brief Parses an INI file and populates the provided pallet structure.
357+
*
358+
* This function reads an INI file and extracts key-value pairs to populate
359+
* the fossil_pizza_pallet_t structure. It assumes a simple INI format with
360+
* sections and key-value pairs.
361+
*
362+
* @param filename The path to the INI file.
363+
* @param pallet Pointer to the pallet structure to populate.
364+
* @return 0 on success, or a negative error code on failure.
365+
*/
366+
int fossil_pizza_ini_parse(const char *filename, fossil_pizza_pallet_t *pallet);
367+
348368
// *****************************************************************************
349369
// Host information
350370
// *****************************************************************************

code/logic/test.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ int fossil_pizza_start(fossil_pizza_engine_t* engine, int argc, char** argv) {
4444
engine->pallet = fossil_pizza_pallet_create(argc, argv);
4545
pizza_sys_memory_set(&engine->score, 0, sizeof(engine->score));
4646

47+
// Parse configuration file if specified
48+
const char* config_file = engine->pallet.config_file;
49+
if (config_file && fossil_pizza_ini_parse(config_file, &engine->pallet) != FOSSIL_PIZZA_SUCCESS) {
50+
pizza_io_printf("Error: Failed to parse configuration file: %s\n", config_file);
51+
return FOSSIL_PIZZA_FAILURE;
52+
}
53+
4754
return FOSSIL_PIZZA_SUCCESS;
4855
}
4956

0 commit comments

Comments
 (0)