/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include "common.h"
#include "config.h"
#include "filebuf.h"
#include "sysdir.h"
#include "buffer.h"
#include "buf_text.h"
#include "git2/config.h"
#include "git2/sys/config.h"
#include "git2/types.h"
#include "strmap.h"
#include "array.h"

#include <ctype.h>
#include <sys/types.h>
#include <regex.h>

typedef struct cvar_t {
	struct cvar_t *next;
	git_config_entry *entry;
	bool included; /* whether this is part of [include] */
} cvar_t;

typedef struct git_config_file_iter {
	git_config_iterator parent;
	git_strmap_iter iter;
	cvar_t* next_var;
} git_config_file_iter;

/* Max depth for [include] directives */
#define MAX_INCLUDE_DEPTH 10

#define CVAR_LIST_HEAD(list) ((list)->head)

#define CVAR_LIST_TAIL(list) ((list)->tail)

#define CVAR_LIST_NEXT(var) ((var)->next)

#define CVAR_LIST_EMPTY(list) ((list)->head == NULL)

#define CVAR_LIST_APPEND(list, var) do {\
	if (CVAR_LIST_EMPTY(list)) {\
		CVAR_LIST_HEAD(list) = CVAR_LIST_TAIL(list) = var;\
	} else {\
		CVAR_LIST_NEXT(CVAR_LIST_TAIL(list)) = var;\
		CVAR_LIST_TAIL(list) = var;\
	}\
} while(0)

#define CVAR_LIST_REMOVE_HEAD(list) do {\
	CVAR_LIST_HEAD(list) = CVAR_LIST_NEXT(CVAR_LIST_HEAD(list));\
} while(0)

#define CVAR_LIST_REMOVE_AFTER(var) do {\
	CVAR_LIST_NEXT(var) = CVAR_LIST_NEXT(CVAR_LIST_NEXT(var));\
} while(0)

#define CVAR_LIST_FOREACH(list, iter)\
	for ((iter) = CVAR_LIST_HEAD(list);\
		 (iter) != NULL;\
		 (iter) = CVAR_LIST_NEXT(iter))

/*
 * Inspired by the FreeBSD functions
 */
#define CVAR_LIST_FOREACH_SAFE(start, iter, tmp)\
	for ((iter) = CVAR_LIST_HEAD(vars);\
		 (iter) && (((tmp) = CVAR_LIST_NEXT(iter) || 1));\
		 (iter) = (tmp))

struct reader {
	git_oid checksum;
	char *file_path;
	git_buf buffer;
	char *read_ptr;
	int line_number;
	int eof;
};

typedef struct {
	git_atomic refcount;
	git_strmap *values;
} refcounted_strmap;

typedef struct {
	git_config_backend parent;
	/* mutex to coordinate accessing the values */
	git_mutex values_mutex;
	refcounted_strmap *values;
} diskfile_header;

typedef struct {
	diskfile_header header;

	git_config_level_t level;

	git_array_t(struct reader) readers;

	bool locked;
	git_filebuf locked_buf;
	git_buf locked_content;

	char  *file_path;
} diskfile_backend;

typedef struct {
	diskfile_header header;

	diskfile_backend *snapshot_from;
} diskfile_readonly_backend;

static int config_read(git_strmap *values, diskfile_backend *cfg_file, struct reader *reader, git_config_level_t level, int depth);
static int config_write(diskfile_backend *cfg, const char *key, const regex_t *preg, const char *value);
static char *escape_value(const char *ptr);

int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in);
static int config_snapshot(git_config_backend **out, git_config_backend *in);

static void set_parse_error(struct reader *reader, int col, const char *error_str)
{
	giterr_set(GITERR_CONFIG, "failed to parse config file: %s (in %s:%d, column %d)",
		error_str, reader->file_path, reader->line_number, col);
}

static int config_error_readonly(void)
{
	giterr_set(GITERR_CONFIG, "this backend is read-only");
	return -1;
}

static void cvar_free(cvar_t *var)
{
	if (var == NULL)
		return;

	git__free((char*)var->entry->name);
	git__free((char *)var->entry->value);
	git__free(var->entry);
	git__free(var);
}

int git_config_file_normalize_section(char *start, char *end)
{
	char *scan;

	if (start == end)
		return GIT_EINVALIDSPEC;

	/* Validate and downcase range */
	for (scan = start; *scan; ++scan) {
		if (end && scan >= end)
			break;
		if (isalnum(*scan))
			*scan = (char)git__tolower(*scan);
		else if (*scan != '-' || scan == start)
			return GIT_EINVALIDSPEC;
	}

	if (scan == start)
		return GIT_EINVALIDSPEC;

	return 0;
}

/* Add or append the new config option */
static int append_entry(git_strmap *values, cvar_t *var)
{
	git_strmap_iter pos;
	cvar_t *existing;
	int error = 0;

	pos = git_strmap_lookup_index(values, var->entry->name);
	if (!git_strmap_valid_index(values, pos)) {
		git_strmap_insert(values, var->entry->name, var, &error);
	} else {
		existing = git_strmap_value_at(values, pos);
		while (existing->next != NULL) {
			existing = existing->next;
		}
		existing->next = var;
	}

	if (error > 0)
		error = 0;

	return error;
}

static void free_vars(git_strmap *values)
{
	cvar_t *var = NULL;

	if (values == NULL)
		return;

	git_strmap_foreach_value(values, var,
		while (var != NULL) {
			cvar_t *next = CVAR_LIST_NEXT(var);
			cvar_free(var);
			var = next;
		});

	git_strmap_free(values);
}

static void refcounted_strmap_free(refcounted_strmap *map)
{
	if (!map)
		return;

	if (git_atomic_dec(&map->refcount) != 0)
		return;

	free_vars(map->values);
	git__free(map);
}

/**
 * Take the current values map from the backend and increase its
 * refcount. This is its own function to make sure we use the mutex to
 * avoid the map pointer from changing under us.
 */
static refcounted_strmap *refcounted_strmap_take(diskfile_header *h)
{
	refcounted_strmap *map;

	if (git_mutex_lock(&h->values_mutex) < 0) {
	    giterr_set(GITERR_OS, "failed to lock config backend");
	    return NULL;
	}

	map = h->values;
	git_atomic_inc(&map->refcount);

	git_mutex_unlock(&h->values_mutex);

	return map;
}

