Changeset 21


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

Implemented Sys2FormatNumber() function.

Location:
rxutilex/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • rxutilex/trunk/FUNCTIONS

    r20 r21  
    99Sys2DisconnectNamedPipe     - Acknowledge that a named pipe session has ended
    1010Sys2DropFuncs               - Deregister all functions
     11Sys2FormatNumber            - Format a number with thousands-grouping characters
    1112Sys2FormatTime              - Format calender time (strftime wrapper)
    1213Sys2GetClipboardText        - Retrieve the current clipboard text
     
    146147REXX ARGUMENTS:    None
    147148REXX RETURN VALUE: ""
     149
     150
     151-------------------------------------------------------------------------
     152Sys2FormatNumber                                                         
     153                                                                         
     154Formats a number to use thousands-grouping characters.  The system values
     155for the current locale are used for the thousands-grouping character and
     156the decimal place, if any.  Note that the IBM C runtime's built-in locale
     157definitions are used; these may not correspond precisely to the system
     158locales as defined in the OS/2 Locale object.
     159
     160The input number may be a positive or negative integer or floating point
     161value.  It must be a simple, non-localized number value; in other words,
     162it must not contain any thousands-grouping characters, and any decimal
     163point which it contains must be a period (rather than any localized
     164decimal symbol).
     165                                                                         
     166REXX ARGUMENTS:                                                         
     167  1. Number to be formatted.                                  (REQUIRED)
     168  2. Number of decimal places to use for floating point values. 
     169     Ignored for integer values.                            (DEFAULT: 2)
     170                                                                         
     171REXX RETURN VALUE: The formatted number, or '' on error.                 
    148172
    149173
  • rxutilex/trunk/TODO

    r17 r21  
    22
    33 * Sys2ReplaceModule - A wrapper for DosReplaceModule()
    4  * Named pipe management functions
    5  * Open/Close/Seek/Read/Write functions with large file support
    64 - Sys2TokenizeString - A string tokenizer
    7  - Sys2FormatNumber - Format a number according to locale
    85 - Sys2FormatCurrency - A strfmon wrapper
    96 - Sys2GetResource - DosGetResource wrapper
     
    2623 ? Query/extract an object's icon   <-- exists in RWS?
    2724
    28 * = Implemented, needs testing
     25* = Implemented, needs more testing
    2926? = Suggestion only
    3027
  • 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}
  • rxutilex/trunk/rxutilex.def

    r20 r21  
    11LIBRARY     RXUTILEX INITINSTANCE TERMINSTANCE
    22DATA        MULTIPLE NONSHARED
    3 DESCRIPTION '@#Alex Taylor:0.1.0#@##1## 7 Oct 2014 22:42:18      REINFORCE::::::@@Extra REXX Utility Functions'
     3DESCRIPTION '@#Alex Taylor:0.1.0#@##1## 28 Oct 2014 20:00:26     REINFORCE::::::@@Extended REXX Utility Functions'
    44
    55EXPORTS     Sys2LoadFuncs
    66Sys2DropFuncs
    77Sys2Version
     8Sys2FormatNumber
    89Sys2FormatTime
    910Sys2GetEpochTime
  • rxutilex/trunk/testlib.cmd

    r20 r21  
    3333say 'Current local time is "'Sys2FormatTime(et, 'l')'"'
    3434say 'Current  UTC  time is "'Sys2FormatTime(et, 'l', 'u')'"'
    35 
    3635say
    3736
    3837say Sys2LocateDLL('ehxdlmri')
    3938
     39say Sys2FormatNumber('100')
     40say Sys2FormatNumber('10000')
     41say Sys2FormatNumber('5003.543', 1)
     42
    4043call Sys2DropFuncs
    4144return 0
Note: See TracChangeset for help on using the changeset viewer.