コード例 #1
0
ファイル: dialogs.c プロジェクト: rkd77/elinks-tv
static unsigned char *
get_auth_entry_info(struct listbox_item *item, struct terminal *term)
{
	struct auth_entry *auth_entry = (struct auth_entry *)item->udata;
	struct string info;

	if (item->type == BI_FOLDER) return NULL;
	if (!init_string(&info)) return NULL;

	add_format_to_string(&info, "%s: ", _("URL", term));
	add_uri_to_string(&info, auth_entry->uri, URI_HTTP_AUTH);

	add_format_to_string(&info, "\n%s: ", _("Realm", term));
	if (auth_entry->realm) {
		int len = strlen((const char *)auth_entry->realm);
		int maxlen = 512; /* Max. number of chars displayed for realm. */

		if (len < maxlen)
			add_bytes_to_string(&info, auth_entry->realm, len);
		else {
			add_bytes_to_string(&info, auth_entry->realm, maxlen);
			add_to_string(&info, (const unsigned char *)"...");
		}
	} else {
		add_to_string(&info, _("none", term));
	}

	add_format_to_string(&info, "\n%s: %s\n", _("State", term),
		auth_entry->valid ? _("valid", term) : _("invalid", term));

	return info.source;
}
コード例 #2
0
ファイル: conv.c プロジェクト: rkd77/elinks-tv
/** @relates string */
struct string *
add_knum_to_string(struct string *string, long long num)
{
	int ret;
	unsigned char t[64];
	int tlen = 0;

	if (num && (num / (1024 * 1024)) * (1024 * 1024) == num) {
		ret = longcat(&t, &tlen, num / (1024 * 1024), sizeof(t) - 2, 0);
		t[tlen++] = 'M';
		t[tlen] = '\0';
	} else if (num && (num / 1024) * 1024 == num) {
		ret = longcat(&t, &tlen, num / 1024, sizeof(t) - 2, 0);
		t[tlen++] = 'k';
		t[tlen] = '\0';
	} else {
		ret = longcat(&t, &tlen, num, sizeof(t) - 1, 0);
	}

	if (ret < 0 || !tlen) return NULL;

	add_bytes_to_string(string, t, tlen);

	return string;
}
コード例 #3
0
ファイル: conv.c プロジェクト: rkd77/elinks-tv
struct string *
add_cp_html_to_string(struct string *string, int src_codepage,
		      const unsigned char *src, int len)
{
	const unsigned char *const end = src + len;
	unicode_val_T unicode;

	for (;;) {
		unicode = cp_to_unicode(src_codepage,
					(unsigned char **) &src, end);
		if (unicode == UCS_NO_CHAR)
			break;

		if (unicode < 0x20 || unicode >= 0x7F
		    || unicode == '<' || unicode == '>' || unicode == '&'
		    || unicode == '\"' || unicode == '\'') {
			int rollback_length = string->length;

			if (!add_bytes_to_string(string, (const unsigned char *)"&#", 2)
			    || !add_long_to_string(string, unicode)
			    || !add_char_to_string(string, ';')) {
				string->length = rollback_length;
				string->source[rollback_length] = '\0';
				return NULL;
			}
		} else {
			if (!add_char_to_string(string, unicode))
				return NULL;
		}
	}

	return string;
}
コード例 #4
0
ファイル: screen.c プロジェクト: rkd77/elinks-tv
static inline void
add_char_color(struct string *screen, const struct string *seq, unsigned char color)
{
	unsigned char color_buf[3];
	unsigned char *color_pos = color_buf;
	int seq_pos = 0;
       	int color_len = 1;

	check_string_magic(seq);
	for (; seq->source[seq_pos] != '%'; seq_pos++) ;

	add_bytes_to_string(screen, seq->source, seq_pos);

	if (color < 10) {
		color_pos += 2;
	} else {
		int color2;

		++color_len;
		if (color < 100) {
			++color_pos;
		} else {
			++color_len;

			if (color < 200) {
				color_buf[0] = '1';
				color -= 100;
			} else {
				color_buf[0] = '2';
				color -= 200;
			}
		}

		color2 = (color % 10);
		color /= 10;
		color_buf[1] = '0' + color;
		color = color2;
	}

	color_buf[2] = '0' + color;

	add_bytes_to_string(screen, color_pos, color_len);

	seq_pos += 2; /* Skip "%d" */
	add_bytes_to_string(screen, &seq->source[seq_pos], seq->length - seq_pos);
}
コード例 #5
0
ファイル: conv.c プロジェクト: rkd77/elinks-tv
struct string *
add_string_replace(struct string *string, unsigned char *src, int len,
		   unsigned char replaceable, unsigned char replacement)
{
	int oldlength = string->length;

	if (!add_bytes_to_string(string, src, len))
		return NULL;

	for (src = string->source + oldlength; len; len--, src++)
		if (*src == replaceable)
			*src = replacement;

	return string;
}
コード例 #6
0
ファイル: conv.c プロジェクト: rkd77/elinks-tv
/** @relates string */
struct string *
add_long_to_string(struct string *string, long long number)
{
	unsigned char buffer[64];
	int length = 0;
	int width;

	assert(string);
	if_assert_failed { return NULL; }

	width = longcat(buffer, &length, number, sizeof(buffer) - 1, 0);
	if (width < 0 || !length) return NULL;

	return add_bytes_to_string(string, buffer, length);
}
コード例 #7
0
ファイル: core.c プロジェクト: UNIVERSAL-IT-SYSTEMS/elinks-1
/* The global Kernel::p method will for each object, directly write
 * object.inspect() followed by the current output record separator to the
 * program's standard output and will bypass the Ruby I/O libraries.
 *
 * Inspired by Vim we hook into the method and pop up a nice message box so it
 * can be used to easily debug scripts without dirtying the screen. */