static int refcounted_strmap_alloc(refcounted_strmap **out)
{
	refcounted_strmap *map;
	int error;

	map = git__calloc(1, sizeof(refcounted_strmap));
	GITERR_CHECK_ALLOC(map);

	git_atomic_set(&map->refcount, 1);

	if ((error = git_strmap_alloc(&map->values)) < 0)
		git__free(map);
	else
		*out = map;

	return error;
}

static int config_open(git_config_backend *cfg, git_config_level_t level)
{
	int res;
	struct reader *reader;
	diskfile_backend *b = (diskfile_backend *)cfg;

	b->level = level;

	if ((res = refcounted_strmap_alloc(&b->header.values)) < 0)
		return res;

	git_array_init(b->readers);
	reader = git_array_alloc(b->readers);
	if (!reader) {
		refcounted_strmap_free(b->header.values);
		return -1;
	}
	memset(reader, 0, sizeof(struct reader));

	reader->file_path = git__strdup(b->file_path);
	GITERR_CHECK_ALLOC(reader->file_path);

	git_buf_init(&reader->buffer, 0);
	res = git_futils_readbuffer_updated(
		&reader->buffer, b->file_path, &reader->checksum, NULL);

	/* It's fine if the file doesn't exist */
	if (res == GIT_ENOTFOUND)
		return 0;

	if (res < 0 || (res = config_read(b->header.values->values, b, reader, level, 0)) < 0) {
		refcounted_strmap_free(b->header.values);
		b->header.values = NULL;
	}

	reader = git_array_get(b->readers, 0);
	git_buf_free(&reader->buffer);

	return res;
}

/* The meat of the refresh, as we want to use it in different places */
static int config__refresh(git_config_backend *cfg)
{
	refcounted_strmap *values = NULL, *tmp;
	diskfile_backend *b = (diskfile_backend *)cfg;
	struct reader *reader = NULL;
	int error = 0;

	if ((error = refcounted_strmap_alloc(&values)) < 0)
		goto out;

	reader = git_array_get(b->readers, git_array_size(b->readers) - 1);
	GITERR_CHECK_ALLOC(reader);

	if ((error = config_read(values->values, b, reader, b->level, 0)) < 0)
		goto out;

	if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
		giterr_set(GITERR_OS, "failed to lock config backend");
		goto out;
	}

	tmp = b->header.values;
	b->header.values = values;
	values = tmp;

	git_mutex_unlock(&b->header.values_mutex);

out:
	refcounted_strmap_free(values);
	if (reader)
		git_buf_free(&reader->buffer);
	return error;
}

static int config_refresh(git_config_backend *cfg)
{
	int error = 0, updated = 0, any_updated = 0;
	diskfile_backend *b = (diskfile_backend *)cfg;
	struct reader *reader = NULL;
	uint32_t i;

	for (i = 0; i < git_array_size(b->readers); i++) {
		reader = git_array_get(b->readers, i);
		error = git_futils_readbuffer_updated(
			&reader->buffer, reader->file_path,
			&reader->checksum, &updated);

		if (error < 0 && error != GIT_ENOTFOUND)
			return error;

		if (updated)
			any_updated = 1;
	}

	if (!any_updated)
		return (error == GIT_ENOTFOUND) ? 0 : error;

	return config__refresh(cfg);
}

static void backend_free(git_config_backend *_backend)
{
	diskfile_backend *backend = (diskfile_backend *)_backend;
	uint32_t i;

	if (backend == NULL)
		return;

	for (i = 0; i < git_array_size(backend->readers); i++) {
		struct reader *r = git_array_get(backend->readers, i);
		git__free(r->file_path);
	}
	git_array_clear(backend->readers);

	git__free(backend->file_path);
	refcounted_strmap_free(backend->header.values);
	git_mutex_free(&backend->header.values_mutex);
	git__free(backend);
}

static void config_iterator_free(
	git_config_iterator* iter)
{
	iter->backend->free(iter->backend);
	git__free(iter);
}

static int config_iterator_next(
	git_config_entry **entry,
	git_config_iterator *iter)
{
	git_config_file_iter *it = (git_config_file_iter *) iter;
	diskfile_header *h = (diskfile_header *) it->parent.backend;
	git_strmap *values = h->values->values;
	int err = 0;
	cvar_t * var;

	if (it->next_var == NULL) {
		err = git_strmap_next((void**) &var, &(it->iter), values);
	} else {
		var = it->next_var;
	}

	if (err < 0) {
		it->next_var = NULL;
		return err;
	}

	*entry = var->entry;
	it->next_var = CVAR_LIST_NEXT(var);

	return 0;
}

static int config_iterator_new(
	git_config_iterator **iter,
	struct git_config_backend* backend)
{
	diskfile_header *h;
	git_config_file_iter *it;
	git_config_backend *snapshot;
	diskfile_backend *b = (diskfile_backend *) backend;
	int error;

	if ((error = config_snapshot(&snapshot, backend)) < 0)
		return error;

	if ((error = snapshot->open(snapshot, b->level)) < 0)
		return error;

	it = git__calloc(1, sizeof(git_config_file_iter));
	GITERR_CHECK_ALLOC(it);

	h = (diskfile_header *)snapshot;

	/* strmap_begin() is currently a macro returning 0 */
	GIT_UNUSED(h);

	it->parent.backend = snapshot;
	it->iter = git_strmap_begin(h->values);
	it->next_var = NULL;

	it->parent.next = config_iterator_next;
	it->parent.free = config_iterator_free;
	*iter = (git_config_iterator *) it;

	return 0;
}

static int config_set(git_config_backend *cfg, const char *name, const char *value)
{
	diskfile_backend *b = (diskfile_backend *)cfg;
	refcounted_strmap *map;
	git_strmap *values;
	char *key, *esc_value = NULL;
	khiter_t pos;
	int rval, ret;

	if ((rval = git_config__normalize_name(name, &key)) < 0)
		return rval;

	if ((map = refcounted_strmap_take(&b->header)) == NULL)
		return -1;
	values = map->values;

	/*
	 * Try to find it in the existing values and update it if it
	 * only has one value.
	 */
	pos = git_strmap_lookup_index(values, key);
	if (git_strmap_valid_index(values, pos)) {
		cvar_t *existing = git_strmap_value_at(values, pos);

		if (existing->next != NULL) {
			giterr_set(GITERR_CONFIG, "multivar incompatible with simple set");
			ret = -1;
			goto out;
		}

		/* don't update if old and new values already match */
		if ((!existing->entry->value && !value) ||
			(existing->entry->value && value &&
			 !strcmp(existing->entry->value, value))) {
			ret = 0;
			goto out;
		}
	}

	/* No early returns due to sanity checks, let's write it out and refresh */

	if (value) {
		esc_value = escape_value(value);
		GITERR_CHECK_ALLOC(esc_value);
	}

	if ((ret = config_write(b, key, NULL, esc_value)) < 0)
		goto out;

	ret = config_refresh(cfg);

out:
	refcounted_strmap_free(map);
	git__free(esc_value);
	git__free(key);
	return ret;
}

