Ignore:
Timestamp:
Oct 28, 2014, 12:30:20 PM (11 years ago)
Author:
Alex Taylor
Message:

Implemented Sys2FormatNumber() function.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • rxutilex/trunk/rxutilex.c

    r20 r21  
    8383#define US_PIDSTR_MAXZ        ( CCHMAXPATH + 100 )                   // ...of a process information string
    8484#define US_TIMESTR_MAXZ         256                                  // ...of a formatted time string
     85#define US_NUMSTR_MAXZ          256                                  // ...of a formatted number string
    8586#define US_PIPESTATUS_MAXZ      128                                  // ...of a pipe status string
    8687
     
    103104    "Sys2QueryForegroundProcess",
    104105    "Sys2QueryPhysicalMemory",
     106    "Sys2FormatNumber",
    105107    "Sys2FormatTime",
    106108    "Sys2GetEpochTime",
     
    127129RexxFunctionHandler Sys2Version;
    128130
     131RexxFunctionHandler Sys2FormatNumber;
    129132RexxFunctionHandler Sys2FormatTime;
    130133RexxFunctionHandler Sys2GetEpochTime;
     
    903906
    904907/* ------------------------------------------------------------------------- *
     908 * Sys2FormatNumber                                                          *
     909 *                                                                           *
     910 * Format a number using locale-specific thousands separators.  The input    *
     911 * number may be a positive or negative integer or floating point value.  It *
     912 * must not contain any separators already, and any decimal point which it   *
     913 * contains must be a period (rather than any localized decimal symbol).     *
     914 *                                                                           *
     915 * REXX ARGUMENTS:                                                           *
     916 *   1. Number to be formatted.                                  (REQUIRED)  *
     917 *   2. Number of decimal places to use for floating point values.  Ignored  *
     918 *      for integer values.  Defaults to 2 if not specified.                 *
     919 *                                                                           *
     920 * REXX RETURN VALUE: The formatted number, or '' on error.                  *
     921 * ------------------------------------------------------------------------- */
     922ULONG APIENTRY Sys2FormatNumber( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
     923{
     924    CHAR  achNumber[ US_NUMSTR_MAXZ ];  // Formatted output string
     925    PSZ    pszTZ,                       // Pointer to TZ environment var
     926           pszSetTZ;
     927    float fVal;
     928    int   iVal;
     929    int   iPrec;
     930
     931    // Make sure we have at least one valid argument (the input number)
     932    if ( argc < 1  || ( !RXVALIDSTRING(argv[0]) )) return ( 40 );
     933
     934
     935    /* These next 4 lines really shouldn't be necessary, but without them
     936     * getenv() and (apparently) tzset() may see the value of TZ as NULL
     937     * if the environment variable was changed in the REXX script.
     938     */
     939    DosScanEnv("TZ", &pszTZ );
     940    pszSetTZ = (PSZ) malloc( strlen( pszTZ ) + 5 );
     941    if ( pszSetTZ ) {
     942        sprintf( pszSetTZ, "TZ=%s", pszTZ );
     943        putenv( pszSetTZ );
     944    }
     945
     946    // Use the locale and timezone settings from the environment
     947    tzset();
     948    setlocale( LC_ALL, "");
     949
     950    // Check for a decimal place and treat as float or integer accordingly
     951    if ( strchr( argv[0].strptr, '.') != NULL ) {
     952        if (( sscanf( argv[0].strptr, "%f", &fVal )) != 1 ) return ( 40 );
     953        if ( argc >= 2  && ( RXVALIDSTRING(argv[1]) ) &&
     954             (( sscanf( argv[1].strptr, "%d", &iPrec )) == 1 ))
     955        {
     956            // Use user-specified precision
     957            sprintf( achNumber, "%'.*f", iPrec, fVal );
     958        }
     959        else
     960            sprintf( achNumber, "%'.2f", fVal );
     961    }
     962    else {
     963        if (( sscanf( argv[0].strptr, "%d", &iVal )) != 1 ) return ( 40 );
     964        sprintf( achNumber, "%'d", iVal );
     965    }
     966
     967    // Return the formatted number
     968    MAKERXSTRING( *prsResult, achNumber, strlen( achNumber ));
     969
     970    if ( pszSetTZ ) free( pszSetTZ );
     971    return ( 0 );
     972}
     973
     974
     975/* ------------------------------------------------------------------------- *
    905976 * Sys2FormatTime                                                            *
    906977 *                                                                           *
     
    9791050    DosScanEnv("TZ", &pszTZ );
    9801051    pszSetTZ = (PSZ) malloc( strlen( pszTZ ) + 5 );
    981     sprintf( pszSetTZ, "TZ=%s", pszTZ );
    982     putenv( pszSetTZ );
     1052    if ( pszSetTZ ) {
     1053        sprintf( pszSetTZ, "TZ=%s", pszTZ );
     1054        putenv( pszSetTZ );
     1055    }
    9831056
    9841057    // Use the locale and timezone settings from the environment
     
    9911064            WriteErrorCode( ttSeconds, "time");
    9921065            MAKERXSTRING( *prsResult, "", 0 );
     1066            if ( pszSetTZ ) free( pszSetTZ );
    9931067            return 0;
    9941068        }
     
    10001074            WriteErrorCode( 1, "gmtime");
    10011075            MAKERXSTRING( *prsResult, "0", 1 );
     1076            if ( pszSetTZ ) free( pszSetTZ );
    10021077            return 0;
    10031078        }
     
    10081083            WriteErrorCode( 1, "localtime");
    10091084            MAKERXSTRING( *prsResult, "0", 1 );
     1085            if ( pszSetTZ ) free( pszSetTZ );
    10101086            return 0;
    10111087        }
     
    10321108        WriteErrorCode( stRC, "strftime");
    10331109        MAKERXSTRING( *prsResult, "", 0 );
     1110        if ( pszSetTZ ) free( pszSetTZ );
    10341111        return ( 0 );
    10351112    }
     
    10381115    MAKERXSTRING( *prsResult, szTime, strlen(szTime) );
    10391116
    1040     free( pszSetTZ );
     1117    if ( pszSetTZ ) free( pszSetTZ );
    10411118    return ( 0 );
    10421119}
Note: See TracChangeset for help on using the changeset viewer.