00001 // Copyright (C) 2001, Compaq Computer Corporation 00002 00003 // This file is part of Vesta. 00004 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 // Last modified on Sat May 28 16:28:45 EDT 2005 by ken@xorian.net 00020 // modified on Sun Jul 28 11:31:51 EDT 2002 by lken@remote.xorian.net 00021 // modified on Fri Feb 11 13:35:30 PST 2000 by mann 00022 // modified on Mon May 3 22:56:46 PDT 1999 by heydon 00023 // modified on Tue Dec 5 10:53:39 PST 1995 by levin 00024 00025 // ************** 00026 // * Basics.H * 00027 // ************** 00028 00029 // This header file contains definitions that are closely connected 00030 // to the language definition. 00031 00032 #ifndef _Basics 00033 #define _Basics 00034 00035 // Procide sizeof assertion capability 00036 #include "SizeAssert.H" 00037 00038 #if defined(__DECCXX) && !defined(_BOOL_EXISTS) 00039 typedef char bool; 00040 const bool true = 1; 00041 const bool false = 0; 00042 #endif 00043 00044 #if defined (__linux__) 00045 #include <stdint.h> 00046 #endif 00047 00048 // Conversions between host and network byte order. 00049 #if defined (__digital__) 00050 #include <machine/endian.h> 00051 #endif 00052 #include <netinet/in.h> 00053 00054 // the names of the boolean values 00055 extern const char* const BoolName[]; 00056 00057 // Character string manipulation (char *) 00058 // (The use of String is deprecated.) 00059 00060 #include <ctype.h> 00061 #include <string.h> 00062 00063 // More standard libraries 00064 00065 #include <assert.h> 00066 #include <stdlib.h> 00067 #include <stdio.h> 00068 00069 // C++ stream library. Some of this is quasi-OS-dependent, but 00070 // it seems pedantic to try to split it between Basics.H and OS.H. 00071 00072 #include <iostream> 00073 #include <sstream> 00074 #include <iosfwd> 00075 #include <fstream> 00076 00077 // Miscellaneous utility functions (arithmetic, random, etc.) 00078 00079 inline int min(int a, int b) { return ((a < b) ? a : b); } 00080 inline int max(int a, int b) { return ((a > b) ? a : b); } 00081 00082 // The macro CONST_INT_64 is used for 64-bit integer constants, which 00083 // are used in a few places. These tend to require special handling 00084 // on non-64-bit platforms. 00085 00086 #if defined(__alpha) 00087 // Any 64-bit platform should probably use this clause. Modify the 00088 // #if when porting to a new platform. 00089 #define CONST_INT_64(x) x##L 00090 #define CONST_UINT_64(x) x##UL 00091 00092 #elif defined(__GNUC__) && (__GNUC__ >= 2) 00093 // The GNU compiler uses the LL suffix to denote a 64-bit integer 00094 // constant. This should work on platforms where long is also 64 00095 // bits. 00096 #define CONST_INT_64(x) x##LL 00097 #define CONST_UINT_64(x) x##ULL 00098 00099 #else 00100 #error Need 64-bit constant macro for this platform 00101 #endif 00102 00103 // ---------------------------------------------------------------------- 00104 // Integer types for use when the specific number of bits is 00105 // important. Similar typedefs are often defined by system headers, 00106 // but unfortunately the names of the types and the header files which 00107 // define them are inconsist between platforms. We isolate these in a 00108 // namespace to avoid the possibility of conflicting with 00109 // similarly-named system-defined types. 00110 // ---------------------------------------------------------------------- 00111 00112 namespace Basics 00113 { 00114 // On all platforms tested, these typedefs are the same. However, 00115 // porting to new platforms may require wrapping some of these in 00116 // #if's. Be sure to run the TestSizes program to check that these 00117 // are all the right size. 00118 typedef char int8; 00119 typedef unsigned char uint8; 00120 typedef short int16; 00121 typedef unsigned short uint16; 00122 typedef int int32; 00123 typedef unsigned int uint32; 00124 00125 #if defined(__alpha) 00126 // Any platform where a long is 64 bits can probably use these 00127 // typedefs. Modify the #if when porting to a new 64-bit platform. 00128 00129 typedef long int64; 00130 typedef unsigned long uint64; 00131 00132 #elif defined(__GNUC__) && (__GNUC__ >= 2) 00133 // Fall through for the GNU compiler on any platform: long long 00134 // should be a 64-bit integer. This should work on platforms where 00135 // long is also 64 bits. 00136 00137 typedef long long int64; 00138 typedef unsigned long long uint64; 00139 00140 #else 00141 // Force a compilation failure if we don't know what to do. 00142 00143 #error Need 64-bit typedefs for this platform 00144 #endif 00145 00146 // Swap bytes in integers of different sizes. This allows 00147 // big-endian machines to read littl-eendian values and vice-versa. 00148 00149 inline uint16 swab16(uint16 p_x) 00150 { 00151 return (((p_x & 0x00ff) << 8) | 00152 ((p_x & 0xff00) >> 8)); 00153 } 00154 00155 inline uint32 swab32(uint32 p_x) 00156 { 00157 return (((p_x & 0x000000ff) << 24) | 00158 ((p_x & 0x0000ff00) << 8) | 00159 ((p_x & 0x00ff0000) >> 8) | 00160 ((p_x & 0xff000000) >> 24)); 00161 } 00162 00163 inline uint64 swab64(uint64 p_x) 00164 { 00165 return (((p_x & CONST_INT_64(0xff00000000000000)) >> 56) | 00166 ((p_x & CONST_INT_64(0x00ff000000000000)) >> 40) | 00167 ((p_x & CONST_INT_64(0x0000ff0000000000)) >> 24) | 00168 ((p_x & CONST_INT_64(0x000000ff00000000)) >> 8) | 00169 ((p_x & CONST_INT_64(0x00000000ff000000)) << 8) | 00170 ((p_x & CONST_INT_64(0x0000000000ff0000)) << 24) | 00171 ((p_x & CONST_INT_64(0x000000000000ff00)) << 40) | 00172 ((p_x & CONST_INT_64(0x00000000000000ff)) << 56)); 00173 } 00174 00175 // htons/ntohs operate on 16-bit values. 00176 00177 inline uint16 hton16(uint16 p_x) 00178 { 00179 return htons(p_x); 00180 } 00181 00182 inline uint16 ntoh16(uint16 p_x) 00183 { 00184 return ntohs(p_x); 00185 } 00186 00187 // htonl/ntohl operate on 32-bit values 00188 00189 inline uint32 hton32(uint32 p_x) 00190 { 00191 return htonl(p_x); 00192 } 00193 00194 inline uint32 ntoh32(uint32 p_x) 00195 { 00196 return ntohl(p_x); 00197 } 00198 00199 // There's no standard for converting 64-bit values to/from network 00200 // byte order. 00201 00202 inline uint64 hton64(uint64 p_x) 00203 { 00204 #if BYTE_ORDER == BIG_ENDIAN 00205 return p_x; 00206 #elif BYTE_ORDER == LITTLE_ENDIAN 00207 return swab64(p_x); 00208 #else 00209 // Force a compilation failure if we don't know what to do. 00210 00211 #error Unknown byte order 00212 #endif 00213 } 00214 00215 inline uint64 ntoh64(uint64 p_x) 00216 { 00217 return hton64(p_x); 00218 } 00219 00220 // Memory allocation attributes for use with a garbage collection 00221 // library. 00222 00223 // The caller promises that this block will not contain pointers to 00224 // other heap blocks. This should be used for character strings, 00225 // bitmaps, etc., to reduce the possibility of heap blocks beaing 00226 // conservatively kept due to random data being misidentified as 00227 // pointers. 00228 struct gc_no_pointers_t { }; 00229 extern gc_no_pointers_t gc_no_pointers; 00230 } 00231 00232 #define NEW(t) new (__FILE__, __LINE__) t 00233 #define NEW_CONSTR(t, args) new (__FILE__, __LINE__) t args 00234 #define NEW_ARRAY(t, size) new (__FILE__, __LINE__) t[size] 00235 #define NEW_PTRFREE(t) new (Basics::gc_no_pointers, __FILE__, __LINE__) t 00236 #define NEW_PTRFREE_CONSTR(t, args) new (Basics::gc_no_pointers, __FILE__, __LINE__) t args 00237 #define NEW_PTRFREE_ARRAY(t, size) new (Basics::gc_no_pointers, __FILE__, __LINE__) t[size] 00238 00239 // Use placement new variants to allow get information about the 00240 // source location of the allocation and add attributes like "no 00241 // pointers in this block". 00242 void *operator new(size_t size, Basics::gc_no_pointers_t unused, 00243 const char *file, unsigned int line); 00244 void *operator new[](size_t size, Basics::gc_no_pointers_t unused, 00245 const char *file, unsigned int line); 00246 00247 void *operator new(size_t size, const char *file, unsigned int line); 00248 void *operator new[](size_t size, const char *file, unsigned int line); 00249 00250 // The Bit{N} typedefs represent unsigned integers, often used for 00251 // bitfields and the like. The use of these names pre-dates porting 00252 // efforts that necessitated signed integer types of different sizes. 00253 // It would be harmless but time-consuming to replace them with the 00254 // types they are defined as aliases of. 00255 typedef Basics::uint8 Bit8; 00256 typedef Basics::uint16 Bit16; 00257 typedef Basics::uint32 Bit32; 00258 typedef Basics::uint64 Bit64; 00259 typedef struct { Bit8 byte[32]; } Byte32; 00260 00261 // Word was originally intended to be "the machine's largest unsigned 00262 // integer", analogous to Modula-3's "Word.T" and useful especially in 00263 // library code transliterated from Modula-3. However, it's tricky to 00264 // use such a type properly, and we ended up with a lot of code that 00265 // assumes a Word is 64 bits. 00266 typedef Bit64 Word; 00267 00268 // There are some places in the code that do fancy pointer math. For 00269 // those purposes, we use this typedef which should be an unsigned 00270 // integer exactly the same size as a pointer. On most every 00271 // platform, sizeof(long) == sizeof(void *). (The TestSizes program 00272 // will report an error message if PointerInt is not the same size as 00273 // a pointer.) 00274 typedef unsigned long PointerInt; 00275 00276 // The size of the C++ 'bool' type is not always the same. (On Tru64 00277 // with the Compaq C++ compiler, it's one byte, on Alpha Linux with 00278 // the GNU compiler it's 8 bytes.) However, we need a boolean type 00279 // which we can depend on always being just 8 bits in size. So, we 00280 // define our own bool type here called "bool8" (as in "an 8-bit 00281 // bool"). 00282 typedef Basics::int8 bool8; 00283 00284 // When using printf-style formatting of integers, the 00285 // FORMAT_LENGTH_INT_64 macro should be used for the length field of a 00286 // 64-bit integer format specifier, like so: 00287 // 00288 // printf("%" FORMAT_LENGTH_INT_64 "x\n", var); 00289 // 00290 // Note: The adjacent string constants will be merged by the compiler. 00291 00292 #if defined(__alpha) 00293 // On platforms where a long is 64-bits, a single l works correctly. 00294 #define FORMAT_LENGTH_INT_64 "l" 00295 00296 #elif defined(__GLIBC__) || defined(__sun__) 00297 // With the GNU libc (i.e. Linux), ll will format a 64-bit integer. 00298 #define FORMAT_LENGTH_INT_64 "ll" 00299 00300 #else 00301 // See the target platform's printf(3) man page. 00302 #error Need 64-bit integer format length specified for this platform 00303 #endif 00304 00305 // PathnameSep was defined early-on as a nod to potential Windows 00306 // compatibility. At this point a Windows port of Vesta, at least in 00307 // its current form, seems unlikely. While this constant is 00308 // vestigial, there would be little point in eliminating it. 00309 #ifdef __unix 00310 const char PathnameSep = '/'; 00311 #else // NT 00312 const char PathnameSep = '\\'; 00313 #endif 00314 00315 // Threads 00316 00317 // #define _PTHREAD_USE_INLINE 00318 #include <pthread.h> 00319 #include "Thread.H" 00320 00321 // Text manipulation (i.e., char* with more automatic storage mgmt.) 00322 00323 #include "Text.H" 00324 00325 namespace Basics 00326 { 00327 // Given an integer error value taken from errno, return a Text 00328 // containing the correposning error message. 00329 Text errno_Text(int err); 00330 } 00331 00332 #endif /* _Basics */