diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..4279bf0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/VoArray"] + path = src/VoArray + url = https://github.com/StevenSYS/VoArray diff --git a/CMakeLists.txt b/CMakeLists.txt index 06dafe6..ac50be2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,10 +2,11 @@ cmake_minimum_required(VERSION 3.11) project(ESMake LANGUAGES C VERSION 1.0) -option(BUILD_FOR_I586 "Build ${PROGRAM_NAME} for i586 (Intel Pentium) or higher" OFF) +option(BUILD_FOR_I586 "Build ${PROJECT_NAME} for i586 (Intel Pentium) or higher" OFF) # Windows Compiler Options -option(BUILD_USING_MSVCRT20 "Build ${PROGRAM_NAME} using msvcrt20 (Windows Compiler Only)" OFF) +option(BUILD_USING_MSVCRT20 "Build ${PROJECT_NAME} using msvcrt20 (Windows Compiler Only)" OFF) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVOARRAY_DEFCONFIG") set(CMAKE_C_FLAGS_DEBUG "-g -Wall") set(CMAKE_C_FLAGS_RELEASE "-O2") if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang") diff --git a/README.md b/README.md index f78191e..54843a9 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,3 @@ # [ESMake](https://github.com/StevenSYS/ESMake) -A program that helps with making errors strings and enums the way I do it - -| Legend | Meaning | -| ------ | --------------------------- | -| > | Output(s) - First line only | -| % | Setting | -| + | Item | -| - | Item (Switch Default) | -| ! | Comment | -| \ | Escape | \ No newline at end of file +A program that helps with making errors strings and enums the way I do it \ No newline at end of file diff --git a/bothExample.em b/bothExample.em deleted file mode 100644 index 2cd5715..0000000 --- a/bothExample.em +++ /dev/null @@ -1,18 +0,0 @@ -> "exampleRet.h" "exampleEnum.h" -%mode "enum" -%preEnum "ERROR_" -%preLang "LANG_ERROR_" -! | Legend | Meaning | -! | ------ | --------------------------- | -! | > | Output(s) - First line only | -! | % | Setting | -! | + | Item | -! | - | Item (Switch Default) | -! | ! | Comment | -! | \ | Escape | - -+EXAMPLE -> "exampleLang.h" -%mode "lang" - -+EXAMPLE "Example error" \ No newline at end of file diff --git a/enumExample.em b/enumExample.em deleted file mode 100644 index febcbbf..0000000 --- a/enumExample.em +++ /dev/null @@ -1,14 +0,0 @@ -> "exampleRet.h" "exampleEnum.h" -%mode "enum" -%preEnum "ERROR_" -%preLang "LANG_ERROR_" -! | Legend | Meaning | -! | ------ | --------------------------- | -! | > | Output(s) - First line only | -! | % | Setting | -! | + | Item | -! | - | Item (Switch Default) | -! | ! | Comment | -! | \ | Escape | - -+EXAMPLE \ No newline at end of file diff --git a/example.em b/example.em new file mode 100644 index 0000000..5c664f4 --- /dev/null +++ b/example.em @@ -0,0 +1,24 @@ +obj outputs { + str ret "ret.h"; + str enum "enum.h"; + str lang1 "lang1.h"; + str lang2 "lang2.h"; +}; + +obj variables { + str preEnum "ERROR_"; + str preLang "LANG_ERROR_"; +}; + +obj items { + obj EXAMPLE { + str lang1 "lang1 - Example"; + str lang2 "lang2 - Example"; + }; + + obj DEFEXAMPLE { + vo def; + str lang1 "lang1 - Default Example"; + str lang2 "lang2 - Default Example"; + }; +}; \ No newline at end of file diff --git a/langExample.em b/langExample.em deleted file mode 100644 index efcba93..0000000 --- a/langExample.em +++ /dev/null @@ -1,13 +0,0 @@ -> "exampleLang.h" -%mode "lang" -%preLang "LANG_ERROR_" -! | Legend | Meaning | -! | ------ | --------------------------- | -! | > | Output(s) - First line only | -! | % | Setting | -! | + | Item | -! | - | Item (Switch Default) | -! | ! | Comment | -! | \ | Escape | - -+EXAMPLE "Example error" \ No newline at end of file diff --git a/src/VoArray b/src/VoArray new file mode 160000 index 0000000..129e105 --- /dev/null +++ b/src/VoArray @@ -0,0 +1 @@ +Subproject commit 129e105267625f5da3cdf114ca18fdba86848ae9 diff --git a/src/errorMake.c b/src/errorMake.c deleted file mode 100644 index fe592e3..0000000 --- a/src/errorMake.c +++ /dev/null @@ -1,215 +0,0 @@ -#include -#include - -#include "file.h" -#include "item.h" -#include "setting.h" -#include "progInfo.h" -#include "whitespace.h" - -static char check = 0; -static char *outNames[MAX_OUTPUTS]; - -static inline unsigned int getItemCount(FILE *fileInput) { - char buffer[LENGTH_BUFFER] = { 0 }; - unsigned int ret = 0; - long int prevPos = ftell(fileInput); - - while (fgets(buffer, LENGTH_BUFFER, fileInput) != NULL) { - if ( - buffer[0] == LEGEND_ITEM || - buffer[0] == LEGEND_ITEMDEFAULT - ) { - ret++; - } - } - - fseek(fileInput, prevPos, SEEK_SET); - return ret; -} - -static inline unsigned int initFiles(FILE *files[]) { - unsigned int i; - unsigned int ret = 0; - - for (i = 0; i < MAX_OUTPUTS && outNames[i] != NULL; i++) { - if (file_open( - &files[i], - outNames[i], - "w" - )) { - return 0; - } - - fprintf(files[i], AUTOGEN_TEXT); - ret++; - } - - if (!ret) { - fprintf(stderr, "ERROR: All files are NULL\n"); - return 0; - } - return ret; -} - -int getOutputs(char *str) { - unsigned char j; - unsigned int i = 0; - unsigned int k; - - for (k = 0; k < MAX_OUTPUTS; k++) { - outNames[k] = NULL; - } - - for (k = 0; k < MAX_OUTPUTS; k++) { - for (j = 0; j < 2; j++) { - check = 0; - - for (i++; str[i]; i++) { - if (str[i] == '"') { - check = 1; - if (j == 0) { - outNames[k] = str + (i + 1); - } else { - str[i] = 0; - } - break; - } else if ( - j == 0 && - !whitespace(str[i]) - ) { - fprintf(stderr, "ERROR: Output contains non whitespace character\n"); - return 1; - } - } - - if (!check) { - if ( - j == 0 && - k > 0 - ) { - break; - } else if (j != 0) { - fprintf(stderr, "ERROR: Output is missing end of string\n"); - } - return 1; - } - } - } - return 0; -} - -int errorMake_readFile(FILE *fileInput) { - char buffer[LENGTH_BUFFER] = { 0 }; - unsigned int i; - unsigned int fileCount = 0; - unsigned int offset = 0; - unsigned int itemCount = getItemCount(fileInput); - size_t bufLen; - enum modes mode; - FILE *files[MAX_OUTPUTS]; - settings_t settings = { 0 }; - setting_t *tmpSet; - - if (fileInput == NULL) { - fprintf(stderr, "ERROR: Required argument is NULL\n"); - return 1; - } - - for (i = 0; i < MAX_OUTPUTS; i++) { - files[i] = NULL; - } - - while (fgets(buffer, LENGTH_BUFFER, fileInput) != NULL) { - offset = 0; - - if ( - ( - buffer[0] != LEGEND_OUTPUT && - buffer[0] != LEGEND_SETTING && - buffer[0] != LEGEND_COMMENT - ) && - !fileCount - ) { - fprintf(stderr, "ERROR: No output files have been specified\n"); - return 1; - } - - switch (buffer[0]) { - case LEGEND_OUTPUT: - for (i = 0; i < MAX_OUTPUTS; i++) { - if (files[i] != NULL) { - fclose(files[i]); - } - } - if (getOutputs(buffer)) { - return 1; - } - - fileCount = initFiles(files); - - if (!fileCount) { - return 1; - } - break; - case LEGEND_SETTING: - if (setting_getStr(&settings, buffer)) { - return 1; - } - - if (strncmp( - buffer + 1, - SETTING_MODE, - LENGTH_BUFFER - 1 - ) == 0) { - tmpSet = setting_find(&settings, SETTING_MODE); - - if (tmpSet == NULL) { - fprintf(stderr, "ERROR: \"" SETTING_MODE "\" isn't set\n"); - return 1; - } - - if (mode_getStr( - tmpSet->value, - &mode - )) { - return 1; - } - } - break; - case LEGEND_ITEM: - case LEGEND_ITEMDEFAULT: - if (item_addFile( - files, - fileCount, - itemCount, - buffer, - mode, - &settings - )) { - return 1; - } - break; - case LEGEND_COMMENT: - break; - case LEGEND_ESCAPE: - offset = 1; - default: - bufLen = strlen(buffer + offset); - for (i = 0; i < fileCount; i++) { - fwrite( - buffer + offset, - sizeof(char), - bufLen, - files[i] - ); - } - break; - } - } - - for (i = 0; i < fileCount; i++) { - fclose(files[i]); - } - return 0; -} \ No newline at end of file diff --git a/src/errorMake.h b/src/errorMake.h deleted file mode 100644 index ec4ff13..0000000 --- a/src/errorMake.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ERRORMAKE__ -#define __ERRORMAKE__ - -/* Functions */ -int errorMake_readFile(FILE *fileInput); - -#endif \ No newline at end of file diff --git a/src/errorString.h b/src/errorString.h new file mode 100644 index 0000000..955477a --- /dev/null +++ b/src/errorString.h @@ -0,0 +1,8 @@ +#ifndef __ERRORSTRING__ +#define __ERRORSTRING__ + #define STR_ERROR_REQUIRED_ARGS "ERROR: Required argument(s) is/are NULL\n" + #define STR_ERROR_FILE_READ "ERROR: Failed to read from file\n" + #define STR_ERROR_VAR_TYPE_UNKNOWN "ERROR: Unknown variable type: %s\n" + #define STR_ERROR_VAR_NAME "ERROR: Failed to get variable name\n" + #define STR_ERROR_VAR_EXISTS_OBJ "ERROR: Variable already exists in object\n" +#endif \ No newline at end of file diff --git a/src/file.c b/src/file.c index 7371560..026e9dc 100644 --- a/src/file.c +++ b/src/file.c @@ -5,6 +5,10 @@ int file_open( const char *filename, const char *mode ) { + if (*output != NULL) { + fclose(*output); + } + *output = fopen(filename, mode); if (*output == NULL) { diff --git a/src/file.h b/src/file.h index 0231518..8af0bd0 100644 --- a/src/file.h +++ b/src/file.h @@ -1,6 +1,8 @@ #ifndef __FILE_H__ #define __FILE_H__ +#include + /* Functions */ int file_open( FILE **output, diff --git a/src/item.c b/src/item.c deleted file mode 100644 index e145298..0000000 --- a/src/item.c +++ /dev/null @@ -1,153 +0,0 @@ -#include - -#include "item.h" -#include "progInfo.h" -#include "whitespace.h" - -int item_addFile( - FILE *files[], - unsigned int fileCount, - unsigned int itemCount, - char *str, - enum modes mode, - settings_t *settings -) { - char check = 0; - char *value; - unsigned int i; - unsigned char j; - static unsigned int currentCount = 0; - static enum modes prevMode = MODE_COUNT; - static setting_t *preEnum = NULL; - static setting_t *preLang = NULL; - - if (mode != prevMode) { - currentCount = 0; - prevMode = mode; - } - - if ( - files == NULL || - str == NULL || - settings == NULL - ) { - fprintf(stderr, "ERROR: Required argument(s) is/are NULL\n"); - return 1; - } - - if ( - mode != MODE_LANG && - preEnum == NULL - ) { - preEnum = setting_find(settings, SETTING_PREENUM); - - if (preEnum == NULL) { - fprintf(stderr, "ERROR: \"" SETTING_PREENUM "\" isn't set\n"); - return 1; - } - } - - if (preLang == NULL) { - preLang = setting_find(settings, SETTING_PRELANG); - - if (preLang == NULL) { - fprintf(stderr, "ERROR: \"" SETTING_PRELANG "\" isn't set\n"); - return 1; - } - } - - switch (mode) { - case MODE_ENUM: - /* Ret */ - for (i = 0; str[i]; i++) { - if (whitespace(str[i])) { - str[i] = 0; - break; - } - } - - if (str[0] == LEGEND_ITEMDEFAULT) { - fprintf( - files[0], - "default: return %s%s;\n", - preLang->value, - str + 1 - ); - } else { - fprintf( - files[0], - "case %s%s: return %s%s;\n", - preEnum->value, - str + 1, - preLang->value, - str + 1 - ); - } - - /* Enum */ - fprintf( - files[1], - "%s%s", - preEnum->value, - str + 1 - ); - - if (currentCount < (itemCount - 1)) { - fprintf(files[1], ","); - } - - fprintf(files[1], "\n"); - break; - case MODE_LANG: - for (i = 0; str[i]; i++) { - if (whitespace(str[i])) { - str[i] = 0; - break; - } - } - - for (j = 0; j < 2; j++) { - check = 0; - - for (i++; str[i]; i++) { - if (str[i] == '"') { - if (j == 0) { - value = str + (i + 1); - } else { - check = 1; - str[i] = 0; - } - break; - } else if ( - j == 0 && - !whitespace(str[i]) - ) { - fprintf(stderr, "ERROR: Non whitespace character before value string\n"); - return 1; - } - } - - if ( - j != 0 && - !check - ) { - fprintf(stderr, "ERROR: Missing end of value string\n"); - return 1; - } - } - - fprintf( - files[0], - "#define %s%s \"%s\"\n", - preLang->value, - str + 1, - value - ); - break; - default: - fprintf(stderr, "ERROR: Unknown mode: %d\n", mode); - return 1; - } - currentCount++; - return 0; -} \ No newline at end of file diff --git a/src/item.h b/src/item.h deleted file mode 100644 index 3d3d5fe..0000000 --- a/src/item.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __ITEM__ -#define __ITEM__ - -#include - -#include "mode.h" -#include "setting.h" - -/* Functions */ -int item_addFile( - FILE *files[], - unsigned int fileCount, - unsigned int itemCount, - char *str, - enum modes mode, - settings_t *settings -); - -#endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index 7ebf8f1..60cadaf 100644 --- a/src/main.c +++ b/src/main.c @@ -2,14 +2,16 @@ #include #include "file.h" +#include "variable.h" #include "progInfo.h" -#include "errorMake.h" int main( int argc, char *argv[] ) { - FILE *fileInput; + int result = 0; + FILE *file; + variable_t var; if (argc < 2) { fprintf(stderr, "ERROR: File wasn't specified\n"); @@ -17,17 +19,38 @@ int main( } if (file_open( - &fileInput, + &file, argv[1], "r" )) { return 1; } - if (errorMake_readFile(fileInput)) { + getVar: + result = variable_getFile(file, &var); + + if (result > 0) { return 1; } - fclose(fileInput); + if (result == 0) { + printf( + "Type: \"%s\"\n" + "Name: \"%s\"\n", + variable_typeNames[var.type], + var.name + ); + + if (var.type == VARTYPE_STR) { + printf("Value: %s\n", var.value.str); + } else { + printf("Value: %d\n", *var.value.num); + } + + variable_uninit(&var); + goto getVar; + } + + fclose(file); return 0; } \ No newline at end of file diff --git a/src/mode.c b/src/mode.c deleted file mode 100644 index 496d08b..0000000 --- a/src/mode.c +++ /dev/null @@ -1,32 +0,0 @@ -#define MODE_NOEXTERNS -#include -#include - -#include "mode.h" - -const char *mode_names[MODE_COUNT] = { - "enum", - "lang" -}; - -int mode_getStr( - const char *str, - enum modes *mode -) { - char check = 0; - unsigned int i; - - for (i = 0; i < MODE_COUNT; i++) { - if (strcmp(str, mode_names[i]) == 0) { - check = 1; - *mode = (enum modes)i; - break; - } - } - - if (!check) { - fprintf(stderr, "ERROR: Unknown mode: %s\n", str); - return 1; - } - return 0; -} \ No newline at end of file diff --git a/src/mode.h b/src/mode.h deleted file mode 100644 index ee1fa6e..0000000 --- a/src/mode.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __MODE__ -#define __MODE__ - -/* Enums */ -enum modes { - MODE_ENUM, - MODE_LANG, - - MODE_COUNT -}; - -#ifndef MODE_NOEXTERNS -/* Externs */ -extern const char *mode_names[MODE_COUNT]; -#endif - -/* Functions */ -int mode_getStr( - const char *str, - enum modes *mode -); - -#endif \ No newline at end of file diff --git a/src/progInfo.h.in b/src/progInfo.h.in index ddd07c9..ceffcf1 100644 --- a/src/progInfo.h.in +++ b/src/progInfo.h.in @@ -2,35 +2,24 @@ #define __PROGINFO__ /* - Program - */ +#ifndef PROGRAM_PRE_RELEASE + #define PROGRAM_PRE_RELEASE 1 +#endif + #define PROGRAM_NAME "@PROJECT_NAME@" +#if PROGRAM_PRE_RELEASE + #define PROGRAM_VERSION "@PROJECT_VERSION@pre" +#else + #define PROGRAM_VERSION "@PROJECT_VERSION@" +#endif /* - Length - */ #define LENGTH_BUFFER 255 -/* - Legend - */ -#define LEGEND_OUTPUT '>' -#define LEGEND_SETTING '%' -#define LEGEND_ITEM '+' -#define LEGEND_ITEMDEFAULT '-' -#define LEGEND_COMMENT '!' -#define LEGEND_ESCAPE '\\' - -/* - Type - */ -#define TYPE_ENUM "enum" -#define TYPE_LANG "lang" - -/* - Max - */ -#define MAX_OUTPUTS 2 - -/* - Setting - */ -#define SETTING_MODE "mode" -#define SETTING_PREENUM "preEnum" -#define SETTING_PRELANG "preLang" - /* - Misc. - */ #define AUTOGEN_TEXT \ "/*\n" \ - " Generated with " PROGRAM_NAME ",\n" \ + " Generated with " PROGRAM_NAME " v" PROGRAM_VERSION ",\n" \ " do not modify this file directly.\n" \ "*/\n" diff --git a/src/setting.c b/src/setting.c deleted file mode 100644 index d172c0c..0000000 --- a/src/setting.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include - -#include "setting.h" -#include "whitespace.h" - -int setting_add( - settings_t *settings, - const setting_t *setting -) { - if (settings->count >= SETTING_LENGTH) { - fprintf(stderr, "ERROR: No free slots in settings variable\n"); - return 1; - } - - strncpy( - settings->i[settings->count].name, - setting->name, - SETTING_LENGTH_STRING - ); - strncpy( - settings->i[settings->count].value, - setting->value, - SETTING_LENGTH_STRING - ); - - settings->count++; - return 0; -} - -setting_t *setting_find( - settings_t *settings, - const char *find -) { - unsigned int i; - - for (i = 0; i < settings->count; i++) { - if (strncmp( - settings->i[i].name, - find, - SETTING_LENGTH_STRING - ) == 0) { - return &settings->i[i]; - } - } - return NULL; -} - -int setting_getStr( - settings_t *settings, - char *str -) { - char check = 0; - char *value; - unsigned int i; - unsigned char j; - - setting_t tmpSet; - setting_t *tmpSetPtr; - - for (i = 1; str[i]; i++) { - if (whitespace(str[i])) { - str[i] = 0; - strncpy( - tmpSet.name, - str + 1, - SETTING_LENGTH_STRING - ); - break; - } - } - - for (j = 0; j < 2; j++) { - check = 0; - - for (i++; str[i]; i++) { - if (str[i] == '"') { - if (j == 0) { - value = str + (i + 1); - } else { - check = 1; - str[i] = 0; - strncpy( - tmpSet.value, - value, - SETTING_LENGTH_STRING - ); - } - break; - } else if ( - j == 0 && - !whitespace(str[i]) - ) { - fprintf(stderr, "ERROR: Non whitespace character before value string\n"); - return 1; - } - } - - if ( - j != 0 && - !check - ) { - fprintf(stderr, "ERROR: Missing end of value string\n"); - return 1; - } - } - - tmpSetPtr = setting_find(settings, tmpSet.name); - - if (tmpSetPtr == NULL) { - setting_add(settings, &tmpSet); - } else { - strncpy( - tmpSetPtr->value, - tmpSet.value, - SETTING_LENGTH_STRING - ); - } - return 0; -} \ No newline at end of file diff --git a/src/setting.h b/src/setting.h deleted file mode 100644 index 830b2f8..0000000 --- a/src/setting.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __SETTING__ -#define __SETTING__ - -/* Macros */ -#define SETTING_LENGTH 3 -#define SETTING_LENGTH_STRING 100 - -/* Structs */ -typedef struct { - char name[SETTING_LENGTH_STRING]; - char value[SETTING_LENGTH_STRING]; -} setting_t; - -typedef struct { - unsigned int count; - setting_t i[SETTING_LENGTH]; -} settings_t; - -/* Functions */ -int setting_add( - settings_t *settings, - const setting_t *setting -); - -int setting_getStr( - settings_t *settings, - char *str -); - -setting_t *setting_find( - settings_t *settings, - const char *find -); - -#endif \ No newline at end of file diff --git a/src/varFlag.c b/src/varFlag.c new file mode 100644 index 0000000..11ca1df --- /dev/null +++ b/src/varFlag.c @@ -0,0 +1,39 @@ +#define VARFLAG_NOEXTERNS +#include +#include + +#include "varFlag.h" +#include "errorString.h" + +const char *varFlag_names[VARFLAG_COUNT] = { + "nn", // No Name + "ad" // Allow Duplicate +}; + +enum varFlags varFlag_check( + const char *str, + size_t maxLen +) { + size_t i; + size_t len = 0; + size_t nameLen = 0; + + if (str == NULL) { + fprintf(stderr, STR_ERROR_REQUIRED_ARGS); + return 1; + } + + for (i = 0; i < VARFLAG_COUNT; i++) { + len = strnlen(str, maxLen); + nameLen = strlen(varFlag_names[i]); + + if (len != nameLen) { + break; + } + + if (strncmp(str, varFlag_names[i], len) == 0) { + return (enum varFlags)i; + } + } + return VARFLAG_NONE; +} \ No newline at end of file diff --git a/src/varFlag.h b/src/varFlag.h new file mode 100644 index 0000000..58c7ea4 --- /dev/null +++ b/src/varFlag.h @@ -0,0 +1,29 @@ +#ifndef __VARFLAG__ +#define __VARFLAG__ + +/* MACROS */ +#define VARFLAG_BM(_val) (1 << _val) + +/* Enums */ +enum varFlags { + VARFLAG_NN, + VARFLAG_AD, + + VARFLAG_COUNT, + + /* Specials */ + VARFLAG_NONE +}; + +/* Functions */ +enum varFlags varFlag_check( + const char *str, + size_t maxLen +); + +#ifndef VARFLAG_NOEXTERNS +/* Externs */ +extern const char *varFlag_names[VARFLAG_COUNT]; +#endif + +#endif \ No newline at end of file diff --git a/src/variable.c b/src/variable.c new file mode 100644 index 0000000..18fea3c --- /dev/null +++ b/src/variable.c @@ -0,0 +1,426 @@ +#define VARIABLE_NOEXTERNS +#include +#include +#include +#include + +#include "varFlag.h" +#include "variable.h" +#include "progInfo.h" +#include "errorString.h" + +#define FREADEC(_ptr, _size, _count, _file) \ + if (!fread(_ptr, _size, _count, _file)) { \ + fprintf(stderr, STR_ERROR_FILE_READ); \ + return 1; \ + } + +#define SKIPSPACE() \ + byte = 0; \ + do { \ + byte = getc(file); \ + if ( \ + byte == EOF || \ + byte == VARIABLE_CHAR_STOP \ + ) { \ + return -1; \ + } \ + } while ( \ + !byte || \ + isspace(byte) \ + ); \ + fseek(file, -1, SEEK_CUR); \ + byte = 0; + +const char *variable_typeNames[VARTYPE_COUNT] = { + "vo", + "num", + "flt", + "dou", + "str", + "obj" +}; + +int variable_init( + variable_t *var, + size_t nameSize, + size_t valSize +) { + if (var == NULL) { + fprintf(stderr, STR_ERROR_REQUIRED_ARGS); + return 1; + } + + var->used = 1; + + if (nameSize) { + var->name = malloc(nameSize); + } + + if (valSize) { + var->value.ptr = malloc(valSize); + } + return 0; +} + +void variable_uninit(variable_t *var) { + if (var == NULL) { + fprintf(stderr, STR_ERROR_REQUIRED_ARGS); + return; + } + + var->used = 0; + var->type = VARTYPE_UNSET; + + if (var->name != NULL) { + free(var->name); + var->name = NULL; + } + + if (var->value.ptr != NULL) { + free(var->value.ptr); + var->value.ptr = NULL; + } + return; +} + +/* Object */ +void variable_clearObj(varObj_t *object) { + VOARRAY_TYPE_SIZE i; + + if (object == NULL) { + fprintf(stderr, STR_ERROR_REQUIRED_ARGS); + return; + } + + for (i = 0; i < object->length; i++) { + object->i[i].used = 0; + object->i[i].type = VARTYPE_VO; + object->i[i].name = NULL; + object->i[i].value.ptr = NULL; + } + return; +} + +variable_t *variable_addObj( + varObj_t *object, + variable_t *var, + VOARRAY_TYPE_SIZE *position +) { + VOARRAY_TYPE_SIZE i = 0; + + if ( + object == NULL || + var == NULL + ) { + fprintf(stderr, STR_ERROR_REQUIRED_ARGS); + return NULL; + } + + if ( + position != NULL && + *position < object->length + ) { + i = *position; + } + + for (; i < object->length; i++) { + if (!object->i[i].used) { + break; + } + } + + if ( + !(var->flags & VARFLAG_BM(VARFLAG_AD)) && + variable_findObj( + object, + var->name, + NULL + ) != NULL + ) { + fprintf(stderr, STR_ERROR_VAR_EXISTS_OBJ); + return NULL; + } + + object->i[i].used = 1; + object->i[i].type = var->type; + object->i[i].name = var->name; + object->i[i].value.ptr = var->value.ptr; + + object->length++; + VOARRAY_RESIZE(variable_t, (*object), NULL); + + if (position != NULL) { + *position = i; + } + return &object->i[i]; +} + +variable_t *variable_findObj( + varObj_t *object, + const char *name, + VOARRAY_TYPE_SIZE *position +) { + VOARRAY_TYPE_SIZE i = 0; + + if ( + object == NULL || + name == NULL + ) { + fprintf(stderr, STR_ERROR_REQUIRED_ARGS); + return NULL; + } + + if ( + position != NULL && + *position < object->length + ) { + i = *position; + } + + for (; i < (object->length - 1); i++) { + if (strcmp(object->i[i].name, name) == 0) { + return &object->i[i]; + } + } + + if (position != NULL) { + *position = i; + } + return NULL; +} + +int variable_uninitObj(varObj_t *object) { + VOARRAY_TYPE_SIZE i; + + for (i = 0; i < (object->length - 1); i++) { + if (object->i[i].type == VARTYPE_OBJ) { + if (variable_uninitObj(object->i[i].value.obj)) { + return 1; + } + } + variable_uninit(&object->i[i]); + } + VOARRAY_UNINIT((*object)); + return 0; +} + +/* From File */ +int variable_getFile( + FILE *file, + variable_t *var +) { + char byte = 0; + char check = 0; + char buffer[LENGTH_BUFFER] = { 0 }; + enum varFlags flag = VARFLAG_NONE; + size_t position; + VOARRAY_TYPE_SIZE i; + + if ( + file == NULL || + var == NULL + ) { + fprintf(stderr, STR_ERROR_REQUIRED_ARGS); + return 1; + } + + var->flags = 0; + var->name = NULL; + var->value.ptr = NULL; + + type: + i = 0; + position = ftell(file); + + SKIPSPACE(); + + do { + if (byte) { + buffer[i] = byte; + i++; + } + + byte = getc(file); + } while ( + byte && + !isspace(byte) + ); + + flag = varFlag_check( + buffer, + LENGTH_BUFFER + ); + + if (flag != VARFLAG_NONE) { + if (!(var->flags & VARFLAG_BM(flag))) { + var->flags += VARFLAG_BM(flag); + } + goto type; + } + + for (i = 0; i < VARTYPE_COUNT; i++) { + if (strncmp( + buffer, + variable_typeNames[i], + LENGTH_BUFFER + ) == 0) { + check = 1; + var->type = (enum variable_types)i; + break; + } + } + + if (!check) { + fprintf(stderr, STR_ERROR_VAR_TYPE_UNKNOWN, buffer); + return 1; + } + + position = ftell(file); + + check = 0; + + if (!(var->flags & VARFLAG_BM(VARFLAG_NN))) { + name: + i = 0; + + fseek(file, position, SEEK_SET); + + SKIPSPACE(); + + do { + if ( + byte && + byte != VARIABLE_CHAR_END + ) { + if (check) { + var->name[i] = byte; + } + i++; + } + + byte = getc(file); + } while ( + byte && + !isspace(byte) + ); + + if (!i) { + fprintf(stderr, STR_ERROR_VAR_NAME); + return 1; + } + + if (!check) { + variable_init( + var, + sizeof(char[i]), + 0 + ); + + check = 1; + goto name; + } + } + + position = ftell(file); + + i = 0; + check = 0; + byte = 0; + buffer[0] = 0; + + switch (var->type) { + case VARTYPE_NUM: + variable_init( + var, + 0, + sizeof(uint8_t) + ); + + do { + if (byte) { + buffer[i] = byte; + i++; + } + + byte = getc(file); + } while ( + byte && + byte != VARIABLE_CHAR_END && + !isspace(byte) + ); + + if (byte != VARIABLE_CHAR_END) { + fprintf(stderr, "§ERROR: Missing line end\n"); + return 1; + } + + *var->value.num = (int32_t)atoi(buffer); + break; + case VARTYPE_STR: + do { + byte = getc(file); + } while ( + byte && + byte != VARIABLE_CHAR_STR && + isspace(byte) + ); + + if (byte != VARIABLE_CHAR_STR) { + fprintf(stderr, "§ERROR: Missing start of string\n"); + return 1; + } + + position = ftell(file); + + do { + if ( + byte && + byte != VARIABLE_CHAR_STR + ) { + i++; + } + byte = getc(file); + } while ( + byte && + byte != VARIABLE_CHAR_STR + ); + + if (byte != VARIABLE_CHAR_STR) { + fprintf(stderr, "§ERROR: Missing end of string\n"); + return 1; + } + + fseek(file, position, SEEK_SET); + + if (i) { + variable_init( + var, + 0, + sizeof(char[i]) + ); + + FREADEC(var->value.str, sizeof(char), i, file); + var->value.str[i] = 0; + } + + fseek(file, 1, SEEK_CUR); + + do { + byte = getc(file); + } while ( + byte && + byte != VARIABLE_CHAR_END && + isspace(byte) + ); + + if (byte != VARIABLE_CHAR_END) { + fprintf(stderr, "§ERROR: Missing line end\n"); + return 1; + } + break; + default: + break; + } + return 0; +} \ No newline at end of file diff --git a/src/variable.h b/src/variable.h new file mode 100644 index 0000000..4f446e4 --- /dev/null +++ b/src/variable.h @@ -0,0 +1,87 @@ +#ifndef __VARIABLE__ +#define __VARIABLE__ + +#include + +#include "VoArray/voArray.h" + +/* Macros */ + +/* - Char - */ +#define VARIABLE_CHAR_STR '"' +#define VARIABLE_CHAR_END ';' +#define VARIABLE_CHAR_STOP '!' + +/* Enums */ +enum variable_types { + VARTYPE_VO, // void + VARTYPE_NUM, // int32_t + VARTYPE_FLT, // float + VARTYPE_DOU, // double + VARTYPE_STR, // char * + VARTYPE_OBJ, // varObj_t + + VARTYPE_COUNT, + + /* Specials */ + VARTYPE_UNSET +}; + +/* VoArrays */ +VOARRAY(varObj_t, struct variable_s); + +/* Structs */ +typedef struct variable_s { + char used; + unsigned char flags; + enum variable_types type; + char *name; + union { + int32_t *num; + float *flt; + double *dou; + char *str; + varObj_t *obj; + + void *ptr; + } value; +} variable_t; + +/* Functions */ +int variable_init( + variable_t *var, + size_t nameSize, + size_t valSize +); + +void variable_uninit(variable_t *var); + +/* Object */ +void variable_clearObj(varObj_t *object); + +variable_t *variable_addObj( + varObj_t *object, + variable_t *var, + VOARRAY_TYPE_SIZE *position +); + +variable_t *variable_findObj( + varObj_t *object, + const char *name, + VOARRAY_TYPE_SIZE *position +); + +int variable_uninitObj(varObj_t *object); + +/* From File */ +int variable_getFile( + FILE *file, + variable_t *var +); + +#ifndef VARIABLE_NOEXTERNS +/* Externs */ +extern const char *variable_typeNames[VARTYPE_COUNT]; +#endif + +#endif \ No newline at end of file diff --git a/src/whitespace.c b/src/whitespace.c deleted file mode 100644 index 480d4ad..0000000 --- a/src/whitespace.c +++ /dev/null @@ -1,14 +0,0 @@ -char whitespace(char chr) { - switch (chr) { - case ' ': - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - return 1; - default: - return 0; - } - return 0; -} \ No newline at end of file diff --git a/src/whitespace.h b/src/whitespace.h deleted file mode 100644 index 9dcae07..0000000 --- a/src/whitespace.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __WHITESPACE__ -#define __WHITESPACE__ - -/* Functions */ -char whitespace(char chr); - -#endif \ No newline at end of file diff --git a/testing.em b/testing.em new file mode 100644 index 0000000..b29ed7b --- /dev/null +++ b/testing.em @@ -0,0 +1,8 @@ +num testNum 10; +str testString "Testing"; +! +obj testArray { + nn num 5; + nn num 10; + nn str "510"; +}; \ No newline at end of file diff --git a/vim/syntax/esmake.vim b/vim/syntax/esmake.vim index 2a370b3..407dac1 100644 --- a/vim/syntax/esmake.vim +++ b/vim/syntax/esmake.vim @@ -1,25 +1,28 @@ " Vim syntax file " Language: ESMake " Maintainer: StevenSYS -" Last Change: 23-03-2026 if exists("b:current_syntax") finish endif -runtime! syntax/c.vim +" Region +syn region emString start="\"" end="\"" +syn region emStop start="!" end=".+" -syn match emOutput "^>" -syn match emSetting "^%\S\+" -syn match emItem "^[+|-]\S\+" -syn match emEscape "^\\.\+" -syn region emComment start="^!" skip="\\$" end="$" +" Match +syn match emNumber "\<\d\+\(_\d\+\)*\>" -" Settings -hi def link emOutput keyword -hi def link emSetting keyword -hi def link emItem structure -hi def link emEscape special -hi def link emComment comment +" Keyword +syn keyword emVarType vo num flt dou str obj +syn keyword emVarFlag nn ad + +hi def link emString string +hi def link emStop comment + +hi def link emNumber number + +hi def link emVarType structure +hi def link emVarFlag keyword let b:current_syntax = "esmake" \ No newline at end of file