Home

Resume

Blog

Teikitu


/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */
/*  »Project«   Teikitu Gaming System (TgS) (∂)
    »File«      TgS Common - Base - API.c
    »Author«    Andrew Aye (EMail: mailto:andrew.aye@gmail.com, Web: http://www.andrewaye.com)
    »Version«   4.51 / »GUID« A9981407-3EC9-42AF-8B6F-8BE6DD919615                                                                                                        */
/*   -------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
/*  Copyright: © 2002-2017, Andrew Aye.  All Rights Reserved.
    This software is free for non-commercial use.  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
      following conditions are met:
        Redistribution of source code must retain this copyright notice, this list of conditions and the following disclaimers.
        Redistribution in binary form must reproduce this copyright notice, this list of conditions and the following disclaimers in the documentation and other materials
          provided with the distribution.
    The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
    The intellectual property rights of the algorithms used reside with Andrew Aye.
    You may not use this software, in whole or in part, in support of any commercial product without the express written consent of the author.
    There is no warranty or other guarantee of fitness of this software for any purpose. It is provided solely "as is".                                                   */
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */

MSVC_PRAGMA(warning( push, 3 ))
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
MSVC_PRAGMA(warning( pop ))


/* == Common ============================================================================================================================================================ */

/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
/*  Random Number Generator - Mersenne Twister */
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */

/* M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number Generator", */
/* ACM Transactions on Modelling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. */
/* Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, */
/* Copyright (C) 2000 - 2009, Richard J. Wagner */
/* All rights reserved. */
/* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: */
/*   1. Redistribution of source code must retain the above copyright notice, this list of conditions and the following disclaimer. */
/*   2. Redistribution in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other */
/*      materials provided with the distribution. */
/*   3. The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES */
/* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */
/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY */
/* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */




/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
/*  File Local Constants - Random Number Generator */
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */

enum { KTgMERSENNE_TWISTER_PERIOD_N         = 624 };
enum { KTgMERSENNE_TWISTER_PERIOD_M         = 397 };
enum { KTgMERSENNE_TWISTER_PERIOD_NM        = KTgMERSENNE_TWISTER_PERIOD_N - KTgMERSENNE_TWISTER_PERIOD_M };

#define KTgMERSENNE_TWISTER_UPPER_MASK      0x80000000UL /* MSB */
#define KTgMERSENNE_TWISTER_LOWER_MASK      0x7fffffffUL /* LSB */

#if !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD
static ETgMODULE_STATE                      s_enRND_MT_State = ETgMODULE_STATE__FREED;
/*# !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD */
#endif

static C_TgUINT32                           s_uiMT_Magic[2] = { 0x0UL, 0x9908b0dfUL };

TgVOID                                      tgCM_Random_MT_Reload( TgVOID );

static P_TgCHAR                             tgSZ_With_Grouping_From_SZ( PU_TgCHAR, C_TgSIZE, CPU_TgCHAR );
static P_TgCHAR                             tgSZ_Read_String_With_Comments_Quotes( PP_TgCHAR, PC_TgCHAR, C_TgBOOL );




/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
/*  File Local Data - Random Number Generator */
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
CLANG_WARN_DISABLE_PUSH(missing-variable-declarations)
TgTLS TgSINT32                              tls_uiMT_Index = KTgMERSENNE_TWISTER_PERIOD_N + 1;
TgTLS union
{
    TgUINT32                                    m_uiData[KTgMERSENNE_TWISTER_PERIOD_N];
    TgVEC_U32_04                                m_vData[KTgMERSENNE_TWISTER_PERIOD_N >> 2];
}                                           tls_uiMT_State;
CLANG_WARN_DISABLE_POP(missing-variable-declarations)

#if !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD
STg1_MP_CS                                  g_csMT_Lock;
/*# !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD */
#endif




/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
/*  Public Functions - Random Number Generator */
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */

/* ---- tgCM_Init_Random_MT --------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgVOID tgCM_Init_Random_MT( TgUINT32 uiSeed )
{
    TgUINT32                            i;

#if !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD
    if (s_enRND_MT_State != ETgMODULE_STATE__BOOTED)
    {
        TgVERIFY( KTgS_OK == tgCM_MP_CS_Init( &g_csMT_Lock ) );
        s_enRND_MT_State = ETgMODULE_STATE__BOOTED;
    }

    tgCM_MP_CS_Enter_Block( &g_csMT_Lock );
/*# !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD */
#endif

    tls_uiMT_State.m_uiData[0] = uiSeed & 0xFFFFFFFFUL;

    for (i = 1; i < KTgMERSENNE_TWISTER_PERIOD_N; ++i)
    {
        tls_uiMT_State.m_uiData[i] = (1812433253UL * (tls_uiMT_State.m_uiData[i - 1] ^ (tls_uiMT_State.m_uiData[i - 1] >> 30)) + i);
        tls_uiMT_State.m_uiData[i] &= 0xFFFFFFFFUL;
    }

    tls_uiMT_Index = KTgMERSENNE_TWISTER_PERIOD_N;

#if !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD
    tgCM_MP_CS_Exit( &g_csMT_Lock );
/*# !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD */
#endif
}


/* ---- tgCM_Init_Random_MT__Key_List ----------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgVOID tgCM_Init_Random_MT__Key_List( PU_TgUINT32 puiKeyList, TgUINT32 nuiKey )
{
    TgUINT32                            i, j, k;

#if !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD
    tgCM_MP_CS_Enter_Block( &g_csMT_Lock );
/*# !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD */
#endif

    tgCM_Init_Random_MT(19650218UL);

    i = 1;
    j = 0;
    k = tgCM_MIN_U32( KTgMERSENNE_TWISTER_PERIOD_N, nuiKey );

    for (; k; --k)
    {
        tls_uiMT_State.m_uiData[i] ^= (tls_uiMT_State.m_uiData[i - 1] ^ (tls_uiMT_State.m_uiData[i - 1] >> 30)) * 1664525UL;
        tls_uiMT_State.m_uiData[i] += puiKeyList[j] + j;
        tls_uiMT_State.m_uiData[i] &= 0xFFFFFFFFUL;
        ++i; ++j;

        if (i >= KTgMERSENNE_TWISTER_PERIOD_N)
        {
            tls_uiMT_State.m_uiData[0] = tls_uiMT_State.m_uiData[KTgMERSENNE_TWISTER_PERIOD_N - 1];
            i = 1;
        };

        if (j >= nuiKey)
        {
            j = 0;
        };
    };

    for (k = KTgMERSENNE_TWISTER_PERIOD_N - 1; k; --k)
    {
        tls_uiMT_State.m_uiData[i] ^= (tls_uiMT_State.m_uiData[i - 1] ^ (tls_uiMT_State.m_uiData[i - 1] >> 30)) * 1566083941UL;
        tls_uiMT_State.m_uiData[i] = (tls_uiMT_State.m_uiData[i] - i) & 0xFFFFFFFFUL;
        ++i;

        if (i >= KTgMERSENNE_TWISTER_PERIOD_N)
        {
            tls_uiMT_State.m_uiData[0] = tls_uiMT_State.m_uiData[KTgMERSENNE_TWISTER_PERIOD_N - 1];
            i = 1;
        };
    };

    tls_uiMT_State.m_uiData[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */

#if !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD
    tgCM_MP_CS_Exit( &g_csMT_Lock );
/*# !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD */
#endif
}


