Skip to content

Commit

Permalink
refactor compiler/main/cli
Browse files Browse the repository at this point in the history
Use an array to describe the available flags.
The flags are no longer hardcoded and the -help section is also
generated from that array.

This way it will be easier to add more flags in the future.

resolves #95
  • Loading branch information
pointbazaar committed Dec 20, 2024
1 parent efefa5e commit 7907aec
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 95 deletions.
2 changes: 1 addition & 1 deletion compiler/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ add_library("sd-base"
typeinference/infer_in_context.c

#util
util/help.c
util/fill_tables.c
util/fill_tables.h
util/fileutils/fileutils.c
util/ctx.c

#flags
cli/flags/flags.c
cli/flags/all_flags.c
cli/flags/validate_flags.c
)

Expand Down
54 changes: 54 additions & 0 deletions compiler/main/cli/flags/all_flags.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>

#include "flag.h"

struct Flag all_flags[] = {
{
"help",
"display help text",
false,
false,
},
{
"debug",
"print debug statements",
false,
false,
},
{
"version",
"display version text",
false,
false,
},
{
"h",
"emit .h (header) files",
false,
false,
},
{
"avr",
"compile for AVR (default)",
false,
false,
},
{
"x86",
"compile for x86-64",
false,
false,
},
{
"print-filenames",
"print associated filenames for a .dg file",
false,
false,
},
};

size_t all_flags_count() {
return sizeof(all_flags) / sizeof(struct Flag);
}
12 changes: 12 additions & 0 deletions compiler/main/cli/flags/all_flags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>

#include "flag.h"

extern struct Flag all_flags[];

size_t all_flags_count();
16 changes: 16 additions & 0 deletions compiler/main/cli/flags/flag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <inttypes.h>
#include <stdbool.h>

struct Flag {
// e.g. -avr
char* name;

char* description;

bool has_arg;

// should be false in the flags array
bool is_set;
};
127 changes: 76 additions & 51 deletions compiler/main/cli/flags/flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,15 @@
#include "../../../util/exit_malloc/exit_malloc.h"

#include "flags.h"
#include "all_flags.h"
#include "flag.h"

#include "validate_flags.h"