/* release the map containing the entry as an equivalent to freeing it */
static void release_map(git_config_entry *entry)
{
	refcounted_strmap *map = (refcounted_strmap *) entry->payload;
	refcounted_strmap_free(map);
}

/*
 * Internal function that actually gets the value in string form
 */
static int config_get(git_config_backend *cfg, const char *key, git_config_entry **out)
{
	diskfile_header *h = (diskfile_header *)cfg;
	refcounted_strmap *map;
	git_strmap *values;
	khiter_t pos;
	cvar_t *var;
	int error = 0;

	if (!h->parent.readonly && ((error = config_refresh(cfg)) < 0))
		return error;

	if ((map = refcounted_strmap_take(h)) == NULL)
		return -1;
	values = map->values;

	pos = git_strmap_lookup_index(values, key);

	/* no error message; the config system will write one */
	if (!git_strmap_valid_index(values, pos)) {
		refcounted_strmap_free(map);
		return GIT_ENOTFOUND;
	}

	var = git_strmap_value_at(values, pos);
	while (var->next)
		var = var->next;

	*out = var->entry;
	(*out)->free = release_map;
	(*out)->payload = map;

	return error;
}

static int config_set_multivar(
	git_config_backend *cfg, const char *name, const char *regexp, const char *value)
{
	diskfile_backend *b = (diskfile_backend *)cfg;
	char *key;
	regex_t preg;
	int result;

	assert(regexp);

	if ((result = git_config__normalize_name(name, &key)) < 0)
		return result;

	result = p_regcomp(&preg, regexp, REG_EXTENDED);
	if (result != 0) {
		giterr_set_regex(&preg, result);
		result = -1;
		goto out;
	}

	/* If we do have it, set call config_write() and reload */
	if ((result = config_write(b, key, &preg, value)) < 0)
		goto out;

	result = config_refresh(cfg);

out:
	git__free(key);
	regfree(&preg);

	return result;
}

static int config_delete(git_config_backend *cfg, const char *name)
{
	cvar_t *var;
	diskfile_backend *b = (diskfile_backend *)cfg;
	refcounted_strmap *map;	git_strmap *values;
	char *key;
	int result;
	khiter_t pos;

	if ((result = git_config__normalize_name(name, &key)) < 0)
		return result;

	if ((map = refcounted_strmap_take(&b->header)) == NULL)
		return -1;
	values = b->header.values->values;

	pos = git_strmap_lookup_index(values, key);
	git__free(key);

	if (!git_strmap_valid_index(values, pos)) {
		refcounted_strmap_free(map);
		giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
		return GIT_ENOTFOUND;
	}

	var = git_strmap_value_at(values, pos);
	refcounted_strmap_free(map);

	if (var->next != NULL) {
		giterr_set(GITERR_CONFIG, "cannot delete multivar with a single delete");
		return -1;
	}

	if ((result = config_write(b, var->entry->name, NULL, NULL)) < 0)
		return result;

	return config_refresh(cfg);
}

static int config_delete_multivar(git_config_backend *cfg, const char *name, const char *regexp)
{
	diskfile_backend *b = (diskfile_backend *)cfg;
	refcounted_strmap *map;
	git_strmap *values;
	char *key;
	regex_t preg;
	int result;
	khiter_t pos;

	if ((result = git_config__normalize_name(name, &key)) < 0)
		return result;

	if ((map = refcounted_strmap_take(&b->header)) == NULL)
		return -1;
	values = b->header.values->values;

	pos = git_strmap_lookup_index(values, key);

	if (!git_strmap_valid_index(values, pos)) {
		refcounted_strmap_free(map);
		git__free(key);
		giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
		return GIT_ENOTFOUND;
	}

	refcounted_strmap_free(map);

	result = p_regcomp(&preg, regexp, REG_EXTENDED);
	if (result != 0) {
		giterr_set_regex(&preg, result);
		result = -1;
		goto out;
	}

	if ((result = config_write(b, key, &preg, NULL)) < 0)
		goto out;

	result = config_refresh(cfg);

out:
	git__free(key);
	regfree(&preg);
	return result;
}

static int config_snapshot(git_config_backend **out, git_config_backend *in)
{
	diskfile_backend *b = (diskfile_backend *) in;

	return git_config_file__snapshot(out, b);
}

static int config_lock(git_config_backend *_cfg)
{
	diskfile_backend *cfg = (diskfile_backend *) _cfg;
	int error;

	if ((error = git_filebuf_open(&cfg->locked_buf, cfg->file_path, 0, GIT_CONFIG_FILE_MODE)) < 0)
		return error;

	error = git_futils_readbuffer(&cfg->locked_content, cfg->file_path);
	if (error < 0 && error != GIT_ENOTFOUND) {
		git_filebuf_cleanup(&cfg->locked_buf);
		return error;
	}

	cfg->locked = true;
	return 0;

}

static int config_unlock(git_config_backend *_cfg, int success)
{
	diskfile_backend *cfg = (diskfile_backend *) _cfg;
	int error = 0;

	if (success) {
		git_filebuf_write(&cfg->locked_buf, cfg->locked_content.ptr, cfg->locked_content.size);
		error = git_filebuf_commit(&cfg->locked_buf);
	}

	git_filebuf_cleanup(&cfg->locked_buf);
	git_buf_free(&cfg->locked_content);
	cfg->locked = false;

	return error;
}