/* ---- tgCM_RAND_MT_U32 ------------------------------------------------------------------------------------------------------------------------------------------------ */
/* Generate a random number [0,0xFFFFFFFF] */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgUINT32 tgCM_RAND_MT_U32( TgVOID )
{
    TgUINT32                            uiRand_Val;

#if !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD
    tgCM_MP_CS_Enter_Block( &g_csMT_Lock );
/*# !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD */
#endif

    if (tls_uiMT_Index >= KTgMERSENNE_TWISTER_PERIOD_N)
    {
        tgCM_Random_MT_Reload();
        TgCRITICAL( tls_uiMT_Index == 0 );
    }

    uiRand_Val = tls_uiMT_State.m_uiData[tls_uiMT_Index++];
    uiRand_Val ^= (uiRand_Val >> 11);
    uiRand_Val ^= (uiRand_Val << 7) & 0x9d2c5680UL;
    uiRand_Val ^= (uiRand_Val << 15) & 0xefc60000UL;
    uiRand_Val ^= (uiRand_Val >> 18);

#if !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD
    tgCM_MP_CS_Exit( &g_csMT_Lock );
/*# !TgCOMPILE_THREAD_LOCAL && TgCOMPILE_THREAD */
#endif

    return (uiRand_Val);
}




/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
/*  Public Functions - Utility Functions */
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */

/* ---- tgCM_RAND_NRM_F32 ----------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgFLOAT32 tgCM_RAND_NRM_F32( C_TgFLOAT32 fMean, C_TgFLOAT32 fStdDev )
{
    TgFLOAT32                           fX, fY, fR, fS;

    do
    {
        fX = 2.0F * tgCM_RAND_F32() - 1.0F;
        fY = 2.0F * tgCM_RAND_F32() - 1.0F;
        fR = fX*fX + fY*fY;
    }
    while (fR >= 1.0F || fR == 0.0F);

    fS = tgPM_SQRT_F32( -2.0F * tgPM_LOG_F32( fR ) / fR );

    return fMean + fX * fS * fStdDev;
}




/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
/*  Public Functions - String API */
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */

#if defined(TgCOMPILE_WIDE_CHAR) /* ---- WIDE CHARACTER ----------------------------------------------------------------------------------------------------------------- */

/* ---- tgSZ_From_U08 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_U08( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgUINT08 uiValue )
{
    TgERROR(0 != pswzDest && 0 < nuiDest);
    TgSNWPRINTF( pswzDest, nuiDest, L"%u", uiValue );
    return (pswzDest);
}


/* ---- tgSZ_From_U16 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_U16( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgUINT16 uiValue )
{
    TgERROR(0 != pswzDest && 0 < nuiDest);
    TgSNWPRINTF( pswzDest, nuiDest, L"%hu", uiValue );
    return (pswzDest);
}


/* ---- tgSZ_From_U32 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_U32( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgUINT32 uiValue )
{
    TgERROR(0 != pswzDest && 0 < nuiDest);
    TgSNWPRINTF( pswzDest, nuiDest, L"%lu", (unsigned long)uiValue );
    return (pswzDest);
}


/* ---- tgSZ_From_U64 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_U64( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgUINT64 uiValue )
{
    TgERROR(0 != pswzDest && 0 < nuiDest);
    TgSNWPRINTF( pswzDest, nuiDest, L"%llu", uiValue );
    return (pswzDest);
}


/* ---- tgSZ_From_S08 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_S08( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgSINT08 iValue )
{
    TgERROR(0 != pswzDest && 0 < nuiDest);
    TgSNWPRINTF( pswzDest, nuiDest, L"%d", iValue );
    return (pswzDest);
}


/* ---- tgSZ_From_S16 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_S16( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgSINT16 iValue )
{
    TgERROR(0 != pswzDest && 0 < nuiDest);
    TgSNWPRINTF( pswzDest, nuiDest, L"%hd", iValue );
    return (pswzDest);
}


/* ---- tgSZ_From_S32 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_S32( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgSINT32 iValue )
{
    TgERROR(0 != pswzDest && 0 < nuiDest);
    TgSNWPRINTF( pswzDest, nuiDest, L"%ld", (long)iValue );
    return (pswzDest);
}


/* ---- tgSZ_From_S64 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_S64( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgSINT64 iValue )
{
    TgERROR(0 != pswzDest && 0 < nuiDest);
    TgSNWPRINTF( pswzDest, nuiDest, L"%lld", iValue );
    return (pswzDest);
}


/* ---- tgSZ_From_F32 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_F32( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgFLOAT32 fValue )
{
    TgERROR(0 != pswzDest && 0 < nuiDest);
    TgSNWPRINTF( pswzDest, nuiDest, L"%f", fValue );
    return (pswzDest);
}


/* ---- tgSZ_From_F64 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_F64( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgFLOAT64 fValue )
{
    TgERROR(0 != pswzDest && 0 < nuiDest);
    TgSNWPRINTF( pswzDest, nuiDest, L"%f", fValue );
    return (pswzDest);
}


/* ---- tgSZ_To_U32 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgUINT32 tgSZ_To_U32( CPCU_TgCHAR pswzSrc )
{
    TgERROR(0 != pswzSrc);
    return (wcstoul( pswzSrc, 0, 10 ));
}


/* ---- tgSZ_To_U64 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgUINT64 tgSZ_To_U64( CPCU_TgCHAR pswzSrc )
{
    TgERROR(0 != pswzSrc);
    return (_wcstoui64( pswzSrc, 0, 10 ));
}


/* ---- tgSZ_To_S32 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_To_S32( CPCU_TgCHAR pswzSrc )
{
    TgERROR(0 != pswzSrc);
    return (wcstol( pswzSrc, 0, 10 ));
}


/* ---- tgSZ_To_S64 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT64 tgSZ_To_S64( CPCU_TgCHAR pswzSrc )
{
    TgERROR(0 != pswzSrc);
    return (_wcstoi64( pswzSrc, 0, 10 ));
}


/* ---- tgSZ_To_F32 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgFLOAT32 tgSZ_To_F32( CPCU_TgCHAR pswzSrc )
{
    TgERROR(0 != pswzSrc);
    return ((TgFLOAT32)(wcstod( pswzSrc, 0 )));
}


/* ---- tgSZ_To_F64 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgFLOAT64 tgSZ_To_F64( CPCU_TgCHAR pswzSrc )
{
    TgERROR(0 != pswzSrc);
    return ((wcstod( pswzSrc, 0 )));
}


/* ---- tgSZ_Length ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSIZE tgSZ_Length( CPCU_TgCHAR pswzSrc )
{
    TgERROR(0 != pswzSrc);
    return ((TgUINT32)(wcslen( pswzSrc ))); /* wcslen doesn't count terminating '\0' */
}


/* ---- tgSZ_Compare ---------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_Compare( CPC_TgCHAR pswzLeft, CPC_TgCHAR pswzRight )
{
    TgERROR(0 != pswzLeft && 0 != pswzRight);
    return (wcscmp( pswzLeft, pswzRight ));
}


/* ---- tgSZ_Compare_NoCase --------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_Compare_NoCase( CPC_TgCHAR pswzLeft, CPC_TgCHAR pswzRight )
{
    TgERROR(0 != pswzLeft && 0 != pswzRight);
    return (_wcsicmp( pswzLeft, pswzRight ));
}


/* ---- tgSZ_CompareN --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_CompareN( CPC_TgCHAR pswzLeft, CPC_TgCHAR pswzRight, C_TgSIZE uiMax )
{
    TgERROR(0 != pswzLeft && 0 != pswzRight);
    return (wcsncmp( pswzLeft, pswzRight, uiMax ));
}


/* ---- tgSZ_CompareN_NoCase -------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_CompareN_NoCase( CPC_TgCHAR pswzLeft, CPC_TgCHAR pswzRight, C_TgSIZE uiMax )
{
    TgERROR(0 != pswzLeft && 0 != pswzRight);
    return (_wcsnicmp( pswzLeft, pswzRight, uiMax ));
}


/* ---- tgSZ_LengthVF --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_LengthVF( CPC_TgCHAR pswzSrc, va_list vaList )
{
    TgERROR(0 != pswzSrc);
#if defined(TgCOMPILE_SUPPORT_MSFT_SYSTEM_INCLUDE)
    return (_vscwprintf( pswzSrc, vaList )); /* _vscwprintf doesn't count terminating '\0' */
