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 + -
显示快捷键?