static VALUE
erb_stdout_p(int argc, VALUE *argv, VALUE self)
{
	int i;
	struct string string;
	struct terminal *term;

	if (!init_string(&string))
		return Qnil;

	for (i = 0; i < argc; i++) {
		VALUE substr;
		unsigned char *ptr;
		int len;

		if (i > 0)
			add_to_string(&string, ", ");

		substr = rb_inspect(argv[i]);

		/* The Ruby p() function writes variable number of objects using
		 * the inspect() method, which adds quotes to the strings, so
		 * gently ignore them. */

		ptr = RSTRING(substr)->ptr;
		len = RSTRING(substr)->len;

		if (*ptr == '"')
			ptr++, len--;

		if (ptr[len - 1] == '"')
			len--;

		add_bytes_to_string(&string, ptr, len);
	}

	term = get_default_terminal();
	if (!term) {
		usrerror("[Ruby] %s", string.source);
		done_string(&string);
		return Qnil;
	}

	info_box(term, MSGBOX_NO_TEXT_INTL | MSGBOX_FREE_TEXT,
		N_("Ruby Message"), ALIGN_LEFT, string.source);

	return Qnil;
}
コード例 #8
0
ファイル: screen.c プロジェクト: rkd77/elinks-tv
static inline void
add_char_true_color(struct string *screen, const struct string *seq, unsigned char *colors)
{
	unsigned char color_buf[3];
	int i;

	check_string_magic(seq);
	add_string_to_string(screen, seq);
	for (i = 0; i < 3; i++) {
		unsigned char *color_pos = color_buf;
		int color_len = 1;
		unsigned char color = colors[i];

		add_char_to_string(screen, ';');

		if (color < 10) {
			color_pos += 2;
		} else {
			int color2;

			++color_len;
			if (color < 100) {
				++color_pos;
			} else {
				++color_len;

				if (color < 200) {
					color_buf[0] = '1';
					color -= 100;
				} else {
					color_buf[0] = '2';
					color -= 200;
				}
			}

			color2 = (color % 10);
			color /= 10;
			color_buf[1] = '0' + color;
			color = color2;
		}
		color_buf[2] = '0' + color;

		add_bytes_to_string(screen, color_pos, color_len);
	}
	add_char_to_string(screen, 'm');
}
コード例 #9
0
ファイル: stack.c プロジェクト: rkd77/elinks-tv
/* Compress a string to a single line with newlines etc. replaced with "\\n"
 * sequence. */
static inline unsigned char *
compress_string(unsigned char *string, unsigned int length)
{
	struct string buffer;
	unsigned char escape[2] = "\\";

	if (!init_string(&buffer)) return NULL;

	for (; length > 0; string++, length--) {
		unsigned char *bytes = string;

		if (*string == '\n' || *string == '\r' || *string == '\t') {
			bytes	  = escape;
			escape[1] = *string == '\n' ? 'n'
				  : (*string == '\r' ? 'r' : 't');
		}

		add_bytes_to_string(&buffer, bytes, bytes == escape ? 2 : 1);
	}

	return buffer.source;
}
コード例 #10
0
ファイル: screen.c プロジェクト: rkd77/elinks-tv
/** Adds the term code for positioning the cursor at @a x and @a y to
 * @a string.  The template term code is: "\033[<y>;<x>H" */
static inline struct string *
add_cursor_move_to_string(struct string *screen, int y, int x)
{
#define CURSOR_NUM_LEN 10 /* 10 chars for @y and @x numbers should be more than enough. */
	unsigned char code[4 + 2 * CURSOR_NUM_LEN + 1];
	unsigned int length = 2;

	code[0] = '\033';
	code[1] = '[';

	if (ulongcat(code, &length, y, CURSOR_NUM_LEN, 0) < 0)
		return screen;

	code[length++] = ';';

	if (ulongcat(code, &length, x, CURSOR_NUM_LEN, 0) < 0)
		return screen;

	code[length++] = 'H';

	return add_bytes_to_string(screen, code, length);
#undef CURSOR_NUM_LEN
}
コード例 #11
0
ファイル: conv.c プロジェクト: rkd77/elinks-tv
struct string *
add_html_to_string(struct string *string, const unsigned char *src, int len)
{
	for (; len; len--, src++) {
		if (*src < 0x20
		    || *src == '<' || *src == '>' || *src == '&'
		    || *src == '\"' || *src == '\'') {
			int rollback_length = string->length;

			if (!add_bytes_to_string(string, (const unsigned char *)"&#", 2)
			    || !add_long_to_string(string, (long long)*src)
			    || !add_char_to_string(string, ';')) {
				string->length = rollback_length;
				string->source[rollback_length] = '\0';
				return NULL;
			}
		} else {
			if (!add_char_to_string(string, *src))
				return NULL;
		}
	}

	return string;
}
コード例 #12
0
ファイル: screen.c プロジェクト: rkd77/elinks-tv
/** Time critical section. */
static inline void
add_char256(struct string *screen, struct screen_driver *driver,
	    struct screen_char *ch, struct screen_state *state)
{
	unsigned char attr_delta = (ch->attr ^ state->attr);