#else
    return (vswprintf( 0, 0, pswzSrc, vaList ));
#endif
}


/* ---- tgCHAR_Is_Print ------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgBOOL tgCHAR_Is_Print( C_TgCHAR uiVal )
{
    return (0 != iswprint( uiVal ) ? TgTRUE : TgFALSE);
}


/* ---- tgCHAR_Is_Space ------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgBOOL tgCHAR_Is_Space( C_TgCHAR uiVal )
{
    return (0 != iswspace( uiVal ) ? TgTRUE : TgFALSE);
}


/* ---- tgCHAR_To_Upper ------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgCHAR tgCHAR_To_Upper( C_TgCHAR uiVal )
{
    return (towupper( uiVal ));
}


/* ---- tgCHAR_To_Lower ------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgCHAR tgCHAR_To_Lower( C_TgCHAR uiVal )
{
    return (towlower( uiVal ));
}


/* ---- tgSZ_To_Upper --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_To_Upper( PCU_TgCHAR pswzSrc, C_TgSIZE nuiSrc )
{
    TgWCSUPR( pswzSrc, nuiSrc + 1 );
    return (pswzSrc);
}


/* ---- tgSZ_To_Lower --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_To_Lower( PCU_TgCHAR pswzSrc, C_TgSIZE nuiSrc )
{
    TgWCSLWR( pswzSrc, nuiSrc + 1 );
    return (pswzSrc);
}


/* ---- tgSZ_Copy ------------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_Copy( PC_TgCHAR pswzDest, C_TgSIZE nuiDest, CPC_TgCHAR pswzSrc )
{
    TgERROR(0 != pswzDest && 0 < nuiDest && 0 != pswzSrc);

#if TgCOMPILE_STR_LENGTH_CHECK
    TgERROR_MSGF( tgSZ_Length( pswzSrc ) < nuiDest,
        TgT("%-16.16s(%-32.32s): Source length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_Copy") );
#endif

    /* Guarantees no possible overflow during execution */
    TgWCSNCPY( pswzDest, nuiDest, pswzSrc, nuiDest - 1 );
    pswzDest[nuiDest - 1] = 0;

    return (pswzDest);
}


/* ---- tgSZ_Append ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_Append( PC_TgCHAR pswzDest, C_TgSIZE nuiDest, CPC_TgCHAR pswzSrc )
{
    TgERROR(0 != pswzDest && 0 < nuiDest && 0 != pswzSrc);

#if TgCOMPILE_STR_LENGTH_CHECK
    TgERROR_MSGF( tgSZ_Length( pswzDest ) + tgSZ_Length( pswzSrc ) < nuiDest,
        TgT("%-16.16s(%-32.32s): Appended length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_Append") );
#endif

    TgWCSNCAT( pswzDest, nuiDest, pswzSrc, nuiDest - (tgSZ_Length( pswzDest ) + 1) );

    return (pswzDest);
}


/* ---- tgSZ_CopyN ------------------------------------------------------------------------------------------------------------------------------------------------------ */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_CopyN( PC_TgCHAR pswzDest, C_TgSIZE nuiDest, CPC_TgCHAR pswzSrc, C_TgSIZE nuiSrc )
{
    TgERROR(0 != pswzDest && 0 < nuiDest && 0 != pswzSrc);

#if TgCOMPILE_STR_LENGTH_CHECK
    TgERROR_MSGF( tgCM_MIN_UXX( nuiSrc, tgSZ_Length( pswzSrc ) ) < nuiDest,
        TgT("%-16.16s(%-32.32s): Source length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_CopyN") );
#endif

    /* Guarantees no possible overflow during execution */
    TgWCSNCPY( pswzDest, nuiDest, pswzSrc, tgCM_MIN_UXX( nuiSrc, nuiDest - 1 ) );
    pswzDest[tgCM_MIN_UXX( nuiSrc, nuiDest - 1 )] = 0;

    return (pswzDest);
}


/* ---- tgSZ_AppendN ---------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_AppendN( PC_TgCHAR pswzDest, C_TgSIZE nuiDest, CPC_TgCHAR pswzSrc, C_TgSIZE nuiSrc )
{
    TgERROR(0 != pswzDest && 0 < nuiDest && 0 != pswzSrc);

#if TgCOMPILE_STR_LENGTH_CHECK
    TgERROR_MSGF( tgSZ_Length( pswzDest ) + tgCM_MIN_UXX( nuiSrc, tgSZ_Length( pswzSrc ) ) < nuiDest,
        TgT("%-16.16s(%-32.32s): Appended length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_Append") );
#endif

    TgWCSNCAT( pswzDest, nuiDest, pswzSrc, tgCM_MIN_UXX( nuiSrc, nuiDest - (tgSZ_Length( pswzDest ) + 1) ) );

    return (pswzDest);
}


/* ---- tgSZ_PrintVF ---------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_PrintVF( PC_TgCHAR pswzDest, C_TgSIZE nuiDest, CPC_TgCHAR pswzSrc, va_list vaList )
{
    TgERROR(0 != pswzDest && 0 < nuiDest && 0 != pswzSrc);

#if defined(TgCOMPILE_SUPPORT_MSFT_SYSTEM_INCLUDE)
    if (0 > TgVSNWPRINTF( pswzDest, nuiDest, pswzSrc, vaList ))
    {
    #if TgCOMPILE_STR_LENGTH_CHECK
        TgERROR_MSGF( 0, TgT("%-16.16s(%-32.32s): Source length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_PrintVF") );
    #endif
    };
#else
#if !defined(TgCOMPILE_FORCE_ANSI) && TgCOMPILE_STR_LENGTH_CHECK
    {
        va_list                             vaTest;

        va_copy(vaTest, vaList);
        TgERROR_MSGF( tgSZ_Length( pswzDest ) + tgSZ_LengthVF( pswzSrc, vaTest ) < nuiDest,
                      TgT("%-16.16s(%-32.32s): Source length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_PrintVF") );
        va_end(vaTest);
    }
#endif

    TgVSNWPRINTF( pswzDest, nuiDest, pswzSrc, vaList );
#endif

    pswzDest[nuiDest - 1] = 0;
    return (pswzDest);
}


/* ---- tgSZ_AppendVF --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_AppendVF( PC_TgCHAR pswzDest, C_TgSIZE nuiDest, CPC_TgCHAR pswzSrc, va_list vaList )
{
    C_TgSIZE                            nuiLength = tgSZ_Length( pswzDest );

    TgERROR(0 != pswzDest && 0 < nuiDest && 0 != pswzSrc);

#if defined(TgCOMPILE_SUPPORT_MSFT_SYSTEM_INCLUDE)
    if (0 > TgVSNWPRINTF( pswzDest + nuiLength, nuiDest - nuiLength, pswzSrc, vaList ))
    {
    #if TgCOMPILE_STR_LENGTH_CHECK
        TgERROR_MSGF( 0, TgT("%-16.16s(%-32.32s): Appended length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_AppendVF") );
    #endif

        pswzDest[nuiDest - 1] = 0;
    };
#else
#if !defined(TgCOMPILE_FORCE_ANSI) && TgCOMPILE_STR_LENGTH_CHECK
    {
        va_list                             vaTest;
        
        va_copy(vaTest, vaList);
        TgERROR_MSGF( tgSZ_Length( pswzDest ) + tgSZ_LengthVF( pswzSrc, vaTest ) < nuiDest,
                     TgT("%-16.16s(%-32.32s): Source length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_PrintVF") );
        va_end(vaTest);
    }
#endif

    TgVSNWPRINTF( pswzDest + nuiLength, nuiDest - nuiLength, pswzSrc, vaList );
#endif

    return (pswzDest);
}


/* ---- tgSZ_Token ------------------------------------------------------------------------------------------------------------------------------------------------------ */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_Token( PC_TgCHAR pszDest, CPC_TgCHAR pszDelim, PP_TgCHAR pszContext )
{
    TgERROR(0 != pszDelim && 0 != pszContext);
#if defined(TgCOMPILE_SUPPORT_MSFT_SYSTEM_INCLUDE)
    return (wcstok_s( pszDest, pszDelim, pszContext ));
#else
    return (wcstok( pszDest, pszDelim, pszContext ));
#endif
}


