コード例 #1
0
ファイル: variables.c プロジェクト: ackeack/workenv
static void
report_parsing_error(ParsingErrors error)
{
	if(error == PE_INVALID_EXPRESSION)
	{
		text_buffer_addf("%s: %s", "Invalid expression", get_last_position());
	}
	else if(error == PE_MISSING_QUOTE)
	{
		text_buffer_addf("%s: %s", "Invalid :let expression (missing quote)",
				get_last_position());
	}
	else
	{
		assert(0 && "Unexpected parsing error code.");
	}
}
コード例 #2
0
ファイル: functions.c プロジェクト: lyuts/vifm
var_t
function_call(const char func_name[], const call_info_t *call_info)
{
	function_t *function = find_function(func_name);
	if(function == NULL)
	{
		text_buffer_addf("%s: %s", "Unknown function", func_name);
		return var_error();
	}
	if(call_info->argc < function->arg_count)
	{
		text_buffer_addf("%s: %s", "Not enough arguments for function", func_name);
		return var_error();
	}
	if(call_info->argc > function->arg_count)
	{
		text_buffer_addf("%s: %s", "Too many arguments for function", func_name);
		return var_error();
	}
	return function->ptr(call_info);
}
コード例 #3
0
ファイル: options.c プロジェクト: francogonzaga/vifm
/* Adds value(s) to the option (+= operator).  Returns zero on success. */
static int
set_add(opt_t *opt, const char value[])
{
	if(opt->type != OPT_INT && opt->type != OPT_SET && opt->type != OPT_STRLIST &&
			opt->type != OPT_CHARSET)
		return -1;

	if(opt->type == OPT_INT)
	{
		char *p;
		int i;

		i = strtol(value, &p, 10);
		if(*p != '\0')
			return -1;
		if(i == 0)
			return 0;

		opt->val.int_val += i;
		notify_option_update(opt, OP_MODIFIED, opt->val);
	}
	else if(opt->type == OPT_SET)
	{
		if(set_op(opt, value, SO_ADD))
		{
			notify_option_update(opt, OP_MODIFIED, opt->val);
		}
	}
	else if(opt->type == OPT_CHARSET)
	{
		const size_t valid_len = strspn(value, *opt->vals);
		if(valid_len != strlen(value))
		{
			text_buffer_addf("Illegal character: <%c>", value[valid_len]);
			return -1;
		}
		if(charset_add_all(opt, value))
		{
			notify_option_update(opt, OP_MODIFIED, opt->val);
		}
	}
	else if(*value != '\0')
	{
		opt->val.str_val = str_add(opt->val.str_val, value);
		notify_option_update(opt, OP_MODIFIED, opt->val);
	}

	return 0;
}
コード例 #4
0
ファイル: variables.c プロジェクト: ackeack/workenv
int
unlet_variables(const char *cmd)
{
	int error = 0;
	assert(initialized);

	while(*cmd != '\0')
	{
		envvar_t *record;

		char name[VAR_NAME_MAX + 1];
		char *p;
		int envvar = 1;

		/* check if its environment variable */
		if(*cmd != '$')
			envvar = 0;
		else
			cmd++;

		/* copy variable name */
		p = name;
		while(*cmd != '\0' && char_is_one_of(ENV_VAR_NAME_CHARS, *cmd) &&
				p - name < sizeof(name) - 1)
			*p++ = *cmd++;
		*p = '\0';

		if(*cmd != '\0' && !isspace(*cmd))
		{
			text_buffer_add("Trailing characters");
			error++;
			break;
		}

		cmd = skip_whitespace(cmd);

		/* currently we support only environment variables */
		if(!envvar)
		{
			text_buffer_addf("%s: %s", "Unsupported variable type", name);

			cmd = skip_non_whitespace(cmd);
			error++;
			continue;
		}

		/* test for empty variable name */
		if(name[0] == '\0')
		{
			text_buffer_addf("%s: %s", "Unsupported variable name", "empty name");
			error++;
			continue;
		}

		record = find_record(name);
		if(record == NULL || record->removed)
		{
			text_buffer_addf("%s: %s", "No such variable", name);
			error++;
			continue;
		}

		if(record->from_parent)
			record->removed = 1;
		else
			free_record(record);
		env_remove(name);
	}

	return error;
}
コード例 #5
0
ファイル: variables.c プロジェクト: ackeack/workenv
int
let_variable(const char *cmd)
{
	char name[VAR_NAME_MAX + 1];
	char *p;
	int append = 0;
	var_t res_var;
	char *str_var;
	ParsingErrors parsing_error;

	assert(initialized);

	/* currently we support only environment variables */
	if(*cmd != '$')
	{
		text_buffer_add("Incorrect variable type");
		return -1;
	}
	cmd++;

	/* copy variable name */
	p = name;
	while(*cmd != '\0' && char_is_one_of(ENV_VAR_NAME_CHARS, *cmd) &&
			*cmd != '.' && *cmd != '=' && p - name < sizeof(name) - 1)
	{
		if(*cmd != '_' && !isalnum(*cmd))
		{
			text_buffer_add("Incorrect variable name");
			return -1;
		}
		*p++ = *cmd++;
	}
	/* test for empty variable name */
	if(p == name)
	{
		text_buffer_addf("%s: %s", "Unsupported variable name", "empty name");
		return -1;
	}
	*p = '\0';

	cmd = skip_whitespace(cmd);

	/* check for dot and skip it */
	if(*cmd == '.')
	{
		append = 1;
		cmd++;
	}

	/* check for equal sign and skip it */
	if(*cmd != '=')
	{
		text_buffer_addf("%s: %s", "Incorrect :let statement", "'=' expected");
		return -1;
	}

	parsing_error = parse(cmd + 1, &res_var);
	if(parsing_error != PE_NO_ERROR)
	{
		report_parsing_error(parsing_error);
		return -1;
	}

	if(get_last_position() != NULL && *get_last_position() != '\0')
	{
		text_buffer_addf("%s: %s", "Incorrect :let statement",
				"trailing characters");
		return -1;
	}

	/* update environment variable */
	str_var = var_to_string(res_var);
	if(append)
		append_envvar(name, str_var);
	else
		set_envvar(name, str_var);
	free(str_var);

	var_free(res_var);

	return 0;
}
コード例 #6
0
ファイル: options.c プロジェクト: francogonzaga/vifm
/* Assigns value to an option of all kinds except boolean.  Returns non-zero in
 * case of error. */
