예제 #1
0
파일: column.c 프로젝트: MichaelBlume/git
/* Display COL_COLUMN or COL_ROW */
static void display_table(const struct string_list *list,
			  unsigned int colopts,
			  const struct column_options *opts)
{
	struct column_data data;
	int x, y, i, initial_width;
	char *empty_cell;

	memset(&data, 0, sizeof(data));
	data.list = list;
	data.colopts = colopts;
	data.opts = *opts;

	ALLOC_ARRAY(data.len, list->nr);
	for (i = 0; i < list->nr; i++)
		data.len[i] = item_length(colopts, list->items[i].string);

	layout(&data, &initial_width);

	if (colopts & COL_DENSE)
		shrink_columns(&data);

	empty_cell = xmallocz(initial_width);
	memset(empty_cell, ' ', initial_width);
	for (y = 0; y < data.rows; y++) {
		for (x = 0; x < data.cols; x++)
			if (display_cell(&data, initial_width, empty_cell, x, y))
				break;
	}

	free(data.len);
	free(data.width);
	free(empty_cell);
}
예제 #2
0
파일: grep.c 프로젝트: niketpathak/git
static int grep_source_load_file(struct grep_source *gs)
{
	const char *filename = gs->identifier;
	struct stat st;
	char *data;
	size_t size;
	int i;

	if (lstat(filename, &st) < 0) {
	err_ret:
		if (errno != ENOENT)
			error_errno(_("failed to stat '%s'"), filename);
		return -1;
	}
	if (!S_ISREG(st.st_mode))
		return -1;
	size = xsize_t(st.st_size);
	i = open(filename, O_RDONLY);
	if (i < 0)
		goto err_ret;
	data = xmallocz(size);
	if (st.st_size != read_in_full(i, data, size)) {
		error_errno(_("'%s': short read"), filename);
		close(i);
		free(data);
		return -1;
	}
	close(i);

	gs->buf = data;
	gs->size = size;
	return 0;
}
예제 #3
0
static void *get_data(unsigned long size)
{
	git_zstream stream;
	void *buf = xmallocz(size);

	memset(&stream, 0, sizeof(stream));

	stream.next_out = buf;
	stream.avail_out = size;
	stream.next_in = fill(1);
	stream.avail_in = len;
	git_inflate_init(&stream);

	for (;;) {
		int ret = git_inflate(&stream, 0);
		use(len - stream.avail_in);
		if (stream.total_out == size && ret == Z_STREAM_END)
			break;
		if (ret != Z_OK) {
			error("inflate returned %d", ret);
			FREE_AND_NULL(buf);
			if (!recover)
				exit(1);
			has_errors = 1;
			break;
		}
		stream.next_in = fill(1);
		stream.avail_in = len;
	}
	git_inflate_end(&stream);
	return buf;
}
예제 #4
0
파일: ll-merge.c 프로젝트: Nowher2/git
/*
 * User defined low-level merge driver support.
 */
static int ll_ext_merge(const struct ll_merge_driver *fn,
			mmbuffer_t *result,
			const char *path,
			mmfile_t *orig, const char *orig_name,
			mmfile_t *src1, const char *name1,
			mmfile_t *src2, const char *name2,
			const struct ll_merge_options *opts,
			int marker_size)
{
	char temp[4][50];
	struct strbuf cmd = STRBUF_INIT;
	struct strbuf_expand_dict_entry dict[6];
	struct strbuf path_sq = STRBUF_INIT;
	const char *args[] = { NULL, NULL };
	int status, fd, i;
	struct stat st;
	assert(opts);

	sq_quote_buf(&path_sq, path);
	dict[0].placeholder = "O"; dict[0].value = temp[0];
	dict[1].placeholder = "A"; dict[1].value = temp[1];
	dict[2].placeholder = "B"; dict[2].value = temp[2];
	dict[3].placeholder = "L"; dict[3].value = temp[3];
	dict[4].placeholder = "P"; dict[4].value = path_sq.buf;
	dict[5].placeholder = NULL; dict[5].value = NULL;

	if (fn->cmdline == NULL)
		die("custom merge driver %s lacks command line.", fn->name);

	result->ptr = NULL;
	result->size = 0;
	create_temp(orig, temp[0], sizeof(temp[0]));
	create_temp(src1, temp[1], sizeof(temp[1]));
	create_temp(src2, temp[2], sizeof(temp[2]));
	xsnprintf(temp[3], sizeof(temp[3]), "%d", marker_size);

	strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict);

	args[0] = cmd.buf;
	status = run_command_v_opt(args, RUN_USING_SHELL);
	fd = open(temp[1], O_RDONLY);
	if (fd < 0)
		goto bad;
	if (fstat(fd, &st))
		goto close_bad;
	result->size = st.st_size;
	result->ptr = xmallocz(result->size);
	if (read_in_full(fd, result->ptr, result->size) != result->size) {
		FREE_AND_NULL(result->ptr);
		result->size = 0;
	}
 close_bad:
	close(fd);
 bad:
	for (i = 0; i < 3; i++)
		unlink_or_warn(temp[i]);
	strbuf_release(&cmd);
	strbuf_release(&path_sq);
	return status;
}
예제 #5
0
파일: ifstats.c 프로젝트: ebichu/dd-wrt
static struct iflist *positionptr(struct iflist *iflist, const int ifindex)
{
	struct iflist *ptmp = iflist;
	struct iflist *last = ptmp;

	while ((ptmp != NULL) && (ptmp->ifindex != ifindex)) {
		last = ptmp;
		ptmp = ptmp->next_entry;
	}
	/* no interface was found, try to create new one */
	if (ptmp == NULL) {
		struct iflist *itmp = xmallocz(sizeof(struct iflist));
		itmp->ifindex = ifindex;
		itmp->index = last->index + 1;
		int r = dev_get_ifname(ifindex, itmp->ifname);
		if (r != 0) {
			write_error("Error getting interface name");
			return(NULL);
		}

		/* last can't be NULL otherwise we will have empty iflist */
		last->next_entry = itmp;
		itmp->prev_entry = last;
		itmp->next_entry = NULL;
		ptmp = itmp;
	}
	return(ptmp);
}
예제 #6
0
파일: setup.c 프로젝트: 1tgr/git
/*
 * Normalize "path", prepending the "prefix" for relative paths. If
 * remaining_prefix is not NULL, return the actual prefix still
 * remains in the path. For example, prefix = sub1/sub2/ and path is
 *
 *  foo          -> sub1/sub2/foo  (full prefix)
 *  ../foo       -> sub1/foo       (remaining prefix is sub1/)
 *  ../../bar    -> bar            (no remaining prefix)
 *  ../../sub1/sub2/foo -> sub1/sub2/foo (but no remaining prefix)
 *  `pwd`/../bar -> sub1/bar       (no remaining prefix)
 */
