diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d0072e4cc9..99862715e9 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,21 @@ 2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2008-11-19 19:30 UTC+0100 Viktor Szakats (harbour.01 syenar hu) + * include/hbapi.h + * source/vm/extend.c + + Added hb_stordl() which is similar to hb_stords() but + accepts a Julian date in long numeric format similarly + to hb_retdl(). + + * contrib/xhb/Makefile + * contrib/xhb/common.mak + + contrib/xhb/filestat.c + + Added FILESTATS() function. + Work of Giancarlo Niccolai / xhb. + Minor cleanups made. + ; Please test. (Only Win32/BCC platform was tested.) + 2008-11-19 18:14 UTC+0100 Viktor Szakats (harbour.01 syenar hu) * source/codepage/cpuakoi.c ! Fixed CP reference to point to KOI8-U instead of KOI8. diff --git a/harbour/contrib/xhb/Makefile b/harbour/contrib/xhb/Makefile index 5e33cfa46e..cf7c999f92 100644 --- a/harbour/contrib/xhb/Makefile +++ b/harbour/contrib/xhb/Makefile @@ -5,6 +5,7 @@ ROOT = ../../ C_SOURCES=\ + filestat.c \ freadlin.c \ hbcrypt.c \ hbxml.c \ diff --git a/harbour/contrib/xhb/common.mak b/harbour/contrib/xhb/common.mak index d939ae2f9c..ffd3f473b9 100644 --- a/harbour/contrib/xhb/common.mak +++ b/harbour/contrib/xhb/common.mak @@ -15,6 +15,7 @@ PRG_HEADERS = \ xhb.ch \ LIB_OBJS = \ + $(OBJ_DIR)filestat$(OBJEXT) \ $(OBJ_DIR)freadlin$(OBJEXT) \ $(OBJ_DIR)hbcrypt$(OBJEXT) \ $(OBJ_DIR)hbxml$(OBJEXT) \ diff --git a/harbour/contrib/xhb/filestat.c b/harbour/contrib/xhb/filestat.c new file mode 100644 index 0000000000..d359b94423 --- /dev/null +++ b/harbour/contrib/xhb/filestat.c @@ -0,0 +1,294 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * FILESTATS() function + * + * Copyright 2004 Giancarlo Niccolai + * + * www - http://www.xharbour.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#define HB_OS_WIN_32_USED + +#include "hbapi.h" +#include "hbapifs.h" +#include "hbdate.h" +#include "hbapierr.h" + +#if defined( OS_UNIX_COMPATIBLE ) + #include + #include + #include + #include + #include +#elif defined( HB_OS_WIN_32 ) + #if ( defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__) || defined( __DMC__ )) && ! defined( INVALID_FILE_ATTRIBUTES ) + #define INVALID_FILE_ATTRIBUTES ((DWORD)(-1)) + #endif +#endif + +static BOOL hb_fsFileStats( + BYTE *pszFileName, + BYTE *pszAttr, + HB_FOFFSET *llSize, + LONG *lcDate, + LONG *lcTime, + LONG *lmDate, + LONG *lmTime ) +{ + BOOL fResult = FALSE; + +#if defined( OS_UNIX_COMPATIBLE ) + + struct stat statbuf; + + if( stat( ( char * ) pszFileName, &statbuf ) == 0 ) + { + // determine if we can read/write/execute the file + USHORT usAttr, ushbAttr = 0; + time_t ftime; +#if _POSIX_C_SOURCE >= 199506L + struct tm tms; +#endif + struct tm *ptms; + + /* See which attribs are applicable */ + if ( statbuf.st_uid == geteuid() ) + { + usAttr = + ((statbuf.st_mode & S_IRUSR ) ? 1 << 2 : 0) | + ((statbuf.st_mode & S_IWUSR ) ? 1 << 1 : 0) | + ((statbuf.st_mode & S_IXUSR ) ? 1 : 0); + } + else if ( statbuf.st_gid == getegid() ) + { + usAttr = + ((statbuf.st_mode & S_IRGRP ) ? 1 << 2 : 0) | + ((statbuf.st_mode & S_IWGRP ) ? 1 << 1 : 0) | + ((statbuf.st_mode & S_IXGRP ) ? 1 : 0); + } + else + { + usAttr = + ((statbuf.st_mode & S_IROTH ) ? 1 << 2 : 0) | + ((statbuf.st_mode & S_IWOTH ) ? 1 << 1 : 0) | + ((statbuf.st_mode & S_IXOTH ) ? 1 : 0); + } + + /* Standard characters */ + if ( (usAttr & 4) == 0 ) /* Hidden (can't read)*/ + ushbAttr |= HB_FA_HIDDEN; + + if ( (usAttr & 2) == 0 ) /* read only (can't write)*/ + ushbAttr |= HB_FA_READONLY; + + if ( (usAttr & 1) == 1 ) /* executable? (xbit)*/ + ushbAttr |= HB_FA_SYSTEM; + + /* Extension characters */ + + if ( ( statbuf.st_mode & S_IFLNK ) == S_IFLNK) + *pszAttr++ = 'Z'; /* Xharbour extension */ + + if ( ( statbuf.st_mode & S_IFSOCK ) == S_IFSOCK ) + *pszAttr++ = 'K'; /* Xharbour extension */ + + /* device */ + if ( ( statbuf.st_mode & S_IFBLK ) == S_IFBLK || + ( statbuf.st_mode & S_IFCHR ) == S_IFCHR ) + ushbAttr |= HB_FA_DEVICE; /* Xharbour extension */ + + if ( ( statbuf.st_mode & S_IFIFO ) == S_IFIFO ) + *pszAttr++ = 'Y'; /* Xharbour extension */ + + if ( S_ISDIR( statbuf.st_mode ) ) + ushbAttr |= HB_FA_DIRECTORY; /* Xharbour extension */ + /* Give the ARCHIVE if readwrite, not executable and not special */ + else if ( S_ISREG( statbuf.st_mode ) && ushbAttr == 0 ) + ushbAttr |= HB_FA_ARCHIVE; + + *llSize = ( HB_FOFFSET ) statbuf.st_size; + + ftime = statbuf.st_mtime; +#if _POSIX_C_SOURCE >= 199506L && !defined( HB_OS_DARWIN_5 ) + ptms = localtime_r( &ftime, &tms ); +#else + ptms = localtime( &ftime ); +#endif + + *lcDate = hb_dateEncode( ptms->tm_year + 1900, + ptms->tm_mon + 1, ptms->tm_mday ); + *lcTime = ptms->tm_hour*3600 + ptms->tm_min * 60 + ptms->tm_sec; + + ftime = statbuf.st_atime; +#if _POSIX_C_SOURCE >= 199506L && !defined( HB_OS_DARWIN_5 ) + ptms = localtime_r( &ftime, &tms ); +#else + ptms = localtime( &ftime ); +#endif + *lmDate = hb_dateEncode( ptms->tm_year + 1900, + ptms->tm_mon + 1, ptms->tm_mday ); + *lmTime = ptms->tm_hour*3600 + ptms->tm_min * 60 + ptms->tm_sec; + + hb_fsAttrDecode( ushbAttr, ( char * ) pszAttr ); + + fResult = TRUE; + } + +#elif defined( HB_OS_WIN_32 ) + + { + DWORD dwAttribs; + WIN32_FIND_DATA ffind; + HANDLE hFind; + FILETIME filetime; + SYSTEMTIME time; + + /* Get attributes... */ + dwAttribs = GetFileAttributes( (char*) pszFileName ); + if ( dwAttribs == INVALID_FILE_ATTRIBUTES ) + { + /* return */ + return FALSE; + } + + hb_fsAttrDecode( hb_fsAttrFromRaw( dwAttribs ), (char*) pszAttr ); + + /* If file existed, do a findfirst */ + hFind = FindFirstFile( (char*) pszFileName, &ffind ); + if ( hFind != INVALID_HANDLE_VALUE ) + { + CloseHandle( hFind ); + + /* get file times and work them out */ + *llSize = ( HB_FOFFSET ) ffind.nFileSizeLow + ( ( HB_FOFFSET ) ffind.nFileSizeHigh << 32 ); + + if ( FileTimeToLocalFileTime( &ffind.ftCreationTime, &filetime ) && + FileTimeToSystemTime( &filetime, &time ) ) + { + *lcDate = hb_dateEncode( time.wYear, time.wMonth, time.wDay ); + *lcTime = time.wHour * 3600 + time.wMinute * 60 + time.wSecond; + } + else + { + *lcDate = hb_dateEncode( 0, 0, 0 ); + *lcTime = 0; + } + + if ( FileTimeToLocalFileTime( &ffind.ftLastAccessTime, &filetime ) && + FileTimeToSystemTime( &filetime, &time ) ) + { + *lmDate = hb_dateEncode( time.wYear, time.wMonth, time.wDay ); + *lmTime = time.wHour * 3600 + time.wMinute * 60 + time.wSecond; + } + else + { + *lcDate = hb_dateEncode( 0, 0, 0 ); + *lcTime = 0; + } + fResult = TRUE; + } + } + +#else + + /* Generic algorithm based on findfirst */ + { + PHB_FFIND findinfo = hb_fsFindFirst( (char*) pszFileName, HB_FA_ALL ); + + if( findinfo ) + { + hb_fsAttrDecode( findinfo->attr, (char*) pszAttr ); + *llSize = ( HB_FOFFSET ) findinfo->size; + *lcDate = findinfo->lDate; + *lcTime = (findinfo->szTime[0] - '0') * 36000 + + (findinfo->szTime[1] - '0') * 3600 + + (findinfo->szTime[3] - '0') * 600 + + (findinfo->szTime[4] - '0') * 60 + + (findinfo->szTime[6] - '0') * 10 + + (findinfo->szTime[7] - '0'); + *lmDate = hb_dateEncode( 0, 0, 0 ); + *lmTime = 0; + hb_fsFindClose( findinfo ); + fResult = TRUE; + } + } + +#endif + + hb_fsSetIOError( fResult, 0 ); + return fResult; +} + +HB_FUNC( FILESTATS ) +{ + BYTE szAttr[21], *szFile = ( BYTE * ) hb_parc( 1 ); + HB_FOFFSET lSize = 0; + LONG lcDate = 0, lcTime = 0, lmDate = 0, lmTime = 0; + + /* Parameter checking */ + if( !szFile || !*szFile ) + { + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, 1, + hb_paramError(1) ); + return; + } + + if ( hb_fsFileStats( szFile, + szAttr, &lSize, &lcDate, &lcTime, &lmDate, &lmTime ) ) + { + hb_storc ( ( char * ) szAttr, 2 ); + hb_stornint( lSize, 3 ); + hb_stordl ( lcDate, 4 ); + hb_stornint( lcTime, 5 ); + hb_stordl ( lmDate, 6 ); + hb_stornint( lmTime, 7 ); + + hb_retl( TRUE ); + } + else + hb_retl( FALSE ); +} diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 207a143fa7..7d3449860f 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -668,6 +668,7 @@ extern HB_EXPORT int hb_storc( const char * szText, int iParam, ... ); /* sto extern HB_EXPORT int hb_storclen( const char * szText, ULONG ulLength, int iParam, ... ); /* stores a fixed length string on a variable by reference */ extern HB_EXPORT int hb_storclen_buffer( char * szText, ULONG ulLength, int iParam, ... ); /* stores a fixed length string buffer on a variable by reference */ extern HB_EXPORT int hb_stords( const char * szDate, int iParam, ... ); /* szDate must have yyyymmdd format */ +extern HB_EXPORT int hb_stordl( long lJulian, int iParam, ... ); /* lJulian must be a date in Julian format */ extern HB_EXPORT int hb_storl( int iLogical, int iParam, ... ); /* stores a logical integer on a variable by reference */ extern HB_EXPORT int hb_storni( int iValue, int iParam, ... ); /* stores an integer on a variable by reference */ extern HB_EXPORT int hb_stornl( long lValue, int iParam, ... ); /* stores a long on a variable by reference */ diff --git a/harbour/source/vm/extend.c b/harbour/source/vm/extend.c index e9b7262f69..cc6c9f99ba 100644 --- a/harbour/source/vm/extend.c +++ b/harbour/source/vm/extend.c @@ -1043,6 +1043,37 @@ int hb_stords( const char * szDate, int iParam, ... ) return 0; } +int hb_stordl( long lJulian, int iParam, ... ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_stordl(%ld, %d, ...)", lJulian, iParam)); + + if( iParam >= -1 && iParam <= hb_pcount() ) + { + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); + BOOL bByRef = HB_IS_BYREF( pItem ); + + if( bByRef ) + pItem = hb_itemUnRef( pItem ); + + if( HB_IS_ARRAY( pItem ) ) + { + int iRetVal; + va_list va; + va_start( va, iParam ); + iRetVal = hb_arraySetDL( pItem, va_arg( va, ULONG ), lJulian ) ? 1 : 0; + va_end( va ); + return iRetVal; + } + else if( bByRef || iParam == -1 ) + { + hb_itemPutDL( pItem, lJulian ); + return 1; + } + } + + return 0; +} + int hb_storl( int iLogical, int iParam, ... ) { HB_TRACE(HB_TR_DEBUG, ("hb_storl(%d, %d, ...)", iLogical, iParam));