%% options copyright owner = Dirk Krause copyright year = 2011-2013 license = bsd %% header $* Function prototypes $* #ifdef __cplusplus extern "C" { #endif int test_identifier(char const *text); #ifdef __cplusplus } #endif %% module #include "dk3all.h" #include #include #if DK3_HAVE_UNISTD_H #include #endif /** Help text, never used, just for demonstration. */ static char const * const help_text[] = { $!text This help text is never shown, it is here just to demonstrate the use of the build-in $!text function. $!end }; /** Find start of text (first non-whitespace). @param t String to test. @return Pointer to start of text or NULL. */ static char * str_start(char *t) { char *back = NULL; char *ptr; ptr = t; while((*ptr) && (back == NULL)) { if(*ptr != ' ') { if(*ptr != '\t') { back = ptr; } } ptr++; } return back; } /** Remove trailing newline. @param t String to modify. */ static void str_delnl(char *t) { char *ptr; ptr = t; while(*ptr) { if(*ptr == '\r') *ptr = '\0'; if(*ptr == '\n') *ptr = '\0'; ptr++; } } /** Test whether a string is an identifier. @param test String to check. @return 1 on success (string is identifier), 0 on error. */ int test_identifier(char const *text) { int back = 0; char const *ptr; int state; int i; $? "+ test_identifier \"%s\"", TR_STR(text) idtest_reset(&state); ptr = text; while(*ptr) { $? ". processing character %c", *ptr if((*ptr >= 'A') && (*ptr <= 'Z')) { i = I_CHAR; } else { if((*ptr >= 'a') && (*ptr <= 'z')) { i = I_CHAR; } else { if((*ptr >= '0') && (*ptr <= '9')) { i = I_DIGIT; } else { if(*ptr == '_') { i = I_UNDER; } else { i = I_ANY; } } } } (void)idtest_step(&state, i); ptr++; } if(idtest_step(&state, I_END) == O_OK) { back = 1; } $? "- test_identifier %d", back return back; } /** Main function. @param argc Number of command line arguments. @param argv Command line arguments array. */ int main(int argc, char *argv[]) { char buffer[1024]; char *p1; int cc; $!trace-init test-ident.deb $? "+ main" do { $? ". start of loop" cc = 0; if(fgets(buffer, sizeof(buffer), stdin)) { p1 = str_start(buffer); if(p1) { $? ". text found \"%s\"", p1 cc = 1; str_delnl(p1); printf("%s %d\n", p1, test_identifier(p1)); } } } while(cc); $? "- main" $!trace-end exit(0); return 0; } %% state machine [options] name = idtest write header = no [states] S_START # No character found yet. S_OK # Everything ok so far. S_ERROR # An error occured. [inputs] I_CHAR # Character. I_UNDER # Underscore. I_DIGIT # Digit. I_ANY # Any other input character. I_END # End of input. [outputs] O_ERROR # Error occured. O_OK # Everything ok so far. [rules] * * S_ERROR O_ERROR * I_END S_START O_ERROR S_START I_CHAR S_OK O_OK S_START I_UNDER S_OK O_OK S_OK I_CHAR S_OK O_OK S_OK I_UNDER S_OK O_OK S_OK I_DIGIT S_OK O_OK S_OK I_END S_START O_OK