1408 lines · 25.8 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <draw.h>#include <ctype.h>#include <html.h>#include "impl.h" typedef struct TokenSource TokenSource;struct TokenSource{	int			i;		/* index of next byte to use */	uchar*		data;		/* all the data */	int			edata;	/* data[0:edata] is valid */	int			chset;	/* one of US_Ascii, etc. */	int			mtype;	/* TextHtml or TextPlain */}; enum {	EOF = -2,	EOB = -1}; #define ISNAMCHAR(c)	((c)<256 && (isalpha(c) || isdigit(c) || (c) == '-' || (c) == '.')) #define SMALLBUFSIZE 240#define BIGBUFSIZE 2000 /* HTML 4.0 tag names. *//* Keep sorted, and in correspondence with enum in iparse.h. */Rune **tagnames;char *_tagnames[] = {	" ",	"!",	"a", 	"abbr",	"acronym",	"address",	"applet", 	"area",	"b",	"base",	"basefont",	"bdo",	"big",	"blink",	"blockquote",	"body",	"bq",	"br",	"button",	"caption",	"center",	"cite",	"code",	"col",	"colgroup",	"dd",	"del",	"dfn",	"dir",	"div",	"dl",	"dt",	"em",	"fieldset",	"font",	"form",	"frame",	"frameset",	"h1",	"h2",	"h3",	"h4",	"h5",	"h6",	"head",	"hr",	"html",	"i",	"iframe",	"img",	"input",	"ins",	"isindex",	"kbd",	"label",	"legend",	"li",	"link",	"map",	"menu",	"meta",	"nobr",	"noframes",	"noscript",	"object",	"ol",	"optgroup",	"option",	"p",	"param",	"pre",	"q",	"s",	"samp",	"script",	"select",	"small",	"span",	"strike",	"strong",	"style",	"sub",	"sup",	"table",	"tbody",	"td",	"textarea",	"tfoot",	"th",	"thead",	"title",	"tr",	"tt",	"u",	"ul",	"var"}; /* HTML 4.0 attribute names. *//* Keep sorted, and in correspondence with enum in i.h. */Rune **attrnames;char* _attrnames[] = {	"abbr",	"accept-charset",	"access-key",	"action",	"align",	"alink",	"alt",	"archive",	"axis",	"background",	"bgcolor",	"border",	"cellpadding",	"cellspacing",	"char",	"charoff",	"charset",	"checked",	"cite",	"class",	"classid",	"clear",	"code",	"codebase",	"codetype",	"color",	"cols",	"colspan",	"compact",	"content",	"coords",	"data",	"datetime",	"declare",	"defer",	"dir",	"disabled",	"enctype",	"face",	"for",	"frame",	"frameborder",	"headers",	"height",	"href",	"hreflang",	"hspace",	"http-equiv",	"id",	"ismap",	"label",	"lang",	"link",	"longdesc",	"marginheight",	"marginwidth",	"maxlength",	"media",	"method",	"multiple",	"name",	"nohref",	"noresize",	"noshade",	"nowrap",	"object",	"onblur",	"onchange",	"onclick",	"ondblclick",	"onfocus",	"onkeypress",	"onkeyup",	"onload",	"onmousedown",	"onmousemove",	"onmouseout",	"onmouseover",	"onmouseup",	"onreset",	"onselect",	"onsubmit",	"onunload",	"profile",	"prompt",	"readonly",	"rel",	"rev",	"rows",	"rowspan",	"rules",	"scheme",	"scope",	"scrolling",	"selected",	"shape",	"size",	"span",	"src",	"standby",	"start",	"style",	"summary",	"tabindex",	"target",	"text",	"title",	"type",	"usemap",	"valign",	"value",	"valuetype",	"version",	"vlink",	"vspace",	"width"};  /* Character entity to unicode character number map. *//* Keep sorted by name. */StringInt *chartab;AsciiInt _chartab[] = {	{"AElig", 198},	{"Aacute", 193},	{"Acirc", 194},	{"Agrave", 192},	{"Aring", 197},	{"Atilde", 195},	{"Auml", 196},	{"Ccedil", 199},	{"ETH", 208},	{"Eacute", 201},	{"Ecirc", 202},	{"Egrave", 200},	{"Euml", 203},	{"Iacute", 205},	{"Icirc", 206},	{"Igrave", 204},	{"Iuml", 207},	{"Ntilde", 209},	{"Oacute", 211},	{"Ocirc", 212},	{"Ograve", 210},	{"Oslash", 216},	{"Otilde", 213},	{"Ouml", 214},	{"THORN", 222},	{"Uacute", 218},	{"Ucirc", 219},	{"Ugrave", 217},	{"Uuml", 220},	{"Yacute", 221},	{"aacute", 225},	{"acirc", 226},	{"acute", 180},	{"aelig", 230},	{"agrave", 224},	{"alpha", 945},	{"amp", 38},	{"aring", 229},	{"atilde", 227},	{"auml", 228},	{"beta", 946},	{"brvbar", 166},	{"ccedil", 231},	{"cdots", 8943},	{"cedil", 184},	{"cent", 162},	{"chi", 967},	{"copy", 169},	{"curren", 164},	{"ddots", 8945},	{"deg", 176},	{"delta", 948},	{"divide", 247},	{"eacute", 233},	{"ecirc", 234},	{"egrave", 232},	{"emdash", 8212},	/* non-standard but commonly used */	{"emsp", 8195},	{"endash", 8211},	/* non-standard but commonly used */	{"ensp", 8194},	{"epsilon", 949},	{"eta", 951},	{"eth", 240},	{"euml", 235},	{"frac12", 189},	{"frac14", 188},	{"frac34", 190},	{"gamma", 947},	{"gt", 62},	{"iacute", 237},	{"icirc", 238},	{"iexcl", 161},	{"igrave", 236},	{"iota", 953},	{"iquest", 191},	{"iuml", 239},	{"kappa", 954},	{"lambda", 955},	{"laquo", 171},	{"ldquo", 8220},	{"ldots", 8230},	{"lsquo", 8216},	{"lt", 60},	{"macr", 175},	{"mdash", 8212},	{"micro", 181},	{"middot", 183},	{"mu", 956},	{"nbsp", 160},	{"ndash", 8211},	{"not", 172},	{"ntilde", 241},	{"nu", 957},	{"oacute", 243},	{"ocirc", 244},	{"ograve", 242},	{"omega", 969},	{"omicron", 959},	{"ordf", 170},	{"ordm", 186},	{"oslash", 248},	{"otilde", 245},	{"ouml", 246},	{"para", 182},	{"phi", 966},	{"pi", 960},	{"plusmn", 177},	{"pound", 163},	{"psi", 968},	{"quad", 8193},	{"quot", 34},	{"raquo", 187},	{"rdquo", 8221},	{"reg", 174},	{"rho", 961},	{"rsquo", 8217},	{"sect", 167},	{"shy", 173},	{"sigma", 963},	{"sp", 8194},	{"sup1", 185},	{"sup2", 178},	{"sup3", 179},	{"szlig", 223},	{"tau", 964},	{"theta", 952},	{"thinsp", 8201},	{"thorn", 254},	{"times", 215},	{"trade", 8482},	{"uacute", 250},	{"ucirc", 251},	{"ugrave", 249},	{"uml", 168},	{"upsilon", 965},	{"uuml", 252},	{"varepsilon", 8712},	{"varphi", 981},	{"varpi", 982},	{"varrho", 1009},	{"vdots", 8942},	{"vsigma", 962},	{"vtheta", 977},	{"xi", 958},	{"yacute", 253},	{"yen", 165},	{"yuml", 255},	{"zeta", 950}};#define NCHARTAB (sizeof(_chartab)/sizeof(_chartab[0])) /* Characters Winstart..Winend are those that Windows *//* uses interpolated into the Latin1 set. *//* They aren't supposed to appear in HTML, but they do.... */enum {	Winstart = 127,	Winend = 159}; static int	winchars[]= { 8226,	/* 8226 is a bullet */	8226, 8226, 8218, 402, 8222, 8230, 8224, 8225,	710, 8240, 352, 8249, 338, 8226, 8226, 8226,	8226, 8216, 8217, 8220, 8221, 8226, 8211, 8212,	732, 8482, 353, 8250, 339, 8226, 8226, 376}; static StringInt*	tagtable;		/* initialized from tagnames */static StringInt*	attrtable;		/* initialized from attrnames */ static void		lexinit(void);static int		getplaindata(TokenSource* ts, Token* a, int* pai);static int		getdata(TokenSource* ts, int firstc, int starti, Token* a, int* pai);static int		getscriptdata(TokenSource* ts, int firstc, int starti, Token* a, int* pai);static int		gettag(TokenSource* ts, int starti, Token* a, int* pai);static Rune*		buftostr(Rune* s, Rune* buf, int j);static int		comment(TokenSource* ts);static int		findstr(TokenSource* ts, Rune* s);static int		ampersand(TokenSource* ts);/*static int		lowerc(int c); */static int		getchar(TokenSource* ts);static void		ungetchar(TokenSource* ts, int c);static void		backup(TokenSource* ts, int savei);/*static void		freeinsidetoken(Token* t); */static void		freeattrs(Attr* ahead);static Attr*		newattr(int attid, Rune* value, Attr* link);static int		Tconv(Fmt* f); int	dbglex = 0;static int lexinited = 0; static voidlexinit(void){	chartab = _cvtstringinttab(_chartab, nelem(_chartab));	tagnames = _cvtstringtab(_tagnames, nelem(_tagnames));	tagtable = _makestrinttab(tagnames, Numtags);	attrnames = _cvtstringtab(_attrnames, nelem(_attrnames));	attrtable = _makestrinttab(attrnames, Numattrs);	fmtinstall('T', Tconv);	lexinited = 1;} static TokenSource*newtokensource(uchar* data, int edata, int chset, int mtype){	TokenSource*	ans; 	assert(chset == US_Ascii || chset == ISO_8859_1 ||			chset == UTF_8 || chset == Unicode);	ans = (TokenSource*)emalloc(sizeof(TokenSource));	ans->i = 0;	ans->data = data;	ans->edata = edata;	ans->chset = chset;	ans->mtype = mtype;	return ans;} enum {	ToksChunk = 500}; /* Call this to get the tokens. *//*  The number of returned tokens is returned in *plen. */Token*_gettoks(uchar* data, int datalen, int chset, int mtype, int* plen){	TokenSource*	ts;	Token*		a;	int	alen;	int	ai;	int	starti;	int	c;	int	tag; 	if(!lexinited)		lexinit();	ts = newtokensource(data, datalen, chset, mtype);	alen = ToksChunk;	a = (Token*)emalloc(alen * sizeof(Token));	ai = 0;	if(dbglex)		fprint(2, "_gettoks starts, ts.i=%d, ts.edata=%d\n", ts->i, ts->edata);	if(ts->mtype == TextHtml){		for(;;){

Lines 1–500 of 1408.