Exemple #1
0
enum status_code
parse_option(struct option_info *option, const char *prefix, const char *arg)
{
	char name[SIZEOF_STR];

	if (!enum_name_prefixed(name, sizeof(name), prefix, option->name))
		return error("Failed to parse option");

	if (!strcmp("show-notes", name)) {
		bool *value = option->value;
		enum status_code res;

		if (parse_bool(option->value, arg) == SUCCESS)
			return SUCCESS;

		*value = TRUE;
		string_copy(opt_notes_arg, NOTES_EQ_ARG);
		res = parse_string(opt_notes_arg + STRING_SIZE(NOTES_EQ_ARG), arg,
				   sizeof(opt_notes_arg) - STRING_SIZE(NOTES_EQ_ARG));
		if (res == SUCCESS && !opt_notes_arg[STRING_SIZE(NOTES_EQ_ARG)])
			opt_notes_arg[STRING_SIZE(NOTES_ARG)] = 0;
		return res;
	}

	if (!strcmp(option->type, "bool"))
		return parse_bool(option->value, arg);

	if (!strcmp(option->type, "double"))
		return parse_step(option->value, arg);

	if (!strncmp(option->type, "enum", 4)) {
		const char *type = option->type + STRING_SIZE("enum ");
		const struct enum_map *map = find_enum_map(type);

		return parse_enum(name, option->value, arg, map);
	}

	if (!strcmp(option->type, "int")) {
		if (strstr(name, "title-overflow")) {
			bool enabled = FALSE;
			int *value = option->value;

			/* We try to parse it as a boolean (and set the
			 * value to 0 if fale), otherwise we parse it as
			 * an integer and use the given value. */
			if (parse_bool(&enabled, arg) == SUCCESS) {
				if (!enabled) {
					*value = 0;
					return SUCCESS;
				}
				arg = "50";
			}
		}

		if (!strcmp(name, "line-number-interval") ||
		    !strcmp(name, "tab-size"))
			return parse_int(option->value, arg, 1, 1024);
		else if (!strcmp(name, "id-width"))
			return parse_int(option->value, arg, 0, SIZEOF_REV - 1);
		else
			return parse_int(option->value, arg, 0, 1024);
	}

	return error("Unhandled option: %s", name);
}
Exemple #2
0
static enum status_code
prompt_toggle_option(struct view *view, const char *argv[], const char *prefix,
		     struct prompt_toggle *toggle, enum view_flag *flags)
{
	char name[SIZEOF_STR];

	if (!enum_name_prefixed(name, sizeof(name), prefix, toggle->name))
		return error("Failed to toggle option %s", toggle->name);

	*flags = toggle->flags;

	if (!strcmp(toggle->type, "bool")) {
		bool *opt = toggle->opt;

		*opt = !*opt;
		if (opt == &opt_mouse)
			enable_mouse(*opt);
		return success("set %s = %s", name, *opt ? "yes" : "no");

	} else if (!strncmp(toggle->type, "enum", 4)) {
		const char *type = toggle->type + STRING_SIZE("enum ");
		enum author *opt = toggle->opt;
		const struct enum_map *map = find_enum_map(type);

		*opt = (*opt + 1) % map->size;
		return success("set %s = %s", name, enum_name(map->entries[*opt].name));

	} else if (!strcmp(toggle->type, "int")) {
		const char *arg = argv[2] ? argv[2] : "1";
		int diff = atoi(arg);
		int *opt = toggle->opt;

		if (!diff)
			diff = *arg == '-' ? -1 : 1;

		if (opt == &opt_diff_context && *opt < 0)
			*opt = -*opt;
		if (opt == &opt_diff_context && diff < 0) {
			if (!*opt)
				return error("Diff context cannot be less than zero");
			if (*opt < -diff)
				diff = -*opt;
		}

		if (strstr(name, "commit-title-overflow")) {
			*opt = *opt ? -*opt : 50;
			if (*opt < 0)
				return success("set %s = no", name);
			diff = 0;
		}

		*opt += diff;
		return success("set %s = %d", name, *opt);

	} else if (!strcmp(toggle->type, "double")) {
		const char *arg = argv[2] ? argv[2] : "1.0";
		double *opt = toggle->opt;
		int sign = 1;
		double diff;

		if (*arg == '-') {
			sign = -1;
			arg++;
		}

		if (parse_step(&diff, arg) != SUCCESS)
			diff = strtod(arg, NULL);

		*opt += sign * diff;
		return success("set %s = %.2f", name, *opt);

	} else if (!strcmp(toggle->type, "const char **")) {
		const char ***opt = toggle->opt;
		bool found = TRUE;
		int i;

		if (argv_size(argv) <= 2) {
			argv_free(*opt);
			(*opt)[0] = NULL;
			return SUCCESS;
		}

		for (i = 2; argv[i]; i++) {
			if (!find_arg(*opt, argv[i])) {
				found = FALSE;
				break;
			}
		}

		if (found) {
			int next, pos;

			for (next = 0, pos = 0; (*opt)[pos]; pos++) {
				const char *arg = (*opt)[pos];

				if (find_arg(argv + 2, arg)) {
					free((void *) arg);
					continue;
				}
				(*opt)[next++] = arg;
			}

			(*opt)[next] = NULL;

		} else if (!argv_copy(opt, argv + 2)) {
			return ERROR_OUT_OF_MEMORY;
		}
		return SUCCESS;

	} else {
		return error("Unsupported `:toggle %s` (%s)", name, toggle->type);
	}
}
Exemple #3
0
static enum view_flag
prompt_toggle_option(struct view *view, const char *argv[],
		     struct prompt_toggle *toggle, char msg[SIZEOF_STR])
{
	char name[SIZEOF_STR];

