mirror of
git://git.psyc.eu/libpsyc
synced 2024-08-15 03:19:02 +00:00
parser fixes & refactoring; added more tests
This commit is contained in:
parent
344f327e19
commit
a0ab246127
21 changed files with 479 additions and 406 deletions
|
@ -9,15 +9,35 @@ enum PSYC_Flags
|
||||||
|
|
||||||
enum PSYC_ReturnCodes
|
enum PSYC_ReturnCodes
|
||||||
{
|
{
|
||||||
PSYC_ERROR_EXPECTED_TAB = -8,
|
PSYC_ERROR_END = -7,
|
||||||
|
PSYC_ERROR_METHOD = -6,
|
||||||
|
PSYC_ERROR_VAR_LEN = -5,
|
||||||
|
PSYC_ERROR_VAR_TAB = -4,
|
||||||
|
PSYC_ERROR_VAR_NAME = -3,
|
||||||
|
PSYC_ERROR_LENGTH = -2,
|
||||||
|
PSYC_ERROR = -1,
|
||||||
|
PSYC_SUCCESS = 0,
|
||||||
PSYC_BODY = 1,
|
PSYC_BODY = 1,
|
||||||
PSYC_BODY_INCOMPLETE,
|
PSYC_BODY_INCOMPLETE = 2,
|
||||||
PSYC_INSUFFICIENT,
|
PSYC_INSUFFICIENT = 3,
|
||||||
PSYC_ROUTING,
|
PSYC_ROUTING = 4,
|
||||||
PSYC_ENTITY,
|
PSYC_ENTITY = 5,
|
||||||
PSYC_ENTITY_INCOMPLETE,
|
PSYC_ENTITY_INCOMPLETE = 6,
|
||||||
PSYC_HEADER_COMPLETE,
|
PSYC_HEADER_COMPLETE = 7,
|
||||||
PSYC_COMPLETE,
|
PSYC_COMPLETE = 8,
|
||||||
|
PSYC_INCOMPLETE = 9,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PSYC_Parts
|
||||||
|
{
|
||||||
|
PSYC_PART_RESET = -1,
|
||||||
|
PSYC_PART_HEADER = 0,
|
||||||
|
PSYC_PART_LENGTH,
|
||||||
|
PSYC_PART_HEADER_END,
|
||||||
|
PSYC_PART_CONTENT,
|
||||||
|
PSYC_PART_METHOD,
|
||||||
|
PSYC_PART_DATA,
|
||||||
|
PSYC_PART_END,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,14 +50,17 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned int cursor; // current position in buffer
|
unsigned int cursor; /** current position in buffer */
|
||||||
|
unsigned int startc; /** line start position */
|
||||||
PSYC_Array buffer;
|
PSYC_Array buffer;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
|
char part; /** part of the packet being parsed currently, see PSYC_Parts */
|
||||||
|
|
||||||
unsigned int contentParsed; //
|
unsigned int contentParsed; /** number of bytes parsed from the content so far */
|
||||||
char inContent;
|
unsigned int contentLength; /** expected length of the content */
|
||||||
unsigned int valueRemaining;
|
char contentLengthFound; /** is there a length given for this packet? */
|
||||||
unsigned int contentLength;
|
unsigned int valueParsed; /** number of bytes parsef from the value so far */
|
||||||
|
unsigned int valueLength; /** expected length of the value */
|
||||||
} PSYC_State;
|
} PSYC_State;
|
||||||
|
|
||||||
#ifndef PSYC_COMPILE_LIBRARY
|
#ifndef PSYC_COMPILE_LIBRARY
|
||||||
|
@ -83,12 +106,6 @@ inline unsigned int PSYC_getContentLength (PSYC_State* s)
|
||||||
return s->contentLength;
|
return s->contentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned int PSYC_getValueRemaining (PSYC_State* s)
|
|
||||||
{
|
|
||||||
return s->valueRemaining;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int PSYC_parse(PSYC_State* state,
|
int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value);
|
||||||
uint8_t* modifier, PSYC_Array* name, PSYC_Array* value);
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
CFLAGS=-I../../include -DDEBUG -DPSYC_COMPILE_LIBRARY -g -O0 -Wall
|
||||||
CC=cc -I../include
|
CC=cc -I../include
|
||||||
# CC=clang
|
# CC=clang
|
||||||
|
|
||||||
|
@ -8,11 +9,11 @@ default:
|
||||||
@/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc"
|
@/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc"
|
||||||
|
|
||||||
diet:
|
diet:
|
||||||
diet ${CC} -static -c -Os $S -DDEBUG -DPSYC_COMPILE_LIBRARY
|
diet ${CC} -static -c -Os $S ${CFLAGS}
|
||||||
diet ar rcs libpsyc.a $O
|
diet ar rcs libpsyc.a $O
|
||||||
|
|
||||||
lib: $S
|
lib: $S
|
||||||
${CC} -static -c -g -O0 $S -lc -DDEBUG -DPSYC_COMPILE_LIBRARY
|
${CC} -static -c -g -O0 $S -lc ${CFLAGS}
|
||||||
ar rcs libpsyc.a $O
|
ar rcs libpsyc.a $O
|
||||||
|
|
||||||
match: match.c
|
match: match.c
|
||||||
|
|
666
src/parser.c
666
src/parser.c
|
@ -7,6 +7,13 @@
|
||||||
|
|
||||||
#include <psyc/parser.h>
|
#include <psyc/parser.h>
|
||||||
|
|
||||||
|
#define ADVANCE_CURSOR_OR_RETURN() \
|
||||||
|
if (++(state->cursor) >= state->buffer.length) \
|
||||||
|
{ \
|
||||||
|
state->cursor = state->startc; \
|
||||||
|
return PSYC_INSUFFICIENT; \
|
||||||
|
}
|
||||||
|
|
||||||
/** @brief isGlyph
|
/** @brief isGlyph
|
||||||
*
|
*
|
||||||
* @todo: document this function
|
* @todo: document this function
|
||||||
|
@ -16,9 +23,10 @@ inline char isGlyph(uint8_t g)
|
||||||
switch(g)
|
switch(g)
|
||||||
{
|
{
|
||||||
case ':':
|
case ':':
|
||||||
case '-':
|
|
||||||
case '+':
|
|
||||||
case '=':
|
case '=':
|
||||||
|
case '?':
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -26,411 +34,319 @@ inline char isGlyph(uint8_t g)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline char isNumeric(uint8_t c)
|
inline char isNumeric(uint8_t c)
|
||||||
{
|
{
|
||||||
return c >= '0' && c <= '9' ;
|
return c >= '0' && c <= '9';
|
||||||
}
|
}
|
||||||
|
|
||||||
inline char isAlphaNumeric(uint8_t c)
|
inline char isAlphaNumeric(uint8_t c)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
(( c >= 'a' && c <= 'z' )||
|
(c >= 'a' && c <= 'z') ||
|
||||||
( c >= 'A' && c <= 'Z' )||
|
(c >= 'A' && c <= 'Z') ||
|
||||||
isNumeric(c))
|
isNumeric(c);
|
||||||
;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline char isKwChar(uint8_t c)
|
||||||
|
|
||||||
/** @brief generalized linebased parser */
|
|
||||||
inline int PSYC_parse(
|
|
||||||
PSYC_State* state,
|
|
||||||
uint8_t* modifier, PSYC_Array* name, PSYC_Array* value)
|
|
||||||
{
|
{
|
||||||
start:
|
return c == '_' || isAlphaNumeric(c);
|
||||||
|
}
|
||||||
|
|
||||||
if (state->valueRemaining != 0)
|
/**
|
||||||
goto binaryArg;
|
* @brief Parse variable name or method name.
|
||||||
|
* @details It should contain one or more keyword characters.
|
||||||
/* first we test if we can access the first char */
|
* @return PSYC_ERROR or PSYC_SUCCESS
|
||||||
if(state->buffer.length<=state->cursor) // cursor is not inside the length
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient data.
|
|
||||||
|
|
||||||
// in case we return insufficent, we rewind to the start.
|
|
||||||
unsigned int startc=state->cursor;
|
|
||||||
|
|
||||||
/******************************************
|
|
||||||
* * * * * * * Inspect Header * * * * * * *
|
|
||||||
*******************************************/
|
|
||||||
/* each line of the header starts with a glyph.
|
|
||||||
* iE :_name, -_name +_name etc, so just test if
|
|
||||||
* the first char is a glyph. */
|
|
||||||
if(0==state->inContent)
|
|
||||||
{
|
|
||||||
if(!isGlyph(state->buffer.ptr[state->cursor])) // is the first char not a glyph?
|
|
||||||
{ // parse length of content here
|
|
||||||
if(isNumeric(state->buffer.ptr[state->cursor]))
|
|
||||||
{
|
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
|
|
||||||
while(isNumeric(state->buffer.ptr[state->cursor]));
|
|
||||||
{
|
|
||||||
state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0';
|
|
||||||
|
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// header ends with a NL
|
|
||||||
if (state->buffer.ptr[state->cursor] != '\n')
|
|
||||||
{
|
|
||||||
return -10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
|
|
||||||
// the only other possibility now is that the packet
|
|
||||||
// is complete(empty packet) or that the method started.
|
|
||||||
if (isAlphaNumeric(state->buffer.ptr[state->cursor]))
|
|
||||||
{
|
|
||||||
state->inContent = 1;
|
|
||||||
|
|
||||||
if (state->flags & PSYC_HEADER_ONLY)
|
|
||||||
return PSYC_HEADER_COMPLETE; // return header finished
|
|
||||||
else
|
|
||||||
goto start;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->buffer.ptr[state->cursor] == '|')
|
|
||||||
{
|
|
||||||
if (state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->buffer.ptr[state->cursor]=='\n')
|
|
||||||
{
|
|
||||||
++(state->cursor);
|
|
||||||
state->inContent = 0;
|
|
||||||
return PSYC_COMPLETE; // return packet finished
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -6; // report error
|
|
||||||
}
|
|
||||||
else // it is a glyph, so a variable name starts here
|
|
||||||
{
|
|
||||||
/***************************************************
|
|
||||||
* * * * * * * Routing Variable Start * * * * * * *
|
|
||||||
**************************************************/
|
|
||||||
|
|
||||||
*modifier = *(state->buffer.ptr+state->cursor);
|
|
||||||
|
|
||||||
if (state->buffer.length <= ++(state->cursor))
|
|
||||||
{
|
|
||||||
state->cursor = startc; // rewind to start of line
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
|
|
||||||
name->ptr = state->buffer.ptr + state->cursor;
|
|
||||||
|
|
||||||
name->length = 1;
|
|
||||||
}
|
|
||||||
} // endif inContent=0
|
|
||||||
|
|
||||||
char method=0;
|
|
||||||
/* each line of the header starts with a glyph.
|
|
||||||
* iE :_name, -_name +_name etc, so just test if
|
|
||||||
* the first char is a glyph. */
|
|
||||||
/* in the body, the same applies, only that the
|
|
||||||
* method does not start with a glyph.*/
|
|
||||||
if(1==state->inContent)
|
|
||||||
{
|
|
||||||
if(!isGlyph(state->buffer.ptr[state->cursor]))
|
|
||||||
{
|
|
||||||
if(!isAlphaNumeric(state->buffer.ptr[state->cursor]) && state->buffer.ptr[state->cursor] != '_')
|
|
||||||
{
|
|
||||||
// the body rule is optional, which means
|
|
||||||
// that now also just |\n can follow.
|
|
||||||
if(state->buffer.ptr[state->cursor] == '|')
|
|
||||||
{
|
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
|
|
||||||
if(state->buffer.ptr[state->cursor]=='\n')
|
|
||||||
{
|
|
||||||
++(state->cursor);
|
|
||||||
state->inContent = 0;
|
|
||||||
return PSYC_COMPLETE; // return packet finished
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -5; // report error
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
name->ptr = state->buffer.ptr+state->cursor;
|
|
||||||
name->length=1;
|
|
||||||
method=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*modifier = *(state->buffer.ptr+state->cursor);
|
|
||||||
|
|
||||||
if (state->buffer.length <= ++(state->cursor))
|
|
||||||
{
|
|
||||||
state->cursor = startc; // rewind
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
|
|
||||||
name->ptr = state->buffer.ptr+state->cursor;
|
|
||||||
name->length=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* validate the incremented cursor */
|
|
||||||
if(state->buffer.length <= ++(state->cursor))
|
|
||||||
{
|
|
||||||
state->cursor=startc;
|
|
||||||
return PSYC_INSUFFICIENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* what follows is the name. At least one char.
|
|
||||||
* allowed is alphanumeric and _ */
|
|
||||||
|
|
||||||
// first char must exist.
|
|
||||||
if(!isAlphaNumeric(state->buffer.ptr[state->cursor]) // is it not alphanum
|
|
||||||
&& state->buffer.ptr[state->cursor] != '_') // AND not '_'. must be invalid then
|
|
||||||
return -1; // return parser error.
|
|
||||||
|
|
||||||
name->length+=1;
|
|
||||||
|
|
||||||
/* now checking how long the name of the variable is. */
|
|
||||||
unsigned int i=0;
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
if(state->buffer.length<= ++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
|
|
||||||
// same as bevore
|
|
||||||
if(!isAlphaNumeric(state->buffer.ptr[state->cursor]) &&
|
|
||||||
state->buffer.ptr[state->cursor] != '_')
|
|
||||||
break; // not valid? then stop the loop right here
|
|
||||||
|
|
||||||
++(name->length); // was a valid char, increase length
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we now parsed the variable name successfully
|
|
||||||
* after the name either a \n or a \t follows.
|
|
||||||
*
|
|
||||||
* for the method, the data starts after an \n
|
|
||||||
* so checking for \n too here
|
|
||||||
|
|
||||||
* We dont check if cursor inside length, because
|
|
||||||
* the last loop iteration did that already.
|
|
||||||
*/
|
*/
|
||||||
if(state->buffer.ptr[state->cursor] == '\t' || state->buffer.ptr[state->cursor] == '\n') // && method==1))
|
inline int PSYC_parseName(PSYC_State* state, PSYC_Array* name)
|
||||||
|
{
|
||||||
|
name->ptr = state->buffer.ptr + state->cursor;
|
||||||
|
name->length = 0;
|
||||||
|
|
||||||
|
while (isKwChar(state->buffer.ptr[state->cursor]))
|
||||||
{
|
{
|
||||||
/* after the \t the data follows, which is
|
name->length++; // was a valid char, increase length
|
||||||
* anything but \n. data can be of length 0
|
ADVANCE_CURSOR_OR_RETURN();
|
||||||
*
|
|
||||||
* for the method: after the \n data follows,
|
|
||||||
* which is anything but \n|\n
|
|
||||||
*
|
|
||||||
* but data is optional, so we first check
|
|
||||||
* here if data follows at all.
|
|
||||||
*
|
|
||||||
* arg-data=value. we set value here so it
|
|
||||||
* points to a valid range and so we point
|
|
||||||
* to the first potential arg-data byte.
|
|
||||||
* If there is no arg-data, we still have
|
|
||||||
* the length attribute on 0. */
|
|
||||||
if((method == 0 && state->buffer.ptr[state->cursor] == '\n') /* emptyvar */ ||
|
|
||||||
(method == 1 && state->cursor+2 < state->buffer.length &&
|
|
||||||
state->buffer.ptr[state->cursor+1] == '|' &&
|
|
||||||
state->buffer.ptr[state->cursor+2] == '\n') /*no data */ )
|
|
||||||
{
|
|
||||||
value->ptr=state->buffer.ptr+state->cursor;
|
|
||||||
value->length=0;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
return name->length > 0 ? PSYC_SUCCESS : PSYC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse binary data into value.
|
||||||
|
* @details length is the expected length of the data, parsed is the number of bytes parsed so far
|
||||||
|
* @return PSYC_COMPLETE or PSYC_INCOMPLETE
|
||||||
|
*/
|
||||||
|
inline int PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* value, unsigned int* length, unsigned int* parsed)
|
||||||
|
{
|
||||||
|
unsigned int remaining = *length - *parsed;
|
||||||
|
value->ptr = state->buffer.ptr + state->cursor;
|
||||||
|
|
||||||
|
if (state->cursor + remaining > state->buffer.length) // is the length larger than this buffer?
|
||||||
{
|
{
|
||||||
value->ptr=state->buffer.ptr+state->cursor+1;
|
|
||||||
if (0 != state->contentLength) // we know the length of the packet
|
|
||||||
{
|
|
||||||
// is the packet in the buffer?
|
|
||||||
if (value->ptr + state->contentLength + 3 > state->buffer.ptr + state->buffer.length)
|
|
||||||
{ // no
|
|
||||||
value->length = state->buffer.length - state->cursor;
|
value->length = state->buffer.length - state->cursor;
|
||||||
//*expectedBytes = state->contentLength - value->length;
|
*parsed += value->length;
|
||||||
}
|
state->cursor = 0;
|
||||||
else // yes, the packet is complete in the buffer.
|
return PSYC_INCOMPLETE;
|
||||||
{
|
|
||||||
value->length= state->buffer.length - state->cursor -3;
|
|
||||||
//*expectedBytes = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // else search for the terminator
|
|
||||||
{
|
|
||||||
value->length=0;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT ; // return insufficient
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0 == method && state->buffer.ptr[state->cursor] == '\n')
|
value->length += remaining;
|
||||||
break;
|
state->cursor += remaining;
|
||||||
|
*parsed += value->length;
|
||||||
|
|
||||||
if(1 == method && state->buffer.ptr[state->cursor] == '\n')
|
|
||||||
{
|
|
||||||
if(state->buffer.length<=(state->cursor)+2) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
|
|
||||||
if(state->buffer.ptr[state->cursor+1] == '|')
|
|
||||||
if(state->buffer.ptr[state->cursor+2] == '\n')
|
|
||||||
{
|
|
||||||
/* packet finishes here */
|
|
||||||
state->cursor+=3;
|
|
||||||
state->inContent = 0;
|
|
||||||
return PSYC_COMPLETE;
|
return PSYC_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
++(value->length);
|
* @brief Parse simple or binary variable
|
||||||
}
|
* @return PSYC_ERROR or PSYC_SUCCESS
|
||||||
}
|
*/
|
||||||
}
|
inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value)
|
||||||
}
|
{
|
||||||
else if(state->inContent == 1 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var!
|
*modifier = *(state->buffer.ptr + state->cursor);
|
||||||
{ // after SP the length follows.
|
ADVANCE_CURSOR_OR_RETURN();
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
|
|
||||||
while(isNumeric(state->buffer.ptr[state->cursor]))
|
if (PSYC_parseName(state, name) != PSYC_SUCCESS)
|
||||||
{
|
return PSYC_ERROR_VAR_NAME;
|
||||||
value->length = 10 * value->length + state->buffer.ptr[state->cursor] - '0';
|
|
||||||
|
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// after the length a TAB follows
|
|
||||||
if (state->buffer.ptr[state->cursor] != '\t')
|
|
||||||
return PSYC_ERROR_EXPECTED_TAB;
|
|
||||||
|
|
||||||
binaryArg:
|
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->valueRemaining = value->length - state->cursor;
|
|
||||||
state->cursor=0;
|
|
||||||
|
|
||||||
value->length = 0;
|
value->length = 0;
|
||||||
value->ptr = state->buffer.ptr;
|
|
||||||
|
|
||||||
|
/* Parse the value.
|
||||||
|
* If we're in the content part check if it's a binary var */
|
||||||
|
if (state->part == PSYC_PART_CONTENT && state->buffer.ptr[state->cursor] == ' ') // binary arg
|
||||||
|
{ // after SP the length follows.
|
||||||
|
ADVANCE_CURSOR_OR_RETURN();
|
||||||
|
state->valueLength = 0;
|
||||||
|
state->valueParsed = 0;
|
||||||
|
|
||||||
|
if (isNumeric(state->buffer.ptr[state->cursor]))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
state->valueLength = 10 * state->valueLength + state->buffer.ptr[state->cursor] - '0';
|
||||||
|
ADVANCE_CURSOR_OR_RETURN();
|
||||||
|
}
|
||||||
|
while (isNumeric(state->buffer.ptr[state->cursor]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return PSYC_ERROR_VAR_LEN;
|
||||||
|
|
||||||
|
// after the length a TAB follows
|
||||||
|
if (state->buffer.ptr[state->cursor] != '\t')
|
||||||
|
return PSYC_ERROR_VAR_TAB;
|
||||||
|
|
||||||
|
if (state->buffer.length <= ++(state->cursor)) // incremented cursor inside length?
|
||||||
|
{
|
||||||
|
state->cursor = 0;
|
||||||
return PSYC_ENTITY_INCOMPLETE;
|
return PSYC_ENTITY_INCOMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the length still in this buffer?
|
if (PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)) == PSYC_INCOMPLETE)
|
||||||
if(state->buffer.length <= state->cursor+value->length+1 )
|
|
||||||
{
|
|
||||||
state->valueRemaining = value->length - state->cursor;
|
|
||||||
state->cursor=0;
|
|
||||||
|
|
||||||
value->ptr = state->buffer.ptr + state->cursor;
|
|
||||||
value->length = state->buffer.length - state->cursor;
|
|
||||||
|
|
||||||
return PSYC_ENTITY_INCOMPLETE;
|
return PSYC_ENTITY_INCOMPLETE;
|
||||||
}
|
|
||||||
|
|
||||||
|
state->cursor++;
|
||||||
|
return PSYC_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (state->buffer.ptr[state->cursor] == '\t') // simple arg
|
||||||
|
{
|
||||||
|
ADVANCE_CURSOR_OR_RETURN();
|
||||||
value->ptr = state->buffer.ptr + state->cursor;
|
value->ptr = state->buffer.ptr + state->cursor;
|
||||||
state->cursor += value->length;
|
|
||||||
state->valueRemaining = 0;
|
while (state->buffer.ptr[state->cursor] != '\n')
|
||||||
|
{
|
||||||
|
value->length++;
|
||||||
|
ADVANCE_CURSOR_OR_RETURN();
|
||||||
|
}
|
||||||
|
state->cursor++;
|
||||||
|
return PSYC_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -8;
|
return PSYC_ERROR_VAR_TAB;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* if there was a \t, then we parsed up until the
|
|
||||||
* \n char from the simple-arg rule ( \t arg-data \n )
|
|
||||||
*
|
|
||||||
* Now, if there would be no \t, we still would be at
|
|
||||||
* the point where a \n must follow.
|
|
||||||
*
|
|
||||||
* So, just checking \n here will cover both cases of
|
|
||||||
* the alternative ( simple-arg / \n ) from rule
|
|
||||||
* routing-modifier
|
|
||||||
*
|
|
||||||
* again, the loop has already validated the cursors
|
|
||||||
* position*/
|
|
||||||
if(state->buffer.ptr[state->cursor] != '\n')
|
|
||||||
return -2; // return parser error.
|
|
||||||
|
|
||||||
/* if a \n follows now, the an body is attached.
|
|
||||||
* if not, a |\n must follow */
|
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
|
|
||||||
if(0 == state->inContent && state->buffer.ptr[state->cursor] == '\n')
|
|
||||||
{
|
|
||||||
state->cursor+=1;
|
|
||||||
state->inContent = 1;
|
|
||||||
|
|
||||||
return PSYC_ROUTING; // return header finished
|
|
||||||
}
|
|
||||||
|
|
||||||
if(state->buffer.ptr[state->cursor] != '|') // no pipe, then only line complete, not the packet.
|
|
||||||
{
|
|
||||||
if (state->inContent == 0)
|
|
||||||
return PSYC_ROUTING;
|
|
||||||
else
|
|
||||||
return PSYC_ENTITY;
|
|
||||||
}
|
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
|
|
||||||
{
|
|
||||||
state->cursor=startc; // set to start value
|
|
||||||
return PSYC_INSUFFICIENT; // return insufficient
|
|
||||||
}
|
|
||||||
if(state->buffer.ptr[state->cursor] != '\n')
|
|
||||||
return -4;
|
|
||||||
|
|
||||||
state->cursor+=1;
|
|
||||||
state->inContent = 0;
|
|
||||||
return PSYC_COMPLETE; // packet is complete
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief generalized line-based parser */
|
||||||
|
int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value)
|
||||||
|
{
|
||||||
|
int ret; /* a return value */
|
||||||
|
unsigned int pos; /* a cursor position */
|
||||||
|
|
||||||
|
/* start position of the current line in the buffer
|
||||||
|
* in case we return insufficent, we rewind to this position */
|
||||||
|
state->startc = state->cursor;
|
||||||
|
|
||||||
|
/* first we test if we can access the first char */
|
||||||
|
if (state->buffer.length <= state->cursor) // cursor is not inside the length
|
||||||
|
return PSYC_INSUFFICIENT; // return insufficient data.
|
||||||
|
|
||||||
|
switch (state->part)
|
||||||
|
{
|
||||||
|
case PSYC_PART_RESET: // new packet starts here, reset state
|
||||||
|
state->valueParsed = 0;
|
||||||
|
state->valueLength = 0;
|
||||||
|
state->contentParsed = 0;
|
||||||
|
state->contentLength = 0;
|
||||||
|
state->contentLengthFound = 0;
|
||||||
|
state->part = PSYC_PART_HEADER;
|
||||||
|
// fall thru
|
||||||
|
|
||||||
|
case PSYC_PART_HEADER:
|
||||||
|
/* Each line of the header starts with a glyph,
|
||||||
|
* i.e. :_name, -_name +_name etc,
|
||||||
|
* so just test if the first char is a glyph.
|
||||||
|
*/
|
||||||
|
if (isGlyph(state->buffer.ptr[state->cursor])) // is the first char a glyph?
|
||||||
|
{ // it is a glyph, so a variable starts here
|
||||||
|
ret = PSYC_parseVar(state, modifier, name, value);
|
||||||
|
return ret == PSYC_SUCCESS ? PSYC_ROUTING : ret;
|
||||||
|
}
|
||||||
|
else // not a glyph
|
||||||
|
{
|
||||||
|
state->part = PSYC_PART_LENGTH;
|
||||||
|
// fall thru
|
||||||
|
}
|
||||||
|
|
||||||
|
case PSYC_PART_LENGTH:
|
||||||
|
/* End of header, content starts with an optional length then a NL */
|
||||||
|
if (isNumeric(state->buffer.ptr[state->cursor]))
|
||||||
|
{
|
||||||
|
state->contentLengthFound = 1;
|
||||||
|
state->contentLength = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0';
|
||||||
|
ADVANCE_CURSOR_OR_RETURN();
|
||||||
|
}
|
||||||
|
while (isNumeric(state->buffer.ptr[state->cursor]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->buffer.ptr[state->cursor] == '\n') /* start of content */
|
||||||
|
{
|
||||||
|
/* If we need to parse the header only and we know the content length, then skip content parsing. */
|
||||||
|
if (state->flags & PSYC_HEADER_ONLY && state->contentLengthFound)
|
||||||
|
state->part = PSYC_PART_DATA;
|
||||||
|
else
|
||||||
|
state->part = PSYC_PART_CONTENT;
|
||||||
|
}
|
||||||
|
else /* not start of content, this must be the end */
|
||||||
|
{
|
||||||
|
/* if we have a length then it should've been followed by a \n */
|
||||||
|
if (state->contentLengthFound)
|
||||||
|
return PSYC_ERROR_LENGTH;
|
||||||
|
|
||||||
|
state->part = PSYC_PART_END;
|
||||||
|
goto PSYC_PART_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADVANCE_CURSOR_OR_RETURN();
|
||||||
|
state->startc = state->cursor;
|
||||||
|
// fall thru
|
||||||
|
|
||||||
|
case PSYC_PART_CONTENT:
|
||||||
|
/* In case of an incomplete binary variable resume parsing it. */
|
||||||
|
if (state->valueParsed < state->valueLength) {
|
||||||
|
ret = PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed));
|
||||||
|
state->contentParsed += value->length;
|
||||||
|
return ret == PSYC_COMPLETE ? PSYC_ENTITY : PSYC_ENTITY_INCOMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Each line of the header starts with a glyph,
|
||||||
|
* i.e. :_name, -_name +_name etc.
|
||||||
|
* So just test if the first char is a glyph.
|
||||||
|
* In the body, the same applies, only that the
|
||||||
|
* method does not start with a glyph.
|
||||||
|
*/
|
||||||
|
if (isGlyph(state->buffer.ptr[state->cursor]))
|
||||||
|
{
|
||||||
|
pos = state->cursor;
|
||||||
|
ret = PSYC_parseVar(state, modifier, name, value);
|
||||||
|
state->contentParsed += state->cursor - pos;
|
||||||
|
return ret == PSYC_SUCCESS ? PSYC_ENTITY : ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state->part = PSYC_PART_METHOD;
|
||||||
|
state->startc = state->cursor;
|
||||||
|
// fall thru
|
||||||
|
}
|
||||||
|
|
||||||
|
case PSYC_PART_METHOD:
|
||||||
|
pos = state->cursor;
|
||||||
|
if (PSYC_parseName(state, name) == PSYC_SUCCESS)
|
||||||
|
{ /* the method ends with a \n then the data follows */
|
||||||
|
if (state->buffer.ptr[state->cursor] != '\n')
|
||||||
|
return PSYC_ERROR_METHOD;
|
||||||
|
|
||||||
|
state->cursor++;
|
||||||
|
state->startc = state->cursor;
|
||||||
|
state->contentParsed += state->cursor - pos;
|
||||||
|
state->part = PSYC_PART_DATA;
|
||||||
|
if (state->cursor >= state->buffer.length)
|
||||||
|
return PSYC_INSUFFICIENT;
|
||||||
|
// fall thru
|
||||||
|
}
|
||||||
|
else /* no method, which means the packet should end now */
|
||||||
|
{
|
||||||
|
state->part = PSYC_PART_END;
|
||||||
|
state->startc = state->cursor;
|
||||||
|
goto PSYC_PART_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PSYC_PART_DATA:
|
||||||
|
value->ptr = state->buffer.ptr + state->cursor;
|
||||||
|
value->length = 0;
|
||||||
|
|
||||||
|
if (state->contentLengthFound) // we know the length of the packet
|
||||||
|
{
|
||||||
|
if (PSYC_parseBinaryValue(state, value, &(state->contentLength), &(state->contentParsed)) == PSYC_INCOMPLETE)
|
||||||
|
return PSYC_BODY_INCOMPLETE;
|
||||||
|
|
||||||
|
state->cursor++;
|
||||||
|
state->part = PSYC_PART_END;
|
||||||
|
return PSYC_BODY;
|
||||||
|
}
|
||||||
|
else // search for the terminator
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (state->buffer.ptr[state->cursor] == '\n')
|
||||||
|
{
|
||||||
|
if (state->cursor+2 >= state->buffer.length) // incremented cursor inside length?
|
||||||
|
{
|
||||||
|
state->cursor = state->startc; // set to start value
|
||||||
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->buffer.ptr[state->cursor+1] == '|' &&
|
||||||
|
state->buffer.ptr[state->cursor+2] == '\n') /* packet ends here */
|
||||||
|
{
|
||||||
|
state->cursor++;
|
||||||
|
state->part = PSYC_PART_END;
|
||||||
|
return PSYC_BODY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value->length++;
|
||||||
|
ADVANCE_CURSOR_OR_RETURN();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case PSYC_PART_END:
|
||||||
|
PSYC_PART_END:
|
||||||
|
/* end of packet, at this point we have already passed a \n
|
||||||
|
and the cursor should point to | */
|
||||||
|
if (state->cursor+1 >= state->buffer.length) // incremented cursor inside length?
|
||||||
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
|
|
||||||
|
if (state->buffer.ptr[state->cursor] == '|' &&
|
||||||
|
state->buffer.ptr[state->cursor+1] == '\n') /* packet ends here */
|
||||||
|
{
|
||||||
|
state->cursor += 2;
|
||||||
|
state->part = PSYC_PART_RESET;
|
||||||
|
return PSYC_COMPLETE;
|
||||||
|
}
|
||||||
|
else /* packet should've ended here, return error */
|
||||||
|
{
|
||||||
|
state->part = PSYC_PART_RESET;
|
||||||
|
return PSYC_ERROR_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PSYC_ERROR; // should not be reached
|
||||||
|
}
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
CFLAGS=-I../../include -DDEBUG -g -O0
|
CFLAGS=-I../../include -DDEBUG -g -O0 -Wall
|
||||||
LDFLAGS=-L..
|
LDFLAGS=-L..
|
||||||
LOADLIBES=-lpsyc
|
LOADLIBES=-lpsyc
|
||||||
TARGETS=testParser testMatch
|
TARGETS=testParser testMatch
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
||||||
# special case because not in the same directory
|
|
||||||
testParser:
|
|
||||||
${CC} ${CFLAGS} ${LDFLAGS} parser/testParser.c ${LOADLIBES} -o testParser
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
for f in parser/*txt; do echo -e "\n>> $$f"; ./testParser $$f; done
|
for f in packets/*; do echo -e "\n>> $$f"; ./testParser $$f; done
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm $(TARGETS)
|
rm -f $(TARGETS)
|
||||||
|
|
|
@ -4,4 +4,3 @@
|
||||||
_request_some_things
|
_request_some_things
|
||||||
content!
|
content!
|
||||||
|
|
|
|
||||||
|
|
3
src/tests/packets/test-0-no-content
Normal file
3
src/tests/packets/test-0-no-content
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
:_source psyc://test.psyc.eu/
|
||||||
|
:_target psyc://test.psyc.eu/
|
||||||
|
|
|
14
src/tests/packets/test-1
Normal file
14
src/tests/packets/test-1
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
|
||||||
|
:_source psyc://foo/~bar
|
||||||
|
:_target psyc://bar/~baz
|
||||||
|
:_tag sch1828hu3r2cm
|
||||||
|
|
||||||
|
:_foo bar baz
|
||||||
|
:_abc_def 11 foo bar
|
||||||
|
baz
|
||||||
|
:_foo_bar yay
|
||||||
|
_message_foo_bar
|
||||||
|
ohai there!
|
||||||
|
\o/
|
||||||
|
|
|
||||||
|
|
|
14
src/tests/packets/test-1-length
Normal file
14
src/tests/packets/test-1-length
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
|
||||||
|
:_source psyc://foo/~bar
|
||||||
|
:_target psyc://bar/~baz
|
||||||
|
:_tag sch1828hu3r2cm
|
||||||
|
85
|
||||||
|
:_foo bar baz
|
||||||
|
:_abc_def 11 foo bar
|
||||||
|
baz
|
||||||
|
:_foo_bar yay
|
||||||
|
_message_foo_bar
|
||||||
|
ohai there!
|
||||||
|
\o/
|
||||||
|
|
|
||||||
|
|
|
14
src/tests/packets/test-1-length-error
Normal file
14
src/tests/packets/test-1-length-error
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
|
||||||
|
:_source psyc://foo/~bar
|
||||||
|
:_target psyc://bar/~baz
|
||||||
|
:_tag sch1828hu3r2cm
|
||||||
|
80
|
||||||
|
:_foo bar baz
|
||||||
|
:_abc_def 11 foo bar
|
||||||
|
baz
|
||||||
|
:_foo_bar yay
|
||||||
|
_message_foo_bar
|
||||||
|
ohai there!
|
||||||
|
\o/
|
||||||
|
|
|
||||||
|
|
|
14
src/tests/packets/test-1-utf8
Normal file
14
src/tests/packets/test-1-utf8
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
|
||||||
|
:_source psyc://foo/~bar
|
||||||
|
:_target psyc://bar/~baz
|
||||||
|
:_tag sch1828hu3r2cm
|
||||||
|
|
||||||
|
:_foo bar baz
|
||||||
|
:_abc_def 15 fóö bär
|
||||||
|
báz
|
||||||
|
:_foo_bar yay
|
||||||
|
_message_foo_bar
|
||||||
|
ohai there!
|
||||||
|
\o/
|
||||||
|
|
|
||||||
|
|
|
25
src/tests/packets/test-2-list
Normal file
25
src/tests/packets/test-2-list
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
|
|
||||||
|
=_source psyc://foo/~bar
|
||||||
|
:_target psyc://bar/~baz
|
||||||
|
=_list_foo foo|bar|baz
|
||||||
|
:_tag sch1828hu3r2cm
|
||||||
|
|
||||||
|
=_foo bar baz
|
||||||
|
=_abc_def 11 ghi jkl
|
||||||
|
|
||||||
|
xq
|
||||||
|
=_list_bar 36 3 foo|3 bar|7 foo
|
||||||
|
bar|11 foo
|
||||||
|
bar
|
||||||
|
baz
|
||||||
|
:_foo_bar yay
|
||||||
|
_message_foo_bar
|
||||||
|
ohai there!
|
||||||
|
\o/
|
||||||
|
|
|
||||||
|
:_target psyc://foo.bar/~baz
|
||||||
|
|
||||||
|
:_test 123
|
||||||
|
_message_test
|
||||||
|
ohai!
|
||||||
|
|
|
34
src/tests/packets/test-3-list
Normal file
34
src/tests/packets/test-3-list
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
|
|
||||||
|
=_source psyc://foo/~bar
|
||||||
|
:_target psyc://bar/~baz
|
||||||
|
=_list_foo foo|bar|baz
|
||||||
|
:_tag sch1828hu3r2cm
|
||||||
|
|
||||||
|
?_test ignored
|
||||||
|
=_foo bar baz
|
||||||
|
=_abc_def 11 ghi jkl
|
||||||
|
|
||||||
|
xq
|
||||||
|
=_list_bar 36 3 foo|3 bar|7 foo
|
||||||
|
bar|11 foo
|
||||||
|
b|r
|
||||||
|
baz
|
||||||
|
:_foo_bar yay
|
||||||
|
=_amount_x 10
|
||||||
|
_message_foo_bar
|
||||||
|
ohai there!
|
||||||
|
\o/
|
||||||
|
|
|
||||||
|
:_target psyc://foo.bar/~baz
|
||||||
|
|
||||||
|
:_test 123
|
||||||
|
_message_test
|
||||||
|
ohai!
|
||||||
|
|
|
||||||
|
:_target psyc://foo.bar/~baz
|
||||||
|
|
||||||
|
+_list_foo yay
|
||||||
|
-_amount_x 2
|
||||||
|
_notice_test
|
||||||
|
test!
|
||||||
|
|
|
5
src/tests/packets/test-4-circuit
Normal file
5
src/tests/packets/test-4-circuit
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
|
||||||
|
:_list_understand_modules _state|_fragments|_context
|
||||||
|
|
||||||
|
_request_features
|
||||||
|
|
|
4
src/tests/packets/test-4-circuit-n
Normal file
4
src/tests/packets/test-4-circuit-n
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
:_list_understand_modules _state|_fragments|_context
|
||||||
|
|
||||||
|
_request_features
|
||||||
|
|
|
9
src/tests/packets/test-5-message-private
Normal file
9
src/tests/packets/test-5-message-private
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
|
|
||||||
|
:_source psyc://test.psyc.eu/~foo
|
||||||
|
:_target psyc://test.psyc.eu/~bar
|
||||||
|
:_tag f00b4rb4z
|
||||||
|
|
||||||
|
:_foo bar
|
||||||
|
_message_private
|
||||||
|
OHAI
|
||||||
|
|
|
9
src/tests/packets/test-6-message-private-remote
Normal file
9
src/tests/packets/test-6-message-private-remote
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
|
|
||||||
|
:_source psyc://test.psyc.eu/~foo
|
||||||
|
:_target psyc://test2.psyc.eu/~bar
|
||||||
|
:_tag f00b4rb4z
|
||||||
|
|
||||||
|
:_foo bar
|
||||||
|
_message_private
|
||||||
|
OHAI
|
||||||
|
|
|
|
@ -1,6 +0,0 @@
|
||||||
parser:
|
|
||||||
$(DIETLIB) cc -L../.. -I../../../include -DDEBUG -lpsyc testParser.c -lpsyc -o testParser
|
|
||||||
|
|
||||||
diet:
|
|
||||||
DIETLIB=/opt/diet/bin/diet make parser
|
|
||||||
|
|
|
@ -13,12 +13,15 @@ int main(int argc, char** argv)
|
||||||
return -1;
|
return -1;
|
||||||
index = read(file,(void*)buffer,sizeof(buffer));
|
index = read(file,(void*)buffer,sizeof(buffer));
|
||||||
|
|
||||||
|
write(1, ">> INPUT:\n", 10);
|
||||||
|
write(1, buffer, index);
|
||||||
|
write(1, ">> PARSE:\n", 10);
|
||||||
|
|
||||||
PSYC_State state;
|
PSYC_State state;
|
||||||
PSYC_initState(&state);
|
PSYC_initState(&state);
|
||||||
|
|
||||||
unsigned int cursor=0,tmp=0;
|
//unsigned int cursor=0,tmp=0;
|
||||||
unsigned long expectedBytes=0;
|
//unsigned long expectedBytes=0;
|
||||||
uint8_t modifier;
|
uint8_t modifier;
|
||||||
int ret;
|
int ret;
|
||||||
PSYC_Array name, value;
|
PSYC_Array name, value;
|
||||||
|
@ -26,27 +29,29 @@ int main(int argc, char** argv)
|
||||||
PSYC_nextBuffer(&state, PSYC_createArray(buffer, index));
|
PSYC_nextBuffer(&state, PSYC_createArray(buffer, index));
|
||||||
|
|
||||||
// try parsing that now
|
// try parsing that now
|
||||||
while(ret=PSYC_parse(&state, &name, &value, &modifier))
|
while((ret=PSYC_parse(&state, &modifier, &name, &value)))
|
||||||
{
|
{
|
||||||
switch (ret)
|
switch (ret)
|
||||||
{
|
{
|
||||||
case PSYC_ROUTING:
|
case PSYC_ROUTING:
|
||||||
case PSYC_ENTITY:
|
case PSYC_ENTITY:
|
||||||
write(0,&modifier,1);
|
write(1, &modifier, 1);
|
||||||
case PSYC_METHOD:
|
case PSYC_BODY:
|
||||||
write(0,name.ptr, name.length);
|
write(1, name.ptr, name.length);
|
||||||
write(0," = ", 3);
|
write(1, " = ", 3);
|
||||||
write(0,value.ptr, value.length);
|
write(1, value.ptr, value.length);
|
||||||
write(0,"\n", 1);
|
write(1, "\n", 1);
|
||||||
break;
|
break;
|
||||||
case PSYC_COMPLETE:
|
case PSYC_COMPLETE:
|
||||||
write(0, "Done parsing.\n", 15);
|
printf("Done parsing.\n");
|
||||||
continue;
|
continue;
|
||||||
|
case PSYC_INSUFFICIENT:
|
||||||
|
printf("Insufficient data.\n");
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
printf("Error while parsing: %i\n", ret);
|
printf("Error while parsing: %i\n", ret);
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue