* intnum.c (yasm_intnum_create_leb128): Create an intnum from a LEB128

encoded value.
* intnum.h (yasm_intnum_create_leb128): Prototype.
* leb128_test.c: Test above.

svn path=/trunk/yasm/; revision=1386
0.5.0rc2
Peter Johnson 19 years ago
parent 5e4df9b9e4
commit 2e18bad174
  1. 38
      libyasm/intnum.c
  2. 12
      libyasm/intnum.h
  3. 54
      libyasm/tests/leb128_test.c

@ -258,6 +258,44 @@ yasm_intnum_create_int(long i)
return intn;
}
yasm_intnum *
yasm_intnum_create_leb128(const unsigned char *ptr, int sign,
unsigned long *size, unsigned long line)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
const unsigned char *ptr_orig = ptr;
unsigned long i = 0;
intn->origsize = 0;
BitVector_Empty(conv_bv);
for (;;) {
BitVector_Chunk_Store(conv_bv, 7, i, *ptr);
i += 7;
if ((*ptr & 0x80) != 0x80)
break;
ptr++;
}
*size = (ptr-ptr_orig)+1;
if(i > BITVECT_NATIVE_SIZE)
yasm__warning(YASM_WARN_GENERAL, line,
N_("Numeric constant too large for internal format"));
else if (sign && (*ptr & 0x40) == 0x40)
BitVector_Interval_Fill(conv_bv, i, BITVECT_NATIVE_SIZE-1);
if (Set_Max(conv_bv) < 32) {
intn->type = INTNUM_UL;
intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
} else {
intn->type = INTNUM_BV;
intn->val.bv = BitVector_Clone(conv_bv);
}
return intn;
}
yasm_intnum *
yasm_intnum_copy(const yasm_intnum *intn)
{

@ -90,6 +90,18 @@ void yasm_intnum_cleanup(void);
*/
/*@only@*/ yasm_intnum *yasm_intnum_create_int(long i);
/** Create a new intnum from LEB128-encoded form.
* \param ptr pointer to start of LEB128 encoded form
* \param sign signed (1) or unsiged (0) LEB128 format
* \param size number of bytes read from ptr (output)
* \param line virtual line (where the number came from)
* \return Newly allocated intnum. Number of bytes read returned into
* bytes_read parameter.
*/
/*@only@*/ yasm_intnum *yasm_intnum_create_leb128
(const unsigned char *ptr, int sign, /*@out@*/ unsigned long *size,
unsigned long line);
/** Duplicate an intnum.
* \param intn intnum
* \return Newly allocated intnum with the same value as intn.

@ -80,7 +80,7 @@ static char failed[1000];
static char failmsg[100];
static int
run_test(Test_Entry *test)
run_output_test(Test_Entry *test)
{
char *valstr = yasm__xstrdup(test->input);
yasm_intnum *intn = yasm_intnum_create_hex(valstr, 0);
@ -129,6 +129,44 @@ run_test(Test_Entry *test)
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, i;
unsigned char out[100];
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)
{
@ -143,7 +181,16 @@ main(void)
failed[0] = '\0';
printf("Test leb128_test: ");
for (i=0; i<numtests; i++) {
int fail = run_test(&tests[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)
@ -154,6 +201,7 @@ main(void)
yasm_intnum_cleanup();
printf(" +%d-%d/%d %d%%\n%s",
numtests-nf, nf, numtests, 100*(numtests-nf)/numtests, failed);
numtests*2-nf, nf, numtests*2, 100*(numtests*2-nf)/(numtests*2),
failed);
return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

Loading…
Cancel
Save