source: trunk/dll/commafmt.c@ 1184

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

Ticket 187: Draft 2: Move remaining function declarations

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