	if (
#ifdef CONFIG_UTF8
	    !(driver->opt.utf8_cp && ch->data == UCS_NO_CHAR) &&
#endif /* CONFIG_UTF8 */
	    attr_delta
	   ) {
		if ((attr_delta & SCREEN_ATTR_FRAME) && driver->opt.frame_seqs) {
			state->border = !!(ch->attr & SCREEN_ATTR_FRAME);
			add_term_string(screen, driver->opt.frame_seqs[state->border]);
		}

		if ((attr_delta & SCREEN_ATTR_ITALIC) && driver->opt.italic) {
			state->italic = !!(ch->attr & SCREEN_ATTR_ITALIC);
			add_term_string(screen, driver->opt.italic[state->italic]);
		}

		if ((attr_delta & SCREEN_ATTR_UNDERLINE) && driver->opt.underline) {
			state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE);
			add_term_string(screen, driver->opt.underline[state->underline]);
		}

		if (attr_delta & SCREEN_ATTR_BOLD) {
			if (ch->attr & SCREEN_ATTR_BOLD) {
				add_bytes_to_string(screen, "\033[1m", 4);
			} else {
				/* Force repainting of the other attributes. */
				state->color[0] = ch->c.color[0] + 1;
			}
		}

		state->attr = ch->attr;
	}

	if (
#ifdef CONFIG_UTF8
	    !(driver->opt.utf8_cp && ch->data == UCS_NO_CHAR) &&
#endif /* CONFIG_UTF8 */
	    !compare_color_256(ch->c.color, state->color)
	   ) {
		copy_color_256(state->color, ch->c.color);

		add_foreground_color(screen, driver->opt.color256_seqs, ch);
		if (!driver->opt.transparent || ch->c.color[1] != 0) {
			add_background_color(screen, driver->opt.color256_seqs, ch);
		}

		if (ch->attr & SCREEN_ATTR_BOLD)
			add_bytes_to_string(screen, "\033[1m", 4);

		if (ch->attr & SCREEN_ATTR_ITALIC && driver->opt.italic) {
			state->italic = !!(ch->attr & SCREEN_ATTR_ITALIC);
			add_term_string(screen, driver->opt.italic[state->italic]);
		}

		if (ch->attr & SCREEN_ATTR_UNDERLINE && driver->opt.underline) {
			state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE);
			add_term_string(screen, driver->opt.underline[state->underline]);
		}
	}

	add_char_data(screen, driver, ch->data, ch->attr & SCREEN_ATTR_FRAME);
}
コード例 #13
0
ファイル: conf.c プロジェクト: UNIVERSAL-IT-SYSTEMS/elinks-1
static enum parse_error
parse_unset(struct option *opt_tree, struct conf_parsing_state *state,
	    struct string *mirror, int is_system_conf)
{
	const unsigned char *optname_orig;
	size_t optname_len;
	unsigned char *optname_copy;

	skip_white(&state->pos);
	if (!*state->pos.look) return show_parse_error(state, ERROR_PARSE);

	/* Option name */
	optname_orig = state->pos.look;
	while (is_option_name_char(*state->pos.look)
	       || *state->pos.look == '.')
		state->pos.look++;
	optname_len = state->pos.look - optname_orig;

	optname_copy = memacpy(optname_orig, optname_len);
	if (!optname_copy) return show_parse_error(state, ERROR_NOMEM);

	{
		struct option *opt;

		opt = get_opt_rec_real(opt_tree, optname_copy);
		mem_free(optname_copy);
		optname_copy = NULL;

		if (!opt || (opt->flags & OPT_HIDDEN)) {
			/* The user wanted to delete the option, and
			 * it has already been deleted; this is not an
			 * error.  This might happen if a version of
			 * ELinks has a built-in URL rewriting rule,
			 * the user disables it, and a later version
			 * no longer has it.  */
			return ERROR_NONE;
		}

		if (!mirror) {
			/* loading a configuration file */
			if (opt->flags & OPT_ALLOC) delete_option(opt);
			else mark_option_as_deleted(opt);
		} else if (is_system_conf) {
			/* scanning a file that will not be rewritten */
			struct option *flagsite = indirect_option(opt);

			if (flagsite->flags & OPT_DELETED)
				flagsite->flags &= ~OPT_MUST_SAVE;
			else
				flagsite->flags |= OPT_MUST_SAVE;
		} else {
			/* rewriting a configuration file */
			struct option *flagsite = indirect_option(opt);

			if (flagsite->flags & OPT_DELETED) {
				/* The "unset" command is already in the file,
				 * and unlike with "set", there is no value
				 * to be updated.  */
			} else if (option_types[opt->type].write) {
				/* Replace the "unset" command with a
				 * "set" command.  */
				add_to_string(mirror, "set ");
				add_bytes_to_string(mirror, optname_orig,
						    optname_len);
				add_to_string(mirror, " = ");
				option_types[opt->type].write(opt, mirror);
				state->mirrored = state->pos.look;
			}
			/* Remember that the option need not be
			 * written to the end of the file.  */
			flagsite->flags &= ~OPT_MUST_SAVE;
		}
	}

