gdcc support added
This commit is contained in:
parent
55cf06a54c
commit
5eff934ef0
|
@ -1,2 +1,6 @@
|
||||||
Compiling LoveToken is near trivial since it only needs iconv and C99.
|
Compiling LoveToken is near trivial since it only needs C99 (and optionally iconv).
|
||||||
Build an object file from lt.c and link it with iconv into a dll/so/etc.
|
Build an object file from lt.c (and link it with iconv if you want conversion) into a dll/so/etc.
|
||||||
|
You can compile with the NO_ICONV definition to skip iconv requirements.
|
||||||
|
|
||||||
|
Also, compiling with GDCC ( http://github.com/DavidPH/GDCC ) is now allowed.
|
||||||
|
It will automatically omit iconv and use some specialized functions to work.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
LoveToken is a tokenizer made for usage with LOVE2D's (LuaJIT) FFI.
|
LoveToken is a tokenizer made for usage with LOVE2D's (LuaJIT) FFI.
|
||||||
It also works just as well in C or C++, or really anything that can load C functions.
|
It also works just as well in C or C++, or really anything that can load C functions.
|
||||||
See COMPILING.txt for info on compiling.
|
See COMPILING.txt for info on compiling.
|
||||||
|
Supported platforms (known): Microsoft Windows, Linux, ZDoom, Mac OS X
|
||||||
|
|
124
src/lt.c
124
src/lt.c
|
@ -27,10 +27,34 @@ THE SOFTWARE.
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <iconv.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#ifdef __GDCC__
|
||||||
|
#include <ACS_Zandronum.h>
|
||||||
|
#else
|
||||||
|
#ifndef NO_ICONV
|
||||||
|
#include <iconv.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GDCC__
|
||||||
|
#define fopen LT_FOpen
|
||||||
|
#define ftell LT_FTell
|
||||||
|
#define fgetc LT_FGetC
|
||||||
|
#define ungetc LT_UnGetC
|
||||||
|
#define fseek LT_FSeek
|
||||||
|
#define fclose LT_FClose
|
||||||
|
#define FILE LT_File
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__str langId;
|
||||||
|
__str data;
|
||||||
|
int pos;
|
||||||
|
} LT_File;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variables
|
* Variables
|
||||||
*/
|
*/
|
||||||
|
@ -38,10 +62,14 @@ THE SOFTWARE.
|
||||||
static LT_GarbageList *gbHead, *gbRover;
|
static LT_GarbageList *gbHead, *gbRover;
|
||||||
static FILE *parseFile;
|
static FILE *parseFile;
|
||||||
static LT_Config cfg;
|
static LT_Config cfg;
|
||||||
|
|
||||||
|
#ifndef NO_ICONV
|
||||||
static iconv_t icDesc;
|
static iconv_t icDesc;
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool assertError = false;
|
static bool assertError = false;
|
||||||
static char *assertString;
|
static char *assertString;
|
||||||
static char *stringChars = "\"", *charChars = "'";
|
static char *stringChars = (char *)"\"", *charChars = (char *)"'";
|
||||||
|
|
||||||
static const char *errors[] = {
|
static const char *errors[] = {
|
||||||
"LT_Error: Syntax error",
|
"LT_Error: Syntax error",
|
||||||
|
@ -67,6 +95,7 @@ const char *LT_TkNames[] = {
|
||||||
* Functions
|
* Functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef NO_ICONV
|
||||||
static void LT_DoConvert(char **str)
|
static void LT_DoConvert(char **str)
|
||||||
{
|
{
|
||||||
size_t i = strlen(*str);
|
size_t i = strlen(*str);
|
||||||
|
@ -81,6 +110,7 @@ static void LT_DoConvert(char **str)
|
||||||
free(*str);
|
free(*str);
|
||||||
*str = strbuf;
|
*str = strbuf;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *LT_Alloc(size_t size)
|
static void *LT_Alloc(size_t size)
|
||||||
{
|
{
|
||||||
|
@ -108,24 +138,93 @@ static void *LT_ReAlloc(void *ptr, size_t newSize)
|
||||||
|
|
||||||
static void *LT_SetGarbage(void *p)
|
static void *LT_SetGarbage(void *p)
|
||||||
{
|
{
|
||||||
|
#ifndef __GDCC__
|
||||||
gbRover->next = LT_Alloc(sizeof(LT_GarbageList));
|
gbRover->next = LT_Alloc(sizeof(LT_GarbageList));
|
||||||
gbRover = gbRover->next;
|
gbRover = gbRover->next;
|
||||||
gbRover->ptr = p;
|
gbRover->ptr = p;
|
||||||
gbRover->next = NULL;
|
gbRover->next = NULL;
|
||||||
|
|
||||||
return gbRover->ptr;
|
return gbRover->ptr;
|
||||||
|
#else
|
||||||
|
return p;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __GDCC__
|
||||||
|
#define StrParam(...) \
|
||||||
|
( \
|
||||||
|
ACS_BeginStrParam(), \
|
||||||
|
__nprintf(__VA_ARGS__), \
|
||||||
|
ACS_EndStrParam() \
|
||||||
|
)
|
||||||
|
#define StrParamL(...) (StrParam("%LS", StrParam(__VA_ARGS__)))
|
||||||
|
|
||||||
|
LT_File *LT_FOpen(__str languageId, const char *mode)
|
||||||
|
{
|
||||||
|
LT_File *file = LT_Alloc(sizeof(LT_File));
|
||||||
|
|
||||||
|
file->langId = languageId;
|
||||||
|
file->data = StrParamL("%S", languageId);
|
||||||
|
file->pos = 0;
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LT_FTell(LT_File *file)
|
||||||
|
{
|
||||||
|
return file->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LT_FGetC(LT_File *file)
|
||||||
|
{
|
||||||
|
int c = ACS_GetChar(file->data, file->pos++);
|
||||||
|
return c < 1 ? EOF : c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LT_UnGetC(int ch, LT_File *file)
|
||||||
|
{
|
||||||
|
int c = ACS_GetChar(file->data, file->pos--);
|
||||||
|
return c < 1 ? EOF : c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LT_FSeek(LT_File *file, long int offset, int whence)
|
||||||
|
{
|
||||||
|
switch(whence)
|
||||||
|
{
|
||||||
|
case SEEK_SET:
|
||||||
|
file->pos = offset;
|
||||||
|
return 0;
|
||||||
|
case SEEK_CUR:
|
||||||
|
file->pos += offset;
|
||||||
|
return 0;
|
||||||
|
case SEEK_END:
|
||||||
|
file->pos = ACS_StrLen(file->data) + offset;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LT_FClose(LT_File *file)
|
||||||
|
{
|
||||||
|
free(file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void LT_Init(LT_Config initCfg)
|
void LT_Init(LT_Config initCfg)
|
||||||
{
|
{
|
||||||
|
#ifndef __GDCC__
|
||||||
gbHead = LT_Alloc(sizeof(LT_GarbageList));
|
gbHead = LT_Alloc(sizeof(LT_GarbageList));
|
||||||
gbHead->next = NULL;
|
gbHead->next = NULL;
|
||||||
gbHead->ptr = NULL;
|
gbHead->ptr = NULL;
|
||||||
|
|
||||||
gbRover = gbHead;
|
gbRover = gbHead;
|
||||||
|
#endif
|
||||||
|
|
||||||
cfg = initCfg;
|
cfg = initCfg;
|
||||||
|
|
||||||
|
#ifndef NO_ICONV
|
||||||
if(cfg.doConvert && cfg.fromCode != NULL && cfg.toCode != NULL)
|
if(cfg.doConvert && cfg.fromCode != NULL && cfg.toCode != NULL)
|
||||||
{
|
{
|
||||||
icDesc = iconv_open(cfg.toCode, cfg.fromCode);
|
icDesc = iconv_open(cfg.toCode, cfg.fromCode);
|
||||||
|
@ -144,6 +243,7 @@ void LT_Init(LT_Config initCfg)
|
||||||
{
|
{
|
||||||
cfg.stripInvalid = false;
|
cfg.stripInvalid = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(cfg.stringChars != NULL)
|
if(cfg.stringChars != NULL)
|
||||||
{
|
{
|
||||||
|
@ -200,6 +300,7 @@ void LT_SetConfig(LT_Config newCfg)
|
||||||
{
|
{
|
||||||
cfg = newCfg;
|
cfg = newCfg;
|
||||||
|
|
||||||
|
#ifndef NO_ICONV
|
||||||
if(cfg.doConvert && cfg.fromCode != NULL && cfg.toCode != NULL)
|
if(cfg.doConvert && cfg.fromCode != NULL && cfg.toCode != NULL)
|
||||||
{
|
{
|
||||||
if(icDesc != NULL)
|
if(icDesc != NULL)
|
||||||
|
@ -229,6 +330,7 @@ void LT_SetConfig(LT_Config newCfg)
|
||||||
{
|
{
|
||||||
cfg.stripInvalid = false;
|
cfg.stripInvalid = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(cfg.stringChars != NULL)
|
if(cfg.stringChars != NULL)
|
||||||
{
|
{
|
||||||
|
@ -283,11 +385,14 @@ void LT_SetConfig(LT_Config newCfg)
|
||||||
|
|
||||||
void LT_Quit()
|
void LT_Quit()
|
||||||
{
|
{
|
||||||
|
#ifndef NO_ICONV
|
||||||
if(cfg.doConvert)
|
if(cfg.doConvert)
|
||||||
{
|
{
|
||||||
iconv_close(icDesc);
|
iconv_close(icDesc);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __GDCC__
|
||||||
gbRover = gbHead;
|
gbRover = gbHead;
|
||||||
|
|
||||||
while(gbRover != NULL)
|
while(gbRover != NULL)
|
||||||
|
@ -307,6 +412,7 @@ void LT_Quit()
|
||||||
|
|
||||||
gbRover = NULL;
|
gbRover = NULL;
|
||||||
gbHead = NULL;
|
gbHead = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LT_Assert(bool assertion, const char *fmt, ...)
|
bool LT_Assert(bool assertion, const char *fmt, ...)
|
||||||
|
@ -348,7 +454,11 @@ LT_AssertInfo LT_CheckAssert()
|
||||||
return ltAssertion;
|
return ltAssertion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __GDCC__
|
||||||
bool LT_OpenFile(const char *filePath)
|
bool LT_OpenFile(const char *filePath)
|
||||||
|
#else
|
||||||
|
bool LT_OpenFile(__str filePath)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
parseFile = fopen(filePath, "r");
|
parseFile = fopen(filePath, "r");
|
||||||
|
|
||||||
|
@ -363,10 +473,14 @@ bool LT_OpenFile(const char *filePath)
|
||||||
|
|
||||||
void LT_SetPos(int newPos)
|
void LT_SetPos(int newPos)
|
||||||
{
|
{
|
||||||
|
#ifndef __GDCC__
|
||||||
if(fseek(parseFile, newPos, SEEK_SET) != 0)
|
if(fseek(parseFile, newPos, SEEK_SET) != 0)
|
||||||
{
|
{
|
||||||
LT_Assert(ferror(parseFile), "LT_SetPos: %s", strerror(errno));
|
LT_Assert(ferror(parseFile), "LT_SetPos: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
fseek(parseFile, newPos, SEEK_SET);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void LT_CloseFile()
|
void LT_CloseFile()
|
||||||
|
@ -408,10 +522,12 @@ char *LT_ReadNumber()
|
||||||
|
|
||||||
str[i++] = '\0';
|
str[i++] = '\0';
|
||||||
|
|
||||||
|
#ifndef NO_ICONV
|
||||||
if(cfg.doConvert)
|
if(cfg.doConvert)
|
||||||
{
|
{
|
||||||
LT_DoConvert(&str);
|
LT_DoConvert(&str);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return LT_SetGarbage(LT_ReAlloc(str, i));
|
return LT_SetGarbage(LT_ReAlloc(str, i));
|
||||||
}
|
}
|
||||||
|
@ -474,10 +590,12 @@ char *LT_ReadString(char term)
|
||||||
|
|
||||||
str[i++] = '\0';
|
str[i++] = '\0';
|
||||||
|
|
||||||
|
#ifndef NO_ICONV
|
||||||
if(cfg.doConvert)
|
if(cfg.doConvert)
|
||||||
{
|
{
|
||||||
LT_DoConvert(&str);
|
LT_DoConvert(&str);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return LT_SetGarbage(LT_ReAlloc(str, i));
|
return LT_SetGarbage(LT_ReAlloc(str, i));
|
||||||
}
|
}
|
||||||
|
@ -856,10 +974,12 @@ LT_Token LT_GetToken()
|
||||||
|
|
||||||
str[i++] = '\0'; // [marrub] Completely forgot this line earlier. Really screwed up everything.
|
str[i++] = '\0'; // [marrub] Completely forgot this line earlier. Really screwed up everything.
|
||||||
|
|
||||||
|
#ifndef NO_ICONV
|
||||||
if(cfg.doConvert)
|
if(cfg.doConvert)
|
||||||
{
|
{
|
||||||
LT_DoConvert(&str);
|
LT_DoConvert(&str);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ungetc(c, parseFile);
|
ungetc(c, parseFile);
|
||||||
|
|
||||||
|
|
10
src/lt.h
10
src/lt.h
|
@ -50,6 +50,10 @@ THE SOFTWARE.
|
||||||
#define LT_EXPORT
|
#define LT_EXPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GDCC__
|
||||||
|
#define NO_ICONV
|
||||||
|
#endif
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TOK_Colon, TOK_Comma, TOK_Div, TOK_Mod, TOK_Mul,
|
TOK_Colon, TOK_Comma, TOK_Div, TOK_Mod, TOK_Mul,
|
||||||
|
@ -79,9 +83,11 @@ typedef struct
|
||||||
{
|
{
|
||||||
bool escapeChars;
|
bool escapeChars;
|
||||||
bool stripInvalid;
|
bool stripInvalid;
|
||||||
|
#ifndef NO_ICONV
|
||||||
bool doConvert;
|
bool doConvert;
|
||||||
const char *fromCode;
|
const char *fromCode;
|
||||||
const char *toCode;
|
const char *toCode;
|
||||||
|
#endif
|
||||||
const char *stringChars;
|
const char *stringChars;
|
||||||
const char *charChars;
|
const char *charChars;
|
||||||
} LT_Config;
|
} LT_Config;
|
||||||
|
@ -117,7 +123,11 @@ bool LT_EXPORT LT_Assert(bool assertion, const char *fmt, ...);
|
||||||
void LT_EXPORT LT_Error(int type); // [marrub] C use ONLY
|
void LT_EXPORT LT_Error(int type); // [marrub] C use ONLY
|
||||||
LT_AssertInfo LT_EXPORT LT_CheckAssert(void);
|
LT_AssertInfo LT_EXPORT LT_CheckAssert(void);
|
||||||
|
|
||||||
|
#ifndef __GDCC__
|
||||||
bool LT_EXPORT LT_OpenFile(const char *filePath);
|
bool LT_EXPORT LT_OpenFile(const char *filePath);
|
||||||
|
#else
|
||||||
|
bool LT_EXPORT LT_OpenFile(__str filePath);
|
||||||
|
#endif
|
||||||
void LT_EXPORT LT_SetPos(int newPos);
|
void LT_EXPORT LT_SetPos(int newPos);
|
||||||
void LT_EXPORT LT_CloseFile(void);
|
void LT_EXPORT LT_CloseFile(void);
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user