source: trunk/dll/i18nutil.c@ 1570

Last change on this file since 1570 was 1400, checked in by Gregg Young, 16 years ago

Remainder of changes to rename commafmt.h/c (Ticket 28, 82); Additional strings moved to PCSZs in init.c (Ticket 6); Added WriteDetailsSwitches used it and LoadDetailsSwitches to consolidate inline code (Ticket 343, 344)

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