/vesta/vestasys.org/basics/basics/36/src/Basics.H

Go to the documentation of this file.
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  */

Generated on Thu May 24 23:01:37 2007 for Vesta by  doxygen 1.5.1