/* t_bdConvFromStr.c */

/*
 * Copyright (C) 2026 David Ireland, D.I. Management Services Pty Limited
 * <https://di-mgt.com.au/contact/> <https://di-mgt.com.au/bigdigits.html>
 * SPDX-License-Identifier: MPL-2.0
 *
 * Last updated:
 * $Date: 2026-04-04 08:59:00 $
 * $Revision: 2.7.1 $
 * $Author: dai $
 */

/* Examples using the bdConvFromStr function [new in v2.7, updated in v2.7.1] */

#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <assert.h>
#include "bigd.h"

int main(void)
{
    BIGD n, ref;
    char *pstr;
    char *endptr;
    int haserror = 0;

    /* Display the BigDigits version number */
    printf("BigDigits version=%d\n", bdVersion());
    if (bdVersion() < 2710) {
        printf("ERROR: require bigd version 2.7.1 or later\n");
        return 1;
    }

    /* Create new BIGD objects */
    n = bdNew();
    ref = bdNew();


    /* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
#endif

    /* Example 1 - parse a complete valid string no leading whitespace */
    pstr = "123456789012345678901234567890123456789012345678901234567890";
    printf("\nInput: '%s'\n", pstr);
    bdConvFromStr(n, pstr, &endptr, 10);
    bdPrintDecimal("n=", n, "\n");
    // Check endptr
    if (endptr == pstr) {
        printf("No digits found or input not acceptable\n");
        printf("'%s'\n", pstr);
        haserror = 1;
    }
    else if (*endptr != '\0') {
        printf("Found trailing character '%c'\n", *endptr);
    }
    else {
        printf("Complete and valid conversion\n");
    }
    if (!haserror) {
        // Check against original function (which skips invalid chars)
        bdConvFromDecimal(ref, pstr);
        assert(bdIsEqual(ref, n));
    }

    /* Example 2 - valid input, leading whitespace and trailing invalid characters "*xyz()" */
    pstr = "    123456789012345678901234567890123456789012345678901234567890*xyz()";
    printf("\nInput: '%s'\n", pstr);
    bdConvFromStr(n, pstr, &endptr, 0);
    bdPrintDecimal("n=", n, "\n");
    // Check endptr
    if (endptr == pstr) {
        printf("No digits found or input not acceptable\n");
        printf("'%s'\n", pstr);
        haserror = 1;
    }
    else if (*endptr != '\0') {
        printf("Found trailing character '%c'\n", *endptr);
    }
    else {
        printf("Complete and valid conversion\n");
    }
    if (!haserror) {
        // Check against original function (which skips invalid chars)
        bdConvFromDecimal(ref, pstr);
        assert(bdIsEqual(ref, n));
    }

    /* Example 3 - invalid input leading '-' is invalid */
    pstr = "    -123456789012345678901234567890123456789012345678901234567890*xyz()";
    printf("\nInput: '%s'\n", pstr);
    bdConvFromStr(n, pstr, &endptr, 0);
    bdPrintDecimal("n=", n, "\n");
    // Check endptr
    if (endptr == pstr) {
        printf("No digits found or input not acceptable\n");
        printf("'%s'\n", pstr);
        haserror = 1;
    }
    else if (*endptr != '\0') {
        printf("Found trailing character '%c'\n", *endptr);
    }
    else {
        printf("Complete and valid conversion\n");
    }
    if (!haserror) {
        // Check against original function (which skips invalid chars)
        bdConvFromDecimal(ref, pstr);
        assert(bdIsEqual(ref, n));
    }

    /* Example 4 - parse valid base 16 digits */
    pstr = "  DEADBEEFCAFEBABE01";
    printf("\nInput: '%s'\n", pstr);
    bdConvFromStr(n, pstr, &endptr, 16);
    bdPrintHex("n=", n, "\n");
    // Check endptr
    if (endptr == pstr) {
        printf("No digits found or input not acceptable\n");
        printf("'%s'\n", pstr);
        haserror = 1;
    }
    else if (*endptr != '\0') {
        printf("Found trailing character '%c'\n", *endptr);
    }
    else {
        printf("Complete and valid conversion\n");
    }
    if (!haserror) {
        // Check against original function (which skips invalid chars)
        bdConvFromHex(ref, pstr);
        assert(bdIsEqual(ref, n));
    }

    /* Example 5 - parse valid base 16 digits with 0x prefix and trailing 'G' */
    pstr = "  0xDEADBEEFCAFEBABE01G";
    printf("\nInput: '%s'\n", pstr);
    bdConvFromStr(n, pstr, &endptr, 0);
    bdPrintHex("n=", n, "\n");
    // Check endptr
    if (endptr == pstr) {
        printf("No digits found or input not acceptable\n");
        printf("'%s'\n", pstr);
        haserror = 1;
    }
    else if (*endptr != '\0') {
        printf("Found trailing character '%c'\n", *endptr);
    }
    else {
        printf("Complete and valid conversion\n");
    }
    if (!haserror) {
        // Check against original function (which skips invalid chars)
        bdConvFromHex(ref, pstr);
        assert(bdIsEqual(ref, n));
    }

    /* Example 6 - parse binary number base 2, with invalid trailing char '2' */
    pstr = "  1101111010101101101111101110111111001010111111101011101010111110000000012";
    printf("\nInput: '%s'\n", pstr);
    bdConvFromStr(n, pstr, &endptr, 2);
    bdPrintHex("n=", n, "\n");
    // Check endptr
    if (endptr == pstr) {
        printf("No digits found or input not acceptable\n");
        printf("'%s'\n", pstr);
        haserror = 1;
    }
    else if (*endptr != '\0') {
        printf("Found trailing character '%c'\n", *endptr);
    }
    else {
        printf("Complete and valid conversion\n");
    }

    /* Example 7 - parse binary number base 2 with 0b prefix */
    pstr = "0b110111101010110110111110111011111100101011111110101110101011111000000001";
    printf("\nInput: '%s'\n", pstr);
    bdConvFromStr(n, pstr, &endptr, 2);
    bdPrintHex("n=", n, "\n");
    // Check endptr
    if (endptr == pstr) {
        printf("No digits found or input not acceptable\n");
        printf("'%s'\n", pstr);
        haserror = 1;
    }
    else if (*endptr != '\0') {
        printf("Found trailing character '%c'\n", *endptr);
    }
    else {
        printf("Complete and valid conversion\n");
    }


    bdFree(&n);
    bdFree(&ref);

    return 0;
}