	return ERROR_NONE;
}
コード例 #14
0
ファイル: common.c プロジェクト: rkd77/elinks-tv
struct connection_state
init_directory_listing(struct string *page, struct uri *uri)
{
	struct string dirpath = NULL_STRING;
	struct string decoded = NULL_STRING;
	struct string location = NULL_STRING;
	unsigned char *info;
	int local = (uri->protocol == PROTOCOL_FILE);

	if (!init_string(page)
	    || !init_string(&dirpath)
	    || !init_string(&decoded)
	    || !init_string(&location)
	    || !add_uri_to_string(&dirpath, uri, URI_DATA)
	    || !add_uri_to_string(&location, uri, URI_DIR_LOCATION))
		goto out_of_memory;

	if (dirpath.length > 0
	    && !dir_sep(dirpath.source[dirpath.length - 1])
	    && !add_char_to_string(&dirpath, local ? CHAR_DIR_SEP : '/'))
		goto out_of_memory;

	/* Decode uri for displaying.  */
	if (!add_string_to_string(&decoded, &dirpath))
		goto out_of_memory;
	decode_uri_string(&decoded);

	if (!local && !add_char_to_string(&location, '/'))
		goto out_of_memory;

	if (!add_to_string(page, (const unsigned char *)"<html>\n<head><title>"))
		goto out_of_memory;

	if (!local && !add_html_to_string(page, location.source, location.length))
		goto out_of_memory;

	if (!add_html_to_string(page, decoded.source, decoded.length)
	    || !add_to_string(page, (const unsigned char *)"</title>\n<base href=\"")
	    || !add_html_to_string(page, location.source, location.length)
	    || !add_html_to_string(page, dirpath.source, dirpath.length))
		goto out_of_memory;

	if (!add_to_string(page, (const unsigned char *)"\" />\n</head>\n<body>\n<h2>"))
		goto out_of_memory;

	/* Use module names? */
	switch (uri->protocol) {
	case PROTOCOL_FILE:
		info = (unsigned char *)"Local";
		break;
	case PROTOCOL_FSP:
		info = (unsigned char *)"FSP";
		break;
	case PROTOCOL_FTP:
		info = (unsigned char *)"FTP";
		break;
	case PROTOCOL_GOPHER:
		info = (unsigned char *)"Gopher";
		break;
	case PROTOCOL_SMB:
		info = (unsigned char *)"Samba";
		break;
	default:
		info = (unsigned char *)"?";
	}

	if (!add_to_string(page, info)
	    || !add_to_string(page, (const unsigned char *)" directory "))
		goto out_of_memory;

	if (!local && !add_string_to_string(page, &location))
		goto out_of_memory;

	/* Make the directory path with links to each subdir. */
	{
		const unsigned char *slash = dirpath.source;
		const unsigned char *pslash = slash;
		const unsigned char sep = local ? CHAR_DIR_SEP :  '/';

		while ((slash = (const unsigned char *)strchr((char *)slash, sep)) != NULL) {
			done_string(&decoded);
			if (!init_string(&decoded)
			    || !add_bytes_to_string(&decoded, pslash, slash - pslash))
				goto out_of_memory;
			decode_uri_string(&decoded);

			if (!add_to_string(page, (const unsigned char *)"<a href=\"")
			    || !add_html_to_string(page, location.source, location.length)
			    || !add_html_to_string(page, dirpath.source, slash + 1 - dirpath.source)
			    || !add_to_string(page, (const unsigned char *)"\">")
			    || !add_html_to_string(page, decoded.source, decoded.length)
			    || !add_to_string(page, (const unsigned char *)"</a>")
			    || !add_html_to_string(page, &sep, 1))
				goto out_of_memory;

			pslash = ++slash;
		}
	}

	if (!add_to_string(page, (const unsigned char *)"</h2>\n<pre>")) {
out_of_memory:
		done_string(page);
	}

	done_string(&dirpath);
	done_string(&decoded);
	done_string(&location);

	return page->length > 0
		? connection_state(S_OK)
		: connection_state(S_OUT_OF_MEM);
}
コード例 #15
0
ファイル: rewrite.c プロジェクト: matthiasbeyer/elinks
static unsigned char *
rewrite_uri(unsigned char *url, struct uri *current_uri, unsigned char *arg)
{
	struct string n = NULL_STRING;
	unsigned char *args[MAX_URI_ARGS];
	int argslen[MAX_URI_ARGS];
	int argc = 0;
	int i;

	if (!init_string(&n)) return NULL;

	/* Extract space separated list of arguments */
	args[argc] = arg;
	for (i = 0; ; i++) {
		if (args[argc][i] == ' ') {
			argslen[argc] = i;
			argc++;
			if (argc == MAX_URI_ARGS) break;
			args[argc] = &args[argc - 1][i];
			i = 0;
			for (; *args[argc] == ' '; args[argc]++);
		} else if (!args[argc][i]) {
			argslen[argc] = i;
			argc++;
			break;
		}
	}

	while (*url) {
		int p;
		int value;

		for (p = 0; url[p] && url[p] != '%'; p++);

		add_bytes_to_string(&n, url, p);
		url += p;

		if (*url != '%') continue;

		url++;
		switch (*url) {
			case 'c':
				if (!current_uri) break;
				add_uri_to_string(&n, current_uri, URI_ORIGINAL);
				break;
			case 's':
				if (arg) encode_uri_string(&n, arg, -1, 1);
				break;
			case '%':
				add_char_to_string(&n, '%');
				break;
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				value = *url - '0';
				if (value >= argc) break;
				encode_uri_string(&n, args[value],
						  argslen[value], 1);
				break;
			default:
				add_bytes_to_string(&n, url - 1, 2);
				break;
		}
		if (*url) url++;
	}

	return n.source;
}
コード例 #16
0
ファイル: forms.c プロジェクト: rkd77/elinks-tv
static void
do_html_select(unsigned char *attr, unsigned char *html,
	       unsigned char *eof, unsigned char **end,
	       struct html_context *html_context)
{
	struct conv_table *ct = (struct conv_table *)html_context->special_f(html_context, SP_TABLE, NULL);
	struct form_control *fc;
	struct string lbl = NULL_STRING, orig_lbl = NULL_STRING;
	unsigned char **values = NULL;
	unsigned char **labels;
	unsigned char *name, *t_attr, *en;
	int namelen;
	int nnmi = 0;
	int order = 0;
	int preselect = -1;
	int group = 0;
	int i, max_width;
	int closing_tag;

