fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6.  
  7. #define MAX_TOKSIZE (8+1) // "SEQUENCE"
  8. #define MAX_PARAMS 4
  9. #define MAX_CSSTRSIZE (15+1)
  10.  
  11. #define MAX_STOKENS 5
  12. #define MAX_MTOKENS 6
  13. #define MAX_ETOKENS 7
  14.  
  15. /**
  16.  * Command codes as returned by the parser when a given command is identified
  17.  */
  18. typedef enum CommandSet {
  19. csUnknown = 0,
  20. csSceneGo = 1, // SCENE*GO
  21. csSceneTGo = 2, // SCENE*T*GO
  22. csSceneTLGo = 3, // SCENE*T*L*GO
  23. csSceneNu = 4, // SCENE*NU
  24. csSceneNd = 5, // SCENE*ND
  25. csSceneUp = 6, // SCENE*UP
  26. csSceneDn = 7, // SCENE*DN
  27. csSceneSt = 8, // SCENE*ST
  28. csSequenceGo = 9, // SEQUENCE*GO
  29. csSequenceSt = 10, // SEQUENCE*ST
  30. csSetSlaveChan = 11, // S*C*L*GO
  31. csSetPackChan = 12, // P*C*L*GO
  32. csSetPackDmx = 13, // P*D*L*GO
  33. csSetModuleChan = 14, // M*D*C*L*GO
  34. csSetButtonState = 15 // P*B*S*\r\n, P*B*S*GO
  35.  
  36. } CommandSet_t;
  37.  
  38. typedef struct ResType {
  39. CommandSet_t cs;
  40. int params[ MAX_PARAMS ];
  41. } ResType;
  42.  
  43. /* -------------------------------------------------------
  44.  *
  45.  * -------------------------------------------------------
  46.  */
  47. bool str_in_arrstr( const char *str, char *const *arrstr, const int arrlen )
  48. {
  49. register int i = 0;
  50. if ( !str || !arrstr )
  51. return false;
  52.  
  53. for (i=0; i < arrlen; i++)
  54. if ( !strcmp(str, arrstr[i]) )
  55. return true;
  56. return false;
  57. }
  58.  
  59. /* -------------------------------------------------------
  60.  *
  61.  * -------------------------------------------------------
  62.  */
  63. int advance_param( char *start, char *token )
  64. {
  65. int i = 0;
  66.  
  67. if ( !start || !token )
  68. return 0;
  69.  
  70. while ( *start && *start != ',' && isdigit( *start ) && i < MAX_TOKSIZE )
  71. {
  72. *token++ = *start++;
  73. i++;
  74. }
  75. *token = 0;
  76.  
  77. return i;
  78. }
  79.  
  80. /* -------------------------------------------------------
  81.  *
  82.  * -------------------------------------------------------
  83.  */
  84. int advance_token( char *start, char *token, char *csp )
  85. {
  86. int i = 0;
  87.  
  88. if ( !start || !token )
  89. return 0;
  90.  
  91. while ( *start && *start != ',' && !isdigit( *start ) && i < MAX_TOKSIZE )
  92. {
  93. *token++ = *csp++ = *start++;
  94. i++;
  95. }
  96. *token = 0;
  97.  
  98. return i;
  99. }
  100.  
  101. /* -------------------------------------------------------
  102.  *
  103.  * -------------------------------------------------------
  104.  */
  105. ResType getResult( const char *atstart, const int maxlen )
  106. {
  107. ResType ret = { csUnknown, {0} };
  108. char *stokens[ MAX_STOKENS ] = {"M", "P", "S", "START", "SEQUENCE"};
  109. char *mtokens[ MAX_MTOKENS ] = {"B", "C", "D", "L", "X", "T"};
  110. char *etokens[ MAX_ETOKENS ] = {"GO", "DN", "UP", "NU", "ND", "ST", "\r\n"};
  111. char token[ MAX_TOKSIZE ] = {'\0'};
  112. char csstr[ MAX_CSSTRSIZE ] = {'\0'};
  113. int i=0, j=0;
  114. char *cp = NULL, *csp = NULL;
  115. bool started = false, isstok = false, ismtok = false, isetok = false;
  116. int iparam = 0;
  117.  
  118. if ( !atstart || maxlen < 1 )
  119. goto ret_unknown;
  120.  
  121. cp = (char *)atstart;
  122. csp = csstr;
  123. started = false;
  124. i = j = iparam = 0;
  125. while ( i < maxlen && *cp != ',' )
  126. {
  127. /*
  128. * start reading the token
  129. */
  130.  
  131. j = advance_token( cp, token, csp );
  132. if ( j == 0 ) {
  133. puts("*** error: garbage found or invalid pointer used");
  134. goto ret_unknown; /* invalid token */
  135. }
  136.  
  137. isetok = str_in_arrstr(token, etokens, MAX_ETOKENS);
  138. if ( isetok )
  139. {
  140. if ( !started ) {
  141. puts("*** error: end of command that never started");
  142. goto ret_unknown;
  143. }
  144. printf( "\ntoken = %s\n", token );
  145. printf( "csstr = %s\n", csstr);
  146. return ret;
  147. }
  148.  
  149. ismtok = str_in_arrstr(token, mtokens, MAX_MTOKENS);
  150. if ( ismtok )
  151. {
  152. if ( !started ) {
  153. puts("*** error: mid of command that never started");
  154. goto ret_unknown;
  155. }
  156. }
  157. else
  158. {
  159. isstok = str_in_arrstr(token, stokens, MAX_STOKENS);
  160. if ( started && isstok ) {
  161. puts("*** error: invalid command (started twice)");
  162. goto ret_unknown;
  163. }
  164.  
  165. if ( !started && isstok )
  166. started = true;
  167. else if ( !isstok ) {
  168. puts("*** error: invalid token found");
  169. goto ret_unknown;
  170. }
  171. }
  172.  
  173. printf( "\ntoken = %s\n", token );
  174.  
  175. cp += j;
  176. csp += j;
  177. i += j;
  178.  
  179. /*
  180. * start reading the token's parameter
  181. */
  182.  
  183. j = advance_param( cp, token );
  184. if ( j == 0 ) {
  185. puts("*** error: invalid parameter or invalid pointer");
  186. goto ret_unknown; /* invalid parameter */
  187. }
  188.  
  189. ret.params[ iparam ] = atoi( token );
  190. printf( "param[ %d ] = %d\n", iparam, ret.params[ iparam ] );
  191. iparam++;
  192.  
  193. cp += j;
  194. i += j;
  195.  
  196. *csp++ = '*';
  197. printf( "csstr = %s\n", csstr );
  198.  
  199. }
  200.  
  201. /* ret.cs = hashmap[ csstr ] */
  202. return ret;
  203.  
  204. ret_unknown:
  205.  
  206. ret.cs = csUnknown;
  207. return ret;
  208. }
  209.  
  210. /* -------------------------------------------------------
  211.  *
  212.  * -------------------------------------------------------
  213.  */
  214.  
  215. int main( void )
  216. {
  217. char *inputdata = "S2C34L871GO,S32C89L100GO,S923C49L510GO";
  218. // char *inputdata = "S2C34L871GO";
  219. int inputlen = strlen( inputdata );
  220.  
  221. printf( "input : %s\n", inputdata );
  222. printf( "inputlen: %d\n", inputlen );
  223. getResult( inputdata, inputlen );
  224.  
  225. exit( EXIT_SUCCESS );
  226. }
  227.  
Success #stdin #stdout 0.01s 1720KB
stdin
Standard input is empty
stdout
input   : S2C34L871GO,S32C89L100GO,S923C49L510GO
inputlen: 38

token = S
param[ 0 ] = 2
csstr = S*

token = C
param[ 1 ] = 34
csstr = S*C*

token = L
param[ 2 ] = 871
csstr = S*C*L*

token = GO
csstr = S*C*L*GO