5af28808 Update Auto-Sync to Python 3.13 and tree-sitter-py 24.0 (#2705) 99f018ac Python binding: (#2742) a07baf83 Auto-Sync update Sparc LLVM-18 (#2704) 81c5c93d Enable to generate legacy MC tests for the fuzzer. (#2733) a25d4980 Add warning about naive search and replace to patch reg names. (#2728) 7ac87d17 Print immediate only memory operands for AArch64. (#2732) c34034c8 Add x30 implicit read to the RET alias. (#2739) 95a4ca3e Update source list before installing valgrind. (#2730) 6909724e Make assertion hit warnings optional in release builds. (#2729) fe6bdc6e Make SStream respect the CS_OPT_UNSIGNED flag. (#2723) 21ce3624 Use cs_ac_type for operand access mode in all arches and use cs_xtensa_op_type for Xtensa operand type (#2721) df26583f clang-format: change license to BSD-3-Clause (#2724) 280b749e Remove unused files. (#2709) 87908ece Add flag for the SoftFail case of the LLVM disassembler. (#2707) efc0ba44 Fix missing operand for smstart, due to space replaced by tab (#2720) 2ae64133 Fix missing sp register read in ret instruction (#2719) 8df252a6 Fix arm pop reg access (#2718) 14612272 ARM: fix typo, cspr -> cpsr (#2716) f2f0a3c3 Fix LoongArch ld/st instructions register info (#2701) 829be2bf LoongArch: Compute absolute address for address operand (#2699) 42fbce6c Add jump group for generic jirl (#2698) fc525c73 Apple AArch64 proprietary (#2692) 895f2f2e Build PDB for debugging on Windows (#2685) 5c3aef03 Version: Update to v6.0.0-alpha4 (#2682) 106f7d3b Update read/written registers for x87 comparison instructions (#2680) ebe3ef2a Add workflow for building on Windows (#2675) 72f7d305 Revert "Add a script to compare the inc file content with the latest generate…" (#2678) 5b5c5ed8 Fix nanomips decoding of jalrc (#2672) ae03cca4 Mips32r6_64r632 is for both mips32r6 and mips64r6 (#2673) 21178aea Add a script to compare the inc file content with the latest generated ones. (#2667) 81a6ba03 MIPS: Fix MIPS16 decoding, wrong flags and ghost registers (#2665) 98a393e3 Stringify BH fields when printing ppc details (#2663) 2607d0f3 Remove undefined constants in riscv_const.py (#2660) (#2661) 5058c634 Decode BH field in print_insn_detail_ppc (#2662) 6461ed08 Add Call group to svc, smc and hvc. (#2651) e2f1dc8d Tms32c64x Little Endian (#2648) 5464c91d Fix build for compilers requiring explicit static for inline functions.. (#2645) bb2f6579 Enhance shift value and types of shift instructions. (#2638) cd282ef5 Update operand type enums of all arch modules to the one in `capstone.h` (#2633) dc0c0909 cmake: Fix building capstone as sub-project (#2629) cd8dd20c - Added missing files for sdist archive (#2624) 9affd99b Give the user some guidance where to add missing enumeration values. (#2639) 1bea3fab Add checks for MIPS details on cstest_py (#2640) ace8056c Add aliases mapping for MIPS & test for id, alias_id (#2635) 1abe1868 Build Tarball before DEB/RPM package. (#2627) 0a012190 Switch to ubuntu-24.04-arm runner image (#2625) 4e0b8c48 Fix wrong version requirement of tricore instructions: (#2620) 8ac2843b chore(version): Update Version to 6.0.0-Alpha3 (#2616) d7ef910b Rebased #2570 (#2614) c831cd5e Fix SystemZ macro in Makefile (#2603) 30601176 Apply new EVM opcode updates (#2602) 3c4d7fc8 Add tricore tc1.8 instructions (#2595) 5f290cad Create debian and rpm package on releases (#2590) 0f09210a delete travis (#2600) 5c5f756f Downgrade labeler to v4 due to https://github.com/actions/labeler/issues/710. (#2598) git-subtree-dir: external/capstone git-subtree-split: 5af288083e9f03e32723f9708c305692f866b666
618 lines
15 KiB
C
618 lines
15 KiB
C
// Copyright © 2024 Rot127 <unisono@quyllur.org>
|
|
// SPDX-License-Identifier: BSD-3
|
|
|
|
#include "unit_test.h"
|
|
#include "../SStream.h"
|
|
#include "../utils.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
static void overflow_SStream_concat0(SStream *OS, bool *returned_in_time)
|
|
{
|
|
char buf[SSTREAM_BUF_LEN + 1] = { 0 };
|
|
memset(&buf, 'A', SSTREAM_BUF_LEN);
|
|
SStream_concat0(OS, buf);
|
|
*returned_in_time = OS->buffer[SSTREAM_BUF_LEN - 1] == '\0';
|
|
}
|
|
|
|
static void overflow_SStream_concat(SStream *OS, bool *returned_in_time)
|
|
{
|
|
char buf[SSTREAM_BUF_LEN + 1] = { 0 };
|
|
memset(&buf, 'A', SSTREAM_BUF_LEN);
|
|
SStream_concat(OS, "%s", buf);
|
|
*returned_in_time = OS->buffer[SSTREAM_BUF_LEN - 1] == '\0';
|
|
}
|
|
|
|
static void overflow_SStream_concat1(SStream *OS, bool *returned_in_time)
|
|
{
|
|
char buf[SSTREAM_BUF_LEN] = { 0 };
|
|
memset(&buf, 'A', SSTREAM_BUF_LEN - 1);
|
|
SStream_concat0(OS, buf);
|
|
// Should return here because null byte is overflown.
|
|
SStream_concat1(OS, 'A');
|
|
*returned_in_time = OS->buffer[SSTREAM_BUF_LEN - 1] == '\0';
|
|
}
|
|
|
|
static bool test_overflow_check()
|
|
{
|
|
printf("Test test_overflow_check\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
bool returned_in_time = true;
|
|
overflow_SStream_concat0(&OS, &returned_in_time);
|
|
if (!returned_in_time) {
|
|
printf("Failed overflow_SStream_concat0\n");
|
|
return false;
|
|
}
|
|
overflow_SStream_concat(&OS, &returned_in_time);
|
|
if (!returned_in_time) {
|
|
printf("Failed overflow_SStream_concat\n");
|
|
return false;
|
|
}
|
|
overflow_SStream_concat1(&OS, &returned_in_time);
|
|
if (!returned_in_time) {
|
|
printf("Failed overflow_SStream_concat1\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool test_markup_os()
|
|
{
|
|
printf("Test test_markup_os\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
SStream_concat0(&OS, "0");
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0");
|
|
OS.markup_stream = true;
|
|
printUInt64(&OS, 0);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "00");
|
|
markup_OS(&OS, Markup_Immediate);
|
|
printUInt64(&OS, 0);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "00<imm:0>");
|
|
markup_OS(&OS, Markup_Memory);
|
|
printUInt32(&OS, 0);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "00<imm:0><mem:0>");
|
|
markup_OS(&OS, Markup_Target);
|
|
printUInt32(&OS, 0);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "00<imm:0><mem:0><tar:0>");
|
|
markup_OS(&OS, Markup_Register);
|
|
SStream_concat0(&OS, "r19");
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "00<imm:0><mem:0><tar:0><reg:r19>");
|
|
return true;
|
|
}
|
|
|
|
bool test_printint8()
|
|
{
|
|
printf("Test test_printint8\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
printInt8(&OS, HEX_THRESHOLD + 1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt8(&OS, HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt8(&OS, -(HEX_THRESHOLD + 1));
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt8(&OS, -HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt8(&OS, INT8_MAX);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0x7f");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt8(&OS, INT8_MIN);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-0x80");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_printint16()
|
|
{
|
|
printf("Test test_printint16\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
printInt16(&OS, HEX_THRESHOLD + 1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt16(&OS, HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt16(&OS, -(HEX_THRESHOLD + 1));
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt16(&OS, -HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt16(&OS, INT16_MAX);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0x7fff");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt16(&OS, INT16_MIN);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-0x8000");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_printint32()
|
|
{
|
|
printf("Test test_printint32\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
printInt32(&OS, HEX_THRESHOLD + 1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt32(&OS, HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt32(&OS, -(HEX_THRESHOLD + 1));
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt32(&OS, -HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt32(&OS, INT32_MAX);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0x7fffffff");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt32(&OS, INT32_MIN);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-0x80000000");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_printint64()
|
|
{
|
|
printf("Test test_printint64\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
printInt64(&OS, HEX_THRESHOLD + 1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt64(&OS, HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt64(&OS, -(HEX_THRESHOLD + 1));
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt64(&OS, -HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt64(&OS, INT64_MAX);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0x7fffffffffffffff");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt64(&OS, INT64_MIN);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "-0x8000000000000000");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_printint32_bang()
|
|
{
|
|
printf("Test test_printint32Bang\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
printInt32Bang(&OS, HEX_THRESHOLD + 1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt32Bang(&OS, HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt32Bang(&OS, -(HEX_THRESHOLD + 1));
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#-0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt32Bang(&OS, -HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#-9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt32Bang(&OS, INT32_MAX);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#0x7fffffff");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt32Bang(&OS, INT32_MIN);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#-0x80000000");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_printint64_bang()
|
|
{
|
|
printf("Test test_printint64Bang\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
printInt64Bang(&OS, HEX_THRESHOLD + 1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt64Bang(&OS, HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt64Bang(&OS, -(HEX_THRESHOLD + 1));
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#-0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt64Bang(&OS, -HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#-9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt64Bang(&OS, INT64_MAX);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#0x7fffffffffffffff");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printInt64Bang(&OS, INT64_MIN);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#-0x8000000000000000");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_printuint16()
|
|
{
|
|
printf("Test test_printuint16\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
printUInt16(&OS, HEX_THRESHOLD + 1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printUInt16(&OS, HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printUInt16(&OS, UINT16_MAX);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xffff");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_printuint8()
|
|
{
|
|
printf("Test test_printuint8\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
printUInt8(&OS, HEX_THRESHOLD + 1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printUInt8(&OS, HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printUInt8(&OS, UINT8_MAX);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xff");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_printuint32_bang()
|
|
{
|
|
printf("Test test_printuint32Bang\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
printUInt32Bang(&OS, HEX_THRESHOLD + 1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printUInt32Bang(&OS, HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printUInt32Bang(&OS, UINT32_MAX);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#0xffffffff");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_printuint64_bang()
|
|
{
|
|
printf("Test test_printuint64Bang\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
printUInt64Bang(&OS, HEX_THRESHOLD + 1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#0xa");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printUInt64Bang(&OS, HEX_THRESHOLD);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#9");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
printUInt64Bang(&OS, UINT64_MAX);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#0xffffffffffffffff");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_trimls() {
|
|
printf("Test test_replc\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
SStream_concat0(&OS, "AAA");
|
|
SStream_trimls(&OS);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "AAA");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
SStream_concat0(&OS, "\t AAA");
|
|
SStream_trimls(&OS);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "AAA");
|
|
|
|
// Don't remove middle tabs and spaces
|
|
SStream_concat0(&OS, "\t AAA");
|
|
SStream_trimls(&OS);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "AAA\t AAA");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
// Test do nothing
|
|
SStream_trimls(&OS);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "");
|
|
|
|
// Everywhere tabs
|
|
char cmp_buf[SSTREAM_BUF_LEN] = { 0 };
|
|
memset(cmp_buf, '\t', sizeof(cmp_buf) - 1);
|
|
SStream_trimls(&OS);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "");
|
|
CHECK_INT_EQUAL_RET_FALSE(OS.index, 0);
|
|
return true;
|
|
}
|
|
|
|
bool test_stream_unsigned_imm()
|
|
{
|
|
printf("Test test_stream_unsigned_imm\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
|
|
OS.unsigned_num = true;
|
|
printInt8(&OS, -1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xff");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
OS.unsigned_num = true;
|
|
printInt16(&OS, -1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xffff");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
OS.unsigned_num = true;
|
|
printInt32(&OS, -1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xffffffff");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
OS.unsigned_num = true;
|
|
printInt32Bang(&OS, -1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#0xffffffff");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
|
|
OS.unsigned_num = true;
|
|
printInt64(&OS, -1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "0xffffffffffffffff");
|
|
SStream_Flush(&OS, NULL);
|
|
|
|
OS.unsigned_num = true;
|
|
printInt64Bang(&OS, -1);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "#0xffffffffffffffff");
|
|
SStream_Flush(&OS, NULL);
|
|
return true;
|
|
}
|
|
|
|
bool test_copy_mnem_opstr() {
|
|
printf("Test test_copy_mnem_opstr\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
SStream_concat0(&OS, "AAA\tBBBB");
|
|
|
|
char mnem_1[1] = { 0 };
|
|
char opstr_1[1] = { 0 };
|
|
SStream_extract_mnem_opstr(&OS, mnem_1, sizeof(mnem_1), opstr_1, sizeof(opstr_1));
|
|
CHECK_STR_EQUAL_RET_FALSE(mnem_1, "");
|
|
CHECK_STR_EQUAL_RET_FALSE(opstr_1, "");
|
|
|
|
char mnem_3[3] = { 0 };
|
|
char opstr_3[3] = { 0 };
|
|
SStream_extract_mnem_opstr(&OS, mnem_3, sizeof(mnem_3), opstr_3, sizeof(opstr_3));
|
|
CHECK_STR_EQUAL_RET_FALSE(mnem_3, "AA");
|
|
CHECK_STR_EQUAL_RET_FALSE(opstr_3, "BB");
|
|
|
|
char mnem_4[4] = { 0 };
|
|
char opstr_4[4] = { 0 };
|
|
SStream_extract_mnem_opstr(&OS, mnem_4, sizeof(mnem_4), opstr_4, sizeof(opstr_4));
|
|
CHECK_STR_EQUAL_RET_FALSE(mnem_4, "AAA");
|
|
CHECK_STR_EQUAL_RET_FALSE(opstr_4, "BBB");
|
|
|
|
char mnem_5[5] = { 0 };
|
|
char opstr_5[5] = { 0 };
|
|
SStream_extract_mnem_opstr(&OS, mnem_5, sizeof(mnem_5), opstr_5, sizeof(opstr_5));
|
|
CHECK_STR_EQUAL_RET_FALSE(mnem_5, "AAA");
|
|
CHECK_STR_EQUAL_RET_FALSE(opstr_5, "BBBB");
|
|
|
|
// No mnemonic
|
|
char mnem_9[9] = { 0 };
|
|
char opstr_9[9] = { 0 };
|
|
SStream_Flush(&OS, NULL);
|
|
SStream_concat0(&OS, " AAA\tBBBB");
|
|
SStream_extract_mnem_opstr(&OS, mnem_9, sizeof(mnem_9), opstr_9, sizeof(opstr_9));
|
|
CHECK_STR_EQUAL_RET_FALSE(mnem_9, "");
|
|
CHECK_STR_EQUAL_RET_FALSE(opstr_9, "AAA\tBBBB");
|
|
|
|
// No opstr
|
|
char mnem_6[6] = { 0 };
|
|
char opstr_6[6] = { 0 };
|
|
SStream_Flush(&OS, NULL);
|
|
SStream_concat0(&OS, "AAA \t");
|
|
SStream_extract_mnem_opstr(&OS, mnem_6, sizeof(mnem_6), opstr_6, sizeof(opstr_6));
|
|
CHECK_STR_EQUAL_RET_FALSE(mnem_6, "AAA");
|
|
CHECK_STR_EQUAL_RET_FALSE(opstr_6, "");
|
|
|
|
return true;
|
|
}
|
|
|
|
bool test_replc()
|
|
{
|
|
printf("Test test_replc\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
char cmp_buf[SSTREAM_BUF_LEN] = { 0 };
|
|
memset(cmp_buf, 'A', sizeof(cmp_buf) - 1);
|
|
cmp_buf[100] = 'C';
|
|
SStream_concat0(&OS, cmp_buf);
|
|
|
|
cmp_buf[0] = 'B';
|
|
const char *next = SStream_replc(&OS, 'A', 'B');
|
|
CHECK_PTR_EQUAL_RET_FALSE(SStream_rbuf(&OS) + 1, next);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, cmp_buf);
|
|
|
|
cmp_buf[1] = 'B';
|
|
next = SStream_replc(&OS, 'A', 'B');
|
|
CHECK_PTR_EQUAL_RET_FALSE(SStream_rbuf(&OS) + 2, next);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, cmp_buf);
|
|
|
|
cmp_buf[100] = 'A'; // Replace the C from before
|
|
next = SStream_replc(&OS, 'C', 'A');
|
|
CHECK_PTR_EQUAL_RET_FALSE(SStream_rbuf(&OS) + 101, next);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, cmp_buf);
|
|
|
|
// X doesn't exist
|
|
next = SStream_replc(&OS, 'X', 'A');
|
|
CHECK_NULL_RET_FALSE(next);
|
|
|
|
// Replacing \0 byte is forbidden.
|
|
next = SStream_replc(&OS, '\0', 'A');
|
|
CHECK_NULL_RET_FALSE(next);
|
|
|
|
// But replacing any \0 byte is allowed.
|
|
SStream_Flush(&OS, NULL);
|
|
next = SStream_replc(&OS, '\0', 'A');
|
|
CHECK_PTR_EQUAL_RET_FALSE(SStream_rbuf(&OS) + 1, next);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "A");
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool test_replc_str()
|
|
{
|
|
printf("Test test_replc_str\n");
|
|
|
|
SStream OS = { 0 };
|
|
SStream_Init(&OS);
|
|
|
|
SStream_replc_str(&OS, 'A', "REPLACED");
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "");
|
|
CHECK_INT_EQUAL_RET_FALSE(OS.index, 0);
|
|
|
|
SStream_replc_str(&OS, '\0', "REPLACED");
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "REPLACED");
|
|
CHECK_INT_EQUAL_RET_FALSE(OS.index, 8);
|
|
|
|
SStream_Flush(&OS, NULL);
|
|
SStream_concat0(&OS, "\tA--X");
|
|
SStream_replc_str(&OS, 'A', "REPLACED");
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "\tREPLACED--X");
|
|
CHECK_INT_EQUAL_RET_FALSE(OS.index, 12);
|
|
SStream_replc_str(&OS, 'X', "REPLACED");
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "\tREPLACED--REPLACED");
|
|
CHECK_INT_EQUAL_RET_FALSE(OS.index, 19);
|
|
|
|
/// Too big strings are ignored.
|
|
char repl[SSTREAM_BUF_LEN] = { 0 };
|
|
memset(repl, 'A', sizeof(repl) - 1);
|
|
SStream_Flush(&OS, NULL);
|
|
SStream_concat0(&OS, "\tA--");
|
|
SStream_replc_str(&OS, 'A', repl);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "\tA--");
|
|
CHECK_INT_EQUAL_RET_FALSE(OS.index, 4);
|
|
|
|
/// Last null byte is not replaced.
|
|
memset(repl, 'A', sizeof(repl) - 1);
|
|
SStream_Flush(&OS, NULL);
|
|
SStream_concat0(&OS, repl);
|
|
SStream_replc_str(&OS, '\0', repl);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, repl);
|
|
CHECK_INT_EQUAL_RET_FALSE(OS.index, 511);
|
|
|
|
/// Last char is replaced.
|
|
memset(repl, 'A', sizeof(repl) - 1);
|
|
repl[sizeof(repl) - 2] = 'X';
|
|
SStream_Flush(&OS, NULL);
|
|
SStream_concat0(&OS, repl);
|
|
SStream_replc_str(&OS, 'X', "Y");
|
|
repl[sizeof(repl) - 2] = 'Y';
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, repl);
|
|
CHECK_INT_EQUAL_RET_FALSE(OS.index, 511);
|
|
|
|
// Possible overflow
|
|
char too_long[SSTREAM_BUF_LEN + 10] = { 0 };
|
|
memset(too_long, 'A', sizeof(too_long) - 1);
|
|
SStream_Flush(&OS, NULL);
|
|
SStream_concat0(&OS, "\tA--");
|
|
SStream_replc_str(&OS, 'A', too_long);
|
|
CHECK_OS_EQUAL_RET_FALSE(OS, "\tA--");
|
|
CHECK_INT_EQUAL_RET_FALSE(OS.index, 4);
|
|
|
|
return true;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
bool result = true;
|
|
result &= test_markup_os();
|
|
result &= test_overflow_check();
|
|
result &= test_printint8();
|
|
result &= test_printint16();
|
|
result &= test_printint32();
|
|
result &= test_printint64();
|
|
result &= test_printint32_bang();
|
|
result &= test_printint64_bang();
|
|
result &= test_printuint8();
|
|
result &= test_printuint16();
|
|
result &= test_printuint32_bang();
|
|
result &= test_printuint64_bang();
|
|
result &= test_stream_unsigned_imm();
|
|
result &= test_replc();
|
|
result &= test_replc_str();
|
|
result &= test_copy_mnem_opstr();
|
|
result &= test_trimls();
|
|
if (result) {
|
|
printf("All tests passed.\n");
|
|
} else {
|
|
printf("Some tests failed.\n");
|
|
}
|
|
return result ? 0 : -1;
|
|
}
|