/*
 * Helpers for formatting and printing strings
 *
 * Copyright 31 August 2008 James Bottomley
 * Copyright (C) 2013, Intel Corporation
 */
#include <linux/kernel.h>
#include <linux/math64.h>
#include <linux/export.h>
#include <linux/ctype.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/string_helpers.h>

/**
 * string_get_size - get the size in the specified units
 * @size:	The size to be converted
 * @units:	units to use (powers of 1000 or 1024)
 * @buf:	buffer to format to
 * @len:	length of buffer
 *
 * This function returns a string formatted to 3 significant figures
 * giving the size in the required units.  Returns 0 on success or
 * error on failure.  @buf is always zero terminated.
 *
 */
int string_get_size(u64 size, const enum string_size_units units,
		    char *buf, int len)
{
	static const char *const units_10[] = {
		"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL
	};
	static const char *const units_2[] = {
		"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB",
		NULL
	};
	static const char *const *const units_str[] = {
		[STRING_UNITS_10] = units_10,
		[STRING_UNITS_2] = units_2,
	};
	static const unsigned int divisor[] = {
		[STRING_UNITS_10] = 1000,
		[STRING_UNITS_2] = 1024,
	};
	int i, j;
	u64 remainder = 0, sf_cap;
	char tmp[8];

	tmp[0] = '\0';
	i = 0;
	if (size >= divisor[units]) {
		while (size >= divisor[units] && units_str[units][i]) {
			remainder = do_div(size, divisor[units]);
			i++;
		}

		sf_cap = size;
		for (j = 0; sf_cap*10 < 1000; j++)
			sf_cap *= 10;

		if (j) {
			remainder *= 1000;
			do_div(remainder, divisor[units]);
			snprintf(tmp, sizeof(tmp), ".%03lld",
				 (unsigned long long)remainder);
			tmp[j+1] = '\0';
		}
	}

	snprintf(buf, len, "%lld%s %s", (unsigned long long)size,
		 tmp, units_str[units][i]);

	return 0;
}
EXPORT_SYMBOL(string_get_size);

static bool unescape_space(char **src, char **dst)
{
	char *p = *dst, *q = *src;

	switch (*q) {
	case 'n':
		*p = '\n';
		break;
	case 'r':
		*p = '\r';
		break;
	case 't':
		*p = '\t';
		break;
	case 'v':
		*p = '\v';
		break;
	case 'f':
		*p = '\f';
		break;
	default:
		return false;
	}
	*dst += 1;
	*src += 1;
	return true;
}

static bool unescape_octal(char **src, char **dst)
{
	char *p = *dst, *q = *src;
	u8 num;

	if (isodigit(*q) == 0)
		return false;

	num = (*q++) & 7;
	while (num < 32 && isodigit(*q) && (q - *src < 3)) {
		num <<= 3;
		num += (*q++) & 7;
	}
	*p = num;
	*dst += 1;
	*src = q;
	return true;
}

static bool unescape_hex(char **src, char **dst)
{
	char *p = *dst, *q = *src;
	int digit;
	u8 num;

	if (*q++ != 'x')
		return false;

	num = digit = hex_to_bin(*q++);
	if (digit < 0)
		return false;

	digit = hex_to_bin(*q);
	if (digit >= 0) {
		q++;
		num = (num << 4) | digit;
	}
	*p = num;
	*dst += 1;
	*src = q;
	return true;
}

static bool unescape_special(char **src, char **dst)
{
	char *p = *dst, *q = *src;

	switch (*q) {
	case '\"':
		*p = '\"';
		break;
	case '\\':
		*p = '\\';
		break;
	case 'a':
		*p = '\a';
		break;
	case 'e':
		*p = '\e';
		break;
	default:
		return false;
	}
	*dst += 1;
	*src += 1;
	return true;
}

