gemstone/src/io/files.h

157 lines
3.8 KiB
C

//
// Created by servostar on 5/30/24.
//
#ifndef GEMSTONE_FILES_H
#define GEMSTONE_FILES_H
#include <stdio.h>
#include <glib.h>
#if defined(WIN32) || defined(_WIN32)
#define PATH_SEPARATOR "\\"
#else
#define PATH_SEPARATOR "/"
#endif
typedef struct FileDiagnosticStatistics_t {
size_t error_count;
size_t warning_count;
size_t info_count;
} FileDiagnosticStatistics;
typedef struct ModuleFile_t {
const char *path;
FILE *handle;
FileDiagnosticStatistics statistics;
} ModuleFile;
typedef struct ModuleFileStack_t {
GArray *files;
} ModuleFileStack;
typedef enum Message_t {
Info,
Warning,
Error
} Message;
typedef struct TokenLocation_t {
unsigned long int line_start;
unsigned long int col_start;
unsigned long int line_end;
unsigned long int col_end;
} TokenLocation;
/**
* @brief Create a new, empty file stack.
* @return
*/
ModuleFileStack new_file_stack();
/**
* @brief Add a new file to the file stack.
* @attention The file handle returned will be invalid
* @param stack
* @param path
* @return A new file module
*/
[[gnu::nonnull(1), gnu::nonnull(2)]]
ModuleFile *push_file(ModuleFileStack *stack, const char *path);
/**
* @brief Delete all files in the stack and the stack itself
* @param stack
*/
[[gnu::nonnull(1)]]
void delete_files(ModuleFileStack *stack);
/**
* Create a new token location
* @param line_start
* @param col_start
* @param line_end
* @param col_end
* @return
*/
TokenLocation new_location(unsigned long int line_start, unsigned long int col_start, unsigned long int line_end,
unsigned long int col_end);
/**
* @brief Create a new empty location with all of its contents set to zero
* @return
*/
TokenLocation empty_location(void);
/**
* @brief Prints some diagnostic message to stdout.
* This also print the token group and the attached source as context.
* @param file
* @param location
* @param kind
* @param message
*/
[[gnu::nonnull(1), gnu::nonnull(2)]]
void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message, ...);
[[gnu::nonnull(2)]]
/**
* @brief Print a general message to stdout. Provides no source context like print_diagnostic()
* @param kind
* @param fmt
* @param ...
*/
void print_message(Message kind, const char *fmt, ...);
/**
* @brief Print statistics about a specific file.
* Will print the amount of infos, warning and errors emitted during compilation.
* @param file
*/
[[gnu::nonnull(1)]]
void print_file_statistics(ModuleFile *file);
/**
* @brief Print statistics of all files in the module stack.
* @param file_stack
*/
[[gnu::nonnull(1)]]
void print_unit_statistics(ModuleFileStack *file_stack);
/**
* @brief Create a new directory. Will return EEXISTS in case the directory already exists.
* @param path
* @return 0 if successful, anything else otherwise
*/
[[gnu::nonnull(1)]]
int create_directory(const char* path);
/**
* @brief Get a string describing the last error set by errno.
* @return a string that must be freed
*/
[[nodiscard("pointer must be freed")]]
const char* get_last_error();
/**
* @brief Resolve the absolute path from a given relative path.
* @param path
* @return
*/
[[gnu::nonnull(1)]]
[[nodiscard("pointer must be freed")]]
const char* get_absolute_path(const char* path);
/**
* @brief Create a file path from a base name, extension a variable amount of directory path segments.
* @param count Amount of path segments to prepend to the basename
* @param name Basename of the file
* @param ext Extension of the file
* @param ... Path segments without path separator
* @return A relative path of a file
*/
[[nodiscard("pointer must be freed")]]
const char* make_file_path(const char* name, const char* ext, int count, ...);
#endif //GEMSTONE_FILES_H