/*
 * libkmod - interface to kernel module operations
 *
 * Copyright (C) 2011  ProFUSION embedded systems
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>

#include "libkmod.h"
#include "libkmod-private.h"

/*
 * Read one logical line from a configuration file.
 *
 * Line endings may be escaped with backslashes, to form one logical line from
 * several physical lines.  No end of line character(s) are included in the
 * result.
 *
 * If linenum is not NULL, it is incremented by the number of physical lines
 * which have been read.
 */
char *getline_wrapped(FILE *fp, unsigned int *linenum)
{
	int size = 256;
	int i = 0;
	char *buf = malloc(size);

	for(;;) {
		int ch = getc_unlocked(fp);

		switch(ch) {
		case EOF:
			if (i == 0) {
				free(buf);
				return NULL;
			}
			/* else fall through */

		case '\n':
			if (linenum)
				(*linenum)++;
			if (i == size)
				buf = realloc(buf, size + 1);
			buf[i] = '\0';
			return buf;

		case '\\':
			ch = getc_unlocked(fp);

			if (ch == '\n') {
				if (linenum)
					(*linenum)++;
				continue;
			}
			/* else fall through */

		default:
			buf[i++] = ch;

			if (i == size) {
				size *= 2;
				buf = realloc(buf, size);
			}
		}
	}
}

/*
 * Replace dashes with underscores.
 * Dashes inside character range patterns (e.g. [0-9]) are left unchanged.
 */
char *underscores(struct kmod_ctx *ctx, char *s)
{
	unsigned int i;

	if (!s)
		return NULL;

	for (i = 0; s[i]; i++) {
		switch (s[i]) {
		case '-':
			s[i] = '_';
			break;

		case ']':
			INFO(ctx, "Unmatched bracket in %s\n", s);
			break;

		case '[':
			i += strcspn(&s[i], "]");
			if (!s[i])
				INFO(ctx, "Unmatched bracket in %s\n", s);
			break;
		}
	}
	return s;
}

inline int alias_normalize(const char *alias, char buf[NAME_MAX], size_t *len)
{
	size_t s;

	for (s = 0; s < NAME_MAX - 1; s++) {
		const char c = alias[s];
		switch (c) {
		case '-':
			buf[s] = '_';
			break;
		case ']':
			return -EINVAL;
		case '[':
			while (alias[s] != ']' &&
					alias[s] != '.' && alias[s] != '\0')
				s++;

			if (alias[s] != ']')
				return -EINVAL;

			s++;
			break;
		case '\0':
		case '.':
			goto finish;
		default:
			buf[s] = c;
		}
	}

finish:
	buf[s] = '\0';

	if (len)
		*len = s;

	return 0;
}

bool startswith(const char *s, const char *prefix) {
        size_t sl, pl;

        assert(s);
        assert(prefix);

        sl = strlen(s);
        pl = strlen(prefix);

        if (pl == 0)
                return true;

        if (sl < pl)
                return false;

        return memcmp(s, prefix, pl) == 0;
}

inline void *memdup(const void *p, size_t n)
{
	void *r = malloc(n);

	if (r == NULL)
		return NULL;

	return memcpy(r, p, n);
}

ssize_t read_str_safe(int fd, char *buf, size_t buflen) {
	size_t todo = buflen;
	size_t done;

	do {
		ssize_t r = read(fd, buf, todo);

		if (r == 0)
			break;
		else if (r > 0)
			todo -= r;
		else {
			if (errno == EAGAIN || errno == EWOULDBLOCK ||
				errno == EINTR)
				continue;
			else
				return -errno;
		}
	} while (todo > 0);

	done = buflen - todo;

	if (done == 0)
		buf[0] = '\0';
	else {
		if (done < buflen)
			buf[done] = '\0';
		else if (buf[done - 1] != '\0')
			return -ENOSPC;
	}

	return done;
}

int read_str_long(int fd, long *value, int base) {
	char buf[32], *end;
	long v;
	int err;

	*value = 0;
	err = read_str_safe(fd, buf, sizeof(buf));
	if (err < 0)
		return err;
	errno = 0;
	v = strtol(buf, &end, base);
	if (end == buf || !isspace(*end))
		return -EINVAL;

	*value = v;
	return 0;
}

int read_str_ulong(int fd, unsigned long *value, int base) {
	char buf[32], *end;
	long v;
	int err;

	*value = 0;
	err = read_str_safe(fd, buf, sizeof(buf));
	if (err < 0)
		return err;
	errno = 0;
	v = strtoul(buf, &end, base);
	if (end == buf || !isspace(*end))
		return -EINVAL;
	*value = v;
	return 0;
}

char *strchr_replace(char *s, int c, char r)
{
	char *p;

	for (p = s; *p != '\0'; p++)
		if (*p == c)
			*p = r;

	return s;
}

bool path_is_absolute(const char *p)
{
	assert(p != NULL);

	return p[0] == '/';
}

char *path_make_absolute_cwd(const char *p)
{
	char *cwd, *r;
	size_t plen;
	size_t cwdlen;

	if (path_is_absolute(p))
		return strdup(p);

	cwd = get_current_dir_name();
	if (cwd == NULL)
		return NULL;

	plen = strlen(p);
	cwdlen = strlen(cwd);

	/* cwd + '/' + p + '\0' */
	r = realloc(cwd, cwdlen + 1 + plen + 1);
	if (r == NULL) {
		free(cwd);
		return NULL;
	}

	r[cwdlen] = '/';
	memcpy(&r[cwdlen + 1], p, plen + 1);

	return r;
}
