Changeset 41
- Timestamp:
- Mar 30, 2018, 6:12:15 PM (7 years ago)
- Location:
- rxutilex/trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
rxutilex/trunk/Makefile
r39 r41 10 10 LFLAGS = /NOLOGO /MAP 11 11 NAME = rxutilex 12 LIBS = rexx.lib 12 LIBS = rexx.lib libuls.lib libconv.lib 13 13 14 14 # Set environment variable DEBUG (=anything) to build with debugging symbols -
rxutilex/trunk/rxutilex.c
r40 r41 40 40 41 41 // Uncomment to use legacy C style locale data instead of the OS/2 ULS library 42 #define LEGACY_C_LOCALE42 // #define LEGACY_C_LOCALE 43 43 44 44 #define INCL_WINATOM … … 64 64 #include <string.h> 65 65 #include <time.h> 66 #include <locale.h> 66 67 67 68 #ifdef LEGACY_C_LOCALE 68 #include <locale.h>69 69 #include <nl_types.h> 70 70 #include <langinfo.h> 71 71 #else 72 72 #include <unidef.h> 73 #include <uconv.h> 73 74 #endif 74 75 … … 109 110 #define US_PIDSTR_MAXZ ( CCHMAXPATH + 100 ) // ...of a process information string 110 111 #define US_TIMESTR_MAXZ 256 // ...of a formatted time string 111 #define US_NUMSTR_MAXZ 64// ...of a formatted number string112 #define US_NUMSTR_MAXZ 32 // ...of a formatted number string 112 113 #define US_PIPESTATUS_MAXZ 128 // ...of a pipe status string 113 114 #define US_DISKINFO_MAXZ 128 // ...of a disk information string … … 197 198 ULONG GetProcess( PCSZ pszProgram, PSZ pszFullName, PULONG pulPID, PULONG pulPPID, PULONG pulType, PUSHORT pusPriority, PULONG pulCPU ); // 2016-02-20 SHL 198 199 200 #ifndef LEGACY_C_LOCALE 201 int GetLocaleString( PSZ *ppszItem, LocaleItem item ); 202 void GroupNumber( PSZ buf, ULONGLONG val, PSZ sep ); 203 #endif 204 199 205 #ifdef NO_SHARED_SOURCE 200 206 BOOL SaveResultString( PRXSTRING prsResult, PCSZ pchBytes, ULONG ulBytes ); // 2016-02-20 SHL … … 1072 1078 { 1073 1079 CHAR achNumber[ US_NUMSTR_MAXZ ]; // Formatted output string 1074 float fVal; // Input value as floating point 1080 int iPrec; // Requested decimal precision 1081 PSZ pszSep = NULL; // Thousands separator string 1082 PSZ pszDec = NULL; // Decimal point string 1083 #ifdef LEGACY_C_LOCALE 1084 float fVal = 0; // Input value as floating point 1075 1085 int iVal; // Input value as integer 1076 int iPrec; // Requested decimal precision 1077 PSZ pszSep = NULL; // Separator string 1078 #ifndef LEGACY_C_LOCALE 1079 CHAR achTemp[ US_NUMSTR_MAXZ ]; // Temporary buffer 1080 LocaleObject locale = NULL; // ULS locale object 1081 struct UniLconv *punilc = NULL; // ULS locale conventions structure 1082 CHAR *p = NULL; // Moving pointers within buffers 1083 CHAR *q = NULL; // ... 1084 int rc = 0; 1086 #else 1087 ULONGLONG llVal = 0; 1088 long double ldVal = 0, 1089 ldFrac = 0; 1090 PSZ p; 1091 CHAR achFrac[ 16 ]; 1092 int rc = 0; 1085 1093 #endif 1086 1094 … … 1109 1117 else if ( !strnicmp( p, "it", 2 )) setlocale( LC_NUMERIC, "IT_IT"); 1110 1118 else if ( !strnicmp( p, "ja", 2 )) setlocale( LC_NUMERIC, "JA_JP"); 1111 /* 1119 /* -- it seems the VAC runtime doesn't recognize most of these... 1112 1120 else if ( !strnicmp( p, "ar", 2 )) setlocale( LC_NUMERIC, "ar_AA"); 1113 1121 else if ( !strnicmp( p, "be", 2 )) setlocale( LC_NUMERIC, "be_BY"); … … 1145 1153 else if ( !strnicmp( p, "uk", 2 )) setlocale( LC_NUMERIC, "uk_UA"); 1146 1154 else if ( !strnicmp( p, "zh", 2 )) setlocale( LC_NUMERIC, "zh_TW"); 1147 */1155 -- */ 1148 1156 else setlocale( LC_NUMERIC, "EN_US"); 1149 1157 free(p); … … 1171 1179 1172 1180 #else 1173 rc = UniCreateLocaleObject( UNI_MBS_STRING_POINTER, "", &locale ); 1174 if ( rc != ULS_SUCCESS ) { 1175 WriteErrorCode( rc, "UniCreateLocaleObject"); 1176 SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL 1181 1182 rc = GetLocaleString( &pszSep, LOCI_sThousand ); 1183 if ( rc ) { 1184 // GetLocaleString has already set the error indicator 1185 SaveResultString( prsResult, NULL, 0 ); 1177 1186 return ( 0 ); 1178 1187 } 1179 rc = UniQueryLocaleInfo(locale_object, &puni_lconv);1180 if ( rc != ULS_SUCCESS) {1181 WriteErrorCode( rc, "UniQueryLocaleInfo");1182 SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL1188 rc = GetLocaleString( &pszDec, LOCI_sDecimal ); 1189 if ( rc ) { 1190 // GetLocaleString has already set the error indicator 1191 SaveResultString( prsResult, NULL, 0 ); 1183 1192 return ( 0 ); 1184 1193 } 1185 1194 1186 1195 // Check for a decimal place and treat as float or integer accordingly 1187 1196 if ( strchr( argv[0].strptr, '.') != NULL ) { 1188 if (( sscanf( argv[0].strptr, "%f", &fVal )) != 1 ) return ( 40 ); 1197 if (( sscanf( argv[0].strptr, "%Lf", &ldVal )) != 1 ) return ( 40 ); 1198 1199 llVal = ldVal; 1200 ldFrac = ldVal - llVal; 1189 1201 if ( argc >= 2 && ( RXVALIDSTRING(argv[1]) ) && 1190 1202 (( sscanf( argv[1].strptr, "%d", &iPrec )) == 1 )) 1191 1203 { 1192 1204 // Use user-specified precision 1193 sprintf( ach Number, "%.*f", iPrec, fVal);1205 sprintf( achFrac, "%.*Lf", iPrec, ldFrac ); 1194 1206 } 1195 1207 else 1196 sprintf( achNumber, "%.2f", fVal ); 1208 sprintf( achFrac, "%.2Lf", ldFrac ); 1209 // Format the integer part 1210 GroupNumber( achNumber, llVal, pszSep ); 1211 // Append the fractional part 1212 if (( p = strchr( achFrac, '.')) != NULL ) { 1213 strncat( achNumber, pszDec, US_NUMSTR_MAXZ - 1 ); 1214 strncat( achNumber, p+1, US_NUMSTR_MAXZ - 1 ); 1215 } 1197 1216 } 1198 1217 else { 1199 if (( sscanf( argv[0].strptr, "%d", &iVal )) != 1 ) return ( 40 ); 1200 sprintf( achNumber, "%d", iVal ); 1201 } 1202 1218 if (( sscanf( argv[0].strptr, "%lld", &llVal )) != 1 ) return ( 40 ); 1219 GroupNumber( achNumber, llVal, pszSep ); 1220 } 1221 1222 free( pszSep ); 1203 1223 #endif 1204 1224 … … 2862 2882 2863 2883 2884 #ifndef LEGACY_C_LOCALE 2885 2886 /* ------------------------------------------------------------------------- * 2887 * GetLocaleString * 2888 * * 2889 * Get the requested representation string for the current locale. * 2890 * The argument is a pointer to a string which will be allocated by this * 2891 * function. It is the caller's responsibility to free() it. * 2892 * * 2893 * ARGUMENTS: * 2894 * PSZ *ppszItem: Pointer to string to be allocated. (O) * 2895 * LocaleItem item: Locale item to query. (I) * 2896 * * 2897 * RETURNS: int * 2898 * The ULS function return code. * 2899 * ------------------------------------------------------------------------- */ 2900 int GetLocaleString( PSZ *ppszItem, LocaleItem item ) 2901 { 2902 UconvObject uconv = NULL; 2903 LocaleObject locale = NULL; 2904 UniChar *puzSep; 2905 int rc = 0; 2906 int buf_size; 2907 PSZ pszBuffer; 2908 2909 rc = UniCreateLocaleObject( UNI_MBS_STRING_POINTER, "", &locale ); 2910 if ( rc != ULS_SUCCESS ) { 2911 WriteErrorCode( rc, "UniCreateLocaleObject"); 2912 return ( rc ); 2913 } 2914 rc = UniQueryLocaleItem( locale, item, &puzSep ); 2915 if ( rc == ULS_SUCCESS ) { 2916 buf_size = UniStrlen( puzSep ) * 3; 2917 pszBuffer = (PSZ) calloc( 1, buf_size + 1 ); 2918 if ( pszBuffer ) { 2919 if ( UniCreateUconvObject(L"", &uconv ) == ULS_SUCCESS ) { 2920 if ( UniStrFromUcs( uconv, pszBuffer, puzSep, buf_size )) 2921 sprintf( pszBuffer, "%ls", puzSep ); 2922 UniFreeUconvObject( uconv ); 2923 } 2924 else 2925 sprintf( pszBuffer, "%ls", puzSep ); 2926 *ppszItem = pszBuffer; 2927 } 2928 else { 2929 rc = ERROR_NOT_ENOUGH_MEMORY; 2930 WriteErrorCode( rc, "calloc"); 2931 } 2932 UniFreeMem( puzSep ); 2933 } 2934 else WriteErrorCode( rc, "UniQueryLocaleItem"); 2935 2936 UniFreeLocaleObject( locale ); 2937 return ( rc ); 2938 } 2939 2940 2941 /* ------------------------------------------------------------------------- * 2942 * GroupNumber * 2943 * * 2944 * Format an unsigned number into three-digit (thousands) groups, separated * 2945 * by the designated separator string. The output buffer must be allocated, * 2946 * and must be large enough to hold a 64-bit integer with the added * 2947 * separators, i.e. 20 + (separator length * 6 ). This function does not * 2948 * perform any bounds checking, so the caller must ensure this. * 2949 * * 2950 * ARGUMENTS: * 2951 * PSZ buf: The output string buffer. (IO) * 2952 * ULONGLONG val: The number value to format. (I) * 2953 * PSZ sep: The group-separator string. (I) * 2954 * * 2955 * RETURNS: N/A * 2956 * ------------------------------------------------------------------------- */ 2957 void GroupNumber( PSZ buf, ULONGLONG val, PSZ sep ) 2958 { 2959 if ( val < 1000 ) { 2960 sprintf( buf, "%u", val ); 2961 return; 2962 } 2963 GroupNumber( buf, val / 1000, sep ); 2964 sprintf( buf+strlen(buf), "%s%03u", sep, val % 1000 ); 2965 } 2966 2967 #endif // #ifndef LEGACY_C_LOCALE 2864 2968 2865 2969 … … 2997 3101 } 2998 3102 2999 #endif //NO_SHARED_SOURCE3000 3103 #endif // #ifdef NO_SHARED_SOURCE 3104 -
rxutilex/trunk/rxutilex.def
r40 r41 1 1 LIBRARY RXUTILEX INITINSTANCE TERMINSTANCE 2 2 DATA MULTIPLE NONSHARED 3 DESCRIPTION '@#Alex Taylor:0.1.6#@##1## 29 Mar 2018 23:50:30REINFORCE::::::@@Extended REXX Utility Functions'3 DESCRIPTION '@#Alex Taylor:0.1.6#@##1## 30 Mar 2018 12:07:43 REINFORCE::::::@@Extended REXX Utility Functions' 4 4 5 5 EXPORTS Sys2LoadFuncs -
rxutilex/trunk/testlib.cmd
r40 r41 50 50 51 51 say 'Current screen resolution:' Sys2QuerySysValue('CXSCREEN') Sys2QuerySysValue('CYSCREEN') 52 say 53 54 say Sys2FormatNumber('9375739912303') 55 say Sys2FormatNumber('64583.449286', 5) 56 52 57 53 58 call Sys2DropFuncs
Note:
See TracChangeset
for help on using the changeset viewer.