TU-Programmieren_2/lab3/modules/iue-po/cpo.h
2025-04-09 10:22:44 +02:00

104 lines
3.1 KiB
C

#pragma once
#include <stdbool.h> // bool
#include <stdio.h> // snprintf|stderr
#include <stdlib.h> // EXIT_FAILURE|EXIT_SUCCESS
#include <string.h> // strncmp|strlen
/// @brief internal function
static bool iuepo_find_option(const char* option, const char* arg) {
char buffer[256];
snprintf(buffer, sizeof(buffer) / sizeof(char), "%s%s", "-", option);
if (strncmp(buffer, arg, strlen(buffer)) == 0)
return true;
snprintf(buffer, sizeof(buffer) / sizeof(char), "%s%s", "--", option);
if (strncmp(buffer, arg, strlen(buffer)) == 0)
return true;
return false;
}
/// @brief internal function
static int iuepo_count_if(const char* option, char** begin, char** end) {
int res = 0;
for (char** iter = begin; iter != end; ++iter) {
if (iuepo_find_option(option, *iter))
++res;
}
return res;
}
/// @brief internal function
static char** iuepo_find_if(const char* option, char** begin, char** end) {
int res = 0;
for (char** iter = begin; iter != end; ++iter) {
if (iuepo_find_option(option, *iter))
return iter;
}
return end;
}
/// @todo Improve documentation of this enum
enum iuepo_option { IUEPO_REQUIRED = 0, IUEPO_OPTIONAL };
/// @todo Improve documentation of this function
/// @brief Optain a string option from command line arguments
static int iuepo_get_string(int argc, char* argv[], const char* option, char* default_value, int N,
enum iuepo_option op) {
int count = iuepo_count_if(option, argv + 1, argv + argc);
if (count == 0) {
if (op == IUEPO_REQUIRED) {
fprintf(stderr, "required option not provided: -/-- %s\n", option);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
if (count > 1) {
fprintf(stderr, "option not unique: -/-- %s (count = %i )\n", option, count);
return EXIT_FAILURE;
}
char** iter = iuepo_find_if(option, argv + 1, argv + argc);
++iter;
if (iter == argv + argc) {
fprintf(stderr, "option not followed by value: -/-- %s\n", option);
return EXIT_FAILURE;
}
if (strncmp("-", *iter, 1) == 0) {
fprintf(stderr, "option -/-- %s not followed by value but another option -/-- %s\n", option, *iter);
return EXIT_FAILURE;
}
if (snprintf(default_value, N, "%s", *iter) >= N) {
fprintf(stderr, "provided buffer size %i for option -/-- %s not sufficient\n", N, option);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
/// @todo Improve documentation of this function
/// @brief Wrapping iuepo_get_string with a subsequent conversion
static int iuepo_get_int(int argc, char* argv[], const char* option, int* default_value, enum iuepo_option op) {
char default_value_string[256] = "\0";
snprintf(default_value_string, sizeof(default_value_string), "%i", *default_value);
if (iuepo_get_string(argc, argv, option, default_value_string, sizeof(default_value_string), op) == EXIT_FAILURE) {
return EXIT_FAILURE;
}
int res = sscanf(default_value_string, "%i", default_value);
if (res != 1) {
fprintf(stderr, "value for option -/-- %s could not be converted\n", option);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}