/*
* HTML syntax checker
*/
#include
#include
/* Start tags are stacked using "tag" structures: */
struct tag {
struct tag *prev; /* pointer to previous start tag */
char name[11];
} *tail = NULL, *newtag;
int caseno = 0; /* which test case are we processing? */
int lineno; /* line being processed */
int nlines; /* # of lines in this case */
void cleanup() /* clear the stack */
{
struct tag *junk;
while (tail != NULL) {
junk = tail->prev;
free(tail);
tail = junk;
}
}
/* Skip through n end of line characters */
void skiplines(int n)
{
int c;
while (n) if ((c = getchar()) == '\n') n--;
}
int gettag()
{
char tagname[11]; /* name of the current tag */
int nchar; /* # of characters in the tag */
int endtag = 0; /* 0 = begin, 1 = end */
int c; /* # of input characters */
nchar = 0;
c = getchar();
if (c == '/') endtag = 1;
else ungetc(c,stdin);
for(;;) {
c = getchar();
if (!isupper(c)) break; /* end of tag? */
if (nchar == 10) {
printf("line %d: too many/few characters in tag name.\n", lineno);
skiplines(nlines-lineno+1);
return 0;
} else {
tagname[nchar++] = c;
}
}
if (c != '>') {
printf("line %d: bad character in tag name.\n", lineno);
if (c == '\n') lineno++;
skiplines(nlines-lineno+1);
return 0;
}
tagname[nchar] = '\0';
if (strlen(tagname) == 0) {
printf("line %d: too many/few characters in tag name.\n", lineno);
skiplines(nlines-lineno+1);
return 0;
}
/* printf("Tag: "); if (endtag) putchar('/'); printf("%s\n", tagname); */
if (!endtag) { /* a new tag */
newtag = (struct tag *)malloc(sizeof(struct tag));
newtag->prev = tail;
strcpy(newtag->name,tagname);
tail = newtag;
} else { /* end of a tagged region */
if (tail != NULL && !strcmp(tail->name,tagname)) { /* okay */
struct tag *temp;
temp = tail;
tail = tail->prev;
free(temp);
} else {
if (tail != NULL)
printf("line %d: expected %s>\n", lineno, tail->name);
else printf("line %d: no matching begin tag.\n", lineno);
skiplines(nlines-lineno+1);
return 0;
}
}
return 1;
}
int process()
{
int c;
lineno = 1;
while (lineno <= nlines) {
c = getchar();
if (c == '\n') lineno++;
else if (c == '<') {
if (!gettag()) return lineno; /* bad tag */
}
}
return 0;
}
main()
{
for(;;) {
if (scanf("%d",&nlines) != 1) {
printf("Unexpected end of file!\n");
exit(1);
}
if (nlines == 0) exit(0); /* end of input */
while (getchar() != '\n') ; /* skip through end of line */
/* NOT REALLY NEEDED? */
printf("Test Case %d\n", ++caseno);
if (!process()) printf("OK\n");
cleanup();
putchar('\n');
}
}