18c35491afd495d828e8f43e3293ef9d9e145c751hbono@chromium.org/*
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *  Copyright (C) 2005-2007  Peter Johnson
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met:
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1. Redistributions of source code must retain the above copyright
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer.
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer in the
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    documentation and/or other materials provided with the distribution.
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE.
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <stdio.h>
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <stdlib.h>
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <string.h>
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "libyasm/intnum.c"
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct Test_Entry {
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* signedness (0=unsigned, 1=signed) */
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int sign;
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* whether input value should be negated */
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int negate;
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* input value (as hex string) */
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *input;
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* correct size returned from both size_leb128 and get_leb128 */
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long outsize;
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* correct return data from get_leb128 */
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const unsigned char *result;
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} Test_Entry;
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Test_Entry tests[] = {
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Unsigned values */
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {0, 0, "0", 1, (const unsigned char *)"\x00"},
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {0, 0, "2", 1, (const unsigned char *)"\x02"},
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {0, 0, "7F", 1, (const unsigned char *)"\x7F"},
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {0, 0, "80", 2, (const unsigned char *)"\x80\x01"},
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {0, 0, "81", 2, (const unsigned char *)"\x81\x01"},
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {0, 0, "82", 2, (const unsigned char *)"\x82\x01"},
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {0, 0, "3239", 2, (const unsigned char *)"\xB9\x64"},
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Signed zero value */
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {1, 0, "0", 1, (const unsigned char *)"\x00"},
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Signed positive values */
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {1, 0, "2", 1, (const unsigned char *)"\x02"},
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {1, 0, "7F", 2, (const unsigned char *)"\xFF\x00"},
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {1, 0, "80", 2, (const unsigned char *)"\x80\x01"},
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {1, 0, "81", 2, (const unsigned char *)"\x81\x01"},
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Signed negative values */
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {1, 1, "2", 1, (const unsigned char *)"\x7E"},
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {1, 1, "7F", 2, (const unsigned char *)"\x81\x7F"},
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {1, 1, "80", 2, (const unsigned char *)"\x80\x7F"},
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {1, 1, "81", 2, (const unsigned char *)"\xFF\x7E"},
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic char failed[1000];
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic char failmsg[100];
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgrun_output_test(Test_Entry *test)
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *valstr = yasm__xstrdup(test->input);
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum *intn = yasm_intnum_create_hex(valstr);
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long size, i;
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned char out[100];
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int bad;
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(valstr);
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (test->negate)
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    size = yasm_intnum_size_leb128(intn, test->sign);
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (size != test->outsize) {
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_intnum_destroy(intn);
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        sprintf(failmsg, "%ssigned %s%s size() bad size: expected %lu, got %lu!",
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                test->sign?"":"un", test->negate?"-":"", test->input,
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                test->outsize, size);
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 1;
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for (i=0; i<sizeof(out); i++)
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        out[i] = 0xFF;
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    size = yasm_intnum_get_leb128(intn, out, test->sign);
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (size != test->outsize) {
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_intnum_destroy(intn);
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        sprintf(failmsg, "%ssigned %s%s get() bad size: expected %lu, got %lu!",
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                test->sign?"":"un", test->negate?"-":"", test->input,
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                test->outsize, size);
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 1;
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bad = 0;
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for (i=0; i<test->outsize && !bad; i++) {
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (out[i] != test->result[i])
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            bad = 1;
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (bad) {
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_intnum_destroy(intn);
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        sprintf(failmsg, "%ssigned %s%s get() bad output!",
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                test->sign?"":"un", test->negate?"-":"", test->input);
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 1;
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_destroy(intn);
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgrun_input_test(Test_Entry *test)
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *valstr = yasm__xstrdup(test->input);
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum *intn = yasm_intnum_create_hex(valstr);
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum *testn;
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long size;
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(valstr);
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (test->negate)
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    testn = yasm_intnum_create_leb128(test->result, test->sign, &size);
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (size != test->outsize) {
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_intnum_destroy(testn);
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_intnum_destroy(intn);
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        sprintf(failmsg, "%ssigned %s%s create() bad size: expected %lu, got %lu!",
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                test->sign?"":"un", test->negate?"-":"", test->input,
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                test->outsize, size);
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 1;
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_calc(intn, YASM_EXPR_EQ, testn);
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!yasm_intnum_is_pos1(intn)) {
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_intnum_destroy(testn);
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_intnum_destroy(intn);
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        sprintf(failmsg, "%ssigned %s%s create() bad output!",
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                test->sign?"":"un", test->negate?"-":"", test->input);
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 1;
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_destroy(testn);
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_destroy(intn);
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgmain(void)
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int nf = 0;
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int numtests = sizeof(tests)/sizeof(Test_Entry);
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int i;
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (BitVector_Boot() != ErrCode_Ok)
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return EXIT_FAILURE;
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_initialize();
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    failed[0] = '\0';
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    printf("Test leb128_test: ");
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for (i=0; i<numtests; i++) {
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        int fail;
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fail = run_output_test(&tests[i]);
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        printf("%c", fail>0 ? 'F':'.');
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fflush(stdout);
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (fail)
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            sprintf(failed, "%s ** F: %s\n", failed, failmsg);
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        nf += fail;
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fail = run_input_test(&tests[i]);
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        printf("%c", fail>0 ? 'F':'.');
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fflush(stdout);
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (fail)
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            sprintf(failed, "%s ** F: %s\n", failed, failmsg);
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        nf += fail;
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_cleanup();
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    printf(" +%d-%d/%d %d%%\n%s",
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org           numtests*2-nf, nf, numtests*2, 100*(numtests*2-nf)/(numtests*2),
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org           failed);
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
200