int fsm_main(const char *s) { const char *p; enum { S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12 } state; state = S0; for (p = s; *p != '\0'; p++) { switch (state) { case S0: /* start */ switch ((unsigned char) *p) { case '1': state = S1; break; case '0': state = S2; break; default: return -1; /* leaf */ } break; case S1: /* e.g. "1" */ switch ((unsigned char) *p) { case '0': case '1': case '2': state = S3; break; default: return -1; /* leaf */ } break; case S2: /* e.g. "0" */ switch ((unsigned char) *p) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': state = S3; break; default: return -1; /* leaf */ } break; case S3: /* e.g. "01" */ switch ((unsigned char) *p) { case ':': state = S4; break; default: return -1; /* leaf */ } break; case S4: /* e.g. "01:" */ switch ((unsigned char) *p) { case '0': case '1': case '2': case '3': case '4': case '5': state = S5; break; default: return -1; /* leaf */ } break; case S5: /* e.g. "01:0" */ switch ((unsigned char) *p) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': state = S6; break; default: return -1; /* leaf */ } break; case S6: /* e.g. "01:00" */ switch ((unsigned char) *p) { case ':': state = S7; break; default: return -1; /* leaf */ } break; case S7: /* e.g. "01:00:" */ switch ((unsigned char) *p) { case '0': case '1': case '2': case '3': case '4': case '5': state = S8; break; default: return -1; /* leaf */ } break; case S8: /* e.g. "01:00:0" */ switch ((unsigned char) *p) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': state = S9; break; default: return -1; /* leaf */ } break; case S9: /* e.g. "01:00:00" */ switch ((unsigned char) *p) { case ' ': state = S10; break; default: return -1; /* leaf */ } break; case S10: /* e.g. "01:00:00 " */ switch ((unsigned char) *p) { case 'A': case 'P': state = S11; break; default: return -1; /* leaf */ } break; case S11: /* e.g. "01:00:00 A" */ switch ((unsigned char) *p) { case 'M': state = S12; break; default: return -1; /* leaf */ } break; case S12: /* e.g. "01:00:00 AM" */ return -1; /* leaf */ default: ; /* unreached */ } } /* end states */ switch (state) { case S12: return 0x1; /* "(01|02|03|04|05|06|07|08|09|10|11|12):[0-5][0-9]:[0-5][0-9] (A|P)M" */ default: return -1; /* unexpected EOT */ } }