First. If this question is not allowed, I am sorry. Please, tell me so, and I will try to delete this. If it is, I will delete this paragraph.
Personal-ish note/Motivation
I was studying assembly because of Tanenbaum and C, and decided to make a "graduation" project from the book: a C compiler for AVR and x86 ISAs, using the C standard with no external source on compilers! For fun, or suffering... and to make my first C "project", not only scripts. So, I wrote a skeleton program that takes files and options ("switches"). So, the file can really grow to any place.
It also means it haunts me at night, with so many design decisions, like enum
for errors and so many static functions; besides features ideas... I always think something is wrong and there will be pain in growing the project, because it will be unreadable, consequentially buggy.
Explanation
Like GCC, any input argument that is not an option is a file name. Unlike GCC, it calls options switches, because Windows does it, and I am using Windows. This is all. It is mostly a skeleton for a program that takes files from the user.
/*
* This file contains the entry function (main) for the SSGCompiler.
* The SSGCompiler is a compiler done as a challenge from the author
* to the author. More information may be found on the GitHub
* repository [REDACTED].
*
* This was originally written at 05/06/2023.
*/
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define EXECUTABLE_NAME "ssgcompiler"
#define SWITCH_PREFIX '/'
enum error {
FATAL_ERROR,
NOT_FATAL_ERROR
};
/* Prints the preamble of an error appended with a message. */
static void print_error_message(enum error err, const char *msg)
{
fputs(EXECUTABLE_NAME, stdout);
if (err == FATAL_ERROR)
fputs(". Fatal error: ", stdout);
else
fputs(". Error: ", stdout);
fputs(msg, stdout);
}
/* Returns whether the switch is a help switch */
static bool switch_is_help(const char *opt)
{
if ( !strcmp(opt, "/?") || !strcmp(opt, "--help")
|| !strcmp(opt, "-help") || !strcmp(opt, "--h")
|| !strcmp(opt, "-h") || !strcmp(opt, "help")) {
return true;
}
return false;
}
/* Returns whether the argument array has the help switch. */
static bool args_contain_help_switch(const char **argv, const int argLen)
{
for (int i = 0; i < argLen; i++) {
if (switch_is_help(argv[i]))
return true;
}
return false;
}
int main(const int argc, const char **argv)
{
if (argc < 2) {
print_error_message(FATAL_ERROR, "no input files.\n");
printf("See '" EXECUTABLE_NAME " /?' for help.\n");
return 1;
}
if (args_contain_help_switch(argv, argc)) {
fputs( "Usage: ssgcompiler [switches] file...\n"
"Switches:\n"
" /? Displays this help message (also --help, "
"-help, --h, -h, help)\n", stdout);
return 0;
}
for (size_t i = 1; i < argc; i++) {
if (!strlen(argv[i]) || argv[i][0] != SWITCH_PREFIX)
continue;
print_error_message(NOT_FATAL_ERROR, "Unrecognized switch: ");
printf("'%s'.\n", argv[i] + 1);
}
return 1;
}
const
asargLen
inargs_contain_help_switch(const char **argv, const int argLen)
. Why justargLen
and not alsoargv
as neither are changed? \$\endgroup\$