/**
 * string_unescape - unquote characters in the given string
 * @src:	source buffer (escaped)
 * @dst:	destination buffer (unescaped)
 * @size:	size of the destination buffer (0 to unlimit)
 * @flags:	combination of the flags (bitwise OR):
 *	%UNESCAPE_SPACE:
 *		'\f' - form feed
 *		'\n' - new line
 *		'\r' - carriage return
 *		'\t' - horizontal tab
 *		'\v' - vertical tab
 *	%UNESCAPE_OCTAL:
 *		'\NNN' - byte with octal value NNN (1 to 3 digits)
 *	%UNESCAPE_HEX:
 *		'\xHH' - byte with hexadecimal value HH (1 to 2 digits)
 *	%UNESCAPE_SPECIAL:
 *		'\"' - double quote
 *		'\\' - backslash
 *		'\a' - alert (BEL)
 *		'\e' - escape
 *	%UNESCAPE_ANY:
 *		all previous together
 *
 * Description:
 * The function unquotes characters in the given string.
 *
 * Because the size of the output will be the same as or less than the size of
 * the input, the transformation may be performed in place.
 *
 * Caller must provide valid source and destination pointers. Be aware that
 * destination buffer will always be NULL-terminated. Source string must be
 * NULL-terminated as well.
 *
 * Return:
 * The amount of the characters processed to the destination buffer excluding
 * trailing '\0' is returned.
 */
int string_unescape(char *src, char *dst, size_t size, unsigned int flags)
{
	char *out = dst;

	while (*src && --size) {
		if (src[0] == '\\' && src[1] != '\0' && size > 1) {
			src++;
			size--;

			if (flags & UNESCAPE_SPACE &&
					unescape_space(&src, &out))
				continue;

			if (flags & UNESCAPE_OCTAL &&
					unescape_octal(&src, &out))
				continue;

			if (flags & UNESCAPE_HEX &&
					unescape_hex(&src, &out))
				continue;

			if (flags & UNESCAPE_SPECIAL &&
					unescape_special(&src, &out))
				continue;

			*out++ = '\\';
		}
		*out++ = *src++;
	}
	*out = '\0';

	return out - dst;
}
EXPORT_SYMBOL(string_unescape);

static int escape_passthrough(unsigned char c, char **dst, size_t *osz)
{
	char *out = *dst;

	if (*osz < 1)
		return -ENOMEM;

	*out++ = c;

	*dst = out;
	*osz -= 1;

	return 1;
}

static int escape_space(unsigned char c, char **dst, size_t *osz)
{
	char *out = *dst;
	unsigned char to;

	if (*osz < 2)
		return -ENOMEM;

	switch (c) {
	case '\n':
		to = 'n';
		break;
	case '\r':
		to = 'r';
		break;
	case '\t':
		to = 't';
		break;
	case '\v':
		to = 'v';
		break;
	case '\f':
		to = 'f';
		break;
	default:
		return 0;
	}

	*out++ = '\\';
	*out++ = to;

	*dst = out;
	*osz -= 2;

	return 1;
}

static int escape_special(unsigned char c, char **dst, size_t *osz)
{
	char *out = *dst;
	unsigned char to;

	if (*osz < 2)
		return -ENOMEM;

	switch (c) {
	case '\\':
		to = '\\';
		break;
	case '\a':
		to = 'a';
		break;
	case '\e':
		to = 'e';
		break;
	default:
		return 0;
	}

	*out++ = '\\';
	*out++ = to;

	*dst = out;
	*osz -= 2;

	return 1;
}

static int escape_null(unsigned char c, char **dst, size_t *osz)
{
	char *out = *dst;

	if (*osz < 2)
		return -ENOMEM;

	if (c)
		return 0;

	*out++ = '\\';
	*out++ = '0';

	*dst = out;
	*osz -= 2;

	return 1;
}

static int escape_octal(unsigned char c, char **dst, size_t *osz)
{
	char *out = *dst;

	if (*osz < 4)
		return -ENOMEM;

	*out++ = '\\';
	*out++ = ((c >> 6) & 0x07) + '0';
	*out++ = ((c >> 3) & 0x07) + '0';
	*out++ = ((c >> 0) & 0x07) + '0';

	*dst = out;
	*osz -= 4;

	return 1;
}

static int escape_hex(unsigned char c, char **dst, size_t *osz)
{
	char *out = *dst;

	if (*osz < 4)
		return -ENOMEM;

	*out++ = '\\';
	*out++ = 'x';
	*out++ = hex_asc_hi(c);
	*out++ = hex_asc_lo(c);

	*dst = out;
	*osz -= 4;

	return 1;
}

