// $Id: common.cxx,v 1.20 2000/09/06 21:14:26 cnidr Exp $ /************************************************************************ Copyright Notice Copyright (c) MCNC, Clearinghouse for Networked Information Discovery and Retrieval, 1994. Permission to use, copy, modify, distribute, and sell this software and its documentation, in whole or in part, for any purpose is hereby granted without fee, provided that 1. The above copyright notice and this permission notice appear in all copies of the software and related documentation. Notices of copyright and/or attribution which appear at the beginning of any file included in this distribution must remain intact. 2. Users of this software agree to make their best efforts (a) to return to MCNC any improvements or extensions that they make, so that these may be included in future releases; and (b) to inform MCNC/CNIDR of noteworthy uses of this software. 3. The names of MCNC and Clearinghouse for Networked Information Discovery and Retrieval may not be used in any advertising or publicity relating to the software without the specific, prior written permission of MCNC/CNIDR. THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MCNC/CNIDR BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ************************************************************************/ /*@@@ File: common.cxx Version: $Revision: 1.20 $ Description: Common functions Author: Nassib Nassar, nrn@cnidr.org @@@*/ #include #include #include #include #include #if (defined(_MSDOS) || defined(_WIN32)) && !defined(UNIX) #include #define DIR_SLASH '\\' #endif #ifdef UNIX #include #define DIR_SLASH '/' #endif #include "common.hxx" #ifdef HAS__FUNC__ void panic(const char *filename, const char *func, long line) #else void panic(const char *filename, long line) #endif { cerr << endl << "?Panic in line " << line << " of file " << filename #ifdef HAS__FUNC__ << "[" << func << "()]" #endif << endl; (void)perror("Unexpected error condition"); abort(); } void AddTrailingSlash(STRING* PathName) { STRINGINDEX x; if ( ((x=PathName->GetLength()) > 1) && (PathName->GetChr(x) != DIR_SLASH) ) { PathName->Cat(DIR_SLASH); } } void RemovePath(STRING* FileName) { STRINGINDEX x; if ((x=FileName->SearchReverse(DIR_SLASH)) != 0) { FileName->EraseBefore(x+1); } } void RemoveFileName(STRING* PathName) { STRINGINDEX x; x = PathName->SearchReverse(DIR_SLASH); PathName->EraseAfter(x); } void RemoveFileExtension(STRING* PathName) { STRINGINDEX x; x = PathName->SearchReverse('.'); PathName->EraseAfter(x); } off_t GetFileSize(const STRING FileName) { struct stat status; if (stat(FileName,&status) != 0) { return (off_t)-1; } return status.st_size; } off_t GetFileSize(const CHR* FileName) { struct stat status; if (stat(FileName,&status) != 0) { return (off_t)-1; } return status.st_size; } off_t GetFileSize(FILE* FilePointer) { /* LONG Position, Size; Position = ftell(FilePointer); fseek(FilePointer, 0L, SEEK_END); Size = ftell(FilePointer); fseek(FilePointer, Position, SEEK_SET); return Size; */ struct stat status; if (fstat(fileno(FilePointer),&status) != 0) { return (off_t)-1; } return status.st_size; } // Returs GDT_TRUE if it is a regular file GDT_BOOLEAN IsFile(const STRING FileName) { #if (defined(_MSDOS) || defined(_WIN32)) && !defined(UNIX) struct _stat status; if (_stat(FileName,&status) != 0) #else struct stat status; if (stat(FileName,&status) != 0) #endif { return GDT_FALSE; } #if (defined(_MSDOS) || defined(_WIN32)) && !defined(UNIX) if (_S_IFREG && status.st_mode) #else if (S_ISREG(status.st_mode)) #endif { return GDT_TRUE; } return GDT_FALSE; } GDT_BOOLEAN IsFile(const CHR* FileName) { #if (defined(_MSDOS) || defined(_WIN32)) && !defined(UNIX) struct _stat status; if (_stat(FileName,&status) != 0) #else struct stat status; if (stat(FileName,&status) != 0) #endif { return GDT_FALSE; } #if (defined(_MSDOS) || defined(_WIN32)) && !defined(UNIX) if (_S_IFREG && status.st_mode) #else if (S_ISREG(status.st_mode)) #endif { return GDT_TRUE; } return GDT_FALSE; } void ExpandFileSpec(STRING* FileSpec) { #if defined(_MSDOS) || defined(_WIN32) if ( FileSpec->GetLength() >= 3 && isalpha(FileSpec->GetChr(1)) && FileSpec->GetChr(2) == ':' && FileSpec->GetChr(3) == DIR_SLASH) { return; } #endif if (FileSpec->GetChr(1) == DIR_SLASH) { return; } STRING OldFileSpec; STRING NewFileSpec; STRINGINDEX p, p2; STRING s; INT Special; CHR Cwd[1024]; getcwd(Cwd, 1022); NewFileSpec = Cwd; AddTrailingSlash(&NewFileSpec); OldFileSpec = *FileSpec; while ( (p=OldFileSpec.Search(DIR_SLASH)) != 0) { Special = 0; s = OldFileSpec; s.EraseAfter(p); #if defined (_MSDOS) || defined (_WIN32) if ( (s.Equals(".\\")) || (s.Equals("\\")) ) #else if ( (s.Equals("./")) || (s.Equals("/")) ) #endif { Special = 1; } #if defined (_MSDOS) || defined (_WIN32) if (s.Equals("..\\")) #else if (s.Equals("../")) #endif { Special = 1; p2 = NewFileSpec.SearchReverse(DIR_SLASH); if (p2 > 1) { NewFileSpec.EraseAfter(p2-1); } p2 = NewFileSpec.SearchReverse(DIR_SLASH); NewFileSpec.EraseAfter(p2); } if (!Special) { NewFileSpec.Cat(s); } OldFileSpec.EraseBefore(p+1); } NewFileSpec.Cat(OldFileSpec); *FileSpec = NewFileSpec; } void GpSwab(PGPTYPE GpPtr) { GPTYPE Gp; #ifdef CROSS_PLATFORM swab((CHR*)GpPtr, (CHR*)&Gp, sizeof(GPTYPE)); #endif *((UINT2*)GpPtr) = (UINT2)((UINT2)*(((UINT2*)&Gp)+1)); *(((UINT2*)GpPtr)+1) = (UINT2)*((UINT2*)&Gp); } GDT_BOOLEAN IsBigEndian() { UINT2 Test = 1; return (*((PUCHR)(&Test)) == 0) ? GDT_TRUE : GDT_FALSE; } GDT_BOOLEAN DBExists(const STRING FileSpec) { struct stat info; GDT_BOOLEAN exists=GDT_FALSE; CHR *CheckName1; CHR *CheckName2; STRING IndexFile; STRING VirtualFile; IndexFile = FileSpec; IndexFile.Cat(".dbi"); CheckName1 = IndexFile.NewCString(); VirtualFile = FileSpec; VirtualFile.Cat(".vdb"); CheckName2 = VirtualFile.NewCString(); if (stat(CheckName1, &info) ==0) { exists = GDT_TRUE; } else if (stat(CheckName2, &info) ==0) { exists = GDT_TRUE; } delete CheckName1; delete CheckName2; return(exists); } INT rename(const STRING From, const STRING To) { #if defined(_MSDOS) || defined(_WIN32) // MSDOS / WIN32 rename does not remove an existing file so // we have to do it ourselves. remove(To); #endif return rename(From, To); } // From Ahti "Ade" Nevalainen to handle non-latin chars GDT_BOOLEAN IsAlnum(int c) { if ( !(isspace(c)) && !(iscntrl(c)) && !(ispunct(c) )) { return GDT_TRUE; } else if (c == '_') { return GDT_TRUE; } return GDT_FALSE; } /* INT IsAlnum(int c) { if ( !(isspace(c)) && !(iscntrl(c)) && !(ispunct(c) )) { return 1; return 0; } */ void trimWhitespace(char* s) { // trim off end space char* p = s + strlen(s) - 1; while ( (p >= s) && (isspace(*p)) ) { p--; } *(p+1) = '\0'; // trim off beginning space p = s; while ( (*p != '\0') && (isspace(*p)) ) { p++; } memmove(s, p, strlen(p) + 1); } DOUBLE ParseIsoDate(const STRING DateString) { // Now, parse out the ISO-8601 date and convert to fractional day STRINGINDEX ptr; STRING TmpDate,TmpTime; INT len; INT YYYY,MM,DD; INT hh,mm; FLOAT ss; DOUBLE date_val,time_val; TmpDate = DateString; if (TmpDate.GetLength() == 0) return 0.0; ptr = TmpDate.Search('T'); if (ptr) { TmpDate.EraseAfter(ptr-1); TmpTime = DateString; TmpTime.EraseBefore(ptr+1); len = TmpTime.Search('Z'); TmpTime.EraseAfter(len-1); // cout << "Split " << DateString << " into " << TmpDate << " and " << TmpTime << endl; } else { TmpDate = DateString; time_val = 0.0; // cout << "Date is " << TmpDate << endl; } // Now, we have the date and time in separate strings, so convert them // each to numeric values // // First, the date ptr = TmpDate.Search('-'); if (ptr) { // The format is YYYY-MM-DD CHR *tDate; tDate = TmpDate.NewCString(); if (isdigit(tDate[0])) { // We might have to look explictly for - if the formatting is bad sscanf(tDate,"%4d-%2d-%2d",&YYYY,&MM,&DD); sprintf(tDate,"%04d%02d%02d",YYYY,MM,DD); TmpDate = tDate; date_val = TmpDate.GetFloat(); } else { return -99999999.0; } delete [] tDate; } ptr = TmpTime.Search(':'); if (ptr) { CHR *tTime; tTime = TmpTime.NewCString(); // We might have to look explictly for : if the formatting is bad sscanf(tTime,"%2d:%2d:%f",&hh,&mm,&ss); time_val = (((ss/60.0) + mm)/60.0 + hh)/24.0; delete [] tTime; } return (date_val + time_val); }