📄 html.c
字号:
menu_stack[menu_stack_size++] = nmenu; } if (!name) menu_stack_size--;}void init_menu(){ menu_stack_size = 0; menu_stack = DUMMY; new_menu_item(stracpy(""), -1, 0);}void free_menu(struct menu_item *m) /* Grrr. Recursion */{ struct menu_item *mm; for (mm = m; mm->text; mm++) { mem_free(mm->text); if (mm->func == MENU_FUNC do_select_submenu) free_menu(mm->data); } mem_free(m);}struct menu_item *detach_menu(){ struct menu_item *i = NULL; if (menu_stack_size) i = menu_stack[0]; if (menu_stack) mem_free(menu_stack); return i;}void destroy_menu(){ if (menu_stack && menu_stack != DUMMY) free_menu(menu_stack[0]); detach_menu();}void menu_labels(struct menu_item *m, unsigned char *base, unsigned char **lbls){ unsigned char *bs; for (; m->text; m++) { if (m->func == MENU_FUNC do_select_submenu) { if ((bs = stracpy(base))) { add_to_strn(&bs, m->text); add_to_strn(&bs, " "); menu_labels(m->data, bs, lbls); mem_free(bs); } } else { if ((bs = stracpy(m->hotkey[1] ? (unsigned char *)"" : base))) add_to_strn(&bs, m->text); lbls[(int)m->data] = bs; } }}int menu_contains(struct menu_item *m, int f){ if (m->func != MENU_FUNC do_select_submenu) return (int)m->data == f; for (m = m->data; m->text; m++) if (menu_contains(m, f)) return 1; return 0;}void do_select_submenu(struct terminal *term, struct menu_item *menu, struct session *ses){ struct menu_item *m; int def = get_current_state(ses); int sel = 0; if (def < 0) def = 0; for (m = menu; m->text; m++, sel++) if (menu_contains(m, def)) goto f; sel = 0; f: do_menu_selected(term, menu, ses, sel);}int do_html_select(unsigned char *attr, unsigned char *html, unsigned char *eof, unsigned char **end, void *f){ struct form_control *fc; unsigned char *t_name, *t_attr, *en; int t_namelen; unsigned char *lbl; int lbl_l; unsigned char *vlbl; int vlbl_l; int nnmi = 0; struct conv_table *ct = special_f(f, SP_TABLE, NULL); unsigned char **val, **lbls; int order, preselect, group; int i, mw; if (has_attr(attr, "multiple")) return 1; find_form_for_input(attr); lbl = NULL; lbl_l = 0; vlbl = NULL; vlbl_l = 0; val = DUMMY; order = 0, group = 0, preselect = -1; init_menu(); se: en = html; see: html = en; while (html < eof && *html != '<') html++; if (html >= eof) { int i; abort: *end = html; if (lbl) mem_free(lbl); if (vlbl) mem_free(vlbl); for (i = 0; i < order; i++) if (val[i]) mem_free(val[i]); mem_free(val); destroy_menu(); *end = en; return 0; } if (lbl) { unsigned char *q, *s = en; int l = html - en; while (l && WHITECHAR(s[0])) s++, l--; while (l && WHITECHAR(s[l-1])) l--; q = convert_string(ct, s, l); if (q) add_to_str(&lbl, &lbl_l, q), mem_free(q); add_bytes_to_str(&vlbl, &vlbl_l, s, l); } 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 == 7 && !casecmp(t_name, "/SELECT", 7)) { if (lbl) { if (!val[order - 1]) val[order - 1] = stracpy(vlbl); if (!nnmi) new_menu_item(lbl, order - 1, 1), lbl = NULL; else mem_free(lbl), lbl = NULL; mem_free(vlbl), vlbl = NULL; } goto end_parse; } if (t_namelen == 7 && !casecmp(t_name, "/OPTION", 7)) { if (lbl) { if (!val[order - 1]) val[order - 1] = stracpy(vlbl); if (!nnmi) new_menu_item(lbl, order - 1, 1), lbl = NULL; else mem_free(lbl), lbl = NULL; mem_free(vlbl), vlbl = NULL; } goto see; } if (t_namelen == 6 && !casecmp(t_name, "OPTION", 6)) { unsigned char *v, *vx; if (lbl) { if (!val[order - 1]) val[order - 1] = stracpy(vlbl); if (!nnmi) new_menu_item(lbl, order - 1, 1), lbl = NULL; else mem_free(lbl), lbl = NULL; mem_free(vlbl), vlbl = NULL; } if (has_attr(t_attr, "disabled")) goto see; if (preselect == -1 && has_attr(t_attr, "selected")) preselect = order; v = get_exact_attr_val(t_attr, "value"); if (!(order & (ALLOC_GR - 1))) { if ((unsigned)order > MAXINT / sizeof(unsigned char *) - ALLOC_GR) overalloc(); if ((unsigned)order > MAXINT / sizeof(char *) - ALLOC_GR) overalloc(); val = mem_realloc(val, (order + ALLOC_GR) * sizeof(unsigned char *)); } val[order++] = v; if ((vx = get_attr_val(t_attr, "label"))) { new_menu_item(convert_string(ct, vx, strlen(vx)), order - 1, 0); mem_free(vx); } if (!v || !vx) { lbl = init_str(), lbl_l = 0; vlbl = init_str(), vlbl_l = 0; nnmi = !!vx; } goto see; } if ((t_namelen == 8 && !casecmp(t_name, "OPTGROUP", 8)) || (t_namelen == 9 && !casecmp(t_name, "/OPTGROUP", 9))) { if (lbl) { if (!val[order - 1]) val[order - 1] = stracpy(vlbl); if (!nnmi) new_menu_item(lbl, order - 1, 1), lbl = NULL; else mem_free(lbl), lbl = NULL; mem_free(vlbl), vlbl = NULL; } if (group) new_menu_item(NULL, -1, 0), group = 0; } if (t_namelen == 8 && !casecmp(t_name, "OPTGROUP", 8)) { char *la; if (!(la = get_attr_val(t_attr, "label"))) la = stracpy(""); new_menu_item(convert_string(ct, la, strlen(la)), -1, 0); mem_free(la); group = 1; } goto see; end_parse: *end = en; if (!order) goto abort; fc = mem_alloc(sizeof(struct form_control)); memset(fc, 0, sizeof(struct form_control)); lbls = mem_alloc(order * sizeof(char *)); memset(lbls, 0, order * sizeof(char *)); fc->form_num = last_form_tag - startf; fc->ctrl_num = attr - last_form_tag; fc->position = attr - startf; fc->method = form.method; fc->action = stracpy(form.action); fc->name = get_attr_val(attr, "name"); fc->type = FC_SELECT; fc->default_state = preselect < 0 ? 0 : preselect; fc->default_value = order ? stracpy(val[fc->default_state]) : stracpy(""); fc->ro = has_attr(attr, "disabled") ? 2 : has_attr(attr, "readonly") ? 1 : 0; fc->nvalues = order; fc->values = val; fc->menu = detach_menu(); fc->labels = lbls; menu_labels(fc->menu, "", lbls); put_chrs("[", 1, put_chars_f, f); html_stack_dup(); format.form = fc; format.attr |= AT_BOLD; mw = 0; for (i = 0; i < order; i++) if (lbls[i] && strlen(lbls[i]) > (size_t)mw) mw = strlen(lbls[i]); for (i = 0; i < mw; i++) put_chrs("_", 1, put_chars_f, f); kill_html_stack_item(&html_top); put_chrs("]", 1, put_chars_f, f); special_f(ff, SP_CONTROL, fc); return 0;}void html_textarea(unsigned char *a){ internal("This should be never called");}void do_html_textarea(unsigned char *attr, unsigned char *html, unsigned char *eof, unsigned char **end, void *f){ struct form_control *fc; unsigned char *p, *t_name, *w; int t_namelen; int cols, rows; int i; find_form_for_input(attr); while (html < eof && (*html == '\n' || *html == '\r')) html++; p = html; while (p < eof && *p != '<') { pp: p++; } if (p >= eof) { *end = eof; return; } if (parse_element(p, eof, &t_name, &t_namelen, NULL, end)) goto pp; if (t_namelen != 9 || casecmp(t_name, "/TEXTAREA", 9)) goto pp; fc = mem_alloc(sizeof(struct form_control)); memset(fc, 0, sizeof(struct form_control)); fc->form_num = last_form_tag - startf; fc->ctrl_num = attr - last_form_tag; fc->position = attr - startf; fc->method = form.method; fc->action = stracpy(form.action); fc->name = get_attr_val(attr, "name"); fc->type = FC_TEXTAREA;; fc->ro = has_attr(attr, "disabled") ? 2 : has_attr(attr, "readonly") ? 1 : 0; fc->default_value = memacpy(html, p - html); if ((cols = get_num(attr, "cols")) <= 0) cols = HTML_DEFAULT_TEXTAREA_WIDTH; cols++; if ((rows = get_num(attr, "rows")) <= 0) rows = HTML_DEFAULT_TEXTAREA_HEIGHT; if (cols > d_opt->xw) cols = d_opt->xw; if (rows > d_opt->yw) rows = d_opt->yw; fc->cols = cols; fc->rows = rows; fc->wrap = 1; if ((w = get_attr_val(attr, "wrap"))) { if (!strcasecmp(w, "hard") || !strcasecmp(w, "physical")) fc->wrap = 2; else if (!strcasecmp(w, "off")) fc->wrap = 0; mem_free(w); } if ((fc->maxlength = get_num(attr, "maxlength")) == -1) fc->maxlength = MAXINT / 4; if (rows > 1) ln_break(1, line_break_f, f); else put_chrs(" ", 1, put_chars_f, f); html_stack_dup(); format.form = fc; format.attr |= AT_BOLD; for (i = 0; i < rows; i++) { int j; for (j = 0; j < cols; j++) put_chrs("_", 1, put_chars_f, f); if (i < rows - 1) ln_break(1, line_break_f, f); } kill_html_stack_item(&html_top); if (rows > 1) ln_break(1, line_break_f, f); else put_chrs(" ", 1, put_chars_f, f); special_f(f, SP_CONTROL, fc);}void html_iframe(unsigned char *a){ unsigned char *name, *url; if (!(url = get_url_val(a, "src"))) return; if (!(name = get_attr_val(a, "name"))) name = stracpy(""); if (*name) put_link_line("IFrame: ", name, url, d_opt->framename); else put_link_line("", "IFrame", url, d_opt->framename); mem_free(name); mem_free(url);}void html_noframes(unsigned char *a){ if (d_opt->frames) html_skip(a);}void html_frame(unsigned char *a){ unsigned char *name, *u2, *url; if (!(u2 = get_url_val(a, "src"))) { url = stracpy(""); } else { url = join_urls(format.href_base, u2); mem_free(u2); } if (!url) return; name = get_attr_val (a, "name"); if (!name) name = stracpy(url); else if (!name[0]) { /* When name doesn't have a value */ mem_free(name); name = stracpy(url); } if (!d_opt->frames || !html_top.frameset) put_link_line("Frame: ", name, url, ""); else { struct frame_param fp; fp.name = name; fp.url = url; fp.parent = html_top.frameset; if (special_f(ff, SP_USED, NULL)) special_f(ff, SP_FRAME, &fp); } mem_free(name); mem_free(url);}void parse_frame_widths(unsigned char *a, int ww, int www, int **op, int *olp){ unsigned char *aa; int q, qq, i, d, nn; unsigned long n; int *oo, *o; int ol; ol = 0; o = DUMMY; new_ch: while (WHITECHAR(*a)) a++; n = strtoul(a, (char **)(void *)&a, 10); if (n > 10000) n = 10000; q = n; if (*a == '%') q = q * ww / 100; else if (*a != '*') q = (q + (www - 1) / 2) / (www ? www : 1); else if (!(q = -q)) q = -1; if ((unsigned)ol > MAXINT / sizeof(int) - 1) overalloc(); o = mem_realloc(o, (ol + 1) * sizeof(int)); o[ol++] = q; if ((aa = strchr(a, ','))) { a = aa + 1; goto new_ch; } *op = o; *olp = ol; q = 2 * ol - 1; for (i = 0; i < ol; i++) if (o[i] > 0) q += o[i] - 1; if (q >= ww) { distribute: for (i = 0; i < ol; i++) if (o[i] < 1) o[i] = 1; q -= ww; d = 0; for (i = 0; i < ol; i++) d += o[i]; qq = q; for (i = 0; i < ol; i++) { q -= o[i] - o[i] * (d - qq) / (d ? d : 1); do_not_optimize_here(&d); /* SIGH! gcc 2.7.2.* has an optimizer bug! */ o[i] = o[i] * (d - qq) / (d ? d : 1); } while (q) { nn = 0; for (i = 0; i < ol; i++) { if (q < 0) o[i]++, q++, nn = 1; if (q > 0 && o[i] > 1) o[i]--, q--, nn = 1; if (!q) break; } if (!nn) break; } } else { int nn = 0; for (i = 0; i < ol; i++) if (o[i] < 0) nn = 1; if (!nn) goto distribute; if ((unsigned)ol > MAXINT / sizeof(int)) overalloc(); oo = mem_alloc(ol * sizeof(int)); memcpy(oo, o, ol * sizeof(int)); for (i = 0; i < ol; i++) if (o[i] < 1) o[i] = 1; q = ww - q; d = 0; for (i = 0; i < ol; i++) if (oo[i] < 0) d += -oo[i]; qq = q; for (i = 0; i < ol; i++) if (oo[i] < 0) { o[i] += (-oo[i] * qq / (d ? d : 1)); q -= (-oo[i] * qq / (d ? d : 1)); } if (q < 0) { q = 0; /*internal("parse_frame_widths: q < 0"); may happen when page contains too big values */ } for (i = 0; i < ol; i++) if (oo[i] < 0) { if (q) o[i]++, q--; } if (q > 0) { q = 0; /*internal("parse_frame_widths: q > 0"); may happen when page contains too big values */ } mem_free(oo); } for (i = 0; i < ol; i++) if (!o[i]) { int j; int m = 0; int mj = 0; for (j = 0; j < ol; j++) if (o[j] > m) m = o[j], mj = j; if (m) o[i] = 1, o[mj]--; }}void html_frameset(unsigned char *a){ int x, y; struct frameset_param fp; unsigned char *c, *d; if (!d_opt->frames || !special_f(ff, SP_USED, NULL)) return; if (!(c = get_attr_val(a, "cols"))) c = stracpy("100%"); if (!(d = get_attr_val(a, "rows"))) d = stracpy("100%"); if (!html_top.frameset) { x = d_opt->xw; y = d_opt->yw; } else { struct frameset_desc *f = html_top.frameset; if (f->yp >= f->y) goto free_cd; x = f->f[f->xp + f->yp * f->x].xw; y = f->f[f->xp + f->yp * f->x].yw; } parse_frame_widths(c, x, HTML_FRAME_CHAR_WIDTH, &fp.xw, &fp.x); parse_frame_widths(d, y, HTML_FRAME_CHAR_HEIGHT, &fp.yw, &fp.y); fp.parent = html_top.frameset; if (fp.x && fp.y) html_top.frameset = special_f(ff, SP_FRAMESET, &fp); mem_free(fp.xw); mem_free(fp.yw); free_cd: mem_free(c); mem_free(d);}/*void html_frameset(unsigned char *a){ int w; int horiz = 0; struct frameset_param *fp; unsigned char *c, *d; if (!d_opt->frames || !special_f(ff, SP_USED, NULL)) return; if (!(c = get_attr_val(a, "cols"))) { horiz = 1; if (!(c = get_attr_val(a, "rows"))) return; } fp = mem_alloc(sizeof(struct frameset_param)); fp->n = 0; fp->horiz = horiz; par_format.leftmargin = par_format.rightmargin = 0; d = c; while (1) { while (WHITECHAR(*d)) d++; if (!*d) break; if (*d == ',') { d++; continue; } if ((w = parse_width(d, 1)) != -1) { if ((unsigned)fp->n > (MAXINT - sizeof(struct frameset_param)) / sizeof(int) - 1) overalloc(); fp = mem_realloc(fp, sizeof(struct frameset_param) + (fp->n + 1) * sizeof(int)); fp->width[fp->n++] = w; } if (!(d = strchr(d, ','))) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -