CHECKBUF();
nexttoken(fp, tokenbuf, lastch)    FILE *fp;    char *tokenbuf;    int *lastch;{    int c;    int token;    char *p;    int i, j;    while ((c = nextch(fp, lastch)) == ' ' || c == '\t') {    }    switch (c) {      case EOF:	token = ENDOFFILE;	break;      case '\n':	token = ENDOFLINE;	break;      case '<':	token = LESS;	break;      case '>':	token = GREATER;	break;      case ':':	token = COLON;	break;      case '!':	token = EXCLAM;	break;      case '~':	token = TILDE;	break;      case '"':	p = tokenbuf;	while ((c = nextch(fp, lastch)) != '"') {	    if (c == '\n' || c == EOF) {		putbackch(c, lastch);		token = ERROR;		goto string_error;	    } else if (c == '\\') {		c = nextch(fp, lastch);		switch (c) {		  case '\\':		  case '"':		    *p++ = c;		    break;		  case '0':		  case '1':		  case '2':		  case '3':		  case '4':		  case '5':		  case '6':		  case '7':		    i = c - '0';		    c = nextch(fp, lastch);		    for (j = 0; j < 2 && c >= '0' && c <= '7'; j++) {			i <<= 3;			i += c - '0';			c = nextch(fp, lastch);		    }		    putbackch(c, lastch);		    *p++ = (char)i;		    break;		  case 'X':		  case 'x':		    i = 0;		    c = nextch(fp, lastch);#define ishexch(c) (((c) >= '0' && (c) <= '9') || \		    ((c) >= 'A' && (c) <= 'F') || \		    ((c) >= 'a' && (c) <= 'f'))		    for (j = 0; j < 2 && ishexch(c); j++) {			i <<= 4;			if (c >= '0' && c <= '9') {			    i += c - '0';			} else if (c >= 'A' && c <= 'F') {			    i += c - 'A' + 10;			} else {			    i += c - 'a' + 10;			}			c = nextch(fp, lastch);		    }		    if (j == 0) {		        token = ERROR;		        goto string_error;		    }		    putbackch(c, lastch);		    *p++ = (char)i;#undef ishexch		    break;		  case '\n':		  case EOF:		    putbackch(c, lastch);		    token = ERROR;		    goto string_error;		  default:		    *p++ = c;		    break;		}	    } else {		*p++ = c;	    }	}	*p = '\0';	token = STRING;	break;      case '#':	while ((c = nextch(fp, lastch)) != '\n' && c != EOF) {	}	if (c == '\n') {	    token = ENDOFLINE;	} else {	    token = ENDOFFILE;	}	break;      default:	if (isalnum(c) || c == '_' || c == '-') {	    p = tokenbuf;	    *p++ = c;	    c = nextch(fp, lastch);	    while (isalnum(c) || c == '_' || c == '-') {		*p++ = c;		c = nextch(fp, lastch);	    }	    *p = '\0';	    putbackch(c, lastch);	    token = KEY;	} else {	    token = ERROR;	}	break;    }string_error:    return(token);}