struct Flags {
//struct Flags should be opaque outside its
//implementation files

bool debug; //-debug
bool help; //-help
bool version; //-version
bool x86; //-x86

bool has_main_fn;

uint8_t count_filenames;
Expand All @@ -33,41 +30,71 @@ struct Flags {
char* token_filename;
char* hex_filename;
char* obj_filename;

struct Flag* all_flags;
};

static char* make_asm_filename(char* filename) {
static bool flags_set(struct Flags* flags, char* name) {

for (size_t i = 0; i < all_flags_count(); i++) {
struct Flag* f = &(flags->all_flags[i]);
if (strcmp(f->name, name) == 0 && f->is_set) {
return true;
}
}
return false;
}

static void sd_print_flags() {

for (size_t i = 0; i < all_flags_count(); i++) {
struct Flag* f = &(all_flags[i]);

printf(" -%-20s %s\n", f->name, f->description);
}
}

void sd_print_help() {

printf("OPTIONS\n");
sd_print_flags();

char* name = "sd";

char* fname_out = exit_malloc(strlen(filename) + 4);
printf("\nEXAMPLES\n");
printf("%s main.dg\n", name);
printf("%s -debug main.dg\n", name);
}

static char* filename_no_extension(char* filename) {

char* fname_out = exit_malloc(strlen(filename) + 5);

strcpy(fname_out, filename);
//remove the '.dg'
fname_out[strlen(fname_out) - 3] = '\0';
strcat(fname_out, ".asm");

return fname_out;
}

static char* make_obj_filename(char* filename) {
static char* make_asm_filename(char* filename) {

char* fname_out = exit_malloc(strlen(filename) + 4);
char* fname_out = filename_no_extension(filename);
strcat(fname_out, ".asm");
return fname_out;
}

strcpy(fname_out, filename);
//remove the '.dg'
fname_out[strlen(fname_out) - 3] = '\0';
strcat(fname_out, ".o");
static char* make_obj_filename(char* filename) {

char* fname_out = filename_no_extension(filename);
strcat(fname_out, ".o");
return fname_out;
}

static char* make_hex_filename(char* filename) {

char* fname_out = exit_malloc(strlen(filename) + 4);

strcpy(fname_out, filename);
//remove the '.dg'
fname_out[strlen(fname_out) - 3] = '\0';
char* fname_out = filename_no_extension(filename);
strcat(fname_out, ".hex");

return fname_out;
}

Expand All @@ -93,14 +120,20 @@ static char* make_token_filename(char* filename) {

static void make_flags_inner(struct Flags* flags, char* arg);

static void make_associated_filenames(struct Flags* flags) {

flags->asm_filename = make_asm_filename(flags_filenames(flags, 0));
flags->token_filename = make_token_filename(flags_filenames(flags, 0));
flags->hex_filename = make_hex_filename(flags_filenames(flags, 0));
flags->obj_filename = make_obj_filename(flags_filenames(flags, 0));
}

struct Flags* makeFlags(int argc, char** argv) {

struct Flags* flags = exit_malloc(sizeof(struct Flags));

flags->debug = false;
flags->help = false;
flags->version = false;
flags->x86 = false;
flags->all_flags = malloc(sizeof(struct Flag) * all_flags_count());
memcpy(flags->all_flags, all_flags, all_flags_count() * sizeof(struct Flag));

flags->count_filenames = 0;

Expand All @@ -113,14 +146,13 @@ struct Flags* makeFlags(int argc, char** argv) {
make_flags_inner(flags, argv[i]);
}

if (flags->help || flags->version) { return flags; }
if (flags_set(flags, "help") || flags_set(flags, "version")) {
return flags;
}

validate_flags(flags);

flags->asm_filename = make_asm_filename(flags_filenames(flags, 0));
flags->token_filename = make_token_filename(flags_filenames(flags, 0));
flags->hex_filename = make_hex_filename(flags_filenames(flags, 0));
flags->obj_filename = make_obj_filename(flags_filenames(flags, 0));
make_associated_filenames(flags);

return flags;
}
Expand All @@ -140,27 +172,17 @@ static void make_flags_inner(struct Flags* flags, char* arg) {
return;
}

if (strcmp(arg, "-debug") == 0) {
flags->debug = true;
return;
}

if (strcmp(arg, "-help") == 0) {
flags->help = true;
return;
}
for (size_t i = 0; i < all_flags_count(); i++) {
struct Flag* f = &(flags->all_flags[i]);

if (strcmp(arg, "-version") == 0) {
flags->version = true;
return;
if (strcmp(arg + 1, f->name) == 0) {
f->is_set = true;
return;
}
}

if (strcmp(arg, "-x86") == 0) {
flags->x86 = true;
return;
}

printf("unrecognized flag: %s. Exiting.\n", arg);
fprintf(stderr, "unrecognized flag: '%s'\n", arg);
fprintf(stderr, "exiting.\n");
exit(1);
}

Expand Down Expand Up @@ -189,16 +211,19 @@ char* flags_filenames(struct Flags* flags, int index) {
}

bool flags_debug(struct Flags* flags) {
return flags->debug;
return flags_set(flags, "debug");
}
bool flags_version(struct Flags* flags) {
return flags->version;
return flags_set(flags, "version");
}
bool flags_help(struct Flags* flags) {
return flags->help;
return flags_set(flags, "help");
}
bool flags_x86(struct Flags* flags) {
return flags->x86;
return flags_set(flags, "x86");
}
bool flags_print_filenames(struct Flags* flags) {
return flags_set(flags, "print-filenames");
}

char* flags_asm_filename(struct Flags* flags) {
Expand Down
3 changes: 3 additions & 0 deletions compiler/main/cli/flags/flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

struct Flags;

void sd_print_help();

struct Flags* makeFlags(int argc, char** argv);
struct Flags* makeFlagsSingleFile(char* filename);

Expand All @@ -18,6 +20,7 @@ bool flags_debug(struct Flags* flags);
bool flags_version(struct Flags* flags);
bool flags_help(struct Flags* flags);
bool flags_x86(struct Flags* flags);
bool flags_print_filenames(struct Flags* flags);

//generated filenames for later on
char* flags_asm_filename(struct Flags* ctx);
Expand Down
6 changes: 3 additions & 3 deletions compiler/main/cli/flags/validate_flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static bool check_dg_extension(char* filename) {
const int ext_index = strlen(filename) - 3;

if (strcmp(filename + ext_index, ".dg") != 0) {
printf("filename has to have .dg extension\n");
fprintf(stderr, "filename has to have .dg extension\n");
return false;
}
return true;
Expand All @@ -52,7 +52,7 @@ static void check_file_exists(char* filename) {
//check if the file actually exists
struct stat mystat;
if (stat(filename, &mystat) == -1) {
printf("error in check_file_exists: filename: %s\n", filename);
fprintf(stderr, "error in check_file_exists: filename: %s\n", filename);
fflush(stdout);
perror("Error: ");
//freeFlags(flags);
Expand All @@ -62,7 +62,7 @@ static void check_file_exists(char* filename) {
mode_t mode = mystat.st_mode;
if (!S_ISREG(mode)) {
//not a regular file
printf("Error: %s is not a regular file.\n", filename);
fprintf(stderr, "Error: %s is not a regular file.\n", filename);
//freeFlags(flags);
exit(1);
}
Expand Down
8 changes: 7 additions & 1 deletion compiler/main/cli/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include <malloc.h>

#include "flags/flags.h"
#include "util/help.h"
#include "util/fileutils/fileutils.h"

#include "compiler.h"
Expand Down Expand Up @@ -32,6 +31,13 @@ int main(int argc, char* argv[]) {
return EXIT_SUCCESS;
}

if (flags_print_filenames(flags)) {
printf("%s\n", flags_asm_filename(flags));
printf("%s\n", flags_token_filename(flags));
printf("%s\n", flags_hex_filename(flags));
printf("%s\n", flags_obj_filename(flags));
}

bool success = compile(flags);

return (success) ? EXIT_SUCCESS : EXIT_FAILURE;
Expand Down
Loading

0 comments on commit 7907aec

Please sign in to comment.