int git_config_file__ondisk(git_config_backend **out, const char *path)
{
	diskfile_backend *backend;

	backend = git__calloc(1, sizeof(diskfile_backend));
	GITERR_CHECK_ALLOC(backend);

	backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
	git_mutex_init(&backend->header.values_mutex);

	backend->file_path = git__strdup(path);
	GITERR_CHECK_ALLOC(backend->file_path);

	backend->header.parent.open = config_open;
	backend->header.parent.get = config_get;
	backend->header.parent.set = config_set;
	backend->header.parent.set_multivar = config_set_multivar;
	backend->header.parent.del = config_delete;
	backend->header.parent.del_multivar = config_delete_multivar;
	backend->header.parent.iterator = config_iterator_new;
	backend->header.parent.snapshot = config_snapshot;
	backend->header.parent.lock = config_lock;
	backend->header.parent.unlock = config_unlock;
	backend->header.parent.free = backend_free;

	*out = (git_config_backend *)backend;

	return 0;
}

static int config_set_readonly(git_config_backend *cfg, const char *name, const char *value)
{
	GIT_UNUSED(cfg);
	GIT_UNUSED(name);
	GIT_UNUSED(value);

	return config_error_readonly();
}

static int config_set_multivar_readonly(
	git_config_backend *cfg, const char *name, const char *regexp, const char *value)
{
	GIT_UNUSED(cfg);
	GIT_UNUSED(name);
	GIT_UNUSED(regexp);
	GIT_UNUSED(value);

	return config_error_readonly();
}

static int config_delete_multivar_readonly(git_config_backend *cfg, const char *name, const char *regexp)
{
	GIT_UNUSED(cfg);
	GIT_UNUSED(name);
	GIT_UNUSED(regexp);

	return config_error_readonly();
}

static int config_delete_readonly(git_config_backend *cfg, const char *name)
{
	GIT_UNUSED(cfg);
	GIT_UNUSED(name);

	return config_error_readonly();
}

static int config_lock_readonly(git_config_backend *_cfg)
{
	GIT_UNUSED(_cfg);

	return config_error_readonly();
}

static int config_unlock_readonly(git_config_backend *_cfg, int success)
{
	GIT_UNUSED(_cfg);
	GIT_UNUSED(success);

	return config_error_readonly();
}

static void backend_readonly_free(git_config_backend *_backend)
{
	diskfile_backend *backend = (diskfile_backend *)_backend;

	if (backend == NULL)
		return;

	refcounted_strmap_free(backend->header.values);
	git_mutex_free(&backend->header.values_mutex);
	git__free(backend);
}

static int config_readonly_open(git_config_backend *cfg, git_config_level_t level)
{
	diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
	diskfile_backend *src = b->snapshot_from;
	diskfile_header *src_header = &src->header;
	refcounted_strmap *src_map;
	int error;

	if (!src_header->parent.readonly && (error = config_refresh(&src_header->parent)) < 0)
		return error;

	/* We're just copying data, don't care about the level */
	GIT_UNUSED(level);

	if ((src_map = refcounted_strmap_take(src_header)) == NULL)
		return -1;
	b->header.values = src_map;

	return 0;
}

int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in)
{
	diskfile_readonly_backend *backend;

	backend = git__calloc(1, sizeof(diskfile_readonly_backend));
	GITERR_CHECK_ALLOC(backend);

	backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
	git_mutex_init(&backend->header.values_mutex);

	backend->snapshot_from = in;

	backend->header.parent.readonly = 1;
	backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
	backend->header.parent.open = config_readonly_open;
	backend->header.parent.get = config_get;
	backend->header.parent.set = config_set_readonly;
	backend->header.parent.set_multivar = config_set_multivar_readonly;
	backend->header.parent.del = config_delete_readonly;
	backend->header.parent.del_multivar = config_delete_multivar_readonly;
	backend->header.parent.iterator = config_iterator_new;
	backend->header.parent.lock = config_lock_readonly;
	backend->header.parent.unlock = config_unlock_readonly;
	backend->header.parent.free = backend_readonly_free;

	*out = (git_config_backend *)backend;

	return 0;
}

static int reader_getchar_raw(struct reader *reader)
{
	int c;

	c = *reader->read_ptr++;

	/*
	Win 32 line breaks: if we find a \r\n sequence,
	return only the \n as a newline
	*/
	if (c == '\r' && *reader->read_ptr == '\n') {
		reader->read_ptr++;
		c = '\n';
	}

	if (c == '\n')
		reader->line_number++;

	if (c == 0) {
		reader->eof = 1;
		c = '\0';
	}

	return c;
}

#define SKIP_WHITESPACE (1 << 1)
#define SKIP_COMMENTS (1 << 2)

static int reader_getchar(struct reader *reader, int flags)
{
	const int skip_whitespace = (flags & SKIP_WHITESPACE);
	const int skip_comments = (flags & SKIP_COMMENTS);
	int c;

	assert(reader->read_ptr);

	do {
		c = reader_getchar_raw(reader);
	} while (c != '\n' && c != '\0' && skip_whitespace && git__isspace(c));

	if (skip_comments && (c == '#' || c == ';')) {
		do {
			c = reader_getchar_raw(reader);
		} while (c != '\n' && c != '\0');
	}

	return c;
}

/*
 * Read the next char, but don't move the reading pointer.
 */
static int reader_peek(struct reader *reader, int flags)
{
	void *old_read_ptr;
	int old_lineno, old_eof;
	int ret;

	assert(reader->read_ptr);

	old_read_ptr = reader->read_ptr;
	old_lineno = reader->line_number;
	old_eof = reader->eof;

	ret = reader_getchar(reader, flags);

	reader->read_ptr = old_read_ptr;
	reader->line_number = old_lineno;
	reader->eof = old_eof;

	return ret;
}

/*
 * Read and consume a line, returning it in newly-allocated memory.
 */
static char *reader_readline(struct reader *reader, bool skip_whitespace)
{
	char *line = NULL;
	char *line_src, *line_end;
	size_t line_len, alloc_len;

	line_src = reader->read_ptr;

	if (skip_whitespace) {
		/* Skip empty empty lines */
		while (git__isspace(*line_src))
			++line_src;
	}

	line_end = strchr(line_src, '\n');

	/* no newline at EOF */
	if (line_end == NULL)
		line_end = strchr(line_src, 0);

	line_len = line_end - line_src;

	if (GIT_ADD_SIZET_OVERFLOW(&alloc_len, line_len, 1) ||
		(line = git__malloc(alloc_len)) == NULL) {
		return NULL;
	}

	memcpy(line, line_src, line_len);

	do line[line_len] = '\0';
	while (line_len-- > 0 && git__isspace(line[line_len]));

	if (*line_end == '\n')
		line_end++;

	if (*line_end == '\0')
		reader->eof = 1;

	reader->line_number++;
	reader->read_ptr = line_end;

	return line;
}

