From 578bfd0aed2ec993f4ad85fa6a7094a852261422 Mon Sep 17 00:00:00 2001 From: Arch Librarian Date: Mon, 20 Sep 2004 16:50:36 +0000 Subject: Base revisions Author: jgg Date: 1998-07-02 02:58:12 GMT Base revisions --- apt-pkg/contrib/error.cc | 139 +++++++++++++++++++++++++++ apt-pkg/contrib/error.h | 84 +++++++++++++++++ apt-pkg/contrib/fileutl.cc | 214 ++++++++++++++++++++++++++++++++++++++++++ apt-pkg/contrib/fileutl.h | 63 +++++++++++++ apt-pkg/contrib/mmap.cc | 227 +++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/contrib/mmap.h | 92 ++++++++++++++++++ apt-pkg/contrib/system.h | 57 ++++++++++++ 7 files changed, 876 insertions(+) create mode 100644 apt-pkg/contrib/error.cc create mode 100644 apt-pkg/contrib/error.h create mode 100644 apt-pkg/contrib/fileutl.cc create mode 100644 apt-pkg/contrib/fileutl.h create mode 100644 apt-pkg/contrib/mmap.cc create mode 100644 apt-pkg/contrib/mmap.h create mode 100644 apt-pkg/contrib/system.h (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc new file mode 100644 index 000000000..59d2b8c8b --- /dev/null +++ b/apt-pkg/contrib/error.cc @@ -0,0 +1,139 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: error.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + Global Erorr Class - Global error mechanism + + We use a simple STL vector to store each error record. A PendingFlag + is kept which indicates when the vector contains a Sever error. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include + +#include + /*}}}*/ + +GlobalError *_error = new GlobalError; + +// GlobalError::GlobalError - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +GlobalError::GlobalError() : PendingFlag(false) +{ +} + /*}}}*/ +// GlobalError::Errno - Get part of the error string from errno /*{{{*/ +// --------------------------------------------------------------------- +/* Function indicates the stdlib function that failed and Description is + a user string that leads the text. Form is: + Description - Function (errno: strerror) + Carefull of the buffer overrun, sprintf. + */ +bool GlobalError::Errno(const char *Function,const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsprintf(S,Description,args); + sprintf(S + strlen(S)," - %s (%i %s)",Function,errno,strerror(errno)); + + // Put it on the list + Item Itm; + Itm.Text = S; + Itm.Error = true; + List.push_back(Itm); + + PendingFlag = true; + + return false; +} + /*}}}*/ +// GlobalError::Error - Add an error to the list /*{{{*/ +// --------------------------------------------------------------------- +/* Just vsprintfs and pushes */ +bool GlobalError::Error(const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsprintf(S,Description,args); + + // Put it on the list + Item Itm; + Itm.Text = S; + Itm.Error = true; + List.push_back(Itm); + + PendingFlag = true; + + return false; +} + /*}}}*/ +// GlobalError::Warning - Add a warning to the list /*{{{*/ +// --------------------------------------------------------------------- +/* This doesn't set the pending error flag */ +bool GlobalError::Warning(const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsprintf(S,Description,args); + + // Put it on the list + Item Itm; + Itm.Text = S; + Itm.Error = false; + List.push_back(Itm); + + return false; +} + /*}}}*/ +// GlobalError::PopMessage - Pulls a single message out /*{{{*/ +// --------------------------------------------------------------------- +/* This should be used in a loop checking empty() each cycle. It returns + true if the message is an error. */ +bool GlobalError::PopMessage(string &Text) +{ + bool Ret = List.front().Error; + Text = List.front().Text; + List.erase(List.begin()); + + // This really should check the list to see if only warnings are left.. + if (empty()) + PendingFlag = false; + + return Ret; +} + /*}}}*/ +// GlobalError::DumpErrors - Dump all of the errors/warns to cerr /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void GlobalError::DumpErrors() +{ + // Print any errors or warnings found + string Err; + while (empty() == false) + { + bool Type = PopMessage(Err); + if (Type == true) + cerr << "E: " << Err << endl; + else + cerr << "W: " << Err << endl; + } +} + /*}}}*/ diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h new file mode 100644 index 000000000..06b998e5e --- /dev/null +++ b/apt-pkg/contrib/error.h @@ -0,0 +1,84 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: error.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + Global Erorr Class - Global error mechanism + + This class has a single global instance. When a function needs to + generate an error condition, such as a read error, it calls a member + in this class to add the error to a stack of errors. + + By using a stack the problem with a scheme like errno is removed and + it allows a very detailed account of what went wrong to be transmitted + to the UI for display. (Errno has problems because each function sets + errno to 0 if it didn't have an error thus eraseing erno in the process + of cleanup) + + Several predefined error generators are provided to handle common + things like errno. The general idea is that all methods return a bool. + If the bool is true then things are OK, if it is false then things + should start being undone and the stack should unwind under program + control. + + A Warning should not force the return of false. Things did not fail, but + they might have had unexpected problems. Errors are stored in a FIFO + so Pop will return the first item.. + + I have some thoughts about extending this into a more general UI<-> + Engine interface, ie allowing the Engine to say 'The disk is full' in + a dialog that says 'Panic' and 'Retry'.. The error generator functions + like errno, Warning and Error return false always so this is normal: + if (open(..)) + return _error->Errno(..); + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_ERROR_H +#define PKGLIB_ERROR_H + +#include +#include + +class GlobalError +{ + struct Item + { + string Text; + bool Error; + }; + + vector List; + bool PendingFlag; + + public: + + // Call to generate an error from a library call. + bool Errno(const char *Function,const char *Description,...); + + /* A warning should be considered less severe than an error, and may be + ignored by the client. */ + bool Error(const char *Description,...); + bool Warning(const char *Description,...); + + // Simple accessors + inline bool PendingError() {return PendingFlag;}; + inline bool empty() {return List.empty();}; + bool PopMessage(string &Text); + void Discard() {List.erase(List.begin(),List.end()); PendingFlag = false;}; + + // Usefull routine to dump to cerr + void DumpErrors(); + + GlobalError(); +}; + +/* The 'extra-ansi' syntax is used to help with collisions. This is the + single global instance of this class. */ +extern GlobalError *_error; + +#endif diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc new file mode 100644 index 000000000..6048ff0bb --- /dev/null +++ b/apt-pkg/contrib/fileutl.cc @@ -0,0 +1,214 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: fileutl.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + File Utilities + + CopyFile - Buffered copy of a single file + GetLock - dpkg compatible lock file manipulation (fcntl) + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include + +#include +#include +#include +#include + /*}}}*/ + +// CopyFile - Buffered copy of a file /*{{{*/ +// --------------------------------------------------------------------- +/* The caller is expected to set things so that failure causes erasure */ +bool CopyFile(File From,File To) +{ + if (From.IsOpen() == false || To.IsOpen() == false) + return false; + + // Buffered copy between fds + unsigned char *Buf = new unsigned char[64000]; + long Size; + while ((Size = read(From.Fd(),Buf,64000)) > 0) + { + if (To.Write(Buf,Size) == false) + { + delete [] Buf; + return false; + } + } + + delete [] Buf; + return true; +} + /*}}}*/ +// GetLock - Gets a lock file /*{{{*/ +// --------------------------------------------------------------------- +/* This will create an empty file of the given name and lock it. Once this + is done all other calls to GetLock in any other process will fail with + -1. The return result is the fd of the file, the call should call + close at some time. */ +int GetLock(string File,bool Errors) +{ + int FD = open(File.c_str(),O_RDWR | O_CREAT | O_TRUNC,0640); + if (FD < 0) + { + if (Errors == true) + _error->Errno("open","Could not open lock file %s",File.c_str()); + return -1; + } + + // Aquire a write lock + struct flock fl; + fl.l_type= F_WRLCK; + fl.l_whence= SEEK_SET; + fl.l_start= 0; + fl.l_len= 1; + if (fcntl(FD,F_SETLK,&fl) == -1) + { + if (Errors == true) + _error->Errno("open","Could not get lock %s",File.c_str()); + close(FD); + return -1; + } + + return FD; +} + /*}}}*/ +// FileExists - Check if a file exists /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FileExists(string File) +{ + struct stat Buf; + if (stat(File.c_str(),&Buf) != 0) + return false; + return true; +} + /*}}}*/ +// SafeGetCWD - This is a safer getcwd that returns a dynamic string /*{{{*/ +// --------------------------------------------------------------------- +/* We return / on failure. */ +string SafeGetCWD() +{ + // Stash the current dir. + char S[300]; + S[0] = 0; + if (getcwd(S,sizeof(S)) == 0) + return "/"; + return S; +} + /*}}}*/ + +// File::File - Open a file /*{{{*/ +// --------------------------------------------------------------------- +/* The most commonly used open mode combinations are given with Mode */ +File::File(string FileName,OpenMode Mode, unsigned long Perms) +{ + Flags = 0; + switch (Mode) + { + case ReadOnly: + iFd = open(FileName.c_str(),O_RDONLY); + break; + + case WriteEmpty: + unlink(FileName.c_str()); + iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms); + break; + + case WriteExists: + iFd = open(FileName.c_str(),O_RDWR); + break; + } + + if (iFd < 0) + _error->Errno("open","Could not open file %s",FileName.c_str()); + else + this->FileName = FileName; +} + /*}}}*/ +// File::~File - Closes the file /*{{{*/ +// --------------------------------------------------------------------- +/* If the proper modes are selected then we close the Fd and possibly + unlink the file on error. */ +File::~File() +{ + Close(); +} + /*}}}*/ +// File::Read - Read a bit of the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool File::Read(void *To,unsigned long Size) +{ + if (read(iFd,To,Size) != (signed)Size) + { + Flags |= Fail; + return _error->Errno("read","Read error"); + } + + return true; +} + /*}}}*/ +// File::Write - Write to the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool File::Write(void *From,unsigned long Size) +{ + if (write(iFd,From,Size) != (signed)Size) + { + Flags |= Fail; + return _error->Errno("write","Write error"); + } + + return true; +} + /*}}}*/ +// File::Seek - Seek in the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool File::Seek(unsigned long To) +{ + if (lseek(iFd,To,SEEK_SET) != (signed)To) + { + Flags |= Fail; + return _error->Error("Unable to seek to %u",To); + } + + return true; +} + /*}}}*/ +// File::Size - Return the size of the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long File::Size() +{ + struct stat Buf; + if (fstat(iFd,&Buf) != 0) + return _error->Errno("fstat","Unable to determine the file size"); + return Buf.st_size; +} + /*}}}*/ +// File::Close - Close the file if the close flag is set /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool File::Close() +{ + bool Res = true; + if ((Flags & AutoClose) == AutoClose) + if (close(iFd) != 0) + Res &= _error->Errno("close","Problem closing the file"); + + if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail && + FileName.empty() == false) + if (unlink(FileName.c_str()) != 0) + Res &= _error->Warning("unlnk","Problem unlinking the file"); + return Res; +} + /*}}}*/ diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h new file mode 100644 index 000000000..1b6666843 --- /dev/null +++ b/apt-pkg/contrib/fileutl.h @@ -0,0 +1,63 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: fileutl.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + File Utilities + + CopyFile - Buffered copy of a single file + GetLock - dpkg compatible lock file manipulation (fcntl) + FileExists - Returns true if the file exists + SafeGetCWD - Returns the CWD in a string with overrun protection + + The file class is a handy abstraction for various functions+classes + that need to accept filenames. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_FILEUTL_H +#define PKGLIB_FILEUTL_H + +#include + +class File +{ + protected: + int iFd; + + enum LocalFlags {AutoClose = (1<<0),Fail = (1<<1),DelOnFail = (1<<2)}; + unsigned long Flags; + string FileName; + + public: + enum OpenMode {ReadOnly,WriteEmpty,WriteExists}; + + bool Read(void *To,unsigned long Size); + bool Write(void *From,unsigned long Size); + bool Seek(unsigned long To); + unsigned long Size(); + bool Close(); + + // Simple manipulators + inline int Fd() {return iFd;}; + inline bool IsOpen() {return iFd >= 0;}; + inline bool Failed() {return (Flags & Fail) == Fail;}; + inline void EraseOnFailure() {Flags |= DelOnFail;}; + inline void OpFail() {Flags |= Fail;}; + + File(string FileName,OpenMode Mode,unsigned long Perms = 0666); + File(int Fd) : iFd(Fd), Flags(AutoClose) {}; + File(int Fd,bool) : iFd(Fd), Flags(0) {}; + virtual ~File(); +}; + +bool CopyFile(string From,string To); +int GetLock(string File,bool Errors = true); +bool FileExists(string File); +string SafeGetCWD(); + +#endif diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc new file mode 100644 index 000000000..85cac1cca --- /dev/null +++ b/apt-pkg/contrib/mmap.cc @@ -0,0 +1,227 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: mmap.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + MMap Class - Provides 'real' mmap or a faked mmap using read(). + + MMap cover class. + + Some broken versions of glibc2 (libc6) have a broken definition + of mmap that accepts a char * -- all other systems (and libc5) use + void *. We can't safely do anything here that would be portable, so + libc6 generates warnings -- which should be errors, g++ isn't properly + strict. + + The configure test notes that some OS's have broken private mmap's + so on those OS's we can't use mmap. This means we have to use + configure to test mmap and can't rely on the POSIX + _POSIX_MAPPED_FILES test. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#define _BSD_SOURCE +#include +#include + +#include +#include +#include +#include +#include + /*}}}*/ + +// MMap::MMap - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +MMap::MMap(File &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0), + Base(0) +{ + if ((Flags & NoImmMap) != NoImmMap) + Map(); +} + /*}}}*/ +// MMap::~MMap - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +MMap::~MMap() +{ + Close(true); +} + /*}}}*/ +// MMap::Map - Perform the mapping /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Map() +{ + iSize = Fd.Size(); + + // Set the permissions. + int Prot = PROT_READ; + int Map = MAP_SHARED; + if ((Flags & ReadOnly) != ReadOnly) + Prot |= PROT_WRITE; + if ((Flags & Public) != Public) + Map = MAP_PRIVATE; + + // Map it. + Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0); + if (Base == (void *)-1) + return _error->Errno("mmap","Couldn't make mmap of %u bytes",iSize); + + return true; +} + /*}}}*/ +// MMap::Close - Close the map /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Close(bool DoClose) +{ + if (Fd.IsOpen() == false) + return true; + + Sync(); + + if (munmap((char *)Base,iSize) != 0) + _error->Warning("Unable to munmap"); + + iSize = 0; + if (DoClose == true) + Fd.Close(); + return true; +} + /*}}}*/ +// MMap::Sync - Syncronize the map with the disk /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Sync() +{ + if ((Flags & ReadOnly) == ReadOnly) + if (msync((char *)Base,iSize,MS_SYNC) != 0) + return _error->Error("msync","Unable to write mmap"); + return true; +} + /*}}}*/ +// MMap::Sync - Syncronize a section of the file to disk /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Sync(unsigned long Start,unsigned long Stop) +{ + if ((Flags & ReadOnly) == ReadOnly) + if (msync((char *)Base+(int)(Start/PAGE_SIZE)*PAGE_SIZE,Stop - Start,MS_SYNC) != 0) + return _error->Error("msync","Unable to write mmap"); + return true; +} + /*}}}*/ + +// DynamicMMap::DynamicMMap - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +DynamicMMap::DynamicMMap(File &F,unsigned long Flags,unsigned long WorkSpace) : + MMap(F,Flags | NoImmMap), WorkSpace(WorkSpace) +{ + unsigned long EndOfFile = Fd.Size(); + Fd.Seek(WorkSpace); + char C = 0; + Fd.Write(&C,sizeof(C)); + Map(); + iSize = EndOfFile; +} + /*}}}*/ +// DynamicMMap::~DynamicMMap - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* We truncate the file to the size of the memory data set */ +DynamicMMap::~DynamicMMap() +{ + unsigned long EndOfFile = iSize; + Close(false); + ftruncate(Fd.Fd(),EndOfFile); + Fd.Close(); +} + /*}}}*/ +// DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long DynamicMMap::RawAllocate(unsigned long Size) +{ + unsigned long Result = iSize; + iSize += Size; + + // Just in case error check + if (Result > WorkSpace) + { + _error->Error("Dynamic MMap ran out of room"); + return 0; + } + + return Result; +} + /*}}}*/ +// DynamicMMap::Allocate - Pooled aligned allocation /*{{{*/ +// --------------------------------------------------------------------- +/* This allocates an Item of size ItemSize so that it is aligned to its + size in the file. */ +unsigned long DynamicMMap::Allocate(unsigned long ItemSize) +{ + // Look for a matching pool entry + Pool *I; + Pool *Empty = 0; + for (I = Pools; I != Pools + PoolCount; I++) + { + if (I->ItemSize == 0) + Empty = I; + if (I->ItemSize == ItemSize) + break; + } + + // No pool is allocated, use an unallocated one + if (I == Pools + PoolCount) + { + // Woops, we ran out, the calling code should allocate more. + if (Empty == 0) + { + _error->Error("Ran out of allocation pools"); + return 0; + } + + I = Empty; + I->ItemSize = ItemSize; + I->Count = 0; + } + + // Out of space, allocate some more + if (I->Count == 0) + { + I->Count = 20*1024/ItemSize; + I->Start = RawAllocate(I->Count*ItemSize); + } + + I->Count--; + unsigned long Result = I->Start; + I->Start += ItemSize; + return Result/ItemSize; +} + /*}}}*/ +// DynamicMMap::WriteString - Write a string to the file /*{{{*/ +// --------------------------------------------------------------------- +/* Strings are not aligned to anything */ +unsigned long DynamicMMap::WriteString(const char *String, + unsigned long Len) +{ + unsigned long Result = iSize; + // Just in case error check + if (Result > WorkSpace) + { + _error->Error("Dynamic MMap ran out of room"); + return 0; + } + + if (Len == 0) + Len = strlen(String); + iSize += Len + 1; + memcpy((char *)Base + Result,String,Len); + ((char *)Base)[Result + Len] = 0; + return Result; +} + /*}}}*/ diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h new file mode 100644 index 000000000..096304177 --- /dev/null +++ b/apt-pkg/contrib/mmap.h @@ -0,0 +1,92 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: mmap.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + MMap Class - Provides 'real' mmap or a faked mmap using read(). + + The purpose of this code is to provide a generic way for clients to + access the mmap function. In enviroments that do not support mmap + from file fd's this function will use read and normal allocated + memory. + + Writing to a public mmap will always fully comit all changes when the + class is deleted. Ie it will rewrite the file, unless it is readonly + + The DynamicMMap class is used to help the on-disk data structure + generators. It provides a large allocated workspace and members + to allocate space from the workspace in an effecient fashion. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_MMAP_H +#define PKGLIB_MMAP_H + +#include +#include + +class MMap +{ + protected: + + File &Fd; + unsigned long Flags; + unsigned long iSize; + void *Base; + + bool Map(); + bool Close(bool DoClose = true); + + public: + + enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2)}; + + // Simple accessors + inline operator void *() {return Base;}; + inline void *Data() {return Base;}; + inline unsigned long Size() {return iSize;}; + + // File manipulators + bool Sync(); + bool Sync(unsigned long Start,unsigned long Stop); + + MMap(File &F,unsigned long Flags); + virtual ~MMap(); +}; + +class DynamicMMap : public MMap +{ + public: + + // This is the allocation pool structure + struct Pool + { + unsigned long ItemSize; + unsigned long Start; + unsigned long Count; + }; + + protected: + + unsigned long WorkSpace; + Pool *Pools; + unsigned int PoolCount; + + public: + + // Allocation + unsigned long RawAllocate(unsigned long Size); + unsigned long Allocate(unsigned long ItemSize); + unsigned long WriteString(const char *String,unsigned long Len = 0); + inline unsigned long WriteString(string S) {return WriteString(S.begin(),S.size());}; + void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;}; + + DynamicMMap(File &F,unsigned long Flags,unsigned long WorkSpace = 1024*1024); + virtual ~DynamicMMap(); +}; + +#endif diff --git a/apt-pkg/contrib/system.h b/apt-pkg/contrib/system.h new file mode 100644 index 000000000..e652348b0 --- /dev/null +++ b/apt-pkg/contrib/system.h @@ -0,0 +1,57 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: system.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + System Header - Usefull private definitions + + This source is placed in the Public Domain, do with it what you will + It was originally written by Brian C. White. + + ##################################################################### */ + /*}}}*/ +// Private header +// Header section: / +#ifndef SYSTEM_H +#define SYSTEM_H + +// MIN_VAL(SINT16) will return -0x8000 and MAX_VAL(SINT16) = 0x7FFF +#define MIN_VAL(t) (((t)(-1) > 0) ? (t)( 0) : (t)(((1L<<(sizeof(t)*8-1)) ))) +#define MAX_VAL(t) (((t)(-1) > 0) ? (t)(-1) : (t)(((1L<<(sizeof(t)*8-1))-1))) + +// Min/Max functions +#if defined(__HIGHC__) +#define MIN(x,y) _min(x,y) +#define MAX(x,y) _max(x,y) +#endif + +// GNU C++ has a min/max operator +#if defined(__GNUG__) +#define MIN(A,B) ((A) ? (B)) +#endif + +/* Templates tend to mess up existing code that uses min/max because of the + strict matching requirements */ +#if !defined(MIN) +#define MIN(A,B) ((A) < (B)?(A):(B)) +#define MAX(A,B) ((A) > (B)?(A):(B)) +#endif + +/* Bound functions, bound will return the value b within the limits a-c + bounv will change b so that it is within the limits of a-c. */ +#define _bound(a,b,c) MIN(c,MAX(b,a)) +#define _boundv(a,b,c) b = _bound(a,b,c) +#define ABS(a) (((a) < (0)) ?-(a) : (a)) + +/* Usefull count macro, use on an array of things and it will return the + number of items in the array */ +#define _count(a) (sizeof(a)/sizeof(a[0])) + +// Flag Macros +#define FLAG(f) (1L << (f)) +#define SETFLAG(v,f) ((v) |= FLAG(f)) +#define CLRFLAG(v,f) ((v) &=~FLAG(f)) +#define CHKFLAG(v,f) ((v) & FLAG(f) ? true : false) + +#endif -- cgit v1.2.3