char *prefix_path_gently(const char *prefix, int len,
			 int *remaining_prefix, const char *path)
{
	const char *orig = path;
	char *sanitized;
	if (is_absolute_path(orig)) {
		sanitized = xmallocz(strlen(path));
		if (remaining_prefix)
			*remaining_prefix = 0;
		if (normalize_path_copy_len(sanitized, path, remaining_prefix)) {
			free(sanitized);
			return NULL;
		}
		if (abspath_part_inside_repo(sanitized)) {
			free(sanitized);
			return NULL;
		}
	} else {
		sanitized = xstrfmt("%.*s%s", len, len ? prefix : "", path);
		if (remaining_prefix)
			*remaining_prefix = len;
		if (normalize_path_copy_len(sanitized, sanitized, remaining_prefix)) {
			free(sanitized);
			return NULL;
		}
	}
	return sanitized;
}
예제 #7
0
파일: refs.c 프로젝트: chidveer/git
int refname_is_safe(const char *refname)
{
	const char *rest;

	if (skip_prefix(refname, "refs/", &rest)) {
		char *buf;
		int result;
		size_t restlen = strlen(rest);

		/* rest must not be empty, or start or end with "/" */
		if (!restlen || *rest == '/' || rest[restlen - 1] == '/')
			return 0;

		/*
		 * Does the refname try to escape refs/?
		 * For example: refs/foo/../bar is safe but refs/foo/../../bar
		 * is not.
		 */
		buf = xmallocz(restlen);
		result = !normalize_path_copy(buf, rest) && !strcmp(buf, rest);
		free(buf);
		return result;
	}

	do {
		if (!isupper(*refname) && *refname != '_')
			return 0;
		refname++;
	} while (*refname);
	return 1;
}
예제 #8
0
파일: wt-status.c 프로젝트: Lekensteyn/git
static void wt_status_print_unmerged_data(struct wt_status *s,
					  struct string_list_item *it)
{
	const char *c = color(WT_STATUS_UNMERGED, s);
	struct wt_status_change_data *d = it->util;
	struct strbuf onebuf = STRBUF_INIT;
	static char *padding;
	static int label_width;
	const char *one, *how;
	int len;

	if (!padding) {
		label_width = maxwidth(wt_status_unmerged_status_string, 1, 7);
		label_width += strlen(" ");
		padding = xmallocz(label_width);
		memset(padding, ' ', label_width);
	}

	one = quote_path(it->string, s->prefix, &onebuf);
	status_printf(s, color(WT_STATUS_HEADER, s), "\t");

	how = wt_status_unmerged_status_string(d->stagemask);
	len = label_width - utf8_strwidth(how);
	status_printf_more(s, c, "%s%.*s%s\n", how, len, padding, one);
	strbuf_release(&onebuf);
}
예제 #9
0
파일: input.c 프로젝트: bearstech/iptraf-ng
void tx_addfield(struct FIELDLIST *list, unsigned int len, unsigned int y,
		 unsigned int x, const char *initstr)
{
	struct FIELD *newfield;

	newfield = xmalloc(sizeof(struct FIELD));

	if (list->list == NULL) {
		list->list = newfield;
		newfield->prevfield = newfield;
		newfield->nextfield = newfield;
	} else {
		newfield->prevfield = list->list->prevfield;
		list->list->prevfield->nextfield = newfield;
		list->list->prevfield = newfield;
		newfield->nextfield = list->list;
	}

	newfield->xpos = x;
	newfield->ypos = y;
	newfield->len = len;
	newfield->tlen = strlen(initstr);
	newfield->buf = xmallocz(len + 1);
	strncpy(newfield->buf, initstr, len);

	if (newfield->tlen > (len))
		newfield->tlen = len;

	wattrset(list->fieldwin, list->fieldattr);
	mvwprintw(list->fieldwin, y, x, "%-*s", len, newfield->buf);

	update_panels();
	doupdate();
}
예제 #10
0
파일: tcptable.c 프로젝트: josarlo84/iptraf
static void add_tcp_hash_entry(struct tcptable *table, struct tcptableent *entry)
{
	unsigned int hp;	/* hash position in table */
	struct tcp_hashentry *ptmp;

	hp = tcp_hash(&entry->saddr, &entry->daddr, entry->ifname);
	ptmp = xmallocz(sizeof(struct tcp_hashentry));
	/*
	 * Add backpointer from screen node to hash node for deletion later
	 * (Actually point to its predecessor coz of the header cell).
	 */

	entry->hash_node = ptmp;

	/*
	 * Update hash node and add it to list.
	 */

	ptmp->tcpnode = entry;
	ptmp->hp = hp;

	if (table->hash_table[hp] == NULL) {
		ptmp->prev_entry = NULL;
		table->hash_table[hp] = ptmp;
		ptmp->index = 1;
	}

	if (table->hash_tails[hp] != NULL) {
		table->hash_tails[hp]->next_entry = ptmp;
		ptmp->prev_entry = table->hash_tails[hp];
		ptmp->index = ptmp->prev_entry->index + 1;
	}
	table->hash_tails[hp] = ptmp;
	ptmp->next_entry = NULL;
}
예제 #11
0
파일: garray.c 프로젝트: hightoon/neovim
/// For a growing array that contains a list of strings: concatenate all the
/// strings with sep as separator.
///
/// @param gap
///
/// @returns the concatenated strings
char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep)
{
  const size_t nelem = (size_t) gap->ga_len;
  const char **strings = gap->ga_data;

  if (nelem == 0) {
    return (char_u *) xstrdup("");
  }

  size_t len = 0;
  for (size_t i = 0; i < nelem; i++) {
    len += strlen(strings[i]);
  }

  // add some space for the (num - 1) separators
  len += (nelem - 1) * strlen(sep);
  char *const ret = xmallocz(len);

  char *s = ret;
  for (size_t i = 0; i < nelem - 1; i++) {
    s = xstpcpy(s, strings[i]);
    s = xstpcpy(s, sep);
  }
  s = xstpcpy(s, strings[nelem - 1]);

  return (char_u *) ret;
}
예제 #12
0
파일: worktree.c 프로젝트: 1tgr/git
static int prune_worktree(const char *id, struct strbuf *reason)
{
	struct stat st;
	char *path;
	int fd, len;

	if (!is_directory(git_path("worktrees/%s", id))) {
		strbuf_addf(reason, _("Removing worktrees/%s: not a valid directory"), id);
		return 1;
	}
	if (file_exists(git_path("worktrees/%s/locked", id)))
		return 0;
	if (stat(git_path("worktrees/%s/gitdir", id), &st)) {
		strbuf_addf(reason, _("Removing worktrees/%s: gitdir file does not exist"), id);
		return 1;
	}
	fd = open(git_path("worktrees/%s/gitdir", id), O_RDONLY);
	if (fd < 0) {
		strbuf_addf(reason, _("Removing worktrees/%s: unable to read gitdir file (%s)"),
			    id, strerror(errno));
		return 1;
	}
	len = st.st_size;
	path = xmallocz(len);
	read_in_full(fd, path, len);
	close(fd);
	while (len && (path[len - 1] == '\n' || path[len - 1] == '\r'))
		len--;
	if (!len) {
		strbuf_addf(reason, _("Removing worktrees/%s: invalid gitdir file"), id);
		free(path);
		return 1;
	}
	path[len] = '\0';
	if (!file_exists(path)) {
		struct stat st_link;
		free(path);
		/*
		 * the repo is moved manually and has not been
		 * accessed since?
		 */
		if (!stat(git_path("worktrees/%s/link", id), &st_link) &&
		    st_link.st_nlink > 1)
			return 0;
		if (st.st_mtime <= expire) {
			strbuf_addf(reason, _("Removing worktrees/%s: gitdir file points to non-existent location"), id);
			return 1;
		} else {
			return 0;
		}
	}
	free(path);
	return 0;
}
예제 #13
0
파일: die.c 프로젝트: aaronwme/netsniff-ng
void panic_handler_add(void (*on_panic)(void *arg), void *arg)
{
	struct panic_handler *handler = xmallocz(sizeof(*handler));

	handler->arg		= arg;
	handler->pid		= getpid();
	handler->is_enabled	= true;
	handler->on_panic	= on_panic;
	handler->next		= panic_handlers;
	panic_handlers		= handler;
};
예제 #14
0
파일: archive.c 프로젝트: AbelTian/git
static void queue_directory(const unsigned char *sha1,
		struct strbuf *base, const char *filename,
		unsigned mode, int stage, struct archiver_context *c)
{
	struct directory *d;
	d = xmallocz(sizeof(*d) + base->len + 1 + strlen(filename));
	d->up	   = c->bottom;
	d->baselen = base->len;
	d->mode	   = mode;
	d->stage   = stage;
	c->bottom  = d;
	d->len = sprintf(d->path, "%.*s%s/", (int)base->len, base->buf, filename);
	hashcpy(d->sha1, sha1);
}
예제 #15
0
파일: check-ref-format.c 프로젝트: 0369/git
/*
 * Return a copy of refname but with leading slashes removed and runs
 * of adjacent slashes replaced with single slashes.
 *
 * This function is similar to normalize_path_copy(), but stripped down
 * to meet check_ref_format's simpler needs.
 */