	html_focusable(html_context, attr);
	init_menu(&lnk_menu);

se:
        en = html;

see:
        html = en;
	while (html < eof && *html != '<') html++;

	if (html >= eof) {

abort:
		*end = html;
		if (lbl.source) done_string(&lbl);
		if (orig_lbl.source) done_string(&orig_lbl);
		if (values) {
			int j;

			for (j = 0; j < order; j++)
				mem_free_if(values[j]);
			mem_free(values);
		}
		destroy_menu(&lnk_menu);
		*end = en;
		return;
	}

	if (lbl.source) {
		unsigned char *q, *s = en;
		int l = html - en;

		while (l && isspace(s[0])) s++, l--;
		while (l && isspace(s[l-1])) l--;
		q = convert_string(ct, s, l,
		                   html_context->options->cp,
		                   CSM_DEFAULT, NULL, NULL, NULL);
		if (q) add_to_string(&lbl, q), mem_free(q);
		add_bytes_to_string(&orig_lbl, s, l);
	}

	if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) {
		html = skip_comment(html, eof);
		goto se;
	}

	if (parse_element(html, eof, &name, &namelen, &t_attr, &en)) {
		html++;
		goto se;
	}

	if (!namelen) goto see;

	if (name[0] == '/') {
		namelen--;
		if (!namelen) goto see;
		name++;
		closing_tag = 1;
	} else {
		closing_tag = 0;
	}

	if (closing_tag && !c_strlcasecmp(name, namelen, (const unsigned char *)"SELECT", 6)) {
		add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi);
		goto end_parse;
	}

	if (!c_strlcasecmp(name, namelen, (const unsigned char *)"OPTION", 6)) {
		add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi);

		if (!closing_tag) {
			unsigned char *value, *label;

			if (has_attr(t_attr, (unsigned char *)"disabled", html_context->doc_cp))
				goto see;
			if (preselect == -1
			    && has_attr(t_attr, (unsigned char *)"selected", html_context->doc_cp))
				preselect = order;
			value = get_attr_val(t_attr, (unsigned char *)"value", html_context->doc_cp);

			if (!mem_align_alloc(&values, order, order + 1, 0xFF))
				goto abort;

			values[order++] = value;
			label = get_attr_val(t_attr, (unsigned char *)"label", html_context->doc_cp);
			if (label) new_menu_item(&lnk_menu, label, order - 1, 0);
			if (!value || !label) {
				init_string(&lbl);
				init_string(&orig_lbl);
				nnmi = !!label;
			}
		}

		goto see;
	}

	if (!c_strlcasecmp(name, namelen, (const unsigned char *)"OPTGROUP", 8)) {
		add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi);

		if (group) new_menu_item(&lnk_menu, NULL, -1, 0), group = 0;

		if (!closing_tag) {
			unsigned char *label;

			label = get_attr_val(t_attr, (unsigned char *)"label", html_context->doc_cp);

			if (!label) {
				label = stracpy((const unsigned char *)"");
				if (!label) goto see;
			}
			new_menu_item(&lnk_menu, label, -1, 0);
			group = 1;
		}
	}

	goto see;


end_parse:
	*end = en;
	if (!order) goto abort;

	labels = (unsigned char **)mem_calloc(order, sizeof(unsigned char *));
	if (!labels) goto abort;

	fc = init_form_control(FC_SELECT, attr, html_context);
	if (!fc) {
		mem_free(labels);
		goto abort;
	}

	fc->id = get_attr_val(attr, (unsigned char *)"id", html_context->doc_cp);
	fc->name = get_attr_val(attr, (unsigned char *)"name", html_context->doc_cp);
	fc->default_state = preselect < 0 ? 0 : preselect;
	fc->default_value = order ? stracpy(values[fc->default_state]) : stracpy((const unsigned char *)"");
	fc->nvalues = order;
	fc->values = values;
	fc->menu = detach_menu(&lnk_menu);
	fc->labels = labels;

	menu_labels(fc->menu, (unsigned char *)"", labels);
	put_chrs(html_context, (unsigned char *)"[", 1);
	html_stack_dup(html_context, ELEMENT_KILLABLE);
	format.form = fc;
	format.style.attr |= AT_BOLD;

	max_width = 0;
	for (i = 0; i < order; i++) {
		if (!labels[i]) continue;
#ifdef CONFIG_UTF8
		if (html_context->options->utf8)
			int_lower_bound(&max_width,
					utf8_ptr2cells(labels[i], NULL));
		else
#endif /* CONFIG_UTF8 */
			int_lower_bound(&max_width, strlen((const char *)labels[i]));
	}

	for (i = 0; i < max_width; i++)
		put_chrs(html_context, (unsigned char *)"_", 1);

	pop_html_element(html_context);
	put_chrs(html_context, (unsigned char *)"]", 1);
	html_context->special_f(html_context, SP_CONTROL, fc);
}
コード例 #17
0
ファイル: conf.c プロジェクト: UNIVERSAL-IT-SYSTEMS/elinks-1
static enum parse_error
parse_set_common(struct option *opt_tree, struct conf_parsing_state *state,
		 struct string *mirror, int is_system_conf, int want_domain)
{
	const unsigned char *domain_orig = NULL;
	size_t domain_len = 0;
	unsigned char *domain_copy = NULL;
	const unsigned char *optname_orig;
	size_t optname_len;
	unsigned char *optname_copy;

