/** @brief parse elements in a list passed through use_module @param[in] str: is the string to parse @param[out] newlist: rlist of elements found @retval 0: successful > 0: failed */ static int LaunchParsingMachine(const char *str, Rlist **newlist) { const char *s = str; state current_state = ST_OPENED; int ret; Buffer *buf = BufferNewWithCapacity(CF_MAXVARSIZE); assert(newlist); while (current_state != ST_CLOSED && *s) { switch(current_state) { case ST_ERROR: Log(LOG_LEVEL_ERR, "Parsing error : Malformed string"); ret = 1; goto clean; case ST_OPENED: if (CLASS_BLANK(*s)) { current_state = ST_OPENED; } else if (CLASS_BRA1(*s)) { current_state = ST_IO; } else if (CLASS_ANY0(*s)) { current_state = ST_ERROR; } s++; break; case ST_IO: if (CLASS_BLANK(*s)) { current_state = ST_IO; } else if (CLASS_START1(*s)) { BufferClear(buf); current_state = ST_ELM1; } else if (CLASS_START2(*s)) { BufferClear(buf); current_state = ST_ELM2; } else if (CLASS_ANY1(*s)) { current_state = ST_ERROR; } s++; break; case ST_ELM1: if (CLASS_END1(*s)) { RlistAppendScalar(newlist, BufferData(buf)); BufferClear(buf); current_state = ST_END1; } else if (CLASS_ANY2(*s)) { BufferAppendChar(buf, *s); current_state = ST_ELM1; } s++; break; case ST_ELM2: if (CLASS_END2(*s)) { RlistAppendScalar(newlist, BufferData(buf)); BufferClear(buf); current_state = ST_END2; } else if (CLASS_ANY3(*s)) { BufferAppendChar(buf, *s); current_state = ST_ELM2; } s++; break; case ST_END1: if (CLASS_SEP(*s)) { current_state = ST_SEP; } else if (CLASS_BRA2(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_BLANK(*s)) { current_state = ST_END1; } else if (CLASS_ANY4(*s)) { current_state = ST_ERROR; } s++; break; case ST_END2: if (CLASS_SEP(*s)) { current_state = ST_SEP; } else if (CLASS_BRA2(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_BLANK(*s)) { current_state = ST_END2; } else if (CLASS_ANY5(*s)) { current_state = ST_ERROR; } s++; break; case ST_SEP: if (CLASS_BLANK(*s)) { current_state = ST_SEP; } else if (CLASS_START1(*s)) { current_state = ST_ELM1; } else if (CLASS_START2(*s)) { current_state = ST_ELM2; } else if (CLASS_ANY6(*s)) { current_state = ST_ERROR; } s++; break; case ST_PRECLOSED: if (CLASS_BLANK(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_EOL(*s)) { current_state = ST_CLOSED; } else if (CLASS_ANY7(*s)) { current_state = ST_ERROR; } s++; break; default: Log(LOG_LEVEL_ERR, "Parsing logic error: unknown state"); ret = 2; goto clean; break; } } if (current_state != ST_CLOSED && current_state != ST_PRECLOSED ) { Log(LOG_LEVEL_ERR, "Parsing error : Malformed string (unexpected end of input)"); ret = 3; goto clean; } BufferDestroy(buf); return 0; clean: BufferDestroy(buf); RlistDestroy(*newlist); assert(ret != 0); return ret; }
/** @brief parse elements in a list passed through use_module @param[in] str: is the string to parse @param[out] newlist: rlist of elements found @retval 0: successful >0: failed */ static int LaunchParsingMachine(const char *str, Rlist **newlist) { const char *s = str; state current_state = ST_OPENED; int ret; char snatched[CF_MAXVARSIZE]; snatched[0]='\0'; char *sn = NULL; while (current_state != ST_CLOSED && *s) { switch(current_state) { case ST_ERROR: Log(LOG_LEVEL_ERR, "Parsing error : Malformed string"); ret = 1; goto clean; case ST_OPENED: if (CLASS_BLANK(*s)) { current_state = ST_OPENED; } else if (CLASS_BRA1(*s)) { current_state = ST_IO; } else if (CLASS_ANY0(*s)) { current_state = ST_ERROR; } s++; break; case ST_IO: if (CLASS_BLANK(*s)) { current_state = ST_IO; } else if (CLASS_START1(*s)) { sn=snatched; current_state = ST_ELM1; } else if (CLASS_START2(*s)) { sn=snatched; current_state = ST_ELM2; } else if (CLASS_ANY1(*s)) { current_state = ST_ERROR; } s++; break; case ST_ELM1: if (CLASS_END1(*s)) { if (sn==NULL) { sn=snatched; } *sn='\0'; RlistAppendScalar(newlist, snatched); sn=NULL; current_state = ST_END1; } else if (CLASS_ANY2(*s)) { if (sn==NULL) { sn=snatched; } *sn=*s; sn++; current_state = ST_ELM1; } s++; break; case ST_ELM2: if (CLASS_END2(*s)) { if (sn==NULL) { sn=snatched; } *sn='\0'; RlistAppendScalar(newlist, snatched); sn=NULL; current_state = ST_END2; } else if (CLASS_ANY3(*s)) { if (sn==NULL) { sn=snatched; } *sn=*s; sn++; current_state = ST_ELM2; } s++; break; case ST_END1: if (CLASS_SEP(*s)) { current_state = ST_SEP; } else if (CLASS_BRA2(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_BLANK(*s)) { current_state = ST_END1; } else if (CLASS_ANY4(*s)) { current_state = ST_ERROR; } s++; break; case ST_END2: if (CLASS_SEP(*s)) { current_state = ST_SEP; } else if (CLASS_BRA2(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_BLANK(*s)) { current_state = ST_END2; } else if (CLASS_ANY5(*s)) { current_state = ST_ERROR; } s++; break; case ST_SEP: if (CLASS_BLANK(*s)) { current_state = ST_SEP; } else if (CLASS_START1(*s)) { current_state = ST_ELM1; } else if (CLASS_START2(*s)) { current_state = ST_ELM2; } else if (CLASS_ANY6(*s)) { current_state = ST_ERROR; } s++; break; case ST_PRECLOSED: if (CLASS_BLANK(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_EOL(*s)) { current_state = ST_CLOSED; } else if (CLASS_ANY7(*s)) { current_state = ST_ERROR; } s++; break; default: Log(LOG_LEVEL_ERR, "Parsing logic error: unknown state"); ret = 2; goto clean; break; } } if (current_state != ST_CLOSED && current_state != ST_PRECLOSED ) { Log(LOG_LEVEL_ERR, "Parsing error : Malformed string (unexpected end of input)"); ret = 3; goto clean; } return 0; clean: if (newlist) { RlistDestroy(*newlist); } return ret; }