Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PROJECT_NAME} C)
set(CMAKE_C_STANDARD 99)

set(CMAKE_EXPORT_COMPILE_COMMANDS on)

# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Debug' as none was specified.")
Expand Down
8 changes: 4 additions & 4 deletions src/io/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include <string.h>
#include <unistd.h> // access()
#include <libgen.h> // dirname()
#include <limits.h> // PATH_MAX
#include <errno.h>
#include "common/config.h"
#include "common/logging.h"
Expand Down Expand Up @@ -68,12 +67,13 @@ File *File_Open(const char *filename, FileAccessType access) {
// find project file
char *find_project_file(const char *rel_path) {
static char path[PATH_MAX];
char exe_dir[PATH_MAX];
char exe_abs_path[PATH_MAX];
char *exe_dir = NULL;
char *home = getenv("HOME");

// 1️. directory of the binary
if (realpath(Config_GetExePath(), exe_dir)) {
strcpy(exe_dir, dirname(exe_dir));
if (realpath(Config_GetExePath(), exe_abs_path)) {
exe_dir = dirname(exe_abs_path);
int n = snprintf(path, sizeof(path), "%s/%s", exe_dir, rel_path);
n = n >= (int)sizeof(path) ? (int)sizeof(path) - 1 : n;
path[n] = '\0';
Expand Down
1 change: 1 addition & 0 deletions src/io/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#ifndef FILE_H
#define FILE_H

#include <limits.h> // PATH_MAX
Comment thread
defname marked this conversation as resolved.
#include "stdio.h"
#include "common/string.h"

Expand Down
19 changes: 18 additions & 1 deletion src/syntax/highlighting.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void SyntaxHighlightingString_Clear(SyntaxHighlightingString *shs) {
/*****************************************************************************/
/* SyntaxHighlighting */

void SyntaxHighlighting_Init(SyntaxHighlighting *hl, const SyntaxDefinition *def) {
void SyntaxHighlighting_Init(SyntaxHighlighting *hl, SyntaxDefinition *def) {
hl->def = def;
hl->strings = Table_CreatePtr();
}
Expand All @@ -99,10 +99,27 @@ void SyntaxHighlighting_Deinit(SyntaxHighlighting *hl) {
if (hl->strings) {
Table_Destroy(hl->strings);
}
if (hl->def) {
SyntaxDefinition_Destroy(hl->def);
}
hl->strings = NULL;
hl->def = NULL;
}

SyntaxHighlighting *SyntaxHighlighting_Create(SyntaxDefinition *def) {
SyntaxHighlighting *hl = malloc(sizeof(SyntaxHighlighting));
if (!hl) {
logFatal("Cannot allocate memory for SyntaxHighlighting.");
}
SyntaxHighlighting_Init(hl, def);
return hl;
}

void SyntaxHighlighting_Destroy(SyntaxHighlighting *hl) {
SyntaxHighlighting_Deinit(hl);
free(hl);
}

static bool regexec_with_cache(const regex_t *regex, const char *str, size_t offset, MatchCache *cache, regmatch_t *match) {
if (cache->done) {
return false;
Expand Down
23 changes: 17 additions & 6 deletions src/syntax/highlighting.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,25 +73,36 @@ void SyntaxHighlightingString_Destroy(SyntaxHighlightingString *shs);
void SyntaxHighlightingString_AddTag(SyntaxHighlightingString *shs, SyntaxHighlightingTag tag);
void SyntaxHighlightingString_Clear(SyntaxHighlightingString *shs);

/**match
/**
* @brief Holds the highlighting information for text of multiple `Strings`.
*/
typedef struct _SyntaxHighlighting {
const SyntaxDefinition *def; //< SyntaxDefinition to use for highlighting
SyntaxDefinition *def; //< SyntaxDefinition to use for highlighting
Table *strings; //< Table of (String -> SyntaxHighlightingString*) elements (holds the ownership of the SyntaxHighlightingString's)
} SyntaxHighlighting;


/**
* @brief Initialize syntax highlighting using def for definitions.
*
* Note that the ownership of `def` is taken!.
*/
void SyntaxHighlighting_Init(SyntaxHighlighting *sh, const SyntaxDefinition *def);
void SyntaxHighlighting_Init(SyntaxHighlighting *sh, SyntaxDefinition *def);

/**
* @brief Deinitialize sh.
*/
/** @brief Deinitialize `sh`. */
void SyntaxHighlighting_Deinit(SyntaxHighlighting *sh);

/**
* @brief Instantiate `SyntaxHighlighting`.
*
* @param def The ownership of `def` is taken!
* @returns The newly created `SyntaxHighlighting` instance.
*/
SyntaxHighlighting *SyntaxHighlighting_Create(SyntaxDefinition *def);

/** @brief Destroy `sh` */
void SyntaxHighlighting_Destroy(SyntaxHighlighting *sh);

/**
* @brief Highlight a string according to given context.
*
Expand Down
76 changes: 76 additions & 0 deletions src/syntax/loader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "loader.h"
#include <string.h>
#include <stdio.h> // snprintf
#include "io/file.h"

void SyntaxHighlightingLoaderError_Init(SyntaxHighlightingLoaderError *error) {
memset(error, 0, sizeof(SyntaxHighlightingLoaderError));
error->code = SYNTAX_LOADER_NO_ERROR;
}


void SyntaxHighlightingLoaderError_Deinit(SyntaxHighlightingLoaderError *error) {
SyntaxDefinitionError_Deinit(&error->def_error);
if (error->parsing_error.message) {
free(error->parsing_error.message);
}
}


SyntaxHighlighting *SyntaxHighlighting_LoadFromFile(const char *format, SyntaxHighlightingLoaderError *error) {
if (!error) {
return NULL;
}
SyntaxHighlightingLoaderError_Init(error);

if (!format) {
error->code = SYNTAX_LOADER_NO_FILENAME;
return NULL;
}

// 1. load the ini file
char filename[PATH_MAX];
snprintf(filename, PATH_MAX, "data/syntax/%s.ini", format);
File *file = File_OpenProjectFile(filename, FILE_ACCESS_READ);
if (!file) {
error->code = SYNTAX_LOADER_FILE_NOT_FOUND;
return NULL;
}

// 2. read the ini file
char *ini = File_Read(file);
if (!ini) {
error->code = SYNTAX_LOADER_FILE_READ_ERROR;
File_Close(file);
return NULL;
}
File_Close(file);

// 3. parse the ini file
IniParser parser;
IniParser_Init(&parser);
IniParser_SetText(&parser, ini);
Table *table = IniParser_Parse(&parser);
if (!table) {
error->code = SYNTAX_LOADER_PARSE_ERROR;
error->parsing_error = *IniParser_GetError(&parser);
error->parsing_error.message = strdup(IniParser_GetError(&parser)->message);
IniParser_Deinit(&parser);
free(ini);
return NULL;
}
IniParser_Deinit(&parser);
free(ini);
Comment thread
defname marked this conversation as resolved.

// 4. create the syntax definition
SyntaxDefinition *def = SyntaxDefinition_FromTable(table, &error->def_error);
if (!def) {
Table_Destroy(table);
error->code = SYNTAX_LOADER_DEFINITION_ERROR;
return NULL;
}
Table_Destroy(table);

// 5. create the highlighting engine
return SyntaxHighlighting_Create(def);
}
43 changes: 43 additions & 0 deletions src/syntax/loader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef SYNTAX_LOADER_H
#define SYNTAX_LOADER_H

#include "highlighting.h"
#include "common/iniparser.h"

typedef enum {
SYNTAX_LOADER_NO_ERROR,
SYNTAX_LOADER_NO_FILENAME,
SYNTAX_LOADER_FILE_NOT_FOUND,
SYNTAX_LOADER_FILE_READ_ERROR,
SYNTAX_LOADER_PARSE_ERROR,
SYNTAX_LOADER_DEFINITION_ERROR
} SyntaxHighlightingLoaderErrorCode;

typedef struct {
SyntaxHighlightingLoaderErrorCode code;
SyntaxDefinitionError def_error;
ParsingError parsing_error;
} SyntaxHighlightingLoaderError;

void SyntaxHighlightingLoaderError_Deinit(SyntaxHighlightingLoaderError *error);


/**
* @brief Load a syntax definition and create the highlight engine.
*
* Load the syntax definition for `format` from data/sytnax/<format>.ini
* (from inside a project's folder) and create the `SyntaxHighlight` instance.
*
* @param format Format to load (something like "ini", "md").
* @param error Will be set in the case of an error and need to be deinitialized by the caller.
* @returns
* The newly created SyntaxHighlighting Instance (ownership transfers to the caller).
* NULL there is definition file or if an error occured.
* In the case of an error `error` will be set and need to be deinitialized by the caller.
*
* Note theat `format` needs to be exactly the same as the filename.
* The convention is to use lower case.
*/
SyntaxHighlighting *SyntaxHighlighting_LoadFromFile(const char *format, SyntaxHighlightingLoaderError *error);

#endif
8 changes: 8 additions & 0 deletions src/syntax/textlayoutbindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ static void update_lines(SyntaxHighlightingBinding *binding, const Line *line, c
}

void SyntaxHighlightingBinding_Update(SyntaxHighlightingBinding *binding, const Line *line, const Line *last_line) {
if (!binding || !binding->sh || !binding->tl || !binding->tl->tb || !line) {
return;
}

if (!last_line) {
last_line = line;
}

Line *prev_line = line->prev;
Stack *open_blocks = NULL;
if (prev_line) {
Expand Down
3 changes: 0 additions & 3 deletions tests/test_syntax_highlighting.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ static void assert_highlight_tags(

String_Deinit(&str);
SyntaxHighlighting_Deinit(&hl);
SyntaxDefinition_Destroy(def);
}

const char *test_ini0 =
Expand Down Expand Up @@ -154,7 +153,6 @@ void test_highlight_string_simple(void) {
Stack_Destroy(open_blocks_at_begin);
String_Deinit(&test1);
SyntaxHighlighting_Deinit(&hl);
SyntaxDefinition_Destroy(def);
}

const char *test_ini1 =
Expand Down Expand Up @@ -454,7 +452,6 @@ void test_stress(void) {

String_Deinit(&test);
SyntaxHighlighting_Deinit(&hl);
SyntaxDefinition_Destroy(def);
}

}
Expand Down
Loading