Merge branch 'main' into 5-create-tokenizer
This commit is contained in:
commit
c18131fa90
|
@ -0,0 +1,14 @@
|
||||||
|
name: "Build check gemstone in SDK"
|
||||||
|
run-name: SDK build check to ${{ inputs.deploy_target }} by @${{ github.actor }}
|
||||||
|
on: [push, pull_request]
|
||||||
|
env:
|
||||||
|
SDK: 0.1.0-alma-9.3
|
||||||
|
jobs:
|
||||||
|
build-check-sdk:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup SDK
|
||||||
|
run: docker pull servostar/gemstone:sdk-"$SDK" && docker build --tag gemstone:devkit-"$SDK" .
|
||||||
|
- name: Compile
|
||||||
|
run: docker run gemstone:devkit-"$SDK" make check
|
|
@ -102,3 +102,28 @@ target_compile_options(debug PUBLIC ${FLAGS} -g)
|
||||||
|
|
||||||
# add src directory as include path
|
# add src directory as include path
|
||||||
target_include_directories(debug PUBLIC src)
|
target_include_directories(debug PUBLIC src)
|
||||||
|
|
||||||
|
# ------------------------------------------------ #
|
||||||
|
# Target Code Check #
|
||||||
|
# ------------------------------------------------ #
|
||||||
|
|
||||||
|
# Same as debug but will fail on warnings
|
||||||
|
# use as check
|
||||||
|
|
||||||
|
add_executable(check
|
||||||
|
${SOURCE_FILES}
|
||||||
|
${LEX_GENERATED_SOURCE_FILE}
|
||||||
|
${YACC_GENERATED_SOURCE_FILE})
|
||||||
|
|
||||||
|
set_target_properties(check
|
||||||
|
PROPERTIES
|
||||||
|
OUTPUT_NAME "gsc"
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY "bin/check")
|
||||||
|
|
||||||
|
# compiler flags targeting a GCC debug environment
|
||||||
|
# extra -Werror flag to treat warnings as error to make github action fail on warning
|
||||||
|
target_compile_options(check PUBLIC ${FLAGS} -g -Werror)
|
||||||
|
|
||||||
|
# add src directory as include path
|
||||||
|
target_include_directories(check PUBLIC src)
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,12 @@
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
/* disable the following functions */
|
||||||
|
/* to avoid failing code check */
|
||||||
|
%option nounput
|
||||||
|
%option noinput
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
"\n" yyLineNumber++;
|
"\n" yyLineNumber++;
|
||||||
|
|
||||||
|
|
37
src/main.c
37
src/main.c
|
@ -1,6 +1,41 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/log.h>
|
||||||
#include <yacc/parser.tab.h>
|
#include <yacc/parser.tab.h>
|
||||||
|
|
||||||
int main() {
|
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Log a debug message to inform about beginning exit procedures
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void notify_exit(void)
|
||||||
|
{
|
||||||
|
DEBUG("Exiting gemstone...");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Run compiler setup here
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void setup(void)
|
||||||
|
{
|
||||||
|
// setup preample
|
||||||
|
|
||||||
|
log_init();
|
||||||
|
DEBUG("starting gemstone...");
|
||||||
|
|
||||||
|
#if LOG_LEVEL <= LOG_LEVEL_DEBUG
|
||||||
|
atexit(¬ify_exit);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// actual setup
|
||||||
|
|
||||||
|
DEBUG("finished starting up gemstone...");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
setup();
|
||||||
|
|
||||||
yyparse();
|
yyparse();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/log.h>
|
||||||
|
|
||||||
|
static struct Logger_t {
|
||||||
|
FILE** streams;
|
||||||
|
size_t stream_count;
|
||||||
|
} GlobalLogger;
|
||||||
|
|
||||||
|
void log_init(void)
|
||||||
|
{
|
||||||
|
log_register_stream(LOG_DEFAULT_STREAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_register_stream(FILE* restrict stream)
|
||||||
|
{
|
||||||
|
if (stream == NULL)
|
||||||
|
PANIC("stream to register is NULL");
|
||||||
|
|
||||||
|
if (GlobalLogger.stream_count == 0)
|
||||||
|
{
|
||||||
|
GlobalLogger.streams = (FILE**) malloc(sizeof(FILE*));
|
||||||
|
GlobalLogger.stream_count = 1;
|
||||||
|
|
||||||
|
if (GlobalLogger.streams == NULL)
|
||||||
|
{
|
||||||
|
PANIC("failed to allocate stream buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GlobalLogger.stream_count++;
|
||||||
|
size_t bytes = GlobalLogger.stream_count * sizeof(FILE*);
|
||||||
|
GlobalLogger.streams = (FILE**) realloc(GlobalLogger.streams, bytes);
|
||||||
|
|
||||||
|
if (GlobalLogger.streams == NULL)
|
||||||
|
{
|
||||||
|
PANIC("failed to reallocate stream buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalLogger.streams[GlobalLogger.stream_count - 1] = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vflogf(
|
||||||
|
FILE* restrict stream,
|
||||||
|
const char* restrict level,
|
||||||
|
const char* restrict file,
|
||||||
|
const unsigned long line,
|
||||||
|
const char* restrict func,
|
||||||
|
const char* restrict format,
|
||||||
|
va_list args)
|
||||||
|
{
|
||||||
|
fprintf(stream, "%s in %s() at %s:%lu: ", level, func, file, line);
|
||||||
|
vfprintf(stream, format, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __logf(
|
||||||
|
const char* restrict level,
|
||||||
|
const char* restrict file,
|
||||||
|
const unsigned long line,
|
||||||
|
const char* restrict func,
|
||||||
|
const char* restrict format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < GlobalLogger.stream_count; i++)
|
||||||
|
{
|
||||||
|
FILE* stream = GlobalLogger.streams[i];
|
||||||
|
|
||||||
|
vflogf(stream, level, file, line, func, format, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __panicf(
|
||||||
|
const char* restrict file,
|
||||||
|
const unsigned long line,
|
||||||
|
const char* restrict func,
|
||||||
|
const char* restrict format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
vflogf(stderr, LOG_STRING_PANIC, file, line, func, format, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __fatalf(
|
||||||
|
const char* restrict file,
|
||||||
|
const unsigned long line,
|
||||||
|
const char* restrict func,
|
||||||
|
const char* restrict format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
vflogf(stderr, LOG_STRING_FATAL, file, line, func, format, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
abort();
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
#ifndef _SYS_ERR_H_
|
||||||
|
#define _SYS_ERR_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
#define LOG_DEFAULT_STREAM stderr
|
||||||
|
|
||||||
|
#define LOG_LEVEL_ERROR 3
|
||||||
|
#define LOG_LEVEL_WARNING 2
|
||||||
|
#define LOG_LEVEL_INFORMATION 1
|
||||||
|
#define LOG_LEVEL_DEBUG 0
|
||||||
|
|
||||||
|
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
||||||
|
|
||||||
|
#define LOG_STRING_PANIC "Critical"
|
||||||
|
#define LOG_STRING_FATAL "Fatal"
|
||||||
|
#define LOG_STRING_ERROR "Error"
|
||||||
|
#define LOG_STRING_WARNING "Warning"
|
||||||
|
#define LOG_STRING_INFORMATION "Information"
|
||||||
|
#define LOG_STRING_DEBUG "Debug"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Panic is used in cases where the process is in an unrecoverable state.
|
||||||
|
* This macro will print debug information to stderr and call abort() to
|
||||||
|
* performa a ungracefull exit. No clean up possible.
|
||||||
|
*/
|
||||||
|
#define PANIC(format, ...) __panicf(__FILE_NAME__, __LINE__, __func__, format"\n", ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Panic is used in cases where the process is in an invalid or undefined state.
|
||||||
|
* This macro will print debug information to stderr and call exit() to
|
||||||
|
* initiate a gracefull exit, giving the process the opportunity to clean up.
|
||||||
|
*/
|
||||||
|
#define FATAL(format, ...) __fatalf(__FILE_NAME__, __LINE__, __func__, format"\n", ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Standard log macros. These will not terminate the application.
|
||||||
|
Can be turned off by setting LOG_LEVEL. All logs which have smaller log numbers
|
||||||
|
will not print.
|
||||||
|
*/
|
||||||
|
#define ERROR(format, ...) __LOG(LOG_STRING_ERROR, LOG_LEVEL_ERROR, format"\n", ##__VA_ARGS__)
|
||||||
|
#define WARN(format, ...) __LOG(LOG_STRING_WARNING, LOG_LEVEL_WARNING, format"\n", ##__VA_ARGS__)
|
||||||
|
#define INFO(format, ...) __LOG(LOG_STRING_INFORMATION, LOG_LEVEL_INFORMATION, format"\n", ##__VA_ARGS__)
|
||||||
|
#define DEBUG(format, ...) __LOG(LOG_STRING_DEBUG, LOG_LEVEL_DEBUG, format"\n", ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define __LOG(level, priority, format, ...) \
|
||||||
|
do { \
|
||||||
|
if (LOG_LEVEL <= priority) \
|
||||||
|
__logf(level, __FILE_NAME__, __LINE__, __func__, format, ##__VA_ARGS__); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Log a message into all registered streams
|
||||||
|
*
|
||||||
|
* @param level of the message
|
||||||
|
* @param file origin of the message cause
|
||||||
|
* @param line line in which log call was made
|
||||||
|
* @param func function the log call was done in
|
||||||
|
* @param format the format to print following args in
|
||||||
|
* @param ...
|
||||||
|
*/
|
||||||
|
void __logf(
|
||||||
|
const char* restrict level,
|
||||||
|
const char* restrict file,
|
||||||
|
const unsigned long line,
|
||||||
|
const char* restrict func,
|
||||||
|
const char* restrict format,
|
||||||
|
...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Log a panic message to stderr and perform gracefull crash with exit() denoting a failure
|
||||||
|
*
|
||||||
|
* @param file origin of the message cause
|
||||||
|
* @param line line in which log call was made
|
||||||
|
* @param func function the log call was done in
|
||||||
|
* @param format the format to print following args in
|
||||||
|
* @param ...
|
||||||
|
*/
|
||||||
|
void __panicf(
|
||||||
|
const char* restrict file,
|
||||||
|
const unsigned long line,
|
||||||
|
const char* restrict func,
|
||||||
|
const char* restrict format,
|
||||||
|
...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Log a critical message to stderr and perform ungracefull crash with abort()
|
||||||
|
*
|
||||||
|
* @param file origin of the message cause
|
||||||
|
* @param line line in which log call was made
|
||||||
|
* @param func function the log call was done in
|
||||||
|
* @param format the format to print following args in
|
||||||
|
* @param ...
|
||||||
|
*/
|
||||||
|
void __fatalf(
|
||||||
|
const char* restrict file,
|
||||||
|
const unsigned long line,
|
||||||
|
const char* restrict func,
|
||||||
|
const char* restrict format,
|
||||||
|
...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the logger by registering stderr as stream
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void log_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register a stream as output source. Must be freed manually at exit if necessary
|
||||||
|
*
|
||||||
|
* @param stream
|
||||||
|
*/
|
||||||
|
void log_register_stream(FILE* restrict stream);
|
||||||
|
|
||||||
|
#endif /* _SYS_ERR_H_ */
|
Loading…
Reference in New Issue