/* $Id$
 *
 *  Copyright (C) 2005  Peter Johnson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#endif

#include <stdio.h>

#include "libyasm/intnum.c"

typedef struct Test_Entry {
    /* signedness (0=unsigned, 1=signed) */
    int sign;

    /* whether input value should be negated */
    int negate;

    /* input value (as hex string) */
    const char *input;

    /* correct size returned from both size_leb128 and get_leb128 */
    unsigned long outsize;

    /* correct return data from get_leb128 */
    const unsigned char *result;
} Test_Entry;

static Test_Entry tests[] = {
    /* Unsigned values */
    {0, 0, "0", 1, (const unsigned char *)"\x00"},
    {0, 0, "2", 1, (const unsigned char *)"\x02"},
    {0, 0, "7F", 1, (const unsigned char *)"\x7F"},
    {0, 0, "80", 2, (const unsigned char *)"\x80\x01"},
    {0, 0, "81", 2, (const unsigned char *)"\x81\x01"},
    {0, 0, "82", 2, (const unsigned char *)"\x82\x01"},
    {0, 0, "3239", 2, (const unsigned char *)"\xB9\x64"},
    /* Signed zero value */
    {1, 0, "0", 1, (const unsigned char *)"\x00"},
    /* Signed positive values */
    {1, 0, "2", 1, (const unsigned char *)"\x02"},
    {1, 0, "7F", 2, (const unsigned char *)"\xFF\x00"},
    {1, 0, "80", 2, (const unsigned char *)"\x80\x01"},
    {1, 0, "81", 2, (const unsigned char *)"\x81\x01"},
    /* Signed negative values */
    {1, 1, "2", 1, (const unsigned char *)"\x7E"},
    {1, 1, "7F", 2, (const unsigned char *)"\x81\x7F"},
    {1, 1, "80", 2, (const unsigned char *)"\x80\x7F"},
    {1, 1, "81", 2, (const unsigned char *)"\xFF\x7E"},
};

static char failed[1000];
static char failmsg[100];

static int
run_output_test(Test_Entry *test)
{
    char *valstr = yasm__xstrdup(test->input);
    yasm_intnum *intn = yasm_intnum_create_hex(valstr, 0);
    unsigned long size, i;
    unsigned char out[100];
    int bad;

    yasm_xfree(valstr);

    if (test->negate)
	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, 0);

    size = yasm_intnum_size_leb128(intn, test->sign);
    if (size != test->outsize) {
	yasm_intnum_destroy(intn);
	sprintf(failmsg, "%ssigned %s%s size() bad size: expected %lu, got %lu!",
		test->sign?"":"un", test->negate?"-":"", test->input,
		test->outsize, size);
	return 1;
    }

    for (i=0; i<sizeof(out); i++)
	out[i] = 0xFF;
    size = yasm_intnum_get_leb128(intn, out, test->sign);
    if (size != test->outsize) {
	yasm_intnum_destroy(intn);
	sprintf(failmsg, "%ssigned %s%s get() bad size: expected %lu, got %lu!",
		test->sign?"":"un", test->negate?"-":"", test->input,
		test->outsize, size);
	return 1;
    }

    bad = 0;
    for (i=0; i<test->outsize && !bad; i++) {
	if (out[i] != test->result[i])
	    bad = 1;
    }
    if (bad) {
	yasm_intnum_destroy(intn);
	sprintf(failmsg, "%ssigned %s%s get() bad output!",
		test->sign?"":"un", test->negate?"-":"", test->input);
	return 1;
    }

    yasm_intnum_destroy(intn);
    return 0;
}

static int
run_input_test(Test_Entry *test)
{
    char *valstr = yasm__xstrdup(test->input);
    yasm_intnum *intn = yasm_intnum_create_hex(valstr, 0);
    yasm_intnum *testn;
    unsigned long size;

    yasm_xfree(valstr);

    if (test->negate)
	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, 0);

    testn = yasm_intnum_create_leb128(test->result, test->sign, &size, 0);
    if (size != test->outsize) {
	yasm_intnum_destroy(testn);
	yasm_intnum_destroy(intn);
	sprintf(failmsg, "%ssigned %s%s create() bad size: expected %lu, got %lu!",
		test->sign?"":"un", test->negate?"-":"", test->input,
		test->outsize, size);
	return 1;
    }

    yasm_intnum_calc(intn, YASM_EXPR_EQ, testn, 0);
    if (!yasm_intnum_is_pos1(intn)) {
	yasm_intnum_destroy(testn);
	yasm_intnum_destroy(intn);
	sprintf(failmsg, "%ssigned %s%s create() bad output!",
		test->sign?"":"un", test->negate?"-":"", test->input);
	return 1;
    }

    yasm_intnum_destroy(testn);
    yasm_intnum_destroy(intn);
    return 0;
}

int
main(void)
{
    int nf = 0;
    int numtests = sizeof(tests)/sizeof(Test_Entry);
    int i;

    if (BitVector_Boot() != ErrCode_Ok)
	return EXIT_FAILURE;
    yasm_intnum_initialize();

    failed[0] = '\0';
    printf("Test leb128_test: ");
    for (i=0; i<numtests; i++) {
	int fail;

	fail = run_output_test(&tests[i]);
	printf("%c", fail>0 ? 'F':'.');
	fflush(stdout);
	if (fail)
	    sprintf(failed, "%s ** F: %s\n", failed, failmsg);
	nf += fail;

	fail = run_input_test(&tests[i]);
	printf("%c", fail>0 ? 'F':'.');
	fflush(stdout);
	if (fail)
	    sprintf(failed, "%s ** F: %s\n", failed, failmsg);
	nf += fail;
    }

    yasm_intnum_cleanup();

    printf(" +%d-%d/%d %d%%\n%s",
	   numtests*2-nf, nf, numtests*2, 100*(numtests*2-nf)/(numtests*2),
	   failed);
    return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