/**
 * string_escape_mem - quote characters in the given memory buffer
 * @src:	source buffer (unescaped)
 * @isz:	source buffer size
 * @dst:	destination buffer (escaped)
 * @osz:	destination buffer size
 * @flags:	combination of the flags (bitwise OR):
 *	%ESCAPE_SPACE:
 *		'\f' - form feed
 *		'\n' - new line
 *		'\r' - carriage return
 *		'\t' - horizontal tab
 *		'\v' - vertical tab
 *	%ESCAPE_SPECIAL:
 *		'\\' - backslash
 *		'\a' - alert (BEL)
 *		'\e' - escape
 *	%ESCAPE_NULL:
 *		'\0' - null
 *	%ESCAPE_OCTAL:
 *		'\NNN' - byte with octal value NNN (3 digits)
 *	%ESCAPE_ANY:
 *		all previous together
 *	%ESCAPE_NP:
 *		escape only non-printable characters (checked by isprint)
 *	%ESCAPE_ANY_NP:
 *		all previous together
 *	%ESCAPE_HEX:
 *		'\xHH' - byte with hexadecimal value HH (2 digits)
 * @esc:	NULL-terminated string of characters any of which, if found in
 *		the source, has to be escaped
 *
 * Description:
 * The process of escaping byte buffer includes several parts. They are applied
 * in the following sequence.
 *	1. The character is matched to the printable class, if asked, and in
 *	   case of match it passes through to the output.
 *	2. The character is not matched to the one from @esc string and thus
 *	   must go as is to the output.
 *	3. The character is checked if it falls into the class given by @flags.
 *	   %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any
 *	   character. Note that they actually can't go together, otherwise
 *	   %ESCAPE_HEX will be ignored.
 *
 * Caller must provide valid source and destination pointers. Be aware that
 * destination buffer will not be NULL-terminated, thus caller have to append
 * it if needs.
 *
 * Return:
 * The amount of the characters processed to the destination buffer, or
 * %-ENOMEM if the size of buffer is not enough to put an escaped character is
 * returned.
 *
 * Even in the case of error @dst pointer will be updated to point to the byte
 * after the last processed character.
 */
int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz,
		      unsigned int flags, const char *esc)
{
	char *out = *dst, *p = out;
	bool is_dict = esc && *esc;
	int ret = 0;

	while (isz--) {
		unsigned char c = *src++;

		/*
		 * Apply rules in the following sequence:
		 *	- the character is printable, when @flags has
		 *	  %ESCAPE_NP bit set
		 *	- the @esc string is supplied and does not contain a
		 *	  character under question
		 *	- the character doesn't fall into a class of symbols
		 *	  defined by given @flags
		 * In these cases we just pass through a character to the
		 * output buffer.
		 */
		if ((flags & ESCAPE_NP && isprint(c)) ||
		    (is_dict && !strchr(esc, c))) {
			/* do nothing */
		} else {
			if (flags & ESCAPE_SPACE) {
				ret = escape_space(c, &p, &osz);
				if (ret < 0)
					break;
				if (ret > 0)
					continue;
			}

			if (flags & ESCAPE_SPECIAL) {
				ret = escape_special(c, &p, &osz);
				if (ret < 0)
					break;
				if (ret > 0)
					continue;
			}

			if (flags & ESCAPE_NULL) {
				ret = escape_null(c, &p, &osz);
				if (ret < 0)
					break;
				if (ret > 0)
					continue;
			}

			/* ESCAPE_OCTAL and ESCAPE_HEX always go last */
			if (flags & ESCAPE_OCTAL) {
				ret = escape_octal(c, &p, &osz);
				if (ret < 0)
					break;
				continue;
			}
			if (flags & ESCAPE_HEX) {
				ret = escape_hex(c, &p, &osz);
				if (ret < 0)
					break;
				continue;
			}
		}

		ret = escape_passthrough(c, &p, &osz);
		if (ret < 0)
			break;
	}

	*dst = p;

	if (ret < 0)
		return ret;

	return p - out;
}
EXPORT_SYMBOL(string_escape_mem);