	skip_white(&state->pos);
	if (!*state->pos.look) return show_parse_error(state, ERROR_PARSE);

	if (want_domain) {
		domain_orig = state->pos.look;
		while (isident(*state->pos.look) || *state->pos.look == '*'
		       || *state->pos.look == '.' || *state->pos.look == '+')
			state->pos.look++;
		domain_len = state->pos.look - domain_orig;

		skip_white(&state->pos);
	}

	/* Option name */
	optname_orig = state->pos.look;
	while (is_option_name_char(*state->pos.look)
	       || *state->pos.look == '.')
		state->pos.look++;
	optname_len = state->pos.look - optname_orig;

	skip_white(&state->pos);

	/* Equal sign */
	if (*state->pos.look != '=')
		return show_parse_error(state, ERROR_PARSE);
	state->pos.look++; /* '=' */
	skip_white(&state->pos);
	if (!*state->pos.look)
		return show_parse_error(state, ERROR_VALUE);

	optname_copy = memacpy(optname_orig, optname_len);
	if (!optname_copy) return show_parse_error(state, ERROR_NOMEM);
	if (want_domain) {
		domain_copy = memacpy(domain_orig, domain_len);
		if (!domain_copy) {
			mem_free(optname_copy);
			return show_parse_error(state, ERROR_NOMEM);
		}
	}

	/* Option value */
	{
		struct option *opt;
		unsigned char *val;
		const struct conf_parsing_pos pos_before_value = state->pos;

		if (want_domain && *domain_copy) {
			struct option *domain_tree;

			domain_tree = get_domain_tree(domain_copy);
			if (!domain_tree) {
				mem_free(domain_copy);
				mem_free(optname_copy);
				skip_option_value(&state->pos);
				return show_parse_error(state, ERROR_NOMEM);
			}

			if (mirror) {
				opt = get_opt_rec_real(domain_tree,
						       optname_copy);
			} else {
				opt = get_opt_rec(opt_tree, optname_copy);
				if (opt) {
					opt = get_option_shadow(opt, opt_tree,
								domain_tree);
					if (!opt) {
						mem_free(domain_copy);
						mem_free(optname_copy);
						skip_option_value(&state->pos);
						return show_parse_error(state,
									ERROR_NOMEM);
					}
				}
			}
		} else {
			opt = mirror
				? get_opt_rec_real(opt_tree, optname_copy)
				: get_opt_rec(opt_tree, optname_copy);
		}
		if (want_domain)
			mem_free(domain_copy);
		domain_copy = NULL;
		mem_free(optname_copy);
		optname_copy = NULL;

		if (!opt || (opt->flags & OPT_HIDDEN)) {
			show_parse_error(state, ERROR_OPTION);
			skip_option_value(&state->pos);
			return ERROR_OPTION;
			/* TODO: Distinguish between two scenarios:
			 * - A newer version of ELinks has saved an
			 *   option that this version does not recognize.
			 *   The option must be preserved.  (This works.)
			 * - The user has added an option, saved
			 *   elinks.conf, restarted ELinks, deleted the
			 *   option, and is now saving elinks.conf again.
			 *   The option should be rewritten to "unset".
			 *   (This does not work yet.)
			 * In both cases, ELinks has no struct option
			 * for that name.  Possible fixes:
			 * - If the tree has OPT_AUTOCREATE, then
			 *   assume the user had created that option,
			 *   and rewrite it to "unset".  Otherwise,
			 *   keep it.
			 * - When the user deletes an option, just mark
			 *   it with OPT_DELETED, and keep it in memory
			 *   as long as OPT_TOUCHED is set.  */
		}

		if (!option_types[opt->type].read) {
			show_parse_error(state, ERROR_VALUE);
			skip_option_value(&state->pos);
			return ERROR_VALUE;
		}

		val = option_types[opt->type].read(opt, &state->pos.look,
						   &state->pos.line);
		if (!val) {
			/* The reader function failed.  Jump back to
			 * the beginning of the value and skip it with
			 * the generic code.  For the error message,
			 * use the line number at the beginning of the
			 * value, because the ending position is not
			 * interesting if there is an unclosed quote.  */
			state->pos = pos_before_value;
			show_parse_error(state, ERROR_VALUE);
			skip_option_value(&state->pos);
			return ERROR_VALUE;
		}

		if (!mirror) {
			/* loading a configuration file */
			if (!option_types[opt->type].set
			    || !option_types[opt->type].set(opt, val)) {
				mem_free(val);
				return show_parse_error(state, ERROR_VALUE);
			}
		} else if (is_system_conf) {
			/* scanning a file that will not be rewritten */
			struct option *flagsite = indirect_option(opt);

			if (!(flagsite->flags & OPT_DELETED)
			    && option_types[opt->type].equals
			    && option_types[opt->type].equals(opt, val))
				flagsite->flags &= ~OPT_MUST_SAVE;
			else
				flagsite->flags |= OPT_MUST_SAVE;
		} else {
			/* rewriting a configuration file */
			struct option *flagsite = indirect_option(opt);

			if (flagsite->flags & OPT_DELETED) {
				/* Replace the "set" command with an
				 * "unset" command.  */
				add_to_string(mirror, "unset ");
				add_bytes_to_string(mirror, optname_orig,
						    optname_len);
				state->mirrored = state->pos.look;
			} else if (option_types[opt->type].write) {
				add_bytes_to_string(mirror, state->mirrored,
						    pos_before_value.look
						    - state->mirrored);
				option_types[opt->type].write(opt, mirror);
				state->mirrored = state->pos.look;
			}
			/* Remember that the option need not be
			 * written to the end of the file.  */
			flagsite->flags &= ~OPT_MUST_SAVE;
		}
		mem_free(val);
	}