/*
 * Consume a line, without storing it anywhere
 */
static void reader_consume_line(struct reader *reader)
{
	char *line_start, *line_end;

	line_start = reader->read_ptr;
	line_end = strchr(line_start, '\n');
	/* No newline at EOF */
	if(line_end == NULL){
		line_end = strchr(line_start, '\0');
	}

	if (*line_end == '\n')
		line_end++;

	if (*line_end == '\0')
		reader->eof = 1;

	reader->line_number++;
	reader->read_ptr = line_end;
}

GIT_INLINE(int) config_keychar(int c)
{
	return isalnum(c) || c == '-';
}

static int parse_section_header_ext(struct reader *reader, const char *line, const char *base_name, char **section_name)
{
	int c, rpos;
	char *first_quote, *last_quote;
	git_buf buf = GIT_BUF_INIT;
	size_t quoted_len, alloc_len, base_name_len = strlen(base_name);

	/*
	 * base_name is what came before the space. We should be at the
	 * first quotation mark, except for now, line isn't being kept in
	 * sync so we only really use it to calculate the length.
	 */

	first_quote = strchr(line, '"');
	if (first_quote == NULL) {
		set_parse_error(reader, 0, "Missing quotation marks in section header");
		goto end_error;
	}

	last_quote = strrchr(line, '"');
	quoted_len = last_quote - first_quote;

	if (quoted_len == 0) {
		set_parse_error(reader, 0, "Missing closing quotation mark in section header");
		goto end_error;
	}

	GITERR_CHECK_ALLOC_ADD(&alloc_len, base_name_len, quoted_len);
	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);

	if (git_buf_grow(&buf, alloc_len) < 0 ||
	    git_buf_printf(&buf, "%s.", base_name) < 0)
		goto end_error;

	rpos = 0;

	line = first_quote;
	c = line[++rpos];

	/*
	 * At the end of each iteration, whatever is stored in c will be
	 * added to the string. In case of error, jump to out
	 */
	do {

		switch (c) {
		case 0:
			set_parse_error(reader, 0, "Unexpected end-of-line in section header");
			goto end_error;

		case '"':
			goto end_parse;

		case '\\':
			c = line[++rpos];

			if (c == 0) {
				set_parse_error(reader, rpos, "Unexpected end-of-line in section header");
				goto end_error;
			}

		default:
			break;
		}

		git_buf_putc(&buf, (char)c);
		c = line[++rpos];
	} while (line + rpos < last_quote);

end_parse:
	if (git_buf_oom(&buf))
		goto end_error;

	if (line[rpos] != '"' || line[rpos + 1] != ']') {
		set_parse_error(reader, rpos, "Unexpected text after closing quotes");
		git_buf_free(&buf);
		return -1;
	}

	*section_name = git_buf_detach(&buf);
	return 0;

end_error:
	git_buf_free(&buf);

	return -1;
}

static int parse_section_header(struct reader *reader, char **section_out)
{
	char *name, *name_end;
	int name_length, c, pos;
	int result;
	char *line;
	size_t line_len;

	line = reader_readline(reader, true);
	if (line == NULL)
		return -1;

	/* find the end of the variable's name */
	name_end = strrchr(line, ']');
	if (name_end == NULL) {
		git__free(line);
		set_parse_error(reader, 0, "Missing ']' in section header");
		return -1;
	}

	GITERR_CHECK_ALLOC_ADD(&line_len, (size_t)(name_end - line), 1);
	name = git__malloc(line_len);
	GITERR_CHECK_ALLOC(name);

	name_length = 0;
	pos = 0;

	/* Make sure we were given a section header */
	c = line[pos++];
	assert(c == '[');

	c = line[pos++];

	do {
		if (git__isspace(c)){
			name[name_length] = '\0';
			result = parse_section_header_ext(reader, line, name, section_out);
			git__free(line);
			git__free(name);
			return result;
		}

		if (!config_keychar(c) && c != '.') {
			set_parse_error(reader, pos, "Unexpected character in header");
			goto fail_parse;
		}

		name[name_length++] = (char)git__tolower(c);

	} while ((c = line[pos++]) != ']');

	if (line[pos - 1] != ']') {
		set_parse_error(reader, pos, "Unexpected end of file");
		goto fail_parse;
	}

	git__free(line);

	name[name_length] = 0;
	*section_out = name;

	return 0;

fail_parse:
	git__free(line);
	git__free(name);
	return -1;
}

static int skip_bom(struct reader *reader)
{
	git_bom_t bom;
	int bom_offset = git_buf_text_detect_bom(&bom,
		&reader->buffer, reader->read_ptr - reader->buffer.ptr);

	if (bom == GIT_BOM_UTF8)
		reader->read_ptr += bom_offset;

	/* TODO: reference implementation is pretty stupid with BoM */

	return 0;
}

/*
	(* basic types *)
	digit = "0".."9"
	integer = digit { digit }
	alphabet = "a".."z" + "A" .. "Z"

	section_char = alphabet | "." | "-"
	extension_char = (* any character except newline *)
	any_char = (* any character *)
	variable_char = "alphabet" | "-"


	(* actual grammar *)
	config = { section }

	section = header { definition }

	header = "[" section [subsection | subsection_ext] "]"

	subsection = "." section
	subsection_ext = "\"" extension "\""

	section = section_char { section_char }
	extension = extension_char { extension_char }

	definition = variable_name ["=" variable_value] "\n"

	variable_name = variable_char { variable_char }
	variable_value = string | boolean | integer

	string = quoted_string | plain_string
	quoted_string = "\"" plain_string "\""
	plain_string = { any_char }

	boolean = boolean_true | boolean_false
	boolean_true = "yes" | "1" | "true" | "on"
	boolean_false = "no" | "0" | "false" | "off"
*/

static int strip_comments(char *line, int in_quotes)
{
	int quote_count = in_quotes, backslash_count = 0;
	char *ptr;

	for (ptr = line; *ptr; ++ptr) {
		if (ptr[0] == '"' && ptr > line && ptr[-1] != '\\')
			quote_count++;

		if ((ptr[0] == ';' || ptr[0] == '#') &&
			(quote_count % 2) == 0 &&
			(backslash_count % 2) == 0) {
			ptr[0] = '\0';
			break;
		}

		if (ptr[0] == '\\')
			backslash_count++;
		else
			backslash_count = 0;
	}

	/* skip any space at the end */
	while (ptr > line && git__isspace(ptr[-1])) {
		ptr--;
	}
	ptr[0] = '\0';

	return quote_count;
}

