marrub
/
LoveToken
Archived
1
0
Fork 0

gdcc support added

master
Marrub 2015-06-11 09:42:36 -04:00
parent 55cf06a54c
commit 5eff934ef0
4 changed files with 139 additions and 4 deletions

View File

@ -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.

View File

@ -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
View File

@ -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);

View File

@ -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);