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