CVS resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / kwsys / IOStream.cxx
blobab710cf8503117bf10673d1f8992dd93ab01b6ed
1 /*=========================================================================
3 Program: KWSys - Kitware System Library
4 Module: $RCSfile: IOStream.cxx,v $
6 Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
7 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the above copyright notices for more information.
13 =========================================================================*/
14 #include "kwsysPrivate.h"
15 #include KWSYS_HEADER(Configure.hxx)
17 // Configure the implementation for the current streams library.
18 #if !KWSYS_IOS_USE_ANSI
19 # define ios_base ios
20 # if defined(__HP_aCC)
21 # define protected public
22 # include <iostream.h> // Hack access to some private stream methods.
23 # undef protected
24 # endif
25 #endif
27 // Include the streams library.
28 #include KWSYS_HEADER(ios/iostream)
29 #include KWSYS_HEADER(IOStream.hxx)
31 // Work-around CMake dependency scanning limitation. This must
32 // duplicate the above list of headers.
33 #if 0
34 # include "Configure.hxx.in"
35 # include "kwsys_ios_iostream.hxx.in"
36 # include "IOStream.hxx.in"
37 #endif
39 // Implement the rest of this file only if it is needed.
40 #if KWSYS_IOS_NEED_OPERATORS_LL
42 # include <stdio.h> // sscanf, sprintf
43 # include <string.h> // memchr
45 # if defined(_MAX_INT_DIG)
46 # define KWSYS_IOS_INT64_MAX_DIG _MAX_INT_DIG
47 # else
48 # define KWSYS_IOS_INT64_MAX_DIG 32
49 # endif
51 namespace KWSYS_NAMESPACE
54 // Scan an input stream for an integer value.
55 static int IOStreamScanStream(kwsys_ios::istream& is, char* buffer)
57 // Prepare to write to buffer.
58 char* out = buffer;
59 char* end = buffer + KWSYS_IOS_INT64_MAX_DIG - 1;
61 // Look for leading sign.
62 if(is.peek() == '+') { *out++ = '+'; is.ignore(); }
63 else if(is.peek() == '-') { *out++ = '-'; is.ignore(); }
65 // Determine the base. If not specified in the stream, try to
66 // detect it from the input. A leading 0x means hex, and a leading
67 // 0 alone means octal.
68 int base = 0;
69 int flags = is.flags() & kwsys_ios::ios_base::basefield;
70 if(flags == kwsys_ios::ios_base::oct) { base = 8; }
71 else if(flags == kwsys_ios::ios_base::dec) { base = 10; }
72 else if(flags == kwsys_ios::ios_base::hex) { base = 16; }
73 bool foundDigit = false;
74 bool foundNonZero = false;
75 if(is.peek() == '0')
77 foundDigit = true;
78 is.ignore();
79 if((is.peek() == 'x' || is.peek() == 'X') && (base == 0 || base == 16))
81 base = 16;
82 foundDigit = false;
83 is.ignore();
85 else if (base == 0)
87 base = 8;
91 // Determine the range of digits allowed for this number.
92 const char* digits = "0123456789abcdefABCDEF";
93 int maxDigitIndex = 10;
94 if(base == 8)
96 maxDigitIndex = 8;
98 else if(base == 16)
100 maxDigitIndex = 10+6+6;
103 // Scan until an invalid digit is found.
104 for(;is.peek() != EOF; is.ignore())
106 if(memchr(digits, *out = (char)is.peek(), maxDigitIndex) != 0)
108 if((foundNonZero || *out != '0') && out < end)
110 ++out;
111 foundNonZero = true;
113 foundDigit = true;
115 else
117 break;
121 // Correct the buffer contents for degenerate cases.
122 if(foundDigit && !foundNonZero)
124 *out++ = '0';
126 else if (!foundDigit)
128 out = buffer;
131 // Terminate the string in the buffer.
132 *out = '\0';
134 return base;
137 // Read an integer value from an input stream.
138 template <class T>
139 kwsys_ios::istream&
140 IOStreamScanTemplate(kwsys_ios::istream& is, T& value, char type)
142 int state = kwsys_ios::ios_base::goodbit;
144 // Skip leading whitespace.
145 # if KWSYS_IOS_USE_ANSI
146 kwsys_ios::istream::sentry okay(is);
147 # else
148 is.eatwhite();
149 kwsys_ios::istream& okay = is;
150 # endif
152 if(okay)
154 # if KWSYS_IOS_USE_ANSI
155 try {
156 # endif
157 // Copy the string to a buffer and construct the format string.
158 char buffer[KWSYS_IOS_INT64_MAX_DIG];
159 # if defined(_MSC_VER)
160 char format[] = "%I64_";
161 const int typeIndex = 4;
162 # else
163 char format[] = "%ll_";
164 const int typeIndex = 3;
165 # endif
166 switch(IOStreamScanStream(is, buffer))
168 case 8: format[typeIndex] = 'o'; break;
169 case 0: // Default to decimal if not told otherwise.
170 case 10: format[typeIndex] = type; break;
171 case 16: format[typeIndex] = 'x'; break;
174 // Use sscanf to parse the number from the buffer.
175 T result;
176 int success = (sscanf(buffer, format, &result) == 1)?1:0;
178 // Set flags for resulting state.
179 if(is.peek() == EOF) { state |= kwsys_ios::ios_base::eofbit; }
180 if(!success) { state |= kwsys_ios::ios_base::failbit; }
181 else { value = result; }
182 # if KWSYS_IOS_USE_ANSI
183 } catch(...) { state |= kwsys_ios::ios_base::badbit; }
184 # endif
187 # if KWSYS_IOS_USE_ANSI
188 is.setstate(kwsys_ios::ios_base::iostate(state));
189 # else
190 is.clear(state);
191 # endif
192 return is;
195 // Print an integer value to an output stream.
196 template <class T>
197 kwsys_ios::ostream&
198 IOStreamPrintTemplate(kwsys_ios::ostream& os, T value, char type)
200 # if KWSYS_IOS_USE_ANSI
201 kwsys_ios::ostream::sentry okay(os);
202 # else
203 kwsys_ios::ostream& okay = os;
204 # endif
205 if(okay)
207 # if KWSYS_IOS_USE_ANSI
208 try {
209 # endif
210 // Construct the format string.
211 char format[8];
212 char* f = format;
213 *f++ = '%';
214 if(os.flags() & kwsys_ios::ios_base::showpos) { *f++ = '+'; }
215 if(os.flags() & kwsys_ios::ios_base::showbase) { *f++ = '#'; }
216 # if defined(_MSC_VER)
217 *f++ = 'I'; *f++ = '6'; *f++ = '4';
218 # else
219 *f++ = 'l'; *f++ = 'l';
220 # endif
221 long bflags = os.flags() & kwsys_ios::ios_base::basefield;
222 if(bflags == kwsys_ios::ios_base::oct) { *f++ = 'o'; }
223 else if(bflags != kwsys_ios::ios_base::hex) { *f++ = type; }
224 else if(os.flags() & kwsys_ios::ios_base::uppercase) { *f++ = 'X'; }
225 else { *f++ = 'x'; }
226 *f = '\0';
228 // Use sprintf to print to a buffer and then write the
229 // buffer to the stream.
230 char buffer[2*KWSYS_IOS_INT64_MAX_DIG];
231 sprintf(buffer, format, value);
232 os << buffer;
233 # if KWSYS_IOS_USE_ANSI
234 } catch(...) { os.clear(os.rdstate() | kwsys_ios::ios_base::badbit); }
235 # endif
237 return os;
240 # if !KWSYS_IOS_HAS_ISTREAM_LONG_LONG
241 // Implement input stream operator for IOStreamSLL.
242 kwsys_ios::istream& IOStreamScan(kwsys_ios::istream& is, IOStreamSLL& value)
244 return IOStreamScanTemplate(is, value, 'd');
247 // Implement input stream operator for IOStreamULL.
248 kwsys_ios::istream& IOStreamScan(kwsys_ios::istream& is, IOStreamULL& value)
250 return IOStreamScanTemplate(is, value, 'u');
252 # endif
254 # if !KWSYS_IOS_HAS_OSTREAM_LONG_LONG
255 // Implement output stream operator for IOStreamSLL.
256 kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream& os, IOStreamSLL value)
258 return IOStreamPrintTemplate(os, value, 'd');
261 // Implement output stream operator for IOStreamULL.
262 kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream& os, IOStreamULL value)
264 return IOStreamPrintTemplate(os, value, 'u');
266 # endif
268 } // namespace KWSYS_NAMESPACE
270 #else
272 namespace KWSYS_NAMESPACE
275 // Create one public symbol in this object file to avoid warnings from
276 // archivers.
277 void IOStreamSymbolToAvoidWarning()
281 } // namespace KWSYS_NAMESPACE
283 #endif // KWSYS_IOS_NEED_OPERATORS_LL