static int included_path(git_buf *out, const char *dir, const char *path)
{
	/* From the user's home */
	if (path[0] == '~' && path[1] == '/')
		return git_sysdir_find_global_file(out, &path[1]);

	return git_path_join_unrooted(out, path, dir, NULL);
}

static const char *escapes = "ntb\"\\";
static const char *escaped = "\n\t\b\"\\";

/* Escape the values to write them to the file */
static char *escape_value(const char *ptr)
{
	git_buf buf = GIT_BUF_INIT;
	size_t len;
	const char *esc;

	assert(ptr);

	len = strlen(ptr);
	if (!len)
		return git__calloc(1, sizeof(char));

	git_buf_grow(&buf, len);

	while (*ptr != '\0') {
		if ((esc = strchr(escaped, *ptr)) != NULL) {
			git_buf_putc(&buf, '\\');
			git_buf_putc(&buf, escapes[esc - escaped]);
		} else {
			git_buf_putc(&buf, *ptr);
		}
		ptr++;
	}

	if (git_buf_oom(&buf)) {
		git_buf_free(&buf);
		return NULL;
	}

	return git_buf_detach(&buf);
}

/* '\"' -> '"' etc */
static int unescape_line(
	char **out, bool *is_multi, const char *ptr, int quote_count)
{
	char *str, *fixed, *esc;
	size_t ptr_len = strlen(ptr), alloc_len;

	*is_multi = false;

	if (GIT_ADD_SIZET_OVERFLOW(&alloc_len, ptr_len, 1) ||
		(str = git__malloc(alloc_len)) == NULL) {
		return -1;
	}

	fixed = str;

	while (*ptr != '\0') {
		if (*ptr == '"') {
			quote_count++;
		} else if (*ptr != '\\') {
			*fixed++ = *ptr;
		} else {
			/* backslash, check the next char */
			ptr++;
			/* if we're at the end, it's a multiline, so keep the backslash */
			if (*ptr == '\0') {
				*is_multi = true;
				goto done;
			}
			if ((esc = strchr(escapes, *ptr)) != NULL) {
				*fixed++ = escaped[esc - escapes];
			} else {
				git__free(str);
				giterr_set(GITERR_CONFIG, "invalid escape at %s", ptr);
				return -1;
			}
		}
		ptr++;
	}

done:
	*fixed = '\0';
	*out = str;

	return 0;
}

static int parse_multiline_variable(struct reader *reader, git_buf *value, int in_quotes)
{
	char *line = NULL, *proc_line = NULL;
	int quote_count;
	bool multiline;

	/* Check that the next line exists */
	line = reader_readline(reader, false);
	if (line == NULL)
		return -1;

	/* We've reached the end of the file, there is no continuation.
	 * (this is not an error).
	 */
	if (line[0] == '\0') {
		git__free(line);
		return 0;
	}

	quote_count = strip_comments(line, !!in_quotes);

	/* If it was just a comment, pretend it didn't exist */
	if (line[0] == '\0') {
		git__free(line);
		return parse_multiline_variable(reader, value, quote_count);
		/* TODO: unbounded recursion. This **could** be exploitable */
	}

	if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) {
		git__free(line);
		return -1;
	}
	/* add this line to the multiline var */

	git_buf_puts(value, proc_line);
	git__free(line);
	git__free(proc_line);

	/*
	 * If we need to continue reading the next line, let's just
	 * keep putting stuff in the buffer
	 */
	if (multiline)
		return parse_multiline_variable(reader, value, quote_count);

	return 0;
}

GIT_INLINE(bool) is_namechar(char c)
{
	return isalnum(c) || c == '-';
}

static int parse_name(
	char **name, const char **value, struct reader *reader, const char *line)
{
	const char *name_end = line, *value_start;

	*name = NULL;
	*value = NULL;

	while (*name_end && is_namechar(*name_end))
		name_end++;

	if (line == name_end) {
		set_parse_error(reader, 0, "Invalid configuration key");
		return -1;
	}

	value_start = name_end;

	while (*value_start && git__isspace(*value_start))
		value_start++;

	if (*value_start == '=') {
		*value = value_start + 1;
	} else if (*value_start) {
		set_parse_error(reader, 0, "Invalid configuration key");
		return -1;
	}

	if ((*name = git__strndup(line, name_end - line)) == NULL)
		return -1;

	return 0;
}

static int parse_variable(struct reader *reader, char **var_name, char **var_value)
{
	const char *value_start = NULL;
	char *line;
	int quote_count;
	bool multiline;

	line = reader_readline(reader, true);
	if (line == NULL)
		return -1;

	quote_count = strip_comments(line, 0);

	/* If there is no value, boolean true is assumed */
	*var_value = NULL;

	if (parse_name(var_name, &value_start, reader, line) < 0)
		goto on_error;

	/*
	 * Now, let's try to parse the value
	 */
	if (value_start != NULL) {
		while (git__isspace(value_start[0]))
			value_start++;

		if (unescape_line(var_value, &multiline, value_start, 0) < 0)
			goto on_error;

		if (multiline) {
			git_buf multi_value = GIT_BUF_INIT;
			git_buf_attach(&multi_value, *var_value, 0);

			if (parse_multiline_variable(reader, &multi_value, quote_count) < 0 ||
				git_buf_oom(&multi_value)) {
				git_buf_free(&multi_value);
				goto on_error;
			}

			*var_value = git_buf_detach(&multi_value);
		}
	}

	git__free(line);
	return 0;

on_error:
	git__free(*var_name);
	git__free(line);
	return -1;
}

