mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-12 23:48:10 -07:00
Merge remote-tracking branch 'origin/dev' into nestednonces
This commit is contained in:
@@ -105,7 +105,7 @@ void ccid_test_app_free(CcidTestApp* app) {
|
||||
furi_record_close(RECORD_GUI);
|
||||
app->gui = NULL;
|
||||
|
||||
free(app->iso7816_handler);
|
||||
iso7816_handler_free(app->iso7816_handler);
|
||||
|
||||
// Free rest
|
||||
free(app);
|
||||
@@ -121,8 +121,7 @@ int32_t ccid_test_app(void* p) {
|
||||
furi_hal_usb_unlock();
|
||||
|
||||
furi_check(furi_hal_usb_set_config(&usb_ccid, &app->ccid_cfg) == true);
|
||||
furi_hal_usb_ccid_set_callbacks(
|
||||
(CcidCallbacks*)&app->iso7816_handler->ccid_callbacks, app->iso7816_handler);
|
||||
iso7816_handler_set_usb_ccid_callbacks();
|
||||
furi_hal_usb_ccid_insert_smartcard();
|
||||
|
||||
//handle button events
|
||||
@@ -142,7 +141,7 @@ int32_t ccid_test_app(void* p) {
|
||||
}
|
||||
|
||||
//tear down USB
|
||||
furi_hal_usb_ccid_set_callbacks(NULL, NULL);
|
||||
iso7816_handler_reset_usb_ccid_callbacks();
|
||||
furi_hal_usb_set_config(usb_mode_prev, NULL);
|
||||
|
||||
//teardown view
|
||||
|
||||
@@ -6,11 +6,17 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include "iso7816_handler.h"
|
||||
|
||||
#include "iso7816_t0_apdu.h"
|
||||
#include "iso7816_atr.h"
|
||||
#include "iso7816_handler.h"
|
||||
#include "iso7816_response.h"
|
||||
|
||||
static Iso7816Handler* iso7816_handler;
|
||||
static CcidCallbacks* ccid_callbacks;
|
||||
static uint8_t* command_apdu_buffer;
|
||||
static uint8_t* response_apdu_buffer;
|
||||
|
||||
void iso7816_icc_power_on_callback(uint8_t* atr_data, uint32_t* atr_data_len, void* context) {
|
||||
furi_check(context);
|
||||
|
||||
@@ -40,12 +46,11 @@ void iso7816_xfr_datablock_callback(
|
||||
|
||||
Iso7816Handler* handler = (Iso7816Handler*)context;
|
||||
|
||||
ISO7816_Response_APDU* response_apdu = (ISO7816_Response_APDU*)&handler->response_apdu_buffer;
|
||||
|
||||
ISO7816_Command_APDU* command_apdu = (ISO7816_Command_APDU*)&handler->command_apdu_buffer;
|
||||
ISO7816_Response_APDU* response_apdu = (ISO7816_Response_APDU*)response_apdu_buffer;
|
||||
ISO7816_Command_APDU* command_apdu = (ISO7816_Command_APDU*)command_apdu_buffer;
|
||||
|
||||
uint8_t result = iso7816_read_command_apdu(
|
||||
command_apdu, pc_to_reader_datablock, pc_to_reader_datablock_len);
|
||||
command_apdu, pc_to_reader_datablock, pc_to_reader_datablock_len, CCID_SHORT_APDU_SIZE);
|
||||
|
||||
if(result == ISO7816_READ_COMMAND_APDU_OK) {
|
||||
handler->iso7816_process_command(command_apdu, response_apdu);
|
||||
@@ -61,8 +66,31 @@ void iso7816_xfr_datablock_callback(
|
||||
}
|
||||
|
||||
Iso7816Handler* iso7816_handler_alloc() {
|
||||
Iso7816Handler* handler = malloc(sizeof(Iso7816Handler));
|
||||
handler->ccid_callbacks.icc_power_on_callback = iso7816_icc_power_on_callback;
|
||||
handler->ccid_callbacks.xfr_datablock_callback = iso7816_xfr_datablock_callback;
|
||||
return handler;
|
||||
iso7816_handler = malloc(sizeof(Iso7816Handler));
|
||||
|
||||
command_apdu_buffer = malloc(sizeof(ISO7816_Command_APDU) + CCID_SHORT_APDU_SIZE);
|
||||
response_apdu_buffer = malloc(sizeof(ISO7816_Response_APDU) + CCID_SHORT_APDU_SIZE);
|
||||
|
||||
ccid_callbacks = malloc(sizeof(CcidCallbacks));
|
||||
ccid_callbacks->icc_power_on_callback = iso7816_icc_power_on_callback;
|
||||
ccid_callbacks->xfr_datablock_callback = iso7816_xfr_datablock_callback;
|
||||
|
||||
return iso7816_handler;
|
||||
}
|
||||
|
||||
void iso7816_handler_set_usb_ccid_callbacks() {
|
||||
furi_hal_usb_ccid_set_callbacks(ccid_callbacks, iso7816_handler);
|
||||
}
|
||||
|
||||
void iso7816_handler_reset_usb_ccid_callbacks() {
|
||||
furi_hal_usb_ccid_set_callbacks(NULL, NULL);
|
||||
}
|
||||
|
||||
void iso7816_handler_free(Iso7816Handler* handler) {
|
||||
free(ccid_callbacks);
|
||||
|
||||
free(command_apdu_buffer);
|
||||
free(response_apdu_buffer);
|
||||
|
||||
free(handler);
|
||||
}
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
#include "iso7816_t0_apdu.h"
|
||||
|
||||
typedef struct {
|
||||
CcidCallbacks ccid_callbacks;
|
||||
void (*iso7816_answer_to_reset)(Iso7816Atr* atr);
|
||||
void (*iso7816_process_command)(
|
||||
const ISO7816_Command_APDU* command,
|
||||
ISO7816_Response_APDU* response);
|
||||
|
||||
uint8_t command_apdu_buffer[sizeof(ISO7816_Command_APDU) + CCID_SHORT_APDU_SIZE];
|
||||
uint8_t response_apdu_buffer[sizeof(ISO7816_Response_APDU) + CCID_SHORT_APDU_SIZE];
|
||||
} Iso7816Handler;
|
||||
|
||||
Iso7816Handler* iso7816_handler_alloc();
|
||||
|
||||
void iso7816_handler_free(Iso7816Handler* handler);
|
||||
void iso7816_handler_set_usb_ccid_callbacks();
|
||||
void iso7816_handler_reset_usb_ccid_callbacks();
|
||||
|
||||
@@ -1,49 +1,48 @@
|
||||
/* Implements rudimentary iso7816-3 support for APDU (T=0) */
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "iso7816_t0_apdu.h"
|
||||
|
||||
//reads dataBuffer with dataLen size, translate it into a ISO7816_Command_APDU type
|
||||
//reads pc_to_reader_datablock_len with pc_to_reader_datablock_len size, translate it into a ISO7816_Command_APDU type
|
||||
//extra data will be pointed to commandDataBuffer
|
||||
uint8_t iso7816_read_command_apdu(
|
||||
ISO7816_Command_APDU* command,
|
||||
const uint8_t* dataBuffer,
|
||||
uint32_t dataLen) {
|
||||
command->CLA = dataBuffer[0];
|
||||
command->INS = dataBuffer[1];
|
||||
command->P1 = dataBuffer[2];
|
||||
command->P2 = dataBuffer[3];
|
||||
const uint8_t* pc_to_reader_datablock,
|
||||
uint32_t pc_to_reader_datablock_len,
|
||||
uint32_t max_apdu_size) {
|
||||
command->CLA = pc_to_reader_datablock[0];
|
||||
command->INS = pc_to_reader_datablock[1];
|
||||
command->P1 = pc_to_reader_datablock[2];
|
||||
command->P2 = pc_to_reader_datablock[3];
|
||||
|
||||
if(dataLen == 4) {
|
||||
if(pc_to_reader_datablock_len == 4) {
|
||||
command->Lc = 0;
|
||||
command->Le = 0;
|
||||
command->LePresent = false;
|
||||
|
||||
return ISO7816_READ_COMMAND_APDU_OK;
|
||||
} else if(dataLen == 5) {
|
||||
} else if(pc_to_reader_datablock_len == 5) {
|
||||
//short le
|
||||
|
||||
command->Lc = 0;
|
||||
command->Le = dataBuffer[4];
|
||||
command->Le = pc_to_reader_datablock[4];
|
||||
command->LePresent = true;
|
||||
|
||||
return ISO7816_READ_COMMAND_APDU_OK;
|
||||
} else if(dataLen > 5 && dataBuffer[4] != 0x00) {
|
||||
} else if(pc_to_reader_datablock_len > 5 && pc_to_reader_datablock[4] != 0x00) {
|
||||
//short lc
|
||||
|
||||
command->Lc = dataBuffer[4];
|
||||
if(command->Lc > 0 && command->Lc < CCID_SHORT_APDU_SIZE) { //-V560
|
||||
memcpy(command->Data, &dataBuffer[5], command->Lc);
|
||||
command->Lc = pc_to_reader_datablock[4];
|
||||
if(command->Lc > 0 && command->Lc < max_apdu_size) { //-V560
|
||||
memcpy(command->Data, &pc_to_reader_datablock[5], command->Lc);
|
||||
|
||||
//does it have a short le too?
|
||||
if(dataLen == (uint32_t)(command->Lc + 5)) {
|
||||
if(pc_to_reader_datablock_len == (uint32_t)(command->Lc + 5)) {
|
||||
command->Le = 0;
|
||||
command->LePresent = false;
|
||||
return ISO7816_READ_COMMAND_APDU_OK;
|
||||
} else if(dataLen == (uint32_t)(command->Lc + 6)) {
|
||||
command->Le = dataBuffer[dataLen - 1];
|
||||
} else if(pc_to_reader_datablock_len == (uint32_t)(command->Lc + 6)) {
|
||||
command->Le = pc_to_reader_datablock[pc_to_reader_datablock_len - 1];
|
||||
command->LePresent = true;
|
||||
|
||||
return ISO7816_READ_COMMAND_APDU_OK;
|
||||
|
||||
@@ -34,7 +34,8 @@ typedef struct {
|
||||
uint8_t iso7816_read_command_apdu(
|
||||
ISO7816_Command_APDU* command,
|
||||
const uint8_t* pc_to_reader_datablock,
|
||||
uint32_t pc_to_reader_datablock_len);
|
||||
uint32_t pc_to_reader_datablock_len,
|
||||
uint32_t max_apdu_size);
|
||||
void iso7816_write_response_apdu(
|
||||
const ISO7816_Response_APDU* response,
|
||||
uint8_t* reader_to_pc_datablock,
|
||||
|
||||
@@ -6,18 +6,27 @@
|
||||
* 13 -> 16 (USART TX to LPUART RX)
|
||||
* 14 -> 15 (USART RX to LPUART TX)
|
||||
*
|
||||
* Optional: Connect an LED with an appropriate series resistor
|
||||
* between pins 1 and 8. It will always be on if the device is
|
||||
* connected to USB power, so unplug it before running the app.
|
||||
*
|
||||
* What this application does:
|
||||
*
|
||||
* - Enables module support and emulates the module on a single device
|
||||
* (hence the above connection),
|
||||
* - Connects to the expansion module service, sets baud rate,
|
||||
* - Enables OTG (5V) on GPIO via plain expansion protocol,
|
||||
* - Waits 5 cycles of idle loop (1 second),
|
||||
* - Starts the RPC session,
|
||||
* - Disables OTG (5V) on GPIO via RPC messages,
|
||||
* - Waits 5 cycles of idle loop (1 second),
|
||||
* - Creates a directory at `/ext/ExpansionTest` and writes a file
|
||||
* named `test.txt` under it,
|
||||
* - Plays an audiovisual alert (sound and blinking display),
|
||||
* - Waits 10 cycles of idle loop,
|
||||
* - Enables OTG (5V) on GPIO via RPC messages,
|
||||
* - Waits 5 cycles of idle loop (1 second),
|
||||
* - Stops the RPC session,
|
||||
* - Waits another 10 cycles of idle loop,
|
||||
* - Disables OTG (5V) on GPIO via plain expansion protocol,
|
||||
* - Exits (plays a sound if any of the above steps failed).
|
||||
*/
|
||||
#include <furi.h>
|
||||
@@ -302,6 +311,22 @@ static bool expansion_test_app_handshake(ExpansionTestApp* instance) {
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_enable_otg(ExpansionTestApp* instance, bool enable) {
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
const ExpansionFrameControlCommand command = enable ?
|
||||
ExpansionFrameControlCommandEnableOtg :
|
||||
ExpansionFrameControlCommandDisableOtg;
|
||||
if(!expansion_test_app_send_control_request(instance, command)) break;
|
||||
if(!expansion_test_app_receive_frame(instance, &instance->frame)) break;
|
||||
if(!expansion_test_app_is_success_response(&instance->frame)) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_start_rpc(ExpansionTestApp* instance) {
|
||||
bool success = false;
|
||||
|
||||
@@ -396,6 +421,27 @@ static bool expansion_test_app_rpc_alert(ExpansionTestApp* instance) {
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_rpc_enable_otg(ExpansionTestApp* instance, bool enable) {
|
||||
bool success = false;
|
||||
|
||||
instance->msg.command_id++;
|
||||
instance->msg.command_status = PB_CommandStatus_OK;
|
||||
instance->msg.which_content = PB_Main_gpio_set_otg_mode_tag;
|
||||
instance->msg.content.gpio_set_otg_mode.mode = enable ? PB_Gpio_GpioOtgMode_ON :
|
||||
PB_Gpio_GpioOtgMode_OFF;
|
||||
instance->msg.has_next = false;
|
||||
|
||||
do {
|
||||
if(!expansion_test_app_send_rpc_request(instance, &instance->msg)) break;
|
||||
if(!expansion_test_app_receive_rpc_request(instance, &instance->msg)) break;
|
||||
if(instance->msg.which_content != PB_Main_empty_tag) break;
|
||||
if(instance->msg.command_status != PB_CommandStatus_OK) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_idle(ExpansionTestApp* instance, uint32_t num_cycles) {
|
||||
uint32_t num_cycles_done;
|
||||
for(num_cycles_done = 0; num_cycles_done < num_cycles; ++num_cycles_done) {
|
||||
@@ -434,13 +480,18 @@ int32_t expansion_test_app(void* p) {
|
||||
if(!expansion_test_app_send_presence(instance)) break;
|
||||
if(!expansion_test_app_wait_ready(instance)) break;
|
||||
if(!expansion_test_app_handshake(instance)) break;
|
||||
if(!expansion_test_app_enable_otg(instance, true)) break;
|
||||
if(!expansion_test_app_idle(instance, 5)) break;
|
||||
if(!expansion_test_app_start_rpc(instance)) break;
|
||||
if(!expansion_test_app_rpc_enable_otg(instance, false)) break;
|
||||
if(!expansion_test_app_idle(instance, 5)) break;
|
||||
if(!expansion_test_app_rpc_mkdir(instance)) break;
|
||||
if(!expansion_test_app_rpc_write(instance)) break;
|
||||
if(!expansion_test_app_rpc_alert(instance)) break;
|
||||
if(!expansion_test_app_idle(instance, 10)) break;
|
||||
if(!expansion_test_app_rpc_enable_otg(instance, true)) break;
|
||||
if(!expansion_test_app_idle(instance, 5)) break;
|
||||
if(!expansion_test_app_stop_rpc(instance)) break;
|
||||
if(!expansion_test_app_idle(instance, 10)) break;
|
||||
if(!expansion_test_app_enable_otg(instance, false)) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "../rpc_debug_app.h"
|
||||
|
||||
#include <lib/toolbox/strint.h>
|
||||
|
||||
static bool rpc_debug_app_scene_input_error_code_validator_callback(
|
||||
const char* text,
|
||||
FuriString* error,
|
||||
@@ -44,9 +46,8 @@ bool rpc_debug_app_scene_input_error_code_on_event(void* context, SceneManagerEv
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == RpcDebugAppCustomEventInputErrorCode) {
|
||||
char* end;
|
||||
int error_code = strtol(app->text_store, &end, 10);
|
||||
if(!*end) {
|
||||
uint32_t error_code;
|
||||
if(strint_to_uint32(app->text_store, NULL, &error_code, 10) == StrintParseNoError) {
|
||||
rpc_system_app_set_error_code(app->rpc, error_code);
|
||||
}
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/modules/dialog_ex.h>
|
||||
|
||||
#include <lib/toolbox/strint.h>
|
||||
|
||||
#include <notification/notification.h>
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
@@ -320,7 +322,7 @@ int32_t uart_echo_app(void* p) {
|
||||
uint32_t baudrate = DEFAULT_BAUD_RATE;
|
||||
if(p) {
|
||||
const char* baudrate_str = p;
|
||||
if(sscanf(baudrate_str, "%lu", &baudrate) != 1) {
|
||||
if(strint_to_uint32(baudrate_str, NULL, &baudrate, 10) != StrintParseNoError) {
|
||||
FURI_LOG_E(TAG, "Invalid baudrate: %s", baudrate_str);
|
||||
baudrate = DEFAULT_BAUD_RATE;
|
||||
}
|
||||
|
||||
@@ -220,3 +220,11 @@ App(
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_strint",
|
||||
sources=["tests/common/*.c", "tests/strint/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#include <toolbox/strint.h>
|
||||
|
||||
MU_TEST(strint_test_basic) {
|
||||
uint32_t result = 0;
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("123456", NULL, &result, 10));
|
||||
mu_assert_int_eq(123456, result);
|
||||
}
|
||||
|
||||
MU_TEST(strint_test_junk) {
|
||||
uint32_t result = 0;
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32(" 123456 ", NULL, &result, 10));
|
||||
mu_assert_int_eq(123456, result);
|
||||
mu_assert_int_eq(
|
||||
StrintParseNoError, strint_to_uint32(" \r\n\r\n 123456 ", NULL, &result, 10));
|
||||
mu_assert_int_eq(123456, result);
|
||||
}
|
||||
|
||||
MU_TEST(strint_test_tail) {
|
||||
uint32_t result = 0;
|
||||
char* tail;
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("123456tail", &tail, &result, 10));
|
||||
mu_assert_int_eq(123456, result);
|
||||
mu_assert_string_eq("tail", tail);
|
||||
mu_assert_int_eq(
|
||||
StrintParseNoError, strint_to_uint32(" \r\n 123456tail", &tail, &result, 10));
|
||||
mu_assert_int_eq(123456, result);
|
||||
mu_assert_string_eq("tail", tail);
|
||||
}
|
||||
|
||||
MU_TEST(strint_test_errors) {
|
||||
uint32_t result = 123;
|
||||
mu_assert_int_eq(StrintParseAbsentError, strint_to_uint32("", NULL, &result, 10));
|
||||
mu_assert_int_eq(123, result);
|
||||
mu_assert_int_eq(StrintParseAbsentError, strint_to_uint32(" asd\r\n", NULL, &result, 10));
|
||||
mu_assert_int_eq(123, result);
|
||||
mu_assert_int_eq(StrintParseSignError, strint_to_uint32("+++123456", NULL, &result, 10));
|
||||
mu_assert_int_eq(123, result);
|
||||
mu_assert_int_eq(StrintParseSignError, strint_to_uint32("-1", NULL, &result, 10));
|
||||
mu_assert_int_eq(123, result);
|
||||
mu_assert_int_eq(
|
||||
StrintParseOverflowError,
|
||||
strint_to_uint32("0xAAAAAAAAAAAAAAAADEADBEEF!!!!!!", NULL, &result, 0));
|
||||
mu_assert_int_eq(123, result);
|
||||
mu_assert_int_eq(StrintParseOverflowError, strint_to_uint32("4294967296", NULL, &result, 0));
|
||||
mu_assert_int_eq(123, result);
|
||||
|
||||
int32_t result_i32 = 123;
|
||||
mu_assert_int_eq(
|
||||
StrintParseOverflowError, strint_to_int32("-2147483649", NULL, &result_i32, 0));
|
||||
mu_assert_int_eq(123, result_i32);
|
||||
}
|
||||
|
||||
MU_TEST(strint_test_bases) {
|
||||
uint32_t result = 0;
|
||||
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("0x123", NULL, &result, 0));
|
||||
mu_assert_int_eq(0x123, result);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("0X123", NULL, &result, 0));
|
||||
mu_assert_int_eq(0x123, result);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("0xDEADBEEF", NULL, &result, 0));
|
||||
mu_assert_int_eq(0xDEADBEEF, result);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("0xDEADBEEF", NULL, &result, 16));
|
||||
mu_assert_int_eq(0xDEADBEEF, result);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("123", NULL, &result, 16));
|
||||
mu_assert_int_eq(0x123, result);
|
||||
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("123", NULL, &result, 0));
|
||||
mu_assert_int_eq(123, result);
|
||||
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("0123", NULL, &result, 0));
|
||||
mu_assert_int_eq(0123, result);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("0123", NULL, &result, 8));
|
||||
mu_assert_int_eq(0123, result);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("123", NULL, &result, 8));
|
||||
mu_assert_int_eq(0123, result);
|
||||
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("0b101", NULL, &result, 0));
|
||||
mu_assert_int_eq(0b101, result);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("0b101", NULL, &result, 2));
|
||||
mu_assert_int_eq(0b101, result);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("0B101", NULL, &result, 0));
|
||||
mu_assert_int_eq(0b101, result);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("101", NULL, &result, 2));
|
||||
mu_assert_int_eq(0b101, result);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(strint_test_limits) {
|
||||
uint64_t result_u64 = 0;
|
||||
mu_assert_int_eq(
|
||||
StrintParseNoError, strint_to_uint64("18446744073709551615", NULL, &result_u64, 0));
|
||||
// `mu_assert_int_eq' does not support longs :(
|
||||
mu_assert(UINT64_MAX == result_u64, "result does not equal UINT64_MAX");
|
||||
|
||||
int64_t result_i64 = 0;
|
||||
mu_assert_int_eq(
|
||||
StrintParseNoError, strint_to_int64("9223372036854775807", NULL, &result_i64, 0));
|
||||
mu_assert(INT64_MAX == result_i64, "result does not equal INT64_MAX");
|
||||
mu_assert_int_eq(
|
||||
StrintParseNoError, strint_to_int64("-9223372036854775808", NULL, &result_i64, 0));
|
||||
mu_assert(INT64_MIN == result_i64, "result does not equal INT64_MIN");
|
||||
|
||||
uint32_t result_u32 = 0;
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint32("4294967295", NULL, &result_u32, 0));
|
||||
mu_assert_int_eq(UINT32_MAX, result_u32);
|
||||
|
||||
int32_t result_i32 = 0;
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_int32("2147483647", NULL, &result_i32, 0));
|
||||
mu_assert_int_eq(INT32_MAX, result_i32);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_int32("-2147483648", NULL, &result_i32, 0));
|
||||
mu_assert_int_eq(INT32_MIN, result_i32);
|
||||
|
||||
uint16_t result_u16 = 0;
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_uint16("65535", NULL, &result_u16, 0));
|
||||
mu_assert_int_eq(UINT16_MAX, result_u16);
|
||||
|
||||
int16_t result_i16 = 0;
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_int16("32767", NULL, &result_i16, 0));
|
||||
mu_assert_int_eq(INT16_MAX, result_i16);
|
||||
mu_assert_int_eq(StrintParseNoError, strint_to_int16("-32768", NULL, &result_i16, 0));
|
||||
mu_assert_int_eq(INT16_MIN, result_i16);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_strint_suite) {
|
||||
MU_RUN_TEST(strint_test_basic);
|
||||
MU_RUN_TEST(strint_test_junk);
|
||||
MU_RUN_TEST(strint_test_tail);
|
||||
MU_RUN_TEST(strint_test_errors);
|
||||
MU_RUN_TEST(strint_test_bases);
|
||||
MU_RUN_TEST(strint_test_limits);
|
||||
}
|
||||
|
||||
int run_minunit_test_strint(void) {
|
||||
MU_RUN_SUITE(test_strint_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_strint)
|
||||
Reference in New Issue
Block a user