static int
set_set(opt_t *opt, const char value[])
{
	if(opt->type == OPT_BOOL)
		return -1;

	if(opt->type == OPT_SET)
	{
		if(set_op(opt, value, SO_SET))
		{
			notify_option_update(opt, OP_SET, opt->val);
		}
	}
	else if(opt->type == OPT_ENUM)
	{
		int i = find_val(opt, value);
		if(i == -1)
			return -1;

		if(opt->val.enum_item != i)
		{
			opt->val.enum_item = i;
			notify_option_update(opt, OP_SET, opt->val);
		}
	}
	else if(opt->type == OPT_STR || opt->type == OPT_STRLIST)
	{
		if(opt->val.str_val == NULL || strcmp(opt->val.str_val, value) != 0)
		{
			(void)replace_string(&opt->val.str_val, value);
			notify_option_update(opt, OP_SET, opt->val);
		}
	}
	else if(opt->type == OPT_INT)
	{
		char *end;
		int int_val = strtoll(value, &end, 10);
		if(opt->val.int_val != int_val)
		{
			opt->val.int_val = int_val;
			notify_option_update(opt, OP_SET, opt->val);
		}
	}
	else if(opt->type == OPT_CHARSET)
	{
		const size_t valid_len = strspn(value, *opt->vals);
		if(valid_len != strlen(value))
		{
			text_buffer_addf("Illegal character: <%c>", value[valid_len]);
			return -1;
		}
		if(charset_set(opt, value))
		{
			notify_option_update(opt, OP_SET, opt->val);
		}
	}
	else
	{
		assert(0 && "Unknown type of option.");
	}

	return 0;
}
コード例 #7
0
ファイル: options.c プロジェクト: francogonzaga/vifm
/* Processes one :set statement.  Returns zero on success. */
static int
process_option(const char arg[])
{
	char option[OPTION_NAME_MAX + 1];
	int err;
	const char *p;
	opt_t *opt;

	p = skip_alphas(arg);

	snprintf(option, p - arg + 1, "%s", arg);

	if(strcmp(option, "all") == 0)
	{
		print_options();
		return 0;
	}

	opt = get_option(option);
	if(opt == NULL)
	{
		text_buffer_addf("%s: %s", "Unknown option", arg);
		return 1;
	}

	err = 0;
	if(*p == '\0')
	{
		opt_t *o = find_option(option);
		if(o != NULL)
		{
			if(o->type == OPT_BOOL)
				err = set_on(opt);
			else
				err = set_print(o);
		}
		else if(strncmp(option, "no", 2) == 0)
		{
			err = set_off(opt);
		}
		else if(strncmp(option, "inv", 3) == 0)
		{
			err = set_inv(opt);
		}
	}
	else if(char_is_one_of(ENDING_CHARS, *p))
	{
		if(*(p + 1) != '\0')
		{
			text_buffer_addf("%s: %s", "Trailing characters", arg);
			return 1;
		}
		if(*p == '!')
			err = set_inv(opt);
		else if(*p == '?')
			err = set_print(opt);
		else
			err = set_reset(opt);
	}
	else if(strncmp(p, "+=", 2) == 0)
	{
		err = set_add(opt, p + 2);
	}
	else if(strncmp(p, "-=", 2) == 0)
	{
		err = set_remove(opt, p + 2);
	}
	else if(*p == '=' || *p == ':')
	{
		err = set_set(opt, p + 1);
	}
	else
	{
		text_buffer_addf("%s: %s", "Trailing characters", arg);
	}

	if(err)
	{
		text_buffer_addf("%s: %s", "Invalid argument", arg);
	}
	return err;
}