static char *collapse_slashes(const char *refname)
{
	char *ret = xmallocz(strlen(refname));
	char ch;
	char prev = '/';
	char *cp = ret;

	while ((ch = *refname++) != '\0') {
		if (prev == '/' && ch == prev)
			continue;

		*cp++ = ch;
		prev = ch;
	}
	*cp = '\0';
	return ret;
}
예제 #16
0
파일: refs.c 프로젝트: 136357477/git
int refname_is_safe(const char *refname)
{
	if (starts_with(refname, "refs/")) {
		char *buf;
		int result;

		buf = xmallocz(strlen(refname));
		/*
		 * Does the refname try to escape refs/?
		 * For example: refs/foo/../bar is safe but refs/foo/../../bar
		 * is not.
		 */
		result = !normalize_path_copy(buf, refname + strlen("refs/"));
		free(buf);
		return result;
	}
	while (*refname) {
		if (!isupper(*refname) && *refname != '_')
			return 0;
		refname++;
	}
	return 1;
}
예제 #17
0
void *patch_delta(const void *src_buf, unsigned long src_size,
		  const void *delta_buf, unsigned long delta_size,
		  unsigned long *dst_size)
{
	const unsigned char *data, *top;
	unsigned char *dst_buf, *out, cmd;
	unsigned long size;

	if (delta_size < DELTA_SIZE_MIN)
		return NULL;

	data = delta_buf;
	top = (const unsigned char *) delta_buf + delta_size;

	/* make sure the orig file size matches what we expect */
	size = get_delta_hdr_size(&data, top);
	if (size != src_size)
		return NULL;

	/* now the result size */
	size = get_delta_hdr_size(&data, top);
	dst_buf = xmallocz(size);

	out = dst_buf;
	while (data < top) {
		cmd = *data++;
		if (cmd & 0x80) {
			unsigned long cp_off = 0, cp_size = 0;
			if (cmd & 0x01) cp_off = *data++;
			if (cmd & 0x02) cp_off |= (*data++ << 8);
			if (cmd & 0x04) cp_off |= (*data++ << 16);
			if (cmd & 0x08) cp_off |= ((unsigned) *data++ << 24);
			if (cmd & 0x10) cp_size = *data++;
			if (cmd & 0x20) cp_size |= (*data++ << 8);
			if (cmd & 0x40) cp_size |= (*data++ << 16);
			if (cp_size == 0) cp_size = 0x10000;
			if (unsigned_add_overflows(cp_off, cp_size) ||
			    cp_off + cp_size > src_size ||
			    cp_size > size)
				break;
			memcpy(out, (char *) src_buf + cp_off, cp_size);
			out += cp_size;
			size -= cp_size;
		} else if (cmd) {
			if (cmd > size)
				break;
			memcpy(out, data, cmd);
			out += cmd;
			data += cmd;
			size -= cmd;
		} else {
			/*
			 * cmd == 0 is reserved for future encoding
			 * extensions. In the mean time we must fail when
			 * encountering them (might be data corruption).
			 */
			error("unexpected delta opcode 0");
			goto bad;
		}
	}

	/* sanity check */
	if (data != top || size != 0) {
		error("delta replay has gone wild");
		bad:
		free(dst_buf);
		return NULL;
	}

	*dst_size = out - dst_buf;
	return dst_buf;
}
예제 #18
0
파일: wrapper.c 프로젝트: Lekensteyn/git
/*
 * xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of
 * "data" to the allocated memory, zero terminates the allocated memory,
 * and returns a pointer to the allocated memory. If the allocation fails,
 * the program dies.
 */
