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)
{
*/
/*@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.
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);
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)
{
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)
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;
}