/*
 * (C) Copyright 2003
 * Tait Electronics Limited, Christchurch, New Zealand
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * This file provides a shell like 'test' function to return
 * true/false from an integer or string compare of two memory
 * locations or a location and a scalar/literal.
 * A few parts were lifted from bash 'test' command
 */

#include <common.h>
#include <config.h>
#include <command.h>
#include <mapmem.h>

#include <asm/io.h>

#define EQ	0
#define NE	1
#define LT	2
#define GT	3
#define LE	4
#define GE	5

struct op_tbl_s {
	char	*op;		/* operator string */
	int	opcode;		/* internal representation of opcode */
};

typedef struct op_tbl_s op_tbl_t;

static const op_tbl_t op_table [] = {
	{ "-lt", LT },
	{ "<"  , LT },
	{ "-gt", GT },
	{ ">"  , GT },
	{ "-eq", EQ },
	{ "==" , EQ },
	{ "-ne", NE },
	{ "!=" , NE },
	{ "<>" , NE },
	{ "-ge", GE },
	{ ">=" , GE },
	{ "-le", LE },
	{ "<=" , LE },
};

static long evalexp(char *s, int w)
{
	long l = 0;
	unsigned long addr;
	void *buf;

	/* if the parameter starts with a * then assume is a pointer to the value we want */
	if (s[0] == '*') {
		addr = simple_strtoul(&s[1], NULL, 16);
		buf = map_physmem(addr, w, MAP_WRBACK);
		if (!buf && addr) {
			puts("Failed to map physical memory\n");
			return 0;
		}
		switch (w) {
		case 1:
			l = (long)(*(u8 *)buf);
			break;
		case 2:
			l = (long)(*(u16 *)buf);
			break;
		case 4:
			l = (long)(*(u32 *)buf);
			break;
		}
		unmap_physmem(buf, w);
		return l;
	} else {
		l = simple_strtoul(s, NULL, 16);
	}

	return l & ((1UL << (w * 8)) - 1);
}

static char * evalstr(char *s)
{
	/* if the parameter starts with a * then assume a string pointer else its a literal */
	if (s[0] == '*') {
		return (char *)simple_strtoul(&s[1], NULL, 16);
	} else if (s[0] == '$') {
		int i = 2;

		if (s[1] != '{')
			return NULL;

		while (s[i] != '}') {
			if (s[i] == 0)
				return NULL;
			i++;
		}
		s[i] = 0;
		return  getenv((const char *)&s[2]);
	} else {
		return s;
	}
}

static int stringcomp(char *s, char *t, int op)
{
	int p;
	char *l, *r;

	l = evalstr(s);
	r = evalstr(t);

	p = strcmp(l, r);
	switch (op) {
	case EQ: return (p == 0);
	case NE: return (p != 0);
	case LT: return (p < 0);
	case GT: return (p > 0);
	case LE: return (p <= 0);
	case GE: return (p >= 0);
	}
	return (0);
}

static int arithcomp (char *s, char *t, int op, int w)
{
	long l, r;

	l = evalexp (s, w);
	r = evalexp (t, w);

	switch (op) {
	case EQ: return (l == r);
	case NE: return (l != r);
	case LT: return (l < r);
	case GT: return (l > r);
	case LE: return (l <= r);
	case GE: return (l >= r);
	}
	return (0);
}

static int binary_test(char *op, char *arg1, char *arg2, int w)
{
	int len, i;
	const op_tbl_t *optp;

	len = strlen(op);

	for (optp = (op_tbl_t *)&op_table, i = 0;
	     i < ARRAY_SIZE(op_table);
	     optp++, i++) {

		if ((strncmp (op, optp->op, len) == 0) && (len == strlen (optp->op))) {
			if (w == 0) {
				return (stringcomp(arg1, arg2, optp->opcode));
			} else {
				return (arithcomp (arg1, arg2, optp->opcode, w));
			}
		}
	}

	printf("Unknown operator '%s'\n", op);
	return 0;	/* op code not found */
}

/* command line interface to the shell test */
static int do_itest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int	value, w;

	/* Validate arguments */
	if ((argc != 4))
		return CMD_RET_USAGE;

	/* Check for a data width specification.
	 * Defaults to long (4) if no specification.
	 * Uses -2 as 'width' for .s (string) so as not to upset existing code
	 */
	switch (w = cmd_get_data_size(argv[0], 4)) {
	case 1:
	case 2:
	case 4:
		value = binary_test (argv[2], argv[1], argv[3], w);
		break;
	case -2:
		value = binary_test (argv[2], argv[1], argv[3], 0);
		break;
	case -1:
	default:
		puts("Invalid data width specifier\n");
		value = 0;
		break;
	}

	return !value;
}

U_BOOT_CMD(
	itest, 4, 0, do_itest,
	"return true/false on integer compare",
	"[.b, .w, .l, .s] [*]value1 <op> [*]value2"
);
