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