	return ERROR_NONE;
}
コード例 #18
0
ファイル: screen.c プロジェクト: rkd77/elinks-tv
/** Time critical section. */
static inline void
add_char16(struct string *screen, struct screen_driver *driver,
	   struct screen_char *ch, struct screen_state *state)
{
	unsigned char border = (ch->attr & SCREEN_ATTR_FRAME);
	unsigned char italic = (ch->attr & SCREEN_ATTR_ITALIC);
	unsigned char underline = (ch->attr & SCREEN_ATTR_UNDERLINE);
	unsigned char bold = (ch->attr & SCREEN_ATTR_BOLD);

	if (
#ifdef CONFIG_UTF8
	    !(driver->opt.utf8_cp && ch->data == UCS_NO_CHAR) &&
#endif /* CONFIG_UTF8 */
	    border != state->border && driver->opt.frame_seqs
	   ) {
		state->border = border;
		add_term_string(screen, driver->opt.frame_seqs[!!border]);
	}

	if (
#ifdef CONFIG_UTF8
	    !(driver->opt.utf8_cp && ch->data == UCS_NO_CHAR) &&
#endif /* CONFIG_UTF8 */
	    italic != state->italic && driver->opt.italic
	   ) {
		state->italic = italic;
		add_term_string(screen, driver->opt.italic[!!italic]);
	}

	if (
#ifdef CONFIG_UTF8
	    !(driver->opt.utf8_cp && ch->data == UCS_NO_CHAR) &&
#endif /* CONFIG_UTF8 */
	    underline != state->underline && driver->opt.underline
	   ) {
		state->underline = underline;
		add_term_string(screen, driver->opt.underline[!!underline]);
	}

	if (
#ifdef CONFIG_UTF8
	    !(driver->opt.utf8_cp && ch->data == UCS_NO_CHAR) &&
#endif /* CONFIG_UTF8 */
	    bold != state->bold
	   ) {
		state->bold = bold;
		if (bold) {
			add_bytes_to_string(screen, (const unsigned char *)"\033[1m", 4);
		} else {
			/* Force repainting of the other attributes. */
			state->color[0] = ch->c.color[0] + 1;
		}
	}

	if (
#ifdef CONFIG_UTF8
	    !(driver->opt.utf8_cp && ch->data == UCS_NO_CHAR) &&
#endif /* CONFIG_UTF8 */
	    !compare_color_16(ch->c.color, state->color)
	   ) {
		copy_color_16(state->color, ch->c.color);

		add_bytes_to_string(screen, (const unsigned char *)"\033[0", 3);

		/* @set_screen_driver_opt has set @driver->opt.color_mode
		 * according to terminal-type-specific options.
		 * The caller of @add_char16 has already partially
		 * checked it, but there are still these possibilities:
		 * - COLOR_MODE_MONO.  Then don't show colors, but
		 *   perhaps use the standout attribute.
		 * - COLOR_MODE_16.  Use 16 colors.
		 * - An unsupported color mode.  Use 16 colors.  */
		if (driver->opt.color_mode != COLOR_MODE_MONO) {
			char code[] = ";30;40";
			unsigned char bgcolor = TERM_COLOR_BACKGROUND_16(ch->c.color);

			code[2] += TERM_COLOR_FOREGROUND_16(ch->c.color);

			if (!driver->opt.transparent || bgcolor != 0) {
				code[5] += bgcolor;
				add_bytes_to_string(screen, (const unsigned char *)code, 6);
			} else {
				add_bytes_to_string(screen, (const unsigned char *)code, 3);
			}

		} else if (ch->attr & SCREEN_ATTR_STANDOUT) {
			/* Flip the fore- and background colors for highlighing
			 * purposes. */
			add_bytes_to_string(screen, (const unsigned char *)";7", 2);
		}

		if (italic && driver->opt.italic) {
			add_bytes_to_string(screen, (const unsigned char *)";3", 2);
		}

		if (underline && driver->opt.underline) {
			add_bytes_to_string(screen, (const unsigned char *)";4", 2);
		}

		/* Check if the char should be rendered bold. */
		if (bold) {
			add_bytes_to_string(screen, (const unsigned char *)";1", 2);
		}

		add_bytes_to_string(screen, (const unsigned char *)"m", 1);
	}

