Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

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 // 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  */

Generated on Mon May 8 00:48:28 2006 for Vesta by  doxygen 1.4.2