Permalink
Browse files

Add nq_memparse, allow nagaqueen to parse directly from memory. Closes

  • Loading branch information...
1 parent 6005c48 commit 721f0b1391ed3fa607a4eee0b5c9206877b0cc3f @nddrylliog nddrylliog committed Nov 28, 2012
Showing with 74 additions and 4 deletions.
  1. +1 −0 .gitignore
  2. +72 −4 grammar/nagaqueen.leg
  3. +1 −0 source/nagaqueen/callbacks.ooc
View
@@ -5,3 +5,4 @@ bin
*~
.libs
bin
+build
View
@@ -53,7 +53,11 @@ void GC_free(void *);
//#define YY_DEBUG
-///////////////////// main struct, for the sake of being re-entrant ////////////////////////
+///////////////////// re-entrant data structures ////////////////////////
+
+struct _NagaQueenIoInterface {
+ int (*read)(void *, size_t, void *);
+};
struct _NagaQueenCore {
/* The user's data */
@@ -63,7 +67,13 @@ struct _NagaQueenCore {
/* Path of the file we're parsing. */
char* path;
/* The stream we're reading from. */
- FILE *stream;
+ void *stream;
+ /* Length of the stream (only used for memory streams) */
+ size_t streamlen;
+ /* Offset in the stream (only used for memory streams) */
+ size_t streamoffset;
+ /* our IO interface */
+ struct _NagaQueenIoInterface io;
/* The begin position and length of the current token in the text */
int token[2];
/* type parsing buffer */
@@ -74,13 +84,33 @@ struct _NagaQueenCore {
typedef struct _NagaQueenCore NagaQueenCore;
+///////////////////// IO interface: supports memory + files ////////////////////////
+
+static int _nq_memread(void *ptr, size_t size, NagaQueenCore *core) {
+ char *source = (char *) core->stream;
+ size_t tocopy = size;
+ size_t remaining = core->streamlen - core->streamoffset;
+ if (tocopy > remaining) {
+ tocopy = remaining;
+ }
+ memcpy(ptr, source + core->streamoffset, tocopy);
+ core->streamoffset += tocopy;
+ return (int) tocopy;
+}
+
+static int _nq_fread(void *ptr, size_t size, NagaQueenCore *core) {
+ FILE *stream = (FILE *) core->stream;
+ return fread(ptr, 1, size, (FILE*) stream);
+}
+
+
#define YY_XTYPE NagaQueenCore *
#define YY_XVAR core
#define YY_INPUT(buf, result, max_size, core) yyInput(buf, &result, max_size, core)
void yyInput(char *buf, int *result, int max_size, NagaQueenCore *core) {
- (*result) = fread(buf, 1, max_size, core->stream);
+ (*result) = core->io.read(buf, max_size, core);
static int doneNewlineHack = 0;
if((*result) == 0 && doneNewlineHack == 0) {
doneNewlineHack = 1;
@@ -1541,6 +1571,39 @@ BOOL_LIT = (TRUE_KW &[^A-Za-z_] { $$=(void*) true; } | FALSE_KW &[^A-Za-z_]
%%
+int nq_memparse(void *this, char *buffer, size_t len) {
+
+ GREG *G = YY_ALLOC(sizeof(GREG), 0);
+ G->buflen = 0;
+
+ NagaQueenCore *core = YY_ALLOC(sizeof(NagaQueenCore), 0);
+ core->yylineno = 0;
+ core->this = this;
+ core->path = NULL;
+ core->stream = buffer;
+ core->streamoffset = 0;
+ core->streamlen = len;
+ if(!core->stream) {
+ printf("Null input buffer\n");
+ return -1;
+ }
+ if(len < 0) {
+ printf("Invalid input buffer length\n");
+ return -1;
+ }
+ nq_setTokenPositionPointer(this, core->token);
+ core->io = (struct _NagaQueenIoInterface) {
+ _nq_memread
+ };
+
+ G->data = core;
+
+ while (yyparse(G)) {}
+
+ return 0;
+
+}
+
int nq_parse(void *this, char *path) {
GREG *G = YY_ALLOC(sizeof(GREG), 0);
@@ -1551,11 +1614,16 @@ int nq_parse(void *this, char *path) {
core->this = this;
core->path = path;
core->stream = fopen(path, "r");
- nq_setTokenPositionPointer(this, core->token);
+ core->streamoffset = -1;
+ core->streamlen = -1;
if(!core->stream) {
printf("Not found: %s\n", path);
return -1;
}
+ nq_setTokenPositionPointer(this, core->token);
+ core->io = (struct _NagaQueenIoInterface) {
+ _nq_fread
+ };
G->data = core;
@@ -1,5 +1,6 @@
import OocListener
+nq_memparse: extern func (l: OocListener, buffer: CString, len: SizeT) -> Int
nq_parse: extern func (l: OocListener, path: CString) -> Int
nq_setTokenPositionPointer: unmangled func (l: OocListener, tokenPosPointer: Int*) {

0 comments on commit 721f0b1

Please sign in to comment.