static int config_parse(
	struct reader *reader,
	int (*on_section)(struct reader **reader, const char *current_section, const char *line, size_t line_len, void *data),
	int (*on_variable)(struct reader **reader, const char *current_section, char *var_name, char *var_value, const char *line, size_t line_len, void *data),
	int (*on_comment)(struct reader **reader, const char *line, size_t line_len, void *data),
	int (*on_eof)(struct reader **reader, const char *current_section, void *data),
	void *data)
{
	char *current_section = NULL, *var_name, *var_value, *line_start;
	char c;
	size_t line_len;
	int result = 0;

	skip_bom(reader);

	while (result == 0 && !reader->eof) {
		line_start = reader->read_ptr;

		c = reader_peek(reader, SKIP_WHITESPACE);

		switch (c) {
		case '\0': /* EOF when peeking, set EOF in the reader to exit the loop */
			reader->eof = 1;
			break;

		case '[': /* section header, new section begins */
			git__free(current_section);
			current_section = NULL;

			if ((result = parse_section_header(reader, &current_section)) == 0 && on_section) {
				line_len = reader->read_ptr - line_start;
				result = on_section(&reader, current_section, line_start, line_len, data);
			}
			break;

		case '\n': /* comment or whitespace-only */
		case ';':
		case '#':
			reader_consume_line(reader);

			if (on_comment) {
				line_len = reader->read_ptr - line_start;
				result = on_comment(&reader, line_start, line_len, data);
			}
			break;

		default: /* assume variable declaration */
			if ((result = parse_variable(reader, &var_name, &var_value)) == 0 && on_variable) {
				line_len = reader->read_ptr - line_start;
				result = on_variable(&reader, current_section, var_name, var_value, line_start, line_len, data);
			}
			break;
		}
	}

	if (on_eof)
		result = on_eof(&reader, current_section, data);

	git__free(current_section);
	return result;
}

struct parse_data {
	git_strmap *values;
	diskfile_backend *cfg_file;
	uint32_t reader_idx;
	git_config_level_t level;
	int depth;
};

static int read_on_variable(
	struct reader **reader,
	const char *current_section,
	char *var_name,
	char *var_value,
	const char *line,
	size_t line_len,
	void *data)
{
	struct parse_data *parse_data = (struct parse_data *)data;
	git_buf buf = GIT_BUF_INIT;
	cvar_t *var;
	int result = 0;

	GIT_UNUSED(line);
	GIT_UNUSED(line_len);

	git__strtolower(var_name);
	git_buf_printf(&buf, "%s.%s", current_section, var_name);
	git__free(var_name);

	if (git_buf_oom(&buf)) {
		git__free(var_value);
		return -1;
	}

	var = git__calloc(1, sizeof(cvar_t));
	GITERR_CHECK_ALLOC(var);
	var->entry = git__calloc(1, sizeof(git_config_entry));
	GITERR_CHECK_ALLOC(var->entry);

	var->entry->name = git_buf_detach(&buf);
	var->entry->value = var_value;
	var->entry->level = parse_data->level;
	var->included = !!parse_data->depth;

	if ((result = append_entry(parse_data->values, var)) < 0)
		return result;

	result = 0;

	/* Add or append the new config option */
	if (!git__strcmp(var->entry->name, "include.path")) {
		struct reader *r;
		git_buf path = GIT_BUF_INIT;
		char *dir;
		uint32_t index;

		r = git_array_alloc(parse_data->cfg_file->readers);
		/* The reader may have been reallocated */
		*reader = git_array_get(parse_data->cfg_file->readers, parse_data->reader_idx);
		memset(r, 0, sizeof(struct reader));

		if ((result = git_path_dirname_r(&path, (*reader)->file_path)) < 0)
			return result;

		/* We need to know our index in the array, as the next config_parse call may realloc */
		index = git_array_size(parse_data->cfg_file->readers) - 1;
		dir = git_buf_detach(&path);
		result = included_path(&path, dir, var->entry->value);
		git__free(dir);

		if (result < 0)
			return result;

		r->file_path = git_buf_detach(&path);
		git_buf_init(&r->buffer, 0);

		result = git_futils_readbuffer_updated(
			&r->buffer, r->file_path, &r->checksum, NULL);

		if (result == 0) {
			result = config_read(parse_data->values, parse_data->cfg_file, r, parse_data->level, parse_data->depth+1);
			r = git_array_get(parse_data->cfg_file->readers, index);
			*reader = git_array_get(parse_data->cfg_file->readers, parse_data->reader_idx);
		} else if (result == GIT_ENOTFOUND) {
			giterr_clear();
			result = 0;
		}

		git_buf_free(&r->buffer);
	}

	return result;
}

static int config_read(git_strmap *values, diskfile_backend *cfg_file, struct reader *reader, git_config_level_t level, int depth)
{
	struct parse_data parse_data;

	if (depth >= MAX_INCLUDE_DEPTH) {
		giterr_set(GITERR_CONFIG, "maximum config include depth reached");
		return -1;
	}

	/* Initialize the reading position */
	reader->read_ptr = reader->buffer.ptr;
	reader->eof = 0;

	/* If the file is empty, there's nothing for us to do */
	if (*reader->read_ptr == '\0')
		return 0;

	parse_data.values = values;
	parse_data.cfg_file = cfg_file;
	parse_data.reader_idx = git_array_size(cfg_file->readers) - 1;
	parse_data.level = level;
	parse_data.depth = depth;

	return config_parse(reader, NULL, read_on_variable, NULL, NULL, &parse_data);
}

static int write_section(git_buf *fbuf, const char *key)
{
	int result;
	const char *dot;
	git_buf buf = GIT_BUF_INIT;

	/* All of this just for [section "subsection"] */
	dot = strchr(key, '.');
	git_buf_putc(&buf, '[');
	if (dot == NULL) {
		git_buf_puts(&buf, key);
	} else {
		char *escaped;
		git_buf_put(&buf, key, dot - key);
		escaped = escape_value(dot + 1);
		GITERR_CHECK_ALLOC(escaped);
		git_buf_printf(&buf, " \"%s\"", escaped);
		git__free(escaped);
	}
	git_buf_puts(&buf, "]\n");

	if (git_buf_oom(&buf))
		return -1;

	result = git_buf_put(fbuf, git_buf_cstr(&buf), buf.size);
	git_buf_free(&buf);

	return result;
}

static const char *quotes_for_value(const char *value)
{
	const char *ptr;

	if (value[0] == ' ' || value[0] == '\0')
		return "\"";

	for (ptr = value; *ptr; ++ptr) {
		if (*ptr == ';' || *ptr == '#')
			return "\"";
	}

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

	return "";
}

struct write_data {
	git_buf *buf;
	git_buf buffered_comment;
	unsigned int in_section : 1,
		preg_replaced : 1;
	const char *section;
	const char *name;
	const regex_t *preg;
	const char *value;
};

static int write_line_to(git_buf *buf, const char *line, size_t line_len)
{
	int result = git_buf_put(buf, line, line_len);

	if (!result && line_len && line[line_len-1] != '\n')
		result = git_buf_printf(buf, "\n");

	return result;
}

