#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#define MAX_TOKSIZE (8+1) // "SEQUENCE"
#define MAX_PARAMS 4
#define MAX_CSSTRSIZE (15+1)
#define MAX_STOKENS 5
#define MAX_MTOKENS 6
#define MAX_ETOKENS 7
/**
* Command codes as returned by the parser when a given command is identified
*/
typedef enum CommandSet {
csUnknown = 0,
csSceneGo = 1, // SCENE*GO
csSceneTGo = 2, // SCENE*T*GO
csSceneTLGo = 3, // SCENE*T*L*GO
csSceneNu = 4, // SCENE*NU
csSceneNd = 5, // SCENE*ND
csSceneUp = 6, // SCENE*UP
csSceneDn = 7, // SCENE*DN
csSceneSt = 8, // SCENE*ST
csSequenceGo = 9, // SEQUENCE*GO
csSequenceSt = 10, // SEQUENCE*ST
csSetSlaveChan = 11, // S*C*L*GO
csSetPackChan = 12, // P*C*L*GO
csSetPackDmx = 13, // P*D*L*GO
csSetModuleChan = 14, // M*D*C*L*GO
csSetButtonState = 15 // P*B*S*\r\n, P*B*S*GO
} CommandSet_t;
typedef struct ResType {
CommandSet_t cs;
int params[ MAX_PARAMS ];
} ResType;
/* -------------------------------------------------------
*
* -------------------------------------------------------
*/
bool str_in_arrstr( const char *str, char *const *arrstr, const int arrlen )
{
register int i = 0;
if ( !str || !arrstr )
return false;
for (i=0; i < arrlen; i++)
if ( !strcmp(str
, arrstr
[i
]) ) return true;
return false;
}
/* -------------------------------------------------------
*
* -------------------------------------------------------
*/
int advance_param( char *start, char *token )
{
int i = 0;
if ( !start || !token )
return 0;
while ( *start
&& *start
!= ',' && isdigit( *start
) && i
< MAX_TOKSIZE
) {
*token++ = *start++;
i++;
}
*token = 0;
return i;
}
/* -------------------------------------------------------
*
* -------------------------------------------------------
*/
int advance_token( char *start, char *token, char *csp )
{
int i = 0;
if ( !start || !token )
return 0;
while ( *start
&& *start
!= ',' && !isdigit( *start
) && i
< MAX_TOKSIZE
) {
*token++ = *csp++ = *start++;
i++;
}
*token = 0;
return i;
}
/* -------------------------------------------------------
*
* -------------------------------------------------------
*/
ResType getResult( const char *atstart, const int maxlen )
{
ResType ret = { csUnknown, {0} };
char *stokens[ MAX_STOKENS ] = {"M", "P", "S", "START", "SEQUENCE"};
char *mtokens[ MAX_MTOKENS ] = {"B", "C", "D", "L", "X", "T"};
char *etokens[ MAX_ETOKENS ] = {"GO", "DN", "UP", "NU", "ND", "ST", "\r\n"};
char token[ MAX_TOKSIZE ] = {'\0'};
char csstr[ MAX_CSSTRSIZE ] = {'\0'};
int i=0, j=0;
char *cp = NULL, *csp = NULL;
bool started = false, isstok = false, ismtok = false, isetok = false;
int iparam = 0;
if ( !atstart || maxlen < 1 )
goto ret_unknown;
cp = (char *)atstart;
csp = csstr;
started = false;
i = j = iparam = 0;
while ( i < maxlen && *cp != ',' )
{
/*
* start reading the token
*/
j = advance_token( cp, token, csp );
if ( j == 0 ) {
puts("*** error: garbage found or invalid pointer used"); goto ret_unknown; /* invalid token */
}
isetok = str_in_arrstr(token, etokens, MAX_ETOKENS);
if ( isetok )
{
if ( !started ) {
puts("*** error: end of command that never started"); goto ret_unknown;
}
printf( "\ntoken = %s\n", token
); printf( "csstr = %s\n", csstr
); return ret;
}
ismtok = str_in_arrstr(token, mtokens, MAX_MTOKENS);
if ( ismtok )
{
if ( !started ) {
puts("*** error: mid of command that never started"); goto ret_unknown;
}
}
else
{
isstok = str_in_arrstr(token, stokens, MAX_STOKENS);
if ( started && isstok ) {
puts("*** error: invalid command (started twice)"); goto ret_unknown;
}
if ( !started && isstok )
started = true;
else if ( !isstok ) {
puts("*** error: invalid token found"); goto ret_unknown;
}
}
printf( "\ntoken = %s\n", token
);
cp += j;
csp += j;
i += j;
/*
* start reading the token's parameter
*/
j = advance_param( cp, token );
if ( j == 0 ) {
puts("*** error: invalid parameter or invalid pointer"); goto ret_unknown; /* invalid parameter */
}
ret.
params[ iparam
] = atoi( token
); printf( "param[ %d ] = %d\n", iparam
, ret.
params[ iparam
] ); iparam++;
cp += j;
i += j;
*csp++ = '*';
printf( "csstr = %s\n", csstr
);
}
/* ret.cs = hashmap[ csstr ] */
return ret;
ret_unknown:
ret.cs = csUnknown;
return ret;
}
/* -------------------------------------------------------
*
* -------------------------------------------------------
*/
int main( void )
{
char *inputdata = "S2C34L871GO,S32C89L100GO,S923C49L510GO";
// char *inputdata = "S2C34L871GO";
int inputlen
= strlen( inputdata
);
printf( "input : %s\n", inputdata
); printf( "inputlen: %d\n", inputlen
); getResult( inputdata, inputlen );
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGJvb2wuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KCiNkZWZpbmUgTUFYX1RPS1NJWkUJKDgrMSkJCQkvLyAiU0VRVUVOQ0UiCiNkZWZpbmUgTUFYX1BBUkFNUwk0CiNkZWZpbmUgTUFYX0NTU1RSU0laRQkoMTUrMSkKCiNkZWZpbmUgTUFYX1NUT0tFTlMJNQojZGVmaW5lIE1BWF9NVE9LRU5TCTYKI2RlZmluZSBNQVhfRVRPS0VOUwk3CgovKioKICogIENvbW1hbmQgY29kZXMgYXMgcmV0dXJuZWQgYnkgdGhlIHBhcnNlciB3aGVuIGEgZ2l2ZW4gY29tbWFuZCBpcyBpZGVudGlmaWVkCiAqLwp0eXBlZGVmIGVudW0gQ29tbWFuZFNldCB7CiAgICAgICAgY3NVbmtub3duCT0gMCwKICAgICAgICBjc1NjZW5lR28JPSAxLAkJCS8vIFNDRU5FKkdPCiAgICAgICAgY3NTY2VuZVRHbwk9IDIsCQkJLy8gU0NFTkUqVCpHTwogICAgICAgIGNzU2NlbmVUTEdvCT0gMywJCQkvLyBTQ0VORSpUKkwqR08KICAgICAgICBjc1NjZW5lTnUJPSA0LAkJCS8vIFNDRU5FKk5VCiAgICAgICAgY3NTY2VuZU5kCT0gNSwJCQkvLyBTQ0VORSpORAogICAgICAgIGNzU2NlbmVVcAk9IDYsCQkJLy8gU0NFTkUqVVAKICAgICAgICBjc1NjZW5lRG4JPSA3LAkJCS8vIFNDRU5FKkROCiAgICAgICAgY3NTY2VuZVN0CT0gOCwJCQkvLyBTQ0VORSpTVAogICAgICAgIGNzU2VxdWVuY2VHbwk9IDksCQkJLy8gU0VRVUVOQ0UqR08KICAgICAgICBjc1NlcXVlbmNlU3QJPSAxMCwJCQkvLyBTRVFVRU5DRSpTVAogICAgICAgIGNzU2V0U2xhdmVDaGFuCT0gMTEsCQkJLy8gUypDKkwqR08KICAgICAgICBjc1NldFBhY2tDaGFuCT0gMTIsCQkJLy8gUCpDKkwqR08KICAgICAgICBjc1NldFBhY2tEbXgJPSAxMywJCQkvLyBQKkQqTCpHTwogICAgICAgIGNzU2V0TW9kdWxlQ2hhbgk9IDE0LAkJCS8vIE0qRCpDKkwqR08KICAgICAgICBjc1NldEJ1dHRvblN0YXRlID0gMTUJCQkvLyBQKkIqUypcclxuLCBQKkIqUypHTwoKfSBDb21tYW5kU2V0X3Q7Cgp0eXBlZGVmIHN0cnVjdCBSZXNUeXBlIHsKCUNvbW1hbmRTZXRfdAljczsKCWludAkJcGFyYW1zWyBNQVhfUEFSQU1TIF07Cn0gUmVzVHlwZTsKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICoKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KYm9vbCBzdHJfaW5fYXJyc3RyKCBjb25zdCBjaGFyICpzdHIsIGNoYXIgKmNvbnN0ICphcnJzdHIsIGNvbnN0IGludCBhcnJsZW4gKQp7CglyZWdpc3RlciBpbnQgaSA9IDA7CglpZiAoICFzdHIgfHwgIWFycnN0ciApCgkJcmV0dXJuIGZhbHNlOwoKCWZvciAoaT0wOyBpIDwgYXJybGVuOyBpKyspCgkJaWYgKCAhc3RyY21wKHN0ciwgYXJyc3RyW2ldKSApCgkJCXJldHVybiB0cnVlOwoJcmV0dXJuIGZhbHNlOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCmludCBhZHZhbmNlX3BhcmFtKCBjaGFyICpzdGFydCwgY2hhciAqdG9rZW4gKQp7CglpbnQgaSA9IDA7CgoJaWYgKCAhc3RhcnQgfHwgIXRva2VuICkKCQlyZXR1cm4gMDsKCgl3aGlsZSAoICpzdGFydCAmJiAqc3RhcnQgIT0gJywnICYmIGlzZGlnaXQoICpzdGFydCApICYmIGkgPCBNQVhfVE9LU0laRSApCgl7CgkJKnRva2VuKysgPSAqc3RhcnQrKzsKCQlpKys7Cgl9CgkqdG9rZW4gPSAwOwoKCXJldHVybiBpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCmludCBhZHZhbmNlX3Rva2VuKCBjaGFyICpzdGFydCwgY2hhciAqdG9rZW4sIGNoYXIgKmNzcCApCnsKCWludCBpID0gMDsKCglpZiAoICFzdGFydCB8fCAhdG9rZW4gKQoJCXJldHVybiAwOwoKCXdoaWxlICggKnN0YXJ0ICYmICpzdGFydCAhPSAnLCcgJiYgIWlzZGlnaXQoICpzdGFydCApICYmIGkgPCBNQVhfVE9LU0laRSApCgl7CgkJKnRva2VuKysgPSAqY3NwKysgPSAqc3RhcnQrKzsKCQlpKys7Cgl9CgkqdG9rZW4gPSAwOwoKCXJldHVybiBpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovClJlc1R5cGUgZ2V0UmVzdWx0KCBjb25zdCBjaGFyICphdHN0YXJ0LCBjb25zdCBpbnQgbWF4bGVuICkKewoJUmVzVHlwZSByZXQgPSB7IGNzVW5rbm93biwgezB9IH07CgljaGFyCSpzdG9rZW5zWyBNQVhfU1RPS0VOUyBdID0geyJNIiwgIlAiLCAiUyIsICJTVEFSVCIsICJTRVFVRU5DRSJ9OwoJY2hhcgkqbXRva2Vuc1sgTUFYX01UT0tFTlMgXSA9IHsiQiIsICJDIiwgIkQiLCAiTCIsICJYIiwgIlQifTsKCWNoYXIJKmV0b2tlbnNbIE1BWF9FVE9LRU5TIF0gPSB7IkdPIiwgIkROIiwgIlVQIiwgIk5VIiwgIk5EIiwgIlNUIiwgIlxyXG4ifTsKCWNoYXIJdG9rZW5bIE1BWF9UT0tTSVpFIF0gICAgPSB7J1wwJ307CgljaGFyCWNzc3RyWyBNQVhfQ1NTVFJTSVpFIF0gID0geydcMCd9OwoJaW50CWk9MCwgaj0wOwoJY2hhcgkqY3AgPSBOVUxMLCAqY3NwID0gTlVMTDsKCWJvb2wJc3RhcnRlZCA9IGZhbHNlLCBpc3N0b2sgPSBmYWxzZSwgaXNtdG9rID0gZmFsc2UsIGlzZXRvayA9IGZhbHNlOwoJaW50CWlwYXJhbSA9IDA7CgoJaWYgKCAhYXRzdGFydCB8fCBtYXhsZW4gPCAxICkKCQlnb3RvIHJldF91bmtub3duOwoKCWNwID0gKGNoYXIgKilhdHN0YXJ0OwoJY3NwID0gY3NzdHI7CglzdGFydGVkID0gZmFsc2U7CglpID0gaiA9IGlwYXJhbSA9IDA7Cgl3aGlsZSAoIGkgPCBtYXhsZW4gJiYgKmNwICE9ICcsJyApCgl7CgkJLyoKCQkgKiBzdGFydCByZWFkaW5nIHRoZSB0b2tlbgoJCSAqLwoKCQlqID0gYWR2YW5jZV90b2tlbiggY3AsIHRva2VuLCBjc3AgKTsgCgkJaWYgKCBqID09IDAgKSB7CgkJCXB1dHMoIioqKiBlcnJvcjogZ2FyYmFnZSBmb3VuZCBvciBpbnZhbGlkIHBvaW50ZXIgdXNlZCIpOwoJCQlnb3RvIHJldF91bmtub3duOyAgICAgICAvKiBpbnZhbGlkIHRva2VuICovCgkJfQoKCQlpc2V0b2sgPSBzdHJfaW5fYXJyc3RyKHRva2VuLCBldG9rZW5zLCBNQVhfRVRPS0VOUyk7CgkJaWYgKCBpc2V0b2sgKQoJCXsKCQkJaWYgKCAhc3RhcnRlZCApIHsKCQkJCXB1dHMoIioqKiBlcnJvcjogZW5kIG9mIGNvbW1hbmQgdGhhdCBuZXZlciBzdGFydGVkIik7CgkJCQlnb3RvIHJldF91bmtub3duOwoJCQl9CgkJCXByaW50ZiggIlxudG9rZW4gPSAlc1xuIiwgdG9rZW4gKTsKCQkJcHJpbnRmKCAiY3NzdHIgPSAlc1xuIiwgY3NzdHIpOwoJCQlyZXR1cm4gcmV0OwoJCX0KCgkJaXNtdG9rID0gc3RyX2luX2FycnN0cih0b2tlbiwgbXRva2VucywgTUFYX01UT0tFTlMpOwoJCWlmICggaXNtdG9rICkKCQl7CgkJCWlmICggIXN0YXJ0ZWQgKSB7CgkJCQlwdXRzKCIqKiogZXJyb3I6IG1pZCBvZiBjb21tYW5kIHRoYXQgbmV2ZXIgc3RhcnRlZCIpOwoJCQkJZ290byByZXRfdW5rbm93bjsKCQkJfQoJCX0KCQllbHNlCgkJewoJCQlpc3N0b2sgPSBzdHJfaW5fYXJyc3RyKHRva2VuLCBzdG9rZW5zLCBNQVhfU1RPS0VOUyk7CgkJCWlmICggc3RhcnRlZCAmJiBpc3N0b2sgKSB7CgkJCQlwdXRzKCIqKiogZXJyb3I6IGludmFsaWQgY29tbWFuZCAoc3RhcnRlZCB0d2ljZSkiKTsKCQkJCWdvdG8gcmV0X3Vua25vd247CgkJCX0KCgkJCWlmICggIXN0YXJ0ZWQgJiYgaXNzdG9rICkKCQkJCXN0YXJ0ZWQgPSB0cnVlOwoJCQllbHNlIGlmICggIWlzc3RvayApIHsKCQkJCXB1dHMoIioqKiBlcnJvcjogaW52YWxpZCB0b2tlbiBmb3VuZCIpOwoJCQkJZ290byByZXRfdW5rbm93bjsKCQkJfQoJCX0KCgkJcHJpbnRmKCAiXG50b2tlbiA9ICVzXG4iLCB0b2tlbiApOwoKCQljcCArPSBqOwoJCWNzcCArPSBqOwoJCWkgKz0gajsKCgkJLyoKCQkgKiBzdGFydCByZWFkaW5nIHRoZSB0b2tlbidzIHBhcmFtZXRlcgoJCSAqLwoKCQlqID0gYWR2YW5jZV9wYXJhbSggY3AsIHRva2VuICk7CgkJaWYgKCBqID09IDAgKSB7CgkJCXB1dHMoIioqKiBlcnJvcjogaW52YWxpZCBwYXJhbWV0ZXIgb3IgaW52YWxpZCBwb2ludGVyIik7CgkJCWdvdG8gcmV0X3Vua25vd247ICAgICAgIC8qIGludmFsaWQgcGFyYW1ldGVyICovCgkJfQoKCQlyZXQucGFyYW1zWyBpcGFyYW0gXSA9IGF0b2koIHRva2VuICk7CgkJcHJpbnRmKCAicGFyYW1bICVkIF0gPSAlZFxuIiwgaXBhcmFtLCByZXQucGFyYW1zWyBpcGFyYW0gXSApOwoJCWlwYXJhbSsrOwoKCQljcCArPSBqOwoJCWkgKz0gajsKCgkJKmNzcCsrID0gJyonOwoJCXByaW50ZiggImNzc3RyID0gJXNcbiIsIGNzc3RyICk7CgoJIH0KCgkvKiByZXQuY3MgPSBoYXNobWFwWyBjc3N0ciBdICovCglyZXR1cm4gcmV0OwoKcmV0X3Vua25vd246CgoJcmV0LmNzID0gY3NVbmtub3duOwoJcmV0dXJuIHJldDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKaW50IG1haW4oIHZvaWQgKQp7CgljaGFyICppbnB1dGRhdGEgICAgICAgICA9ICJTMkMzNEw4NzFHTyxTMzJDODlMMTAwR08sUzkyM0M0OUw1MTBHTyI7Ci8vCWNoYXIgKmlucHV0ZGF0YSAgICAgICAgID0gIlMyQzM0TDg3MUdPIjsKCWludCBpbnB1dGxlbiAgICAgICAgICAgID0gc3RybGVuKCBpbnB1dGRhdGEgKTsKCglwcmludGYoICJpbnB1dCAgIDogJXNcbiIsIGlucHV0ZGF0YSApOwoJcHJpbnRmKCAiaW5wdXRsZW46ICVkXG4iLCBpbnB1dGxlbiApOwoJZ2V0UmVzdWx0KCBpbnB1dGRhdGEsIGlucHV0bGVuICk7CgoJZXhpdCggRVhJVF9TVUNDRVNTICk7Cn0K