added missing doxygen
This commit is contained in:
parent
814d3483b7
commit
4703486daf
|
@ -7,6 +7,7 @@
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
#include <io/files.h>
|
#include <io/files.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <toml.h>
|
||||||
|
|
||||||
static GHashTable* args = NULL;
|
static GHashTable* args = NULL;
|
||||||
|
|
||||||
|
@ -188,10 +189,10 @@ void print_help(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_bool(bool* boolean, toml_table_t *table, const char* name) {
|
static void get_bool(bool* boolean, const toml_table_t *table, const char* name) {
|
||||||
DEBUG("retrieving boolean %s", name);
|
DEBUG("retrieving boolean %s", name);
|
||||||
|
|
||||||
toml_datum_t datum = toml_bool_in(table, name);
|
const toml_datum_t datum = toml_bool_in(table, name);
|
||||||
|
|
||||||
if (datum.ok) {
|
if (datum.ok) {
|
||||||
*boolean = datum.u.b;
|
*boolean = datum.u.b;
|
||||||
|
@ -199,10 +200,10 @@ static void get_bool(bool* boolean, toml_table_t *table, const char* name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_str(char** string, toml_table_t *table, const char* name) {
|
static void get_str(char** string, const toml_table_t *table, const char* name) {
|
||||||
DEBUG("retrieving string %s", name);
|
DEBUG("retrieving string %s", name);
|
||||||
|
|
||||||
toml_datum_t datum = toml_string_in(table, name);
|
const toml_datum_t datum = toml_string_in(table, name);
|
||||||
|
|
||||||
if (datum.ok) {
|
if (datum.ok) {
|
||||||
*string = datum.u.s;
|
*string = datum.u.s;
|
||||||
|
@ -210,10 +211,10 @@ static void get_str(char** string, toml_table_t *table, const char* name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_int(int* integer, toml_table_t *table, const char* name) {
|
static void get_int(int* integer, const toml_table_t *table, const char* name) {
|
||||||
DEBUG("retrieving integer %s", name);
|
DEBUG("retrieving integer %s", name);
|
||||||
|
|
||||||
toml_datum_t datum = toml_int_in(table, name);
|
const toml_datum_t datum = toml_int_in(table, name);
|
||||||
|
|
||||||
if (datum.ok) {
|
if (datum.ok) {
|
||||||
*integer = (int) datum.u.i;
|
*integer = (int) datum.u.i;
|
||||||
|
@ -221,7 +222,7 @@ static void get_int(int* integer, toml_table_t *table, const char* name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_project_table(ProjectConfig *config, toml_table_t *project_table) {
|
static int parse_project_table(ProjectConfig *config, const toml_table_t *project_table) {
|
||||||
DEBUG("parsing project table...");
|
DEBUG("parsing project table...");
|
||||||
|
|
||||||
// project name
|
// project name
|
||||||
|
@ -268,7 +269,7 @@ static int get_mode_from_str(TargetCompilationMode* mode, const char* name) {
|
||||||
return PROJECT_SEMANTIC_ERR;
|
return PROJECT_SEMANTIC_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_target(ProjectConfig *config, toml_table_t *target_table, const char* name) {
|
static int parse_target(const ProjectConfig *config, const toml_table_t *target_table, const char* name) {
|
||||||
DEBUG("parsing target table...");
|
DEBUG("parsing target table...");
|
||||||
|
|
||||||
TargetConfig* target_config = default_target_config();
|
TargetConfig* target_config = default_target_config();
|
||||||
|
@ -297,7 +298,7 @@ static int parse_target(ProjectConfig *config, toml_table_t *target_table, const
|
||||||
return PROJECT_OK;
|
return PROJECT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_targets(ProjectConfig *config, toml_table_t *root) {
|
static int parse_targets(ProjectConfig *config, const toml_table_t *root) {
|
||||||
DEBUG("parsing targets of project \"%s\"", config->name);
|
DEBUG("parsing targets of project \"%s\"", config->name);
|
||||||
|
|
||||||
toml_table_t *targets = toml_table_in(root, "target");
|
toml_table_t *targets = toml_table_in(root, "target");
|
||||||
|
@ -311,7 +312,7 @@ static int parse_targets(ProjectConfig *config, toml_table_t *root) {
|
||||||
for (int i = 0; i < MAX_TARGETS_PER_PROJECT; i++) {
|
for (int i = 0; i < MAX_TARGETS_PER_PROJECT; i++) {
|
||||||
const char *key = toml_key_in(targets, i);
|
const char *key = toml_key_in(targets, i);
|
||||||
|
|
||||||
if (!key)
|
if (key == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
toml_table_t *target = toml_table_in(targets, key);
|
toml_table_t *target = toml_table_in(targets, key);
|
||||||
|
@ -331,18 +332,18 @@ int load_project_config(ProjectConfig *config) {
|
||||||
return PROJECT_TOML_ERR;
|
return PROJECT_TOML_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
char err_buf[200];
|
char err_buf[TOML_ERROR_MSG_BUF];
|
||||||
|
|
||||||
toml_table_t *conf = toml_parse_file(config_file, err_buf, sizeof(err_buf));
|
toml_table_t *conf = toml_parse_file(config_file, err_buf, sizeof(err_buf));
|
||||||
fclose(config_file);
|
fclose(config_file);
|
||||||
|
|
||||||
if (!conf) {
|
if (conf == NULL) {
|
||||||
print_message(Error, "Invalid project configuration: %s", err_buf);
|
print_message(Error, "Invalid project configuration: %s", err_buf);
|
||||||
return PROJECT_SEMANTIC_ERR;
|
return PROJECT_SEMANTIC_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
toml_table_t *project = toml_table_in(conf, "project");
|
toml_table_t *project = toml_table_in(conf, "project");
|
||||||
if (!project) {
|
if (project == NULL) {
|
||||||
print_message(Error, "Invalid project configuration: missing project table.");
|
print_message(Error, "Invalid project configuration: missing project table.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#ifndef GEMSTONE_OPT_H
|
#ifndef GEMSTONE_OPT_H
|
||||||
#define GEMSTONE_OPT_H
|
#define GEMSTONE_OPT_H
|
||||||
|
|
||||||
#include <toml.h>
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#define MAX_TARGETS_PER_PROJECT 100
|
#define MAX_TARGETS_PER_PROJECT 100
|
||||||
|
@ -15,11 +14,20 @@
|
||||||
#define PROJECT_TOML_ERR 1
|
#define PROJECT_TOML_ERR 1
|
||||||
#define PROJECT_SEMANTIC_ERR 2
|
#define PROJECT_SEMANTIC_ERR 2
|
||||||
|
|
||||||
|
#define TOML_ERROR_MSG_BUF 256
|
||||||
|
|
||||||
typedef enum TargetCompilationMode_t {
|
typedef enum TargetCompilationMode_t {
|
||||||
|
// output an executable binary
|
||||||
Application,
|
Application,
|
||||||
|
// output a binary object file
|
||||||
Library
|
Library
|
||||||
} TargetCompilationMode;
|
} TargetCompilationMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A target defines a source file which is to be compiled into a specific
|
||||||
|
* format. Additionally properties such as output folders can be set.
|
||||||
|
* Intermediate representations can be printed as well.
|
||||||
|
*/
|
||||||
typedef struct TargetConfig_t {
|
typedef struct TargetConfig_t {
|
||||||
char* name;
|
char* name;
|
||||||
bool print_ast;
|
bool print_ast;
|
||||||
|
@ -38,6 +46,11 @@ typedef struct TargetConfig_t {
|
||||||
int optimization_level;
|
int optimization_level;
|
||||||
} TargetConfig;
|
} TargetConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A project is a collection of targets. Each target can point to
|
||||||
|
* very different sources. The project binds these targets together
|
||||||
|
* and specifies metadata about the authors and others.
|
||||||
|
*/
|
||||||
typedef struct ProjectConfig_t {
|
typedef struct ProjectConfig_t {
|
||||||
// name of the project
|
// name of the project
|
||||||
char* name;
|
char* name;
|
||||||
|
@ -52,35 +65,102 @@ typedef struct ProjectConfig_t {
|
||||||
GHashTable* targets;
|
GHashTable* targets;
|
||||||
} ProjectConfig;
|
} ProjectConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a command line option.
|
||||||
|
*/
|
||||||
typedef struct Option_t {
|
typedef struct Option_t {
|
||||||
|
// index in which the option appeared in the argument array
|
||||||
int index;
|
int index;
|
||||||
|
// identifier of the option
|
||||||
const char* string;
|
const char* string;
|
||||||
|
// option if format is equals to --option=value
|
||||||
const char* value;
|
const char* value;
|
||||||
|
// whether or not this option has a value
|
||||||
bool is_opt;
|
bool is_opt;
|
||||||
} Option;
|
} Option;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create the default configuration for targets.
|
||||||
|
* @return A pointer to a new target configuration.
|
||||||
|
*/
|
||||||
|
[[nodiscard("must be freed")]]
|
||||||
TargetConfig* default_target_config();
|
TargetConfig* default_target_config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create the default configuration for a project.
|
||||||
|
* Contains no targets.
|
||||||
|
* @return A pointer to a new project configuration.
|
||||||
|
*/
|
||||||
|
[[nodiscard("must be freed")]]
|
||||||
ProjectConfig* default_project_config();
|
ProjectConfig* default_project_config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a new default target configuration an write command line
|
||||||
|
* option onto the default configuration.
|
||||||
|
* @return A default config with user specified values.
|
||||||
|
*/
|
||||||
|
[[nodiscard("must be freed")]]
|
||||||
TargetConfig* default_target_config_from_args();
|
TargetConfig* default_target_config_from_args();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load a project configuration from a TOML file with the name
|
||||||
|
* PROJECT_CONFIG_FILE.
|
||||||
|
* @param config Configuration to fill values from file into.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
[[gnu::nonnull(1)]]
|
||||||
int load_project_config(ProjectConfig *config);
|
int load_project_config(ProjectConfig *config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print a help dialog to stdout.
|
||||||
|
*/
|
||||||
void print_help(void);
|
void print_help(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete a project config by deallocation.
|
||||||
|
* @param config The config to free.
|
||||||
|
*/
|
||||||
|
[[gnu::nonnull(1)]]
|
||||||
void delete_project_config(ProjectConfig* config);
|
void delete_project_config(ProjectConfig* config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete a target configuration by deallocation.
|
||||||
|
*/
|
||||||
|
[[gnu::nonnull(1)]]
|
||||||
void delete_target_config(TargetConfig*);
|
void delete_target_config(TargetConfig*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse the given command line arguments so that calls to
|
||||||
|
* is_option_set() and get_option() can be made safely.
|
||||||
|
* @param argc Number of arguments
|
||||||
|
* @param argv Array of arguments
|
||||||
|
*/
|
||||||
void parse_options(int argc, char* argv[]);
|
void parse_options(int argc, char* argv[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tests whether an option was set as argument.
|
||||||
|
* @attention Requires a previous call to parse_options()
|
||||||
|
* @param option Name of option to check for.
|
||||||
|
* @return 1 if the options was set, 0 otherwise
|
||||||
|
*/
|
||||||
[[gnu::nonnull(1)]]
|
[[gnu::nonnull(1)]]
|
||||||
bool is_option_set(const char* option);
|
bool is_option_set(const char* option);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the options information if present
|
||||||
|
* @attention Requires a previous call to parse_options()
|
||||||
|
* @param option
|
||||||
|
* @return A valid option struct or NULL if not found.
|
||||||
|
*/
|
||||||
[[gnu::nonnull(1)]]
|
[[gnu::nonnull(1)]]
|
||||||
const Option* get_option(const char* option);
|
const Option* get_option(const char* option);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Put a copy of all options whos index is greather than the index
|
||||||
|
* of the option specified by command.
|
||||||
|
* @param command
|
||||||
|
* @return an array of options that followed command.
|
||||||
|
*/
|
||||||
[[gnu::nonnull(1)]]
|
[[gnu::nonnull(1)]]
|
||||||
[[nodiscard("must be freed")]]
|
[[nodiscard("must be freed")]]
|
||||||
GArray* get_non_options_after(const char* command);
|
GArray* get_non_options_after(const char* command);
|
||||||
|
|
|
@ -72,9 +72,7 @@ static int setup_target_environment(const TargetConfig *target) {
|
||||||
assert(target->output_directory != NULL);
|
assert(target->output_directory != NULL);
|
||||||
assert(target->archive_directory != NULL);
|
assert(target->archive_directory != NULL);
|
||||||
|
|
||||||
int result;
|
int result = create_directory(target->archive_directory);
|
||||||
|
|
||||||
result = create_directory(target->archive_directory);
|
|
||||||
if (result != 0 && errno != EEXIST) {
|
if (result != 0 && errno != EEXIST) {
|
||||||
const char *message = get_last_error();
|
const char *message = get_last_error();
|
||||||
assert(message != NULL);
|
assert(message != NULL);
|
||||||
|
@ -102,7 +100,7 @@ static int setup_target_environment(const TargetConfig *target) {
|
||||||
* @param ast
|
* @param ast
|
||||||
* @param target
|
* @param target
|
||||||
*/
|
*/
|
||||||
static void print_ast_to_file(AST_NODE_PTR ast, TargetConfig *target) {
|
static void print_ast_to_file(const AST_NODE_PTR ast, const TargetConfig *target) {
|
||||||
assert(ast != NULL);
|
assert(ast != NULL);
|
||||||
assert(target != NULL);
|
assert(target != NULL);
|
||||||
|
|
||||||
|
@ -132,7 +130,7 @@ static void print_ast_to_file(AST_NODE_PTR ast, TargetConfig *target) {
|
||||||
* @param unit
|
* @param unit
|
||||||
* @param target
|
* @param target
|
||||||
*/
|
*/
|
||||||
static void build_target(ModuleFileStack *unit, TargetConfig *target) {
|
static void build_target(ModuleFileStack *unit, const TargetConfig *target) {
|
||||||
print_message(Info, "Building target: %s", target->name);
|
print_message(Info, "Building target: %s", target->name);
|
||||||
|
|
||||||
AST_NODE_PTR ast = AST_new_node(empty_location(), AST_Module, NULL);
|
AST_NODE_PTR ast = AST_new_node(empty_location(), AST_Module, NULL);
|
||||||
|
@ -157,8 +155,6 @@ static void build_target(ModuleFileStack *unit, TargetConfig *target) {
|
||||||
* @brief Compile a single file.
|
* @brief Compile a single file.
|
||||||
* Creates a single target by the given command line arguments.
|
* Creates a single target by the given command line arguments.
|
||||||
* @param unit
|
* @param unit
|
||||||
* @param argc
|
|
||||||
* @param argv
|
|
||||||
*/
|
*/
|
||||||
static void compile_file(ModuleFileStack *unit) {
|
static void compile_file(ModuleFileStack *unit) {
|
||||||
INFO("compiling basic files...");
|
INFO("compiling basic files...");
|
||||||
|
@ -181,7 +177,7 @@ static void compile_file(ModuleFileStack *unit) {
|
||||||
* @param unit
|
* @param unit
|
||||||
* @param config
|
* @param config
|
||||||
*/
|
*/
|
||||||
static void build_project_targets(ModuleFileStack *unit, ProjectConfig *config) {
|
static void build_project_targets(ModuleFileStack *unit, const ProjectConfig *config) {
|
||||||
if (is_option_set("all")) {
|
if (is_option_set("all")) {
|
||||||
// build all targets in the project
|
// build all targets in the project
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/col.h>
|
#include <sys/col.h>
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ ModuleFile *push_file(ModuleFileStack *stack, const char *path) {
|
||||||
|
|
||||||
void delete_files(ModuleFileStack *stack) {
|
void delete_files(ModuleFileStack *stack) {
|
||||||
for (size_t i = 0; i < stack->files->len; i++) {
|
for (size_t i = 0; i < stack->files->len; i++) {
|
||||||
ModuleFile *file = ((ModuleFile *) stack->files->data) + i;
|
const ModuleFile *file = (ModuleFile *) stack->files->data + i;
|
||||||
|
|
||||||
if (file->handle != NULL) {
|
if (file->handle != NULL) {
|
||||||
DEBUG("closing file: %s", file->path);
|
DEBUG("closing file: %s", file->path);
|
||||||
|
@ -62,6 +61,8 @@ void delete_files(ModuleFileStack *stack) {
|
||||||
DEBUG("deleted module file stack");
|
DEBUG("deleted module file stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Number of bytes to read at once whilest
|
||||||
|
// seeking the current line in print_diagnostic()
|
||||||
#define SEEK_BUF_BYTES 256
|
#define SEEK_BUF_BYTES 256
|
||||||
|
|
||||||
static inline unsigned long int min(unsigned long int a, unsigned long int b) {
|
static inline unsigned long int min(unsigned long int a, unsigned long int b) {
|
||||||
|
@ -121,16 +122,15 @@ void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, c
|
||||||
|
|
||||||
free((void *) absolute_path);
|
free((void *) absolute_path);
|
||||||
|
|
||||||
size_t lines = location->line_end - location->line_start + 1;
|
const size_t lines = location->line_end - location->line_start + 1;
|
||||||
|
|
||||||
for (size_t l = 0; l < lines; l++) {
|
for (size_t l = 0; l < lines; l++) {
|
||||||
printf(" %4ld | ", location->line_start + l);
|
printf(" %4ld | ", location->line_start + l);
|
||||||
|
|
||||||
size_t limit;
|
|
||||||
size_t chars = 0;
|
size_t chars = 0;
|
||||||
|
|
||||||
// print line before token group start
|
// print line before token group start
|
||||||
limit = min(location->col_start, SEEK_BUF_BYTES);
|
size_t limit = min(location->col_start, SEEK_BUF_BYTES);
|
||||||
while (limit > 1) {
|
while (limit > 1) {
|
||||||
custom_fgets(buffer, (int) limit, file->handle);
|
custom_fgets(buffer, (int) limit, file->handle);
|
||||||
chars += printf("%s", buffer);
|
chars += printf("%s", buffer);
|
||||||
|
|
Loading…
Reference in New Issue