source: trunk/dll/i18nutil.c@ 1673

Last change on this file since 1673 was 1673, checked in by Gregg Young, 13 years ago

Update to Doxygen comment style Ticket 55. Also some minor code cleanup.

  • 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: i18nutil.c 1673 2012-12-30 18:51:01Z 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
[1400]18 08 Mar 09 GKY Renamed commafmt.h/c i18nutil.h/c
[98]19
20***********************************************************************/
21
[1673]22/**
[860]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.
[154]31 */
[2]32
[907]33#include <string.h>
[154]34
[1184]35#include "fm3dll.h"
[1205]36#include "init.h" // Data declaration(s)
[1399]37#include "i18nutil.h"
[2]38
[154]39size_t commafmt(char *pszBuf, // Output buffer
40 UINT cBufSize, // Buffer size, including nul
41 long lNumber) // Number to convert
[2]42{
[154]43 UINT cChars = 1; // Number of characters generated (excluding nul)
44 UINT cDigits = 1; // For commas
45 INT sign = 1;
[2]46
[154]47 char *pch = pszBuf + cBufSize - 1;
[98]48
[154]49 if (cBufSize < 2)
[551]50 goto ABORT;
[2]51
[551]52 *pch-- = 0; // Stuff terminator
[154]53 --cBufSize;
[551]54 if (lNumber < 0) {
[154]55 sign = -1;
56 lNumber = -lNumber;
57 }
[2]58
[551]59 for (; cChars <= cBufSize; ++cChars, ++cDigits) {
[860]60 *pch-- = (CHAR)(lNumber % 10 + '0');
[154]61 lNumber /= 10;
62 if (!lNumber)
63 break;
[551]64 if (cDigits % 3 == 0) {
[860]65 *pch-- = *ThousandsSeparator;
[154]66 ++cChars;
67 }
68 if (cChars >= cBufSize)
69 goto ABORT;
[551]70 } // for
[2]71
[551]72 if (sign < 0) {
[154]73 if (cBufSize == 0)
74 goto ABORT;
75 *pch-- = '-';
76 ++cChars;
77 }
[2]78
[154]79 strcpy(pszBuf, ++pch); // Left align
80
81 return cChars;
82
83ABORT:
[551]84 *pszBuf = 0;
85 return 0;
[2]86}
87
[860]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 */
[2]96
[154]97size_t CommaFmtULL(char *pszBuf, // Output buffer
98 UINT cBufSize, // Buffer size, including nul
99 ULONGLONG ullNumber, // Number to convert
[857]100 CHAR chPreferred) // Preferred suffix, blank, K, M, G
[154]101{
102 CHAR chSuffix = ' ';
103 size_t c;
[551]104
105 if (ullNumber >= 1ULL << 31 || (chPreferred != ' ' && ullNumber >= 1024)) {
[154]106 ullNumber = (ullNumber + 1023) >> 10;
107 chSuffix = 'K';
[859]108 if (ullNumber >= 1ULL << 31 || (chPreferred == 'M' && ullNumber >= 1024) ||
109 (chPreferred == 'G' && ullNumber >= 1024)) {
[154]110 ullNumber = (ullNumber + 1023) >> 10;
111 chSuffix = 'M';
[857]112 if (ullNumber >= 1ULL << 31 || (chPreferred == 'G' && ullNumber >= 1024)) {
113 ullNumber = (ullNumber + 1023) >> 10;
114 chSuffix = 'G';
115 }
[154]116 }
117 }
[98]118
[860]119 c = commafmt(pszBuf, cBufSize, (LONG)ullNumber);
[2]120
[154]121 if (chSuffix != ' ') {
[551]122 if (c + 4 > cBufSize) {
[154]123 *pszBuf = 0;
124 c = 0;
125 }
[551]126 else {
[154]127 pszBuf += c;
128 *pszBuf++ = chSuffix;
129 *pszBuf++ = 'i';
130 *pszBuf++ = 'B';
131 c += 3;
132 *pszBuf = 0;
133 }
134 }
135 return c;
136}
[2]137
[154]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;
[551]147
148 if (ulNumber >= 1ULL << 31 || (chPreferred != ' ' && ulNumber >= 1024)) {
[154]149 ulNumber = (ulNumber + 1023) >> 10;
150 chSuffix = 'K';
[551]151 if (ulNumber >= 1ULL << 31 || (chPreferred == 'M' && ulNumber >= 1024)) {
[154]152 ulNumber = (ulNumber + 1023) >> 10;
153 chSuffix = 'M';
[2]154 }
155 }
[154]156
157 c = commafmt(pszBuf, cBufSize, ulNumber);
158
159 if (chSuffix != ' ') {
[551]160 if (c + 4 > cBufSize) {
[154]161 *pszBuf = 0;
162 c = 0;
163 }
[551]164 else {
[154]165 pszBuf += c;
166 *pszBuf++ = chSuffix;
167 *pszBuf++ = 'i';
168 *pszBuf++ = 'B';
169 c += 3;
170 *pszBuf = 0;
171 }
172 }
173 return c;
[2]174}
[793]175
[1397]176VOID DateFormat(CHAR szBuf[DATE_BUF_BYTES], CDATE Date)
[1395]177{
178 switch(ulDateFmt) {
179
180 case 3:
181
[1397]182 sprintf(szBuf, "%04u%s%02u%s%02u", Date.year, DateSeparator,
[1395]183 Date.day, DateSeparator, Date.month);
184 break;
185
186 case 2:
187
[1397]188 sprintf(szBuf, "%04u%s%02u%s%02u", Date.year, DateSeparator,
[1395]189 Date.month, DateSeparator, Date.day);
190 break;
191
192 case 1:
193
[1397]194 sprintf(szBuf, "%02u%s%02u%s%04u", Date.day, DateSeparator,
[1395]195 Date.month, DateSeparator, Date.year);
196 break;
197
198 case 0:
199 default:
200
[1397]201 sprintf(szBuf, "%02u%s%02u%s%04u", Date.month, DateSeparator,
[1395]202 Date.day, DateSeparator, Date.year);
203 break;
204 }
205}
206
[1397]207VOID FDateFormat(CHAR szBuf[DATE_BUF_BYTES], FDATE Date)
[1395]208{
209 switch(ulDateFmt) {
210
211 case 3:
212
[1397]213 sprintf(szBuf, "%04u%s%02u%s%02u", Date.year + 1980, DateSeparator,
[1395]214 Date.day, DateSeparator, Date.month);
215 break;
216
217 case 2:
218
[1397]219 sprintf(szBuf, "%04u%s%02u%s%02u", Date.year + 1980, DateSeparator,
[1395]220 Date.month, DateSeparator, Date.day);
221 break;
222
223 case 1:
224
[1397]225 sprintf(szBuf, "%02u%s%02u%s%04u", Date.day, DateSeparator,
[1395]226 Date.month, DateSeparator, Date.year + 1980);
227 break;
228
229 case 0:
230 default:
231
[1397]232 sprintf(szBuf, "%02u%s%02u%s%04u", Date.month, DateSeparator,
[1395]233 Date.day, DateSeparator, Date.year + 1980);
234 break;
235 }
236}
237
[1397]238VOID DTDateFormat(CHAR szBuf[DATE_BUF_BYTES], DATETIME Date)
[1395]239{
240 switch(ulDateFmt) {
241
242 case 3:
243
[1397]244 sprintf(szBuf, "%04u%s%02u%s%02u", Date.year, DateSeparator,
[1395]245 Date.day, DateSeparator, Date.month);
246 break;
247
248 case 2:
249
[1397]250 sprintf(szBuf, "%04u%s%02u%s%02u", Date.year, DateSeparator,
[1395]251 Date.month, DateSeparator, Date.day);
252 break;
253
254 case 1:
255
[1397]256 sprintf(szBuf, "%02u%s%02u%s%04u", Date.day, DateSeparator,
[1395]257 Date.month, DateSeparator, Date.year);
258 break;
259
260 case 0:
261 default:
262
[1397]263 sprintf(szBuf, "%02u%s%02u%s%04u", Date.month, DateSeparator,
[1395]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.