void *xmemdupz(const void *data, size_t len)
{
	return memcpy(xmallocz(len), data, len);
}
예제 #19
0
파일: wt-status.c 프로젝트: Lekensteyn/git
static void wt_status_print_change_data(struct wt_status *s,
					int change_type,
					struct string_list_item *it)
{
	struct wt_status_change_data *d = it->util;
	const char *c = color(change_type, s);
	int status;
	char *one_name;
	char *two_name;
	const char *one, *two;
	struct strbuf onebuf = STRBUF_INIT, twobuf = STRBUF_INIT;
	struct strbuf extra = STRBUF_INIT;
	static char *padding;
	static int label_width;
	const char *what;
	int len;

	if (!padding) {
		/* If DIFF_STATUS_* uses outside the range [A..Z], we're in trouble */
		label_width = maxwidth(wt_status_diff_status_string, 'A', 'Z');
		label_width += strlen(" ");
		padding = xmallocz(label_width);
		memset(padding, ' ', label_width);
	}

	one_name = two_name = it->string;
	switch (change_type) {
	case WT_STATUS_UPDATED:
		status = d->index_status;
		if (d->head_path)
			one_name = d->head_path;
		break;
	case WT_STATUS_CHANGED:
		if (d->new_submodule_commits || d->dirty_submodule) {
			strbuf_addstr(&extra, " (");
			if (d->new_submodule_commits)
				strbuf_addf(&extra, _("new commits, "));
			if (d->dirty_submodule & DIRTY_SUBMODULE_MODIFIED)
				strbuf_addf(&extra, _("modified content, "));
			if (d->dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)
				strbuf_addf(&extra, _("untracked content, "));
			strbuf_setlen(&extra, extra.len - 2);
			strbuf_addch(&extra, ')');
		}
		status = d->worktree_status;
		break;
	default:
		die("BUG: unhandled change_type %d in wt_status_print_change_data",
		    change_type);
	}

	one = quote_path(one_name, s->prefix, &onebuf);
	two = quote_path(two_name, s->prefix, &twobuf);

	status_printf(s, color(WT_STATUS_HEADER, s), "\t");
	what = wt_status_diff_status_string(status);
	if (!what)
		die(_("bug: unhandled diff status %c"), status);
	len = label_width - utf8_strwidth(what);
	assert(len >= 0);
	if (status == DIFF_STATUS_COPIED || status == DIFF_STATUS_RENAMED)
		status_printf_more(s, c, "%s%.*s%s -> %s",
				   what, len, padding, one, two);
	else
		status_printf_more(s, c, "%s%.*s%s",
				   what, len, padding, one);
	if (extra.len) {
		status_printf_more(s, color(WT_STATUS_HEADER, s), "%s", extra.buf);
		strbuf_release(&extra);
	}
	status_printf_more(s, GIT_COLOR_NORMAL, "\n");
	strbuf_release(&onebuf);
	strbuf_release(&twobuf);
}
예제 #20
0
파일: setup.c 프로젝트: 1tgr/git
/*
 * Try to read the location of the git directory from the .git file,
 * return path to git directory if found.
 *
 * On failure, if return_error_code is not NULL, return_error_code
 * will be set to an error code and NULL will be returned. If
 * return_error_code is NULL the function will die instead (for most
 * cases).
 */