/* ---- tgSZ_StrChr ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
CP_TgCHAR tgSZ_StrChr( CPC_TgCHAR pszSrc, C_TgCHAR pszSub )
{
    return (wcschr( pszSrc, pszSub ));
}


/* ---- tgSZ_StrStr ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
CP_TgCHAR tgSZ_StrStr( CPC_TgCHAR pszSrc, CPC_TgCHAR pszSub )
{
    return (wcsstr( pszSrc, pszSub ));
}


#else /* ---- ANSI CHARACTER -------------------------------------------------------------------------------------------------------------------------------------------- */

/* ---- tgSZ_From_U08 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_U08( PCU_TgCHAR pszDest, C_TgSIZE nuiDest, C_TgUINT08 uiValue )
{
    TgERROR(0 != pszDest && 0 < nuiDest);
    TgSNPRINTF( pszDest, nuiDest, "%u", uiValue );
    return (pszDest);
}


/* ---- tgSZ_From_U16 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_U16( PCU_TgCHAR pszDest, C_TgSIZE nuiDest, C_TgUINT16 uiValue )
{
    TgERROR(0 != pszDest && 0 < nuiDest);
    TgSNPRINTF( pszDest, nuiDest, "%hu", uiValue );
    return (pszDest);
}


/* ---- tgSZ_From_U32 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_U32( PCU_TgCHAR pszDest, C_TgSIZE nuiDest, C_TgUINT32 uiValue )
{
    TgERROR(0 != pszDest && 0 < nuiDest);
    TgSNPRINTF( pszDest, nuiDest, "%u", (unsigned int)uiValue );
    return (pszDest);
}


/* ---- tgSZ_From_U64 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_U64( PCU_TgCHAR pszDest, C_TgSIZE nuiDest, C_TgUINT64 uiValue )
{
    TgERROR(0 != pszDest && 0 < nuiDest);
    TgSNPRINTF( pszDest, nuiDest, "%llu", uiValue );
    return (pszDest);
}


/* ---- tgSZ_From_S08 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_S08( PCU_TgCHAR pszDest, C_TgSIZE nuiDest, C_TgSINT08 iValue )
{
    TgERROR(0 != pszDest && 0 < nuiDest);
    TgSNPRINTF( pszDest, nuiDest, "%d", iValue );
    return (pszDest);
}


/* ---- tgSZ_From_S16 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_S16( PCU_TgCHAR pszDest, C_TgSIZE nuiDest, C_TgSINT16 iValue )
{
    TgERROR(0 != pszDest && 0 < nuiDest);
    TgSNPRINTF( pszDest, nuiDest, "%hd", iValue );
    return (pszDest);
}


/* ---- tgSZ_From_S32 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_S32( PCU_TgCHAR pszDest, C_TgSIZE nuiDest, C_TgSINT32 iValue )
{
    TgERROR(0 != pszDest && 0 < nuiDest);
    TgSNPRINTF( pszDest, nuiDest, "%d", (int)iValue );
    return (pszDest);
}


/* ---- tgSZ_From_S64 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_S64( PCU_TgCHAR pszDest, C_TgSIZE nuiDest, C_TgSINT64 iValue )
{
    TgERROR(0 != pszDest && 0 < nuiDest);
    TgSNPRINTF( pszDest, nuiDest, "%lld", iValue );
    return (pszDest);
}


/* ---- tgSZ_From_F32 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_F32( PCU_TgCHAR pszDest, C_TgSIZE nuiDest, C_TgFLOAT32 fValue )
{
    TgERROR(0 != pszDest && 0 < nuiDest);
    TgSNPRINTF( pszDest, nuiDest, "%f", (TgFLOAT64)fValue );
    return (pszDest);
}


/* ---- tgSZ_From_F64 --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_From_F64( PCU_TgCHAR pszDest, C_TgSIZE nuiDest, C_TgFLOAT64 fValue )
{
    TgERROR(0 != pszDest && 0 < nuiDest);
    TgSNPRINTF( pszDest, nuiDest, "%f", fValue );
    return (pszDest);
}


/* ---- tgSZ_To_U32 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgUINT32 tgSZ_To_U32( CPCU_TgCHAR pszSrc )
{
    TgERROR(0 != pszSrc);
    return ((TgUINT32)strtoul( pszSrc, 0, 10 ));
}


/* ---- tgSZ_To_U64 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgUINT64 tgSZ_To_U64( CPCU_TgCHAR pszSrc )
{
    CP_TgCHAR                           pszData;
    TgUINT64                            uiRet;
    TgBOOL                              bNeg;

    TgERROR(0 != pszSrc);

    pszData = pszSrc;
    uiRet = 0;

    if (pszData[0] == TgTEXT( '-' ))
    {
        bNeg = TgTRUE;
        ++pszData;
    }
    else
    {
        bNeg = TgFALSE;
    };

    while (pszData[0])
    {
        if (pszData[0] < TgTEXT('0') || pszData[0] > TgTEXT('9'))
        {
            return (0);
        };
        if (uiRet > (KTgMAX_U64 / 10))
        {
            return (KTgMAX_U64);
        };
        uiRet *= 10;
        if (KTgMAX_U64 - uiRet < (TgUINT64)(pszData[0] - TgTEXT('0')))
        {
            return (KTgMAX_U64);
        };
        uiRet += (TgUINT64)(pszData[0] - TgTEXT('0'));
        ++pszData;
    };

    return (bNeg == TgTRUE ? KTgMAX_U64 - uiRet + 1 : uiRet);
}


/* ---- tgSZ_To_S32 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_To_S32( CPCU_TgCHAR pszSrc )
{
    TgERROR(0 != pszSrc);
    return ((TgSINT32)strtol( pszSrc, 0, 10 ));
}


/* ---- tgSZ_To_S64 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT64 tgSZ_To_S64( CPCU_TgCHAR pszSrc )
{
    CP_TgCHAR                           pszData;
    TgSINT64                            iRet;
    TgBOOL                              bNeg;

    TgERROR(0 != pszSrc);

    pszData = pszSrc;
    iRet = 0;

    if (pszData[0] == TgTEXT('-'))
    {
        bNeg = TgTRUE;
        ++pszData;
    }
    else
    {
        bNeg = TgFALSE;
    };

    while (pszData[0])
    {
        if (pszData[0] < TgTEXT('0') || pszData[0] > TgTEXT('9'))
        {
            return (0);
        };

        if (bNeg)
        {
            if (-iRet < (KTgMIN_S64 / 10))
            {
                return (KTgMIN_S64);
            };
        }
        else
        {
            if (iRet > (KTgMAX_S64 / 10))
            {
                return (KTgMAX_S64);
            };
        };

        iRet *= 10;

        if (bNeg)
        {
            if (KTgMIN_S64 + iRet > -(pszData[0] - TgTEXT( '0' )))
            {
                return (KTgMIN_S64);
            };
        }
        else
        {
            if (KTgMAX_S64 - iRet < (pszData[0] - TgTEXT( '0' )))
            {
                return (KTgMAX_S64);
            };
        };
        iRet += (pszData[0] - TgTEXT('0'));
        ++pszData;
    };

    return (bNeg == TgTRUE ? -iRet : iRet);
}


/* ---- tgSZ_To_F32 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgFLOAT32 tgSZ_To_F32( CPCU_TgCHAR pszSrc )
{
    TgERROR(0 != pszSrc);
    return ((TgFLOAT32)(strtod( pszSrc, 0 )));
}


/* ---- tgSZ_To_F64 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgFLOAT64 tgSZ_To_F64( CPCU_TgCHAR pszSrc )
{
    TgERROR(0 != pszSrc);
    return (strtod( pszSrc, 0 ));
}


/* ---- tgSZ_Length ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSIZE tgSZ_Length( CPCU_TgCHAR pszSrc )
{
    TgERROR(0 != pszSrc);
    return (strlen( pszSrc )); /* strlen doesn't count terminating '\0' */
}


