source: trunk/dll/commafmt.c@ 1395

Last change on this file since 1395 was 1395, checked in by Gregg Young, 17 years ago

Allow user to turn off alert and/or error beeps in settings notebook. Ticket 341 Move repeated strings to PCSZs. Ticket 6 Add *DateFormat functions to format dates based on locale Ticket 28 Eliminate Win_Error2 by moving function names to PCSZs used in Win_Error Ticket 6

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.3 KB
RevLine 
[98]1
2/***********************************************************************
3
4 $Id: commafmt.c 1395 2009-02-08 01:48:16Z gyoung $
5
6 Command formatting tools
7
8 Copyright (c) 1993-98 M. Kimes
[154]9 Copyright (c) 2004, 2005 Steven H. Levine
[98]10
[154]11 06 Jan 04 SHL Disable hundfmt, clean commafmt
12 25 May 05 SHL Drop hundfmt
13 25 May 05 SHL Add CommaFmtULL, CommaFmtUL
[793]14 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[860]15 05 Nov 07 GKY Use commafmtULL to display file sizes for large file support
16 10 Nov 07 GKY Get thousands separator from country info for file sizes.
[1395]17 07 Feb 09 GKY Add *DateFormat functions to format dates based on locale
[98]18
19***********************************************************************/
20
[2]21/*
[860]22 * COMMAFMT.C
23 * Adapted from public domain code by Bob Stout
24 *
25 * 2. By making the numeric argument a long and prototyping it before
26 * use, passed numeric arguments will be implicitly cast to longs
27 * thereby avoiding int overflow.
28 * 3. Use the thousands grouping and thousands separator from the
29 * ANSI locale to make this more robust.
[154]30 */
[2]31
[907]32#include <string.h>
[154]33
[1184]34#include "fm3dll.h"
[1205]35#include "init.h" // Data declaration(s)
[1160]36#include "commafmt.h"
[2]37
[154]38size_t commafmt(char *pszBuf, // Output buffer
39 UINT cBufSize, // Buffer size, including nul
40 long lNumber) // Number to convert
[2]41{
[154]42 UINT cChars = 1; // Number of characters generated (excluding nul)
43 UINT cDigits = 1; // For commas
44 INT sign = 1;
[2]45
[154]46 char *pch = pszBuf + cBufSize - 1;
[98]47
[154]48 if (cBufSize < 2)
[551]49 goto ABORT;
[2]50
[551]51 *pch-- = 0; // Stuff terminator
[154]52 --cBufSize;
[551]53 if (lNumber < 0) {
[154]54 sign = -1;
55 lNumber = -lNumber;
56 }
[2]57
[551]58 for (; cChars <= cBufSize; ++cChars, ++cDigits) {
[860]59 *pch-- = (CHAR)(lNumber % 10 + '0');
[154]60 lNumber /= 10;
61 if (!lNumber)
62 break;
[551]63 if (cDigits % 3 == 0) {
[860]64 *pch-- = *ThousandsSeparator;
[154]65 ++cChars;
66 }
67 if (cChars >= cBufSize)
68 goto ABORT;
[551]69 } // for
[2]70
[551]71 if (sign < 0) {
[154]72 if (cBufSize == 0)
73 goto ABORT;
74 *pch-- = '-';
75 ++cChars;
76 }
[2]77
[154]78 strcpy(pszBuf, ++pch); // Left align
79
80 return cChars;
81
82ABORT:
[551]83 *pszBuf = 0;
84 return 0;
[2]85}
86
[860]87/**
88 * Format long long number with commas and SI unit suffix
89 * @param pszBuf Points to output buffer
90 * @param cBufSize Buffer size including space for terminating nul
91 * @param ullNumber Number to convert
92 * @param chPreferred Preferred suffix, blank, K, M
93 * @return size of formatting string excluding terminating nul
94 */
[2]95
[154]96size_t CommaFmtULL(char *pszBuf, // Output buffer
97 UINT cBufSize, // Buffer size, including nul
98 ULONGLONG ullNumber, // Number to convert
[857]99 CHAR chPreferred) // Preferred suffix, blank, K, M, G
[154]100{
101 CHAR chSuffix = ' ';
102 size_t c;
[551]103
104 if (ullNumber >= 1ULL << 31 || (chPreferred != ' ' && ullNumber >= 1024)) {
[154]105 ullNumber = (ullNumber + 1023) >> 10;
106 chSuffix = 'K';
[859]107 if (ullNumber >= 1ULL << 31 || (chPreferred == 'M' && ullNumber >= 1024) ||
108 (chPreferred == 'G' && ullNumber >= 1024)) {
[154]109 ullNumber = (ullNumber + 1023) >> 10;
110 chSuffix = 'M';
[857]111 if (ullNumber >= 1ULL << 31 || (chPreferred == 'G' && ullNumber >= 1024)) {
112 ullNumber = (ullNumber + 1023) >> 10;
113 chSuffix = 'G';
114 }
[154]115 }
116 }
[98]117
[860]118 c = commafmt(pszBuf, cBufSize, (LONG)ullNumber);
[2]119
[154]120 if (chSuffix != ' ') {
[551]121 if (c + 4 > cBufSize) {
[154]122 *pszBuf = 0;
123 c = 0;
124 }
[551]125 else {
[154]126 pszBuf += c;
127 *pszBuf++ = chSuffix;
128 *pszBuf++ = 'i';
129 *pszBuf++ = 'B';
130 c += 3;
131 *pszBuf = 0;
132 }
133 }
134 return c;
135}
[2]136
[154]137//=== CommaFmtUL: format unsigned long number with commas and SI unit suffix ===
138
139size_t CommaFmtUL(char *pszBuf, // Output buffer
140 UINT cBufSize, // Buffer size, including nul
141 ULONG ulNumber, // Number to convert
142 CHAR chPreferred) // Preferred suffix, blank, K, M
143{
144 CHAR chSuffix = ' ';
145 size_t c;
[551]146
147 if (ulNumber >= 1ULL << 31 || (chPreferred != ' ' && ulNumber >= 1024)) {
[154]148 ulNumber = (ulNumber + 1023) >> 10;
149 chSuffix = 'K';
[551]150 if (ulNumber >= 1ULL << 31 || (chPreferred == 'M' && ulNumber >= 1024)) {
[154]151 ulNumber = (ulNumber + 1023) >> 10;
152 chSuffix = 'M';
[2]153 }
154 }
[154]155
156 c = commafmt(pszBuf, cBufSize, ulNumber);
157
158 if (chSuffix != ' ') {
[551]159 if (c + 4 > cBufSize) {
[154]160 *pszBuf = 0;
161 c = 0;
162 }
[551]163 else {
[154]164 pszBuf += c;
165 *pszBuf++ = chSuffix;
166 *pszBuf++ = 'i';
167 *pszBuf++ = 'B';
168 c += 3;
169 *pszBuf = 0;
170 }
171 }
172 return c;
[2]173}
[793]174
[1395]175VOID DateFormat(PSZ pszBuf, CDATE Date)
176{
177 switch(ulDateFmt) {
178
179 case 3:
180
181 sprintf(pszBuf, "%04u%s%02u%s%02u", Date.year, DateSeparator,
182 Date.day, DateSeparator, Date.month);
183 break;
184
185 case 2:
186
187 sprintf(pszBuf, "%04u%s%02u%s%02u", Date.year, DateSeparator,
188 Date.month, DateSeparator, Date.day);
189 break;
190
191 case 1:
192
193 sprintf(pszBuf, "%02u%s%02u%s%04u", Date.day, DateSeparator,
194 Date.month, DateSeparator, Date.year);
195 break;
196
197 case 0:
198 default:
199
200 sprintf(pszBuf, "%02u%s%02u%s%04u", Date.month, DateSeparator,
201 Date.day, DateSeparator, Date.year);
202 break;
203 }
204}
205
206VOID FDateFormat(PSZ pszBuf, FDATE Date)
207{
208 switch(ulDateFmt) {
209
210 case 3:
211
212 sprintf(pszBuf, "%04u%s%02u%s%02u", Date.year + 1980, DateSeparator,
213 Date.day, DateSeparator, Date.month);
214 break;
215
216 case 2:
217
218 sprintf(pszBuf, "%04u%s%02u%s%02u", Date.year + 1980, DateSeparator,
219 Date.month, DateSeparator, Date.day);
220 break;
221
222 case 1:
223
224 sprintf(pszBuf, "%02u%s%02u%s%04u", Date.day, DateSeparator,
225 Date.month, DateSeparator, Date.year + 1980);
226 break;
227
228 case 0:
229 default:
230
231 sprintf(pszBuf, "%02u%s%02u%s%04u", Date.month, DateSeparator,
232 Date.day, DateSeparator, Date.year + 1980);
233 break;
234 }
235}
236
237VOID DTDateFormat(PSZ pszBuf, DATETIME Date)
238{
239 switch(ulDateFmt) {
240
241 case 3:
242
243 sprintf(pszBuf, "%04u%s%02u%s%02u", Date.year, DateSeparator,
244 Date.day, DateSeparator, Date.month);
245 break;
246
247 case 2:
248
249 sprintf(pszBuf, "%04u%s%02u%s%02u", Date.year, DateSeparator,
250 Date.month, DateSeparator, Date.day);
251 break;
252
253 case 1:
254
255 sprintf(pszBuf, "%02u%s%02u%s%04u", Date.day, DateSeparator,
256 Date.month, DateSeparator, Date.year);
257 break;
258
259 case 0:
260 default:
261
262 sprintf(pszBuf, "%02u%s%02u%s%04u", Date.month, DateSeparator,
263 Date.day, DateSeparator, Date.year);
264 break;
265 }
266}
267
268#pragma alloc_text(MISC8,commafmt,CommaFmtUL,CommaFmtULL)
Note: See TracBrowser for help on using the repository browser.