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
Line 
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
9 Copyright (c) 2004, 2005 Steven H. Levine
10
11 06 Jan 04 SHL Disable hundfmt, clean commafmt
12 25 May 05 SHL Drop hundfmt
13 25 May 05 SHL Add CommaFmtULL, CommaFmtUL
14 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
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.
17 07 Feb 09 GKY Add *DateFormat functions to format dates based on locale
18
19***********************************************************************/
20
21/*
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.
30 */
31
32#include <string.h>
33
34#include "fm3dll.h"
35#include "init.h" // Data declaration(s)
36#include "commafmt.h"
37
38size_t commafmt(char *pszBuf, // Output buffer
39 UINT cBufSize, // Buffer size, including nul
40 long lNumber) // Number to convert
41{
42 UINT cChars = 1; // Number of characters generated (excluding nul)
43 UINT cDigits = 1; // For commas
44 INT sign = 1;
45
46 char *pch = pszBuf + cBufSize - 1;
47
48 if (cBufSize < 2)
49 goto ABORT;
50
51 *pch-- = 0; // Stuff terminator
52 --cBufSize;
53 if (lNumber < 0) {
54 sign = -1;
55 lNumber = -lNumber;
56 }
57
58 for (; cChars <= cBufSize; ++cChars, ++cDigits) {
59 *pch-- = (CHAR)(lNumber % 10 + '0');
60 lNumber /= 10;
61 if (!lNumber)
62 break;
63 if (cDigits % 3 == 0) {
64 *pch-- = *ThousandsSeparator;
65 ++cChars;
66 }
67 if (cChars >= cBufSize)
68 goto ABORT;
69 } // for
70
71 if (sign < 0) {
72 if (cBufSize == 0)
73 goto ABORT;
74 *pch-- = '-';
75 ++cChars;
76 }
77
78 strcpy(pszBuf, ++pch); // Left align
79
80 return cChars;
81
82ABORT:
83 *pszBuf = 0;
84 return 0;
85}
86
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 */
95
96size_t CommaFmtULL(char *pszBuf, // Output buffer
97 UINT cBufSize, // Buffer size, including nul
98 ULONGLONG ullNumber, // Number to convert
99 CHAR chPreferred) // Preferred suffix, blank, K, M, G
100{
101 CHAR chSuffix = ' ';
102 size_t c;
103
104 if (ullNumber >= 1ULL << 31 || (chPreferred != ' ' && ullNumber >= 1024)) {
105 ullNumber = (ullNumber + 1023) >> 10;
106 chSuffix = 'K';
107 if (ullNumber >= 1ULL << 31 || (chPreferred == 'M' && ullNumber >= 1024) ||
108 (chPreferred == 'G' && ullNumber >= 1024)) {
109 ullNumber = (ullNumber + 1023) >> 10;
110 chSuffix = 'M';
111 if (ullNumber >= 1ULL << 31 || (chPreferred == 'G' && ullNumber >= 1024)) {
112 ullNumber = (ullNumber + 1023) >> 10;
113 chSuffix = 'G';
114 }
115 }
116 }
117
118 c = commafmt(pszBuf, cBufSize, (LONG)ullNumber);
119
120 if (chSuffix != ' ') {
121 if (c + 4 > cBufSize) {
122 *pszBuf = 0;
123 c = 0;
124 }
125 else {
126 pszBuf += c;
127 *pszBuf++ = chSuffix;
128 *pszBuf++ = 'i';
129 *pszBuf++ = 'B';
130 c += 3;
131 *pszBuf = 0;
132 }
133 }
134 return c;
135}
136
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;
146
147 if (ulNumber >= 1ULL << 31 || (chPreferred != ' ' && ulNumber >= 1024)) {
148 ulNumber = (ulNumber + 1023) >> 10;
149 chSuffix = 'K';
150 if (ulNumber >= 1ULL << 31 || (chPreferred == 'M' && ulNumber >= 1024)) {
151 ulNumber = (ulNumber + 1023) >> 10;
152 chSuffix = 'M';
153 }
154 }
155
156 c = commafmt(pszBuf, cBufSize, ulNumber);
157
158 if (chSuffix != ' ') {
159 if (c + 4 > cBufSize) {
160 *pszBuf = 0;
161 c = 0;
162 }
163 else {
164 pszBuf += c;
165 *pszBuf++ = chSuffix;
166 *pszBuf++ = 'i';
167 *pszBuf++ = 'B';
168 c += 3;
169 *pszBuf = 0;
170 }
171 }
172 return c;
173}
174
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.