commit 431e32de9b41c230b0791fb9f2f293859d189e59 from: rsc date: Fri Sep 30 17:45:40 2005 UTC More & names and numbers. commit - 01a1c31a7d99fd24ba134ddc33fb3df95a668f3a commit + 431e32de9b41c230b0791fb9f2f293859d189e59 blob - 81391f96923142bba020e315db4f5ef56e60d2b8 blob + cc368ac2c5e367c1de93b60c0e00a807ea8581fc --- src/libhtml/lex.c +++ src/libhtml/lex.c @@ -333,7 +333,9 @@ AsciiInt _chartab[] = { {"kappa", 954}, {"lambda", 955}, {"laquo", 171}, + {"ldquo", 8220}, {"ldots", 8230}, + {"lsquo", 8216}, {"lt", 60}, {"macr", 175}, {"mdash", 8212}, @@ -364,8 +366,10 @@ AsciiInt _chartab[] = { {"quad", 8193}, {"quot", 34}, {"raquo", 187}, + {"rdquo", 8221}, {"reg", 174}, {"rho", 961}, + {"rsquo", 8217}, {"sect", 167}, {"shy", 173}, {"sigma", 963}, @@ -492,9 +496,9 @@ _gettoks(uchar* data, int datalen, int chset, int mtyp ai = 0; if(dbglex) fprint(2, "_gettoks starts, ts.i=%d, ts.edata=%d\n", ts->i, ts->edata); - if(ts->mtype == TextHtml) { - for(;;) { - if(ai == alen) { + if(ts->mtype == TextHtml){ + for(;;){ + if(ai == alen){ a = (Token*)erealloc(a, (alen+ToksChunk)*sizeof(Token)); alen += ToksChunk; } @@ -502,9 +506,9 @@ _gettoks(uchar* data, int datalen, int chset, int mtyp c = getchar(ts); if(c < 0) break; - if(c == '<') { + if(c == '<'){ tag = gettag(ts, starti, a, &ai); - if(tag == Tscript) { + if(tag == Tscript){ // special rules for getting Data after.... starti = ts->i; c = getchar(ts); @@ -521,8 +525,8 @@ _gettoks(uchar* data, int datalen, int chset, int mtyp } else { // plain text (non-html) tokens - for(;;) { - if(ai == alen) { + for(;;){ + if(ai == alen){ a = (Token*)erealloc(a, (alen+ToksChunk)*sizeof(Token)); alen += ToksChunk; } @@ -560,14 +564,14 @@ getplaindata(TokenSource* ts, Token* a, int* pai) s = nil; j = 0; starti = ts->i; - for(c = getchar(ts); c >= 0; c = getchar(ts)) { - if(c < ' ') { - if(isspace(c)) { - if(c == '\r') { + for(c = getchar(ts); c >= 0; c = getchar(ts)){ + if(c < ' '){ + if(isspace(c)){ + if(c == '\r'){ // ignore it unless no following '\n', // in which case treat it like '\n' c = getchar(ts); - if(c != '\n') { + if(c != '\n'){ if(c >= 0) ungetchar(ts, c); c = '\n'; @@ -577,9 +581,9 @@ getplaindata(TokenSource* ts, Token* a, int* pai) else c = 0; } - if(c != 0) { + if(c != 0){ buf[j++] = c; - if(j == sizeof(buf)-1) { + if(j == sizeof(buf)-1){ s = buftostr(s, buf, j); j = 0; } @@ -627,19 +631,19 @@ getdata(TokenSource* ts, int firstc, int starti, Token s = nil; j = 0; c = firstc; - while(c >= 0) { - if(c == '&') { + while(c >= 0){ + if(c == '&'){ c = ampersand(ts); if(c < 0) break; } - else if(c < ' ') { - if(isspace(c)) { - if(c == '\r') { + else if(c < ' '){ + if(isspace(c)){ + if(c == '\r'){ // ignore it unless no following '\n', // in which case treat it like '\n' c = getchar(ts); - if(c != '\n') { + if(c != '\n'){ if(c >= 0) ungetchar(ts, c); c = '\n'; @@ -652,13 +656,13 @@ getdata(TokenSource* ts, int firstc, int starti, Token c = 0; } } - else if(c == '<') { + else if(c == '<'){ ungetchar(ts, c); break; } - if(c != 0) { + if(c != 0){ buf[j++] = c; - if(j == BIGBUFSIZE-1) { + if(j == BIGBUFSIZE-1){ s = buftostr(s, buf, j); j = 0; } @@ -696,12 +700,12 @@ getscriptdata(TokenSource* ts, int firstc, int starti, tstarti = starti; c = firstc; done = 0; - while(c >= 0) { - if(c == '<') { + while(c >= 0){ + if(c == '<'){ // other browsers ignore stuff to end of line after i; c = getchar(ts); - if(c == '!') { + if(c == '!'){ while(c >= 0 && c != '\n' && c != '\r') c = getchar(ts); if(c == '\r') @@ -709,7 +713,7 @@ getscriptdata(TokenSource* ts, int firstc, int starti, if(c == '\n') c = getchar(ts); } - else if(c >= 0) { + else if(c >= 0){ backup(ts, savei); tag = gettag(ts, tstarti, a, pai); if(tag == -1) @@ -717,7 +721,7 @@ getscriptdata(TokenSource* ts, int firstc, int starti, if(tag != Comment) (*pai)--; backup(ts, tstarti); - if(tag == Tscript + RBRA) { + if(tag == Tscript + RBRA){ done = 1; break; } @@ -727,9 +731,9 @@ getscriptdata(TokenSource* ts, int firstc, int starti, } if(c < 0) break; - if(c != 0) { + if(c != 0){ buf[j++] = c; - if(j == BIGBUFSIZE-1) { + if(j == BIGBUFSIZE-1){ s = buftostr(s, buf, j); j = 0; } @@ -737,7 +741,7 @@ getscriptdata(TokenSource* ts, int firstc, int starti, tstarti = ts->i; c = getchar(ts); } - if(done || ts->i == ts->edata) { + if(done || ts->i == ts->edata){ s = buftostr(s, buf, j); tok = &a[(*pai)++]; tok->tag = Data; @@ -784,15 +788,15 @@ gettag(TokenSource* ts, int starti, Token* a, int* pai tok->attr = nil; tok->starti = starti; c = getchar(ts); - if(c == '/') { + if(c == '/'){ rbra = RBRA; c = getchar(ts); } if(c < 0) goto eob_done; - if(c >= 256 || !isalpha(c)) { + if(c >= 256 || !isalpha(c)){ // not a tag - if(c == '!') { + if(c == '!'){ ans = comment(ts); if(ans != -1) return ans; @@ -809,7 +813,7 @@ gettag(TokenSource* ts, int starti, Token* a, int* pai // c starts a tagname buf[0] = c; i = 1; - while(1) { + for(;;){ c = getchar(ts); if(c < 0) goto eob_done; @@ -826,34 +830,34 @@ gettag(TokenSource* ts, int starti, Token* a, int* pai // attribute gathering loop al = nil; - while(1) { + for(;;){ // look for "ws name" or "ws name ws = ws val" (ws=whitespace) // skip whitespace attrloop_continue: - while(c < 256 && isspace(c)) { + while(c < 256 && isspace(c)){ c = getchar(ts); if(c < 0) goto eob_done; } if(c == '>') goto attrloop_done; - if(c == '<') { + if(c == '<'){ if(warn) fprint(2, "warning: unclosed tag\n"); ungetchar(ts, c); goto attrloop_done; } - if(c >= 256 || !isalpha(c)) { + if(c >= 256 || !isalpha(c)){ if(warn) fprint(2, "warning: expected attribute name\n"); // skipt to next attribute name - while(1) { + for(;;){ c = getchar(ts); if(c < 0) goto eob_done; if(c < 256 && isalpha(c)) goto attrloop_continue; - if(c == '<') { + if(c == '<'){ if(warn) fprint(2, "warning: unclosed tag\n"); ungetchar(ts, 60); @@ -866,7 +870,7 @@ attrloop_continue: // gather attribute name buf[0] = c; i = 1; - while(1) { + for(;;){ c = getchar(ts); if(c < 0) goto eob_done; @@ -876,23 +880,23 @@ attrloop_continue: buf[i++] = c; } afnd = _lookup(attrtable, Numattrs, buf, i, &attid); - if(warn && !afnd) { + if(warn && !afnd){ buf[i] = 0; fprint(2, "warning: unknown attribute name %S\n", buf); } // skip whitespace - while(c < 256 && isspace(c)) { + while(c < 256 && isspace(c)){ c = getchar(ts); if(c < 0) goto eob_done; } - if(c != '=') { + if(c != '='){ if(afnd) al = newattr(attid, nil, al); goto attrloop_continue; } //# c is '=' here; skip whitespace - while(1) { + for(;;){ c = getchar(ts); if(c < 0) goto eob_done; @@ -900,7 +904,7 @@ attrloop_continue: break; } quote = 0; - if(c == '\'' || c == '"') { + if(c == '\'' || c == '"'){ quote = c; c = getchar(ts); if(c < 0) @@ -908,31 +912,31 @@ attrloop_continue: } val = nil; nv = 0; - while(1) { + for(;;){ valloop_continue: if(c < 0) goto eob_done; - if(c == '>') { - if(quote) { + if(c == '>'){ + if(quote){ // c might be part of string (though not good style) // but if line ends before close quote, assume // there was an unmatched quote ti = ts->i; - while(1) { + for(;;){ c = getchar(ts); if(c < 0) goto eob_done; - if(c == quote) { + if(c == quote){ backup(ts, ti); buf[nv++] = '>'; - if(nv == BIGBUFSIZE-1) { + if(nv == BIGBUFSIZE-1){ val = buftostr(val, buf, nv); nv = 0; } c = getchar(ts); goto valloop_continue; } - if(c == '\n') { + if(c == '\n'){ if(warn) fprint(2, "warning: apparent unmatched quote\n"); backup(ts, ti); @@ -944,14 +948,14 @@ valloop_continue: else goto valloop_done; } - if(quote) { - if(c == quote) { + if(quote){ + if(c == quote){ c = getchar(ts); if(c < 0) goto eob_done; goto valloop_done; } - if(c == '\r') { + if(c == '\r'){ c = getchar(ts); goto valloop_continue; } @@ -962,20 +966,20 @@ valloop_continue: if(c < 256 && isspace(c)) goto valloop_done; } - if(c == '&') { + if(c == '&'){ c = ampersand(ts); if(c == -1) goto eob_done; } buf[nv++] = c; - if(nv == BIGBUFSIZE-1) { + if(nv == BIGBUFSIZE-1){ val = buftostr(val, buf, nv); nv = 0; } c = getchar(ts); } valloop_done: - if(afnd) { + if(afnd){ val = buftostr(val, buf, nv); al = newattr(attid, val, al); } @@ -1017,19 +1021,19 @@ comment(TokenSource* ts) nexti = ts->i; havecomment = 0; c = getchar(ts); - if(c == '-') { + if(c == '-'){ c = getchar(ts); - if(c == '-') { + if(c == '-'){ if(findstr(ts, L(Larrow))) havecomment = 1; else backup(ts, nexti); } } - if(!havecomment) { + if(!havecomment){ if(c == '>') havecomment = 1; - else if(c >= 0) { + else if(c >= 0){ if(findstr(ts, L(Lgt))) havecomment = 1; } @@ -1053,15 +1057,15 @@ findstr(TokenSource* ts, Rune* s) c0 = s[0]; n = runestrlen(s); - while(1) { + for(;;){ c = getchar(ts); if(c < 0) break; - if(c == c0) { + if(c == c0){ if(n == 1) return 1; nexti = ts->i; - for(i = 1; i < n; i++) { + for(i = 1; i < n; i++){ c = getchar(ts); if(c < 0) goto mainloop_done; @@ -1077,6 +1081,18 @@ mainloop_done: return 0; } +static int +xdigit(int c) +{ + if('0' <= c && c <= '9') + return c-'0'; + if('a' <= c && c <= 'f') + return c-'a'+10; + if('A' <= c && c <= 'F') + return c-'A'+10; + return -1; +} + // We've just read an '&'; look for an entity reference // name, and if found, return translated char. // if there is a complete entity name but it isn't known, @@ -1100,36 +1116,42 @@ ampersand(TokenSource* ts) c = getchar(ts); fnd = 0; ans = -1; - if(c == '#') { + if(c == '#'){ c = getchar(ts); v = 0; - while(c >= 0) { - if(!(c < 256 && isdigit(c))) - break; - v = v*10 + c - 48; + if(c == 'x'){ c = getchar(ts); + while((i=xdigit(c)) != -1){ + v = v*16 + i; + c = getchar(ts); + } + }else{ + while('0' <= c && c <= '9'){ + v = v*10 + c - '0'; + c = getchar(ts); + } } - if(c >= 0) { + if(c >= 0){ if(!(c == ';' || c == '\n' || c == '\r')) ungetchar(ts, c); c = v; if(c == 160) c = 160; - if(c >= Winstart && c <= Winend) { + if(c >= Winstart && c <= Winend){ c = winchars[c - Winstart]; } ans = c; fnd = 1; } } - else if(c < 256 && isalpha(c)) { + else if(c < 256 && isalpha(c)){ buf[0] = c; k = 1; - while(1) { + for(;;){ c = getchar(ts); if(c < 0) break; - if(ISNAMCHAR(c)) { + if(ISNAMCHAR(c)){ if(k < SMALLBUFSIZE-1) buf[k++] = c; } @@ -1139,17 +1161,17 @@ ampersand(TokenSource* ts) break; } } - if(c >= 0) { + if(c >= 0){ fnd = _lookup(chartab, NCHARTAB, buf, k, &ans); - if(!fnd) { + if(!fnd){ // Try prefixes of s if(c == ';' || c == '\n' || c == '\r') ungetchar(ts, c); i = k; - while(--k > 0) { + while(--k > 0){ fnd = _lookup(chartab, NCHARTAB, buf, k, &ans); - if(fnd) { - while(i > k) { + if(fnd){ + while(i > k){ i--; ungetchar(ts, buf[i]); } @@ -1159,7 +1181,7 @@ ampersand(TokenSource* ts) } } } - if(!fnd) { + if(!fnd){ backup(ts, savei); ans = '&'; } @@ -1181,14 +1203,14 @@ getchar(TokenSource* ts) return -1; buf = ts->data; c = buf[ts->i]; - switch(ts->chset) { + switch(ts->chset){ case ISO_8859_1: if(c >= Winstart && c <= Winend) c = winchars[c - Winstart]; ts->i++; break; case US_Ascii: - if(c > 127) { + if(c > 127){ if(warn) fprint(2, "non-ascii char (%x) when US-ASCII specified\n", c); } @@ -1197,7 +1219,7 @@ getchar(TokenSource* ts) case UTF_8: ok = fullrune((char*)(buf+ts->i), ts->edata-ts->i); n = chartorune(&r, (char*)(buf+ts->i)); - if(ok) { + if(ok){ if(warn && c == 0x80) fprint(2, "warning: invalid utf-8 sequence (starts with %x)\n", ts->data[ts->i]); ts->i += n; @@ -1210,7 +1232,7 @@ getchar(TokenSource* ts) } break; case Unicode: - if(ts->i < ts->edata - 1) { + if(ts->i < ts->edata - 1){ //standards say most-significant byte first c = (c << 8)|(buf[ts->i + 1]); ts->i += 2; @@ -1235,9 +1257,9 @@ ungetchar(TokenSource* ts, int c) char a[UTFmax]; n = 1; - switch(ts->chset) { + switch(ts->chset){ case UTF_8: - if(c >= 128) { + if(c >= 128){ r = c; n = runetochar(a, &r); } @@ -1273,8 +1295,8 @@ _tokaval(Token* t, int attid, Rune** pans, int xfer) Attr* attr; attr = t->attr; - while(attr != nil) { - if(attr->attid == attid) { + while(attr != nil){ + if(attr->attid == attid){ if(pans != nil) *pans = attr->value; if(xfer) @@ -1308,12 +1330,12 @@ Tconv(Fmt *f) if(dbglex > 1) i = snprint(buf, sizeof(buf), "[%d]", t->starti); tag = t->tag; - if(tag == Data) { + if(tag == Data){ i += snprint(buf+i, sizeof(buf)-i-1, "'%S'", t->text); } else { srbra = ""; - if(tag >= RBRA) { + if(tag >= RBRA){ tag -= RBRA; srbra = "/"; } @@ -1321,7 +1343,7 @@ Tconv(Fmt *f) if(tag == Notfound) tname = L(Lquestion); i += snprint(buf+i, sizeof(buf)-i-1, "<%s%S", srbra, tname); - for(a = t->attr; a != nil; a = a->next) { + for(a = t->attr; a != nil; a = a->next){ aname = attrnames[a->attid]; i += snprint(buf+i, sizeof(buf)-i-1, " %S", aname); if(a->value != nil) @@ -1356,7 +1378,7 @@ freeattrs(Attr* ahead) Attr* nexta; a = ahead; - while(a != nil) { + while(a != nil){ nexta = a->next; free(a->value); free(a); @@ -1377,7 +1399,7 @@ _freetokens(Token* tarray, int n) if(tarray == nil) return; - for(i = 0; i < n; i++) { + for(i = 0; i < n; i++){ t = &tarray[i]; free(t->text); freeattrs(t->attr);