	enum_name_copy(name, toggle->name, strlen(toggle->name));

	if (!strcmp(toggle->type, "bool")) {
		bool *opt = toggle->opt;

		*opt = !*opt;
		string_format_size(msg, SIZEOF_STR, "set %s = %s", name, *opt ? "yes" : "no");

	} else if (!strncmp(toggle->type, "enum", 4)) {
		const char *type = toggle->type + STRING_SIZE("enum ");
		enum author *opt = toggle->opt;
		const struct enum_map *map = find_enum_map(type);

		*opt = (*opt + 1) % map->size;
		string_format_size(msg, SIZEOF_STR, "set %s = %s", name,
				   enum_name(map->entries[*opt]));

	} else if (!strcmp(toggle->type, "int")) {
		const char *arg = argv[2] ? argv[2] : "1";
		int diff = atoi(arg);
		int *opt = toggle->opt;

		if (!diff)
			diff = *arg == '-' ? -1 : 1;

		if (opt == &opt_diff_context && diff < 0) {
			if (!*opt) {
				report("Diff context cannot be less than zero");
				return VIEW_NO_FLAGS;
			}
			if (*opt < -diff)
				diff = -*opt;
		}

		if (opt == &opt_title_overflow) {
			*opt = *opt ? -*opt : 50;
			if (*opt < 0) {
				string_format_size(msg, SIZEOF_STR, "set %s = no", name);
				return toggle->flags;
			}
		}

		*opt += diff;
		string_format_size(msg, SIZEOF_STR, "set %s = %d", name, *opt);

	} else if (!strcmp(toggle->type, "double")) {
		const char *arg = argv[2] ? argv[2] : "1.0";
		double *opt = toggle->opt;
		int sign = 1;
		double diff;

		if (*arg == '-') {
			sign = -1;
			arg++;
		}

		if (parse_step(&diff, arg) != SUCCESS)
			diff = strtod(arg, NULL);

		*opt += sign * diff;
		string_format_size(msg, SIZEOF_STR, "set %s = %.2f", name, *opt);

	} else if (!strcmp(toggle->type, "const char **")) {
		const char ***opt = toggle->opt;
		bool found = TRUE;
		int i;

		for (i = 2; argv[i]; i++) {
			if (!find_arg(*opt, argv[i])) {
				found = FALSE;
				break;
			}
		}

		if (found) {
			int next, pos;

			for (next = 0, pos = 0; (*opt)[pos]; pos++) {
				const char *arg = (*opt)[pos];

				if (find_arg(argv + 2, arg)) {
					free((void *) arg);
					continue;
				}
				(*opt)[next++] = arg;
			}

			(*opt)[next] = NULL;

		} else if (!argv_copy(opt, argv + 2)) {
			report("Failed to append arguments");
			return VIEW_NO_FLAGS;
		}

	} else {
		die("Unsupported `:toggle %s` (%s)", name, toggle->type);
	}

	return toggle->flags;
}