html_tbl.c

来自「this is the file used to browse web」· C语言 代码 · 共 1,263 行 · 第 1/3 页

C
1,263
字号
#include "links.h"#define AL_TR		-1#define VAL_TR		-1#define VAL_TOP		0#define VAL_MIDDLE	1#define VAL_BOTTOM	2#define W_AUTO		-1#define W_REL		-2#define F_VOID		0#define F_ABOVE		1#define F_BELOW		2#define F_HSIDES	3#define F_LHS		4#define F_RHS		8#define F_VSIDES	12#define F_BOX		15#define R_NONE		0#define R_ROWS		1#define R_COLS		2#define R_ALL		3#define R_GROUPS	4void get_align(char *attr, int *a){	char *al;	if ((al = get_attr_val(attr, "align"))) {		if (!(strcasecmp(al, "left"))) *a = AL_LEFT;		if (!(strcasecmp(al, "right"))) *a = AL_RIGHT;		if (!(strcasecmp(al, "center"))) *a = AL_CENTER;		if (!(strcasecmp(al, "justify"))) *a = AL_BLOCK;		if (!(strcasecmp(al, "char"))) *a = AL_RIGHT; /* NOT IMPLEMENTED */		mem_free(al);	}}void get_valign(char *attr, int *a){	char *al;	if ((al = get_attr_val(attr, "valign"))) {		if (!(strcasecmp(al, "top"))) *a = VAL_TOP;		if (!(strcasecmp(al, "middle"))) *a = VAL_MIDDLE;		if (!(strcasecmp(al, "bottom"))) *a = VAL_BOTTOM;		if (!(strcasecmp(al, "baseline"))) *a = VAL_TOP; /* NOT IMPLEMENTED */		mem_free(al);	}}void get_c_width(char *attr, int *w, int sh){	char *al;	if ((al = get_attr_val(attr, "width"))) {		if (*al && al[strlen(al) - 1] == '*') {			char *en;			unsigned long n;			al[strlen(al) - 1] = 0;			n = strtoul(al, &en, 10);			if (n < 10000 && !*en) *w = W_REL - n;		} else {			int p = get_width(attr, "width", sh);			if (p >= 0) *w = p;		}		mem_free(al);	}}#define INIT_X		8#define INIT_Y		8struct table_cell {	int used;	int spanned;	int mx, my;	unsigned char *start;	unsigned char *end;	int align;	int valign;	int b;	struct rgb bgcolor;	int group;	int colspan;	int rowspan;	int min_width;	int max_width;	int x_width;	int height;	int xpos, ypos, xw, yw;	int link_num;};struct table_column {	int group;	int align;	int valign;	int width;};struct table {	struct part *p;	int x, y;	int rx, ry;	int border, cellpd, vcellpd, cellsp;	int frame, rules, width, wf;	int *min_c, *max_c;	int *w_c;	int rw;	int min_t, max_t;	struct table_cell *cells;	int c, rc;	struct table_column *cols;	int xc;	int *xcols;	int *r_heights;	int rh;	int link_num;};#define CELL(t, x, y) (&(t)->cells[(y) * (t)->rx + (x)])unsigned char frame_table[81] = {	0x00, 0xb3, 0xba,	0xc4, 0xc0, 0xd3,	0xcd, 0xd4, 0xc8,	0xc4, 0xd9, 0xbd,	0xc4, 0xc1, 0xd0,	0xcd, 0xd4, 0xc8,	0xcd, 0xbe, 0xbc,	0xcd, 0xbe, 0xbc,	0xcd, 0xcf, 0xca,	0xb3, 0xb3, 0xba,	0xda, 0xc3, 0xd3,	0xd5, 0xc6, 0xc8,	0xbf, 0xb4, 0xbd,	0xc2, 0xc5, 0xd0,	0xd5, 0xc6, 0xc8,	0xb8, 0xb5, 0xbc,	0xb8, 0xb5, 0xbc,	0xd1, 0xd8, 0xca,	0xba, 0xba, 0xba,	0xd6, 0xd6, 0xc7,	0xc9, 0xc9, 0xcc,	0xb7, 0xb7, 0xb6,	0xd2, 0xd2, 0xd7,	0xc9, 0xc9, 0xcc,	0xbb, 0xbb, 0xb9,	0xbb, 0xbb, 0xb9,	0xcb, 0xcb, 0xce,};unsigned char hline_table[3] = { 0x20, 0xc4, 0xcd };unsigned char vline_table[3] = { 0x20, 0xb3, 0xba };struct table *new_table(){	struct table *t;	t = mem_alloc(sizeof(struct table));	memset(t, 0, sizeof(struct table));	t->p = NULL;	t->x = t->y = 0;	t->rx = INIT_X;	t->ry = INIT_Y;	t->cells = mem_alloc(INIT_X * INIT_Y * sizeof(struct table_cell));	memset(t->cells, 0, INIT_X * INIT_Y * sizeof(struct table_cell));	t->c = 0;	t->rc = INIT_X;	t->cols = mem_alloc(INIT_X * sizeof(struct table_column));	memset(t->cols, 0, INIT_X * sizeof(struct table_column));	t->xcols = DUMMY;	t->xc = 0;	t->r_heights = DUMMY;	return t;}void free_table(struct table *t){	if (t->min_c) mem_free(t->min_c);	if (t->max_c) mem_free(t->max_c);	if (t->w_c) mem_free(t->w_c);	mem_free(t->r_heights);	mem_free(t->cols);	mem_free(t->xcols);	mem_free(t->cells);	mem_free(t);}void expand_cells(struct table *t, int x, int y){	int i, j;	if (x >= t->x) {		if (t->x) {			for (i = 0; i < t->y; i++) if (CELL(t, t->x - 1, i)->colspan == -1) {				for (j = t->x; j <= x; j++) {					CELL(t, j, i)->used = 1;					CELL(t, j, i)->spanned = 1;					CELL(t, j, i)->rowspan = CELL(t, t->x - 1, i)->rowspan;					CELL(t, j, i)->colspan = -1;					CELL(t, j, i)->mx = CELL(t, t->x - 1, i)->mx;					CELL(t, j, i)->my = CELL(t, t->x - 1, i)->my;				}			}		}		t->x = x + 1;	}	if (y >= t->y) {		if (t->y) {			for (i = 0; i < t->x; i++) if (CELL(t, i, t->y - 1)->rowspan == -1) {				for (j = t->y; j <= y; j++) {					CELL(t, i, j)->used = 1;					CELL(t, i, j)->spanned = 1;					CELL(t, i, j)->rowspan = -1;					CELL(t, i, j)->colspan = CELL(t, i, t->y - 1)->colspan;					CELL(t, i, j)->mx = CELL(t, i, t->y - 1)->mx;					CELL(t, i, j)->my = CELL(t, i, t->y - 1)->my;				}			}		}		t->y = y + 1;	}}struct table_cell *new_cell(struct table *t, int x, int y){	struct table nt;	int i, j;	if (x < t->x && y < t->y) goto ret;	rep:	if (x < t->rx && y < t->ry) {		expand_cells(t, x, y);		goto ret;	}	nt.rx = t->rx;	nt.ry = t->ry;	while (x >= nt.rx) {		if ((unsigned)nt.rx > MAXINT / 2) overalloc();		nt.rx *= 2;	}	while (y >= nt.ry) {		if ((unsigned)nt.ry > MAXINT / 2) overalloc();		nt.ry *= 2;	}	if ((unsigned)nt.rx * (unsigned)nt.ry / (unsigned)nt.rx != (unsigned)nt.ry) overalloc();	if ((unsigned)nt.rx * (unsigned)nt.ry > MAXINT / sizeof(struct table_cell)) overalloc();	nt.cells = mem_alloc(nt.rx * nt.ry * sizeof(struct table_cell));	memset(nt.cells, 0, nt.rx * nt.ry * sizeof(struct table_cell));	for (i = 0; i < t->x; i++)		for (j = 0; j < t->y; j++)			memcpy(CELL(&nt, i, j), CELL(t, i, j), sizeof(struct table_cell));	mem_free(t->cells);	t->cells = nt.cells;	t->rx = nt.rx;	t->ry = nt.ry;	goto rep;	ret:	return CELL(t, x, y);}void new_columns(struct table *t, int span, int width, int align, int valign, int group){	if ((unsigned)t->c + (unsigned)span > MAXINT) overalloc();	if (t->c + span > t->rc) {		int n = t->rc;		struct table_column *nc;		while (t->c + span > n) {			if ((unsigned)n > MAXINT / 2) overalloc();			n *= 2;		}		if ((unsigned)n > MAXINT / sizeof(struct table_column)) overalloc();		nc = mem_realloc(t->cols, n * sizeof(struct table_column));		t->rc = n;		t->cols = nc;	}	while (span--) {		t->cols[t->c].align = align;		t->cols[t->c].valign = valign;		t->cols[t->c].width = width;		t->cols[t->c++].group = group;		group = 0;	}}void set_td_width(struct table *t, int x, int width, int f){	if (x >= t->xc) {		int n = t->xc ? t->xc : 1;		int i;		int *nc;		while (x >= n) {			if ((unsigned)n > MAXINT / 2) overalloc();			n *= 2;		}		if ((unsigned)n > MAXINT / sizeof(int)) overalloc();		nc = mem_realloc(t->xcols, n * sizeof(int));		for (i = t->xc; i < n; i++) nc[i] = W_AUTO;		t->xc = n;		t->xcols = nc;	}	if (t->xcols[x] == W_AUTO || f) {		set:		t->xcols[x] = width;		return;	}	if (width == W_AUTO) return;	if (width < 0 && t->xcols[x] >= 0) goto set;	if (width >= 0 && t->xcols[x] < 0) return;	t->xcols[x] = (t->xcols[x] + width) / 2;}unsigned char *skip_table(unsigned char *html, unsigned char *eof){	int level = 1;	unsigned char *name;	int namelen;	r:	while (html < eof && (*html != '<' || parse_element(html, eof, &name, &namelen, NULL, &html))) html++;	if (html >= eof) return eof;	if (namelen == 5 && !casecmp(name, "TABLE", 5)) level++;	if (namelen == 6 && !casecmp(name, "/TABLE", 6)) if (!--level) return html;	goto r;}struct s_e {	unsigned char *s, *e;};struct table *parse_table(unsigned char *html, unsigned char *eof, unsigned char **end, struct rgb *bgcolor, int sh, struct s_e **bad_html, int *bhp){	int qqq;	struct table *t;	struct table_cell *cell;	unsigned char *t_name, *t_attr, *en;	int t_namelen;	int x = 0, y = -1;	int p = 0;	unsigned char *lbhp = NULL;	int l_al = AL_LEFT;	int l_val = VAL_MIDDLE;	int csp, rsp;	int group = 0;	int i, j, k;	struct rgb l_col;	int c_al = AL_TR, c_val = VAL_TR, c_width = W_AUTO, c_span = 0;	memcpy(&l_col, bgcolor, sizeof(struct rgb));	*end = html;	if (bad_html) {		*bad_html = DUMMY;		*bhp = 0;	}	if (!(t = new_table())) return NULL;	se:	en = html;	see:	html = en;	if (bad_html && !p && !lbhp) {		if (!(*bhp & (ALLOC_GR-1))) {			if ((unsigned)*bhp > MAXINT / sizeof(struct s_e) - ALLOC_GR) overalloc();			*bad_html = mem_realloc(*bad_html, (*bhp + ALLOC_GR) * sizeof(struct s_e));		}		lbhp = (*bad_html)[(*bhp)++].s = html;	}	while (html < eof && *html != '<') html++;	if (html >= eof) {		if (p) CELL(t, x, y)->end = html;		if (lbhp) (*bad_html)[*bhp-1].e = html;		goto scan_done;	}	if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) {		html = skip_comment(html, eof);		goto se;	}	if (parse_element(html, eof, &t_name, &t_namelen, &t_attr, &en)) {		html++;		goto se;	}	if (t_namelen == 5 && !casecmp(t_name, "TABLE", 5)) {		en = skip_table(en, eof);		goto see;	}	if (t_namelen == 6 && !casecmp(t_name, "/TABLE", 6)) {		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);		if (p) CELL(t, x, y)->end = html;		if (lbhp) (*bad_html)[*bhp-1].e = html;		goto scan_done;	}	if (t_namelen == 8 && !casecmp(t_name, "COLGROUP", 8)) {		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;		c_al = AL_TR;		c_val = VAL_TR;		c_width = W_AUTO;		get_align(t_attr, &c_al);		get_valign(t_attr, &c_val);		get_c_width(t_attr, &c_width, sh);		if ((c_span = get_num(t_attr, "span")) == -1) c_span = 1;		goto see;	}	if (t_namelen == 9 && !casecmp(t_name, "/COLGROUP", 9)) {		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;		c_span = 0;		c_al = AL_TR;		c_val = VAL_TR;		c_width = W_AUTO;		goto see;	}	if (t_namelen == 3 && !casecmp(t_name, "COL", 3)) {		int sp, wi, al, val;		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;		if ((sp = get_num(t_attr, "span")) == -1) sp = 1;		wi = c_width;		al = c_al;		val = c_val;		get_align(t_attr, &al);		get_valign(t_attr, &val);		get_c_width(t_attr, &wi, sh);		new_columns(t, sp, wi, al, val, !!c_span);		c_span = 0;		goto see;	}	if (t_namelen == 3 && (!casecmp(t_name, "/TR", 3) || !casecmp(t_name, "/TD", 3) || !casecmp(t_name, "/TH", 3))) {		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);		if (p) CELL(t, x, y)->end = html, p = 0;		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;	}	if (t_namelen == 2 && !casecmp(t_name, "TR", 2)) {		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);		if (p) CELL(t, x, y)->end = html, p = 0;		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;		if (group) group--;		l_al = AL_LEFT;		l_val = VAL_MIDDLE;		memcpy(&l_col, bgcolor, sizeof(struct rgb));		get_align(t_attr, &l_al);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?