	add_char_data(screen, driver, ch->data, border);
}
コード例 #19
0
ファイル: conf.c プロジェクト: UNIVERSAL-IT-SYSTEMS/elinks-1
static enum parse_error
parse_bind(struct option *opt_tree, struct conf_parsing_state *state,
	   struct string *mirror, int is_system_conf)
{
	unsigned char *keymap, *keystroke, *action;
	enum parse_error err = ERROR_NONE;
	struct conf_parsing_pos before_error;

	skip_white(&state->pos);
	if (!*state->pos.look) return show_parse_error(state, ERROR_PARSE);

	/* Keymap */
	before_error = state->pos;
	keymap = option_types[OPT_STRING].read(NULL, &state->pos.look,
					       &state->pos.line);
	skip_white(&state->pos);
	if (!keymap || !*state->pos.look) {
		state->pos = before_error;
		return show_parse_error(state, ERROR_PARSE);
	}

	/* Keystroke */
	before_error = state->pos;
	keystroke = option_types[OPT_STRING].read(NULL, &state->pos.look,
						  &state->pos.line);
	skip_white(&state->pos);
	if (!keystroke || !*state->pos.look) {
		mem_free(keymap); mem_free_if(keystroke);
		state->pos = before_error;
		return show_parse_error(state, ERROR_PARSE);
	}

	/* Equal sign */
	skip_white(&state->pos);
	if (*state->pos.look != '=') {
		mem_free(keymap); mem_free(keystroke);
		return show_parse_error(state, ERROR_PARSE);
	}
	state->pos.look++; /* '=' */

	skip_white(&state->pos);
	if (!*state->pos.look) {
		mem_free(keymap); mem_free(keystroke);
		return show_parse_error(state, ERROR_PARSE);
	}

	/* Action */
	before_error = state->pos;
	action = option_types[OPT_STRING].read(NULL, &state->pos.look,
					       &state->pos.line);
	if (!action) {
		mem_free(keymap); mem_free(keystroke);
		state->pos = before_error;
		return show_parse_error(state, ERROR_PARSE);
	}

	if (!mirror) {
		/* loading a configuration file */
		/* We don't bother to bind() if -default-keys. */
		if (!get_cmd_opt_bool("default-keys")
		    && bind_do(keymap, keystroke, action, is_system_conf)) {
			/* bind_do() tried but failed. */
			err = show_parse_error(state, ERROR_VALUE);
		} else {
			err = ERROR_NONE;
		}
	} else if (is_system_conf) {
		/* scanning a file that will not be rewritten */
		/* TODO */
	} else {
		/* rewriting a configuration file */
		/* Mirror what we already have.  If the keystroke has
		 * been unbound, then act_str is simply "none" and
		 * this does not require special handling.  */
		unsigned char *act_str = bind_act(keymap, keystroke);

		if (act_str) {
			add_bytes_to_string(mirror, state->mirrored,
					    before_error.look - state->mirrored);
			add_to_string(mirror, act_str);
			mem_free(act_str);
			state->mirrored = state->pos.look;
		} else {
			err = show_parse_error(state, ERROR_VALUE);
		}
	}
	mem_free(keymap); mem_free(keystroke); mem_free(action);
	return err;
}
コード例 #20
0
ファイル: osdep.c プロジェクト: rkd77/elinks-tv
/* Set xterm-like term window's title. */
void
set_window_title(unsigned char *title, int codepage)
{
	struct string filtered;

#ifndef HAVE_SYS_CYGWIN_H
	/* Check if we're in a xterm-like terminal. */
	//if (!is_xterm()) return;
#endif

	if (!init_string(&filtered)) return;

	/* Copy title to filtered if different from NULL */
	if (title) {
		unsigned char *scan = title;
		unsigned char *end = title + strlen((const char *)title);

		/* Remove control characters, so that they cannot
		 * interfere with the command we send to the terminal.
		 * However, do not attempt to limit the title length
		 * to terminal width, because the title is usually
		 * drawn in a different font anyway.  */
		/* Note that this is the right place where to do it, since
		 * potential alternative set_window_title() routines might
		 * want to take different precautions. */
		for (;;) {
			unsigned char *charbegin = scan;
			unicode_val_T unicode
				= cp_to_unicode(codepage, &scan, end);
			int charlen = scan - charbegin;

			if (unicode == UCS_NO_CHAR)
				break;

			/* This need not recognize all Unicode control
			 * characters.  Only those that can make the
			 * terminal misparse the command.  */
			if (unicode < 0x20
			    || (unicode >= 0x7F && unicode < 0xA0))
				continue;

			/* If the title is getting too long, truncate
			 * it and add an ellipsis.
			 *
			 * xterm entirely rejects 1024-byte or longer
			 * titles.  GNU Screen 4.00.03 misparses
			 * titles longer than 765 bytes, and is unable
			 * to display the title in hardstatus if the
			 * title and other stuff together exceed 766
			 * bytes.  So set the limit quite a bit lower.  */
			if (filtered.length + charlen >= 600 - 3) {
				add_to_string(&filtered, (const unsigned char *)"...");
				break;
			}

			add_bytes_to_string(&filtered, charbegin, charlen);
		}
	}

	//getCurrentView()->setTitle(filtered.source);

	/* Send terminal escape sequence + title string */
//	printf("\033]0;%s\a", filtered.source);

#if 0
	/* Miciah don't like this so it is disabled because it changes the
	 * default window name. --jonas */
	/* Set the GNU screen window name */
	if (is_gnuscreen())
		printf("\033k%s\033\134", filtered.source);
#endif

	//fflush(stdout);

	done_string(&filtered);
}