Example #1
0
File: io.c Project: Oblomov/tig
bool
io_read_buf(struct io *io, char buf[], size_t bufsize)
{
	struct buffer result = {0};

	if (io_get(io, &result, '\n', TRUE)) {
		result.data = chomp_string(result.data);
		string_ncopy_do(buf, bufsize, result.data, strlen(result.data));
	}

	return io_done(io) && result.data;
}
Example #2
0
void
string_copy_rev(char *dst, const char *src)
{
	size_t srclen;

	if (!*src)
		return;

	for (srclen = 0; srclen < SIZEOF_REV; srclen++)
		if (!src[srclen] || isspace(src[srclen]))
			break;

	string_ncopy_do(dst, SIZEOF_REV, src, srclen);
}
Example #3
0
static enum status_code
parse_string(char *opt, const char *arg, size_t optsize)
{
	int arglen = strlen(arg);

	switch (arg[0]) {
	case '\"':
	case '\'':
		if (arglen == 1 || arg[arglen - 1] != arg[0])
			return ERROR_UNMATCHED_QUOTATION;
		arg += 1; arglen -= 2;
	default:
		string_ncopy_do(opt, optsize, arg, arglen);
		return SUCCESS;
	}
}
Example #4
0
bool
parse_blame_info(struct blame_commit *commit, char author[SIZEOF_STR], char *line)
{
	if (match_blame_header("author ", &line)) {
		string_ncopy_do(author, SIZEOF_STR, line, strlen(line));

	} else if (match_blame_header("author-mail ", &line)) {
		char *end = strchr(line, '>');

		if (end)
			*end = 0;
		if (*line == '<')
			line++;
		commit->author = get_author(author, line);
		author[0] = 0;

	} else if (match_blame_header("author-time ", &line)) {
		parse_timesec(&commit->time, line);

	} else if (match_blame_header("author-tz ", &line)) {
		parse_timezone(&commit->time, line);

	} else if (match_blame_header("summary ", &line)) {
		string_ncopy(commit->title, line, strlen(line));

	} else if (match_blame_header("previous ", &line)) {
		if (strlen(line) <= SIZEOF_REV)
			return FALSE;
		string_copy_rev(commit->parent_id, line);
		line += SIZEOF_REV;
		commit->parent_filename = get_path(line);
		if (!commit->parent_filename)
			return TRUE;

	} else if (match_blame_header("filename ", &line)) {
		commit->filename = get_path(line);
		return TRUE;
	}

	return FALSE;
}
Example #5
0
static enum status_code
add_to_refs(const char *id, size_t idlen, char *name, size_t namelen, struct ref_opt *opt)
{
	struct ref *ref = NULL;
	enum reference_type type = REFERENCE_BRANCH;
	void **ref_slot = NULL;

	if (!prefixcmp(name, "refs/tags/")) {
		type = REFERENCE_TAG;
		if (!suffixcmp(name, namelen, "^{}")) {
			namelen -= 3;
			name[namelen] = 0;
		} else {
			type = REFERENCE_LOCAL_TAG;
		}

		namelen -= STRING_SIZE("refs/tags/");
		name	+= STRING_SIZE("refs/tags/");

	} else if (!prefixcmp(name, "refs/remotes/")) {
		type = REFERENCE_REMOTE;
		namelen -= STRING_SIZE("refs/remotes/");
		name	+= STRING_SIZE("refs/remotes/");
		if (!strcmp(opt->remote, name))
			type = REFERENCE_TRACKED_REMOTE;

	} else if (!prefixcmp(name, "refs/replace/")) {
		type = REFERENCE_REPLACE;
		id	= name + strlen("refs/replace/");
		idlen	= namelen - strlen("refs/replace/");
		name	= "replaced";
		namelen	= strlen(name);

	} else if (!prefixcmp(name, "refs/heads/")) {
		namelen -= STRING_SIZE("refs/heads/");
		name	+= STRING_SIZE("refs/heads/");
		if (strlen(opt->head) == namelen &&
		    !strncmp(opt->head, name, namelen))
			type = REFERENCE_HEAD;

	} else if (!strcmp(name, "HEAD")) {
		/* Handle the case of HEAD not being a symbolic ref,
		 * i.e. during a rebase. */
		if (*opt->head)
			return SUCCESS;
		type = REFERENCE_HEAD;
	}

	/* If we are reloading or it's an annotated tag, replace the
	 * previous SHA1 with the resolved commit id; relies on the fact
	 * git-ls-remote lists the commit id of an annotated tag right
	 * before the commit id it points to. */
	if (type == REFERENCE_REPLACE) {
		ref = string_map_remove(&refs_by_id, id);

	} else {
		ref_slot = string_map_put_to(&refs_by_name, name);
		if (!ref_slot)
			return ERROR_OUT_OF_MEMORY;
		ref = *ref_slot;
	}

	if (!ref) {
		ref = calloc(1, sizeof(*ref) + namelen);
		if (!ref)
			return ERROR_OUT_OF_MEMORY;
		strncpy(ref->name, name, namelen);
		if (ref_slot)
			*ref_slot = ref;
	}

	if (strncmp(ref->id, id, idlen) || ref->type != type) {
		opt->changed |= WATCH_REFS;
		if (*ref->id)
			remove_ref_from_id_map(ref);
	}

	ref->valid = true;
	ref->type = type;
	string_ncopy_do(ref->id, SIZEOF_REV, id, idlen);

	if (type == REFERENCE_HEAD) {
		if (!refs_head ||
		    (refs_head != ref && memcmp(refs_head, ref, sizeof(*ref))))
			opt->changed |= WATCH_HEAD;
		refs_head = ref;
	}

	if (type == REFERENCE_TAG)
		refs_tags++;

	return add_ref_to_id_map(ref);
}
Example #6
0
File: refdb.c Project: JakeSc/tig
static int
add_to_refs(const char *id, size_t idlen, char *name, size_t namelen, struct ref_opt *opt)
{
	struct ref *ref = NULL;
	enum reference_type type = REFERENCE_BRANCH;
	int pos;

	if (!prefixcmp(name, "refs/tags/")) {
		type = REFERENCE_TAG;
		if (!suffixcmp(name, namelen, "^{}")) {
			namelen -= 3;
			name[namelen] = 0;
		} else {
			type = REFERENCE_LOCAL_TAG;
		}

		namelen -= STRING_SIZE("refs/tags/");
		name	+= STRING_SIZE("refs/tags/");

	} else if (!prefixcmp(name, "refs/remotes/")) {
		type = REFERENCE_REMOTE;
		namelen -= STRING_SIZE("refs/remotes/");
		name	+= STRING_SIZE("refs/remotes/");
		if (!strcmp(opt->remote, name))
			type = REFERENCE_TRACKED_REMOTE;

	} else if (!prefixcmp(name, "refs/replace/")) {
		type = REFERENCE_REPLACE;
		id	= name + strlen("refs/replace/");
		idlen	= namelen - strlen("refs/replace/");
		name	= "replaced";
		namelen	= strlen(name);

	} else if (!prefixcmp(name, "refs/heads/")) {
		namelen -= STRING_SIZE("refs/heads/");
		name	+= STRING_SIZE("refs/heads/");
		if (strlen(opt->head) == namelen &&
		    !strncmp(opt->head, name, namelen))
			type = REFERENCE_HEAD;

	} else if (!strcmp(name, "HEAD")) {
		/* Handle the case of HEAD not being a symbolic ref,
		 * i.e. during a rebase. */
		if (*opt->head)
			return OK;
		type = REFERENCE_HEAD;
	}

	/* If we are reloading or it's an annotated tag, replace the
	 * previous SHA1 with the resolved commit id; relies on the fact
	 * git-ls-remote lists the commit id of an annotated tag right
	 * before the commit id it points to. */
	for (pos = 0; pos < refs_size; pos++) {
		int cmp = type == REFERENCE_REPLACE
			? strcmp(id, refs[pos]->id) : strcmp(name, refs[pos]->name);

		if (!cmp) {
			ref = refs[pos];
			break;
		}
	}

	if (!ref) {
		if (!realloc_refs(&refs, refs_size, 1))
			return ERR;
		ref = calloc(1, sizeof(*ref) + namelen);
		if (!ref)
			return ERR;
		refs[refs_size++] = ref;
		strncpy(ref->name, name, namelen);
	}

	if (strncmp(ref->id, id, idlen))
		opt->changed |= WATCH_REFS;

	ref->valid = TRUE;
	ref->type = type;
	string_ncopy_do(ref->id, SIZEOF_REV, id, idlen);

	if (type == REFERENCE_HEAD) {
		if (!refs_head ||
		    (refs_head != ref && memcmp(refs_head, ref, sizeof(*ref))))
			opt->changed |= WATCH_HEAD;
		refs_head = ref;
	}
	return OK;
}
Example #7
0
File: prompt.c Project: gonzus/tig
static char *
prompt_input(const char *prompt, struct input *input)
{
	enum input_status status = INPUT_OK;
	unsigned char chars_length[SIZEOF_STR];
	struct key key;
	size_t promptlen = strlen(prompt);
	int pos = 0, chars = 0;

	input->buf[pos] = 0;

	while (status == INPUT_OK || status == INPUT_SKIP) {

		update_status("%s%.*s", prompt, pos, input->buf);

		if (get_input(pos + promptlen, &key, FALSE) == OK) {
			int len = strlen(key.data.bytes);

			if (pos + len >= sizeof(input->buf)) {
				report("Input string too long");
				return NULL;
			}

			string_ncopy_do(input->buf + pos, sizeof(input->buf) - pos, key.data.bytes, len);
			pos += len;
			chars_length[chars++] = len;
			status = input->handler(input, &key);
			if (status != INPUT_OK) {
				pos -= len;
				chars--;
			} else {
				int changed_pos = strlen(input->buf);

				if (changed_pos != pos) {
					pos = changed_pos;
					chars_length[chars - 1] = changed_pos - (pos - len);
				}
			}
		} else {
			status = input->handler(input, &key);
			if (status == INPUT_DELETE) {
				int len = chars_length[--chars];

				pos -= len;
				status = INPUT_OK;
			} else {
				int changed_pos = strlen(input->buf);

				if (changed_pos != pos) {
					pos = changed_pos;
					chars_length[chars++] = changed_pos - pos;
				}
			}
		}
		input->buf[pos] = 0;
	}

	report_clear();

	if (status == INPUT_CANCEL)
		return NULL;

	input->buf[pos++] = 0;

	return input->buf;
}
Example #8
0
static int
add_to_refs(const char *id, size_t idlen, char *name, size_t namelen, struct ref_opt *opt)
{
	struct ref *ref = NULL;
	bool tag = FALSE;
	bool ltag = FALSE;
	bool remote = FALSE;
	bool replace = FALSE;
	bool tracked = FALSE;
	bool head = FALSE;
	int pos;

	if (!prefixcmp(name, "refs/tags/")) {
		if (!suffixcmp(name, namelen, "^{}")) {
			namelen -= 3;
			name[namelen] = 0;
		} else {
			ltag = TRUE;
		}

		tag = TRUE;
		namelen -= STRING_SIZE("refs/tags/");
		name	+= STRING_SIZE("refs/tags/");

	} else if (!prefixcmp(name, "refs/remotes/")) {
		remote = TRUE;
		namelen -= STRING_SIZE("refs/remotes/");
		name	+= STRING_SIZE("refs/remotes/");
		tracked  = !strcmp(opt->remote, name);

	} else if (!prefixcmp(name, "refs/replace/")) {
		replace = TRUE;
		id	= name + strlen("refs/replace/");
		idlen	= namelen - strlen("refs/replace/");
		name	= "replaced";
		namelen	= strlen(name);

	} else if (!prefixcmp(name, "refs/heads/")) {
		namelen -= STRING_SIZE("refs/heads/");
		name	+= STRING_SIZE("refs/heads/");
		head	 = strlen(opt->head) == namelen
			   && !strncmp(opt->head, name, namelen);

	} else if (!strcmp(name, "HEAD")) {
		/* Handle the case of HEAD not being a symbolic ref,
		 * i.e. during a rebase. */
		if (*opt->head)
			return OK;
		head = TRUE;
	}

	/* If we are reloading or it's an annotated tag, replace the
	 * previous SHA1 with the resolved commit id; relies on the fact
	 * git-ls-remote lists the commit id of an annotated tag right
	 * before the commit id it points to. */
	for (pos = 0; pos < refs_size; pos++) {
		int cmp = replace ? strcmp(id, refs[pos]->id) : strcmp(name, refs[pos]->name);

		if (!cmp) {
			ref = refs[pos];
			break;
		}
	}

	if (!ref) {
		if (!realloc_refs(&refs, refs_size, 1))
			return ERR;
		ref = calloc(1, sizeof(*ref) + namelen);
		if (!ref)
			return ERR;
		refs[refs_size++] = ref;
		strncpy(ref->name, name, namelen);
	}

	ref->valid = TRUE;
	ref->head = head;
	ref->tag = tag;
	ref->ltag = ltag;
	ref->remote = remote;
	ref->replace = replace;
	ref->tracked = tracked;
	string_ncopy_do(ref->id, SIZEOF_REV, id, idlen);

	if (head)
		refs_head = ref;
	return OK;
}
Example #9
0
File: prompt.c Project: bbolli/tig
static char *
prompt_input(const char *prompt, input_handler handler, void *data)
{
	enum input_status status = INPUT_OK;
	static char buf[SIZEOF_STR];
	unsigned char chars_length[SIZEOF_STR];
	struct key_input input;
	size_t promptlen = strlen(prompt);
	int pos = 0, chars = 0;

	buf[pos] = 0;

	while (status == INPUT_OK || status == INPUT_SKIP) {
		update_status("%s%.*s", prompt, pos, buf);

		switch (get_input(pos + promptlen, &input, FALSE)) {
		case KEY_RETURN:
		case KEY_ENTER:
		case '\n':
			status = pos ? INPUT_STOP : INPUT_CANCEL;
			break;

		case KEY_BACKSPACE:
			if (pos > 0) {
				int len = chars_length[--chars];

				pos -= len;
				buf[pos] = 0;
			} else {
				status = INPUT_CANCEL;
			}
			break;

		case KEY_ESC:
			status = INPUT_CANCEL;
			break;

		default:
			if (pos >= sizeof(buf)) {
				report("Input string too long");
				return NULL;
			}

			status = handler(data, buf, &input);
			if (status == INPUT_OK) {
				int len = strlen(input.data.bytes);

				string_ncopy_do(buf + pos, sizeof(buf) - pos, input.data.bytes, len);
				pos += len;
				chars_length[chars++] = len;
			}
		}
	}

	report_clear();

	if (status == INPUT_CANCEL)
		return NULL;

	buf[pos++] = 0;

	return buf;
}