#include #include /* * this code is easiest to design as a state machine, see linecount-fsm.jpg */ typedef enum { EL, PC, EOLC, LNGC, ENDC, CL, CPC, CLNGC, CENDC } statelist; unsigned int line=0; statelist empty_line(char c) { if (c == '/') return PC; if (c == '\n') return EL; if (c == '\t') return EL; if (c == ' ') return EL; return CL; } statelist potential_comment(char c) { if (c == '/') return EOLC; if (c == '*') return LNGC; return EL; } statelist eol_comment(char c) { if (c == '\n') return EL; return EOLC; } statelist long_comment(char c) { if (c == '*') return ENDC; return LNGC; } statelist end_comment(char c) { if (c == '/') return EL; return LNGC; } statelist code_line(char c) { if (c == '\n') { ++line; return EL; } if (c == '/') return CPC; return CL; } statelist cpotential_comment(char c) { if (c == '/') { ++line; return EOLC; } if (c == '*') return CLNGC; return CL; } statelist clong_comment(char c) { if (c == '\n') { ++line; return LNGC; } if (c == '*') return CENDC; return CLNGC; } statelist cend_comment(char c) { if (c == '/') return CL; return CLNGC; } int main(int argc, char *argv[]) { FILE *fp; char c; statelist state = EL; line = 0; if (argc!=2) { printf("Usage '%s '\n",argv[0]); exit(1); } fp=fopen(argv[1],"r"); //read data from opened file if (fp == NULL) { printf("File '%s' could not be opened\n",argv[1]); exit(3); } while( (c=getc(fp)) != EOF ) // switch (state) { case EL: state = empty_line(c); break; case PC: state = potential_comment(c); break; case EOLC: state = eol_comment(c); break; case LNGC: state = long_comment(c); break; case ENDC: state = end_comment(c); break; case CL: state = code_line(c); break; case CPC: state = cpotential_comment(c); break; case CLNGC: state = clong_comment(c); break; case CENDC: state = cend_comment(c); break; default: printf("State machine is screwed\n"); exit(2); } /* * missed EOF transitions on state graph */ switch (state) { case CL: case CPC: case CLNGC: case CENDC: ++line; break; default: break; } fclose(fp); printf("LOC: %d\n",line); return 0; }