/* ---- tgSZ_Compare ---------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_Compare( CPC_TgCHAR pszLeft, CPC_TgCHAR pszRight )
{
    TgERROR(0 != pszLeft && 0 != pszRight);
    return (strcmp( pszLeft, pszRight ));
}


/* ---- tgSZ_Compare_NoCase --------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_Compare_NoCase( CPC_TgCHAR pszLeft, CPC_TgCHAR pszRight )
{
    TgERROR(0 != pszLeft && 0 != pszRight);
#if defined(TgCOMPILE_SUPPORT_MSFT_SYSTEM_INCLUDE)
    return (_stricmp(pszLeft, pszRight));
#else
    return (strcasecmp(pszLeft, pszRight));
#endif
}


/* ---- tgSZ_CompareN --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_CompareN( CPC_TgCHAR pszLeft, CPC_TgCHAR pszRight, C_TgSIZE uiMax )
{
    TgERROR(0 != pszLeft && 0 != pszRight);
    return (strncmp( pszLeft, pszRight, uiMax ));
}


/* ---- tgSZ_CompareN_NoCase -------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_CompareN_NoCase( CPC_TgCHAR pszLeft, CPC_TgCHAR pszRight, C_TgSIZE uiMax )
{
    TgERROR(0 != pszLeft && 0 != pszRight);
#if defined(TgCOMPILE_SUPPORT_MSFT_SYSTEM_INCLUDE)
    return (_strnicmp(pszLeft, pszRight, uiMax));
#else
    return (strncasecmp( pszLeft, pszRight, uiMax ));
#endif
}


/* ---- tgSZ_LengthVF --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
CLANG_ATTRIBUTE(__format__ (__printf__, 1, 0))
TgSINT32 tgSZ_LengthVF( CPC_TgCHAR pszSrc, va_list vaList )
{
    TgERROR(0 != pszSrc);
#if defined(TgCOMPILE_SUPPORT_MSFT_SYSTEM_INCLUDE)
    return (_vscprintf( pszSrc, vaList )); /* _vscprintf doesn't count terminating '\0' */
#else
    return (vsnprintf( 0, 0, pszSrc, vaList ));
#endif
}


/* ---- tgCHAR_Is_Print ------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgBOOL tgCHAR_Is_Print( C_TgCHAR uiVal )
{
    return (0 != isprint( (unsigned char)uiVal ) ? TgTRUE : TgFALSE);
}


/* ---- tgCHAR_Is_Space ------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgBOOL tgCHAR_Is_Space( C_TgCHAR uiVal )
{
    return (0 != isspace( (unsigned char)uiVal ) ? TgTRUE : TgFALSE);
}


/* ---- tgCHAR_To_Upper ------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgCHAR tgCHAR_To_Upper( C_TgCHAR uiVal )
{
    return ((TgCHAR)toupper( uiVal ));
}


/* ---- tgCHAR_To_Lower ------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgCHAR tgCHAR_To_Lower( C_TgCHAR uiVal )
{
    return ((TgCHAR)tolower( uiVal ));
}


/* ---- tgSZ_To_Upper --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_To_Upper( PCU_TgCHAR pszSrc, C_TgSIZE nuiSrc )
{
#if defined(TgCOMPILE_PLATFORM_IPH) || defined(TgCOMPILE_PLATFORM_MAC)
    TgUINT32                            uiIndex;

    if (0 == pszSrc)
    {
        return (nullptr);
    };

    for (uiIndex = 0; *(pszSrc + uiIndex) != '\0' && uiIndex < nuiSrc; ++uiIndex)
    {
        *(pszSrc + uiIndex) = (TgCHAR)toupper( *(pszSrc + uiIndex) );
    };

    return (pszSrc);

#else
    TgSTRUPR( pszSrc, nuiSrc + 1 );
    return (pszSrc);
#endif
}


/* ---- tgSZ_To_Lower --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_To_Lower( PCU_TgCHAR pszSrc, C_TgSIZE nuiSrc )
{
#if defined(TgCOMPILE_PLATFORM_IPH) || defined(TgCOMPILE_PLATFORM_MAC)
    TgUINT32                            uiIndex;

    if (0 == pszSrc)
    {
        return (nullptr);
    };

    for (uiIndex = 0; *(pszSrc + uiIndex) != '\0' && uiIndex < nuiSrc; ++uiIndex)
    {
        *(pszSrc + uiIndex) = (TgCHAR)tolower( *(pszSrc + uiIndex) );
    };

    return (pszSrc);

#else
    TgSTRLWR( pszSrc, nuiSrc + 1 );
    return (pszSrc);
#endif
}


/* ---- tgSZ_Copy ------------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_Copy( PC_TgCHAR pszDest, C_TgSIZE nuiDest, CPC_TgCHAR pszSrc )
{
    TgERROR(0 != pszDest && 0 < nuiDest && 0 != pszSrc);

#if TgCOMPILE_STR_LENGTH_CHECK
    TgERROR_MSGF( tgSZ_Length( pszSrc ) < nuiDest, TgT("%-16.16s(%-32.32s): Source length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_Copy") );
#endif

    /* Guarantees no possible overflow during execution */
    TgSTRNCPY( pszDest, nuiDest, pszSrc, nuiDest - 1 );
    pszDest[nuiDest - 1] = 0;

    return (pszDest);
}


/* ---- tgSZ_Append ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_Append( PC_TgCHAR pszDest, C_TgSIZE nuiDest, CPC_TgCHAR pszSrc )
{
    TgERROR(0 != pszDest && 0 < nuiDest && 0 != pszSrc);

#if TgCOMPILE_STR_LENGTH_CHECK
    TgERROR_MSGF( tgSZ_Length( pszDest ) + tgSZ_Length( pszSrc ) < nuiDest,
        TgT("%-16.16s(%-32.32s): Appended length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_Append") );
#endif

    TgSTRNCAT( pszDest, nuiDest, pszSrc, nuiDest - (tgSZ_Length( pszDest ) + 1) );

    return (pszDest);
}


/* ---- tgSZ_CopyN ------------------------------------------------------------------------------------------------------------------------------------------------------ */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_CopyN( PC_TgCHAR pszDest, C_TgSIZE nuiDest, CPC_TgCHAR pszSrc, C_TgSIZE nuiSrc )
{
    TgERROR(0 != pszDest && 0 < nuiDest && 0 != pszSrc);

#if TgCOMPILE_STR_LENGTH_CHECK
    TgERROR_MSGF( tgCM_MIN_UXX( nuiSrc, tgSZ_Length( pszSrc ) ) < nuiDest,
        TgT("%-16.16s(%-32.32s): Source length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_CopyN") );
#endif

    /* Guarantees no possible overflow during execution */
    TgSTRNCPY( pszDest, nuiDest, pszSrc, tgCM_MIN_UXX( nuiSrc, nuiDest - 1 ) );
    pszDest[tgCM_MIN_UXX( nuiSrc, nuiDest - 1 )] = 0;

    return (pszDest);
}


