source: trunk/dll/commafmt.c@ 1205

Last change on this file since 1205 was 1205, checked in by John Small, 17 years ago

Ticket 187: Move datadevlarations/definitions out of fm3dll.h

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.3 KB
Line 
1
2/***********************************************************************
3
4 $Id: commafmt.c 1205 2008-09-13 06:47:51Z jbs $
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
18***********************************************************************/
19
20/*
21 * COMMAFMT.C
22 * Adapted from public domain code by Bob Stout
23 *
24 * 2. By making the numeric argument a long and prototyping it before
25 * use, passed numeric arguments will be implicitly cast to longs
26 * thereby avoiding int overflow.
27 * 3. Use the thousands grouping and thousands separator from the
28 * ANSI locale to make this more robust.
29 */
30
31#include <string.h>
32
33#include "fm3dll.h"
34#include "init.h" // Data declaration(s)
35#include "commafmt.h"
36
37size_t commafmt(char *pszBuf, // Output buffer
38 UINT cBufSize, // Buffer size, including nul
39 long lNumber) // Number to convert
40{
41 UINT cChars = 1; // Number of characters generated (excluding nul)
42 UINT cDigits = 1; // For commas
43 INT sign = 1;
44
45 char *pch = pszBuf + cBufSize - 1;
46
47 if (cBufSize < 2)
48 goto ABORT;
49
50 *pch-- = 0; // Stuff terminator
51 --cBufSize;
52 if (lNumber < 0) {
53 sign = -1;
54 lNumber = -lNumber;
55 }
56
57 for (; cChars <= cBufSize; ++cChars, ++cDigits) {
58 *pch-- = (CHAR)(lNumber % 10 + '0');
59 lNumber /= 10;
60 if (!lNumber)
61 break;
62 if (cDigits % 3 == 0) {
63 *pch-- = *ThousandsSeparator;
64 ++cChars;
65 }
66 if (cChars >= cBufSize)
67 goto ABORT;
68 } // for
69
70 if (sign < 0) {
71 if (cBufSize == 0)
72 goto ABORT;
73 *pch-- = '-';
74 ++cChars;
75 }
76
77 strcpy(pszBuf, ++pch); // Left align
78
79 return cChars;
80
81ABORT:
82 *pszBuf = 0;
83 return 0;
84}
85
86/**
87 * Format long long number with commas and SI unit suffix
88 * @param pszBuf Points to output buffer
89 * @param cBufSize Buffer size including space for terminating nul
90 * @param ullNumber Number to convert
91 * @param chPreferred Preferred suffix, blank, K, M
92 * @return size of formatting string excluding terminating nul
93 */
94
95size_t CommaFmtULL(char *pszBuf, // Output buffer
96 UINT cBufSize, // Buffer size, including nul
97 ULONGLONG ullNumber, // Number to convert
98 CHAR chPreferred) // Preferred suffix, blank, K, M, G
99{
100 CHAR chSuffix = ' ';
101 size_t c;
102
103 if (ullNumber >= 1ULL << 31 || (chPreferred != ' ' && ullNumber >= 1024)) {
104 ullNumber = (ullNumber + 1023) >> 10;
105 chSuffix = 'K';
106 if (ullNumber >= 1ULL << 31 || (chPreferred == 'M' && ullNumber >= 1024) ||
107 (chPreferred == 'G' && ullNumber >= 1024)) {
108 ullNumber = (ullNumber + 1023) >> 10;
109 chSuffix = 'M';
110 if (ullNumber >= 1ULL << 31 || (chPreferred == 'G' && ullNumber >= 1024)) {
111 ullNumber = (ullNumber + 1023) >> 10;
112 chSuffix = 'G';
113 }
114 }
115 }
116
117 c = commafmt(pszBuf, cBufSize, (LONG)ullNumber);
118
119 if (chSuffix != ' ') {
120 if (c + 4 > cBufSize) {
121 *pszBuf = 0;
122 c = 0;
123 }
124 else {
125 pszBuf += c;
126 *pszBuf++ = chSuffix;
127 *pszBuf++ = 'i';
128 *pszBuf++ = 'B';
129 c += 3;
130 *pszBuf = 0;
131 }
132 }
133 return c;
134}
135
136//=== CommaFmtUL: format unsigned long number with commas and SI unit suffix ===
137
138size_t CommaFmtUL(char *pszBuf, // Output buffer
139 UINT cBufSize, // Buffer size, including nul
140 ULONG ulNumber, // Number to convert
141 CHAR chPreferred) // Preferred suffix, blank, K, M
142{
143 CHAR chSuffix = ' ';
144 size_t c;
145
146 if (ulNumber >= 1ULL << 31 || (chPreferred != ' ' && ulNumber >= 1024)) {
147 ulNumber = (ulNumber + 1023) >> 10;
148 chSuffix = 'K';
149 if (ulNumber >= 1ULL << 31 || (chPreferred == 'M' && ulNumber >= 1024)) {
150 ulNumber = (ulNumber + 1023) >> 10;
151 chSuffix = 'M';
152 }
153 }
154
155 c = commafmt(pszBuf, cBufSize, ulNumber);
156
157 if (chSuffix != ' ') {
158 if (c + 4 > cBufSize) {
159 *pszBuf = 0;
160 c = 0;
161 }
162 else {
163 pszBuf += c;
164 *pszBuf++ = chSuffix;
165 *pszBuf++ = 'i';
166 *pszBuf++ = 'B';
167 c += 3;
168 *pszBuf = 0;
169 }
170 }
171 return c;
172}
173
174#pragma alloc_text(MISC8,commafmt,CommaFmtU64)
Note: See TracBrowser for help on using the repository browser.