build.c
来自「这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易」· C语言 代码 · 共 2,670 行 · 第 1/5 页
C
2,670 行
n = j-i; } } if(ps->skipwhite) { _trimwhite(s, n, &t, &nt); if(t == nil) { free(s); s = nil; } else if(t != s) { t = _Strndup(t, nt); free(s); s = t; } if(s != nil) ps->skipwhite = 0; } tok->text = nil; // token doesn't own string anymore if(s != nil) addtext(ps, s); } else switch(tag) { // Some abbrevs used in following DTD comments // %text = #PCDATA // | TT | I | B | U | STRIKE | BIG | SMALL | SUB | SUP // | EM | STRONG | DFN | CODE | SAMP | KBD | VAR | CITE // | A | IMG | APPLET | FONT | BASEFONT | BR | SCRIPT | MAP // | INPUT | SELECT | TEXTAREA // %block = P | UL | OL | DIR | MENU | DL | PRE | DL | DIV | CENTER // | BLOCKQUOTE | FORM | ISINDEX | HR | TABLE // %flow = (%text | %block)* // %body.content = (%heading | %text | %block | ADDRESS)* // <!ELEMENT A - - (%text) -(A)> // Anchors are not supposed to be nested, but you sometimes see // href anchors inside destination anchors. case Ta: if(ps->curanchor != 0) { if(warn) fprint(2, "warning: nested <A> or missing </A>\n"); ps->curanchor = 0; } name = aval(tok, Aname); href = aurlval(tok, Ahref, nil, di->base); // ignore rel, rev, and title attrs if(href != nil) { target = atargval(tok, di->target); di->anchors = newanchor(++is->nanchors, name, href, target, di->anchors); if(name != nil) name = _Strdup(name); // for DestAnchor construction, below ps->curanchor = is->nanchors; ps->curfg = push(&ps->fgstk, di->link); ps->curul = push(&ps->ulstk, ULunder); } if(name != nil) { // add a null item to be destination additem(ps, newispacer(ISPnull), tok); di->dests = newdestanchor(++is->nanchors, name, ps->lastit, di->dests); } break; case Ta+RBRA : if(ps->curanchor != 0) { ps->curfg = popretnewtop(&ps->fgstk, di->text); ps->curul = popretnewtop(&ps->ulstk, ULnone); ps->curanchor = 0; } break; // <!ELEMENT APPLET - - (PARAM | %text)* > // We can't do applets, so ignore PARAMS, and let // the %text contents appear for the alternative rep case Tapplet: case Tapplet+RBRA: if(warn && tag == Tapplet) fprint(2, "warning: <APPLET> ignored\n"); break; // <!ELEMENT AREA - O EMPTY> case Tarea: map = di->maps; if(map == nil) { if(warn) fprint(2, "warning: <AREA> not inside <MAP>\n"); continue; } map->areas = newarea(atabval(tok, Ashape, shape_tab, NSHAPETAB, SHrect), aurlval(tok, Ahref, nil, di->base), atargval(tok, di->target), map->areas); setdimarray(tok, Acoords, &map->areas->coords, &map->areas->ncoords); break; // <!ELEMENT (B|STRONG) - - (%text)*> case Tb: case Tstrong: pushfontstyle(ps, FntB); break; case Tb+RBRA: case Tcite+RBRA: case Tcode+RBRA: case Tdfn+RBRA: case Tem+RBRA: case Tkbd+RBRA: case Ti+RBRA: case Tsamp+RBRA: case Tstrong+RBRA: case Ttt+RBRA: case Tvar+RBRA : case Taddress+RBRA: popfontstyle(ps); break; // <!ELEMENT BASE - O EMPTY> case Tbase: t = di->base; di->base = aurlval(tok, Ahref, di->base, di->base); if(t != nil) free(t); di->target = atargval(tok, di->target); break; // <!ELEMENT BASEFONT - O EMPTY> case Tbasefont: ps->adjsize = aintval(tok, Asize, 3) - 3; break; // <!ELEMENT (BIG|SMALL) - - (%text)*> case Tbig: case Tsmall: sz = ps->adjsize; if(tag == Tbig) sz += Large; else sz += Small; pushfontsize(ps, sz); break; case Tbig+RBRA: case Tsmall+RBRA: popfontsize(ps); break; // <!ELEMENT BLOCKQUOTE - - %body.content> case Tblockquote: changeindent(ps, BQTAB); break; case Tblockquote+RBRA: changeindent(ps, -BQTAB); break; // <!ELEMENT BODY O O %body.content> case Tbody: ps->skipping = 0; bg = makebackground(nil, acolorval(tok, Abgcolor, di->background.color)); bgurl = aurlval(tok, Abackground, nil, di->base); if(bgurl != nil) { if(di->backgrounditem != nil) freeitem((Item*)di->backgrounditem); // really should remove old item from di->images list, // but there should only be one BODY element ... di->backgrounditem = (Iimage*)newiimage(bgurl, nil, ALnone, 0, 0, 0, 0, 0, 0, nil); di->backgrounditem->nextimage = di->images; di->images = di->backgrounditem; } ps->curbg = bg; di->background = bg; di->text = acolorval(tok, Atext, di->text); di->link = acolorval(tok, Alink, di->link); di->vlink = acolorval(tok, Avlink, di->vlink); di->alink = acolorval(tok, Aalink, di->alink); if(di->text != ps->curfg) { ps->curfg = di->text; ps->fgstk.n = 0; } break; case Tbody+RBRA: // HTML spec says ignore things after </body>, // but IE and Netscape don't // ps.skipping = 1; break; // <!ELEMENT BR - O EMPTY> case Tbr: addlinebrk(ps, atabval(tok, Aclear, clear_tab, NCLEARTAB, 0)); break; // <!ELEMENT CAPTION - - (%text;)*> case Tcaption: if(curtab == nil) { if(warn) fprint(2, "warning: <CAPTION> outside <TABLE>\n"); continue; } if(curtab->caption != nil) { if(warn) fprint(2, "warning: more than one <CAPTION> in <TABLE>\n"); continue; } ps = newpstate(ps); curtab->caption_place = atabval(tok, Aalign, align_tab, NALIGNTAB, ALtop); break; case Tcaption+RBRA: nextps = ps->next; if(curtab == nil || nextps == nil) { if(warn) fprint(2, "warning: unexpected </CAPTION>\n"); continue; } curtab->caption = ps->items->next; free(ps); ps = nextps; break; case Tcenter: case Tdiv: if(tag == Tcenter) al = ALcenter; else al = atabval(tok, Aalign, align_tab, NALIGNTAB, ps->curjust); pushjust(ps, al); break; case Tcenter+RBRA: case Tdiv+RBRA: popjust(ps); break; // <!ELEMENT DD - O %flow > case Tdd: if(ps->hangstk.n == 0) { if(warn) fprint(2, "warning: <DD> not inside <DL\n"); continue; } h = top(&ps->hangstk, 0); if(h != 0) changehang(ps, -10*LISTTAB); else addbrk(ps, 0, 0); push(&ps->hangstk, 0); break; //<!ELEMENT (DIR|MENU) - - (LI)+ -(%block) > //<!ELEMENT (OL|UL) - - (LI)+> case Tdir: case Tmenu: case Tol: case Tul: changeindent(ps, LISTTAB); push(&ps->listtypestk, listtyval(tok, (tag==Tol)? LT1 : LTdisc)); push(&ps->listcntstk, aintval(tok, Astart, 1)); break; case Tdir+RBRA: case Tmenu+RBRA: case Tol+RBRA: case Tul+RBRA: if(ps->listtypestk.n == 0) { if(warn) fprint(2, "warning: %T ended no list\n", tok); continue; } addbrk(ps, 0, 0); pop(&ps->listtypestk); pop(&ps->listcntstk); changeindent(ps, -LISTTAB); break; // <!ELEMENT DL - - (DT|DD)+ > case Tdl: changeindent(ps, LISTTAB); push(&ps->hangstk, 0); break; case Tdl+RBRA: if(ps->hangstk.n == 0) { if(warn) fprint(2, "warning: unexpected </DL>\n"); continue; } changeindent(ps, -LISTTAB); if(top(&ps->hangstk, 0) != 0) changehang(ps, -10*LISTTAB); pop(&ps->hangstk); break; // <!ELEMENT DT - O (%text)* > case Tdt: if(ps->hangstk.n == 0) { if(warn) fprint(2, "warning: <DT> not inside <DL>\n"); continue; } h = top(&ps->hangstk, 0); pop(&ps->hangstk); if(h != 0) changehang(ps, -10*LISTTAB); changehang(ps, 10*LISTTAB); push(&ps->hangstk, 1); break; // <!ELEMENT FONT - - (%text)*> case Tfont: sz = top(&ps->fntsizestk, Normal); if(_tokaval(tok, Asize, &nsz, 0)) { if(_prefix(L"+", nsz)) sz = Normal + _Strtol(nsz+1, nil, 10) + ps->adjsize; else if(_prefix(L"-", nsz)) sz = Normal - _Strtol(nsz+1, nil, 10) + ps->adjsize; else if(nsz != nil) sz = Normal + (_Strtol(nsz, nil, 10) - 3); } ps->curfg = push(&ps->fgstk, acolorval(tok, Acolor, ps->curfg)); pushfontsize(ps, sz); break; case Tfont+RBRA: if(ps->fgstk.n == 0) { if(warn) fprint(2, "warning: unexpected </FONT>\n"); continue; } ps->curfg = popretnewtop(&ps->fgstk, di->text); popfontsize(ps); break; // <!ELEMENT FORM - - %body.content -(FORM) > case Tform: if(is->curform != nil) { if(warn) fprint(2, "warning: <FORM> nested inside another\n"); continue; } action = aurlval(tok, Aaction, di->base, di->base); s = aval(tok, Aid); name = astrval(tok, Aname, s); if(s) free(s); target = atargval(tok, di->target); method = atabval(tok, Amethod, method_tab, NMETHODTAB, HGet); if(warn && _tokaval(tok, Aenctype, &enctype, 0) && _Strcmp(enctype, L"application/x-www-form-urlencoded")) fprint(2, "form enctype %S not handled\n", enctype); frm = newform(++is->nforms, name, action, target, method, di->forms); di->forms = frm; is->curform = frm; break; case Tform+RBRA: if(is->curform == nil) { if(warn) fprint(2, "warning: unexpected </FORM>\n"); continue; } // put fields back in input order is->curform->fields = (Formfield*)_revlist((List*)is->curform->fields); is->curform = nil; break; // <!ELEMENT FRAME - O EMPTY> case Tframe: ks = is->kidstk; if(ks == nil) { if(warn) fprint(2, "warning: <FRAME> not in <FRAMESET>\n"); continue; } ks->kidinfos = kd = newkidinfo(0, ks->kidinfos); kd->src = aurlval(tok, Asrc, nil, di->base); kd->name = aval(tok, Aname); if(kd->name == nil) { s = _ltoStr(++is->nframes); kd->name = _Strdup2(L"_fr", s); free(s); } kd->marginw = auintval(tok, Amarginwidth, 0); kd->marginh = auintval(tok, Amarginheight, 0); kd->framebd = auintval(tok, Aframeborder, 1); kd->flags = atabval(tok, Ascrolling, fscroll_tab, NFSCROLLTAB, kd->flags); norsz = aflagval(tok, Anoresize); if(norsz) kd->flags |= FRnoresize; break; // <!ELEMENT FRAMESET - - (FRAME|FRAMESET)+> case Tframeset: ks = newkidinfo(1, nil); pks = is->kidstk; if(pks == nil) di->kidinfo = ks; else { ks->next = pks->kidinfos; pks->kidinfos = ks; } ks->nextframeset = pks; is->kidstk = ks; setdimarray(tok, Arows, &ks->rows, &ks->nrows); if(ks->nrows == 0) { ks->rows = (Dimen*)emalloc(sizeof(Dimen)); ks->nrows = 1; ks->rows[0] = makedimen(Dpercent, 100); } setdimarray(tok, Acols, &ks->cols, &ks->ncols); if(ks->ncols == 0) { ks->cols = (Dimen*)emalloc(sizeof(Dimen)); ks->ncols = 1; ks->cols[0] = makedimen(Dpercent, 100); } break; case Tframeset+RBRA: if(is->kidstk == nil) { if(warn) fprint(2, "warning: unexpected </FRAMESET>\n"); continue; } ks = is->kidstk; // put kids back in original order // and add blank frames to fill out cells n = ks->nrows*ks->ncols; nblank = n - _listlen((List*)ks->kidinfos); while(nblank-- > 0) ks->kidinfos = newkidinfo(0, ks->kidinfos); ks->kidinfos = (Kidinfo*)_revlist((List*)ks->kidinfos); is->kidstk = is->kidstk->nextframeset; if(is->kidstk == nil) { // end input ans = nil; goto return_ans; } break; // <!ELEMENT H1 - - (%text;)*>, etc. case Th1: case Th2: case Th3: case Th4: case Th5: case Th6: bramt = 1; if(ps->items == ps->lastit) bramt = 0; addbrk(ps, bramt, IFcleft|IFcright); sz = Verylarge - (tag - Th1); if(sz < Tiny) sz = Tiny; pushfontsize(ps, sz); sty = top(&ps->fntstylestk, FntR); if(tag == Th1) sty = FntB; pushfontstyle(ps, sty); pushjust(ps, atabval(tok, Aalign, align_tab, NALIGNTAB, ps->curjust)); ps->skipwhite = 1; break; case Th1+RBRA: case Th2+RBRA: case Th3+RBRA: case Th4+RBRA: case Th5+RBRA: case Th6+RBRA: addbrk(ps, 1, IFcleft|IFcright); popfontsize(ps); popfontstyle(ps); popjust(ps); break; case Thead: // HTML spec says ignore regular markup in head, // but Netscape and IE don't // ps.skipping = 1; break; case Thead+RBRA: ps->skipping = 0; break; // <!ELEMENT HR - O EMPTY> case Thr: al = atabval(tok, Aalign, align_tab, NALIGNTAB, ALcenter); sz = auintval(tok, Asize, HRSZ); wd = adimen(tok, Awidth); if(dimenkind(wd) == Dnone) wd = makedimen(Dpercent, 100); nosh = aflagval(tok, Anoshade); additem(ps, newirule(al, sz, nosh, wd), tok); addbrk(ps, 0, 0); break; case Ti: case Tcite: case Tdfn: case Tem: case Tvar: case Taddress: pushfontstyle(ps, FntI); break; // <!ELEMENT IMG - O EMPTY> case Timg: map = nil; oldcuranchor = ps->curanchor; if(_tokaval(tok, Ausemap, &usemap, 0)) { if(!_prefix(L"#", usemap)) { if(warn) fprint(2, "warning: can't handle non-local map %S\n", usemap); } else { map = getmap(di, usemap+1); if(ps->curanchor == 0) { di->anchors = newanchor(++is->nanchors, nil, nil, di->target, di->anchors); ps->curanchor = is->nanchors; } } } align = atabval(tok, Aalign, align_tab, NALIGNTAB, ALbottom); dfltbd = 0; if(ps->curanchor != 0) dfltbd = 2; src = aurlval(tok, Asrc, nil, di->base); if(src == nil) { if(warn) fprint(2, "warning: <img> has no src attribute\n"); ps->curanchor = oldcuranchor; continue; } img = newiimage(src, aval(tok, Aalt),
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?