/* ---- tgSZ_AppendN ---------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_AppendN( PC_TgCHAR pszDest, C_TgSIZE nuiDest, CPC_TgCHAR pszSrc, C_TgSIZE nuiSrc )
{
    TgERROR(0 != pszDest && 0 < nuiDest && 0 != pszSrc);

#if TgCOMPILE_STR_LENGTH_CHECK
    TgERROR_MSGF( tgSZ_Length( pszDest ) + tgCM_MIN_UXX( nuiSrc, tgSZ_Length( pszSrc ) ) < nuiDest,
        TgT("%-16.16s(%-32.32s): Appended length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_Append") );
#endif

    TgSTRNCAT( pszDest, nuiDest, pszSrc, tgCM_MIN_UXX( nuiSrc, nuiDest - (tgSZ_Length( pszDest ) + 1) ) );

    return (pszDest);
}


/* ---- tgSZ_PrintVF ---------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
CLANG_ATTRIBUTE(__format__ (__printf__, 3, 0))
P_TgCHAR tgSZ_PrintVF( PC_TgCHAR pszDest, C_TgSIZE nuiDest, CPC_TgCHAR pszSrc, va_list vaList )
{
    TgERROR(0 != pszDest && 0 < nuiDest && 0 != pszSrc);

    if (0 > TgVSNPRINTF( pszDest, nuiDest, pszSrc, vaList ))
    {
    #if TgCOMPILE_STR_LENGTH_CHECK
        TgERROR_MSGF( 0, TgT("%-16.16s(%-32.32s): Source length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_PrintVF") );
    #endif

        pszDest[0] = 0;
    };

    return (pszDest);
}


/* ---- tgSZ_AppendVF --------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
CLANG_ATTRIBUTE(__format__ (__printf__, 3, 0))
P_TgCHAR tgSZ_AppendVF( PC_TgCHAR pszDest, C_TgSIZE nuiDest, CPC_TgCHAR pszSrc, va_list vaList )
{
    C_TgSIZE                            nuiLength = tgSZ_Length( pszDest );

    TgERROR(0 != pszDest && 0 < nuiDest && 0 != pszSrc);

#if defined(TgCOMPILE_SUPPORT_MSFT_SYSTEM_INCLUDE)
    if (0 > TgVSNPRINTF( pszDest + nuiLength, nuiDest - nuiLength, pszSrc, vaList ))
    {
    #if TgCOMPILE_STR_LENGTH_CHECK
        TgERROR_MSGF( 0, TgT("%-16.16s(%-32.32s): Appended length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_AppendVF") );
    #endif

        pszDest[nuiDest - 1] = 0;
    };
#else
#if !defined(TgCOMPILE_FORCE_ANSI) && TgCOMPILE_STR_LENGTH_CHECK
    {
        va_list                             vaTest;
        
        va_copy(vaTest, vaList);
        TgERROR_MSGF( tgSZ_Length( pszDest ) + tgSZ_LengthVF( pszSrc, vaTest ) < nuiDest,
                     TgT("%-16.16s(%-32.32s): Source length is greater than destination size.\n"), TgT("Base"), TgT("tgSZ_PrintVF") );
        va_end(vaTest);
    }
#endif

    TgVSNPRINTF( pszDest + nuiLength, nuiDest - nuiLength, pszSrc, vaList );
#endif

    return (pszDest);
}


/* ---- tgSZ_Token ------------------------------------------------------------------------------------------------------------------------------------------------------ */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_Token( PC_TgCHAR pszDest, CPC_TgCHAR pszDelim, PP_TgCHAR pszContext )
{
    TgERROR(0 != pszDelim && 0 != pszContext);
#if defined(TgCOMPILE_SUPPORT_MSFT_SYSTEM_INCLUDE)
    return (strtok_s( pszDest, pszDelim, pszContext ));
#else
    return (strtok_r( pszDest, pszDelim, pszContext ));
#endif
}


/* ---- tgSZ_StrChr ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
CP_TgCHAR tgSZ_StrChr( CPC_TgCHAR pszSrc, C_TgCHAR iVal )
{
    return (strchr( pszSrc, iVal ));
}


/* ---- tgSZ_StrStr ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
CP_TgCHAR tgSZ_StrStr( CPC_TgCHAR pszSrc, CPC_TgCHAR pszSub )
{
    return (strstr( pszSrc, pszSub ));
}


#endif /* ---- ANSI CHARACTER ------------------------------------------------------------------------------------------------------------------------------------------- */


/* ---- tgSZ_With_Grouping_From_U32 ------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_With_Grouping_From_U32( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgUINT32 uiValue )
{
    TgCHAR                              szTemp[32];

    if (nullptr == tgSZ_From_U32( szTemp, 32, uiValue ))
        return nullptr;
    return (tgSZ_With_Grouping_From_SZ( pswzDest, nuiDest, szTemp ));
}


/* ---- tgSZ_With_Grouping_From_U64 ------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_With_Grouping_From_U64( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgUINT64 uiValue )
{
    TgCHAR                              szTemp[64];

    if (nullptr == tgSZ_From_U64( szTemp, 64, uiValue ))
        return nullptr;
    return (tgSZ_With_Grouping_From_SZ( pswzDest, nuiDest, szTemp ));
}


/* ---- tgSZ_With_Grouping_From_S32 ------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_With_Grouping_From_S32( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgSINT32 iValue )
{
    TgCHAR                              szTemp[32];

    if (nullptr == tgSZ_From_S32( szTemp, 32, iValue ))
        return nullptr;
    return (tgSZ_With_Grouping_From_SZ( pswzDest, nuiDest, szTemp ));
}


/* ---- tgSZ_With_Grouping_From_S64 ------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
P_TgCHAR tgSZ_With_Grouping_From_S64( PCU_TgCHAR pswzDest, C_TgSIZE nuiDest, C_TgSINT64 iValue )
{
    TgCHAR                              szTemp[64];

    if (nullptr == tgSZ_From_S64( szTemp, 64, iValue ))
        return nullptr;
    return (tgSZ_With_Grouping_From_SZ( pswzDest, nuiDest, szTemp ));
}


/* ---- tgSZ_To_Bool ---------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgBOOL tgSZ_To_Bool( CPCU_TgCHAR pswzSrc )
{
    if (0 != pswzSrc[1])
    {
        return (0 == tgSZ_Compare_NoCase( pswzSrc, TgT("true") ) ? TgTRUE : TgFALSE);
    }
    else
    {
        return (1 == tgSZ_To_U32( pswzSrc ) ? TgTRUE : TgFALSE);
    };
}


/* ---- tgSZ_To_U08 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgUINT08 tgSZ_To_U08( CPCU_TgCHAR pswzSrc )
{
    return ((TgUINT08)tgCM_MIN_U32( KTgMAX_U08, tgSZ_To_U32( pswzSrc ) ));
}


/* ---- tgSZ_To_U16 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgUINT16 tgSZ_To_U16( CPCU_TgCHAR pswzSrc )
{
    return ((TgUINT16)tgCM_MIN_U32( KTgMAX_U16, tgSZ_To_U32( pswzSrc ) ));
}


/* ---- tgSZ_To_S08 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT08 tgSZ_To_S08( CPCU_TgCHAR pswzSrc )
{
    return ((TgSINT08)tgCM_CLP_S32( tgSZ_To_S32( pswzSrc ), KTgMIN_S08, KTgMAX_S08 ));
}


/* ---- tgSZ_To_S16 ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT16 tgSZ_To_S16( CPCU_TgCHAR pswzSrc )
{
    return ((TgSINT16)tgCM_CLP_S32( tgSZ_To_S32( pswzSrc ), KTgMIN_S16, KTgMAX_S16 ));
}


/* ---- tgSZ_Hash ------------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgUINTXX tgSZ_Hash( CPCU_TgCHAR pswzSrc )
{
    TgUINTXX                            uiHash = 5381;
    TgUINTXX                            uiIndex;

    TgERROR(0 != pswzSrc);

    for (uiIndex = 0; 0 != pswzSrc[uiIndex]; ++uiIndex)
    {
        uiHash = ((uiHash << 5) + uiHash) + (TgUINTXX)pswzSrc[uiIndex]; /* DJB */
    }

    TgERROR(0 == pswzSrc[0] || KTgEMPTY_HASH != uiHash);

    return uiHash;
}


