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
RevLine 
[98]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
[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.
[98]17
18***********************************************************************/
19
[2]20/*
[860]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.
[154]29 */
[2]30
[907]31#include <string.h>
[154]32
[1184]33#include "fm3dll.h"
[1160]34#include "commafmt.h"
[2]35
[154]36size_t commafmt(char *pszBuf, // Output buffer
37 UINT cBufSize, // Buffer size, including nul
38 long lNumber) // Number to convert
[2]39{
[154]40 UINT cChars = 1; // Number of characters generated (excluding nul)
41 UINT cDigits = 1; // For commas
42 INT sign = 1;
[2]43
[154]44 char *pch = pszBuf + cBufSize - 1;
[98]45
[154]46 if (cBufSize < 2)
[551]47 goto ABORT;
[2]48
[551]49 *pch-- = 0; // Stuff terminator
[154]50 --cBufSize;
[551]51 if (lNumber < 0) {
[154]52 sign = -1;
53 lNumber = -lNumber;
54 }
[2]55
[551]56 for (; cChars <= cBufSize; ++cChars, ++cDigits) {
[860]57 *pch-- = (CHAR)(lNumber % 10 + '0');
[154]58 lNumber /= 10;
59 if (!lNumber)
60 break;
[551]61 if (cDigits % 3 == 0) {
[860]62 *pch-- = *ThousandsSeparator;
[154]63 ++cChars;
64 }
65 if (cChars >= cBufSize)
66 goto ABORT;
[551]67 } // for
[2]68
[551]69 if (sign < 0) {
[154]70 if (cBufSize == 0)
71 goto ABORT;
72 *pch-- = '-';
73 ++cChars;
74 }
[2]75
[154]76 strcpy(pszBuf, ++pch); // Left align
77
78 return cChars;
79
80ABORT:
[551]81 *pszBuf = 0;
82 return 0;
[2]83}
84
[860]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 */
[2]93
[154]94size_t CommaFmtULL(char *pszBuf, // Output buffer
95 UINT cBufSize, // Buffer size, including nul
96 ULONGLONG ullNumber, // Number to convert
[857]97 CHAR chPreferred) // Preferred suffix, blank, K, M, G
[154]98{
99 CHAR chSuffix = ' ';
100 size_t c;
[551]101
102 if (ullNumber >= 1ULL << 31 || (chPreferred != ' ' && ullNumber >= 1024)) {
[154]103 ullNumber = (ullNumber + 1023) >> 10;
104 chSuffix = 'K';
[859]105 if (ullNumber >= 1ULL << 31 || (chPreferred == 'M' && ullNumber >= 1024) ||
106 (chPreferred == 'G' && ullNumber >= 1024)) {
[154]107 ullNumber = (ullNumber + 1023) >> 10;
108 chSuffix = 'M';
[857]109 if (ullNumber >= 1ULL << 31 || (chPreferred == 'G' && ullNumber >= 1024)) {
110 ullNumber = (ullNumber + 1023) >> 10;
111 chSuffix = 'G';
112 }
[154]113 }
114 }
[98]115
[860]116 c = commafmt(pszBuf, cBufSize, (LONG)ullNumber);
[2]117
[154]118 if (chSuffix != ' ') {
[551]119 if (c + 4 > cBufSize) {
[154]120 *pszBuf = 0;
121 c = 0;
122 }
[551]123 else {
[154]124 pszBuf += c;
125 *pszBuf++ = chSuffix;
126 *pszBuf++ = 'i';
127 *pszBuf++ = 'B';
128 c += 3;
129 *pszBuf = 0;
130 }
131 }
132 return c;
133}
[2]134
[154]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;
[551]144
145 if (ulNumber >= 1ULL << 31 || (chPreferred != ' ' && ulNumber >= 1024)) {
[154]146 ulNumber = (ulNumber + 1023) >> 10;
147 chSuffix = 'K';
[551]148 if (ulNumber >= 1ULL << 31 || (chPreferred == 'M' && ulNumber >= 1024)) {
[154]149 ulNumber = (ulNumber + 1023) >> 10;
150 chSuffix = 'M';
[2]151 }
152 }
[154]153
154 c = commafmt(pszBuf, cBufSize, ulNumber);
155
156 if (chSuffix != ' ') {
[551]157 if (c + 4 > cBufSize) {
[154]158 *pszBuf = 0;
159 c = 0;
160 }
[551]161 else {
[154]162 pszBuf += c;
163 *pszBuf++ = chSuffix;
164 *pszBuf++ = 'i';
165 *pszBuf++ = 'B';
166 c += 3;
167 *pszBuf = 0;
168 }
169 }
170 return c;
[2]171}
[793]172
173#pragma alloc_text(MISC8,commafmt,CommaFmtU64)
Note: See TracBrowser for help on using the repository browser.