static int write_line(struct write_data *write_data, const char *line, size_t line_len)
{
	return write_line_to(write_data->buf, line, line_len);
}

static int write_value(struct write_data *write_data)
{
	const char *q;
	int result;

	q = quotes_for_value(write_data->value);
	result = git_buf_printf(write_data->buf,
		"\t%s = %s%s%s\n", write_data->name, q, write_data->value, q);

	/* If we are updating a single name/value, we're done.  Setting `value`
	 * to `NULL` will prevent us from trying to write it again later (in
	 * `write_on_section`) if we see the same section repeated.
	 */
	if (!write_data->preg)
		write_data->value = NULL;

	return result;
}

static int write_on_section(
	struct reader **reader,
	const char *current_section,
	const char *line,
	size_t line_len,
	void *data)
{
	struct write_data *write_data = (struct write_data *)data;
	int result = 0;

	GIT_UNUSED(reader);

	/* If we were previously in the correct section (but aren't anymore)
	 * and haven't written our value (for a simple name/value set, not
	 * a multivar), then append it to the end of the section before writing
	 * the new one.
	 */
	if (write_data->in_section && !write_data->preg && write_data->value)
		result = write_value(write_data);

	write_data->in_section = strcmp(current_section, write_data->section) == 0;

	/*
	 * If there were comments just before this section, dump them as well.
	 */
	if (!result) {
		result = git_buf_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size);
		git_buf_clear(&write_data->buffered_comment);
	}

	if (!result)
		result = write_line(write_data, line, line_len);

	return result;
}

static int write_on_variable(
	struct reader **reader,
	const char *current_section,
	char *var_name,
	char *var_value,
	const char *line,
	size_t line_len,
	void *data)
{
	struct write_data *write_data = (struct write_data *)data;
	bool has_matched = false;
	int error;

	GIT_UNUSED(reader);
	GIT_UNUSED(current_section);

	/*
	 * If there were comments just before this variable, let's dump them as well.
	 */
	if ((error = git_buf_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size)) < 0)
		return error;

	git_buf_clear(&write_data->buffered_comment);

	/* See if we are to update this name/value pair; first examine name */
	if (write_data->in_section &&
		strcasecmp(write_data->name, var_name) == 0)
		has_matched = true;

	/* If we have a regex to match the value, see if it matches */
	if (has_matched && write_data->preg != NULL)
		has_matched = (regexec(write_data->preg, var_value, 0, NULL, 0) == 0);

	git__free(var_name);
	git__free(var_value);

	/* If this isn't the name/value we're looking for, simply dump the
	 * existing data back out and continue on.
	 */
	if (!has_matched)
		return write_line(write_data, line, line_len);

	write_data->preg_replaced = 1;

	/* If value is NULL, we are deleting this value; write nothing. */
	if (!write_data->value)
		return 0;

	return write_value(write_data);
}

static int write_on_comment(struct reader **reader, const char *line, size_t line_len, void *data)
{
	struct write_data *write_data;

	GIT_UNUSED(reader);

	write_data = (struct write_data *)data;
	return write_line_to(&write_data->buffered_comment, line, line_len);
}

static int write_on_eof(
	struct reader **reader, const char *current_section, void *data)
{
	struct write_data *write_data = (struct write_data *)data;
	int result = 0;

	GIT_UNUSED(reader);

	/*
	 * If we've buffered comments when reaching EOF, make sure to dump them.
	 */
	if ((result = git_buf_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size)) < 0)
		return result;

	/* If we are at the EOF and have not written our value (again, for a
	 * simple name/value set, not a multivar) then we have never seen the
	 * section in question and should create a new section and write the
	 * value.
	 */
	if ((!write_data->preg || !write_data->preg_replaced) && write_data->value) {
		/* write the section header unless we're already in it */
		if (!current_section || strcmp(current_section, write_data->section))
			result = write_section(write_data->buf, write_data->section);

		if (!result)
			result = write_value(write_data);
	}

	return result;
}

/*
 * This is pretty much the parsing, except we write out anything we don't have
 */
static int config_write(diskfile_backend *cfg, const char *key, const regex_t *preg, const char* value)
{
	int result;
	char *section, *name, *ldot;
	git_filebuf file = GIT_FILEBUF_INIT;
	git_buf buf = GIT_BUF_INIT;
	struct reader *reader = git_array_get(cfg->readers, 0);
	struct write_data write_data;

	if (cfg->locked) {
		result = git_buf_puts(&reader->buffer, git_buf_cstr(&cfg->locked_content));
	} else {
		/* Lock the file */
		if ((result = git_filebuf_open(
			     &file, cfg->file_path, GIT_FILEBUF_HASH_CONTENTS, GIT_CONFIG_FILE_MODE)) < 0) {
			git_buf_free(&reader->buffer);
			return result;
		}

		/* We need to read in our own config file */
		result = git_futils_readbuffer(&reader->buffer, cfg->file_path);
	}

	/* Initialise the reading position */
	if (result == GIT_ENOTFOUND) {
		reader->read_ptr = NULL;
		reader->eof = 1;
		git_buf_clear(&reader->buffer);
	} else if (result == 0) {
		reader->read_ptr = reader->buffer.ptr;
		reader->eof = 0;
	} else {
		git_filebuf_cleanup(&file);
		return -1; /* OS error when reading the file */
	}

	ldot = strrchr(key, '.');
	name = ldot + 1;
	section = git__strndup(key, ldot - key);

	write_data.buf = &buf;
	git_buf_init(&write_data.buffered_comment, 0);
	write_data.section = section;
	write_data.in_section = 0;
	write_data.preg_replaced = 0;
	write_data.name = name;
	write_data.preg = preg;
	write_data.value = value;

	result = config_parse(reader, write_on_section, write_on_variable, write_on_comment, write_on_eof, &write_data);
	git__free(section);
	git_buf_free(&write_data.buffered_comment);

	if (result < 0) {
		git_filebuf_cleanup(&file);
		goto done;
	}

	if (cfg->locked) {
		size_t len = buf.asize;
		/* Update our copy with the modified contents */
		git_buf_free(&cfg->locked_content);
		git_buf_attach(&cfg->locked_content, git_buf_detach(&buf), len);
	} else {
		git_filebuf_write(&file, git_buf_cstr(&buf), git_buf_len(&buf));
		result = git_filebuf_commit(&file);
	}

done:
	git_buf_free(&buf);
	git_buf_free(&reader->buffer);
	return result;
}
