Exemplo n.º 1
0
static int
nexttoken(
    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 'n':
		    *p++ = '\n';
		    break;
		  case 'r':
		    *p++ = '\r';
		    break;
		  case 't':
		    *p++ = '\t';
		    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;
		    for (j = 0; j < 2; j++) {
			c = nextch(fp, lastch);
 			i <<= 4;
			if (c >= '0' && c <= '9') {
			    i += c - '0';
			} else if (c >= 'A' && c <= 'F') {
			    i += c - 'A' + 10;
			} else if (c >= 'a' && c <= 'f') {
			    i += c - 'a' + 10;
			} else {
			    putbackch(c, lastch);
			    i >>= 4;
			    break;
		        }
		    }
		    if (j == 0) {
		        token = ERROR;
		        goto string_error;
		    }
		    *p++ = (char)i;
		    break;
		  case EOF:
		    putbackch(c, lastch);
		    token = ERROR;
		    goto string_error;
		  default:
		    *p++ = c;
		    break;
		}
	    } else {
		*p++ = c;
	    }
	}
static int
nexttoken(FILE *fp, char **tokenbuf, int *lastch, size_t *buflen)
{
    int c;
    while ((c = nextch(fp, lastch)) == ' ' || c == '\t') {
    }

    int token;
    char *p;
    int i;
    size_t len = 0;
    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 (len >= *buflen - 1) {
                    *buflen += BUFSIZ;
                    *tokenbuf = (char *)realloc(*tokenbuf, *buflen);
                    p = *tokenbuf + len;
            }
            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++ = static_cast<char>(c);
                    len++;
                    break;
                case 'n':
                    *p++ = '\n';
                    len++;
                    break;
                case 'r':
                    *p++ = '\r';
                    len++;
                    break;
                case 't':
                    *p++ = '\t';
                    len++;
                    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 (int j = 0; j < 2 && c >= '0' && c <= '7'; j++) {
                        i <<= 3;
                        i += c - '0';
                        c = nextch(fp, lastch);
                    }
                    putbackch(c, lastch);
                    *p++ = static_cast<char>(i);
                    len++;
                    break;
                case 'X':
                case 'x':
                    i = 0;
                    int j;
                    for (j = 0; j < 2; j++) {
                        c = nextch(fp, lastch);
                        i <<= 4;
                        if (c >= '0' && c <= '9') {
                            i += c - '0';
                        } else if (c >= 'A' && c <= 'F') {
                            i += c - 'A' + 10;
                        } else if (c >= 'a' && c <= 'f') {
                            i += c - 'a' + 10;
                        } else {
                            putbackch(c, lastch);
                            i >>= 4;
                            break;
                        }
                    }
                    if (j == 0) {
                        token = ERROR;
                        goto string_error;
                    }
                    *p++ = static_cast<char>(i);
                    len++;
                    break;
                case EOF:
                    putbackch(c, lastch);
                    token = ERROR;
                    goto string_error;
                default:
                    *p++ = static_cast<char>(c);
                    len++;
                    break;
                }
            } else {
                *p++ = static_cast<char>(c);
                len++;
            }
        }