/* ---- tgSZ_Hash_File_Name --------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgUINTXX tgSZ_Hash_File_Name( CPCU_TgCHAR pszDest )
{
    C_TgUINTXX                          nuiDest = tgSZ_Length( pszDest );
    TgUINTXX                            uiHash = KTgEMPTY_HASH;
    TgUINTXX                            uiIndex;
    TgUINTXX                            uiHashIndex;

    TgERROR(0 != pszDest);

    for (uiIndex = nuiDest; uiIndex > 0 && TgCHAR_PATH_SEPERATOR != pszDest[uiIndex - 1]; --uiIndex);

    for (uiHashIndex = uiIndex; uiHashIndex < nuiDest; ++uiHashIndex)
    {
        uiHash = ((uiHash << 5) + uiHash) + (TgUINTXX)pszDest[uiHashIndex]; /* DJB */
    }

    return (uiHash);
}


/* ---- tgSZ_Hash_Directory --------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgUINTXX tgSZ_Hash_Directory( CPCU_TgCHAR pszDest )
{
    C_TgUINTXX                          nuiDest = tgSZ_Length( pszDest );
    TgUINTXX                            uiHash = KTgEMPTY_HASH;
    TgUINTXX                            uiIndex;
    TgUINTXX                            uiHashIndex;

    TgERROR(0 != pszDest);

    for (uiIndex = nuiDest; uiIndex > 0 && TgCHAR_PATH_SEPERATOR != pszDest[uiIndex - 1]; --uiIndex);

    for (uiHashIndex = 0; uiHashIndex < uiIndex; ++uiHashIndex)
    {
        uiHash = ((uiHash << 5) + uiHash) + (TgUINTXX)pszDest[uiHashIndex]; /* DJB */
    }

    return (uiHash);
}


/* ---- tgSZ_CompareEnd ------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_CompareEnd( CPC_TgCHAR pswzLeft, CPC_TgCHAR pswzRight )
{
    TgUINTXX                            nuiLeft, nuiRight, nuiMin;

    TgERROR(0 != pswzLeft && 0 != pswzRight);
    nuiLeft = tgSZ_Length( pswzLeft );
    nuiRight = tgSZ_Length( pswzRight );
    nuiMin = tgCM_MIN_UXX( nuiLeft, nuiRight );

    return (tgSZ_Compare( pswzLeft + nuiLeft - nuiMin, pswzRight + nuiRight - nuiMin ));
}


/* ---- tgSZ_CompareEnd_NoCase ------------------------------------------------------------------------------------------------------------------------------------------ */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_CompareEnd_NoCase( CPC_TgCHAR pswzLeft, CPC_TgCHAR pswzRight )
{
    TgUINTXX                            nuiLeft, nuiRight, nuiMin;

    TgERROR(0 != pswzLeft && 0 != pswzRight);
    nuiLeft = tgSZ_Length( pswzLeft );
    nuiRight = tgSZ_Length( pswzRight );
    nuiMin = tgCM_MIN_UXX( nuiLeft, nuiRight );

    return (tgSZ_Compare_NoCase( pswzLeft + nuiLeft - nuiMin, pswzRight + nuiRight - nuiMin ));
}


/* ---- tgSZ_PrintF ----------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
CLANG_ATTRIBUTE(__format__ (__printf__, 3, 0))
P_TgCHAR tgSZ_PrintF( PC_TgCHAR pswzDest, C_TgSIZE uiLength, CPC_TgCHAR pswzSrc, ... )
{
    va_list                             vaList;

    va_start( vaList, pswzSrc );
    tgSZ_PrintVF( pswzDest, uiLength, pswzSrc, vaList );
    va_end( vaList );

    return (pswzDest);
}


/* ---- tgSZ_AppendF ---------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
CLANG_ATTRIBUTE(__format__ (__printf__, 3, 0))
P_TgCHAR tgSZ_AppendF( PC_TgCHAR pswzDest, C_TgSIZE uiLength, CPC_TgCHAR pswzSrc, ... )
{
    va_list                             vaList;

    va_start( vaList, pswzSrc );
    tgSZ_AppendVF( pswzDest, uiLength, pswzSrc, vaList );
    va_end( vaList );

    return (pswzDest);
}


/* ---- tgSZ_Token_List ------------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgSINT32 tgSZ_Token_List( PC_TgCHAR pszSrc, PP_TgCHAR apTokenList, C_TgSINT32 niToken )
{
    P_TgCHAR                            pszNext;
    TgSINT32                            iToken;

    TgERROR(nullptr != apTokenList);
    TgERROR(niToken > 0);

    apTokenList[0] = tgSZ_Read_String_With_Comments_Quotes( &pszNext, pszSrc, TgTRUE );
    for (iToken = 1; iToken < niToken; ++iToken)
    {
        apTokenList[iToken] = tgSZ_Read_String_With_Comments_Quotes( &pszNext, nullptr, TgTRUE );
        if (!apTokenList[iToken])
            break;
    }

    return (iToken);
}


/* ---- tgSZ_AnsiToWideChar --------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
#if !defined(TgCOMPILE_FORCE_ANSI) && defined(TgCOMPILE_PLATFORM_WIN)
TgBOOL tgSZ_AnsiToWideChar( PC_TgWIDECHAR pswzDest, C_TgSIZE nuiDest, CPC_TgANSICHAR pszSrc, C_TgSIZE nuiSrc )
{
     size_t                              uiReturnValue;

    mbstowcs_s( &uiReturnValue, pswzDest, nuiDest, pszSrc, nuiSrc );
    return (nuiSrc == uiReturnValue ? TgTRUE : TgFALSE);
}
/*# !defined(TgCOMPILE_FORCE_ANSI) && defined(TgCOMPILE_PLATFORM_WIN) */
#endif


/* ---- tgSZ_AnsiToAnsiChar --------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
#if !defined(TgCOMPILE_FORCE_ANSI) && defined(TgCOMPILE_PLATFORM_WIN)
TgBOOL tgSZ_AnsiToAnsiChar( PC_TgANSICHAR pszDest, C_TgSIZE nuiDest, CPC_TgANSICHAR pszSrc, C_TgSIZE nuiSrc )
{
    TgMEMCPY( pszDest, nuiDest, pszSrc, nuiSrc );
    return (TgTRUE);
}
/*# !defined(TgCOMPILE_FORCE_ANSI) && defined(TgCOMPILE_PLATFORM_WIN) */
#endif


/* ---- tgSZ_WideToWideChar --------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
#if !defined(TgCOMPILE_FORCE_ANSI) && defined(TgCOMPILE_PLATFORM_WIN)
TgBOOL tgSZ_WideToWideChar( PC_TgWIDECHAR pswzDest, C_TgSIZE nuiDest, CPC_TgWIDECHAR pswzSrc, C_TgSIZE nuiSrc )
{
    TgMEMCPY( pswzDest, nuiDest, pswzSrc, nuiSrc );
    return (TgTRUE);
}
/*# !defined(TgCOMPILE_FORCE_ANSI) && defined(TgCOMPILE_PLATFORM_WIN) */
#endif


