예제 #1
0
/**
 @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;
}
예제 #2
0
파일: rlist.c 프로젝트: cduclos/core
/**
 @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;
}