const char *read_gitfile_gently(const char *path, int *return_error_code)
{
	const int max_file_size = 1 << 20;  /* 1MB */
	int error_code = 0;
	char *buf = NULL;
	char *dir = NULL;
	const char *slash;
	struct stat st;
	int fd;
	ssize_t len;

	if (stat(path, &st)) {
		error_code = READ_GITFILE_ERR_STAT_FAILED;
		goto cleanup_return;
	}
	if (!S_ISREG(st.st_mode)) {
		error_code = READ_GITFILE_ERR_NOT_A_FILE;
		goto cleanup_return;
	}
	if (st.st_size > max_file_size) {
		error_code = READ_GITFILE_ERR_TOO_LARGE;
		goto cleanup_return;
	}
	fd = open(path, O_RDONLY);
	if (fd < 0) {
		error_code = READ_GITFILE_ERR_OPEN_FAILED;
		goto cleanup_return;
	}
	buf = xmallocz(st.st_size);
	len = read_in_full(fd, buf, st.st_size);
	close(fd);
	if (len != st.st_size) {
		error_code = READ_GITFILE_ERR_READ_FAILED;
		goto cleanup_return;
	}
	if (!starts_with(buf, "gitdir: ")) {
		error_code = READ_GITFILE_ERR_INVALID_FORMAT;
		goto cleanup_return;
	}
	while (buf[len - 1] == '\n' || buf[len - 1] == '\r')
		len--;
	if (len < 9) {
		error_code = READ_GITFILE_ERR_NO_PATH;
		goto cleanup_return;
	}
	buf[len] = '\0';
	dir = buf + 8;

	if (!is_absolute_path(dir) && (slash = strrchr(path, '/'))) {
		size_t pathlen = slash+1 - path;
		dir = xstrfmt("%.*s%.*s", (int)pathlen, path,
			      (int)(len - 8), buf + 8);
		free(buf);
		buf = dir;
	}
	if (!is_git_directory(dir)) {
		error_code = READ_GITFILE_ERR_NOT_A_REPO;
		goto cleanup_return;
	}
	path = real_path(dir);

cleanup_return:
	if (return_error_code)
		*return_error_code = error_code;
	else if (error_code) {
		switch (error_code) {
		case READ_GITFILE_ERR_STAT_FAILED:
		case READ_GITFILE_ERR_NOT_A_FILE:
			/* non-fatal; follow return path */
			break;
		case READ_GITFILE_ERR_OPEN_FAILED:
			die_errno("Error opening '%s'", path);
		case READ_GITFILE_ERR_TOO_LARGE:
			die("Too large to be a .git file: '%s'", path);
		case READ_GITFILE_ERR_READ_FAILED:
			die("Error reading %s", path);
		case READ_GITFILE_ERR_INVALID_FORMAT:
			die("Invalid gitfile format: %s", path);
		case READ_GITFILE_ERR_NO_PATH:
			die("No path in gitfile: %s", path);
		case READ_GITFILE_ERR_NOT_A_REPO:
			die("Not a git repository: %s", dir);
		default:
			assert(0);
		}
	}

	free(buf);
	return error_code ? NULL : path;
}
예제 #21
0
파일: ifstats.c 프로젝트: ebichu/dd-wrt
static void initiflist(struct iflist **list)
{
	char ifname[IFNAMSIZ];

	*list = NULL;

	FILE *fd = open_procnetdev();
	if (fd == NULL) {
		tui_error(ANYKEY_MSG, "Unable to obtain interface list");
		return;
	}

	while (get_next_iface(fd, ifname, sizeof(ifname))) {
		if (!*ifname)
			continue;

		if (ifinlist(*list, ifname))	/* ignore entry if already in */
			continue;	/* interface list */

		/*
		 * Check if the interface is actually up running.  This prevents
		 * inactive devices in /proc/net/dev from actually appearing in
		 * interface lists used by IPTraf.
		 */

		if (!dev_up(ifname))
			continue;

		int ifindex = dev_get_ifindex(ifname);
		if (ifindex < 0)
			continue;
		/*
		 * At this point, the interface is now sure to be up and running.
		 */

		struct iflist *itmp = xmallocz(sizeof(struct iflist));
		strcpy(itmp->ifname, ifname);
		itmp->ifindex = ifindex;
		rate_init(&itmp->rate, 5);

		/* make the linked list sorted by ifindex */
		struct iflist *cur = *list, *last = NULL;
		while (cur != NULL && cur->ifindex < ifindex) {
			last = cur;
			cur = cur->next_entry;
		}
		itmp->prev_entry = last;
		itmp->next_entry = cur;
		if (cur)
			cur->prev_entry = itmp;
		if (last)
			last->next_entry = itmp;
		else
			*list = itmp;
	}
	fclose(fd);

	/* let the index follow the sorted linked list */
	unsigned int index = 1;
	struct iflist *cur;
	for (cur = *list; cur != NULL; cur = cur->next_entry)
		cur->index = index++;
}
예제 #22
0
파일: test-path-utils.c 프로젝트: 0369/git
int main(int argc, char **argv)
{
	if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
		char *buf = xmallocz(strlen(argv[2]));
		int rv = normalize_path_copy(buf, argv[2]);
		if (rv)
			buf = "++failed++";
		puts(buf);
		return 0;
	}

	if (argc >= 2 && !strcmp(argv[1], "real_path")) {
		while (argc > 2) {
			puts(real_path(argv[2]));
			argc--;
			argv++;
		}
		return 0;
	}

	if (argc >= 2 && !strcmp(argv[1], "absolute_path")) {
		while (argc > 2) {
			puts(absolute_path(argv[2]));
			argc--;
			argv++;
		}
		return 0;
	}

	if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) {
		int len;
		struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
		char *path = xstrdup(argv[2]);

		/*
		 * We have to normalize the arguments because under
		 * Windows, bash mangles arguments that look like
		 * absolute POSIX paths or colon-separate lists of
		 * absolute POSIX paths into DOS paths (e.g.,
		 * "/foo:/foo/bar" might be converted to
		 * "D:\Src\msysgit\foo;D:\Src\msysgit\foo\bar"),
		 * whereas longest_ancestor_length() requires paths
		 * that use forward slashes.
		 */
		if (normalize_path_copy(path, path))
			die("Path \"%s\" could not be normalized", argv[2]);
		string_list_split(&ceiling_dirs, argv[3], PATH_SEP, -1);
		filter_string_list(&ceiling_dirs, 0,
				   normalize_ceiling_entry, NULL);
		len = longest_ancestor_length(path, &ceiling_dirs);
		string_list_clear(&ceiling_dirs, 0);
		free(path);
		printf("%d\n", len);
		return 0;
	}

	if (argc >= 4 && !strcmp(argv[1], "prefix_path")) {
		char *prefix = argv[2];
		int prefix_len = strlen(prefix);
		int nongit_ok;
		setup_git_directory_gently(&nongit_ok);
		while (argc > 3) {
			puts(prefix_path(prefix, prefix_len, argv[3]));
			argc--;
			argv++;
		}
		return 0;
	}

	if (argc == 4 && !strcmp(argv[1], "strip_path_suffix")) {
		char *prefix = strip_path_suffix(argv[2], argv[3]);
		printf("%s\n", prefix ? prefix : "(null)");
		return 0;
	}

	if (argc == 3 && !strcmp(argv[1], "print_path")) {
		puts(argv[2]);
		return 0;
	}

	if (argc == 4 && !strcmp(argv[1], "relative_path")) {
		struct strbuf sb = STRBUF_INIT;
		const char *in, *prefix, *rel;
		normalize_argv_string(&in, argv[2]);
		normalize_argv_string(&prefix, argv[3]);
		rel = relative_path(in, prefix, &sb);
		if (!rel)
			puts("(null)");
		else
			puts(strlen(rel) > 0 ? rel : "(empty)");
		strbuf_release(&sb);
		return 0;
	}

	if (argc == 2 && !strcmp(argv[1], "basename"))
		return test_function(basename_data, basename, argv[1]);

	if (argc == 2 && !strcmp(argv[1], "dirname"))
		return test_function(dirname_data, dirname, argv[1]);

	fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
		argv[1] ? argv[1] : "(there was none)");
	return 1;
}
예제 #23
0
파일: charset.c 프로젝트: Saneyan/neovim
/// Translate a string into allocated memory, replacing special chars with
/// printable chars.  Returns NULL when out of memory.
///
/// @param s
///
/// @return translated string
char_u *transstr(char_u *s)
{
  char_u *res;
  char_u *p;
  int l, c;
  char_u hexbuf[11];

  if (has_mbyte) {
    // Compute the length of the result, taking account of unprintable
    // multi-byte characters.
    size_t len = 0;
    p = s;

    while (*p != NUL) {
      if ((l = (*mb_ptr2len)(p)) > 1) {
        c = (*mb_ptr2char)(p);
        p += l;

        if (vim_isprintc(c)) {
          len += l;
        } else {
          transchar_hex(hexbuf, c);
          len += STRLEN(hexbuf);
        }
      } else {
        l = byte2cells(*p++);

        if (l > 0) {
          len += l;
        } else {
          // illegal byte sequence
          len += 4;
        }
      }
    }
    res = xmallocz(len);
  } else {
    res = xmallocz(vim_strsize(s));
  }

  *res = NUL;
  p = s;

  while (*p != NUL) {
    if (has_mbyte && ((l = (*mb_ptr2len)(p)) > 1)) {
      c = (*mb_ptr2char)(p);

      if (vim_isprintc(c)) {
        // append printable multi-byte char
        STRNCAT(res, p, l);
      } else {
        transchar_hex(res + STRLEN(res), c);
      }
      p += l;
    } else {
      STRCAT(res, transchar_byte(*p++));
    }
  }

  return res;
}
예제 #24
0
파일: fltedit.c 프로젝트: josarlo84/iptraf
void modify_host_parameters(struct filterlist *fl)
{
	WINDOW *bwin;
	PANEL *bpanel;
	WINDOW *win;
	PANEL *panel;
	struct filterent *fe;
	struct filterent *ftemp;

	struct filterent *firstvisible = NULL;

	unsigned int idx = 0;
	int endloop_local = 0;
	int ch;
	int gh_aborted = 0;

	char s_portstr1[8];
	char d_portstr1[8];
	char s_portstr2[8];
	char d_portstr2[8];

	char inexstr[2];
	char matchop[2];

	bwin = newwin(15, 80, (LINES - 15) / 2, (COLS - 80) / 2);

	bpanel = new_panel(bwin);
	win = newwin(13, 78, (LINES - 13) / 2, (COLS - 78) / 2);
	panel = new_panel(win);

	wattrset(bwin, BOXATTR);
	tx_box(bwin, ACS_VLINE, ACS_HLINE);

	mvwprintw(bwin, 0, 2, " Source ");
	mvwprintw(bwin, 0, 38, " Destination ");
	mvwprintw(bwin, 0, 74, " I/E ");

	mvwprintw(bwin, 14, 1, " Filter Data ");
	tx_stdwinset(win);
	scrollok(win, 0);
	wattrset(win, STDATTR);
	tx_colorwin(win);

	move(LINES - 1, 1);
	tx_printkeyhelp("Up/Down", "-move ptr ", stdscr, HIGHATTR,
			STATUSBARATTR);
	tx_printkeyhelp("I", "-insert ", stdscr, HIGHATTR, STATUSBARATTR);
	tx_printkeyhelp("A", "-add to list ", stdscr, HIGHATTR, STATUSBARATTR);
	tx_printkeyhelp("D", "-delete ", stdscr, HIGHATTR, STATUSBARATTR);
	tx_printkeyhelp("Enter", "-edit ", stdscr, HIGHATTR, STATUSBARATTR);
	tx_printkeyhelp("X/Ctrl+X", "-exit", stdscr, HIGHATTR, STATUSBARATTR);

	update_panels();
	doupdate();

	firstvisible = fl->head;

	update_hp_screen(firstvisible, win);

	idx = 0;
	fe = firstvisible;

	update_panels();
	doupdate();

	do {
		if (fe != NULL) {
			print_hostparam_line(fe, idx, win, BARSTDATTR);
		}

		ch = wgetch(win);

		if (fe != NULL)
			print_hostparam_line(fe, idx, win, STDATTR);

		switch (ch) {
		case KEY_UP:
			if (fl->head != NULL) {
				if (fe->prev_entry != NULL) {
					if (idx > 0)
						idx--;
					else {
						scrollok(win, 1);
						wscrl(win, -1);
						firstvisible =
						    firstvisible->prev_entry;
					}
					fe = fe->prev_entry;
				}
			}
			break;
		case KEY_DOWN:
			if (fl->head != NULL) {
				if (fe->next_entry != NULL) {
					if (idx < 12)
						idx++;
					else {
						scrollok(win, 1);
						wscrl(win, 1);
						firstvisible =
						    firstvisible->next_entry;
					}
					fe = fe->next_entry;
				}
			}
			break;
		case 'i':
		case 'I':
		case KEY_IC:
			ftemp = xmallocz(sizeof(struct filterent));

			gethostparams(&(ftemp->hp), "", "", "", "", "", "", "",
				      "", "I", "N", &gh_aborted);

			if (gh_aborted) {
				free(ftemp);
				continue;
			}

			if (fl->head == NULL) {
				ftemp->next_entry = ftemp->prev_entry = NULL;
				fl->head = fl->tail = ftemp;
				firstvisible = fl->head;
				idx = 0;
			} else {
				ftemp->next_entry = fe;
				ftemp->prev_entry = fe->prev_entry;

				/*
				 * Point firstvisible at new entry if we inserted at the
				 * top of the list.
				 */

				if (ftemp->prev_entry == NULL) {
					fl->head = ftemp;
					firstvisible = ftemp;
				} else
					fe->prev_entry->next_entry = ftemp;

				fe->prev_entry = ftemp;
			}

			if (ftemp->next_entry == NULL)
				fl->tail = ftemp;

			fe = ftemp;
			update_hp_screen(firstvisible, win);
			break;
		case 'a':
		case 'A':
		case 1:
			ftemp = xmallocz(sizeof(struct filterent));

			gethostparams(&(ftemp->hp), "", "", "", "", "", "", "",
				      "", "I", "N", &gh_aborted);

			if (gh_aborted) {
				free(ftemp);
				continue;
			}

			/*
			 * Add new node to the end of the list (or to the head if the
			 * list is empty.
			 */
			if (fl->tail != NULL) {
				fl->tail->next_entry = ftemp;
				ftemp->prev_entry = fl->tail;
			} else {
				fl->head = ftemp;
				fl->tail = ftemp;
				ftemp->prev_entry = ftemp->next_entry = NULL;
				firstvisible = fl->head;
				fe = ftemp;
				idx = 0;
			}

			ftemp->next_entry = NULL;
			fl->tail = ftemp;
			update_hp_screen(firstvisible, win);
			break;
		case 'd':
		case 'D':
		case KEY_DC:
			if (fl->head != NULL) {
				/*
				 * Move firstvisible down if it's pointing to the target
				 * entry.
				 */

				if (firstvisible == fe)
					firstvisible = fe->next_entry;

				/*
				 * Detach target node from list.
				 */
				if (fe->next_entry != NULL)
					fe->next_entry->prev_entry =
					    fe->prev_entry;
				else
					fl->tail = fe->prev_entry;

				if (fe->prev_entry != NULL)
					fe->prev_entry->next_entry =
					    fe->next_entry;
				else
					fl->head = fe->next_entry;

				/*
				 * Move pointer up if we're deleting the last entry.
				 * The list tail pointer has since been moved to the
				 * previous entry.
				 */
				if (fe->prev_entry == fl->tail) {
					ftemp = fe->prev_entry;

					/*
					 * Move screen pointer up. Really adjust the index if
					 * the pointer is anywhere below the top of the screen.
					 */
					if (idx > 0)
						idx--;
					else {
						/*
						 * Otherwise scroll the list down, and adjust the
						 * firstvisible pointer to point to the entry
						 * previous to the target.
						 */
						if (ftemp != NULL) {
							firstvisible = ftemp;
						}
					}
				} else
					/*
					 * If we reach this point, we're deleting from before
					 * the tail of the list.  In that case, we point the
					 * screen pointer at the entry following the target.
					 */
					ftemp = fe->next_entry;

				free(fe);
				fe = ftemp;
				update_hp_screen(firstvisible, win);
			}
			break;
		case 13:
			if (fe != NULL) {
				sprintf(s_portstr1, "%u", fe->hp.sport1);
				sprintf(s_portstr2, "%u", fe->hp.sport2);
				sprintf(d_portstr1, "%u", fe->hp.dport1);
				sprintf(d_portstr2, "%u", fe->hp.dport2);
				inexstr[0] = toupper(fe->hp.reverse);
				inexstr[1] = '\0';
				matchop[0] = toupper(fe->hp.match_opposite);
				matchop[1] = '\0';

				gethostparams(&(fe->hp), fe->hp.s_fqdn,
					      fe->hp.s_mask, s_portstr1,
					      s_portstr2, fe->hp.d_fqdn,
					      fe->hp.d_mask, d_portstr1,
					      d_portstr2, inexstr, matchop,
					      &gh_aborted);

				update_hp_screen(firstvisible, win);
			}

			break;
		case 'x':
		case 'X':
		case 'q':
		case 'Q':
		case 27:
		case 24:
			endloop_local = 1;
			break;
		case 'l':
		case 'L':
			tx_refresh_screen();
			break;
		}
		update_panels();
		doupdate();
	} while (!endloop_local);

	del_panel(panel);
	delwin(win);
	del_panel(bpanel);
	delwin(bwin);
	update_panels();
	doupdate();
}
예제 #25
0
파일: merge-tree.c 프로젝트: koraktor/git
static char *traverse_path(const struct traverse_info *info, const struct name_entry *n)
{
	char *path = xmallocz(traverse_path_len(info, n) + the_hash_algo->rawsz);
	return make_traverse_path(path, info, n);
}
예제 #26
0
파일: othptab.c 프로젝트: josarlo84/iptraf
struct othptabent *add_othp_entry(struct othptable *table, struct pkt_hdr *pkt,
				  struct sockaddr_storage *saddr,
				  struct sockaddr_storage *daddr,
				  int is_ip,
				  int protocol,
				  char *packet2,
				  char *ifname, int *rev_lookup, int rvnfd,
				  int logging, FILE *logfile, int fragment)
{
	struct othptabent *new_entry;
	struct othptabent *temp;

	new_entry = xmallocz(sizeof(struct othptabent));

	new_entry->is_ip = is_ip;
	new_entry->fragment = fragment;

	if (options.mac || !is_ip) {
		if (pkt->pkt_hatype == ARPHRD_ETHER) {
			convmacaddr((char *) pkt->ethhdr->h_source, new_entry->smacaddr);
			convmacaddr((char *) pkt->ethhdr->h_dest, new_entry->dmacaddr);
		} else if (pkt->pkt_hatype == ARPHRD_FDDI) {
			convmacaddr((char *) pkt->fddihdr->saddr, new_entry->smacaddr);
			convmacaddr((char *) pkt->fddihdr->daddr, new_entry->dmacaddr);
		}
	}

	if (is_ip) {
		sockaddr_copy(&new_entry->saddr, saddr);
		sockaddr_copy(&new_entry->daddr, daddr);

		revname(rev_lookup, saddr, new_entry->s_fqdn,
			sizeof(new_entry->s_fqdn), rvnfd);
		revname(rev_lookup, daddr, new_entry->d_fqdn,
			sizeof(new_entry->d_fqdn), rvnfd);

		if (!fragment) {
			if (protocol == IPPROTO_ICMP) {
				new_entry->un.icmp.type =
				    ((struct icmphdr *) packet2)->type;
				new_entry->un.icmp.code =
				    ((struct icmphdr *) packet2)->code;
			} else if (protocol == IPPROTO_ICMPV6) {
				new_entry->un.icmp6.type =
				    ((struct icmp6_hdr *) packet2)->icmp6_type;
				new_entry->un.icmp6.code =
				    ((struct icmp6_hdr *) packet2)->icmp6_code;
			} else if (protocol == IPPROTO_UDP) {
				servlook(ntohs(((struct udphdr *) packet2)->source),
					 IPPROTO_UDP, new_entry->un.udp.s_sname,
					 10);
				servlook(ntohs(((struct udphdr *) packet2)->dest),
					 IPPROTO_UDP, new_entry->un.udp.d_sname,
					 10);
			} else if (protocol == IPPROTO_OSPFIGP) {
				new_entry->un.ospf.type =
				    ((struct ospfhdr *) packet2)->ospf_type;
				new_entry->un.ospf.area =
				    ntohl(((struct ospfhdr *) packet2)->
					  ospf_areaid.s_addr);
				inet_ntop(AF_INET,
					  &((struct ospfhdr *)packet2)->ospf_routerid,
					  new_entry->un.ospf.routerid,
					  sizeof(new_entry->un.ospf.routerid));
			}
		}
	} else {
		new_entry->linkproto = pkt->pkt_hatype;

		if (protocol == ETH_P_ARP) {
			new_entry->un.arp.opcode =
			    ((struct arp_hdr *) packet2)->ar_op;
			memcpy(&(new_entry->un.arp.src_ip_address),
			       &(((struct arp_hdr *) packet2)->ar_sip), 4);
			memcpy(&(new_entry->un.arp.dest_ip_address),
			       &(((struct arp_hdr *) packet2)->ar_tip), 4);
		} else if (protocol == ETH_P_RARP) {
			new_entry->un.rarp.opcode =
			    ((struct arphdr *) packet2)->ar_op;
			memcpy(&(new_entry->un.rarp.src_mac_address),
			       &(((struct arp_hdr *) packet2)->ar_sha), 6);
			memcpy(&(new_entry->un.rarp.dest_mac_address),
			       &(((struct arp_hdr *) packet2)->ar_tha), 6);
		}
	}

	new_entry->protocol = protocol;
	strcpy(new_entry->iface, ifname);

	new_entry->pkt_length = pkt->pkt_len;

	if (table->head == NULL) {
		new_entry->prev_entry = NULL;
		table->head = new_entry;
		table->firstvisible = new_entry;
	}
	/*
	 * Max number of entries in the lower window is 512.  Upon reaching
	 * this figure, oldest entries are thrown out.
	 */

	if (table->count == 512) {
		if (table->firstvisible == table->head) {
			wscrl(table->othpwin, 1);
			printothpentry(table, table->lastvisible->next_entry,
				       table->oimaxy - 1, logging, logfile);
			table->firstvisible = table->firstvisible->next_entry;
			table->lastvisible = table->lastvisible->next_entry;
		}
		temp = table->head;
		table->head = table->head->next_entry;
		table->head->prev_entry = NULL;
		free(temp);
	} else
		table->count++;

	if (table->tail != NULL) {
		new_entry->prev_entry = table->tail;
		table->tail->next_entry = new_entry;
	}
	table->tail = new_entry;
	new_entry->next_entry = NULL;

	table->lastpos++;
	new_entry->index = table->lastpos;

	if (table->count <= table->oimaxy) {
		table->lastvisible = new_entry;
		printothpentry(table, new_entry, table->count - 1, logging,
			       logfile);
	} else if (table->lastvisible == table->tail->prev_entry) {
		wscrl(table->othpwin, 1);
		table->firstvisible = table->firstvisible->next_entry;
		table->lastvisible = table->tail;
		printothpentry(table, new_entry, table->oimaxy - 1, logging,
			       logfile);
	}
	return new_entry;
}
예제 #27
0
파일: cursor.c 프로젝트: ZyX-I/neovim
static int coladvance2(
    pos_T *pos,
    bool addspaces,                /* change the text to achieve our goal? */
    bool finetune,                 /* change char offset for the exact column */
    colnr_T wcol                   /* column to move to */
)
{
  int idx;
  char_u      *ptr;
  char_u      *line;
  colnr_T col = 0;
  int csize = 0;
  int one_more;
  int head = 0;

  one_more = (State & INSERT)
             || restart_edit != NUL
             || (VIsual_active && *p_sel != 'o')
             || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL);
  line = ml_get_buf(curbuf, pos->lnum, false);

  if (wcol >= MAXCOL) {
    idx = (int)STRLEN(line) - 1 + one_more;
    col = wcol;

    if ((addspaces || finetune) && !VIsual_active) {
      curwin->w_curswant = linetabsize(line) + one_more;
      if (curwin->w_curswant > 0)
        --curwin->w_curswant;
    }
  } else {
    int width = curwin->w_width - win_col_off(curwin);

    if (finetune
        && curwin->w_p_wrap
        && curwin->w_width != 0
        && wcol >= (colnr_T)width) {
      csize = linetabsize(line);
      if (csize > 0)
        csize--;

      if (wcol / width > (colnr_T)csize / width
          && ((State & INSERT) == 0 || (int)wcol > csize + 1)) {
        /* In case of line wrapping don't move the cursor beyond the
         * right screen edge.  In Insert mode allow going just beyond
         * the last character (like what happens when typing and
         * reaching the right window edge). */
        wcol = (csize / width + 1) * width - 1;
      }
    }

    ptr = line;
    while (col <= wcol && *ptr != NUL) {
      /* Count a tab for what it's worth (if list mode not on) */
      csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
      MB_PTR_ADV(ptr);
      col += csize;
    }
    idx = (int)(ptr - line);
    /*
     * Handle all the special cases.  The virtual_active() check
     * is needed to ensure that a virtual position off the end of
     * a line has the correct indexing.  The one_more comparison
     * replaces an explicit add of one_more later on.
     */
    if (col > wcol || (!virtual_active() && one_more == 0)) {
      idx -= 1;
      /* Don't count the chars from 'showbreak'. */
      csize -= head;
      col -= csize;
    }

    if (virtual_active()
        && addspaces
        && ((col != wcol && col != wcol + 1) || csize > 1)) {
      /* 'virtualedit' is set: The difference between wcol and col is
       * filled with spaces. */

      if (line[idx] == NUL) {
        /* Append spaces */
        int correct = wcol - col;
        char_u *newline = xmallocz((size_t)(idx + correct));
        memcpy(newline, line, (size_t)idx);
        memset(newline + idx, ' ', (size_t)correct);

        ml_replace(pos->lnum, newline, false);
        changed_bytes(pos->lnum, (colnr_T)idx);
        idx += correct;
        col = wcol;
      } else {
        /* Break a tab */
        int linelen = (int)STRLEN(line);
        int correct = wcol - col - csize + 1;             /* negative!! */
        char_u  *newline;

        if (-correct > csize)
          return FAIL;

        newline = xmallocz((size_t)(linelen - 1 + csize));
        // Copy first idx chars
        memcpy(newline, line, (size_t)idx);
        // Replace idx'th char with csize spaces
        memset(newline + idx, ' ', (size_t)csize);
        // Copy the rest of the line
        memcpy(newline + idx + csize, line + idx + 1,
               (size_t)(linelen - idx - 1));

        ml_replace(pos->lnum, newline, false);
        changed_bytes(pos->lnum, idx);
        idx += (csize - 1 + correct);
        col += correct;
      }
    }
  }

  if (idx < 0)
    pos->col = 0;
  else
    pos->col = idx;

  pos->coladd = 0;

  if (finetune) {
    if (wcol == MAXCOL) {
      /* The width of the last character is used to set coladd. */
      if (!one_more) {
        colnr_T scol, ecol;

        getvcol(curwin, pos, &scol, NULL, &ecol);
        pos->coladd = ecol - scol;
      }
    } else {
      int b = (int)wcol - (int)col;

      /* The difference between wcol and col is used to set coladd. */
      if (b > 0 && b < (MAXCOL - 2 * curwin->w_width))
        pos->coladd = b;

      col += b;
    }
  }

  // Prevent from moving onto a trail byte.
  if (has_mbyte) {
    mark_mb_adjustpos(curbuf, pos);
  }

  if (col < wcol)
    return FAIL;
  return OK;
}