/* ---- tgSZ_WideToAnsiChar --------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
#if !defined(TgCOMPILE_FORCE_ANSI) && defined(TgCOMPILE_PLATFORM_WIN)
TgBOOL tgSZ_WideToAnsiChar( PC_TgANSICHAR pszDest, C_TgSIZE nuiDest, CPC_TgWIDECHAR pszSrc, C_TgSIZE nuiSrc )
{
    size_t                              uiReturnValue;

    wcstombs_s( &uiReturnValue, pszDest, nuiDest, pszSrc, nuiSrc );
    return (nuiSrc == uiReturnValue ? TgTRUE : TgFALSE);
}
/*# !defined(TgCOMPILE_FORCE_ANSI) && defined(TgCOMPILE_PLATFORM_WIN) */
#endif




/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
/*  Private Functions                                                                                                                                                     */
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */

/* ---- tgCM_Random_MT_Reload ------------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgVOID tgCM_Random_MT_Reload( TgVOID )
{
    TgUINT32                            uiIndex, uiSeed;

    if (KTgMERSENNE_TWISTER_PERIOD_N + 1 == tls_uiMT_Index)
    {
        tgCM_Init_Random_MT( 4357UL );
    };

    for (uiIndex = 0; uiIndex < KTgMERSENNE_TWISTER_PERIOD_NM; ++uiIndex)
    {
        uiSeed = (tls_uiMT_State.m_uiData[uiIndex] & KTgMERSENNE_TWISTER_UPPER_MASK);
        uiSeed |= (tls_uiMT_State.m_uiData[uiIndex + 1] & KTgMERSENNE_TWISTER_LOWER_MASK);
        tls_uiMT_State.m_uiData[uiIndex] = tls_uiMT_State.m_uiData[uiIndex + KTgMERSENNE_TWISTER_PERIOD_M] ^ (uiSeed >> 1);
        tls_uiMT_State.m_uiData[uiIndex] ^= s_uiMT_Magic[uiSeed & 0x1UL];
    };

    for (; uiIndex < KTgMERSENNE_TWISTER_PERIOD_N - 1; ++uiIndex)
    {
        uiSeed = (tls_uiMT_State.m_uiData[uiIndex] & KTgMERSENNE_TWISTER_UPPER_MASK);
        uiSeed |= (tls_uiMT_State.m_uiData[uiIndex + 1] & KTgMERSENNE_TWISTER_LOWER_MASK);
        tls_uiMT_State.m_uiData[uiIndex] = tls_uiMT_State.m_uiData[uiIndex - KTgMERSENNE_TWISTER_PERIOD_NM] ^ (uiSeed >> 1);
        tls_uiMT_State.m_uiData[uiIndex] ^= s_uiMT_Magic[uiSeed & 0x1UL];
    };

    uiSeed = (tls_uiMT_State.m_uiData[KTgMERSENNE_TWISTER_PERIOD_N - 1] & KTgMERSENNE_TWISTER_UPPER_MASK);
    uiSeed |= (tls_uiMT_State.m_uiData[0] & KTgMERSENNE_TWISTER_LOWER_MASK);
    tls_uiMT_State.m_uiData[KTgMERSENNE_TWISTER_PERIOD_N - 1] =
        tls_uiMT_State.m_uiData[KTgMERSENNE_TWISTER_PERIOD_M - 1] ^ (uiSeed >> 1);
    tls_uiMT_State.m_uiData[KTgMERSENNE_TWISTER_PERIOD_N - 1] ^= s_uiMT_Magic[uiSeed & 0x1UL];

    tls_uiMT_Index = 0;
}




/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
/*  File Local Functions */
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */

/* ---- tgSZ_With_Grouping_From_SZ -------------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
static P_TgCHAR tgSZ_With_Grouping_From_SZ( PU_TgCHAR pszDest, C_TgSIZE nuiDest, CPU_TgCHAR pszSrc )
{
    TgUINTXX                            nuiSrc;
    TgUINTXX                            uiSrc;
    TgUINTXX                            uiDest;

    TgERROR(0 != pszDest && 0 < nuiDest);

    nuiSrc = tgSZ_Length( pszSrc );
    uiSrc = 0;
    uiDest = 0;

    if (pszSrc[uiSrc] == TgT('-'))
    {
        --nuiSrc;
        pszDest[uiDest++] = pszSrc[uiSrc++];
    }

    if (nuiDest < (nuiSrc + nuiSrc / 3))
        return nullptr;

    switch (nuiSrc % 3)
    {
        default:
            while (uiSrc < nuiSrc)
            {
                pszDest[uiDest++] = TgT(',');
        case 0: pszDest[uiDest++] = pszSrc[uiSrc++];
        case 2: pszDest[uiDest++] = pszSrc[uiSrc++];
        case 1: pszDest[uiDest++] = pszSrc[uiSrc++];
            }
    } /* Duff's Algorithm */

    pszDest[uiDest++] = pszSrc[uiSrc++];
    return (pszDest);
}


/* ---- tgSZ_Read_String_With_Comments_Quotes --------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
CLANG_WARN_DISABLE_PUSH(cast-qual)
static P_TgCHAR tgSZ_Read_String_With_Comments_Quotes( PP_TgCHAR ppszNextOut, PC_TgCHAR pszSrc, C_TgBOOL bIgnoreComments )
{
    P_TgCHAR                            pszStart;
    P_TgCHAR                            pszNext;

    TgERROR(nullptr != ppszNextOut);

    pszStart = nullptr == pszSrc ? *ppszNextOut : pszSrc;
    if (nullptr == pszStart || !pszStart[0])
    {
        *ppszNextOut = nullptr;
        return (nullptr);
    }

    for (; tgCHAR_Is_Space( pszStart[0] ); ++pszStart);
    if (!pszStart[0])
    {
        *ppszNextOut = nullptr;
        return (nullptr);
    }

    pszNext = pszStart;
    while (!bIgnoreComments && pszNext[0] == TgT('/'))
    {
        if (pszNext[1] == TgT('*'))
        {
            pszNext = (P_TgCHAR)tgSZ_StrStr( pszNext, TgT("*/") );
            if (!pszNext) /* Parse Error - Unpaired comment markers */
            {
                *ppszNextOut = nullptr;
                return (nullptr);
            }
            pszNext += 2;
        }
        else if (pszNext[1] == TgT('/'))
        {
            pszNext = (P_TgCHAR)tgSZ_StrChr( pszNext, TgT('\n') );
            if (!pszNext)
            {
                *ppszNextOut = nullptr;
                return (nullptr);
            }
            ++pszNext;
        }
        else
        {
            break;
        }

        for (; tgCHAR_Is_Space( pszNext[0] ); ++pszNext);
        if (!pszNext[0])
        {
            *ppszNextOut = nullptr;
            return (nullptr);
        }
    }

    while (pszNext[0] && !tgCHAR_Is_Space( pszNext[0] ))
    {
        if (pszNext[0] == TgT('\"'))
        {
            pszNext = (P_TgCHAR)tgSZ_StrChr( ++pszNext, TgT('\"') );
            if (!pszNext) /* Parse Error - Unpaired quotation */
            {
                *ppszNextOut = nullptr;
                return (pszStart);
            }
        }
        ++pszNext;
    }

    if (pszNext[0])
    {
        pszNext[0] = 0;
        *ppszNextOut = pszNext + 1;
    }
    else
    {
        *ppszNextOut = nullptr;
    }

    return (pszStart);
}
CLANG_WARN_DISABLE_POP(cast-qual)