/*
 * (C) Copyright 2003
 * Tait Electronics Limited, Christchurch, New Zealand
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * 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>

#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;

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

#define op_tbl_size (sizeof(op_table)/sizeof(op_table[0]))

static long evalexp(char *s, int w)
{
	long l, *p;

	/* if the parameter starts with a * then assume is a pointer to the value we want */
	if (s[0] == '*') {
		p = (long *)simple_strtoul(&s[1], NULL, 16);
		l = *p;
	} else {
		l = simple_strtoul(s, NULL, 16);
	}

	return (l & ((1 << (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 {
		return s;
	}
}

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

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

	/* we'll do a compare based on the length of the shortest string */
	n = min(strlen(l), strlen(r));

	p = strncmp(l, r, n);
	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);
}

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

	len = strlen(op);

	for (optp = (op_tbl_t *)&op_table, i = 0;
	     i < op_tbl_size;
	     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 */
int do_itest ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] )
{
	int	value, w;

	/* Validate arguments */
	if ((argc != 4)){
		cmd_usage(cmdtp);
		return 1;
	}

	/* 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"
);
