diff --git a/harbour/ChangeLog b/harbour/ChangeLog index dcce8d9c49..f2fa6f4144 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,214 @@ 2002-12-01 23:12 UTC+0100 Foo Bar */ +2004-10-11 21:40 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/Makefile + + harbour/make_bsd.sh + + harbour/make_drw.sh + * harbour/make_tgz.sh + + harbour/bin/hb-func.sh + * harbour/bin/pack_src.sh + + harbour/bin/postinst.bat + + harbour/bin/postinst.sh + * harbour/config/dir.cf + * harbour/config/bsd/gcc.cf + * harbour/config/bsd/global.cf + + harbour/config/darwin/dir.cf + + harbour/config/darwin/gcc.cf + + harbour/config/darwin/global.cf + + harbour/config/darwin/install.cf + * harbour/config/dos/dir.cf + * harbour/config/dos/global.cf + * harbour/config/dos/install.cf + * harbour/config/dos/owatcom.cf + * harbour/config/dos/watcom.cf + * harbour/config/linux/gcc.cf + * harbour/config/linux/global.cf + * harbour/contrib/Makefile + * harbour/contrib/dot/pp_harb.ch + * harbour/contrib/libct/Makefile + * harbour/contrib/libct/bit1.c + * harbour/contrib/libct/bit2.c + * harbour/contrib/libct/bit3.c + * harbour/contrib/libct/files.c + * harbour/contrib/libct/ftoc.c + - harbour/contrib/libct/invertwin.prg + + harbour/contrib/libct/invrtwin.prg + * harbour/contrib/libct/keyset.c + * harbour/contrib/libct/makefile.bc + * harbour/contrib/libmisc/dates2.c + * harbour/contrib/rdd_ads/ads1.c + * harbour/contrib/rdd_ads/adsfunc.c + * harbour/contrib/samples/date.c + * harbour/include/dbinfo.ch + * harbour/include/hbapi.h + * harbour/include/hbapicdp.h + * harbour/include/hbapifs.h + * harbour/include/hbapigt.h + * harbour/include/hbapiitm.h + * harbour/include/hbcomp.h + * harbour/include/hbdate.h + * harbour/include/hbdbf.h + * harbour/include/hbdbferr.h + * harbour/include/hbdefs.h + * harbour/include/hbexprb.c + * harbour/include/hbexprc.c + * harbour/include/hbexprop.h + * harbour/include/hbmacro.h + * harbour/include/hbmath.h + * harbour/include/hbpcode.h + * harbour/include/hbrddcdx.h + * harbour/include/hbrdddbf.h + * harbour/include/hbrdddbt.h + * harbour/include/hbrddfpt.h + * harbour/include/hbrddntx.h + * harbour/include/hbset.h + * harbour/include/hbsetup.h + * harbour/include/set.ch + * harbour/source/common/Makefile + * harbour/source/common/expropt1.c + * harbour/source/common/expropt2.c + - harbour/source/common/hbffind.c + * harbour/source/common/hbfsapi.c + * harbour/source/common/hbstr.c + * harbour/source/common/hbver.c + + harbour/source/common/hbverdsp.c + * harbour/source/compiler/genc.c + * harbour/source/compiler/gencli.c + * harbour/source/compiler/harbour.c + * harbour/source/compiler/harbour.l + * harbour/source/compiler/harbour.slx + * harbour/source/compiler/harbour.sly + * harbour/source/compiler/harbour.y + * harbour/source/compiler/hbfix.c + * harbour/source/compiler/hbpcode.c + * harbour/source/compiler/hbusage.c + * harbour/source/compiler/simplex.c + * harbour/source/macro/macro.l + * harbour/source/macro/macro.slx + * harbour/source/macro/macro.y + * harbour/source/pp/ppcore.c + * harbour/source/rdd/dbcmd.c + * harbour/source/rdd/dbf1.c + * harbour/source/rdd/dbfcdx/dbfcdx1.c + - harbour/source/rdd/dbfcdx/dbfcdx1.h + * harbour/source/rdd/dbffpt/dbffpt1.c + * harbour/source/rdd/dbfntx/dbfntx1.c + * harbour/source/rtl/Makefile + * harbour/source/rtl/abs.c + * harbour/source/rtl/at.c + * harbour/source/rtl/datec.c + * harbour/source/rtl/dates.c + * harbour/source/rtl/dateshb.c + * harbour/source/rtl/datesx.c + * harbour/source/rtl/empty.c + * harbour/source/rtl/errorapi.c + * harbour/source/rtl/errorint.c + * harbour/source/rtl/filesys.c + * harbour/source/rtl/fstemp.c + + harbour/source/rtl/hbffind.c + * harbour/source/rtl/hbrandom.c + * harbour/source/rtl/idle.c + * harbour/source/rtl/inkey.c + * harbour/source/rtl/math.c + * harbour/source/rtl/minmax.c + * harbour/source/rtl/pad.c + * harbour/source/rtl/padc.c + * harbour/source/rtl/padl.c + * harbour/source/rtl/padr.c + * harbour/source/rtl/philes.c + * harbour/source/rtl/round.c + * harbour/source/rtl/soundex.c + * harbour/source/rtl/str.c + * harbour/source/rtl/strcase.c + * harbour/source/rtl/strmatch.c + * harbour/source/rtl/strtran.c + * harbour/source/rtl/strzero.c + * harbour/source/rtl/substr.c + * harbour/source/rtl/val.c + * harbour/source/rtl/gtcrs/gtcrs.c + * harbour/source/rtl/gtcrs/kbdcrs.c + * harbour/source/rtl/gtdos/gtdos.c + * harbour/source/rtl/gtsln/gtsln.c + * harbour/source/rtl/gtsln/kbsln.c + * harbour/source/rtl/gtsln/keytrans.c + * harbour/source/vm/arrays.c + * harbour/source/vm/codebloc.c + * harbour/source/vm/estack.c + * harbour/source/vm/eval.c + * harbour/source/vm/extend.c + * harbour/source/vm/hvm.c + * harbour/source/vm/itemapi.c + * harbour/source/vm/macro.c + * harbour/source/vm/memvars.c + * harbour/source/vm/runner.c + * harbour/tests/bldtest/bldtest.c + * harbour/utils/hbtest/hbtest.prg + * harbour/utils/hbtest/rt_misc.prg + * harbour/utils/hbtest/rt_str.prg + * Sorry but it's too much modification for full description + cvs diff gives file 785982 bytes length. So I only count the + main things: + ! cleand the code (no more warning messages under Linux and GCC and + DOS OpenWatcom) - some of them were real bugs + ! cleaned all endian dependend code I've found - now Harbour can be + compiled on LITLE and BIG endian machines - for some other like + PDP ENDIAN it's enough to define proper macros in hbdefs.h + + added macros for to get/put values in chosen byte order: + HB_GET_LE_[U]INT{16,24,32,64}( pPtr ) + HB_GET_BE_[U]INT{16,24,32,64}( pPtr ) + HB_PUT_LE_[U]INT{16,24,32,64}( pPtr, nVal ) + HB_PUT_BE_[U]INT{16,24,32,64}( pPtr, nVal ) + + added macro HB_CAST_BYTE_NUMBERS_OFF which disables casting in + HB_{GET|PUT}_{LE|BE}_* macros - it's necessary for some platforms + like ALPHA DEC. + ! cleaned the code for 64bit machines + * changed all parameters in hb_date* functions (day, month, year, week) + from LONG to int - it doesn't change binary compatibility for 32bit + machines but can cause troubles with compiling the old source + + changed HB_IT_LONG type to HB_LONG which is mapped to long long + by default for 32 bit machines. + + change HB_IT_INTEGER to be real 'int' C type not 'short int' + + added HB_IS_NUMINT() macro + + added hb_parnll, hb_stornll, hb_retnll, hbretnlllen, hb_itemPutNLL, + hb_itemPutNLLLen, hb_itemGetNLL which operates on LONGLONG + + added hb_parnint, hb_stornint, hb_retnint, hb_retnintlen, + hb_itemPutNInt, hb_itemPutNIntLen, hb_itemGetNInt which operates on + HB_LONG + + added HB_PUSHLONGLONG pcode + + changed compiler and optimizer to use HB_LONG numbers and reduce + conversion from to double which may damage the 64bit number. + + common functions for string to number conversions for compiler, RTL + and RDD to reduce problems with differ FL values for the same number: + hb_compStrToNum(), hb_valStrnToNum(), hb_strToNum(), hb_strnToNum() + + common function hb_numRoun() which uses exactly the same algorithms + as string to number conversion for the same reason - please keep + this functions together. + + hack inside hb_numRound() similar to the one used by CL5.3 + + hb_numInt() which uses uses the same hack as hb_numRound() + + rewritten number to string conversion + + some new string manipulation functions hb_strncpy(), hb_strncat(), ... + They works differ the the C one - always set 0 at the end, the buffer + has to be n+1 bytes length, the n is total size of buffer not the + left free space. + ! cleaned some code which operates on ASCIIZ string to avoid potential + buffer overflow + + updated RDD code - it's the first part - in few days I plan to change + workarea structure in both projects - it will break any 3rd party RDDs + so they have to be updated. I want to add SUPERTABLE into workarea + to allow creating new RDD on-line. + ! cleaned the bugs with negating integers - on most machines (like x86) + the integers are not 0 symmetric - it means that x = -x does not work + for {INT,LONG,LONGLONG}_MIN (hb_vmNegate, ABS()) + + cleaned error messages to be Clipper compatible. + + updated build process for .DEB packages - now hb* scripts and shared + libs are created by standard make install + * added new .prg #defines: __PLATFORM__, + __ARCH{16|32|64}BIT__, __LITTLE_ENDIAN__|__BIG_ENDIAN__|__PDP_ENDIAN__ + !!! cPlatfrom can have lower letters (for xHarbour compatibility) + If you do not like it please change it. + * others ... + 2004-10-10 21:35 UTC+0300 Alexander Kresin * source/rdd/dbfntx/dbfntx1.c ! Fixed a bug, introduced in a last change. diff --git a/harbour/Makefile b/harbour/Makefile index 4e18027acc..1e3c2950ca 100644 --- a/harbour/Makefile +++ b/harbour/Makefile @@ -12,4 +12,25 @@ DIRS=\ contrib \ # samples \ + +ifeq ($(HB_POSTINST),) + +ifneq ($(HB_ROOTPOSTINST),) +HB_POSTINST = $(HB_ROOTPOSTINST) $(HB_POSTINSTPARAM) +else +ifneq ($(SHLVL),) +HB_POSTINST = $(TOP)$(ROOT)bin/postinst.sh $(HB_POSTINSTPARAM) +else +ifeq ($(HB_ARCHITECTURE),dos) +HB_POSTINST = $(subst /,\,$(TOP)$(ROOT)bin/postinst.bat) $(HB_POSTINSTPARAM) +else +ifeq ($(HB_ARCHITECTURE),w32) +HB_POSTINST = $(subst /,\,$(TOP)$(ROOT)bin/postinst.bat) $(HB_POSTINSTPARAM) +endif +endif +endif +endif + +endif + include $(ROOT)config/dir.cf diff --git a/harbour/bin/hb-func.sh b/harbour/bin/hb-func.sh new file mode 100644 index 0000000000..8010502c50 --- /dev/null +++ b/harbour/bin/hb-func.sh @@ -0,0 +1,492 @@ +#!/bin/sh +[ "$BASH" ] || exec bash `which $0` ${1+"$@"} +# +# $Id$ +# + +# --------------------------------------------------------------- +# Copyright 2003 Przemyslaw Czerpak +# small set of functions used by Harbour scripts +# warnig: some bash extensions are used +# +# See doc/license.txt for licensing terms. +# --------------------------------------------------------------- + +get_hbplatform() +{ + local id + + # please add your distro suffix if it not belong to the one recognized below + # and remember that order checking can be important + + [ "${id}" = "" ] && id=`rel=$(rpm -q --queryformat='.%{VERSION}' mandrake-release 2>/dev/null) && echo "mdk$rel"|tr -d "."` + [ "${id}" = "" ] && id=`rel=$(rpm -q --queryformat='.%{VERSION}' redhat-release 2>/dev/null) && echo "rh$rel"|tr -d "."` + [ "${id}" = "" ] && id=`rel=$(rpm -q --queryformat='.%{VERSION}' fedora-release 2>/dev/null) && echo "fc$rel"|tr -d "."` + [ "${id}" = "" ] && id=`rel=$(rpm -q --queryformat='.%{VERSION}' suse-release 2>/dev/null) && echo "fc$rel"|tr -d "."` + [ "${id}" = "" ] && id=`rel=$(rpm -q --queryformat='.%{VERSION}' conectiva-release 2>/dev/null) && echo "cl$rel"|tr -d "."` + [ "${id}" = "" ] && id=`rel=$(rpm -q --queryformat='.%{VERSION}' aurox-release 2>/dev/null) && echo "cl$rel"|tr -d "."` + [ "${id}" = "" ] && id=`[ -f /etc/pld-release ] && cat /etc/pld-release|sed -e '/1/ !d' -e 's/[^0-9]//g' -e 's/^/pld/'` + echo -n "${id}" +} + +get_hbver() +{ + local FVER MAJOR MINOR REVIS hb_rootdir + + hb_rootdir="${1-.}" + FVER="${hb_rootdir}/include/hbver.h" + MAJOR=`sed -e '/HB_VER_MAJOR/ s/[^0-9]*\([^ ]*\).*/\1/g p' -e 'd' "${FVER}"` + MINOR=`sed -e '/HB_VER_MINOR/ s/[^0-9]*\([^ ]*\).*/\1/g p' -e 'd' "${FVER}"` + REVIS=`sed -e '/HB_VER_REVISION/ s/[^0-9]*\([^ ]*\).*/\1/g p' -e 'd' "${FVER}"` + echo -n "${MAJOR}.${MINOR}.${REVIS}" +} + +get_solibname() +{ + local name + + name="${HB_SHAREDLIB_NAME}" + [ -z "${name}" ] && name="harbour" + echo -n "${name}" +} + +mk_hbgetlibs() +{ + if [ -z "$@" ] + then + echo -n "vm pp rtl rdd dbfdbt dbffpt dbfcdx dbfntx ${HB_DB_DRVEXT} macro common lang codepage gtnul gtcrs gtsln gtxvt gtxwc gtalleg gtcgi gtstd gtpca gtwin gtwvt gtdos gtos2 debug profiler" + else + echo -n "$@" + fi +} + +mk_hbgetlibsctb() +{ + if [ -z "$@" ] + then + echo -n "ct rddads" + else + echo -n "$@" + fi +} + +mk_hbtools() +{ + local name hb_pref hb_tool hb_libs hb_libsc + + name=`get_solibname` + hb_pref="$4" + [ -z "${hb_pref}" ] && hb_pref="${HB_TOOLS_PREF-hb}" + hb_cmpname="${HB_CMPNAME-harbour}" + if [ "${HB_ARCHITECTURE}" = "dos" ]; then + hb_tool="$1/${hb_pref}-bld" + else + hb_tool="$1/${hb_pref}-build" + fi + hb_libs=`mk_hbgetlibs "$2"` + hb_libsc=`mk_hbgetlibsctb "$3"` + [ -z "${HB_GT_LIB}" ] && HB_GT_LIB="gtstd" + + [ -z "${_DEFAULT_BIN_DIR}" ] && _DEFAULT_BIN_DIR="${HB_BIN_INSTALL}" + [ -z "${_DEFAULT_INC_DIR}" ] && _DEFAULT_INC_DIR="${HB_INC_INSTALL}" + [ -z "${_DEFAULT_LIB_DIR}" ] && _DEFAULT_LIB_DIR="${HB_LIB_INSTALL}" + + HB_SYS_LIBS="-lm" + HB_CRS_LIB="" + HB_SLN_LIB="" + if [ "${HB_COMPILER}" = "mingw32" ]; then + HB_SYS_LIBS="${HB_SYS_LIBS} -luser32 -lwinspool -lgdi32 -lcomctl32 -lcomdlg32 -lole32 -loleaut32 -luuid -lwsock32 -lws2_32" + elif [ "${HB_COMPILER}" = "djgpp" ]; then + HB_SYS_LIBS="${HB_SYS_LIBS}" + else + if [ "${HB_NCURSES_194}" = "yes" ]; then + HB_CRS_LIB="ncur194" + else + HB_CRS_LIB="ncurses" + fi + HB_SLN_LIB="slang" + fi + + echo "Generating ${hb_tool}... " + cat > ${hb_tool} < +# simple script to build binaries .tgz from Harbour sources +# +# See doc/license.txt for licensing terms. +# --------------------------------------------------------------- +# + +if [ \$# = 0 ]; then + echo "syntax: \$0 [] [.prg|.o] + +\"${hb_pref}cc\", \"${hb_pref}cmp\", \"${hb_pref}lnk\" and \"${hb_pref}mk\" parameters: + -o # output file name +\"${hb_pref}lnk\" and \"${hb_pref}mk\" parameters: + -static # link with static ${name} libs + -fullstatic # link with all static libs + -shared # link with shared libs (default) + -mt # link with multi-thread libs + -gt # link with GT driver, can be repeated to + # link with more GTs. The first one will be + # the default at runtime + -fmstat # link with the memory statistics lib + -nofmstat # do not link with the memory statistics lib (default) + -[no]strip # strip (no strip) binaries + -main= # set the name of main program function/procedure. + # if not set then 'MAIN' is used or if it doesn't + # exist the name of first public function/procedure + # in first linked object module (link) +" + exit 1 +elif [ "\$*" = "mk-links" ]; then + DIR="\${0%/*}" + NAME="\${0##*/}" + if [ "\${DIR}" != "\${NAME}" ]; then + (cd "\${DIR}" + for n in ${hb_pref}cc ${hb_pref}cmp ${hb_pref}mk ${hb_pref}lnk gharbour harbour-link; do + if [ "\${HB_ARCHITECTURE}" = "dos" ]; then + cp -f "\${NAME}" "\${n}" + else + ln -sf "\${NAME}" "\${n}" + fi + done + ) + fi + exit +fi + +## default parameters +HB_STATIC="no" +HB_MT="" +HB_GT="${HB_GT_LIB#gt}" +HB_MG="${HB_MULTI_GT}" + +HB_GPM_MOUSE="${HB_GPM_MOUSE}" + +HB_GT_REQ="" +HB_FM_REQ="" +HB_STRIP="yes" +HB_MAIN_FUNC="" +[ -n "\$TMPDIR" ] || TMPDIR="\$TMP" +[ -n "\$TMPDIR" ] || TMPDIR="\$TEMP" +[ -n "\$TMPDIR" ] || TMPDIR="/tmp" +_TMP_FILE_="\${TMPDIR}/hb-build-\$USER-\$\$.c" + +## parse params +P=( "\$@" ); n=0; DIROUT="."; FILEOUT="" +while [ \$n -lt \${#P[@]} ]; do + v=\${P[\$n]}; p="" + case "\$v" in + -o*) + d="\${v#-o}"; p="\${v}" + if [ -d "\${d}" ]; then + DIROUT="\${d%/}" + elif [ -d "\${d%/*}" ]; then + DIROUT="\${d%/*}"; FILEOUT="\${d##*/}"; p="-o\${d%.*}" + elif [ -n "\${d}" ]; then + FILEOUT="\${d}"; p="-o\${d%.*}" + fi ;; + -static) HB_STATIC="yes" ;; + -fullstatic) HB_STATIC="full" ;; + -shared) HB_STATIC="no" ;; + -mt) HB_MT="MT" ;; + -gt*) HB_GT_REQ="\${HB_GT_REQ} \${v#-gt}" ;; + -fmstat) HB_FM_REQ="STAT" ;; + -nofmstat) HB_FM_REQ="NOSTAT" ;; + -strip) HB_STRIP="yes" ;; + -nostrip) HB_STRIP="no" ;; + -main=*) HB_MAIN_FUNC="\${v#*=}" ;; + -*) p="\${v}" ;; + *) [ -z \${FILEOUT} ] && FILEOUT="\${v##*/}"; p="\${v}" ;; + esac + [ -n "\$p" ] && PP[\$n]="\$p" + n=\$[\$n + 1] +done +P=( "\${PP[@]}" ) + +case "\${HB_MT}" in + [Mm][Tt]|[Yy][Ee][Ss]|1) HB_MT="MT";; + *) HB_MT="";; +esac + +SYSTEM_LIBS="${HB_SYS_LIBS}" +# use pthread system library for MT programs +if [ "\${HB_MT}" = "MT" ]; then + SYSTEM_LIBS="-lpthread \${SYSTEM_LIBS}" +fi + +HB_GT_STAT="" +[ -z "\${HB_GT_REQ}" ] && HB_GT_REQ="\${HB_GT}" +if [ "\${HB_MG}" != "yes" ]; then + if [ "\${HB_STATIC}" = "yes" ] || [ "\${HB_STATIC}" = "full" ]; then + HB_GT_STAT=\`echo \${HB_GT_REQ}|tr A-Z a-z\` + fi + HB_GT_REQ="" +else + HB_GT_REQ=\`echo \${HB_GT_REQ}|tr a-z A-Z\` +fi +HB_MAIN_FUNC=\`echo \${HB_MAIN_FUNC}|tr a-z A-Z\` + +# set environment variables +export HB_ARCHITECTURE="${HB_ARCHITECTURE}" +export HB_COMPILER="${HB_COMPILER}" +[ -z "\${HB_BIN_INSTALL}" ] && export HB_BIN_INSTALL="${_DEFAULT_BIN_DIR}" +[ -z "\${HB_INC_INSTALL}" ] && export HB_INC_INSTALL="${_DEFAULT_INC_DIR}" +[ -z "\${HB_LIB_INSTALL}" ] && export HB_LIB_INSTALL="${_DEFAULT_LIB_DIR}" + +# be sure that ${name} binaries are in your path +export PATH="\${HB_BIN_INSTALL}:\${PATH}" + +HB_PATHS="-I\${HB_INC_INSTALL}" +GCC_PATHS="\${HB_PATHS} -L\${HB_LIB_INSTALL}" +LINK_OPT="" + +HB_GPM_LIB="" +if [ -f "\${HB_LIB_INSTALL}/libgtsln.a" ]; then + SYSTEM_LIBS="\${SYSTEM_LIBS} -l${HB_SLN_LIB:-slang}" + [ "\${HB_GPM_MOUSE}" = "yes" ] && HB_GPM_LIB="gpm" +fi +if [ -f "\${HB_LIB_INSTALL}/libgtcrs.a" ]; then + SYSTEM_LIBS="\${SYSTEM_LIBS} -l${HB_CRS_LIB:-ncurses}" + [ "\${HB_GPM_MOUSE}" = "yes" ] && HB_GPM_LIB="gpm" +fi +if [ "\${HB_WITHOUT_X11}" != "yes" ]; then + if [ -f "\${HB_LIB_INSTALL}/libgtxvt.a" ] || [ -f "\${HB_LIB_INSTALL}/libgtxwc.a" ]; then + SYSTEM_LIBS="\${SYSTEM_LIBS} -L/usr/X11R6/lib -lX11" + fi +fi +[ -n "\${HB_GPM_LIB}" ] && SYSTEM_LIBS="\${SYSTEM_LIBS} -l\${HB_GPM_LIB}" + +if [ "\${HB_STATIC}" = "full" ]; then + if [ "\${HB_STATIC}" = "full" ]; then + SYSTEM_LIBS="\${SYSTEM_LIBS} -ldl" + fi + LINK_OPT="\${LINK_OPT} -static" + HB_STATIC="yes" +fi + +HB_LNK_REQ="" +for gt in \${HB_GT_REQ}; do + if [ "\${HB_STATIC}" = "yes" ] || [ "\${gt}" = "ALLEG" ]; then + HB_LNK_REQ="\${HB_LNK_REQ} HB_GT_\${gt}" + if [ "\${gt}" = "ALLEG" ]; then + if [ "\${HB_STATIC}" = "yes" ]; then + SYSTEM_LIBS="\`allegro-config --static 2>/dev/null\` \${SYSTEM_LIBS}" + else + SYSTEM_LIBS="\`allegro-config --libs 2>/dev/null\` \${SYSTEM_LIBS}" + fi + fi + fi +done +[ -n "\${HB_FM_REQ}" ] && HB_LNK_REQ="\${HB_LNK_REQ} HB_FM_\${HB_FM_REQ}" + +HARBOUR_LIBS="" +if [ "\${HB_STATIC}" = "yes" ]; then + libs="${hb_libs} ${hb_libsc}" +else + l="${name}" + [ "\${HB_MT}" = "MT" ] && [ -f "\${HB_LIB_INSTALL}/lib\${l}mt.so" ] && l="\${l}mt" + [ -f "\${HB_LIB_INSTALL}/lib\${l}.so" ] && HARBOUR_LIBS="\${HARBOUR_LIBS} -l\${l}" + libs="gtalleg hbodbc debug profiler ${hb_libsc}" +fi +for l in \${libs} +do + if [ "\${HB_MG}" = "yes" ] || [ "\${l#gt}" = "\${l}" ] || [ "\${l}" = "gt\${HB_GT_STAT}" ]; then + [ "\${HB_MT}" = "MT" ] && [ -f "\${HB_LIB_INSTALL}/lib\${l}mt.a" ] && l="\${l}mt" + if [ -f "\${HB_LIB_INSTALL}/lib\${l}.a" ]; then + HARBOUR_LIBS="\${HARBOUR_LIBS} -l\${l}" + fi + fi +done +if [ "\${HB_ARCHITECTURE}" = "darwin" ]; then + HARBOUR_LIBS="\${HARBOUR_LIBS} \${HARBOUR_LIBS}" +else + HARBOUR_LIBS="-Wl,--start-group \${HARBOUR_LIBS} -Wl,--end-group" +fi +l="fm" +[ "\${HB_MT}" = "MT" ] && [ -f "\${HB_LIB_INSTALL}/lib\${l}mt.a" ] && l="\${l}mt" +if [ -f "\${HB_LIB_INSTALL}/lib\${l}.a" ]; then + if [ "\${HB_STATIC}" = "yes" ] && [ "\${HB_FM_REQ}" = "STAT" ]; then + HARBOUR_LIBS="-l\${l} \${HARBOUR_LIBS}" + else + HARBOUR_LIBS="\${HARBOUR_LIBS} -l\${l}" + fi +fi + +FOUTC1="\${FILEOUT%.*}.c" +FOUTO1="\${FILEOUT%.*}.o" +FOUTE1="\${FILEOUT%.[Pp][Rr][Gg]}" +FOUTE1="\${FOUTE1%.[oc]}" +FOUTC="\${DIROUT}/\${FILEOUT%.*}.c" +FOUTO="\${DIROUT}/\${FILEOUT%.*}.o" +FOUTE="\${DIROUT}/\${FILEOUT%.[Pp][Rr][Gg]}" +FOUTE="\${FOUTE%.[oc]}" + +hb_cc() +{ + ${hb_cmpname} "\$@" \${HB_PATHS} && [ -f "\${FOUTC}" ] +} + +hb_link() +{ + if [ -n "\${HB_MAIN_FUNC}" ]; then + HB_MAIN_FUNC="@\${HB_MAIN_FUNC}" + elif [ -f "\${FOUTO}" ]; then + HB_MAIN_FUNC=\`hb_lnk_main "\${FOUTO}"\` + fi + if [ -n "\${HB_LNK_REQ}" ] || [ -n "\${HB_GT_REQ}" ] || [ -n "\${HB_MAIN_FUNC}" ]; then + hb_lnk_request > \${_TMP_FILE_} && \\ + gcc "\$@" "\${_TMP_FILE_}" \${LINK_OPT} \${GCC_PATHS} \${HARBOUR_LIBS} \${SYSTEM_LIBS} -o "\${FOUTE}" + else + gcc "\$@" \${LINK_OPT} \${GCC_PATHS} \${HARBOUR_LIBS} \${SYSTEM_LIBS} -o "\${FOUTE}" + fi +} + +hb_cmp() +{ + hb_cc "\$@" && \\ + gcc -c "\${FOUTC}" -o "\${FOUTO}" \${GCC_PATHS} && \\ + rm -f "\${FOUTC}" +} + +hb_lnk_request() +{ + echo "#include \\"hbapi.h\\"" + if [ -n "\${HB_LNK_REQ}" ]; then + for fn in \${HB_LNK_REQ}; do + echo "extern HB_FUNC( \${fn} );" + done + echo "void hb_lnk_ForceLink_build( void )" + echo "{" + for fn in \${HB_LNK_REQ}; do + echo " HB_FUNCNAME( \${fn} )();" + done + echo "}" + fi + gt="\${HB_GT_REQ%% *}" + if [ -n "\$gt" ] || [ -n "\${HB_MAIN_FUNC}" ]; then + echo "#include \\"hbinit.h\\"" + echo "extern char * s_defaultGT;" + echo "extern char * s_pszLinkedMain;" + echo "HB_CALL_ON_STARTUP_BEGIN( hb_lnk_SetDefault_build )" + if [ -n "\$gt" ]; then + echo " s_defaultGT = \\"\$gt\\";" + fi + if [ -n "\${HB_MAIN_FUNC}" ]; then + echo " s_pszLinkedMain = \\"\${HB_MAIN_FUNC}\\";" + fi + echo "HB_CALL_ON_STARTUP_END( hb_lnk_SetDefault_build )" + fi +} + +hb_lnk_main() +{ + (nm \$1 -g -n --defined-only|sed -e '/HB_FUN_/ ! d' -e 's/^[0-9a-fA-F]* T HB_FUN_//'|head -1|grep -v '^MAIN\$')2>/dev/null +# (nm \$1 -n --defined-only|sed -e '/HB_FUN_/ ! d' -e 's/^[0-9a-fA-F]* [Tt] HB_FUN_//'|head -1|grep -v '^MAIN\$')2>/dev/null +} + +hb_cleanup() +{ + rm -f "\${_TMP_FILE_}" +} + +trap hb_cleanup EXIT &>/dev/null + +## get basename +HB="\${0##*/}" + +case "\${HB}" in + *cc) + hb_cc "\${P[@]}" + ;; + *cmp|gharbour) + hb_cmp "\${P[@]}" + ;; + *lnk|harbour-link) + hb_link "\${P[@]}" && \\ + ( [ "\${HB_STRIP}" != "yes" ] || strip "\${FOUTE}" ) + ;; + *mk) + hb_cmp "\${P[@]}" && \\ + hb_link "\${FOUTO}" && \\ + ( [ "\${HB_STRIP}" != "yes" ] || strip "\${FOUTE}" ) && \\ + rm -f "\${FOUTO}" + ;; +esac +EOF + chmod 755 ${hb_tool} + echo "Creating links..." + ${hb_tool} mk-links +} + +mk_hblibso() +{ + local LIBS LIBSMT l lm ll hb_rootdir hb_ver hb_libs + + name=`get_solibname` + hb_rootdir="${1-.}" + + hb_ver=`get_hbver "${hb_rootdir}"` + hb_libs=`mk_hbgetlibs "$2"` + [ -z "${HB_GT_LIB}" ] && HB_GT_LIB="gtstd" + + (cd $HB_LIB_INSTALL + LIBS="" + LIBSMT="" + for l in ${hb_libs} + do + case $l in + debug|profiler|fm|hbodbc|gtalleg|rddads) ;; + *) + ls="lib${l}.a" + if [ -f lib${l}mt.a ] + then + lm="lib${l}mt.a" + else + lm="${ls}" + fi + if [ "${HB_MULTI_GT}" = "yes" ] || \ + [ "${l#gt}" = "${l}" ] || \ + [ "${l}" = "${HB_GT_LIB}" ] + then + if [ -f $ls ] + then + LIBS="$LIBS $ls" + fi + if [ -f $lm ] + then + LIBSMT="$LIBSMT $lm" + fi + fi + ;; + esac + done + echo "Making lib${name}-${hb_ver}.so..." + $HB_BIN_INSTALL/hb-mkslib lib${name}-${hb_ver}.so $LIBS + [ "$HB_MT" != "MT" ] || $HB_BIN_INSTALL/hb-mkslib lib${name}mt-${hb_ver}.so $LIBSMT + for l in lib${name}-${hb_ver}.so lib${name}mt-${hb_ver}.so + do + if [ -f $l ] + then + ll=${l%-${hb_ver}.so}.so + ln -sf $l $ll + case $HB_LIB_INSTALL in + */usr/lib/*|*/usr/local/lib/*) + ln -sf ${name}/$l ../$ll + ;; + */usr/local/*) + mkdir -p ../../lib + ln -sf ../${name}/lib/$l ../../lib/$ll + ;; + *) + ;; + esac + fi + done + ) + #export LD_LIBRARY_PATH="$HB_LIB_INSTALL:$LD_LIBRARY_PATH" +} diff --git a/harbour/bin/pack_src.sh b/harbour/bin/pack_src.sh index 09aaa3e923..9299a79972 100644 --- a/harbour/bin/pack_src.sh +++ b/harbour/bin/pack_src.sh @@ -51,6 +51,7 @@ $hb_collect config/os2/*.cf $hb_collect config/w32/*.cf # DOC +$hb_collect doc/Makefile $hb_collect doc/*.txt $hb_collect doc/en/*.txt $hb_collect doc/es/*.txt @@ -70,9 +71,9 @@ $hb_collect source/Makefile # SOURCE\COMPILER $hb_collect source/compiler/Makefile -$hb_collect source/compiler/*.[cyl] -$hb_collect source/compiler/*.simple +$hb_collect source/compiler/*.[cylh] $hb_collect source/compiler/*.sl[xy] +$hb_collect source/compiler/*.simple # SOURCE\DEBUG $hb_collect source/debug/Makefile @@ -88,7 +89,7 @@ $hb_collect source/codepage/*.[ch] # SOURCE\MACRO $hb_collect source/macro/Makefile -$hb_collect source/macro/*.[cyl] +$hb_collect source/macro/*.[cylh] $hb_collect source/macro/*.slx # SOURCE\PP @@ -124,6 +125,13 @@ $hb_collect source/rdd/dbfntx/*.prg $hb_collect source/rdd/nulsys/Makefile $hb_collect source/rdd/nulsys/*.prg +for d in ${HB_DB_DRVEXT} +do + $hb_collect source/rdd/$d/Makefile + $hb_collect source/rdd/$d/*.[ch] + $hb_collect source/rdd/$d/*.prg +done + # SOURCE\RTL $hb_collect source/rtl/Makefile $hb_collect source/rtl/*.[ch] @@ -173,6 +181,23 @@ $hb_collect source/rtl/gtstd/*.[ch] $hb_collect source/rtl/gtwin/Makefile $hb_collect source/rtl/gtwin/*.[ch] +# SOURCE\RTL\GTWVT +$hb_collect source/rtl/gtwvt/Makefile* +$hb_collect source/rtl/gtwvt/*.[ch] + +# SOURCE\RTL\GTXVT +$hb_collect source/rtl/gtxvt/Makefile* +$hb_collect source/rtl/gtxvt/*.[ch] + +# SOURCE\RTL\GTXWC +$hb_collect source/rtl/gtxwc/Makefile* +$hb_collect source/rtl/gtxwc/*.[ch] + +# SOURCE\RTL\GTALLEG +$hb_collect source/rtl/gtalleg/Makefile* +$hb_collect source/rtl/gtalleg/*.[ch] +$hb_collect source/rtl/gtalleg/*.sfc + # SOURCE\VM $hb_collect source/vm/Makefile $hb_collect source/vm/*.[ch] @@ -184,10 +209,15 @@ $hb_collect tests/*.ch $hb_collect tests/*.dbf $hb_collect tests/*.fpt $hb_collect tests/*.prg +$hb_collect tests/*.src $hb_collect tests/*.txt +# TESTS\BLDTEST +$hb_collect tests/bldtest/Makefile +$hb_collect tests/bldtest/*.[ch] + # UTILS -$hb_collect utils/Makefile* +$hb_collect utils/Makefile # UTILS\HBDOC $hb_collect utils/hbdoc/Makefile @@ -222,6 +252,12 @@ $hb_collect utils/hbtest/*.prg # CONTRIB $hb_collect contrib/Makefile +# CONTRIB\RDD_ADS +$hb_collect contrib/rdd_ads/Makefile +$hb_collect contrib/rdd_ads/*.[ch] +$hb_collect contrib/rdd_ads/*.prg +$hb_collect contrib/rdd_ads/*.ch + # CONTRIB\LIBCT $hb_collect contrib/libct/Makefile $hb_collect contrib/libct/*.[ch] diff --git a/harbour/bin/postinst.bat b/harbour/bin/postinst.bat new file mode 100644 index 0000000000..45fdb46fe0 --- /dev/null +++ b/harbour/bin/postinst.bat @@ -0,0 +1,29 @@ +@echo off +rem +rem $Id$ +rem + +rem --------------------------------------------------------------- +rem Copyright 2003 Przemyslaw Czerpak +rem simple script run after Harbour make install to finish install +rem process +rem +rem See doc/license.txt for licensing terms. +rem --------------------------------------------------------------- + +goto inst_%HB_ARCHITECTURE% + +:inst_dos +rem DOS post install part + +goto end + + +:inst_w32 +rem Windows post install part + +goto end + + +:inst_ +:end diff --git a/harbour/bin/postinst.sh b/harbour/bin/postinst.sh new file mode 100644 index 0000000000..3e9c20decb --- /dev/null +++ b/harbour/bin/postinst.sh @@ -0,0 +1,64 @@ +#!/bin/sh +[ "$BASH" ] || exec bash `which $0` ${1+"$@"} +# +# $Id$ +# + +# --------------------------------------------------------------- +# Copyright 2003 Przemyslaw Czerpak +# simple script run after Harbour make install to finish install +# process +# +# See doc/license.txt for licensing terms. +# --------------------------------------------------------------- + +if [ -z "$HB_ARCHITECTURE" ] || [ -z "$HB_COMPILER" ] || \ + [ -z "$HB_BIN_INSTALL" ] || \ + [ -z "$HB_INC_INSTALL" ] || \ + [ -z "$HB_LIB_INSTALL" ] +then + echo "The following envvars must be set:" + echo " HB_ARCHITECTURE" + echo " HB_COMPILER" + echo " HB_BIN_INSTALL" + echo " HB_INC_INSTALL" + echo " HB_LIB_INSTALL" + exit 1 +fi + +hb_root=`dirname "$0"` +if [ "${hb_root}" = "." ] +then + hb_root=".." +else + hb_root=`dirname "${hb_root}"` +fi +. ${hb_root}/bin/hb-func.sh + +if [ "$HB_COMPILER" = "gcc" ] || [ "$HB_COMPILER" = "mingw32" ] || [ "$HB_COMPILER" = "djgpp" ] +then + if [ "${HB_ARCHITECTURE}" == "bsd" ]; then + MAKE=gmake + else + MAKE=make + fi + if [ "${HB_ARCHITECTURE}" != "dos" ]; then + install -m755 "${hb_root}/bin/hb-mkslib.sh" "${HB_BIN_INSTALL}/hb-mkslib" + fi + mk_hbtools "${HB_BIN_INSTALL}" "$@" + [ "$HB_COMPILER" = "gcc" ] && mk_hblibso "${hb_root}" + + # build fm lib with memory statistic + (cd ${hb_root}/source/vm + C_USR=${C_USR//-DHB_FM_STATISTICS_OFF/} + rm -f fm.o + ${MAKE} -r fm.o + ar -cr ${HB_LIB_INSTALL}/libfm.a fm.o + rm -f fm.o + if [ "${HB_MT}" = "MT" ]; then + ${MAKE} -r fm.o 'HB_LIBCOMP_MT=YES' + ar -cr ${HB_LIB_INSTALL}/libfmmt.a fm.o + rm -f fm.o + fi + ) +fi diff --git a/harbour/config/bsd/gcc.cf b/harbour/config/bsd/gcc.cf index f94b7335d3..13547e87a7 100644 --- a/harbour/config/bsd/gcc.cf +++ b/harbour/config/bsd/gcc.cf @@ -69,8 +69,3 @@ ARFLAGS = $(A_USR) AR_RULE = $(AR) $(ARFLAGS) r $@ $^ || $(RM) $@ include $(TOP)$(ROOT)config/rules.cf - - - - - diff --git a/harbour/config/bsd/global.cf b/harbour/config/bsd/global.cf index de1bb410bf..12af6eb122 100644 --- a/harbour/config/bsd/global.cf +++ b/harbour/config/bsd/global.cf @@ -26,13 +26,11 @@ RD = rm -f -r CP = cp -f MV = mv -f MD = mkdir +MDP = mkdir -p +RANLIB = ranlib dirbase:: - @[ -d $(HB_ARCHITECTURE) ] || $(MD) $(HB_ARCHITECTURE); \ - [ -d $(ARCH) ] || $(MD) $(ARCH) + @[ -d $(ARCH_DIR) ] || $(MDP) $(ARCH_DIR) clean:: -$(RD) $(ARCH_DIR) - - - diff --git a/harbour/config/darwin/dir.cf b/harbour/config/darwin/dir.cf new file mode 100644 index 0000000000..08f9ed936f --- /dev/null +++ b/harbour/config/darwin/dir.cf @@ -0,0 +1,14 @@ +# +# $Id$ +# + +ifeq ($(PM),) # Only traverse directories if not compiling a specific module + +DIR_RULE =\ + @for d in $(DIRS); do \ + if [ -d $$d ]; then \ + $(MAKE) -C $$d $@; \ + fi \ + done + +endif # ! compiling a specific program module \ No newline at end of file diff --git a/harbour/config/darwin/gcc.cf b/harbour/config/darwin/gcc.cf new file mode 100644 index 0000000000..8ffbdd28b5 --- /dev/null +++ b/harbour/config/darwin/gcc.cf @@ -0,0 +1,104 @@ +# +# $Id$ +# + +include $(TOP)$(ROOT)config/$(HB_ARCHITECTURE)/global.cf + +OBJ_EXT = .o +EXE_EXT = +LIB_PREF = lib +LIB_EXT = .a + +CC = $(CCACHE) gcc +CC_IN = -c +CC_OUT = -o +CPPFLAGS = -fsigned-char -no-cpp-precomp -I. -I$(TOP)include -I$(HB_INC_COMPILE) +CFLAGS = -Wall -W -DHB_OS_DARWIN -DHB_BIG_ENDIAN +ifeq ($(HB_LEX),SIMPLEX) +CFLAGS += -DSIMPLEX +endif + +LD = gcc +LD_OUT = -o + +# Add all libraries specified in HB_USER_LIBS. +LINKPATHS += $(foreach lib, $(HB_USER_LIBS), -L$(TOP)$(ROOT)source/$(lib)/$(ARCH)) +LINKLIBS += $(foreach lib, $(HB_USER_LIBS), -l$(lib)) + +# Add all libraries specified in CONTRIBS and LIBS. +ifeq ($(HB_LIB_COMPILE),) +LINKPATHS += $(foreach lib, $(CONTRIBS), -L$(TOP)$(ROOT)contrib/$(lib)/$(ARCH)) +LINKPATHS += $(foreach lib, $(LIBS), -L$(TOP)$(ROOT)source/$(lib)/$(ARCH)) +else +LINKPATHS += -L$(HB_LIB_COMPILE) +endif + +# LINKLIBS += -Wl,--start-group +LINKLIBS += $(foreach lib, $(CONTRIBS), -l$(lib)) +LINKLIBS += $(foreach lib, $(LIBS), -l$(lib)) + +# If LIBS specifies the rdd library, add all DB drivers. +ifeq ($(findstring rdd,$(LIBS)),rdd) +LINKPATHS += $(foreach drv, $(HB_DB_DRIVERS), -L$(TOP)$(ROOT)source/rdd/$(drv)/$(ARCH)) +LINKLIBS += $(foreach drv, $(HB_DB_DRIVERS), -l$(drv)) +endif + +# Add the specified GT driver library +ifeq ($(findstring rtl,$(LIBS)),rtl) +LINKPATHS += -L$(TOP)$(ROOT)source/rtl/$(HB_GT_LIB)/$(ARCH) +LINKLIBS += -l$(HB_GT_LIB) +ifeq ($(HB_MULTI_GT),yes) +LINKPATHS += -L$(TOP)$(ROOT)source/rtl/gtnul/$(ARCH) +LINKLIBS += -lgtnul +endif + +# HB_SCREEN_LIB: empty, or one of ncurses, slang +ifeq ($(HB_GT_LIB),gtcrs) +HB_SCREEN_LIB:=ncurses +else +ifeq ($(HB_GT_LIB),gtsln) +HB_SCREEN_LIB:=slang +endif +endif + +ifneq ($(HB_SCREEN_LIB),) +LINKLIBS += -l$(HB_SCREEN_LIB) +endif + +# In BSD, slang still needs curses :( +ifeq ($(HB_GT_LIB),gtsln) +LINKLIBS += -lncurses +endif + +ifeq ($(HB_GT_LIB),gtxvt) +LINKLIBS += -lX11 +LINKPATHS +=-L/usr/X11R6/lib +else +ifeq ($(HB_GT_LIB),gtxwc) +LINKLIBS += -lX11 +LINKPATHS +=-L/usr/X11R6/lib +endif +endif + +# HB_GPM_MOUSE: use gpm mouse driver +# Actually, there is no gpm on BSD. +ifeq ($(HB_GPM_MOUSE),yes) +LINKLIBS += -lgpm +endif + +endif + +LINKLIBS += -lm +# -Wl,--end-group + +LDFLAGS = $(LINKPATHS) +LD_RULE = $(LD) $(CFLAGS) $(LD_OUT) $@ $^ $(LDFLAGS) $(L_USR) $(LINKLIBS) $(LINKLIBS) + +#AR = ar +#ARFLAGS = $(A_USR) +#AR_RULE = $(AR) $(ARFLAGS) r $@ $^ || $(RM) $@ +LIBTOOL = libtool +LIBTOOLFLAGS = $(LIBTOOL_USR) +AR_RULE = $(LIBTOOL) -static $(LIBTOOLFLAGS) -o $@ $^ || $(RM) $@ +RANLIB = ranlib +include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/darwin/global.cf b/harbour/config/darwin/global.cf new file mode 100644 index 0000000000..2e234a9fe3 --- /dev/null +++ b/harbour/config/darwin/global.cf @@ -0,0 +1,41 @@ +# +# $Id$ +# + +all : first + +HB_GT_LIBS=\ + gtcgi \ + gtcrs \ + gtpca \ + gtstd \ + gtnul \ + +ifeq ($(HB_COMMERCE),yes) + HB_GPM_MOUSE = no +else +ifneq ($(HB_WITHOUT_GTSLN),yes) + HB_GT_LIBS += gtsln +endif +endif + +ifeq ($(HB_GT_LIB),) + HB_GT_LIB = gtstd +endif + +ARCH_DIR = $(ARCH) +MK = $(MAKE) + +RM = rm -f +RD = rm -f -r +CP = cp -f +MV = mv -f +MD = mkdir +MDP = mkdir -p +RANLIB = ranlib + +dirbase:: + @[ -d $(ARCH_DIR) ] || $(MDP) $(ARCH_DIR) + +clean:: + -$(RD) $(ARCH_DIR) diff --git a/harbour/config/darwin/install.cf b/harbour/config/darwin/install.cf new file mode 100644 index 0000000000..8823259c16 --- /dev/null +++ b/harbour/config/darwin/install.cf @@ -0,0 +1,25 @@ +# +# $Id$ +# + +INSTALL_RULE =\ + @if [ ! -d $(INSTALL_DIR) ]; \ + then \ + echo "! Can't install, path not found:" $(INSTALL_DIR); \ + else \ + for i in $(INSTALL_OBJS); \ + do \ + if [ -r $$i ]; \ + then \ + echo "! Installing $$i on $(INSTALL_DIR)"; \ + $(CP) $$i $(INSTALL_DIR); \ + else \ + echo "! Can't install $$i, not found"; \ + fi \ + done; \ + if [ $(INSTALL_DIR) = $(HB_LIB_INSTALL) ]; \ + then \ + $(RANLIB) $(foreach file,$(notdir $(INSTALL_OBJS)),$(INSTALL_DIR)/$(file)); \ + fi \ + fi + diff --git a/harbour/config/dir.cf b/harbour/config/dir.cf index abfc60a74f..1de75b114d 100644 --- a/harbour/config/dir.cf +++ b/harbour/config/dir.cf @@ -13,5 +13,10 @@ all : first first clean install:: $(DIR_RULE) +ifneq ($(HB_POSTINST),) +install:: + $(HB_POSTINST) +endif + endif endif diff --git a/harbour/config/dos/dir.cf b/harbour/config/dos/dir.cf index c32f7221a5..afbfd85f72 100644 --- a/harbour/config/dos/dir.cf +++ b/harbour/config/dos/dir.cf @@ -2,18 +2,39 @@ # $Id$ # -include $(TOP)$(ROOT)config/$(HB_ARCHITECTURE)/global.cf - ifeq ($(PM),) # Only traverse directories if not compiling a specific module ifeq ($(DIRS),) # Empty directory list -DIR_RULE =\ - @echo Done + +DIR_RULE = @echo Done + else + +ifeq ($(SHLVL),) # COMMAND.COM + +# We have to use script to overcome the DOS limit of max 128 characters +# NOTE: The empty line directly before 'endef' HAVE TO exist! +# It causes that every commands will be separated by LF +define dir_mk +$(DIR_MAKE) -C $(file) $@ + +endef + DIR_LIST := $(subst /,\,$(DIRS)) DIR_MAKE := $(subst /,\,$(MK)) -DIR_RULE =\ - $(COMSPEC) /C FOR %d IN ($(DIR_LIST)) DO $(DIR_MAKE) -C %d $@ -endif +DIR_RULE = $(foreach file, $(DIR_LIST), $(dir_mk)) -endif # ! compiling a specific program module \ No newline at end of file +else # bash +DIR_LIST = $(subst \,/,$(DIRS)) +DIR_RULE =\ + for d in $(DIR_LIST); do \ + if [ -d $$d ]; then \ + $(MAKE) -C $$d $@; \ + fi \ + done + +endif # ! COMMAND.COM + +endif # ! Empty directory list + +endif # ! compiling a specific program module diff --git a/harbour/config/dos/global.cf b/harbour/config/dos/global.cf index 74f0d7507e..a04f9063c0 100644 --- a/harbour/config/dos/global.cf +++ b/harbour/config/dos/global.cf @@ -7,17 +7,21 @@ ifndef MK all : first HB_GT_LIBS=\ - gtcgi \ - gtdos \ - gtpca \ - gtstd \ -# gtcrs \ -# gtsln \ + gtcgi \ + gtpca \ + gtstd \ + gtdos \ +# gtnul \ +# gtcrs \ +# gtsln \ + ifeq ($(HB_GT_LIB),) HB_GT_LIB = gtdos endif +ifeq ($(SHLVL),) # COMMAND.COM + # There is a conflict with the use of '\' and '/' characters # The MAKE requires '/' in filenames (ARCH_DIR) however some compilers # and some DOS commands require '\' (ARCH_DOS) @@ -34,7 +38,7 @@ else ifeq ($(HB_COMPILER),rsx32) #Use standard dos path, which is already set up. else - ifeq ($(HB_COMPILER),watcom) + ifneq ($(findstring watcom,$(HB_COMPILER)),) #Use standard dos path, which is already set up. else ifeq ($(HB_COMPILER),djgpp) @@ -57,17 +61,37 @@ CP = copy MV = move MD = md +#this will be used only under DJGPP +RANLIB = ranlib + dirbase:: - -if not exist $(HB_ARCHITECTURE) $(MD) $(HB_ARCHITECTURE) - -if not exist $(ARCH_DOS) $(MD) $(ARCH_DOS) + -@for %d in ($(HB_ARCHITECTURE) $(ARCH_DOS)) do if not exist %d\nul $(MD) %d clean:: - -for %f in ($(ARCH_DOS)\*.*) do $(RM) %f - -if exist *.bak $(RM) *.bak - -if exist *.obj $(RM) *.obj - -if exist core $(RM) core - -if exist *.o $(RM) *.o - -$(RD) $(ARCH_DOS) - -$(RD) $(HB_ARCHITECTURE) -endif + -@for %f in ($(ARCH_DOS)\*.* *.bak *.obj *.o *.tds) do $(RM) %f + -@for %d in ($(ARCH_DOS) $(HB_ARCHITECTURE)) do if exist %d\nul $(RD) %d +else # bash + +ARCH_DIR = $(ARCH) +MK = $(MAKE) + +RM = rm -f +RD = rm -f -r +CP = cp -f +MV = mv -f +MD = mkdir + +#this will be used only under MINGW +RANLIB = ranlib + + +dirbase:: + @[ -d $(HB_ARCHITECTURE) ] || $(MD) $(HB_ARCHITECTURE); \ + [ -d $(ARCH_DIR) ] || $(MD) $(ARCH_DIR) + +clean:: + -$(RD) $(ARCH) + +endif +endif diff --git a/harbour/config/dos/install.cf b/harbour/config/dos/install.cf index baf7508210..6c62a89c7c 100644 --- a/harbour/config/dos/install.cf +++ b/harbour/config/dos/install.cf @@ -2,8 +2,46 @@ # $Id$ # -include $(TOP)$(ROOT)config/$(HB_ARCHITECTURE)/global.cf +ifeq ($(INSTALL_OBJS),) # Empty install list + +INSTALL_RULE = @echo Done + +else + +ifeq ($(SHLVL),) # COMMAND.COM + +# We have to use script to overcome the DOS limit of max 128 characters +# NOTE: The empty line directly before 'endef' HAVE TO exist! +# It causes that every commands will be separated by LF +define inst_file +$(CP) $(file) $(subst /,\,$(INSTALL_DIR)) + +endef INSTALL_LIST = $(subst /,\,$(INSTALL_OBJS)) +INSTALL_RULE = $(foreach file, $(INSTALL_LIST), $(inst_file)) + +else # bash + +INSTALL_DIRSH = $(subst \,/,$(INSTALL_DIR)) +INSTALL_OBJSH = $(subst \,/,$(INSTALL_OBJS)) INSTALL_RULE =\ - $(COMSPEC) /c FOR %f IN ($(INSTALL_LIST)) DO COPY %f $(subst /,\,$(INSTALL_DIR)) + @if [ ! -d $(INSTALL_DIRSH) ]; \ + then \ + echo "! Can't install, path not found:" $(INSTALL_DIRSH); \ + else \ + for i in $(INSTALL_OBJSH); \ + do \ + if [ -r $$i ]; \ + then \ + echo "! Installing $$i on $(INSTALL_DIRSH)"; \ + $(CP) $$i $(INSTALL_DIRSH); \ + else \ + echo "! Can't install $$i, not found"; \ + fi \ + done \ + fi + +endif + +endif diff --git a/harbour/config/dos/owatcom.cf b/harbour/config/dos/owatcom.cf index 31523d2c36..4e6fbd944a 100644 --- a/harbour/config/dos/owatcom.cf +++ b/harbour/config/dos/owatcom.cf @@ -2,7 +2,7 @@ # $Id$ # # The Harbour project -# GNU MAKE file for OpenWatcom C/C++ compiler +# GNU MAKE file for OpenWatcom include $(TOP)$(ROOT)config/$(HB_ARCHITECTURE)/global.cf @@ -18,17 +18,29 @@ CC_IN = CC_OUT = -fo= # important: -j is necessary for proper build -CPPFLAGS = -j -w3 -d2 -5s -5r -fp5 -oxehtz -zq -zt0 -bt=DOS -CFLAGS := -i$(subst /,\,$(HB_INC_COMPILE)) -i. +#CPPFLAGS = -j -w3 -d1 -5s -5r -fp5 -oehtz -s -zq -zt0 -bt=DOS +CPPFLAGS = -j -w2 -d1 -zq -bt=DOS -# work arround to DOS command line size limit -export WPP386 := $(CPPFLAGS) -CPPFLAGS = +#architecture flags +CPPFLAGS += -5 -fp5 + +# optimization flags +# don't enable -ol optimization in OpenWatcom 1.1 - gives buggy code +CPPFLAGS += -onaehtzr -oi+ -ei -zp8 -s -zt0 + +CPPFLAGS += -i. -i$(TOP)include -i$(TOP)$(ROOT)include -iinclude +ifneq ($(HB_LIB_COMPILE),) + CPPFLAGS += -i$(HB_INC_COMPILE) +endif ifeq ($(HB_LEX),SIMPLEX) CFLAGS += -DSIMPLEX endif +# work arround to DOS command line size limit +export WPP386 := $(strip $(CPPFLAGS)) +CPPFLAGS = + # Note: The empty line directly before 'endef' HAVE TO exist! # It causes that the 'echo' command is separated by LF define link_file @@ -45,6 +57,7 @@ endef define link_exe_file echo $(LDFLAGS) NAME $@ > __link__.tmp $(foreach file, $^, $(link_file)) +$(foreach lib, $(HB_USER_LIBS), $(link_lib)) $(foreach lib, $(LINKLIBS), $(link_lib)) $(foreach lib, $(RDDLIBS), $(link_lib)) $(foreach lib, $(GTLIBS), $(link_lib)) @@ -53,28 +66,38 @@ endef LD = wlink LDFLAGS = debug all OP osn=DOS OP stack=65536 OP CASEEXACT OP stub=cwstub.exe + +HB_USER_LIBS := $(foreach lib, $(HB_USER_LIBS), $(subst /,\,$(TOP)$(ROOT)source/$(lib)/$(ARCH)/$(lib))) + ifeq ($(HB_LIB_COMPILE),) LINKLIBS := $(foreach lib, $(CONTRIBS), $(subst /,\,$(TOP)$(ROOT)contrib/$(lib)/$(ARCH)/$(subst lib,,$(lib)))) -LINKLIBS := $(foreach lib, $(LIBS), $(subst /,\,$(TOP)$(ROOT)source/$(lib)/$(ARCH)/$(lib))) +LINKLIBS += $(foreach lib, $(LIBS), $(subst /,\,$(TOP)$(ROOT)source/$(lib)/$(ARCH)/$(lib))) else LINKLIBS := $(foreach lib, $(CONTRIBS), $(subst /,\,$(HB_LIB_COMPILE)/$(lib))) -LINKLIBS := $(foreach lib, $(LIBS), $(subst /,\,$(HB_LIB_COMPILE)/$(lib))) +LINKLIBS += $(foreach lib, $(LIBS), $(subst /,\,$(HB_LIB_COMPILE)/$(lib))) endif # If LIBS specifies the rdd library, add all DB drivers. ifeq ($(findstring rdd,$(LIBS)),rdd) +ifeq ($(HB_LIB_COMPILE),) RDDLIBS := $(foreach drv, $(HB_DB_DRIVERS), $(subst /,\,$(TOP)$(ROOT)source/rdd/$(drv)/$(ARCH)/$(drv))) +else +RDDLIBS := $(foreach drv, $(HB_DB_DRIVERS), $(subst /,\,$(HB_LIB_COMPILE)/$(drv))) +endif endif ifeq ($(findstring rtl,$(LIBS)),rtl) +ifeq ($(HB_LIB_COMPILE),) GTLIBS := $(TOP)$(ROOT)source/rtl/$(HB_GT_LIB)/$(ARCH)/$(HB_GT_LIB) +else +GTLIBS := $(HB_LIB_COMPILE)/$(HB_GT_LIB) +endif ifeq ($(HB_MULTI_GT),yes) -GTLIBS := $(TOP)$(ROOT)source/rtl/gtnul/$(ARCH)/gtnul +GTLIBS += $(TOP)$(ROOT)source/rtl/gtnul/$(ARCH)/gtnul endif GTLIBS := $(subst /,\,$(GTLIBS)) endif - LD_RULE = $(link_exe_file) #Note: The empty line below HAVE TO exist! diff --git a/harbour/config/dos/watcom.cf b/harbour/config/dos/watcom.cf index 325feb4539..051ab60306 100644 --- a/harbour/config/dos/watcom.cf +++ b/harbour/config/dos/watcom.cf @@ -45,10 +45,10 @@ LD = wlink LDFLAGS = debug all OP osn=DOS4G OP stack=65536 OP CASEEXACT ifeq ($(HB_LIB_COMPILE),) LINKLIBS := $(foreach lib, $(CONTRIBS), $(subst /,\,$(TOP)$(ROOT)contrib/$(lib)/$(ARCH)/$(subst lib,,$(lib)))) -LINKLIBS := $(foreach lib, $(LIBS), $(subst /,\,$(TOP)$(ROOT)source/$(lib)/$(ARCH)/$(lib))) +LINKLIBS += $(foreach lib, $(LIBS), $(subst /,\,$(TOP)$(ROOT)source/$(lib)/$(ARCH)/$(lib))) else LINKLIBS := $(foreach lib, $(CONTRIBS), $(subst /,\,$(HB_LIB_COMPILE)/$(lib))) -LINKLIBS := $(foreach lib, $(LIBS), $(subst /,\,$(HB_LIB_COMPILE)/$(lib))) +LINKLIBS += $(foreach lib, $(LIBS), $(subst /,\,$(HB_LIB_COMPILE)/$(lib))) endif # If LIBS specifies the rdd library, add all DB drivers. diff --git a/harbour/config/linux/gcc.cf b/harbour/config/linux/gcc.cf index f887fa729b..47ffe5f2b5 100644 --- a/harbour/config/linux/gcc.cf +++ b/harbour/config/linux/gcc.cf @@ -13,12 +13,19 @@ CC = $(HB_CCACHE) gcc CC_IN = -c CC_OUT = -o CPPFLAGS = -I. -I$(HB_INC_COMPILE) + +# We are under linux +CFLAGS = -DHB_OS_LINUX -Wall -W -fsigned-char + +# uncomment this if you want to farce relocateable code for .so libs +# it's necessary on some platforms but can reduce performance +#CFLAGS += -fPIC + ifeq ($(HB_LEX),SIMPLEX) -CFLAGS = -Wall -g -DSIMPLEX -else -CFLAGS = -Wall -g +CFLAGS += -DSIMPLEX endif + LD = $(HB_CCACHE) gcc LD_OUT = -o @@ -64,6 +71,6 @@ LDFLAGS = $(LINKPATHS) AR = ar ARFLAGS = $(A_USR) -AR_RULE = $(AR) $(ARFLAGS) r $@ $^ || $(RM) $@ +AR_RULE = $(AR) $(ARFLAGS) cr $@ $^ || $(RM) $@ include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/linux/global.cf b/harbour/config/linux/global.cf index 4c3f32e0b6..d869339ec0 100644 --- a/harbour/config/linux/global.cf +++ b/harbour/config/linux/global.cf @@ -22,10 +22,10 @@ RD = rm -f -r CP = cp -f MV = mv -f MD = mkdir +MDP = mkdir -p dirbase:: - @[ -d $(HB_ARCHITECTURE) ] || $(MD) $(HB_ARCHITECTURE); \ - [ -d $(ARCH) ] || $(MD) $(ARCH) + @[ -d $(ARCH_DIR) ] || $(MDP) $(ARCH_DIR) clean:: -$(RD) $(ARCH_DIR) diff --git a/harbour/contrib/Makefile b/harbour/contrib/Makefile index 92460a04c9..05cff3ca27 100644 --- a/harbour/contrib/Makefile +++ b/harbour/contrib/Makefile @@ -75,6 +75,16 @@ DIRS=\ else ifeq ($(HB_ARCHITECTURE),bsd) +DIRS=\ + htmllib \ + libct \ + libgt \ + libmisc \ + samples \ + +else +ifeq ($(HB_ARCHITECTURE),dos) + DIRS=\ htmllib \ libct \ @@ -96,5 +106,6 @@ endif endif endif endif +endif include $(ROOT)config/dir.cf diff --git a/harbour/contrib/dot/pp_harb.ch b/harbour/contrib/dot/pp_harb.ch index bed52b138f..bd876773cb 100644 --- a/harbour/contrib/dot/pp_harb.ch +++ b/harbour/contrib/dot/pp_harb.ch @@ -1645,7 +1645,7 @@ static BOOL s_bArrayPrefix = FALSE; //----------------------------------------------------------------------------// - static HB_FUNC( SETARRAYPREFIX ) + HB_FUNC_STATIC( SETARRAYPREFIX ) { PHB_ITEM pbArrayPrefix = hb_param( 1, HB_IT_LOGICAL ); @@ -1656,13 +1656,13 @@ } //----------------------------------------------------------------------------// - static HB_FUNC( GETARRAYPREFIX ) + HB_FUNC_STATIC( GETARRAYPREFIX ) { hb_retl( s_bArrayPrefix ); } //----------------------------------------------------------------------------// - static HB_FUNC( NEXTTOKEN ) + HB_FUNC_STATIC( NEXTTOKEN ) { PHB_ITEM pLine = hb_param( 1, HB_IT_STRING ); PHB_ITEM pDontRecord = hb_param( 2, HB_IT_LOGICAL ); @@ -2027,7 +2027,7 @@ } //----------------------------------------------------------------------------// - static HB_FUNC( NEXTIDENTIFIER ) + HB_FUNC_STATIC( NEXTIDENTIFIER ) { PHB_ITEM pLine = hb_param( 1, HB_IT_STRING ); PHB_ITEM pSkipped = hb_param( 2, HB_IT_ANY ); diff --git a/harbour/contrib/libct/Makefile b/harbour/contrib/libct/Makefile index c74cee5e98..b492e81bef 100644 --- a/harbour/contrib/libct/Makefile +++ b/harbour/contrib/libct/Makefile @@ -66,7 +66,7 @@ PRG_SOURCES= \ ctmisc.prg \ datetime.prg \ dattime2.prg \ - invertwin.prg \ + invrtwin.prg \ numconv.prg \ screen2.prg \ setlast.prg \ diff --git a/harbour/contrib/libct/bit1.c b/harbour/contrib/libct/bit1.c index 73b3a291e6..7989501bfc 100644 --- a/harbour/contrib/libct/bit1.c +++ b/harbour/contrib/libct/bit1.c @@ -59,13 +59,13 @@ #include "ct.h" #include "clipdefs.h" -long static __hex2int( char *cNum1, int iLenHex ); -long static __getparam( int iParam ); -long static __numand( long wNum1, long wNum2 ); -long static __numor ( long wNum1, long wNum2 ); -long static __numxor( long wNum1, long wNum2 ); -long static __numnot( long wNum1, long wNum2 ); -long static __numfun( int iPCount, long (*operation)(long wNum1, long wNum2)); +static long __hex2int( char *cNum1, int iLenHex ); +static long __getparam( int iParam ); +static long __numand( long wNum1, long wNum2 ); +static long __numor ( long wNum1, long wNum2 ); +static long __numxor( long wNum1, long wNum2 ); +static long __numnot( long wNum1, long wNum2 ); +static long __numfun( int iPCount, long (*operation)(long wNum1, long wNum2)); /* $DOC$ @@ -381,7 +381,7 @@ HB_FUNC ( HEX2NUM ) } */ -long static __hex2int( char *cNum1, int iLenHex ) +static long __hex2int( char *cNum1, int iLenHex ) { int i; int iNum; @@ -406,7 +406,7 @@ long static __hex2int( char *cNum1, int iLenHex ) } -long static __getparam( int iParam ) +static long __getparam( int iParam ) { if ( ISCHAR( iParam ) ) @@ -417,32 +417,32 @@ long static __getparam( int iParam ) } -long static __numand( long uiNum1, long uiNum2 ) +static long __numand( long uiNum1, long uiNum2 ) { return uiNum1 & uiNum2; } -long static __numor( long uiNum1, long uiNum2 ) +static long __numor( long uiNum1, long uiNum2 ) { return uiNum1 | uiNum2; } -long static __numxor( long uiNum1, long uiNum2 ) +static long __numxor( long uiNum1, long uiNum2 ) { return uiNum1 ^ uiNum2; } -long static __numnot( long uiNum1, long uiNum2 ) +static long __numnot( long uiNum1, long uiNum2 ) { HB_SYMBOL_UNUSED (uiNum2); return ~uiNum1; } -long static __numfun( int iPCount, long (*operation)(long wNum1, long wNum2)) +static long __numfun( int iPCount, long (*operation)(long wNum1, long wNum2)) { long uiNumOp = 0; long uiNum1, uiNum2; diff --git a/harbour/contrib/libct/bit2.c b/harbour/contrib/libct/bit2.c index 9444178f00..2084fb606d 100644 --- a/harbour/contrib/libct/bit2.c +++ b/harbour/contrib/libct/bit2.c @@ -56,8 +56,8 @@ #include "ct.h" -long int static __hex2long( char *cNum1, int iLenHex ); -long int static __getparam( int iParam ); +static long __hex2long( char *cNum1, int iLenHex ); +static long __getparam( int iParam ); /* $DOC$ @@ -245,7 +245,7 @@ HB_FUNC ( ISBIT ) } -long int static __hex2long( char *cNum1, int iLenHex ) +static long __hex2long( char *cNum1, int iLenHex ) { register int i; register int iNum; @@ -270,7 +270,7 @@ long int static __hex2long( char *cNum1, int iLenHex ) } -long int static __getparam( int iParam ) +static long __getparam( int iParam ) { if ( ISCHAR( iParam ) ) diff --git a/harbour/contrib/libct/bit3.c b/harbour/contrib/libct/bit3.c index ce6456e5bf..dabc13186e 100644 --- a/harbour/contrib/libct/bit3.c +++ b/harbour/contrib/libct/bit3.c @@ -59,14 +59,14 @@ #include "ct.h" #include "clipdefs.h" -long static __hex2long( char *cNum1, int iLenHex ); -long static __getparam( int iParam ); -long static __numand( long wNum1, long wNum2 ); -long static __numor ( long wNum1, long wNum2 ); -long static __numxor( long wNum1, long wNum2 ); -long static __numnot( long wNum1, long wNum2 ); -long static __numfun( int iPCount, long (*operation)(long wNum1, long wNum2), BOOL * pbOk ); -void static sizeofbits( USHORT * pusBytes, LONG * plPattern, LONG * plTestMSB ); +static long __hex2long( char *cNum1, int iLenHex ); +static long __getparam( int iParam ); +static long __numand( long wNum1, long wNum2 ); +static long __numor ( long wNum1, long wNum2 ); +static long __numxor( long wNum1, long wNum2 ); +static long __numnot( long wNum1, long wNum2 ); +static long __numfun( int iPCount, long (*operation)(long wNum1, long wNum2), BOOL * pbOk ); +static void sizeofbits( USHORT * pusBytes, LONG * plPattern, LONG * plTestMSB ); /* $DOC$ * $FUNCNAME$ @@ -482,7 +482,7 @@ HB_FUNC ( NUMMIRRX ) } -long static __hex2long( char *cNum1, int iLenHex ) +static long __hex2long( char *cNum1, int iLenHex ) { int i; int iNum; @@ -507,7 +507,7 @@ long static __hex2long( char *cNum1, int iLenHex ) } -long static __getparam( int iParam ) +static long __getparam( int iParam ) { if ( ISCHAR( iParam ) ) @@ -518,32 +518,32 @@ long static __getparam( int iParam ) } -long static __numand( long lNum1, long lNum2 ) +static long __numand( long lNum1, long lNum2 ) { return lNum1 & lNum2; } -long static __numor( long lNum1, long lNum2 ) +static long __numor( long lNum1, long lNum2 ) { return lNum1 | lNum2; } -long static __numxor( long lNum1, long lNum2 ) +static long __numxor( long lNum1, long lNum2 ) { return lNum1 ^ lNum2; } -long static __numnot( long lNum1, long lNum2 ) +static long __numnot( long lNum1, long lNum2 ) { HB_SYMBOL_UNUSED (lNum2); return ~lNum1; } -long static __numfun( int iPCount, long (*operation)(long wNum1, long wNum2), BOOL * pbOk ) +static long __numfun( int iPCount, long (*operation)(long wNum1, long wNum2), BOOL * pbOk ) { long lNumOp = 0; long lNum1, lNum2; @@ -615,7 +615,7 @@ long static __numfun( int iPCount, long (*operation)(long wNum1, long wNum2), BO } -void static sizeofbits( USHORT * pusBytes, long *plPattern, long *plTestMSB ) +static void sizeofbits( USHORT * pusBytes, long *plPattern, long *plTestMSB ) { *pusBytes = ((ISNIL(1) || hb_parni(1) == 0) ? sizeof( int ) * 8 diff --git a/harbour/contrib/libct/files.c b/harbour/contrib/libct/files.c index f11162cd29..f5b0704f03 100644 --- a/harbour/contrib/libct/files.c +++ b/harbour/contrib/libct/files.c @@ -53,10 +53,12 @@ #define HB_OS_WIN_32_USED #include +#include -#if defined(HB_OS_DOS) -static struct ffblk fsOldFiles; +#if defined( HB_OS_DOS ) && !defined( __WATCOMC__ ) + static struct ffblk fsOldFiles; #endif + #if defined(HB_OS_OS2) && defined(__GNUC__) #include "hb_io.h" @@ -71,11 +73,17 @@ static struct ffblk fsOldFiles; #elif defined(HB_OS_DOS) && !defined(__RSX32__) #if defined(__DJGPP__) + #include + #include + #include #include #endif #include "hb_io.h" #include "dos.h" + #if defined( __WATCOMC__ ) + #else #include + #endif #endif #if defined(__GNUC__) && !defined(__MINGW32__) #include @@ -84,17 +92,20 @@ static struct ffblk fsOldFiles; #include #include #include + #include #if !defined(HAVE_POSIX_IO) #define HAVE_POSIX_IO #endif #endif + #if (defined(HB_OS_WIN_32) || defined(__MINGW32__)) && !defined(__CYGWIN__) static HANDLE hLastFind; static WIN32_FIND_DATA Lastff32; LPTSTR GetDate(FILETIME *rTime); LPTSTR GetTime(FILETIME *rTime); -#if !defined(_MSC_VER) && !defined(__RSXNT__) + +#if !defined( _MSC_VER ) && !defined( __RSXNT__ ) && !defined( __WATCOMC__ ) #include #endif #endif @@ -121,6 +132,7 @@ LPTSTR GetTime(FILETIME *rTime); #define FA_VOLCOMP 32768 /* M */ #endif +#if defined( OS_UNIX_COMPATIBLE ) || defined(HB_OS_OS2) static USHORT osToHarbourMask( USHORT usMask ) { USHORT usRetMask; @@ -167,12 +179,11 @@ static USHORT osToHarbourMask( USHORT usMask ) return usRetMask; } - +#endif HB_FUNC(FILEATTR) { - #if defined(HB_OS_DOS) #if defined(__DJGPP__) || defined(__BORLANDC__) { @@ -190,8 +201,8 @@ HB_FUNC(FILEATTR) iAttri = _chmod( szFile, 0 ); #endif hb_retni(iAttri); - #endif } + #endif #elif defined(HB_OS_WIN_32) { @@ -368,7 +379,7 @@ HB_FUNC(FILESEEK) } } } -#elif defined(HB_OS_DOS) +#elif defined(HB_OS_DOS) && !defined( __WATCOMC__ ) { int iFind; char *szFiles; @@ -470,7 +481,7 @@ HB_FUNC(FILESIZE) hb_retnl(dwFileSize); } } -#elif defined(HB_OS_DOS) +#elif defined(HB_OS_DOS) && !defined( __WATCOMC__ ) { int iFind; if (hb_pcount() >0) @@ -581,7 +592,7 @@ HB_FUNC(FILEDATE) hb_xfree(szDateString); } } -#elif defined(HB_OS_DOS) +#elif defined(HB_OS_DOS) && !defined( __WATCOMC__ ) { int iFind; if (hb_pcount() >0) @@ -697,7 +708,7 @@ HB_FUNC(FILETIME) hb_xfree(szDateString); } } -#elif defined(HB_OS_DOS) +#elif defined(HB_OS_DOS) && !defined( __WATCOMC__ ) { char szTime[7]; int iFind; @@ -736,7 +747,7 @@ HB_FUNC(FILETIME) struct tm *ft; stat(szFile,&sStat ); tm_t = sStat.st_mtime; - + ft = localtime( &tm_t ); sprintf( szTime, "%02d:%02d:%02d",ft->tm_hour, ft->tm_min, ft->tm_sec ); hb_retc(szTime); } diff --git a/harbour/contrib/libct/ftoc.c b/harbour/contrib/libct/ftoc.c index 89a577217f..fbf6af93bf 100644 --- a/harbour/contrib/libct/ftoc.c +++ b/harbour/contrib/libct/ftoc.c @@ -158,7 +158,7 @@ HB_FUNC( CTOF ) { pcString = hb_parc( 1 ); - for (i=0; i 0 && lMonth < 13 ) - return s_daysinmonth[ lMonth - 1 ] + - ( ( lMonth == 2 && hb_isleapyear( lYear ) ) ? 1 : 0 ); + if( iMonth > 0 && iMonth < 13 ) + return s_daysinmonth[ iMonth - 1 ] + + ( ( iMonth == 2 && hb_isleapyear( iYear ) ) ? 1 : 0 ); else return 0; } -long hb_doy( long lYear, long lMonth, long lDay ) +int hb_doy( int iYear, int iMonth, int iDay ) { int i; int iDoy = 0; - HB_TRACE(HB_TR_DEBUG, ("hb_doy(%ld, %ld, %ld)", lYear, lMonth, lDay)); + HB_TRACE(HB_TR_DEBUG, ("hb_doy(%d, %d, %d)", iYear, iMonth, iDay)); - for( i = 1; i < lMonth; i++ ) - iDoy += hb_daysinmonth( lYear, i ); + for( i = 1; i < iMonth; i++ ) + iDoy += hb_daysinmonth( iYear, i ); - return iDoy + lDay; + return iDoy + iDay; } -long hb_wom( long lYear, long lMonth, long lDay ) +int hb_wom( int iYear, int iMonth, int iDay ) { int iWom; - HB_TRACE(HB_TR_DEBUG, ("hb_wom(%ld, %ld, %ld)", lYear, lMonth, lDay)); + HB_TRACE(HB_TR_DEBUG, ("hb_wom(%d, %d, %d)", iYear, iMonth, iDay)); - iWom = lDay + hb_dateDOW( lYear, lMonth, 1 ) - 1; + iWom = iDay + hb_dateDOW( iYear, iMonth, 1 ) - 1; if( iWom > 0 ) - return ( iWom - hb_dateDOW( lYear, lMonth, lDay ) ) / 7 + 1; + return ( iWom - hb_dateDOW( iYear, iMonth, iDay ) ) / 7 + 1; else return 0; } -long hb_woy( long lYear, long lMonth, long lDay, BOOL bISO ) +int hb_woy( int iYear, int iMonth, int iDay, BOOL bISO ) { int iWeek, n; - HB_TRACE(HB_TR_DEBUG, ("hb_woy(%ld, %ld, %ld, %d)", lYear, lMonth, lDay, (int) bISO)); + HB_TRACE(HB_TR_DEBUG, ("hb_woy(%d, %d, %d, %d)", iYear, iMonth, iDay, (int) bISO)); - lDay = hb_doy( lYear, lMonth, lDay ); + iDay = hb_doy( iYear, iMonth, iDay ); n = ( ( ( 1 - ( bISO ? 1 : 0 ) ) % 7 ) ) - 1; - lDay += ( n > 0 ) ? 1 : 0; - iWeek = lDay / 7; + iDay += ( n > 0 ) ? 1 : 0; + iWeek = iDay / 7; if( bISO ) iWeek += ( n < 4 ) ? 1 : 0; else @@ -170,10 +170,10 @@ HB_FUNC( ISLEAPYEAR ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); - hb_retl( hb_isleapyear( lYear ) ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); + hb_retl( hb_isleapyear( iYear ) ); } else hb_retl( FALSE ); @@ -185,10 +185,10 @@ HB_FUNC( DAYSINMONTH ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); - hb_retni( hb_daysinmonth( lYear, lMonth ) ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); + hb_retni( hb_daysinmonth( iYear, iMonth ) ); } else hb_retni( 0 ); @@ -200,10 +200,10 @@ HB_FUNC( EOM ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); - hb_retd( lYear, lMonth, hb_daysinmonth( lYear, lMonth ) ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); + hb_retd( iYear, iMonth, hb_daysinmonth( iYear, iMonth ) ); } else hb_retdl( 0 ); @@ -215,10 +215,10 @@ HB_FUNC( BOM ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); - hb_retd( lYear, lMonth, 1 ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); + hb_retd( iYear, iMonth, 1 ); } else hb_retdl( 0 ); @@ -230,10 +230,10 @@ HB_FUNC( WOM ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); - hb_retni( hb_wom( lYear, lMonth, lDay ) ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); + hb_retni( hb_wom( iYear, iMonth, iDay ) ); } else hb_retni( 0 ); @@ -245,10 +245,10 @@ HB_FUNC( DOY ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); - hb_retni( hb_doy( lYear, lMonth, lDay ) ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); + hb_retni( hb_doy( iYear, iMonth, iDay ) ); } else hb_retni( 0 ); @@ -262,10 +262,10 @@ HB_FUNC( WOY ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); - hb_retni( hb_woy( lYear, lMonth, lDay, ISLOG( 2 ) ? hb_parl( 2 ) : TRUE ) ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); + hb_retni( hb_woy( iYear, iMonth, iDay, ISLOG( 2 ) ? hb_parl( 2 ) : TRUE ) ); } else hb_retni( 0 ); @@ -277,10 +277,10 @@ HB_FUNC( EOY ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); - hb_retd( lYear, 12, 31 ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); + hb_retd( iYear, 12, 31 ); } else hb_retdl( 0 ); @@ -292,10 +292,10 @@ HB_FUNC( BOY ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); - hb_retd( lYear, 1, 1 ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); + hb_retd( iYear, 1, 1 ); } else hb_retdl( 0 ); diff --git a/harbour/contrib/rdd_ads/ads1.c b/harbour/contrib/rdd_ads/ads1.c index 34ed06b9c1..f0673f691c 100644 --- a/harbour/contrib/rdd_ads/ads1.c +++ b/harbour/contrib/rdd_ads/ads1.c @@ -88,8 +88,8 @@ extern ADSHANDLE adsConnectHandle; #endif HB_INIT_SYMBOLS_BEGIN( ads1__InitSymbols ) -{ "_ADS", HB_FS_PUBLIC, HB_FUNCNAME( _ADS ), NULL }, -{ "ADS_GETFUNCTABLE", HB_FS_PUBLIC, HB_FUNCNAME( ADS_GETFUNCTABLE ), NULL } +{ "_ADS", HB_FS_PUBLIC, {HB_FUNCNAME( _ADS )}, NULL }, +{ "ADS_GETFUNCTABLE", HB_FS_PUBLIC, {HB_FUNCNAME( ADS_GETFUNCTABLE )}, NULL } HB_INIT_SYMBOLS_END( ads1__InitSymbols ) #if defined(_MSC_VER) @@ -105,7 +105,7 @@ HB_INIT_SYMBOLS_END( ads1__InitSymbols ) #pragma startup ads1__InitSymbols #endif -static RDDFUNCS adsSuper = { NULL }; +static RDDFUNCS adsSuper; void adsSetListener_callback( HB_set_enum setting, HB_set_listener_enum when ) { @@ -167,6 +167,7 @@ static void commonError( ADSAREAP pArea, USHORT uiGenCode, USHORT uiSubCode, cha return; } +#if 0 static void DumpArea( ADSAREAP pArea ) /* For debugging: call this to dump ads server settings to HB_TRACE. Currently in a quick-and-dirty state... */ { UNSIGNED8 pucTemp[1025]; @@ -215,7 +216,7 @@ static void DumpArea( ADSAREAP pArea ) /* For debugging: call this to dump ads } } } - +#endif /* static BOOL hb_nltoa( LONG lValue, char * szBuffer, USHORT uiLen ) { @@ -1245,7 +1246,7 @@ static ERRCODE adsPutValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) USHORT uiCount; BYTE * szText; BOOL bTypeError = TRUE; - long lDay, lMonth, lYear; + int iDay, iMonth, iYear; UNSIGNED8 pucFormat[ 11 ]; UNSIGNED16 pusLen = 11; @@ -1339,8 +1340,8 @@ static ERRCODE adsPutValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) bTypeError = FALSE; AdsGetDateFormat ( pucFormat, &pusLen ); AdsSetDateFormat ( (UNSIGNED8*)"YYYYMMDD" ); - hb_dateDecode( hb_itemGetDL( pItem ), &lYear, &lMonth, &lDay ); - hb_dateStrPut( ( char * ) szText, lYear, lMonth, lDay ); + hb_dateDecode( hb_itemGetDL( pItem ), &iYear, &iMonth, &iDay ); + hb_dateStrPut( ( char * ) szText, iYear, iMonth, iDay ); ulRetVal = AdsSetDate( pArea->hTable, ADSFIELD( uiIndex ), szText, 8 ); AdsSetDateFormat ( pucFormat ); } @@ -1745,7 +1746,7 @@ static ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo ) USHORT uiFields, uiCount; UNSIGNED8 szName[ ADS_MAX_FIELD_NAME + 1 ]; /* See adsGettValue() for why we don't use pArea->uiMaxFieldNameLength here */ - UNSIGNED16 pusBufLen, pusType; + UNSIGNED16 pusBufLen, pusType, pusDecimals; DBFIELDINFO dbFieldInfo; HB_TRACE(HB_TR_DEBUG, ("adsOpen(%p)", pArea)); @@ -1829,8 +1830,8 @@ static ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo ) case ADS_TIMESTAMP: case ADS_AUTOINC: dbFieldInfo.uiType = HB_IT_LONG; - AdsGetFieldDecimals( pArea->hTable, szName, ( UNSIGNED16 * ) &pulLength ); - dbFieldInfo.uiDec = ( USHORT ) pulLength; + AdsGetFieldDecimals( pArea->hTable, szName, ( UNSIGNED16 * ) &pusDecimals ); + dbFieldInfo.uiDec = ( USHORT ) pusDecimals; break; case ADS_LOGICAL: @@ -2711,7 +2712,7 @@ static ERRCODE adsScopeInfo( ADSAREAP pArea, USHORT nScope, PHB_ITEM pItem ) static ERRCODE adsSetFilter( ADSAREAP pArea, LPDBFILTERINFO pFilterInfo ) { - BOOL bValidExpr = FALSE; + UNSIGNED16 bValidExpr = FALSE; UNSIGNED16 usResolve = ADS_RESOLVE_DYNAMIC ; /*ADS_RESOLVE_IMMEDIATE ;get this from a SETting*/ UNSIGNED32 ulRetVal = AE_INVALID_EXPRESSION; @@ -2730,7 +2731,6 @@ static ERRCODE adsSetFilter( ADSAREAP pArea, LPDBFILTERINFO pFilterInfo ) if ( bValidExpr ) { - if ( hb_set.HB_SET_OPTIMIZE ) { ulRetVal = AdsSetAOF( pArea->hTable, (UNSIGNED8*) hb_itemGetCPtr( pFilterInfo->abFilterText), usResolve ); @@ -2742,7 +2742,7 @@ static ERRCODE adsSetFilter( ADSAREAP pArea, LPDBFILTERINFO pFilterInfo ) } /* else let SUPER handle filtering */ } - return ulRetVal == AE_SUCCESS ? SUCCESS : FAILURE ; + return ulRetVal == AE_SUCCESS ? SUCCESS : FAILURE; } #define adsSetLocate NULL @@ -3108,10 +3108,10 @@ HB_FUNC( ADS_GETFUNCTABLE ) uiCount = ( USHORT * ) hb_itemGetPtr( hb_param( 1, HB_IT_POINTER ) ); * uiCount = RDDFUNCSCOUNT; + pTable = ( RDDFUNCS * ) hb_itemGetPtr( hb_param( 2, HB_IT_POINTER ) ); HB_TRACE(HB_TR_DEBUG, ("ADS_GETFUNCTABLE(%i, %p)", *uiCount, pTable)); - pTable = ( RDDFUNCS * ) hb_itemGetPtr( hb_param( 2, HB_IT_POINTER ) ); if( pTable ) { iSetListenerHandle = hb_setListenerAdd( adsSetListener_callback ); @@ -3197,7 +3197,7 @@ HB_FUNC( ADSCUSTOMIZEAOF ) { ADSAREAP pArea; UNSIGNED32 ulNumRecs = 0; - UNSIGNED32 ulRecord; + UNSIGNED32 ulRecord = 0; UNSIGNED32 *pulRecords; UNSIGNED16 usOption = ADS_AOF_ADD_RECORD; UNSIGNED32 ulRetVal = AE_SUCCESS + 1; /* initialize to something other than success */ diff --git a/harbour/contrib/rdd_ads/adsfunc.c b/harbour/contrib/rdd_ads/adsfunc.c index 9da01f682b..49c4f8c685 100644 --- a/harbour/contrib/rdd_ads/adsfunc.c +++ b/harbour/contrib/rdd_ads/adsfunc.c @@ -226,7 +226,7 @@ HB_FUNC( ADSGETSERVERTIME ) SIGNED32 plTime = 0; - ADSHANDLE hConnect = ISNUM( 1 ) ? hb_parnl( 1 ) : adsConnectHandle; + ADSHANDLE hConnect = ISNUM( 1 ) ? ( ADSHANDLE ) hb_parnl( 1 ) : adsConnectHandle; ulRetVal = AdsGetServerTime( hConnect, pucDateBuf, &pusDateBufLen, &plTime, pucTimeBuf, &pusTimeBufLen ); @@ -1375,14 +1375,14 @@ HB_FUNC( ADSISINDEXED ) HB_FUNC( ADSISEXPRVALID ) /* cExpr */ { ADSAREAP pArea; - BOOL bValidExpr = FALSE; + UNSIGNED16 bValidExpr = FALSE; pArea = (ADSAREAP) hb_rddGetCurrentWorkAreaPointer(); - if(pArea && ISCHAR( 1 ) ) + if( pArea && ISCHAR( 1 ) ) AdsIsExprValid( pArea->hTable, (UNSIGNED8*) hb_parc( 1 ), (UNSIGNED16*) &bValidExpr ); - hb_retl(bValidExpr); + hb_retl( bValidExpr != FALSE ); } HB_FUNC( ADSGETNUMINDEXES ) /* cExpr */ @@ -1428,11 +1428,7 @@ HB_FUNC( ADSGETNUMOPENTABLES ) HB_FUNC( ADSSHOWERROR ) { - UNSIGNED8* pucTitle; - if( ISCHAR( 1 ) ) - { - pucTitle = (UNSIGNED8*) hb_parc( 1 ); - } + UNSIGNED8* pucTitle = ISCHAR( 1 ) ? (UNSIGNED8*) hb_parc( 1 ) : NULL; AdsShowError( pucTitle ); } @@ -1911,4 +1907,4 @@ HB_FUNC( ADSCOPYTABLECONTENTS ) } #endif /* ADS_REQUIRE_VERSION6 */ -/* Please add all-version functions above this block */ \ No newline at end of file +/* Please add all-version functions above this block */ diff --git a/harbour/contrib/samples/date.c b/harbour/contrib/samples/date.c index 036b8e33e4..a4c5eab7da 100644 --- a/harbour/contrib/samples/date.c +++ b/harbour/contrib/samples/date.c @@ -59,23 +59,23 @@ */ HB_FUNC( MDY ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; char szDate[ 9 ]; char szFormatted[ 11 ]; char * szReturn; int iBufferLen; int iLen; - hb_dateDecode( hb_parnl( 1 ), &lYear, &lMonth, &lDay ); + hb_dateDecode( hb_parnl( 1 ), &iYear, &iMonth, &iDay ); hb_dateFormat( hb_pardsbuff( szDate, 1 ), szFormatted, "MM/DD/YYYY" ); - iLen = strlen( hb_dateCMonth( lMonth ) ); + iLen = strlen( hb_dateCMonth( iMonth ) ); iBufferLen = iLen + ( hb_set.hb_set_century ? 9 : 7 ); szReturn = ( char * ) hb_xgrab( iBufferLen ); memset( szReturn, ' ', iBufferLen + 1 ); - memcpy( szReturn, hb_dateCMonth( lMonth ), iLen ); + memcpy( szReturn, hb_dateCMonth( iMonth ), iLen ); memcpy( szReturn + iLen + 1, szFormatted + 3, 2 ); szReturn[ iLen + 3 ] = ','; memcpy( szReturn + iLen + 5, szFormatted + 6 + ( hb_set.hb_set_century ? 0 : 2 ), 2 + ( hb_set.hb_set_century ? 2 : 0 ) ); @@ -88,24 +88,24 @@ HB_FUNC( MDY ) */ HB_FUNC( DMY ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; char szDate[ 9 ]; char szFormatted[ 11 ]; char * szReturn; int iBufferLen; int iLen; - hb_dateDecode( hb_parnl( 1 ), &lYear, &lMonth, &lDay ); + hb_dateDecode( hb_parnl( 1 ), &iYear, &iMonth, &iDay ); hb_dateFormat( hb_pardsbuff( szDate, 1 ), szFormatted, "MM/DD/YYYY" ); - iLen = strlen( hb_dateCMonth( lMonth ) ); + iLen = strlen( hb_dateCMonth( iMonth ) ); iBufferLen = iLen + ( hb_set.hb_set_century ? 9 : 7 ); szReturn = ( char * ) hb_xgrab( iBufferLen ); memset( szReturn, ' ', iBufferLen ); memcpy( szReturn, szFormatted + 3, 2 ); - memcpy( szReturn + 3, hb_dateCMonth( lMonth ), iLen ); + memcpy( szReturn + 3, hb_dateCMonth( iMonth ), iLen ); memcpy( szReturn + iLen + 4, szFormatted + 6 + ( hb_set.hb_set_century ? 0 : 2 ), 2 + ( hb_set.hb_set_century ? 2 : 0 ) ); hb_retclen( szReturn, iBufferLen ); @@ -116,27 +116,27 @@ HB_FUNC( DMY ) */ HB_FUNC( DATEASAGE ) { - long lAge = 0; + int iAge = 0; PHB_ITEM pDate = hb_param( 1, HB_IT_DATE ); if( pDate ) { - long lYear, lMonth, lDay; - long lThisYear, lThisMonth, lThisDay; + int iYear, iMonth, iDay; + int iThisYear, iThisMonth, iThisDay; - hb_dateToday( &lThisYear, &lThisMonth, &lThisDay ); - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); + hb_dateToday( &iThisYear, &iThisMonth, &iThisDay ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); - if( lThisYear > lYear ) + if( iThisYear > iYear ) { - lAge = lThisYear - lYear; + iAge = iThisYear - iYear; - if( lThisMonth < lMonth || ( lThisMonth == lMonth && lThisDay < lDay ) ) - --lAge; + if( iThisMonth < iMonth || ( iThisMonth == iMonth && iThisDay < iDay ) ) + --iAge; } } - hb_retnl( lAge ); + hb_retni( iAge ); } /* ADDMONTH( , ) --> @@ -144,39 +144,39 @@ HB_FUNC( DATEASAGE ) */ HB_FUNC( ADDMONTH ) { - long lMonths = hb_parnl( 2 ); - long lYear, lMonth, lDay; + int iMonths = hb_parnl( 2 ); + int iYear, iMonth, iDay; int iLimit, iMonthAdd, iYearAdd; long lNew; - hb_dateDecode( hb_parnl( 1 ), &lYear, &lMonth, &lDay ); + hb_dateDecode( hb_parnl( 1 ), &iYear, &iMonth, &iDay ); - iLimit = 12 - lMonth + 1; - iYearAdd = lMonths / 12; - lMonths %= 12; + iLimit = 12 - iMonth + 1; + iYearAdd = iMonths / 12; + iMonths %= 12; - if( lMonths >= iLimit ) + if( iMonths >= iLimit ) iYearAdd++; - lYear += iYearAdd; + iYear += iYearAdd; - iMonthAdd = lMonths % 12; - lMonth = ( lMonth + iMonthAdd ) % 12; + iMonthAdd = iMonths % 12; + iMonth = ( iMonth + iMonthAdd ) % 12; - if( lMonth == 0 ) - lMonth = 12; + if( iMonth == 0 ) + iMonth = 12; - lNew = hb_dateEncode( lYear, lMonth, lDay ); + lNew = hb_dateEncode( iYear, iMonth, iDay ); if( !lNew ) { - lMonth = ( lMonth + 1 ) % 12; - lDay = 1; - lYear = lYear + ( ( lMonth + 1 ) / 12 ); + iMonth = ( iMonth + 1 ) % 12; + iDay = 1; + iYear = iYear + ( ( iMonth + 1 ) / 12 ); } - hb_retd( lYear, lMonth, lDay ); + hb_retd( iYear, iMonth, iDay ); } /* DATEASARRAY( ) --> { Year, Month, Day } @@ -190,19 +190,19 @@ HB_FUNC( DATEASARRAY ) if( pDate ) { PHB_ITEM pItem; - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); - pItem = hb_itemPutNL( NULL, lYear ); + pItem = hb_itemPutNI( NULL, iYear ); hb_itemArrayPut( pReturn, 1, pItem ); hb_itemRelease( pItem ); - pItem = hb_itemPutNL( NULL, lMonth ); + pItem = hb_itemPutNI( NULL, iMonth ); hb_itemArrayPut( pReturn, 2, pItem ); hb_itemRelease( pItem ); - pItem = hb_itemPutNL( NULL, lDay ); + pItem = hb_itemPutNI( NULL, iDay ); hb_itemArrayPut( pReturn, 3, pItem ); hb_itemRelease( pItem ); } @@ -218,7 +218,7 @@ HB_FUNC( ARRAYASDATE ) PHB_ITEM pArray = hb_param( 1, HB_IT_ARRAY ); if( pArray ) - hb_retd( hb_arrayGetNL( pArray, 1 ), hb_arrayGetNL( pArray, 2 ), hb_arrayGetNL( pArray, 3 ) ); + hb_retd( hb_arrayGetNI( pArray, 1 ), hb_arrayGetNI( pArray, 2 ), hb_arrayGetNI( pArray, 3 ) ); else hb_retdl( 0 ); } @@ -231,11 +231,11 @@ HB_FUNC( DATEISLEAP ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); - hb_retl( ( lYear % 4 == 0 && lYear % 100 != 0 ) || ( lYear % 400 == 0 ) ); + hb_retl( ( iYear % 4 == 0 && iYear % 100 != 0 ) || ( iYear % 400 == 0 ) ); } else hb_retl( FALSE ); @@ -245,5 +245,5 @@ HB_FUNC( DATEISLEAP ) */ HB_FUNC( NTOD ) { - hb_retd( hb_parnl( 3 ), hb_parnl( 1 ), hb_parnl( 2 ) ); + hb_retd( hb_parni( 3 ), hb_parni( 1 ), hb_parni( 2 ) ); } diff --git a/harbour/include/dbinfo.ch b/harbour/include/dbinfo.ch index f398b14b6e..91ecad18d0 100644 --- a/harbour/include/dbinfo.ch +++ b/harbour/include/dbinfo.ch @@ -113,6 +113,11 @@ /* Harbour extensions */ #define DBOI_SKIPEVAL 100 /* skip while code block doesn't return TRUE */ #define DBOI_SKIPEVALBACK 101 /* skip backward while code block doesn't return TRUE */ +#define DBOI_SKIPREGEX 102 /* skip while regular expression on index key doesn't return TRUE */ +#define DBOI_SKIPREGEXBACK 103 /* skip backward while regular expression on index key doesn't return TRUE */ +#define DBOI_SKIPWILD 104 /* skip while while comparison with given pattern with wildcards doesn't return TRUE */ +#define DBOI_SKIPWILDBACK 105 /* skip backward while comparison with given pattern with wildcards doesn't return TRUE */ +#define DBOI_SCOPEEVAL 106 /* skip through index evaluating given C function */ /* Return values for DBOI_OPTLEVEL */ #define DBOI_OPTIMIZED_NONE 0 @@ -126,6 +131,13 @@ #define DBRI_RECNO 4 #define DBRI_UPDATED 5 +/* constants for some SCOPED DBOI_* parameter */ +#define DBRMI_FUNCTION 1 +#define DBRMI_PARAM 2 +#define DBRMI_LOVAL 3 +#define DBRMI_HIVAL 4 +#define DBRMI_RESULT 5 +#define DBRMI_SIZE 5 /* constants for dbInfo() */ #define DBI_ISDBF 1 /* Does this RDD support DBFs? */ @@ -160,6 +172,37 @@ #define DBI_DB_VERSION 101 /* Version of the Host driver */ #define DBI_RDD_VERSION 102 /* current RDD's version */ +/* HARBOUR extension */ +#define DBI_LOCKSCHEME 128 /* Locking scheme used by RDD */ +#define DBI_ISREADONLY 129 /* Was the file opened readonly? */ +#define DBI_ROLLBACK 130 /* Rollback changes made to current record */ + #define DBI_USER 1000 /* User-defined DBI_ constants */ +/* BLOB support - definitions for internal use by BLOB.CH */ +#define DBI_BLOB_DIRECT_EXPORT 201 +#define DBI_BLOB_DIRECT_GET 202 +#define DBI_BLOB_DIRECT_IMPORT 203 +#define DBI_BLOB_DIRECT_PUT 204 +#define DBI_BLOB_ROOT_GET 205 +#define DBI_BLOB_ROOT_PUT 206 +#define DBI_BLOB_ROOT_LOCK 207 +#define DBI_BLOB_ROOT_UNLOCK 208 + +/* CA-CLIPPER documented for public use */ +#define DBI_BLOB_DIRECT_LEN 209 +#define DBI_BLOB_DIRECT_TYPE 210 +#define DBI_BLOB_INTEGRITY 211 +#define DBI_BLOB_OFFSET 212 +#define DBI_BLOB_RECOVER 213 + +#define DBS_BLOB_GET 201 /* This is internal definition */ +#define DBS_BLOB_LEN 202 +#define DBS_BLOB_OFFSET 203 +#define DBS_BLOB_POINTER 204 +#define DBS_BLOB_TYPE 205 + +#define BLOB_EXPORT_APPEND 1 +#define BLOB_EXPORT_OVERWRITE 0 + #endif /* HB_DBINFO_CH_ */ diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index b018588d73..f9c2765e40 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -73,7 +73,6 @@ extern "C" { #define HB_IT_LONG ( ( USHORT ) 0x0008 ) #define HB_IT_DOUBLE ( ( USHORT ) 0x0010 ) #define HB_IT_DATE ( ( USHORT ) 0x0020 ) -#define HB_IT_LONGLONG ( ( USHORT ) 0x0040 ) #define HB_IT_LOGICAL ( ( USHORT ) 0x0080 ) #define HB_IT_SYMBOL ( ( USHORT ) 0x0100 ) #define HB_IT_ALIAS ( ( USHORT ) 0x0200 ) @@ -86,7 +85,9 @@ extern "C" { #define HB_IT_ARRAY ( ( USHORT ) 0x8000 ) #define HB_IT_OBJECT HB_IT_ARRAY #define HB_IT_NUMERIC ( ( USHORT ) ( HB_IT_INTEGER | HB_IT_LONG | HB_IT_DOUBLE ) ) +#define HB_IT_NUMINT ( ( USHORT ) ( HB_IT_INTEGER | HB_IT_LONG ) ) #define HB_IS_NUMBER( p ) ( ( p )->type & HB_IT_NUMERIC ) +#define HB_IS_NUMINT( p ) ( ( p )->type & HB_IT_NUMINT ) #define HB_IT_ANY ( ( USHORT ) 0xFFFF ) #define HB_IS_OF_TYPE( p, t ) ( ( ( p )->type & ~HB_IT_BYREF ) == t ) @@ -107,6 +108,12 @@ extern "C" { #define HB_IS_MEMVAR( p ) HB_IS_OF_TYPE( p, HB_IT_MEMVAR ) #define HB_IS_POINTER( p ) HB_IS_OF_TYPE( p, HB_IT_POINTER ) +#if defined(__GNUC__) +# define HB_ITEM_NIL { HB_IT_NIL, {} } +#else +# define HB_ITEM_NIL { HB_IT_NIL, NULL } +#endif + #define ISNIL( n ) ( hb_param( n, HB_IT_ANY ) == NULL || HB_IS_NIL( hb_param( n, HB_IT_ANY ) ) ) /* NOTE: Intentionally using a different method */ #define ISCHAR( n ) ( hb_param( n, HB_IT_STRING ) != NULL ) #define ISNUM( n ) ( hb_param( n, HB_IT_NUMERIC ) != NULL ) @@ -172,7 +179,7 @@ struct hb_struLogical struct hb_struLong { USHORT length; - long value; + HB_LONG value; }; struct hb_struMemvar @@ -283,21 +290,25 @@ typedef USHORT ERRCODE; extern HB_SYMB hb_symEval; /* Extend API */ -extern char HB_EXPORT * hb_parc( int iParam, ... ); /* retrieve a string parameter */ -extern ULONG HB_EXPORT hb_parclen( int iParam, ... ); /* retrieve a string parameter length */ -extern ULONG HB_EXPORT hb_parcsiz( int iParam, ... ); /* retrieve a by-reference string parameter length, including terminator */ -extern char HB_EXPORT * hb_pards( int iParam, ... ); /* retrieve a date as a string yyyymmdd */ -extern char HB_EXPORT * hb_pardsbuff( char * szDate, int iParam, ... ); /* retrieve a date as a string yyyymmdd */ -extern ULONG HB_EXPORT hb_parinfa( int iParamNum, ULONG uiArrayIndex ); /* retrieve length or element type of an array parameter */ -extern int HB_EXPORT hb_parinfo( int iParam ); /* Determine the param count or data type */ -extern int HB_EXPORT hb_parl( int iParam, ... ); /* retrieve a logical parameter as an int */ -extern double HB_EXPORT hb_parnd( int iParam, ... ); /* retrieve a numeric parameter as a double */ -extern int HB_EXPORT hb_parni( int iParam, ... ); /* retrieve a numeric parameter as a integer */ -extern long HB_EXPORT hb_parnl( int iParam, ... ); /* retrieve a numeric parameter as a long */ -extern void HB_EXPORT * hb_parptr( int iParam, ... ); /* retrieve a parameter as a pointer */ -extern PHB_ITEM HB_EXPORT hb_param( int iParam, int iMask ); /* retrieve a generic parameter */ -extern PHB_ITEM HB_EXPORT hb_paramError( int iParam ); /* Returns either the generic parameter or a NIL item if param not provided */ -extern BOOL HB_EXPORT hb_extIsArray( int iParam ); +extern char HB_EXPORT * hb_parc( int iParam, ... ); /* retrieve a string parameter */ +extern ULONG HB_EXPORT hb_parclen( int iParam, ... ); /* retrieve a string parameter length */ +extern ULONG HB_EXPORT hb_parcsiz( int iParam, ... ); /* retrieve a by-reference string parameter length, including terminator */ +extern char HB_EXPORT * hb_pards( int iParam, ... ); /* retrieve a date as a string yyyymmdd */ +extern char HB_EXPORT * hb_pardsbuff( char * szDate, int iParam, ... ); /* retrieve a date as a string yyyymmdd */ +extern ULONG HB_EXPORT hb_parinfa( int iParamNum, ULONG uiArrayIndex ); /* retrieve length or element type of an array parameter */ +extern int HB_EXPORT hb_parinfo( int iParam ); /* Determine the param count or data type */ +extern int HB_EXPORT hb_parl( int iParam, ... ); /* retrieve a logical parameter as an int */ +extern double HB_EXPORT hb_parnd( int iParam, ... ); /* retrieve a numeric parameter as a double */ +extern int HB_EXPORT hb_parni( int iParam, ... ); /* retrieve a numeric parameter as a integer */ +extern long HB_EXPORT hb_parnl( int iParam, ... ); /* retrieve a numeric parameter as a long */ +extern HB_LONG HB_EXPORT hb_parnint( int iParam, ... ); /* retrieve a numeric parameter as a HB_LONG */ +extern void HB_EXPORT * hb_parptr( int iParam, ... ); /* retrieve a parameter as a pointer */ +extern PHB_ITEM HB_EXPORT hb_param( int iParam, int iMask ); /* retrieve a generic parameter */ +extern PHB_ITEM HB_EXPORT hb_paramError( int iParam ); /* Returns either the generic parameter or a NIL item if param not provided */ +extern BOOL HB_EXPORT hb_extIsArray( int iParam ); +#ifndef HB_LONG_LONG_OFF +extern LONGLONG HB_EXPORT hb_parnll( int iParam, ... ); /* retrieve a numeric parameter as a long long */ +#endif #ifndef HB_NO_DEFAULT_API_MACROS #ifndef HB_API_MACROS @@ -326,10 +337,14 @@ extern BOOL HB_EXPORT hb_extIsArray( int iParam ); #define hb_retnd( dNumber ) hb_itemPutND( &hb_stack.Return, dNumber ) #define hb_retni( iNumber ) hb_itemPutNI( &hb_stack.Return, iNumber ) #define hb_retnl( lNumber ) hb_itemPutNL( &hb_stack.Return, lNumber ) +#define hb_retnll( lNumber ) hb_itemPutNLL( &hb_stack.Return, lNumber ) #define hb_retnlen( dNumber, iWidth, iDec ) hb_itemPutNLen( &hb_stack.Return, dNumber, iWidth, iDec ) #define hb_retndlen( dNumber, iWidth, iDec ) hb_itemPutNDLen( &hb_stack.Return, dNumber, iWidth, iDec ) #define hb_retnilen( iNumber, iWidth ) hb_itemPutNILen( &hb_stack.Return, iNumber, iWidth ) #define hb_retnllen( lNumber, iWidth ) hb_itemPutNLLen( &hb_stack.Return, lNumber, iWidth ) +#define hb_retnlllen( lNumber, iWidth ) hb_itemPutNLLLen( &hb_stack.Return, lNumber, iWidth ) +#define hb_retnint( iNumber ) hb_itemPutNInt( &hb_stack.Return, iNumber ) +#define hb_retnintlen( lNumber, iWidth ) hb_itemPutNIntLen( &hb_stack.Return, lNumber, iWidth ) #define hb_retptr( pointer ) hb_itemPutPtr( &hb_stack.Return, pointer ) #else @@ -343,18 +358,24 @@ extern void HB_EXPORT hb_retc_const( char * szText ); /* returns a string as a extern void HB_EXPORT hb_retclen( char * szText, ULONG ulLen ); /* returns a string with a specific length */ extern void HB_EXPORT hb_retclen_buffer( char * szText, ULONG ulLen ); /* sames as above, but accepts an allocated buffer */ extern void HB_EXPORT hb_retds( char * szDate ); /* returns a date, must use yyyymmdd format */ -extern void HB_EXPORT hb_retd( long lYear, long lMonth, long lDay ); /* returns a date */ +extern void HB_EXPORT hb_retd( int iYear, int iMonth, int iDay ); /* returns a date */ extern void HB_EXPORT hb_retdl( long lJulian ); /* returns a long value as a julian date */ extern void HB_EXPORT hb_retl( int iTrueFalse ); /* returns a logical integer */ extern void HB_EXPORT hb_retnd( double dNumber ); /* returns a double */ extern void HB_EXPORT hb_retni( int iNumber ); /* returns a integer number */ -extern void HB_EXPORT hb_retnl( long lNumber ); /* returns a long number */ +extern void HB_EXPORT hb_retnl( long lNumber );/* returns a long number */ +extern void HB_EXPORT hb_retnint( HB_LONG lNumber );/* returns a long number */ extern void HB_EXPORT hb_retnlen( double dNumber, int iWidth, int iDec ); /* returns a double, with specific width and decimals */ extern void HB_EXPORT hb_retndlen( double dNumber, int iWidth, int iDec ); /* returns a double, with specific width and decimals */ extern void HB_EXPORT hb_retnilen( int iNumber, int iWidth ); /* returns a integer number, with specific width */ extern void HB_EXPORT hb_retnllen( long lNumber, int iWidth ); /* returns a long number, with specific width */ +extern void HB_EXPORT hb_retnintlen( HB_LONG lNumber, int iWidth ); /* returns a long long number, with specific width */ extern void HB_EXPORT hb_reta( ULONG ulLen ); /* returns an array with a specific length */ extern void HB_EXPORT hb_retptr( void * ptr ); /* returns a pointer */ +#ifndef HB_LONG_LONG_OFF +extern void HB_EXPORT hb_retnll( LONGLONG lNumber );/* returns a long long number */ +extern void HB_EXPORT hb_retnlllen( LONGLONG lNumber, int iWidth ); /* returns a long long number, with specific width */ +#endif #endif @@ -365,7 +386,11 @@ extern int HB_EXPORT hb_storl( int iLogical, int iParam, ... ); /* stores a l extern int HB_EXPORT hb_storni( int iValue, int iParam, ... ); /* stores an integer on a variable by reference */ extern int HB_EXPORT hb_stornl( long lValue, int iParam, ... ); /* stores a long on a variable by reference */ extern int HB_EXPORT hb_stornd( double dValue, int iParam, ... ); /* stores a double on a variable by reference */ +extern int HB_EXPORT hb_stornint( HB_LONG lValue, int iParam, ... ); /* stores a HB_LONG on a variable by reference */ extern int HB_EXPORT hb_storptr( void * pointer, int iParam, ... ); /* stores a pointer on a variable by reference */ +#ifndef HB_LONG_LONG_OFF +extern int HB_EXPORT hb_stornll( LONGLONG lValue, int iParam, ... ); /* stores a long long on a variable by reference */ +#endif extern void HB_EXPORT hb_xinit( void ); /* Initialize fixed memory subsystem */ extern void HB_EXPORT hb_xexit( void ); /* Deinitialize fixed memory subsystem */ @@ -374,7 +399,7 @@ extern void HB_EXPORT * hb_xgrab( ULONG ulSize ); /* allocate extern void HB_EXPORT hb_xfree( void * pMem ); /* frees memory */ extern void HB_EXPORT * hb_xrealloc( void * pMem, ULONG ulSize ); /* reallocates memory */ extern ULONG HB_EXPORT hb_xsize( void * pMem ); /* returns the size of an allocated memory block */ -extern ULONG hb_xquery( USHORT uiMode ); /* Query different types of memory information */ +extern ULONG hb_xquery( USHORT uiMode ); /* Query different types of memory information */ #if UINT_MAX == ULONG_MAX /* NOTE: memcpy/memset can work with ULONG data blocks */ @@ -388,38 +413,42 @@ extern void * hb_xmemset( void * pDestArg, int iFill, ULONG ulLen ); /* set mo #endif /* array management */ -extern BOOL HB_EXPORT hb_arrayNew( PHB_ITEM pItem, ULONG ulLen ); /* creates a new array */ -extern ULONG HB_EXPORT hb_arrayLen( PHB_ITEM pArray ); /* retrives the array len */ -extern BOOL HB_EXPORT hb_arrayIsObject( PHB_ITEM pArray ); /* retrives if the array is an object */ -extern BOOL HB_EXPORT hb_arrayAdd( PHB_ITEM pArray, PHB_ITEM pItemValue ); /* add a new item to the end of an array item */ -extern BOOL HB_EXPORT hb_arrayIns( PHB_ITEM pArray, ULONG ulIndex ); /* insert a nil item into an array, without changing the length */ -extern BOOL HB_EXPORT hb_arrayDel( PHB_ITEM pArray, ULONG ulIndex ); /* delete an array item, without changing length */ -extern BOOL HB_EXPORT hb_arraySize( PHB_ITEM pArray, ULONG ulLen ); /* sets the array total length */ -extern BOOL hb_arrayLast( PHB_ITEM pArray, PHB_ITEM pResult ); /* retrieve last item in an array */ -extern BOOL hb_arrayRelease( PHB_ITEM pArray ); /* releases an array - don't call it - use ItemRelease() !!! */ -extern BOOL HB_EXPORT hb_arraySet( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ); /* sets an array element */ -extern BOOL HB_EXPORT hb_arrayGet( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ); /* retrieves an item */ -extern PHB_ITEM hb_arrayGetItemPtr( PHB_ITEM pArray, ULONG ulIndex ); /* returns pointer to specified element of the array */ -extern ULONG hb_arrayCopyC( PHB_ITEM pArray, ULONG ulIndex, char * szBuffer, ULONG ulLen ); /* copy a string into an array item */ -extern char * hb_arrayGetC( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the string contained on an array element */ -extern char * hb_arrayGetCPtr( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the string pointer on an array element */ -extern ULONG hb_arrayGetCLen( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the string length contained on an array element */ -extern void * hb_arrayGetPtr( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the pointer contained on an array element */ -extern BOOL hb_arrayGetL( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the logical value contained on an array element */ -extern int hb_arrayGetNI( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the int value contained on an array element */ -extern long hb_arrayGetNL( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the long numeric value contained on an array element */ -extern double hb_arrayGetND( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the double value contained on an array element */ -extern char * hb_arrayGetDS( PHB_ITEM pArray, ULONG ulIndex, char * szDate ); /* retrieves the date value contained in an array element */ -extern long hb_arrayGetDL( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the date value contained in an array element, as a long integer */ -extern USHORT hb_arrayGetType( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the type of an array item */ -extern BOOL hb_arrayFill( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * pulCount ); /* fill an array with a given item */ -extern ULONG hb_arrayScan( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * pulCount ); /* scan an array for a given item, or until code-block item returns TRUE */ -extern BOOL hb_arrayEval( PHB_ITEM pArray, PHB_ITEM bBlock, ULONG * pulStart, ULONG * pulCount ); /* execute a code-block for every element of an array item */ -extern BOOL hb_arrayCopy( PHB_ITEM pSrcArray, PHB_ITEM pDstArray, ULONG * pulStart, ULONG * pulCount, ULONG * pulTarget ); /* copy items from one array to another */ -extern PHB_ITEM hb_arrayClone( PHB_ITEM pArray, PHB_NESTED_CLONED pClonedList ); /* returns a duplicate of an existing array, including all nested items */ -extern BOOL hb_arraySort( PHB_ITEM pArray, ULONG * pulStart, ULONG * pulCount, PHB_ITEM pBlock ); /* sorts an array item */ -extern PHB_ITEM hb_arrayFromStack( USHORT uiLen ); /* Creates and returns an Array of n Elements from the Eval Stack - Does NOT pop the items. */ -extern PHB_ITEM hb_arrayFromParams( PHB_ITEM *pBase ); /* Creates and returns an Array of Generic Parameters for specified base symbol. */ +extern BOOL HB_EXPORT hb_arrayNew( PHB_ITEM pItem, ULONG ulLen ); /* creates a new array */ +extern ULONG HB_EXPORT hb_arrayLen( PHB_ITEM pArray ); /* retrives the array len */ +extern BOOL HB_EXPORT hb_arrayIsObject( PHB_ITEM pArray ); /* retrives if the array is an object */ +extern BOOL HB_EXPORT hb_arrayAdd( PHB_ITEM pArray, PHB_ITEM pItemValue ); /* add a new item to the end of an array item */ +extern BOOL HB_EXPORT hb_arrayIns( PHB_ITEM pArray, ULONG ulIndex ); /* insert a nil item into an array, without changing the length */ +extern BOOL HB_EXPORT hb_arrayDel( PHB_ITEM pArray, ULONG ulIndex ); /* delete an array item, without changing length */ +extern BOOL HB_EXPORT hb_arraySize( PHB_ITEM pArray, ULONG ulLen ); /* sets the array total length */ +extern BOOL hb_arrayLast( PHB_ITEM pArray, PHB_ITEM pResult ); /* retrieve last item in an array */ +extern BOOL hb_arrayRelease( PHB_ITEM pArray ); /* releases an array - don't call it - use ItemRelease() !!! */ +extern BOOL HB_EXPORT hb_arraySet( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ); /* sets an array element */ +extern BOOL HB_EXPORT hb_arrayGet( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ); /* retrieves an item */ +extern PHB_ITEM hb_arrayGetItemPtr( PHB_ITEM pArray, ULONG ulIndex ); /* returns pointer to specified element of the array */ +extern ULONG hb_arrayCopyC( PHB_ITEM pArray, ULONG ulIndex, char * szBuffer, ULONG ulLen ); /* copy a string into an array item */ +extern char * hb_arrayGetC( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the string contained on an array element */ +extern char * hb_arrayGetCPtr( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the string pointer on an array element */ +extern ULONG hb_arrayGetCLen( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the string length contained on an array element */ +extern void * hb_arrayGetPtr( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the pointer contained on an array element */ +extern BOOL hb_arrayGetL( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the logical value contained on an array element */ +extern int hb_arrayGetNI( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the int value contained on an array element */ +extern long hb_arrayGetNL( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the long numeric value contained on an array element */ +extern HB_LONG hb_arrayGetNInt( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the HB_LONG value contained on an array element */ +extern double hb_arrayGetND( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the double value contained on an array element */ +extern char * hb_arrayGetDS( PHB_ITEM pArray, ULONG ulIndex, char * szDate ); /* retrieves the date value contained in an array element */ +extern long hb_arrayGetDL( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the date value contained in an array element, as a long integer */ +extern USHORT hb_arrayGetType( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the type of an array item */ +extern BOOL hb_arrayFill( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * pulCount ); /* fill an array with a given item */ +extern ULONG hb_arrayScan( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * pulCount ); /* scan an array for a given item, or until code-block item returns TRUE */ +extern BOOL hb_arrayEval( PHB_ITEM pArray, PHB_ITEM bBlock, ULONG * pulStart, ULONG * pulCount ); /* execute a code-block for every element of an array item */ +extern BOOL hb_arrayCopy( PHB_ITEM pSrcArray, PHB_ITEM pDstArray, ULONG * pulStart, ULONG * pulCount, ULONG * pulTarget ); /* copy items from one array to another */ +extern PHB_ITEM hb_arrayClone( PHB_ITEM pArray, PHB_NESTED_CLONED pClonedList ); /* returns a duplicate of an existing array, including all nested items */ +extern BOOL hb_arraySort( PHB_ITEM pArray, ULONG * pulStart, ULONG * pulCount, PHB_ITEM pBlock ); /* sorts an array item */ +extern PHB_ITEM hb_arrayFromStack( USHORT uiLen ); /* Creates and returns an Array of n Elements from the Eval Stack - Does NOT pop the items. */ +extern PHB_ITEM hb_arrayFromParams( PHB_ITEM *pBase ); /* Creates and returns an Array of Generic Parameters for specified base symbol. */ +#ifndef HB_LONG_LONG_OFF +extern LONGLONG hb_arrayGetNLL( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the long long numeric value contained on an array element */ +#endif /* string management */ @@ -435,16 +464,26 @@ extern char * hb_strdup( const char * pszText ); /* returns a pointer to a new extern BOOL hb_strMatchRegExp( const char * szString, const char * szMask ); /* compare two strings using a regular expression pattern */ extern BOOL hb_strEmpty( const char * szText, ULONG ulLen ); /* returns whether a string contains only white space */ extern void hb_strDescend( char * szStringTo, const char * szStringFrom, ULONG ulLen ); /* copy a string to a buffer, inverting each character */ +extern BOOL hb_strMatchWild(const char *szString, const char *szPattern ); /* compare two strings using pattern with wildcard (?*) */ extern ULONG hb_strAt( const char * szSub, ULONG ulSubLen, const char * szText, ULONG ulLen ); /* returns an index to a sub-string within another string */ extern char * hb_strUpper( char * szText, ULONG ulLen ); /* convert an existing string buffer to upper case */ extern char * hb_strLower( char * szText, ULONG ulLen ); /* convert an existing string buffer to lower case */ +extern char * hb_strncpy( char * pDest, const char * pSource, ULONG ulLen ); /* copy at most ulLen bytes from string buffer to another buffer and _always_ set 0 in destin buffer */ +extern char * hb_strncat( char * pDest, const char * pSource, ULONG ulLen ); /* copy at most ulLen-strlen(pDest) bytes from string buffer to another buffer and _always_ set 0 in destin buffer */ +extern char * hb_strncpyTrim( char * pDest, const char * pSource, ULONG ulLen ); extern char * hb_strncpyUpper( char * pDest, const char * pSource, ULONG ulLen ); /* copy an existing string buffer to another buffer, as upper case */ extern char * hb_strncpyUpperTrim( char * pDest, const char * pSource, ULONG ulLen ); extern double hb_strVal( const char * szText, ULONG ulLen ); /* return the numeric value of a character string representation of a number */ extern char * hb_strLTrim( const char * szText, ULONG * ulLen ); /* return a pointer to the first non-white space character */ extern ULONG hb_strRTrimLen( const char * szText, ULONG ulLen, BOOL bAnySpace ); /* return length of a string, ignoring trailing white space (or true spaces) */ +extern BOOL hb_compStrToNum( const char* szNum, HB_LONG * plVal, double * pdVal, int * piDec, int * piWidth ); /* converts string to number, sets iDec, iWidth and returns TRUE if results is double */ +extern BOOL hb_valStrnToNum( const char* szNum, ULONG ulLen, HB_LONG * plVal, double * pdVal, int * piDec, int * piWidth ); +extern BOOL hb_strToNum( const char* szNum, HB_LONG * plVal, double * pdVal ); /* converts string to number, returns TRUE if results is double */ +extern BOOL hb_strnToNum( const char* szNum, ULONG ulLen, HB_LONG * plVal, double * pdVal ); /* converts string to number, returns TRUE if results is double */ extern double hb_numRound( double dResult, int iDec ); /* round a number to a specific number of digits */ +extern double hb_numInt( double dNum ); /* take the integer part of the number */ + /* class management */ extern void hb_clsReleaseAll( void ); /* releases all defined classes */ @@ -481,7 +520,7 @@ extern ULONG hb_cmdargProcessVM( int*, int* ); /* Check for command line inte extern PHB_SYMB hb_symbolNew( char * szName ); /* create a new symbol */ /* Codeblock management */ -extern HB_CODEBLOCK_PTR hb_codeblockNew( BYTE * pBuffer, USHORT uiLocals, USHORT * pLocalPosTable, PHB_SYMB pSymbols ); /* create a code-block */ +extern HB_CODEBLOCK_PTR hb_codeblockNew( BYTE * pBuffer, USHORT uiLocals, BYTE * pLocalPosTable, PHB_SYMB pSymbols ); /* create a code-block */ extern HB_CODEBLOCK_PTR hb_codeblockMacroNew( BYTE * pBuffer, USHORT usLen ); extern void hb_codeblockDelete( HB_ITEM_PTR pItem ); /* delete a codeblock */ extern PHB_ITEM hb_codeblockGetVar( PHB_ITEM pItem, LONG iItemPos ); /* get local variable referenced in a codeblock */ diff --git a/harbour/include/hbapicdp.h b/harbour/include/hbapicdp.h index 8aa8ef8d25..35ca89c052 100644 --- a/harbour/include/hbapicdp.h +++ b/harbour/include/hbapicdp.h @@ -109,5 +109,6 @@ extern void hb_cdpnTranslate( char*, PHB_CODEPAGE, PHB_CODEPAGE, unsigned int ); extern int hb_cdpcmp( char*, char*, ULONG, PHB_CODEPAGE, ULONG* ); extern int hb_cdpchrcmp( char cFirst, char cSecond, PHB_CODEPAGE cdpage ); +extern PHB_CODEPAGE hb_cdp_page; #endif /* HB_APICDP_H_ */ diff --git a/harbour/include/hbapifs.h b/harbour/include/hbapifs.h index 689f652eeb..2596d34bb6 100644 --- a/harbour/include/hbapifs.h +++ b/harbour/include/hbapifs.h @@ -174,12 +174,12 @@ extern FHANDLE hb_spCreateEx( BYTE * pFilename, USHORT uiAttr, USHORT uiFlags ); /* File Find API structure */ typedef struct { - char szName[ _POSIX_PATH_MAX + 1 ]; - LONG lDate; - char szDate[ 9 ]; /* in YYYYMMDD format */ - char szTime[ 9 ]; /* in HH:MM:SS format */ - USHORT attr; - ULONG size; /* TOFIX: Use LONGLONG or double instead */ + char szName[ _POSIX_PATH_MAX + 1 ]; + LONG lDate; + char szDate[ 9 ]; /* in YYYYMMDD format */ + char szTime[ 9 ]; /* in HH:MM:SS format */ + USHORT attr; + HB_FOFFSET size; /* Private */ diff --git a/harbour/include/hbapigt.h b/harbour/include/hbapigt.h index 6211e3f840..5aa4df9edd 100644 --- a/harbour/include/hbapigt.h +++ b/harbour/include/hbapigt.h @@ -71,9 +71,7 @@ #include "hbapi.h" -#if defined(HB_EXTERN_C) -extern "C" { -#endif +HB_EXTERN_BEGIN /* NOTE: The declaration of hb_gtSetPos(), hb_gtGetPos(), hb_gtWrite(), hb_gtWriteAt(), hb_gtRepChar(), hb_gtBox(), hb_gtBoxS(), hb_gtBoxD() diff --git a/harbour/include/hbapiitm.h b/harbour/include/hbapiitm.h index 90f036d026..8f6728e5c1 100644 --- a/harbour/include/hbapiitm.h +++ b/harbour/include/hbapiitm.h @@ -75,48 +75,56 @@ extern BOOL hb_evalRelease ( PEVALINFO pEvalInfo ); extern PHB_ITEM hb_itemDo ( PHB_ITEM pItem, ULONG ulPCount, ... ); extern PHB_ITEM hb_itemDoC ( char * szFunc, ULONG ulPCount, ... ); -extern PHB_ITEM hb_itemArrayGet ( PHB_ITEM pArray, ULONG ulIndex ); -extern PHB_ITEM hb_itemArrayNew ( ULONG ulLen ); -extern PHB_ITEM hb_itemArrayPut ( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ); -extern ULONG hb_itemCopyC ( PHB_ITEM pItem, char * szBuffer, ULONG ulLen ); -extern BOOL hb_itemFreeC ( char * szText ); -extern char * hb_itemGetC ( PHB_ITEM pItem ); -extern char * hb_itemGetCPtr ( PHB_ITEM pItem ); -extern ULONG hb_itemGetCLen ( PHB_ITEM pItem ); -extern char * hb_itemGetDS ( PHB_ITEM pItem, char * szDate ); -extern long hb_itemGetDL ( PHB_ITEM pItem ); -extern BOOL hb_itemGetL ( PHB_ITEM pItem ); -extern double hb_itemGetND ( PHB_ITEM pItem ); -extern int hb_itemGetNI ( PHB_ITEM pItem ); -extern long hb_itemGetNL ( PHB_ITEM pItem ); -extern void hb_itemGetNLen ( PHB_ITEM pItem, int * piWidth, int * piDec ); -extern void * hb_itemGetPtr ( PHB_ITEM pItem ); -extern PHB_ITEM hb_itemNew ( PHB_ITEM pNull ); -extern void hb_itemInit ( PHB_ITEM pItem ); -extern USHORT hb_itemPCount ( void ); -extern PHB_ITEM hb_itemParam ( USHORT uiParam ); -extern PHB_ITEM hb_itemPutC ( PHB_ITEM pItem, char * szText ); -extern PHB_ITEM hb_itemPutCConst( PHB_ITEM pItem, char * szText ); -extern PHB_ITEM hb_itemPutCPtr ( PHB_ITEM pItem, char * szText, ULONG ulLen ); -extern PHB_ITEM hb_itemPutCL ( PHB_ITEM pItem, char * szText, ULONG ulLen ); -extern void hb_itemSetCMemo ( PHB_ITEM pItem ); -extern PHB_ITEM hb_itemPutD ( PHB_ITEM pItem, long lYear, long lMonth, long lDay ); -extern PHB_ITEM hb_itemPutDS ( PHB_ITEM pItem, char * szDate ); -extern PHB_ITEM hb_itemPutDL ( PHB_ITEM pItem, long lJulian ); -extern PHB_ITEM hb_itemPutL ( PHB_ITEM pItem, BOOL bValue ); -extern PHB_ITEM hb_itemPutND ( PHB_ITEM pItem, double dNumber ); -extern PHB_ITEM hb_itemPutNI ( PHB_ITEM pItem, int iNumber ); -extern PHB_ITEM hb_itemPutNL ( PHB_ITEM pItem, long lNumber ); -extern PHB_ITEM hb_itemPutNLen ( PHB_ITEM pItem, double dNumber, int iWidth, int iDec ); -extern PHB_ITEM hb_itemPutNDLen ( PHB_ITEM pItem, double dNumber, int iWidth, int iDec ); -extern PHB_ITEM hb_itemPutNILen ( PHB_ITEM pItem, int iNumber, int iWidth ); -extern PHB_ITEM hb_itemPutNLLen ( PHB_ITEM pItem, long lNumber, int iWidth ); -extern PHB_ITEM hb_itemPutPtr ( PHB_ITEM pItem, void * pValue ); -extern BOOL hb_itemRelease ( PHB_ITEM pItem ); -extern PHB_ITEM hb_itemReturn ( PHB_ITEM pItem ); -extern ULONG hb_itemSize ( PHB_ITEM pItem ); -extern USHORT hb_itemType ( PHB_ITEM pItem ); -extern char * hb_itemTypeStr ( PHB_ITEM pItem ); +extern PHB_ITEM hb_itemArrayGet ( PHB_ITEM pArray, ULONG ulIndex ); +extern PHB_ITEM hb_itemArrayNew ( ULONG ulLen ); +extern PHB_ITEM hb_itemArrayPut ( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ); +extern ULONG hb_itemCopyC ( PHB_ITEM pItem, char * szBuffer, ULONG ulLen ); +extern BOOL hb_itemFreeC ( char * szText ); +extern char * hb_itemGetC ( PHB_ITEM pItem ); +extern char * hb_itemGetCPtr ( PHB_ITEM pItem ); +extern ULONG hb_itemGetCLen ( PHB_ITEM pItem ); +extern char * hb_itemGetDS ( PHB_ITEM pItem, char * szDate ); +extern long hb_itemGetDL ( PHB_ITEM pItem ); +extern BOOL hb_itemGetL ( PHB_ITEM pItem ); +extern double hb_itemGetND ( PHB_ITEM pItem ); +extern int hb_itemGetNI ( PHB_ITEM pItem ); +extern long hb_itemGetNL ( PHB_ITEM pItem ); +extern HB_LONG hb_itemGetNInt ( PHB_ITEM pItem ); +extern void hb_itemGetNLen ( PHB_ITEM pItem, int * piWidth, int * piDec ); +extern void * hb_itemGetPtr ( PHB_ITEM pItem ); +extern PHB_ITEM hb_itemNew ( PHB_ITEM pNull ); +extern void hb_itemInit ( PHB_ITEM pItem ); +extern USHORT hb_itemPCount ( void ); +extern PHB_ITEM hb_itemParam ( USHORT uiParam ); +extern PHB_ITEM hb_itemPutC ( PHB_ITEM pItem, char * szText ); +extern PHB_ITEM hb_itemPutCConst( PHB_ITEM pItem, char * szText ); +extern PHB_ITEM hb_itemPutCPtr ( PHB_ITEM pItem, char * szText, ULONG ulLen ); +extern PHB_ITEM hb_itemPutCL ( PHB_ITEM pItem, char * szText, ULONG ulLen ); +extern void hb_itemSetCMemo ( PHB_ITEM pItem ); +extern PHB_ITEM hb_itemPutD ( PHB_ITEM pItem, int iYear, int iMonth, int iDay ); +extern PHB_ITEM hb_itemPutDS ( PHB_ITEM pItem, char * szDate ); +extern PHB_ITEM hb_itemPutDL ( PHB_ITEM pItem, long lJulian ); +extern PHB_ITEM hb_itemPutL ( PHB_ITEM pItem, BOOL bValue ); +extern PHB_ITEM hb_itemPutND ( PHB_ITEM pItem, double dNumber ); +extern PHB_ITEM hb_itemPutNI ( PHB_ITEM pItem, int iNumber ); +extern PHB_ITEM hb_itemPutNL ( PHB_ITEM pItem, long lNumber ); +extern PHB_ITEM hb_itemPutNInt ( PHB_ITEM pItem, HB_LONG lNumber ); +extern PHB_ITEM hb_itemPutNIntLen( PHB_ITEM pItem, HB_LONG lNumber, int iWidth ); +extern PHB_ITEM hb_itemPutNLen ( PHB_ITEM pItem, double dNumber, int iWidth, int iDec ); +extern PHB_ITEM hb_itemPutNDLen ( PHB_ITEM pItem, double dNumber, int iWidth, int iDec ); +extern PHB_ITEM hb_itemPutNILen ( PHB_ITEM pItem, int iNumber, int iWidth ); +extern PHB_ITEM hb_itemPutNLLen ( PHB_ITEM pItem, long lNumber, int iWidth ); +extern PHB_ITEM hb_itemPutPtr ( PHB_ITEM pItem, void * pValue ); +extern BOOL hb_itemRelease ( PHB_ITEM pItem ); +extern PHB_ITEM hb_itemReturn ( PHB_ITEM pItem ); +extern ULONG hb_itemSize ( PHB_ITEM pItem ); +extern USHORT hb_itemType ( PHB_ITEM pItem ); +extern char * hb_itemTypeStr ( PHB_ITEM pItem ); +#ifndef HB_LONG_LONG_OFF +extern LONGLONG hb_itemGetNLL ( PHB_ITEM pItem ); +extern PHB_ITEM hb_itemPutNLL ( PHB_ITEM pItem, LONGLONG lNumber ); +extern PHB_ITEM hb_itemPutNLLLen( PHB_ITEM pItem, LONGLONG lNumber, int iWidth ); +#endif /* Non Clipper compliant internal API */ @@ -132,7 +140,7 @@ extern char * hb_itemStr ( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pD extern char * hb_itemString ( PHB_ITEM pItem, ULONG * ulLen, BOOL * bFreeReq ); /* Convert any scalar to a string */ extern BOOL hb_itemStrBuf ( char *szResult, PHB_ITEM pNumber, int iSize, int iDec ); /* convert a number to a string */ extern PHB_ITEM hb_itemValToStr ( PHB_ITEM pItem ); /* Convert any scalar to a string */ -extern char * hb_itemPadConv ( PHB_ITEM pItem, char * buffer, ULONG * pulSize ); +extern char * hb_itemPadConv ( PHB_ITEM pItem, ULONG * pulSize, BOOL * bFreeReq ); extern void hb_itemSwap ( PHB_ITEM pItem1, PHB_ITEM pItem2 ); #if defined(HB_EXTERN_C) diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index 150f8e6e76..34a44acc1c 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -355,11 +355,11 @@ extern void hb_compGenMessageData( char * szMsg ); /* generates an underscor extern void hb_compGenPopVar( char * szVarName ); /* generates the pcode to pop a value from the virtual machine stack onto a variable */ extern void hb_compGenPushDouble( double dNumber, BYTE bWidth, BYTE bDec ); /* Pushes a number on the virtual machine stack */ extern void hb_compGenPushFunCall( char * ); /* generates the pcode to push function's call */ -extern void hb_compGenPushVar( char * szVarName ); /* generates the pcode to push a variable value to the virtual machine stack */ +extern void hb_compGenPushVar( char * szVarName ); /* generates the pcode to push a variable value to the virtual machine stack */ extern void hb_compGenPushVarRef( char * szVarName ); /* generates the pcode to push a variable by reference to the virtual machine stack */ extern void hb_compGenPushInteger( int iNumber ); /* Pushes a integer number on the virtual machine stack */ extern void hb_compGenPushLogical( int iTrueFalse ); /* pushes a logical value on the virtual machine stack */ -extern void hb_compGenPushLong( long lNumber ); /* Pushes a long number on the virtual machine stack */ +extern void hb_compGenPushLong( HB_LONG lNumber ); /* Pushes a long number on the virtual machine stack */ extern void hb_compGenPushNil( void ); /* Pushes nil on the virtual machine stack */ extern void hb_compGenPushString( char * szText, ULONG ulLen ); /* Pushes a string on the virtual machine stack */ extern void hb_compGenPushSymbol( char * szSymbolName, BOOL bFunction, BOOL bAlias ); /* Pushes a symbol on to the Virtual machine stack */ diff --git a/harbour/include/hbdate.h b/harbour/include/hbdate.h index 3d739bf51d..2777227f80 100644 --- a/harbour/include/hbdate.h +++ b/harbour/include/hbdate.h @@ -60,16 +60,16 @@ extern "C" { #endif extern double hb_dateSeconds( void ); -extern void hb_dateToday( long * plYear, long * plMonth, long * plDay ); +extern void hb_dateToday( int * piYear, int * piMonth, int * piDay ); extern void hb_dateTimeStr( char * pszTime ); extern char * hb_dateCMonth( int iMonth ); extern char * hb_dateCDOW( int iDay ); -extern long hb_dateDOW( long lYear, long lMonth, long lDay ); +extern int hb_dateDOW( int iYear, int iMonth, int iDay ); extern char * hb_dateFormat( const char * szDate, char * szFormattedDate, const char * szDateFormat ); -extern long hb_dateEncode( long lYear, long lMonth, long lDay ); -extern void hb_dateDecode( long julian, long * plYear, long * plMonth, long * plDay ); -extern void hb_dateStrPut( char * szDate, long lYear, long lMonth, long lDay ); -extern void hb_dateStrGet( const char * szDate, long * plYear, long * plMonth, long * plDay ); +extern long hb_dateEncode( int iYear, int iMonth, int iDay ); +extern void hb_dateDecode( long julian, int * piYear, int * piMonth, int * piDay ); +extern void hb_dateStrPut( char * szDate, int iYear, int iMonth, int iDay ); +extern void hb_dateStrGet( const char * szDate, int * piYear, int * piMonth, int * piDay ); extern char * hb_dateDecStr( char * szDate, long lJulian ); extern long hb_dateEncStr( char * szDate ); diff --git a/harbour/include/hbdbf.h b/harbour/include/hbdbf.h index 7ffd5b173f..8afd8fea0a 100644 --- a/harbour/include/hbdbf.h +++ b/harbour/include/hbdbf.h @@ -55,15 +55,7 @@ #include "hbapirdd.h" -/* 23/10/00 - maurilio.longo@libero.it - When using GCC under OS/2 pack(1) byte aligns every structure */ -#if defined(__EMX__) && ! defined(__RSXNT__) - #pragma pack(1) -#endif - -#if defined(HB_EXTERN_C) -extern "C" { -#endif +HB_EXTERN_BEGIN /* DBF header */ @@ -73,9 +65,9 @@ typedef struct _DBFHEADER BYTE bYear; BYTE bMonth; BYTE bDay; - ULONG ulRecCount; - USHORT uiHeaderLen; - USHORT uiRecordLen; + BYTE ulRecCount[ 4 ]; + BYTE uiHeaderLen[ 2 ]; + BYTE uiRecordLen[ 2 ]; BYTE bReserved1[ 16 ]; BYTE bHasTags; BYTE bCodePage; @@ -101,13 +93,6 @@ typedef struct _DBFFIELD typedef DBFFIELD * LPDBFFIELD; -#if defined(HB_EXTERN_C) -} -#endif - -#if defined(__EMX__) && ! defined(__RSXNT__) - #pragma pack() -#endif - +HB_EXTERN_END #endif /* HB_DBF_H_ */ diff --git a/harbour/include/hbdbferr.h b/harbour/include/hbdbferr.h index a6006b3cf3..0ce7a721a3 100644 --- a/harbour/include/hbdbferr.h +++ b/harbour/include/hbdbferr.h @@ -53,13 +53,12 @@ #ifndef HB_DBFERR_H_ #define HB_DBFERR_H_ -#if defined(HB_EXTERN_C) -extern "C" { -#endif +HB_EXTERN_BEGIN /* DBF errors */ #define EDBF_OPEN_DBF 1001 #define EDBF_CREATE_DBF 1004 +#define EDBF_CREATE 1006 #define EDBF_READ 1010 #define EDBF_WRITE 1011 #define EDBF_CORRUPT 1012 @@ -73,9 +72,6 @@ extern "C" { /* ORDER errors */ #define EDBF_INVALIDKEY 1026 - -#if defined(HB_EXTERN_C) -} -#endif +HB_EXTERN_END #endif /* HB_DBFERR_H_ */ diff --git a/harbour/include/hbdefs.h b/harbour/include/hbdefs.h index 5f786d254d..c74f5c0373 100644 --- a/harbour/include/hbdefs.h +++ b/harbour/include/hbdefs.h @@ -61,8 +61,33 @@ #include "hbsetup.h" #include "hbtrace.h" -/* Include windows.h if applicable and requested */ +/* +#define HB_CLIPPER_INT_ITEMS +*/ +#define HB_LONG_LONG_OFF +#if defined( HB_OS_WIN_32 ) + #if !defined( HB_WIN32_IO_OFF ) + #define HB_WIN32_IO + #endif + #if defined( HB_WIN32_IO ) && !defined( HB_OS_WIN_32_USED ) + /* disabled to avoid problems with windows.h */ + /* #define HB_OS_WIN_32_USED */ + #endif + /* + * This is a temporary hack to resolve problem with binary + * compatibility 3-rd party binaries - mostly FWH now. + * I hope we will be able to remove it soon + #ifndef HB_LONG_HOLDERS + #define HB_FWH_COMPATIBLE + #endif + */ +#else + #undef HB_WIN32_IO + #undef HB_OS_WIN_32_USED +#endif + +/* Include windows.h if applicable and requested */ #if defined(HB_OS_WIN_32_USED) && defined(HB_OS_WIN_32) #define WIN32_LEAN_AND_MEAN @@ -110,6 +135,10 @@ #define HB_DOS_INT86 _int86 #define HB_DOS_INT86X _int86x #define HB_XREGS x + #elif defined( __DJGPP__ ) + #define HB_DOS_INT86 int86 + #define HB_DOS_INT86X int86x + #define HB_XREGS w #else #define HB_DOS_INT86 int86 #define HB_DOS_INT86X int86x @@ -123,11 +152,11 @@ #undef BOOL /* boolean */ typedef int BOOL; - #undef UINT - typedef unsigned int UINT; /* compiler/target dependant */ + #undef UINT /* varies with platform */ + typedef unsigned int UINT; - #undef BYTE - typedef unsigned char BYTE; /* 1 byte unsigned */ + #undef BYTE /* 1 byte unsigned */ + typedef unsigned char BYTE; #undef SHORT /* 2 bytes signed */ typedef short int SHORT; @@ -135,62 +164,553 @@ #undef USHORT /* 2 bytes unsigned */ typedef unsigned short int USHORT; - #undef LONG /* 4 bytes signed */ + #undef LONG /* 4 or 8 bytes signed */ typedef long LONG; - #undef ULONG /* 4 bytes unsigned */ + #undef ULONG /* 4 or 8 bytes unsigned */ typedef unsigned long ULONG; #undef FALSE #define FALSE 0 #undef TRUE - #define TRUE !0 + #define TRUE (!0) + +#ifndef HB_LONG_LONG_OFF + #if ! defined(_WINNT_H) + #if !defined(LONGLONG) + #if defined(__GNUC__) + typedef long long LONGLONG; + #else + typedef __int64 LONGLONG; + #endif + #endif + #if !defined(ULONGLONG) + #if defined(__GNUC__) + typedef unsigned long long ULONGLONG; + #else + typedef unsigned __int64 ULONGLONG; + #endif + #endif + #endif + + #ifdef __GNUC__ + #if defined(ULLONG_MAX) + #define ULONGLONG_MAX ULLONG_MAX + #elif defined(ULONG_LONG_MAX) + #define ULONGLONG_MAX ULONG_LONG_MAX + #else + #define ULONGLONG_MAX 18446744073709551615ULL + #endif + #if defined(LLONG_MAX) + #define LONGLONG_MAX LLONG_MAX + #elif defined(LONG_LONG_MAX) + #define LONGLONG_MAX LONG_LONG_MAX + #else + #define LONGLONG_MAX 9223372036854775807LL + #endif + #if defined(LLONG_MIN) + #define LONGLONG_MIN LLONG_MIN + #elif defined(LONG_LONG_MIN) + #define LONGLONG_MIN LONG_LONG_MIN + #else + #define LONGLONG_MIN (-LONGLONG_MAX - 1LL) + #endif + #else + #if !defined(LONGLONG_MIN) + #define LONGLONG_MIN _I64_MIN + #endif + #if !defined(LONGLONG_MAX) + #define LONGLONG_MAX _I64_MAX + #endif + #if !defined(ULONGLONG_MAX) + #define ULONGLONG_MAX _UI64_MAX + #endif + #endif +#endif /* HB_LONG_LONG_OFF */ #endif /* HB_DONT_DEFINE_BASIC_TYPES */ +/* + * below are some hacks which don't have to be true on some machines + * please update it if necessary + */ +#if ULONG_MAX > UINT_MAX && UINT_MAX > USHORT_MAX +# define HB_ARCH_64BIT +#elif ULONG_MAX == UINT_MAX && UINT_MAX > USHORT_MAX +# define HB_ARCH_32BIT +#elif ULONG_MAX > UINT_MAX && UINT_MAX == USHORT_MAX +# define HB_ARCH_16BIT +#endif + +#if USHRT_MAX == 0xffff +# if !defined( UINT16 ) + typedef USHORT UINT16; +# endif +# if !defined( INT16 ) + typedef SHORT INT16; +# endif +# if !defined( UINT16_MAX ) +# define UINT16_MAX USHRT_MAX +# endif +# if !defined( INT16_MAX ) +# define INT16_MAX SHRT_MAX +# endif +# if !defined( INT16_MIN ) +# define INT16_MIN SHRT_MIN +# endif +#endif + +#if UINT_MAX == 0xffffffff +# if !defined( UINT32 ) + typedef UINT UINT32; +# endif +# if !defined( INT32 ) + typedef int INT32; +# endif +# if !defined( UINT32_MAX ) +# define UINT32_MAX UINT_MAX +# endif +# if !defined( INT32_MAX ) +# define INT32_MAX INT_MAX +# endif +# if !defined( INT32_MIN ) +# define INT32_MIN INT_MIN +# endif +#elif ULONG_MAX == 0xffffffff +# if !defined( UINT32 ) + typedef ULONG UINT32; +# endif +# if !defined( INT32 ) + typedef LONG INT32; +# endif +# if !defined( UINT32_MAX ) +# define UINT32_MAX ULONG_MAX +# endif +# if !defined( INT32_MAX ) +# define INT32_MAX LONG_MAX +# endif +# if !defined( INT32_MIN ) +# define INT32_MIN LONG_MIN +# endif +#endif + +#if defined( HB_ARCH_64BIT ) +# if !defined( UINT64 ) + typedef ULONG UINT64; +# endif +# if !defined( INT64 ) + typedef LONG INT64; +# endif +# if !defined( UINT64_MAX ) +# define UINT64_MAX ULONG_MAX +# endif +# if !defined( INT64_MAX ) +# define INT64_MAX LONG_MAX +# endif +# if !defined( INT64_MIN ) +# define INT64_MIN LONG_MIN +# endif +#elif !defined( HB_LONG_LONG_OFF ) +# if !defined( UINT64 ) + typedef ULONGLONG UINT64; +# endif +# if !defined( INT64 ) + typedef LONGLONG INT64; +# endif +# if !defined( UINT64_MAX ) +# define UINT64_MAX ULONGLONG_MAX +# endif +# if !defined( INT64_MAX ) +# define INT64_MAX LONGLONG_MAX +# endif +# if !defined( INT64_MIN ) +# define INT64_MIN LONGLONG_MIN +# endif +#endif + +#ifndef HB_LONG_DOUBLE_OFF + typedef long double HB_MAXDBL; +#else + typedef double HB_MAXDBL; +#endif + +#if defined( HB_CLIPPER_INT_ITEMS ) +# define HB_INT_MAX SHRT_MAX +# define HB_INT_MIN SHRT_MIN +# define HB_LONG_MAX LONG_MAX +# define HB_LONG_MIN LONG_MIN +# define HB_ULONG_MAX ULONG_MAX + typedef LONG HB_LONG; + typedef ULONG HB_ULONG; +# define PFHL "l" +#elif !defined( HB_LONG_LONG_OFF ) && ULONG_MAX == UINT_MAX +# define HB_INT_MAX INT_MAX +# define HB_INT_MIN INT_MIN +# define HB_LONG_MAX LONGLONG_MAX +# define HB_LONG_MIN LONGLONG_MIN +# define HB_ULONG_MAX ULONGLONG_MAX + typedef LONGLONG HB_LONG; + typedef ULONGLONG HB_ULONG; +#else +# define HB_INT_MAX INT_MAX +# define HB_INT_MIN INT_MIN +# define HB_LONG_MAX LONG_MAX +# define HB_LONG_MIN LONG_MIN +# define HB_ULONG_MAX ULONG_MAX + typedef LONG HB_LONG; + typedef ULONG HB_ULONG; +# define PFHL "l" +#endif + +#define HB_DBL_LIM_INT(d) ( HB_INT_MIN <= (d) && (d) <= HB_INT_MAX ) +#define HB_DBL_LIM_LONG(d) ( (HB_MAXDBL) HB_LONG_MIN <= (HB_MAXDBL) (d) && (HB_MAXDBL) (d) <= (HB_MAXDBL) HB_LONG_MAX ) +#define HB_LIM_INT(l) ( HB_INT_MIN <= (l) && (l) <= HB_INT_MAX ) +#define HB_LIM_LONG(l) ( HB_LONG_MIN <= (l) && (l) <= HB_LONG_MAX ) + +#define HB_DBL_LIM_INT8(d) ( -128 <= (d) && (d) <= 127 ) +#define HB_DBL_LIM_INT16(d) ( INT16_MIN <= (d) && (d) <= INT16_MAX ) +#define HB_DBL_LIM_INT32(d) ( INT32_MIN <= (d) && (d) <= INT32_MAX ) +#define HB_DBL_LIM_INT64(d) ( (HB_MAXDBL) INT64_MIN <= (HB_MAXDBL) (d) && (HB_MAXDBL) (d) <= (HB_MAXDBL) INT64_MAX ) +#define HB_LIM_INT8(l) ( -128 <= (l) && (l) <= 127 ) +#define HB_LIM_INT16(l) ( INT16_MIN <= (l) && (l) <= INT16_MAX ) +#define HB_LIM_INT32(l) ( INT32_MIN <= (l) && (l) <= INT32_MAX ) +#define HB_LIM_INT64(l) ( INT64_MIN <= (l) && (l) <= INT64_MAX ) + +#if HB_LONG_MAX > 10000000000 +# define HB_LONG_LENGTH( l ) ( ( (l) <= -1000000000 || (l) >= HB_LL( 10000000000 ) ) ? 20 : 10 ) +#else +# define HB_LONG_LENGTH( l ) ( ( (l) <= -1000000000 ) ? 20 : 10 ) +#endif +#if HB_INT_MIN <= -1000000000 +# define HB_INT_LENGTH( i ) ( ( (i) <= -1000000000 ) ? 20 : 10 ) +#else +# define HB_INT_LENGTH( i ) 10 +#endif +/* NOTE: Yes, -999999999.0 is right instead of -1000000000.0 [vszakats] */ +/* This comment is from hb_vmNeg() - if it's true only in this case then + the limit should be changed and this function fixed */ +#define HB_DBL_LENGTH( d ) ( ( (d) >= 10000000000.0 || (d) <= -999999999.0 ) ? 20 : 10 ) + +/* uncomment this if you need strict Clipper compatibility */ +/* #define PCODE_LONG_LIM(l) HB_LIM_INT32( l ) */ + +/* #define PCODE_LONG_LIM(l) HB_LIM_LONG( l ) */ + /* type of reference counter */ -typedef ULONG HB_COUNTER; +typedef unsigned long HB_COUNTER; /* type for memory pointer diff */ -typedef ULONG HB_PTRDIFF; +typedef long HB_PTRDIFF; + +#ifdef HB_LONG_LONG_OFF + typedef LONG HB_FOFFSET; + /* we can add hack with double as work around what should + effectively give 52bit file size limit */ +#else + typedef LONGLONG HB_FOFFSET; +#endif + +/* maximum length of double number in decimal representation: + log10(2^1024) ~ 308.25 */ +#define HB_MAX_DOUBLE_LENGTH 320 + +/* This value is used to hack the double FL value in round/int + operation - similar thing is done by CL5.3 - I do not know + only the exact factor value but it should be close to this one. + When HB_C52_STRICT is set this macro is not used. +*/ +#define HB_DBLFL_PREC_FACTOR 1.0000000000000002; + +/* try to detect byte order if not explicitly set */ +#if !defined( HB_PDP_ENDIAN ) && !defined( HB_BIG_ENDIAN ) && \ + !defined( HB_LITTLE_ENDIAN ) && \ + defined( __BYTE_ORDER ) && defined( __LITTLE_ENDIAN ) && \ + defined( __BIG_ENDIAN ) && defined( __PDP_ENDIAN ) + +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define HB_LITTLE_ENDIAN +# elif __BYTE_ORDER == __BIG_ENDIAN +# define HB_BIG_ENDIAN +# elif __BYTE_ORDER == __BIG_ENDIAN +# define HB_PDP_ENDIAN +# endif + +#endif + #define HB_MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) #define HB_MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) #define HB_LOBYTE( w ) ( ( BYTE ) ( w ) ) -#define HB_HIBYTE( w ) ( ( BYTE ) ( ( ( USHORT ) ( w ) >> 8 ) & 0xFF ) ) -#define HB_MKSHORT( lo, hi ) ( ( SHORT ) ( ( ( SHORT ) ( hi ) ) << 8 ) | ( lo ) ) -#define HB_MKUSHORT( lo, hi ) ( ( USHORT ) ( ( ( USHORT ) ( hi ) ) << 8 ) | ( lo ) ) -#define HB_MKLONG( b1, b2, b3, b4 ) ( ( ( ( LONG ) ( b4 ) ) << 24 ) | \ - ( ( ( LONG ) ( b3 ) ) << 16 ) | \ - ( ( ( LONG ) ( b2 ) ) << 8 ) | \ - ( ( ( LONG ) ( b1 ) ) ) ) -#define HB_MKULONG( b1, b2, b3, b4 ) ( ( ( ( ULONG ) ( b4 ) ) << 24 ) | \ - ( ( ( ULONG ) ( b3 ) ) << 16 ) | \ - ( ( ( ULONG ) ( b2 ) ) << 8 ) | \ - ( ( ( ULONG ) ( b1 ) ) ) ) +#define HB_HIBYTE( w ) ( ( BYTE ) ( ( ( w ) >> 8 ) & 0xFF ) ) +#define HB_LOWORD( l ) ( ( UINT16 ) ( l ) ) +#define HB_HIWORD( l ) ( ( UINT16 ) ( ( ( l ) >> 16 ) & 0xFFFF ) ) +#define HB_MKSHORT( lo, hi ) ( ( SHORT ) ( ( ( INT16 ) ( hi ) ) << 8 ) | ( lo ) ) +#define HB_MKUSHORT( lo, hi ) ( ( USHORT ) ( ( ( UINT16 ) ( hi ) ) << 8 ) | ( lo ) ) +#define HB_MKLONG( b1, b2, b3, b4 ) ( ( LONG ) \ + ( ( ( ( INT32 ) ( b4 ) ) << 24 ) | \ + ( ( ( INT32 ) ( b3 ) ) << 16 ) | \ + ( ( ( INT32 ) ( b2 ) ) << 8 ) | \ + ( ( ( INT32 ) ( b1 ) ) ) ) ) +#define HB_MKULONG( b1, b2, b3, b4 ) ( ( ULONG ) \ + ( ( ( ( UINT32 ) ( b4 ) ) << 24 ) | \ + ( ( ( UINT32 ) ( b3 ) ) << 16 ) | \ + ( ( ( UINT32 ) ( b2 ) ) << 8 ) | \ + ( ( ( UINT32 ) ( b1 ) ) ) ) ) -#define HB_SWAP_USHORT( w ) ( ( USHORT ) ( ( ( ( USHORT ) ( w ) & 0xFF00 ) >> 8 ) | \ - ( ( ( USHORT ) ( w ) & 0x00FF ) << 8 ) ) ) -#define HB_SWAP_ULONG( w ) ( ( ULONG ) ( ( ( ( ULONG ) ( w ) & 0x000000FFL ) << 24 ) | \ - ( ( ( ULONG ) ( w ) & 0x0000FF00L ) << 8 ) | \ - ( ( ( ULONG ) ( w ) & 0x00FF0000L ) >> 8 ) | \ - ( ( ( ULONG ) ( w ) & 0xFF000000L ) >> 24 ) ) ) +#define HB_SWAP_UINT16( w ) ( ( UINT16 ) ( ( ( ( UINT16 ) ( w ) & 0xFF00 ) >> 8 ) | \ + ( ( ( UINT16 ) ( w ) & 0x00FF ) << 8 ) ) ) +#define HB_SWAP_UINT32( w ) ( ( UINT32 ) ( ( ( ( UINT32 ) ( w ) & 0x000000FF ) << 24 ) | \ + ( ( ( UINT32 ) ( w ) & 0x0000FF00 ) << 8 ) | \ + ( ( ( UINT32 ) ( w ) & 0x00FF0000 ) >> 8 ) | \ + ( ( ( UINT32 ) ( w ) & 0xFF000000 ) >> 24 ) ) ) -#if defined(HB_PDP_ENDIAN) +/* + * It's a hack for MSC which doesn't support LL suffix for LONGLONG + * numeric constant. This suffix is necessary for some compilers - + * without it they cut the number to LONG + */ +#if defined( _MSC_VER ) || defined( __BORLANDC__ ) +# define HB_LL( num ) ((LONGLONG)num) +#else +# define HB_LL( num ) num##LL +#endif + +#ifndef PFLL +# if defined( __BORLANDC__ ) || defined( _MSC_VER ) +# define PFLL "I64" +# elif defined( __LCC__ ) +# define PFLL "ll" +# else +# define PFLL "L" +# endif +#endif +#ifndef PFHL +# define PFHL PFLL +#endif + +#define HB_SWAP_UINT64( w ) ( ( UINT64 ) ( ( ( ( UINT64 ) ( w ) & HB_LL( 0x00000000000000FF ) ) << 56 ) | \ + ( ( ( UINT64 ) ( w ) & HB_LL( 0x000000000000FF00 ) ) << 40 ) | \ + ( ( ( UINT64 ) ( w ) & HB_LL( 0x0000000000FF0000 ) ) >> 24 ) | \ + ( ( ( UINT64 ) ( w ) & HB_LL( 0x00000000FF000000 ) ) >> 8 ) | \ + ( ( ( UINT64 ) ( w ) & HB_LL( 0x000000FF00000000 ) ) >> 8 ) | \ + ( ( ( UINT64 ) ( w ) & HB_LL( 0x0000FF0000000000 ) ) >> 24 ) | \ + ( ( ( UINT64 ) ( w ) & HB_LL( 0x00FF000000000000 ) ) >> 40 ) | \ + ( ( ( UINT64 ) ( w ) & HB_LL( 0xFF00000000000000 ) ) >> 56 ) ) ) +/* + * on some machines it's not safe to take numbers from BYTE buffer + * directly by C casting because they have to be stored at odd addresses + * Now this hack is only for integer numbers, if you will need it for + * double too on your machine please define proper macros/function + */ +#ifdef HB_CAST_BYTE_NUMBERS_OFF + + #define HB_GET_LE_UINT16( p ) ( ( UINT16 ) \ + ( ( UINT16 ) (( BYTE * )( p ))[0] | \ + ( UINT16 ) (( BYTE * )( p ))[1] << 8 ) ) + #define HB_GET_LE_UINT32( p ) ( ( UINT32 ) \ + ( ( UINT32 ) (( BYTE * )( p ))[0] | \ + ( UINT32 ) (( BYTE * )( p ))[1] << 8 | \ + ( UINT32 ) (( BYTE * )( p ))[2] << 16 | \ + ( UINT32 ) (( BYTE * )( p ))[3] << 24 ) ) + #define HB_GET_LE_UINT64( p ) ( ( UINT64 ) \ + ( ( UINT64 ) (( BYTE * )( p ))[0] | \ + ( UINT64 ) (( BYTE * )( p ))[1] << 8 | \ + ( UINT64 ) (( BYTE * )( p ))[2] << 16 | \ + ( UINT64 ) (( BYTE * )( p ))[3] << 24 | \ + ( UINT64 ) (( BYTE * )( p ))[4] << 32 | \ + ( UINT64 ) (( BYTE * )( p ))[5] << 40 | \ + ( UINT64 ) (( BYTE * )( p ))[6] << 48 | \ + ( UINT64 ) (( BYTE * )( p ))[7] << 56 ) ) + + #define HB_PUT_LE_UINT16( p, w ) { \ + (( BYTE * )( p ))[0] = ( BYTE )( w ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 8 ); \ + } + #define HB_PUT_LE_UINT32( p, w ) { \ + (( BYTE * )( p ))[0] = ( BYTE )( w ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 8 ); \ + (( BYTE * )( p ))[2] = ( BYTE )( (w) >> 16 ); \ + (( BYTE * )( p ))[3] = ( BYTE )( (w) >> 24 ); \ + } + #define HB_PUT_LE_UINT64( p, w ) { \ + (( BYTE * )( p ))[0] = ( BYTE )( w ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 8 ); \ + (( BYTE * )( p ))[2] = ( BYTE )( (w) >> 16 ); \ + (( BYTE * )( p ))[3] = ( BYTE )( (w) >> 24 ); \ + (( BYTE * )( p ))[4] = ( BYTE )( (w) >> 32 ); \ + (( BYTE * )( p ))[5] = ( BYTE )( (w) >> 40 ); \ + (( BYTE * )( p ))[6] = ( BYTE )( (w) >> 48 ); \ + (( BYTE * )( p ))[7] = ( BYTE )( (w) >> 56 ); \ + } + + #define HB_GET_BE_UINT16( p ) ( ( UINT16 ) \ + ( ( UINT16 ) (( BYTE * )( p ))[0] << 8 | \ + ( UINT16 ) (( BYTE * )( p ))[1] ) ) + #define HB_GET_BE_UINT32( p ) ( ( UINT32 ) \ + ( ( UINT32 ) (( BYTE * )( p ))[0] << 24 | \ + ( UINT32 ) (( BYTE * )( p ))[1] << 16 | \ + ( UINT32 ) (( BYTE * )( p ))[2] << 8 | \ + ( UINT32 ) (( BYTE * )( p ))[3] ) ) + #define HB_GET_BE_UINT64( p ) ( ( UINT64 ) \ + ( ( UINT64 ) (( BYTE * )( p ))[0] << 56 | \ + ( UINT64 ) (( BYTE * )( p ))[1] << 48 | \ + ( UINT64 ) (( BYTE * )( p ))[2] << 40 | \ + ( UINT64 ) (( BYTE * )( p ))[3] << 32 | \ + ( UINT64 ) (( BYTE * )( p ))[4] << 24 | \ + ( UINT64 ) (( BYTE * )( p ))[5] << 16 | \ + ( UINT64 ) (( BYTE * )( p ))[6] << 8 | \ + ( UINT64 ) (( BYTE * )( p ))[7] ) ) + + #define HB_PUT_BE_UINT16( p, w ) { \ + (( BYTE * )( p ))[0] = ( BYTE )( (w) >> 8 ); \ + (( BYTE * )( p ))[1] = ( BYTE )( w ); \ + } + #define HB_PUT_BE_UINT32( p, w ) { \ + (( BYTE * )( p ))[0] = ( BYTE )( (w) >> 24 ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 16 ); \ + (( BYTE * )( p ))[2] = ( BYTE )( (w) >> 8 ); \ + (( BYTE * )( p ))[3] = ( BYTE )( w ); \ + } + #define HB_PUT_BE_UINT64( p, w ) { \ + (( BYTE * )( p ))[0] = ( BYTE )( (w) >> 56 ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 48 ); \ + (( BYTE * )( p ))[2] = ( BYTE )( (w) >> 40 ); \ + (( BYTE * )( p ))[3] = ( BYTE )( (w) >> 32 ); \ + (( BYTE * )( p ))[4] = ( BYTE )( (w) >> 24 ); \ + (( BYTE * )( p ))[5] = ( BYTE )( (w) >> 16 ); \ + (( BYTE * )( p ))[6] = ( BYTE )( (w) >> 8 ); \ + (( BYTE * )( p ))[7] = ( BYTE )( w ); \ + } +#endif + +/* + * 24 bit integers are not directly supported by any processor we used so far + * so we always have to build them from BYTEs and cannot use C casting + */ +#define HB_GET_LE_INT24( p ) ( ( INT32 ) \ + ( ( INT32 ) (( BYTE * )( p ))[0] | \ + ( INT32 ) (( BYTE * )( p ))[1] << 8 | \ + ( INT32 ) (( BYTE * )( p ))[2] << 16 | \ + ( INT32 ) ((( BYTE * )( p ))[2] & 0x80 ? 0xFF : 0x00 ) << 24 ) ) +#define HB_GET_LE_UINT24( p ) ( ( UINT32 ) \ + ( ( UINT32 ) (( BYTE * )( p ))[0] | \ + ( UINT32 ) (( BYTE * )( p ))[1] << 8 | \ + ( UINT32 ) (( BYTE * )( p ))[2] << 16 ) ) +#define HB_PUT_LE_UINT24( p, w ) { \ + (( BYTE * )( p ))[0] = ( BYTE )( w ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 8 ); \ + (( BYTE * )( p ))[2] = ( BYTE )( (w) >> 16 ); \ + } + + +#if defined( HB_PDP_ENDIAN ) #error PDP-Endian support unimplemented. If you have such machine do it yourself. -#elif !defined(HB_BIG_ENDIAN) +#elif defined( HB_BIG_ENDIAN ) + /* We use Big-Endian here */ + +# ifndef HB_CAST_BYTE_NUMBERS_OFF + + #define HB_GET_LE_UINT16( p ) HB_SWAP_UINT16( *( UINT16 * )( p ) ) + #define HB_PUT_LE_UINT16( p, w ) ( *( UINT16 * )( p ) = HB_SWAP_UINT16( w ) ) + #define HB_GET_LE_UINT32( p ) HB_SWAP_UINT32( *( UINT32 * )( p ) ) + #define HB_PUT_LE_UINT32( p, l ) ( *( UINT32 * )( p ) = HB_SWAP_UINT32( l ) ) + #define HB_GET_LE_UINT64( p ) HB_SWAP_UINT64( *( UINT64 * )( p ) ) + #define HB_PUT_LE_UINT64( p, l ) ( *( UINT64 * )( p ) = HB_SWAP_UINT64( l ) ) + + #define HB_GET_BE_UINT16( p ) ( *( UINT16 * )( p ) ) + #define HB_PUT_BE_UINT16( p, w ) ( *( UINT16 * )( p ) = ( UINT16 ) ( w ) ) + #define HB_GET_BE_UINT32( p ) ( *( UINT32 * )( p ) ) + #define HB_PUT_BE_UINT32( p, l ) ( *( UINT32 * )( p ) = ( UINT32 ) ( l ) ) + #define HB_GET_BE_UINT64( p ) ( *( UINT64 * )( p ) ) + #define HB_PUT_BE_UINT64( p, l ) ( *( UINT64 * )( p ) = ( UINT64 ) ( l ) ) + +# endif + + #define HB_USHORT_FROM_LE( w ) HB_MKUSHORT( HB_HIBYTE( w ), HB_LOBYTE( w ) ) + #define HB_ULONG_FROM_LE( l ) HB_MKULONG( HB_HIBYTE( HB_HIWORD( l ) ), HB_LOBYTE( HB_HIWORD( l ) ), HB_HIBYTE( l ), HB_LOBYTE( l ) ) + #define HB_USHORT_TO_LE( w ) HB_USHORT_FROM_LE( w ) + #define HB_ULONG_TO_LE( l ) HB_ULONG_FROM_LE( l ) + + #define HB_ORD2DBL( o, d ) { \ + *( double * )( d ) = *( double * )( o ); \ + if ( ( ( BYTE * ) ( d ) )[ 0 ] & 0x80 ) { \ + ( ( BYTE * ) ( d ) )[ 0 ] ^= 0x80; \ + } else { \ + ( ( LONG * ) ( d ) )[ 0 ] ^= 0xFFFFFFFFL; \ + ( ( LONG * ) ( d ) )[ 1 ] ^= 0xFFFFFFFFL; \ + } } + #define HB_DBL2ORD( d, o ) { \ + *( double * )( o ) = *( double * )( d ); \ + if ( *( double * )( o ) >= 0.0 ) { \ + ( ( BYTE * ) ( o ) )[ 0 ] ^= 0x80; \ + } else { \ + ( ( LONG * ) ( o ) )[ 0 ] ^= 0xFFFFFFFFL; \ + ( ( LONG * ) ( o ) )[ 1 ] ^= 0xFFFFFFFFL; \ + } } + +#if defined( __GNUC__ ) +/* Be careful with double conversion. Some machines can use mixed form + (Little/Big) for BYTE ORDER and WORD ORDER or even completely differ + internal representation */ + + #define HB_GET_LE_DOUBLE( p ) \ + ( { \ + union { \ + double d; \ + BYTE buffer[ 8 ]; \ + } u; \ + u.buffer[ 0 ] = (( BYTE * )( p ))[ 7 ]; \ + u.buffer[ 1 ] = (( BYTE * )( p ))[ 6 ]; \ + u.buffer[ 2 ] = (( BYTE * )( p ))[ 5 ]; \ + u.buffer[ 3 ] = (( BYTE * )( p ))[ 4 ]; \ + u.buffer[ 4 ] = (( BYTE * )( p ))[ 3 ]; \ + u.buffer[ 5 ] = (( BYTE * )( p ))[ 2 ]; \ + u.buffer[ 6 ] = (( BYTE * )( p ))[ 1 ]; \ + u.buffer[ 7 ] = (( BYTE * )( p ))[ 0 ]; \ + u.d; \ + } ) + #define HB_PUT_LE_DOUBLE( p, d ) \ + ( { \ + union { \ + double d; \ + BYTE buffer[ 8 ]; \ + } u; \ + u.d = d; + (( BYTE * )( p ))[ 7 ] = u.buffer[ 0 ]; \ + (( BYTE * )( p ))[ 6 ] = u.buffer[ 1 ]; \ + (( BYTE * )( p ))[ 5 ] = u.buffer[ 2 ]; \ + (( BYTE * )( p ))[ 4 ] = u.buffer[ 3 ]; \ + (( BYTE * )( p ))[ 3 ] = u.buffer[ 4 ]; \ + (( BYTE * )( p ))[ 2 ] = u.buffer[ 5 ]; \ + (( BYTE * )( p ))[ 1 ] = u.buffer[ 6 ]; \ + (( BYTE * )( p ))[ 0 ] = u.buffer[ 7 ]; \ + u.d; \ + } ) +#else + #error Little-Endian IEEE 754 double type conversion unimplemented with a non-GCC compiler +#endif + +#else /* We use Little-Endian here */ - #define HB_GET_LE_USHORT( p ) ( *( USHORT * )( p ) ) - #define HB_PUT_LE_USHORT( p, w ) ( *( USHORT * )( p ) = ( USHORT ) ( w ) ) - #define HB_GET_LE_ULONG( p ) ( *( ULONG * )( p ) ) - #define HB_PUT_LE_ULONG( p, l ) ( *( ULONG * )( p ) = ( ULONG ) ( l ) ) +# ifndef HB_CAST_BYTE_NUMBERS_OFF - #define HB_GET_BE_USHORT( p ) HB_SWAP_USHORT( *( USHORT * )( p ) ) - #define HB_PUT_BE_USHORT( p, w ) ( *( USHORT * )( p ) = HB_SWAP_USHORT( w ) ) - #define HB_GET_BE_ULONG( p ) HB_SWAP_ULONG( *( ULONG * )( p ) ) - #define HB_PUT_BE_ULONG( p, l ) ( *( ULONG * )( p ) = HB_SWAP_ULONG( l ) ) + #define HB_GET_LE_UINT16( p ) ( *( UINT16 * )( p ) ) + #define HB_PUT_LE_UINT16( p, w ) ( *( UINT16 * )( p ) = ( UINT16 ) ( w ) ) + #define HB_GET_LE_UINT32( p ) ( *( UINT32 * )( p ) ) + #define HB_PUT_LE_UINT32( p, l ) ( *( UINT32 * )( p ) = ( UINT32 ) ( l ) ) + #define HB_GET_LE_UINT64( p ) ( *( UINT64 * )( p ) ) + #define HB_PUT_LE_UINT64( p, l ) ( *( UINT64 * )( p ) = ( UINT64 ) ( l ) ) + + #define HB_GET_BE_UINT16( p ) HB_SWAP_UINT16( *( UINT16 * )( p ) ) + #define HB_PUT_BE_UINT16( p, w ) ( *( UINT16 * )( p ) = HB_SWAP_UINT16( w ) ) + #define HB_GET_BE_UINT32( p ) HB_SWAP_UINT32( *( UINT32 * )( p ) ) + #define HB_PUT_BE_UINT32( p, l ) ( *( UINT32 * )( p ) = HB_SWAP_UINT32( l ) ) + #define HB_GET_BE_UINT64( p ) HB_SWAP_UINT64( *( UINT64 * )( p ) ) + #define HB_PUT_BE_UINT64( p, l ) ( *( UINT64 * )( p ) = HB_SWAP_UINT64( l ) ) + +#endif #define HB_GET_LE_DOUBLE( p ) ( *( double * )( p ) ) #define HB_PUT_LE_DOUBLE( p, d ) ( *( double * )( p ) = ( double ) ( d ) ) @@ -199,13 +719,6 @@ typedef ULONG HB_PTRDIFF; #define HB_ULONG_FROM_LE( l ) ( ( ULONG )( l ) ) #define HB_USHORT_TO_LE( w ) ( ( USHORT )( w ) ) #define HB_ULONG_TO_LE( l ) ( ( ULONG )( l ) ) - #define HB_DOUBLE_TO_LE( d ) ( ( double )( d ) ) - - #define HB_PCODE_MKSHORT( p ) ( *( SHORT * )( p ) ) - #define HB_PCODE_MKUSHORT( p ) ( *( USHORT * )( p ) ) - #define HB_PCODE_MKLONG( p ) ( *( LONG * )( p ) ) - #define HB_PCODE_MKULONG( p ) ( *( ULONG * )( p ) ) - #define HB_PCODE_MKDOUBLE( p ) ( *( double * )( p ) ) #define HB_ORD2DBL( o, d ) { \ if ( ( ( BYTE * ) ( o ) )[ 0 ] & 0x80 ) { \ @@ -249,85 +762,54 @@ typedef ULONG HB_PTRDIFF; ( ( BYTE * ) ( o ) )[ 7 ] = ( ( BYTE * ) ( d ) )[ 0 ] ^ ( BYTE ) 0xFF; \ } } -#else - /* We use Big-Endian here */ - - #define HB_GET_LE_USHORT( p ) HB_SWAP_USHORT( *( USHORT * )( p ) ) - #define HB_PUT_LE_USHORT( p, w ) ( *( USHORT * )( p ) = HB_SWAP_USHORT( w ) ) - #define HB_GET_LE_ULONG( p ) HB_SWAP_ULONG( *( ULONG * )( p ) ) - #define HB_PUT_LE_ULONG( p, l ) ( *( ULONG * )( p ) = HB_SWAP_ULONG( l ) ) - #define HB_GET_BE_USHORT( p ) ( *( USHORT * )( p ) ) - #define HB_PUT_BE_USHORT( p, w ) ( *( USHORT * )( p ) = ( USHORT ) ( w ) ) - #define HB_GET_BE_ULONG( p ) ( *( ULONG * )( p ) ) - #define HB_PUT_BE_ULONG( p, l ) ( *( ULONG * )( p ) = ( ULONG ) ( l ) ) - - #define HB_USHORT_FROM_LE( w ) HB_MKUSHORT( HB_HIBYTE( w ), HB_LOBYTE( w ) ) - #define HB_ULONG_FROM_LE( l ) HB_MKULONG( HB_HIBYTE( HB_HIWORD( l ) ), HB_LOBYTE( HB_HIWORD( l ) ), HB_HIBYTE( l ), HB_LOBYTE( l ) ) - #define HB_USHORT_TO_LE( w ) HB_USHORT_FROM_LE( w ) - #define HB_ULONG_TO_LE( l ) HB_ULONG_FROM_LE( l ) - - #define HB_PCODE_MKSHORT( p ) HB_MKSHORT( *( BYTE * )( p ), ( ( BYTE * )( p ) )[ 1 ] ) - #define HB_PCODE_MKUSHORT( p ) HB_MKUSHORT( *( BYTE * )( p ), ( ( BYTE * )( p ) )[ 1 ] ) - #define HB_PCODE_MKLONG( p ) HB_MKLONG( *( BYTE * )( p ), ( ( BYTE * )( p ) )[ 1 ], ( ( BYTE * )( p ) )[ 2 ], ( ( BYTE * )( p ) )[ 3 ] ) - #define HB_PCODE_MKULONG( p ) HB_MKULONG( *( BYTE * )( p ), ( ( BYTE * )( p ) )[ 1 ], ( ( BYTE * )( p ) )[ 2 ], ( ( BYTE * )( p ) )[ 3 ] ) - - #define HB_ORD2DBL( o, d ) { \ - *( double * )( d ) = *( double * )( o ); \ - if ( ( ( BYTE * ) ( d ) )[ 0 ] & 0x80 ) { \ - ( ( BYTE * ) ( d ) )[ 0 ] ^= 0x80; \ - } else { \ - ( ( LONG * ) ( d ) )[ 0 ] ^= 0xFFFFFFFFL; \ - ( ( LONG * ) ( d ) )[ 1 ] ^= 0xFFFFFFFFL; \ - } } - #define HB_DBL2ORD( d, o ) { \ - *( double * )( o ) = *( double * )( d ); \ - if ( *( double * )( o ) >= 0.0 ) { \ - ( ( BYTE * ) ( o ) )[ 0 ] ^= 0x80; \ - } else { \ - ( ( LONG * ) ( o ) )[ 0 ] ^= 0xFFFFFFFFL; \ - ( ( LONG * ) ( o ) )[ 1 ] ^= 0xFFFFFFFFL; \ - } } - -#if defined( __GNUC__ ) -/* Be careful with double conversion. Some machines can use mixed form - (Little/Big) for BYTE ORDER and WORD ORDER or even completely differ - internal representation */ - - #define HB_GET_LE_DOUBLE( p ) HB_PCODE_MKDOUBLE( p ) - #define HB_PUT_LE_DOUBLE( p, d ) ( *( double * )( p ) = HB_DOUBLE_TO_LE( d ) ) - - #define HB_DOUBLE_TO_LE( d ) HB_DOUBLE_FROM_LE( d ) - #define HB_DOUBLE_FROM_LE( d ) \ - ( { \ - BYTE double_var[ 8 ]; \ - *( double * )double_var = d; \ - HB_PCODE_MKDOUBLE( double_var ); \ - } ) - #define HB_PCODE_MKDOUBLE( p ) \ - ( { \ - union { \ - double d; \ - BYTE buffer[ 8 ]; \ - } u; \ - u.buffer[ 0 ] = ( p )[ 7 ]; \ - u.buffer[ 1 ] = ( p )[ 6 ]; \ - u.buffer[ 2 ] = ( p )[ 5 ]; \ - u.buffer[ 3 ] = ( p )[ 4 ]; \ - u.buffer[ 4 ] = ( p )[ 3 ]; \ - u.buffer[ 5 ] = ( p )[ 2 ]; \ - u.buffer[ 6 ] = ( p )[ 1 ]; \ - u.buffer[ 7 ] = ( p )[ 0 ]; \ - u.d; \ - } ) -#else - #error Little-Endian IEEE 754 double type conversion unimplemented with a non-GCC compiler #endif +#define HB_GET_LE_INT16( p ) (( INT16 ) HB_GET_LE_UINT16( p )) +#define HB_GET_LE_INT32( p ) (( INT32 ) HB_GET_LE_UINT32( p )) +#define HB_GET_LE_INT64( p ) (( INT64 ) HB_GET_LE_UINT64( p )) + +#define HB_PCODE_MKSHORT( p ) (( SHORT ) HB_GET_LE_INT16( p )) +#define HB_PCODE_MKUSHORT( p ) (( USHORT ) HB_GET_LE_UINT16( p )) +#define HB_PCODE_MKLONG( p ) (( LONG ) HB_GET_LE_INT32( p )) +#define HB_PCODE_MKULONG( p ) (( ULONG ) HB_GET_LE_UINT32( p )) +#define HB_PCODE_MKLONGLONG( p ) (( LONGLONG ) HB_GET_LE_INT64( p )) +#define HB_PCODE_MKULONGLONG( p ) (( ULONGLONG ) HB_GET_LE_UINT64( p )) +#define HB_PCODE_MKDOUBLE( p ) (( double ) HB_GET_LE_DOUBLE( p )) +#define HB_PCODE_MKINT24( p ) (( LONG ) HB_GET_LE_INT24( p )) +#define HB_PCODE_MKUINT24( p ) (( ULONG ) HB_GET_LE_UINT24( p )) + +/* + * Below are hacked version of INT64 macros which operates on double + * when INT64 is not supported - they are necessary for PCODE and + * database access + */ +#if defined( HB_LONG_LONG_OFF ) && !defined( UINT64_MAX ) + #undef HB_GET_LE_INT64 + #undef HB_GET_LE_UINT64 + #undef HB_PUT_LE_UINT64 + #undef HB_PCODE_MKLONGLONG + #undef HB_PCODE_MKULONGLONG + #undef HB_DBL_LIM_INT64 + #define UINT64_MAXDBL ( (( double ) UINT32_MAX + 1.0) * (( double ) UINT32_MAX + 1.0) - 1 ) + #define HB_GET_LE_INT64( p ) ( ( double ) HB_GET_LE_UINT32( p ) + \ + ( double ) HB_GET_LE_UINT32( p + 4 ) * UINT32_MAX - \ + ((( BYTE * )( p ))[7] & 0x80 ? UINT64_MAXDBL : 0 ) ) + #define HB_GET_LE_UINT64( p ) ( ( double ) HB_GET_LE_UINT32( p ) + \ + ( double ) HB_GET_LE_UINT32( p + 4 ) * UINT32_MAX ) + #define HB_PUT_LE_UINT64( p, w ) { \ + double _d = ( double ) ( w ); \ + if ( _d < 0 ) \ + _d += UINT64_MAXDBL; \ + HB_PUT_LE_UINT32( p, ( UINT32 ) _d ); \ + HB_PUT_LE_UINT32( p + 4, ( UINT32 ) ( _d / ( double ) UINT32_MAX ) ); \ + } + #define HB_PCODE_MKLONGLONG( p ) (( double ) HB_GET_LE_INT64( p )) + #define HB_PCODE_MKULONGLONG( p ) (( double ) HB_GET_LE_UINT64( p )) + #define HB_DBL_LIM_INT64(d) ( (HB_MAXDBL) -UINT64_MAXDBL / 2 - 1 <= (HB_MAXDBL) (d) && (HB_MAXDBL) (d) <= (HB_MAXDBL) UINT64_MAXDBL / 2 ) #endif -#define HB_PCODE_MK24BIT( p ) HB_MKLONG( *( BYTE * )( p ), ( ( BYTE * )( p ) )[ 1 ], ( ( BYTE * )( p ) )[ 2 ], 0 ) -#define HB_SYMBOL_UNUSED( symbol ) ( void ) symbol +#define HB_SYMBOL_UNUSED( symbol ) ( void ) symbol /* *********************************************************************** * The name of starting procedure @@ -372,6 +854,9 @@ typedef PHB_FUNC HB_FUNC_PTR; #elif defined( __BORLANDC__ ) #define HB_EXPORT _declspec( dllexport ) + #elif defined( __WATCOMC__ ) + #define HB_EXPORT __declspec( dllexport ) + #elif defined( WIN32 ) && !defined( ASANT ) #define HB_EXPORT _declspec( dllexport ) @@ -394,10 +879,18 @@ typedef PHB_FUNC HB_FUNC_PTR; are also prefixed with HB_. [vszakats] */ #define HB_FUNCNAME( funcname ) HB_FUN_##funcname -#define HB_FUNC( funcname ) HARBOUR HB_EXPORT HB_FUN_##funcname ( void ) -#define HB_FUNC_STATIC( funcname ) static HARBOUR HB_FUN_##funcname ( void ) -#define HB_FUNC_INIT( funcname ) static HARBOUR HB_FUN_##funcname ( void ) -#define HB_FUNC_EXIT( funcname ) static HARBOUR HB_FUN_##funcname ( void ) + +#if ( defined( _MSC_VER ) || defined( __WATCOMC__ ) ) && defined( HB_FUNC_NO_DECORATION ) + #define HB_EXTERN_C_ extern "C" +#else + #define HB_EXTERN_C_ +#endif + +#define HB_FUNC( funcname ) HB_EXTERN_C_ HARBOUR HB_EXPORT HB_FUN_##funcname ( void ) +#define HB_FUNC_STATIC( funcname ) HB_EXTERN_C_ static HARBOUR HB_FUN_##funcname ( void ) +#define HB_FUNC_EXTERN( funcname ) HB_EXTERN_C_ extern HARBOUR HB_FUN_##funcname ( void ) +#define HB_FUNC_INIT( funcname ) HB_EXTERN_C_ static HARBOUR HB_FUN_##funcname ( void ) +#define HB_FUNC_EXIT( funcname ) HB_EXTERN_C_ static HARBOUR HB_FUN_##funcname ( void ) typedef ULONG HB_HANDLE; /* handle to memvar value */ typedef char HB_SYMBOLSCOPE; /* stores symbol's scope */ @@ -426,22 +919,4 @@ typedef BYTE HB_ATTR; #define HB_CHAR_SOFT1 ( ( char ) 141 ) #define HB_CHAR_SOFT2 ( ( char ) HB_CHAR_LF ) -#ifndef HB_LONG_LONG_OFF -#if !defined(LONGLONG) && !defined(_WINNT_H) -#if defined(__GNUC__) - typedef long long LONGLONG; -#else - typedef __int64 LONGLONG; -#endif -#endif - -#if !defined(ULONGLONG) && !defined(_WINNT_H) -#if defined(__GNUC__) - typedef unsigned long long ULONGLONG; -#else - typedef unsigned __int64 ULONGLONG; -#endif -#endif -#endif /* HB_LONG_LONG_OFF */ - #endif /* HB_DEFS_H_ */ diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 9f335a4c5e..58bd749912 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -361,25 +361,29 @@ static HB_EXPR_FUNC( hb_compExprUseString ) bValidMacro = hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_MACRO_PARAM ); if( bUseTextSubst ) - { + { if( HB_SUPPORT_HARBOUR ) { if( bValidMacro ) - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROTEXT ); - else - hb_compErrorMacro( pSelf->value.asString.string ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROTEXT ); + else + { + hb_compErrorMacro( pSelf->value.asString.string ); + } } else { /* Clipper always generates macro substitution pcode * even if it is not a valid expression */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROTEXT ); - if( !bValidMacro ) - hb_compErrorMacro( pSelf->value.asString.string ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROTEXT ); + if( !bValidMacro ) + { + hb_compErrorMacro( pSelf->value.asString.string ); + } } - } - hb_xfree( szDupl ); + } + hb_xfree( szDupl ); } break; case HB_EA_POP_PCODE: @@ -566,9 +570,9 @@ static void hb_compExprCodeblockEarly( HB_EXPR_PTR pSelf ) szDupl = hb_strupr( hb_strdup( pSelf->value.asCodeblock.string ) ); if( !hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_MACRO_PARAM ) ) { - hb_compErrorCodeblock( pSelf->value.asCodeblock.string ); - hb_compErrorMacro( pSelf->value.asCodeblock.string ); - } + hb_compErrorCodeblock( pSelf->value.asCodeblock.string ); + hb_compErrorMacro( pSelf->value.asCodeblock.string ); + } hb_xfree( szDupl ); pNew = hb_compExprNewMacro( hb_compExprNewString(pSelf->value.asCodeblock.string), 0, NULL ); HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); @@ -1140,7 +1144,7 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) pExpr = pExpr->value.asList.pExprList; /* the first element in the array */ if( pIdx->value.asNum.NumType == HB_ET_LONG ) - lIndex = pIdx->value.asNum.lVal; + lIndex = ( LONG ) pIdx->value.asNum.lVal; else lIndex = ( LONG ) pIdx->value.asNum.dVal; @@ -1178,7 +1182,7 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) LONG lIndex; if( pIdx->value.asNum.NumType == HB_ET_LONG ) - lIndex = pIdx->value.asNum.lVal; + lIndex = ( LONG ) pIdx->value.asNum.lVal; else lIndex = ( LONG ) pIdx->value.asNum.dVal; @@ -1478,7 +1482,7 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) { HB_EXPR_PTR pName = pSelf->value.asFunCall.pFunName; HB_EXPR_PTR pParms = pSelf->value.asFunCall.pParms; - USHORT usCount; + USHORT usCount = 0; if( pParms ) { diff --git a/harbour/include/hbexprc.c b/harbour/include/hbexprc.c index 619fef1eb1..6c5ed2793b 100644 --- a/harbour/include/hbexprc.c +++ b/harbour/include/hbexprc.c @@ -477,7 +477,7 @@ BOOL hb_compExprIsValidMacro( char * szText, BOOL *pbUseTextSubst, HB_MACRO_DECL } *pbUseTextSubst |= bTextSubst; } - HB_SYMBOL_UNUSED( HB_MACRO_PARAM ); + HB_SYMBOL_UNUSED( HB_MACRO_VARNAME ); /* to suppress BCC warning */ return bMacroText; } @@ -497,7 +497,7 @@ HB_EXPR_PTR hb_compExprReducePlusStrings( HB_EXPR_PTR pLeft, HB_EXPR_PTR pRight, pLeft->value.asString.string[ pLeft->ulLength ] = '\0'; hb_compExprFree( pRight, HB_MACRO_PARAM ); - HB_SYMBOL_UNUSED( HB_MACRO_PARAM ); /* to suppress BCC warning */ + HB_SYMBOL_UNUSED( HB_MACRO_VARNAME ); /* to suppress BCC warning */ return pLeft; } #else @@ -517,7 +517,7 @@ HB_EXPR_PTR hb_compExprReducePlusStrings( HB_EXPR_PTR pLeft, HB_EXPR_PTR pRight, pLeft->value.asString.dealloc = TRUE; hb_compExprFree( pRight, HB_MACRO_PARAM ); - HB_SYMBOL_UNUSED( HB_MACRO_PARAM ); /* to suppress BCC warning */ + HB_SYMBOL_UNUSED( HB_MACRO_VARNAME ); /* to suppress BCC warning */ return pLeft; } #endif diff --git a/harbour/include/hbexprop.h b/harbour/include/hbexprop.h index 5801dc704f..5b2f7d7f75 100644 --- a/harbour/include/hbexprop.h +++ b/harbour/include/hbexprop.h @@ -187,7 +187,7 @@ typedef struct HB_EXPR_ } asRTVar; /* PUBLIC or PRIVATE variable declaration */ struct { - long lVal; /* long value */ + HB_LONG lVal; /* long value */ double dVal; /* double value */ unsigned char bWidth; /* unsigned char used intentionally */ unsigned char bDec; /* unsigned char used intentionally */ @@ -309,7 +309,7 @@ HB_EXPR_PTR hb_compExprNew( int ); HB_EXPR_PTR hb_compExprNewEmpty( void ); HB_EXPR_PTR hb_compExprNewNil( void ); HB_EXPR_PTR hb_compExprNewDouble( double, BYTE, BYTE ); -HB_EXPR_PTR hb_compExprNewLong( LONG ); +HB_EXPR_PTR hb_compExprNewLong( HB_LONG ); HB_EXPR_PTR hb_compExprNewString( char * ); HB_EXPR_PTR hb_compExprNewLogical( int ); HB_EXPR_PTR hb_compExprNewSelf( void ); diff --git a/harbour/include/hbmacro.h b/harbour/include/hbmacro.h index b3d2bd94f8..b86176ace6 100644 --- a/harbour/include/hbmacro.h +++ b/harbour/include/hbmacro.h @@ -134,7 +134,7 @@ extern void hb_compGenJumpHere( ULONG ulOffset, HB_BISON_PTR pMacro ); extern ULONG hb_compGenJumpTrue( LONG lOffset, HB_BISON_PTR pMacro ); extern void hb_compMemvarGenPCode( BYTE bPCode, char * szVarName, HB_BISON_PTR pMacro ); extern void hb_compGenPushSymbol( char * szSymbolName, BOOL bFunction, BOOL bAlias, HB_BISON_PTR pMacro ); -extern void hb_compGenPushLong( long lNumber, HB_BISON_PTR pMacro ); +extern void hb_compGenPushLong( HB_LONG lNumber, HB_BISON_PTR pMacro ); extern void hb_compGenMessage( char * szMsgName, HB_BISON_PTR pMacro ); extern void hb_compGenMessageData( char * szMsg, HB_BISON_PTR pMacro ); extern void hb_compGenPopVar( char * szVarName, HB_BISON_PTR pMacro ); diff --git a/harbour/include/hbmath.h b/harbour/include/hbmath.h index 5800b3f932..8fa8a7e228 100644 --- a/harbour/include/hbmath.h +++ b/harbour/include/hbmath.h @@ -62,9 +62,7 @@ #include #endif -#if defined(HB_EXTERN_C) -extern "C" { -#endif +HB_EXTERN_BEGIN #if defined(__WATCOMC__) #define HB_MATH_HANDLER @@ -92,6 +90,11 @@ extern "C" { #define HB_MATH_HANDLER #endif +#if !defined(HB_MATH_HANDLER) && defined(__GNUC__) && \ + ( defined(HB_OS_LINUX) || defined(HB_OS_UNIX) ) + #define HB_MATH_ERRNO +#endif + typedef struct _HB_MATH_EXCEPTION { int type; @@ -123,8 +126,6 @@ extern double hb_random_num( void ); /* include defines from math.ch */ #include -#if defined(HB_EXTERN_C) -} -#endif +HB_EXTERN_END #endif /* HB_MATH_H_ */ diff --git a/harbour/include/hbpcode.h b/harbour/include/hbpcode.h index ca227b9cf3..6a99bdd5fc 100644 --- a/harbour/include/hbpcode.h +++ b/harbour/include/hbpcode.h @@ -191,9 +191,9 @@ typedef enum HB_P_MPUSHSTR, /* 124 Macro compiled pushed string */ HB_P_LOCALNEARADDINT, /* 125 Add/Subtract specified int into specified local without using the stack. */ HB_P_MACROPUSHREF, /* 126 Reference to macro variable @&mvar */ + HB_P_PUSHLONGLONG, /* 127 places an integer number on the virtual machine stack */ /* NOTE: This have to be the last definition */ - HB_P_LAST_PCODE /* 127 this defines the number of defined pcodes */ + HB_P_LAST_PCODE /* 128 this defines the number of defined pcodes */ } HB_PCODE; #endif /* HB_PCODE_H_ */ - diff --git a/harbour/include/hbrddcdx.h b/harbour/include/hbrddcdx.h index be78831a82..5276976452 100644 --- a/harbour/include/hbrddcdx.h +++ b/harbour/include/hbrddcdx.h @@ -62,18 +62,19 @@ #define HB_EXTERNAL_RDDDBF_USE #include "hbrdddbf.h" -#if defined(HB_EXTERN_C) -extern "C" { -#endif +HB_EXTERN_BEGIN /* CDX constants and defaults */ #define CDX_INDEXEXT ".cdx" #define CDX_MAXKEY 240 #define CDX_MAXTAGNAMELEN 10 #define CDX_PAGELEN 512 -#define CDX_INT_FREESPACE 500 -#define CDX_EXT_FREESPACE 488 +#define CDX_HEADERLEN 1024 +#define CDX_HEADERPAGES ((CDX_HEADERLEN+CDX_PAGELEN-1)/CDX_PAGELEN) +#define CDX_INT_FREESPACE (CDX_PAGELEN-12) /* 500 */ +#define CDX_EXT_FREESPACE (CDX_PAGELEN-24) /* 488 */ #define CDX_DUMMYNODE 0xFFFFFFFFL + //#define CDX_LOCKOFFSET 0x7FFFFFFEL //#define CDX_LOCKSIZE 1L #define CDX_STACKSIZE 64 @@ -87,14 +88,16 @@ extern "C" { #define CDX_BALANCE_LEAFPAGES 3 #define CDX_BALANCE_INTPAGES 3 -/* -#define CDX_CURKEY_UNDEF 1 -#define CDX_CURKEY_REC 2 -#define CDX_CURKEY_VAL 4 -#define CDX_CURKEY_INPAGE 8 -#define CDX_CURKEY_INSTACK 16 -#define CDX_CURKEY_NOTEXIST 32 -*/ +#define CDX_CURKEY_UNDEF (1<< 0) +#define CDX_CURKEY_REC (1<< 1) +#define CDX_CURKEY_VAL (1<< 2) +#define CDX_CURKEY_INPAGE (1<< 3) +#define CDX_CURKEY_INSTACK (1<< 4) +#define CDX_CURKEY_NOTEXIST (1<< 5) +#define CDX_CURKEY_RAWCNT (1<< 6) +#define CDX_CURKEY_RAWPOS (1<< 7) +#define CDX_CURKEY_LOGCNT (1<< 8) +#define CDX_CURKEY_LOGPOS (1<< 9) #define TOP_RECORD 1 #define BTTM_RECORD 2 @@ -109,6 +112,19 @@ extern "C" { #define NODE_BALANCE 8 #define NODE_EAT 16 +#define CURKEY_RAWCNT(pTag) (((pTag)->curKeyState & CDX_CURKEY_RAWCNT) != 0) +#define CURKEY_LOGCNT(pTag) (((pTag)->curKeyState & CDX_CURKEY_LOGCNT) != 0) + +#define CURKEY_RAWPOS(pTag) ( ((pTag)->curKeyState & CDX_CURKEY_RAWPOS) != 0 && \ + (pTag)->rawKeyRec == (pTag)->CurKey->rec ) +#define CURKEY_SETRAWPOS(pTag) { (pTag)->curKeyState |= CDX_CURKEY_RAWPOS; \ + (pTag)->rawKeyRec = (pTag)->CurKey->rec; } + +#define CURKEY_LOGPOS(pTag) ( ((pTag)->curKeyState & CDX_CURKEY_LOGPOS) != 0 && \ + (pTag)->logKeyRec == (pTag)->pIndex->pArea->ulRecNo ) +#define CURKEY_SETLOGPOS(pTag) { (pTag)->curKeyState |= CDX_CURKEY_LOGPOS; \ + (pTag)->logKeyRec = (pTag)->pIndex->pArea->ulRecNo; } + /* #define CURKEY_UNDEF(pTag) (((pTag)->curKeyState & CDX_CURKEY_UNDEF) != 0) #define CURKEY_NOTEXIST(pTag) (((pTag)->curKeyState & CDX_CURKEY_NOTEXIST) != 0) @@ -134,6 +150,8 @@ extern "C" { #define CDX_TYPE_COMPOUND 0x40 /* FoxPro */ #define CDX_TYPE_STRUCTURE 0x80 /* FoxPro */ +typedef void ( * HB_EVALSCOPE_FUNC )( ULONG, BYTE *, ULONG, void * ); + /* CDX index node strucutres */ /* Compact Index Header Record */ typedef struct _CDXTAGHEADER @@ -150,7 +168,7 @@ typedef struct _CDXTAGHEADER BYTE forExpLen[ 2 ]; /* length of filter expression */ BYTE keyExpPos[ 2 ]; /* offset of key expression */ BYTE keyExpLen[ 2 ]; /* length of key expression */ - BYTE keyExpPool[ CDX_PAGELEN ]; + BYTE keyExpPool[ CDX_HEADERLEN - 512 ]; } CDXTAGHEADER; typedef CDXTAGHEADER * LPCDXTAGHEADER; @@ -283,7 +301,13 @@ typedef struct _CDXTAG BOOL TagEOF; BOOL fRePos; - BYTE curKeyState; /* see: CDX_CURKEY_* */ + int curKeyState; /* see: CDX_CURKEY_* */ + ULONG rawKeyCount; + ULONG rawKeyPos; + ULONG rawKeyRec; + ULONG logKeyCount; + ULONG logKeyPos; + ULONG logKeyRec; ULONG TagBlock; /* a page offset where a tag header is stored */ ULONG RootBlock; /* a page offset with the root of keys tree */ @@ -329,9 +353,49 @@ typedef struct _CDXINDEX #endif BOOL fChanged; /* changes written to index, need upadte ulVersion */ ULONG ulVersion; /* network version/update flag */ + BOOL fFlush; /* changes written to index, need upadte ulVersion */ } CDXINDEX; typedef CDXINDEX * LPCDXINDEX; +/* for index creation */ +typedef struct +{ + ULONG nOffset; /* offset in temporary file */ + ULONG ulKeys; /* number of keys in page */ + ULONG ulKeyBuf; /* number of keys in memory buffer */ + ULONG ulCurKey; /* current key in memory buffer */ + BYTE * pKeyPool; /* memory buffer */ +} CDXSWAPPAGE; +typedef CDXSWAPPAGE * LPCDXSWAPPAGE; + +typedef struct +{ + LPCDXTAG pTag; /* current Tag */ + FHANDLE hTempFile; /* handle to temporary file */ + char * szTempFileName; /* temporary file name */ + int keyLen; /* key length */ + BYTE bTrl; /* filler char for shorter keys */ + BOOL fUnique; /* TRUE if index is unique */ + ULONG ulMaxRec; /* the highest record number */ + ULONG ulTotKeys; /* total number of keys indexed */ + ULONG ulKeys; /* keys in curently created page */ + ULONG ulPages; /* number of pages */ + ULONG ulCurPage; /* current page */ + ULONG ulPgKeys; /* maximum number of key in page memory buffer */ + ULONG ulMaxKey; /* maximum number of keys in single page */ + BYTE * pKeyPool; /* memory buffer for current page then for pages */ + LPCDXSWAPPAGE pSwapPage; /* list of pages */ + LPCDXPAGE NodeList[ CDX_STACKSIZE ]; /* Stack of pages */ + BYTE pLastKey[ CDX_MAXKEY ]; /* last key val */ + ULONG ulLastRec; + BYTE * pRecBuff; +#ifndef HB_CDX_PACKTRAIL + int iLastTrl; /* last key trailing spaces */ +#endif +} CDXSORTINFO; +typedef CDXSORTINFO * LPCDXSORTINFO; + + /* * DBF WORKAREA @@ -384,6 +448,8 @@ typedef struct _CDXAREA BYTE bMemoType; /* MEMO type used in DBF memo fields */ BOOL fHasMemo; /* WorkArea with Memo fields */ BOOL fHasTags; /* WorkArea with MDX or CDX index */ + BOOL fDataFlush; /* data was written to DBF and not commited */ + BOOL fMemoFlush; /* data was written to MEMO and not commited */ BYTE bVersion; /* DBF version ID byte */ BYTE bCodePage; /* DBF codepage ID */ BOOL fShared; /* Shared file */ @@ -418,10 +484,11 @@ typedef struct _CDXAREA * example. */ - BOOL fCdxAppend; /* Appended record changed */ - LPCDXINDEX lpIndexes; /* Pointer to indexes array */ - USHORT uiTag; /* current tag focus */ - BYTE * bCdxSortTab; /* Table with storted characters */ + BOOL fCdxAppend; /* Appended record changed */ + LPCDXINDEX lpIndexes; /* Pointer to indexes array */ + USHORT uiTag; /* current tag focus */ + BYTE * bCdxSortTab; /* Table with storted characters */ + LPCDXSORTINFO pSort; /* Index build structur */ } CDXAREA; @@ -446,7 +513,7 @@ static ERRCODE hb_cdxGoBottom( CDXAREAP pArea ); #define hb_cdxGoToId NULL static ERRCODE hb_cdxGoTop( CDXAREAP pArea ); static ERRCODE hb_cdxSeek( CDXAREAP pArea, BOOL bSoftSeek, PHB_ITEM pKey, BOOL bFindLast ); -#define hb_cdxSkip NULL +static ERRCODE hb_cdxSkip( CDXAREAP pArea, LONG lToSkip ); #define hb_cdxSkipFilter NULL static ERRCODE hb_cdxSkipRaw( CDXAREAP pArea, LONG lToSkip ); #define hb_cdxAddField NULL @@ -506,13 +573,13 @@ static ERRCODE hb_cdxOrderListRebuild( CDXAREAP pArea ); static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo ); static ERRCODE hb_cdxOrderDestroy( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ); static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pOrderInfo ); -#define hb_cdxClearFilter NULL +static ERRCODE hb_cdxClearFilter( CDXAREAP pArea ); #define hb_cdxClearLocate NULL static ERRCODE hb_cdxClearScope( CDXAREAP pArea ); -#define hb_cdxCountScope NULL +static ERRCODE hb_cdxCountScope( CDXAREAP pArea, void * pPtr, LONG * plRec ); #define hb_cdxFilterText NULL static ERRCODE hb_cdxScopeInfo( CDXAREAP pArea, USHORT nScope, PHB_ITEM pItem ); -#define hb_cdxSetFilter NULL +static ERRCODE hb_cdxSetFilter( CDXAREAP pArea, LPDBFILTERINFO pFilterInfo ); #define hb_cdxSetLocate NULL static ERRCODE hb_cdxSetScope( CDXAREAP pArea, LPDBORDSCOPEINFO sInfo ); #define hb_cdxSkipScope NULL @@ -534,10 +601,6 @@ static ERRCODE hb_cdxSetScope( CDXAREAP pArea, LPDBORDSCOPEINFO sInfo ); #define hb_cdxExists NULL #define hb_cdxWhoCares NULL -//#define hb_cdxSwapBytes( n ) HB_SWAP_ULONG( n ); - -#if defined(HB_EXTERN_C) -} -#endif +HB_EXTERN_END #endif /* HB_RDDCDX_H_ */ diff --git a/harbour/include/hbrdddbf.h b/harbour/include/hbrdddbf.h index 7f1984207a..527d7cc64f 100644 --- a/harbour/include/hbrdddbf.h +++ b/harbour/include/hbrdddbf.h @@ -53,19 +53,17 @@ #ifndef HB_RDDDBF_H_ #define HB_RDDDBF_H_ +#include "hbsetup.h" #include "hbapirdd.h" #include "hbdbferr.h" +#ifndef HB_CDP_SUPPORT_OFF #include "hbapicdp.h" - -#if defined(HB_EXTERN_C) -extern "C" { #endif +HB_EXTERN_BEGIN /* DBF default file extensions */ -#define DBF_TABLEEXT ".dbf" -/* DBF lock */ -#define DBF_LOCKPOS 1000000000L +#define DBF_TABLEEXT ".dbf" /* DBF locking schemes */ #define DBF_LOCKPOS_CLIP 1000000000L #define DBF_LOCKPOS_CL53 1000000000L @@ -100,9 +98,6 @@ extern "C" { #define DBF_EXLUSIVE_LOCKSIZE 1L #endif - - - /* * DBF WORKAREA * ------------ @@ -154,6 +149,8 @@ typedef struct _DBFAREA BYTE bMemoType; /* MEMO type used in DBF memo fields */ BOOL fHasMemo; /* WorkArea with Memo fields */ BOOL fHasTags; /* WorkArea with MDX or CDX index */ + BOOL fDataFlush; /* data was written to DBF and not commited */ + BOOL fMemoFlush; /* data was written to MEMO and not commited */ BYTE bVersion; /* DBF version ID byte */ BYTE bCodePage; /* DBF codepage ID */ BOOL fShared; /* Shared file */ @@ -176,7 +173,9 @@ typedef struct _DBFAREA BYTE bLockType; /* Type of locking shemes */ ULONG * pLocksPos; /* List of records locked */ ULONG ulNumLocksPos; /* Number of records locked */ +#ifndef HB_CDP_SUPPORT_OFF PHB_CODEPAGE cdPage; /* Area's codepage pointer */ +#endif } DBFAREA; typedef DBFAREA * LPDBFAREA; @@ -185,7 +184,6 @@ typedef DBFAREA * LPDBFAREA; #define DBFAREAP LPDBFAREA #endif - #ifndef HB_EXTERNAL_RDDDBF_USE /* @@ -224,7 +222,7 @@ static ERRCODE hb_dbfPutRec( DBFAREAP pArea, BYTE * pBuffer ); static ERRCODE hb_dbfPutValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ); static ERRCODE hb_dbfRecall( DBFAREAP pArea ); static ERRCODE hb_dbfRecCount( DBFAREAP pArea, ULONG * pRecCount ); -#define hb_dbfRecInfo NULL +static ERRCODE hb_dbfRecInfo( DBFAREAP pArea, PHB_ITEM pRecID, USHORT uiInfoType, PHB_ITEM pInfo ); static ERRCODE hb_dbfRecNo( DBFAREAP pArea, PHB_ITEM pRecNo ); static ERRCODE hb_dbfSetFieldExtent( DBFAREAP pArea, USHORT uiFieldExtent ); #define hb_dbfAlias NULL @@ -288,20 +286,18 @@ static ERRCODE hb_dbfWriteDBHeader( DBFAREAP pArea ); #define hb_dbfExit NULL static ERRCODE hb_dbfDrop( PHB_ITEM pItemTable ); -static BOOL hb_dbfExists( PHB_ITEM pItemTable, PHB_ITEM pItemIndex ); #define hb_dbfWhoCares NULL #endif /* HB_EXTERNAL_RDDDBF_USE */ +extern BOOL HB_EXPORT hb_dbfExists( PHB_ITEM pItemTable, PHB_ITEM pItemIndex ); extern ULONG HB_EXPORT hb_dbfGetMemoBlock( DBFAREAP pArea, USHORT uiIndex ); extern void HB_EXPORT hb_dbfPutMemoBlock( DBFAREAP pArea, USHORT uiIndex, ULONG ulBlock ); extern ERRCODE HB_EXPORT hb_dbfGetEGcode( ERRCODE errCode ); extern BOOL HB_EXPORT hb_dbfLockIdxFile( FHANDLE hFile, BYTE bScheme, USHORT usMode, ULONG *pPoolPos ); extern BOOL HB_EXPORT hb_dbfLockIdxGetData( BYTE bScheme, ULONG *ulPos, ULONG *ulPool ); -#if defined(HB_EXTERN_C) -} -#endif +HB_EXTERN_END #endif /* HB_RDDDBF_H_ */ diff --git a/harbour/include/hbrdddbt.h b/harbour/include/hbrdddbt.h index e891cda222..e80e548ba3 100644 --- a/harbour/include/hbrdddbt.h +++ b/harbour/include/hbrdddbt.h @@ -53,6 +53,7 @@ #ifndef HB_RDDDBT_H_ #define HB_RDDDBT_H_ +#include "hbsetup.h" #include "hbdbf.h" #include "hbdbferr.h" #include "hbapirdd.h" @@ -62,9 +63,7 @@ #define HB_EXTERNAL_RDDDBF_USE #include "hbrdddbf.h" -#if defined(HB_EXTERN_C) -extern "C" { -#endif +HB_EXTERN_BEGIN /* MEMO constants and defaults */ #define DBT_MEMOEXT ".dbt" @@ -189,12 +188,6 @@ static ERRCODE hb_dbtWriteDBHeader( DBTAREAP pArea ); #define hb_dbtExists NULL #define hb_dbtWhoCares NULL - -#if defined(HB_EXTERN_C) -} -#endif - -extern ULONG hb_dbfGetMemoBlock( DBFAREAP pArea, USHORT uiIndex ); -extern void hb_dbfPutMemoBlock( DBFAREAP pArea, USHORT uiIndex, ULONG ulBlock ); +HB_EXTERN_END #endif /* HB_RDDDBT */ diff --git a/harbour/include/hbrddfpt.h b/harbour/include/hbrddfpt.h index 383b4843f3..29d9fe15fd 100644 --- a/harbour/include/hbrddfpt.h +++ b/harbour/include/hbrddfpt.h @@ -63,9 +63,7 @@ #define HB_EXTERNAL_RDDDBF_USE #include "hbrdddbf.h" -#if defined(HB_EXTERN_C) -extern "C" { -#endif +HB_EXTERN_BEGIN /* MEMO constants and defaults */ #define FPT_MEMOEXT ".fpt" @@ -102,33 +100,43 @@ extern "C" { //#define FPTIT_SIX_VREF 0x2000 //#define FPTIT_SIX_MREF 0x4000 -#define FPTIT_FLEX_GC 0x03E8 -#define FPTIT_FLEX_UNUSED 0x03E9 +#define FPTIT_FLEX_GC 0x03E8 // 1000 +#define FPTIT_FLEX_UNUSED 0x03E9 // 1001 +#define FPTIT_FLEX_ARRAY 0x03EA // 1002 +#define FPTIT_FLEX_OBJECT 0x03EB // 1003 * +#define FPTIT_FLEX_VOARR 0x03EC // 1004 * +#define FPTIT_FLEX_VOOBJ 0x03ED // 1005 * +#define FPTIT_FLEX_NIL 0x03EE // 1006 +#define FPTIT_FLEX_TRUE 0x03EF // 1007 +#define FPTIT_FLEX_FALSE 0x03F0 // 1008 +#define FPTIT_FLEX_LDATE 0x03F1 // 1009 +#define FPTIT_FLEX_CHAR 0x03F2 // 1010 +#define FPTIT_FLEX_UCHAR 0x03F3 // 1011 * +#define FPTIT_FLEX_SHORT 0x03F4 // 1012 +#define FPTIT_FLEX_USHORT 0x03F5 // 1013 * +#define FPTIT_FLEX_LONG 0x03F6 // 1014 +#define FPTIT_FLEX_ULONG 0x03F7 // 1015 * +#define FPTIT_FLEX_DOUBLE 0x03F8 // 1016 +#define FPTIT_FLEX_LDOUBLE 0x03F9 // 1017 * +#define FPTIT_FLEX_COMPCH 0x03FA // 1018 * -#define FPTIT_FLEX_ARRAY 0x03EA -#define FPTIT_FLEX_NIL 0x03EE -#define FPTIT_FLEX_TRUE 0x03EF -#define FPTIT_FLEX_FALSE 0x03F0 -#define FPTIT_FLEX_LDATE 0x03F1 -#define FPTIT_FLEX_BYTE 0x03F2 -#define FPTIT_FLEX_SHORT 0x03F4 -#define FPTIT_FLEX_LONG 0x03F6 -#define FPTIT_FLEX_DOUBLE 0x03F8 - -#define FPTIT_FLEXAR_ARAY 0x0C #define FPTIT_FLEXAR_NIL 0x00 +#define FPTIT_FLEXAR_STR 0x07 +#define FPTIT_FLEXAR_ARAY 0x0C +#define FPTIT_FLEXAR_DATE 0x0E +#define FPTIT_FLEXAR_DBL 0x0F +#define FPTIT_FLEXAR_BYTE 0x11 +#define FPTIT_FLEXAR_CHAR 0x12 +#define FPTIT_FLEXAR_SHORT 0x13 +#define FPTIT_FLEXAR_USHORT 0x14 +#define FPTIT_FLEXAR_LONG 0x15 +#define FPTIT_FLEXAR_NUL 0x18 #define FPTIT_FLEXAR_TRUE 0x19 #define FPTIT_FLEXAR_FALSE 0x1A -#define FPTIT_FLEXAR_DATE 0x0E -#define FPTIT_FLEXAR_BYTE1 0x11 -#define FPTIT_FLEXAR_BYTE 0x12 #define FPTIT_FLEXAR_BYTE2 0x1D -#define FPTIT_FLEXAR_SHORT 0x13 #define FPTIT_FLEXAR_SHORT2 0x1E -#define FPTIT_FLEXAR_LONG 0x20 -#define FPTIT_FLEXAR_DBL 0x0F -#define FPTIT_FLEXAR_STR 0x07 -#define FPTIT_FLEXAR_NUL 0x18 +#define FPTIT_FLEXAR_LONG2 0x20 +#define FPTIT_FLEXAR_ULONG 0x21 /* #define HB_IT_NIL ( ( USHORT ) 0x0000 ) @@ -155,7 +163,7 @@ typedef struct _FPTHEADER BYTE flexRev[ 4 ]; /* Offset of reversed GC page */ BYTE flexDir[ 4 ]; /* Offset of GC page */ BYTE counter[ 4 ]; /* cyclic counter to sign changes in network env. */ - BYTE reserved3[ 4 ]; /* */ + BYTE rootBlock[ 4 ]; /* Clipper 5.3 ROOT data block */ BYTE flexSize[ 2 ]; /* FlexFile3 alternative block size */ BYTE reserved4[ 482 ]; /* */ } FPTHEADER; @@ -233,7 +241,7 @@ typedef FPTAREA * LPFPTAREA; #define hb_fptDeleted NULL #define hb_fptFieldCount NULL #define hb_fptFieldDisplay NULL -#define hb_fptFieldInfo NULL +static ERRCODE hb_fptFieldInfo( FPTAREAP pArea, USHORT uiIndex, USHORT uiType, PHB_ITEM pItem ); #define hb_fptFieldName NULL #define hb_fptFlush NULL #define hb_fptGetRec NULL @@ -311,8 +319,6 @@ static ERRCODE hb_fptWriteDBHeader( FPTAREAP pArea ); #define hb_fptExists NULL #define hb_fptWhoCares NULL -#if defined(HB_EXTERN_C) -} -#endif +HB_EXTERN_END #endif /* HB_RDDFPT */ diff --git a/harbour/include/hbrddntx.h b/harbour/include/hbrddntx.h index 2d05786ae3..f24171a7a0 100644 --- a/harbour/include/hbrddntx.h +++ b/harbour/include/hbrddntx.h @@ -269,6 +269,8 @@ typedef struct _NTXAREA BYTE bMemoType; /* MEMO type used in DBF memo fields */ BOOL fHasMemo; /* WorkArea with Memo fields */ BOOL fHasTags; /* WorkArea with MDX or CDX index */ + BOOL fDataFlush; /* data was written to DBF and not commited */ + BOOL fMemoFlush; /* data was written to MEMO and not commited */ BYTE bVersion; /* DBF version ID byte */ BYTE bCodePage; /* DBF codepage ID */ BOOL fShared; /* Shared file */ diff --git a/harbour/include/hbset.h b/harbour/include/hbset.h index d6e925ed24..0aa0fc01dc 100644 --- a/harbour/include/hbset.h +++ b/harbour/include/hbset.h @@ -129,7 +129,9 @@ typedef enum HB_SET_DIRCASE = 103, HB_SET_DIRSEPARATOR = 104, HB_SET_EOF = 105, - HB_SET_DBFLOCKSCHEME = 106 + HB_SET_HARDCOMMIT = 106, + HB_SET_FORCEOPT = 107, + HB_SET_DBFLOCKSCHEME = 108 } HB_set_enum; @@ -194,6 +196,8 @@ typedef struct int HB_SET_VIDEOMODE; BOOL HB_SET_WRAP; int HB_SET_DBFLOCKSCHEME; + BOOL HB_SET_HARDCOMMIT; + BOOL HB_SET_FORCEOPT; } HB_SET_STRUCT; #define HB_SET_CASE_MIXED 0 diff --git a/harbour/include/hbsetup.h b/harbour/include/hbsetup.h index 1bed3ea4ca..50e88d4dcd 100644 --- a/harbour/include/hbsetup.h +++ b/harbour/include/hbsetup.h @@ -298,8 +298,14 @@ #endif #endif +#ifdef HB_OS_DARWIN + #if ! defined(HB_OS_BSD) + #define HB_OS_BSD + #endif +#endif + #ifndef HB_OS_UNIX - #ifdef OS_UNIX_COMPATIBLE + #if defined(OS_UNIX_COMPATIBLE) || defined(HB_OS_LINUX) || defined(HB_OS_BSD) #define HB_OS_UNIX #endif #endif @@ -334,7 +340,13 @@ #if defined(__cplusplus) && !defined(__IBMCPP__) #define HB_EXTERN_C + #define HB_EXTERN_BEGIN extern "C" { + #define HB_EXTERN_END } +#else + #define HB_EXTERN_BEGIN + #define HB_EXTERN_END #endif + #endif /* HB_SETUP_H_ */ diff --git a/harbour/include/set.ch b/harbour/include/set.ch index 8520d7c923..a94673b789 100644 --- a/harbour/include/set.ch +++ b/harbour/include/set.ch @@ -120,8 +120,11 @@ #define _SET_DIRCASE 103 /* Harbour extension */ #define _SET_DIRSEPARATOR 104 /* Harbour extension */ #define _SET_EOF 105 /* Harbour extension */ +#define _SET_HARDCOMMIT 106 /* Harbour extension */ +#define _SET_FORCEOPT 107 /* Harbour extension */ +#define _SET_DBFLOCKSCHEME 108 /* Harbour extension */ #define HB_SET_BASE 100 -#define HB_SET_COUNT 6 +#define HB_SET_COUNT 9 #endif /* _SET_CH */ diff --git a/harbour/make_bsd.sh b/harbour/make_bsd.sh new file mode 100644 index 0000000000..1157fb85ee --- /dev/null +++ b/harbour/make_bsd.sh @@ -0,0 +1,112 @@ +#!/usr/local/bin/bash +# +# $Id$ +# + +# --------------------------------------------------------------- +# Template to initialize the environment before starting +# the GNU make system for Harbour +# +# For further information about the GNU make system please +# check doc/gmake.txt +# +# Copyright 1999-2001 Viktor Szakats (viktor.szakats@syenar.hu) +# See doc/license.txt for licensing terms. +# --------------------------------------------------------------- + +if [ -z "$HB_ARCHITECTURE" ]; then export HB_ARCHITECTURE=bsd; fi +if [ -z "$HB_COMPILER" ]; then export HB_COMPILER=gcc; fi +if [ -z "$HB_GT_LIB" ]; then export HB_GT_LIB=gtstd; fi +if [ -z "$HB_MULTI_GT" ]; then export HB_MULTI_GT=no; fi +if [ -z "$HB_MT" ]; then export HB_MT=MT; fi + +# export PRG_USR= +# export C_USR= +# export L_USR= + +# Set to constant value to be consistent with the non-GNU make files. + +export PREFIX=/usr/local + +if [ -z "$HB_BIN_INSTALL" ]; then export HB_BIN_INSTALL=$PREFIX/bin/; fi +if [ -z "$HB_LIB_INSTALL" ]; then export HB_LIB_INSTALL=$PREFIX/lib/xharbour/; fi +if [ -z "$HB_INC_INSTALL" ]; then export HB_INC_INSTALL=$PREFIX/include/xharbour/; fi + +if [ -z "$HB_ARCHITECTURE" ]; then + echo "Error: HB_ARCHITECTURE is not set." +fi +if [ -z "$HB_COMPILER" ]; then + echo "Error: HB_COMPILER is not set." +fi + +if [ -z "$HB_ARCHITECTURE" ] || [ -z "$HB_COMPILER" ]; then + + echo + echo "Usage: make_gnu.sh [command]" + echo + echo "The following commands are supported:" + echo " - all (default)" + echo " - clean" + echo " - install" + echo + echo "Notes:" + echo + echo " - HB_ARCHITECTURE and HB_COMPILER envvars must be set." + echo " The following values are currently supported:" + echo + echo " HB_ARCHITECTURE:" + echo " - dos (HB_GT_LIB=gtdos by default)" + echo " - w32 (HB_GT_LIB=gtw32 by default)" + echo " - linux (HB_GT_LIB=gtstd by default)" + echo " - os2 (HB_GT_LIB=gtos2 by default)" + echo + read + echo " HB_COMPILER:" + echo " - When HB_ARCHITECTURE=dos" + echo " - bcc16 (Borland C++ 3.x, 4.x, 5.0x, DOS 16-bit)" + echo " - djgpp (Delorie GNU C, DOS 32-bit)" + echo " - rxs32 (EMX/RSXNT/DOS GNU C, DOS 32-bit)" + echo " - watcom (Watcom C++ 9.x, 10.x, 11.x, DOS 32-bit)" + echo " - When HB_ARCHITECTURE=w32" + echo " - bcc32 (Borland C++ 4.x, 5.x, Windows 32-bit)" + echo " - gcc (Cygnus/Cygwin GNU C, Windows 32-bit)" + echo " - mingw32 (Cygnus/Mingw32 GNU C, Windows 32-bit)" + echo " - rxsnt (EMX/RSXNT/Win32 GNU C, Windows 32-bit)" + echo " - icc (IBM Visual Age C++, Windows 32-bit)" + echo " - msvc (Microsoft Visual C++, Windows 32-bit)" + echo " - When HB_ARCHITECTURE=linux" + echo " - gcc (GNU C, 32-bit)" + echo " - When HB_ARCHITECTURE=os2" + echo " - gcc (EMX GNU C, OS/2 32-bit)" + echo " - icc (IBM Visual Age C++ 3.0, OS/2 32-bit)" + echo + read + echo " HB_GT_LIB:" + echo " - gtstd (Standard streaming) (for all architectures)" + echo " - gtdos (DOS console) (for dos architecture)" + echo " - gtwin (Win32 console) (for w32 architecture)" + echo " - gtwvt (Win32 win console) (for w32 architecture)" + echo " - gtos2 (OS/2 console) (for os2 architecture)" + echo " - gtpca (PC ANSI console) (for all architectures)" + echo " - gtcrs (Curses console) (for linux, w32 architectures)" + echo " - gtsln (Slang console) (for linux, w32 architectures)" + echo " - gtxvt (XWindow console) (for linux architecture)" + echo + echo " - Use these optional envvars to configure the make process" + echo " when using the 'all' command:" + echo + echo " PRG_USR - Extra Harbour compiler options" + echo " C_USR - Extra C compiler options" + echo " L_USR - Extra linker options" + exit + +else + + # --------------------------------------------------------------- + # Start the GNU make system + gmake $* + + if [ "$*" = "clean" ]; then + find . -type d -name "$HB_ARCHITECTURE" | xargs rmdir 2> /dev/null + fi +fi diff --git a/harbour/make_drw.sh b/harbour/make_drw.sh new file mode 100644 index 0000000000..3b70262b85 --- /dev/null +++ b/harbour/make_drw.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# +# $Id$ +# + +# --------------------------------------------------------------- +# Template to initialize the environment before starting +# the GNU make system for Harbour +# +# For further information about the GNU make system please +# check doc/gmake.txt +# +# Copyright 1999-2001 Viktor Szakats (viktor.szakats@syenar.hu) +# See doc/license.txt for licensing terms. +# --------------------------------------------------------------- + +export HB_ARCHITECTURE=darwin +export HB_COMPILER=gcc +export HB_GPM_MOUSE=no +export HB_MULTI_GT=no +export PREFIX=/usr/local + +if [ -z "$HB_GT_LIB" ]; then export HB_GT_LIB=gtstd; fi + +# Set to constant value to be consistent with the non-GNU make files. + +if [ -z "$HB_BIN_INSTALL" ]; then export HB_BIN_INSTALL=$PREFIX/bin/; fi +if [ -z "$HB_LIB_INSTALL" ]; then export HB_LIB_INSTALL=$PREFIX/lib/xharbour/; fi +if [ -z "$HB_INC_INSTALL" ]; then export HB_INC_INSTALL=$PREFIX/include/xharbour/; fi + +. `dirname $0`/make_gnu.sh $* diff --git a/harbour/make_tgz.sh b/harbour/make_tgz.sh index e8b4b50508..fe50971b68 100644 --- a/harbour/make_tgz.sh +++ b/harbour/make_tgz.sh @@ -10,25 +10,32 @@ # See doc/license.txt for licensing terms. # --------------------------------------------------------------- -# please add your distro suffix if it not belong to the one recognized below -# and remember that order checking can be important -hb_platform=`rel=$(rpm -q --queryformat='.%{VERSION}' mandrake-release 2>/dev/null) && echo "mdk$rel"|tr -d "."` -[ "${hb_platform}" = "" ] && hb_platform=`rel=$(rpm -q --queryformat='.%{VERSION}' redhat-release 2>/dev/null) && echo "rh$rel"|tr -d "."` - -[ "${hb_platform}" = "" ] || hb_platform="-${hb_platform}" +cd `dirname $0` +. bin/hb-func.sh name="harbour" -hb_ver="0.44.0" +hb_ver=`get_hbver` +hb_platform=`get_hbplatform` +[ "${hb_platform}" = "" ] || hb_platform="-${hb_platform}" +hb_archfile="${name}-${hb_ver}${hb_platform}.bin.tar.gz" +hb_instfile="${name}-${hb_ver}${hb_platform}.inst.sh" hb_lnkso="yes" hb_pref="hb" -hb_libs="vm pp rtl rdd dbfdbt dbffpt dbfcdx dbfntx macro common lang codepage gtnul gtcrs gtsln gtcgi gtstd gtpca odbc ct debug profiler" -export C_USR="-DHB_FM_STATISTICS_OFF -O3" +hb_contrib="libct rdd_ads" +export C_USR="-DHB_FM_STATISTICS_OFF -O2" if [ -z "$HB_ARCHITECTURE" ]; then export HB_ARCHITECTURE=linux; fi if [ -z "$HB_COMPILER" ]; then export HB_COMPILER=gcc; fi if [ -z "$HB_GPM_MOUSE" ]; then export HB_GPM_MOUSE=yes; fi if [ -z "$HB_GT_LIB" ]; then export HB_GT_LIB=gtcrs; fi if [ -z "$HB_MULTI_GT" ]; then export HB_MULTI_GT=no; fi if [ -z "$HB_MT" ]; then export HB_MT=no; fi +if [ -z "$HB_COMMERCE" ]; then export HB_COMMERCE=no; fi + +if [ "$HB_COMMERCE" = yes ] +then + export HB_GPM_MOUSE=no + export HB_WITHOUT_GTSLN=yes +fi export HB_BIN_INSTALL="/usr/bin" export HB_INC_INSTALL="/usr/include/${name}" @@ -36,21 +43,23 @@ export HB_LIB_INSTALL="/usr/lib/${name}" # buid umask 022 -make clean -make -pushd contrib/libct - make clean - make -popd +make -r clean +make -r +for l in ${hb_contrib} +do + (cd "contrib/$l" + make -r clean + make -r) +done # install if [ -z "$TMPDIR" ]; then TMPDIR="/tmp"; fi HB_INST_PREF="$TMPDIR/$name.bin.$USER.$$" rm -fR "${HB_INST_PREF}" -_DEFAULT_BIN_DIR=$HB_BIN_INSTALL -_DEFAULT_INC_DIR=$HB_INC_INSTALL -_DEFAULT_LIB_DIR=$HB_LIB_INSTALL +export _DEFAULT_BIN_DIR=$HB_BIN_INSTALL +export _DEFAULT_INC_DIR=$HB_INC_INSTALL +export _DEFAULT_LIB_DIR=$HB_LIB_INSTALL export HB_BIN_INSTALL="$HB_INST_PREF/$HB_BIN_INSTALL" export HB_INC_INSTALL="$HB_INST_PREF/$HB_INC_INSTALL" export HB_LIB_INSTALL="$HB_INST_PREF/$HB_LIB_INSTALL" @@ -58,326 +67,20 @@ export HB_LIB_INSTALL="$HB_INST_PREF/$HB_LIB_INSTALL" mkdir -p $HB_BIN_INSTALL mkdir -p $HB_INC_INSTALL mkdir -p $HB_LIB_INSTALL -make -i install -pushd contrib/libct - make -i install -popd - -# build fm lib with memory statistic -pushd source/vm - TMP_C_USR=$C_USR - C_USR=${C_USR//-DHB_FM_STATISTICS_OFF/-DHB_PARANOID_MEM_CHECK} - rm -f fm.o - make fm.o - ar -r $HB_LIB_INSTALL/libfm.a fm.o - rm -f fm.o - if [ $HB_MT = "MT" ]; then - make fm.o 'HB_LIBCOMP_MT=YES' - ar -r $HB_LIB_INSTALL/libfmmt.a fm.o - rm -f fm.o - fi - C_USR=$TMP_C_USR -popd +make -r -i install +for l in ${hb_contrib} +do + (cd "contrib/$l" + make -r -i install) +done # Keep the size of the binaries to a minimim. -strip $HB_BIN_INSTALL/* +strip $HB_BIN_INSTALL/harbour # Keep the size of the libraries to a minimim. strip --strip-debug $HB_LIB_INSTALL/* install -m755 bin/hb-mkslib.sh $HB_BIN_INSTALL/hb-mkslib -pushd $HB_LIB_INSTALL -LIBS="" -LIBSMT="" -for l in ${hb_libs} -do - case $l in - debug|profiler) ;; - *) - ls="lib${l}.a" - if [ -f lib${l}mt.a ] - then - lm="lib${l}mt.a" - else - lm="${ls}" - fi - if [ "${HB_MULTI_GT}" = "yes" ] || \ - [ "${l#gt}" = "${l}" ] || \ - [ "${l}" == "${HB_GT_LIB}" ] - then - if [ -f $ls ] - then - LIBS="$LIBS $ls" - fi - if [ -f $lm ] - then - LIBSMT="$LIBSMT $lm" - fi - fi - ;; - esac -done -$HB_BIN_INSTALL/hb-mkslib lib${name}-${hb_ver}.so $LIBS -[ $HB_MT != "MT" ] || $HB_BIN_INSTALL/hb-mkslib lib${name}mt-${hb_ver}.so $LIBSMT -for l in lib${name}-${hb_ver}.so lib${name}mt-${hb_ver}.so -do - if [ -f $l ] - then - ll=${l%-${hb_ver}.so}.so - ln -s $l $ll && ln -s ${name}/$l $HB_INST_PREF/usr/lib/$ll - fi -done -#export LD_LIBRARY_PATH="$HB_LIB_INSTALL:$LD_LIBRARY_PATH" -popd - -# Add a harbour compiler wrapper. -cat > $HB_BIN_INSTALL/${hb_pref}-build <] [.prg|.o] - -\"${hb_pref}cc\", \"${hb_pref}cmp\", \"${hb_pref}lnk\" and \"${hb_pref}mk\" parameters: - -o # output file name -\"${hb_pref}lnk\" and \"${hb_pref}mk\" parameters: - -static # link with static ${name} libs - -fullstatic # link with all static libs - -shared # link with shared libs (default) - -mt # link with multi-thread libs - -gt # link with GT driver, can be repeated to - # link with more GTs. The first one will be - # the default at runtime - -fmstat # link with the memory statistics lib - -nofmstat # do not link with the memory statistics lib (default) - -main= # set the name of main program function/procedure. - # if not set then 'MAIN' is used or if it doesn't - # exist the name of first public function/procedure - # in first linked object module (link) -" - exit 1 -elif [ "\$*" == "mk-links" ]; then - DIR="\${0%/*}" - NAME="\${0##*/}" - if [ "\${DIR}" != "\${NAME}" ]; then - for n in ${hb_pref}cc ${hb_pref}cmp ${hb_pref}mk ${hb_pref}lnk gharbour harbour-link; do - ln -sf "\${NAME}" "\${DIR}/\${n}" - done - fi - exit -fi - -## default parameters -HB_STATIC="no" -HB_MT="" -HB_GT="${HB_GT_LIB#gt}" -HB_MG="${HB_MULTI_GT}" - -HB_GT_REQ="" -HB_FM_REQ="" -HB_MAIN_FUNC="" -_TMP_FILE_="/tmp/hb-build-\$USER-\$\$.c" - -## parse params -P=( "\$@" ); n=0; DIROUT="."; FILEOUT="" -while [ \$n -lt \${#P[@]} ]; do - v=\${P[\$n]}; p="" - case "\$v" in - -o*) - d="\${v#-o}"; p="\${v}" - if [ -d "\${d}" ]; then - DIROUT="\${d%/}" - elif [ -d "\${d%/*}" ]; then - DIROUT="\${d%/*}"; FILEOUT="\${d##*/}"; p="-o\${d%.*}" - elif [ -n "\${d}" ]; then - FILEOUT="\${d}"; p="-o\${d%.*}" - fi ;; - -static) HB_STATIC="yes" ;; - -fullstatic) HB_STATIC="full" ;; - -shared) HB_STATIC="no" ;; - -mt) HB_MT="MT" ;; - -gt*) HB_GT_REQ="\${HB_GT_REQ} \${v#-gt}" ;; - -fmstat) HB_FM_REQ="STAT" ;; - -nofmstat) HB_FM_REQ="NOSTAT" ;; - -main=*) HB_MAIN_FUNC="\${v#*=}" ;; - -*) p="\${v}" ;; - *) [ -z \${FILEOUT} ] && FILEOUT="\${v##*/}"; p="\${v}" ;; - esac - [ -n "\$p" ] && PP[\$n]="\$p" - n=\$[\$n + 1] -done -P=( "\${PP[@]}" ) - -case "\${HB_MT}" in - [Mm][Tt]|[Yy][Ee][Ss]|1) HB_MT="MT";; - *) HB_MT="";; -esac - -SYSTEM_LIBS="-lm -lncurses -lslang -lgpm" -# use pthread system library for MT programs -if [ "\${HB_MT}" = "MT" ]; then - SYSTEM_LIBS="-lpthread \${SYSTEM_LIBS}" -fi - -HB_GT_STAT="" -[ -z "\${HB_GT_REQ}" ] && HB_GT_REQ="\${HB_GT}" -if [ "\${HB_MG}" != "yes" ]; then - [ "\${HB_STATIC}" = "yes" ] && HB_GT_STAT=\`echo \${HB_GT_REQ}|tr A-Z a-z\` - HB_GT_REQ="" -else - HB_GT_REQ=\`echo \${HB_GT_REQ}|tr a-z A-Z\` -fi -HB_MAIN_FUNC=\`echo \${HB_MAIN_FUNC}|tr a-z A-Z\` - -# set environment variables -export HB_ARCHITECTURE="${HB_ARCHITECTURE}" -export HB_COMPILER="${HB_COMPILER}" -[ -z "\${HB_BIN_INSTALL}" ] && export HB_BIN_INSTALL="${_DEFAULT_BIN_DIR}" -[ -z "\${HB_INC_INSTALL}" ] && export HB_INC_INSTALL="${_DEFAULT_INC_DIR}" -[ -z "\${HB_LIB_INSTALL}" ] && export HB_LIB_INSTALL="${_DEFAULT_LIB_DIR}" - -# be sure that ${name} binaries are in your path -export PATH="\${HB_BIN_INSTALL}:\${PATH}" - -HB_PATHS="-I\${HB_INC_INSTALL}" -GCC_PATHS="\${HB_PATHS} -L\${HB_LIB_INSTALL}" -LINK_OPT="" -if [ "\${HB_STATIC}" = "full" ]; then - LINK_OPT="\${LINK_OPT} -static" - HB_STATIC="yes" -fi - -HARBOUR_LIBS="" -if [ "\${HB_STATIC}" = "yes" ]; then - libs="${hb_libs}" -else - l="${name}" - [ "\${HB_MT}" = "MT" ] && [ -f "\${HB_LIB_INSTALL}/lib\${l}mt.so" ] && l="\${l}mt" - [ -f "\${HB_LIB_INSTALL}/lib\${l}.so" ] && HARBOUR_LIBS="\${HARBOUR_LIBS} -l\${l}" - libs="debug profiler" -fi -for l in \${libs} -do - if [ "\${HB_MG}" = "yes" ] || [ "\${l#gt}" = "\${l}" ] || [ "\${l}" == "gt\${HB_GT_STAT}" ]; then - [ "\${HB_MT}" = "MT" ] && [ -f "\${HB_LIB_INSTALL}/lib\${l}mt.a" ] && l="\${l}mt" - [ -f "\${HB_LIB_INSTALL}/lib\${l}.a" ] && HARBOUR_LIBS="\${HARBOUR_LIBS} -l\${l}" - fi -done -HARBOUR_LIBS="-Wl,--start-group \${HARBOUR_LIBS} -Wl,--end-group" -l="fm" -[ "\${HB_MT}" = "MT" ] && [ -f "\${HB_LIB_INSTALL}/lib\${l}mt.a" ] && l="\${l}mt" -if [ -f "\${HB_LIB_INSTALL}/lib\${l}.a" ]; then - if [ "\${HB_STATIC}" = "yes" ] && [ "\${HB_FM_REQ}" = "STAT" ]; then - HARBOUR_LIBS="-l\${l} \${HARBOUR_LIBS}" - else - HARBOUR_LIBS="\${HARBOUR_LIBS} -l\${l}" - fi -fi - -FOUTC="\${DIROUT}/\${FILEOUT%.*}.c" -FOUTO="\${DIROUT}/\${FILEOUT%.*}.o" -FOUTE="\${DIROUT}/\${FILEOUT%.[Pp][Rr][Gg]}" -FOUTE="\${FOUTE%.[oc]}" - -hb_cc() -{ - harbour "\$@" \${HB_PATHS} && [ -f "\${FOUTC}" ] -} - -hb_link() -{ - if [ -n "\${HB_MAIN_FUNC}" ]; then - HB_MAIN_FUNC="@\${HB_MAIN_FUNC}" - elif [ -f "\${FOUTO}" ]; then - HB_MAIN_FUNC=\`hb_lnk_main "\${FOUTO}"\` - fi - if [ -n "\${HB_GT_REQ}" ] || [ -n "\${HB_FM_REQ}" ] || [ -n "\${HB_MAIN_FUNC}" ]; then - hb_lnk_request > \${_TMP_FILE_} && \\ - gcc "\$@" "\${_TMP_FILE_}" \${LINK_OPT} \${GCC_PATHS} \${HARBOUR_LIBS} \${SYSTEM_LIBS} -o "\${FOUTE}" - else - gcc "\$@" \${LINK_OPT} \${GCC_PATHS} \${HARBOUR_LIBS} \${SYSTEM_LIBS} -o "\${FOUTE}" - fi -} - -hb_cmp() -{ - hb_cc "\$@" && \\ - gcc -g -c "\${FOUTC}" -o "\${FOUTO}" \${GCC_PATHS} && \\ - rm -f "\${FOUTC}" -} - -hb_lnk_request() -{ - echo "#include \\"hbapi.h\\"" - if [ "\${HB_STATIC}" = "yes" ] || [ -n "\${HB_FM_REQ}" ]; then - for gt in \${HB_GT_REQ}; do - echo "extern HB_FUNC( HB_GT_\${gt} );" - done - if [ -n "\${HB_FM_REQ}" ]; then - echo "extern HB_FUNC( HB_FM_\${HB_FM_REQ} );" - fi - echo "void hb_lnk_ForceLink_build( void )" - echo "{" - for gt in \${HB_GT_REQ}; do - echo " HB_FUNCNAME( HB_GT_\${gt} )();" - done - if [ -n "\${HB_FM_REQ}" ]; then - echo " HB_FUNCNAME( HB_FM_\${HB_FM_REQ} )();" - fi - echo "}" - fi - gt="\${HB_GT_REQ%% *}" - if [ -n "\$gt" ] || [ -n "\${HB_MAIN_FUNC}" ]; then - echo "#include \\"hbinit.h\\"" - echo "extern char * s_defaultGT;" - echo "extern char * s_pszLinkedMain;" - echo "HB_CALL_ON_STARTUP_BEGIN( hb_lnk_SetDefault_build )" - if [ -n "\$gt" ]; then - echo " s_defaultGT = \\"\$gt\\";" - fi - if [ -n "\${HB_MAIN_FUNC}" ]; then - echo " s_pszLinkedMain = \\"\${HB_MAIN_FUNC}\\";" - fi - echo "HB_CALL_ON_STARTUP_END( hb_lnk_SetDefault_build )" - fi -} - -hb_lnk_main() -{ - (nm \$1 -g -n --defined-only|sed -e '/HB_FUN_/ ! d' -e 's/^[0-9a-fA-F]* T HB_FUN_//'|head -1|grep -v '^MAIN\$')2>/dev/null -# (nm \$1 -n --defined-only|sed -e '/HB_FUN_/ ! d' -e 's/^[0-9a-fA-F]* [Tt] HB_FUN_//'|head -1|grep -v '^MAIN\$')2>/dev/null -} - -hb_cleanup() -{ - rm -f "\${_TMP_FILE_}" -} - -trap hb_cleanup EXIT &>/dev/null - -## get basename -HB="\${0##*/}" - -case "\${HB}" in - *cc) - hb_cc "\${P[@]}" - ;; - *cmp|gharbour) - hb_cmp "\${P[@]}" - ;; - *lnk|harbour-link) - hb_link "\${P[@]}" - ;; - *mk) - hb_cmp "\${P[@]}" && \\ - hb_link "\${FOUTO}" && \\ - strip "\${FOUTE}" && \\ - rm -f "\${FOUTO}" - ;; -esac -EOF -chmod 755 $HB_BIN_INSTALL/${hb_pref}-build -$HB_BIN_INSTALL/${hb_pref}-build mk-links - mkdir -p $HB_INST_PREF/etc/harbour install -m644 source/rtl/gtcrs/hb-charmap.def $HB_INST_PREF/etc/harbour/hb-charmap.def cat > $HB_INST_PREF/etc/harbour.cfg < "${hb_instfile}" < "${hb_archfile}" + exit +fi +if [ \`id -u\` != 0 ]; then + echo "This package has to be installed from root account." + exit 1 +fi +echo "Do you want to install ${name} (y/n)" +read ASK +if [ "\${ASK}" != "y" ] && [ "\${ASK}" != "Y" ]; then + exit 1 +fi +(sed -e '1,/^HB_INST_EOF\$/ d' \$0 | gzip -cd | tar xvf - -C /) && ldconfig +exit \$? +HB_INST_EOF +EOF +cat "${hb_archfile}" >> "${hb_instfile}" +chmod +x "${hb_instfile}" +rm -f "${hb_archfile}" diff --git a/harbour/source/common/Makefile b/harbour/source/common/Makefile index 8995e581c5..7518cbd775 100644 --- a/harbour/source/common/Makefile +++ b/harbour/source/common/Makefile @@ -5,7 +5,6 @@ ROOT = ../../ C_SOURCES=\ - hbffind.c \ hbfhnd.c \ hbfsapi.c \ hbgete.c \ @@ -13,6 +12,7 @@ C_SOURCES=\ hbstr.c \ hbtrace.c \ hbver.c \ + hbverdsp.c \ reserved.c \ expropt1.c \ expropt2.c \ diff --git a/harbour/source/common/expropt1.c b/harbour/source/common/expropt1.c index bb8b13d118..56bcef2b1a 100644 --- a/harbour/source/common/expropt1.c +++ b/harbour/source/common/expropt1.c @@ -165,7 +165,7 @@ HB_EXPR_PTR hb_compExprNewDouble( double dValue, BYTE ucWidth, BYTE ucDec ) HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewDouble(%f, %i)", dValue, ucDec)); - pExpr =hb_compExprNew( HB_ET_NUMERIC ); + pExpr = hb_compExprNew( HB_ET_NUMERIC ); pExpr->value.asNum.dVal = dValue; pExpr->value.asNum.bWidth = ucWidth; @@ -176,13 +176,13 @@ HB_EXPR_PTR hb_compExprNewDouble( double dValue, BYTE ucWidth, BYTE ucDec ) return pExpr; } -HB_EXPR_PTR hb_compExprNewLong( long lValue ) +HB_EXPR_PTR hb_compExprNewLong( HB_LONG lValue ) { HB_EXPR_PTR pExpr; - HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewLong(%li)", lValue)); + HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewLong(%" PFHL "d)", lValue)); - pExpr =hb_compExprNew( HB_ET_NUMERIC ); + pExpr = hb_compExprNew( HB_ET_NUMERIC ); pExpr->value.asNum.lVal = lValue; pExpr->value.asNum.bDec = 0; @@ -195,7 +195,7 @@ HB_EXPR_PTR hb_compExprNewLong( long lValue ) int hb_compExprIsInteger( HB_EXPR_PTR pExpr ) { return ( pExpr->ExprType == HB_ET_NUMERIC && pExpr->value.asNum.NumType == HB_ET_LONG && - pExpr->value.asNum.lVal >= -32768 && pExpr->value.asNum.lVal <= 32767 ); + HB_LIM_INT16( pExpr->value.asNum.lVal ) ); } int hb_compExprAsInteger( HB_EXPR_PTR pExpr ) @@ -223,14 +223,14 @@ HB_EXPR_PTR hb_compExprNewCodeBlock( char *string, BOOL isMacro, BOOL lateEval ) HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewCodeBlock(%s,%u,%u)",string,isMacro,lateEval)); - pExpr =hb_compExprNew( HB_ET_CODEBLOCK ); + pExpr = hb_compExprNew( HB_ET_CODEBLOCK ); pExpr->value.asCodeblock.pExprList = NULL; pExpr->value.asCodeblock.pLocals = NULL; /* this will hold local variables declarations */ pExpr->ValType = HB_EV_CODEBLOCK; - pExpr->value.asCodeblock.string = string; - pExpr->value.asCodeblock.isMacro = isMacro; - pExpr->value.asCodeblock.lateEval = lateEval; + pExpr->value.asCodeblock.string = string; + pExpr->value.asCodeblock.isMacro = isMacro; + pExpr->value.asCodeblock.lateEval = lateEval; return pExpr; } @@ -258,7 +258,7 @@ HB_EXPR_PTR hb_compExprNewLogical( int iValue ) HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewLogical(%i)", iValue)); - pExpr =hb_compExprNew( HB_ET_LOGICAL ); + pExpr = hb_compExprNew( HB_ET_LOGICAL ); pExpr->value.asLogical = iValue; pExpr->ValType = HB_EV_LOGICAL; @@ -285,7 +285,7 @@ HB_EXPR_PTR hb_compExprNewSelf( void ) HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewSelf()")); - pExpr =hb_compExprNew( HB_ET_SELF ); + pExpr = hb_compExprNew( HB_ET_SELF ); pExpr->ValType = HB_EV_OBJECT; return pExpr; @@ -297,7 +297,7 @@ HB_EXPR_PTR hb_compExprNewVarRef( char * szVarName ) HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewVarRef(%s)", szVarName)); - pExpr =hb_compExprNew( HB_ET_VARREF ); + pExpr = hb_compExprNew( HB_ET_VARREF ); pExpr->value.asSymbol = szVarName; pExpr->ValType = HB_EV_VARREF; @@ -856,9 +856,15 @@ HB_EXPR_PTR hb_compExprNewNegate( HB_EXPR_PTR pNegExpr ) if( pNegExpr->ExprType == HB_ET_NUMERIC ) { if( pNegExpr->value.asNum.NumType == HB_ET_DOUBLE ) + { pNegExpr->value.asNum.dVal = - pNegExpr->value.asNum.dVal; + pNegExpr->value.asNum.bWidth = HB_DBL_LENGTH( pNegExpr->value.asNum.dVal ); + } else + { pNegExpr->value.asNum.lVal = - pNegExpr->value.asNum.lVal; + pNegExpr->value.asNum.bWidth = HB_LONG_LENGTH( pNegExpr->value.asNum.lVal ); + } pExpr = pNegExpr; } else @@ -901,4 +907,3 @@ ULONG hb_compExprListLen( HB_EXPR_PTR pExpr ) return ulLen; } - diff --git a/harbour/source/common/expropt2.c b/harbour/source/common/expropt2.c index 47c7db671b..ea43c6c2ad 100644 --- a/harbour/source/common/expropt2.c +++ b/harbour/source/common/expropt2.c @@ -82,22 +82,11 @@ HB_EXPR_PTR hb_compExprReduceMod( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) { if( pRight->value.asNum.lVal ) { - double dVal = pLeft->value.asNum.lVal % pRight->value.asNum.lVal; - - if( ( double ) LONG_MIN <= dVal && dVal <= ( double ) LONG_MAX ) - { - pSelf->value.asNum.lVal = ( long ) dVal; - pSelf->value.asNum.bDec = 0; - pSelf->value.asNum.NumType = HB_ET_LONG; - } - else - { - pSelf->value.asNum.dVal = dVal; - pSelf->value.asNum.bWidth = HB_DEFAULT_WIDTH; - pSelf->value.asNum.bDec = 0; - pSelf->value.asNum.NumType = HB_ET_DOUBLE; - } + HB_LONG lVal = pLeft->value.asNum.lVal % pRight->value.asNum.lVal; + pSelf->value.asNum.lVal = lVal; + pSelf->value.asNum.bDec = 0; + pSelf->value.asNum.NumType = HB_ET_LONG; pSelf->ExprType = HB_ET_NUMERIC; pSelf->ValType = HB_EV_NUMERIC; hb_compExprFree( pLeft, HB_MACRO_PARAM ); @@ -130,19 +119,17 @@ HB_EXPR_PTR hb_compExprReduceDiv( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) if( pRight->value.asNum.lVal ) { - double dVal = ( double ) pLeft->value.asNum.lVal / ( double ) pRight->value.asNum.lVal; - - if( fmod( dVal, 1.0 ) == 0.0 ) + if( pLeft->value.asNum.lVal % pRight->value.asNum.lVal == 0 ) { /* Return integer results as long */ - pSelf->value.asNum.lVal = ( long ) dVal; + pSelf->value.asNum.lVal = pLeft->value.asNum.lVal / pRight->value.asNum.lVal; pSelf->value.asNum.bDec = 0; pSelf->value.asNum.NumType = HB_ET_LONG; } else { /* Return non-integer results as double */ - pSelf->value.asNum.dVal = dVal; + pSelf->value.asNum.dVal = ( double ) pLeft->value.asNum.lVal / ( double ) pRight->value.asNum.lVal; pSelf->value.asNum.bWidth = HB_DEFAULT_WIDTH; pSelf->value.asNum.bDec = HB_DEFAULT_DECIMALS; pSelf->value.asNum.NumType = HB_ET_DOUBLE; @@ -220,17 +207,17 @@ HB_EXPR_PTR hb_compExprReduceMult( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) { case HB_ET_LONG: { - double dVal = ( double ) pLeft->value.asNum.lVal * ( double ) pRight->value.asNum.lVal; + HB_MAXDBL dVal = ( HB_MAXDBL ) pLeft->value.asNum.lVal * ( HB_MAXDBL ) pRight->value.asNum.lVal; - if( ( double ) LONG_MIN <= dVal && dVal <= ( double ) LONG_MAX ) + if ( HB_DBL_LIM_LONG( dVal ) ) { - pSelf->value.asNum.lVal = ( long ) dVal; + pSelf->value.asNum.lVal = ( HB_LONG ) dVal; pSelf->value.asNum.bDec = 0; pSelf->value.asNum.NumType = HB_ET_LONG; } else { - pSelf->value.asNum.dVal = dVal; + pSelf->value.asNum.dVal = ( double ) dVal; pSelf->value.asNum.bWidth = HB_DEFAULT_WIDTH; pSelf->value.asNum.bDec = 0; pSelf->value.asNum.NumType = HB_ET_DOUBLE; @@ -294,17 +281,17 @@ HB_EXPR_PTR hb_compExprReduceMinus( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) { case HB_ET_LONG: { - double dVal = ( double ) pLeft->value.asNum.lVal - ( double ) pRight->value.asNum.lVal; + HB_MAXDBL dVal = ( HB_MAXDBL ) pLeft->value.asNum.lVal - ( HB_MAXDBL ) pRight->value.asNum.lVal; - if( ( double ) LONG_MIN <= dVal && dVal <= ( double ) LONG_MAX ) + if ( HB_DBL_LIM_LONG( dVal ) ) { - pSelf->value.asNum.lVal = ( long ) dVal; + pSelf->value.asNum.lVal = ( HB_LONG ) dVal; pSelf->value.asNum.bDec = 0; pSelf->value.asNum.NumType = HB_ET_LONG; } else { - pSelf->value.asNum.dVal = dVal; + pSelf->value.asNum.dVal = ( double ) dVal; pSelf->value.asNum.bWidth = HB_DEFAULT_WIDTH; pSelf->value.asNum.bDec = 0; pSelf->value.asNum.NumType = HB_ET_DOUBLE; @@ -376,17 +363,17 @@ HB_EXPR_PTR hb_compExprReducePlus( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) { case HB_ET_LONG: { - double dVal = ( double ) pLeft->value.asNum.lVal + ( double ) pRight->value.asNum.lVal; + HB_MAXDBL dVal = ( HB_MAXDBL ) pLeft->value.asNum.lVal + ( HB_MAXDBL ) pRight->value.asNum.lVal; - if( ( double ) LONG_MIN <= dVal && dVal <= ( double ) LONG_MAX ) + if ( HB_DBL_LIM_LONG( dVal ) ) { - pSelf->value.asNum.lVal = ( long ) dVal; + pSelf->value.asNum.lVal = ( HB_LONG ) dVal; pSelf->value.asNum.bDec = 0; pSelf->value.asNum.NumType = HB_ET_LONG; } else { - pSelf->value.asNum.dVal = dVal; + pSelf->value.asNum.dVal = ( double ) dVal; pSelf->value.asNum.bWidth = HB_DEFAULT_WIDTH; pSelf->value.asNum.bDec = 0; pSelf->value.asNum.NumType = HB_ET_DOUBLE; @@ -434,28 +421,28 @@ HB_EXPR_PTR hb_compExprReducePlus( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) { if( pRight->ulLength == 0 ) { - pSelf->ExprType = HB_ET_NONE; /* suppress deletion of operator components */ - hb_compExprFree( pSelf, HB_MACRO_PARAM ); + pSelf->ExprType = HB_ET_NONE; /* suppress deletion of operator components */ + hb_compExprFree( pSelf, HB_MACRO_PARAM ); pSelf = pLeft; hb_compExprFree( pRight, HB_MACRO_PARAM ); } else if( pLeft->ulLength == 0 ) { - pSelf->ExprType = HB_ET_NONE; /* suppress deletion of operator components */ - hb_compExprFree( pSelf, HB_MACRO_PARAM ); + pSelf->ExprType = HB_ET_NONE; /* suppress deletion of operator components */ + hb_compExprFree( pSelf, HB_MACRO_PARAM ); pSelf = pRight; hb_compExprFree( pLeft, HB_MACRO_PARAM ); } else { - /* Do not reduce strings with the macro operator '&' - */ - if( strchr(pLeft->value.asString.string, '&') == NULL ) - { - pSelf->ExprType = HB_ET_NONE; /* suppress deletion of operator components */ - hb_compExprFree( pSelf, HB_MACRO_PARAM ); + /* Do not reduce strings with the macro operator '&' + */ + if( strchr(pLeft->value.asString.string, '&') == NULL ) + { + pSelf->ExprType = HB_ET_NONE; /* suppress deletion of operator components */ + hb_compExprFree( pSelf, HB_MACRO_PARAM ); pSelf = hb_compExprReducePlusStrings( pLeft, pRight, HB_MACRO_PARAM ); - } + } } } else @@ -1203,7 +1190,7 @@ BOOL hb_compExprReduceCHR( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) else { pExpr->value.asString.string = ( char * ) hb_xgrab( 2 ); - pExpr->value.asString.string[ 0 ] = ( ( long ) pArg->value.asNum.dVal % 256 ); + pExpr->value.asString.string[ 0 ] = ( ( unsigned int ) pArg->value.asNum.dVal % 256 ); pExpr->value.asString.string[ 1 ] = '\0'; pExpr->value.asString.dealloc = TRUE; pExpr->ulLength = 1; diff --git a/harbour/source/common/hbfsapi.c b/harbour/source/common/hbfsapi.c index fa923a3e35..aa308e1f64 100644 --- a/harbour/source/common/hbfsapi.c +++ b/harbour/source/common/hbfsapi.c @@ -204,6 +204,7 @@ PHB_FNAME hb_fsFNameSplit( char * pszFileName ) /* This function joins path, name and extension into a string with a filename */ char * hb_fsFNameMerge( char * pszFileName, PHB_FNAME pFileName ) { + static char szPathSep[] = {OS_PATH_DELIMITER,0}; /* see NOTE below */ char * pszName; HB_TRACE(HB_TR_DEBUG, ("hb_fsFNameMerge(%p, %p)", pszFileName, pFileName)); @@ -213,12 +214,18 @@ char * hb_fsFNameMerge( char * pszFileName, PHB_FNAME pFileName ) /* Strip preceding path separators from the filename */ pszName = pFileName->szName; - if( pszName && pszName[ 0 ] != '\0' && strchr( OS_PATH_DELIMITER_LIST, pszName[ 0 ] ) ) + if( pszName && pszName[ 0 ] != '\0' && strchr( OS_PATH_DELIMITER_LIST, pszName[ 0 ] ) != NULL ) pszName++; /* Add path if specified */ if( pFileName->szPath ) - strcat( pszFileName, pFileName->szPath ); + hb_strncat( pszFileName, pFileName->szPath, _POSIX_PATH_MAX - 1 ); + + /* + NOTE: be _very_ careful about 'optimising' this next section code! + (specifically, initialising szPathSep) as MSVC with /Ni + (or anything that infers it like /Ox) will cause you trouble. + */ /* If we have a path, append a path separator to the path if there was none. */ @@ -228,18 +235,20 @@ char * hb_fsFNameMerge( char * pszFileName, PHB_FNAME pFileName ) if( strchr( OS_PATH_DELIMITER_LIST, pszFileName[ iLen ] ) == NULL ) { - char szPathSep[ 2 ]; + /* + char szPathSep[2]; - szPathSep[ 0 ] = OS_PATH_DELIMITER; - szPathSep[ 1 ] = '\0'; + szPathSep[ 0 ] = OS_PATH_DELIMITER; + szPathSep[ 1 ] = '\0'; - strcat( pszFileName, szPathSep ); + */ + hb_strncat( pszFileName, szPathSep, _POSIX_PATH_MAX - 1 ); } } /* Add filename (without extension) if specified */ if( pszName ) - strcat( pszFileName, pszName ); + hb_strncat( pszFileName, pszName, _POSIX_PATH_MAX - 1 ); /* Add extension if specified */ if( pFileName->szExtension ) @@ -247,9 +256,9 @@ char * hb_fsFNameMerge( char * pszFileName, PHB_FNAME pFileName ) /* Add a dot if the extension doesn't have it */ if( pFileName->szExtension[ 0 ] != '\0' && pFileName->szExtension[ 0 ] != '.' ) - strcat( pszFileName, "." ); + hb_strncat( pszFileName, ".", _POSIX_PATH_MAX - 1 ); - strcat( pszFileName, pFileName->szExtension ); + hb_strncat( pszFileName, pFileName->szExtension, _POSIX_PATH_MAX - 1 ); } HB_TRACE(HB_TR_INFO, ("hb_fsFNameMerge: szPath: |%s|\n", pFileName->szPath)); @@ -260,4 +269,3 @@ char * hb_fsFNameMerge( char * pszFileName, PHB_FNAME pFileName ) return pszFileName; } - diff --git a/harbour/source/common/hbstr.c b/harbour/source/common/hbstr.c index e1ffbf6b78..489a04e226 100644 --- a/harbour/source/common/hbstr.c +++ b/harbour/source/common/hbstr.c @@ -65,6 +65,7 @@ #include /* Needed by hb_strupr() */ #include "hbapi.h" +#include "hbmath.h" ULONG hb_strAt( const char * szSub, ULONG ulSubLen, const char * szText, ULONG ulLen ) { @@ -157,58 +158,439 @@ int hb_stricmp( const char * s1, const char * s2 ) return rc; } +/* + * This function copies szText to destination buffer. + * NOTE: Unlike the documentation for strncpy, this routine will always append + * a null + */ +HB_EXPORT char * hb_strncpy( char * pDest, const char * pSource, ULONG ulLen ) +{ + char *pBuf = pDest; + + HB_TRACE(HB_TR_DEBUG, ("hb_strncpy(%p, %s, %lu)", pDest, pSource, ulLen)); + + pDest[ ulLen ] ='\0'; + + while( ulLen && ( *pDest++ = *pSource++ ) != '\0' ) + { + ulLen--; + } + + while (ulLen--) + { + *pDest++ = '\0'; + } + + return pBuf; +} + +/* + * This function copies szText to destination buffer. + * NOTE: Unlike the documentation for strncat, this routine will always append + * a null and the ulLen param is pDest size not pSource limit + */ +HB_EXPORT char * hb_strncat( char * pDest, const char * pSource, ULONG ulLen ) +{ + char *pBuf = pDest; + + HB_TRACE(HB_TR_DEBUG, ("hb_strncpy(%p, %s, %lu)", pDest, pSource, ulLen)); + + pDest[ ulLen ] ='\0'; + + while( ulLen && *pDest ) + { + pDest++; + ulLen--; + } + + while( ulLen && ( *pDest++ = *pSource++ ) != '\0' ) + { + ulLen--; + } + +/* if someone will need this then please uncomment the cleaning the rest of buffer. */ +/* + while (ulLen--) + { + *pDest++ = '\0'; + } +*/ + return pBuf; +} + +/* This function copies and converts szText to upper case. + * NOTE: Unlike the documentation for strncpy, this routine will always append + * a null + */ +HB_EXPORT char * hb_strncpyUpper( char * pDest, const char * pSource, ULONG ulLen ) +{ + char *pBuf = pDest; + + HB_TRACE(HB_TR_DEBUG, ("hb_strncpyUpper(%p, %s, %lu)", pDest, pSource, ulLen)); + + pDest[ ulLen ] ='\0'; + + /* some compilers impliment toupper as a macro, and this has side effects! */ + /* *pDest++ = toupper( *pSource++ ); */ + while( ulLen && (*pDest++ = toupper( *pSource )) != '\0' ) + { + ulLen--; + pSource++; + } + + while (ulLen--) + { + *pDest++ = '\0'; + } + + return pBuf; +} + +/* This function copies and converts szText to upper case AND Trims it + * NOTE: Unlike the documentation for strncpy, this routine will always append + * a null + */ +HB_EXPORT char * hb_strncpyUpperTrim( char * pDest, const char * pSource, ULONG ulLen ) +{ + char *pBuf = pDest; + ULONG ulSLen = strlen( pSource ); + + HB_TRACE(HB_TR_DEBUG, ("hb_strncpyUpperTrim(%p, %s, %lu)", pDest, pSource, ulLen)); + + pDest[ ulLen ] ='\0'; + + while( ulSLen && pSource[ ulSLen - 1 ] == ' ') + { + ulSLen--; + } + + /* some compilers impliment toupper as a macro, and this has side effects! */ + /* *pDest++ = toupper( *pSource++ ); */ + while( ulLen && ulSLen && (*pDest++ = toupper( *pSource )) != '\0' ) + { + ulSLen--; + ulLen--; + pSource++; + } + + while (ulLen--) + { + *pDest++ = '\0'; + } + + return pBuf; +} + +/* + * This function copies trimed szText to destination buffer. + * NOTE: Unlike the documentation for strncpy, this routine will always append + * a null + */ +HB_EXPORT char * hb_strncpyTrim( char * pDest, const char * pSource, ULONG ulLen ) +{ + char *pBuf = pDest; + LONG lSLen = strlen( pSource ); + + HB_TRACE(HB_TR_DEBUG, ("hb_strncpyTrim(%p, %s, %lu)", pDest, pSource, ulLen)); + + pDest[ ulLen ] ='\0'; + + while( lSLen && pSource[ lSLen - 1 ] == ' ') + { + lSLen--; + } + + /* some compilers impliment toupper as a macro, and this has side effects! */ + /* *pDest++ = toupper( *pSource++ ); */ + while( ulLen && lSLen && ( *pDest++ = *pSource++ ) != '\0' ) + { + lSLen--; + ulLen--; + } + + while (ulLen--) + { + *pDest++ = '\0'; + } + + return pBuf; +} + +static double hb_numPow10( int nPrecision ) +{ + static double s_dPow10[16] = { 1.0, /* 0 */ + 10.0, /* 1 */ + 100.0, /* 2 */ + 1000.0, /* 3 */ + 10000.0, /* 4 */ + 100000.0, /* 5 */ + 1000000.0, /* 6 */ + 10000000.0, /* 7 */ + 100000000.0, /* 8 */ + 1000000000.0, /* 9 */ + 10000000000.0, /* 10 */ + 100000000000.0, /* 11 */ + 1000000000000.0, /* 12 */ + 10000000000000.0, /* 13 */ + 100000000000000.0, /* 14 */ + 1000000000000000.0 }; /* 15 */ + if ( nPrecision < 16 ) + { + if ( nPrecision >= 0 ) + { + return s_dPow10[ nPrecision ]; + } + else if ( nPrecision > -16 ) + { + return 1.0 / s_dPow10[ -nPrecision ]; + } + } + + return pow(10.0, (double) nPrecision); +} + +double hb_numRound( double dNum, int iDec ) +{ + static const double doBase = 10.0f; + double doComplete5, doComplete5i, dPow; + + HB_TRACE(HB_TR_DEBUG, ("hb_numRound(%lf, %d)", dNum, iDec)); + + if( dNum == 0.0 ) + return 0.0; + + if ( iDec < 0 ) + { + dPow = hb_numPow10( -iDec ); + doComplete5 = dNum / dPow * doBase; + } + else + { + dPow = hb_numPow10( iDec ); + doComplete5 = dNum * dPow * doBase; + } + + if( dNum < 0.0f ) + doComplete5 -= 5.0f; + else + doComplete5 += 5.0f; + + doComplete5 /= doBase; + +#if defined( HB_DBLFL_PREC_FACTOR ) && !defined( HB_C52_STRICT ) + /* similar operation is done by Cl5.3 + it's a hack to force rounding FL values UP */ + doComplete5 *= HB_DBLFL_PREC_FACTOR; +#endif + + modf( doComplete5, &doComplete5i ); + + if ( iDec < 0 ) + return doComplete5i * dPow; + else + return doComplete5i / dPow; +} + +double hb_numInt( double dNum ) +{ + double dInt; + +#if defined( HB_DBLFL_PREC_FACTOR ) && !defined( HB_C52_STRICT ) + /* Similar hack as in round to make this functions compatible */ + dNum *= HB_DBLFL_PREC_FACTOR; +#endif + modf( dNum, &dInt ); + + return dInt; +} + +static BOOL hb_str2number( BOOL fPCode, const char* szNum, ULONG ulLen, HB_LONG * lVal, double * dVal, int * piDec, int * piWidth ) +{ + BOOL fDbl = FALSE, fDec = FALSE, fNeg = FALSE, fHex = FALSE; + ULONG ulPos = 0; + int c, iWidth = 0, iDec = 0, iDecR = 0; + + HB_TRACE(HB_TR_DEBUG, ("hb_str2number(%d, %p, %ul %p, %p, %p, %p)", (int) fPCode, szNum, ulLen, lVal, dVal, piDec, piWidth )); + + while ( ulPos < ulLen && isspace( szNum[ulPos] ) ) + ulPos++; + + if ( szNum[ulPos] == '-' ) + { + fNeg = TRUE; + ulPos++; + } + else + { + fNeg = FALSE; + if ( szNum[ulPos] == '+' ) + ulPos++; + } + + *lVal = 0; + + /* Hex Number */ + if( fPCode && ulPos + 1 < ulLen && szNum[ulPos] == '0' && + ( szNum[ulPos+1] == 'X' || szNum[ulPos+1] == 'x' ) ) + { + ulPos += 2; + iWidth = HB_DEFAULT_WIDTH; + fHex = TRUE; + for ( ; ulPos < ulLen; ulPos++ ) + { + c = szNum[ulPos]; + if ( c >= '0' && c <= '9' ) + c -= '0'; + else if ( c >= 'A' && c <= 'F' ) + c -= 'A' - 10; + else if ( c >= 'a' && c <= 'f' ) + c -= 'a' - 10; + else + break; + *lVal = ( *lVal << 4 ) + c; + } + } + else + { + HB_LONG lLimV; + int iLimC; + + lLimV = HB_LONG_MAX / 10; + iLimC = HB_LONG_MAX % 10; + + iWidth = ulPos; + + for ( ; ulPos < ulLen; ulPos++ ) + { + c = szNum[ulPos]; + if ( c >= '0' && c <= '9' ) + { + if ( fDbl ) + { + *dVal = *dVal * 10.0 + ( c - '0' ); + } + else if ( *lVal < lLimV || ( *lVal <= lLimV && ( c - '0' ) <= iLimC ) ) + { + *lVal = *lVal * 10 + ( c - '0' ); + } + else + { + *dVal = (double) *lVal * 10.0 + ( c - '0' ); + fDbl = TRUE; + } + if ( fDec ) + iDec++; + else + iWidth++; + } + else if ( c == '.' && !fDec ) + { + fDec = TRUE; + } + else + { + while ( !fDec && ulPos < ulLen ) + { + if ( szNum[ulPos++] == '.' ) + fDec = TRUE; + else + iWidth++; + } + if ( fDec ) + iDecR = ulLen - ulPos; + break; + } + } + } + + if ( fNeg ) + { + if ( fDbl ) + *dVal = -*dVal; + else + *lVal = -*lVal; + } + if ( !fDbl && ( +#if defined( PCODE_LONG_LIM ) + ( fPCode && !fHex && !PCODE_LONG_LIM( *lVal ) ) || +#endif + fDec ) ) + { + *dVal = (double) *lVal; + fDbl = TRUE; + } + if ( fDbl && iDec ) + *dVal /= hb_numPow10( iDec ); + + if ( piDec ) + *piDec = iDec + iDecR; + if ( piWidth ) + { + if ( fHex ) + *piWidth = iWidth; + else + { + int iSize = fDbl ? HB_DBL_LENGTH( *dVal ) : HB_LONG_LENGTH( *lVal ); + + if ( fPCode ) + { + if ( iWidth < 10 || fNeg ) + *piWidth = iSize; + else + *piWidth = iWidth + ( iDec == 0 ? 1 : 0 ); + } + else + { + if ( iSize > 10 || iWidth > 10 ) + *piWidth = iSize; + else if ( iDec + iDecR == 0 ) + *piWidth = ( int ) ulLen; + else if ( iWidth == 0 ) + *piWidth = 1; + else if ( fNeg && iWidth == 1 && *dVal != 0 ) + *piWidth = 2; + else + *piWidth = iWidth; + } + } + } + + return fDbl; +} + +BOOL HB_EXPORT hb_compStrToNum( const char* szNum, HB_LONG * plVal, double * pdVal, int * piDec, int * piWidth ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_compStrToNum( %s, %p, %p, %p, %p)", szNum, plVal, pdVal, piDec, piWidth )); + return hb_str2number( TRUE, szNum, strlen( szNum ), plVal, pdVal, piDec, piWidth ); +} + +BOOL HB_EXPORT hb_valStrnToNum( const char* szNum, ULONG ulLen, HB_LONG * plVal, double * pdVal, int * piDec, int * piWidth ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_valStrToNum( %s, %l, %p, %p, %p, %p)", szNum, ulLen, plVal, pdVal, piDec, piWidth )); + return hb_str2number( FALSE, szNum, ulLen, plVal, pdVal, piDec, piWidth ); +} + +BOOL HB_EXPORT hb_strToNum( const char* szNum, HB_LONG * plVal, double * pdVal ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_strToNum(%s, %p, %p)", szNum, plVal, pdVal )); + return hb_str2number( FALSE, szNum, strlen( szNum ), plVal, pdVal, NULL, NULL ); +} + +BOOL HB_EXPORT hb_strnToNum( const char* szNum, ULONG ulLen, HB_LONG * plVal, double * pdVal ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_strToNum(%s, %l, %p, %p)", szNum, ulLen, plVal, pdVal )); + return hb_str2number( FALSE, szNum, ulLen, plVal, pdVal, NULL, NULL ); +} + /* returns the numeric value of a character string representation of a number */ double hb_strVal( const char * szText, ULONG ulLen ) { - long double ldValue = 0.0; - ULONG ulPos; - ULONG ulDecPos = 0; - BOOL bNegative = FALSE; - long double ldScale = 0.1L; + HB_LONG lVal; + double dVal; - HB_TRACE(HB_TR_DEBUG, ("hb_strVal(%s, %d)", szText, ulLen)); + HB_TRACE(HB_TR_DEBUG, ("hb_strVal(%s)", szText)); - /* Look for sign */ - - for( ulPos = 0; ulPos < ulLen; ulPos++ ) - { - if( szText[ ulPos ] == '-' ) - { - bNegative = TRUE; - ulPos++; - break; - } - else if( szText[ ulPos ] == '+' ) - { - ulPos++; - break; - } - else if( ! HB_ISSPACE( szText[ ulPos ] ) ) - break; - } - - /* Build the number */ - - for(; ulPos < ulLen; ulPos++ ) - { - if( szText[ ulPos ] == '.' && ulDecPos == 0 ) - { - ulDecPos++; - ldScale = 0.1L; - } - else if( szText[ ulPos ] >= '0' && szText[ ulPos ] <= '9' ) - { - if( ulDecPos ) - { - ldValue += ldScale * ( long double )( szText[ ulPos ] - '0' ); - ldScale *= 0.1L; - } - else - ldValue = ( ldValue * 10.0L ) + ( long double )( szText[ ulPos ] - '0' ); - } - else - break; - } - - return ( double )( bNegative && ldValue != 0.0L ? -ldValue : ldValue ); + if ( ! hb_str2number( FALSE, szText, ulLen, &lVal, &dVal, NULL, NULL ) ) + dVal = ( double ) lVal; + return dVal; } diff --git a/harbour/source/common/hbver.c b/harbour/source/common/hbver.c index d2e567e71d..cef9348335 100644 --- a/harbour/source/common/hbver.c +++ b/harbour/source/common/hbver.c @@ -271,8 +271,7 @@ char * hb_verPlatform( void ) struct utsname un; uname( &un ); - - sprintf( pszPlatform, "%s %s", un.sysname, un.release ); + sprintf( pszPlatform, "%s %s %s", un.sysname, un.release, un.machine ); } #elif defined(HB_OS_MAC) @@ -436,199 +435,3 @@ char * hb_verHarbour( void ) return pszVersion; } - -void hb_verBuildInfo( void ) -{ - hb_conOutErr( "Harbour Build Info", 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - hb_conOutErr( "---------------------------", 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - - { - char * pszVersion = hb_verHarbour(); - hb_conOutErr( "Version: ", 0 ); - hb_conOutErr( pszVersion, 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - hb_xfree( pszVersion ); - } - - { - char * pszVersion = hb_verCompiler(); - hb_conOutErr( "Compiler: ", 0 ); - hb_conOutErr( pszVersion, 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - hb_xfree( pszVersion ); - } - - { - char * pszVersion = hb_verPlatform(); - hb_conOutErr( "Platform: ", 0 ); - hb_conOutErr( pszVersion, 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - hb_xfree( pszVersion ); - } - - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "Built on: ", 0 ); - hb_conOutErr( __DATE__, 0 ); - hb_conOutErr( " ", 0 ); - hb_conOutErr( __TIME__, 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "Last ChangeLog entry: ", 0 ); - hb_conOutErr( HB_VER_LENTRY, 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "ChangeLog CVS version: ", 0 ); - hb_conOutErr( HB_VER_CHLCVS, 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - - if( strlen( HB_VER_C_USR ) ) - { - hb_conOutErr( "Harbour compiler switches: ", 0 ); - hb_conOutErr( HB_VER_C_USR, 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - } - - if( strlen( HB_VER_L_USR ) ) - { - hb_conOutErr( "C compiler switches: ", 0 ); - hb_conOutErr( HB_VER_L_USR, 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - } - - if( strlen( HB_VER_PRG_USR ) ) - { - hb_conOutErr( "Linker switches: ", 0 ); - hb_conOutErr( HB_VER_PRG_USR, 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - } - - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "Harbour extensions: ", 0 ); -#if defined( HB_EXTENSION ) - hb_conOutErr( "Yes", 0 ); -#else - hb_conOutErr( "No", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "CA-Clipper 5.2e undocumented: ", 0 ); -#if defined( HB_C52_UNDOC ) - hb_conOutErr( "Yes", 0 ); -#else - hb_conOutErr( "No", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "CA-Clipper 5.2e strict compatibility: ", 0 ); -#if defined( HB_C52_STRICT ) - hb_conOutErr( "Yes", 0 ); -#else - hb_conOutErr( "No", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "CA-Clipper 5.3x compatible extensions: ", 0 ); -#if defined( HB_COMPAT_C53 ) - hb_conOutErr( "Yes", 0 ); -#else - hb_conOutErr( "No", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "Alaska Xbase++ compatible extensions: ", 0 ); -#if defined( HB_COMPAT_XPP ) - hb_conOutErr( "Yes", 0 ); -#else - hb_conOutErr( "No", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "CA-Visual Objects compatible extensions: ", 0 ); -#if defined( HB_COMPAT_VO ) - hb_conOutErr( "Yes", 0 ); -#else - hb_conOutErr( "No", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "Multisoft Flagship compatible extensions: ", 0 ); -#if defined( HB_COMPAT_FLAGSHIP ) - hb_conOutErr( "Yes", 0 ); -#else - hb_conOutErr( "No", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "Microsoft FoxPro compatible extensions: ", 0 ); -#if defined( HB_COMPAT_FOXPRO ) - hb_conOutErr( "Yes", 0 ); -#else - hb_conOutErr( "No", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "dBase compatible extensions: ", 0 ); -#if defined( HB_COMPAT_DBASE ) - hb_conOutErr( "Yes", 0 ); -#else - hb_conOutErr( "No", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "Object file generation support: ", 0 ); -#if defined( HARBOUR_OBJ_GENERATION ) - hb_conOutErr( "Yes", 0 ); -#else - hb_conOutErr( "No", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "ANSI C usage: ", 0 ); -#if defined( HARBOUR_STRICT_ANSI_C ) - hb_conOutErr( "Strict", 0 ); -#else - hb_conOutErr( "Non strict", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "C++ mode: ", 0 ); -#if defined(__cplusplus) - hb_conOutErr( "On", 0 ); -#else - hb_conOutErr( "Off", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "Compiler YACC debug mode: ", 0 ); -#if defined( HARBOUR_YYDEBUG ) - hb_conOutErr( "On", 0 ); -#else - hb_conOutErr( "Off", 0 ); -#endif - hb_conOutErr( hb_conNewLine(), 0 ); - - hb_conOutErr( "Memory tracing and statistics: ", 0 ); - hb_conOutErr( hb_xquery( HB_MEM_USEDMAX ) != 0 ? "On" : "Off", 0 ); -/* -#if defined( HB_FM_STATISTICS ) - hb_conOutErr( "On", 0 ); -#else - hb_conOutErr( "Off", 0 ); -#endif -*/ - hb_conOutErr( hb_conNewLine(), 0 ); - - { - char buffer[ 64 ]; - sprintf( buffer, "Maximum symbol name length: %i", HB_SYMBOL_NAME_LEN ); - hb_conOutErr( buffer, 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); - } - - hb_conOutErr( "---------------------------", 0 ); - hb_conOutErr( hb_conNewLine(), 0 ); -} diff --git a/harbour/source/common/hbverdsp.c b/harbour/source/common/hbverdsp.c new file mode 100644 index 0000000000..0107212bce --- /dev/null +++ b/harbour/source/common/hbverdsp.c @@ -0,0 +1,257 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Display build information - code moved from hb_ver.c + * + * Copyright 1999 {list of individual authors and e-mail addresses} + * www - http://www.harbour-project.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. + * + */ + +/* + * + * See doc/license.txt for licensing terms. + * + */ + +#include "hbapi.h" +#include "hbver.h" +#include "hbmemory.ch" + +void hb_verBuildInfo( void ) +{ + hb_conOutErr( "Harbour Build Info", 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + hb_conOutErr( "---------------------------", 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + + { + char * pszVersion = hb_verHarbour(); + hb_conOutErr( "Version: ", 0 ); + hb_conOutErr( pszVersion, 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + hb_xfree( pszVersion ); + } + + { + char * pszVersion = hb_verCompiler(); + hb_conOutErr( "Compiler: ", 0 ); + hb_conOutErr( pszVersion, 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + hb_xfree( pszVersion ); + } + + { + char * pszVersion = hb_verPlatform(); + hb_conOutErr( "Platform: ", 0 ); + hb_conOutErr( pszVersion, 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + hb_xfree( pszVersion ); + } + + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "Built on: ", 0 ); + hb_conOutErr( __DATE__, 0 ); + hb_conOutErr( " ", 0 ); + hb_conOutErr( __TIME__, 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "Last ChangeLog entry: ", 0 ); + hb_conOutErr( HB_VER_LENTRY, 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "ChangeLog CVS version: ", 0 ); + hb_conOutErr( HB_VER_CHLCVS, 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + + if( strlen( HB_VER_C_USR ) ) + { + hb_conOutErr( "Harbour compiler switches: ", 0 ); + hb_conOutErr( HB_VER_C_USR, 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + } + + if( strlen( HB_VER_L_USR ) ) + { + hb_conOutErr( "C compiler switches: ", 0 ); + hb_conOutErr( HB_VER_L_USR, 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + } + + if( strlen( HB_VER_PRG_USR ) ) + { + hb_conOutErr( "Linker switches: ", 0 ); + hb_conOutErr( HB_VER_PRG_USR, 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + } + + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "Harbour extensions: ", 0 ); +#if defined( HB_EXTENSION ) + hb_conOutErr( "Yes", 0 ); +#else + hb_conOutErr( "No", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "CA-Clipper 5.2e undocumented: ", 0 ); +#if defined( HB_C52_UNDOC ) + hb_conOutErr( "Yes", 0 ); +#else + hb_conOutErr( "No", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "CA-Clipper 5.2e strict compatibility: ", 0 ); +#if defined( HB_C52_STRICT ) + hb_conOutErr( "Yes", 0 ); +#else + hb_conOutErr( "No", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "CA-Clipper 5.3x compatible extensions: ", 0 ); +#if defined( HB_COMPAT_C53 ) + hb_conOutErr( "Yes", 0 ); +#else + hb_conOutErr( "No", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "Alaska Xbase++ compatible extensions: ", 0 ); +#if defined( HB_COMPAT_XPP ) + hb_conOutErr( "Yes", 0 ); +#else + hb_conOutErr( "No", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "CA-Visual Objects compatible extensions: ", 0 ); +#if defined( HB_COMPAT_VO ) + hb_conOutErr( "Yes", 0 ); +#else + hb_conOutErr( "No", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "Multisoft Flagship compatible extensions: ", 0 ); +#if defined( HB_COMPAT_FLAGSHIP ) + hb_conOutErr( "Yes", 0 ); +#else + hb_conOutErr( "No", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "Microsoft FoxPro compatible extensions: ", 0 ); +#if defined( HB_COMPAT_FOXPRO ) + hb_conOutErr( "Yes", 0 ); +#else + hb_conOutErr( "No", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "dBase compatible extensions: ", 0 ); +#if defined( HB_COMPAT_DBASE ) + hb_conOutErr( "Yes", 0 ); +#else + hb_conOutErr( "No", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "Object file generation support: ", 0 ); +#if defined( HARBOUR_OBJ_GENERATION ) + hb_conOutErr( "Yes", 0 ); +#else + hb_conOutErr( "No", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "ANSI C usage: ", 0 ); +#if defined( HARBOUR_STRICT_ANSI_C ) + hb_conOutErr( "Strict", 0 ); +#else + hb_conOutErr( "Non strict", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "C++ mode: ", 0 ); +#if defined(__cplusplus) + hb_conOutErr( "On", 0 ); +#else + hb_conOutErr( "Off", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "Compiler YACC debug mode: ", 0 ); +#if defined( HARBOUR_YYDEBUG ) + hb_conOutErr( "On", 0 ); +#else + hb_conOutErr( "Off", 0 ); +#endif + hb_conOutErr( hb_conNewLine(), 0 ); + + hb_conOutErr( "Memory tracing and statistics: ", 0 ); + hb_conOutErr( hb_xquery( HB_MEM_USEDMAX ) != 0 ? "On" : "Off", 0 ); +/* +#if defined( HB_FM_STATISTICS ) + hb_conOutErr( "On", 0 ); +#else + hb_conOutErr( "Off", 0 ); +#endif +*/ + hb_conOutErr( hb_conNewLine(), 0 ); + + { + char buffer[ 64 ]; + sprintf( buffer, "Maximum symbol name length: %i", HB_SYMBOL_NAME_LEN ); + hb_conOutErr( buffer, 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); + } + + hb_conOutErr( "---------------------------", 0 ); + hb_conOutErr( hb_conNewLine(), 0 ); +} diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index ba17559792..4ee331f163 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -396,7 +396,7 @@ static HB_GENC_FUNC( hb_p_arraydim ) fprintf( cargo->yyc, "\tHB_P_ARRAYDIM, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -538,7 +538,7 @@ static HB_GENC_FUNC( hb_p_arraygen ) fprintf( cargo->yyc, "\tHB_P_ARRAYGEN, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -585,10 +585,7 @@ static HB_GENC_FUNC( hb_p_jumpnear ) pFunc->pCode[ lPCodePos + 1 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] ); - - if( lOffset > 127 ) - lOffset -= 256; + LONG lOffset = ( signed char ) ( pFunc->pCode[ lPCodePos + 1 ] ); fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); } @@ -603,10 +600,7 @@ static HB_GENC_FUNC( hb_p_jump ) pFunc->pCode[ lPCodePos + 2 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 ); - - if( lOffset > SHRT_MAX ) - lOffset -= 65536; + LONG lOffset = HB_PCODE_MKSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ); fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); } @@ -622,10 +616,7 @@ static HB_GENC_FUNC( hb_p_jumpfar ) pFunc->pCode[ lPCodePos + 3 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536 ); - if( lOffset > 8388607L ) - lOffset -= 16777216; - + LONG lOffset = HB_PCODE_MKINT24( &( pFunc->pCode[ lPCodePos + 1 ] ) ); fprintf( cargo->yyc, "\t/* %li (abs: %08li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); } fprintf( cargo->yyc, "\n" ); @@ -638,11 +629,7 @@ static HB_GENC_FUNC( hb_p_jumpfalsenear ) pFunc->pCode[ lPCodePos + 1 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] ); - - if( lOffset > 127 ) - lOffset -= 256; - + LONG lOffset = ( signed char ) ( pFunc->pCode[ lPCodePos + 1 ] ); fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); } fprintf( cargo->yyc, "\n" ); @@ -656,11 +643,7 @@ static HB_GENC_FUNC( hb_p_jumpfalse ) pFunc->pCode[ lPCodePos + 2 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 ); - - if( lOffset > SHRT_MAX ) - lOffset -= 65536; - + LONG lOffset = HB_PCODE_MKSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ); fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); } fprintf( cargo->yyc, "\n" ); @@ -675,11 +658,8 @@ static HB_GENC_FUNC( hb_p_jumpfalsefar ) pFunc->pCode[ lPCodePos + 3 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536 ); - if( lOffset > 8388607L ) - lOffset -= 16777216; - - fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); + LONG lOffset = HB_PCODE_MKINT24( &( pFunc->pCode[ lPCodePos + 1 ] ) ); + fprintf( cargo->yyc, "\t/* %li (abs: %08li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); } fprintf( cargo->yyc, "\n" ); return 4; @@ -691,10 +671,7 @@ static HB_GENC_FUNC( hb_p_jumptruenear ) pFunc->pCode[ lPCodePos + 1 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] ); - if( lOffset > 127 ) - lOffset -= 256; - + LONG lOffset = ( signed char ) ( pFunc->pCode[ lPCodePos + 1 ] ); fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); } fprintf( cargo->yyc, "\n" ); @@ -708,10 +685,7 @@ static HB_GENC_FUNC( hb_p_jumptrue ) pFunc->pCode[ lPCodePos + 2 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 ); - if( lOffset > SHRT_MAX ) - lOffset -= 65536; - + LONG lOffset = HB_PCODE_MKSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ); fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); } fprintf( cargo->yyc, "\n" ); @@ -726,11 +700,8 @@ static HB_GENC_FUNC( hb_p_jumptruefar ) pFunc->pCode[ lPCodePos + 3 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536 ); - if( lOffset > 8388607L ) - lOffset -= 16777216; - - fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); + LONG lOffset = HB_PCODE_MKINT24( &( pFunc->pCode[ lPCodePos + 1 ] ) ); + fprintf( cargo->yyc, "\t/* %li (abs: %08li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); } fprintf( cargo->yyc, "\n" ); return 4; @@ -764,7 +735,7 @@ static HB_GENC_FUNC( hb_p_line ) pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); if( cargo->bVerbose ) - fprintf( cargo->yyc, "\t/* %i */", pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 ); + fprintf( cargo->yyc, "\t/* %i */", HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -896,7 +867,7 @@ static HB_GENC_FUNC( hb_p_message ) fprintf( cargo->yyc, "\tHB_P_MESSAGE, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -992,7 +963,7 @@ static HB_GENC_FUNC( hb_p_parameter ) pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ], pFunc->pCode[ lPCodePos + 3 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 4; } @@ -1029,7 +1000,7 @@ static HB_GENC_FUNC( hb_p_popaliasedfield ) fprintf( cargo->yyc, "\tHB_P_POPALIASEDFIELD, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1048,7 +1019,7 @@ static HB_GENC_FUNC( hb_p_popaliasedvar ) fprintf( cargo->yyc, "\tHB_P_POPALIASEDVAR, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1058,7 +1029,7 @@ static HB_GENC_FUNC( hb_p_popfield ) fprintf( cargo->yyc, "\tHB_P_POPFIELD, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1070,7 +1041,7 @@ static HB_GENC_FUNC( hb_p_poplocal ) pFunc->pCode[ lPCodePos + 2 ] ); if( cargo->bVerbose ) { - SHORT wVar = * ( ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ] ); + int iVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ); /* Variable with negative order are local variables * referenced in a codeblock -handle it with care */ @@ -1079,13 +1050,13 @@ static HB_GENC_FUNC( hb_p_poplocal ) { /* we are accesing variables within a codeblock */ /* the names of codeblock variable are lost */ - if( wVar < 0 ) - fprintf( cargo->yyc, "\t/* localvar%i */", -wVar ); + if( iVar < 0 ) + fprintf( cargo->yyc, "\t/* localvar%i */", -iVar ); else - fprintf( cargo->yyc, "\t/* codeblockvar%i */", wVar ); + fprintf( cargo->yyc, "\t/* codeblockvar%i */", iVar ); } else - fprintf( cargo->yyc, "\t/* %s */", hb_compLocalVariableFind( pFunc, wVar )->szName ); + fprintf( cargo->yyc, "\t/* %s */", hb_compLocalVariableFind( pFunc, iVar )->szName ); } fprintf( cargo->yyc, "\n" ); return 3; @@ -1097,7 +1068,7 @@ static HB_GENC_FUNC( hb_p_poplocalnear ) pFunc->pCode[ lPCodePos + 1 ] ); if( cargo->bVerbose ) { - char wVar = ( char ) pFunc->pCode[ lPCodePos + 1 ]; + int iVar = ( signed char ) pFunc->pCode[ lPCodePos + 1 ]; /* Variable with negative order are local variables * referenced in a codeblock -handle it with care */ @@ -1106,13 +1077,13 @@ static HB_GENC_FUNC( hb_p_poplocalnear ) { /* we are accesing variables within a codeblock */ /* the names of codeblock variable are lost */ - if( wVar < 0 ) - fprintf( cargo->yyc, "\t/* localvar%i */", -wVar ); + if( iVar < 0 ) + fprintf( cargo->yyc, "\t/* localvar%i */", -iVar ); else - fprintf( cargo->yyc, "\t/* codeblockvar%i */", wVar ); + fprintf( cargo->yyc, "\t/* codeblockvar%i */", iVar ); } else - fprintf( cargo->yyc, "\t/* %s */", hb_compLocalVariableFind( pFunc, wVar )->szName ); + fprintf( cargo->yyc, "\t/* %s */", hb_compLocalVariableFind( pFunc, iVar )->szName ); } fprintf( cargo->yyc, "\n" ); return 2; @@ -1123,7 +1094,7 @@ static HB_GENC_FUNC( hb_p_popmemvar ) fprintf( cargo->yyc, "\tHB_P_POPMEMVAR, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1137,7 +1108,7 @@ static HB_GENC_FUNC( hb_p_popstatic ) { PVAR pVar; PFUNCTION pTmp = hb_comp_functions.pFirst; - USHORT wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + USHORT wVar = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ); while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) pTmp = pTmp->pNext; pVar = hb_compVariableFind( pTmp->pStatics, wVar - pTmp->iStaticsBase ); @@ -1153,7 +1124,7 @@ static HB_GENC_FUNC( hb_p_popvariable ) fprintf( cargo->yyc, "\tHB_P_POPVARIABLE, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1181,7 +1152,7 @@ static HB_GENC_FUNC( hb_p_pushaliasedfield ) fprintf( cargo->yyc, "\tHB_P_PUSHALIASEDFIELD, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1200,7 +1171,7 @@ static HB_GENC_FUNC( hb_p_pushaliasedvar ) fprintf( cargo->yyc, "\tHB_P_PUSHALIASEDVAR, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1217,18 +1188,17 @@ static HB_GENC_FUNC( hb_p_pushblock ) pFunc->pCode[ lPCodePos + 2 ] ); if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", - pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256 ); + HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); fprintf( cargo->yyc, "\n" ); - w = * ( ( USHORT * ) &( pFunc->pCode [ lPCodePos + 3 ] ) ); + w = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 3 ] ) ); fprintf( cargo->yyc, "\t%i, %i,", pFunc->pCode[ lPCodePos + 3 ], pFunc->pCode[ lPCodePos + 4 ] ); if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* number of local parameters (%i) */", w ); fprintf( cargo->yyc, "\n" ); - wVar = * ( ( USHORT * ) &( pFunc->pCode [ lPCodePos + 5 ] ) ); + wVar = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 5 ] ) ); fprintf( cargo->yyc, "\t%i, %i,", pFunc->pCode[ lPCodePos + 5 ], pFunc->pCode[ lPCodePos + 6 ] ); @@ -1239,7 +1209,7 @@ static HB_GENC_FUNC( hb_p_pushblock ) /* create the table of referenced local variables */ while( wVar-- ) { - w = * ( ( USHORT * ) &( pFunc->pCode [ lPCodePos ] ) ); + w = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos ] ) ); fprintf( cargo->yyc, "\t%i, %i,", pFunc->pCode[ lPCodePos ], pFunc->pCode[ lPCodePos + 1 ] ); @@ -1277,13 +1247,18 @@ static HB_GENC_FUNC( hb_p_pushdouble ) fprintf( cargo->yyc, "\tHB_P_PUSHDOUBLE," ); ++lPCodePos; - for( i = 0; i < sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE ); ++i ) + for( i = 0; i < ( int ) ( sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE ) ); ++i ) + { fprintf( cargo->yyc, " %i,", ( ( BYTE * ) pFunc->pCode )[ lPCodePos + i ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %.*f, %d, %d */", + } + if( cargo->bVerbose ) + { + fprintf( cargo->yyc, "\t/* %.*f, %d, %d */", *( ( BYTE * ) &( pFunc->pCode[ lPCodePos + sizeof( double ) ] ) ), - *( ( double * ) &( pFunc->pCode[ lPCodePos ] ) ), + HB_PCODE_MKDOUBLE( &( pFunc->pCode[ lPCodePos ] ) ), *( ( BYTE * ) &( pFunc->pCode[ lPCodePos + sizeof( double ) ] ) ), *( ( BYTE * ) &( pFunc->pCode[ lPCodePos + sizeof( double ) + sizeof( BYTE ) ] ) ) ); + } fprintf( cargo->yyc, "\n" ); return sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE ) + 1; @@ -1294,7 +1269,7 @@ static HB_GENC_FUNC( hb_p_pushfield ) fprintf( cargo->yyc, "\tHB_P_PUSHFIELD, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1304,7 +1279,7 @@ static HB_GENC_FUNC( hb_p_pushbyte ) fprintf( cargo->yyc, "\tHB_P_PUSHBYTE, %i,", pFunc->pCode[ lPCodePos + 1 ] ); if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", - pFunc->pCode[ lPCodePos + 1 ] ); + ( signed char ) pFunc->pCode[ lPCodePos + 1 ] ); fprintf( cargo->yyc, "\n" ); return 2; } @@ -1314,9 +1289,7 @@ static HB_GENC_FUNC( hb_p_pushint ) fprintf( cargo->yyc, "\tHB_P_PUSHINT, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", - pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256 ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", HB_PCODE_MKSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1411,10 +1384,34 @@ static HB_GENC_FUNC( hb_p_pushlong ) pFunc->pCode[ lPCodePos + 2 ], pFunc->pCode[ lPCodePos + 3 ], pFunc->pCode[ lPCodePos + 4 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %li */", *( ( long * ) &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %li */", HB_PCODE_MKLONG( &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); fprintf( cargo->yyc, "\n" ); - return 1 + sizeof( long ); + return 5; +} + +static HB_GENC_FUNC( hb_p_pushlonglong ) +{ + fprintf( cargo->yyc, "\tHB_P_PUSHLONGLONG, %i, %i, %i, %i, %i, %i, %i, %i, ", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + pFunc->pCode[ lPCodePos + 3 ], + pFunc->pCode[ lPCodePos + 4 ], + pFunc->pCode[ lPCodePos + 5 ], + pFunc->pCode[ lPCodePos + 6 ], + pFunc->pCode[ lPCodePos + 7 ], + pFunc->pCode[ lPCodePos + 8 ] ); + if( cargo->bVerbose ) + { +#ifdef HB_LONG_LONG_OFF + fprintf( cargo->yyc, "\t/* %f */", HB_PCODE_MKLONGLONG( &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); +#else + fprintf( cargo->yyc, "\t/* %" PFLL "i */", HB_PCODE_MKLONGLONG( &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); +#endif + } + fprintf( cargo->yyc, "\n" ); + + return 9; } static HB_GENC_FUNC( hb_p_pushmemvar ) @@ -1422,7 +1419,7 @@ static HB_GENC_FUNC( hb_p_pushmemvar ) fprintf( cargo->yyc, "\tHB_P_PUSHMEMVAR, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1432,7 +1429,7 @@ static HB_GENC_FUNC( hb_p_pushmemvarref ) fprintf( cargo->yyc, "\tHB_P_PUSHMEMVARREF, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1464,7 +1461,7 @@ static HB_GENC_FUNC( hb_p_pushstatic ) { PVAR pVar; PFUNCTION pTmp = hb_comp_functions.pFirst; - USHORT wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + USHORT wVar = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ); while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) pTmp = pTmp->pNext; pVar = hb_compVariableFind( pTmp->pStatics, wVar - pTmp->iStaticsBase ); @@ -1484,7 +1481,7 @@ static HB_GENC_FUNC( hb_p_pushstaticref ) PVAR pVar; PFUNCTION pTmp = hb_comp_functions.pFirst; - USHORT wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + USHORT wVar = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ); while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) pTmp = pTmp->pNext; pVar = hb_compVariableFind( pTmp->pStatics, wVar - pTmp->iStaticsBase ); @@ -1498,8 +1495,7 @@ static HB_GENC_FUNC( hb_p_pushstaticref ) static HB_GENC_FUNC( hb_p_pushstr ) { ULONG ulStart = lPCodePos; - USHORT wLen = pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256; + USHORT wLen = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ); fprintf( cargo->yyc, "\tHB_P_PUSHSTR, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], @@ -1576,7 +1572,7 @@ static HB_GENC_FUNC( hb_p_pushsym ) pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); if( cargo->bVerbose ) - fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1596,7 +1592,8 @@ static HB_GENC_FUNC( hb_p_pushvariable ) fprintf( cargo->yyc, "\tHB_P_PUSHVARIABLE, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 )->szName ); + if( cargo->bVerbose ) + fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) )->szName ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -1632,8 +1629,8 @@ static HB_GENC_FUNC( hb_p_seqbegin ) pFunc->pCode[ lPCodePos + 3 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536 ); - fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, lPCodePos + lOffset ); + LONG lOffset = HB_PCODE_MKINT24( &( pFunc->pCode[ lPCodePos + 1 ] ) ); + fprintf( cargo->yyc, "\t/* %li (abs: %08li) */", lOffset, lPCodePos + lOffset ); } fprintf( cargo->yyc, "\n" ); return 4; @@ -1649,8 +1646,8 @@ static HB_GENC_FUNC( hb_p_seqend ) pFunc->pCode[ lPCodePos + 3 ] ); if( cargo->bVerbose ) { - LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536 ); - fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, lPCodePos + lOffset ); + LONG lOffset = HB_PCODE_MKINT24( &( pFunc->pCode[ lPCodePos + 1 ] ) ); + fprintf( cargo->yyc, "\t/* %li (abs: %08li) */", lOffset, lPCodePos + lOffset ); } fprintf( cargo->yyc, "\n" ); return 4; @@ -1684,7 +1681,8 @@ static HB_GENC_FUNC( hb_p_statics ) pFunc->pCode[ lPCodePos + 2 ], pFunc->pCode[ lPCodePos + 3 ], pFunc->pCode[ lPCodePos + 4 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* symbol (_INITSTATICS), %i statics */", pFunc->pCode[ lPCodePos + 3 ] + pFunc->pCode[ lPCodePos + 4 ] * 256 ); + if( cargo->bVerbose ) + fprintf( cargo->yyc, "\t/* symbol (_INITSTATICS), %i statics */", HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 3 ] ) ) ); fprintf( cargo->yyc, "\n" ); return (USHORT) lByteCount; @@ -1786,7 +1784,6 @@ static HB_GENC_FUNC( hb_p_macrolistend ) return 1; } -#define HB_PCODE_MKSHORT( p ) ( *( SHORT * )( p ) ) static HB_GENC_FUNC( hb_p_localnearaddint ) { fprintf( cargo->yyc, "\tHB_P_LOCALNEARADDINT, %i, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], @@ -1939,7 +1936,8 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = { hb_p_dummy, /* end: */ hb_p_localnearaddint, - hb_p_macropushref + hb_p_macropushref, + hb_p_pushlonglong }; static void hb_compGenCReadable( PFUNCTION pFunc, FILE * yyc ) diff --git a/harbour/source/compiler/gencli.c b/harbour/source/compiler/gencli.c index c40363ac96..c697b0534b 100644 --- a/harbour/source/compiler/gencli.c +++ b/harbour/source/compiler/gencli.c @@ -423,7 +423,7 @@ static HB_GENC_FUNC( hb_p_arraydim ) fprintf( cargo->yyc, "\tHB_P_ARRAYDIM, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); - if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 ); + if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); fprintf( cargo->yyc, "\n" ); return 3; } @@ -450,6 +450,8 @@ static HB_GENC_FUNC( hb_p_doshort ) HB_FUNCALLS_PTR pTemp = pFunCalls, pPrev = NULL; char * szFunName; + HB_SYMBOL_UNUSED( pFunc ); + while( pTemp->pNext != NULL ) { pPrev = pTemp; @@ -525,6 +527,10 @@ static HB_GENC_FUNC( hb_p_endblock ) static HB_GENC_FUNC( hb_p_endproc ) { + HB_SYMBOL_UNUSED( pFunc ); + HB_SYMBOL_UNUSED( cargo ); + HB_SYMBOL_UNUSED( lPCodePos ); + // if( (lPCodePos+1) == pFunc->lPCodePos ) // fprintf( cargo->yyc, "\tHB_P_ENDPROC\n" ); // else @@ -605,6 +611,8 @@ static HB_GENC_FUNC( hb_p_functionshort ) HB_FUNCALLS_PTR pTemp = pFunCalls, pPrev = NULL; char * szFunName; + HB_SYMBOL_UNUSED( pFunc ); + while( pTemp->pNext != NULL ) { pPrev = pTemp; @@ -630,13 +638,12 @@ static HB_GENC_FUNC( hb_p_functionshort ) static HB_GENC_FUNC( hb_p_arraygen ) { - int i; + int i, n = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ); fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "call vararg object ObjArrayGen( ..." ); - for( i = 0; i < pFunc->pCode[ lPCodePos + 1 ] + - ( pFunc->pCode[ lPCodePos + 2 ] * 256 ); i++ ) + for( i = 0; i < n; i++ ) fprintf( cargo->yyc, ",object" ); fprintf( cargo->yyc, ")\n" ); @@ -896,6 +903,8 @@ static HB_GENC_FUNC( hb_p_lessequal ) static HB_GENC_FUNC( hb_p_line ) { + HB_SYMBOL_UNUSED( pFunc ); + fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "nop // HB_P_LINE\n" ); @@ -1423,7 +1432,7 @@ static HB_GENC_FUNC( hb_p_pushdouble ) fprintf( cargo->yyc, "\tHB_P_PUSHDOUBLE," ); ++lPCodePos; - for( i = 0; i < sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE ); ++i ) + for( i = 0; i < (int) ( sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE ) ); ++i ) fprintf( cargo->yyc, " %i,", ( ( BYTE * ) pFunc->pCode )[ lPCodePos + i ] ); if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %.*f, %d, %d */", *( ( BYTE * ) &( pFunc->pCode[ lPCodePos + sizeof( double ) ] ) ), @@ -1578,7 +1587,7 @@ static HB_GENC_FUNC( hb_p_pushlong ) // if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %li */", *( ( long * ) &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); // fprintf( cargo->yyc, "\n" ); - return 1 + sizeof( long ); + return 5; } static HB_GENC_FUNC( hb_p_pushmemvar ) @@ -1606,6 +1615,7 @@ static HB_GENC_FUNC( hb_p_pushnil ) HB_FUNCALLS_PTR pTemp = pFunCalls; HB_SYMBOL_UNUSED( pFunc ); + HB_SYMBOL_UNUSED( cargo ); HB_SYMBOL_UNUSED( lPCodePos ); if( pTemp ) @@ -2013,7 +2023,6 @@ static HB_GENC_FUNC( hb_p_macrolistend ) return 1; } -#define HB_PCODE_MKSHORT( p ) ( *( SHORT * )( p ) ) static HB_GENC_FUNC( hb_p_localnearaddint ) { fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index 6f4fb6330d..c0cfae3a64 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -2279,7 +2279,7 @@ ULONG hb_compGenJump( LONG lOffset ) } else if( lOffset >= (-8388608L) && lOffset <= 8388607L ) { - hb_compGenPCode4( HB_P_JUMPFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( (USHORT)( lOffset >> 16 ) & 0xFF ), ( BOOL ) 1 ); + hb_compGenPCode4( HB_P_JUMPFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( ( lOffset >> 16 ) & 0xFF ), ( BOOL ) 1 ); } else { @@ -2311,7 +2311,7 @@ ULONG hb_compGenJumpFalse( LONG lOffset ) } else if( lOffset >= (-8388608L) && lOffset <= 8388607L ) { - hb_compGenPCode4( HB_P_JUMPFALSEFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( (USHORT)( lOffset >> 16 ) & 0xFF ), ( BOOL ) 1 ); + hb_compGenPCode4( HB_P_JUMPFALSEFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( ( lOffset >> 16 ) & 0xFF ), ( BOOL ) 1 ); } else { @@ -2343,7 +2343,7 @@ ULONG hb_compGenJumpTrue( LONG lOffset ) } else if( lOffset >= (-8388608L) && lOffset <= 8388607L ) { - hb_compGenPCode4( HB_P_JUMPTRUEFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( (USHORT)( lOffset >> 16 ) & 0xFF ), ( BOOL ) 1 ); + hb_compGenPCode4( HB_P_JUMPTRUEFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( ( lOffset >> 16 ) & 0xFF ), ( BOOL ) 1 ); } else { @@ -3131,8 +3131,7 @@ void hb_compGenPushDouble( double dNumber, BYTE bWidth, BYTE bDec ) BYTE pBuffer[ sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE ) + 1 ]; pBuffer[ 0 ] = HB_P_PUSHDOUBLE; - - memcpy( ( BYTE * ) &( pBuffer[ 1 ] ), ( BYTE * ) &dNumber, sizeof( double ) ); + HB_PUT_LE_DOUBLE( &( pBuffer[ 1 ] ), dNumber ); pBuffer[ 1 + sizeof( double ) ] = bWidth; pBuffer[ 1 + sizeof( double ) + sizeof( BYTE ) ] = bDec; @@ -3156,30 +3155,29 @@ void hb_compGenPushFunCall( char * szFunName ) } /* generates the pcode to push a long number on the virtual machine stack */ -void hb_compGenPushLong( long lNumber ) +void hb_compGenPushLong( HB_LONG lNumber ) { if( lNumber == 0 ) hb_compGenPCode1( HB_P_ZERO ); else if( lNumber == 1 ) hb_compGenPCode1( HB_P_ONE ); - else if( ( ( char * ) &lNumber )[ 2 ] == 0 && ( ( char * ) &lNumber )[ 3 ] == 0 ) + else if( HB_LIM_INT8( lNumber ) ) + hb_compGenPCode2( HB_P_PUSHBYTE, (BYTE) lNumber, TRUE ); + else if( HB_LIM_INT16( lNumber ) ) + hb_compGenPCode3( HB_P_PUSHINT, HB_LOBYTE( lNumber ), HB_HIBYTE( lNumber ), TRUE ); + else if( HB_LIM_INT32( lNumber ) ) { - if( ( ( char * ) &lNumber )[ 1 ] == 0 ) - hb_compGenPCode2( HB_P_PUSHBYTE, ( ( char * ) &lNumber )[ 0 ], ( BOOL ) 1 ); - else - hb_compGenPCode3( HB_P_PUSHINT, ( ( char * ) &lNumber )[ 0 ], ( ( char * ) &lNumber )[ 1 ], ( BOOL ) 1 ); + BYTE pBuffer[ 5 ]; + pBuffer[ 0 ] = HB_P_PUSHLONG; + HB_PUT_LE_UINT32( pBuffer + 1, lNumber ); + hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), TRUE ); } else { - BYTE pBuffer[5]; - - pBuffer[0] = HB_P_PUSHLONG; - pBuffer[1] = ( ( BYTE * ) &lNumber )[0]; - pBuffer[2] = ( ( BYTE * ) &lNumber )[1]; - pBuffer[3] = ( ( BYTE * ) &lNumber )[2]; - pBuffer[4] = ( ( BYTE * ) &lNumber )[3]; - - hb_compGenPCodeN( pBuffer, 5, 1 ); + BYTE pBuffer[ 9 ]; + pBuffer[ 0 ] = HB_P_PUSHLONGLONG; + HB_PUT_LE_UINT64( pBuffer + 1, lNumber ); + hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), TRUE ); } } diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index 5ad33c3459..b5da4e8389 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -99,9 +99,8 @@ char *hb_lex_codeblock = NULL; %} SpaceTab [ \t]+ -Number ([0-9]+)|([0-9]*\.[0-9]+) +Number ([0-9]+)|([0-9]*\.[0-9]+)|(0x[0-9A-Fa-f]+) InvalidNumber [0-9]+\. -HexNumber 0x[0-9A-F]+ Identifier (([a-zA-Z])|([_a-zA-Z][_a-zA-Z0-9]+)) MacroVar \&{Identifier}[\.]? @@ -1660,36 +1659,6 @@ Separator {SpaceTab} {Number} { return yy_ConvertNumber( yytext ); } -{HexNumber} { - long lNumber = 0; - - sscanf( yytext, "%lxI", &lNumber ); - - if( ( double ) SHRT_MIN <= lNumber && - lNumber <= ( double ) SHRT_MAX ) - { - yylval.valInteger.iNumber = lNumber; - yylval.valInteger.szValue = yytext; - return NUM_INTEGER; - } - else if( ( double ) LONG_MIN <= lNumber && - lNumber <= ( double ) LONG_MAX ) - { - yylval.valLong.lNumber = lNumber; - yylval.valLong.szValue = yytext; - return NUM_LONG; - } - else - { - /* NOTE: This will never happen */ - yylval.valDouble.dNumber = lNumber; - yylval.valDouble.bWidth = HB_DEFAULT_WIDTH; - yylval.valDouble.bDec = 0; - yylval.valDouble.szValue = yytext; - return NUM_DOUBLE; - } - } - {TrueValue} { hb_comp_iState =RSEPARATOR; return TRUEVALUE; } {FalseValue} { hb_comp_iState =RSEPARATOR; return FALSEVALUE; } @@ -1749,42 +1718,28 @@ int yy_lex_input( char *buffer, int iBufferSize ) static int yy_ConvertNumber( char * szBuffer ) { - char * ptr; + HB_LONG lNumber; + double dNumber; + int iDec, iWidth; - yylval.valDouble.dNumber = hb_strVal( szBuffer, strlen( szBuffer ) ); /* atof( szBuffer ); */ - ptr = strchr( szBuffer, '.' ); - if( ptr ) + if( hb_compStrToNum( szBuffer, &lNumber, &dNumber, &iDec, &iWidth ) ) { - yylval.valDouble.bDec = strlen( ptr + 1 ); - yylval.valDouble.bWidth = strlen( szBuffer ) - yylval.valDouble.bDec; - if( yylval.valDouble.bDec ) - yylval.valDouble.bWidth--; + yylval.valDouble.dNumber = dNumber; + yylval.valDouble.bDec = iDec; + yylval.valDouble.bWidth = iWidth; yylval.valDouble.szValue = szBuffer; return NUM_DOUBLE; } + else if( SHRT_MIN <= lNumber && lNumber <= SHRT_MAX ) + { + yylval.valInteger.iNumber = ( int ) lNumber; + yylval.valInteger.szValue = szBuffer; + return NUM_INTEGER; + } else { - if( ( double )SHRT_MIN <= yylval.valDouble.dNumber && - yylval.valDouble.dNumber <= ( double )SHRT_MAX ) - { - yylval.valInteger.iNumber = ( int ) yylval.valDouble.dNumber; - yylval.valInteger.szValue = szBuffer; - return NUM_INTEGER; - } - else if( ( double )LONG_MIN <= yylval.valDouble.dNumber && - yylval.valDouble.dNumber <= ( double )LONG_MAX ) - { - yylval.valLong.lNumber = ( long ) yylval.valDouble.dNumber; - yylval.valLong.szValue = szBuffer; - return NUM_LONG; - } - else - { - yylval.valDouble.bWidth = strlen( szBuffer ) + 1; - yylval.valDouble.bDec = 0; - yylval.valDouble.szValue = szBuffer; - return NUM_DOUBLE; - } + yylval.valLong.lNumber = lNumber; + yylval.valLong.szValue = szBuffer; + return NUM_LONG; } } - diff --git a/harbour/source/compiler/harbour.slx b/harbour/source/compiler/harbour.slx index d9f73373e9..335e0775eb 100644 --- a/harbour/source/compiler/harbour.slx +++ b/harbour/source/compiler/harbour.slx @@ -70,7 +70,8 @@ static unsigned char iIdentifier = 0; static char *sIdOnHold, *s_sLastBlock = NULL; char * hb_comp_SLX_LastBlock( BOOL bReset ); -long hb_comp_SLX_Hex2L( char* sHex ); + +static int hb_comp_SLX_Str2Num( char* szNum, HB_LONG * lVal, double * dVal, int * iDec, int * iWidth ); static int hb_comp_SLX_ElementToken( char* szToken, unsigned int iTokenLen ); static int hb_comp_SLX_InterceptAction( int iRet, char *sToken ); static int hb_comp_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, BOOL *ptr_bIgnoreWords, int iLastToken, char *sToken, char *s_szBuffer ); @@ -668,77 +669,38 @@ static int hb_comp_SLX_ElementToken( char* szToken, unsigned int iTokenLen ) { /* ConverNumber */ + HB_LONG lNumber; + double dNumber; + int iDec, iWidth; + yylval.string = (char*) hb_xgrab( TOKEN_SIZE ); yylval.string[0] = 0; + iRet = hb_comp_SLX_Str2Num( yytext, &lNumber, &dNumber, &iDec, &iWidth ); - /* Hex Number */ - if( yytext[0] == '0' && yytext[1] == 'X' ) + if( !isdigit( yytext[0] ) && !( yytext[0] == '.' && isdigit( yytext[1] ) ) ) { - long lNumber = hb_comp_SLX_Hex2L( yytext + 2 ); - - if( ( double ) SHRT_MIN <= lNumber && lNumber <= ( double ) SHRT_MAX ) - { - yylval.valInteger.iNumber = lNumber; - yylval.valInteger.szValue = yytext; - iRet = NUM_INTEGER; - } - else if( ( double ) LONG_MIN <= lNumber && lNumber <= ( double ) LONG_MAX ) - { - yylval.valLong.lNumber = lNumber; - yylval.valLong.szValue = yytext; - iRet = NUM_LONG; - } - else - { - /* NOTE: This will never happen */ - yylval.valDouble.dNumber = lNumber; - yylval.valDouble.bWidth = HB_DEFAULT_WIDTH; - yylval.valDouble.bDec = 0; - yylval.valDouble.szValue = yytext; - iRet = NUM_DOUBLE; - } + hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_SYNTAX, yytext, NULL ); + return yytext[0]; + } + else if ( iRet == NUM_DOUBLE ) + { + yylval.valDouble.dNumber = dNumber; + yylval.valDouble.bDec = iDec; + yylval.valDouble.bWidth = iWidth; + yylval.valDouble.szValue = yytext; + } + else if( HB_LIM_INT16( lNumber ) ) + { + yylval.valInteger.iNumber = ( int ) lNumber; + yylval.valInteger.szValue = yytext; + iRet = NUM_INTEGER; } else { - yylval.valDouble.dNumber = atof( yytext ); - tmpPtr = strchr( yytext, '.' ); - - if( tmpPtr ) - { - yylval.valDouble.bDec = strlen( tmpPtr + 1 ); - yylval.valDouble.bWidth = yyleng - yylval.valDouble.bDec; - if( yylval.valDouble.bDec ) - { - yylval.valDouble.bWidth--; - } - yylval.valDouble.szValue = yytext; - iRet = NUM_DOUBLE; - } - else - { - if( ( double )SHRT_MIN <= yylval.valDouble.dNumber && yylval.valDouble.dNumber <= ( double )SHRT_MAX ) - { - yylval.valInteger.iNumber = ( int ) yylval.valDouble.dNumber; - yylval.valInteger.szValue = yytext; - iRet = NUM_INTEGER; - } - else if( ( double )LONG_MIN <= yylval.valDouble.dNumber && yylval.valDouble.dNumber <= ( double )LONG_MAX ) - { - yylval.valLong.lNumber = ( long ) yylval.valDouble.dNumber; - yylval.valLong.szValue = yytext; - iRet = NUM_LONG; - } - else - { - yylval.valDouble.bWidth = yyleng + 1; - yylval.valDouble.bDec = 0; - yylval.valDouble.szValue = yytext; - iRet = NUM_DOUBLE; - } - } + yylval.valLong.lNumber = lNumber; + yylval.valLong.szValue = yytext; } - iRet += DONT_REDUCE; } @@ -746,40 +708,12 @@ static int hb_comp_SLX_ElementToken( char* szToken, unsigned int iTokenLen ) return iRet; } -long hb_comp_SLX_Hex2L( char* sHex ) +static int hb_comp_SLX_Str2Num( char* szNum, HB_LONG * plVal, double * pdVal, int * piDec, int * piWidth ) { - int i, iExp = 0, iLen = strlen( sHex ) - 1; - long lVal, lSum = 0; - char cChar; - - while( iLen >= 0 ) - { - cChar = sHex[ iLen-- ]; - - if( cChar > 64 && cChar < 91 ) - { - lVal = cChar - 55; - } - else - { - lVal = cChar - 48; - } - - if( lVal ) - { - i = 0; - while( i++ < iExp ) - { - lVal *= 16; - } - - lSum += lVal; - } - - iExp++; - } - - return lSum; + BOOL fDbl; + + fDbl = hb_compStrToNum( szNum, plVal, pdVal, piDec, piWidth ); + return fDbl ? NUM_DOUBLE : NUM_LONG; } static int hb_comp_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, BOOL *ptr_bIgnoreWords, int iLastToken, char *sToken, char *s_szBuffer ) diff --git a/harbour/source/compiler/harbour.sly b/harbour/source/compiler/harbour.sly index d187387c4e..cb410123f2 100644 --- a/harbour/source/compiler/harbour.sly +++ b/harbour/source/compiler/harbour.sly @@ -130,7 +130,7 @@ static HB_RTVAR_PTR hb_comp_rtvars = NULL; static BOOL bTrancuateBaseArray = FALSE; static HB_EXPR_PTR pGetArgList = NULL, pBaseArrayName = NULL, pGetVarArray; -static s_bBlock = FALSE, s_bBlockMacro = FALSE, s_bBlockDeclared = FALSE, s_bSetGet; +static BOOL s_bBlock = FALSE, s_bBlockMacro = FALSE, s_bBlockDeclared = FALSE, s_bSetGet; static HB_EXPR_PTR pBlockSimple; extern int hb_compLocalGetPos( char * szVarName ); /* returns the order + 1 of a local variable */ diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 5cc51a879d..24cbd4fbde 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -137,9 +137,9 @@ static void hb_compDebugStart( void ) { }; %union /* special structure used by lex and yacc to share info */ { - char * string; /* to hold a string returned by lex */ - int iNumber; /* to hold a temporary integer number */ - long lNumber; /* to hold a temporary long number */ + char * string; /* to hold a string returned by lex */ + int iNumber; /* to hold a temporary integer number */ + HB_LONG lNumber; /* to hold a temporary long number */ struct { int iNumber; /* to hold a number returned by lex */ @@ -147,8 +147,8 @@ static void hb_compDebugStart( void ) { }; } valInteger; struct { - long lNumber; /* to hold a long number returned by lex */ - char * szValue; + HB_LONG lNumber; /* to hold a long number returned by lex */ + char * szValue; } valLong; struct { diff --git a/harbour/source/compiler/hbfix.c b/harbour/source/compiler/hbfix.c index 1415d26657..2247f31c8a 100644 --- a/harbour/source/compiler/hbfix.c +++ b/harbour/source/compiler/hbfix.c @@ -68,8 +68,7 @@ typedef HB_FIX_FUNC_ * HB_FIX_FUNC_PTR; static HB_FIX_FUNC( hb_p_pushstr ) { HB_SYMBOL_UNUSED( cargo ); - return 3 + pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256; + return 3 + HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ); } static HB_FIX_FUNC( hb_p_pushstrshort ) @@ -90,21 +89,23 @@ static HB_FIX_FUNC( hb_p_endblock ) static HB_FIX_FUNC( hb_p_pushblock ) { USHORT wVar; - USHORT * pLocal; ULONG ulStart = lPCodePos; ++cargo->iNestedCodeblock; - wVar = * ( ( USHORT * ) &( pFunc->pCode [ lPCodePos + 5 ] ) ); + wVar = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 5 ] ) ); /* opcode + codeblock size + number of parameters + number of local variables */ lPCodePos += 7; /* fix local variable's reference */ while( wVar-- ) { + BYTE * pLocal = &( pFunc->pCode[ lPCodePos ] ); + USHORT wLocal = HB_PCODE_MKUSHORT( pLocal ); - pLocal = ( USHORT * ) &( pFunc->pCode [ lPCodePos ] ); - *pLocal += pFunc->wParamCount; + wLocal += pFunc->wParamCount; + pLocal[ 0 ] = HB_LOBYTE( wLocal ); + pLocal[ 1 ] = HB_HIBYTE( wLocal ); lPCodePos +=2; } return (USHORT) (lPCodePos - ulStart); @@ -150,9 +151,12 @@ static HB_FIX_FUNC( hb_p_poplocal ) { /* only local variables used outside of a codeblock need fixing */ - SHORT * pVar = ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ]; + BYTE * pVar = &( pFunc->pCode[ lPCodePos + 1 ] ); + SHORT iVar = HB_PCODE_MKSHORT( pVar ); - *pVar += pFunc->wParamCount; + iVar += pFunc->wParamCount; + pVar[ 0 ] = HB_LOBYTE( iVar ); + pVar[ 1 ] = HB_HIBYTE( iVar ); } return (USHORT) 3; @@ -164,9 +168,12 @@ static HB_FIX_FUNC( hb_p_pushlocal ) { /* only local variables used outside of a codeblock need fixing */ - SHORT * pVar = ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ]; + BYTE * pVar = &( pFunc->pCode[ lPCodePos + 1 ] ); + SHORT iVar = HB_PCODE_MKSHORT( pVar ); - *pVar += pFunc->wParamCount; + iVar += pFunc->wParamCount; + pVar[ 0 ] = HB_LOBYTE( iVar ); + pVar[ 1 ] = HB_HIBYTE( iVar ); } return (USHORT) 3; @@ -178,9 +185,12 @@ static HB_FIX_FUNC( hb_p_pushlocalref ) { /* only local variables used outside of a codeblock need fixing */ - SHORT * pVar = ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ]; + BYTE * pVar = &( pFunc->pCode[ lPCodePos + 1 ] ); + SHORT iVar = HB_PCODE_MKSHORT( pVar ); - *pVar += pFunc->wParamCount; + iVar += pFunc->wParamCount; + pVar[ 0 ] = HB_LOBYTE( iVar ); + pVar[ 1 ] = HB_HIBYTE( iVar ); } return (USHORT) 3; @@ -192,10 +202,13 @@ static HB_FIX_FUNC( hb_p_poplocalnear ) { /* only local variables used outside of a codeblock need fixing */ - SHORT * pVar = ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ]; + BYTE * pVar = &( pFunc->pCode[ lPCodePos + 1 ] ); + SHORT iVar = HB_PCODE_MKSHORT( pVar ); - *pVar += pFunc->wParamCount; - if( *pVar >= -128 && *pVar <= 127 ) + iVar += pFunc->wParamCount; + pVar[ 0 ] = HB_LOBYTE( iVar ); + pVar[ 1 ] = HB_HIBYTE( iVar ); + if( iVar >= -128 && iVar <= 127 ) { pFunc->pCode[ lPCodePos + 2 ] = HB_P_NOOP; hb_compNOOPadd( pFunc, lPCodePos + 2 ); @@ -217,10 +230,13 @@ static HB_FIX_FUNC( hb_p_pushlocalnear ) { /* only local variables used outside of a codeblock need fixing */ - SHORT * pVar = ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ]; + BYTE * pVar = &( pFunc->pCode[ lPCodePos + 1 ] ); + SHORT iVar = HB_PCODE_MKSHORT( pVar ); - *pVar += pFunc->wParamCount; - if( *pVar >= -128 && *pVar <= 127 ) + iVar += pFunc->wParamCount; + pVar[ 0 ] = HB_LOBYTE( iVar ); + pVar[ 1 ] = HB_HIBYTE( iVar ); + if( iVar >= -128 && iVar <= 127 ) { pFunc->pCode[ lPCodePos + 2 ] = HB_P_NOOP; hb_compNOOPadd( pFunc, lPCodePos + 2 ); @@ -407,9 +423,10 @@ static HB_FIX_FUNC_PTR s_fixlocals_table[] = NULL, /* HB_P_ONE, */ NULL, /* HB_P_MACROLIST, */ NULL, /* HB_P_MACROLISTEND, */ - NULL, /* HB_P_MPUSHSTR */ + NULL, /* HB_P_MPUSHSTR, */ hb_p_localnearaddint, /* HB_P_LOCALNEARADDINT, */ - NULL /* HB_P_MACROPUSHREF */ + NULL, /* HB_P_MACROPUSHREF, */ + NULL /* HB_P_PUSHLONGLONG */ }; void hb_compFixFuncPCode( PFUNCTION pFunc ) diff --git a/harbour/source/compiler/hbpcode.c b/harbour/source/compiler/hbpcode.c index b71dec900e..87d3fcf845 100644 --- a/harbour/source/compiler/hbpcode.c +++ b/harbour/source/compiler/hbpcode.c @@ -141,7 +141,7 @@ static BYTE s_pcode_len[] = { 3, /* HB_P_PUSHLOCAL, */ 2, /* HB_P_PUSHLOCALNEAR, */ 3, /* HB_P_PUSHLOCALREF, */ - 1 + sizeof( long ), /* HB_P_PUSHLONG, */ + 5, /* HB_P_PUSHLONG, */ 3, /* HB_P_PUSHMEMVAR, */ 3, /* HB_P_PUSHMEMVARREF, */ 1, /* HB_P_PUSHNIL, */ @@ -171,7 +171,8 @@ static BYTE s_pcode_len[] = { 1, /* HB_P_MACROLISTEND, */ 0, /* HB_P_MPUSHSTR */ 4, /* HB_P_LOCALNEARADDINT, */ - 1 /* HB_P_MACROPUSHREF */ + 1, /* HB_P_MACROPUSHREF, */ + 9 /* HB_P_PUSHLONGLONG */ }; static PVAR hb_compPrivateFind( char * szPrivateName ) @@ -322,6 +323,7 @@ void hb_compStrongType( int iSize ) if( ( pFunc->pStack[ pFunc->iStackIndex ] == '-' + VT_OFFSET_VARIANT ) || pFunc->pStack[ pFunc->iStackIndex ] >= ( 'A' + VT_OFFSET_VARIANT ) ) { cSubType1 = ( pFunc->pStack[ pFunc->iStackIndex ] -= VT_OFFSET_VARIANT ); + cType1 = 'X'; } else { @@ -375,7 +377,7 @@ void hb_compStrongType( int iSize ) case HB_P_DO : case HB_P_FUNCTION : - wVar = pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256; + wVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ); /* DON't put break; Has to fall through */ case HB_P_DOSHORT : case HB_P_FUNCTIONSHORT : @@ -626,7 +628,7 @@ void hb_compStrongType( int iSize ) ;/* The Object is not declared. */ else if( cSubType1 == 'S' ) { - pSym = hb_compSymbolGetPos( pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256 ); + pSym = hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ) ); if( pSym && pSym->szName && pFunc->iStackClasses && pFunc->pStackClasses[ pFunc->iStackClasses - 1 ] ) { @@ -667,7 +669,7 @@ void hb_compStrongType( int iSize ) /* Also handled by HB_P_MESSAGE. */ case HB_P_SEND : - wVar = * ( ( SHORT * ) &( pFunc->pCode )[ ulPos + 1 ] ); + wVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ); /* Fall Through - don't add break !!! */ @@ -1732,6 +1734,7 @@ void hb_compStrongType( int iSize ) /* Numerics */ case HB_P_PUSHDOUBLE : + case HB_P_PUSHLONGLONG : case HB_P_PUSHLONG : case HB_P_PUSHINT : case HB_P_PUSHBYTE : @@ -1757,13 +1760,13 @@ void hb_compStrongType( int iSize ) else { if( pFunc->pCode[ ulPos ] == HB_P_PUSHSYMNEAR ) - { + { pSym = hb_compSymbolGetPos( pFunc->pCode[ ulPos + 1 ] ); - } + } else - { - pSym = hb_compSymbolGetPos( pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256 ); - } + { + pSym = hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ) ); + } /*printf( "\nSymbol: %s\n", pSym->szName );*/ @@ -1843,7 +1846,7 @@ void hb_compStrongType( int iSize ) } else { - wVar = * ( ( SHORT * ) &( pFunc->pCode )[ ulPos + 1 ] ); + wVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ); } /* we are accesing variables within a codeblock */ @@ -1929,7 +1932,7 @@ void hb_compStrongType( int iSize ) case HB_P_PUSHSTATICREF : case HB_P_PUSHSTATIC : pTmp = hb_comp_functions.pFirst; - wVar = pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256; + wVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ); while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) { @@ -2009,7 +2012,7 @@ void hb_compStrongType( int iSize ) case HB_P_PUSHALIASEDFIELD : case HB_P_PUSHFIELD : if( ! pSym ) - pSym = hb_compSymbolGetPos( pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256 ); + pSym = hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ) ); if( pSym && pSym->szName && pFunc->pFields ) { @@ -2023,7 +2026,7 @@ void hb_compStrongType( int iSize ) case HB_P_PUSHMEMVARREF : case HB_P_PUSHMEMVAR : if( ! pSym ) - pSym = hb_compSymbolGetPos( pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256 ); + pSym = hb_compSymbolGetPos( HB_PCODE_MKUSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ) ); if( pSym ) { @@ -2130,7 +2133,7 @@ void hb_compStrongType( int iSize ) /* Arrays. */ case HB_P_ARRAYDIM : - wVar = pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256; + wVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ); if( pFunc->iStackIndex < wVar ) /* TODO Error Message after finalizing all possible pcodes. */ @@ -2146,7 +2149,7 @@ void hb_compStrongType( int iSize ) break; case HB_P_ARRAYGEN : - wVar = pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256; + wVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ); /* TODO Error Message after finalizing all possible pcodes. */ if( pFunc->iStackIndex < wVar ) @@ -2340,7 +2343,7 @@ void hb_compStrongType( int iSize ) case HB_P_POPFIELD : if( pFunc->pCode[ ulPos ] == HB_P_POPFIELD || pFunc->pCode[ ulPos ] == HB_P_POPALIASEDFIELD ) { - wVar = pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256; + wVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ); pSym = hb_compSymbolGetPos( wVar ); } @@ -2370,7 +2373,7 @@ void hb_compStrongType( int iSize ) pFunc->iStackIndex--; if( pFunc->pCode[ ulPos ] == HB_P_POPMEMVAR ) - wVar = pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256; + wVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ); if( ! pSym ) pSym = hb_compSymbolGetPos( wVar ); @@ -2682,7 +2685,7 @@ void hb_compStrongType( int iSize ) if( pFunc->pCode[ ulPos ] == HB_P_POPLOCAL ) { - wVar = * ( ( SHORT * ) &( pFunc->pCode )[ ulPos + 1 ] ); + wVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ); } else { @@ -2872,7 +2875,7 @@ void hb_compStrongType( int iSize ) pFunc->iStackIndex--; pTmp = hb_comp_functions.pFirst; - wVar = pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256; + wVar = HB_PCODE_MKSHORT( &( pFunc->pCode[ ulPos + 1 ] ) ); while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) pTmp = pTmp->pNext; diff --git a/harbour/source/compiler/hbusage.c b/harbour/source/compiler/hbusage.c index 589a4c9594..32e05f5bf2 100644 --- a/harbour/source/compiler/hbusage.c +++ b/harbour/source/compiler/hbusage.c @@ -104,7 +104,7 @@ void hb_compPrintUsage( char * szSelf ) printf( "\nSyntax: %s [options]" "\n", szSelf ); - for( iLine = 0; iLine < ( sizeof( szOptions ) / sizeof( char * ) ); iLine++ ) + for( iLine = 0; iLine < ( int ) ( sizeof( szOptions ) / sizeof( char * ) ); iLine++ ) printf( szOptions[ iLine ], OS_OPT_DELIMITER_LIST[ 0 ] ); } @@ -130,7 +130,7 @@ void hb_compPrintModes( void ) printf( "\nCompatibility flags (lowercase/uppercase significant): -k[options]\n" ); - for( iLine = 0; iLine < ( sizeof( szOptions ) / sizeof( char * ) ); iLine++ ) + for( iLine = 0; iLine < ( int ) ( sizeof( szOptions ) / sizeof( char * ) ); iLine++ ) printf( szOptions[ iLine ] ); } diff --git a/harbour/source/compiler/simplex.c b/harbour/source/compiler/simplex.c index b38b6c73cd..683efd6911 100644 --- a/harbour/source/compiler/simplex.c +++ b/harbour/source/compiler/simplex.c @@ -60,9 +60,9 @@ #endif /* Language Definitions Readability. */ -#define SELF_CONTAINED_WORDS_ARE LEX_WORD static aSelfs[] = -#define LANGUAGE_KEY_WORDS_ARE LEX_WORD static aKeys[] = -#define LANGUAGE_WORDS_ARE LEX_WORD static aWords[] = +#define SELF_CONTAINED_WORDS_ARE static LEX_WORD aSelfs[] = +#define LANGUAGE_KEY_WORDS_ARE static LEX_WORD aKeys[] = +#define LANGUAGE_WORDS_ARE static LEX_WORD aWords[] = #define LANGUAGE_RULES_ARE static int aiRules[][ MAX_MATCH + 2 ] = #define ACCEPT_TOKEN_AND_DROP_DELIMITER_IF_ONE_OF_THESE(x) static char *szOmmit = x #define ACCEPT_TOKEN_AND_RETURN_DELIMITERS static LEX_DELIMITER aDelimiters[] = diff --git a/harbour/source/macro/macro.l b/harbour/source/macro/macro.l index b74adddd92..d8ed6579b8 100644 --- a/harbour/source/macro/macro.l +++ b/harbour/source/macro/macro.l @@ -114,9 +114,8 @@ NOTE: -C controls the speed/size ratio of generated scanner %} SpaceTab [ \t]+ -Number ([0-9]+)|([0-9]*\.[0-9]+) +Number ([0-9]+)|([0-9]*\.[0-9]+)|(0x[0-9A-Fa-f]+) InvalidNumber [0-9]+\. -HexNumber 0x[0-9A-F]+ Identifier (([a-zA-Z])|([_a-zA-Z][_a-zA-Z0-9]+)) MacroVar \&{Identifier}[\.]? @@ -247,62 +246,28 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ %} {Number} { - char * ptr; + HB_LONG lNumber; + double dNumber; + int iDec, iWidth; pMacro->FlexState = LOOKUP; - yylval_ptr->valDouble.dNumber = atof( yytext ); - ptr = strchr( yytext, '.' ); - if( ptr ) + + if( hb_compStrToNum( yytext, &lNumber, &dNumber, &iDec, &iWidth ) ) { - yylval_ptr->valDouble.bDec = strlen( ptr + 1 ); - yylval_ptr->valDouble.bWidth = strlen( yytext ) - yylval_ptr->valDouble.bDec; - if( yylval_ptr->valDouble.bDec ) - yylval_ptr->valDouble.bWidth--; - yylval_ptr->valDouble.szValue = yytext ; + yylval_ptr->valDouble.dNumber = dNumber; + yylval_ptr->valDouble.bDec = iDec; + yylval_ptr->valDouble.bWidth = iWidth; + yylval_ptr->valDouble.szValue = yytext; return NUM_DOUBLE; } else { - if( ( double )LONG_MIN <= yylval_ptr->valDouble.dNumber && - yylval_ptr->valDouble.dNumber <= ( double )LONG_MAX ) - { - yylval_ptr->valLong.lNumber = ( long ) yylval_ptr->valDouble.dNumber; - yylval_ptr->valLong.szValue = yytext; - return NUM_LONG; - } - else - { - yylval_ptr->valDouble.bWidth = strlen( yytext ) + 1; - yylval_ptr->valDouble.bDec = 0; - yylval_ptr->valDouble.szValue = yytext; - return NUM_DOUBLE; - } + yylval_ptr->valLong.lNumber = lNumber; + yylval_ptr->valLong.szValue = yytext; + return NUM_LONG; } } - -{HexNumber} { - long lNumber = 0; - pMacro->FlexState = LOOKUP; - - sscanf( yytext, "%lxI", &lNumber ); - - if( ( double )LONG_MIN <= lNumber && lNumber <= ( double )LONG_MAX ) - { - yylval_ptr->valLong.lNumber = lNumber; - yylval_ptr->valLong.szValue = yytext; - return NUM_LONG; - } - else - { - yylval_ptr->valDouble.dNumber = lNumber; - yylval_ptr->valDouble.bWidth = HB_DEFAULT_WIDTH; - yylval_ptr->valDouble.bDec = 0; - yylval_ptr->valDouble.szValue = yytext; - return NUM_DOUBLE; - } -} - {MacroVar} { HB_TRACE(HB_TR_DEBUG, ("{MacroVar}(%s)", yytext)); if( yytext[ yyleng-1 ] == '.' ) diff --git a/harbour/source/macro/macro.slx b/harbour/source/macro/macro.slx index 94c7cb9a68..3090170136 100644 --- a/harbour/source/macro/macro.slx +++ b/harbour/source/macro/macro.slx @@ -87,7 +87,7 @@ static YYSTYPE *pYYLVAL; static int hb_macro_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, char *sToken ); static int hb_macro_SLX_ElementToken( char* szToken, unsigned int iTokenLen ); -long hb_macro_SLX_Hex2L( char* sHex ); +static int hb_comp_SLX_Str2Num( char* szNum, HB_LONG * lVal, double * dVal, int * iDec, int * iWidth ); void * yy_bytes_buffer( char * pBuffer, int iBufSize ); @@ -311,58 +311,25 @@ static int hb_macro_SLX_ElementToken( char* szToken, unsigned int iTokenLen ) } else { + /* ConverNumber */ - if( yytext[0] == '0' && yytext[1] == 'X' ) + HB_LONG lNumber; + double dNumber; + int iDec, iWidth; + + iRet = hb_comp_SLX_Str2Num( yytext, &lNumber, &dNumber, &iDec, &iWidth ); + + if ( iRet == NUM_DOUBLE ) { - long lNumber = hb_macro_SLX_Hex2L( yytext + 2 ); - - if( ( double ) LONG_MIN <= lNumber && lNumber <= ( double ) LONG_MAX ) - { - pYYLVAL->valLong.lNumber = lNumber; - pYYLVAL->valLong.szValue = yytext; - iRet = NUM_LONG; - } - else - { - pYYLVAL->valDouble.dNumber = lNumber; - pYYLVAL->valDouble.bWidth = HB_DEFAULT_WIDTH; - pYYLVAL->valDouble.bDec = 0; - pYYLVAL->valDouble.szValue = yytext; - iRet = NUM_DOUBLE; - } + pYYLVAL->valDouble.dNumber = dNumber; + pYYLVAL->valDouble.bDec = iDec; + pYYLVAL->valDouble.bWidth = iWidth; + pYYLVAL->valDouble.szValue = yytext; } else { - pYYLVAL->valDouble.dNumber = atof( yytext ); - tmpPtr = strchr( yytext, '.' ); - - if( tmpPtr ) - { - pYYLVAL->valDouble.bDec = strlen( tmpPtr + 1 ); - pYYLVAL->valDouble.bWidth = yyleng - pYYLVAL->valDouble.bDec; - if( pYYLVAL->valDouble.bDec ) - { - pYYLVAL->valDouble.bWidth--; - } - pYYLVAL->valDouble.szValue = yytext; - iRet = NUM_DOUBLE; - } - else - { - if( ( double )LONG_MIN <= pYYLVAL->valDouble.dNumber && pYYLVAL->valDouble.dNumber <= ( double )LONG_MAX ) - { - pYYLVAL->valLong.lNumber = ( long ) pYYLVAL->valDouble.dNumber; - pYYLVAL->valLong.szValue = yytext; - iRet = NUM_LONG; - } - else - { - pYYLVAL->valDouble.bWidth = yyleng + 1; - pYYLVAL->valDouble.bDec = 0; - pYYLVAL->valDouble.szValue = yytext; - iRet = NUM_DOUBLE; - } - } + pYYLVAL->valLong.lNumber = lNumber; + pYYLVAL->valLong.szValue = yytext; } } @@ -370,40 +337,12 @@ static int hb_macro_SLX_ElementToken( char* szToken, unsigned int iTokenLen ) return iRet + DONT_REDUCE; } -long hb_macro_SLX_Hex2L( char* sHex ) +static int hb_comp_SLX_Str2Num( char* szNum, HB_LONG * plVal, double * pdVal, int * piDec, int * piWidth ) { - int i, iExp = 0, iLen = strlen( sHex ) - 1; - long lVal, lSum = 0; - char cChar; - - while( iLen >= 0 ) - { - cChar = sHex[ iLen-- ]; - - if( cChar > 64 && cChar < 91 ) - { - lVal = cChar - 55; - } - else - { - lVal = cChar - 48; - } - - if( lVal) - { - i = 0; - while( i++ < iExp ) - { - lVal *= 16; - } - - lSum += lVal; - } - - iExp++; - } - - return lSum; + BOOL fDbl; + + fDbl = hb_compStrToNum( szNum, plVal, pdVal, piDec, piWidth ); + return fDbl ? NUM_DOUBLE : NUM_LONG; } int hb_macro_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, char *sToken ) diff --git a/harbour/source/macro/macro.y b/harbour/source/macro/macro.y index daa570fefd..467960fd2b 100644 --- a/harbour/source/macro/macro.y +++ b/harbour/source/macro/macro.y @@ -124,9 +124,9 @@ extern void yyerror( char * ); /* parsing error management function */ %union /* special structure used by lex and yacc to share info */ { - char * string; /* to hold a string returned by lex */ - int iNumber; /* to hold a temporary integer number */ - long lNumber; /* to hold a temporary long number */ + char * string; /* to hold a string returned by lex */ + int iNumber; /* to hold a temporary integer number */ + HB_LONG lNumber; /* to hold a temporary long number */ struct { int iNumber; /* to hold a number returned by lex */ @@ -134,15 +134,15 @@ extern void yyerror( char * ); /* parsing error management function */ } valInteger; struct { - long lNumber; /* to hold a long number returned by lex */ - char * szValue; + HB_LONG lNumber; /* to hold a long number returned by lex */ + char * szValue; } valLong; struct { - double dNumber; /* to hold a double number returned by lex */ + double dNumber; /* to hold a double number returned by lex */ /* NOTE: Intentionally using "unsigned char" instead of "BYTE" */ unsigned char bWidth; /* to hold the width of the value */ - unsigned char bDec; /* to hold the number of decimal points in the value */ + unsigned char bDec; /* to hold the number of decimal points in the value */ char * szValue; } valDouble; HB_EXPR_PTR asExpr; @@ -156,6 +156,12 @@ extern void yyerror( char * ); /* parsing error management function */ int yylex( YYSTYPE *, HB_MACRO_PTR ); %} +%{ +#ifdef __WATCOMC__ +/* disable warnings for unreachable code */ +#pragma warning 13 9 +#endif +%} %token IDENTIFIER NIL NUM_DOUBLE INASSIGN NUM_LONG %token IIF IF LITERAL TRUEVALUE FALSEVALUE @@ -791,6 +797,12 @@ IfInline : IIF '(' Expression ',' EmptyExpression ',' %% +#ifdef __WATCOMC__ +/* enable warnings for unreachable code */ +#pragma warning 13 1 +#endif + + /* ** ------------------------------------------------------------------------ ** */ diff --git a/harbour/source/pp/ppcore.c b/harbour/source/pp/ppcore.c index caee6cb08b..2f5447b034 100644 --- a/harbour/source/pp/ppcore.c +++ b/harbour/source/pp/ppcore.c @@ -392,6 +392,46 @@ void hb_pp_Init( void ) hb_pp_nCondCompile = 0; + { + char sOS[64]; + char sVer[64]; + char *pSrc, *pDst; + char * szPlatform = hb_verPlatform(); + int n; + + strcpy( sOS, "__PLATFORM__" ); + + pSrc = szPlatform; + n = strlen( sOS ); + pDst = sOS; + + while ( *pSrc && *pSrc != ' ' && n < ( int ) sizeof( sOS ) - 1 ) + { + if ( *pSrc == '_' || ( *pSrc >= 'A' && *pSrc <= 'Z' ) + || ( *pSrc >= 'a' && *pSrc <= 'z' ) + || ( *pSrc >= '0' && *pSrc <= '9' ) ) + { + pDst[n++] = *pSrc; + } + pSrc++; + } + pDst[ n ] = 0; + + n = 0; + pDst = sVer; + pDst[n++] = '"'; + if ( *pSrc == ' ' ) + { + while ( *(++pSrc) && n < ( int ) sizeof( sVer ) - 2 ) + pDst[n++] = *pSrc; + } + pDst[n++] = '"'; + pDst[ n ] = 0; + + hb_xfree( szPlatform ); + hb_pp_AddDefine( sOS, sVer ); + } + { char szResult[ 6 ]; USHORT usHarbour = ( 256 * HB_VER_MAJOR ) + HB_VER_MINOR; @@ -422,6 +462,22 @@ void hb_pp_Init( void ) hb_pp_AddDefine( "__TIME__", szResult ); } +#if defined( HB_ARCH_16BIT ) + hb_pp_AddDefine( "__ARCH16BIT__", NULL ); +#elif defined( HB_ARCH_32BIT ) + hb_pp_AddDefine( "__ARCH32BIT__", NULL ); +#elif defined( HB_ARCH_64BIT ) + hb_pp_AddDefine( "__ARCH64BIT__", NULL ); +#endif + +#if defined( HB_LITTLE_ENDIAN ) + hb_pp_AddDefine( "__LITTLE_ENDIAN__", NULL ); +#elif defined( HB_BIG_ENDIAN ) + hb_pp_AddDefine( "__BIG_ENDIAN__", NULL ); +#elif defined( HB_PDP_ENDIAN ) + hb_pp_AddDefine( "__PDP_ENDIAN__", NULL ); +#endif + #ifdef HARBOUR_START_PROCEDURE hb_pp_AddDefine( "__HB_MAIN__", HARBOUR_START_PROCEDURE ); #endif @@ -493,10 +549,10 @@ int hb_pp_ParseDirective( char * sLine ) hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_TOO_MANY_INCLUDES, sLine, NULL ); else { - #if defined(__CYGWIN__) || defined(__IBMCPP__) - hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, "" ); + #if defined(__CYGWIN__) || defined(__IBMCPP__) || defined(__LCC__) + hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, "" ); #else - hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, sys_errlist[ errno ] ); + hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, strerror( errno ) ); #endif } } @@ -2917,7 +2973,7 @@ static BOOL ScanMacro( char * expreal, int lenitem, int * pNewLen ) static int ReplacePattern( char patttype, char * expreal, int lenreal, char * ptro, int lenres ) { - int rmlen = lenreal, ifou, lenitem, i; + int rmlen = lenreal, ifou, lenitem, i = 0; char sQuotes[ 4 ] = "\"\","; HB_TRACE(HB_TR_DEBUG, ("ReplacePattern(%c, %s, %d, %s, %p)", patttype, expreal, lenreal, ptro, lenres)); @@ -4197,7 +4253,7 @@ static BOOL OpenInclude( char * szFileName, HB_PATHNAMES * pSearch, PHB_FNAME pM PHB_FNAME pFileName; PFILE pFile; - HB_TRACE(HB_TR_DEBUG, ("OpenInclude(%s, %p, %p, %p, %d)", szFileName, pSearch, pMainFileName, fptr, (int) bStandardOnly)); + HB_TRACE(HB_TR_DEBUG, ("OpenInclude(%s, %p, %p, %d, %s)", szFileName, pSearch, pMainFileName, (int) bStandardOnly, szInclude)); errno = 0; if( bStandardOnly ) diff --git a/harbour/source/rdd/dbcmd.c b/harbour/source/rdd/dbcmd.c index 8180eddacf..e1b6823020 100644 --- a/harbour/source/rdd/dbcmd.c +++ b/harbour/source/rdd/dbcmd.c @@ -4103,4 +4103,4 @@ ERRCODE hb_rddGetTempAlias( char * szAliasTmp ) { return SUCCESS; } -} \ No newline at end of file +} diff --git a/harbour/source/rdd/dbf1.c b/harbour/source/rdd/dbf1.c index 66b496f9f8..e0f9a55f39 100644 --- a/harbour/source/rdd/dbf1.c +++ b/harbour/source/rdd/dbf1.c @@ -50,6 +50,7 @@ * */ +#include "hbsetup.h" #include "hbapi.h" #include "hbinit.h" #include "hbvm.h" @@ -64,8 +65,14 @@ #include "hbdbsort.h" #include "error.ch" #include -#include "hbapicdp.h" -extern PHB_CODEPAGE hb_cdp_page; + +#ifndef HB_CDP_SUPPORT_OFF +# include "hbapicdp.h" +#endif + +#if defined( __XCC__ ) || defined( __MINGW32__ ) + #include +#endif #define __PRG_SOURCE__ __FILE__ @@ -81,7 +88,7 @@ HB_INIT_SYMBOLS_BEGIN( dbf1__InitSymbols ) { "DBF_GETFUNCTABLE", HB_FS_PUBLIC, {HB_FUNCNAME( DBF_GETFUNCTABLE )}, NULL } HB_INIT_SYMBOLS_END( dbf1__InitSymbols ) -#if defined(HB_STATIC_STARTUP) +#if defined(HB_PRAGMA_STARTUP) #pragma startup dbf1__InitSymbols #elif defined(_MSC_VER) #if _MSC_VER >= 1010 @@ -92,8 +99,6 @@ HB_INIT_SYMBOLS_END( dbf1__InitSymbols ) #endif static HB_$INITSYM hb_vm_auto_dbf1__InitSymbols = dbf1__InitSymbols; #pragma data_seg() -#elif ! defined(__GNUC__) - #pragma startup dbf1__InitSymbols #endif static RDDFUNCS dbfSuper; @@ -194,10 +199,50 @@ static RDDFUNCS dbfTable = { ( DBENTRYP_BP ) hb_dbfBof, ( DBENTRYP_SVP ) hb_dbfWhoCares }; +static BYTE s_dbfVersion = 0x03; /* Stores the current default DBF type for DBCREATE() */ + /* * Common functions. */ +static void hb_dbfSetBlankRecord( DBFAREAP pArea ) +{ + BYTE *pPtr = pArea->pRecord, bFill = ' ', bNext; + ULONG ulSize = 1; /* 1 byte ' ' for DELETE flag */ + USHORT uiCount; + LPFIELD pField; + + for( uiCount = 0, pField = pArea->lpFields; uiCount < pArea->uiFieldCount; uiCount++, pField++ ) + { + USHORT uiLen = pField->uiLen; + + if ( ( pField->uiType == HB_IT_MEMO && uiLen == 4 ) || + ( pField->uiType == HB_IT_DATE && uiLen == 3 ) || + pField->uiType == HB_IT_INTEGER || + pField->uiType == HB_IT_DOUBLE ) + { + bNext = '\0'; + } + else + { + bNext = ' '; + } + + if ( bNext == bFill ) + { + ulSize += uiLen; + } + else + { + memset( pPtr, bFill, ulSize ); + pPtr += ulSize; + ulSize = uiLen; + bFill = bNext; + } + } + memset( pPtr, bFill, ulSize ); +} + /* * Return the total number of records. */ @@ -281,6 +326,7 @@ static BOOL hb_dbfWriteRecord( DBFAREAP pArea ) hb_itemRelease( pError ); return FALSE; } + pArea->fDataFlush = TRUE; return TRUE; } @@ -373,7 +419,7 @@ static ERRCODE hb_dbfLockRecord( DBFAREAP pArea, ULONG ulRecNo, BOOL * pResult, if( pArea->ulNumLocksPos > 0 ) { ULONG ul; - for( ul=0; ul< pArea->ulNumLocksPos; ul++ ) + for( ul = 0; ul < pArea->ulNumLocksPos; ul++ ) if( pArea->pLocksPos[ ul ] == ulRecNo ) { * pResult = TRUE; @@ -478,14 +524,14 @@ static BOOL hb_dbfIsLocked( DBFAREAP pArea, ULONG ulRecNo ) static void hb_dbfGetLockArray( DBFAREAP pArea, PHB_ITEM pItem ) { ULONG ulCount; - PHB_ITEM pRecNo; - pRecNo = hb_itemNew( NULL ); HB_TRACE(HB_TR_DEBUG, ("hb_dbfGetLockArray(%p, %p)", pArea, pItem)); + hb_arrayNew( pItem, pArea->ulNumLocksPos ); for( ulCount = 0; ulCount < pArea->ulNumLocksPos; ulCount++ ) - hb_arrayAdd( pItem, hb_itemPutNL( pRecNo, pArea->pLocksPos[ ulCount ] ) ); - hb_itemRelease( pRecNo ); + { + hb_itemPutNL( hb_arrayGetItemPtr( pItem, ulCount + 1 ), pArea->pLocksPos[ ulCount ] ); + } } /* @@ -493,7 +539,7 @@ static void hb_dbfGetLockArray( DBFAREAP pArea, PHB_ITEM pItem ) * This function is common for different DBF based RDD implementation * so I don't make it static */ -ERRCODE hb_dbfGetEGcode( ERRCODE errCode ) +ERRCODE HB_EXPORT hb_dbfGetEGcode( ERRCODE errCode ) { ERRCODE errEGcode; @@ -551,21 +597,32 @@ ERRCODE hb_dbfGetEGcode( ERRCODE errCode ) * This function is common for different MEMO implementation * so I left it in DBF. */ -ULONG hb_dbfGetMemoBlock( DBFAREAP pArea, USHORT uiIndex ) +ULONG HB_EXPORT hb_dbfGetMemoBlock( DBFAREAP pArea, USHORT uiIndex ) { - USHORT uiCount; - BYTE bByte; - ULONG ulBlock; + ULONG ulBlock= 0 ; HB_TRACE(HB_TR_DEBUG, ("hb_dbfGetMemoBlock(%p, %hu)", pArea, uiIndex)); - ulBlock = 0; - for( uiCount = 0; uiCount < 10; uiCount++ ) + /* 3/05/2004 Support 0x30 format DBF memo */ + if ( pArea->lpFields[ uiIndex ].uiLen == 4 ) { - bByte = pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] + uiCount ]; - if( bByte >= '0' && bByte <= '9' ) - ulBlock = ulBlock * 10 + ( bByte - '0' ); + ulBlock = HB_GET_LE_UINT32( &pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] ] ); } + else + { + USHORT uiCount; + BYTE bByte; + + for( uiCount = 0; uiCount < 10; uiCount++ ) + { + bByte = pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] + uiCount ]; + if( bByte >= '0' && bByte <= '9' ) + { + ulBlock = ulBlock * 10 + ( bByte - '0' ); + } + } + } + return ulBlock; } @@ -574,21 +631,31 @@ ULONG hb_dbfGetMemoBlock( DBFAREAP pArea, USHORT uiIndex ) * This function is common for different MEMO implementation * so I left it in DBF. */ -void hb_dbfPutMemoBlock( DBFAREAP pArea, USHORT uiIndex, ULONG ulBlock ) +void HB_EXPORT hb_dbfPutMemoBlock( DBFAREAP pArea, USHORT uiIndex, ULONG ulBlock ) { - SHORT iCount; - HB_TRACE(HB_TR_DEBUG, ("hb_dbfPutMemoBlock(%p, %hu, %lu)", pArea, uiIndex, ulBlock)); - for( iCount = 9; iCount >= 0; iCount-- ) + /* 3/05/2004 Support 0x30 format DBF memo */ + if ( pArea->lpFields[ uiIndex ].uiLen == 4 ) { - if( ulBlock > 0 ) + HB_PUT_LE_UINT32( &pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] ], ulBlock ); + } + else + { + SHORT iCount; + + for( iCount = 9; iCount >= 0; iCount-- ) { - pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] + iCount ] = ( BYTE )( ulBlock % 10 ) + '0'; - ulBlock /= 10; + if( ulBlock > 0 ) + { + pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] + iCount ] = ( BYTE )( ulBlock % 10 ) + '0'; + ulBlock /= 10; + } + else + { + pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] + iCount ] = ' '; + } } - else - pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] + iCount ] = ' '; } } @@ -633,7 +700,9 @@ BOOL HB_EXPORT hb_dbfLockIdxFile( FHANDLE hFile, BYTE bScheme, USHORT usMode, UL BOOL fRet = FALSE, fWait; if ( !hb_dbfLockIdxGetData( bScheme, &ulPos, &ulPool ) ) - return fRet; + { + return fRet ; + } do { @@ -650,6 +719,10 @@ BOOL HB_EXPORT hb_dbfLockIdxFile( FHANDLE hFile, BYTE bScheme, USHORT usMode, UL ulSize = ulPool + 1; } } + else + { + *pPoolPos = 0; + } break; case FL_UNLOCK: @@ -658,6 +731,10 @@ BOOL HB_EXPORT hb_dbfLockIdxFile( FHANDLE hFile, BYTE bScheme, USHORT usMode, UL if ( ! *pPoolPos ) ulSize = ulPool + 1; } + else + { + *pPoolPos = 0; + } break; default: @@ -668,6 +745,7 @@ BOOL HB_EXPORT hb_dbfLockIdxFile( FHANDLE hFile, BYTE bScheme, USHORT usMode, UL /* TODO: call special error handler (LOCKHANDLER) hiere if fWait */ } while ( fWait ); + return fRet; } @@ -767,8 +845,8 @@ static ERRCODE hb_dbfGoTo( DBFAREAP pArea, ULONG ulRecNo ) pArea->fBof = pArea->fEof = pArea->fValidBuffer = TRUE; pArea->fPositioned = pArea->fDeleted = FALSE; - /* Clear buffer */ - memset( pArea->pRecord, ' ', pArea->uiRecordLen ); + /* Clear record buffer */ + hb_dbfSetBlankRecord( pArea ) ; } pArea->fFound = FALSE; @@ -832,7 +910,8 @@ static ERRCODE hb_dbfSkip( DBFAREAP pArea, LONG lToSkip ) pArea->fTop = pArea->fBottom = FALSE; - if( lToSkip == 0 || hb_set.HB_SET_DELETED || pArea->dbfi.itmCobExpr ) + if( lToSkip == 0 || hb_set.HB_SET_DELETED || + pArea->dbfi.itmCobExpr || pArea->dbfi.fFilter ) return SUPER_SKIP( ( AREAP ) pArea, lToSkip ); uiError = SELF_SKIPRAW( ( AREAP ) pArea, lToSkip ); @@ -876,8 +955,8 @@ static ERRCODE hb_dbfSkipRaw( DBFAREAP pArea, LONG lToSkip ) return SUCCESS; } else - /* return SELF_GOTO( ( AREAP ) pArea, pArea->ulRecNo + lToSkip ); */ - return SELF_GOTO( ( AREAP ) pArea, ((LONG)pArea->ulRecNo + lToSkip) <= 0 ? 0 : (pArea->ulRecNo + lToSkip)); + return SELF_GOTO( ( AREAP ) pArea, pArea->ulRecNo + lToSkip ); + /* return SELF_GOTO( ( AREAP ) pArea, ((LONG)pArea->ulRecNo + lToSkip) <= 0 ? 0 : (pArea->ulRecNo + lToSkip)); */ } /* @@ -949,8 +1028,9 @@ static ERRCODE hb_dbfAppend( DBFAREAP pArea, BOOL bUnLockAll ) } } - /* Clear buffer and update pArea */ - memset( pArea->pRecord, ' ', pArea->uiRecordLen ); + /* Clear record buffer and update pArea */ + hb_dbfSetBlankRecord( pArea ) ; + pArea->fValidBuffer = pArea->fUpdateHeader = pArea->fRecordChanged = pArea->fAppend = pArea->fPositioned = TRUE; pArea->ulRecCount ++; @@ -1022,23 +1102,23 @@ static ERRCODE hb_dbfFlush( DBFAREAP pArea ) uiError = SELF_GOCOLD( ( AREAP ) pArea ); if( pArea->fUpdateHeader ) { - /* Update record count */ - if( pArea->fShared ) - pArea->ulRecCount = hb_dbfCalcRecCount( pArea ); - else - { - /* Seek to logical eof and write eof mark */ - hb_fsSeek( pArea->hDataFile, pArea->uiHeaderLen + - pArea->uiRecordLen * pArea->ulRecCount, FS_SET ); - hb_fsWrite( pArea->hDataFile, ( BYTE * ) "\032", 1 ); - hb_fsWrite( pArea->hDataFile, NULL, 0 ); - } SELF_WRITEDBHEADER( ( AREAP ) pArea ); } - hb_fsCommit( pArea->hDataFile ); - if( pArea->fHasMemo && pArea->hMemoFile != FS_ERROR ) - hb_fsCommit( pArea->hMemoFile ); + if ( hb_set.HB_SET_HARDCOMMIT ) + { + if ( pArea->fDataFlush ) + { + hb_fsCommit( pArea->hDataFile ); + pArea->fDataFlush = FALSE; + } + if( pArea->fHasMemo && pArea->hMemoFile != FS_ERROR && pArea->fMemoFlush ) + { + hb_fsCommit( pArea->hMemoFile ); + pArea->fMemoFlush = FALSE; + } + } + return uiError; } @@ -1069,7 +1149,9 @@ static ERRCODE hb_dbfGetValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) case HB_IT_STRING: hb_itemPutCL( pItem, ( char * ) pArea->pRecord + pArea->pFieldOffset[ uiIndex ], pField->uiLen ); +#ifndef HB_CDP_SUPPORT_OFF hb_cdpnTranslate( pItem->item.asString.value, pArea->cdPage, hb_cdp_page, pField->uiLen ); +#endif break; case HB_IT_LOGICAL: @@ -1080,9 +1162,44 @@ static ERRCODE hb_dbfGetValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) break; case HB_IT_DATE: - memcpy( szBuffer, pArea->pRecord + pArea->pFieldOffset[ uiIndex ], 8 ); - szBuffer[ 8 ] = 0; - hb_itemPutDS( pItem, szBuffer ); + if ( pField->uiLen == 3 ) + { + hb_itemPutDL( pItem, HB_GET_LE_UINT24( pArea->pRecord + pArea->pFieldOffset[ uiIndex ] ) ); + } + else + { + memcpy( szBuffer, pArea->pRecord + pArea->pFieldOffset[ uiIndex ], 8 ); + szBuffer[ 8 ] = 0; + hb_itemPutDS( pItem, szBuffer ); + } + break; + + case HB_IT_INTEGER: + switch ( pField->uiLen ) + { + case 2: + hb_itemPutNIntLen( pItem, ( HB_LONG ) HB_GET_LE_UINT16( pArea->pRecord + pArea->pFieldOffset[ uiIndex ] ), 10 ); + break; + case 4: + hb_itemPutNIntLen( pItem, ( HB_LONG ) HB_GET_LE_UINT32( pArea->pRecord + pArea->pFieldOffset[ uiIndex ] ), 10 ); + break; + case 8: +#ifndef HB_LONG_LONG_OFF + hb_itemPutNIntLen( pItem, ( HB_LONG ) HB_GET_LE_UINT64( pArea->pRecord + pArea->pFieldOffset[ uiIndex ] ), 20 ); +#else + hb_itemPutNLen( pItem, HB_GET_LE_UINT64( pArea->pRecord + pArea->pFieldOffset[ uiIndex ] ), 20, 0 ); +#endif + break; + default: + bError = TRUE; + break; + } + break; + + case HB_IT_DOUBLE: + hb_itemPutNDLen( pItem, HB_GET_LE_DOUBLE( pArea->pRecord + pArea->pFieldOffset[ uiIndex ] ), + 20 - ( pField->uiDec > 0 ? ( pField->uiDec + 1 ) : 0 ), + ( int ) pField->uiDec ); break; case HB_IT_LONG: @@ -1096,19 +1213,29 @@ static ERRCODE hb_dbfGetValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) else */ { - memcpy( szBuffer, pArea->pRecord + pArea->pFieldOffset[ uiIndex ], - pField->uiLen ); - szBuffer[ pField->uiLen ] = 0; + HB_LONG lVal; + double dVal; + BOOL fDbl; + + fDbl = hb_strnToNum( (const char *) pArea->pRecord + pArea->pFieldOffset[ uiIndex ], + pField->uiLen, &lVal, &dVal ); + if( pField->uiDec ) - hb_itemPutNDLen( pItem, atof( szBuffer ), + { + hb_itemPutNDLen( pItem, fDbl ? dVal : ( double ) lVal, ( int ) pField->uiLen - ( ( int ) pField->uiDec + 1 ), ( int ) pField->uiDec ); + } + else if( pField->uiLen > 9 ) + { + hb_itemPutNDLen( pItem, fDbl ? dVal : ( double ) lVal, + ( int ) pField->uiLen, 0 ); + } else - if( pField->uiLen > 9 ) - hb_itemPutNDLen( pItem, atof( szBuffer ), - ( int ) pField->uiLen, ( int ) pField->uiDec ); - else - hb_itemPutNLLen( pItem, atol( szBuffer ), ( int ) pField->uiLen ); + { + hb_itemPutNLLen( pItem, ( long ) ( fDbl ? dVal : lVal ), + ( int ) pField->uiLen ); + } } break; @@ -1270,13 +1397,15 @@ static ERRCODE hb_dbfPutValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) { if( pField->uiType == HB_IT_STRING ) { - uiSize = ( USHORT ) hb_itemGetCLen( pItem ); + uiSize = ( USHORT ) pItem->item.asString.length; if( uiSize > pField->uiLen ) uiSize = pField->uiLen; memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], - hb_itemGetCPtr( pItem ), uiSize ); + pItem->item.asString.value, uiSize ); +#ifndef HB_CDP_SUPPORT_OFF if( HB_IS_STRING( pItem ) ) hb_cdpnTranslate( (char *) pArea->pRecord + pArea->pFieldOffset[ uiIndex ], hb_cdp_page, pArea->cdPage, uiSize ); +#endif memset( pArea->pRecord + pArea->pFieldOffset[ uiIndex ] + uiSize, ' ', pField->uiLen - uiSize ); } @@ -1288,8 +1417,16 @@ static ERRCODE hb_dbfPutValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) { if( pField->uiType == HB_IT_DATE ) { - hb_itemGetDS( pItem, szBuffer ); - memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], szBuffer, 8 ); + if ( pField->uiLen == 3 ) + { + HB_PUT_LE_UINT24( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], + hb_itemGetDL( pItem ) ); + } + else + { + hb_itemGetDS( pItem, szBuffer ); + memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], szBuffer, 8 ); + } } else uiError = EDBF_DATATYPE; @@ -1310,8 +1447,65 @@ static ERRCODE hb_dbfPutValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) '*', pField->uiLen ); } } + else if ( pField->uiType == HB_IT_INTEGER ) + { + HB_LONG lVal; + int iSize; + + if ( HB_IS_DOUBLE( pItem ) && + ! HB_DBL_LIM_INT64( pItem->item.asDouble.value ) ) + { + lVal = 0; + iSize = 99; + } + else + { +#ifndef HB_LONG_LONG_OFF + lVal = hb_itemGetNLL( pItem ); + iSize = HB_LIM_INT16( lVal ) ? 2 : + ( HB_LIM_INT32( lVal ) ? 4 : 8 ); +#else + double d = hb_itemGetND( pItem ); + lVal = hb_itemGetNL( pItem ); + iSize = HB_DBL_LIM_INT16( d ) ? 2 : + ( HB_DBL_LIM_INT32( d ) ? 4 : 8 ); +#endif + } + if ( iSize > pField->uiLen ) + { + uiError = EDBF_DATAWIDTH; + } + else + { + switch ( pField->uiLen ) + { + case 2: + HB_PUT_LE_UINT16( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], ( INT16 ) lVal ); + break; + case 4: + HB_PUT_LE_UINT32( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], ( INT32 ) lVal ); + break; + case 8: +#ifndef HB_LONG_LONG_OFF + HB_PUT_LE_UINT64( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], ( INT64 ) lVal ); +#else + HB_PUT_LE_UINT64( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], hb_itemGetND( pItem ) ); +#endif + break; + default: + uiError = EDBF_DATATYPE; + break; + } + } + } + else if( pField->uiType == HB_IT_DOUBLE ) + { + HB_PUT_LE_DOUBLE( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], hb_itemGetND( pItem ) ); + } else + { uiError = EDBF_DATATYPE; + } } else if( HB_IS_LOGICAL( pItem ) ) { @@ -1334,7 +1528,8 @@ static ERRCODE hb_dbfPutValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) hb_errPutFlags( pError, EF_CANDEFAULT ); SELF_ERROR( ( AREAP ) pArea, pError ); hb_itemRelease( pError ); - return FAILURE; + return SUCCESS; + // return FAILURE; } /* Update deleted flag */ @@ -1392,7 +1587,7 @@ static ERRCODE hb_dbfRecNo( DBFAREAP pArea, PHB_ITEM pRecNo ) if( pArea->lpdbPendingRel ) SELF_FORCEREL( ( AREAP ) pArea ); - hb_itemPutNL( pRecNo, pArea->ulRecNo ); + hb_itemPutNLLen( pRecNo, pArea->ulRecNo, 7 ); return SUCCESS; } @@ -1409,6 +1604,7 @@ static ERRCODE hb_dbfSetFieldExtent( DBFAREAP pArea, USHORT uiFieldExtent ) /* Alloc field offsets array */ pArea->pFieldOffset = ( USHORT * ) hb_xgrab( uiFieldExtent * sizeof( USHORT * ) ); memset( pArea->pFieldOffset, 0, uiFieldExtent * sizeof( USHORT * ) ); + return SUCCESS; } @@ -1434,25 +1630,18 @@ static ERRCODE hb_dbfClose( DBFAREAP pArea ) /* Update header */ if( pArea->fUpdateHeader ) { - /* Update record count */ - if( pArea->fShared ) - pArea->ulRecCount = hb_dbfCalcRecCount( pArea ); - - /* hb_dbfWriteDBHeader( pArea ); */ SELF_WRITEDBHEADER( ( AREAP ) pArea ); - - /* Seek to logical eof and write eof mark */ - hb_fsSeek( pArea->hDataFile, pArea->uiHeaderLen + - pArea->uiRecordLen * pArea->ulRecCount, FS_SET ); - hb_fsWrite( pArea->hDataFile, ( BYTE * ) "\032", 1 ); - hb_fsWrite( pArea->hDataFile, NULL, 0 ); } } /* Close the data file */ if( pArea->hDataFile != FS_ERROR ) { - hb_fsCommit( pArea->hDataFile ); + if ( pArea->fDataFlush && hb_set.HB_SET_HARDCOMMIT ) + { + hb_fsCommit( pArea->hDataFile ); + pArea->fDataFlush = FALSE; + } hb_fsClose( pArea->hDataFile ); pArea->hDataFile = FS_ERROR; } @@ -1460,7 +1649,11 @@ static ERRCODE hb_dbfClose( DBFAREAP pArea ) /* Close the memo file */ if( pArea->fHasMemo && pArea->hMemoFile != FS_ERROR ) { - hb_fsCommit( pArea->hMemoFile ); + if ( pArea->fMemoFlush && hb_set.HB_SET_HARDCOMMIT ) + { + hb_fsCommit( pArea->hMemoFile ); + pArea->fMemoFlush = FALSE; + } hb_fsClose( pArea->hMemoFile ); pArea->hMemoFile = FS_ERROR; } @@ -1500,8 +1693,8 @@ static ERRCODE hb_dbfClose( DBFAREAP pArea ) static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo ) { USHORT uiSize, uiCount; - BOOL bHasMemo, bRetry; - DBFFIELD * pBuffer, dbField; + BOOL fHasMemo, bRetry; + DBFFIELD * pBuffer, *pThisField; PHB_FNAME pFileName; PHB_ITEM pFileExt, pError; @@ -1519,9 +1712,10 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo ) pError = hb_errNew(); hb_errPutGenCode( pError, EG_CREATE ); hb_errPutSubCode( pError, EDBF_CREATE_DBF ); + hb_errPutOsCode( pError, hb_fsError() ); hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_CREATE ) ); hb_errPutFileName( pError, ( char * ) pCreateInfo->abName ); - hb_errPutFlags( pError, EF_CANRETRY ); + hb_errPutFlags( pError, EF_CANRETRY | EF_CANDEFAULT ); } bRetry = ( SELF_ERROR( ( AREAP ) pArea, pError ) == E_RETRY ); } @@ -1544,48 +1738,73 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo ) uiSize = pArea->uiFieldCount * sizeof( DBFFIELD ); pBuffer = ( DBFFIELD * ) hb_xgrab( uiSize ); + memset( pBuffer, 0, uiSize ); + pThisField = pBuffer; + pArea->uiRecordLen = 1; - bHasMemo = FALSE; - memset( &dbField, 0, sizeof( DBFFIELD ) ); + pArea->bVersion = s_dbfVersion; + + fHasMemo = FALSE; + for( uiCount = 0; uiCount < pArea->uiFieldCount; uiCount++ ) { - strncpy( ( char * ) dbField.bName, + strncpy( ( char * ) pThisField->bName, ( ( PHB_DYNS ) pArea->lpFields[ uiCount ].sym )->pSymbol->szName, 10 ); switch( pArea->lpFields[ uiCount ].uiType ) { case HB_IT_STRING: - dbField.bType = 'C'; - dbField.bLen = ( BYTE ) pArea->lpFields[ uiCount ].uiLen; - dbField.bDec = ( BYTE ) ( pArea->lpFields[ uiCount ].uiLen / 256 ); + pThisField->bType = 'C'; + pThisField->bLen = ( BYTE ) pArea->lpFields[ uiCount ].uiLen; + pThisField->bDec = ( BYTE ) ( pArea->lpFields[ uiCount ].uiLen / 256 ); pArea->uiRecordLen += pArea->lpFields[ uiCount ].uiLen; break; case HB_IT_LOGICAL: - dbField.bType = 'L'; - dbField.bLen = 1; - dbField.bDec = 0; + pThisField->bType = 'L'; + pThisField->bLen = 1; + pThisField->bDec = 0; pArea->uiRecordLen ++; break; case HB_IT_MEMO: - dbField.bType = 'M'; - dbField.bLen = 10; - dbField.bDec = 0; - pArea->uiRecordLen += 10; - bHasMemo = TRUE; + pThisField->bType = 'M'; + pThisField->bLen = ( BYTE ) pArea->lpFields[ uiCount ].uiLen; + if ( pThisField->bLen != 4 ) + pThisField->bLen = 10; + pThisField->bDec = 0; + pArea->uiRecordLen += pThisField->bLen; + fHasMemo = TRUE; break; case HB_IT_DATE: - dbField.bType = 'D'; - dbField.bLen = 8; - dbField.bDec = 0; - pArea->uiRecordLen += 8; + pThisField->bType = 'D'; + pThisField->bLen = ( BYTE ) pArea->lpFields[ uiCount ].uiLen; + if ( pThisField->bLen != 3 ) + pThisField->bLen = 8; + pThisField->bDec = 0; + pArea->uiRecordLen += pThisField->bLen; break; case HB_IT_LONG: - dbField.bType = 'N'; - dbField.bLen = ( BYTE ) pArea->lpFields[ uiCount ].uiLen; - dbField.bDec = ( BYTE ) pArea->lpFields[ uiCount ].uiDec; + pThisField->bType = 'N'; + pThisField->bLen = ( BYTE ) pArea->lpFields[ uiCount ].uiLen; + pThisField->bDec = ( BYTE ) pArea->lpFields[ uiCount ].uiDec; + pArea->uiRecordLen += pArea->lpFields[ uiCount ].uiLen; + break; + + case HB_IT_DOUBLE: + pThisField->bType = 'B'; + pThisField->bLen = 8; + pThisField->bDec = ( BYTE ) pArea->lpFields[ uiCount ].uiDec; + pArea->uiRecordLen += pArea->lpFields[ uiCount ].uiLen; + break; + + case HB_IT_INTEGER: + pThisField->bType = 'I'; + pThisField->bLen = ( BYTE ) pArea->lpFields[ uiCount ].uiLen; + if ( pThisField->bLen != 2 && pThisField->bLen != 8 ) + pThisField->bLen = 4; + pThisField->bDec = 0; pArea->uiRecordLen += pArea->lpFields[ uiCount ].uiLen; break; @@ -1593,18 +1812,16 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo ) hb_xfree( pBuffer ); return FAILURE; } - pBuffer[ uiCount ] = dbField; + pThisField++ ; } - pArea->fShared = pCreateInfo->fShared; pArea->ulRecCount = 0; - pArea->uiHeaderLen = sizeof( DBFHEADER ) + uiSize + 2; - pArea->fHasMemo = bHasMemo; + pArea->uiHeaderLen = sizeof( DBFHEADER ) + uiSize + ( pArea->bVersion == 0x30 ? 1 : 2 ); + pArea->fHasMemo = fHasMemo; pArea->uiMemoBlockSize = 0; - pArea->bVersion = 0x03; /* Write header */ - if( SELF_WRITEDBHEADER( ( AREAP ) pArea ) == FAILURE ) + if ( SELF_WRITEDBHEADER( ( AREAP ) pArea ) == FAILURE ) { hb_fsClose( pArea->hDataFile ); pArea->hDataFile = FS_ERROR; @@ -1613,26 +1830,33 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo ) } /* Write fields and eof mark */ - if( hb_fsWrite( pArea->hDataFile, ( BYTE * ) pBuffer, uiSize ) != uiSize || - hb_fsWrite( pArea->hDataFile, ( BYTE * ) "\r\0\032", 3 ) != 3 ) + if ( hb_fsWrite( pArea->hDataFile, ( BYTE * ) pBuffer, uiSize ) != uiSize || + ( pArea->bVersion == 0x30 ? + hb_fsWrite( pArea->hDataFile, ( BYTE * ) "\r\032", 2 ) != 2 : + hb_fsWrite( pArea->hDataFile, ( BYTE * ) "\r\0\032", 3 ) != 3 ) ) { hb_fsClose( pArea->hDataFile ); pArea->hDataFile = FS_ERROR; hb_xfree( pBuffer ); return FAILURE; } + pArea->fDataFlush = TRUE; hb_xfree( pBuffer ); /* Create memo file */ - if( bHasMemo ) + if ( fHasMemo ) { BYTE *tmp; ERRCODE result; pArea->szMemoFileName = ( char * ) hb_xgrab( _POSIX_PATH_MAX + 1 ); pFileName = hb_fsFNameSplit( ( char * ) pCreateInfo->abName ); pArea->szMemoFileName[ 0 ] = 0; - if( pFileName->szPath ) + + if ( pFileName->szPath ) + { strcat( pArea->szMemoFileName, pFileName->szPath ); + } + strcat( pArea->szMemoFileName, pFileName->szName ); hb_xfree( pFileName ); pFileExt = hb_itemPutC( NULL, "" ); @@ -1644,10 +1868,13 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo ) pCreateInfo->abName = ( BYTE * ) pArea->szMemoFileName; result = SELF_CREATEMEMFILE( ( AREAP ) pArea, pCreateInfo ); pCreateInfo->abName = tmp; + return result; } else + { return SUCCESS; + } } /* @@ -1688,6 +1915,10 @@ static ERRCODE hb_dbfInfo( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) hb_itemPutC( pItem, DBF_TABLEEXT ); break; + case DBI_FULLPATH: + hb_itemPutC( pItem, pArea->szDataFileName); + break; + case DBI_MEMOEXT: hb_itemPutC( pItem, "" ); break; @@ -1696,14 +1927,6 @@ static ERRCODE hb_dbfInfo( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) hb_itemPutNI( pItem, pArea->uiMemoBlockSize ); break; - case DBI_FULLPATH: - hb_itemPutC( pItem, pArea->szDataFileName); - break; - - case DBI_SHARED: - hb_itemPutL( pItem, pArea->fShared ); - break; - case DBI_FILEHANDLE: hb_itemPutNL( pItem, (LONG)pArea->hDataFile ); break; @@ -1712,11 +1935,131 @@ static ERRCODE hb_dbfInfo( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) hb_itemPutNL( pItem, (LONG)pArea->hMemoFile ); break; + case DBI_SHARED: + { + BOOL fShared = pArea->fShared; + + if ( HB_IS_LOGICAL( pItem ) ) + { + pArea->fShared = hb_itemGetL( pItem ); + } + hb_itemPutL( pItem, fShared ); + break; + } + case DBI_ISFLOCK: + hb_itemPutL( pItem, pArea->fFLocked ); + break; + + case DBI_ISREADONLY: + hb_itemPutL( pItem, pArea->fReadonly ); + break; + + case DBI_VALIDBUFFER: + hb_itemPutL( pItem, pArea->fValidBuffer ); + break; + + case DBI_LOCKCOUNT: + hb_itemPutNL( pItem, pArea->ulNumLocksPos ); + break; + + case DBI_LOCKSCHEME: + { + SHORT bScheme = hb_itemGetNI( pItem ); + hb_itemPutNI( pItem, pArea->bLockType ); + switch ( bScheme ) + { + case HB_SET_DBFLOCK_CLIP: + case HB_SET_DBFLOCK_CL53: + case HB_SET_DBFLOCK_VFP: + pArea->bLockType = (BYTE) bScheme; + } + break; + } + case DBI_ROLLBACK: + if ( pArea->fRecordChanged ) + { + if ( pArea->fAppend ) + { + hb_dbfSetBlankRecord( pArea ) ; + pArea->fDeleted = FALSE; + } + else + { + pArea->fRecordChanged = pArea->fValidBuffer = FALSE; + } + } + break; + + default: + return SUPER_INFO( ( AREAP ) pArea, uiIndex, pItem ); } return SUCCESS; } +/* + * Retrieve information about a raw + */ +static ERRCODE hb_dbfRecInfo( DBFAREAP pArea, PHB_ITEM pRecID, USHORT uiInfoType, PHB_ITEM pInfo ) +{ + ULONG ulRecNo = hb_itemGetNL( pRecID ); + + HB_TRACE(HB_TR_DEBUG, ("hb_dbfRecInfo(%p, %p, %hu, %p)", pArea, pRecID, uiInfoType, pInfo)); + + + if( ulRecNo == 0 ) + { + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + ulRecNo = pArea->ulRecNo; + } + + switch( uiInfoType ) + { + case DBRI_DELETED: + { + BOOL bDeleted; + ULONG ulPrevRec = 0; + + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + + if( pArea->ulRecNo != ulRecNo ) + { + ulPrevRec = pArea->ulRecNo; + SELF_GOTO( ( AREAP ) pArea, ulRecNo ); + } + SELF_DELETED( ( AREAP ) pArea, &bDeleted ); + if( ulPrevRec != 0 ) + { + SELF_GOTO( ( AREAP ) pArea, ulPrevRec ); + } + hb_itemPutL( pInfo, bDeleted ); + break; + } + + case DBRI_LOCKED: + hb_itemPutL( pInfo, hb_dbfIsLocked( pArea, ulRecNo ) ); + break; + + case DBRI_RECSIZE: + hb_itemPutNL( pInfo, pArea->uiRecordLen ); + break; + + case DBRI_RECNO: + hb_itemPutNL( pInfo, ulRecNo ); + break; + + case DBRI_UPDATED: + hb_itemPutL( pInfo, ulRecNo == pArea->ulRecNo && pArea->fRecordChanged ); + break; + + default: + return SUPER_RECINFO( ( AREAP ) pArea, pRecID, uiInfoType, pInfo ); + } + return SUCCESS; +} + /* * Clear the WorkArea for use. */ @@ -1728,6 +2071,7 @@ static ERRCODE hb_dbfNewArea( DBFAREAP pArea ) return FAILURE; pArea->hDataFile = pArea->hMemoFile = FS_ERROR; + pArea->fDataFlush = pArea->fMemoFlush = FALSE; /* Size for deleted records flag */ pArea->uiRecordLen = 1; @@ -1743,10 +2087,10 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) BOOL bRetry, bError, bLock; PHB_ITEM pError, pFileExt; PHB_FNAME pFileName; - char * szFileName; BYTE * pBuffer; LPDBFFIELD pField; DBFIELDINFO pFieldInfo; + BYTE szPath[ _POSIX_PATH_MAX + 1 ]; HB_TRACE(HB_TR_DEBUG, ("hb_dbfOpen(%p, %p)", pArea, pOpenInfo)); @@ -1766,6 +2110,7 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) pArea->bLockType = HB_SET_DBFLOCK_CLIP; } ( ( PHB_DYNS ) pArea->atomAlias )->hArea = pOpenInfo->uiArea; +#ifndef HB_CDP_SUPPORT_OFF if( pOpenInfo->cdpId ) { pArea->cdPage = hb_cdpFind( (char *) pOpenInfo->cdpId ); @@ -1774,6 +2119,7 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) } else pArea->cdPage = hb_cdp_page; +#endif pArea->fShared = pOpenInfo->fShared; pArea->fReadonly = pOpenInfo->fReadonly; /* Force exclusive mode @@ -1791,16 +2137,21 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) do { bLock = FALSE; - pArea->hDataFile = hb_spOpen( pOpenInfo->abName, uiFlags ); + if ( ! hb_spFile( pOpenInfo->abName, szPath ) ) + { + hb_strncpy( ( char * ) szPath, ( const char * ) pOpenInfo->abName, _POSIX_PATH_MAX ); + } + pArea->hDataFile = hb_spOpen( szPath, uiFlags ); #ifdef DBF_EXLUSIVE_LOCKPOS if( pArea->hDataFile != FS_ERROR ) { if ( !hb_fsLock( pArea->hDataFile, DBF_EXLUSIVE_LOCKPOS, DBF_EXLUSIVE_LOCKSIZE, - FL_LOCK | ( pArea->fShared ? FLX_SHARED : FLX_EXCLUSIVE ) ) ) + FL_LOCK | ( ( pArea->fShared || pArea->fReadonly ) ? + FLX_SHARED : FLX_EXCLUSIVE ) ) ) { hb_fsClose( pArea->hDataFile ); pArea->hDataFile = FS_ERROR; - bLock = TRUE; + bLock = TRUE; } } #endif @@ -1813,21 +2164,31 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) hb_errPutSubCode( pError, EDBF_OPEN_DBF ); hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_OPEN ) ); hb_errPutFileName( pError, ( char * ) pOpenInfo->abName ); - /* - * Temporary fix for neterr() support and Clipper compatibility, - * should be revised with a better solution. - */ - if ( hb_fsError() == EACCES || bLock ) - hb_errPutOsCode( pError, 32 ); - else - hb_errPutOsCode( pError, hb_fsError() ); hb_errPutFlags( pError, EF_CANRETRY | EF_CANDEFAULT ); } + /* + * Temporary fix for neterr() support and Clipper compatibility, + * should be revised with a better solution. + */ + if ( hb_fsError() == EACCES || bLock ) + { + hb_errPutOsCode( pError, 32 ); + } + else if ( hb_fsError() == 0 ) + { + break; + } + else + { + hb_errPutOsCode( pError, hb_fsError() ); + } + bRetry = ( SELF_ERROR( ( AREAP ) pArea, pError ) == E_RETRY ); } else bRetry = FALSE; } while( bRetry ); + if( pError ) { hb_itemRelease( pError ); @@ -1842,8 +2203,7 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) } /* Allocate only after succesfully open file */ - pArea->szDataFileName = (char *) hb_xgrab( strlen( (char * ) pOpenInfo->abName)+1 ); - strcpy( pArea->szDataFileName, ( char * ) pOpenInfo->abName ); + pArea->szDataFileName = hb_strdup( ( char * ) szPath ); /* Read file header and exit if error */ if( SELF_READDBHEADER( ( AREAP ) pArea ) == FAILURE ) @@ -1852,39 +2212,9 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) return FAILURE; } - /* Open memo file if exists */ - if( pArea->fHasMemo ) - { - BYTE *tmp; - pFileName = hb_fsFNameSplit( ( char * ) pOpenInfo->abName ); - pFileExt = hb_itemPutC( NULL, "" ); - SELF_INFO( ( AREAP ) pArea, DBI_MEMOEXT, pFileExt ); - szFileName = ( char * ) hb_xgrab( _POSIX_PATH_MAX + 1 ); - szFileName[ 0 ] = 0; - if( pFileName->szPath ) - strcat( szFileName, pFileName->szPath ); - strcat( szFileName, pFileName->szName ); - strncat( szFileName, hb_itemGetCPtr( pFileExt ), _POSIX_PATH_MAX - - strlen( szFileName ) ); - hb_itemRelease( pFileExt ); - hb_xfree( pFileName ); - tmp = pOpenInfo->abName; - pOpenInfo->abName = ( BYTE * ) szFileName; - pArea->szMemoFileName = szFileName; - - /* Open memo file and exit if error */ - if( SELF_OPENMEMFILE( ( AREAP ) pArea, pOpenInfo ) == FAILURE ) - { - pOpenInfo->abName = tmp; - SELF_CLOSE( ( AREAP ) pArea ); - return FAILURE; - } - pOpenInfo->abName = tmp; - } /* Add fields */ uiFields = ( pArea->uiHeaderLen - sizeof( DBFHEADER ) ) / sizeof( DBFFIELD ); - SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields ); uiSize = uiFields * sizeof( DBFFIELD ); pBuffer = ( BYTE * ) hb_xgrab( uiSize ); @@ -1923,6 +2253,27 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) return FAILURE; } + /* some RDDs use the additional space in the header after field arrray + for private data we should check for 0x0D marker to not use this + data as fields description */ + for( uiCount = 0; uiCount < uiFields; uiCount++ ) + { + if ( pBuffer[ uiCount * sizeof( DBFFIELD ) ] == 0x0d ) + { + uiFields = uiCount; + break; + } + } + + if ( uiFields == 0 ) + { + bError = TRUE; + } + else + { + SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields ); + } + /* Size for deleted flag */ pArea->uiRecordLen = 1; @@ -1932,7 +2283,7 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) pField = ( LPDBFFIELD ) ( pBuffer + uiCount * sizeof( DBFFIELD ) ); pFieldInfo.atomName = pField->bName; pFieldInfo.atomName[10] = '\0'; - hb_strUpper( (char *) pFieldInfo.atomName, 10 ); + hb_strUpper( (char *) pFieldInfo.atomName, 11 ); pFieldInfo.uiLen = pField->bLen; pFieldInfo.uiDec = 0; switch( pField->bType ) @@ -1949,26 +2300,63 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) case 'M': pFieldInfo.uiType = HB_IT_MEMO; - pFieldInfo.uiLen = 10; + pArea->fHasMemo = TRUE ; break; case 'D': pFieldInfo.uiType = HB_IT_DATE; - pFieldInfo.uiLen = 8; + if ( pFieldInfo.uiLen != 3 ) + pFieldInfo.uiLen = 8; + break; + + case 'I': + pFieldInfo.uiType = HB_IT_INTEGER; + if ( pFieldInfo.uiLen != 2 && pFieldInfo.uiLen != 8 ) + pFieldInfo.uiLen = 4; + break; + + case '2': + case '4': + pFieldInfo.uiType = HB_IT_INTEGER; + pFieldInfo.uiLen = pField->bType - '0'; break; case 'N': + case 'F': pFieldInfo.uiType = HB_IT_LONG; + /* DBASE documentation defines maximum numeric field size as 20 + * but Clipper alows to create longer fileds so I remove this + * limit, Druzus + */ + /* if( pField->bLen > 20 ) bError = TRUE; else - pFieldInfo.uiDec = pField->bDec; + */ + pFieldInfo.uiDec = pField->bDec; + break; + + case '8': + case 'B': + pFieldInfo.uiType = HB_IT_DOUBLE; + pFieldInfo.uiLen = 8; + pFieldInfo.uiDec = pField->bDec; break; default: bError = TRUE; break; } + + /* Peter, is it necessary? + shouldn't be such filed after 0x0D terminator? + */ + if( pArea->bVersion == 0x30 && pField->bType == 0 ) + { + bError = FALSE; + break; + } + /* Add field */ if( !bError ) bError = ( SELF_ADDFIELD( ( AREAP ) pArea, &pFieldInfo ) == FAILURE ); @@ -1979,6 +2367,8 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) } hb_xfree( pBuffer ); + /* Open memo file if exists */ + /* Exit if error */ if( bError ) { @@ -1997,6 +2387,35 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) return FAILURE; } + if( pArea->fHasMemo ) + { + BYTE *tmp; + pFileName = hb_fsFNameSplit( ( char * ) szPath ); + pFileExt = hb_itemPutC( NULL, "" ); + SELF_INFO( ( AREAP ) pArea, DBI_MEMOEXT, pFileExt ); + + szPath[ 0 ] = 0; + if( pFileName->szPath ) + strcat( ( char * ) szPath, pFileName->szPath ); + strncat( ( char * ) szPath, pFileName->szName, _POSIX_PATH_MAX - strlen( ( char * ) szPath ) ); + strncat( ( char * ) szPath, pFileExt->item.asString.value, _POSIX_PATH_MAX - strlen( ( char * ) szPath ) ); + hb_itemRelease( pFileExt ); + hb_xfree( pFileName ); + tmp = pOpenInfo->abName; + pOpenInfo->abName = szPath; + pArea->szMemoFileName = hb_strdup( ( char * ) szPath ); + + /* Open memo file and exit if error */ + if( SELF_OPENMEMFILE( ( AREAP ) pArea, pOpenInfo ) == FAILURE ) + { + pOpenInfo->abName = tmp; + SELF_CLOSE( ( AREAP ) pArea ); + return FAILURE; + } + pOpenInfo->abName = tmp; + } + + /* Alloc buffer */ pArea->pRecord = ( BYTE * ) hb_xgrab( pArea->uiRecordLen ); pArea->fValidBuffer = FALSE; @@ -2042,6 +2461,16 @@ static ERRCODE hb_dbfPack( DBFAREAP pArea ) HB_TRACE(HB_TR_DEBUG, ("hb_dbfPack(%p)", pArea)); + if( pArea->fReadonly ) + { + pError = hb_errNew(); + hb_errPutGenCode( pError, EG_READONLY ); + hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_READONLY ) ); + hb_errPutSubCode( pError, EDBF_READONLY ); + SELF_ERROR( ( AREAP ) pArea, pError ); + hb_itemRelease( pError ); + return FAILURE; + } if( pArea->fShared ) { pError = hb_errNew(); @@ -2069,8 +2498,6 @@ static ERRCODE hb_dbfPack( DBFAREAP pArea ) ulUserEvery = 1; } - /* Force write new header */ - pArea->fUpdateHeader = TRUE; ulRecOut = ulEvery = 0; ulRecIn = 1; while ( ulRecIn <= pArea->ulRecCount ) @@ -2113,7 +2540,12 @@ static ERRCODE hb_dbfPack( DBFAREAP pArea ) hb_vmDo( 0 ); } - pArea->ulRecCount = ulRecOut; + if ( pArea->ulRecCount != ulRecOut ) + { + pArea->ulRecCount = ulRecOut; + /* Force write new header */ + pArea->fUpdateHeader = TRUE; + } return hb_dbfGoTo( pArea, 1 ); } @@ -2282,6 +2714,16 @@ static ERRCODE hb_dbfZap( DBFAREAP pArea ) HB_TRACE(HB_TR_DEBUG, ("hb_dbfZap(%p)", pArea)); + if( pArea->fReadonly ) + { + pError = hb_errNew(); + hb_errPutGenCode( pError, EG_READONLY ); + hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_READONLY ) ); + hb_errPutSubCode( pError, EDBF_READONLY ); + SELF_ERROR( ( AREAP ) pArea, pError ); + hb_itemRelease( pError ); + return FAILURE; + } if( pArea->fShared ) { pError = hb_errNew(); @@ -2296,9 +2738,9 @@ static ERRCODE hb_dbfZap( DBFAREAP pArea ) if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; - hb_dbfGoTo( pArea, 0 ); pArea->fUpdateHeader = TRUE; pArea->ulRecCount = 0; + hb_dbfGoTo( pArea, 0 ); /* Zap memo file */ if( pArea->fHasMemo ) @@ -2638,6 +3080,7 @@ static ERRCODE hb_dbfOpenMemFile( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) hb_itemRelease( pError ); return FAILURE; } + /* * Read the database file header record in the WorkArea. */ @@ -2654,12 +3097,12 @@ static ERRCODE hb_dbfReadDBHeader( DBFAREAP pArea ) do { hb_fsSeek( pArea->hDataFile, 0, FS_SET ); - if( hb_fsRead( pArea->hDataFile, ( BYTE * ) &dbHeader, sizeof( DBFHEADER ) ) != sizeof( DBFHEADER ) || - ( dbHeader.bVersion != 0x03 && /* dBase III */ - dbHeader.bVersion != 0x30 && /* VisualFoxPro 6.0 */ - dbHeader.bVersion != 0x83 && /* dBase III w/memo */ - dbHeader.bVersion != 0xF5 /* FoxPro??? w/memo */ - ) ) + if ( hb_fsRead( pArea->hDataFile, ( BYTE * ) &dbHeader, sizeof( DBFHEADER ) ) != sizeof( DBFHEADER ) || + ( dbHeader.bVersion != 0x03 && /* dBase III */ + dbHeader.bVersion != 0x30 && /* VisualFoxPro 6.0 */ + dbHeader.bVersion != 0x83 && /* dBase III w/memo */ + dbHeader.bVersion != 0xF5 /* FoxPro??? w/memo */ + ) ) { bError = TRUE; if( !pError ) @@ -2687,12 +3130,17 @@ static ERRCODE hb_dbfReadDBHeader( DBFAREAP pArea ) pArea->bDay = dbHeader.bDay; pArea->bMonth = dbHeader.bMonth; pArea->bYear = dbHeader.bYear; - pArea->fHasTags = dbHeader.bHasTags; + pArea->fHasTags = ( dbHeader.bHasTags & 0x01 ) != 0; pArea->bVersion = dbHeader.bVersion; pArea->bCodePage = dbHeader.bCodePage; - pArea->uiHeaderLen = HB_USHORT_FROM_LE( dbHeader.uiHeaderLen ); - pArea->ulRecCount = HB_ULONG_FROM_LE( dbHeader.ulRecCount ); - pArea->fHasMemo = FALSE; + pArea->uiHeaderLen = HB_GET_LE_UINT16( dbHeader.uiHeaderLen ); + pArea->ulRecCount = HB_GET_LE_UINT32( dbHeader.ulRecCount ); + + pArea->fHasMemo = ( pArea->bVersion == 0xF5 || /* FoxPro 2.x or earlier with Memo */ + pArea->bVersion == 0x83 || /* dBase III with Memo */ + ( pArea->bVersion == 0x30 && + ( dbHeader.bHasTags & 0x02 ) ) ); /* VisualFox with Memo */ + return SUCCESS; } @@ -2703,17 +3151,18 @@ static ERRCODE hb_dbfWriteDBHeader( DBFAREAP pArea ) { BOOL fLck = FALSE; DBFHEADER dbfHeader; - LONG lYear, lMonth, lDay; + int iYear, iMonth, iDay; HB_TRACE(HB_TR_DEBUG, ("hb_dbfWriteDBHeader(%p)", pArea)); memset( &dbfHeader, 0, sizeof( DBFHEADER ) ); dbfHeader.bVersion = pArea->bVersion; - hb_dateToday( &lYear, &lMonth, &lDay ); - dbfHeader.bYear = ( BYTE ) ( lYear - 1900 ); - dbfHeader.bMonth = ( BYTE ) lMonth; - dbfHeader.bDay = ( BYTE ) lDay; - dbfHeader.bHasTags = ( BYTE ) pArea->fHasTags; + hb_dateToday( &iYear, &iMonth, &iDay ); + dbfHeader.bYear = ( BYTE ) ( iYear - 1900 ); + dbfHeader.bMonth = ( BYTE ) iMonth; + dbfHeader.bDay = ( BYTE ) iDay; + dbfHeader.bHasTags = ( BYTE ) ( pArea->fHasTags ? 0x01 : 0x00 ) | + ( ( pArea->fHasMemo && pArea->bVersion == 0x30 ) ? 0x02 : 0x00 ); dbfHeader.bCodePage = pArea->bCodePage; /* Update record count */ @@ -2727,12 +3176,22 @@ static ERRCODE hb_dbfWriteDBHeader( DBFAREAP pArea ) } pArea->ulRecCount = hb_dbfCalcRecCount( pArea ); } + else + { + /* Exclusive mode */ + /* Seek to logical eof and write eof mark */ + hb_fsSeek( pArea->hDataFile, pArea->uiHeaderLen + + pArea->uiRecordLen * pArea->ulRecCount, FS_SET ); + hb_fsWrite( pArea->hDataFile, ( BYTE * ) "\032", 1 ); + hb_fsWrite( pArea->hDataFile, NULL, 0 ); + } - HB_PUT_LE_ULONG( &dbfHeader.ulRecCount, pArea->ulRecCount ); - HB_PUT_LE_USHORT( &dbfHeader.uiHeaderLen, pArea->uiHeaderLen ); - HB_PUT_LE_USHORT( &dbfHeader.uiRecordLen, pArea->uiRecordLen ); + HB_PUT_LE_UINT32( dbfHeader.ulRecCount, pArea->ulRecCount ); + HB_PUT_LE_UINT16( dbfHeader.uiHeaderLen, pArea->uiHeaderLen ); + HB_PUT_LE_UINT16( dbfHeader.uiRecordLen, pArea->uiRecordLen ); hb_fsSeek( pArea->hDataFile, 0, FS_SET ); hb_fsWrite( pArea->hDataFile, ( BYTE * ) &dbfHeader, sizeof( DBFHEADER ) ); + pArea->fDataFlush = TRUE; pArea->fUpdateHeader = FALSE; if( fLck ) SELF_RAWLOCK( ( AREAP ) pArea, HEADER_UNLOCK, 0 ); @@ -2741,23 +3200,40 @@ static ERRCODE hb_dbfWriteDBHeader( DBFAREAP pArea ) static ERRCODE hb_dbfDrop( PHB_ITEM pItemTable ) { - BYTE * pBuffer; - char szFileName[ _POSIX_PATH_MAX + 1 ]; + HB_TRACE(HB_TR_DEBUG, ("hb_dbfDrop(%p)", pItemTable)); - pBuffer = (BYTE *) hb_itemGetCPtr( pItemTable ); - strcpy( (char *) szFileName, (char *) pBuffer ); - if ( !strchr( szFileName, '.' )) - strcat( szFileName, DBF_TABLEEXT ); - return hb_fsDelete( (BYTE *) szFileName ); + if ( pItemTable && HB_IS_STRING( pItemTable ) ) + { + BYTE * pBuffer; + char szFileName[ _POSIX_PATH_MAX + 1 ]; + ULONG ulLen; + + pBuffer = (BYTE *) pItemTable->item.asString.value; + szFileName[ _POSIX_PATH_MAX ] = '\0'; + strncpy( (char *) szFileName, (char *) pBuffer, _POSIX_PATH_MAX ); + ulLen = strlen( szFileName ); + if ( ulLen > 0 ) + { + PHB_FNAME pFileName = hb_fsFNameSplit( szFileName ); + if ( !pFileName->szExtension ) + { + strncat( szFileName, DBF_TABLEEXT, _POSIX_PATH_MAX - ulLen ); + } + hb_xfree( pFileName ); + return hb_fsDelete( (BYTE *) szFileName ) ? SUCCESS : FAILURE; + } + } + return FAILURE; } /* returns 1 if exists, 0 else */ -BOOL hb_dbfExists( PHB_ITEM pItemTable, PHB_ITEM pItemIndex ) +BOOL HB_EXPORT hb_dbfExists( PHB_ITEM pItemTable, PHB_ITEM pItemIndex ) { char szFileName[ _POSIX_PATH_MAX + 1 ]; BYTE * pBuffer; - pBuffer = (BYTE *) hb_itemGetCPtr( pItemIndex != NULL ? pItemIndex : pItemTable ); + pBuffer = (BYTE *) ( pItemIndex != NULL ? pItemIndex->item.asString.value : pItemTable->item.asString.value ); + strcpy( (char *) szFileName, (char *) pBuffer ); if ( pItemTable && !strchr( szFileName, '.' )) strcat( szFileName, DBF_TABLEEXT ); @@ -2785,3 +3261,19 @@ HB_FUNC( DBF_GETFUNCTABLE ) else hb_retni( FAILURE ); } + +HB_FUNC( DBSETDBFVERSION ) +{ + BYTE bOldVersion = s_dbfVersion; + + if ( hb_pcount() > 0 ) + { + BYTE bVersion = ( BYTE ) hb_parni( 1 ); + if ( bVersion == 0x30 || bVersion == 0x03 ) + { + s_dbfVersion = bVersion; + } + } + hb_retni( bOldVersion ); +} + diff --git a/harbour/source/rdd/dbfcdx/dbfcdx1.c b/harbour/source/rdd/dbfcdx/dbfcdx1.c index ecce9589d1..3abcd534e8 100644 --- a/harbour/source/rdd/dbfcdx/dbfcdx1.c +++ b/harbour/source/rdd/dbfcdx/dbfcdx1.c @@ -10,6 +10,7 @@ * Copyright 2000-2003 Horacio Roldan (portions) * Copyright 2003 Przemyslaw Czerpak - all code except * hb_cdxTagDoIndex and related hb_cdxSort* rewritten. + * Copyright 2004 Przemyslaw Czerpak - rest of code rewritten * www - http://www.xharbour.org * * This program is free software; you can redistribute it and/or modify @@ -53,14 +54,17 @@ * */ +#define HB_CDX_CLIP_AUTOPEN +#define HB_CDX_PACKTRAIL #define HB_CDX_DBGCODE -/*#define HB_CDX_DBGCODE_EXT */ - -/*#define HB_CDX_DSPDBG_INFO */ -/*#define HB_CDP_SUPPORT_OFF */ -/*#define HB_CDX_DBGTIME */ -/*#define HB_CDX_DBGUPDT */ +/* +#define HB_CDX_DBGCODE_EXT +#define HB_CDX_DSPDBG_INFO +#define HB_CDP_SUPPORT_OFF +#define HB_CDX_DBGTIME +#define HB_CDX_DBGUPDT +*/ #include "hbapi.h" #include "hbinit.h" @@ -69,6 +73,9 @@ #include "hbvm.h" #include "hbset.h" #include "hbrddcdx.h" +#ifdef __XHARBOUR__ +#include "regex.h" +#endif #define __PRG_SOURCE__ __FILE__ #ifndef __XHARBOUR__ @@ -82,7 +89,6 @@ #ifndef HB_CDP_SUPPORT_OFF /* for nation sorting support */ #include "hbapicdp.h" - extern PHB_CODEPAGE hb_cdp_page; #define hb_cdpcharcmp( c1, c2, cdpage ) \ ( ( cdpage && cdpage->lSort ) ? \ hb_cdpchrcmp( c1, c2, cdpage ) : \ @@ -94,10 +100,9 @@ /* - * TODO: !!! hb_cdxFindTag doesn't use bag name! - * TODO: Tag->fRePos = TURE means that rootPage->...->childLeafPage path is - * bad and has to be reloaded - * CurKey->rec == 0 means that there is no correct CurKey + * Tag->fRePos = TURE means that rootPage->...->childLeafPage path is + * bad and has to be reloaded + * CurKey->rec == 0 means that there is no correct CurKey */ /* create a new Tag (make index) */ @@ -127,7 +132,8 @@ static void hb_cdxIndexPoolFree( LPCDXINDEX pIndex, int nPagesLeft ); /* split Root Page */ static int hb_cdxPageRootSplit( LPCDXPAGE pPage ); - +/* free create index structur */ +static void hb_cdxSortFree( LPCDXSORTINFO pSort ); static RDDFUNCS cdxSuper; static RDDFUNCS cdxTable = @@ -311,7 +317,9 @@ HB_INIT_SYMBOLS_BEGIN( dbfcdx1__InitSymbols ) { "DBFCDX_GETFUNCTABLE", HB_FS_PUBLIC, {HB_FUNCNAME( DBFCDX_GETFUNCTABLE )}, NULL } HB_INIT_SYMBOLS_END( dbfcdx1__InitSymbols ) -#if defined(_MSC_VER) +#if defined(HB_PRAGMA_STARTUP) + #pragma startup dbfcdx1__InitSymbols +#elif defined(_MSC_VER) #if _MSC_VER >= 1010 #pragma data_seg( ".CRT$XIY" ) #pragma comment( linker, "/Merge:.CRT=.data" ) @@ -320,8 +328,6 @@ HB_INIT_SYMBOLS_END( dbfcdx1__InitSymbols ) #endif static HB_$INITSYM hb_vm_auto_dbfcdx1__InitSymbols = dbfcdx1__InitSymbols; #pragma data_seg() -#elif ! defined(__GNUC__) - #pragma startup dbfcdx1__InitSymbols #endif #ifdef HB_CDX_DSPDBG_INFO @@ -355,6 +361,7 @@ static CDXDBGTIME cdxTimeIntBlc = 0; static CDXDBGTIME cdxTimeExtBlc = 0; static CDXDBGTIME cdxTimeGetKey = 0; static CDXDBGTIME cdxTimeFreeKey = 0; +static CDXDBGTIME cdxTimeIdxBld = 0; static CDXDBGTIME hb_cdxGetTime() { @@ -378,7 +385,7 @@ static void hb_cdxErrInternal( char * szMsg ) hb_errInternal( 9201, szMsg ? szMsg : "hb_cdxErrInternal: data integrity error.", "", "" ); } -static ERRCODE hb_cdxErrorRT( CDXAREAP pArea, USHORT uiGenCode, USHORT uiSubCode, char * filename, USHORT uiFlags ) +static ERRCODE hb_cdxErrorRT( CDXAREAP pArea, USHORT uiGenCode, USHORT uiSubCode, char * filename, USHORT uiOsCode, USHORT uiFlags ) { PHB_ITEM pError; ERRCODE iRet; @@ -386,6 +393,7 @@ static ERRCODE hb_cdxErrorRT( CDXAREAP pArea, USHORT uiGenCode, USHORT uiSubCode pError = hb_errNew(); hb_errPutGenCode( pError, uiGenCode ); hb_errPutSubCode( pError, uiSubCode ); + hb_errPutOsCode( pError, uiOsCode ); hb_errPutDescription( pError, hb_langDGetErrorDesc( uiGenCode ) ); if ( filename ) hb_errPutFileName( pError, filename ); @@ -601,7 +609,7 @@ static int hb_cdxValCompare( LPCDXTAG pTag, BYTE * val1, BYTE len1, /* * store Item in index key - * TODO: uiType check + * TODO: uiType check and generate RT error if necessary */ static LPCDXKEY hb_cdxKeyPutItem( LPCDXKEY pKey, PHB_ITEM pItem, ULONG ulRec, LPCDXTAG pTag, BOOL fTrans, BOOL fSize ) { @@ -615,12 +623,12 @@ static LPCDXKEY hb_cdxKeyPutItem( LPCDXKEY pKey, PHB_ITEM pItem, ULONG ulRec, LP { case HB_IT_STRING: case HB_IT_STRING | HB_IT_MEMO: - len = ( BYTE ) HB_MIN( pItem->item.asString.length, pTag->uiLen ); + len = (BYTE) HB_MIN( pItem->item.asString.length, (ULONG) pTag->uiLen ); if ( fSize && len < pTag->uiLen ) { memcpy( ptr, pItem->item.asString.value, len ); memset( ptr + len, pTag->uiType == 'C' ? ' ' : '\0', pTag->uiLen - len ); - len = pTag->uiLen; + len = ( BYTE ) pTag->uiLen; } else { @@ -630,7 +638,7 @@ static LPCDXKEY hb_cdxKeyPutItem( LPCDXKEY pKey, PHB_ITEM pItem, ULONG ulRec, LP case HB_IT_INTEGER: case HB_IT_LONG: case HB_IT_DOUBLE: -#ifndef HB_LONG_LONG_OFF +#ifdef HB_IT_LONGLONG case HB_IT_LONGLONG: #endif d = hb_itemGetND( pItem ); @@ -694,8 +702,10 @@ static PHB_ITEM hb_cdxKeyGetItem( LPCDXKEY pKey, PHB_ITEM pItem, USHORT uiType ) #endif } } + else if ( pItem ) + hb_itemClear( pItem ); else - pItem = hb_itemNew( pItem ); + pItem = hb_itemNew( NULL ); return pItem; } @@ -783,6 +793,9 @@ static BOOL hb_cdxEvalCond( CDXAREAP pArea, PHB_ITEM pCondItem, BOOL fSetWA ) int iCurrArea = 0; BOOL fRet; + if ( !pCondItem ) + return TRUE; + if ( fSetWA ) { iCurrArea = hb_rddGetCurrentWorkAreaNumber(); if ( iCurrArea != pArea->uiArea ) @@ -838,16 +851,77 @@ static BOOL hb_cdxEvalSeekCond( LPCDXTAG pTag, PHB_ITEM pCondItem ) return fRet; } +/* + * find field index for single field expressions + */ +static USHORT hb_cdxFieldIndex( CDXAREAP pArea, char * cExpr ) +{ + char szKeyExpr[ CDX_MAXKEY + 1 ], + szAlias[ HARBOUR_MAX_RDD_ALIAS_LENGTH + 1 ]; + int i, j, l, n = 0; + + if ( SELF_ALIAS( ( AREAP ) pArea, ( BYTE * ) szAlias ) == SUCCESS ) + l = strlen( szAlias ); + else + l = 0; + + hb_strncpyUpperTrim( szKeyExpr, cExpr, CDX_MAXKEY ); + + /* + * strip the _FIELD-> and FIELD-> prefix, it could be nested so repeat + * this process until all prefixes will be removed + */ + do + { + j = n; + if ( strncmp( &szKeyExpr[ n ], "FIELD", 5 ) == 0 ) + i = 5; + else if ( strncmp( &szKeyExpr[ n ], "_FIELD", 6 ) == 0 ) + i = 6; + else if ( l > 0 && strncmp( &szKeyExpr[ n ], szAlias, l ) == 0 ) + i = l; + else + i = 0; + + if ( i > 0 ) + { + i = n + 5; + while ( szKeyExpr[ i ] == ' ' ) + i++; + if ( szKeyExpr[ i ] == '-' && szKeyExpr[ i + 1 ] == '>' ) + { + n = i + 2; + while ( szKeyExpr[ n ] == ' ' ) + n++; + } + } + } + while ( n != j ); + + return hb_rddFieldIndex( ( AREAP ) pArea, &szKeyExpr[ n ] ); +} + /* * check if Key is in top scope */ static BOOL hb_cdxTopScope( LPCDXTAG pTag ) { - return !pTag->topScopeKey || !pTag->topScopeKey->len || - hb_cdxValCompare( pTag, pTag->topScopeKey->val, - pTag->topScopeKey->len, - pTag->CurKey->val, - pTag->CurKey->len, FALSE ) <= 0; + LPCDXKEY pKey; + + if ( pTag->UsrAscend ) + { + pKey = pTag->topScopeKey; + return !pKey || !pKey->len || + hb_cdxValCompare( pTag, pKey->val, pKey->len, + pTag->CurKey->val, pTag->CurKey->len, FALSE ) <= 0; + } + else + { + pKey = pTag->bottomScopeKey; + return !pKey || !pKey->len || + hb_cdxValCompare( pTag, pKey->val, pKey->len, + pTag->CurKey->val, pTag->CurKey->len, FALSE ) >= 0; + } } /* @@ -855,11 +929,22 @@ static BOOL hb_cdxTopScope( LPCDXTAG pTag ) */ static BOOL hb_cdxBottomScope( LPCDXTAG pTag ) { - return !pTag->bottomScopeKey || !pTag->bottomScopeKey->len || - hb_cdxValCompare( pTag, pTag->bottomScopeKey->val, - pTag->bottomScopeKey->len, - pTag->CurKey->val, - pTag->CurKey->len, FALSE ) >= 0; + LPCDXKEY pKey; + + if ( pTag->UsrAscend ) + { + pKey = pTag->bottomScopeKey; + return !pKey || !pKey->len || + hb_cdxValCompare( pTag, pKey->val, pKey->len, + pTag->CurKey->val, pTag->CurKey->len, FALSE ) >= 0; + } + else + { + pKey = pTag->topScopeKey; + return !pKey || !pKey->len || + hb_cdxValCompare( pTag, pKey->val, pKey->len, + pTag->CurKey->val, pTag->CurKey->len, FALSE ) <= 0; + } } /* @@ -872,7 +957,7 @@ static void hb_cdxTagClearScope( LPCDXTAG pTag, USHORT nScope ) HB_TRACE(HB_TR_DEBUG, ("hb_cdxTagClearScope(%p, %hu)", pTag, nScope)); - if ( nScope == 0 ) + if ( pTag->UsrAscend ? nScope == 0 : nScope != 0 ) { pScope = &pTag->topScope; pScopeKey = &pTag->topScopeKey; @@ -891,6 +976,9 @@ static void hb_cdxTagClearScope( LPCDXTAG pTag, USHORT nScope ) { hb_cdxKeyFree( *pScopeKey ); *pScopeKey = NULL; + pTag->curKeyState &= ~( CDX_CURKEY_RAWCNT | CDX_CURKEY_LOGCNT ); + if ( nScope == 0 ) + pTag->curKeyState &= ~( CDX_CURKEY_RAWPOS | CDX_CURKEY_LOGPOS ); } } @@ -989,8 +1077,8 @@ static ULONG hb_cdxIndexGetAvailPage( LPCDXINDEX pIndex, BOOL bHeader ) { if ( hb_fsSeek( hFile, ulPos, FS_SET ) != ulPos || hb_fsRead( hFile, (BYTE *) byBuf, 4 ) != 4 ) - hb_errInternal( EDBF_READ, "Read index page failed.", "", "" ); - pIndex->freePage = HB_GET_LE_ULONG( byBuf ); + hb_errInternal( EDBF_READ, "hb_cdxIndexGetAvailPage: Read index page failed.", "", "" ); + pIndex->freePage = HB_GET_LE_UINT32( byBuf ); #ifdef HB_CDX_DBGUPDT cdxReadNO++; #endif @@ -998,7 +1086,7 @@ static ULONG hb_cdxIndexGetAvailPage( LPCDXINDEX pIndex, BOOL bHeader ) } else { - int iCnt = (bHeader ? 2 : 1 ); + int iCnt = ( bHeader ? CDX_HEADERPAGES : 1 ); if ( pIndex->nextAvail != CDX_DUMMYNODE ) ulPos = pIndex->nextAvail; @@ -1018,6 +1106,7 @@ static ULONG hb_cdxIndexGetAvailPage( LPCDXINDEX pIndex, BOOL bHeader ) if ( hb_fsWrite( hFile, byBuf, CDX_PAGELEN ) != CDX_PAGELEN ) hb_errInternal( EDBF_WRITE, "Write in index page failed.(2)", "", "" ); } + pIndex->fChanged = TRUE; } } return ulPos; @@ -1030,7 +1119,7 @@ static void hb_cdxIndexPutAvailPage( LPCDXINDEX pIndex, ULONG ulPos, BOOL bHeade { if ( ulPos != 0 && ulPos != CDX_DUMMYNODE ) { - int iCnt = (bHeader ? 2 : 1 ); + int iCnt = ( bHeader ? CDX_HEADERPAGES : 1 ); LPCDXLIST pLst; if ( pIndex->fReadonly ) @@ -1069,7 +1158,7 @@ static void hb_cdxIndexFlushAvailPage( LPCDXINDEX pIndex ) ulPos = pIndex->freePage; while ( pLst && pLst->fStat ) { - HB_PUT_LE_ULONG( byPageBuf, pLst->ulAddr ); + HB_PUT_LE_UINT32( byPageBuf, pLst->ulAddr ); if ( hb_fsSeek( pIndex->hFile, ulPos, FS_SET ) != ulPos || hb_fsWrite( pIndex->hFile, byPageBuf, CDX_PAGELEN ) != CDX_PAGELEN ) { @@ -1131,7 +1220,7 @@ static void hb_cdxIndexPageRead( LPCDXINDEX pIndex, ULONG ulPos, BYTE * pBuffer, if ( hb_fsSeek( pIndex->hFile, ulPos, FS_SET ) != ulPos || hb_fsRead( pIndex->hFile, pBuffer, uiSize ) != uiSize ) - hb_errInternal( EDBF_READ, "Read index page failed.", "", "" ); + hb_errInternal( EDBF_READ, "hb_cdxIndexPageRead: Read index page failed.", "", "" ); #ifdef HB_CDX_DBGUPDT cdxReadNO++; #endif @@ -1156,8 +1245,8 @@ static void hb_cdxIndexCheckVersion( LPCDXINDEX pIndex ) #ifdef HB_CDX_DBGUPDT cdxReadNO++; #endif - ulFree = HB_GET_LE_ULONG( &byBuf[0] ); - ulVer = HB_GET_BE_ULONG( &byBuf[4] ); + ulFree = HB_GET_LE_UINT32( &byBuf[0] ); + ulVer = HB_GET_BE_UINT32( &byBuf[4] ); if ( !pIndex->fShared ) pIndex->ulVersion = pIndex->freePage; else if ( ulVer != pIndex->ulVersion || ulFree != pIndex->freePage ) @@ -1167,8 +1256,8 @@ static void hb_cdxIndexCheckVersion( LPCDXINDEX pIndex ) pIndex->freePage = ulFree; hb_cdxIndexDiscardBuffers( pIndex ); } - /* TODO: !!! ## remove it */ - /*hb_cdxIndexDiscardBuffers( pIndex ); */ + /* TODO: !!! ## remove it it's for test only */ + /* hb_cdxIndexDiscardBuffers( pIndex ); */ } /* @@ -1178,7 +1267,8 @@ static BOOL hb_cdxIndexLockRead( LPCDXINDEX pIndex ) { BOOL ret; - if ( pIndex->lockRead > 0 || pIndex->lockWrite > 0 || !pIndex->fShared ) + if ( pIndex->lockRead > 0 || pIndex->lockWrite > 0 || + !pIndex->pArea->fShared || !pIndex->fShared ) { pIndex->lockRead++; return TRUE; @@ -1193,10 +1283,10 @@ static BOOL hb_cdxIndexLockRead( LPCDXINDEX pIndex ) #endif ret = hb_dbfLockIdxFile( pIndex->hFile, pIndex->pArea->bLockType, - FL_LOCK | FLX_SHARED | FLX_WAIT, &pIndex->ulLockPos ); + FL_LOCK | FLX_SHARED | FLX_WAIT, &pIndex->ulLockPos ); if ( !ret ) - /* TODO: change into RT error dbfcdx/1038 */ - hb_errInternal( 9107, "hb_cdxIndexLockRead: lock failure.", "", "" ); + hb_cdxErrorRT( pIndex->pArea, EG_LOCK, EDBF_LOCK, pIndex->szFileName, hb_fsError(), 0 ); + if ( ret ) { pIndex->lockRead++; @@ -1222,7 +1312,7 @@ static BOOL hb_cdxIndexLockWrite( LPCDXINDEX pIndex ) if ( pIndex->lockWrite != 0 ) hb_errInternal( 9105, "hb_cdxIndexLockWrite: bad count of locks.", "", "" ); - if ( !pIndex->fShared ) + if ( !pIndex->pArea->fShared || !pIndex->fShared ) ret = TRUE; else { @@ -1232,11 +1322,10 @@ static BOOL hb_cdxIndexLockWrite( LPCDXINDEX pIndex ) pIndex->WrLck = TRUE; #endif ret = hb_dbfLockIdxFile( pIndex->hFile, pIndex->pArea->bLockType, - FL_LOCK | FLX_EXCLUSIVE | FLX_WAIT, &pIndex->ulLockPos ); + FL_LOCK | FLX_EXCLUSIVE | FLX_WAIT, &pIndex->ulLockPos ); } if ( !ret ) - /* TODO: change into RT error dbfcdx/1038 */ - hb_errInternal( 9107, "hb_cdxIndexLockWrite: lock failure.", "", "" ); + hb_cdxErrorRT( pIndex->pArea, EG_LOCK, EDBF_LOCK, pIndex->szFileName, hb_fsError(), 0 ); if ( ret ) { @@ -1267,7 +1356,7 @@ static BOOL hb_cdxIndexUnLockRead( LPCDXINDEX pIndex ) hb_cdxIndexPoolFree( pIndex, CDX_PAGECACHESIZE ); - if ( pIndex->fShared ) + if ( pIndex->pArea->fShared && pIndex->fShared ) { #ifdef HB_CDX_DBGCODE if ( pIndex->WrLck || ! pIndex->RdLck ) @@ -1306,19 +1395,20 @@ static BOOL hb_cdxIndexUnLockWrite( LPCDXINDEX pIndex ) hb_cdxIndexPoolFree( pIndex, CDX_PAGECACHESIZE ); pIndex->lockWrite--; - if ( pIndex->fShared ) + if ( pIndex->pArea->fShared && pIndex->fShared ) { if ( pIndex->fChanged ) { BYTE byBuf[8]; (pIndex->ulVersion)++; - HB_PUT_LE_ULONG( &byBuf[0], pIndex->freePage ); - HB_PUT_BE_ULONG( &byBuf[4], pIndex->ulVersion ); + HB_PUT_LE_UINT32( &byBuf[0], pIndex->freePage ); + HB_PUT_BE_UINT32( &byBuf[4], pIndex->ulVersion ); if ( hb_fsSeek( pIndex->hFile, 0x04, FS_SET ) != 0x04 || hb_fsWrite( pIndex->hFile, byBuf, 8) != 8 ) { hb_errInternal( EDBF_WRITE, "Write in index page failed (ver)", "", "" ); } + pIndex->fFlush = TRUE; pIndex->fChanged = FALSE; } #ifdef HB_CDX_DBGCODE @@ -1336,17 +1426,22 @@ static BOOL hb_cdxIndexUnLockWrite( LPCDXINDEX pIndex ) if ( pIndex->ulVersion != pIndex->freePage ) { BYTE byBuf[4]; - HB_PUT_LE_ULONG( &byBuf[0], pIndex->freePage ); + HB_PUT_LE_UINT32( &byBuf[0], pIndex->freePage ); if ( hb_fsSeek( pIndex->hFile, 0x04, FS_SET ) != 0x04 || hb_fsWrite( pIndex->hFile, byBuf, 4) != 4 ) { hb_errInternal( EDBF_WRITE, "Write in index page failed (ver.ex)", "", "" ); } pIndex->ulVersion = pIndex->freePage; + pIndex->fFlush = TRUE; #ifdef HB_CDX_DBGUPDT cdxWriteNO++; #endif } + else if ( pIndex->fChanged ) + { + pIndex->fFlush = TRUE; + } pIndex->fChanged = FALSE; } return TRUE; @@ -1369,6 +1464,7 @@ static void hb_cdxIndexDiscardBuffers( LPCDXINDEX pIndex ) hb_cdxTagClose( pIndex->pCompound ); hb_cdxTagPoolFree( pIndex->pCompound, 0 ); pIndex->pCompound->fRePos = TRUE; + pIndex->pCompound->curKeyState = 0; if ( pIndex->pCompound->CurKey ) pIndex->pCompound->CurKey->rec = 0; } @@ -1378,6 +1474,7 @@ static void hb_cdxIndexDiscardBuffers( LPCDXINDEX pIndex ) hb_cdxTagClose( pTag ); hb_cdxTagPoolFree( pTag, 0 ); pTag->fRePos = TRUE; + pTag->curKeyState = 0; if ( pTag->CurKey && !pTag->Custom ) pTag->CurKey->rec = 0; pTag = pTag->pNext; @@ -1455,7 +1552,7 @@ static BYTE * hb_cdxPageGetKeyVal( LPCDXPAGE pPage, SHORT iKey ) while ( pPage->bufKeyNum <= iKey ) { iPos = pPage->bufKeyNum * pPage->ReqByte; - iTmp = HB_GET_LE_USHORT( &pPage->node.extNode.keyPool[ iPos + pPage->ReqByte - 2 ] ) >> + iTmp = HB_GET_LE_UINT16( &pPage->node.extNode.keyPool[ iPos + pPage->ReqByte - 2 ] ) >> ( 16 - pPage->TCBits - pPage->DCBits ); iDup = ( pPage->bufKeyNum == 0 ) ? 0 : ( iTmp & pPage->DCMask ); iTrl = ( iTmp >> pPage->DCBits ) & pPage->TCMask; @@ -1493,11 +1590,11 @@ static ULONG hb_cdxPageGetKeyRec( LPCDXPAGE pPage, SHORT iKey ) hb_cdxErrInternal( "hb_cdxPageGetKeyRec: wrong iKey index." ); #endif if ( pPage->pKeyBuf ) - return HB_GET_LE_ULONG( &pPage->pKeyBuf[ ( iKey + 1 ) * ( pPage->TagParent->uiLen + 6 ) - 6 ] ); + return HB_GET_LE_UINT32( &pPage->pKeyBuf[ ( iKey + 1 ) * ( pPage->TagParent->uiLen + 6 ) - 6 ] ); else if ( pPage->PageType & CDX_NODE_LEAF ) - return HB_GET_LE_ULONG( &pPage->node.extNode.keyPool[ iKey * pPage->ReqByte ] ) & pPage->RNMask; + return HB_GET_LE_UINT32( &pPage->node.extNode.keyPool[ iKey * pPage->ReqByte ] ) & pPage->RNMask; else - return HB_GET_BE_ULONG( &pPage->node.intNode.keyPool[ + return HB_GET_BE_UINT32( &pPage->node.intNode.keyPool[ ( iKey + 1 ) * ( pPage->TagParent->uiLen + 8 ) - 8 ] ); } @@ -1512,7 +1609,7 @@ static ULONG hb_cdxPageGetKeyPage( LPCDXPAGE pPage, SHORT iKey ) if ( pPage->PageType & CDX_NODE_LEAF ) hb_cdxErrInternal( "hb_cdxPageGetKeyPage: page is a leaf." ); #endif - return HB_GET_BE_ULONG( &pPage->node.intNode.keyPool[ + return HB_GET_BE_UINT32( &pPage->node.intNode.keyPool[ ( iKey + 1 ) * ( pPage->TagParent->uiLen + 8 ) - 4 ] ); } @@ -1569,9 +1666,9 @@ static void hb_cdxPageCheckKeys( LPCDXPAGE pPage ) /* * Check decoded leaf page if all trailing and duplicate characters are set */ -static void hb_cdxPageCheckDupTrl( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys ) +static void hb_cdxPageCheckDupTrl( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys, BOOL fSpc ) { - SHORT iNum = pPage->TagParent->uiLen, iKey, iPos; + SHORT iNum = pPage->TagParent->uiLen, iKey, iPos, iFree = CDX_EXT_FREESPACE; SHORT iLen = iNum + 6; BYTE bDup, bTrl; BYTE bTrail = ( pPage->TagParent->uiType == 'C' ) ? ' ' : '\0'; @@ -1585,7 +1682,11 @@ static void hb_cdxPageCheckDupTrl( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys ++bTrl; if ( iKey > 0 ) { - SHORT iMax = iNum - /* bTrl; */ HB_MAX( pKeyBuf[ iPos - 1 ], bTrl ); +#ifdef HB_CDX_PACKTRAIL + SHORT iMax = iNum - bTrl; +#else + SHORT iMax = iNum - HB_MAX( pKeyBuf[ iPos - 1 ], bTrl ); +#endif while ( bDup < iMax && pKeyBuf[ iPos + bDup ] == pKeyBuf[ iPos - iLen + bDup ] ) ++bDup; @@ -1598,7 +1699,7 @@ static void hb_cdxPageCheckDupTrl( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys } if ( bDup != ( iKey == 0 ? 0 : pKeyBuf[ iPos + iNum + 4 ] ) ) { - printf("\r\nbDup=%d, keybuf->bDup=%d, iKey=%d/%d\r\n", bDup, pKeyBuf[ iPos + iNum + 4 ], iKey, iKeys ); + printf("\r\nbDup=%d, keybuf->bDup=%d (bTrl=%d), iKey=%d/%d\r\n", bDup, pKeyBuf[ iPos + iNum + 4 ], bTrl, iKey, iKeys ); fflush(stdout); bErr = TRUE; } @@ -1609,13 +1710,13 @@ static void hb_cdxPageCheckDupTrl( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys &pKeyBuf[ iPos - iLen ], iNum, &pKeyBuf[ iPos ], iNum, TRUE ); if ( K > 0 || ( K == 0 && - HB_GET_LE_ULONG( &pKeyBuf[ iPos + iNum - iLen ] ) >= - HB_GET_LE_ULONG( &pKeyBuf[ iPos + iNum ] ) ) ) + HB_GET_LE_UINT32( &pKeyBuf[ iPos + iNum - iLen ] ) >= + HB_GET_LE_UINT32( &pKeyBuf[ iPos + iNum ] ) ) ) { printf( "\r\nikey=%d, iKeys=%d, K=%d, ulRecPrev=%ld, ulRec=%ld", iKey, iKeys, K, - HB_GET_LE_ULONG( &pKeyBuf[ iPos + iNum - iLen ] ), - HB_GET_LE_ULONG( &pKeyBuf[ iPos + iNum ] ) ); + (ULONG) HB_GET_LE_UINT32( &pKeyBuf[ iPos + iNum - iLen ] ), + (ULONG) HB_GET_LE_UINT32( &pKeyBuf[ iPos + iNum ] ) ); printf( "\r\npbValPrev=[%s] pbVal=[%s], [%d], pKeyBuf=%p", &pKeyBuf[ iPos - iLen ], &pKeyBuf[ iPos ], memcmp( &pKeyBuf[ iPos - iLen ], &pKeyBuf[ iPos ], iNum ), @@ -1624,9 +1725,31 @@ static void hb_cdxPageCheckDupTrl( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys bErr = TRUE; } } + iFree -= iNum + pPage->ReqByte - bDup - bTrl; + } + if ( fSpc && ( iFree != pPage->iFree /* || iFree < 0 */ ) ) + { + printf( "\r\nFreeSpace calculated wrong! iFree=%d, pPage->iFree=%d", + iFree, pPage->iFree ); + fflush(stdout); + bErr = TRUE; } if ( bErr ) + { + printf("\r\nPage=%lx, Page->iFree=%d, iLen=%d\r\n", pPage->Page, pPage->iFree, iNum ); + fflush(stdout); hb_cdxErrInternal( "hb_cdxPageCheckDupTrl: index corrupted." ); + } +} + +static void hb_cdxPageLeafDecode( LPCDXPAGE pPage, BYTE * pKeyBuf ); +static void hb_cdxPageCheckDupTrlRaw( LPCDXPAGE pPage ) +{ + BYTE *pKeyBuf = (BYTE *) hb_xgrab( pPage->iKeys * ( pPage->TagParent->uiLen + 6 ) ); + + hb_cdxPageLeafDecode( pPage, pKeyBuf ); + hb_cdxPageCheckDupTrl( pPage, pKeyBuf, pPage->iKeys, TRUE ); + hb_xfree( pKeyBuf ); } #endif @@ -1643,11 +1766,11 @@ static void hb_cdxSetLeafRecord( BYTE *pDst, ULONG ulRec, int iDup, int iTrl, for ( i = 0; i < iReq; i++, ulRec >>= 8 ) { if ( i < iReq - 2 ) - pDst[ i ] = ulRec & 0xff; + pDst[ i ] = ( BYTE ) ( ulRec & 0xff ); else if ( i == iReq - 2 ) - pDst[ i ] = ( ulRec & 0xff ) | ( usBit & 0xff ); + pDst[ i ] = ( BYTE ) ( ulRec & 0xff ) | ( usBit & 0xff ); else - pDst[ i ] = ( ulRec & 0xff ) | ( ( usBit >> 8 ) & 0xff ); + pDst[ i ] = ( BYTE ) ( ulRec & 0xff ) | ( ( usBit >> 8 ) & 0xff ); } } @@ -1670,7 +1793,7 @@ static void hb_cdxPageLeafEncode( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys ) #ifdef HB_CDX_DBGCODE_EXT if ( ! pKeyBuf ) hb_cdxErrInternal( "hb_cdxPageLeafEncode: page has no buffer." ); - hb_cdxPageCheckDupTrl( pPage, pKeyBuf, iKeys ); + hb_cdxPageCheckDupTrl( pPage, pKeyBuf, iKeys, TRUE ); #endif iNum = pPage->TagParent->uiLen; iLen = iNum + 6; @@ -1683,7 +1806,7 @@ static void hb_cdxPageLeafEncode( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys ) iDup = pSrc[ iNum + 4 ]; iTrl = pSrc[ iNum + 5 ]; iTmp = iNum - iTrl - iDup; - hb_cdxSetLeafRecord( pRecPos, HB_GET_LE_ULONG( &pSrc[ iNum ] ), iDup, iTrl, + hb_cdxSetLeafRecord( pRecPos, HB_GET_LE_UINT32( &pSrc[ iNum ] ), iDup, iTrl, iReq, pPage->DCBits, pPage->TCBits ); if ( iTmp > 0 ) { @@ -1705,7 +1828,7 @@ static void hb_cdxPageLeafEncode( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys ) if ( pKeyPos - pRecPos != pPage->iFree ) { printf("\r\nPage=0x%lx, calc=%d, iFree=%d, req=%d, keys=%d, keyLen=%d\r\n", - pPage->Page, pKeyPos - pRecPos, pPage->iFree, pPage->ReqByte, iKeys, iNum ); + pPage->Page, (int) (pKeyPos - pRecPos), pPage->iFree, pPage->ReqByte, iKeys, iNum ); fflush(stdout); hb_cdxErrInternal( "hb_cdxPageLeafEncode: FreeSpace calculated wrong!." ); } @@ -1723,7 +1846,7 @@ static void hb_cdxPageLeafEncode( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys ) pPage->pKeyBuf = pKeyBf; } hb_cdxPageCheckKeys( pPage ); - hb_cdxPageCheckDupTrl( pPage, pKeyBuf, pPage->iKeys ); + hb_cdxPageCheckDupTrl( pPage, pKeyBuf, pPage->iKeys, TRUE ); #endif } @@ -1751,7 +1874,7 @@ static void hb_cdxPageLeafDecode( LPCDXPAGE pPage, BYTE * pKeyBuf ) for ( iKey = 0; iKey < pPage->iKeys; iKey++, pRec += iReq ) { pTmp = &pRec[ iReq - 2 ]; - iTmp = HB_GET_LE_USHORT( pTmp ) >> iBits; + iTmp = HB_GET_LE_UINT16( pTmp ) >> iBits; iDup = ( iKey == 0 ) ? 0 : ( iTmp & pPage->DCMask ); iTrl = ( iTmp >> pPage->DCBits ) & pPage->TCMask; iNew = iLen - iDup - iTrl; @@ -1778,8 +1901,8 @@ static void hb_cdxPageLeafDecode( LPCDXPAGE pPage, BYTE * pKeyBuf ) memset( pDst, bTrail, iTrl ); pDst += iTrl; } - ulRec = HB_GET_LE_ULONG( pRec ) & pPage->RNMask; - HB_PUT_LE_ULONG( pDst, ulRec ); + ulRec = HB_GET_LE_UINT32( pRec ) & pPage->RNMask; + HB_PUT_LE_UINT32( pDst, ulRec ); pDst += 4; *(pDst++) = ( BYTE ) iDup; *(pDst++) = ( BYTE ) iTrl; @@ -1812,7 +1935,7 @@ static void hb_cdxPageLeafInitSpace( LPCDXPAGE pPage ) /* * calculate the size of keys stored in buffer, return - * the nymber of keys wich can be stored in the page + * the number of keys wich can be stored in the page */ static void hb_cdxPageCalcLeafSpace( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKeys ) { @@ -1826,7 +1949,7 @@ static void hb_cdxPageCalcLeafSpace( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKey RNMask = pPage->RNMask; ReqByte = pPage->ReqByte; #ifdef HB_CDX_DBGCODE_EXT - hb_cdxPageCheckDupTrl( pPage, pKeyBuf, iKeys ); + hb_cdxPageCheckDupTrl( pPage, pKeyBuf, iKeys, FALSE ); #endif for ( iKey = 0; iKey < iKeys; iKey++ ) { @@ -1836,7 +1959,7 @@ static void hb_cdxPageCalcLeafSpace( LPCDXPAGE pPage, BYTE * pKeyBuf, SHORT iKey bDup = bPtr[ 4 ] = 0; else bDup = bPtr[ 4 ]; - ulRec = HB_GET_LE_ULONG( bPtr ); + ulRec = HB_GET_LE_UINT32( bPtr ); iSize = ReqByte + iNum - bTrl - bDup; if ( ulRec > RNMask ) { @@ -1888,9 +2011,10 @@ static int hb_cdxPageLeafDelKey( LPCDXPAGE pPage ) pPage->pKeyBuf = pKeyBuf; } #ifdef HB_CDX_DSPDBG_INFO - printf("\r\ndelkey: Page=%lx, iKey=%d/%d, rec=%ld", + printf("\r\ndelkey: Page=%lx, iKey=%d/%d, rec=%ld, iFree=%d", pPage->Page, iKey, pPage->iKeys, - HB_GET_LE_ULONG( &pPage->pKeyBuf[ ( iKey + 1 ) * iLen - 6 ] )); + (ULONG) HB_GET_LE_UINT32( &pPage->pKeyBuf[ ( iKey + 1 ) * iLen - 6 ] ), + pPage->iFree ); fflush(stdout); #endif iSpc = pPage->ReqByte + pPage->TagParent->uiLen - @@ -1904,9 +2028,12 @@ static int hb_cdxPageLeafDelKey( LPCDXPAGE pPage ) { SHORT iPrev = ( iKey - 1 ) * iLen, iNext = ( iKey + 1 ) * iLen, iNum = pPage->TagParent->uiLen; - iNum -= /* pPage->pKeyBuf[ iNext + iNum + 5 ]; */ - HB_MAX( pPage->pKeyBuf[ iNext + iLen - 1 ], +#ifdef HB_CDX_PACKTRAIL + iNum -= pPage->pKeyBuf[ iNext + iLen - 1 ]; +#else + iNum -= HB_MAX( pPage->pKeyBuf[ iNext + iLen - 1 ], pPage->pKeyBuf[ iPrev + iLen - 1 ] ); +#endif iDup = HB_MIN( pPage->pKeyBuf[ iPos ], pPage->pKeyBuf[ iNext - 2] ); if ( iDup > iNum ) @@ -1919,6 +2046,19 @@ static int hb_cdxPageLeafDelKey( LPCDXPAGE pPage ) pPage->pKeyBuf[ iNext + iDup ] ) ++iDup; } +#ifdef HB_CDX_DSPDBG_INFO + printf("+%d=%d", iSpc+iDup, pPage->iFree+iSpc+iDup ); + if ( iSpc+iDup < 0 ) + printf( " iLen=%d, iDup=%d, iNum=%d pd=%d pt=%d cd=%d ct=%d nd=%d nt=%d", + iLen-6, iDup, iNum, + pPage->pKeyBuf[ iPrev + iLen - 2 ], + pPage->pKeyBuf[ iPrev + iLen - 1 ], + pPage->pKeyBuf[ ( iKey + 1 ) * iLen - 2 ], + pPage->pKeyBuf[ ( iKey + 1 ) * iLen - 1 ], + pPage->pKeyBuf[ iNext + iLen - 2 ], + pPage->pKeyBuf[ iNext + iLen - 1 ] ); + fflush(stdout); +#endif } iSpc += ( pPage->pKeyBuf[ iPos ] = ( BYTE ) iDup ); } @@ -1932,12 +2072,14 @@ static int hb_cdxPageLeafDelKey( LPCDXPAGE pPage ) pPage->fBufChanged = pPage->fChanged = TRUE; #ifdef HB_CDX_DBGCODE_EXT hb_cdxPageCheckKeys( pPage ); - hb_cdxPageCheckDupTrl( pPage, pPage->pKeyBuf, pPage->iKeys ); + hb_cdxPageCheckDupTrl( pPage, pPage->pKeyBuf, pPage->iKeys, TRUE ); #endif if ( iKey >= pPage->iKeys ) iRet |= NODE_NEWLASTKEY; if ( pPage->iKeys == 0 ) iRet |= NODE_JOIN; + else if ( pPage->iFree < 0 ) + iRet |= NODE_SPLIT; /* if ( pPage->iFree >= CDX_EXT_FREESPACE / 2 ) */ if ( pPage->iFree >= pPage->ReqByte ) iRet |= NODE_BALANCE; @@ -1978,7 +2120,7 @@ static int hb_cdxPageLeafAddKey( LPCDXPAGE pPage, LPCDXKEY pKey ) #ifdef HB_CDX_DBGCODE_EXT hb_cdxPageCheckKeys( pPage ); - hb_cdxPageCheckDupTrl( pPage, pPage->pKeyBuf, pPage->iKeys ); + hb_cdxPageCheckDupTrl( pPage, pPage->pKeyBuf, pPage->iKeys, TRUE ); #endif iTrl = iDup = 0; @@ -1997,12 +2139,16 @@ static int hb_cdxPageLeafAddKey( LPCDXPAGE pPage, LPCDXKEY pKey ) memcpy( &pPage->pKeyBuf[ iPos ], pKey->val, pKey->len ); memset( &pPage->pKeyBuf[ iPos + pKey->len ], bTrail, iNum - pKey->len ); } - HB_PUT_LE_ULONG( &pPage->pKeyBuf[ iPos + iNum ], pKey->rec ); + HB_PUT_LE_UINT32( &pPage->pKeyBuf[ iPos + iNum ], pKey->rec ); while ( iTrl < iNum && pPage->pKeyBuf[ iPos + iNum - iTrl - 1 ] == bTrail ) ++iTrl; if ( iKey > 0 ) { +#ifdef HB_CDX_PACKTRAIL + iMax = iNum - iTrl; +#else iMax = iNum - HB_MAX( iTrl, pPage->pKeyBuf[ iPos - 1 ] ); +#endif if ( iDup > iMax ) { iDup = iMax; @@ -2019,7 +2165,11 @@ static int hb_cdxPageLeafAddKey( LPCDXPAGE pPage, LPCDXKEY pKey ) iSpc = pPage->ReqByte + iNum - iTrl - iDup; if ( iKey < pPage->iKeys ) { +#ifdef HB_CDX_PACKTRAIL + iMax = iNum - pPage->pKeyBuf[ iPos + iLen + iLen - 1 ]; +#else iMax = iNum - HB_MAX( iTrl, pPage->pKeyBuf[ iPos + iLen + iLen - 1 ] ); +#endif iSpc += pPage->pKeyBuf[ iPos + iLen + iLen - 2 ]; iDup = 0; while ( iDup < iMax && pPage->pKeyBuf[ iPos + iDup ] == @@ -2039,7 +2189,7 @@ static int hb_cdxPageLeafAddKey( LPCDXPAGE pPage, LPCDXKEY pKey ) pPage->fBufChanged = pPage->fChanged = TRUE; #ifdef HB_CDX_DBGCODE_EXT hb_cdxPageCheckKeys( pPage ); - hb_cdxPageCheckDupTrl( pPage, pPage->pKeyBuf, pPage->iKeys ); + hb_cdxPageCheckDupTrl( pPage, pPage->pKeyBuf, pPage->iKeys, TRUE ); #endif if ( iKey >= pPage->iKeys - 1 ) iRet |= NODE_NEWLASTKEY; @@ -2088,8 +2238,8 @@ static void hb_cdxPageIntSetKey( LPCDXPAGE pPage, SHORT iKey, BOOL fIns, BYTE * memset( &pPage->node.intNode.keyPool[ iPos ], ( pPage->TagParent->uiType == 'C' ) ? ' ' : '\0', iLen ); if ( ulRec ) - HB_PUT_BE_ULONG( &pPage->node.intNode.keyPool[ iPos + iLen ], ulRec ); - HB_PUT_BE_ULONG( &pPage->node.intNode.keyPool[ iPos + iLen + 4 ], ulPag ); + HB_PUT_BE_UINT32( &pPage->node.intNode.keyPool[ iPos + iLen ], ulRec ); + HB_PUT_BE_UINT32( &pPage->node.intNode.keyPool[ iPos + iLen + 4 ], ulPag ); pPage->fChanged = TRUE; } @@ -2103,7 +2253,7 @@ static void hb_cdxPageIntDelKey( LPCDXPAGE pPage, SHORT iKey ) #ifdef HB_CDX_DSPDBG_INFO printf("\r\nintDelKey: Page=%lx, iKey=%d/%d, ulPag=%lx", pPage->Page, iKey, pPage->iKeys, - HB_GET_BE_ULONG( &pPage->node.intNode.keyPool[ (iKey+1) * iLen - 4 ] ) ); + (ULONG) HB_GET_BE_UINT32( &pPage->node.intNode.keyPool[ (iKey+1) * iLen - 4 ] ) ); fflush(stdout); #endif #ifdef HB_CDX_DBGCODE @@ -2136,16 +2286,16 @@ static void hb_cdxPageLoad( LPCDXPAGE pPage ) pPage->fBufChanged = FALSE; } hb_cdxIndexPageRead( pPage->TagParent->pIndex, pPage->Page, (BYTE *) &pPage->node, sizeof( CDXNODE ) ); - pPage->PageType = ( BYTE ) HB_GET_LE_USHORT( pPage->node.intNode.attr ); - pPage->Left = HB_GET_LE_ULONG( pPage->node.intNode.leftPtr ); - pPage->Right = HB_GET_LE_ULONG( pPage->node.intNode.rightPtr ); - pPage->iKeys = HB_GET_LE_USHORT( pPage->node.intNode.nKeys ); + pPage->PageType = ( BYTE ) HB_GET_LE_UINT16( pPage->node.intNode.attr ); + pPage->Left = HB_GET_LE_UINT32( pPage->node.intNode.leftPtr ); + pPage->Right = HB_GET_LE_UINT32( pPage->node.intNode.rightPtr ); + pPage->iKeys = HB_GET_LE_UINT16( pPage->node.intNode.nKeys ); pPage->fChanged = FALSE; if ( ( pPage->PageType & CDX_NODE_LEAF ) != 0 ) { - pPage->iFree = HB_GET_LE_USHORT( pPage->node.extNode.freeSpc ); - pPage->RNMask = HB_GET_LE_ULONG( pPage->node.extNode.recMask ); + pPage->iFree = HB_GET_LE_UINT16( pPage->node.extNode.freeSpc ); + pPage->RNMask = HB_GET_LE_UINT32( pPage->node.extNode.recMask ); /* TODO: redundant, use it directly */ pPage->DCMask = pPage->node.extNode.dupMask; pPage->TCMask = pPage->node.extNode.trlMask; @@ -2184,15 +2334,15 @@ static void hb_cdxPageStore( LPCDXPAGE pPage ) else if ( pPage->iKeys > pPage->TagParent->MaxKeys ) hb_cdxErrInternal( "hb_cdxPageStore: number of keys exceed!." ); #endif - HB_PUT_LE_USHORT( pPage->node.intNode.attr, pPage->PageType ); - HB_PUT_LE_USHORT( pPage->node.intNode.nKeys, pPage->iKeys ); - HB_PUT_LE_ULONG( pPage->node.intNode.leftPtr, pPage->Left ); - HB_PUT_LE_ULONG( pPage->node.intNode.rightPtr, pPage->Right ); + HB_PUT_LE_UINT16( pPage->node.intNode.attr, pPage->PageType ); + HB_PUT_LE_UINT16( pPage->node.intNode.nKeys, pPage->iKeys ); + HB_PUT_LE_UINT32( pPage->node.intNode.leftPtr, pPage->Left ); + HB_PUT_LE_UINT32( pPage->node.intNode.rightPtr, pPage->Right ); if ( ( pPage->PageType & CDX_NODE_LEAF ) != 0 ) { - HB_PUT_LE_USHORT( pPage->node.extNode.freeSpc, pPage->iFree ); - HB_PUT_LE_ULONG( pPage->node.extNode.recMask, pPage->RNMask ); + HB_PUT_LE_UINT16( pPage->node.extNode.freeSpc, pPage->iFree ); + HB_PUT_LE_UINT32( pPage->node.extNode.recMask, pPage->RNMask ); /* TODO: redundant, use it directly */ pPage->node.extNode.dupMask = pPage->DCMask; pPage->node.extNode.trlMask = pPage->TCMask; @@ -2509,7 +2659,12 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, int iChildRet ) /* update number of duplicate characters when join pages */ if ( pPtr > pKeyPool ) { - BYTE bDup = 0, bMax = iLen - 6 - HB_MAX( pPtr[ iLen - 1 ], pPtr[ -1 ] ); + BYTE bDup = 0, bMax; +#ifdef HB_CDX_PACKTRAIL + bMax = iLen - 6 - pPtr[ iLen - 1 ]; +#else + bMax = iLen - 6 - HB_MAX( pPtr[ iLen - 1 ], pPtr[ -1 ] ); +#endif while ( bDup < bMax && pPtr[ bDup ] == pPtr[ bDup - iLen ] ) ++bDup; pPtr[ iLen - 2 ] = bDup; @@ -2537,7 +2692,7 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, int iChildRet ) } #ifdef HB_CDX_DBGCODE_EXT - hb_cdxPageCheckDupTrl( pPage, pKeyPool, iKeys ); + hb_cdxPageCheckDupTrl( pPage, pKeyPool, iKeys, FALSE ); #endif pPtr = pKeyPool; fIns = FALSE; @@ -2551,25 +2706,32 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, int iChildRet ) else lpTmpPage = NULL; +#if 1 if ( !fIns && lpTmpPage != NULL ) { -#if 1 SHORT j, iSize = 0, iMaxReq; ULONG ulMaxRec = 0, ul; BYTE * pbKey, bMax; for ( j = 0; j < iKeys; j++ ) { - if ( ulMaxRec < ( ul = HB_GET_LE_ULONG( &pPtr[ ( j + 1 ) * iLen - 6 ] ) ) ) + if ( ulMaxRec < ( ul = HB_GET_LE_UINT32( &pPtr[ ( j + 1 ) * iLen - 6 ] ) ) ) ulMaxRec = ul; iSize += iLen - 6 - ( j == 0 ? 0 : pPtr[ ( j + 1 ) * iLen - 2 ] ) - pPtr[ ( j + 1 ) * iLen - 1 ]; } pbKey = hb_cdxPageGetKeyVal( lpTmpPage, 0 ); - bMax = ( lpTmpPage->node.extNode.keyPool[ lpTmpPage->ReqByte - 2 ] + bMax = ( HB_GET_LE_UINT16( &lpTmpPage->node.extNode.keyPool[ lpTmpPage->ReqByte - 2 ] ) >> ( 16 - lpTmpPage->TCBits ) ) & lpTmpPage->TCMask; +#ifdef HB_CDX_PACKTRAIL + bMax = iLen - 6 - bMax; +#else bMax = iLen - 6 - HB_MAX( pPtr[ iKeys * iLen - 1 ], bMax ); +#endif for ( j = 0; j < bMax && pPtr[ ( iKeys - 1 ) * iLen + j ] == pbKey[ j ]; j++ ); +#ifdef HB_CDX_DSPDBG_INFO + printf("\r\nbDup=%d, bTrl=%d ", j, iLen - 6 - bMax ); fflush(stdout); +#endif iSize -= j; iMaxReq = lpTmpPage->ReqByte; ul = lpTmpPage->RNMask; @@ -2583,19 +2745,11 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, int iChildRet ) ( iMaxReq - lpTmpPage->ReqByte ) * lpTmpPage->iKeys; if ( iSize < 0 ) fIns = TRUE; -#else - if ( lpTmpPage->ReqByte > iMaxReq ) - iMaxReq = lpTmpPage->ReqByte; - if ( lpTmpPage->iFree < iKeys * ( iLen - 6 + iMaxReq ) + - ( iMaxReq - lpTmpPage->ReqByte ) * lpTmpPage->iKeys ) - fIns = TRUE; -#endif else { - /* TODO: iBufSize to avoid new allocation if old buffer is large enough */ #ifdef HB_CDX_DSPDBG_INFO - printf("\r\ninserting #keys=%d/%d (%d) parent=%lx, child=%lx, rec=%ld", - iKeys, lpTmpPage->iKeys, i, pPage->Page, lpTmpPage->Page, HB_GET_LE_ULONG( pPtr + iLen - 6 )); + printf("\r\ninserting bDup=%d #keys=%d/%d (%d) parent=%lx, child=%lx (%d), rec=%ld", + j, iKeys, lpTmpPage->iKeys, i, pPage->Page, lpTmpPage->Page, iSize, (ULONG) HB_GET_LE_UINT32( pPtr + iLen - 6 )); fflush(stdout); #endif if ( iBufSize >= iKeys + lpTmpPage->iKeys ) @@ -2619,17 +2773,23 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, int iChildRet ) memcpy( pPtr, lpTmpPage->pKeyBuf, lpTmpPage->iKeys * iLen ); else hb_cdxPageLeafDecode( lpTmpPage, pPtr ); +#ifdef HB_CDX_PACKTRAIL + bMax = iLen - 6 - pPtr[ iLen - 1 ]; +#else bMax = iLen - 6 - HB_MAX( pPtr[ iLen - 1 ], pPtr[ -1 ] ); +#endif while ( bDup < bMax && pPtr[ bDup ] == pPtr[ bDup - iLen ] ) ++bDup; pPtr[ iLen - 2 ] = bDup; iKeys += lpTmpPage->iKeys; +#ifdef HB_CDX_DSPDBG_INFO + printf(" bDup2=%d, bTrl2=%d ", bDup, pPtr[ iLen - 1 ] ); fflush(stdout); +#endif } pPtr = pKeyPool; childs[i] = lpTmpPage; if ( iFirstKey + i >= pPage->iKeys ) iRet |= NODE_NEWLASTKEY; -#if 0 #ifdef HB_CDX_DBGCODE_EXT childs[i]->iKeys = 0; if ( childs[i]->pKeyBuf ) @@ -2640,15 +2800,16 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, int iChildRet ) } hb_cdxPageCalcLeafSpace( childs[i], pPtr, iKeys ); hb_cdxPageLeafEncode( childs[i], pPtr, childs[i]->iKeys ); + iSize += ( iMaxReq - childs[i]->ReqByte ) * childs[i]->iKeys; if ( iSize != childs[i]->iFree ) { printf("\r\ninserting, iSize=%d, childs[i]->iFree=%d", iSize, childs[i]->iFree); fflush(stdout); printf("\r\niKeys=%d, iMaxReq=%d", iKeys, iMaxReq); fflush(stdout); hb_cdxErrInternal( "hb_cdxPageGetChild: index corrupted." ); } -#endif #endif } +#endif } else fIns = TRUE; @@ -2702,7 +2863,7 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, int iChildRet ) /* update parent key */ if ( i < iBlncKeys ) hb_cdxPageIntSetKey( pPage, iFirstKey + i, fIns, - pPtr - iLen, HB_GET_LE_ULONG( pPtr - 6 ), + pPtr - iLen, HB_GET_LE_UINT32( pPtr - 6 ), childs[i]->Page ); else iBlncKeys++; @@ -2838,7 +2999,7 @@ static int hb_cdxPageKeyIntBalance( LPCDXPAGE pPage, int iChildRet ) } #ifdef HB_CDX_DSPDBG_INFO - printf("\r\nbalance: Page=%lx (%d/%d)", pPage->Page, iFirstKey, iBlncKeys); + printf("\r\nbalance: Page=%lx(%d) (%d/%d)", pPage->Page, pPage->iKeys, iFirstKey, iBlncKeys); fflush(stdout); #endif @@ -2896,7 +3057,7 @@ static int hb_cdxPageKeyIntBalance( LPCDXPAGE pPage, int iChildRet ) #else iDiv = iMax - iMin; #endif - if ( iDiv >= 2 || fForce ) + if ( iKeys > 0 && ( iDiv >= 2 || fForce ) ) { #if 1 if ( iBlncKeys == 1 && iKeys > pPage->TagParent->MaxKeys && @@ -2913,16 +3074,16 @@ static int hb_cdxPageKeyIntBalance( LPCDXPAGE pPage, int iChildRet ) else #endif { - iMax = ( iKeys + iNeedKeys - 1 ) / iNeedKeys; - iMin = HB_MAX( iKeys / iNeedKeys, 1 ); + iMin = HB_MAX( iKeys / iNeedKeys, 2 ); + iMax = HB_MAX( ( iKeys + iNeedKeys - 1 ) / iNeedKeys, iMin ); for ( i = iBlncKeys - 1; i > 1 && childs[i]->iKeys >= iMin && childs[i]->iKeys <= iMax; i-- ) { iKeys -= childs[i]->iKeys; hb_cdxPageFree( childs[i], FALSE ); iBlncKeys--; - iMax = ( iKeys + iNeedKeys - 1 ) / iNeedKeys; - iMin = HB_MAX( iKeys / iNeedKeys, 1 ); + iMin = HB_MAX( iKeys / iNeedKeys, 2 ); + iMax = HB_MAX( ( iKeys + iNeedKeys - 1 ) / iNeedKeys, iMin ); } while ( iBlncKeys > 2 && childs[0]->iKeys >= iMin && childs[0]->iKeys <= iMax ) { @@ -2934,8 +3095,8 @@ static int hb_cdxPageKeyIntBalance( LPCDXPAGE pPage, int iChildRet ) { childs[i] = childs[i+1]; } - iMax = ( iKeys + iNeedKeys - 1 ) / iNeedKeys; - iMin = HB_MAX( iKeys / iNeedKeys, 1 ); + iMin = HB_MAX( iKeys / iNeedKeys, 2 ); + iMax = HB_MAX( ( iKeys + iNeedKeys - 1 ) / iNeedKeys, iMin ); } } } @@ -3086,7 +3247,7 @@ static int hb_cdxPageKeyIntBalance( LPCDXPAGE pPage, int iChildRet ) if ( iFirstKey + i < pPage->iKeys ) { hb_cdxPageIntSetKey( pPage, iFirstKey + i, FALSE, - pPtr - iLen, HB_GET_BE_ULONG( pPtr - 8 ), + pPtr - iLen, HB_GET_BE_UINT32( pPtr - 8 ), childs[i]->Page ); } #ifdef HB_CDX_DSPDBG_INFO @@ -3197,14 +3358,14 @@ static int hb_cdxPageRootSplit( LPCDXPAGE pPage ) /* * remove current Key from Tag */ -static int hb_cdxPageKeyDelete( LPCDXPAGE pPage ) +static int hb_cdxPageKeyRemove( LPCDXPAGE pPage ) { int iChildRet; if ( pPage->PageType & CDX_NODE_LEAF ) iChildRet = hb_cdxPageLeafDelKey( pPage ); else /* interior node */ - iChildRet = hb_cdxPageKeyDelete( pPage->Child ); + iChildRet = hb_cdxPageKeyRemove( pPage->Child ); return hb_cdxPageBalance( pPage, iChildRet ); } @@ -3255,20 +3416,20 @@ static void hb_cdxTagHeaderStore( LPCDXTAG pTag ) pTag->OptFlags |= CDX_TYPE_FORFILTER; memset( &tagHeader, 0, sizeof( CDXTAGHEADER ) ); - HB_PUT_LE_ULONG( tagHeader.rootPtr, pTag->RootBlock ); - HB_PUT_LE_USHORT( tagHeader.keySize, pTag->uiLen ); + HB_PUT_LE_UINT32( tagHeader.rootPtr, pTag->RootBlock ); + HB_PUT_LE_UINT16( tagHeader.keySize, pTag->uiLen ); tagHeader.indexOpt = pTag->OptFlags; tagHeader.indexSig = 1; if ( !pTag->AscendKey ) - HB_PUT_LE_USHORT( tagHeader.ascendFlg, 1 ); + HB_PUT_LE_UINT16( tagHeader.ascendFlg, 1 ); uiKeyLen = pTag->KeyExpr == NULL ? 0 : strlen( pTag->KeyExpr ); uiForLen = pTag->ForExpr == NULL ? 0 : strlen( pTag->ForExpr ); - HB_PUT_LE_USHORT( tagHeader.keyExpPos, 0 ); - HB_PUT_LE_USHORT( tagHeader.keyExpLen, uiKeyLen + 1 ); - HB_PUT_LE_USHORT( tagHeader.forExpPos, uiKeyLen + 1 ); - HB_PUT_LE_USHORT( tagHeader.forExpLen, uiForLen + 1 ); + HB_PUT_LE_UINT16( tagHeader.keyExpPos, 0 ); + HB_PUT_LE_UINT16( tagHeader.keyExpLen, uiKeyLen + 1 ); + HB_PUT_LE_UINT16( tagHeader.forExpPos, uiKeyLen + 1 ); + HB_PUT_LE_UINT16( tagHeader.forExpLen, uiForLen + 1 ); if ( uiKeyLen > 0 ) { strcpy( ( char * ) tagHeader.keyExpPool, pTag->KeyExpr ); @@ -3291,7 +3452,7 @@ static void hb_cdxTagLoad( LPCDXTAG pTag ) /* read the page from a file */ hb_cdxIndexPageRead( pTag->pIndex, pTag->TagBlock, (BYTE *) &pHeader, sizeof( CDXTAGHEADER ) ); - pTag->RootBlock = HB_GET_LE_ULONG( pHeader.rootPtr ); + pTag->RootBlock = HB_GET_LE_UINT32( pHeader.rootPtr ); /* Return if: * no root page allocated * invalid root page offset (position inside an index file) @@ -3299,26 +3460,21 @@ static void hb_cdxTagLoad( LPCDXTAG pTag ) */ if ( pTag->RootBlock == 0 || pTag->RootBlock % CDX_PAGELEN != 0 || pTag->RootBlock >= hb_fsSeek( pTag->pIndex->hFile, 0, FS_END ) || - HB_GET_LE_USHORT( pHeader.keySize ) > CDX_MAXKEY ) + HB_GET_LE_UINT16( pHeader.keySize ) > CDX_MAXKEY ) { /* TODO: pTag->RootBlock = 0; || {internal,RT}Error ? */ return; } - pTag->uiLen = HB_GET_LE_USHORT( pHeader.keySize ); + pTag->uiLen = HB_GET_LE_UINT16( pHeader.keySize ); pTag->MaxKeys = CDX_INT_FREESPACE / ( pTag->uiLen + 8 ); pTag->OptFlags = pHeader.indexOpt; - pTag->UniqueKey = ( pTag->OptFlags & CDX_TYPE_UNIQUE ); - pTag->Temporary = ( pTag->OptFlags & CDX_TYPE_TEMPORARY ); - pTag->Custom = ( pTag->OptFlags & CDX_TYPE_CUSTOM ); - pTag->AscendKey = pTag->UsrAscend = ( HB_GET_LE_USHORT( pHeader.ascendFlg ) == 0 ); + pTag->UniqueKey = ( pTag->OptFlags & CDX_TYPE_UNIQUE ) != 0; + pTag->Temporary = ( pTag->OptFlags & CDX_TYPE_TEMPORARY ) != 0; + pTag->Custom = ( pTag->OptFlags & CDX_TYPE_CUSTOM ) != 0; + pTag->AscendKey = pTag->UsrAscend = ( HB_GET_LE_UINT16( pHeader.ascendFlg ) == 0 ); pTag->UsrUnique = FALSE; - pTag->KeyExpr = ( char * ) hb_xgrab( CDX_MAXKEY + 1 ); - /* QUESTION: Is UPPER a valid operation here? - * This will break expressions like: - * somefield+'lowerletter'+otherfield - * TODO: - */ - hb_strncpyUpper( pTag->KeyExpr, ( char * ) pHeader.keyExpPool, CDX_MAXKEY ); + pTag->KeyExpr = ( char * ) hb_xgrab( CDX_MAXKEY + 1 ); + hb_strncpyTrim( pTag->KeyExpr, ( const char * ) pHeader.keyExpPool, CDX_MAXKEY ); if ( ( pTag->OptFlags & CDX_TYPE_STRUCTURE ) || pTag->KeyExpr[ 0 ] == 0 ) return; @@ -3335,7 +3491,7 @@ static void hb_cdxTagLoad( LPCDXTAG pTag ) { case HB_IT_INTEGER: case HB_IT_LONG: -#ifndef HB_LONG_LONG_OFF +#ifdef HB_IT_LONGLONG case HB_IT_LONGLONG: #endif case HB_IT_DOUBLE: @@ -3363,15 +3519,14 @@ static void hb_cdxTagLoad( LPCDXTAG pTag ) if ( pTag->uiType == 'C' ) hb_cdxMakeSortTab( pTag->pIndex->pArea ); - pTag->nField = hb_rddFieldIndex( ( AREAP ) pTag->pIndex->pArea, pTag->KeyExpr ); + pTag->nField = hb_cdxFieldIndex( pTag->pIndex->pArea, pTag->KeyExpr ); /* Check if there is a FOR expression CDX_TYPE_FORFILTER */ if ( pHeader.keyExpPool[ strlen( pTag->KeyExpr ) + 1 ] != 0 ) { pTag->ForExpr = ( char * ) hb_xgrab( CDX_MAXKEY + 1 ); - /* TODO: Uppering is bad */ - hb_strncpyUpper( pTag->ForExpr, ( const char * ) pHeader.keyExpPool + - strlen( pTag->KeyExpr ) + 1, CDX_MAXKEY ); + hb_strncpyTrim( pTag->ForExpr, ( const char * ) pHeader.keyExpPool + + strlen( pTag->KeyExpr ) + 1, CDX_MAXKEY ); SELF_COMPILE( ( AREAP ) pTag->pIndex->pArea, ( BYTE * ) pTag->ForExpr ); /* TODO: RT error if SELF_COMPILE return FAILURE */ pTag->pForItem = pTag->pIndex->pArea->valResult; @@ -3477,6 +3632,7 @@ static void hb_cdxTagClose( LPCDXTAG pTag ) { hb_cdxTagHeaderStore( pTag ); } + pTag->fRePos = TRUE; } /* @@ -3489,7 +3645,7 @@ static void hb_cdxTagOpen( LPCDXTAG pTag ) if ( !pTag->RootPage ) { hb_cdxIndexPageRead( pTag->pIndex, pTag->TagBlock, (BYTE *) &tagHeader, sizeof( CDXTAGHEADER ) ); - pTag->RootBlock = HB_GET_LE_ULONG( tagHeader.rootPtr ); + pTag->RootBlock = HB_GET_LE_UINT32( tagHeader.rootPtr ); if ( pTag->RootBlock && pTag->RootBlock != CDX_DUMMYNODE ) pTag->RootPage = hb_cdxPageNew( pTag, NULL, pTag->RootBlock ); if ( !pTag->RootPage ) @@ -3620,8 +3776,11 @@ static int hb_cdxPageSeekKey( LPCDXPAGE pPage, LPCDXKEY pKey, ULONG ulKeyRec, BO hb_cdxPageGetKeyRec( pPage, pPage->iCurKey ) != hb_cdxPageGetKeyRec( pPage->Child, pPage->Child->iKeys-1 ) ) { + printf("\r\nkeyLen=%d", pPage->TagParent->uiLen); printf("\r\nparent=%lx, iKey=%d, rec=%ld", pPage->Page, pPage->iCurKey, hb_cdxPageGetKeyRec( pPage, pPage->iCurKey )); printf("\r\n child=%lx, iKey=%d, rec=%ld", pPage->Child->Page, pPage->Child->iKeys-1, hb_cdxPageGetKeyRec( pPage->Child, pPage->Child->iKeys-1 )); + printf("\r\nparent val=[%s]", hb_cdxPageGetKeyVal( pPage, pPage->iCurKey )); + printf("\r\n child val=[%s]", hb_cdxPageGetKeyVal( pPage->Child, pPage->Child->iKeys-1 )); fflush(stdout); hb_cdxErrInternal("hb_cdxPageSeekKey: wrong parent key."); } @@ -3664,6 +3823,20 @@ static int hb_cdxPageSeekKey( LPCDXPAGE pPage, LPCDXKEY pKey, ULONG ulKeyRec, BO return k; } +/* + * an interface for fast check record number in record filter + */ +static BOOL hb_cdxCheckRecordScope( CDXAREAP pArea, ULONG ulRec ) +{ + LONG lRecNo = ( LONG ) ulRec; + + if ( SELF_COUNTSCOPE( ( AREAP ) pArea, NULL, &lRecNo ) == SUCCESS && lRecNo == 0 ) + { + return FALSE; + } + return TRUE; +} + /* * read Top Key from Page or its children */ @@ -3714,21 +3887,28 @@ static BOOL hb_cdxPageReadPrevKey( LPCDXPAGE pPage ) pOwnerPage = pPage; pPage = pPage->Child; } - pPage->iCurKey--; - while ( pPage->iCurKey < 0 ) + + do { - if ( pPage->Left == CDX_DUMMYNODE || !pOwnerPage ) + pPage->iCurKey--; + if ( pPage->iCurKey < 0 ) { - pPage->iCurKey = 0; - if ( pPage->iKeys > 0 ) - hb_cdxSetCurKey( pPage ); - return FALSE; + while ( pPage->Left == CDX_DUMMYNODE || !pOwnerPage ) + { + pPage->iCurKey = 0; + if ( pPage->iKeys > 0 ) + hb_cdxSetCurKey( pPage ); + return FALSE; + } + pOwnerPage->Child = hb_cdxPageNew( pPage->TagParent, pPage->Owner, pPage->Left ); + hb_cdxPageFree( pPage, !pPage->fChanged ); + pPage = pOwnerPage->Child; + pPage->iCurKey = pPage->iKeys - 1; } - pOwnerPage->Child = hb_cdxPageNew( pPage->TagParent, pPage->Owner, pPage->Left ); - hb_cdxPageFree( pPage, !pPage->fChanged ); - pPage = pOwnerPage->Child; - pPage->iCurKey = pPage->iKeys - 1; } + while ( ( pPage->TagParent->OptFlags & CDX_TYPE_STRUCTURE ) == 0 && + ! hb_cdxCheckRecordScope( pPage->TagParent->pIndex->pArea, + hb_cdxPageGetKeyRec( pPage, pPage->iCurKey ) ) ); hb_cdxSetCurKey( pPage ); return TRUE; @@ -3746,19 +3926,26 @@ static BOOL hb_cdxPageReadNextKey( LPCDXPAGE pPage ) pOwnerPage = pPage; pPage = pPage->Child; } - pPage->iCurKey++; - while ( pPage->iCurKey >= pPage->iKeys ) + + do { - if ( pPage->Right == CDX_DUMMYNODE || !pOwnerPage ) + pPage->iCurKey++; + while ( pPage->iCurKey >= pPage->iKeys ) { - pPage->iCurKey = pPage->iKeys; - return FALSE; + if ( pPage->Right == CDX_DUMMYNODE || !pOwnerPage ) + { + pPage->iCurKey = pPage->iKeys; + return FALSE; + } + pOwnerPage->Child = hb_cdxPageNew( pPage->TagParent, pPage->Owner, pPage->Right ); + hb_cdxPageFree( pPage, !pPage->fChanged ); + pPage = pOwnerPage->Child; + pPage->iCurKey = 0; } - pOwnerPage->Child = hb_cdxPageNew( pPage->TagParent, pPage->Owner, pPage->Right ); - hb_cdxPageFree( pPage, !pPage->fChanged ); - pPage = pOwnerPage->Child; - pPage->iCurKey = 0; } + while ( ( pPage->TagParent->OptFlags & CDX_TYPE_STRUCTURE ) == 0 && + ! hb_cdxCheckRecordScope( pPage->TagParent->pIndex->pArea, + hb_cdxPageGetKeyRec( pPage, pPage->iCurKey ) ) ); hb_cdxSetCurKey( pPage ); return TRUE; @@ -3806,17 +3993,17 @@ static BOOL hb_cdxPageReadPrevUniqKey( LPCDXPAGE pPage ) static BOOL hb_cdxPageReadNextUniqKey( LPCDXPAGE pPage ) { LPCDXPAGE pOwnerPage = NULL; -/* BYTE pbVal[CDX_MAXKEY]; */ + /* BYTE pbVal[CDX_MAXKEY]; */ while ( pPage->Child ) { pOwnerPage = pPage; pPage = pPage->Child; } -/* - * memcpy( pbVal, hb_cdxPageGetKeyVal( pPage, pPage->iCurKey ), pPage->TagParent->uiLen ); - * pPage->iCurKey++; - * while ( pPage->iCurKey >= pPage->iKeys || memcmp( pbVal, hb_cdxPageGetKeyVal( pPage, pPage->iCurKey ), pPage->TagParent->uiLen ) == 0 ) +/* + memcpy( pbVal, hb_cdxPageGetKeyVal( pPage, pPage->iCurKey ), pPage->TagParent->uiLen ); + pPage->iCurKey++; + while ( pPage->iCurKey >= pPage->iKeys || memcmp( pbVal, hb_cdxPageGetKeyVal( pPage, pPage->iCurKey ), pPage->TagParent->uiLen ) == 0 ) */ while ( pPage->iCurKey >= pPage->iKeys || memcmp( pPage->TagParent->CurKey->val, hb_cdxPageGetKeyVal( pPage, pPage->iCurKey ), pPage->TagParent->uiLen ) == 0 ) { @@ -3903,7 +4090,6 @@ static void hb_cdxTagKeyRead( LPCDXTAG pTag, BYTE bTypRead ) break; } } - /* fBof = fEof = FALSE; */ switch( bTypRead ) { case TOP_RECORD: @@ -3981,6 +4167,13 @@ static ULONG hb_cdxTagKeyFind( LPCDXTAG pTag, LPCDXKEY pKey ) else if ( ulKeyRec == CDX_IGNORE_REC_NUM ) ulKeyRec = CDX_MAX_REC_NUM; } + else if ( ! pTag->UsrAscend ) + { + if ( ulKeyRec == CDX_MAX_REC_NUM ) + ulKeyRec = CDX_IGNORE_REC_NUM; + else if ( ulKeyRec == CDX_IGNORE_REC_NUM ) + ulKeyRec = CDX_MAX_REC_NUM; + } pTag->CurKey->rec = 0; pTag->fRePos = FALSE; @@ -4005,26 +4198,185 @@ static ULONG hb_cdxTagKeyFind( LPCDXTAG pTag, LPCDXKEY pKey ) /* * add the Key into the Tag */ -static void hb_cdxTagKeyAdd( LPCDXTAG pTag, LPCDXKEY pKey ) +static BOOL hb_cdxTagKeyAdd( LPCDXTAG pTag, LPCDXKEY pKey ) { - BOOL fFound; - hb_cdxTagOpen( pTag ); - fFound = ( hb_cdxPageSeekKey( pTag->RootPage, pKey, - pTag->UniqueKey ? CDX_IGNORE_REC_NUM : pKey->rec, - TRUE ) == 0 ); - if ( ! fFound ) + if ( hb_cdxPageSeekKey( pTag->RootPage, pKey, + pTag->UniqueKey ? CDX_IGNORE_REC_NUM : pKey->rec, + TRUE ) != 0 ) { -#ifdef HB_CDX_DBGUPDT - cdxTmpStackSize = 0; -#endif hb_cdxPageKeyInsert( pTag->RootPage, pKey ); -#ifdef HB_CDX_DBGUPDT - if ( cdxTmpStackSize > cdxStackSize ) - cdxStackSize = cdxTmpStackSize; -#endif + pTag->curKeyState &= ~( CDX_CURKEY_RAWPOS | CDX_CURKEY_LOGPOS | + CDX_CURKEY_RAWCNT | CDX_CURKEY_LOGCNT ); + pTag->fRePos = TRUE; /* TODO: !!! remove when page leaf balance can save CurKey */ hb_cdxTagKeyFind( pTag, pKey ); + return TRUE; + } + return FALSE; +} + +/* + * delete the Key from the Tag + */ +static BOOL hb_cdxTagKeyDel( LPCDXTAG pTag, LPCDXKEY pKey ) +{ + if ( hb_cdxTagKeyFind( pTag, pKey ) != 0 ) + { + hb_cdxPageKeyRemove( pTag->RootPage ); + //pTag->rawKeyCount--; + pTag->curKeyState &= ~( CDX_CURKEY_RAWPOS | CDX_CURKEY_LOGPOS | + CDX_CURKEY_RAWCNT | CDX_CURKEY_LOGCNT ); + pTag->CurKey->rec = 0; + return TRUE; + } + return FALSE; +} + +/* + * Go to the first visiable record in Tag + */ +static void hb_cdxTagGoTop( LPCDXTAG pTag ) +{ + LPCDXKEY pKey = pTag->UsrAscend ? pTag->topScopeKey : pTag->bottomScopeKey; + + if ( pKey ) + hb_cdxTagKeyFind( pTag, pKey ); + else + hb_cdxTagKeyRead( pTag, TOP_RECORD ); + + do + { + if ( pTag->CurKey->rec == 0 || pTag->TagEOF || ! hb_cdxBottomScope( pTag ) ) + { + pTag->CurKey->rec = 0; + break; + } + else if ( ( pTag->OptFlags & CDX_TYPE_STRUCTURE ) != 0 || + hb_cdxCheckRecordScope( pTag->pIndex->pArea, pTag->CurKey->rec ) ) + { + pTag->rawKeyPos = 1; + CURKEY_SETRAWPOS( pTag ); + break; + } + hb_cdxTagKeyRead( pTag, NEXT_RECORD ); + } + while ( TRUE ); +} + +/* + * Go to the last visiable record in Tag + */ +static void hb_cdxTagGoBottom( LPCDXTAG pTag ) +{ + LPCDXKEY pKey = pTag->UsrAscend ? pTag->bottomScopeKey : pTag->topScopeKey; + + if ( pKey ) + hb_cdxTagKeyFind( pTag, pKey ); + else + hb_cdxTagKeyRead( pTag, BTTM_RECORD ); + + do + { + if ( pTag->CurKey->rec == 0 || pTag->TagBOF || ! hb_cdxTopScope( pTag ) ) + { + pTag->CurKey->rec = 0; + break; + } + else if ( ( pTag->OptFlags & CDX_TYPE_STRUCTURE ) != 0 || + hb_cdxCheckRecordScope( pTag->pIndex->pArea, pTag->CurKey->rec ) ) + { + if ( CURKEY_RAWCNT( pTag ) ) + { + pTag->rawKeyPos = pTag->rawKeyCount; + CURKEY_SETRAWPOS( pTag ); + } + break; + } + hb_cdxTagKeyRead( pTag, PREV_RECORD ); + } + while ( TRUE ); +} + +/* + * skip to Next Key in the Tag + */ +static void hb_cdxTagSkipNext( LPCDXTAG pTag ) +{ + BOOL fPos = CURKEY_RAWPOS( pTag ), fEof = FALSE; + ULONG ulSkip = 1; + + if ( pTag->CurKey->rec != 0 ) + { + if ( !hb_cdxTopScope( pTag ) ) + { + ulSkip = 0; + hb_cdxTagGoTop( pTag ); + } + else + hb_cdxTagKeyRead( pTag, NEXT_RECORD ); + } + + while ( !fEof ) + { + if ( pTag->TagEOF || pTag->CurKey->rec == 0 || + !hb_cdxBottomScope( pTag ) || !hb_cdxTopScope( pTag ) ) + fEof = TRUE; + else if ( ( pTag->OptFlags & CDX_TYPE_STRUCTURE ) != 0 || + hb_cdxCheckRecordScope( pTag->pIndex->pArea, pTag->CurKey->rec ) ) + break; + hb_cdxTagKeyRead( pTag, NEXT_RECORD ); + } + + if ( fEof ) + { + pTag->CurKey->rec = 0; + pTag->TagEOF = TRUE; + } + else if ( fPos ) + { + pTag->rawKeyPos += ulSkip; + CURKEY_SETRAWPOS( pTag ); + } +} + +/* + * skip to Previous Key in the Tag + */ +static void hb_cdxTagSkipPrev( LPCDXTAG pTag ) +{ + BOOL fPos = CURKEY_RAWPOS( pTag ), fBof = FALSE; + ULONG ulSkip = 1; + + if ( pTag->CurKey->rec == 0 ) + { + ulSkip = 0; + hb_cdxTagGoBottom( pTag ); + } + else + hb_cdxTagKeyRead( pTag, PREV_RECORD ); + + while ( !fBof ) + { + if ( pTag->TagBOF || pTag->CurKey->rec == 0 || + !hb_cdxBottomScope( pTag ) || !hb_cdxTopScope( pTag ) ) + fBof = TRUE; + else if ( ( pTag->OptFlags & CDX_TYPE_STRUCTURE ) != 0 || + hb_cdxCheckRecordScope( pTag->pIndex->pArea, pTag->CurKey->rec ) ) + break; + hb_cdxTagKeyRead( pTag, PREV_RECORD ); + } + + + if ( fBof ) + { + hb_cdxTagGoTop( pTag ); + pTag->TagBOF = TRUE; + } + else if ( fPos ) + { + pTag->rawKeyPos -= ulSkip; + CURKEY_SETRAWPOS( pTag ); } } @@ -4070,16 +4422,14 @@ static void hb_cdxTagIndexTagNew( LPCDXTAG pTag, if ( KeyExp != NULL ) { pTag->KeyExpr = ( char * ) hb_xgrab( CDX_MAXKEY + 1 ); - /* TODO: !!! upering is buggy */ - hb_strncpyUpper( pTag->KeyExpr, KeyExp, CDX_MAXKEY ); - pTag->nField = hb_rddFieldIndex( (AREAP) pTag->pIndex->pArea, pTag->KeyExpr ); + hb_strncpyTrim( pTag->KeyExpr, KeyExp, CDX_MAXKEY ); + pTag->nField = hb_cdxFieldIndex( pTag->pIndex->pArea, pTag->KeyExpr ); } pTag->pKeyItem = pKeyItem; if ( ForExp != NULL ) { pTag->ForExpr = ( char * ) hb_xgrab( CDX_MAXKEY + 1 ); - /* TODO: !!! upering is buggy */ - hb_strncpyUpper( pTag->ForExpr, ForExp, CDX_MAXKEY ); + hb_strncpyTrim( pTag->ForExpr, ForExp, CDX_MAXKEY ); } pTag->pForItem = pForItem; pTag->AscendKey = pTag->UsrAscend = fAscnd; @@ -4129,9 +4479,8 @@ static void hb_cdxIndexDelTag( LPCDXINDEX pIndex, char * szTagName ) { LPCDXTAG pTag = *pTagPtr; LPCDXKEY pKey = hb_cdxKeyPutC( NULL, szTagName, CDX_MAXTAGNAMELEN, pTag->TagBlock ); - if ( hb_cdxTagKeyFind( pIndex->pCompound, pKey ) > 0 ) + if ( hb_cdxTagKeyDel( pIndex->pCompound, pKey ) ) { - hb_cdxPageKeyDelete( pIndex->pCompound->RootPage ); if ( pTag != pIndex->TagList || pTag->pNext != NULL ) { LPCDXPAGE pPage; @@ -4139,10 +4488,13 @@ static void hb_cdxIndexDelTag( LPCDXINDEX pIndex, char * szTagName ) hb_cdxTagOpen( pTag ); pPage = pTag->RootPage; hb_cdxTagClose( pTag ); - if ( pPage ) - hb_cdxIndexFreePages( pPage ); + if ( ! pIndex->fShared ) + { + if ( pPage ) + hb_cdxIndexFreePages( pPage ); + hb_cdxIndexPutAvailPage( pIndex, pTag->TagBlock, TRUE ); + } pTag->TagChanged = FALSE; - hb_cdxIndexPutAvailPage( pIndex, pTag->TagBlock, TRUE ); } } *pTagPtr = pTag->pNext; @@ -4203,12 +4555,13 @@ static void hb_cdxIndexReindex( LPCDXINDEX pIndex ) pIndex->freePage = 0; hb_fsSeek( pIndex->hFile, 0, FS_SET ); hb_fsWrite( pIndex->hFile, NULL, 0 ); + pIndex->fChanged = TRUE; /* Rebuild the compound (master) tag */ if ( pCompound ) { pIndex->pCompound = hb_cdxTagNew( pIndex, pCompound->szName, CDX_DUMMYNODE ); - pIndex->pCompound->OptFlags = CDX_TYPE_COMPACT | CDX_TYPE_COMPOUND | CDX_TYPE_STRUCTURE;; + pIndex->pCompound->OptFlags = CDX_TYPE_COMPACT | CDX_TYPE_COMPOUND | CDX_TYPE_STRUCTURE; hb_cdxTagIndexTagNew( pIndex->pCompound, NULL, NULL, 'C', CDX_MAXTAGNAMELEN, NULL, NULL, TRUE, FALSE, FALSE ); hb_cdxTagFree( pCompound ); @@ -4293,21 +4646,19 @@ static void hb_cdxIndexLoad( LPCDXINDEX pIndex, char * szBaseName ) /* TODO: check if index file is not corrupted */ - pIndex->fShared = pIndex->pArea->fShared; - pIndex->fReadonly = pIndex->pArea->fReadonly; hb_cdxIndexLockRead( pIndex ); /* load the tags*/ pIndex->pCompound = hb_cdxTagNew( pIndex, szBaseName, 0L ); pIndex->pCompound->OptFlags = CDX_TYPE_COMPACT | CDX_TYPE_COMPOUND | CDX_TYPE_STRUCTURE; TagList = NULL; pTagPtr = &TagList; - hb_cdxTagKeyRead( pIndex->pCompound, TOP_RECORD ); + hb_cdxTagGoTop( pIndex->pCompound ); while ( !pIndex->pCompound->TagEOF ) { (*pTagPtr) = hb_cdxTagNew( pIndex, (char *) pIndex->pCompound->CurKey->val, pIndex->pCompound->CurKey->rec ); pTagPtr = &(*pTagPtr)->pNext; - hb_cdxTagKeyRead( pIndex->pCompound, NEXT_RECORD ); + hb_cdxTagSkipNext( pIndex->pCompound ); } hb_cdxIndexUnLockRead( pIndex ); hb_cdxReorderTagList( &TagList ); @@ -4320,6 +4671,75 @@ static void hb_cdxIndexLoad( LPCDXINDEX pIndex, char * szBaseName ) #endif } +/* + * create index file name + */ +static void hb_cdxCreateFName( CDXAREAP pArea, char * szBagName, + char * szFileName, char * szBaseName ) +{ + PHB_FNAME pFileName; + BOOL fName = szBagName && strlen( szBagName ) > 0; + + pFileName = hb_fsFNameSplit( fName ? szBagName : pArea->szDataFileName ); + + if ( szBaseName ) + { + hb_strncpyUpperTrim( szBaseName, pFileName->szName, CDX_MAXTAGNAMELEN ); + } + + if ( pFileName->szPath ) + { + hb_strncpy( szFileName, pFileName->szPath, _POSIX_PATH_MAX ); + } + /* + * This code is disabled, IMHO such behavior is better then + * Clipper one but unfortunately it cause incompatibilities + */ +/* + else if ( fName ) + { + PHB_FNAME pDbfFName = hb_fsFNameSplit( pArea->szDataFileName ); + + if ( pDbfFName->szPath ) + { + hb_strncpy( szFileName, pDbfFName->szPath, _POSIX_PATH_MAX ); + } + else + { + szFileName[ 0 ] = '.'; + szFileName[ 1 ] = OS_PATH_DELIMITER; + szFileName[ 2 ] = '\0'; + } + hb_xfree( pDbfFName ); + } +*/ + else + { + szFileName[ 0 ] = '.'; + szFileName[ 1 ] = OS_PATH_DELIMITER; + szFileName[ 2 ] = '\0'; + } + hb_strncat( szFileName, pFileName->szName, _POSIX_PATH_MAX ); + + if ( fName && pFileName->szExtension ) + { + hb_strncat( szFileName, pFileName->szExtension, _POSIX_PATH_MAX ); + } + else + { + DBORDERINFO pExtInfo; + memset( &pExtInfo, 0, sizeof( pExtInfo ) ); + pExtInfo.itmResult = hb_itemPutC( NULL, "" ); + if ( SELF_ORDINFO( ( AREAP ) pArea, DBOI_BAGEXT, &pExtInfo ) == SUCCESS && + hb_itemGetCLen( pExtInfo.itmResult ) > 0 ) + { + hb_strncat( szFileName, hb_itemGetCPtr( pExtInfo.itmResult ), _POSIX_PATH_MAX ); + } + hb_itemRelease( pExtInfo.itmResult ); + } + hb_xfree( pFileName ); +} + /* * free (close) used indexes, if not fAll then keep structure index */ @@ -4355,21 +4775,19 @@ static void hb_cdxOrdListClear( CDXAREAP pArea, BOOL fAll, LPCDXINDEX pKeepInd ) } } + /* * find order bag by its name - * TODO: This only checks for basename of bag, - * a complete (but reliable) test should be done to look for the same file - * druzus: if we allow to make more bugs with the same name - - * I'm not a fun of this */ static LPCDXINDEX hb_cdxFindBag( CDXAREAP pArea, char * szBagName ) { LPCDXINDEX pIndex; PHB_FNAME pFileName; - char * szBaseName; + char * szBaseName, * szBasePath; pFileName = hb_fsFNameSplit( szBagName ); szBaseName = hb_strdup( pFileName->szName ); + szBasePath = pFileName->szPath ? hb_strdup( pFileName->szPath ) : NULL; hb_strUpper( szBaseName, strlen(szBaseName) ); pIndex = pArea->lpIndexes; @@ -4377,13 +4795,15 @@ static LPCDXINDEX hb_cdxFindBag( CDXAREAP pArea, char * szBagName ) { hb_xfree( pFileName ); pFileName = hb_fsFNameSplit( pIndex->szFileName ); - hb_strUpper( pFileName->szName, strlen(pFileName->szName) ); - if ( !hb_stricmp( pFileName->szName, szBaseName ) ) + if ( !hb_stricmp( pFileName->szName, szBaseName ) && ( !szBasePath || + ( pFileName->szPath && !hb_stricmp( pFileName->szPath, szBasePath ) ) ) ) break; pIndex = pIndex->pNext; } hb_xfree( pFileName ); hb_xfree( szBaseName ); + if ( szBasePath ) + hb_xfree( szBasePath ); return pIndex; } @@ -4440,47 +4860,56 @@ static USHORT hb_cdxGetTagNumber( CDXAREAP pArea, LPCDXTAG pFindTag ) /* * find Tag in tag list */ -static USHORT hb_cdxFindTag( CDXAREAP pArea, PHB_ITEM pItem ) +static LPCDXTAG hb_cdxFindTag( CDXAREAP pArea, PHB_ITEM pTagItem, + PHB_ITEM pBagItem, USHORT *puiTag ) { - USHORT uiTag = 0; + LPCDXTAG pTag = NULL; + USHORT uiTag = 0, uiFind = 0; + LPCDXINDEX pIndex, pBagIndex; + char szName[ CDX_MAXTAGNAMELEN + 1 ]; - if ( pItem ) + szName[ 0 ] = '\0'; + if ( HB_IS_NUMBER( pTagItem ) ) { - if ( HB_IS_NUMBER( pItem ) ) - { - uiTag = hb_itemGetNI( pItem ); - if ( ! hb_cdxGetTagByNumber(pArea, uiTag ) ) - uiTag = 0; - } - else if ( HB_IS_STRING( pItem ) ) - { - LPCDXTAG pTag; - LPCDXINDEX pIndex; - char szName[ CDX_MAXTAGNAMELEN + 1 ]; + uiFind = hb_itemGetNI( pTagItem ); + } + else if ( HB_IS_STRING( pTagItem ) ) + { + hb_strncpyUpperTrim( szName, pTagItem->item.asString.value, + HB_MIN( pTagItem->item.asString.length, CDX_MAXTAGNAMELEN ) ); + } + pIndex = pArea->lpIndexes; - hb_strncpyUpperTrim( szName, pItem->item.asString.value, - HB_MIN( pItem->item.asString.length, CDX_MAXTAGNAMELEN) ); - pIndex = pArea->lpIndexes; - pTag = NULL; - uiTag = 0; - while ( pIndex && !pTag) + if ( pIndex && ( uiFind != 0 || szName[ 0 ] ) ) + { + if ( pBagItem && HB_IS_STRING( pBagItem ) && pBagItem->item.asString.length > 0 ) + pBagIndex = hb_cdxFindBag( pArea, pBagItem->item.asString.value ); + else + pBagIndex = NULL; + + while ( pIndex ) + { + pTag = pIndex->TagList; + while ( pTag ) { - pTag = pIndex->TagList; - while ( pTag ) - { - uiTag++; - if ( !hb_stricmp( pTag->szName, szName ) ) - break; - pTag = pTag->pNext; - } - pIndex = pIndex->pNext; + uiTag++; + if ( ( ! pBagIndex || pBagIndex == pIndex ) && + ( uiFind != 0 ? uiTag == uiFind : !hb_stricmp( pTag->szName, szName ) ) ) + break; + pTag = pTag->pNext; } - if ( !pTag ) - uiTag = 0; + if ( pTag || pBagIndex == pIndex ) + break; + pIndex = pIndex->pNext; } + if ( !pTag ) + uiTag = 0; } - return uiTag; + if ( puiTag ) + *puiTag = uiTag; + + return pTag; } /* @@ -4500,11 +4929,13 @@ static LPCDXTAG hb_cdxGetActiveTag( CDXAREAP pArea ) /* * refresh CurKey value and set proper path from RootPage to LeafPage - * fUniq is used for forward skipunique */ -static BOOL hb_cdxCurKeyRefresh( CDXAREAP pArea, LPCDXTAG pTag, BOOL fUniq ) +static BOOL hb_cdxCurKeyRefresh( CDXAREAP pArea, LPCDXTAG pTag ) { - if ( pArea->fEof || pArea->ulRecNo == 0 ) + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + + if ( !pArea->fPositioned ) { pTag->TagEOF = TRUE; pTag->fRePos = FALSE; @@ -4513,16 +4944,35 @@ static BOOL hb_cdxCurKeyRefresh( CDXAREAP pArea, LPCDXTAG pTag, BOOL fUniq ) } else if ( pTag->fRePos || pTag->CurKey->rec != pArea->ulRecNo ) { + BYTE buf[CDX_MAXKEY]; + BOOL fBuf = FALSE; + + /* Try to find previous if it's key for the same record */ if ( pTag->CurKey->rec == pArea->ulRecNo ) + { + fBuf = TRUE; + memcpy( buf, pTag->CurKey->val, pTag->CurKey->len ); hb_cdxTagKeyFind( pTag, pTag->CurKey ); + } if ( pTag->CurKey->rec != pArea->ulRecNo ) { + BOOL fValidBuf = pArea->fValidBuffer; LPCDXKEY pKey = hb_cdxKeyEval( NULL, pTag, TRUE ); - hb_cdxTagKeyFind( pTag, pKey ); - if ( fUniq && !pTag->TagEOF && pTag->CurKey->rec != pArea->ulRecNo ) + /* not found, create new key from DBF and if differs seek again */ + if ( !fBuf || memcmp( buf, pKey->val, pKey->len ) != 0 ) { - memcpy( pTag->CurKey->val, pKey->val, pKey->len ); - pTag->CurKey->rec = 0; + fBuf = TRUE; + memcpy( buf, pKey->val, pKey->len ); + hb_cdxTagKeyFind( pTag, pKey ); + } + /* not found, if key was generated from DBF buffer then force to + * update it, create the new key and if differs seek again */ + if ( pTag->CurKey->rec != pArea->ulRecNo && fValidBuf ) + { + SELF_GOTO( ( AREAP ) pArea, pArea->ulRecNo ); + pKey = hb_cdxKeyEval( pKey, pTag, TRUE ); + if ( memcmp( buf, pKey->val, pKey->len ) != 0 ) + hb_cdxTagKeyFind( pTag, pKey ); } hb_cdxKeyFree( pKey ); } @@ -4537,7 +4987,6 @@ static BOOL hb_cdxCurKeyRefresh( CDXAREAP pArea, LPCDXTAG pTag, BOOL fUniq ) static ERRCODE hb_cdxSkipUnique( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward ) { ERRCODE retval; - BOOL fOut = FALSE; HB_TRACE(HB_TR_DEBUG, ("hb_cdxSkipUnique(%p, %p, %i)", pArea, pTag, fForward)); @@ -4547,49 +4996,80 @@ static ERRCODE hb_cdxSkipUnique( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward ) if ( ! pTag ) return SELF_SKIP( ( AREAP ) pArea, fForward ? 1 : -1 ); - hb_cdxIndexLockRead( pTag->pIndex ); - if ( !pArea->fEof ) + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + + pArea->fTop = pArea->fBottom = FALSE; + + if ( !pArea->fPositioned ) { - if ( ! hb_cdxCurKeyRefresh( pArea, pTag, fForward ) ) - { - if ( !fForward && pTag->TagEOF && !pArea->fEof ) - fOut = TRUE; - } - } - if ( fForward ) - { - if ( !pArea->fEof && !pTag->TagEOF ) - { - hb_cdxTagKeyRead( pTag, NXTU_RECORD ); - if ( !pTag->TagEOF ) - { - if ( !hb_cdxTopScope( pTag ) ) - hb_cdxTagKeyFind( pTag, pTag->topScopeKey ); - if ( !hb_cdxBottomScope( pTag ) ) - fOut = TRUE; - } - } - retval = SELF_GOTO( ( AREAP ) pArea, ( fOut || pArea->fEof || pTag->TagEOF ) - ? 0 : pTag->CurKey->rec ); + if ( fForward ) + retval = SELF_GOTO( ( AREAP ) pArea, 0 ); + else + retval = SELF_GOBOTTOM( ( AREAP ) pArea ); } else { - if ( pArea->fEof ) + LPCDXKEY pKey = NULL; + BOOL fOut = FALSE; + + hb_cdxIndexLockRead( pTag->pIndex ); + if ( ! hb_cdxCurKeyRefresh( pArea, pTag ) ) { - retval = SELF_GOBOTTOM( ( AREAP ) pArea ); + if ( pTag->TagEOF ) + fOut = TRUE; + else if ( ( fForward ? pTag->UsrAscend : !pTag->UsrAscend ) && + pTag->CurKey->rec != 0 ) + { + pKey = hb_cdxKeyEval( pKey, pTag, TRUE ); + } + } + if ( fForward ) + { + if ( pArea->fPositioned && !pTag->TagEOF ) + { + if ( !pKey ) + { + pKey = hb_cdxKeyCopy( NULL, pTag->CurKey ); + hb_cdxTagSkipNext( pTag ); + } + while ( !pTag->TagEOF ) + { + if ( hb_cdxValCompare( pTag, pKey->val, pKey->len, + pTag->CurKey->val, pTag->CurKey->len, TRUE ) != 0 ) + { + SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ); + SELF_SKIPFILTER( ( AREAP ) pArea, 1 ); + break; + } + hb_cdxTagSkipNext( pTag ); + } + } + retval = SELF_GOTO( ( AREAP ) pArea, ( !pArea->fPositioned || pTag->TagEOF ) + ? 0 : pTag->CurKey->rec ); } else { if ( !fOut && !pTag->TagBOF ) { - hb_cdxTagKeyRead( pTag, PRVU_RECORD ); - if ( !pTag->TagBOF ) + if ( !pKey ) { - if ( !hb_cdxTopScope( pTag ) || - !hb_cdxBottomScope( pTag ) ) - fOut = TRUE; + pKey = hb_cdxKeyCopy( NULL, pTag->CurKey ); + hb_cdxTagSkipPrev( pTag ); + } + while ( !pTag->TagBOF ) + { + if ( hb_cdxValCompare( pTag, pKey->val, pKey->len, + pTag->CurKey->val, pTag->CurKey->len, TRUE ) != 0 ) + { + SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ); + SELF_SKIPFILTER( ( AREAP ) pArea, -1 ); + break; + } + hb_cdxTagSkipPrev( pTag ); } } + if ( fOut || pTag->TagBOF ) { retval = SELF_GOTOP( ( AREAP ) pArea ); @@ -4600,9 +5080,10 @@ static ERRCODE hb_cdxSkipUnique( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward ) retval = SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ); } } + hb_cdxIndexUnLockRead( pTag->pIndex ); + if ( pKey ) + hb_cdxKeyFree( pKey ); } - hb_cdxIndexUnLockRead( pTag->pIndex ); - /* Update Bof and Eof flags */ if( fForward ) pArea->fBof = FALSE; @@ -4618,7 +5099,7 @@ static ERRCODE hb_cdxSkipUnique( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward ) static BOOL hb_cdxDBOISkipEval( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward, PHB_ITEM pEval ) { - BOOL fFound = FALSE; + BOOL fFound = FALSE, fFirst = TRUE; HB_TRACE(HB_TR_DEBUG, ("hb_cdxSkipEval(%p, %p, %i, %p)", pArea, pTag, fForward, pEval)); @@ -4632,48 +5113,60 @@ static BOOL hb_cdxDBOISkipEval( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward, return fForward ? !pArea->fEof : !pArea->fBof; } + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + + pArea->fTop = pArea->fBottom = FALSE; + hb_cdxIndexLockRead( pTag->pIndex ); - if ( !pArea->fEof ) + if ( ! hb_cdxCurKeyRefresh( pArea, pTag ) ) { - hb_cdxCurKeyRefresh( pArea, pTag, FALSE ); + if ( !pTag->TagEOF && pTag->CurKey->rec != 0 && + ( fForward ? pTag->UsrAscend : !pTag->UsrAscend ) ) + fFirst = FALSE; } if ( fForward ) { - if ( !pTag->TagEOF && !pArea->fEof ) + if ( fFirst ) + hb_cdxTagSkipNext( pTag ); + while ( !pTag->TagEOF ) { - if ( !hb_cdxTopScope( pTag ) ) - hb_cdxTagKeyFind( pTag, pTag->topScopeKey ); - else - hb_cdxTagKeyRead( pTag, NEXT_RECORD ); - - while ( !pTag->TagEOF && hb_cdxBottomScope( pTag ) ) + if ( SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ) == FAILURE ) + break; + if ( hb_cdxEvalSeekCond( pTag, pEval ) ) { - if ( SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ) == FAILURE ) + ULONG ulRecNo = pArea->ulRecNo; + SELF_SKIPFILTER( ( AREAP ) pArea, 1 ); + if ( pArea->ulRecNo == ulRecNo || hb_cdxEvalSeekCond( pTag, pEval ) ) + { + fFound = TRUE; break; - fFound = hb_cdxEvalSeekCond( pTag, pEval ); - if ( fFound ) - break; - hb_cdxTagKeyRead( pTag, NEXT_RECORD ); + } } + hb_cdxTagSkipNext( pTag ); } if ( !fFound ) SELF_GOTO( ( AREAP ) pArea, 0 ); } else { - if ( pArea->fEof ) - SELF_GOBOTTOM( ( AREAP ) pArea ); - else if ( !pTag->TagBOF ) - hb_cdxTagKeyRead( pTag, PREV_RECORD ); - - while ( !pTag->TagBOF && hb_cdxTopScope( pTag ) && hb_cdxBottomScope( pTag ) ) + if ( fFirst ) + hb_cdxTagSkipPrev( pTag ); + while ( !pTag->TagBOF ) { if ( SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ) == FAILURE ) break; - fFound = hb_cdxEvalSeekCond( pTag, pEval ); - if ( fFound ) - break; - hb_cdxTagKeyRead( pTag, PREV_RECORD ); + if ( hb_cdxEvalSeekCond( pTag, pEval ) ) + { + ULONG ulRecNo = pArea->ulRecNo; + SELF_SKIPFILTER( ( AREAP ) pArea, -1 ); + if ( pArea->ulRecNo == ulRecNo || hb_cdxEvalSeekCond( pTag, pEval ) ) + { + fFound = TRUE; + break; + } + } + hb_cdxTagSkipPrev( pTag ); } if ( !fFound ) { @@ -4692,6 +5185,259 @@ static BOOL hb_cdxDBOISkipEval( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward, return fFound; } +/* + * skip while comparison with given pattern with wildcards doesn't return TRUE + */ +static BOOL hb_cdxDBOISkipWild( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward, + PHB_ITEM pWildItm ) +{ + BOOL fFound = FALSE, fFirst = TRUE; + char *szPattern = hb_itemGetCPtr( pWildItm ); + + HB_TRACE(HB_TR_DEBUG, ("hb_cdxSkipWild(%p, %p, %i, %p)", pArea, pTag, fForward, pWildItm)); + + if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) + return FALSE; + + if ( ! pTag || pTag->uiType != 'C' || !szPattern || !*szPattern ) + { + if ( SELF_SKIP( ( AREAP ) pArea, fForward ? 1 : -1 ) == FAILURE ) + return FALSE; + return fForward ? pArea->fPositioned : !pArea->fBof; + } + + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + + pArea->fTop = pArea->fBottom = FALSE; + + hb_cdxIndexLockRead( pTag->pIndex ); + if ( ! hb_cdxCurKeyRefresh( pArea, pTag ) ) + { + if ( !pTag->TagEOF && pTag->CurKey->rec != 0 && + ( fForward ? pTag->UsrAscend : !pTag->UsrAscend ) ) + fFirst = FALSE; + } + if ( fForward ) + { + if ( fFirst ) + hb_cdxTagSkipNext( pTag ); + while ( !pTag->TagEOF ) + { + if ( hb_strMatchWild( (const char *) pTag->CurKey->val, szPattern ) ) + { + ULONG ulRecNo = pArea->ulRecNo; + SELF_SKIPFILTER( ( AREAP ) pArea, 1 ); + if ( pArea->ulRecNo == ulRecNo || + hb_strMatchWild( (const char *) pTag->CurKey->val, szPattern ) ) + { + fFound = TRUE; + break; + } + } + hb_cdxTagSkipNext( pTag ); + } + SELF_GOTO( ( AREAP ) pArea, fFound ? pTag->CurKey->rec : 0 ); + } + else + { + if ( fFirst ) + hb_cdxTagSkipPrev( pTag ); + while ( !pTag->TagBOF ) + { + if ( hb_strMatchWild( (const char *) pTag->CurKey->val, szPattern ) ) + { + ULONG ulRecNo = pArea->ulRecNo; + SELF_SKIPFILTER( ( AREAP ) pArea, -1 ); + if ( pArea->ulRecNo == ulRecNo || + hb_strMatchWild( (const char *) pTag->CurKey->val, szPattern ) ) + { + fFound = TRUE; + break; + } + } + hb_cdxTagSkipPrev( pTag ); + } + if ( fFound ) + SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ); + else + { + SELF_GOTOP( ( AREAP ) pArea ); + pArea->fBof = TRUE; + } + } + hb_cdxIndexUnLockRead( pTag->pIndex ); + + /* Update Bof and Eof flags */ + if( fForward ) + pArea->fBof = FALSE; + else + pArea->fEof = FALSE; + + return fFound; +} + +#if defined(__XHARBOUR__) +/* + * skip while regular expression on index key val doesn't return TRUE + */ +static BOOL hb_cdxDBOISkipRegEx( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward, + PHB_ITEM pRegExItm ) +{ + BOOL fFound = FALSE, fFirst = TRUE; + regex_t re, *pReg; + regmatch_t aMatches[1]; + int CFlags = REG_EXTENDED, EFlags = 0; + char *szMask = hb_itemGetCPtr( pRegExItm ); + BOOL fFree = FALSE; + + HB_TRACE(HB_TR_DEBUG, ("hb_cdxSkipRegEx(%p, %p, %i, %s)", pArea, pTag, fForward, szMask)); + + if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) + return FALSE; + + if ( ! pTag || pTag->uiType != 'C' || !szMask || !*szMask ) + { + if ( SELF_SKIP( ( AREAP ) pArea, fForward ? 1 : -1 ) == FAILURE ) + return FALSE; + return fForward ? pArea->fPositioned : !pArea->fBof; + } + + if( pRegExItm->item.asString.length > 3 && memcmp( szMask, "***", 3 ) == 0 ) + { + pReg = (regex_t *) ( szMask + 3 ); + } + else + { + if( regcomp( &re, szMask, CFlags ) != 0 ) + { + return FALSE; + } + pReg = &re; + fFree = TRUE; + } + + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + + pArea->fTop = pArea->fBottom = FALSE; + + hb_cdxIndexLockRead( pTag->pIndex ); + if ( ! hb_cdxCurKeyRefresh( pArea, pTag ) ) + { + if ( !pTag->TagEOF && pTag->CurKey->rec != 0 && + ( fForward ? pTag->UsrAscend : !pTag->UsrAscend ) ) + fFirst = FALSE; + } + if ( fForward ) + { + if ( fFirst ) + hb_cdxTagSkipNext( pTag ); + while ( !pTag->TagEOF ) + { + if( regexec( pReg, (const char *) pTag->CurKey->val, 1, aMatches, EFlags ) == 0 ) + { + ULONG ulRecNo = pArea->ulRecNo; + SELF_SKIPFILTER( ( AREAP ) pArea, 1 ); + if ( pArea->ulRecNo == ulRecNo || + regexec( pReg, (const char *) pTag->CurKey->val, 1, aMatches, EFlags ) == 0 ) + { + fFound = TRUE; + break; + } + } + hb_cdxTagSkipNext( pTag ); + } + SELF_GOTO( ( AREAP ) pArea, fFound ? pTag->CurKey->rec : 0 ); + } + else + { + if ( fFirst ) + hb_cdxTagSkipPrev( pTag ); + while ( !pTag->TagBOF ) + { + if( regexec( pReg, (const char *) pTag->CurKey->val, 1, aMatches, EFlags ) == 0 ) + { + ULONG ulRecNo = pArea->ulRecNo; + SELF_SKIPFILTER( ( AREAP ) pArea, -1 ); + if ( pArea->ulRecNo == ulRecNo || + regexec( pReg, (const char *) pTag->CurKey->val, 1, aMatches, EFlags ) == 0 ) + { + fFound = TRUE; + break; + } + } + hb_cdxTagSkipPrev( pTag ); + } + if ( fFound ) + SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ); + else + { + SELF_GOTOP( ( AREAP ) pArea ); + pArea->fBof = TRUE; + } + } + hb_cdxIndexUnLockRead( pTag->pIndex ); + + /* Update Bof and Eof flags */ + if( fForward ) + pArea->fBof = FALSE; + else + pArea->fEof = FALSE; + + if( fFree ) + regfree( pReg ); + + return fFound; +} +#endif + +/* + * evaluate given C function in given scope + */ +ULONG hb_cdxDBOIScopeEval( LPCDXTAG pTag, HB_EVALSCOPE_FUNC pFunc, void *pParam, PHB_ITEM pItemLo, PHB_ITEM pItemHi ) +{ + ULONG ulCount = 0, ulLen = ( ULONG ) pTag->uiLen; + LPCDXKEY pCurKey = hb_cdxKeyCopy( NULL, pTag->CurKey ), + pTopScopeKey = pTag->topScopeKey, + pBtmScopeKey = pTag->bottomScopeKey; + + /* TODO: RT error when item type differ then Tag type */ + if ( !pItemLo || HB_IS_NIL( pItemLo ) ) + pTag->topScopeKey = NULL; + else + pTag->topScopeKey = hb_cdxKeyPutItem( NULL, pItemLo, CDX_IGNORE_REC_NUM, pTag, TRUE, FALSE ); + + if ( !pItemHi || HB_IS_NIL( pItemHi ) ) + pTag->bottomScopeKey = NULL; + else + pTag->bottomScopeKey = hb_cdxKeyPutItem( NULL, pItemHi, CDX_MAX_REC_NUM, pTag, TRUE, FALSE ); + + hb_cdxIndexLockRead( pTag->pIndex ); + hb_cdxTagGoTop( pTag ); + while ( !pTag->TagEOF && hb_cdxBottomScope( pTag ) ) + { + pFunc( pTag->CurKey->rec, pTag->CurKey->val, ulLen, pParam ); + ulCount++; + hb_cdxTagSkipNext( pTag ); + } + hb_cdxIndexUnLockRead( pTag->pIndex ); + + if ( pTag->topScopeKey ) + hb_cdxKeyFree( pTag->topScopeKey ); + pTag->topScopeKey = pTopScopeKey; + if ( pTag->bottomScopeKey ) + hb_cdxKeyFree( pTag->bottomScopeKey ); + pTag->bottomScopeKey = pBtmScopeKey; + pTag->curKeyState &= ~( CDX_CURKEY_RAWPOS | CDX_CURKEY_LOGPOS ); + + pTag->fRePos = TRUE; + hb_cdxKeyCopy( pTag->CurKey, pCurKey ); + hb_cdxKeyFree( pCurKey ); + + return ulCount; +} + /* * return number of keys in order */ @@ -4705,56 +5451,66 @@ static LONG hb_cdxDBOIKeyCount( CDXAREAP pArea, LPCDXTAG pTag, BOOL fFilters ) if ( fFilters ) { - PHB_ITEM pRecNo; - ULONG ulRec; - USHORT uiTag; - LPDBRELINFO lpdbRelations; - - uiTag = pArea->uiTag; - pArea->uiTag = hb_cdxGetTagNumber( pArea, pTag ); - /* remove relations when skiping: it's faster and resolve problem - * when child can repos on skip */ - lpdbRelations = pArea->lpdbRelations; - pArea->lpdbRelations = NULL; - - pRecNo = hb_itemPutNL( NULL, 0 ); - SELF_RECNO( ( AREAP ) pArea, pRecNo ); - ulRec = hb_itemGetNL( pRecNo ); - hb_itemRelease( pRecNo ); - - SELF_GOTOP( ( AREAP ) pArea ); - while ( !( ( AREAP ) pArea )->fEof ) + if ( pTag && CURKEY_LOGCNT( pTag ) ) { - lKeyCount++; - SELF_SKIP( ( AREAP ) pArea, 1 ); + lKeyCount = pTag->logKeyCount; + } + else + { + PHB_ITEM pRecNo; + ULONG ulRec; + USHORT uiTag; + + uiTag = pArea->uiTag; + pArea->uiTag = hb_cdxGetTagNumber( pArea, pTag ); + + pRecNo = hb_itemPutNL( NULL, 0 ); + SELF_RECNO( ( AREAP ) pArea, pRecNo ); + ulRec = hb_itemGetNL( pRecNo ); + hb_itemRelease( pRecNo ); + + SELF_GOTOP( ( AREAP ) pArea ); + while ( !pArea->fEof ) + { + lKeyCount++; + SELF_SKIP( ( AREAP ) pArea, 1 ); + } + SELF_GOTO( ( AREAP ) pArea, ulRec ); + pArea->uiTag = uiTag; + if ( pTag ) + { + pTag->logKeyCount = lKeyCount; + pTag->curKeyState |= CDX_CURKEY_LOGCNT; + } } - SELF_GOTO( ( AREAP ) pArea, ulRec ); - /* restore relations and current order */ - pArea->lpdbRelations = lpdbRelations; - pArea->uiTag = uiTag; } else if ( pTag ) { LPCDXKEY pCurKey; hb_cdxIndexLockRead( pTag->pIndex ); - pCurKey = hb_cdxKeyCopy( NULL, pTag->CurKey ); - if ( pTag->topScope || pTag->bottomScope || pTag->UsrUnique ) + if ( CURKEY_RAWCNT( pTag ) ) { - if ( pTag->topScope ) - hb_cdxTagKeyFind( pTag, pTag->topScopeKey ); - else - hb_cdxTagKeyRead( pTag, TOP_RECORD ); + lKeyCount = pTag->rawKeyCount; + } + else if ( pTag->topScopeKey || pTag->bottomScopeKey || pTag->UsrUnique || pArea->dbfi.fFilter ) + { + pCurKey = hb_cdxKeyCopy( NULL, pTag->CurKey ); + hb_cdxTagGoTop( pTag ); while ( !pTag->TagEOF && hb_cdxBottomScope( pTag ) ) { lKeyCount++; - hb_cdxTagKeyRead( pTag, NEXT_RECORD ); + hb_cdxTagSkipNext( pTag ); } + pTag->fRePos = TRUE; + hb_cdxKeyCopy( pTag->CurKey, pCurKey ); + hb_cdxKeyFree( pCurKey ); } else { LPCDXPAGE pPage; - hb_cdxTagKeyRead( pTag, TOP_RECORD ); + pCurKey = hb_cdxKeyCopy( NULL, pTag->CurKey ); + hb_cdxTagGoTop( pTag ); pPage = pTag->RootPage; while ( pPage->Child ) pPage = pPage->Child; @@ -4772,10 +5528,12 @@ static LONG hb_cdxDBOIKeyCount( CDXAREAP pArea, LPCDXTAG pTag, BOOL fFilters ) } hb_cdxPageFree( pPage, TRUE ); } + pTag->fRePos = TRUE; + hb_cdxKeyCopy( pTag->CurKey, pCurKey ); + hb_cdxKeyFree( pCurKey ); } - pTag->fRePos = TRUE; - hb_cdxKeyCopy( pTag->CurKey, pCurKey ); - hb_cdxKeyFree( pCurKey ); + pTag->rawKeyCount = lKeyCount; + pTag->curKeyState |= CDX_CURKEY_RAWCNT; hb_cdxIndexUnLockRead( pTag->pIndex ); } else /* no filter, no order */ @@ -4792,54 +5550,69 @@ static LONG hb_cdxDBOIKeyNo( CDXAREAP pArea, LPCDXTAG pTag, BOOL fFilters ) { ULONG lKeyNo = 0; + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + /* TODO: what with deleted flag? */ if ( fFilters && ! pArea->dbfi.itmCobExpr ) - fFilters = 0; + fFilters = FALSE; - if ( pArea->fEof ) + if ( !pArea->fPositioned ) lKeyNo = 0; else if ( fFilters ) { - PHB_ITEM pRecNo; - ULONG ulRec; - USHORT uiTag; - LPDBRELINFO lpdbRelations; - - uiTag = pArea->uiTag; - pArea->uiTag = hb_cdxGetTagNumber( pArea, pTag ); - /* remove relations when skiping: it's faster and resolve problem - * when child can repos on skip */ - lpdbRelations = pArea->lpdbRelations; - pArea->lpdbRelations = NULL; - - pRecNo = hb_itemPutNL( NULL, 0 ); - SELF_RECNO( ( AREAP ) pArea, pRecNo ); - ulRec = hb_itemGetNL( pRecNo ); - hb_itemRelease( pRecNo ); - do + if ( pTag && CURKEY_LOGPOS( pTag ) ) { - lKeyNo++; - SELF_SKIP( ( AREAP ) pArea, -1 ); - } while ( !( ( AREAP ) pArea )->fBof ); - SELF_GOTO( ( AREAP ) pArea, ulRec ); - /* restore relations and current order */ - pArea->lpdbRelations = lpdbRelations; - pArea->uiTag = uiTag; + lKeyNo = pTag->logKeyPos; + } + else + { + PHB_ITEM pRecNo; + ULONG ulRec; + USHORT uiTag; + + /* TODO !!!: check for EOF and current filter */ + + uiTag = pArea->uiTag; + pArea->uiTag = hb_cdxGetTagNumber( pArea, pTag ); + + pRecNo = hb_itemPutNL( NULL, 0 ); + SELF_RECNO( ( AREAP ) pArea, pRecNo ); + ulRec = hb_itemGetNL( pRecNo ); + hb_itemRelease( pRecNo ); + do + { + lKeyNo++; + SELF_SKIP( ( AREAP ) pArea, -1 ); + } while ( !( ( AREAP ) pArea )->fBof ); + SELF_GOTO( ( AREAP ) pArea, ulRec ); + pArea->uiTag = uiTag; + if ( pTag ) + { + pTag->logKeyPos = lKeyNo; + CURKEY_SETLOGPOS( pTag ); + } + } } else if ( pTag ) { hb_cdxIndexLockRead( pTag->pIndex ); - if ( hb_cdxCurKeyRefresh( pArea, pTag, FALSE ) ) + hb_cdxTagOpen( pTag ); + if ( hb_cdxCurKeyRefresh( pArea, pTag ) ) { - if ( pTag->topScope || pTag->bottomScope || pTag->UsrUnique ) + if ( CURKEY_RAWPOS( pTag ) ) + { + lKeyNo = pTag->rawKeyPos; + } + else if ( pTag->topScopeKey || pTag->bottomScopeKey || pTag->UsrUnique || pArea->dbfi.fFilter ) { if ( hb_cdxBottomScope( pTag ) ) { LPCDXKEY pCurKey = hb_cdxKeyCopy( NULL, pTag->CurKey ); - while ( !pTag->TagBOF && !pTag->TagEOF && hb_cdxTopScope( pTag ) ) + while ( !pTag->TagBOF ) { lKeyNo++; - hb_cdxTagKeyRead( pTag, PREV_RECORD ); + hb_cdxTagSkipPrev( pTag ); } pTag->fRePos = TRUE; hb_cdxKeyCopy( pTag->CurKey, pCurKey ); @@ -4886,6 +5659,11 @@ static LONG hb_cdxDBOIKeyNo( CDXAREAP pArea, LPCDXTAG pTag, BOOL fFilters ) } } } + if ( lKeyNo != 0 ) + { + pTag->rawKeyPos = lKeyNo; + CURKEY_SETRAWPOS( pTag ); + } } hb_cdxIndexUnLockRead( pTag->pIndex ); } @@ -4906,6 +5684,10 @@ static LONG hb_cdxDBOIKeyNo( CDXAREAP pArea, LPCDXTAG pTag, BOOL fFilters ) static ERRCODE hb_cdxDBOIKeyGoto( CDXAREAP pArea, LPCDXTAG pTag, ULONG ulKeyNo, BOOL fFilters ) { ERRCODE retval; + ULONG ulKeyCnt = ulKeyNo; + + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); /* TODO: what with deleted flag? */ if ( fFilters && ! pArea->dbfi.itmCobExpr ) @@ -4918,53 +5700,62 @@ static ERRCODE hb_cdxDBOIKeyGoto( CDXAREAP pArea, LPCDXTAG pTag, ULONG ulKeyNo, USHORT uiTag = pArea->uiTag; pArea->uiTag = hb_cdxGetTagNumber( pArea, pTag ); retval = SELF_GOTOP( ( AREAP ) pArea ); - while ( !pArea->fEof && ulKeyNo-- ) + while ( !pArea->fEof && --ulKeyCnt ) retval = SELF_SKIP( ( AREAP ) pArea, 1 ); pArea->uiTag = uiTag; + if ( pTag && pArea->fPositioned ) + { + pTag->logKeyPos = ulKeyNo; + CURKEY_SETLOGPOS( pTag ); + } } else if ( pTag ) { hb_cdxIndexLockRead( pTag->pIndex ); - if ( pTag->topScope || pTag->bottomScope || pTag->UsrUnique ) + if ( pTag->topScopeKey || pTag->bottomScopeKey || pTag->UsrUnique || pArea->dbfi.fFilter ) { - if ( pTag->topScope ) - hb_cdxTagKeyFind( pTag, pTag->topScopeKey ); - else - hb_cdxTagKeyRead( pTag, TOP_RECORD ); + hb_cdxTagGoTop( pTag ); while ( !pTag->TagBOF && !pTag->TagEOF && hb_cdxBottomScope( pTag ) && - --ulKeyNo ) - hb_cdxTagKeyRead( pTag, NEXT_RECORD ); + --ulKeyCnt ) + hb_cdxTagSkipNext( pTag ); } else { LPCDXPAGE pPage, pOwnerPage = NULL; ULONG ulNextPg; - hb_cdxTagKeyRead( pTag, TOP_RECORD ); + hb_cdxTagGoTop( pTag ); pPage = pTag->RootPage; while ( pPage->Child ) { pOwnerPage = pPage; pPage = pPage->Child; } - while ( (ULONG) pPage->iKeys < ulKeyNo && pOwnerPage && + while ( (ULONG) pPage->iKeys < ulKeyCnt && pOwnerPage && ( ulNextPg = pTag->UsrAscend ? pPage->Right : pPage->Left ) != CDX_DUMMYNODE ) { - ulKeyNo -= pPage->iKeys; + ulKeyCnt -= pPage->iKeys; pOwnerPage->Child = hb_cdxPageNew( pPage->TagParent, pPage->Owner, ulNextPg ); hb_cdxPageFree( pPage, FALSE ); pPage = pOwnerPage->Child; } - if ( (ULONG) pPage->iKeys >= ulKeyNo ) + if ( (ULONG) pPage->iKeys >= ulKeyCnt ) { - pPage->iCurKey = pTag->UsrAscend ? ( SHORT ) ulKeyNo - 1 : pPage->iKeys - ( SHORT ) ulKeyNo; + pPage->iCurKey = pTag->UsrAscend ? ( SHORT ) ulKeyCnt - 1 : pPage->iKeys - ( SHORT ) ulKeyCnt; hb_cdxSetCurKey( pPage ); } else + { pTag->CurKey->rec = 0; + } } hb_cdxIndexUnLockRead( pTag->pIndex ); retval = SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ); + if ( pArea->fPositioned ) + { + pTag->rawKeyPos = ulKeyNo; + CURKEY_SETRAWPOS( pTag ); + } } else { @@ -4974,6 +5765,22 @@ static ERRCODE hb_cdxDBOIKeyGoto( CDXAREAP pArea, LPCDXTAG pTag, ULONG ulKeyNo, return retval; } +static void hb_cdxClearLogPosInfo( CDXAREAP pArea ) +{ + LPCDXINDEX pIndex = pArea->lpIndexes; + LPCDXTAG pTag; + + while ( pIndex ) + { + pTag = pIndex->TagList; + while ( pTag ) + { + pTag->curKeyState &= ~( CDX_CURKEY_LOGPOS | CDX_CURKEY_LOGCNT ); + pTag = pTag->pNext; + } + pIndex = pIndex->pNext; + } +} /* * -- DBFCDX METHODS -- @@ -4989,7 +5796,7 @@ static ERRCODE hb_cdxGoBottom( CDXAREAP pArea ) LPCDXTAG pTag; ERRCODE retval; - HB_TRACE(HB_TR_DEBUG, ("cdxGoBottom(%p)", pArea)); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxGoBottom(%p)", pArea)); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; @@ -4999,20 +5806,26 @@ static ERRCODE hb_cdxGoBottom( CDXAREAP pArea ) return SUPER_GOBOTTOM( ( AREAP ) pArea ); hb_cdxIndexLockRead( pTag->pIndex ); - if ( pTag->bottomScope ) - hb_cdxTagKeyFind( pTag, pTag->bottomScopeKey ); - else - hb_cdxTagKeyRead( pTag, BTTM_RECORD ); - if ( pTag->CurKey->rec != 0 && ! hb_cdxTopScope( pTag ) ) - pTag->CurKey->rec = 0; + + hb_cdxTagGoBottom( pTag ); pArea->fTop = FALSE; pArea->fBottom = TRUE; retval = SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ); - if ( retval != FAILURE && !pArea->fEof ) + + if ( retval != FAILURE && pArea->fPositioned ) + { retval = SELF_SKIPFILTER( ( AREAP ) pArea, -1 ); + + if ( CURKEY_LOGCNT( pTag ) && pArea->fPositioned ) + { + pTag->logKeyPos = pTag->logKeyCount; + CURKEY_SETLOGPOS( pTag ); + } + } hb_cdxIndexUnLockRead( pTag->pIndex ); + return retval; } @@ -5025,7 +5838,7 @@ static ERRCODE hb_cdxGoTop( CDXAREAP pArea ) LPCDXTAG pTag; ERRCODE retval; - HB_TRACE(HB_TR_DEBUG, ("cdxGoTop(%p)", pArea)); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxGoTop(%p)", pArea)); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; @@ -5035,19 +5848,20 @@ static ERRCODE hb_cdxGoTop( CDXAREAP pArea ) return SUPER_GOTOP( ( AREAP ) pArea ); hb_cdxIndexLockRead( pTag->pIndex ); - if ( pTag->topScope ) - hb_cdxTagKeyFind( pTag, pTag->topScopeKey ); - else - hb_cdxTagKeyRead( pTag, TOP_RECORD ); - if ( pTag->CurKey->rec != 0 && ! hb_cdxBottomScope( pTag ) ) - pTag->CurKey->rec = 0; + + hb_cdxTagGoTop( pTag ); pArea->fTop = TRUE; pArea->fBottom = FALSE; retval = SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ); - if ( retval != FAILURE && !pArea->fEof ) + + if ( retval != FAILURE && pArea->fPositioned ) retval = SELF_SKIPFILTER( ( AREAP ) pArea, 1 ); + + pTag->logKeyPos = 1; + CURKEY_SETLOGPOS( pTag ); + hb_cdxIndexUnLockRead( pTag->pIndex ); return retval; } @@ -5057,7 +5871,7 @@ static ERRCODE hb_cdxSeek( CDXAREAP pArea, BOOL fSoftSeek, PHB_ITEM pKeyItm, BOO { LPCDXTAG pTag; - HB_TRACE(HB_TR_DEBUG, ("cdxSeek(%p, %d, %p, %d)", pArea, fSoftSeek, pKeyItm, fFindLast)); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxSeek(%p, %d, %p, %d)", pArea, fSoftSeek, pKeyItm, fFindLast)); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; @@ -5066,7 +5880,7 @@ static ERRCODE hb_cdxSeek( CDXAREAP pArea, BOOL fSoftSeek, PHB_ITEM pKeyItm, BOO if ( ! pTag ) { - hb_cdxErrorRT( pArea, EG_NOORDER, 1201, NULL, EF_CANDEFAULT ); + hb_cdxErrorRT( pArea, EG_NOORDER, 1201, NULL, 0, EF_CANDEFAULT ); return FAILURE; } else @@ -5079,9 +5893,6 @@ static ERRCODE hb_cdxSeek( CDXAREAP pArea, BOOL fSoftSeek, PHB_ITEM pKeyItm, BOO pArea->fTop = pArea->fBottom = FALSE; pArea->fEof = FALSE; - if ( !pTag->UsrAscend ) - fFindLast = !fFindLast; - /* TODO: runtime error if valtype(pKeyItm) != pTag->Type */ pKey = hb_cdxKeyPutItem( NULL, pKeyItm, fFindLast ? CDX_MAX_REC_NUM : CDX_IGNORE_REC_NUM, pTag, TRUE, FALSE ); @@ -5091,31 +5902,23 @@ static ERRCODE hb_cdxSeek( CDXAREAP pArea, BOOL fSoftSeek, PHB_ITEM pKeyItm, BOO fEOF = TRUE; else if ( fSoftSeek ) { - if ( pTag->UsrAscend ) - { - if ( ! hb_cdxBottomScope( pTag ) ) - fEOF = TRUE; - else if ( ! hb_cdxTopScope( pTag ) ) - hb_cdxTagKeyFind( pTag, pTag->topScopeKey ); - } - else - { - if ( ! hb_cdxTopScope( pTag ) ) - fEOF = TRUE; - else if ( ! hb_cdxBottomScope( pTag ) ) - hb_cdxTagKeyFind( pTag, pTag->bottomScopeKey ); - } - if ( pTag->CurKey->rec == 0 ) + if ( ! hb_cdxBottomScope( pTag ) ) fEOF = TRUE; + else if ( ! hb_cdxTopScope( pTag ) ) + { + hb_cdxTagGoTop( pTag ); + if ( pTag->CurKey->rec == 0 ) + fEOF = TRUE; + } } hb_cdxIndexUnLockRead( pTag->pIndex ); if ( !fEOF ) { retval = SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ); - if ( retval != FAILURE && !pArea->fEof ) + if ( retval != FAILURE && pArea->fPositioned ) { retval = SELF_SKIPFILTER( ( AREAP ) pArea, fFindLast ? -1 : 1 ); - if ( retval != FAILURE && ulRec && ! pArea->fEof ) + if ( retval != FAILURE && ulRec && pArea->fPositioned ) { pArea->fFound = ( ulRec == pArea->ulRecNo || hb_cdxValCompare( pTag, pKey->val, pKey->len, @@ -5125,7 +5928,7 @@ static ERRCODE hb_cdxSeek( CDXAREAP pArea, BOOL fSoftSeek, PHB_ITEM pKeyItm, BOO } } } - if ( retval != FAILURE && ! pArea->fEof && + if ( retval != FAILURE && ( fEOF || ! hb_cdxTopScope( pTag ) || ! hb_cdxBottomScope( pTag ) ) ) { @@ -5138,6 +5941,51 @@ static ERRCODE hb_cdxSeek( CDXAREAP pArea, BOOL fSoftSeek, PHB_ITEM pKeyItm, BOO } /* ( DBENTRYP_L ) hb_cdxSkip : NULL */ +static ERRCODE hb_cdxSkip( CDXAREAP pArea, LONG lToSkip ) +{ + LPCDXTAG pTag; + ULONG ulPos; + + HB_TRACE(HB_TR_DEBUG, ("hb_cdxSkip(%p, %ld)", pArea, lToSkip)); + + pTag = lToSkip == 0 ? NULL : hb_cdxGetActiveTag( pArea ); + ulPos = ( pTag && CURKEY_LOGPOS( pTag ) ) ? pTag->logKeyPos : 0; + + if ( SUPER_SKIP( ( AREAP ) pArea, lToSkip ) == FAILURE ) + return FAILURE; + + if ( pTag ) + { + if ( lToSkip > 0 ) + { + if ( pArea->fEof ) + { + if ( lToSkip == 1 && ulPos && !CURKEY_LOGCNT( pTag ) ) + { + pTag->logKeyCount = ulPos; + pTag->curKeyState |= CDX_CURKEY_LOGCNT; + } + } + else if ( ulPos ) + { + pTag->logKeyPos += lToSkip - ( ulPos ? 0 : 1 ); + pTag->logKeyRec = pArea->ulRecNo; + } + } + else if ( pArea->fBof ) + { + pTag->logKeyPos = 1; + CURKEY_SETLOGPOS( pTag ); + } + else if ( ulPos ) + { + pTag->logKeyPos += lToSkip + ( ulPos ? 0 : 1 ); + pTag->logKeyRec = pArea->ulRecNo; + } + } + return SUCCESS; +} + /* ( DBENTRYP_L ) hb_cdxSkipFilter : NULL */ /* ( DBENTRYP_L ) hb_cdxSkipRaw */ @@ -5145,9 +5993,9 @@ static ERRCODE hb_cdxSkipRaw( CDXAREAP pArea, LONG lToSkip ) { LPCDXTAG pTag; ERRCODE retval; - BOOL fOut = FALSE; + BOOL fOut = FALSE, fForward; - HB_TRACE(HB_TR_DEBUG, ("cdxSkipRaw(%p, %ld)", pArea, lToSkip)); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxSkipRaw(%p, %ld)", pArea, lToSkip)); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; @@ -5157,75 +6005,62 @@ static ERRCODE hb_cdxSkipRaw( CDXAREAP pArea, LONG lToSkip ) if ( ! pTag || lToSkip == 0 ) return SUPER_SKIPRAW( ( AREAP ) pArea, lToSkip ); + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + + fForward = ( lToSkip > 0 ); + hb_cdxIndexLockRead( pTag->pIndex ); - if ( !pArea->fEof ) + if ( ! hb_cdxCurKeyRefresh( pArea, pTag ) ) { - if ( ! hb_cdxCurKeyRefresh( pArea, pTag, FALSE ) ) + if ( fForward ) { - if ( lToSkip > 0 ) - { - if ( pTag->TagEOF ) - fOut = TRUE; - else - lToSkip--; - } - else if ( pTag->TagEOF && !pArea->fEof ) + if ( pTag->TagEOF ) fOut = TRUE; + else if ( pTag->UsrAscend ) + lToSkip--; + } + else if ( pArea->fPositioned ) + { + if ( pTag->TagEOF ) + fOut = TRUE; + else if ( !pTag->UsrAscend ) + lToSkip++; } } - if ( lToSkip >= 0 ) + if ( fForward ) { - if ( !pArea->fEof && !fOut ) + if ( pArea->fPositioned && !fOut ) { - while ( !pTag->TagEOF && lToSkip-- > 0 ) + while ( lToSkip-- > 0 ) { - hb_cdxTagKeyRead( pTag, NEXT_RECORD ); - if ( !pTag->TagEOF ) + hb_cdxTagSkipNext( pTag ); + if ( pTag->TagEOF ) { - if ( !hb_cdxTopScope( pTag ) ) - hb_cdxTagKeyFind( pTag, pTag->topScopeKey ); - else if ( !hb_cdxBottomScope( pTag ) ) - { - fOut = TRUE; - break; - } + fOut = TRUE; + break; } } } - retval = SELF_GOTO( ( AREAP ) pArea, ( pArea->fEof || pTag->TagEOF || fOut ) + retval = SELF_GOTO( ( AREAP ) pArea, ( !pArea->fPositioned || pTag->TagEOF || fOut ) ? 0 : pTag->CurKey->rec ); } else /* if ( lToSkip < 0 ) */ { - if ( pArea->fEof ) + if ( fOut ) + hb_cdxTagGoTop( pTag ); + else { - if ( pTag->bottomScope ) - hb_cdxTagKeyFind( pTag, pTag->bottomScopeKey ); - else - hb_cdxTagKeyRead( pTag, BTTM_RECORD ); - if ( pTag->CurKey->rec == 0 || ! hb_cdxTopScope( pTag ) ) - fOut = TRUE; - lToSkip++; - } - while ( !fOut && !pTag->TagBOF && lToSkip++ < 0 ) - { - hb_cdxTagKeyRead( pTag, PREV_RECORD ); - if ( pTag->TagBOF || !hb_cdxTopScope( pTag ) || !hb_cdxBottomScope( pTag ) ) + while ( lToSkip++ < 0 ) { - fOut = TRUE; - break; + hb_cdxTagSkipPrev( pTag ); + if ( pTag->TagBOF ) + { + fOut = TRUE; + break; + } } } - if ( fOut || pTag->TagBOF ) - { - if ( pTag->topScope ) - hb_cdxTagKeyFind( pTag, pTag->topScopeKey ); - else - hb_cdxTagKeyRead( pTag, TOP_RECORD ); - if ( pTag->CurKey->rec != 0 && ! hb_cdxBottomScope( pTag ) ) - pTag->CurKey->rec = 0; - fOut = TRUE; - } retval = SELF_GOTO( ( AREAP ) pArea, pTag->CurKey->rec ); pArea->fBof = fOut; } @@ -5252,14 +6087,25 @@ static ERRCODE hb_cdxFlush( CDXAREAP pArea ) LPCDXINDEX pIndex; ERRCODE uiError; + HB_TRACE(HB_TR_DEBUG, ("hb_cdxFlush(%p)", pArea)); + + if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE ) + return FAILURE; + uiError = SUPER_FLUSH( ( AREAP ) pArea ); - pIndex = pArea->lpIndexes; - while ( pIndex ) + if ( hb_set.HB_SET_HARDCOMMIT ) { - if ( pIndex->hFile != FS_ERROR ) - hb_fsCommit( pIndex->hFile ); - pIndex = pIndex->pNext; + pIndex = pArea->lpIndexes; + while ( pIndex ) + { + if ( pIndex->hFile != FS_ERROR && pIndex->fFlush ) + { + hb_fsCommit( pIndex->hFile ); + pIndex->fFlush = FALSE; + } + pIndex = pIndex->pNext; + } } return uiError; @@ -5347,8 +6193,8 @@ static ERRCODE hb_cdxGoCold( CDXAREAP pArea ) hb_cdxIndexLockWrite( pTag->pIndex ); fLck = TRUE; } - if ( fDel && hb_cdxTagKeyFind( pTag, pTag->HotKey ) > 0 ) - hb_cdxPageKeyDelete( pTag->RootPage ); + if ( fDel ) + hb_cdxTagKeyDel( pTag, pTag->HotKey ); if ( fAdd ) hb_cdxTagKeyAdd( pTag, pKey ); } @@ -5442,6 +6288,12 @@ static ERRCODE hb_cdxClose( CDXAREAP pArea ) if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; + if ( pArea->pSort ) + { + hb_cdxSortFree( pArea->pSort ); + pArea->pSort = NULL; + } + hb_cdxOrdListClear( pArea, TRUE, NULL ); if ( pArea->bCdxSortTab ) { @@ -5452,12 +6304,14 @@ static ERRCODE hb_cdxClose( CDXAREAP pArea ) printf( "\r\ncdxTimeIntBld=%f, cdxTimeExtBld=%f, cdxTimeBld=%f\r\n" "cdxTimeGetKey=%f, cdxTimeFreeKey=%f\r\n" "cdxTimeExtBlc=%f, cdxTimeIntBlc=%f\r\n" + "cdxTimeIdxBld=%f\r\n" "cdxTimeTotal=%f\r\n", (double) cdxTimeIntBld / 1000000, (double) cdxTimeExtBld / 1000000, (double) ( cdxTimeIntBld + cdxTimeExtBld ) / 1000000, (double) cdxTimeGetKey / 1000000, (double) cdxTimeFreeKey / 1000000, (double) cdxTimeIntBlc / 1000000, (double) cdxTimeExtBlc / 1000000, - (double) ( cdxTimeIntBld + cdxTimeExtBld + + (double) cdxTimeIdxBld / 1000000, + (double) ( cdxTimeIntBld + cdxTimeExtBld + cdxTimeIdxBld + cdxTimeGetKey + cdxTimeFreeKey + cdxTimeExtBlc + cdxTimeIntBlc ) / 1000000 ); fflush(stdout); @@ -5497,29 +6351,21 @@ static ERRCODE hb_cdxOpen( CDXAREAP pArea, LPDBOPENINFO pOpenInfo ) } /* If SET_AUTOPEN open index */ +#ifdef HB_CDX_CLIP_AUTOPEN + if ( hb_set.HB_SET_AUTOPEN ) +#else if ( pArea->fHasTags && hb_set.HB_SET_AUTOPEN ) +#endif { - char * szFileName; - BYTE szSpFile[ _POSIX_PATH_MAX + 3 + 10 ]; - PHB_FNAME pFileName; + char szFileName[ _POSIX_PATH_MAX + 1 ], szSpFile[ _POSIX_PATH_MAX + 1 ]; DBORDERINFO pOrderInfo; - pFileName = hb_fsFNameSplit( pArea->szDataFileName ); - szFileName = ( char * ) hb_xgrab( _POSIX_PATH_MAX + 3 ); - szFileName[ 0 ] = '\0'; - if ( pFileName->szPath ) - strcpy( szFileName, pFileName->szPath ); - strncat( szFileName, pFileName->szName, _POSIX_PATH_MAX - strlen( szFileName ) ); - pOrderInfo.itmResult = hb_itemPutC( NULL, "" ); - SELF_ORDINFO( ( AREAP ) pArea, DBOI_BAGEXT, &pOrderInfo ); - strncat( szFileName, pOrderInfo.itmResult->item.asString.value, _POSIX_PATH_MAX - strlen( szFileName ) ); - hb_itemRelease( pOrderInfo.itmResult ); - hb_xfree( pFileName ); + hb_cdxCreateFName( pArea, NULL, szFileName, NULL ); - if ( hb_spFile( ( BYTE * ) szFileName, szSpFile ) ) + if ( hb_spFile( ( BYTE * ) szFileName, ( BYTE * ) szSpFile ) ) { pOrderInfo.itmResult = hb_itemPutNI( NULL, 0 ); - pOrderInfo.atomBagName = hb_itemPutC( NULL, (char *) szSpFile ); + pOrderInfo.atomBagName = hb_itemPutC( NULL, szSpFile ); pOrderInfo.itmOrder = NULL; SELF_ORDLSTADD( ( AREAP ) pArea, &pOrderInfo ); pOrderInfo.itmOrder = hb_itemPutNI( NULL, hb_set.HB_SET_AUTORDER ); @@ -5530,7 +6376,14 @@ static ERRCODE hb_cdxOpen( CDXAREAP pArea, LPDBOPENINFO pOpenInfo ) SELF_GOTOP( ( AREAP ) pArea ); } - hb_xfree( szFileName ); + else + { + pArea->fHasTags = FALSE; + } + } + else + { + pArea->fHasTags = FALSE; } return SUCCESS; @@ -5569,7 +6422,7 @@ static ERRCODE hb_cdxSysName( CDXAREAP pArea, BYTE * pBuffer ) /* ( DBENTRYP_V ) hb_cdxPack */ static ERRCODE hb_cdxPack( CDXAREAP pArea ) { - HB_TRACE(HB_TR_DEBUG, ("nb_cdxPack(%p)", pArea )); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxPack(%p)", pArea )); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; @@ -5620,58 +6473,29 @@ static ERRCODE hb_cdxOrderListAdd( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ) { USHORT uiFlags; FHANDLE hFile; - char * szBaseName, * szFileName, * szFileNameDbfPath = NULL; - BYTE szSpFile[ _POSIX_PATH_MAX + 3 + 10 ]; + char szBaseName[ CDX_MAXTAGNAMELEN ]; + char szSpFile[ _POSIX_PATH_MAX + 1 ], szFileName[ _POSIX_PATH_MAX + 1 ]; LPCDXINDEX pIndex, pIndexTmp; BOOL bRetry; - HB_TRACE(HB_TR_DEBUG, ("cdxOrderListAdd(%p, %p)", pArea, pOrderInfo)); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxOrderListAdd(%p, %p)", pArea, pOrderInfo)); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; - szFileName = ( char * ) hb_xgrab( _POSIX_PATH_MAX + 3 ); - strcpy( szFileName, pOrderInfo->atomBagName->item.asString.value ); - szFileName = ( char * ) hb_fileNameConv( szFileName ) ; - - if ( strlen( szFileName ) == 0 ) - { - hb_xfree( szFileName ); + if ( hb_itemGetCLen( pOrderInfo->atomBagName ) == 0 ) return FAILURE; - } - else - { - PHB_FNAME pFileName = hb_fsFNameSplit( szFileName ); - if ( !pFileName->szExtension ) - { - DBORDERINFO pExtInfo; - pExtInfo.itmResult = hb_itemPutC( NULL, "" ); - SELF_ORDINFO( ( AREAP ) pArea, DBOI_BAGEXT, &pExtInfo ); - strcat( szFileName, pExtInfo.itmResult->item.asString.value ); - hb_itemRelease( pExtInfo.itmResult ); - } - szBaseName = ( char * ) hb_xgrab( CDX_MAXTAGNAMELEN + 1 ); - hb_strncpyUpper( szBaseName, pFileName->szName, CDX_MAXTAGNAMELEN ); - if ( !pFileName->szPath ) - { - hb_xfree( pFileName ); - pFileName = hb_fsFNameSplit( pArea->szDataFileName ); - if ( pFileName->szPath ) - { - szFileNameDbfPath = ( char * ) hb_xgrab( _POSIX_PATH_MAX + 3 ); - strcpy( szFileNameDbfPath, pFileName->szPath ); - strncat( szFileNameDbfPath, szFileName, - _POSIX_PATH_MAX - strlen( szFileNameDbfPath ) ); - } - } - hb_xfree( pFileName ); - } + hb_cdxCreateFName( pArea, hb_itemGetCPtr( pOrderInfo->atomBagName ), + szFileName, szBaseName ); - if ( pArea->lpIndexes != NULL) + if ( strlen( szBaseName ) == 0 ) + return FAILURE; + + if ( pArea->lpIndexes != NULL ) { pIndexTmp = pArea->lpIndexes; - while ( pIndexTmp && ( strcmp( szBaseName, pIndexTmp->pCompound->szName ) != 0 ) ) + while ( pIndexTmp && ( hb_stricmp( szBaseName, pIndexTmp->pCompound->szName ) != 0 ) ) pIndexTmp = pIndexTmp->pNext; if ( pIndexTmp ) { @@ -5687,10 +6511,6 @@ static ERRCODE hb_cdxOrderListAdd( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ) pArea->uiTag = hb_cdxGetTagNumber( pArea, pIndexTmp->TagList ); SELF_GOTOP( ( AREAP ) pArea ); } - if ( szFileNameDbfPath != NULL ) - hb_xfree( szFileNameDbfPath ); - hb_xfree( szFileName ); - hb_xfree( szBaseName ); return FAILURE; } } @@ -5699,35 +6519,38 @@ static ERRCODE hb_cdxOrderListAdd( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ) ( pArea->fShared ? FO_DENYNONE : FO_EXCLUSIVE ); do { - hFile = FS_ERROR; - if ( szFileNameDbfPath && - hb_spFile( ( BYTE * ) szFileNameDbfPath, szSpFile ) ) - hFile = hb_spOpen( szSpFile, uiFlags ); - else if ( hb_spFile( ( BYTE * ) szFileName, szSpFile ) ) - hFile = hb_spOpen( szSpFile, uiFlags ); - else + if ( ! hb_spFile( ( BYTE * ) szFileName, ( BYTE * ) szSpFile ) ) *szSpFile = '\0'; + + hFile = hb_spOpen( ( BYTE * ) ( *szSpFile ? szSpFile : szFileName ), uiFlags ); if ( hFile == FS_ERROR ) - bRetry = ( hb_cdxErrorRT( pArea, EG_OPEN, 1003, *szSpFile ? (char *) szSpFile : szFileName, - EF_CANRETRY | EF_CANDEFAULT ) == E_RETRY ); + bRetry = ( hb_cdxErrorRT( pArea, EG_OPEN, 1003, *szSpFile ? szSpFile : szFileName, + hb_fsError(), EF_CANRETRY | EF_CANDEFAULT ) == E_RETRY ); else + { + if ( hb_fsSeek( hFile, 0, FS_END ) <= sizeof( CDXTAGHEADER ) ) + { + hb_fsClose( hFile ); + hFile = FS_ERROR; + hb_cdxErrorRT( pArea, EG_CORRUPTION, EDBF_CORRUPT, + *szSpFile ? szSpFile : szFileName, hb_fsError(), EF_CANDEFAULT ); + } bRetry = FALSE; + } } while ( bRetry ); - if ( szFileNameDbfPath != NULL ) - hb_xfree( szFileNameDbfPath ); - hb_xfree( szFileName ); - if ( hFile == FS_ERROR ) { - hb_xfree( szBaseName ); return FAILURE; } pIndex = hb_cdxIndexNew( pArea ); - pIndex->hFile = hFile; - pIndex->szFileName = hb_strdup( (char *) szSpFile ); + pIndex->hFile = hFile; + pIndex->fShared = pArea->fShared; + pIndex->fReadonly = pArea->fReadonly; + pIndex->szFileName = hb_strdup( szSpFile ); + if ( pArea->lpIndexes == NULL ) { pArea->lpIndexes = pIndex; @@ -5742,7 +6565,6 @@ static ERRCODE hb_cdxOrderListAdd( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ) /* TODO: check if index file is not corrupted */ hb_cdxIndexLoad( pIndex, szBaseName ); - hb_xfree( szBaseName ); /* dbfcdx specific: If there was no controlling order, set this one. * This is the behaviour of Clipper's dbfcdx, although @@ -5762,7 +6584,7 @@ static ERRCODE hb_cdxOrderListAdd( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ) */ static ERRCODE hb_cdxOrderListClear( CDXAREAP pArea ) { - HB_TRACE(HB_TR_DEBUG, ("cdxOrderListClear(%p)", pArea)); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxOrderListClear(%p)", pArea)); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; @@ -5781,7 +6603,7 @@ static ERRCODE hb_cdxOrderListFocus( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ) { LPCDXTAG pTag; - HB_TRACE(HB_TR_DEBUG, ("cdxOrderListFocus(%p, %p)", pArea, pOrderInfo)); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxOrderListFocus(%p, %p)", pArea, pOrderInfo)); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; @@ -5794,7 +6616,7 @@ static ERRCODE hb_cdxOrderListFocus( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ) pOrderInfo->itmResult = hb_itemPutC( pOrderInfo->itmResult, pTag->szName ); if ( pOrderInfo->itmOrder ) - pArea->uiTag = hb_cdxFindTag( pArea, pOrderInfo->itmOrder ); + hb_cdxFindTag( pArea, pOrderInfo->itmOrder, pOrderInfo->atomBagName, &(pArea->uiTag) ); /* TODO: RTerror if not found? */ return SUCCESS; @@ -5806,19 +6628,19 @@ static ERRCODE hb_cdxOrderListRebuild( CDXAREAP pArea ) LPCDXINDEX pIndex, * pIndexPtr; USHORT uiPrevTag; - HB_TRACE(HB_TR_DEBUG, ("nb_cdxPack(%p)", pArea )); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxPack(%p)", pArea )); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; if ( pArea->fShared ) { - hb_cdxErrorRT( pArea, EG_SHARED, EDBF_SHARED, pArea->szDataFileName, 0 ); + hb_cdxErrorRT( pArea, EG_SHARED, EDBF_SHARED, pArea->szDataFileName, 0, 0 ); return FAILURE; } if ( pArea->fReadonly ) { - hb_cdxErrorRT( pArea, EG_READONLY, EDBF_READONLY, pArea->szDataFileName, 0 ); + hb_cdxErrorRT( pArea, EG_READONLY, EDBF_READONLY, pArea->szDataFileName, 0, 0 ); return FAILURE; } @@ -5859,10 +6681,8 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo BOOL fNewFile, fOpenedIndex; PHB_ITEM pKeyExp, pForExp, pResult; HB_MACRO_PTR pExpMacro, pForMacro; - char * szFileName, * szCpndTagName, * szTagName; - BYTE szSpFile[ _POSIX_PATH_MAX + 3 + 10 ]; - PHB_FNAME pFileName; - DBORDERINFO pExtInfo; + char szCpndTagName[ CDX_MAXTAGNAMELEN + 1 ], szTagName[ CDX_MAXTAGNAMELEN + 1 ]; + char szFileName[ _POSIX_PATH_MAX + 1 ], szSpFile[ _POSIX_PATH_MAX + 1 ]; LPCDXINDEX pIndex; LPCDXTAG pTag; USHORT uiType, uiLen; @@ -5871,7 +6691,7 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo pForExp = NULL; pExpMacro = pForMacro = NULL; - HB_TRACE(HB_TR_DEBUG, ("cdxOrderCreate(%p, %p)", pArea, pOrderInfo)); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxOrderCreate(%p, %p)", pArea, pOrderInfo)); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; @@ -5912,7 +6732,7 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo { case HB_IT_INTEGER: case HB_IT_LONG: -#ifndef HB_LONG_LONG_OFF +#ifdef HB_IT_LONGLONG case HB_IT_LONGLONG: #endif case HB_IT_DOUBLE: @@ -5936,7 +6756,9 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo if ( pExpMacro != NULL ) hb_macroDelete( pExpMacro ); SELF_GOTO( ( AREAP ) pArea, ulRecNo ); + hb_cdxErrorRT( pArea, EG_DATATYPE, 1026, NULL, 0, 0 ); /* TODO: !!! runtime error ? */ + hb_itemRelease( pResult ); return FAILURE; } hb_itemRelease( pResult ); @@ -5946,7 +6768,7 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo if ( pExpMacro != NULL ) hb_macroDelete( pExpMacro ); SELF_GOTO( ( AREAP ) pArea, ulRecNo ); - hb_cdxErrorRT( pArea, EG_DATAWIDTH, 1026, NULL, 0 ); + hb_cdxErrorRT( pArea, EG_DATAWIDTH, 1026, NULL, 0, 0 ); return FAILURE; } /* Check conditional expression */ @@ -6009,69 +6831,82 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo return FAILURE; } } - /* Check file name */ - szFileName = ( char * ) hb_xgrab( _POSIX_PATH_MAX + 3 ); - szFileName[ 0 ] = '\0'; - if ( !pOrderInfo->abBagName || ( strlen( ( char * ) pOrderInfo->abBagName ) == 0 ) ) + /* + * abBagName -> cBag, atomBagName -> cTag + * The following scheme implemented: + * 1. abBagName == NULL -> add the Tag to the structural index + * 2. atomBagName == NULL -> overwrite any index file of abBagName + * 3. ads the Tag to index file + */ + + hb_cdxCreateFName( pArea, ( char * ) pOrderInfo->abBagName, + szFileName, szCpndTagName ); + + if ( pOrderInfo->atomBagName && strlen( ( char * ) pOrderInfo->atomBagName ) > 0 ) { - pFileName = hb_fsFNameSplit( pArea->szDataFileName ); - if ( pFileName->szPath ) - strcat( szFileName, pFileName->szPath ); - strcat( szFileName, pFileName->szName ); - pExtInfo.itmResult = hb_itemPutC( NULL, "" ); - SELF_ORDINFO( ( AREAP ) pArea, DBOI_BAGEXT, &pExtInfo ); - strcat( szFileName, pExtInfo.itmResult->item.asString.value ); - hb_itemRelease( pExtInfo.itmResult ); - } - else - { - strcpy( szFileName, ( char * ) pOrderInfo->abBagName ); - pFileName = hb_fsFNameSplit( szFileName ); - if ( !pFileName->szExtension ) - { - pExtInfo.itmResult = hb_itemPutC( NULL, "" ); - SELF_ORDINFO( ( AREAP ) pArea, DBOI_BAGEXT, &pExtInfo ); - strcat( szFileName, pExtInfo.itmResult->item.asString.value ); - hb_itemRelease( pExtInfo.itmResult ); - } - } - szTagName = ( char * ) hb_xgrab( CDX_MAXTAGNAMELEN + 1 ); - szCpndTagName = ( char * ) hb_xgrab( CDX_MAXTAGNAMELEN + 1 ); - hb_strncpyUpperTrim( szCpndTagName, pFileName->szName, CDX_MAXTAGNAMELEN ); - hb_xfree( pFileName ); - if ( pOrderInfo->atomBagName && ( strlen( ( char * ) pOrderInfo->atomBagName ) > 0 ) ) hb_strncpyUpperTrim( szTagName, ( char * ) pOrderInfo->atomBagName, CDX_MAXTAGNAMELEN ); + fNewFile = FALSE; + } else + { strcpy( szTagName, szCpndTagName ); + fNewFile = TRUE; + } if ( !pArea->lpdbOrdCondInfo || ( pArea->lpdbOrdCondInfo->fAll && !pArea->lpdbOrdCondInfo->fAdditive ) ) hb_cdxOrdListClear( pArea, FALSE, NULL ); pIndex = hb_cdxFindBag( pArea, szFileName ); + + if ( fNewFile && pIndex != NULL ) + { + LPCDXINDEX * pIndexPtr = &pArea->lpIndexes; + while ( *pIndexPtr ) + { + if ( pIndex == *pIndexPtr ) + { + *pIndexPtr = pIndex->pNext; + break; + } + pIndexPtr = &(*pIndexPtr)->pNext; + } + hb_cdxIndexFree( pIndex ); + pIndex = NULL; + } fOpenedIndex = ( pIndex != NULL ); - fNewFile = FALSE; if ( !fOpenedIndex ) { FHANDLE hFile; - fNewFile = ! hb_spFile( ( BYTE * ) szFileName, szSpFile ); - if ( fNewFile ) + BOOL bRetry; + + if ( !fNewFile ) + fNewFile = ! hb_spFile( ( BYTE * ) szFileName, ( BYTE * ) szSpFile ); + + do { - /* TODO: no API to take real file name with path */ - hFile = hb_spCreate( ( BYTE * ) szFileName, FC_NORMAL ); - } - else - { - strcpy( szFileName, ( char * ) szSpFile ); - hFile = hb_spOpen( ( BYTE * ) szFileName, - FO_READWRITE | ( pArea->fShared ? FO_DENYNONE : FO_EXCLUSIVE ) ); - } + if ( fNewFile ) + { + /* TODO: no API to take real file name with path */ + hFile = hb_spCreate( ( BYTE * ) szFileName, FC_NORMAL ); + } + else + { + hb_strncpy( szFileName, szSpFile, _POSIX_PATH_MAX ); + hFile = hb_spOpen( ( BYTE * ) szFileName, + FO_READWRITE | ( pArea->fShared ? FO_DENYNONE : FO_EXCLUSIVE ) ); + } + if ( hFile == FS_ERROR ) + bRetry = ( hb_cdxErrorRT( pArea, EG_CREATE, EDBF_CREATE, szFileName, + hb_fsError(), EF_CANRETRY | EF_CANDEFAULT ) == E_RETRY ); + else + bRetry = FALSE; + + } while ( bRetry ); + if ( hFile == FS_ERROR ) { - hb_xfree( szFileName ); - hb_xfree( szTagName ); - hb_xfree( szCpndTagName ); hb_itemRelease( pKeyExp ); if ( pForExp != NULL ) hb_itemRelease( pForExp ); @@ -6080,9 +6915,9 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo if ( pForMacro != NULL ) hb_macroDelete( pForMacro ); SELF_GOTO( ( AREAP ) pArea, ulRecNo ); - /* TODO: !!! runtime error ? */ return FAILURE; } + pIndex = hb_cdxIndexNew( pArea ); pIndex->hFile = hFile; pIndex->fShared = pArea->fShared; @@ -6111,6 +6946,7 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo { hb_fsSeek( pIndex->hFile, 0, FS_SET ); hb_fsWrite( pIndex->hFile, NULL, 0 ); + pIndex->fChanged = TRUE; hb_cdxIndexDropAvailPage( pIndex ); if ( pIndex->pCompound != NULL ) hb_cdxTagFree( pIndex->pCompound ); @@ -6124,19 +6960,21 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo /* Update DBF header */ if ( !pArea->fHasTags ) { + PHB_FNAME pFileName; pFileName = hb_fsFNameSplit( pArea->szDataFileName ); - hb_strncpyUpper( szFileName, pFileName->szName, CDX_MAXTAGNAMELEN ); + hb_strncpyUpperTrim( szFileName, pFileName->szName, CDX_MAXTAGNAMELEN ); hb_xfree( pFileName ); - if ( strcmp( szFileName, szCpndTagName ) == 0 ) + if ( hb_stricmp( szFileName, szCpndTagName ) == 0 ) { pArea->fHasTags = TRUE; - SELF_WRITEDBHEADER( ( AREAP ) pArea ); +#ifdef HB_CDX_CLIP_AUTOPEN + if ( !pArea->fReadonly && hb_set.HB_SET_AUTOPEN ) +#else + if ( !pArea->fReadonly ) +#endif + SELF_WRITEDBHEADER( ( AREAP ) pArea ); } } - hb_xfree( szFileName ); - - if ( !pArea->lpdbOrdCondInfo || pArea->lpdbOrdCondInfo->fAll ) - pArea->uiTag = 0; pTag = hb_cdxIndexAddTag( pIndex, szTagName, pOrderInfo->abExpr->item.asString.value, pKeyExp, bType, uiLen, ( char * ) ( pArea->lpdbOrdCondInfo ? pArea->lpdbOrdCondInfo->abFor : @@ -6144,8 +6982,6 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo ( pArea->lpdbOrdCondInfo ? !pArea->lpdbOrdCondInfo->fDescending : TRUE ) , pOrderInfo->fUnique, ( pArea->lpdbOrdCondInfo ? pArea->lpdbOrdCondInfo->fCustom : FALSE ) ); - hb_xfree( szTagName ); - hb_xfree( szCpndTagName ); if ( pArea->lpdbOrdCondInfo && ( !pArea->lpdbOrdCondInfo->fAll && !pArea->lpdbOrdCondInfo->fAdditive ) ) { @@ -6178,10 +7014,9 @@ static ERRCODE hb_cdxOrderDestroy( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ) { LPCDXINDEX pIndex, pIndexTmp; LPCDXTAG pTag; - USHORT uiTag; char * szFileName; - HB_TRACE(HB_TR_DEBUG, ("cdxOrderDestroy(%p, %p)", pArea, pOrderInfo)); + HB_TRACE(HB_TR_DEBUG, ("hb_cdxOrderDestroy(%p, %p)", pArea, pOrderInfo)); if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; @@ -6191,12 +7026,11 @@ static ERRCODE hb_cdxOrderDestroy( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ) if ( pOrderInfo->itmOrder ) { - uiTag = hb_cdxFindTag( pArea, pOrderInfo->itmOrder ); - if ( uiTag ) + pTag = hb_cdxFindTag( pArea, pOrderInfo->itmOrder, pOrderInfo->atomBagName, NULL ); + if ( pTag ) { - pTag = hb_cdxGetTagByNumber( pArea, uiTag ); pIndex = pTag->pIndex; - if ( !pIndex->fShared && !pIndex->fReadonly ) + if ( /* !pIndex->fShared && */ !pIndex->fReadonly ) { hb_cdxIndexLockWrite( pIndex ); hb_cdxIndexDelTag( pIndex, pTag->szName ); @@ -6209,7 +7043,12 @@ static ERRCODE hb_cdxOrderDestroy( CDXAREAP pArea, LPDBORDERINFO pOrderInfo ) if ( pArea->fHasTags ) { pArea->fHasTags = FALSE; - SELF_WRITEDBHEADER( ( AREAP ) pArea ); +#ifdef HB_CDX_CLIP_AUTOPEN + if ( !pArea->fReadonly && hb_set.HB_SET_AUTOPEN ) +#else + if ( !pArea->fReadonly ) +#endif + SELF_WRITEDBHEADER( ( AREAP ) pArea ); } } else @@ -6260,20 +7099,63 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO case DBOI_BAGEXT: case DBOI_LOCKOFFSET: case DBOI_HPLOCKING: + case DBOI_KEYSINCLUDED: break; default: if ( pOrderInfo->itmOrder ) - /* TODO: check for atom bug name (indename) */ - uiTag = hb_cdxFindTag( pArea, pOrderInfo->itmOrder ); + pTag = hb_cdxFindTag( pArea, pOrderInfo->itmOrder, pOrderInfo->atomBagName, &uiTag ); else + { uiTag = pArea->uiTag; - pTag = hb_cdxGetTagByNumber( pArea, uiTag ); + pTag = hb_cdxGetTagByNumber( pArea, uiTag ); + } } switch( uiIndex ) { case DBOI_CONDITION: pOrderInfo->itmResult = hb_itemPutC( pOrderInfo->itmResult, ( pTag ? pTag->ForExpr : "" ) ); + if ( pTag && pOrderInfo->itmNewVal && HB_IS_STRING( pOrderInfo->itmNewVal ) ) + { + if ( pTag->ForExpr != NULL ) + { + hb_xfree( pTag->ForExpr ); + pTag->ForExpr = NULL; + } + if ( pTag->pForItem != NULL ) + { + if ( hb_itemType( pTag->pForItem ) != HB_IT_BLOCK ) + hb_macroDelete( ( HB_MACRO_PTR ) hb_itemGetPtr( pTag->pForItem ) ); + hb_itemRelease( pTag->pForItem ); + pTag->pForItem = NULL; + } + if ( hb_itemGetCLen( pOrderInfo->itmNewVal ) > 0 ) + { + HB_MACRO_PTR pMacro; + char * pForExpr = hb_itemGetCPtr( pOrderInfo->itmNewVal ); + + if ( SELF_COMPILE( ( AREAP ) pTag->pIndex->pArea, ( BYTE *) pForExpr ) == SUCCESS ) + /* TODO: RT error if SELF_COMPILE return FAILURE */ + { + pTag->pForItem = pTag->pIndex->pArea->valResult; + pTag->pIndex->pArea->valResult = NULL; + pMacro = ( HB_MACRO_PTR ) hb_itemGetPtr( pTag->pForItem ); + hb_macroRun( pMacro ); + if ( hb_itemType( hb_stackItemFromTop( -1 ) ) == HB_IT_LOGICAL ) + { + pTag->ForExpr = ( char * ) hb_xgrab( CDX_MAXKEY + 1 ); + hb_strncpyTrim( pTag->ForExpr, pForExpr, CDX_MAXKEY ); + } + else + { + hb_macroDelete( pMacro ); + hb_itemRelease( pTag->pForItem ); + pTag->pForItem = NULL; + } + hb_stackPop(); + } + } + } break; case DBOI_EXPRESSION: @@ -6324,6 +7206,46 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO hb_cdxDBOISkipEval( pArea, pTag, FALSE, pOrderInfo->itmNewVal ) ); break; + case DBOI_SKIPWILD: + pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, + hb_cdxDBOISkipWild( pArea, pTag, TRUE, pOrderInfo->itmNewVal ) ); + break; + + case DBOI_SKIPWILDBACK: + pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, + hb_cdxDBOISkipWild( pArea, pTag, FALSE, pOrderInfo->itmNewVal ) ); + break; + +#if defined(__XHARBOUR__) + case DBOI_SKIPREGEX: + pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, + hb_cdxDBOISkipRegEx( pArea, pTag, TRUE, pOrderInfo->itmNewVal ) ); + break; + + case DBOI_SKIPREGEXBACK: + pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, + hb_cdxDBOISkipRegEx( pArea, pTag, FALSE, pOrderInfo->itmNewVal ) ); + break; +#endif + + case DBOI_SCOPEEVAL: + if ( pTag && hb_arrayLen( pOrderInfo->itmNewVal ) == DBRMI_SIZE && + hb_arrayGetPtr( pOrderInfo->itmNewVal, DBRMI_FUNCTION ) != NULL ) + { + pOrderInfo->itmResult = hb_itemPutNL( pOrderInfo->itmResult, + hb_cdxDBOIScopeEval( pTag, ( HB_EVALSCOPE_FUNC ) + hb_arrayGetPtr( pOrderInfo->itmNewVal, DBRMI_FUNCTION ), + hb_arrayGetPtr( pOrderInfo->itmNewVal, DBRMI_PARAM ), + hb_arrayGetItemPtr( pOrderInfo->itmNewVal, DBRMI_LOVAL ), + hb_arrayGetItemPtr( pOrderInfo->itmNewVal, DBRMI_HIVAL ) ) ); + } + else + { + /* TODO: RT error */ + ; + } + break; + case DBOI_NAME: pOrderInfo->itmResult = hb_itemPutC( pOrderInfo->itmResult, ( pTag ? pTag->szName : "" ) ); break; @@ -6344,7 +7266,7 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO break; case DBOI_FULLPATH: - pOrderInfo->itmResult = hb_itemPutC( pOrderInfo->itmResult, ( pTag ? pTag->pIndex->szFileName : "" ) ); + pOrderInfo->itmResult = hb_itemPutC( pOrderInfo->itmResult, pTag ? pTag->pIndex->szFileName : "" ); break; case DBOI_BAGEXT: @@ -6364,28 +7286,32 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO break; } - case DBOI_ORDERCOUNT: - uiTag = 0; - if ( pArea->lpIndexes ) - { - pTag = pArea->lpIndexes->TagList; - while ( pTag ) - { - uiTag++; - if ( pTag->pNext ) - pTag = pTag->pNext; - else - { - if ( pTag->pIndex->pNext ) - pTag = pTag->pIndex->pNext->TagList; - else - pTag = NULL; - } - } - } - pOrderInfo->itmResult = hb_itemPutNI( pOrderInfo->itmResult, uiTag ); + case DBOI_KEYSINCLUDED: + pOrderInfo->itmResult = hb_itemPutNL( pOrderInfo->itmResult, + pArea->pSort ? pArea->pSort->ulTotKeys : 0 ); break; + case DBOI_ORDERCOUNT: + { + LPCDXINDEX pIndex; + char *pszBag = hb_itemGetCLen( pOrderInfo->atomBagName ) > 0 ? + hb_itemGetCPtr( pOrderInfo->atomBagName ) : NULL; + uiTag = 0; + pIndex = pszBag ? hb_cdxFindBag( pArea, pszBag ) : pArea->lpIndexes; + while ( pIndex ) + { + pTag = pIndex->TagList; + while ( pTag ) + { + uiTag++; + pTag = pTag->pNext; + } + pIndex = pszBag ? NULL : pIndex->pNext; + } + pOrderInfo->itmResult = hb_itemPutNI( pOrderInfo->itmResult, uiTag ); + break; + } + case DBOI_FILEHANDLE: pOrderInfo->itmResult = hb_itemPutNL( pOrderInfo->itmResult, ( pTag ? ( LONG ) pTag->pIndex->hFile : FS_ERROR ) ); break; @@ -6397,13 +7323,19 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO case DBOI_ISDESC: pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, ( pTag ? !pTag->UsrAscend : FALSE ) ); if ( pOrderInfo->itmNewVal && HB_IS_LOGICAL( pOrderInfo->itmNewVal ) ) + { pTag->UsrAscend = ! hb_itemGetL( pOrderInfo->itmNewVal ); + pTag->curKeyState &= ~( CDX_CURKEY_RAWPOS | CDX_CURKEY_LOGPOS ); + } break; case DBOI_UNIQUE: pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, ( pTag ? pTag->UniqueKey || pTag->UsrUnique : FALSE ) ); if ( pOrderInfo->itmNewVal && HB_IS_LOGICAL( pOrderInfo->itmNewVal ) && !pTag->UniqueKey ) + { pTag->UsrUnique = hb_itemGetL( pOrderInfo->itmNewVal ); + pTag->curKeyState &= ~( CDX_CURKEY_RAWPOS | CDX_CURKEY_LOGPOS ); + } break; case DBOI_KEYTYPE: @@ -6427,12 +7359,14 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO case DBOI_KEYVAL: hb_itemClear( pOrderInfo->itmResult ); - if ( pTag && !pArea->fEof ) + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + if ( pTag && pArea->fPositioned ) { if ( pTag->CurKey->rec != pArea->ulRecNo ) { hb_cdxIndexLockRead( pTag->pIndex ); - hb_cdxCurKeyRefresh( pArea, pTag, FALSE ); + hb_cdxCurKeyRefresh( pArea, pTag ); hb_cdxIndexUnLockRead( pTag->pIndex ); } if ( pTag->CurKey->rec == pArea->ulRecNo ) @@ -6476,6 +7410,11 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO case DBOI_CUSTOM: pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, ( pTag ? pTag->Custom : FALSE ) ); + if ( pOrderInfo->itmNewVal && HB_IS_LOGICAL( pOrderInfo->itmNewVal ) + && hb_itemGetL( pOrderInfo->itmNewVal ) ) + { + pTag->Custom = TRUE; + } break; case DBOI_KEYADD: @@ -6488,21 +7427,21 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO if ( pTag->Custom ) { LPCDXKEY pKey; + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); hb_cdxIndexLockWrite( pTag->pIndex ); if ( pOrderInfo->itmNewVal && !HB_IS_NIL( pOrderInfo->itmNewVal ) ) pKey = hb_cdxKeyPutItem( NULL, pOrderInfo->itmNewVal, pArea->ulRecNo, pTag, TRUE, TRUE ); else pKey = hb_cdxKeyEval( NULL, pTag, TRUE ); - hb_cdxTagKeyAdd( pTag, pKey ); - if ( uiTag != pArea->uiTag ) - hb_cdxTagClose( pTag ); + pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, + hb_cdxTagKeyAdd( pTag, pKey ) ); hb_cdxIndexUnLockWrite( pTag->pIndex ); - pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, TRUE ); hb_cdxKeyFree( pKey ); } else { - hb_cdxErrorRT( pArea, 0, 1052, "", 0 ); + hb_cdxErrorRT( pArea, 0, 1052, NULL, 0, 0 ); } } break; @@ -6517,28 +7456,21 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO if ( pTag->Custom ) { LPCDXKEY pKey; + if( pArea->lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); hb_cdxIndexLockWrite( pTag->pIndex ); if ( pOrderInfo->itmNewVal && !HB_IS_NIL( pOrderInfo->itmNewVal ) ) pKey = hb_cdxKeyPutItem( NULL, pOrderInfo->itmNewVal, pArea->ulRecNo, pTag, TRUE, TRUE ); else pKey = hb_cdxKeyEval( NULL, pTag, TRUE ); - if ( hb_cdxTagKeyFind( pTag, pKey ) > 0 ) - { - hb_cdxPageKeyDelete( pTag->RootPage ); - pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, TRUE ); - } - else - { - pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, FALSE ); - } - if ( uiTag != pArea->uiTag ) - hb_cdxTagClose( pTag ); + pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult, + hb_cdxTagKeyDel( pTag, pKey ) ); hb_cdxIndexUnLockWrite( pTag->pIndex ); hb_cdxKeyFree( pKey ); } else { - hb_cdxErrorRT( pArea, 0, 1052, "", 0 ); + hb_cdxErrorRT( pArea, 0, 1052, NULL, 0, 0 ); } } break; @@ -6550,7 +7482,13 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO return SUCCESS; } -/* ( DBENTRYP_V ) hb_cdxClearFilter : NULL */ +/* ( DBENTRYP_V ) hb_cdxClearFilter */ +static ERRCODE hb_cdxClearFilter( CDXAREAP pArea ) +{ + hb_cdxClearLogPosInfo( pArea ); + return SUPER_CLEARFILTER( ( AREAP ) pArea ); +} + /* ( DBENTRYP_V ) hb_cdxClearLocate : NULL */ /* ( DBENTRYP_V ) hb_cdxClearScope */ @@ -6570,7 +7508,18 @@ static ERRCODE hb_cdxClearScope( CDXAREAP pArea ) return SUCCESS; } -/* ( DBENTRYP_VPLP ) hb_cdxCountScope : NULL */ +/* ( DBENTRYP_VPLP ) hb_cdxCountScope */ +static ERRCODE hb_cdxCountScope( CDXAREAP pArea, void * pPtr, LONG * plRec ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_cdxCountScope(%p, %p, %p)", pArea, pPtr, plRec)); + + if ( pPtr == NULL ) + { + return SUCCESS; + } + return SUPER_COUNTSCOPE( ( AREAP ) pArea, pPtr, plRec ); +} + /* ( DBENTRYP_I ) hb_cdxFilterText : NULL */ /* ( DBENTRYP_SI ) hb_cdxScopeInfo */ @@ -6587,21 +7536,26 @@ static ERRCODE hb_cdxScopeInfo( CDXAREAP pArea, USHORT nScope, PHB_ITEM pItem ) { PHB_ITEM *pScope; - nScope = ( ( nScope == 0 ) ? 0 : 1 ) ^ ( pTag->UsrAscend ? 0 : 1 ); - pScope = ( nScope == 0 ) ? &(pTag->topScope) : &(pTag->bottomScope); + pScope = ( pTag->UsrAscend ? nScope == 0 : nScope != 0 ) ? + &(pTag->topScope) : &(pTag->bottomScope); if ( *pScope ) hb_itemCopy( pItem, *pScope ); } return SUCCESS; } -/* ( DBENTRYP_VFI ) hb_cdxSetFilter : NULL */ +/* ( DBENTRYP_VFI ) hb_cdxSetFilter */ +static ERRCODE hb_cdxSetFilter( CDXAREAP pArea, LPDBFILTERINFO pFilterInfo ) +{ + hb_cdxClearLogPosInfo( pArea ); + return SUPER_SETFILTER( ( AREAP ) pArea, pFilterInfo ); +} + /* ( DBENTRYP_VLO ) hb_cdxSetLocate : NULL */ /* ( DBENTRYP_VOS ) hb_cdxSetScope */ static ERRCODE hb_cdxSetScope( CDXAREAP pArea, LPDBORDSCOPEINFO sInfo ) { - USHORT nScope = sInfo->nScope; LPCDXTAG pTag; HB_TRACE(HB_TR_DEBUG, ("hb_cdxSetScope(%p, %p)", pArea, sInfo)); @@ -6610,21 +7564,15 @@ static ERRCODE hb_cdxSetScope( CDXAREAP pArea, LPDBORDSCOPEINFO sInfo ) if ( pTag ) { - nScope = ( ( nScope == 0 ) ? 0 : 1 ) ^ ( pTag->UsrAscend ? 0 : 1 ); - if ( !sInfo->scopeValue ) { - hb_cdxTagClearScope( pTag, nScope ); + hb_cdxTagClearScope( pTag, sInfo->nScope ); } else { - PHB_ITEM *pScope; - LPCDXKEY *pScopeKey; USHORT type; BOOL fOK, fCB = FALSE; - pScope = (nScope == 0) ? &(pTag->topScope) : &(pTag->bottomScope); - pScopeKey = (nScope == 0) ? &(pTag->topScopeKey) : &(pTag->bottomScopeKey); type = sInfo->scopeValue->type; if ( type == HB_IT_BLOCK ) { @@ -6634,7 +7582,6 @@ static ERRCODE hb_cdxSetScope( CDXAREAP pArea, LPDBORDSCOPEINFO sInfo ) type = HB_VM_STACK.Return.type; fCB = TRUE; } - /* printf("\r\ntype=%lx", type);fflush(stdout); */ switch ( pTag->uiType ) { @@ -6651,13 +7598,30 @@ static ERRCODE hb_cdxSetScope( CDXAREAP pArea, LPDBORDSCOPEINFO sInfo ) } if ( fOK ) { + PHB_ITEM *pScope; + LPCDXKEY *pScopeKey; + + if ( pTag->UsrAscend ? sInfo->nScope == 0 : sInfo->nScope != 0 ) + { + pScope = &(pTag->topScope); + pScopeKey = &(pTag->topScopeKey); + } + else + { + pScope = &(pTag->bottomScope); + pScopeKey = &(pTag->bottomScopeKey); + } + if ( *pScope == NULL ) *pScope = hb_itemNew( NULL ); hb_itemCopy( *pScope, sInfo->scopeValue ); *pScopeKey = hb_cdxKeyPutItem( *pScopeKey, fCB ? &(HB_VM_STACK.Return) : sInfo->scopeValue, - (nScope == 0) ? CDX_IGNORE_REC_NUM : CDX_MAX_REC_NUM, + (sInfo->nScope == 0) ? CDX_IGNORE_REC_NUM : CDX_MAX_REC_NUM, pTag, TRUE, FALSE ); + pTag->curKeyState &= ~( CDX_CURKEY_RAWCNT | CDX_CURKEY_LOGCNT ); + if ( sInfo->nScope == 0 ) + pTag->curKeyState &= ~( CDX_CURKEY_RAWPOS | CDX_CURKEY_LOGPOS ); } else { @@ -6700,1161 +7664,488 @@ static ERRCODE hb_cdxSetScope( CDXAREAP pArea, LPDBORDSCOPEINFO sInfo ) -/* ######################################################################### */ -/* ######################################################################### */ -/* ######################################################################### */ /* ######################################################################### */ -#include "dbfcdx1.h" - -/* ######################################################################### */ -static LPSORTINFO hb_cdxSortNew( LPCDXTAG pTag, BOOL bUnique ); -static void hb_cdxSortFree( LPSORTINFO pSort ); -static void hb_cdxSortLinkNew( LPSORTINFO pSort, LONG * NewLink ); -static void hb_cdxSortGetNewChunk( LPSORTINFO pSort ); -static void hb_cdxSortInsertWord( LPSORTINFO pSort, LONG Tag, char * Value, - USHORT uiLen ); -static void hb_cdxSortStuffKey( LPSORTINFO pSort, LPSORTDATA * wx, BOOL fTag ); -static void hb_cdxSortGetNode( LPSORTINFO pSort, BYTE Character, - LONG * NewLink, BOOL fTag ); -static LPSORTDATA hb_cdxSortLinkGet( LPSORTINFO pSort, LONG Value ); -static void hb_cdxSortDisplayWord( LPSORTINFO pSort ); -static void hb_cdxSortRecurseDict( LPSORTINFO pSort, LONG WPtr, LONG WBgn ); -static void hb_cdxSortSendWord( LPSORTINFO pSort, BYTE * Value ); -static void hb_cdxSortOutputWord( LPSORTINFO pSort, LONG Tag, BYTE * Value, - USHORT uiLen ); -static void hb_cdxSortAddToNode( LPSORTINFO pSort, USHORT Lvl, LONG Tag, LONG Link, - LPCDXKEYINFO Value ); -static void hb_cdxSortAddExternal( LPSORTINFO pSort, USHORT Lvl, LONG Tag, LONG Link, - LPCDXKEYINFO Value ); -static void hb_cdxSortAddInternal( LPSORTINFO pSort, USHORT Lvl, LONG Tag, LONG Link, - LPCDXKEYINFO Value ); -/* ######################################################################### */ - -static LPCDXKEYINFO hb_cdxSortKeyNew( void ) +static int hb_cdxQuickSortCompare( LPCDXSORTINFO pSort, BYTE * pKey1, BYTE * pKey2 ) { - LPCDXKEYINFO pKey; - pKey = ( LPCDXKEYINFO ) hb_xgrab( sizeof( CDXKEYINFO ) ); - memset( pKey, 0, sizeof( CDXKEYINFO ) ); - return pKey; + int i, iLen = pSort->keyLen; + + i = hb_cdxValCompare( pSort->pTag, pKey1, iLen, pKey2, iLen, TRUE ); + + if ( i == 0 ) + { + i = ( HB_GET_LE_UINT32( pKey1 + iLen ) < HB_GET_LE_UINT32( pKey2 + iLen ) ) ? -1 : 1; + } + + return i; } -static void hb_cdxSortKeyFree( LPCDXKEYINFO pKey ) +static BOOL hb_cdxQSort( LPCDXSORTINFO pSort, BYTE * pSrc, BYTE * pBuf, LONG lKeys ) { - if ( pKey ) + if ( lKeys > 1 ) { - if ( pKey->Value ) - hb_xfree( pKey->Value ); - hb_xfree( pKey ); - } -} + int iLen = pSort->keyLen + 4; + LONG l1, l2; + BYTE * pPtr1, * pPtr2, *pDst; + BOOL f1, f2; -static LPCDXKEYINFO hb_cdxSortKeyCopy( LPCDXKEYINFO pKeyDest, LPCDXKEYINFO pKey ) -{ - if ( !pKeyDest ) - pKeyDest = hb_cdxSortKeyNew(); - if ( pKeyDest->Value ) - { - hb_xfree( pKeyDest->Value ); - pKeyDest->Value = NULL; - pKeyDest->length = pKeyDest->realLength = 0; - } - if ( pKey ) - { - pKeyDest->Value = (BYTE *) hb_xgrab( pKey->length + 1 ); - memcpy( pKeyDest->Value, pKey->Value, pKey->length ); - pKeyDest->length = pKey->length; - pKeyDest->realLength = pKey->realLength; - pKeyDest->Value[ pKeyDest->length ] = '\0'; - pKeyDest->fString = pKey->fString; - pKeyDest->Tag = pKey->Tag; - pKeyDest->Xtra = pKey->Xtra; - } - return pKeyDest; -} + l1 = lKeys >> 1; + l2 = lKeys - l1; + pPtr1 = &pSrc[ 0 ]; + pPtr2 = &pSrc[ l1 * iLen ]; -static LPCDXKEYINFO hb_cdxSortKeyPut( LPCDXKEYINFO pKey, BYTE * pbVal, USHORT uiLen, USHORT uiRealLen, BOOL fString ) -{ - if ( !pKey ) - pKey = hb_cdxSortKeyNew(); - if ( pKey->Value ) - { - hb_xfree( pKey->Value ); - pKey->Value = NULL; - } - pKey->realLength = uiRealLen; - pKey->fString = fString; - if ( pbVal == NULL ) - pKey->length = 0; - else - { - if ( uiLen > uiRealLen ) - uiLen = uiRealLen; - pKey->length = uiLen; - pKey->Value = ( BYTE * ) hb_xgrab( uiLen + 1 ); - memcpy( pKey->Value, pbVal, uiLen ); - pKey->Value[ uiLen ] = '\0'; - } - return pKey; -} - -static SHORT hb_cdxSortKeyFindDup( LPCDXKEYINFO pKey1, LPCDXKEYINFO pKey2 ) -{ - SHORT usDup = 0; - if ( pKey2 != NULL ) - { - int iLimit = (pKey1->length > pKey2->length) ? pKey2->length : pKey1->length; - while ( usDup < iLimit && ( (BYTE) pKey1->Value[ usDup ] ) == - ( (BYTE) pKey2->Value[ usDup ] ) ) + f1 = hb_cdxQSort( pSort, pPtr1, &pBuf[ 0 ], l1 ); + f2 = hb_cdxQSort( pSort, pPtr2, &pBuf[ l1 * iLen ], l2 ); + if ( f1 ) { - usDup++; - } - } - return usDup; -} - -#ifndef HB_CDP_SUPPORT_OFF -static int hb_cdxSortKeyCompare( LPCDXKEYINFO pKey1, LPCDXKEYINFO pKey2, PHB_CODEPAGE cdpage ) -#else -static int hb_cdxSortKeyCompare( LPCDXKEYINFO pKey1, LPCDXKEYINFO pKey2 ) -#endif -{ - int iLimit, iResult = 0, iPos = 0; - if ( pKey1 == NULL ) - return ( pKey2 == NULL ) ? 0 : -1; - if ( pKey2 == NULL ) - return 1; - iLimit = (pKey1->length > pKey2->length) ? pKey2->length : pKey1->length; - if ( pKey1->fString && pKey2->fString) - { -#ifndef HB_CDP_SUPPORT_OFF - while ( iResult == 0 && iPos < iLimit ) - { - /* for nation sorting support */ - iResult = hb_cdpcharcmp( pKey1->Value[ iPos ], pKey2->Value[ iPos ], cdpage ); - iPos++; /* EndPos += 1; */ - } -#else - if ( iLimit > 0 ) - iResult = memcmp(pKey1->Value, pKey2->Value, iLimit); -#endif - if ( iResult == 0 ) - { - BYTE c1, c2; - iPos = iLimit; - iLimit = ( pKey1->realLength > pKey2->realLength ) ? pKey2->realLength : pKey1->realLength; - while ( iResult == 0 && iPos < iLimit ) - { - c1 = (BYTE) ( ( iPos < pKey1->length ) ? ( pKey1->Value[ iPos ]) : ' ' ); - c2 = (BYTE) ( ( iPos < pKey2->length ) ? ( pKey2->Value[ iPos ]) : ' ' ); -#ifndef HB_CDP_SUPPORT_OFF - /* for nation sorting support */ - iResult = hb_cdpcharcmp( c1, c2, cdpage ); -#else - iResult = c1 - c2; -#endif - iPos++; - } - } - if ( iResult == 0 ) - iResult = pKey1->realLength - pKey2->realLength; - } - else if ( iLimit == 0 || (iResult = memcmp( pKey1->Value, pKey2->Value, iLimit )) == 0 ) - iResult = pKey1->length - pKey2->length; - if ( iResult < 0 ) - return -1; - else if ( iResult > 0 ) - return 1; - else - return 0; -} - -static int hb_cdxSortKeyValCompare( LPCDXTAG pTag, - BYTE * pKeyVal1, BYTE keyLen1, - BYTE * pKeyVal2, BYTE keyLen2 ) -{ - CDXKEYINFO pKey1, pKey2; - pKey1.Value = pKeyVal1; - pKey1.length = keyLen1; - pKey2.Value = pKeyVal2; - pKey2.length = keyLen2; - pKey2.realLength = pKey1.realLength = pTag->uiLen; - pKey2.fString = pKey1.fString = ( pTag->uiType == 'C' ); -#ifndef HB_CDP_SUPPORT_OFF - return hb_cdxSortKeyCompare( &pKey1, &pKey2, pTag->pIndex->pArea->cdPage ); -#else - return hb_cdxSortKeyCompare( &pKey1, &pKey2 ); -#endif -} - - -static void hb_cdxSortSwapSendWord( LPSORTINFO pSort, BYTE * Value ) -{ - LONG Tag; - BYTE bLen; - double d; - - LPSORTSWAPITEM pItem; - - bLen = Value[0]; - bLen -= 8; - Value++; - HB_ORD2DBL( &Value[bLen], &d ); - Tag = ( LONG ) d; - /* hb_cdxSortOutputWord( pSort, Tag, Value, uiLen ); */ - if ( pSort->pSwapPage->nCurPos + sizeof(SORTSWAPITEM) + bLen - 1 >= sizeof(pSort->pSwapPage->page) ) { - if ( hb_fsWrite( pSort->hTempFile, (BYTE *) pSort->pSwapPage->page, pSort->pSwapPage->nCurPos ) != pSort->pSwapPage->nCurPos ) - { - hb_errInternal( 9999, "Create index: Write error in temporary file.", "", "" ); - } - pSort->pSwapPage->pageLen += pSort->pSwapPage->nCurPos; - pSort->pSwapPage->nCurPos = 0; - } - - pItem = (LPSORTSWAPITEM) (pSort->pSwapPage->page + pSort->pSwapPage->nCurPos); - pItem->recno = Tag; - pItem->keyLen = bLen; - memcpy( pItem->key, (char *) Value, bLen ); - pSort->pSwapPage->nCurPos += sizeof(SORTSWAPITEM) + bLen - 1; - /* - typedef struct _SORTSWAPITEM - { - ULONG rec_no; - UCHAR keyLen; - char key[ 1 ]; - } SORTSWAPITEM; - */ -} - -static void hb_cdxSortSwapRecurseDict( LPSORTINFO pSort, LONG WPtr, LONG WBgn ) -{ - /* USHORT WCnt; */ - BYTE WCnt; - - if( WPtr == 0 ) - return; - WCnt = pSort->WPch[ 0 ]; - pSort->WAdr = hb_cdxSortLinkGet( pSort, WPtr ); - pSort->WPch[ WCnt + 1 ] = pSort->WAdr->sortu.A.Character; - pSort->WPch[ 0 ]++; - if( SORT_GET_NUSE( pSort->WAdr->sortu.A.NUse ) == SORT_STACK_OF_CHAR ) - { - memcpy( &pSort->WPch[ pSort->WPch[ 0 ] + 1 ], - pSort->WAdr->sortu.B.ChrStack, 4 ); - pSort->WPch[ 0 ] += SORT_GET_STACK_LEN( pSort->WAdr->sortu.A.NUse ) + 1; - } - if( SORT_GET_NUSE(pSort->WAdr->sortu.A.NUse) == SORT_END_OF_WORD ) - hb_cdxSortSwapSendWord( pSort, pSort->WPch ); - else - { - if( pSort->WAdr->sortu.A.WordArray != 0 ) - hb_cdxSortSwapRecurseDict( pSort, pSort->WAdr->sortu.A.WordArray, WBgn ); - pSort->WAdr = hb_cdxSortLinkGet( pSort, WPtr ); - } - pSort->WPch[ 0 ] = WCnt; - if( pSort->WAdr->sortu.A.LevelLink != 0 && - SORT_GET_NUSE( pSort->WAdr->sortu.A.NUse) != SORT_STACK_OF_CHAR ) - hb_cdxSortSwapRecurseDict( pSort, pSort->WAdr->sortu.A.LevelLink, WCnt ); -} - -static void hb_cdxSortSwapFillPage( LPSORTINFO pSort ) -{ - pSort->WPch[ 0 ] = 0; - hb_cdxSortSwapRecurseDict( pSort, pSort->RootLink, 0 ); -} - -static int hb_cdxSortSwapSavePage( LPSORTINFO pSort ) -{ - SORTSWAPPAGE swap; - BYTE *ptr; - pSort->nSwapPages++; - - if ( ! pSort->hTempFile ) { - BYTE szName[ _POSIX_PATH_MAX + 1 ]; - pSort->hTempFile = hb_fsCreateTemp( NULL, NULL, FC_NORMAL, szName ); - if ( pSort->hTempFile == FS_ERROR ) { - hb_errInternal( 9999, "Create index: Can't create temporary file.", "", "" ); - } - else { - pSort->szTempFileName = (char *) hb_xgrab( strlen( (char * ) szName) + 1 ); - strcpy( pSort->szTempFileName, ( char * ) szName ); - } - } - swap.nFileOffset = hb_fsSeek( pSort->hTempFile, 0, SEEK_END ); - swap.mark[0] = 'C'; - swap.mark[1] = 'X'; - swap.pageNum = pSort->nSwapPages - 1; - swap.pageLen = 0; - swap.keyCount = pSort->WordCount; - swap.nCurPos = 0; - ptr = swap.page; - memcpy( ptr, swap.mark, 2 ); - ptr += 2 * sizeof(char); - memcpy( ptr, (char *) &swap.pageNum, sizeof(swap.pageNum) ); - ptr += sizeof(swap.pageNum); - memcpy( ptr, (char *) &swap.pageLen, sizeof(swap.pageLen) ); - ptr += sizeof(swap.pageLen); - memcpy( ptr, (char *) &swap.keyCount, sizeof(swap.keyCount) ); - /* ptr += sizeof(ULONG); */ - swap.nCurPos += 2 * sizeof(char) + sizeof(USHORT) + 2 * sizeof(ULONG); - - /* - if ( hb_fsWrite( pSort->hTempFile, (BYTE *) swap.page, swap.nCurPos ) != swap.nCurPos ) - { - hb_errInternal( 9999, "Create index: Write error in temporary file.", "", "" ); - } - */ - pSort->pSwapPage = &swap; - hb_cdxSortSwapFillPage( pSort ); - pSort->pSwapPage = NULL; - - if ( swap.nCurPos > 0 ) { - if ( hb_fsWrite( pSort->hTempFile, (BYTE *) swap.page, swap.nCurPos ) != swap.nCurPos ) - { - hb_errInternal( 9999, "Create index: Write error in temporary file.", "", "" ); - } - swap.pageLen += swap.nCurPos; - swap.nCurPos = 0; - } - hb_fsSeek( pSort->hTempFile, swap.nFileOffset + 2 * sizeof(char) + sizeof(swap.pageNum), SEEK_SET ); - if ( hb_fsWrite( pSort->hTempFile, (BYTE *) &swap.pageLen, sizeof(swap.pageLen) ) != sizeof(ULONG) ) - { - hb_errInternal( 9999, "Create index: Write error in temporary file.", "", "" ); - } - - /* Clear memory structures */ - pSort->TotalWordCount += pSort->WordCount; - pSort->WordCount = 0; - /*pSort->KeyCnt = 0;*/ /* esto debera sacarlo */ - if( pSort->ChunkList != NULL ) - { - USHORT usCount; - for( usCount = 0; usCount < pSort->ChunkLimit; usCount++ ) - { - if( pSort->ChunkList[ usCount ] != 0 ) - memset( ( BYTE * ) pSort->ChunkList[ usCount ], 0, pSort->SortChunk * sizeof( BYTE ) ); - } - } - /* BYTE * SortBuffer; ??? */ - pSort->ChunkCur = 0; - pSort->NodeCur = 1; - pSort->KeySize = 0; - /* LPCDXDATA NodeList[ 32 ]; */ - hb_cdxSortLinkNew( pSort, &pSort->RootLink ); - - return 0; -} - -static BOOL hb_cdxSortSwapGetNextKey( LPSORTINFO pSort, LONG * pKeyRec, BYTE * pKeyVal, - USHORT * pKeyLen ) -{ - LPSORTSWAPPAGE pPage; - USHORT winPage, nPage; - ULONG winKeyRec; - BYTE winKeyLen; - BYTE * winKeyVal; - int iResult = 1; - - /* this way some compilers don't emit warnings */ - winPage = winKeyLen = 0; - winKeyRec = 0; - winKeyVal = NULL; - for ( nPage = 0 ; nPage < pSort->nSwapPages ; nPage++) { - pPage = pSort->pSwapPage + nPage; - if( pPage->keysLeft ) - { - if( winKeyVal ) - { - iResult = hb_cdxSortKeyValCompare( pSort->CurTag, winKeyVal, winKeyLen, - pPage->tmpKeyVal, pPage->tmpKeyLen ); - } - if( iResult > 0 || ( iResult == 0 && pPage->tmpRecNo < winKeyRec ) ) - { - winPage = nPage; - winKeyVal = pPage->tmpKeyVal; - winKeyLen = pPage->tmpKeyLen; - winKeyRec = pPage->tmpRecNo; - } - } - } - if( winKeyVal ) - { - pPage = pSort->pSwapPage + winPage; - *pKeyRec = winKeyRec; - *pKeyLen = winKeyLen; - memcpy( pKeyVal, winKeyVal, winKeyLen); - - if( --pPage->keysLeft ) - { - LPSORTSWAPITEM pItem = NULL; - if ( pPage->nBufLeft < (USHORT) (sizeof(SORTSWAPITEM) + (USHORT) pPage->tmpKeyLen - 1) ) { - printf("Error! --- swapgetnextkey\n"); - } - pPage->nCurPos += (sizeof(SORTSWAPITEM) + (USHORT) pPage->tmpKeyLen - 1); - pPage->nBufLeft -= (sizeof(SORTSWAPITEM) + (USHORT) pPage->tmpKeyLen - 1); - /* Debugging */ - if ( pPage->nCurPos > 512 ) { - printf("Error! --- swapgetnextkey\n"); - } - if ( pPage->nBufLeft > 512 ) { - printf("Error! --- swapgetnextkey\n"); - } - if ( pPage->nBufLeft >= (sizeof(SORTSWAPITEM) - 1) ) { - pItem = (LPSORTSWAPITEM) (pPage->page + pPage->nCurPos); - if ( pPage->nBufLeft < (USHORT) (sizeof(SORTSWAPITEM) + (USHORT) pItem->keyLen - 1 ) ) - pItem = NULL; - } - if ( !pItem ) { - pPage->nBytesLeft += pPage->nBufLeft; - hb_fsSeek( pSort->hTempFile, pPage->nFileOffset + pPage->pageLen - pPage->nBytesLeft, SEEK_SET ); - pPage->nBufLeft = (USHORT) ( ( pPage->nBytesLeft < sizeof(pPage->page) ) ? pPage->nBytesLeft : sizeof(pPage->page) ); - if ( hb_fsRead( pSort->hTempFile, (BYTE *) (pPage->page), pPage->nBufLeft ) != pPage->nBufLeft ) - hb_errInternal( HB_EI_ERRUNRECOV, "hb_cdxTagDoIndex: Read error reading temporary index file", "hb_cdxTagDoIndex", NULL ); - pPage->nBytesLeft -= pPage->nBufLeft; - pPage->nCurPos = 0; - pItem = (LPSORTSWAPITEM) (pPage->page); - } - pPage->tmpRecNo = pItem->recno; - pPage->tmpKeyLen = pItem->keyLen; - pPage->tmpKeyVal = ( BYTE * ) pItem->key; - } - return TRUE; - } - else - { - return FALSE; - } -} - -static int hb_cdxSortSwapBuildIndex( LPSORTINFO pSort ) -{ - LPSORTSWAPPAGE pPage; - LPSORTSWAPITEM pItem; - BYTE *ptr; - USHORT nPage; - LONG nKeyRec; - BYTE KeyVal[2][CDX_MAXKEY + 1], *pKeyVal, *pKeyPrevVal; - USHORT nKeyLen, nKeyPrevLen; - - pSort->pSwapPage = (LPSORTSWAPPAGE) hb_xgrab( pSort->nSwapPages * sizeof( SORTSWAPPAGE ) ); - if ( !pSort->pSwapPage ) - hb_errInternal( HB_EI_ERRUNRECOV, "hb_cdxTagDoIndex: Not enough memory for index merging", "hb_cdxTagDoIndex", NULL ); - - hb_fsSeek( pSort->hTempFile, 0, SEEK_SET ); - - for ( nPage = 0 ; nPage < pSort->nSwapPages ; nPage++) { - pPage = pSort->pSwapPage + nPage; - pPage->nFileOffset = hb_fsSeek( pSort->hTempFile, 0, SEEK_CUR ); - pPage->nBufLeft = 2 * sizeof(char) + sizeof(USHORT) + 2 * sizeof(ULONG); - if ( hb_fsRead( pSort->hTempFile, (BYTE *) (pPage->page), pPage->nBufLeft ) != pPage->nBufLeft ) - hb_errInternal( HB_EI_ERRUNRECOV, "hb_cdxTagDoIndex: Read error reading temporary index file", "hb_cdxTagDoIndex", NULL ); - ptr = pPage->page; - memcpy( pPage->mark, ptr, 2 ); - ptr += 2 * sizeof(char); - memcpy( (char *) &pPage->pageNum, ptr, sizeof(pPage->pageNum) ); - ptr += sizeof(pPage->pageNum); - memcpy( (char *) &pPage->pageLen, ptr, sizeof(pPage->pageLen) ); - ptr += sizeof(pPage->pageLen); - memcpy( (char *) &pPage->keyCount, ptr, sizeof(pPage->keyCount) ); - if ( memcmp( pPage->mark, "CX", 2 * sizeof(char) ) ) - hb_errInternal( HB_EI_ERRUNRECOV, "hb_cdxTagDoIndex: Internal error 1", "hb_cdxTagDoIndex", NULL ); - if ( pPage->pageNum != nPage ) - hb_errInternal( HB_EI_ERRUNRECOV, "hb_cdxTagDoIndex: Internal error 2", "hb_cdxTagDoIndex", NULL ); - /*pPage->nCurPos ;*/ - pPage->nBytesLeft = pPage->pageLen - pPage->nBufLeft; - pPage->keysLeft = pPage->keyCount; - - pPage->nBufLeft = (USHORT) ( ( pPage->nBytesLeft < sizeof(pPage->page) ) ? pPage->nBytesLeft : sizeof(pPage->page) ); - if ( hb_fsRead( pSort->hTempFile, (BYTE *) (pPage->page), pPage->nBufLeft ) != pPage->nBufLeft ) - hb_errInternal( HB_EI_ERRUNRECOV, "hb_cdxTagDoIndex: Read error reading tempmrary index file", "hb_cdxTagDoIndex", NULL ); - pPage->nBytesLeft -= pPage->nBufLeft; - pPage->nCurPos = 0; - - pItem = (LPSORTSWAPITEM) (pPage->page); - pPage->tmpRecNo = pItem->recno; - pPage->tmpKeyLen = pItem->keyLen; - pPage->tmpKeyVal = ( BYTE * ) pItem->key; - - hb_fsSeek( pSort->hTempFile, pPage->nFileOffset + pPage->pageLen, SEEK_SET ); -#ifdef CDXDEBUG - printf("Pgina %i, offset %x, largo %x : %i, claves: %i, bleft: %i\n", - pPage->pageNum, pPage->nFileOffset, pPage->pageLen, pPage->pageLen, pPage->keyCount, pPage->nBytesLeft); -#endif - } - - pKeyVal = KeyVal[0]; - pKeyPrevVal = NULL; - nKeyPrevLen = 0; /* init to avoid warnings */ - while ( hb_cdxSortSwapGetNextKey( pSort, &nKeyRec, pKeyVal, &nKeyLen ) ) - { - if ( pSort->Unique ) - { - if ( pKeyPrevVal ) { - if ( nKeyPrevLen == nKeyLen ) { - if (! hb_cdxSortKeyValCompare( pSort->CurTag, pKeyPrevVal, (BYTE) nKeyPrevLen, - pKeyVal, (BYTE) nKeyLen ) ) - { - continue; - } - } - } - pKeyPrevVal = pKeyVal; - nKeyPrevLen = nKeyLen; - hb_cdxSortOutputWord( pSort, nKeyRec, pKeyVal, nKeyLen ); - if ( pKeyVal == KeyVal[0] ) - { - pKeyVal = KeyVal[1]; - } - else - { - pKeyVal = KeyVal[0]; - } + pDst = pBuf; } else { - hb_cdxSortOutputWord( pSort, nKeyRec, pKeyVal, nKeyLen ); + pDst = pSrc; + pPtr1 = &pBuf[ 0 ]; + } + if ( !f2 ) + { + pPtr2 = &pBuf[ l1 * iLen ]; + } + while ( l1 > 0 && l2 > 0 ) + { + if ( hb_cdxQuickSortCompare( pSort, pPtr1, pPtr2 ) < 0 ) + { + memcpy( pDst, pPtr1, iLen ); + pPtr1 += iLen; + l1--; + } + else + { + memcpy( pDst, pPtr2, iLen ); + pPtr2 += iLen; + l2--; + } + pDst += iLen; + } + if ( l1 > 0 ) + { + memcpy( pDst, pPtr1, iLen * l1 ); + } + else if ( l2 > 0 && f1 == f2 ) + { + memcpy( pDst, pPtr2, iLen * l2 ); + } + return !f1; + } + return TRUE; +} + +static void hb_cdxSortSortPage( LPCDXSORTINFO pSort ) +{ +#ifdef HB_CDX_DBGTIME + cdxTimeIdxBld -= hb_cdxGetTime(); +#endif + if ( !hb_cdxQSort( pSort, pSort->pKeyPool, &pSort->pKeyPool[ pSort->ulKeys * ( pSort->keyLen + 4 ) ], pSort->ulKeys ) ) + { + memcpy( pSort->pKeyPool, &pSort->pKeyPool[ pSort->ulKeys * ( pSort->keyLen + 4 ) ], pSort->ulKeys * ( pSort->keyLen + 4 ) ); + } +#ifdef HB_CDX_DBGTIME + cdxTimeIdxBld += hb_cdxGetTime(); +#endif +} + +static void hb_cdxSortAddNodeKey( LPCDXSORTINFO pSort, int iLevel, BYTE *pKeyVal, ULONG ulRec, ULONG ulPage ) +{ + LPCDXPAGE pPage; + BOOL fNew; + int iLen = pSort->keyLen, iDup = 0, iTrl = 0, iTmp, iPos; + BYTE *pTmp; + + pPage = pSort->NodeList[ iLevel ]; + if ( iLevel == 0 ) + { + while ( pKeyVal[ iLen - iTrl - 1 ] == pSort->bTrl && iTrl < iLen ) + { + iTrl++; + } + if ( pPage != NULL && pPage->iKeys > 0 ) + { +#ifdef HB_CDX_PACKTRAIL + int iMax = iLen - iTrl; +#else + int iMax = iLen - HB_MAX( iTrl, pSort->iLastTrl ); +#endif + while ( pKeyVal[ iDup ] == pSort->pLastKey[ iDup ] && iDup < iMax ) + { + iDup++; + } + } +#ifndef HB_CDX_PACKTRAIL + pSort->iLastTrl = iTrl; +#endif + } + if( pPage == NULL ) + { + fNew = TRUE; + } + else + { + if ( iLevel == 0 ) + { + fNew = ( pPage->iFree - ( iLen - iDup - iTrl ) - pPage->ReqByte ) < 0; + } + else + { + fNew = ( pSort->NodeList[ iLevel ]->iKeys >= pSort->pTag->MaxKeys ); } } - /* - ------- - hb_fsSeek( pSort->hTempFile, swap.nFileOffset + 2 * sizeof(char) + sizeof(ULONG), SEEK_SET ); - * - * - * - // para grabar la clave... - hb_cdxSortOutputWord( pSort, Tag, Value, uiLen-8 ); - */ - hb_xfree( pSort->pSwapPage ); - pSort->pSwapPage = NULL; - return 0; + if( fNew ) + { + pPage = hb_cdxPageNew( pSort->pTag, NULL, 0 ); + pPage->PageType = ( iLevel == 0 ) ? CDX_NODE_LEAF : CDX_NODE_BRANCH; + if ( iLevel == 0 ) + { + hb_cdxPageLeafInitSpace( pPage ); + iDup = 0; + while ( pSort->ulMaxRec > pPage->RNMask ) + { + pPage->ReqByte++; + pPage->RNBits += 8; + pPage->RNMask = ( pPage->RNMask << 8 ) | 0xFF; + } + } + if ( pSort->NodeList[ iLevel ] != NULL ) + { + pSort->NodeList[ iLevel ]->Right = pPage->Page; + pPage->Left = pSort->NodeList[ iLevel ]->Page; + if ( iLevel == 0 ) + { +#ifdef HB_CDX_DBGCODE_EXT + hb_cdxPageCheckDupTrlRaw( pSort->NodeList[ iLevel ] ); +#endif + hb_cdxSortAddNodeKey( pSort, iLevel + 1, pSort->pLastKey, pSort->ulLastRec, pSort->NodeList[ iLevel ]->Page ); + } + else + { + iPos = ( pSort->NodeList[ iLevel ]->iKeys - 1 ) * ( iLen + 8 ); + pTmp = &pSort->NodeList[ iLevel ]->node.intNode.keyPool[ iPos ]; + hb_cdxSortAddNodeKey( pSort, iLevel + 1, pTmp, HB_GET_BE_UINT32( &pTmp[ iLen ] ), pSort->NodeList[ iLevel ]->Page ); + } + hb_cdxPageFree( pSort->NodeList[ iLevel ], TRUE ); + } + pSort->NodeList[ iLevel ] = pPage; + } + if ( iLevel == 0 ) + { + iPos = pPage->iKeys * pPage->ReqByte; + hb_cdxSetLeafRecord( &pPage->node.extNode.keyPool[ iPos ], + ulRec, iDup, iTrl, + pPage->ReqByte, pPage->DCBits, pPage->TCBits ); + iTmp = iLen - iDup - iTrl; + if ( iTmp > 0 ) + { + memcpy( &pPage->node.extNode.keyPool[ pPage->iFree + iPos - iTmp ], + &pKeyVal[ iDup ], iTmp ); + } + pPage->iFree -= iTmp + pPage->ReqByte; + pPage->iKeys++; +#ifdef HB_CDX_DBGCODE_EXT + hb_cdxPageCheckDupTrlRaw( pSort->NodeList[ iLevel ] ); +#endif + } + else + { + pPage = pSort->NodeList[ iLevel ]; + iPos = pPage->iKeys * ( iLen + 8 ); + pTmp = &pPage->node.intNode.keyPool[ iPos ]; + memcpy( pTmp, pKeyVal, iLen ); + HB_PUT_BE_UINT32( &pTmp[ iLen ], ulRec ); + HB_PUT_BE_UINT32( &pTmp[ iLen + 4 ], ulPage ); + pPage->iKeys++; + } } -static LPSORTINFO hb_cdxSortNew( LPCDXTAG pTag, BOOL bUnique ) +static void hb_cdxSortWritePage( LPCDXSORTINFO pSort ) { - BYTE * P; - LPSORTINFO pSort; + ULONG ulSize = pSort->ulKeys * ( pSort->keyLen + 4 ); - pSort = ( LPSORTINFO ) hb_xgrab( sizeof( SORTINFO ) ); - memset( pSort, 0, sizeof( SORTINFO ) ); - pSort->SortChunk = SORT_CHUNK_LIMIT; - pSort->NodeLimit = pSort->SortChunk / sizeof( SORTDATA ); - pSort->NodeMask = pSort->NodeShift = pSort->NodeCur = 1; - pSort->ChunkLimit = 0x8000; - while( pSort->NodeMask < pSort->NodeLimit - 1 ) + hb_cdxSortSortPage( pSort ); + + if ( pSort->hTempFile == FS_ERROR ) { - pSort->NodeMask = ( pSort->NodeMask << 1 ) + 1; - pSort->ChunkLimit >>= 1; - pSort->NodeShift++; + BYTE szName[ _POSIX_PATH_MAX + 1 ]; + pSort->hTempFile = hb_fsCreateTemp( NULL, NULL, FC_NORMAL, szName ); + if ( pSort->hTempFile == FS_ERROR ) + { + hb_errInternal( 9999, "hb_cdxSortWritePage: Can't create temporary file.", "", "" ); + } + pSort->szTempFileName = hb_strdup( ( char * ) szName ); } - pSort->ChunkSize = pSort->ChunkLimit; - pSort->ChunkList = ( LONG * ) hb_xgrab( pSort->ChunkSize * sizeof( LONG ) ); - memset( pSort->ChunkList, 0, pSort->ChunkSize * sizeof( LONG ) ); - P = ( BYTE * ) hb_xgrab( pSort->SortChunk * sizeof( BYTE ) ); - memset( P, 0, pSort->SortChunk * sizeof( BYTE ) ); - pSort->ChunkList[ 0 ] = ( LONG ) P; - hb_cdxSortLinkNew( pSort, &pSort->RootLink ); - pSort->Unique = bUnique; - pSort->Ascend = TRUE; - pSort->CurTag = pTag; - pSort->KeyTot = pTag->pIndex->pArea->ulRecCount; - pSort->KeyWork = hb_cdxSortKeyNew(); - pSort->LastKey = hb_cdxSortKeyNew(); + pSort->pSwapPage[ pSort->ulCurPage ].ulKeys = pSort->ulKeys; + pSort->pSwapPage[ pSort->ulCurPage ].nOffset = hb_fsSeek( pSort->hTempFile, 0, SEEK_END ); + if ( hb_fsWriteLarge( pSort->hTempFile, pSort->pKeyPool, ulSize ) != ulSize ) + { + hb_errInternal( 9999, "hb_cdxSortWritePage: Write error in temporary file.", "", "" ); + } + pSort->ulKeys = 0; + pSort->ulCurPage++; +} + +static BOOL hb_cdxSortKeyGet( LPCDXSORTINFO pSort, BYTE ** pKeyVal, ULONG *pulRec ) +{ + int i, iLen = pSort->keyLen; + ULONG ulPage, ulKeyPage = 0, ulRec = 0; + BYTE *pKey = NULL, *pTmp; + + for ( ulPage = 0; ulPage < pSort->ulPages; ulPage++ ) + { + if ( pSort->pSwapPage[ ulPage ].ulKeys > 0 ) + { + if ( pSort->pSwapPage[ ulPage ].ulKeyBuf == 0 ) + { + ULONG ulKeys = HB_MIN( pSort->ulPgKeys, pSort->pSwapPage[ ulPage ].ulKeys ); + ULONG ulSize = ulKeys * ( pSort->keyLen + 4 ); + + if ( hb_fsSeek( pSort->hTempFile, pSort->pSwapPage[ ulPage ].nOffset, SEEK_SET ) != pSort->pSwapPage[ ulPage ].nOffset || + hb_fsReadLarge( pSort->hTempFile, pSort->pSwapPage[ ulPage ].pKeyPool, ulSize ) != ulSize ) + { + hb_errInternal( 9999, "hb_cdxSortKeyGet: Read error from temporary file.", "", "" ); + } + pSort->pSwapPage[ ulPage ].nOffset += ulSize; + pSort->pSwapPage[ ulPage ].ulKeyBuf = ulKeys; + pSort->pSwapPage[ ulPage ].ulCurKey = 0; + } + pTmp = &pSort->pSwapPage[ ulPage ].pKeyPool[ pSort->pSwapPage[ ulPage ].ulCurKey * ( iLen + 4 ) ]; + if ( ! pKey ) + { + i = 1; + } + else + { + i = hb_cdxValCompare( pSort->pTag, pKey, iLen, pTmp, iLen, TRUE ); + if ( i == 0 ) + { + i = ( ulRec < HB_GET_LE_UINT32( &pTmp[ iLen ] ) ) ? -1 : 1; + } + } + if ( i > 0 ) + { + pKey = pTmp; + ulRec = HB_GET_LE_UINT32( &pKey[ iLen ] ); + ulKeyPage = ulPage; + } + } + } + if ( pKey ) + { + pSort->pSwapPage[ ulKeyPage ].ulCurKey++; + pSort->pSwapPage[ ulKeyPage ].ulKeys--; + pSort->pSwapPage[ ulKeyPage ].ulKeyBuf--; + *pulRec = ulRec; + *pKeyVal = pKey; + return TRUE; + } + return FALSE; +} + +static void hb_cdxSortKeyAdd( LPCDXSORTINFO pSort, ULONG ulRec, BYTE * pKeyVal, int iKeyLen ) +{ + int iLen = pSort->keyLen; + BYTE *pDst; + + if ( pSort->ulKeys >= pSort->ulPgKeys ) + { + hb_cdxSortWritePage( pSort ); + } + pDst = &pSort->pKeyPool[ pSort->ulKeys * ( iLen + 4 ) ]; + + memcpy( pDst, pKeyVal, iKeyLen ); + if ( iLen > iKeyLen ) + { + memset( &pDst[ iKeyLen ], pSort->bTrl, iLen - iKeyLen ); + } + HB_PUT_LE_UINT32( &pDst[ iLen ], ulRec ); + pSort->ulKeys++; + pSort->ulTotKeys++; +} + +static LPCDXSORTINFO hb_cdxSortNew( LPCDXTAG pTag, ULONG ulRecCount ) +{ + LPCDXSORTINFO pSort; + BYTE * pBuf; + int iLen = pTag->uiLen; + ULONG ulSize, ulMax; + + if ( ulRecCount == 0 ) + { + return NULL; + } + + pSort = ( LPCDXSORTINFO ) hb_xgrab( sizeof( CDXSORTINFO ) ); + memset( pSort, 0, sizeof( CDXSORTINFO ) ); + /* ulMax = ( 1L << 30 ) / ( iLen + 4 ); */ + ulMax = ( 1L << 21 ) / ( iLen + 4 ); + if ( ulMax > ulRecCount ) + { + ulMax = ulRecCount; + } + + do + { + ulSize = ulMax * ( iLen + 4 ); + pBuf = ( BYTE * ) hb_xalloc( ulSize << 2 ); + if ( pBuf ) + { + hb_xfree( pBuf ); + pBuf = ( BYTE * ) hb_xalloc( ulSize << 1 ); + } + else + { + ulMax >>= 1; + } + } + while ( ! pBuf ); + + pSort->pTag = pTag; + pSort->hTempFile = FS_ERROR; + pSort->keyLen = iLen; + pSort->bTrl = pTag->uiType == 'C' ? ' ' : '\0'; + pSort->fUnique = pTag->UniqueKey; + pSort->ulMaxKey = ulMax << 1; + pSort->ulPgKeys = ulMax; + pSort->ulMaxRec = ulRecCount; + pSort->pKeyPool = pBuf; + pSort->ulPages = ( ulRecCount + pSort->ulPgKeys - 1 ) / pSort->ulPgKeys; + pSort->pSwapPage = ( LPCDXSWAPPAGE ) hb_xgrab( sizeof( CDXSWAPPAGE ) * pSort->ulPages ); + memset( pSort->pSwapPage, 0, sizeof( CDXSWAPPAGE ) * pSort->ulPages ); + return pSort; } -static void hb_cdxSortPageWrite( LPCDXINDEX pIndex, ULONG ulPos, LPCDXDATA pPage ) +static void hb_cdxSortFree( LPCDXSORTINFO pSort ) { -/* it's a temporary hack */ -#ifdef HB_BIG_ENDIAN - pPage->Node_Atr = HB_SWAP_USHORT( pPage->Node_Atr ); - pPage->Rght_Ptr = HB_SWAP_ULONG ( pPage->Rght_Ptr ); - pPage->Left_Ptr = HB_SWAP_ULONG ( pPage->Left_Ptr ); - pPage->Entry_Ct = HB_SWAP_USHORT( pPage->Entry_Ct ); -#endif - hb_cdxIndexPageWrite( pIndex, ulPos, (BYTE *) pPage, sizeof( CDXDATA ) ); -#ifdef HB_BIG_ENDIAN - pPage->Node_Atr = HB_SWAP_USHORT( pPage->Node_Atr ); - pPage->Rght_Ptr = HB_SWAP_ULONG ( pPage->Rght_Ptr ); - pPage->Left_Ptr = HB_SWAP_ULONG ( pPage->Left_Ptr ); - pPage->Entry_Ct = HB_SWAP_USHORT( pPage->Entry_Ct ); -#endif -} - -static void hb_cdxSortFree( LPSORTINFO pSort ) -{ - USHORT usCount; - LONG pa; - - pSort->Closing = TRUE; - for( usCount = 0; usCount <= 30; usCount++ ) + if ( pSort->hTempFile != FS_ERROR ) { - if( pSort->NodeList[ usCount ] != NULL ) - { - pa = pSort->NodeList[ usCount ]->Rght_Ptr; - pSort->NodeList[ usCount ]->Rght_Ptr = CDX_DUMMYNODE; - if( pSort->NodeList[ usCount ]->Entry_Ct > 0 ) - { - if( pSort->NodeList[ usCount + 1 ] == NULL ) - { - pSort->CurTag->RootBlock = pa; - pSort->NodeList[ usCount ]->Node_Atr |= CDX_NODE_ROOT; - } - hb_cdxSortPageWrite( pSort->CurTag->pIndex, pa, pSort->NodeList[ usCount ] ); - if( pSort->NodeList[ usCount + 1 ] != NULL ) - hb_cdxSortAddToNode( pSort, ( USHORT ) ( usCount + 1 ), pa, - pSort->LastTag, pSort->KeyWork ); - } - hb_xfree( ( LPCDXDATA ) pSort->NodeList[ usCount ] ); - } - } - - if( pSort->ChunkList != NULL ) - { - for( usCount = 0; usCount < pSort->ChunkLimit; usCount++ ) - { - if( pSort->ChunkList[ usCount ] != 0 ) - hb_xfree( ( BYTE * ) pSort->ChunkList[ usCount ] ); - } - hb_xfree( pSort->ChunkList ); - } - hb_cdxSortKeyFree( pSort->KeyWork ); - hb_cdxSortKeyFree( pSort->LastKey ); - - if ( pSort->hTempFile ) - { - /* hb_fsCommit( pSort->hTempFile ); */ hb_fsClose( pSort->hTempFile ); - pSort->hTempFile = FS_ERROR; } if ( pSort->szTempFileName ) { hb_fsDelete( (BYTE *) ( pSort->szTempFileName ) ); hb_xfree( pSort->szTempFileName ); - pSort->szTempFileName = NULL; } - + if ( pSort->pKeyPool ) + { + hb_xfree( pSort->pKeyPool ); + } + if ( pSort->pSwapPage ) + { + hb_xfree( pSort->pSwapPage ); + } + if ( pSort->pRecBuff ) + { + hb_xfree( pSort->pRecBuff ); + } hb_xfree( pSort ); } -static void hb_cdxSortLinkNew( LPSORTINFO pSort, LONG * NewLink ) +static void hb_cdxSortOut( LPCDXSORTINFO pSort ) { - if( pSort->NodeCur >= pSort->NodeLimit ) - hb_cdxSortGetNewChunk( pSort ); - * NewLink = ( pSort->ChunkCur << pSort->NodeShift ) + pSort->NodeCur; - pSort->NodeCur++; -} + BOOL fUnique = pSort->fUnique, fNext; + ULONG ulPage, ulRec, ulKey; + BYTE * pKeyVal; + int iLen = pSort->keyLen, iLevel; -static void hb_cdxSortGetNewChunk( LPSORTINFO pSort ) -{ - BYTE * P; - - pSort->ChunkCur++; - if( pSort->ChunkCur == pSort->ChunkLimit ) + pSort->ulPages = pSort->ulCurPage + 1; + pSort->ulPgKeys = pSort->ulMaxKey / pSort->ulPages; + /* printf( "\r\npSort->ulPages=%ld\r\n", (long) pSort->ulPages ); fflush(stdout); */ + if ( pSort->ulPages > 1 ) { - hb_cdxSortSwapSavePage( pSort ); - return; - } - P = ( BYTE * ) pSort->ChunkList[ pSort->ChunkCur ]; - if( P == NULL ) - P = ( BYTE * ) hb_xgrab( pSort->SortChunk * sizeof( BYTE ) ); - if( pSort->ChunkCur != 0 ) - { - memset( P, 0, pSort->SortChunk * sizeof( BYTE ) ); - pSort->ChunkList[ pSort->ChunkCur ] = ( LONG ) P; - pSort->NodeCur = 0; - } -} - -static void hb_cdxSortInsertWord( LPSORTINFO pSort, LONG Tag, char * Value, - USHORT uiLen ) -{ - char s[ 8 ]; - double d; - USHORT cc, nc; - LPSORTDATA wx; - - d = ( double ) Tag; - HB_DBL2ORD( &d, s ); - - if( pSort->NodeLimit - pSort->NodeCur < uiLen + 8 ) - { - cc = pSort->ChunkCur; - nc = pSort->NodeCur; - hb_cdxSortGetNewChunk( pSort ); - if( pSort->ChunkCur > 0 ) + BYTE * pBuf = pSort->pKeyPool; + hb_cdxSortWritePage( pSort ); + for ( ulPage = 0; ulPage < pSort->ulPages; ulPage++ ) { - pSort->ChunkCur = cc; - pSort->NodeCur = nc; + pSort->pSwapPage[ ulPage ].ulKeyBuf = 0; + pSort->pSwapPage[ ulPage ].ulCurKey = 0; + pSort->pSwapPage[ ulPage ].pKeyPool = pBuf; + pBuf += pSort->ulPgKeys * ( pSort->keyLen + 4 ); } } - pSort->WordCount++; - memcpy( pSort->WPch+1, Value, uiLen ); - pSort->WPch[0] = (BYTE) uiLen; - - if( pSort->WPch[0] > pSort->KeySize ) - pSort->KeySize = pSort->WPch[0]; - pSort->LevelPtr = pSort->RootLink; - pSort->PriorPtr = 0; - pSort->WCur = 0; - do - hb_cdxSortStuffKey( pSort, &wx, FALSE ); - while( pSort->WCur != pSort->WPch[0] ); - if( pSort->Unique ) - { - if( SORT_GET_NUSE(wx->sortu.A.NUse) == SORT_END_OF_KEY ) - { - pSort->WordCount--; - return; - } - SORT_SET_NUSE( wx->sortu.A.NUse, SORT_END_OF_KEY); - } - - memcpy( &pSort->WPch[ pSort->WPch[0] + 1 ], s, 8 ); - pSort->WPch[0] += 8; - do - hb_cdxSortStuffKey( pSort, &wx, TRUE ); - while( pSort->WCur != pSort->WPch[0] ); - - SORT_SET_NUSE(wx->sortu.A.NUse, SORT_END_OF_WORD); -} - -static void hb_cdxSortStuffKey( LPSORTINFO pSort, LPSORTDATA * wx, BOOL fTag ) -{ - SHORT v; - LONG p1; - LPSORTDATA x; - - hb_cdxSortGetNode( pSort, pSort->WPch[ pSort->WCur + 1 ], &p1, fTag ); - * wx = hb_cdxSortLinkGet( pSort, p1 ); - pSort->WCur++; - if( pSort->LevelPtr == 0 ) - { - if( pSort->PriorPtr > 0 ) - { - x = hb_cdxSortLinkGet( pSort, pSort->PriorPtr ); - x->sortu.A.WordArray = (USHORT) p1; - } - v = pSort->WPch[0] - pSort->WCur - 1; - if( v > 0 ) - { - if( v > 4 ) - v = 4; - memcpy( ( * wx )->sortu.B.ChrStack, &pSort->WPch[ pSort->WCur+1 ], v ); - SORT_SET_NUSE( ( * wx )->sortu.A.NUse, SORT_STACK_OF_CHAR ); - SORT_SET_STACK_LEN( ( * wx )->sortu.A.NUse, v-1 ); - pSort->WCur += v; - } - } - pSort->PriorPtr = p1; - pSort->LevelPtr = ( * wx )->sortu.A.WordArray; -} - -static void hb_cdxSortGetNode( LPSORTINFO pSort, BYTE Character, LONG * NewLink, BOOL fTag ) -{ - char c; - int df; - LONG p, q, r; - LPSORTDATA px, qx, rx; -#ifndef HB_CDP_SUPPORT_OFF - PHB_CODEPAGE cdPage = pSort->CurTag->pIndex->pArea->cdPage; -#endif - - if( pSort->LevelPtr == 0 ) - { - hb_cdxSortLinkNew( pSort, NewLink ); - px = hb_cdxSortLinkGet( pSort, * NewLink ); - px->sortu.A.Character = Character; - if( fTag ) - px->sortu.A.NUse |= SORT_NOT_KEY; - return; - } - p = pSort->LevelPtr; - px = hb_cdxSortLinkGet( pSort, pSort->LevelPtr ); - q = pSort->PriorPtr; - - if( SORT_GET_NUSE(px->sortu.A.NUse) == SORT_STACK_OF_CHAR ) - { - hb_cdxSortLinkNew( pSort, &r ); - c = px->sortu.A.Character; - qx = hb_cdxSortLinkGet( pSort, q ); - qx->sortu.A.WordArray = (USHORT) r; - rx = hb_cdxSortLinkGet( pSort, r ); - rx->sortu.A.Character = c; - rx->sortu.A.WordArray = (USHORT) p; - px = hb_cdxSortLinkGet( pSort, p ); - px->sortu.A.Character = px->sortu.B.ChrStack[ 0 ]; - memmove( &px->sortu.B.ChrStack[ 0 ], &px->sortu.B.ChrStack[ 1 ], 3 ); - px->sortu.B.ChrStack[ 3 ] = 0; - if( px->sortu.A.NUse & SORT_NOT_KEY ) - rx->sortu.A.NUse |= SORT_NOT_KEY; - if( SORT_GET_STACK_LEN( px->sortu.A.NUse ) ) - { - SORT_SET_STACK_LEN( px->sortu.A.NUse, - SORT_GET_STACK_LEN( px->sortu.A.NUse ) - 1 ); - SORT_SET_NUSE( px->sortu.A.NUse, SORT_STACK_OF_CHAR ); - } - else - SORT_SET_NUSE( px->sortu.A.NUse, SORT_ACTIVE_LIST ); - - p = r; - px = hb_cdxSortLinkGet( pSort, p ); - } - - if( pSort->CurTag->uiType == 'C' && ( !( px->sortu.A.NUse & SORT_NOT_KEY ) || !fTag ) ) -#ifndef HB_CDP_SUPPORT_OFF - /* for nation sorting support */ - df = hb_cdpcharcmp( fTag ? ' ' : Character, ( px->sortu.A.NUse & SORT_NOT_KEY ) ? ' ' : px->sortu.A.Character, cdPage ); -#else - df = ( fTag ? ' ' : Character ) - ( ( px->sortu.A.NUse & SORT_NOT_KEY ) ? ' ' : px->sortu.A.Character ); -#endif - else if( ( px->sortu.A.NUse & SORT_NOT_KEY ) && !fTag ) - df = 1; - else if( fTag && !( px->sortu.A.NUse & SORT_NOT_KEY ) ) - df = -1; - else if( Character > px->sortu.A.Character ) - df = 1; - else if( Character < px->sortu.A.Character ) - df = -1; else - df = 0; - - if( !pSort->Ascend ) - df = -df; - - while( px->sortu.A.LevelLink != 0 && df > 0 ) { - q = p; - p = px->sortu.A.LevelLink; - px = hb_cdxSortLinkGet( pSort, p ); - - if( SORT_GET_NUSE(px->sortu.A.NUse) == SORT_STACK_OF_CHAR ) + hb_cdxSortSortPage( pSort ); + pSort->pSwapPage[ 0 ].ulKeys = pSort->ulKeys; + pSort->pSwapPage[ 0 ].ulKeyBuf = pSort->ulKeys; + pSort->pSwapPage[ 0 ].ulCurKey = 0; + pSort->pSwapPage[ 0 ].pKeyPool = pSort->pKeyPool; + } + for ( ulKey = 0; ulKey < pSort->ulTotKeys; ulKey++ ) + { + if ( ! hb_cdxSortKeyGet( pSort, &pKeyVal, &ulRec ) ) { - hb_cdxSortLinkNew( pSort, &r ); - c = px->sortu.A.Character; - qx = hb_cdxSortLinkGet( pSort, q ); - qx->sortu.A.WordArray = (USHORT) r; - rx = hb_cdxSortLinkGet( pSort, r ); - rx->sortu.A.Character = c; - rx->sortu.A.WordArray = (USHORT) p; - px = hb_cdxSortLinkGet( pSort, p ); - px->sortu.A.Character = px->sortu.B.ChrStack[ 0 ]; - memmove( &px->sortu.B.ChrStack[ 0 ], &px->sortu.B.ChrStack[ 1 ], 3 ); - px->sortu.B.ChrStack[ 3 ] = 0; - if( px->sortu.A.NUse & SORT_NOT_KEY ) - rx->sortu.A.NUse |= SORT_NOT_KEY; - if( SORT_GET_STACK_LEN( px->sortu.A.NUse ) ) + hb_errInternal( 9999, "hb_cdxSortOut: memory structure corrupted.", "", "" ); + } + if ( fUnique ) + { + if ( ulKey != 0 && hb_cdxValCompare( pSort->pTag, pSort->pLastKey, iLen, pKeyVal, iLen, TRUE ) == 0 ) { - SORT_SET_STACK_LEN( px->sortu.A.NUse, - SORT_GET_STACK_LEN( px->sortu.A.NUse ) - 1 ); - SORT_SET_NUSE( px->sortu.A.NUse, SORT_STACK_OF_CHAR ); + continue; } - else - SORT_SET_NUSE( px->sortu.A.NUse, SORT_ACTIVE_LIST ); - p = r; - px = hb_cdxSortLinkGet( pSort, p ); } - - if( pSort->CurTag->uiType == 'C' && ( !( px->sortu.A.NUse & SORT_NOT_KEY ) || !fTag ) ) -#ifndef HB_CDP_SUPPORT_OFF - /* for nation sorting support */ - df = hb_cdpcharcmp( fTag ? ' ' : Character, ( px->sortu.A.NUse & SORT_NOT_KEY ) ? ' ' : px->sortu.A.Character, cdPage ); -#else - df = ( fTag ? ' ' : Character ) - ( ( px->sortu.A.NUse & SORT_NOT_KEY ) ? ' ' : px->sortu.A.Character ); -#endif - else if( (px->sortu.A.NUse & SORT_NOT_KEY) && !fTag) - df = 1; - else if( fTag && !( px->sortu.A.NUse & SORT_NOT_KEY ) ) - df = -1; - else if( Character > px->sortu.A.Character ) - df = 1; - else if( Character < px->sortu.A.Character ) - df = -1; - else - df = 0; - - if( !pSort->Ascend ) - df = -df; - } - - if( df == 0 ) - * NewLink = p; - else - { - hb_cdxSortLinkNew( pSort, &r ); - if( df < 0 ) - { - qx = hb_cdxSortLinkGet( pSort, q ); - if( q == pSort->PriorPtr ) - qx->sortu.A.WordArray = (USHORT) r; - else - qx->sortu.A.LevelLink = (USHORT) r; - } - else - { - p = px->sortu.A.LevelLink; - px->sortu.A.LevelLink = (USHORT) r; - } - rx = hb_cdxSortLinkGet( pSort, r ); - rx->sortu.A.LevelLink = (USHORT) p; - rx->sortu.A.Character = Character; - if( fTag ) - rx->sortu.A.NUse |= SORT_NOT_KEY; - * NewLink = r; - } -} - -static LPSORTDATA hb_cdxSortLinkGet( LPSORTINFO pSort, LONG Value ) -{ - LPSORTDATA P; - - if( Value > 0 ) - { - P = ( LPSORTDATA ) pSort->ChunkList[ Value >> pSort->NodeShift ]; - if( P != NULL ) - return &P[ Value & pSort->NodeMask ]; - else - return NULL; - } - return NULL; -} - -static void hb_cdxSortDisplayWord( LPSORTINFO pSort ) -{ - /* esto hay que cambiarlo, est para prueba TODO */ - if ( pSort->nSwapPages ) { - if ( pSort->WordCount ) - hb_cdxSortSwapSavePage( pSort ); - hb_cdxSortSwapBuildIndex( pSort ); - } - else - { - pSort->TotalWordCount = pSort->WordCount; - pSort->WPch[ 0 ] = 0; - hb_cdxSortRecurseDict( pSort, pSort->RootLink, 0 ); - } -} - -static void hb_cdxSortRecurseDict( LPSORTINFO pSort, LONG WPtr, LONG WBgn ) -{ - /* USHORT WCnt;*/ - BYTE WCnt; - - if( WPtr == 0 ) - return; - WCnt = pSort->WPch[ 0 ]; - pSort->WAdr = hb_cdxSortLinkGet( pSort, WPtr ); - pSort->WPch[ WCnt + 1 ] = pSort->WAdr->sortu.A.Character; - pSort->WPch[ 0 ]++; - if( SORT_GET_NUSE( pSort->WAdr->sortu.A.NUse ) == SORT_STACK_OF_CHAR ) - { - memcpy( &pSort->WPch[ pSort->WPch[ 0 ] + 1 ], - pSort->WAdr->sortu.B.ChrStack, 4 ); - pSort->WPch[ 0 ] += SORT_GET_STACK_LEN( pSort->WAdr->sortu.A.NUse ) + 1; - } - if( SORT_GET_NUSE(pSort->WAdr->sortu.A.NUse) == SORT_END_OF_WORD ) - hb_cdxSortSendWord( pSort, pSort->WPch ); - else - { - if( pSort->WAdr->sortu.A.WordArray != 0 ) - hb_cdxSortRecurseDict( pSort, pSort->WAdr->sortu.A.WordArray, WBgn ); - pSort->WAdr = hb_cdxSortLinkGet( pSort, WPtr ); - } - pSort->WPch[ 0 ] = WCnt; - if( pSort->WAdr->sortu.A.LevelLink != 0 && - SORT_GET_NUSE( pSort->WAdr->sortu.A.NUse) != SORT_STACK_OF_CHAR ) - hb_cdxSortRecurseDict( pSort, pSort->WAdr->sortu.A.LevelLink, WCnt ); -} - -static void hb_cdxSortSendWord( LPSORTINFO pSort, BYTE * Value ) -{ - LONG Tag; - USHORT uiLen; - double d; - - uiLen = ( USHORT ) Value[0]; - Value++; - HB_ORD2DBL( &Value[uiLen - 8], &d ); - Tag = ( LONG ) d; - hb_cdxSortOutputWord( pSort, Tag, Value, uiLen - 8 ); -} - -static void hb_cdxSortOutputWord( LPSORTINFO pSort, LONG Tag, BYTE * Value, - USHORT uiLen ) -{ - pSort->KeyCnt++; - /* - Patch for empty fields - */ - while( uiLen > 0 && Value[uiLen-1] == - ( pSort->CurTag->uiType == 'C' ? ' ' : 0 ) ) - { - uiLen--; - } - hb_cdxSortKeyPut( pSort->KeyWork, Value, uiLen, - pSort->CurTag->uiLen, ( pSort->CurTag->uiType == 'C' ) ); - hb_cdxSortAddToNode( pSort, 0, Tag, Tag, pSort->KeyWork ); - pSort->LastTag = Tag; - hb_cdxSortKeyCopy( pSort->LastKey, pSort->KeyWork ); -} - -static void hb_cdxSortAddToNode( LPSORTINFO pSort, USHORT Lvl, LONG Tag, - LONG Link, LPCDXKEYINFO Value ) -{ - USHORT i, bitcnt; - LONG sr, mask; - - if( pSort->NodeList[ Lvl ] == NULL ) - { - pSort->NodeList[ Lvl ] = ( LPCDXDATA ) hb_xgrab( sizeof( CDXDATA ) ); - memset( pSort->NodeList[ Lvl ], 0, sizeof( CDXDATA ) ); - if( Lvl == 0 ) - { - sr = pSort->KeyTot; - i = pSort->CurTag->uiLen; - for( bitcnt = 0; i; bitcnt++, i >>= 1 ); - pSort->NodeList[ 0 ]->cdxu.External.ShortBytes = 3; - pSort->NodeList[ 0 ]->cdxu.External.RecNumBits = 24 - bitcnt * 2; - mask = HB_CDXBITMASK( pSort->NodeList[ 0 ]->cdxu.External.RecNumBits ); - while ( sr > mask ) - { - pSort->NodeList[ 0 ]->cdxu.External.ShortBytes++; - pSort->NodeList[ 0 ]->cdxu.External.RecNumBits += 8; - mask = mask << 8 | 0xFF; - } - HB_PUT_LE_ULONG( pSort->NodeList[ 0 ]->cdxu.External.RecNumMask, mask ); - HB_PUT_LE_USHORT( pSort->NodeList[ 0 ]->cdxu.External.FreeSpace, CDX_EXTERNAL_SPACE ); - pSort->NodeList[ 0 ]->cdxu.External.DupCntBits = - pSort->NodeList[ 0 ]->cdxu.External.TrlCntBits = (BYTE) bitcnt; - pSort->NodeList[ 0 ]->cdxu.External.DupCntMask = - (BYTE) HB_CDXBITMASK( pSort->NodeList[ 0 ]->cdxu.External.DupCntBits ); - pSort->NodeList[ 0 ]->cdxu.External.TrlCntMask = - (BYTE) HB_CDXBITMASK( pSort->NodeList[ 0 ]->cdxu.External.TrlCntBits ); - } - pSort->NodeList[ Lvl ]->Left_Ptr = CDX_DUMMYNODE; - pSort->NodeList[ Lvl ]->Rght_Ptr = hb_cdxIndexGetAvailPage( pSort->CurTag->pIndex, FALSE ); - pSort->NodeList[ Lvl ]->Node_Atr = ( Lvl == 0 ) ? CDX_NODE_LEAF : CDX_NODE_BRANCH; - } - if( Lvl == 0 ) - hb_cdxSortAddExternal( pSort, Lvl, Tag, Link, Value ); - else - hb_cdxSortAddInternal( pSort, Lvl, Tag, Link, Value ); -} - -static void hb_cdxSortAddExternal( LPSORTINFO pSort, USHORT Lvl, LONG Tag, LONG Link, - LPCDXKEYINFO Value ) -{ - USHORT k, ct, cd, v, c; - LONG pa; - - if( pSort->NodeList[ Lvl ]->Entry_Ct == 0 ) - { - memset( pSort->NodeList[ Lvl ]->cdxu.External.ExtData, 0, - sizeof( pSort->NodeList[ Lvl ]->cdxu.External.ExtData ) ); - HB_PUT_LE_USHORT( pSort->NodeList[ Lvl ]->cdxu.External.FreeSpace, CDX_EXTERNAL_SPACE ); - - hb_cdxSortKeyPut( pSort->LastKey, (BYTE*) "", 0, 0, ( pSort->CurTag->uiType == 'C' ) ); - } - ct = ( USHORT ) ( pSort->CurTag->uiLen - Value->length ); - cd = hb_cdxSortKeyFindDup( Value, pSort->LastKey ); - #ifdef HB_CDX_DBGCODE_EXT -#ifndef HB_CDP_SUPPORT_OFF - if( hb_cdxSortKeyCompare( Value, pSort->LastKey, pSort->CurTag->pIndex->pArea->cdPage ) < 0 ) -#else - if( hb_cdxSortKeyCompare( Value, pSort->LastKey ) < 0 ) + if ( ulKey != 0 ) + { + int i = hb_cdxValCompare( pSort->pTag, pSort->pLastKey, iLen, pKeyVal, iLen, TRUE ); + if ( i == 0 ) + { + i = ( pSort->ulLastRec < ulRec ) ? -1 : 1; + } + if ( i > 0 ) + { + printf("\r\nulKey=%ld, pKeyVal=[%s][%ld], pKeyLast=[%s][%ld]\r\n", + ulKey, pKeyVal, ulRec, pSort->pLastKey, pSort->ulLastRec); fflush(stdout); + hb_errInternal( 9999, "hb_cdxSortOut: sorting fails.", "", "" ); + } + } #endif + hb_cdxSortAddNodeKey( pSort, 0, pKeyVal, ulRec, 0 ); + memcpy( pSort->pLastKey, pKeyVal, iLen ); + pSort->ulLastRec = ulRec; + } + +#ifdef HB_CDX_DBGCODE + if ( hb_cdxSortKeyGet( pSort, &pKeyVal, &ulRec ) ) { -/* - printf("\r\nValue->length=%2d, Value->Value=%s", Value->length, Value->Value); - printf("\r\n Last->length=%2d, Last->Value=%s", pSort->LastKey->length, pSort->LastKey->Value); - fflush(stdout); -*/ - hb_cdxErrInternal( "hb_cdxSortAddExternal: Index corrupted" ); + hb_errInternal( 9999, "hb_cdxSortOut: memory structure corrupted(2).", "", "" ); } #endif - v = ( USHORT ) ( pSort->NodeList[ Lvl ]->Entry_Ct * - pSort->NodeList[ Lvl ]->cdxu.External.ShortBytes ); - k = HB_GET_LE_USHORT( pSort->NodeList[ Lvl ]->cdxu.External.FreeSpace ); - c = k - ( USHORT ) ( pSort->CurTag->uiLen + - pSort->NodeList[ Lvl ]->cdxu.External.ShortBytes - - cd - ct ); - HB_PUT_LE_USHORT( pSort->NodeList[ Lvl ]->cdxu.External.FreeSpace, c ); - k += v; -/* - // RECMASK - rr = ( (ULONGLONG) ct << ( ( pSort->NodeList[ Lvl ]->cdxu.External.ShortBytes * 8 ) - - pSort->NodeList[ Lvl ]->cdxu.External.TrlCntBits ) ) | - ( (ULONGLONG) cd << ( ( pSort->NodeList[ Lvl ]->cdxu.External.ShortBytes * 8 ) - - pSort->NodeList[ Lvl ]->cdxu.External.TrlCntBits - - pSort->NodeList[ Lvl ]->cdxu.External.DupCntBits ) ) | - Tag; - memcpy( &pSort->NodeList[ Lvl ]->cdxu.External.ExtData[ v ], &rr, pSort->NodeList[ Lvl ]->cdxu.External.ShortBytes ); -*/ - hb_cdxSetLeafRecord( &pSort->NodeList[ Lvl ]->cdxu.External.ExtData[ v ], - Tag, cd, ct, - pSort->NodeList[ Lvl ]->cdxu.External.ShortBytes, - pSort->NodeList[ Lvl ]->cdxu.External.DupCntBits, - pSort->NodeList[ Lvl ]->cdxu.External.TrlCntBits ); - k -= ( USHORT ) ( pSort->CurTag->uiLen - cd - ct ); - if( pSort->CurTag->uiLen - cd - ct > 0 ) - memcpy( &pSort->NodeList[ Lvl ]->cdxu.External.ExtData[ k ], - Value->Value + cd, - pSort->CurTag->uiLen - cd - ct ); - pSort->NodeList[ Lvl ]->Entry_Ct++; - if( HB_GET_LE_USHORT( pSort->NodeList[ Lvl ]->cdxu.External.FreeSpace ) < - ( pSort->CurTag->uiLen + - pSort->NodeList[ Lvl ]->cdxu.External.ShortBytes ) * 1 ) /* 2 only if count after the key was added */ + + if ( pSort->NodeList[ 0 ] == NULL ) { - pa = pSort->NodeList[ Lvl ]->Rght_Ptr; - /* TODO : check this, may be wrong */ - /* if( pSort->KeyCnt < pSort->KeyTot ) */ - if( pSort->KeyCnt < pSort->TotalWordCount ) - pSort->NodeList[ Lvl ]->Rght_Ptr = hb_cdxIndexGetAvailPage( pSort->CurTag->pIndex, FALSE ); - else - pSort->NodeList[ Lvl ]->Rght_Ptr = CDX_DUMMYNODE; - pSort->NodeList[ Lvl ]->Node_Atr = CDX_NODE_LEAF; - hb_cdxSortPageWrite( pSort->CurTag->pIndex, pa, pSort->NodeList[ Lvl ] ); - pSort->NodeList[ Lvl ]->Left_Ptr = pa; - hb_cdxSortAddToNode( pSort, ( USHORT ) ( Lvl + 1 ), pa, Link, Value ); - pSort->NodeList[ Lvl ]->Entry_Ct = 0; + pSort->NodeList[ 0 ] = hb_cdxPageNew( pSort->pTag, NULL, 0 ); + pSort->NodeList[ 0 ]->PageType = CDX_NODE_LEAF; + hb_cdxPageLeafInitSpace( pSort->NodeList[ 0 ] ); } -} -static void hb_cdxSortAddInternal( LPSORTINFO pSort, USHORT Lvl, LONG Tag, LONG Link, - LPCDXKEYINFO Value ) -{ - USHORT v; - LONG pa; - - if( pSort->NodeList[ Lvl ]->Entry_Ct == 0 ) - memset( pSort->NodeList[ Lvl ]->cdxu.Internal.IntData, - pSort->CurTag->uiType == 'C' ? 32 : 0, - sizeof( pSort->NodeList[ Lvl ]->cdxu.Internal.IntData ) ); - v = ( USHORT ) ( pSort->NodeList[ Lvl ]->Entry_Ct * - ( pSort->CurTag->uiLen + 8 ) ); - memcpy( &pSort->NodeList[ Lvl ]->cdxu.Internal.IntData[ v ], - Value->Value, Value->length ); - v += pSort->CurTag->uiLen; - HB_PUT_BE_ULONG( &pSort->NodeList[ Lvl ]->cdxu.Internal.IntData[ v ], Link ); - HB_PUT_BE_ULONG( &pSort->NodeList[ Lvl ]->cdxu.Internal.IntData[ v + 4 ], Tag ); - pSort->NodeList[ Lvl ]->Entry_Ct++; - if( pSort->NodeList[ Lvl ]->Entry_Ct >= pSort->CurTag->MaxKeys ) + iLevel = 0; + fNext = TRUE; + do { - pa = pSort->NodeList[ Lvl ]->Rght_Ptr; - if( !pSort->Closing ) - pSort->NodeList[ Lvl ]->Rght_Ptr = hb_cdxIndexGetAvailPage( pSort->CurTag->pIndex, FALSE ); + if ( iLevel + 1 == CDX_STACKSIZE || pSort->NodeList[ iLevel + 1 ] == NULL ) + { + pSort->NodeList[ iLevel ]->PageType |= CDX_NODE_ROOT; + pSort->pTag->RootBlock = pSort->NodeList[ iLevel ]->Page; + fNext = FALSE; + } else - pSort->NodeList[ Lvl ]->Rght_Ptr = CDX_DUMMYNODE; - pSort->NodeList[ Lvl ]->Node_Atr = CDX_NODE_BRANCH; - hb_cdxSortPageWrite( pSort->CurTag->pIndex, pa, pSort->NodeList[ Lvl ] ); - pSort->NodeList[ Lvl ]->Left_Ptr = pa; - hb_cdxSortAddToNode( pSort, ( USHORT ) ( Lvl + 1 ), pa, Link, Value ); - pSort->NodeList[ Lvl ]->Entry_Ct = 0; + { + hb_cdxSortAddNodeKey( pSort, iLevel + 1, pSort->pLastKey, pSort->ulLastRec, pSort->NodeList[ iLevel ]->Page ); + } + hb_cdxPageFree( pSort->NodeList[ iLevel ], TRUE ); + iLevel++; } -} + while ( fNext ); -/* ######################################################################### */ + hb_cdxSortFree( pSort ); +} static void hb_cdxTagEmptyIndex( LPCDXTAG pTag ) { @@ -7868,13 +8159,13 @@ static void hb_cdxTagDoIndex( LPCDXTAG pTag ) { ULONG ulRecNo, ulRecCount; BOOL bForOk; - LPSORTINFO pSort; + LPCDXSORTINFO pSort; PHB_ITEM pItem; HB_MACRO_PTR pMacro; BYTE cTemp[8]; LPCDXAREA pArea = pTag->pIndex->pArea; LONG lStep = 0; - BOOL bDirectRead, bEnd; + BOOL bDirectRead; PHB_ITEM pForItem, pWhileItem, pEvalItem; #ifndef HB_CDP_SUPPORT_OFF /* TODO: this hack is not thread safe, hb_cdp_page has to be thread specific */ @@ -7888,68 +8179,101 @@ static void hb_cdxTagDoIndex( LPCDXTAG pTag ) } else { - BOOL bSaveDeleted = hb_set.HB_SET_DELETED; + BOOL bSaveDeleted = hb_set.HB_SET_DELETED, fSaveRecDeleted = pArea->fDeleted; PHB_ITEM pSaveFilter = pArea->dbfi.itmCobExpr; USHORT uiSaveTag = pArea->uiTag; + ULONG ulSaveRecNo = pArea->ulRecNo, ulStartRec = 0, ulNextCount = 0; + BYTE * pSaveRecBuff = pArea->pRecord; + int iRecBuff = 0, iRecBufSize = USHRT_MAX / pArea->uiRecordLen; + hb_set.HB_SET_DELETED = FALSE; pArea->dbfi.itmCobExpr = NULL; - pSort = hb_cdxSortNew( pTag, pTag->UniqueKey ); pItem = hb_itemNew( NULL ); - ulRecCount = pArea->ulRecCount; + SELF_RECCOUNT( ( AREAP ) pArea, &ulRecCount ); + pArea->pSort = pSort = hb_cdxSortNew( pTag, ulRecCount ); pForItem = pTag->pForItem; bForOk = TRUE; pEvalItem = ( pArea->lpdbOrdCondInfo ? pArea->lpdbOrdCondInfo->itmCobEval : NULL); pWhileItem = ( pArea->lpdbOrdCondInfo ? pArea->lpdbOrdCondInfo->itmCobWhile : NULL); - bEnd = FALSE; - bDirectRead = !hb_set.HB_SET_STRICTREAD && !pArea->lpdbRelations && - ( !pArea->lpdbOrdCondInfo || pArea->lpdbOrdCondInfo->fAll ); - if ( !bDirectRead ) + + if ( !pArea->lpdbOrdCondInfo || pArea->lpdbOrdCondInfo->fAll ) { - if ( !pArea->lpdbOrdCondInfo || pArea->lpdbOrdCondInfo->fAll ) + pArea->uiTag = 0; + } + else if ( pArea->lpdbOrdCondInfo->lRecno ) + { + ulStartRec = ulRecCount = pArea->lpdbOrdCondInfo->lRecno; + ulNextCount = 1; + } + else if ( pArea->lpdbOrdCondInfo->fRest || pArea->lpdbOrdCondInfo->lNextCount > 0 ) + { + if ( pArea->lpdbOrdCondInfo->lStartRecno ) { - pArea->uiTag = 0; - SELF_GOTOP( ( AREAP ) pArea ); - } - else if ( pArea->lpdbOrdCondInfo->lRecno ) - { - SELF_GOTO( ( AREAP ) pArea, pArea->lpdbOrdCondInfo->lRecno ); - bEnd = TRUE; - } - else if ( pArea->lpdbOrdCondInfo->fUseCurrent ) - { - if ( pArea->lpdbOrdCondInfo->lStartRecno ) - { - SELF_GOTO( ( AREAP ) pArea, pArea->lpdbOrdCondInfo->lStartRecno ); - } - else - { - SELF_GOTOP( ( AREAP ) pArea ); - } - } - else if ( pArea->lpdbOrdCondInfo->fRest || pArea->lpdbOrdCondInfo->lNextCount ) - { - if ( pArea->lpdbOrdCondInfo->lStartRecno ) - { - SELF_GOTO( ( AREAP ) pArea, pArea->lpdbOrdCondInfo->lStartRecno ); - } + ulStartRec = pArea->lpdbOrdCondInfo->lStartRecno; } else { - pArea->uiTag = 0; - SELF_GOTOP( ( AREAP ) pArea ); + ulStartRec = pArea->ulRecNo; + } + if ( pArea->lpdbOrdCondInfo->lNextCount > 0 ) + { + ulNextCount = pArea->lpdbOrdCondInfo->lNextCount; + ulRecCount = ulStartRec + ulNextCount - 1; } } - for ( ulRecNo = 1; ulRecNo <= ulRecCount; ulRecNo++ ) + else if ( !pArea->lpdbOrdCondInfo->fUseCurrent ) + { + pArea->uiTag = 0; + } + + bDirectRead = !hb_set.HB_SET_STRICTREAD && !pArea->lpdbRelations && + ( !pArea->lpdbOrdCondInfo || pArea->lpdbOrdCondInfo->fAll || + pArea->uiTag == 0 ) && pSort; + + if ( bDirectRead ) + { + pSort->pRecBuff = (BYTE *) hb_xgrab( pArea->uiRecordLen * iRecBufSize ); + if ( ulStartRec == 0 ) + { + ulStartRec = 1; + } + } + else + { + if ( ulStartRec == 0 ) + { + SELF_GOTOP( ( AREAP ) pArea ); + } + else + { + SELF_GOTO( ( AREAP ) pArea, ulStartRec ); + } + ulStartRec = 1; + } + + for ( ulRecNo = ulStartRec; ulRecNo <= ulRecCount; ulRecNo++ ) { if ( bDirectRead ) { - hb_fsSeek( pArea->hDataFile, - pArea->uiHeaderLen + ( ulRecNo - 1 ) * pArea->uiRecordLen, - FS_SET ); - hb_fsRead( pArea->hDataFile, pArea->pRecord, pArea->uiRecordLen ); + if ( iRecBuff == 0 || iRecBuff >= iRecBufSize ) + { + int iRec; + if ( ulRecCount - ulRecNo >= (ULONG) iRecBufSize ) + iRec = iRecBufSize; + else + iRec = ulRecCount - ulRecNo + 1; + + hb_fsSeek( pArea->hDataFile, + pArea->uiHeaderLen + ( ulRecNo - 1 ) * pArea->uiRecordLen, + FS_SET ); + hb_fsReadLarge( pArea->hDataFile, pSort->pRecBuff, pArea->uiRecordLen * iRec ); + iRecBuff = 0; + } + pArea->pRecord = pSort->pRecBuff + iRecBuff * pArea->uiRecordLen; pArea->ulRecNo = ulRecNo; pArea->fDeleted = ( pArea->pRecord[ 0 ] == '*' ); + iRecBuff++; } else if ( pWhileItem && !hb_cdxEvalCond ( NULL, pWhileItem, FALSE ) ) break; @@ -7985,35 +8309,44 @@ static void hb_cdxTagDoIndex( LPCDXTAG pTag ) switch( hb_itemType( pItem ) ) { case HB_IT_STRING: - hb_cdxSortInsertWord( pSort, ( LONG ) pArea->ulRecNo, - pItem->item.asString.value, - HB_CDXMAXKEY( pItem->item.asString.length ) ); + hb_cdxSortKeyAdd( pSort, pArea->ulRecNo, + ( BYTE * ) pItem->item.asString.value, + HB_CDXMAXKEY( pItem->item.asString.length ) ); break; case HB_IT_INTEGER: case HB_IT_LONG: -#ifndef HB_LONG_LONG_OFF +#ifdef HB_IT_LONGLONG case HB_IT_LONGLONG: #endif case HB_IT_DOUBLE: d = hb_itemGetND( pItem ); HB_DBL2ORD( &d, &cTemp[0] ); - hb_cdxSortInsertWord( pSort, pArea->ulRecNo, (char *) cTemp, 8 ); + hb_cdxSortKeyAdd( pSort, pArea->ulRecNo, cTemp, 8 ); break; case HB_IT_DATE: d = (double) pItem->item.asDate.value; HB_DBL2ORD( &d, &cTemp[0] ); - hb_cdxSortInsertWord( pSort, pArea->ulRecNo, (char *) cTemp, 8 ); + hb_cdxSortKeyAdd( pSort, pArea->ulRecNo, cTemp, 8 ); break; case HB_IT_LOGICAL: cTemp[0] = (BYTE) (hb_itemGetL( pItem ) ? 'T' : 'F'); - hb_cdxSortInsertWord( pSort, pArea->ulRecNo, (char *) cTemp, 1 ); + hb_cdxSortKeyAdd( pSort, pArea->ulRecNo, cTemp, 1 ); break; default: - printf( "hb_cdxTagDoIndex: hb_itemType( pItem ) = %i", hb_itemType( pItem ) ); + if ( hb_vmRequestQuery() ) + { + pEvalItem = NULL; + ulNextCount = 1; + } + else + { + printf( "hb_cdxTagDoIndex: hb_itemType( pItem ) = %i", hb_itemType( pItem ) ); + } + break; } } if ( pEvalItem ) @@ -8030,28 +8363,35 @@ static void hb_cdxTagDoIndex( LPCDXTAG pTag ) break; } } + if( ulNextCount > 0 ) + { + if ( --ulNextCount == 0 ) + break; + } if ( !bDirectRead ) { - if ( bEnd ) - break; - if ( pArea->lpdbOrdCondInfo && pArea->lpdbOrdCondInfo->lNextCount > 0 ) - { - pArea->lpdbOrdCondInfo->lNextCount--; - if ( pArea->lpdbOrdCondInfo->lNextCount <= 0 ) - break; - } SELF_SKIP( ( AREAP ) pArea, 1 ); if ( pArea->fEof ) break; } } - if ( pSort->WordCount + pSort->TotalWordCount > 0 ) - hb_cdxSortDisplayWord( pSort ); + if ( pSort ) + { + hb_cdxSortOut( pSort ); + pArea->pSort = NULL; + } else + { hb_cdxTagEmptyIndex( pTag ); - hb_cdxSortFree( pSort ); + } hb_itemRelease( pItem ); + if ( bDirectRead ) + { + pArea->pRecord = pSaveRecBuff; + pArea->ulRecNo = ulSaveRecNo; + pArea->fDeleted = fSaveRecDeleted; + } hb_set.HB_SET_DELETED = bSaveDeleted; pArea->dbfi.itmCobExpr = pSaveFilter; pArea->uiTag = uiSaveTag; @@ -8062,4 +8402,3 @@ static void hb_cdxTagDoIndex( LPCDXTAG pTag ) hb_cdp_page = cdpTmp; #endif } - diff --git a/harbour/source/rdd/dbfcdx/dbfcdx1.h b/harbour/source/rdd/dbfcdx/dbfcdx1.h deleted file mode 100644 index 086831f291..0000000000 --- a/harbour/source/rdd/dbfcdx/dbfcdx1.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * $Id$ - */ - -/* - * Harbour Project source code: - * DBFCDX RDD - * - * Copyright 1999 Bruno Cantero - * Copyright 2000-2002 Horacio Roldan (portions) - * www - http://www.harbour-project.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 CDX_INTERNAL_SPACE 500 -#define CDX_EXTERNAL_SPACE 488 - -#define SORT_CHUNK_LIMIT 16384 -#define SORT_ACTIVE_LIST 0 -#define SORT_END_OF_KEY 1 -#define SORT_END_OF_WORD 2 -#define SORT_STACK_OF_CHAR 3 -#define SORT_NOT_KEY 0x10 - -#if (__BORLANDC__ > 1040) /* Use this only above Borland C++ 3.1 */ - #pragma option -a1 /* byte alignment */ -#elif defined(_MSC_VER) - #pragma pack(push, 1) -#elif defined(__GNUC__) - #pragma pack(1) -#elif defined(__WATCOMC__) - #pragma pack(push, 1); -#elif defined(__cplusplus) - #pragma pack(1) -#endif - -typedef struct -{ - BYTE FreeSpace[2]; - BYTE RecNumMask[4]; - BYTE DupCntMask; - BYTE TrlCntMask; - BYTE RecNumBits; - BYTE DupCntBits; - BYTE TrlCntBits; - BYTE ShortBytes; - BYTE ExtData[ CDX_EXTERNAL_SPACE ]; -} CDXEXTERNAL; - -typedef struct -{ - BYTE IntData[ CDX_INTERNAL_SPACE ]; -} CDXINTERNAL; - -typedef struct _CDXDATA -{ - USHORT Node_Atr; - USHORT Entry_Ct; - LONG Left_Ptr; - LONG Rght_Ptr; - union - { - CDXEXTERNAL External; - CDXINTERNAL Internal; - } cdxu; -} CDXDATA; -typedef CDXDATA * LPCDXDATA; - -typedef struct _SORTSWAPPAGE -{ - char mark[2]; - USHORT pageNum; - ULONG pageLen; - ULONG keyCount; - USHORT nCurPos; - USHORT nBufLeft; - ULONG nFileOffset; - ULONG nBytesLeft; - ULONG keysLeft; - ULONG tmpRecNo; /* to speed up access */ - BYTE tmpKeyLen; - BYTE * tmpKeyVal; - BYTE page[ 512 ]; -} SORTSWAPPAGE; -typedef SORTSWAPPAGE * LPSORTSWAPPAGE; - -typedef struct _SORTSWAPITEM -{ - ULONG recno; - BYTE keyLen; - char key[ 1 ]; -} SORTSWAPITEM; -typedef SORTSWAPITEM * LPSORTSWAPITEM; - -#if (__BORLANDC__ > 1040) /* Use this only above Borland C++ 3.1 */ - #pragma option -a /* default alignment */ -#elif defined(_MSC_VER) - #pragma pack(pop) -#elif defined(__GNUC__) - #pragma pack() -#elif defined(__WATCOMC__) - #pragma pack(pop); -#elif defined(__cplusplus) - #pragma pack() -#endif - -/*SORT stuff*/ -typedef struct -{ - BYTE Character; - BYTE NUse; - USHORT WordArray; - USHORT Fill02; - USHORT LevelLink; -} SORT_A; - -typedef struct -{ - BYTE Fill03[ 4 ]; - BYTE ChrStack[ 4 ]; -} SORT_B; - -typedef struct -{ - LONG Fill04; - LONG ChrFill; -} SORT_C; - -#define SORT_GET_NUSE( w ) (( w ) & 0x07 ) -#define SORT_SET_NUSE( w, n ) (( w ) = ( ( w ) & 0xF8 ) | ( n ) ) -#define SORT_GET_STACK_LEN( w ) (( w ) >> 6 ) -#define SORT_SET_STACK_LEN( w, n ) (( w ) = ( ( w ) & 0x3F ) | ( ( n ) << 6 ) ) - -typedef struct -{ - union - { - SORT_A A; - SORT_B B; - SORT_C C; - } sortu; -} SORTDATA; - -typedef SORTDATA * LPSORTDATA; - -typedef struct _CDXKEYINFO -{ - BYTE * Value; - USHORT length; - USHORT realLength; - BOOL fString; - ULONG Tag; - ULONG Xtra; - struct _CDXKEYINFO * pNext; -} CDXKEYINFO; -typedef CDXKEYINFO * LPCDXKEYINFO; - -typedef struct -{ - LONG WordCount; - LONG RootLink; - LONG LevelPtr; - LONG PriorPtr; - LONG KeyTot; - LONG KeyCnt; - LONG LastTag; - LONG * ChunkList; - BYTE * SortBuffer; - USHORT SortChunk; - USHORT NodeLimit; - USHORT NodeMask; - USHORT NodeShift; - USHORT ChunkSize; - USHORT ChunkLimit; - USHORT ChunkCur; - USHORT NodeCur; - USHORT KeySize; - USHORT WCur; - BOOL Unique; - BOOL Ascend; - BOOL Closing; - - USHORT nSwapPages; - LPSORTSWAPPAGE pSwapPage; - FHANDLE hTempFile; - char * szTempFileName; - LONG TotalWordCount; - - BYTE WPch[ 256 ]; - SORTDATA * WAdr; - struct _CDXTAG * CurTag; - LPCDXDATA NodeList[ 32 ]; - LPCDXKEYINFO KeyWork; - LPCDXKEYINFO LastKey; -} SORTINFO; - -typedef SORTINFO * LPSORTINFO; diff --git a/harbour/source/rdd/dbffpt/dbffpt1.c b/harbour/source/rdd/dbffpt/dbffpt1.c index 78650927fb..5d9af00f57 100644 --- a/harbour/source/rdd/dbffpt/dbffpt1.c +++ b/harbour/source/rdd/dbffpt/dbffpt1.c @@ -54,6 +54,13 @@ * If you do not wish that, delete this exception notice. * */ +#if defined( HB_FPT_NO_READLOCK ) && !defined( HB_FPT_USE_READLOCK ) + #define HB_FPT_USE_READLOCK +#endif + +#ifndef HB_FPT_USE_READLOCK + #define HB_FPT_SAFE +#endif #include "hbapi.h" #include "hbinit.h" @@ -65,7 +72,6 @@ #ifndef HB_CDP_SUPPORT_OFF # include "hbapicdp.h" - extern PHB_CODEPAGE hb_cdp_page; #endif #define __PRG_SOURCE__ __FILE__ @@ -267,35 +273,105 @@ HB_INIT_SYMBOLS_END( dbffpt1__InitSymbols ) #endif +static ERRCODE hb_fptIsDbLocked( FPTAREAP pArea, BOOL *bLocked ) +{ + HB_ITEM recItm = HB_ITEM_NIL, resultItm = HB_ITEM_NIL; + + if ( pArea->fShared && !pArea->fFLocked && !pArea->fRecordChanged ) + { + if ( SELF_RECINFO( ( AREAP ) pArea, &recItm, DBRI_LOCKED, &resultItm ) == FAILURE ) + return FAILURE; + *bLocked = hb_itemGetL( &resultItm ); + } + else + *bLocked = TRUE; + + return SUCCESS; +} +#if defined( HB_FPT_USE_READLOCK ) +/* + * Read Lock for Memo + */ +static BOOL hb_fptReadLock( FPTAREAP pArea, ULONG uiIndex, ULONG *pulOffset ) +{ + BOOL fRet= TRUE ; +#ifndef HB_FPT_NO_READLOCK + if ( pArea->fShared && !pArea->fFLocked ) // and we are not open EXCLUSIVE or FILELOCKED + { + *pulOffset = pArea->uiMemoBlockSize * hb_dbfGetMemoBlock( (DBFAREAP) pArea, uiIndex - 1 ) ; + if ( *pulOffset ) // There is something in the memo so lock it + { + do + { + fRet = hb_fsLock( pArea->hMemoFile, *pulOffset, pArea->uiMemoBlockSize, + FL_LOCK | FLX_SHARED | FLX_WAIT ); + } while ( !fRet ); + } + } + else +#endif + { + *pulOffset = 0 ; + } + return fRet ; +} + +/* + * Read UnLock for Memo + */ +static BOOL hb_fptReadUnLock( FPTAREAP pArea, ULONG ulOffset ) +{ + if ( ulOffset ) + { + hb_fsLock( pArea->hMemoFile, ulOffset, pArea->uiMemoBlockSize, FL_UNLOCK ); + } + return TRUE ; +} +#endif + /* * Exclusive lock memo file. */ -static BOOL hb_fptFileLockEx( FPTAREAP pArea ) +static BOOL hb_fptFileLockEx( FPTAREAP pArea, BOOL fWait ) { BOOL fRet; - do - { - fRet = hb_fsLock( pArea->hMemoFile, FPT_LOCKPOS, FPT_LOCKSIZE, - FL_LOCK | FLX_EXCLUSIVE | FLX_WAIT ); - } while ( !fRet ); - - return fRet; + if ( !pArea->fShared ) + { + fRet = TRUE; + } + else + { + do + { + fRet = hb_fsLock( pArea->hMemoFile, FPT_LOCKPOS, FPT_LOCKSIZE, + FL_LOCK | FLX_EXCLUSIVE | ( fWait ? FLX_WAIT : 0 ) ); + } while ( !fRet && fWait ); + } + return fRet; } /* * Shared lock memo file. */ -static BOOL hb_fptFileLockSh( FPTAREAP pArea ) + + +static BOOL hb_fptFileLockSh( FPTAREAP pArea, BOOL fWait ) { BOOL fRet; - do - { - fRet = hb_fsLock( pArea->hMemoFile, FPT_LOCKPOS, FPT_LOCKSIZE, - FL_LOCK | FLX_SHARED | FLX_WAIT ); - } while ( !fRet ); - + if ( !pArea->fShared ) + { + fRet = TRUE; + } + else + { + do + { + fRet = hb_fsLock( pArea->hMemoFile, FPT_LOCKPOS, FPT_LOCKSIZE, + FL_LOCK | FLX_SHARED | ( fWait ? FLX_WAIT : 0 ) ); + } while ( !fRet && fWait ); + } return fRet; } @@ -338,7 +414,7 @@ static BOOL hb_fptFileUnLock( FPTAREAP pArea ) to recalculate it: nItem = ( nItem - 3 ) / 4 if FPTHEADER->flexDir = 0 then we can create it by allocating - two 1024 bytes pages ofr flexRev and flexDir page. + two 1024 bytes pages for flexRev and flexDir page. FPTHEADER->flexRev[4] 1024 bytes in next free block FPTHEADER->flexDir[4] next 1024 bytes flexRev page is copy of flexDir page but the items are stored @@ -480,8 +556,8 @@ static ERRCODE hb_fptWriteGCitems( FPTAREAP pArea, LPMEMOGCTABLE pGCtable, USHOR { if ( pGCtable->pGCitems[i].fChanged ) { - HB_PUT_BE_ULONG( fptBlock.type, FPTIT_FLEX_UNUSED ); - HB_PUT_BE_ULONG( fptBlock.size, pArea->uiMemoBlockSize * + HB_PUT_BE_UINT32( fptBlock.type, FPTIT_FLEX_UNUSED ); + HB_PUT_BE_UINT32( fptBlock.size, pArea->uiMemoBlockSize * pGCtable->pGCitems[i].ulSize - sizeof( FPTBLOCK ) ); hb_fsSeek( pArea->hMemoFile, pGCtable->pGCitems[i].ulOffset * pArea->uiMemoBlockSize, FS_SET ); @@ -491,6 +567,7 @@ static ERRCODE hb_fptWriteGCitems( FPTAREAP pArea, LPMEMOGCTABLE pGCtable, USHOR errCode = EDBF_WRITE; } pGCtable->pGCitems[i].fChanged = FALSE; + pArea->fMemoFlush = TRUE; } } return errCode; @@ -513,7 +590,7 @@ static ERRCODE hb_fptGCfreeBlock( FPTAREAP pArea, LPMEMOGCTABLE pGCtable, if( hb_fsRead( pArea->hMemoFile, ( BYTE * ) &fptBlock, sizeof( FPTBLOCK ) ) == sizeof( FPTBLOCK ) ) { - ulByteSize = HB_GET_BE_ULONG( fptBlock.size ) + sizeof( FPTBLOCK ); + ulByteSize = HB_GET_BE_UINT32( fptBlock.size ) + sizeof( FPTBLOCK ); } } else @@ -680,14 +757,14 @@ static ERRCODE hb_fptReadGCdata( FPTAREAP pArea, LPMEMOGCTABLE pGCtable ) hb_fsSeek( pArea->hMemoFile, 0, FS_SET ); if ( hb_fsRead( pArea->hMemoFile, ( BYTE * ) &pGCtable->fptHeader, sizeof( FPTHEADER ) ) >= 512 ) { - pGCtable->ulNextBlock = HB_GET_BE_ULONG( pGCtable->fptHeader.nextBlock ); + pGCtable->ulNextBlock = HB_GET_BE_UINT32( pGCtable->fptHeader.nextBlock ); if ( pArea->bMemoType == MEMO_FPT_SIX || pArea->bMemoType == MEMO_FPT_SIXHB ) { pGCtable->bType = MEMO_FPT_SIX; pGCtable->usMaxItem = MAX_SIXFREEBLOCKS; - pGCtable->usItems = HB_GET_LE_USHORT( pGCtable->fptHeader.nGCitems ); + pGCtable->usItems = HB_GET_LE_UINT16( pGCtable->fptHeader.nGCitems ); if ( pGCtable->usItems > pGCtable->usMaxItem ) { return EDBF_CORRUPT; @@ -697,8 +774,8 @@ static ERRCODE hb_fptReadGCdata( FPTAREAP pArea, LPMEMOGCTABLE pGCtable ) for( i = 0; i < pGCtable->usItems; i++ ) { - pGCtable->pGCitems[i].ulSize = HB_GET_LE_USHORT( &pGCtable->fptHeader.reserved2[ i * 6 ] ); - pGCtable->pGCitems[i].ulOffset = HB_GET_LE_ULONG( &pGCtable->fptHeader.reserved2[ i * 6 + 2 ] ); + pGCtable->pGCitems[i].ulSize = HB_GET_LE_UINT16( &pGCtable->fptHeader.reserved2[ i * 6 ] ); + pGCtable->pGCitems[i].ulOffset = HB_GET_LE_UINT32( &pGCtable->fptHeader.reserved2[ i * 6 + 2 ] ); pGCtable->pGCitems[i].fChanged = FALSE; } } @@ -711,19 +788,19 @@ static ERRCODE hb_fptReadGCdata( FPTAREAP pArea, LPMEMOGCTABLE pGCtable ) pGCtable->bType = MEMO_FPT_FLEX; pGCtable->usMaxItem = MAX_FLEXFREEBLOCKS; - pGCtable->ulRevPage = HB_GET_LE_ULONG( pGCtable->fptHeader.flexRev ); - pGCtable->ulDirPage = HB_GET_LE_ULONG( pGCtable->fptHeader.flexDir ); - pGCtable->ulCounter = HB_GET_LE_ULONG( pGCtable->fptHeader.counter ); + pGCtable->ulRevPage = HB_GET_LE_UINT32( pGCtable->fptHeader.flexRev ); + pGCtable->ulDirPage = HB_GET_LE_UINT32( pGCtable->fptHeader.flexDir ); + pGCtable->ulCounter = HB_GET_LE_UINT32( pGCtable->fptHeader.counter ); if ( pGCtable->ulDirPage ) { hb_fsSeek( pArea->hMemoFile, pGCtable->ulDirPage, FS_SET ); if ( hb_fsRead( pArea->hMemoFile, ( BYTE * ) &fptBlock, sizeof( FPTBLOCK ) ) != sizeof( FPTBLOCK ) || - HB_GET_BE_ULONG( fptBlock.type ) != FPTIT_FLEX_GC ) + HB_GET_BE_UINT32( fptBlock.type ) != FPTIT_FLEX_GC ) { return EDBF_CORRUPT; } - pGCtable->ulSize = HB_GET_BE_ULONG( fptBlock.size ); + pGCtable->ulSize = HB_GET_BE_UINT32( fptBlock.size ); bPageBuf = ( BYTE * ) hb_xgrab( pGCtable->ulSize ); if ( hb_fsRead( pArea->hMemoFile, bPageBuf, ( USHORT ) pGCtable->ulSize ) != ( USHORT ) pGCtable->ulSize ) @@ -732,16 +809,16 @@ static ERRCODE hb_fptReadGCdata( FPTAREAP pArea, LPMEMOGCTABLE pGCtable ) return EDBF_CORRUPT; } pGCtable->usMaxItem = (USHORT ) ( ( pGCtable->ulSize - 2 ) >> 3 ); - pGCtable->usItems = ( HB_GET_LE_USHORT( bPageBuf ) - 3 ) >> 2; + pGCtable->usItems = ( HB_GET_LE_UINT16( bPageBuf ) - 3 ) >> 2; pGCtable->pGCitems = ( LPMEMOGCITEM ) hb_xgrab( sizeof( MEMOGCITEM ) * ( HB_MIN( pGCtable->usItems, pGCtable->usMaxItem ) + 1 ) ); for( i = 0; i < pGCtable->usItems; i++ ) { - pGCtable->pGCitems[i].ulOffset = HB_GET_LE_ULONG( &bPageBuf[ i * 8 + 2 ] ) / + pGCtable->pGCitems[i].ulOffset = HB_GET_LE_UINT32( &bPageBuf[ i * 8 + 2 ] ) / pArea->uiMemoBlockSize; - pGCtable->pGCitems[i].ulSize = HB_GET_LE_ULONG( &bPageBuf[ i * 8 + 6 ] ) / + pGCtable->pGCitems[i].ulSize = HB_GET_LE_UINT32( &bPageBuf[ i * 8 + 6 ] ) / pArea->uiMemoBlockSize; pGCtable->pGCitems[i].fChanged = FALSE; } @@ -772,15 +849,15 @@ static ERRCODE hb_fptWriteGCdata( FPTAREAP pArea, LPMEMOGCTABLE pGCtable ) { if ( pGCtable->bType == MEMO_FPT_SIX ) { - HB_PUT_LE_USHORT( pGCtable->fptHeader.nGCitems, pGCtable->usItems ); + HB_PUT_LE_UINT16( pGCtable->fptHeader.nGCitems, pGCtable->usItems ); memset( pGCtable->fptHeader.reserved2, 0, sizeof( pGCtable->fptHeader.reserved2 ) ); j = ( pGCtable->usItems > pGCtable->usMaxItem ) ? pGCtable->usItems - pGCtable->usMaxItem : 0; for( i = j ; i < pGCtable->usItems; i++ ) { - HB_PUT_LE_USHORT( &pGCtable->fptHeader.reserved2[ ( i - j ) * 6 ], + HB_PUT_LE_UINT16( &pGCtable->fptHeader.reserved2[ ( i - j ) * 6 ], (( USHORT ) pGCtable->pGCitems[i].ulSize ) ); - HB_PUT_LE_ULONG( &pGCtable->fptHeader.reserved2[ ( i - j ) * 6 + 2 ], + HB_PUT_LE_UINT32( &pGCtable->fptHeader.reserved2[ ( i - j ) * 6 + 2 ], pGCtable->pGCitems[i].ulOffset ); } } @@ -827,18 +904,18 @@ static ERRCODE hb_fptWriteGCdata( FPTAREAP pArea, LPMEMOGCTABLE pGCtable ) FPTBLOCK fptBlock; BYTE *bPageBuf; - HB_PUT_BE_ULONG( fptBlock.type, FPTIT_FLEX_GC ); - HB_PUT_BE_ULONG( fptBlock.size, pGCtable->ulSize ); + HB_PUT_BE_UINT32( fptBlock.type, FPTIT_FLEX_GC ); + HB_PUT_BE_UINT32( fptBlock.size, pGCtable->ulSize ); bPageBuf = ( BYTE * ) hb_xgrab( pGCtable->ulSize ); memset( bPageBuf, 0xAD, pGCtable->ulSize ); - HB_PUT_LE_USHORT( bPageBuf, ( (USHORT) pGCtable->usItems << 2 ) + 3 ); + HB_PUT_LE_UINT16( bPageBuf, ( (USHORT) pGCtable->usItems << 2 ) + 3 ); j = ( pGCtable->usItems > pGCtable->usMaxItem ) ? pGCtable->usItems - pGCtable->usMaxItem : 0; for( i = j ; i < pGCtable->usItems; i++ ) { - HB_PUT_LE_ULONG( &bPageBuf[ ( i - j ) * 8 + 2 ], + HB_PUT_LE_UINT32( &bPageBuf[ ( i - j ) * 8 + 2 ], pGCtable->pGCitems[i].ulOffset * pArea->uiMemoBlockSize ); - HB_PUT_LE_ULONG( &bPageBuf[ ( i - j ) * 8 + 6 ], + HB_PUT_LE_UINT32( &bPageBuf[ ( i - j ) * 8 + 6 ], pGCtable->pGCitems[i].ulSize * pArea->uiMemoBlockSize ); } hb_fsSeek( pArea->hMemoFile, pGCtable->ulDirPage, FS_SET ); @@ -853,9 +930,9 @@ static ERRCODE hb_fptWriteGCdata( FPTAREAP pArea, LPMEMOGCTABLE pGCtable ) { for( i = j; i < pGCtable->usItems; i++ ) { - HB_PUT_LE_ULONG( &bPageBuf[ ( i - j ) * 8 + 2 ], + HB_PUT_LE_UINT32( &bPageBuf[ ( i - j ) * 8 + 2 ], ( ( USHORT ) pGCtable->pGCitems[i].ulSize * pArea->uiMemoBlockSize ) ); - HB_PUT_LE_ULONG( &bPageBuf[ ( i - j ) * 8 + 6 ], + HB_PUT_LE_UINT32( &bPageBuf[ ( i - j ) * 8 + 6 ], pGCtable->pGCitems[i].ulOffset * pArea->uiMemoBlockSize ); } hb_fsSeek( pArea->hMemoFile, pGCtable->ulRevPage, FS_SET ); @@ -869,9 +946,9 @@ static ERRCODE hb_fptWriteGCdata( FPTAREAP pArea, LPMEMOGCTABLE pGCtable ) } hb_xfree( bPageBuf ); } - HB_PUT_LE_ULONG( pGCtable->fptHeader.flexRev, pGCtable->ulRevPage ); - HB_PUT_LE_ULONG( pGCtable->fptHeader.flexDir, pGCtable->ulDirPage ); - HB_PUT_LE_ULONG( pGCtable->fptHeader.counter, pGCtable->ulCounter ); + HB_PUT_LE_UINT32( pGCtable->fptHeader.flexRev, pGCtable->ulRevPage ); + HB_PUT_LE_UINT32( pGCtable->fptHeader.flexDir, pGCtable->ulDirPage ); + HB_PUT_LE_UINT32( pGCtable->fptHeader.counter, pGCtable->ulCounter ); } if ( pGCtable->bChanged > 1 && errCode == SUCCESS ) @@ -880,7 +957,7 @@ static ERRCODE hb_fptWriteGCdata( FPTAREAP pArea, LPMEMOGCTABLE pGCtable ) } if ( errCode == SUCCESS ) { - HB_PUT_BE_ULONG( pGCtable->fptHeader.nextBlock, pGCtable->ulNextBlock ); + HB_PUT_BE_UINT32( pGCtable->fptHeader.nextBlock, pGCtable->ulNextBlock ); hb_fsSeek( pArea->hMemoFile, 0, FS_SET ); if ( hb_fsWrite( pArea->hMemoFile, ( BYTE * ) &pGCtable->fptHeader, ( USHORT )ulHdrSize ) != ( USHORT ) ulHdrSize ) { @@ -893,6 +970,7 @@ static ERRCODE hb_fptWriteGCdata( FPTAREAP pArea, LPMEMOGCTABLE pGCtable ) hb_fsWrite( pArea->hMemoFile, NULL, 0 ); } } + pArea->fMemoFlush = TRUE; pGCtable->bChanged = 0; } return errCode; @@ -919,7 +997,78 @@ static ULONG hb_fptGetMemoLen( FPTAREAP pArea, USHORT uiIndex ) sizeof( FPTBLOCK ) ) != sizeof( FPTBLOCK ) ) return 0; - return HB_GET_BE_ULONG( fptBlock.size ); + return HB_GET_BE_UINT32( fptBlock.size ); +} + +/* + * Return the type of memo. + */ +static char * hb_fptGetMemoType( FPTAREAP pArea, USHORT uiIndex ) +{ + ULONG ulBlock, ulType; + FPTBLOCK fptBlock; + + HB_TRACE(HB_TR_DEBUG, ("hb_fptGetMemoLen(%p, %hu)", pArea, uiIndex)); + + ulBlock = hb_dbfGetMemoBlock( (DBFAREAP) pArea, uiIndex ); + + if( ulBlock == 0 ) + return "C"; + + hb_fsSeek( pArea->hMemoFile, ulBlock * pArea->uiMemoBlockSize, FS_SET ); + + if( hb_fsRead( pArea->hMemoFile, ( BYTE * ) &fptBlock, + sizeof( FPTBLOCK ) ) != sizeof( FPTBLOCK ) ) + return "U"; + + ulType = HB_GET_BE_UINT32( fptBlock.type ); + + switch ( ulType ) + { + case FPTIT_SIX_LNUM: + case FPTIT_SIX_DNUM: + return "N"; + case FPTIT_SIX_LDATE: + return "D"; + case FPTIT_SIX_LOG: + return "L"; + case FPTIT_SIX_CHAR: + return "M"; + case FPTIT_SIX_ARRAY: + return "A"; +// case FPTIT_SIX_BLOCK: +// case FPTIT_SIX_VREF: +// case FPTIT_SIX_MREF: + + case FPTIT_FLEX_ARRAY: + case FPTIT_FLEX_VOARR: + return "A"; + case FPTIT_FLEX_OBJECT: + case FPTIT_FLEX_VOOBJ: + return "O"; + case FPTIT_FLEX_NIL: + return "U"; + case FPTIT_FLEX_TRUE: + case FPTIT_FLEX_FALSE: + return "L"; + case FPTIT_FLEX_LDATE: + return "D"; + case FPTIT_FLEX_CHAR: + case FPTIT_FLEX_UCHAR: + case FPTIT_FLEX_SHORT: + case FPTIT_FLEX_USHORT: + case FPTIT_FLEX_LONG: + case FPTIT_FLEX_ULONG: + case FPTIT_FLEX_DOUBLE: + case FPTIT_FLEX_LDOUBLE: + return "N"; + case FPTIT_TEXT: + return "M"; + case FPTIT_PICT: + case FPTIT_FLEX_COMPCH: + return "C"; + } + return "U"; } /* @@ -935,21 +1084,21 @@ static ERRCODE hb_fptReadSixItem( FPTAREAP pArea, BYTE ** pbMemoBuf, BYTE * bBuf ulLen = SIX_ITEM_BUFSIZE; if ( bBufEnd - (*pbMemoBuf) >= ( LONG ) ulLen ) { - usType = HB_GET_LE_USHORT( &(*pbMemoBuf)[0] ); + usType = HB_GET_LE_UINT16( &(*pbMemoBuf)[0] ); switch ( usType ) { case FPTIT_SIX_LNUM: - hb_itemPutNL( pItem, ( LONG ) HB_GET_LE_ULONG( &(*pbMemoBuf)[6] ) ); + hb_itemPutNL( pItem, ( LONG ) HB_GET_LE_UINT32( &(*pbMemoBuf)[6] ) ); break; case FPTIT_SIX_DNUM: hb_itemPutNDLen( pItem, HB_GET_LE_DOUBLE( &(*pbMemoBuf)[6] ), - HB_GET_LE_USHORT( &(*pbMemoBuf)[2] ), - HB_GET_LE_USHORT( &(*pbMemoBuf)[4] ) ); + HB_GET_LE_UINT16( &(*pbMemoBuf)[2] ), + HB_GET_LE_UINT16( &(*pbMemoBuf)[4] ) ); break; case FPTIT_SIX_LDATE: - hb_itemPutDL( pItem, ( LONG ) HB_GET_LE_ULONG( &(*pbMemoBuf)[6] ) ); + hb_itemPutDL( pItem, ( LONG ) HB_GET_LE_UINT32( &(*pbMemoBuf)[6] ) ); break; case FPTIT_SIX_LOG: @@ -957,7 +1106,7 @@ static ERRCODE hb_fptReadSixItem( FPTAREAP pArea, BYTE ** pbMemoBuf, BYTE * bBuf break; case FPTIT_SIX_CHAR: - ulLen = HB_GET_LE_ULONG( &(*pbMemoBuf)[2] ); + ulLen = HB_GET_LE_UINT32( &(*pbMemoBuf)[2] ); if ( pArea->bMemoType == MEMO_FPT_SIX ) { ulLen &= 0xFFFF; /* only 2 bytes (SHORT) for SIX compatibility */ @@ -976,12 +1125,12 @@ static ERRCODE hb_fptReadSixItem( FPTAREAP pArea, BYTE ** pbMemoBuf, BYTE * bBuf } break; -/* case FPTIT_SIX_BLOCK: */ -/* case FPTIT_SIX_VREF: */ -/* case FPTIT_SIX_MREF: */ +// case FPTIT_SIX_BLOCK: +// case FPTIT_SIX_VREF: +// case FPTIT_SIX_MREF: case FPTIT_SIX_ARRAY: - ulLen = HB_GET_LE_ULONG( &(*pbMemoBuf)[2] ); + ulLen = HB_GET_LE_UINT32( &(*pbMemoBuf)[2] ); if ( pArea->bMemoType == MEMO_FPT_SIX ) { ulLen &= 0xFFFF; /* only 2 bytes (SHORT) for SIX compatibility */ @@ -1052,7 +1201,7 @@ static ERRCODE hb_fptReadFlexItem( FPTAREAP pArea, BYTE ** pbMemoBuf, BYTE * bBu case FPTIT_FLEXAR_DATE: if ( bBufEnd - (*pbMemoBuf) >= 4 ) { - hb_itemPutDL( pItem, (LONG) HB_GET_LE_ULONG( *pbMemoBuf ) ); + hb_itemPutDL( pItem, (LONG) HB_GET_LE_UINT32( *pbMemoBuf ) ); *pbMemoBuf += 4; } else @@ -1060,7 +1209,17 @@ static ERRCODE hb_fptReadFlexItem( FPTAREAP pArea, BYTE ** pbMemoBuf, BYTE * bBu errCode = EDBF_CORRUPT; } break; - case FPTIT_FLEXAR_BYTE1: + case FPTIT_FLEXAR_CHAR: + if ( bBufEnd - (*pbMemoBuf) >= 2 ) + { + hb_itemPutNI( pItem, (signed char) **pbMemoBuf ); + *pbMemoBuf += 2; + } + else + { + errCode = EDBF_CORRUPT; + } + break; case FPTIT_FLEXAR_BYTE: if ( bBufEnd - (*pbMemoBuf) >= 2 ) { @@ -1086,7 +1245,20 @@ static ERRCODE hb_fptReadFlexItem( FPTAREAP pArea, BYTE ** pbMemoBuf, BYTE * bBu case FPTIT_FLEXAR_SHORT: if ( bBufEnd - (*pbMemoBuf) >= 3 ) { - hb_itemPutNI( pItem, (SHORT) HB_GET_LE_USHORT( *pbMemoBuf ) ); + hb_itemPutNILen( pItem, (SHORT) HB_GET_LE_UINT16( *pbMemoBuf ), + (*pbMemoBuf)[2] ); + *pbMemoBuf += 3; + } + else + { + errCode = EDBF_CORRUPT; + } + break; + case FPTIT_FLEXAR_USHORT: + if ( bBufEnd - (*pbMemoBuf) >= 3 ) + { + hb_itemPutNIntLen( pItem, (USHORT) HB_GET_LE_UINT16( *pbMemoBuf ), + (*pbMemoBuf)[2] ); *pbMemoBuf += 3; } else @@ -1097,7 +1269,7 @@ static ERRCODE hb_fptReadFlexItem( FPTAREAP pArea, BYTE ** pbMemoBuf, BYTE * bBu case FPTIT_FLEXAR_SHORT2: if ( bBufEnd - (*pbMemoBuf) >= 4 ) { - hb_itemPutNI( pItem, (SHORT) HB_GET_LE_USHORT( *pbMemoBuf ) ); + hb_itemPutNI( pItem, (SHORT) HB_GET_LE_UINT16( *pbMemoBuf ) ); *pbMemoBuf += 4; } else @@ -1106,9 +1278,32 @@ static ERRCODE hb_fptReadFlexItem( FPTAREAP pArea, BYTE ** pbMemoBuf, BYTE * bBu } break; case FPTIT_FLEXAR_LONG: + if ( bBufEnd - (*pbMemoBuf) >= 5 ) + { + hb_itemPutNLLen( pItem, (LONG) HB_GET_LE_UINT32( *pbMemoBuf ), + (*pbMemoBuf)[4] ); + *pbMemoBuf += 5; + } + else + { + errCode = EDBF_CORRUPT; + } + break; + case FPTIT_FLEXAR_LONG2: if ( bBufEnd - (*pbMemoBuf) >= 6 ) { - hb_itemPutNL( pItem, (LONG) HB_GET_LE_ULONG( *pbMemoBuf ) ); + hb_itemPutNL( pItem, (LONG) HB_GET_LE_UINT32( *pbMemoBuf ) ); + *pbMemoBuf += 6; + } + else + { + errCode = EDBF_CORRUPT; + } + break; + case FPTIT_FLEXAR_ULONG: + if ( bBufEnd - (*pbMemoBuf) >= 6 ) + { + hb_itemPutNInt( pItem, HB_GET_LE_UINT32( *pbMemoBuf ) ); *pbMemoBuf += 6; } else @@ -1135,7 +1330,7 @@ static ERRCODE hb_fptReadFlexItem( FPTAREAP pArea, BYTE ** pbMemoBuf, BYTE * bBu case FPTIT_FLEXAR_STR: if ( bBufEnd - (*pbMemoBuf) >= 2 ) { - ulLen = HB_GET_LE_USHORT( *pbMemoBuf ); + ulLen = HB_GET_LE_UINT16( *pbMemoBuf ); *pbMemoBuf += 2; if ( bBufEnd - (*pbMemoBuf) >= ( LONG ) ulLen ) { @@ -1159,7 +1354,7 @@ static ERRCODE hb_fptReadFlexItem( FPTAREAP pArea, BYTE ** pbMemoBuf, BYTE * bBu case FPTIT_FLEXAR_ARAY: if ( bBufEnd - (*pbMemoBuf) >= 2 ) { - ulLen = HB_GET_LE_USHORT( *pbMemoBuf ); + ulLen = HB_GET_LE_UINT16( *pbMemoBuf ); *pbMemoBuf += 2; if ( bBufEnd - (*pbMemoBuf) >= ( LONG ) ulLen ) { @@ -1219,10 +1414,10 @@ static ERRCODE hb_fptGetMemo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) } else { - ulSize = HB_GET_BE_ULONG( fptBlock.size ); + ulSize = HB_GET_BE_UINT32( fptBlock.size ); } - ulType = HB_GET_BE_ULONG( fptBlock.type ); + ulType = HB_GET_BE_UINT32( fptBlock.type ); pBuffer = ( BYTE * ) hb_xgrab( HB_MAX( ulSize + 1, 8 ) ); memset( pBuffer, '\0', 8); if ( hb_fsReadLarge( pArea->hMemoFile, pBuffer, ulSize ) != ulSize ) @@ -1239,9 +1434,9 @@ static ERRCODE hb_fptGetMemo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) case FPTIT_SIX_LOG: case FPTIT_SIX_CHAR: case FPTIT_SIX_ARRAY: -/* case FPTIT_SIX_BLOCK: */ -/* case FPTIT_SIX_VREF: */ -/* case FPTIT_SIX_MREF: */ +// case FPTIT_SIX_BLOCK: +// case FPTIT_SIX_VREF: +// case FPTIT_SIX_MREF: bMemoBuf = pBuffer; errCode = hb_fptReadSixItem( pArea, &bMemoBuf, bMemoBuf + ulSize, pItem ); break; @@ -1259,16 +1454,25 @@ static ERRCODE hb_fptGetMemo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) hb_itemPutL( pItem, FALSE ); break; case FPTIT_FLEX_LDATE: - hb_itemPutDL( pItem, (LONG) HB_GET_LE_ULONG( pBuffer ) ); + hb_itemPutDL( pItem, (LONG) HB_GET_LE_UINT32( pBuffer ) ); break; - case FPTIT_FLEX_BYTE: - hb_itemPutNI( pItem, pBuffer[0] ); + case FPTIT_FLEX_CHAR: + hb_itemPutNI( pItem, (signed char) pBuffer[0] ); + break; + case FPTIT_FLEX_UCHAR: + hb_itemPutNI( pItem, (BYTE) pBuffer[0] ); break; case FPTIT_FLEX_SHORT: - hb_itemPutNI( pItem, (SHORT) HB_GET_LE_USHORT( pBuffer ) ); + hb_itemPutNI( pItem, (SHORT) HB_GET_LE_UINT16( pBuffer ) ); + break; + case FPTIT_FLEX_USHORT: + hb_itemPutNInt( pItem, HB_GET_LE_UINT16( pBuffer ) ); break; case FPTIT_FLEX_LONG: - hb_itemPutNL( pItem, (LONG) HB_GET_LE_ULONG( pBuffer ) ); + hb_itemPutNL( pItem, (LONG) HB_GET_LE_UINT32( pBuffer ) ); + break; + case FPTIT_FLEX_ULONG: + hb_itemPutNInt( pItem, HB_GET_LE_UINT32( pBuffer ) ); break; case FPTIT_FLEX_DOUBLE: hb_itemPutND( pItem, HB_GET_LE_DOUBLE( pBuffer ) ); @@ -1277,12 +1481,16 @@ static ERRCODE hb_fptGetMemo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) #ifndef HB_CDP_SUPPORT_OFF hb_cdpnTranslate( ( char *) pBuffer, pArea->cdPage, hb_cdp_page, ulSize ); #endif - case FPTIT_PICT: pBuffer[ ulSize ] = '\0'; hb_itemPutCPtr( pItem, ( char * ) pBuffer, ulSize ); hb_itemSetCMemo( pItem ); pBuffer = NULL; break; + case FPTIT_PICT: + pBuffer[ ulSize ] = '\0'; + hb_itemPutCPtr( pItem, ( char * ) pBuffer, ulSize ); + pBuffer = NULL; + break; default: hb_itemClear( pItem ); break; @@ -1310,7 +1518,7 @@ static ULONG hb_fptCountSixItemLength( FPTAREAP pArea, PHB_ITEM pItem ) usType = hb_itemType( pItem ); switch ( usType ) { - case HB_IT_ARRAY: /* HB_IT_OBJECT = HB_IT_ARRAY */ + case HB_IT_ARRAY: // HB_IT_OBJECT = HB_IT_ARRAY ulSize = SIX_ITEM_BUFSIZE; ulLen = hb_arrayLen( pItem ); if ( pArea->bMemoType == MEMO_FPT_SIX ) @@ -1334,6 +1542,9 @@ static ULONG hb_fptCountSixItemLength( FPTAREAP pArea, PHB_ITEM pItem ) break; case HB_IT_INTEGER: case HB_IT_LONG: +#ifdef HB_IT_LONGLONG + case HB_IT_LONGLONG: +#endif case HB_IT_DOUBLE: case HB_IT_DATE: case HB_IT_LOGICAL: @@ -1350,6 +1561,8 @@ static ULONG hb_fptStoreSixItem( FPTAREAP pArea, PHB_ITEM pItem, BYTE ** bBufPtr { USHORT usType; ULONG ulLen, i, ulSize; + HB_LONG iVal; + int iWidth, iDec; PHB_ITEM pTmpItem; memset( *bBufPtr, '\0', SIX_ITEM_BUFSIZE ); @@ -1357,14 +1570,14 @@ static ULONG hb_fptStoreSixItem( FPTAREAP pArea, PHB_ITEM pItem, BYTE ** bBufPtr ulSize = SIX_ITEM_BUFSIZE; switch ( usType ) { - case HB_IT_ARRAY: /* HB_IT_OBJECT = HB_IT_ARRAY */ - HB_PUT_LE_USHORT( &(*bBufPtr)[0], FPTIT_SIX_ARRAY ); + case HB_IT_ARRAY: // HB_IT_OBJECT = HB_IT_ARRAY + HB_PUT_LE_UINT16( &(*bBufPtr)[0], FPTIT_SIX_ARRAY ); ulLen = hb_arrayLen( pItem ); if ( pArea->bMemoType == MEMO_FPT_SIX ) { ulLen &= 0xFFFF; /* only 2 bytes (SHORT) for SIX compatibility */ } - HB_PUT_LE_ULONG( &(*bBufPtr)[2], ulLen ); + HB_PUT_LE_UINT32( &(*bBufPtr)[2], ulLen ); *bBufPtr += SIX_ITEM_BUFSIZE; for ( i = 1 ; i <= ulLen ; i++ ) { @@ -1374,54 +1587,64 @@ static ULONG hb_fptStoreSixItem( FPTAREAP pArea, PHB_ITEM pItem, BYTE ** bBufPtr break; case HB_IT_INTEGER: - HB_PUT_LE_USHORT( &(*bBufPtr)[0], FPTIT_SIX_LNUM ); - HB_PUT_LE_USHORT( &(*bBufPtr)[2], pItem->item.asInteger.length ); - HB_PUT_LE_ULONG( &(*bBufPtr)[6], pItem->item.asInteger.value ); - *bBufPtr += SIX_ITEM_BUFSIZE; - break; - case HB_IT_LONG: - HB_PUT_LE_USHORT( &(*bBufPtr)[0], FPTIT_SIX_LNUM ); - HB_PUT_LE_USHORT( &(*bBufPtr)[2], pItem->item.asLong.length ); - HB_PUT_LE_ULONG( &(*bBufPtr)[6], pItem->item.asLong.value ); - *bBufPtr += SIX_ITEM_BUFSIZE; +#ifdef HB_IT_LONGLONG + case HB_IT_LONGLONG: +#endif + iVal = hb_itemGetNL( pItem ); + hb_itemGetNLen( pItem, &iWidth, &iDec ); + if ( HB_LIM_INT32( iVal ) ) + { + HB_PUT_LE_UINT16( &(*bBufPtr)[0], FPTIT_SIX_LNUM ); + HB_PUT_LE_UINT16( &(*bBufPtr)[2], iWidth ); + HB_PUT_LE_UINT32( &(*bBufPtr)[6], iVal ); + *bBufPtr += SIX_ITEM_BUFSIZE; + } + else + { + HB_PUT_LE_UINT16( &(*bBufPtr)[0], FPTIT_SIX_DNUM ); + HB_PUT_LE_UINT16( &(*bBufPtr)[2], iWidth ); + HB_PUT_LE_UINT16( &(*bBufPtr)[4], iDec ); + HB_PUT_LE_DOUBLE( &(*bBufPtr)[6], ( double ) iVal ); + *bBufPtr += SIX_ITEM_BUFSIZE; + } break; case HB_IT_DOUBLE: - HB_PUT_LE_USHORT( &(*bBufPtr)[0], FPTIT_SIX_DNUM ); - HB_PUT_LE_USHORT( &(*bBufPtr)[2], pItem->item.asDouble.length ); - HB_PUT_LE_USHORT( &(*bBufPtr)[4], pItem->item.asDouble.decimal ); + HB_PUT_LE_UINT16( &(*bBufPtr)[0], FPTIT_SIX_DNUM ); + HB_PUT_LE_UINT16( &(*bBufPtr)[2], pItem->item.asDouble.length ); + HB_PUT_LE_UINT16( &(*bBufPtr)[4], pItem->item.asDouble.decimal ); HB_PUT_LE_DOUBLE( &(*bBufPtr)[6], pItem->item.asDouble.value ); *bBufPtr += SIX_ITEM_BUFSIZE; break; case HB_IT_DATE: - HB_PUT_LE_USHORT( &(*bBufPtr)[0], FPTIT_SIX_LDATE ); - HB_PUT_LE_ULONG( &(*bBufPtr)[6], pItem->item.asDate.value ); + HB_PUT_LE_UINT16( &(*bBufPtr)[0], FPTIT_SIX_LDATE ); + HB_PUT_LE_UINT32( &(*bBufPtr)[6], pItem->item.asDate.value ); *bBufPtr += SIX_ITEM_BUFSIZE; break; case HB_IT_LOGICAL: - HB_PUT_LE_USHORT( &(*bBufPtr)[0], FPTIT_SIX_LOG ); + HB_PUT_LE_UINT16( &(*bBufPtr)[0], FPTIT_SIX_LOG ); *(BOOL*) ( &(*bBufPtr)[6] ) = pItem->item.asLogical.value; *bBufPtr += SIX_ITEM_BUFSIZE; break; case HB_IT_STRING: case HB_IT_MEMO: - HB_PUT_LE_USHORT( &(*bBufPtr)[0], FPTIT_SIX_CHAR ); + HB_PUT_LE_UINT16( &(*bBufPtr)[0], FPTIT_SIX_CHAR ); ulLen = pItem->item.asString.length; if ( pArea->bMemoType == MEMO_FPT_SIX ) { ulLen &= 0xFFFF; /* only 2 bytes (SHORT) for SIX compatibility */ } - HB_PUT_LE_ULONG( &(*bBufPtr)[2], ulLen ); + HB_PUT_LE_UINT32( &(*bBufPtr)[2], ulLen ); *bBufPtr += SIX_ITEM_BUFSIZE; if ( ulLen > 0 ) { memcpy( *bBufPtr, pItem->item.asString.value, ulLen ); #ifndef HB_CDP_SUPPORT_OFF - hb_cdpnTranslate( ( char *) *bBufPtr, pArea->cdPage, hb_cdp_page, ulLen ); + hb_cdpnTranslate( ( char *) *bBufPtr, hb_cdp_page, pArea->cdPage, ulLen ); #endif *bBufPtr += ulLen; } @@ -1440,6 +1663,7 @@ static ULONG hb_fptCountFlexItemLength( FPTAREAP pArea, PHB_ITEM pItem ) { ULONG ulLen, i, ulSize = 1; USHORT usType; + HB_LONG iVal; usType = hb_itemType( pItem ); switch ( usType ) @@ -1461,10 +1685,14 @@ static ULONG hb_fptCountFlexItemLength( FPTAREAP pArea, PHB_ITEM pItem ) ulSize += 4; break; case HB_IT_INTEGER: - ulSize += 3; - break; case HB_IT_LONG: - ulSize += 6; +#ifdef HB_IT_LONGLONG + case HB_IT_LONGLONG: +#endif + iVal = hb_itemGetNL( pItem ); + ulSize += ( HB_LIM_INT8( iVal ) ? 2 : + ( HB_LIM_INT16( iVal ) ? 3 : + ( HB_LIM_INT32( iVal ) ? 6 : 10 ) ) ); break; case HB_IT_DOUBLE: ulSize += 10; @@ -1480,6 +1708,7 @@ static void hb_fptStoreFlexItem( FPTAREAP pArea, PHB_ITEM pItem, BYTE ** bBufPtr { ULONG ulLen, i; USHORT usType; + HB_LONG iVal; usType = hb_itemType( pItem ); switch ( usType ) @@ -1487,7 +1716,7 @@ static void hb_fptStoreFlexItem( FPTAREAP pArea, PHB_ITEM pItem, BYTE ** bBufPtr case HB_IT_ARRAY: ulLen = hb_arrayLen( pItem ) & 0xFFFF; *(*bBufPtr)++ = FPTIT_FLEXAR_ARAY; - HB_PUT_LE_USHORT( *bBufPtr, ( USHORT ) ulLen ); + HB_PUT_LE_UINT16( *bBufPtr, ( USHORT ) ulLen ); *bBufPtr += 2; for ( i = 1 ; i <= ulLen ; i++ ) { @@ -1498,31 +1727,54 @@ static void hb_fptStoreFlexItem( FPTAREAP pArea, PHB_ITEM pItem, BYTE ** bBufPtr case HB_IT_STRING: *(*bBufPtr)++ = FPTIT_FLEXAR_STR; ulLen = pItem->item.asString.length & 0xFFFF; - HB_PUT_LE_USHORT( *bBufPtr, ( USHORT ) ulLen ); + HB_PUT_LE_UINT16( *bBufPtr, ( USHORT ) ulLen ); *bBufPtr += 2; memcpy( *bBufPtr, pItem->item.asString.value, ulLen ); #ifndef HB_CDP_SUPPORT_OFF - hb_cdpnTranslate( ( char *) *bBufPtr, pArea->cdPage, hb_cdp_page, ulLen ); + hb_cdpnTranslate( ( char *) *bBufPtr, hb_cdp_page, pArea->cdPage, ulLen ); #endif *bBufPtr += ulLen; break; case HB_IT_DATE: *(*bBufPtr)++ = FPTIT_FLEXAR_DATE; - HB_PUT_LE_ULONG( *bBufPtr, pItem->item.asDate.value ); + HB_PUT_LE_UINT32( *bBufPtr, pItem->item.asDate.value ); *bBufPtr += 4; break; case HB_IT_INTEGER: - *(*bBufPtr)++ = FPTIT_FLEXAR_SHORT; - HB_PUT_LE_USHORT( *bBufPtr, pItem->item.asInteger.value ); - *bBufPtr += 2; - *(*bBufPtr)++ = '\0'; - break; case HB_IT_LONG: - *(*bBufPtr)++ = FPTIT_FLEXAR_LONG; - HB_PUT_LE_ULONG( *bBufPtr, pItem->item.asLong.value ); - *bBufPtr += 4; - *(*bBufPtr)++ = '\0'; - *(*bBufPtr)++ = '\0'; +#ifdef HB_IT_LONGLONG + case HB_IT_LONGLONG: +#endif + iVal = hb_itemGetNL( pItem ); + if ( HB_LIM_INT8( iVal ) ) + { + *(*bBufPtr)++ = FPTIT_FLEXAR_CHAR; + *(*bBufPtr)++ = (BYTE) iVal; + *(*bBufPtr)++ = '\0'; + } + else if ( HB_LIM_INT16( iVal ) ) + { + *(*bBufPtr)++ = FPTIT_FLEXAR_SHORT; + HB_PUT_LE_UINT16( *bBufPtr, iVal ); + *bBufPtr += 2; + *(*bBufPtr)++ = '\0'; + } + else if ( HB_LIM_INT32( iVal ) ) + { + *(*bBufPtr)++ = FPTIT_FLEXAR_LONG; + HB_PUT_LE_UINT32( *bBufPtr, iVal ); + *bBufPtr += 4; + *(*bBufPtr)++ = '\0'; + *(*bBufPtr)++ = '\0'; + } + else + { + *(*bBufPtr)++ = FPTIT_FLEXAR_DBL; + *(*bBufPtr)++ = 20; + *(*bBufPtr)++ = '\0'; + HB_PUT_LE_DOUBLE( *bBufPtr, (double) iVal ); + *bBufPtr += 8; + } break; case HB_IT_DOUBLE: *(*bBufPtr)++ = FPTIT_FLEXAR_DBL; @@ -1591,8 +1843,8 @@ static ERRCODE hb_fptWriteMemo( FPTAREAP pArea, ULONG ulBlock, BYTE *bBufPtr, return errCode; } - HB_PUT_BE_ULONG( fptBlock.type, ulType ); - HB_PUT_BE_ULONG( fptBlock.size, ulLen ); + HB_PUT_BE_UINT32( fptBlock.type, ulType ); + HB_PUT_BE_UINT32( fptBlock.size, ulLen ); hb_fsSeek( pArea->hMemoFile, *ulStoredBlock * pArea->uiMemoBlockSize, FS_SET ); hb_fsWrite( pArea->hMemoFile, ( BYTE * ) &fptBlock, sizeof( FPTBLOCK ) ); @@ -1616,6 +1868,7 @@ static ERRCODE hb_fptWriteMemo( FPTAREAP pArea, ULONG ulBlock, BYTE *bBufPtr, pArea->uiMemoBlockSize - 1, FS_SET ); hb_fsWrite( pArea->hMemoFile, ( BYTE * ) "\xAF", 1 ); } + pArea->fMemoFlush = TRUE; } else { @@ -1638,8 +1891,9 @@ static ERRCODE hb_fptPutMemo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) { ULONG ulLen, ulBlock, ulType; BYTE itmBuffer[FLEX_ITEM_BUFSIZE]; - BYTE *bBufPtr = NULL, *bBufAlloc = NULL; + BYTE *bBufPtr = NULL, *bBufAlloc = NULL; ERRCODE errCode; + HB_LONG iVal; HB_TRACE(HB_TR_DEBUG, ("hb_fptPutMemo(%p, %hu, %p)", pArea, uiIndex, pItem)); @@ -1667,7 +1921,7 @@ static ERRCODE hb_fptPutMemo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) { bBufPtr = bBufAlloc = ( BYTE * ) hb_xgrab( ulLen ); hb_fptStoreSixItem( pArea, pItem, &bBufPtr ); - ulType = ( ULONG ) HB_GET_LE_USHORT( bBufAlloc ); + ulType = ( ULONG ) HB_GET_LE_UINT16( bBufAlloc ); bBufPtr = bBufAlloc; } } @@ -1698,20 +1952,44 @@ static ERRCODE hb_fptPutMemo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) case HB_IT_DATE: ulType = FPTIT_FLEX_LDATE; ulLen = 4; - HB_PUT_LE_ULONG( itmBuffer, pItem->item.asDate.value ); + HB_PUT_LE_UINT32( itmBuffer, pItem->item.asDate.value ); bBufPtr = itmBuffer; break; case HB_IT_INTEGER: - ulType = FPTIT_FLEX_SHORT; - ulLen = 2; - HB_PUT_LE_USHORT( itmBuffer, pItem->item.asInteger.value ); - bBufPtr = itmBuffer; - break; case HB_IT_LONG: - ulType = FPTIT_FLEX_LONG; - ulLen = 4; - HB_PUT_LE_ULONG( itmBuffer, pItem->item.asLong.value ); - bBufPtr = itmBuffer; +#ifdef HB_IT_LONGLONG + case HB_IT_LONGLONG: +#endif + iVal = hb_itemGetNL( pItem ); + if ( HB_LIM_INT8( iVal ) ) + { + ulType = FPTIT_FLEX_CHAR; + ulLen = 1; + *itmBuffer = ( BYTE ) iVal; + bBufPtr = itmBuffer; + } + else if ( HB_LIM_INT16( iVal ) ) + { + ulType = FPTIT_FLEX_SHORT; + ulLen = 2; + HB_PUT_LE_UINT16( itmBuffer, iVal ); + bBufPtr = itmBuffer; + } + else if ( HB_LIM_INT32( iVal ) ) + { + ulType = FPTIT_FLEX_LONG; + ulLen = 4; + HB_PUT_LE_UINT32( itmBuffer, iVal ); + bBufPtr = itmBuffer; + } + else + { + double d = (double) iVal; + ulType = FPTIT_FLEX_DOUBLE; + ulLen = 8; + HB_PUT_LE_DOUBLE( itmBuffer, d ); + bBufPtr = itmBuffer; + } break; case HB_IT_DOUBLE: ulType = FPTIT_FLEX_DOUBLE; @@ -1719,7 +1997,7 @@ static ERRCODE hb_fptPutMemo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) HB_PUT_LE_DOUBLE( itmBuffer, pItem->item.asDouble.value ); bBufPtr = itmBuffer; break; - default : + default: ulType = FPTIT_BINARY; ulLen = 0; break; @@ -1748,75 +2026,6 @@ static ERRCODE hb_fptPutMemo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) /* FPT METHODS */ -/* - * Obtain the length of a field value. - * ( DBENTRYP_SVL ) hb_fptGetVarLen - */ -static ERRCODE hb_fptGetVarLen( FPTAREAP pArea, USHORT uiIndex, ULONG * pLength ) -{ - BOOL bDeleted; - - HB_TRACE(HB_TR_DEBUG, ("hb_fptGetVarLen(%p, %hu, %p)", pArea, uiIndex, pLength)); - - /* Force read record */ - if( SELF_DELETED( ( AREAP ) pArea, &bDeleted ) == FAILURE ) - return FAILURE; - - if( pArea->fHasMemo && pArea->hMemoFile != FS_ERROR && - pArea->lpFields[ uiIndex - 1 ].uiType == HB_IT_MEMO ) - { - if( hb_fptFileLockSh( pArea ) ) - { - * pLength = hb_fptGetMemoLen( pArea, uiIndex - 1 ); - hb_fptFileUnLock( pArea ); - } - else - { - * pLength = 0; - } - return SUCCESS; - } - - return SUPER_GETVARLEN( ( AREAP ) pArea, uiIndex, pLength ); -} - -/* - * Retrieve information about the current driver. - * ( DBENTRYP_SI ) hb_fptInfo - */ -static ERRCODE hb_fptInfo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_fptInfo(%p, %hu, %p)", pArea, uiIndex, pItem)); - - switch( uiIndex ) - { - case DBI_MEMOEXT: - if ( pArea->fHasMemo && pArea->hMemoFile != FS_ERROR ) - { - PHB_FNAME pFileName; - - pFileName = hb_fsFNameSplit( ( char * ) pArea->szMemoFileName ); - hb_itemPutC( pItem, pFileName->szExtension ); - hb_xfree( pFileName ); - } - else - { - hb_itemPutC( pItem, ( hb_set.HB_SET_MFILEEXT && - strlen( hb_set.HB_SET_MFILEEXT ) > 0 ) ? - hb_set.HB_SET_MFILEEXT : - FPT_MEMOEXT ); - } - break; - - /* case DBI_RDD_VERSION */ - - default: - return SUPER_INFO( ( AREAP ) pArea, uiIndex, pItem ); - } - - return SUCCESS; -} - /* * Open a data store in the WorkArea. * ( DBENTRYP_VP ) hb_fptOpen : NULL @@ -1848,32 +2057,122 @@ static ERRCODE hb_fptSysName( FPTAREAP pArea, BYTE * pBuffer ) return SUCCESS; } +/* + * Obtain the length of a field value. + * ( DBENTRYP_SVL ) hb_fptGetVarLen + */ +static ERRCODE hb_fptGetVarLen( FPTAREAP pArea, USHORT uiIndex, ULONG * pLength ) +{ + + HB_TRACE(HB_TR_DEBUG, ("hb_fptGetVarLen(%p, %hu, %p)", pArea, uiIndex, pLength)); + + if( pArea->fHasMemo && pArea->hMemoFile != FS_ERROR && + pArea->lpFields[ uiIndex - 1 ].uiType == HB_IT_MEMO ) + { + ERRCODE uiError = SUCCESS; + BOOL bLocked, bDeleted; +#if defined( HB_FPT_USE_READLOCK ) + ULONG ulOffset; +#endif + + if ( hb_fptIsDbLocked( pArea, &bLocked ) == FAILURE ) + return FAILURE; + +#if defined( HB_FPT_USE_READLOCK ) + if ( SELF_DELETED( ( AREAP ) pArea, &bDeleted ) == FAILURE ) + return FAILURE; + + if ( bLocked || hb_fptReadLock( pArea, uiIndex, &ulOffset ) ) +#else + if ( bLocked || hb_fptFileLockSh( pArea, TRUE ) ) +#endif + { +#ifdef HB_FPT_SAFE + /* Force read record? */ + if ( !bLocked ) + pArea->fValidBuffer = FALSE; + + /* update any pending relations and reread record if necessary */ + uiError = SELF_DELETED( ( AREAP ) pArea, &bDeleted ); + if ( uiError == SUCCESS ) +#endif + *pLength = hb_fptGetMemoLen( pArea, uiIndex - 1 ); + + if ( !bLocked ) + { +#if defined( HB_FPT_USE_READLOCK ) + hb_fptReadUnLock( pArea, ulOffset ) ; +#else + hb_fptFileUnLock( pArea ); +#endif + } + } + else + { + *pLength = 0; + uiError = FAILURE; + } + return uiError; + } + + return SUPER_GETVARLEN( ( AREAP ) pArea, uiIndex, pLength ); +} + /* * Obtain the current value of a field. * ( DBENTRYP_SI ) hb_fptGetValue */ static ERRCODE hb_fptGetValue( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) { - BOOL bDeleted; - ERRCODE uiError; HB_TRACE(HB_TR_DEBUG, ("hb_fptGetValue(%p, %hu, %p)", pArea, uiIndex, pItem)); if( pArea->fHasMemo && pArea->hMemoFile != FS_ERROR && pArea->lpFields[ uiIndex - 1 ].uiType == HB_IT_MEMO ) { - /* Force read record */ - if( SELF_DELETED( ( AREAP ) pArea, &bDeleted ) == FAILURE ) + ERRCODE uiError; + BOOL bLocked, bDeleted; +#if defined( HB_FPT_USE_READLOCK ) + ULONG ulOffset; +#endif + + if ( hb_fptIsDbLocked( pArea, &bLocked ) == FAILURE ) return FAILURE; - if( hb_fptFileLockSh( pArea ) ) + +#if defined( HB_FPT_USE_READLOCK ) + if ( SELF_DELETED( ( AREAP ) pArea, &bDeleted ) == FAILURE ) + return FAILURE; + + if ( bLocked || hb_fptReadLock( pArea, uiIndex, &ulOffset ) ) +#else + if ( bLocked || hb_fptFileLockSh( pArea, TRUE ) ) +#endif { - uiError = hb_fptGetMemo( pArea, uiIndex - 1, pItem ); - hb_fptFileUnLock( pArea ); +#ifdef HB_FPT_SAFE + /* Force read record? */ + if ( !bLocked ) + pArea->fValidBuffer = FALSE; + /* update any pending relations and reread record if necessary */ + uiError = SELF_DELETED( ( AREAP ) pArea, &bDeleted ); + + if ( uiError == SUCCESS ) +#endif + uiError = hb_fptGetMemo( pArea, uiIndex - 1, pItem ); + + if ( !bLocked ) + { +#if defined( HB_FPT_USE_READLOCK ) + hb_fptReadUnLock( pArea, ulOffset ) ; +#else + hb_fptFileUnLock( pArea ); +#endif + } } else { uiError = EDBF_LOCK; } + if ( uiError != SUCCESS ) { PHB_ITEM pError = hb_errNew(); @@ -1907,7 +2206,7 @@ static ERRCODE hb_fptPutValue( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) if( pArea->fHasMemo && pArea->hMemoFile != FS_ERROR && pArea->lpFields[ uiIndex - 1 ].uiType == HB_IT_MEMO ) { - /* Force read record */ + /* update any pending relations and reread record if necessary */ if( SELF_DELETED( ( AREAP ) pArea, &bDeleted ) == FAILURE ) return FAILURE; @@ -1918,17 +2217,21 @@ static ERRCODE hb_fptPutValue( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) if( !pArea->fRecordChanged && SELF_GOHOT( ( AREAP ) pArea ) == FAILURE ) return FAILURE; - if( hb_fptFileLockEx( pArea ) ) + if( hb_fptFileLockEx( pArea, TRUE ) ) { uiError = hb_fptPutMemo( pArea, uiIndex -1, pItem ); +#if defined( HB_FPT_SAFE ) + if( uiError == SUCCESS ) + /* Force writer record to eliminate race condition */ + if ( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE ) + return FAILURE; +#endif hb_fptFileUnLock( pArea ); } else { uiError = EDBF_LOCK; } - /* Update deleted flag */ - pArea->pRecord[ 0 ] = (BYTE) (pArea->fDeleted ? '*' : ' '); if( uiError != SUCCESS ) { @@ -2002,11 +2305,11 @@ static ERRCODE hb_fptCreateMemFile( FPTAREAP pArea, LPDBOPENINFO pCreateInfo ) hb_set.HB_SET_MBLOCKSIZE < 0xFFFF ) ? hb_set.HB_SET_MBLOCKSIZE : FPT_DEFBLOCKSIZE; pArea->bMemoType = MEMO_FPT_HB; - /* pArea->bMemoType = MEMO_FPT_SIX; */ + //pArea->bMemoType = MEMO_FPT_SIX; ulNextBlock = ( sizeof( FPTHEADER ) + pArea->uiMemoBlockSize - 1 ) / pArea->uiMemoBlockSize; - HB_PUT_BE_ULONG( fptHeader.nextBlock, ulNextBlock ); - HB_PUT_BE_USHORT( fptHeader.blockSize, pArea->uiMemoBlockSize ); + HB_PUT_BE_UINT32( fptHeader.nextBlock, ulNextBlock ); + HB_PUT_BE_UINT16( fptHeader.blockSize, pArea->uiMemoBlockSize ); if ( pArea->bMemoType == MEMO_FPT_SIX || pArea->bMemoType == MEMO_FPT_SIXHB ) { @@ -2033,6 +2336,7 @@ static ERRCODE hb_fptCreateMemFile( FPTAREAP pArea, LPDBOPENINFO pCreateInfo ) } /* trunc file */ hb_fsWrite( pArea->hMemoFile, NULL, 0 ); + pArea->fMemoFlush = TRUE; return SUCCESS; } @@ -2088,13 +2392,13 @@ static ERRCODE hb_fptOpenMemFile( FPTAREAP pArea, LPDBOPENINFO pOpenInfo ) hb_fsSeek( pArea->hMemoFile, 0, FS_SET ); if ( hb_fsRead( pArea->hMemoFile, ( BYTE * ) &fptHeader, sizeof( FPTHEADER ) ) >= 512 ) { - pArea->uiMemoBlockSize = HB_GET_BE_USHORT( fptHeader.blockSize ); + pArea->uiMemoBlockSize = HB_GET_BE_UINT16( fptHeader.blockSize ); pArea->bMemoType = 0; /* Check for compatibility with Harbour memo headers */ if ( memcmp( fptHeader.signature1, "Harbour", 7 ) == 0 ) { /* hack for detecting old harbour FPT files without FLEX support */ - if ( HB_GET_BE_ULONG( fptHeader.signature2 ) == FPTIT_TEXT ) + if ( HB_GET_BE_UINT32( fptHeader.signature2 ) == FPTIT_TEXT ) pArea->bMemoType = MEMO_FPT_SIXHB; else pArea->bMemoType = MEMO_FPT_HB; @@ -2115,7 +2419,7 @@ static ERRCODE hb_fptOpenMemFile( FPTAREAP pArea, LPDBOPENINFO pOpenInfo ) { pArea->bMemoType = MEMO_FPT_FLEX; if ( pArea->uiMemoBlockSize == 0 ) - pArea->uiMemoBlockSize = HB_GET_LE_USHORT( fptHeader.flexSize ); + pArea->uiMemoBlockSize = HB_GET_LE_UINT16( fptHeader.flexSize ); } } @@ -2147,7 +2451,8 @@ static ERRCODE hb_fptReadDBHeader( FPTAREAP pArea ) if( SUPER_READDBHEADER( ( AREAP ) pArea ) == FAILURE ) return FAILURE; - pArea->fHasMemo = ( pArea->bVersion == 0xF5 ); +// Set in SUPER() now 3/05/2004 +// pArea->fHasMemo = ( pArea->bVersion == 0xF5 ); return SUCCESS; } @@ -2160,8 +2465,147 @@ static ERRCODE hb_fptWriteDBHeader( FPTAREAP pArea ) { HB_TRACE(HB_TR_DEBUG, ("hb_fptWriteDBHeader(%p)", pArea)); - if ( pArea->fHasMemo ) + if ( pArea->fHasMemo && pArea->bVersion != 0x30 && pArea->bVersion != 0x31 ) + { pArea->bVersion = 0xF5; - + } return SUPER_WRITEDBHEADER( ( AREAP ) pArea ); } + +/* + * Retrieve information about the current driver. + * ( DBENTRYP_SI ) hb_fptInfo + */ +static ERRCODE hb_fptInfo( FPTAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_fptInfo(%p, %hu, %p)", pArea, uiIndex, pItem)); + + switch( uiIndex ) + { + case DBI_MEMOEXT: + if ( pArea->fHasMemo && pArea->hMemoFile != FS_ERROR ) + { + PHB_FNAME pFileName; + + pFileName = hb_fsFNameSplit( ( char * ) pArea->szMemoFileName ); + hb_itemPutC( pItem, pFileName->szExtension ); + hb_xfree( pFileName ); + } + else + { + hb_itemPutC( pItem, ( hb_set.HB_SET_MFILEEXT && + strlen( hb_set.HB_SET_MFILEEXT ) > 0 ) ? + hb_set.HB_SET_MFILEEXT : + FPT_MEMOEXT ); + } + break; + + /* case DBI_RDD_VERSION */ + + case DBI_BLOB_DIRECT_EXPORT: + case DBI_BLOB_DIRECT_GET: + case DBI_BLOB_DIRECT_IMPORT: + case DBI_BLOB_DIRECT_PUT: + case DBI_BLOB_ROOT_GET: + case DBI_BLOB_ROOT_PUT: + break; + + case DBI_BLOB_ROOT_LOCK: + hb_itemPutL( pItem, hb_fptFileLockEx( pArea, FALSE ) ); + break; + + case DBI_BLOB_ROOT_UNLOCK: + hb_fptFileUnLock( pArea ); + hb_itemClear( pItem ); + break; + + case DBI_BLOB_DIRECT_LEN: + case DBI_BLOB_DIRECT_TYPE: + case DBI_BLOB_INTEGRITY: + case DBI_BLOB_OFFSET: + case DBI_BLOB_RECOVER: + /* TODO: implement it */ + break; + + default: + return SUPER_INFO( ( AREAP ) pArea, uiIndex, pItem ); + } + + return SUCCESS; +} + +/* + * Retrieve information about a field. + * ( DBENTRYP_SSI ) hb_fptFieldInfo + */ +static ERRCODE hb_fptFieldInfo( FPTAREAP pArea, USHORT uiIndex, USHORT uiType, PHB_ITEM pItem ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_fptFieldInfo(%p, %hu, %hu, %p)", pArea, uiIndex, uiType, pItem)); + + if( uiIndex > pArea->uiFieldCount ) + return FAILURE; + + if( pArea->fHasMemo && pArea->hMemoFile != FS_ERROR && + pArea->lpFields[ uiIndex - 1 ].uiType == HB_IT_MEMO ) + { + BOOL bLocked; +#if defined( HB_FPT_USE_READLOCK ) + ULONG ulOffset; +#endif + switch( uiType ) + { + case DBS_BLOB_GET: + case DBS_BLOB_LEN: + case DBS_BLOB_OFFSET: + case DBS_BLOB_POINTER: + case DBS_BLOB_TYPE: + break; + default: + return SUPER_FIELDINFO( ( AREAP ) pArea, uiIndex, uiType, pItem ); + } + + if ( hb_fptIsDbLocked( pArea, &bLocked ) == FAILURE ) + return FAILURE; + +#if defined( HB_FPT_USE_READLOCK ) + if ( bLocked || hb_fptReadLock( pArea, uiIndex, &ulOffset ) ) +#else + if ( bLocked || hb_fptFileLockSh( pArea, TRUE ) ) +#endif + { + switch( uiType ) + { + case DBS_BLOB_GET: + /* TODO: !!! pItem := { , } */ + break; + case DBS_BLOB_LEN: + hb_itemPutNL( pItem, hb_fptGetMemoLen( pArea, uiIndex - 1 ) ); + break; + case DBS_BLOB_OFFSET: + hb_itemPutNL( pItem, pArea->uiMemoBlockSize * + hb_dbfGetMemoBlock( (DBFAREAP) pArea, uiIndex - 1 ) ); + break; + case DBS_BLOB_POINTER: + hb_itemPutNL( pItem, + hb_dbfGetMemoBlock( (DBFAREAP) pArea, uiIndex - 1 ) ); + break; + case DBS_BLOB_TYPE: + hb_itemPutC( pItem, hb_fptGetMemoType( pArea, uiIndex - 1 ) ); + break; + } + if ( !bLocked ) + { +#if defined( HB_FPT_USE_READLOCK ) + hb_fptReadUnLock( pArea, ulOffset ) ; +#else + hb_fptFileUnLock( pArea ); +#endif + } + } + } + else + { + return SUPER_FIELDINFO( ( AREAP ) pArea, uiIndex, uiType, pItem ); + } + return SUCCESS; +} diff --git a/harbour/source/rdd/dbfntx/dbfntx1.c b/harbour/source/rdd/dbfntx/dbfntx1.c index 778dad0fcb..c9d187dc94 100644 --- a/harbour/source/rdd/dbfntx/dbfntx1.c +++ b/harbour/source/rdd/dbfntx/dbfntx1.c @@ -298,39 +298,28 @@ static void hb_IncString( NTXAREAP pArea, char* s, int slen ) static char * numToStr( PHB_ITEM pItem, char* szBuffer, USHORT length, USHORT dec ) { - if( HB_IS_DOUBLE( pItem ) ) + char *ptr = szBuffer; + + hb_itemStrBuf( szBuffer, pItem, length, dec ); + + while( *ptr == ' ' ) { - if( dec == 0 ) + *ptr++ = '0'; + } + + if( *ptr == '-' ) + { + *ptr = '0'; + szBuffer[0] = ','; + for( ptr = &szBuffer[1]; *ptr; ptr++ ) { - if( length > 9 ) - sprintf( szBuffer, "%0*.0f", length, - hb_numRound( hb_itemGetND( pItem ), 0 ) ); - else - sprintf( szBuffer, "%0*li", length, - ( LONG ) hb_numRound( hb_itemGetND( pItem ), 0 ) ); - } - else - sprintf( szBuffer, "%0*.*f", length, - dec, hb_numRound( hb_itemGetND( pItem ), - dec ) ); - } - else - { - if( dec == 0 ) - sprintf( szBuffer, "%0*li", length, hb_itemGetNL( pItem ) ); - else - sprintf( szBuffer, "%0*.*f", length, - dec, hb_itemGetND( pItem ) ); - } - szBuffer[ length ] = 0; - if( hb_itemGetND( pItem ) < 0 ) - { - char *ptr = szBuffer; - *ptr++ = ','; - for( ;*ptr;ptr++ ) if( *ptr >= '0' && *ptr <= '9' ) + { *ptr = (char) ( 92 - (int)*ptr ); + } + } } + return szBuffer; } @@ -856,7 +845,7 @@ static void hb_ntxGetCurrentKey( LPTAGINFO pTag, LPKEYINFO pKey ) static BOOL hb_ntxTagGoToNextKey( LPTAGINFO pTag, BOOL lContinue ) { BOOL lCurrrentKey = FALSE; - LPPAGEINFO pPage, pChildPage; + LPPAGEINFO pPage = NULL, pChildPage; LPNTXITEM p; /* pTag->blockNext = 0; pTag->keyNext = 0; */ @@ -958,7 +947,7 @@ static BOOL hb_ntxTagGoToNextKey( LPTAGINFO pTag, BOOL lContinue ) static BOOL hb_ntxTagGoToPrevKey( LPTAGINFO pTag, BOOL lContinue ) { BOOL lCurrrentKey = FALSE; - LPPAGEINFO pPage, pChildPage; + LPPAGEINFO pPage = NULL, pChildPage; /* pTag->blockPrev = 0; pTag->keyPrev = 0; */ if( pTag->CurKeyInfo->Tag && ((ULONG)pTag->CurKeyInfo->Xtra) == pTag->Owner->Owner->ulRecNo ) @@ -1356,7 +1345,7 @@ static void hb_ntxPageFree( LPTAGINFO pTag, BOOL lFull ) static LPPAGEINFO hb_ntxPageNew( LPTAGINFO pTag ) { - LPPAGEINFO pPage; + LPPAGEINFO pPage = NULL; if( pTag->Owner->NextAvail > 0 ) { @@ -2148,7 +2137,7 @@ static BOOL hb_ntxGetSortedKey( LPTAGINFO pTag, LPNTXSORTINFO pSortInfo, LPSORTI { char *key1, *key2; short int nPage, iPage; - int result; + int result = 0; BOOL fDescend = !pTag->AscendKey; USHORT itemLength = sizeof( ULONG ) + pTag->KeyLength; LPSORTITEM pKey = *ppKey; @@ -2278,7 +2267,7 @@ static void hb_ntxBufferSave( LPTAGINFO pTag, LPNTXSORTINFO pSortInfo ) /* printf( "\nhb_ntxBufferSave - 1 ( maxKeys=%d )",maxKeys ); */ if( pSortInfo->nSwappages > 1 ) { - BOOL lKeys; + BOOL lKeys = FALSE; LPSORTITEM pKeyRoot = (LPSORTITEM) hb_xgrab( pSortInfo->itemLength ); USHORT pageItemLength = sizeof( ULONG ) + pTag->KeyLength; USHORT maxKeysSwapPage = 512/pageItemLength, nRead; @@ -2338,7 +2327,7 @@ static void hb_ntxBufferSave( LPTAGINFO pTag, LPNTXSORTINFO pSortInfo ) { while( pKey ) { - for( i = 0; ( i < maxKeys || numKey == pSortInfo->ulKeyCount-1 ) && pKey > 0; i++, numKey++, pKey = pKey->pNext ) + for( i = 0; ( i < maxKeys || numKey == pSortInfo->ulKeyCount-1 ) && pKey != 0; i++, numKey++, pKey = pKey->pNext ) { /* printf( "\nhb_ntxBufferSave - 2 ( i=%d maxKeys=%d )",i,maxKeys ); */ item = (NTXITEM *)( buffer + itemlist->item_offset[i] ); @@ -2438,7 +2427,7 @@ static BOOL hb_ntxReadBuf( NTXAREAP pArea, BYTE* readBuffer, USHORT* numRecinBuf static ERRCODE hb_ntxIndexCreate( LPNTXINDEX pIndex ) { - ULONG ulRecNo, ulRecCount, ulKeyNo = 0, lStep = 0, ulRecMax; + ULONG ulRecNo = 0, ulRecCount, ulKeyNo = 0, lStep = 0, ulRecMax = 0; USHORT uiCurLen; char szBuffer[ HB_MAX_DOUBLE_LENGTH + 1 ]; char * pszTempName = NULL; @@ -2450,8 +2439,8 @@ static ERRCODE hb_ntxIndexCreate( LPNTXINDEX pIndex ) NTXSORTINFO sortInfo; BYTE* readBuffer; USHORT numRecinBuf = 0, nParts = 0; - BYTE * pRecordTmp; - BOOL fValidBuffer; + BYTE * pRecordTmp = NULL; + BOOL fValidBuffer = FALSE; PHB_CODEPAGE cdpTmp = hb_cdp_page; ulRecCount = pArea->ulRecCount; diff --git a/harbour/source/rtl/Makefile b/harbour/source/rtl/Makefile index 7019043a44..e526d52554 100644 --- a/harbour/source/rtl/Makefile +++ b/harbour/source/rtl/Makefile @@ -44,6 +44,7 @@ C_SOURCES=\ gtapiu.c \ gx.c \ hardcr.c \ + hbffind.c \ hbrandom.c \ idle.c \ inkey.c \ @@ -184,4 +185,3 @@ DIRS=$(HB_GT_LIBS) include $(TOP)$(ROOT)config/lib.cf include $(TOP)$(ROOT)config/dir.cf - diff --git a/harbour/source/rtl/abs.c b/harbour/source/rtl/abs.c index b7563b96b5..125c15080d 100644 --- a/harbour/source/rtl/abs.c +++ b/harbour/source/rtl/abs.c @@ -71,19 +71,31 @@ HB_FUNC( ABS ) if( iNumber >= 0 ) hb_retnilen( iNumber, iWidth ); +#if -HB_INT_MAX > HB_INT_MIN + else if ( iNumber < -HB_INT_MAX ) +#if HB_LONG_MAX > HB_INT_MAX + hb_retnint( - ( HB_LONG ) iNumber ); +#else + hb_retndlen( - ( double ) iNumber, 0, iDec ); +#endif +#endif else hb_retni( -iNumber ); } else if( HB_IS_LONG( pNumber ) ) { - long lNumber = hb_itemGetNL( pNumber ); + HB_LONG lNumber = hb_itemGetNInt( pNumber ); if( lNumber >= 0 ) - hb_retnllen( lNumber, iWidth ); + hb_retnintlen( lNumber, iWidth ); +#if -HB_LONG_MAX > HB_LONG_MIN + else if ( lNumber < -HB_LONG_MAX ) + hb_retndlen( - ( double ) lNumber, 0, iDec ); +#endif else - hb_retnl( -lNumber ); + hb_retnint( -lNumber ); } - else if( HB_IS_DOUBLE( pNumber ) ) + else { double dNumber = hb_itemGetND( pNumber ); diff --git a/harbour/source/rtl/at.c b/harbour/source/rtl/at.c index 287a9bf520..515fd05be3 100644 --- a/harbour/source/rtl/at.c +++ b/harbour/source/rtl/at.c @@ -83,7 +83,7 @@ HB_FUNC( AT ) { ULONG ulTextLength = hb_itemGetCLen( pText ); ULONG ulStart = ISNUM( 3 ) ? hb_parnl( 3 ) : 1; - ULONG ulEnd = ISNUM( 4 ) ? hb_parnl( 4 ) : ulTextLength; + ULONG ulEnd = ISNUM( 4 ) ? ( ULONG ) hb_parnl( 4 ) : ulTextLength; ULONG ulPos; if ( ulStart > ulTextLength || ulEnd < ulStart ) hb_retnl( 0 ); diff --git a/harbour/source/rtl/datec.c b/harbour/source/rtl/datec.c index 57a4ba65f6..3583f389fc 100644 --- a/harbour/source/rtl/datec.c +++ b/harbour/source/rtl/datec.c @@ -76,10 +76,10 @@ HB_FUNC( CMONTH ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); - hb_retc( hb_dateCMonth( lMonth ) ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); + hb_retc( hb_dateCMonth( iMonth ) ); } else hb_errRT_BASE_SubstR( EG_ARG, 1116, NULL, "CMONTH", 1, hb_paramError( 1 ) ); @@ -95,10 +95,10 @@ HB_FUNC( CDOW ) if( lDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( lDate, &lYear, &lMonth, &lDay ); - hb_retc( hb_dateCDOW( hb_dateDOW( lYear, lMonth, lDay ) ) ); + hb_dateDecode( lDate, &iYear, &iMonth, &iDay ); + hb_retc( hb_dateCDOW( hb_dateDOW( iYear, iMonth, iDay ) ) ); } else hb_retc( NULL ); diff --git a/harbour/source/rtl/dates.c b/harbour/source/rtl/dates.c index d5b20a8411..4950813af6 100644 --- a/harbour/source/rtl/dates.c +++ b/harbour/source/rtl/dates.c @@ -78,43 +78,49 @@ #include "hbapi.h" #include "hbdate.h" -long HB_EXPORT hb_dateEncode( long lYear, long lMonth, long lDay ) +#ifdef HB_C52_STRICT + #define HB_DATE_YEAR_LIMIT 2999 +#else + #define HB_DATE_YEAR_LIMIT 9999 +#endif + +LONG HB_EXPORT hb_dateEncode( int iYear, int iMonth, int iDay ) { - HB_TRACE(HB_TR_DEBUG, ("hb_dateEncode(%ld, %ld, %ld)", lYear, lMonth, lDay)); + HB_TRACE(HB_TR_DEBUG, ("hb_dateEncode(%d, %d, %d)", iYear, iMonth, iDay)); /* Perform date validation */ - if( lYear >= 1 && lYear <= 2999 && - lMonth >= 1 && lMonth <= 12 && - lDay >= 1 ) + if( iYear >= 1 && iYear <= HB_DATE_YEAR_LIMIT && + iMonth >= 1 && iMonth <= 12 && + iDay >= 1 ) { /* Month, year, and lower day limits are simple, but upper day limit is dependent upon month and leap year */ - USHORT auiDayLimit[ 12 ] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + int auiDayLimit[ 12 ] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - if( ( ( lYear % 4 == 0 && lYear % 100 != 0 ) || lYear % 400 == 0 ) ) + if( ( ( iYear % 4 == 0 && iYear % 100 != 0 ) || iYear % 400 == 0 ) ) auiDayLimit[ 1 ] = 29; - if( lDay <= ( long ) auiDayLimit[ ( int ) lMonth - 1 ] ) + if( iDay <= auiDayLimit[ iMonth - 1 ] ) { - long lFactor = ( lMonth < 3 ) ? -1 : 0; + int iFactor = ( iMonth < 3 ) ? -1 : 0; - return ( 1461 * ( lFactor + 4800 + lYear ) / 4 ) + - ( ( lMonth - 2 - ( lFactor * 12 ) ) * 367 ) / 12 - - ( 3 * ( ( lFactor + 4900 + lYear ) / 100 ) / 4 ) + - lDay - 32075; + return ( ( LONG )( iFactor + 4800 + iYear ) * 1461 / 4 ) + + ( ( LONG )( iMonth - 2 - ( iFactor * 12 ) ) * 367 ) / 12 - + ( ( LONG )( ( iFactor + 4900 + iYear ) / 100 ) * 3 / 4 ) + + ( LONG ) iDay - 32075; } } return 0; } -void HB_EXPORT hb_dateDecode( long lJulian, long * plYear, long * plMonth, long * plDay ) +void HB_EXPORT hb_dateDecode( LONG lJulian, int *piYear, int *piMonth, int *piDay ) { - HB_TRACE(HB_TR_DEBUG, ("hb_dateDecode(%ld, %p, %p, %p)", lJulian, plYear, plMonth, plDay)); + HB_TRACE(HB_TR_DEBUG, ("hb_dateDecode(%ld, %p, %p, %p)", lJulian, piYear, piMonth, piDay)); if( lJulian > 0 ) { - long U, V, W, X; + LONG U, V, W, X; lJulian += 68569; W = ( lJulian * 4 ) / 146097; @@ -124,94 +130,92 @@ void HB_EXPORT hb_dateDecode( long lJulian, long * plYear, long * plMonth, long V = 80 * lJulian / 2447; U = V / 11; - *plYear = X + U + ( W - 49 ) * 100; - *plMonth = V + 2 - ( U * 12 ); - *plDay = lJulian - ( 2447 * V / 80 ); + *piYear = (int) ( X + U + ( W - 49 ) * 100 ); + *piMonth = (int) ( V + 2 - ( U * 12 ) ); + *piDay = (int) ( lJulian - ( 2447 * V / 80 ) ); } else { - *plYear = - *plMonth = - *plDay = 0; + *piYear = + *piMonth = + *piDay = 0; } } -void HB_EXPORT hb_dateStrPut( char * szDate, long lYear, long lMonth, long lDay ) +void HB_EXPORT hb_dateStrPut( char * szDate, int iYear, int iMonth, int iDay ) { - HB_TRACE(HB_TR_DEBUG, ("hb_dateStrPut(%p, %ld, %ld, %ld)", szDate, lYear, lMonth, lDay)); + HB_TRACE(HB_TR_DEBUG, ("hb_dateStrPut(%p, %d, %d, %d)", szDate, iYear, iMonth, iDay)); - if( lYear >= 0 && lMonth && lDay ) + if( iYear >= 0 && iMonth && iDay ) { - szDate[ 0 ] = ( ( lYear % 10000 ) / 1000 ) + '0'; - szDate[ 1 ] = ( ( lYear % 1000 ) / 100 ) + '0'; - szDate[ 2 ] = ( ( lYear % 100 ) / 10 ) + '0'; - szDate[ 3 ] = ( lYear % 10 ) + '0'; + szDate[ 0 ] = ( ( iYear % 10000 ) / 1000 ) + '0'; + szDate[ 1 ] = ( ( iYear % 1000 ) / 100 ) + '0'; + szDate[ 2 ] = ( ( iYear % 100 ) / 10 ) + '0'; + szDate[ 3 ] = ( iYear % 10 ) + '0'; - szDate[ 4 ] = ( lMonth / 10 ) + '0'; - szDate[ 5 ] = ( lMonth % 10 ) + '0'; + szDate[ 4 ] = ( iMonth / 10 ) + '0'; + szDate[ 5 ] = ( iMonth % 10 ) + '0'; - szDate[ 6 ] = ( lDay / 10 ) + '0'; - szDate[ 7 ] = ( lDay % 10 ) + '0'; + szDate[ 6 ] = ( iDay / 10 ) + '0'; + szDate[ 7 ] = ( iDay % 10 ) + '0'; } - else if ( lYear || lMonth || lDay ) + else if ( iYear || iMonth || iDay ) memset( szDate, '0', 8 ); else memset( szDate, ' ', 8 ); } -void hb_dateStrGet( const char * szDate, long * plYear, long * plMonth, long * plDay ) +void HB_EXPORT hb_dateStrGet( const char * szDate, int * piYear, int * piMonth, int * piDay ) { - HB_TRACE(HB_TR_DEBUG, ("hb_dateStrGet(%s, %p, %p, %p)", szDate, plYear, plMonth, plDay)); + HB_TRACE(HB_TR_DEBUG, ("hb_dateStrGet(%s, %p, %p, %p)", szDate, piYear, piMonth, piDay)); if( szDate && szDate[ 8 ] == '\0' ) { /* Date string has correct length, so attempt to convert */ - *plYear = ( ( USHORT ) ( szDate[ 0 ] - '0' ) * 1000 ) + + *piYear = ( ( USHORT ) ( szDate[ 0 ] - '0' ) * 1000 ) + ( ( USHORT ) ( szDate[ 1 ] - '0' ) * 100 ) + ( ( USHORT ) ( szDate[ 2 ] - '0' ) * 10 ) + ( USHORT ) ( szDate[ 3 ] - '0' ); - *plMonth = ( ( szDate[ 4 ] - '0' ) * 10 ) + ( szDate[ 5 ] - '0' ); - *plDay = ( ( szDate[ 6 ] - '0' ) * 10 ) + ( szDate[ 7 ] - '0' ); + *piMonth = ( ( szDate[ 4 ] - '0' ) * 10 ) + ( szDate[ 5 ] - '0' ); + *piDay = ( ( szDate[ 6 ] - '0' ) * 10 ) + ( szDate[ 7 ] - '0' ); } else { /* Date string missing or bad length, so force an empty date */ - *plYear = - *plMonth = - *plDay = 0; + *piYear = + *piMonth = + *piDay = 0; } } /* This function always closes the date with a zero byte, so it needs a 9 character long buffer. */ -char * hb_dateDecStr( char * szDate, long lJulian ) +char HB_EXPORT * hb_dateDecStr( char * szDate, LONG lJulian ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; HB_TRACE(HB_TR_DEBUG, ("hb_dateDecStr(%p, %ld)", szDate, lJulian)); - hb_dateDecode( lJulian, &lYear, &lMonth, &lDay ); - hb_dateStrPut( szDate, lYear, lMonth, lDay ); + hb_dateDecode( lJulian, &iYear, &iMonth, &iDay ); + hb_dateStrPut( szDate, iYear, iMonth, iDay ); szDate[ 8 ] = '\0'; return szDate; } -long hb_dateEncStr( char * szDate ) +LONG HB_EXPORT hb_dateEncStr( char * szDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; HB_TRACE(HB_TR_DEBUG, ("hb_dateEncStr(%s)", szDate)); - hb_dateStrGet( szDate, &lYear, &lMonth, &lDay ); + hb_dateStrGet( szDate, &iYear, &iMonth, &iDay ); - return hb_dateEncode( lYear, lMonth, lDay ); + return hb_dateEncode( iYear, iMonth, iDay ); } -/* NOTE: szFormattedDate must be an at least 11 chars wide buffer */ - -char * hb_dateFormat( const char * szDate, char * szFormattedDate, const char * szDateFormat ) +char HB_EXPORT * hb_dateFormat( const char * szDate, char * szFormattedDate, const char * szDateFormat ) { /* * NOTE: szFormattedDate must point to a buffer of at least 11 bytes. @@ -383,32 +387,32 @@ char * hb_dateFormat( const char * szDate, char * szFormattedDate, const char * return szFormattedDate; } -long hb_dateDOW( long lYear, long lMonth, long lDay ) +int HB_EXPORT hb_dateDOW( int iYear, int iMonth, int iDay ) { - HB_TRACE(HB_TR_DEBUG, ("hb_dateDOW(%ld, %ld, %ld)", lYear, lMonth, lDay)); + HB_TRACE(HB_TR_DEBUG, ("hb_dateDOW(%d, %d, %d)", iYear, iMonth, iDay)); - if( lMonth < 3 ) + if( iMonth < 3 ) { - lMonth += 13; - lYear--; + iMonth += 13; + iYear--; } else - lMonth++; + iMonth++; - return ( lDay + 26 * lMonth / 10 + - lYear + lYear / 4 - lYear / 100 + lYear / 400 + 6 ) % 7 + 1; + return ( iDay + 26 * iMonth / 10 + + iYear + iYear / 4 - iYear / 100 + iYear / 400 + 6 ) % 7 + 1; } -void hb_dateToday( long * plYear, long * plMonth, long * plDay ) +void HB_EXPORT hb_dateToday( int * piYear, int * piMonth, int * piDay ) { #if defined(HB_OS_WIN_32) { SYSTEMTIME st; GetLocalTime( &st ); - *plYear = st.wYear; - *plMonth = st.wMonth; - *plDay = st.wDay; + *piYear = st.wYear; + *piMonth = st.wMonth; + *piDay = st.wDay; } #else { @@ -418,16 +422,16 @@ void hb_dateToday( long * plYear, long * plMonth, long * plDay ) time( &t ); oTime = localtime( &t ); - *plYear = oTime->tm_year + 1900; - *plMonth = oTime->tm_mon + 1; - *plDay = oTime->tm_mday; + *piYear = oTime->tm_year + 1900; + *piMonth = oTime->tm_mon + 1; + *piDay = oTime->tm_mday; } #endif } /* NOTE: The passed buffer must be at least 9 chars long */ -void hb_dateTimeStr( char * pszTime ) +void HB_EXPORT hb_dateTimeStr( char * pszTime ) { #if defined(HB_OS_WIN_32) { diff --git a/harbour/source/rtl/dateshb.c b/harbour/source/rtl/dateshb.c index 34374cee65..ccb97b6f33 100644 --- a/harbour/source/rtl/dateshb.c +++ b/harbour/source/rtl/dateshb.c @@ -220,11 +220,11 @@ HB_FUNC( YEAR ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); - hb_retnllen( lYear, 5 ); + hb_retnllen( iYear, 5 ); } else hb_errRT_BASE_SubstR( EG_ARG, 1112, NULL, "YEAR", 1, hb_paramError( 1 ) ); @@ -236,11 +236,11 @@ HB_FUNC( MONTH ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); - hb_retnllen( lMonth, 3 ); + hb_retnilen( iMonth, 3 ); } else hb_errRT_BASE_SubstR( EG_ARG, 1113, NULL, "MONTH", 1, hb_paramError( 1 ) ); @@ -252,11 +252,11 @@ HB_FUNC( DAY ) if( pDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( hb_itemGetDL( pDate ), &lYear, &lMonth, &lDay ); + hb_dateDecode( hb_itemGetDL( pDate ), &iYear, &iMonth, &iDay ); - hb_retnllen( lDay, 3 ); + hb_retnilen( iDay, 3 ); } else hb_errRT_BASE_SubstR( EG_ARG, 1114, NULL, "DAY", 1, hb_paramError( 1 ) ); @@ -271,9 +271,9 @@ HB_FUNC( TIME ) HB_FUNC( DATE ) { - long lYear, lMonth, lDay; - hb_dateToday( &lYear, &lMonth, &lDay ); - hb_retd( lYear, lMonth, lDay ); + int iYear, iMonth, iDay; + hb_dateToday( &iYear, &iMonth, &iDay ); + hb_retd( iYear, iMonth, iDay ); } HB_FUNC( DOW ) @@ -286,14 +286,14 @@ HB_FUNC( DOW ) if( lDate ) { - long lYear, lMonth, lDay; + int iYear, iMonth, iDay; - hb_dateDecode( lDate, &lYear, &lMonth, &lDay ); + hb_dateDecode( lDate, &iYear, &iMonth, &iDay ); - hb_retnllen( hb_dateDOW( lYear, lMonth, lDay ), 3 ); + hb_retnilen( hb_dateDOW( iYear, iMonth, iDay ), 3 ); } else - hb_retnllen( 0, 3 ); + hb_retnilen( 0, 3 ); } else hb_errRT_BASE_SubstR( EG_ARG, 1115, NULL, "DOW", 1, hb_paramError( 1 ) ); diff --git a/harbour/source/rtl/datesx.c b/harbour/source/rtl/datesx.c index 9c5f7d3632..a1f5d1f8f4 100644 --- a/harbour/source/rtl/datesx.c +++ b/harbour/source/rtl/datesx.c @@ -62,7 +62,7 @@ HB_FUNC( STOD ) #ifdef HB_FAST_STOD hb_retds( hb_parc( 1 ) ); #else - hb_retds( ( ISCHAR( 1 ) && hb_parclen( 1 ) == 8 ) ? hb_parc( 1 ) : " " ); + hb_retds( hb_parclen( 1 ) == 8 ? hb_parc( 1 ) : " " ); #endif } diff --git a/harbour/source/rtl/empty.c b/harbour/source/rtl/empty.c index 09fae65fb9..d1b753a660 100644 --- a/harbour/source/rtl/empty.c +++ b/harbour/source/rtl/empty.c @@ -73,7 +73,7 @@ HB_FUNC( EMPTY ) break; case HB_IT_LONG: - hb_retl( hb_itemGetNL( pItem ) == 0 ); + hb_retl( hb_itemGetNInt( pItem ) == 0 ); break; case HB_IT_DOUBLE: diff --git a/harbour/source/rtl/errorapi.c b/harbour/source/rtl/errorapi.c index 9ffb201e28..aefba60067 100644 --- a/harbour/source/rtl/errorapi.c +++ b/harbour/source/rtl/errorapi.c @@ -772,6 +772,10 @@ USHORT hb_errRT_BASE( ULONG ulGenCode, ULONG ulSubCode, char * szDescription, ch hb_itemArrayPut( pArray, 1, pArg ); } } + else if ( ulArgCount == 0 ) + { + pArray = NULL; + } else { pArray = hb_itemArrayNew( ulArgCount ); @@ -783,18 +787,24 @@ USHORT hb_errRT_BASE( ULONG ulGenCode, ULONG ulSubCode, char * szDescription, ch } va_end( va ); - pError = hb_errRT_New( ES_ERROR, HB_ERR_SS_BASE, ulGenCode, ulSubCode, szDescription, szOperation, 0, EF_CANRETRY ); + /* I replaced EF_CANRETRY with EF_NONE for Clipper compatibility + * If it's wrong and I missed sth please fix me, Druzus. + */ + pError = hb_errRT_New( ES_ERROR, HB_ERR_SS_BASE, ulGenCode, ulSubCode, szDescription, szOperation, 0, EF_NONE /* EF_CANRETRY */ ); - /* Assign the new array to the object data item. */ - hb_vmPushSymbol( hb_dynsymGet( "_ARGS" )->pSymbol ); - hb_vmPush( pError ); - hb_vmPush( pArray ); - hb_vmDo( 1 ); - - /* Release the Array. */ - if( bRelease ) + if ( pArray ) { - hb_itemRelease( pArray ); + /* Assign the new array to the object data item. */ + hb_vmPushSymbol( hb_dynsymGet( "_ARGS" )->pSymbol ); + hb_vmPush( pError ); + hb_vmPush( pArray ); + hb_vmDo( 1 ); + + /* Release the Array. */ + if( bRelease ) + { + hb_itemRelease( pArray ); + } } /* Ok, launch... */ @@ -815,24 +825,27 @@ USHORT hb_errRT_BASE_Ext1( ULONG ulGenCode, ULONG ulSubCode, char * szDescriptio va_list va; ULONG ulArgPos; - pArray = hb_itemArrayNew( ulArgCount ); - - /* Build the array from the passed arguments. */ - va_start( va, ulArgCount ); - for( ulArgPos = 1; ulArgPos <= ulArgCount; ulArgPos++ ) - hb_itemArrayPut( pArray, ulArgPos, va_arg( va, PHB_ITEM ) ); - va_end( va ); - pError = hb_errRT_New( ES_ERROR, HB_ERR_SS_BASE, ulGenCode, ulSubCode, szDescription, szOperation, uiOsCode, uiFlags ); - /* Assign the new array to the object data item. */ - hb_vmPushSymbol( hb_dynsymGet( "_ARGS" )->pSymbol ); - hb_vmPush( pError ); - hb_vmPush( pArray ); - hb_vmDo( 1 ); + if ( ulArgCount > 0 ) + { + pArray = hb_itemArrayNew( ulArgCount ); - /* Release the Array. */ - hb_itemRelease( pArray ); + /* Build the array from the passed arguments. */ + va_start( va, ulArgCount ); + for( ulArgPos = 1; ulArgPos <= ulArgCount; ulArgPos++ ) + hb_itemArrayPut( pArray, ulArgPos, va_arg( va, PHB_ITEM ) ); + va_end( va ); + + /* Assign the new array to the object data item. */ + hb_vmPushSymbol( hb_dynsymGet( "_ARGS" )->pSymbol ); + hb_vmPush( pError ); + hb_vmPush( pArray ); + hb_vmDo( 1 ); + + /* Release the Array. */ + hb_itemRelease( pArray ); + } /* Ok, launch... */ uiAction = hb_errLaunch( pError ); @@ -851,24 +864,27 @@ PHB_ITEM hb_errRT_BASE_Subst( ULONG ulGenCode, ULONG ulSubCode, char * szDescrip va_list va; ULONG ulArgPos; - pArray = hb_itemArrayNew( ulArgCount ); - - /* Build the array from the passed arguments. */ - va_start( va, ulArgCount ); - for( ulArgPos = 1; ulArgPos <= ulArgCount; ulArgPos++ ) - hb_itemArrayPut( pArray, ulArgPos, va_arg( va, PHB_ITEM ) ); - va_end( va ); - pError = hb_errRT_New_Subst( ES_ERROR, HB_ERR_SS_BASE, ulGenCode, ulSubCode, szDescription, szOperation, 0, EF_NONE ); - /* Assign the new array to the object data item. */ - hb_vmPushSymbol( hb_dynsymGet( "_ARGS" )->pSymbol ); - hb_vmPush( pError ); - hb_vmPush( pArray ); - hb_vmDo( 1 ); + if ( ulArgCount > 0 ) + { + pArray = hb_itemArrayNew( ulArgCount ); - /* Release the Array. */ - hb_itemRelease( pArray ); + /* Build the array from the passed arguments. */ + va_start( va, ulArgCount ); + for( ulArgPos = 1; ulArgPos <= ulArgCount; ulArgPos++ ) + hb_itemArrayPut( pArray, ulArgPos, va_arg( va, PHB_ITEM ) ); + va_end( va ); + + /* Assign the new array to the object data item. */ + hb_vmPushSymbol( hb_dynsymGet( "_ARGS" )->pSymbol ); + hb_vmPush( pError ); + hb_vmPush( pArray ); + hb_vmDo( 1 ); + + /* Release the Array. */ + hb_itemRelease( pArray ); + } /* Ok, launch... */ pRetVal = hb_errLaunchSubst( pError ); @@ -904,6 +920,10 @@ void hb_errRT_BASE_SubstR( ULONG ulGenCode, ULONG ulSubCode, char * szDescriptio hb_itemArrayPut( pArray, 1, pArg ); } } + else if ( ulArgCount == 0 ) + { + pArray = NULL; + } else { pArray = hb_itemArrayNew( ulArgCount ); @@ -917,16 +937,19 @@ void hb_errRT_BASE_SubstR( ULONG ulGenCode, ULONG ulSubCode, char * szDescriptio pError = hb_errRT_New_Subst( ES_ERROR, HB_ERR_SS_BASE, ulGenCode, ulSubCode, szDescription, szOperation, 0, EF_NONE ); - /* Assign the new array to the object data item. */ - hb_vmPushSymbol( hb_dynsymGet( "_ARGS" )->pSymbol ); - hb_vmPush( pError ); - hb_vmPush( pArray ); - hb_vmDo( 1 ); - - /* Release the Array. */ - if( bRelease ) + if ( pArray ) { - hb_itemRelease( pArray ); + /* Assign the new array to the object data item. */ + hb_vmPushSymbol( hb_dynsymGet( "_ARGS" )->pSymbol ); + hb_vmPush( pError ); + hb_vmPush( pArray ); + hb_vmDo( 1 ); + + /* Release the Array. */ + if( bRelease ) + { + hb_itemRelease( pArray ); + } } /* Ok, launch... */ diff --git a/harbour/source/rtl/errorint.c b/harbour/source/rtl/errorint.c index 8fc1e117af..f00e7c3569 100644 --- a/harbour/source/rtl/errorint.c +++ b/harbour/source/rtl/errorint.c @@ -73,6 +73,15 @@ void hb_errInternal( ULONG ulIntCode, char * szText, char * szPar1, char * szPar hb_stackDispCall(); + /* release console settings */ + hb_conRelease(); + + if( hb_cmdargCheck( "ERRGPF" ) ) + { + int *pGPF = NULL; + *pGPF = 0; + *(--pGPF) = 0; + } + exit( EXIT_FAILURE ); } - diff --git a/harbour/source/rtl/filesys.c b/harbour/source/rtl/filesys.c index 981adf8188..d789a803db 100644 --- a/harbour/source/rtl/filesys.c +++ b/harbour/source/rtl/filesys.c @@ -90,6 +90,10 @@ This has been corrected by ptucker */ +#if defined(HB_OS_LINUX) +# define _LARGEFILE64_SOURCE +#endif + #ifndef HB_OS_WIN_32_USED #define HB_OS_WIN_32_USED #endif @@ -190,7 +194,7 @@ #endif #ifndef S_IRWXU - #define S_IRWXU 0x01C0 /* RWE permissions mask for owner */ + #define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) #endif #ifndef S_IRUSR @@ -205,6 +209,38 @@ #define S_IXUSR 0x0040 /* owner may execute */ #endif +#ifndef S_IRWXG + #define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +#endif + +#ifndef S_IRGRP + #define S_IRGRP 0x00020 /* read permission, group */ +#endif + +#ifndef S_IWGRP + #define S_IWGRP 0x00010 /* write permission, grougroup */ +#endif + +#ifndef S_IXGRP + #define S_IXGRP 0x00008/* execute/search permission, group */ +#endif + +#ifndef S_IRWXO + #define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +#endif + +#ifndef S_IROTH + #define S_IROTH 0x00004 /* read permission, other */ +#endif + +#ifndef S_IWOTH + #define S_IWOTH 0x00002 /* write permission, other */ +#endif + +#ifndef S_IXOTH + #define S_IXOTH 0x00001/* execute/search permission, other */ +#endif + #ifndef SH_COMPAT #define SH_COMPAT 0x00 /* Compatibility */ #endif @@ -243,10 +279,10 @@ static USHORT s_uiErrorLast = 0; #define HB_FS_DRIVE_LETTER #endif -#if UINT_MAX == ULONG_MAX - #define HB_FS_LARGE_OPTIMIZED -#else +#if UINT_MAX == USHRT_MAX #define LARGE_MAX ( UINT_MAX - 1L ) +#else + #define HB_FS_LARGE_OPTIMIZED #endif #if defined(X__WIN32__) @@ -304,7 +340,7 @@ static int convert_open_flags( USHORT uiFlags ) HB_TRACE(HB_TR_INFO, ("convert_open_flags: added O_RDWR\n")); } -#if ! defined(HB_FS_SOPEN) +#if ! defined(HB_FS_SOPEN) && ! defined( HB_OS_UNIX ) /* shared flags */ if( ( uiFlags & FO_DENYREAD ) == FO_DENYREAD ) { @@ -337,11 +373,90 @@ static int convert_open_flags( USHORT uiFlags ) } #endif + if( uiFlags & FO_CREAT ) + { + result_flags |= O_CREAT; + HB_TRACE(HB_TR_INFO, ("convert_open_flags: added O_CREAT\n")); + } + + if( uiFlags & FO_TRUNC ) + { + result_flags |= O_TRUNC; + HB_TRACE(HB_TR_INFO, ("convert_open_flags: added O_TRUNC\n")); + } + + if( uiFlags & FO_EXCL ) + { + result_flags |= O_EXCL; + HB_TRACE(HB_TR_INFO, ("convert_open_flags: added O_EXCL\n")); + } + HB_TRACE(HB_TR_INFO, ("convert_open_flags: result is 0x%04x\n", result_flags)); return result_flags; } +static unsigned convert_pmode_flags( USHORT uiFlags ) +{ + unsigned result_pmode = 0; + + HB_TRACE(HB_TR_DEBUG, ("convert_pmode_flags(%hu)", uiFlags)); + + if( uiFlags & FC_HIDDEN ) + { + result_pmode = S_IRUSR; + } + else + { + result_pmode = S_IRUSR | S_IRGRP | S_IROTH; + } + + if( !( uiFlags & FC_READONLY) ) + { + if( result_pmode & S_IRUSR ) result_pmode |= S_IWUSR; + if( result_pmode & S_IRGRP ) result_pmode |= S_IWGRP; + if( result_pmode & S_IROTH ) result_pmode |= S_IWOTH; + } + + if( uiFlags & FC_SYSTEM ) + { + if( result_pmode & S_IRUSR ) result_pmode |= S_IXUSR; + if( result_pmode & S_IRGRP ) result_pmode |= S_IXGRP; + if( result_pmode & S_IROTH ) result_pmode |= S_IXOTH; + } + + HB_TRACE(HB_TR_INFO, ("convert_pmode_flags: 0x%04x\n", result_pmode)); + + return result_pmode; +} + +static void convert_create_flags( USHORT uiFlags, int * result_flags, unsigned * result_pmode ) +{ + HB_TRACE(HB_TR_DEBUG, ("convert_create_flags(%hu, %p, %p)", uiFlags, result_flags, result_pmode)); + + /* by default FC_NORMAL is set */ + *result_flags = O_BINARY | O_CREAT | O_TRUNC | O_RDWR; + *result_pmode = convert_pmode_flags( uiFlags ); + + HB_TRACE(HB_TR_INFO, ("convert_create_flags: 0x%04x, 0x%04x\n", *result_flags, *result_pmode)); +} + +static void convert_create_flags_ex( USHORT uiAttr, USHORT uiFlags, int * result_flags, unsigned * result_pmode ) +{ + HB_TRACE(HB_TR_DEBUG, ("convert_create_flags_ex(%hu, %hu, %p, %p)", uiAttr, uiFlags, result_flags, result_pmode)); + + /* by default FC_NORMAL is set */ + + /* *result_flags = O_BINARY | O_CREAT | O_TRUNC | O_RDWR; */ + *result_flags = convert_open_flags( uiFlags ) | O_BINARY | O_CREAT | O_TRUNC | O_RDWR; + if ( uiFlags & FO_EXCL ) + *result_flags |= O_EXCL; + + *result_pmode = convert_pmode_flags( uiAttr ); + + HB_TRACE(HB_TR_INFO, ("convert_create_flags: 0x%04x, 0x%04x\n", *result_flags, *result_pmode)); +} + static int convert_seek_flags( USHORT uiFlags ) { /* by default FS_SET is set */ @@ -358,58 +473,6 @@ static int convert_seek_flags( USHORT uiFlags ) return result_flags; } -static void convert_create_flags( USHORT uiFlags, int * result_flags, unsigned * result_pmode ) -{ - HB_TRACE(HB_TR_DEBUG, ("convert_create_flags(%hu, %p, %p)", uiFlags, result_flags, result_pmode)); - - /* by default FC_NORMAL is set */ - - *result_flags = O_BINARY | O_CREAT | O_TRUNC | O_RDWR; - *result_pmode = S_IRUSR | S_IWUSR; - - if( uiFlags & FC_READONLY ) - { - *result_pmode = S_IRUSR; - HB_TRACE(HB_TR_INFO, ("convert_create_flags: S_IRUSR")); - } - - if( uiFlags & FC_HIDDEN ) - *result_flags |= 0; - - if( uiFlags & FC_SYSTEM ) - *result_flags |= 0; - - HB_TRACE(HB_TR_INFO, ("convert_create_flags: 0x%04x, 0x%04x\n", *result_flags, *result_pmode)); -} - -static void convert_create_flags_ex( USHORT uiAttr, USHORT uiFlags, int * result_flags, unsigned * result_pmode ) -{ - HB_TRACE(HB_TR_DEBUG, ("convert_create_flags_ex(%hu, %hu, %p, %p)", uiAttr, uiFlags, result_flags, result_pmode)); - - /* by default FC_NORMAL is set */ - - /* *result_flags = O_BINARY | O_CREAT | O_TRUNC | O_RDWR; */ - *result_flags = convert_open_flags( uiFlags ) | O_BINARY | O_CREAT | O_TRUNC | O_RDWR; - if ( uiFlags & FO_EXCL ) - *result_flags |= O_EXCL; - - *result_pmode = S_IRUSR | S_IWUSR; - - if( uiAttr & FC_READONLY ) - { - *result_pmode = S_IRUSR; - HB_TRACE(HB_TR_INFO, ("convert_create_flags_ex: S_IRUSR")); - } - - if( uiAttr & FC_HIDDEN ) - *result_flags |= 0; - - if( uiAttr & FC_SYSTEM ) - *result_flags |= 0; - - HB_TRACE(HB_TR_INFO, ("convert_create_flags: 0x%04x, 0x%04x\n", *result_flags, *result_pmode)); -} - #endif /* @@ -474,56 +537,100 @@ BYTE * hb_filecase( char * str ) FHANDLE hb_fsPOpen( BYTE * pFilename, BYTE * pMode ) { - FHANDLE hFileHandle; + FHANDLE hFileHandle = FS_ERROR; HB_TRACE(HB_TR_DEBUG, ("hb_fsPOpen(%p, %s)", pFilename, pMode)); #if defined(OS_UNIX_COMPATIBLE) { - FHANDLE hPipeHandle[2]; + FHANDLE hPipeHandle[2], hNullHandle; pid_t pid; + BYTE * pbyTmp; BOOL bRead; + ULONG ulLen; + int iMaxFD; + + ulLen = strlen( pFilename ); + if( pMode && ( *pMode == 'r' || *pMode == 'w' ) ) + bRead = ( *pMode == 'r' ); + else + { + if( pFilename[0] == '|' ) + bRead = FALSE; + else if( pFilename[ ulLen - 1 ] == '|' ) + bRead = TRUE; + else + bRead = FALSE; + } + + if( pFilename[0] == '|' ) + { + ++pFilename; + --ulLen; + } + if( pFilename[ ulLen - 1 ] == '|' ) + { + pbyTmp = hb_strdup( pFilename ); + pbyTmp[--ulLen] = 0; + pFilename = pbyTmp; + } else + pbyTmp = NULL; - bRead = ( *pMode == 'r' ); - errno = 0; if( pipe( hPipeHandle ) == 0 ) { if( ( pid = fork() ) != -1 ) { if( pid != 0 ) { - if( bRead ) { - close( hPipeHandle[ 1 ] ); - hFileHandle = hPipeHandle[ 0 ]; - } else { - close( hPipeHandle[ 0 ] ); - hFileHandle = hPipeHandle[ 1 ]; - } - } else { + if( bRead ) { + close( hPipeHandle[ 1 ] ); + hFileHandle = hPipeHandle[ 0 ]; + } else { + close( hPipeHandle[ 0 ] ); + hFileHandle = hPipeHandle[ 1 ]; + } + } else { char *argv[4]; - argv[0] = "sh"; + argv[0] = "sh"; argv[1] = "-c"; argv[2] = ( char * ) pFilename; argv[3] = ( char * ) 0; - if( bRead ) { - close( hPipeHandle[ 0 ] ); - dup2( hPipeHandle[ 1 ], 1 ); - } else { - close( hPipeHandle[ 1 ] ); - dup2( hPipeHandle[ 0 ], 0 ); - } + hNullHandle = open("/dev/null", O_RDWR); + if( bRead ) { + close( hPipeHandle[ 0 ] ); + dup2( hPipeHandle[ 1 ], 1 ); + dup2( hNullHandle, 0 ); + dup2( hNullHandle, 2 ); + } else { + close( hPipeHandle[ 1 ] ); + dup2( hPipeHandle[ 0 ], 0 ); + dup2( hNullHandle, 1 ); + dup2( hNullHandle, 2 ); + } + iMaxFD = sysconf( _SC_OPEN_MAX ); + if ( iMaxFD < 3 ) + iMaxFD = 1024; + for( hNullHandle = 3; hNullHandle < iMaxFD; ++hNullHandle ) + close(hNullHandle); + setuid(getuid()); + setgid(getgid()); execve("/bin/sh", argv, environ); - exit(1); - } - } else { - close( hPipeHandle[0] ); - close( hPipeHandle[1] ); - } + exit(1); + } + } + else + { + close( hPipeHandle[0] ); + close( hPipeHandle[1] ); + } } - s_uiErrorLast = errno; + + s_uiErrorLast = hFileHandle != FS_ERROR ? 0 : errno; + + if( pbyTmp ) + hb_xfree( pbyTmp ); } #else HB_SYMBOL_UNUSED( pFilename ); HB_SYMBOL_UNUSED( pMode ); - hFileHandle = FS_ERROR; s_uiErrorLast = FS_ERROR; #endif @@ -600,9 +707,9 @@ FHANDLE HB_EXPORT hb_fsOpen( BYTE * pFilename, USHORT uiFlags ) #elif defined(HAVE_POSIX_IO) && ! defined(__IBMCPP__) && ! defined(_MSC_VER) - errno = 0; - hFileHandle = open( ( char * ) pFilename, convert_open_flags( uiFlags ) ); - s_uiErrorLast = errno; + hFileHandle = open( ( char * ) pFilename, convert_open_flags( uiFlags ), + convert_pmode_flags( 0 ) ); + s_uiErrorLast = hFileHandle != FS_ERROR ? 0 : errno; #elif defined(_MSC_VER) { @@ -639,12 +746,11 @@ FHANDLE HB_EXPORT hb_fsOpen( BYTE * pFilename, USHORT uiFlags ) else if( uiFlags & FO_DENYWRITE ) iShare = SH_DENYWR; - errno = 0; if( iShare ) hFileHandle = sopen( ( char * ) pFilename, convert_open_flags( uiFlags ), iShare ); else hFileHandle = open( ( char * ) pFilename, convert_open_flags( uiFlags ) ); - s_uiErrorLast = errno; + s_uiErrorLast = hFileHandle != FS_ERROR ? 0 : errno; } #else @@ -698,16 +804,9 @@ FHANDLE HB_EXPORT hb_fsCreate( BYTE * pFilename, USHORT uiAttr ) #elif defined(HB_FS_FILE_IO) - errno = 0; convert_create_flags( uiAttr, &oflag, &pmode ); hFileHandle = open( ( char * ) pFilename, oflag, pmode ); - if( hFileHandle == -1 ) - { - /* This if block is required, because errno will be set - if the file did not exist and had to be created, even - when the create is successful! */ - s_uiErrorLast = errno; - } + s_uiErrorLast = hFileHandle != FS_ERROR ? 0 : errno; #else @@ -740,16 +839,9 @@ FHANDLE HB_EXPORT hb_fsCreateEx( BYTE * pFilename, USHORT uiAttr, USHORT uiFlags #if defined(HB_FS_FILE_IO) - errno = 0; convert_create_flags_ex( uiAttr, uiFlags, &oflag, &pmode ); hFileHandle = open( ( char * ) pFilename, oflag, pmode ); - if( hFileHandle == -1 ) - { - /* This if block is required, because errno will be set - if the file did not exist and had to be created, even - when the create is successful! */ - s_uiErrorLast = errno; - } + s_uiErrorLast = hFileHandle != FS_ERROR ? 0 : errno; #else @@ -842,6 +934,9 @@ BOOL hb_fsSetDevMode( FHANDLE hFileHandle, USHORT uiDevMode ) #else + HB_SYMBOL_UNUSED( hFileHandle ); + HB_SYMBOL_UNUSED( uiDevMode ); + bResult = FALSE; s_uiErrorLast = FS_ERROR; @@ -1084,216 +1179,72 @@ ULONG HB_EXPORT hb_fsWriteLarge( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCoun return ulWritten; } -ULONG HB_EXPORT hb_fsSeek( FHANDLE hFileHandle, LONG lOffset, USHORT uiFlags ) +void HB_EXPORT hb_fsCommit( FHANDLE hFileHandle ) { - ULONG ulPos; - USHORT Flags; + HB_TRACE(HB_TR_DEBUG, ("hb_fsCommit(%p)", hFileHandle)); - HB_TRACE(HB_TR_DEBUG, ("hb_fsSeek(%p, %ld, %hu)", hFileHandle, lOffset, uiFlags)); +#if defined(X__WIN32__) - Flags = convert_seek_flags( uiFlags ); + FlushFileBuffers( ( HANDLE ) DostoWinHandle( hFileHandle ) ); + s_uiErrorLast = ( USHORT ) GetLastError(); + +#elif defined(HB_OS_OS2) - if( lOffset < 0 && Flags == SEEK_SET ) { - - #if defined(HB_OS_OS2) - - { - APIRET ret = DosSetFilePtr( hFileHandle, 0, SEEK_CUR, &ulPos ); - - if( ret != 0 ) - { - ulPos = 0; - s_uiErrorLast = ( USHORT ) ret; - } - } - - #elif defined(HB_FS_FILE_IO) - - /* get current offset */ errno = 0; - #if defined(X__WIN32__) - ulPos = SetFilePointer( DostoWinHandle( hFileHandle ), 0, NULL, FILE_CURRENT ); - if( ( DWORD ) ulPos == 0xFFFFFFFF ) - errno = GetLastError(); - #else - ulPos = lseek( hFileHandle, 0, SEEK_CUR ); - #endif - if( errno != 0 ) - { - ulPos = 0; - s_uiErrorLast = errno; - } - else - s_uiErrorLast = 25; /* 'Seek Error' */ - #else + /* TODO: what about error code from DosResetBuffer() call? */ + DosResetBuffer( hFileHandle ); - ulPos = 0; - s_uiErrorLast = 25; /* 'Seek Error' */ - - #endif - - } - else - { - - #if defined(HB_OS_OS2) - - { - APIRET ret = DosSetFilePtr( hFileHandle, lOffset, Flags, &ulPos ); - - if( ret != 0 ) - { - ulPos = 0; - s_uiErrorLast = ( USHORT ) ret; - } - } - - #elif defined(HB_FS_FILE_IO) - - errno = 0; - #if defined(X__WIN32__) - ulPos = SetFilePointer( DostoWinHandle( hFileHandle ), lOffset, NULL, ( DWORD ) Flags ); - if( ( DWORD ) ulPos == 0xFFFFFFFF ) - errno = GetLastError(); - #else - ulPos = lseek( hFileHandle, lOffset, Flags ); - #endif - if( errno != 0 ) - ulPos = 0; s_uiErrorLast = errno; + } +#elif defined(HB_OS_UNIX) + + /* NOTE: close() functions releases all lock regardles if it is an + * original or duplicated file handle + */ + #if defined(_POSIX_SYNCHRONIZED_IO) && (_POSIX_SYNCHRONIZED_IO > 0) + /* faster - flushes data buffers only, without updating directory info + */ + s_uiErrorLast = ( fdatasync( hFileHandle ) < -1 ) ? FS_ERROR : 0; + if( s_uiErrorLast == EINVAL ) + { + /* This implementation does not support synchronised I/O for + this file, so use the slower method that flushes all file + data buffers and i-node info for this file. + */ + s_uiErrorLast = ( fsync( hFileHandle ) < -1 ) ? FS_ERROR : 0; + } #else - - ulPos = 0; - s_uiErrorLast = FS_ERROR; - + /* slower - flushes all file data buffers and i-node info + */ + s_uiErrorLast = ( fsync( hFileHandle ) < -1 ) ? FS_ERROR : 0; #endif - /* Convert 'Unknown Command' to 'Seek Error' */ - if( s_uiErrorLast == 22 ) - s_uiErrorLast = 25; - } +#elif defined(__WATCOMC__) - return ulPos; -} + _dos_commit( hFileHandle ); -ULONG HB_EXPORT hb_fsTell( FHANDLE hFileHandle ) -{ - ULONG ulPos; +#elif defined(HB_FS_FILE_IO) && !defined(HB_OS_OS2) && !defined(HB_OS_UNIX) - HB_TRACE(HB_TR_DEBUG, ("hb_fsTell(%p)", hFileHandle)); - -#if defined(HB_FS_FILE_IO) - - errno = 0; - #if defined(X__WIN32__) - ulPos = SetFilePointer( DostoWinHandle( hFileHandle ), 0, NULL, FILE_CURRENT ); - if( ( DWORD ) ulPos == 0xFFFFFFFF ) - errno = GetLastError(); - #else - ulPos = lseek( hFileHandle, 0L, SEEK_CUR ); - #endif - s_uiErrorLast = errno; - -#else - - ulPos = 0; - s_uiErrorLast = FS_ERROR; - -#endif - - return ulPos; -} - -USHORT HB_EXPORT hb_fsError( void ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_fsError()")); - - return s_uiErrorLast; -} - -void hb_fsSetError( USHORT uiError ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_fsSetError(%hu)", uiError)); - - s_uiErrorLast = uiError; -} - -BOOL HB_EXPORT hb_fsDelete( BYTE * pFilename ) -{ - BOOL bResult; - - HB_TRACE(HB_TR_DEBUG, ("hb_fsDelete(%s)", (char*) pFilename)); - -#if defined(X__WIN32__) - - if( ( bResult = DeleteFile( ( char * ) pFilename ) ) == 0 ) { - #if !defined(__BORLANDC__) - errno = WintoDosError( GetLastError() ); - #else - __NTerror(); - #endif + int dup_handle; + + errno = 0; + + dup_handle = dup( hFileHandle ); + if( dup_handle != -1 ) + close( dup_handle ); + + s_uiErrorLast = errno; } - s_uiErrorLast = errno; - -#elif defined(HAVE_POSIX_IO) - - errno = 0; - bResult = ( unlink( ( char * ) pFilename ) == 0 ); - s_uiErrorLast = errno; - -#elif defined(_MSC_VER) || defined(__MINGW32__) - - errno = 0; - bResult = ( remove( ( char * ) pFilename ) == 0 ); - s_uiErrorLast = errno; #else - bResult = FALSE; s_uiErrorLast = FS_ERROR; #endif - - return bResult; -} - -BOOL HB_EXPORT hb_fsRename( BYTE * pOldName, BYTE * pNewName ) -{ - BOOL bResult; - - HB_TRACE(HB_TR_DEBUG, ("hb_fsRename(%s, %s)", (char*) pOldName, (char*) pNewName)); - -#if defined(X__WIN32__) - - errno = 0; - if( ( bResult = MoveFile( ( char * ) pOldName, ( char * ) pNewName ) ) == 0 ) - { - #if !defined(__BORLANDC__) - errno = WintoDosError( GetLastError() ); - #else - __NTerror(); - #endif - } - s_uiErrorLast = errno; - -#elif defined(HB_FS_FILE_IO) - - errno = 0; - bResult = ( rename( ( char * ) pOldName, ( char * ) pNewName ) == 0 ); - s_uiErrorLast = errno; - -#else - - bResult = FALSE; - s_uiErrorLast = FS_ERROR; - -#endif - - return bResult; } BOOL HB_EXPORT hb_fsLock ( FHANDLE hFileHandle, ULONG ulStart, @@ -1416,19 +1367,19 @@ BOOL HB_EXPORT hb_fsLock ( FHANDLE hFileHandle, ULONG ulStart, */ struct flock lock_info; - errno = 0; - switch( uiMode & FL_MASK ) { case FL_LOCK: - lock_info.l_type = F_WRLCK; + lock_info.l_type = (uiMode & FLX_SHARED) ? F_RDLCK : F_WRLCK; lock_info.l_start = ulStart; lock_info.l_len = ulLength; lock_info.l_whence = SEEK_SET; /* start from the beginning of the file */ lock_info.l_pid = getpid(); - bResult = ( fcntl( hFileHandle, F_SETLK, &lock_info ) >= 0 ); + bResult = ( fcntl( hFileHandle, + (uiMode & FLX_WAIT) ? F_SETLKW: F_SETLK, + &lock_info ) >= 0 ); break; case FL_UNLOCK: @@ -1446,7 +1397,7 @@ BOOL HB_EXPORT hb_fsLock ( FHANDLE hFileHandle, ULONG ulStart, bResult = FALSE; } - s_uiErrorLast = errno; + s_uiErrorLast = bResult ? 0 : errno; } #elif defined(HAVE_POSIX_IO) && !defined(__IBMCPP__) && ( !defined(__GNUC__) || defined(__DJGPP__) ) @@ -1477,72 +1428,301 @@ BOOL HB_EXPORT hb_fsLock ( FHANDLE hFileHandle, ULONG ulStart, return bResult; } -void HB_EXPORT hb_fsCommit( FHANDLE hFileHandle ) +BOOL HB_EXPORT hb_fsLockLarge( FHANDLE hFileHandle, HB_FOFFSET ulStart, + HB_FOFFSET ulLength, USHORT uiMode ) { - HB_TRACE(HB_TR_DEBUG, ("hb_fsCommit(%p)", hFileHandle)); + BOOL bResult; -#if defined(X__WIN32__) - - FlushFileBuffers( ( HANDLE ) DostoWinHandle( hFileHandle ) ); - s_uiErrorLast = ( USHORT ) GetLastError(); - -#elif defined(HB_OS_OS2) + HB_TRACE(HB_TR_DEBUG, ("hb_fsLockLarge(%p, %" PFHL "u, %" PFHL "u, %hu)", hFileHandle, ulStart, ulLength, uiMode)); +#if defined(HB_FS_FILE_IO) && defined(HB_OS_LINUX) && \ + defined(__USE_LARGEFILE64) + /* + * The macro: __USE_LARGEFILE64 is set when _LARGEFILE64_SOURCE is + * define and efectively enables lseek64/flock64 functions on 32bit + * machines. + */ { - errno = 0; + struct flock64 lock_info; - /* TODO: what about error code from DosResetBuffer() call? */ - DosResetBuffer( hFileHandle ); - - s_uiErrorLast = errno; - } - -#elif defined(HB_OS_UNIX) - - /* NOTE: close() functions releases all lock regardles if it is an - * original or duplicated file handle - */ - #if defined(_POSIX_SYNCHRONIZED_IO) && (_POSIX_SYNCHRONIZED_IO > 0) - /* faster - flushes data buffers only, without updating directory info - */ - s_uiErrorLast = ( fdatasync( hFileHandle ) < -1 ) ? FS_ERROR : 0; - if( s_uiErrorLast == EINVAL ) + switch( uiMode & FL_MASK ) { - /* This implementation does not support synchronised I/O for - this file, so use the slower method that flushes all file - data buffers and i-node info for this file. - */ - s_uiErrorLast = ( fsync( hFileHandle ) < -1 ) ? FS_ERROR : 0; + case FL_LOCK: + + lock_info.l_type = (uiMode & FLX_SHARED) ? F_RDLCK : F_WRLCK; + lock_info.l_start = ulStart; + lock_info.l_len = ulLength; + lock_info.l_whence = SEEK_SET; /* start from the beginning of the file */ + lock_info.l_pid = getpid(); + + bResult = ( fcntl( hFileHandle, + (uiMode & FLX_WAIT) ? F_SETLKW64: F_SETLK64, + &lock_info ) != -1 ); + break; + + case FL_UNLOCK: + + lock_info.l_type = F_UNLCK; /* unlock */ + lock_info.l_start = ulStart; + lock_info.l_len = ulLength; + lock_info.l_whence = SEEK_SET; + lock_info.l_pid = getpid(); + + bResult = ( fcntl( hFileHandle, F_SETLK64, &lock_info ) != -1 ); + break; + + default: + bResult = FALSE; } + s_uiErrorLast = bResult ? 0 : errno; + } +#else + bResult = hb_fsLock( hFileHandle, (ULONG) ulStart, (ULONG) ulLength, uiMode ); +#endif + + return bResult; +} + +ULONG HB_EXPORT hb_fsSeek( FHANDLE hFileHandle, LONG lOffset, USHORT uiFlags ) +{ + ULONG ulPos; + USHORT Flags; + + HB_TRACE(HB_TR_DEBUG, ("hb_fsSeek(%p, %ld, %hu)", hFileHandle, lOffset, uiFlags)); + + Flags = convert_seek_flags( uiFlags ); + + if( lOffset < 0 && Flags == SEEK_SET ) + { + + #if defined(HB_OS_OS2) + + { + APIRET ret = DosSetFilePtr( hFileHandle, 0, SEEK_CUR, &ulPos ); + + if( ret != 0 ) + { + ulPos = 0; + s_uiErrorLast = ( USHORT ) ret; + } + } + + #elif defined(HB_FS_FILE_IO) + + /* get current offset */ + errno = 0; + #if defined(X__WIN32__) + ulPos = SetFilePointer( DostoWinHandle( hFileHandle ), 0, NULL, FILE_CURRENT ); + if( ( DWORD ) ulPos == 0xFFFFFFFF ) + errno = GetLastError(); + #else + ulPos = lseek( hFileHandle, 0, SEEK_CUR ); + #endif + if( errno != 0 ) + { + ulPos = 0; + s_uiErrorLast = errno; + } + else + s_uiErrorLast = 25; /* 'Seek Error' */ + #else - /* slower - flushes all file data buffers and i-node info - */ - s_uiErrorLast = ( fsync( hFileHandle ) < -1 ) ? FS_ERROR : 0; + + ulPos = 0; + s_uiErrorLast = 25; /* 'Seek Error' */ + #endif -#elif defined(__WATCOMC__) - - _dos_commit( hFileHandle ); - -#elif defined(HB_FS_FILE_IO) && !defined(HB_OS_OS2) && !defined(HB_OS_UNIX) - + } + else { - int dup_handle; + + #if defined(HB_OS_OS2) + + { + APIRET ret = DosSetFilePtr( hFileHandle, lOffset, Flags, &ulPos ); + + if( ret != 0 ) + { + ulPos = 0; + s_uiErrorLast = ( USHORT ) ret; + } + } + + #elif defined(HB_FS_FILE_IO) errno = 0; - - dup_handle = dup( hFileHandle ); - if( dup_handle != -1 ) - close( dup_handle ); - + #if defined(X__WIN32__) + ulPos = SetFilePointer( DostoWinHandle( hFileHandle ), lOffset, NULL, ( DWORD ) Flags ); + if( ( DWORD ) ulPos == 0xFFFFFFFF ) + errno = GetLastError(); + #else + ulPos = lseek( hFileHandle, lOffset, Flags ); + #endif + if( errno != 0 ) + ulPos = 0; s_uiErrorLast = errno; + + #else + + ulPos = 0; + s_uiErrorLast = FS_ERROR; + + #endif + + /* Convert 'Unknown Command' to 'Seek Error' */ + if( s_uiErrorLast == 22 ) + s_uiErrorLast = 25; } + return ulPos; +} + +HB_FOFFSET HB_EXPORT hb_fsSeekLarge( FHANDLE hFileHandle, HB_FOFFSET llOffset, USHORT uiFlags ) +{ + HB_FOFFSET llPos; + + HB_TRACE(HB_TR_DEBUG, ("hb_fsSeekLarge(%p, %" PFHL "u, %hu)", hFileHandle, llOffset, uiFlags)); + +#if defined(HB_FS_FILE_IO) && defined(HB_OS_LINUX) && \ + defined(__USE_LARGEFILE64) + /* + * The macro: __USE_LARGEFILE64 is set when _LARGEFILE64_SOURCE is + * define and efectively enables lseek64/flock64 functions on 32bit + * machines. + */ + { + USHORT Flags = convert_seek_flags( uiFlags ); + llPos = lseek64( hFileHandle, llOffset, Flags ); + s_uiErrorLast = ( llPos != (HB_FOFFSET) -1 ? 0 : errno ); + + if ( llPos == (HB_FOFFSET) -1 ) + { + llPos = lseek64( hFileHandle, 0L, SEEK_CUR ); + } + } +#else + llPos = (HB_FOFFSET) hb_fsSeek( hFileHandle, (LONG) llOffset, uiFlags ); +#endif + + return llPos; +} + +ULONG HB_EXPORT hb_fsTell( FHANDLE hFileHandle ) +{ + ULONG ulPos; + + HB_TRACE(HB_TR_DEBUG, ("hb_fsTell(%p)", hFileHandle)); + +#if defined(HB_FS_FILE_IO) + + errno = 0; + #if defined(X__WIN32__) + ulPos = SetFilePointer( DostoWinHandle( hFileHandle ), 0, NULL, FILE_CURRENT ); + if( ( DWORD ) ulPos == 0xFFFFFFFF ) + errno = GetLastError(); + #else + ulPos = lseek( hFileHandle, 0L, SEEK_CUR ); + #endif + s_uiErrorLast = errno; + #else + ulPos = 0; s_uiErrorLast = FS_ERROR; #endif + + return ulPos; +} + +USHORT HB_EXPORT hb_fsError( void ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_fsError()")); + + return s_uiErrorLast; +} + +void hb_fsSetError( USHORT uiError ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_fsSetError(%hu)", uiError)); + + s_uiErrorLast = uiError; +} + +BOOL HB_EXPORT hb_fsDelete( BYTE * pFilename ) +{ + BOOL bResult; + + HB_TRACE(HB_TR_DEBUG, ("hb_fsDelete(%s)", (char*) pFilename)); + +#if defined(X__WIN32__) + + if( ( bResult = DeleteFile( ( char * ) pFilename ) ) == 0 ) + { + #if !defined(__BORLANDC__) + errno = WintoDosError( GetLastError() ); + #else + __NTerror(); + #endif + } + s_uiErrorLast = errno; + +#elif defined(HAVE_POSIX_IO) + + errno = 0; + bResult = ( unlink( ( char * ) pFilename ) == 0 ); + s_uiErrorLast = errno; + +#elif defined(_MSC_VER) || defined(__MINGW32__) + + errno = 0; + bResult = ( remove( ( char * ) pFilename ) == 0 ); + s_uiErrorLast = errno; + +#else + + bResult = FALSE; + s_uiErrorLast = FS_ERROR; + +#endif + + return bResult; +} + +BOOL HB_EXPORT hb_fsRename( BYTE * pOldName, BYTE * pNewName ) +{ + BOOL bResult; + + HB_TRACE(HB_TR_DEBUG, ("hb_fsRename(%s, %s)", (char*) pOldName, (char*) pNewName)); + +#if defined(X__WIN32__) + + errno = 0; + if( ( bResult = MoveFile( ( char * ) pOldName, ( char * ) pNewName ) ) == 0 ) + { + #if !defined(__BORLANDC__) + errno = WintoDosError( GetLastError() ); + #else + __NTerror(); + #endif + } + s_uiErrorLast = errno; + +#elif defined(HB_FS_FILE_IO) + + errno = 0; + bResult = ( rename( ( char * ) pOldName, ( char * ) pNewName ) == 0 ); + s_uiErrorLast = errno; + +#else + + bResult = FALSE; + s_uiErrorLast = FS_ERROR; + +#endif + + return bResult; } BOOL HB_EXPORT hb_fsMkDir( BYTE * pDirname ) @@ -1801,6 +1981,8 @@ USHORT HB_EXPORT hb_fsChDrv( BYTE nDrive ) #endif #else + HB_SYMBOL_UNUSED( nDrive ); + uiResult = FS_ERROR; s_uiErrorLast = FS_ERROR; @@ -1870,6 +2052,8 @@ USHORT HB_EXPORT hb_fsIsDrv( BYTE nDrive ) #else + HB_SYMBOL_UNUSED( nDrive ); + uiResult = FS_ERROR; s_uiErrorLast = FS_ERROR; diff --git a/harbour/source/rtl/fstemp.c b/harbour/source/rtl/fstemp.c index e2e4150613..e504a8ecc9 100644 --- a/harbour/source/rtl/fstemp.c +++ b/harbour/source/rtl/fstemp.c @@ -113,6 +113,8 @@ FHANDLE hb_fsCreateTemp( const BYTE * pszDir, const BYTE * pszPrefix, USHORT uiA } } #else + HB_SYMBOL_UNUSED( uiAttr ); + if( ( ( pszDir ? strlen( pszDir ) : 0 ) + ( pszPrefix ? strlen( pszPrefix ) : 0 ) + 6 ) < _POSIX_PATH_MAX ) { FHANDLE fhnd; diff --git a/harbour/source/rtl/gtcrs/gtcrs.c b/harbour/source/rtl/gtcrs/gtcrs.c index 9deb60e079..ad8e552874 100644 --- a/harbour/source/rtl/gtcrs/gtcrs.c +++ b/harbour/source/rtl/gtcrs/gtcrs.c @@ -164,6 +164,10 @@ void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr ) { HB_TRACE(HB_TR_DEBUG, ("hb_gt_Init()")); + HB_SYMBOL_UNUSED( iFilenoStdin ); + HB_SYMBOL_UNUSED( iFilenoStdout ); + HB_SYMBOL_UNUSED( iFilenoStderr ); + s_uiDispCount = 0; hb_gt_terminal_Init(); @@ -581,7 +585,7 @@ void hb_gt_DispEnd() { HB_TRACE(HB_TR_DEBUG, ("hb_gt_DispEnd()")); - if( --s_uiDispCount == 0 ); + if( --s_uiDispCount == 0 ) refresh(); } diff --git a/harbour/source/rtl/gtcrs/kbdcrs.c b/harbour/source/rtl/gtcrs/kbdcrs.c index 3d2ab80d96..36256665b3 100644 --- a/harbour/source/rtl/gtcrs/kbdcrs.c +++ b/harbour/source/rtl/gtcrs/kbdcrs.c @@ -278,7 +278,7 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask ) { static unsigned char key_codes[ HB_MAX_KEYMAP_CHARS + 1 ]; /* buffer for multi-characters keycodes */ static int key_waiting = -1; /* position of next character from buffer if > 0 */ - unsigned int ch; + int ch; HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) eventmask)); diff --git a/harbour/source/rtl/gtdos/gtdos.c b/harbour/source/rtl/gtdos/gtdos.c index f70bb4f8ee..7505d9f117 100644 --- a/harbour/source/rtl/gtdos/gtdos.c +++ b/harbour/source/rtl/gtdos/gtdos.c @@ -1514,7 +1514,7 @@ BOOL hb_gt_SetMode( USHORT uiRows, USHORT uiCols ) BOOL bIsVesa = FALSE; USHORT bSuccess = FALSE; - HB_TRACE( HB_TR_DEBUG, ("hb_gt_SetMode(%hu, %hu)", usRows, usCols) ); + HB_TRACE( HB_TR_DEBUG, ("hb_gt_SetMode(%hu, %hu)", uiRows, uiCols) ); /* Available modes in B&N and color screens */ if( uiCols == 40 ) diff --git a/harbour/source/rtl/gtsln/gtsln.c b/harbour/source/rtl/gtsln/gtsln.c index 61fea2ffa5..8ac085e2ff 100644 --- a/harbour/source/rtl/gtsln/gtsln.c +++ b/harbour/source/rtl/gtsln/gtsln.c @@ -83,7 +83,9 @@ #include #include +#ifndef HB_OS_DARWIN #include +#endif #include "hbapi.h" #include "hbapigt.h" @@ -159,6 +161,8 @@ volatile BOOL hb_gt_sln_bScreen_Size_Changed = FALSE; /* window's resize handler */ static void sigwinch_handler( int sig ) { + HB_SYMBOL_UNUSED( sig ); + hb_gt_sln_bScreen_Size_Changed = TRUE; SLsignal( SIGWINCH, sigwinch_handler ); } @@ -170,6 +174,8 @@ void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr ) { BOOL gt_Inited = FALSE; + HB_SYMBOL_UNUSED( iFilenoStdin ); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_Init()")); s_iFilenoStdout = iFilenoStdout; @@ -1256,6 +1262,38 @@ static void hb_gt_build_conv_tabs() switch( ch ) { +#ifdef SLSMG_HLINE_CHAR_TERM + case SLSMG_HLINE_CHAR_TERM : s_convHighChars[ 196 ] = SLch; break; + case SLSMG_VLINE_CHAR_TERM : s_convHighChars[ 179 ] = SLch; break; + case SLSMG_ULCORN_CHAR_TERM : s_convHighChars[ 218 ] = SLch; break; + case SLSMG_URCORN_CHAR_TERM : s_convHighChars[ 191 ] = SLch; break; + case SLSMG_LLCORN_CHAR_TERM : s_convHighChars[ 192 ] = SLch; break; + case SLSMG_LRCORN_CHAR_TERM : s_convHighChars[ 217 ] = SLch; break; + case SLSMG_CKBRD_CHAR_TERM : s_convHighChars[ 176 ] = SLch; break; + case SLSMG_RTEE_CHAR_TERM : s_convHighChars[ 180 ] = SLch; break; + case SLSMG_LTEE_CHAR_TERM : s_convHighChars[ 195 ] = SLch; break; + case SLSMG_UTEE_CHAR_TERM : s_convHighChars[ 194 ] = SLch; break; + case SLSMG_DTEE_CHAR_TERM : s_convHighChars[ 193 ] = SLch; break; + case SLSMG_PLUS_CHAR_TERM : s_convHighChars[ 197 ] = SLch; break; + case SLSMG_DIAMOND_CHAR_TERM : s_convHighChars[ 04 ] = SLch; + break; + case SLSMG_LARROW_CHAR_TERM : s_convHighChars[ 17 ] = SLch; + s_convHighChars[ 27 ] = SLch; + break; + case SLSMG_RARROW_CHAR_TERM : s_convHighChars[ 16 ] = SLch; + s_convHighChars[ 26 ] = SLch; + break; + case SLSMG_DARROW_CHAR_TERM : s_convHighChars[ 25 ] = SLch; + s_convHighChars[ 31 ] = SLch; + break; + case SLSMG_UARROW_CHAR_TERM : s_convHighChars[ 24 ] = SLch; + s_convHighChars[ 30 ] = SLch; + break; + case SLSMG_BOARD_CHAR_TERM : s_convHighChars[ 178 ] = SLch; + break; + case SLSMG_BLOCK_CHAR_TERM : s_convHighChars[ 219 ] = SLch; + break; +#else case SLSMG_HLINE_CHAR : s_convHighChars[ 196 ] = SLch; break; case SLSMG_VLINE_CHAR : s_convHighChars[ 179 ] = SLch; break; case SLSMG_ULCORN_CHAR : s_convHighChars[ 218 ] = SLch; break; @@ -1292,6 +1330,7 @@ static void hb_gt_build_conv_tabs() break; case SLSMG_BLOCK_CHAR : s_convHighChars[ 219 ] = SLch; break; +#endif } ++p; diff --git a/harbour/source/rtl/gtsln/kbsln.c b/harbour/source/rtl/gtsln/kbsln.c index 11de6d3cd1..531dfc3f0d 100644 --- a/harbour/source/rtl/gtsln/kbsln.c +++ b/harbour/source/rtl/gtsln/kbsln.c @@ -295,7 +295,7 @@ int hb_gt_ExtendedKeySupport() int hb_gt_ReadKey( HB_inkey_enum eventmask ) { static int InDeadState = FALSE; - unsigned int ch, tmp, kbdflags; + int ch, tmp, kbdflags; #ifdef DO_LOCAL_DEBUG USHORT savy, savx; #endif @@ -484,4 +484,4 @@ int hb_gt_Kbd_State() return hb_gt_try_get_Kbd_State(); } -/* *********************************************************************** */ \ No newline at end of file +/* *********************************************************************** */ diff --git a/harbour/source/rtl/gtsln/keytrans.c b/harbour/source/rtl/gtsln/keytrans.c index 5538499ea6..f267cf6ae9 100644 --- a/harbour/source/rtl/gtsln/keytrans.c +++ b/harbour/source/rtl/gtsln/keytrans.c @@ -380,11 +380,11 @@ static void hb_gt_SortKeyTranslationTable( void ) { int i, j, min, KeyTmp[ 2 ]; - for ( i = 0; i < ( KeyTranslationTableSize - 1 ); i++ ) + for ( i = 0; i < (int) ( KeyTranslationTableSize - 1 ); i++ ) { min = i; - for ( j = i + 1; j < KeyTranslationTableSize; j++ ) + for ( j = i + 1; j < (int) KeyTranslationTableSize; j++ ) { if ( KeyTranslationTable[ j ][ 0 ] < KeyTranslationTable[ min ][ 0 ] ) min = j; @@ -445,22 +445,20 @@ static int hb_gt_FindKeyTranslation( int SlangKey ) /* ************************************************************************* */ -int hb_gt_SetKeyInKeyTranslationTable( int SlangKey, int ClipKey ) +void hb_gt_SetKeyInKeyTranslationTable( int SlangKey, int ClipKey ) { - int i; if ( ( SlangKey >= KeyTranslationTable[ 0 ][ 0 ] ) && ( SlangKey <= KeyTranslationTable[ KeyTranslationTableSize - 1 ][ 0 ] ) ) { - for ( i = 0; i < KeyTranslationTableSize; i++ ) + int i; + for ( i = 0; i < (int) KeyTranslationTableSize; i++ ) { if ( SlangKey == KeyTranslationTable[ i ][ 0 ] ) KeyTranslationTable[ i ][ 1 ] = ClipKey; /* we don't break here because SlangKey can be defined more than once */ } } - - return( i < KeyTranslationTableSize ); } /* ************************************************************************* */ diff --git a/harbour/source/common/hbffind.c b/harbour/source/rtl/hbffind.c similarity index 100% rename from harbour/source/common/hbffind.c rename to harbour/source/rtl/hbffind.c diff --git a/harbour/source/rtl/hbrandom.c b/harbour/source/rtl/hbrandom.c index c15c2323b8..e1127e08eb 100644 --- a/harbour/source/rtl/hbrandom.c +++ b/harbour/source/rtl/hbrandom.c @@ -59,7 +59,7 @@ #endif /* Globally available data, no need to MT it */ -volatile static int s_bInit = 0; +static volatile int s_bInit = 0; /* * HB_RANDOM diff --git a/harbour/source/rtl/idle.c b/harbour/source/rtl/idle.c index 28b6f63cb4..2cacb583a5 100644 --- a/harbour/source/rtl/idle.c +++ b/harbour/source/rtl/idle.c @@ -133,6 +133,10 @@ void hb_releaseCPU( void ) HB_DOS_INT86( 0x2F, ®s, ®s ); } +#elif defined(HB_OS_DARWIN) + { + usleep( 1 ); + } #elif defined(HB_OS_UNIX) { static struct timespec nanosecs = { 0, 1000 }; diff --git a/harbour/source/rtl/inkey.c b/harbour/source/rtl/inkey.c index c3025047f3..fa0db95757 100644 --- a/harbour/source/rtl/inkey.c +++ b/harbour/source/rtl/inkey.c @@ -358,7 +358,8 @@ void hb_inkeyPut( int ch ) s_inkeyBuffer[ head++ ] = ch; if( head >= hb_set.HB_SET_TYPEAHEAD ) head = 0; if( head != s_inkeyTail ) s_inkeyHead = head; - else /* TODO: Add error sound */ ; + /* else */ + /* TODO: Add error sound */ } else s_inkeyForce = ch; /* Typeahead support is disabled */ diff --git a/harbour/source/rtl/math.c b/harbour/source/rtl/math.c index 04e7e38021..5c63055894 100644 --- a/harbour/source/rtl/math.c +++ b/harbour/source/rtl/math.c @@ -68,6 +68,13 @@ _LIB_VERSION_TYPE _LIB_VERSION = _XOPEN_; #include "hbvm.h" #include "hbmath.h" +#if defined(HB_MATH_ERRNO) +# include +# if !defined( HB_OS_BSD ) +# include +# endif +#endif + /* * ************************************************************ * Harbour Math functions Part I: @@ -75,7 +82,7 @@ _LIB_VERSION_TYPE _LIB_VERSION = _XOPEN_; * ************************************************************ */ -static HB_MATH_EXCEPTION s_hb_exc = {HB_MATH_ERR_NONE, "", "", 0.0, 0.0, 0.0, 1}; +static HB_MATH_EXCEPTION s_hb_exc = {HB_MATH_ERR_NONE, "", "", 0.0, 0.0, 0.0, 1, 0, 0}; /* reset math error information */ void hb_mathResetError (void) @@ -126,6 +133,7 @@ int hb_mathIsMathErr (void) /* route C math lib errors to Harbour error handling */ #if defined(HB_MATH_HANDLER) + int matherr (struct exception * err) { int retval; @@ -138,38 +146,38 @@ int matherr (struct exception * err) { case DOMAIN: { - s_hb_exc.type = HB_MATH_ERR_DOMAIN; - s_hb_exc.error = "Argument not in domain of function"; + s_hb_exc.type = HB_MATH_ERR_DOMAIN; + s_hb_exc.error = "Argument not in domain of function"; }; break; case SING: { - s_hb_exc.type = HB_MATH_ERR_SING; - s_hb_exc.error = "Calculation results in singularity"; + s_hb_exc.type = HB_MATH_ERR_SING; + s_hb_exc.error = "Calculation results in singularity"; }; break; case OVERFLOW: { - s_hb_exc.type = HB_MATH_ERR_OVERFLOW; - s_hb_exc.error = "Calculation result too large to represent"; + s_hb_exc.type = HB_MATH_ERR_OVERFLOW; + s_hb_exc.error = "Calculation result too large to represent"; }; break; case UNDERFLOW: { - s_hb_exc.type = HB_MATH_ERR_UNDERFLOW; - s_hb_exc.error = "Calculation result too small to represent"; + s_hb_exc.type = HB_MATH_ERR_UNDERFLOW; + s_hb_exc.error = "Calculation result too small to represent"; }; break; case TLOSS: { - s_hb_exc.type = HB_MATH_ERR_TLOSS; - s_hb_exc.error = "Total loss of significant digits"; + s_hb_exc.type = HB_MATH_ERR_TLOSS; + s_hb_exc.error = "Total loss of significant digits"; }; break; case PLOSS: { - s_hb_exc.type = HB_MATH_ERR_PLOSS; - s_hb_exc.error = "Partial loss of significant digits"; + s_hb_exc.type = HB_MATH_ERR_PLOSS; + s_hb_exc.error = "Partial loss of significant digits"; }; break; default: { - s_hb_exc.type = HB_MATH_ERR_UNKNOWN; - s_hb_exc.error = "Unknown math error"; + s_hb_exc.type = HB_MATH_ERR_UNKNOWN; + s_hb_exc.error = "Unknown math error"; }; break; } @@ -193,6 +201,77 @@ int matherr (struct exception * err) return (retval); } + +#elif defined(HB_MATH_ERRNO) + +int hb_mathErrSet( double dResult, double arg1, double arg2, char * szFunc, int errCode ) +{ + HB_MATH_HANDLERPROC mathHandler; + + HB_TRACE (HB_TR_DEBUG, ("hb_mathErrSet(%f, %d)", dResult, errCode)); + + switch (errCode) + { + case EDOM: + case ERANGE: + case EOVERFLOW: + break; + + default: + if ( isnan( dResult ) ) + { + errCode = EDOM; + } + else if ( isinf( dResult ) ) + { + errCode = ERANGE; + } + } + + if ( errCode == 0 ) + { + return 0; + } + + hb_mathResetError(); + + /* map math error types */ + switch (errCode) + { + case EDOM: + s_hb_exc.type = HB_MATH_ERR_DOMAIN; + s_hb_exc.error = "Argument not in domain of function"; + break; + + case ERANGE: + s_hb_exc.type = HB_MATH_ERR_SING; + s_hb_exc.error = "Calculation results in singularity"; + break; + + case EOVERFLOW: + s_hb_exc.type = HB_MATH_ERR_OVERFLOW; + s_hb_exc.error = "Calculation result too large to represent"; + break; + + default: + s_hb_exc.type = HB_MATH_ERR_UNKNOWN; + s_hb_exc.error = "Unknown math error"; + break; + } + + s_hb_exc.funcname = szFunc; + s_hb_exc.arg1 = arg1; + s_hb_exc.arg2 = arg2; + s_hb_exc.retval = dResult; + s_hb_exc.handled = 0; + + mathHandler = hb_mathGetHandler(); + if (mathHandler != NULL) + { + (*(mathHandler))(&s_hb_exc); + } + return 1; +} #endif /* @@ -232,10 +311,10 @@ HB_FUNC (MATHERRMODE) /* ([]) -> */ { int iNewMode = hb_parni (1); if ((iNewMode == HB_MATH_ERRMODE_DEFAULT) || - (iNewMode == HB_MATH_ERRMODE_CDEFAULT) || - (iNewMode == HB_MATH_ERRMODE_USER) || - (iNewMode == HB_MATH_ERRMODE_USERDEFAULT) || - (iNewMode == HB_MATH_ERRMODE_USERCDEFAULT)) + (iNewMode == HB_MATH_ERRMODE_CDEFAULT) || + (iNewMode == HB_MATH_ERRMODE_USER) || + (iNewMode == HB_MATH_ERRMODE_USERDEFAULT) || + (iNewMode == HB_MATH_ERRMODE_USERCDEFAULT)) { hb_mathSetErrMode (iNewMode); } @@ -263,17 +342,17 @@ int hb_matherr (HB_MATH_EXCEPTION * pexc) { PHB_ITEM pMatherrResult; - PHB_ITEM pArg1 = hb_itemPutND (NULL, pexc->arg1); - PHB_ITEM pArg2 = hb_itemPutND (NULL, pexc->arg2); + PHB_ITEM pArg1 = hb_itemPutND(NULL, pexc->arg1); + PHB_ITEM pArg2 = hb_itemPutND(NULL, pexc->arg2); PHB_ITEM pArray; PHB_ITEM pError; /* create an array with the two double arguments */ /* NOTE: Unfortunately, we cannot decide whether one or two parameters have been used when the math function has been called, so we always take two */ - pArray = hb_itemArrayNew (2); - hb_itemArrayPut (pArray, 1, pArg1); - hb_itemArrayPut (pArray, 2, pArg2); + pArray = hb_itemArrayNew(2); + hb_itemArrayPut(pArray, 1, pArg1); + hb_itemArrayPut(pArray, 2, pArg2); /* create an error object */ /* NOTE: In case of HB_MATH_ERRMODE_USER[C]DEFAULT, I am setting both EF_CANSUBSTITUTE and EF_CANDEFAULT to .T. here. @@ -317,25 +396,27 @@ int hb_matherr (HB_MATH_EXCEPTION * pexc) { case HB_MATH_ERRMODE_USER: { - /* user failed to handle the math exception, so quit the app [yes, that's the meaning of this mode !!] */ - iret = 0; - hb_vmRequestQuit(); + /* user failed to handle the math exception, so quit the app [yes, that's the meaning of this mode !!] */ + iret = 0; + hb_vmRequestQuit(); }; break; case HB_MATH_ERRMODE_DEFAULT: case HB_MATH_ERRMODE_USERDEFAULT: { - /* return 1 to suppress C RTL error msgs, but leave error handling to the calling Harbour routine */ - iret = 1; + /* return 1 to suppress C RTL error msgs, but leave error handling to the calling Harbour routine */ + iret = 1; }; break; case HB_MATH_ERRMODE_CDEFAULT: case HB_MATH_ERRMODE_USERCDEFAULT: { - /* use the correction value supplied in pexc->retval */ - pexc->handled = 1; - iret = 1; + /* use the correction value supplied in pexc->retval */ + pexc->handled = 1; + iret = 1; }; break; + default: + iret = 1; } return (iret); @@ -377,24 +458,24 @@ HB_MATH_HANDLERPROC hb_mathGetHandler (void) return ((HB_MATH_HANDLERPROC)s_mathHandlerProc); } - /* * ************************************************************ * Harbour Math functions Part IV: - * example of hb_mathSet/GetHandler: add a new math handler that calls a given codeblock for every math error + * example of hb_mathSet/GetHandler: add a new math handler that + * calls a given codeblock for every math error * ************************************************************ */ static PHB_ITEM spMathErrorBlock = NULL; static HB_MATH_HANDLERPROC sPrevMathHandler = NULL; -static int hb_matherrblock (HB_MATH_EXCEPTION * pexc) +static int hb_matherrblock( HB_MATH_EXCEPTION * pexc ) { int retval; /* call codeblock for both case: handled and unhandled exceptions */ - if (spMathErrorBlock != NULL) + if( spMathErrorBlock != NULL ) { PHB_ITEM pArray, pRet; PHB_ITEM pType, pFuncname, pError, pArg1, pArg2, pRetval, pHandled; @@ -426,7 +507,7 @@ static int hb_matherrblock (HB_MATH_EXCEPTION * pexc) hb_itemRelease (pRetval); hb_itemRelease (pHandled); - if (pexc->handled) + if( pexc->handled ) { /* math exception has already been handled, so codeblock call above was only informative */ retval = 1; @@ -437,35 +518,35 @@ static int hb_matherrblock (HB_MATH_EXCEPTION * pexc) pHandled = hb_itemArrayGet (pArray, 2); if (pHandled != NULL) { - pexc->handled = hb_itemGetL (pHandled); - hb_itemRelease (pHandled); + pexc->handled = hb_itemGetL( pHandled ); + hb_itemRelease( pHandled ); } if (pexc->handled) { - /* YES ! */ - /* extract retval for math routine and matherr() */ - pRetval = hb_itemArrayGet (pArray, 1); - if (pRetval != NULL) - { - pexc->retval = hb_itemGetND (pRetval); - hb_itemGetNLen (pRetval, &(pexc->retvalwidth), &(pexc->retvaldec)); - hb_itemRelease (pRetval); - } - if ((pRet != NULL) && HB_IS_NUMERIC (pRet)) - { - retval = hb_itemGetNI (pRet); /* block may also return 0 to force C math lib warnings */ - hb_itemRelease (pRet); - } - else - { - retval = 1; /* default return value to suppress C math lib warnings */ - } + /* YES ! */ + /* extract retval for math routine and matherr() */ + pRetval = hb_itemArrayGet (pArray, 1); + if (pRetval != NULL) + { + pexc->retval = hb_itemGetND (pRetval); + hb_itemGetNLen (pRetval, &(pexc->retvalwidth), &(pexc->retvaldec)); + hb_itemRelease (pRetval); + } + if ((pRet != NULL) && HB_IS_NUMERIC (pRet)) + { + retval = hb_itemGetNI (pRet); /* block may also return 0 to force C math lib warnings */ + hb_itemRelease (pRet); + } + else + { + retval = 1; /* default return value to suppress C math lib warnings */ + } } else { - /* NO ! */ - retval = 1; + /* NO ! */ + retval = 1; } } hb_itemRelease (pArray); @@ -488,7 +569,7 @@ static int hb_matherrblock (HB_MATH_EXCEPTION * pexc) retval = (*sPrevMathHandler)(pexc); } } - return (retval); + return retval; } /* set/get math error block */ @@ -524,7 +605,7 @@ HB_FUNC (MATHERRORBLOCK) /* ([]) -> */ { if (spMathErrorBlock == NULL) { - spMathErrorBlock = hb_itemNew (NULL); + spMathErrorBlock = hb_itemNew (NULL); } hb_itemCopy (spMathErrorBlock, pNewErrorBlock); } @@ -533,16 +614,15 @@ HB_FUNC (MATHERRORBLOCK) /* ([]) -> */ /* a parameter other than a block has been passed -> delete error handler ! */ if (spMathErrorBlock != NULL) { - hb_itemRelease (spMathErrorBlock); - spMathErrorBlock = NULL; + hb_itemRelease (spMathErrorBlock); + spMathErrorBlock = NULL; } } } return; } - - + /* * ************************************************************ * Harbour Math functions Part V: @@ -550,132 +630,144 @@ HB_FUNC (MATHERRORBLOCK) /* ([]) -> */ * ************************************************************ */ -HB_FUNC (EXP) +HB_FUNC( EXP ) { - if (ISNUM (1)) - { - HB_MATH_EXCEPTION hb_exc; - double dResult; + if( ISNUM( 1 ) ) + { + HB_MATH_EXCEPTION hb_exc; + double dResult; - hb_mathResetError(); - dResult = exp (hb_parnd (1)); - - if (hb_mathIsMathErr()) - { - /* the C-RTL provides a kind of matherr() mechanism */ - int iLastError = hb_mathGetLastError (&hb_exc); - if (iLastError != HB_MATH_ERR_NONE) +#if defined(HB_MATH_ERRNO) + errno = 0; + dResult = exp( hb_parnd( 1 ) ); + if ( hb_mathErrSet( dResult, hb_parnd (1), 0.0, "EXP", errno ) ) +#else + hb_mathResetError(); + dResult = exp( hb_parnd( 1 ) ); + if ( hb_mathIsMathErr() ) +#endif { - if (hb_exc.handled) - { - hb_retndlen (hb_exc.retval, hb_exc.retvalwidth, hb_exc.retvaldec); - } - else - { - /* math exception is up to the Harbour function, so do this as Clipper compatible as possible */ - if (iLastError == HB_MATH_ERR_OVERFLOW) - { - hb_retndlen (HUGE_VAL, -1, -1); - } - else - { - hb_retnd (0.0); - } - } - return; + /* the C-RTL provides a kind of matherr() mechanism */ + int iLastError = hb_mathGetLastError( &hb_exc ); + if( iLastError != HB_MATH_ERR_NONE ) + { + if( hb_exc.handled ) + { + hb_retndlen( hb_exc.retval, hb_exc.retvalwidth, hb_exc.retvaldec ); + } + else + { + /* math exception is up to the Harbour function, so do this as Clipper compatible as possible */ + if ( iLastError == HB_MATH_ERR_OVERFLOW ) + { + hb_retndlen( HUGE_VAL, -1, -1 ); + } + else + { + hb_retnd( 0.0 ); + } + } + return; + } } - } - hb_retnd (dResult); + hb_retnd( dResult ); } else { - hb_errRT_BASE_SubstR (EG_ARG, 1096, NULL, "EXP", 1, hb_paramError (1)); + hb_errRT_BASE_SubstR( EG_ARG, 1096, NULL, "EXP", 1, hb_paramError( 1 ) ); } } HB_FUNC (LOG) { + if( ISNUM ( 1 ) ) + { + HB_MATH_EXCEPTION hb_exc; + double dResult; - if (ISNUM (1)) - { - HB_MATH_EXCEPTION hb_exc; - double dResult; - - hb_mathResetError(); - dResult = log (hb_parnd (1)); - - if (hb_mathIsMathErr()) - { - /* the C-RTL provides a kind of matherr() mechanism */ - int iLastError = hb_mathGetLastError (&hb_exc); - if (iLastError != HB_MATH_ERR_NONE) +#if defined(HB_MATH_ERRNO) + errno = 0; + dResult = log( hb_parnd( 1 ) ); + if ( hb_mathErrSet( dResult, hb_parnd (1), 0.0, "LOG", errno ) ) +#else + hb_mathResetError(); + dResult = log( hb_parnd( 1 ) ); + if ( hb_mathIsMathErr() ) +#endif { - if (hb_exc.handled) - { - hb_retndlen (hb_exc.retval, hb_exc.retvalwidth, hb_exc.retvaldec); - } - else - { - /* math exception is up to the Harbour function, so do this as Clipper compatible as possible */ - switch (iLastError) - { - case HB_MATH_ERR_SING: /* argument to log was 0.0 */ - case HB_MATH_ERR_DOMAIN: /* argument to log was < 0.0 */ - { - hb_retndlen (-HUGE_VAL, -1, -1); /* return -infinity */ - }; break; - default: - { - hb_retnd (0.0); - } - } - } - return; + /* the C-RTL provides a kind of matherr() mechanism */ + int iLastError = hb_mathGetLastError( &hb_exc ); + if( iLastError != HB_MATH_ERR_NONE ) + { + if( hb_exc.handled ) + { + hb_retndlen( hb_exc.retval, hb_exc.retvalwidth, hb_exc.retvaldec ); + } + else + { + /* math exception is up to the Harbour function, so do this as Clipper compatible as possible */ + switch( iLastError ) + { + case HB_MATH_ERR_SING: /* argument to log was 0.0 */ + case HB_MATH_ERR_DOMAIN: /* argument to log was < 0.0 */ + { + hb_retndlen( -HUGE_VAL, -1, -1 ); /* return -infinity */ + }; break; + default: + { + hb_retnd( 0.0 ); + } + } + } + return; + } } - } - hb_retnd (dResult); + hb_retnd( dResult ); } else { - hb_errRT_BASE_SubstR (EG_ARG, 1095, NULL, "LOG", 1, hb_paramError (1)); + hb_errRT_BASE_SubstR( EG_ARG, 1095, NULL, "LOG", 1, hb_paramError( 1 ) ); } } - -HB_FUNC (SQRT) +HB_FUNC( SQRT ) { - if (ISNUM (1)) - { - HB_MATH_EXCEPTION hb_exc; - double dResult; + if( ISNUM( 1 ) ) + { + HB_MATH_EXCEPTION hb_exc; + double dResult; - hb_mathResetError(); - dResult = sqrt (hb_parnd (1)); - - if (hb_mathIsMathErr()) - { - /* the C-RTL provides a kind of matherr() mechanism */ - int iLastError = hb_mathGetLastError (&hb_exc); - if (iLastError != HB_MATH_ERR_NONE) +#if defined(HB_MATH_ERRNO) + errno = 0; + dResult = sqrt( hb_parnd( 1 ) ); + if ( hb_mathErrSet( dResult, hb_parnd( 1 ), 0.0, "SQRT", errno ) ) +#else + hb_mathResetError(); + dResult = sqrt( hb_parnd( 1 ) ); + if ( hb_mathIsMathErr() ) +#endif { - if (hb_exc.handled) - { - hb_retndlen (hb_exc.retval, hb_exc.retvalwidth, hb_exc.retvaldec); - } - else - { - /* math exception is up to the Harbour function, so do this as Clipper compatible as possible */ - hb_retnd (0.0); /* return 0.0 on all errors (all (?) of type DOMAIN) */ - } - return; + /* the C-RTL provides a kind of matherr() mechanism */ + int iLastError = hb_mathGetLastError( &hb_exc ); + if( iLastError != HB_MATH_ERR_NONE ) + { + if( hb_exc.handled ) + { + hb_retndlen( hb_exc.retval, hb_exc.retvalwidth, hb_exc.retvaldec ); + } + else + { + /* math exception is up to the Harbour function, so do this as Clipper compatible as possible */ + hb_retnd( 0.0 ); /* return 0.0 on all errors (all (?) of type DOMAIN) */ + } + return; + } } - } - hb_retnd (dResult); + hb_retnd( dResult ); } else { - hb_errRT_BASE_SubstR (EG_ARG, 1097, NULL, "SQRT", 1, hb_paramError (1)); + hb_errRT_BASE_SubstR( EG_ARG, 1097, NULL, "SQRT", 1, hb_paramError( 1 ) ); } } - diff --git a/harbour/source/rtl/minmax.c b/harbour/source/rtl/minmax.c index 32894de761..b8f4f6ff21 100644 --- a/harbour/source/rtl/minmax.c +++ b/harbour/source/rtl/minmax.c @@ -60,41 +60,28 @@ HB_FUNC( MAX ) PHB_ITEM p1 = hb_param( 1, HB_IT_ANY ); PHB_ITEM p2 = hb_param( 2, HB_IT_ANY ); - if( HB_IS_NUMERIC( p1 ) && HB_IS_NUMERIC( p2 ) ) + if( HB_IS_NUMINT( p1 ) && HB_IS_NUMINT( p2 ) ) { - /* NOTE: The order of these if() branches is significant, - please, don't change it. [vszakats] */ + HB_LONG l1 = hb_itemGetNInt( p1 ); + HB_LONG l2 = hb_itemGetNInt( p2 ); - if( HB_IS_DOUBLE( p1 ) || HB_IS_DOUBLE( p2 ) ) - { - double d1 = hb_itemGetND( p1 ); - double d2 = hb_itemGetND( p2 ); + hb_retnint( l1 >= l2 ? l1 : l2 ); + } + else if( HB_IS_NUMERIC( p1 ) && HB_IS_NUMERIC( p2 ) ) + { + double d1 = hb_itemGetND( p1 ); + double d2 = hb_itemGetND( p2 ); - int iDec1; - int iDec2; + int iDec1; + int iDec2; - hb_itemGetNLen( p1, NULL, &iDec1 ); - hb_itemGetNLen( p2, NULL, &iDec2 ); + hb_itemGetNLen( p1, NULL, &iDec1 ); + hb_itemGetNLen( p2, NULL, &iDec2 ); - if( d1 >= d2 ) - hb_retndlen( d1, 0, iDec1 ); - else - hb_retndlen( d2, 0, iDec2 ); - } - else if( HB_IS_LONG( p1 ) || HB_IS_LONG( p2 ) ) - { - long l1 = hb_itemGetNL( p1 ); - long l2 = hb_itemGetNL( p2 ); - - hb_retnl( l1 >= l2 ? l1 : l2 ); - } + if( d1 >= d2 ) + hb_retndlen( d1, 0, iDec1 ); else - { - int i1 = hb_itemGetNI( p1 ); - int i2 = hb_itemGetNI( p2 ); - - hb_retni( i1 >= i2 ? i1 : i2 ); - } + hb_retndlen( d2, 0, iDec2 ); } else if( HB_IS_LOGICAL( p1 ) && HB_IS_LOGICAL( p2 ) ) { @@ -119,41 +106,28 @@ HB_FUNC( MIN ) PHB_ITEM p1 = hb_param( 1, HB_IT_ANY ); PHB_ITEM p2 = hb_param( 2, HB_IT_ANY ); - if( HB_IS_NUMERIC( p1 ) && HB_IS_NUMERIC( p2 ) ) + if( HB_IS_NUMINT( p1 ) && HB_IS_NUMINT( p2 ) ) { - /* NOTE: The order of these if() branches is significant, - please, don't change it. [vszakats] */ + HB_LONG l1 = hb_itemGetNInt( p1 ); + HB_LONG l2 = hb_itemGetNInt( p2 ); - if( HB_IS_DOUBLE( p1 ) || HB_IS_DOUBLE( p2 ) ) - { - double d1 = hb_itemGetND( p1 ); - double d2 = hb_itemGetND( p2 ); + hb_retnint( l1 <= l2 ? l1 : l2 ); + } + else if( HB_IS_NUMERIC( p1 ) && HB_IS_NUMERIC( p2 ) ) + { + double d1 = hb_itemGetND( p1 ); + double d2 = hb_itemGetND( p2 ); - int iDec1; - int iDec2; + int iDec1; + int iDec2; - hb_itemGetNLen( p1, NULL, &iDec1 ); - hb_itemGetNLen( p2, NULL, &iDec2 ); + hb_itemGetNLen( p1, NULL, &iDec1 ); + hb_itemGetNLen( p2, NULL, &iDec2 ); - if( d1 <= d2 ) - hb_retndlen( d1, 0, iDec1 ); - else - hb_retndlen( d2, 0, iDec2 ); - } - else if( HB_IS_LONG( p1 ) || HB_IS_LONG( p2 ) ) - { - long l1 = hb_itemGetNL( p1 ); - long l2 = hb_itemGetNL( p2 ); - - hb_retnl( l1 <= l2 ? l1 : l2 ); - } + if( d1 <= d2 ) + hb_retndlen( d1, 0, iDec1 ); else - { - int i1 = hb_itemGetNI( p1 ); - int i2 = hb_itemGetNI( p2 ); - - hb_retni( i1 <= i2 ? i1 : i2 ); - } + hb_retndlen( d2, 0, iDec2 ); } else if( HB_IS_LOGICAL( p1 ) && HB_IS_LOGICAL( p2 ) ) { diff --git a/harbour/source/rtl/pad.c b/harbour/source/rtl/pad.c index ef9449a09a..19d0fcd648 100644 --- a/harbour/source/rtl/pad.c +++ b/harbour/source/rtl/pad.c @@ -52,11 +52,10 @@ #include "hbapi.h" -extern HB_FUNC( PADR ); +HB_FUNC_EXTERN( PADR ); /* synonymn for PADR */ HB_FUNC( PAD ) { HB_FUNCNAME( PADR )(); } - diff --git a/harbour/source/rtl/padc.c b/harbour/source/rtl/padc.c index 2b84679508..b1c92b35b2 100644 --- a/harbour/source/rtl/padc.c +++ b/harbour/source/rtl/padc.c @@ -58,10 +58,15 @@ HB_FUNC( PADC ) { ULONG ulSize; - char buffer[ 128 ]; - char * szText = hb_itemPadConv( hb_param( 1, HB_IT_ANY ), buffer, &ulSize ); + BOOL bFreeReq; + char * szText; - if( szText && ISNUM( 2 ) ) + if ( ISNUM( 2 ) ) + szText = hb_itemPadConv( hb_param( 1, HB_IT_ANY ), &ulSize, &bFreeReq ); + else + szText = NULL; + + if( szText ) { long lLen = hb_parnl( 2 ); @@ -92,8 +97,9 @@ HB_FUNC( PADC ) hb_retclen( szText, lLen ); } + if ( bFreeReq ) + hb_xfree( szText ); } else hb_retc( NULL ); } - diff --git a/harbour/source/rtl/padl.c b/harbour/source/rtl/padl.c index f1be546c86..f243af5a38 100644 --- a/harbour/source/rtl/padl.c +++ b/harbour/source/rtl/padl.c @@ -58,10 +58,15 @@ HB_FUNC( PADL ) { ULONG ulSize; - char buffer[ 128 ]; - char * szText = hb_itemPadConv( hb_param( 1, HB_IT_ANY ), buffer, &ulSize ); + BOOL bFreeReq; + char * szText; - if( szText && ISNUM( 2 ) ) + if ( ISNUM( 2 ) ) + szText = hb_itemPadConv( hb_param( 1, HB_IT_ANY ), &ulSize, &bFreeReq ); + else + szText = NULL; + + if( szText ) { long lLen = hb_parnl( 2 ); @@ -87,8 +92,9 @@ HB_FUNC( PADL ) hb_retclen( szText, lLen ); } + if ( bFreeReq ) + hb_xfree( szText ); } else hb_retc( NULL ); } - diff --git a/harbour/source/rtl/padr.c b/harbour/source/rtl/padr.c index 0dab6ca509..9682604988 100644 --- a/harbour/source/rtl/padr.c +++ b/harbour/source/rtl/padr.c @@ -58,10 +58,15 @@ HB_FUNC( PADR ) { ULONG ulSize; - char buffer[ 128 ]; - char * szText = hb_itemPadConv( hb_param( 1, HB_IT_ANY ), buffer, &ulSize ); + BOOL bFreeReq; + char * szText; - if( szText && ISNUM( 2 ) ) + if ( ISNUM( 2 ) ) + szText = hb_itemPadConv( hb_param( 1, HB_IT_ANY ), &ulSize, &bFreeReq ); + else + szText = NULL; + + if( szText ) { long lLen = hb_parnl( 2 ); @@ -87,8 +92,9 @@ HB_FUNC( PADR ) hb_retclen( szText, lLen ); } + if ( bFreeReq ) + hb_xfree( szText ); } else hb_retc( NULL ); } - diff --git a/harbour/source/rtl/philes.c b/harbour/source/rtl/philes.c index 495aec8674..f7998497ec 100644 --- a/harbour/source/rtl/philes.c +++ b/harbour/source/rtl/philes.c @@ -131,7 +131,7 @@ HB_FUNC( FWRITE ) if( ISNUM( 1 ) && ISCHAR( 2 ) ) hb_retnl( hb_fsWriteLarge( hb_parni( 1 ), ( BYTE * ) hb_parc( 2 ), - ISNUM( 3 ) ? hb_parnl( 3 ) : hb_parclen( 2 ) ) ); + ISNUM( 3 ) ? ( ULONG ) hb_parnl( 3 ) : hb_parclen( 2 ) ) ); else hb_retnl( 0 ); } diff --git a/harbour/source/rtl/round.c b/harbour/source/rtl/round.c index 339063ac07..5e617393db 100644 --- a/harbour/source/rtl/round.c +++ b/harbour/source/rtl/round.c @@ -76,44 +76,32 @@ HB_FUNC( INT ) if( pNumber ) { - double dNumber = hb_itemGetND( pNumber ); - int iWidth; + if( HB_IS_NUMINT( pNumber ) ) + hb_itemReturn( pNumber ); + else + { + int iWidth; - hb_itemGetNLen( pNumber, &iWidth, NULL ); - - hb_retndlen( dNumber >= 0 ? floor( dNumber ) : ceil( dNumber ), iWidth, 0 ); + hb_itemGetNLen( pNumber, &iWidth, NULL ); + hb_retnlen( hb_numInt( hb_itemGetND( pNumber ) ), iWidth, 0 ); + } } else hb_errRT_BASE_SubstR( EG_ARG, 1090, NULL, "INT", 1, hb_paramError( 1 ) ); } -double hb_numRound( double doValue, int nPrecision ) -{ - static const double doBase = 10.0f; - double doComplete5, doComplete5i; - - HB_TRACE(HB_TR_DEBUG, ("hb_numRound(%lf, %d)", doValue, nPrecision)); - - doComplete5 = doValue * pow( doBase, ( double ) ( nPrecision + 1 ) ); - - if( doValue < 0.0f ) - doComplete5 -= 5.0f; - else - doComplete5 += 5.0f; - - doComplete5 /= doBase; - modf( doComplete5, &doComplete5i ); - - return doComplete5i / pow( doBase, ( double ) nPrecision ); -} - HB_FUNC( ROUND ) { - if( ISNUM( 1 ) && ISNUM( 2 ) ) + PHB_ITEM pNumber = hb_param( 1, HB_IT_NUMERIC ); + + if( pNumber && ISNUM( 2 ) ) { int iDec = hb_parni( 2 ); - hb_retndlen( hb_numRound( hb_parnd( 1 ), iDec ), 0, HB_MAX( iDec, 0 ) ); + if( iDec == 0 && HB_IS_NUMINT( pNumber ) ) + hb_itemReturn( pNumber ); + else + hb_retnlen( hb_numRound( hb_itemGetND( pNumber ), iDec ), 0, HB_MAX( iDec, 0 ) ); } else hb_errRT_BASE_SubstR( EG_ARG, 1094, NULL, "ROUND", 2, hb_paramError( 1 ), hb_paramError( 2 ) ); diff --git a/harbour/source/rtl/soundex.c b/harbour/source/rtl/soundex.c index bd80eb72ee..1f2688a51e 100644 --- a/harbour/source/rtl/soundex.c +++ b/harbour/source/rtl/soundex.c @@ -94,7 +94,7 @@ HB_FUNC( SOUNDEX ) { static const char s_szTable[] = "01230120022455012623010202"; /* NOTE: SoundEx result codes for letters from "A" to "Z" */ /* "ABCDEFGHIJKLMNOPQRSTUVWXYZ" */ - char cCharConverted = ( ( cChar - 'A' ) > ( sizeof( s_szTable ) - 1 ) ) ? '9' : s_szTable[ cChar - 'A' ]; + char cCharConverted = ( ( cChar - 'A' ) > ( ( int ) sizeof( s_szTable ) - 1 ) ) ? '9' : s_szTable[ cChar - 'A' ]; if( nResultPos == 0 ) szResult[ nResultPos++ ] = cChar; diff --git a/harbour/source/rtl/str.c b/harbour/source/rtl/str.c index affd8634a3..5b41535df7 100644 --- a/harbour/source/rtl/str.c +++ b/harbour/source/rtl/str.c @@ -67,25 +67,15 @@ HB_FUNC( STR ) if( hb_pcount() >= 2 ) { - if( ISNUM( 2 ) ) - { - pWidth = hb_param( 2, HB_IT_NUMERIC ); - if( !pWidth ) - bValid = FALSE; - } - else if( !ISNIL( 2 ) ) + pWidth = hb_param( 2, HB_IT_NUMERIC ); + if( !pWidth ) bValid = FALSE; } if( hb_pcount() >= 3 ) { - if( ISNUM( 3 ) ) - { - pDec = hb_param( 3, HB_IT_NUMERIC ); - if( !pDec ) - bValid = FALSE; - } - else if( !ISNIL( 3 ) ) + pDec = hb_param( 3, HB_IT_NUMERIC ); + if( !pDec ) bValid = FALSE; } } @@ -102,6 +92,6 @@ HB_FUNC( STR ) hb_retc( NULL ); } else - hb_errRT_BASE_SubstR( EG_ARG, 1099, NULL, "STR", 3, hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); + hb_errRT_BASE_SubstR( EG_ARG, 1099, NULL, "STR", HB_MIN( hb_pcount(), 3 ), hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); } diff --git a/harbour/source/rtl/strcase.c b/harbour/source/rtl/strcase.c index 581fb6be1d..48928df404 100644 --- a/harbour/source/rtl/strcase.c +++ b/harbour/source/rtl/strcase.c @@ -93,68 +93,6 @@ char * hb_strUpper( char * szText, ULONG ulLen ) return szText; } -/* This function copies and converts szText to upper case. - */ -char * hb_strncpyUpper( char * pDest, const char * pSource, ULONG ulLen ) -{ - char *pBuf = pDest; - - HB_TRACE(HB_TR_DEBUG, ("hb_strncpyUpper(%p, %s, %lu)", pDest, pSource, ulLen)); - - pDest[ ulLen ] ='\0'; - - /* some compilers implements toupper as a macro, and this has side effects! */ - /* *pDest++ = toupper( *pSource++ ); */ - while( ulLen && (*pDest++ = toupper( *pSource )) != '\0' ) - { - ulLen--; - pSource++; - } - - while( ulLen > 0 ) - { - *pDest++ = '\0'; - ulLen--; - } - - return pBuf; -} - -/* This function copies and converts szText to upper case AND Trims it - */ -char * hb_strncpyUpperTrim( char * pDest, const char * pSource, ULONG ulLen ) -{ - char *pBuf = pDest; - LONG ulSLen = strlen( pSource ); - - HB_TRACE(HB_TR_DEBUG, ("hb_strncpyUpperTrim(%p, %s, %lu)", pDest, pSource, ulLen)); - - pDest[ ulLen ] ='\0'; - - while( ulSLen && pSource[ ulSLen - 1 ] == ' ') - { - ulSLen--; - } - - /* some compilers implements toupper as a macro, and this has side effects! */ - /* *pDest++ = toupper( *pSource++ ); */ - while( ulLen && ulSLen && (*pDest++ = toupper( *pSource ) ) != '\0' ) - { - ulSLen--; - ulLen--; - pSource++; - } - - while( ulLen > 0 ) - { - *pDest++ = '\0'; - ulLen--; - } - - return pBuf; -} - - /* converts string to lower case */ HB_FUNC( LOWER ) { diff --git a/harbour/source/rtl/strmatch.c b/harbour/source/rtl/strmatch.c index 8b2318e509..8375203137 100644 --- a/harbour/source/rtl/strmatch.c +++ b/harbour/source/rtl/strmatch.c @@ -97,6 +97,60 @@ static BOOL hb_strMatchDOS( const char * pszString, const char * pszMask ) ( *pszMask == '\0' && *pszString != '\0' ) ); } +#define HB_MAX_WILDPATTERN 256 + +BOOL HB_EXPORT hb_strMatchWild( const char *szString, const char *szPattern ) +{ + BOOL fMatch = TRUE, fAny = FALSE; + ULONG ulAnyPosP[HB_MAX_WILDPATTERN], ulAnyPosV[HB_MAX_WILDPATTERN], + ulSize, ulLen, ulAny, i, j; + + i = j = ulAny = 0; + ulLen = strlen( szString ); + ulSize = strlen( szPattern ); + while ( i < ulSize ) + { + if ( szPattern[i] == '*' ) + { + fAny = TRUE; + i++; + } + else if ( j < ulLen && ( szPattern[i] == '?' || szPattern[i] == szString[j] ) ) + { + if ( fAny ) + { + if ( ulAny < HB_MAX_WILDPATTERN ) + { + ulAnyPosP[ulAny] = i; + ulAnyPosV[ulAny] = j; + ulAny++; + } + fAny = FALSE; + } + j++; + i++; + } + else if ( fAny && j < ulLen ) + { + j++; + } + else if ( ulAny > 0 ) + { + ulAny--; + i = ulAnyPosP[ulAny]; + j = ulAnyPosV[ulAny] + 1; + fAny = TRUE; + } + else + { + fMatch = FALSE; + break; + } + } + return fMatch; +} + + /* TODO: Replace it with a code that supports real regular expressions * */ @@ -107,3 +161,13 @@ BOOL hb_strMatchRegExp( const char * szString, const char * szMask ) return hb_strMatchDOS( szString, szMask ); } + +/* + * WildMatch( cPattern, cValue ) compares cValue ith cPattern, cPattern + * may contain wildcard characters (?*) + */ +HB_FUNC( WILDMATCH ) +{ + hb_retl( ( ! ISCHAR( 1 ) || ! ISCHAR( 2 ) ) ? FALSE : + hb_strMatchWild( hb_parc( 2 ), hb_parc( 1 ) ) ); +} diff --git a/harbour/source/rtl/strtran.c b/harbour/source/rtl/strtran.c index 5bfdd1609d..5c85be1f49 100644 --- a/harbour/source/rtl/strtran.c +++ b/harbour/source/rtl/strtran.c @@ -189,9 +189,9 @@ HB_FUNC( STRTRAN ) hb_retclen( szText, ulText ); } else - hb_errRT_BASE_SubstR( EG_ARG, 1126, NULL, "STRTRAN", 3, hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); /* NOTE: Undocumented but existing Clipper Run-time error [vszakats] */ + hb_errRT_BASE_SubstR( EG_ARG, 1126, NULL, "STRTRAN", HB_MIN( hb_pcount(), 3 ), hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); /* NOTE: Undocumented but existing Clipper Run-time error [vszakats] */ } else - hb_errRT_BASE_SubstR( EG_ARG, 1126, NULL, "STRTRAN", 3, hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); /* NOTE: Undocumented but existing Clipper Run-time error [vszakats] */ + hb_errRT_BASE_SubstR( EG_ARG, 1126, NULL, "STRTRAN", HB_MIN( hb_pcount(), 3 ), hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); /* NOTE: Undocumented but existing Clipper Run-time error [vszakats] */ } diff --git a/harbour/source/rtl/strzero.c b/harbour/source/rtl/strzero.c index d31b5d3676..96480bf8b3 100644 --- a/harbour/source/rtl/strzero.c +++ b/harbour/source/rtl/strzero.c @@ -126,9 +126,9 @@ HB_FUNC( STRZERO ) /* NOTE: In CA-Cl*pper STRZERO() is written in Clipper, and will call STR() to do the job, the error (if any) will also be thrown by STR(). [vszakats] */ - hb_errRT_BASE_SubstR( EG_ARG, 1099, NULL, "STR", 3, hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); + hb_errRT_BASE_SubstR( EG_ARG, 1099, NULL, "STR", HB_MIN( hb_pcount(), 3 ), hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); #else - hb_errRT_BASE_SubstR( EG_ARG, 9999, NULL, "STRZERO", 3, hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); + hb_errRT_BASE_SubstR( EG_ARG, 9999, NULL, "STRZERO", HB_MIN( hb_pcount(), 3 ), hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); #endif } } diff --git a/harbour/source/rtl/substr.c b/harbour/source/rtl/substr.c index 5e8de9b218..da76a20872 100644 --- a/harbour/source/rtl/substr.c +++ b/harbour/source/rtl/substr.c @@ -90,7 +90,7 @@ HB_FUNC( SUBSTR ) } else { - hb_errRT_BASE_SubstR( EG_ARG, 1110, NULL, "SUBSTR", 3, hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); + hb_errRT_BASE_SubstR( EG_ARG, 1110, NULL, "SUBSTR", HB_MIN( hb_pcount(), 3 ), hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); /* NOTE: Exit from inside [vszakats] */ return; } @@ -107,5 +107,5 @@ HB_FUNC( SUBSTR ) hb_retc( NULL ); } else - hb_errRT_BASE_SubstR( EG_ARG, 1110, NULL, "SUBSTR", 3, hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); + hb_errRT_BASE_SubstR( EG_ARG, 1110, NULL, "SUBSTR", HB_MIN( hb_pcount(), 3 ), hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); } diff --git a/harbour/source/rtl/val.c b/harbour/source/rtl/val.c index b5ecd74e78..14e578d591 100644 --- a/harbour/source/rtl/val.c +++ b/harbour/source/rtl/val.c @@ -50,8 +50,6 @@ * */ -#include - #include "hbapi.h" #include "hbapiitm.h" #include "hbapierr.h" @@ -64,30 +62,18 @@ HB_FUNC( VAL ) if( pText ) { char * szText = hb_itemGetCPtr( pText ); - int iWidth = ( int ) hb_itemGetCLen( pText ); - int iDec; - double dValue = hb_strVal( szText, hb_itemGetCLen( pText ) ); + int iWidth, iDec, iLen = ( int ) hb_itemGetCLen( pText ); + BOOL fDbl; + HB_LONG lValue; + double dValue; - for( iDec = 0; iDec < iWidth && szText[ iDec ] != '.'; iDec++ ); + fDbl = hb_valStrnToNum( szText, iLen, &lValue, &dValue , &iDec, &iWidth ); - if( iDec >= iWidth - 1 ) - hb_retnlen( dValue, iWidth, 0 ); + if ( !fDbl ) + hb_retnintlen( lValue, iWidth ); else - { - /* NOTE: Kludge Warning! This condition: - "|| ( iDec == 1 && szText[ 0 ] == '-' && dValue != 0.0 )" - may not be the generic way to handle the width of this "-.1" - string. I could not find a matching case which - fails for the same reason, nor a better way to handle it. - The problem is that in this case only, the width is - calculated upon conditions which can only be discovered by - parsing the string, but the parsing is made by a lower level - generic function. [vszakats] */ - - hb_retnlen( dValue, iDec + ( iDec == 0 || ( iDec == 1 && szText[ 0 ] == '-' && dValue != 0.0 ) ? 1 : 0 ), iWidth - iDec - 1 ); - } + hb_retnlen( dValue, iWidth, iDec ); } else hb_errRT_BASE_SubstR( EG_ARG, 1098, NULL, "VAL", 1, hb_paramError( 1 ) ); } - diff --git a/harbour/source/vm/arrays.c b/harbour/source/vm/arrays.c index e4584d06f2..f1a8023240 100644 --- a/harbour/source/vm/arrays.c +++ b/harbour/source/vm/arrays.c @@ -350,6 +350,28 @@ long hb_arrayGetNL( PHB_ITEM pArray, ULONG ulIndex ) return 0; } +#ifndef HB_LONG_LONG_OFF +LONGLONG hb_arrayGetNLL( PHB_ITEM pArray, ULONG ulIndex ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_arrayGetNLL(%p, %lu)", pArray, ulIndex)); + + if( HB_IS_ARRAY( pArray ) && ulIndex > 0 && ulIndex <= pArray->item.asArray.value->ulLen ) + return hb_itemGetNLL( pArray->item.asArray.value->pItems + ulIndex - 1 ); + else + return 0; +} +#endif + +HB_LONG hb_arrayGetNInt( PHB_ITEM pArray, ULONG ulIndex ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_arrayGetNLL(%p, %lu)", pArray, ulIndex)); + + if( HB_IS_ARRAY( pArray ) && ulIndex > 0 && ulIndex <= pArray->item.asArray.value->ulLen ) + return hb_itemGetNInt( pArray->item.asArray.value->pItems + ulIndex - 1 ); + else + return 0; +} + double hb_arrayGetND( PHB_ITEM pArray, ULONG ulIndex ) { HB_TRACE(HB_TR_DEBUG, ("hb_arrayGetND(%p, %lu)", pArray, ulIndex)); @@ -513,7 +535,7 @@ ULONG hb_arrayScan( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * hb_vmPushSymbol( &hb_symEval ); hb_vmPush( pValue ); hb_vmPush( pBaseArray->pItems + ulStart ); - hb_vmPushNumber( ( double ) ( ulStart + 1 ), 0 ); + hb_vmPushLong( ulStart + 1 ); hb_vmDo( 2 ); if( HB_IS_LOGICAL( &hb_stack.Return ) && hb_stack.Return.item.asLogical.value ) @@ -546,7 +568,7 @@ ULONG hb_arrayScan( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * } else if( HB_IS_DATE( pValue ) ) { - long lValue = hb_itemGetDL( pValue ); + long lValue = hb_itemGetDL( pValue ); /* NOTE: This is correct: Get the date as a long value. [vszakats] */ for( ulStart--; ulCount > 0; ulCount--, ulStart++ ) { @@ -558,7 +580,7 @@ ULONG hb_arrayScan( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * } else if( HB_IS_LOGICAL( pValue ) ) { - BOOL bValue = hb_itemGetL( pValue ); /* NOTE: This is correct: Get the date as a long value. [vszakats] */ + BOOL bValue = hb_itemGetL( pValue ); for( ulStart--; ulCount > 0; ulCount--, ulStart++ ) { @@ -615,7 +637,7 @@ BOOL hb_arrayEval( PHB_ITEM pArray, PHB_ITEM bBlock, ULONG * pulStart, ULONG * p hb_vmPushSymbol( &hb_symEval ); hb_vmPush( bBlock ); hb_vmPush( pItem ); - hb_vmPushNumber( ( double ) ( ulStart + 1 ), 0 ); + hb_vmPushLong( ulStart + 1 ); hb_vmDo( 2 ); } } diff --git a/harbour/source/vm/codebloc.c b/harbour/source/vm/codebloc.c index e6031127ee..4854d73337 100644 --- a/harbour/source/vm/codebloc.c +++ b/harbour/source/vm/codebloc.c @@ -69,7 +69,7 @@ */ HB_CODEBLOCK_PTR hb_codeblockNew( BYTE * pBuffer, USHORT uiLocals, - USHORT * pLocalPosTable, + BYTE * pLocalPosTable, PHB_SYMB pSymbols ) { HB_CODEBLOCK_PTR pCBlock; @@ -107,7 +107,8 @@ HB_CODEBLOCK_PTR hb_codeblockNew( BYTE * pBuffer, * TODO: If Harbour will support threads in the future then we need * to implement some kind of semaphores here. */ - pLocal = hb_stackItemFromBase( *pLocalPosTable++ ); + pLocal = hb_stackItemFromBase( HB_PCODE_MKUSHORT( pLocalPosTable ) ); + pLocalPosTable += 2; if( ! HB_IS_MEMVAR( pLocal ) ) { diff --git a/harbour/source/vm/estack.c b/harbour/source/vm/estack.c index 2f69b1c299..f508528eca 100644 --- a/harbour/source/vm/estack.c +++ b/harbour/source/vm/estack.c @@ -309,7 +309,7 @@ void hb_stackDispLocal( void ) break; case HB_IT_LONG: - printf( HB_I_("LONG = %lu "), hb_itemGetNL( *pBase ) ); + printf( HB_I_("LONG = %" PFHL "i ") , hb_itemGetNInt( *pBase ) ); break; case HB_IT_INTEGER: diff --git a/harbour/source/vm/eval.c b/harbour/source/vm/eval.c index d060a75a1b..c38ff4fd2b 100644 --- a/harbour/source/vm/eval.c +++ b/harbour/source/vm/eval.c @@ -351,9 +351,6 @@ HB_FUNC( HB_FORNEXT ) /* nStart, nEnd | bEnd, bCode, nStep */ PHB_ITEM pCodeBlock = hb_param( 3, HB_IT_BLOCK ); LONG lStep = ( hb_pcount() > 3 ) ? hb_parnl( 4 ) : 1; - if( ! pEndBlock ) - lEnd = hb_parnl( 2 ); - if( pCodeBlock ) { if( pEndBlock ) @@ -376,6 +373,7 @@ HB_FUNC( HB_FORNEXT ) /* nStart, nEnd | bEnd, bCode, nStep */ } else { + lEnd = hb_parnl( 2 ); while( lStart <= lEnd ) { hb_vmPushSymbol( &hb_symEval ); diff --git a/harbour/source/vm/extend.c b/harbour/source/vm/extend.c index 95d49d0e13..637b3cffdd 100644 --- a/harbour/source/vm/extend.c +++ b/harbour/source/vm/extend.c @@ -403,13 +403,17 @@ long HB_EXPORT hb_parnl( int iParam, ... ) pItem = hb_itemUnRef( pItem ); if( HB_IS_LONG( pItem ) ) - return pItem->item.asLong.value; + return ( long ) pItem->item.asLong.value; else if( HB_IS_INTEGER( pItem ) ) return ( long ) pItem->item.asInteger.value; else if( HB_IS_DOUBLE( pItem ) ) +#ifdef __GCC_ + return ( long ) ( unsigned long ) pItem->item.asDouble.value; +#else return ( long ) pItem->item.asDouble.value; +#endif else if( HB_IS_DATE( pItem ) ) - return pItem->item.asDate.value; + return ( long ) pItem->item.asDate.value; else if( HB_IS_ARRAY( pItem ) ) { va_list va; @@ -426,6 +430,47 @@ long HB_EXPORT hb_parnl( int iParam, ... ) return 0; } +#ifndef HB_LONG_LONG_OFF +LONGLONG HB_EXPORT hb_parnll( int iParam, ... ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_parnll(%d, ...)", iParam)); + + if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) + { + PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + + if( HB_IS_BYREF( pItem ) ) + pItem = hb_itemUnRef( pItem ); + + if( HB_IS_LONG( pItem ) ) + return ( LONGLONG ) pItem->item.asLong.value; + else if( HB_IS_INTEGER( pItem ) ) + return ( LONGLONG ) pItem->item.asInteger.value; + else if( HB_IS_DOUBLE( pItem ) ) +#ifdef __GCC_ + return ( LONGLONG ) ( ULONGLONG ) pItem->item.asDouble.value; +#else + return ( LONGLONG ) pItem->item.asDouble.value; +#endif + else if( HB_IS_DATE( pItem ) ) + return ( LONGLONG ) pItem->item.asDate.value; + else if( HB_IS_ARRAY( pItem ) ) + { + va_list va; + ULONG ulArrayIndex; + + va_start( va, iParam ); + ulArrayIndex = va_arg( va, ULONG ); + va_end( va ); + + return hb_arrayGetNLL( pItem, ulArrayIndex ); + } + } + + return 0; +} +#endif + void HB_EXPORT * hb_parptr( int iParam, ... ) { HB_TRACE(HB_TR_DEBUG, ("hb_parptr(%d, ...)", iParam)); @@ -576,11 +621,11 @@ void HB_EXPORT hb_retds( char * szDate ) } #undef hb_retd -void HB_EXPORT hb_retd( long lYear, long lMonth, long lDay ) +void HB_EXPORT hb_retd( int iYear, int iMonth, int iDay ) { - HB_TRACE(HB_TR_DEBUG, ("hb_retd(%04i, %02i, %02i)", lYear, lMonth, lDay)); + HB_TRACE(HB_TR_DEBUG, ("hb_retd(%04i, %02i, %02i)", iYear, iMonth, iDay)); - hb_itemPutD( &hb_stack.Return, lYear, lMonth, lDay ); + hb_itemPutD( &hb_stack.Return, iYear, iMonth, iDay ); } #undef hb_retdl @@ -623,6 +668,24 @@ void HB_EXPORT hb_retnl( long lNumber ) hb_itemPutNL( &hb_stack.Return, lNumber ); } +#ifndef HB_LONG_LONG_OFF +#undef hb_retnll +void HB_EXPORT hb_retnll( LONGLONG llNumber ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_retnll(%" PFLL "d)", llNumber)); + + hb_itemPutNLL( &hb_stack.Return, llNumber ); +} +#endif + +#undef hb_retnint +void HB_EXPORT hb_retnint( HB_LONG lNumber ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_retnl(%ld)", lNumber)); + + hb_itemPutNInt( &hb_stack.Return, lNumber ); +} + #undef hb_retnlen void HB_EXPORT hb_retnlen( double dNumber, int iWidth, int iDec ) { @@ -655,6 +718,24 @@ void HB_EXPORT hb_retnllen( long lNumber, int iWidth ) hb_itemPutNLLen( &hb_stack.Return, lNumber, iWidth ); } +#ifndef HB_LONG_LONG_OFF +#undef hb_retnlllen +void HB_EXPORT hb_retnlllen( LONGLONG llNumber, int iWidth ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_retnlllen(%" PFLL "d, %d)", llNumber, iWidth)); + + hb_itemPutNLLLen( &hb_stack.Return, llNumber, iWidth ); +} +#endif + +#undef hb_retnintlen +void HB_EXPORT hb_retnintlen( HB_LONG lNumber, int iWidth ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_retnintlen(%" PFHL "d, %d)", lNumber, iWidth)); + + hb_itemPutNIntLen( &hb_stack.Return, lNumber, iWidth ); +} + #undef hb_retptr void HB_EXPORT hb_retptr( void * pointer ) { @@ -870,6 +951,76 @@ int HB_EXPORT hb_stornl( long lValue, int iParam, ... ) return 0; } +#ifndef HB_LONG_LONG_OFF +int HB_EXPORT hb_stornll( LONGLONG llValue, int iParam, ... ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_stornll(%" PFLL "d, %d, ...)", llValue, iParam)); + + if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) + { + PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + BOOL bByRef = HB_IS_BYREF( pItem ); + + if( bByRef ) + pItem = hb_itemUnRef( pItem ); + + if( HB_IS_ARRAY( pItem ) ) + { + va_list va; + PHB_ITEM pItemNew = hb_itemPutNLL( NULL, llValue ); + va_start( va, iParam ); + hb_arraySet( pItem, va_arg( va, ULONG ), pItemNew ); + va_end( va ); + hb_itemRelease( pItemNew ); + return 1; + } + else if( bByRef || iParam == -1 ) + { + hb_itemPutNLL( pItem, llValue ); + return 1; + } + + return 0; + } + + return 0; +} +#endif + +int HB_EXPORT hb_stornint( HB_LONG lValue, int iParam, ... ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_stornint(%" PFHL "d, %d, ...)", lValue, iParam)); + + if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) + { + PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + BOOL bByRef = HB_IS_BYREF( pItem ); + + if( bByRef ) + pItem = hb_itemUnRef( pItem ); + + if( HB_IS_ARRAY( pItem ) ) + { + va_list va; + PHB_ITEM pItemNew = hb_itemPutNInt( NULL, lValue ); + va_start( va, iParam ); + hb_arraySet( pItem, va_arg( va, ULONG ), pItemNew ); + va_end( va ); + hb_itemRelease( pItemNew ); + return 1; + } + else if( bByRef || iParam == -1 ) + { + hb_itemPutNInt( pItem, lValue ); + return 1; + } + + return 0; + } + + return 0; +} + int HB_EXPORT hb_stornd( double dNumber, int iParam, ... ) { HB_TRACE(HB_TR_DEBUG, ("hb_stornd(%lf, %d, ...)", dNumber, iParam)); diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 9c9d22aea1..c4e57f4be3 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -173,6 +173,14 @@ static void hb_vmPushMacroBlock( BYTE * pCode, PHB_SYMB pSymbols ); /* create static void hb_vmPushLocal( SHORT iLocal ); /* pushes the containts of a local onto the stack */ static void hb_vmPushLocalByRef( SHORT iLocal ); /* pushes a local by refrence onto the stack */ static void hb_vmPushLongConst( long lNumber ); /* Pushes a long constant (pcode) */ +static void hb_vmPushHBLong( HB_LONG lNumber ); /* pushes a HB_LONG number onto the stack */ +#if !defined( HB_LONG_LONG_OFF ) + static void hb_vmPushLongLongConst( LONGLONG lNumber ); /* Pushes a long long constant (pcode) */ +#endif +#if HB_INT_MAX >= INT32_MAX +static void hb_vmPushIntegerConst( int iNumber ); /* Pushes a int constant (pcode) */ +#endif +static void hb_vmPushNumInt( HB_LONG lNumber ); /* pushes a number on to the stack and decides if it is integer or HB_LONG */ extern void hb_vmPushNumType( double dNumber, int iDec, int iType1, int iType2 ); /* pushes a number on to the stack and decides if it is integer, long or double */ static void hb_vmPushStatic( USHORT uiStatic ); /* pushes the containts of a static onto the stack */ static void hb_vmPushStaticByRef( USHORT uiStatic ); /* pushes a static by refrence onto the stack */ @@ -183,6 +191,7 @@ static void hb_vmDuplTwo( void ); /* duplicates the latest two v /* Pop */ static BOOL hb_vmPopLogical( void ); /* pops the stack latest value and returns its logical value */ static long hb_vmPopDate( void ); /* pops the stack latest value and returns its date value as a long */ +static HB_LONG hb_vmPopHBLong( void ); /* pops the stack latest value and returns its HB_LONG value */ static double hb_vmPopNumber( void ); /* pops the stack latest value and returns its numeric value */ static double hb_vmPopDouble( int * ); /* pops the stack latest value and returns its double numeric format value */ static void hb_vmPopAlias( void ); /* pops the workarea number form the eval stack */ @@ -497,7 +506,6 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) LONG w = 0; BOOL bCanRecover = FALSE; ULONG ulPrivateBase; - LONG lOffset; ULONG ulLastOpcode = 0; /* opcodes profiler support */ ULONG ulPastClock = 0; /* opcodes profiler support */ #ifndef HB_GUI @@ -665,12 +673,12 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_ARRAYDIM: - hb_vmArrayDim( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmArrayDim( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; case HB_P_ARRAYGEN: - hb_vmArrayGen( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + hb_vm_iExtraElements ); + hb_vmArrayGen( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) + hb_vm_iExtraElements ); hb_vm_iExtraElements = 0; w += 3; break; @@ -678,7 +686,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* Object */ case HB_P_MESSAGE: - hb_vmPushSymbol( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_vmPushSymbol( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; @@ -692,7 +700,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* Execution */ case HB_P_DO: - hb_vmDo( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmDo( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; @@ -705,7 +713,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) if( ( &hb_stack.Return )->type ) hb_itemClear( &hb_stack.Return ); - hb_vmDo( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmDo( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); hb_itemMove( hb_stackTopItem(), &hb_stack.Return ); hb_stackPush(); w += 3; @@ -725,10 +733,11 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) if( ( &hb_stack.Return )->type ) hb_itemClear( &hb_stack.Return ); - hb_vmSend( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmSend( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; - if( pCode[ 3 ] == HB_P_POP ) + /* Is This OK??? */ + if( pCode[ w ] == HB_P_POP ) w++; else { @@ -757,14 +766,14 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) HB_TRACE(HB_TR_INFO, ("Opcode: HB_P_LINE: %s (%i)", (hb_stackBaseItem())->item.asSymbol.value->szName, (hb_stackBaseItem())->item.asSymbol.lineno)); - (hb_stackBaseItem())->item.asSymbol.lineno = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); + (hb_stackBaseItem())->item.asSymbol.lineno = HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); if( s_bDebugging && s_bDebugShowLines ) - hb_vmDebuggerShowLine( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmDebuggerShowLine( (hb_stackBaseItem())->item.asSymbol.lineno ); w += 3; break; case HB_P_PARAMETER: - hb_memvarNewParameter( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ), hb_stackItemFromBase( pCode[ w + 3 ] ) ); + hb_memvarNewParameter( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ), hb_stackItemFromBase( pCode[ w + 3 ] ) ); HB_TRACE(HB_TR_INFO, ("(hb_vmPopParameter)")); w += 4; break; @@ -775,12 +784,12 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_SFRAME: - hb_vmSFrame( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_vmSFrame( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; case HB_P_STATICS: - hb_vmStatics( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ), pCode[ w + 3 ] + ( pCode[ w + 4 ] * 256 ) ); + hb_vmStatics( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ), HB_PCODE_MKUSHORT( &( pCode[ w + 3 ] ) ) ); w += 5; break; @@ -790,15 +799,15 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_LOCALNAME: - hb_vmLocalName( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ), + hb_vmLocalName( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ), ( char * ) pCode + w + 3 ); w += 3; while( pCode[ w++ ] ); break; case HB_P_STATICNAME: - hb_vmStaticName( pCode[ w + 1 ], pCode[ w + 2 ] + ( pCode[ w + 3 ] * 256 ), - ( char * ) pCode + w + 4 ); + hb_vmStaticName( pCode[ w + 1 ], HB_PCODE_MKUSHORT( &( pCode[ w + 2 ] ) ), + ( char * ) pCode + w + 4 ); w += 4; while( pCode[ w++ ] ); break; @@ -835,12 +844,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) * 2) store the address of RECOVER or END opcode */ ( hb_stackTopItem() )->type = HB_IT_LONG; - - lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 ); - if( lOffset > 8388607L ) - lOffset = ( lOffset - 16777216 ); - - ( hb_stackTopItem() )->item.asLong.value = w + lOffset; + ( hb_stackTopItem() )->item.asLong.value = w + HB_PCODE_MKINT24( &pCode[ w + 1 ] );; hb_stackPush(); /* * 3) store current RECOVER base @@ -896,11 +900,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* * skip outside of SEQUENCE structure */ - lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 ); - if( lOffset > 8388607L ) - lOffset = ( lOffset - 16777216 ); - - w += lOffset; + w += HB_PCODE_MKINT24( &pCode[ w + 1 ] ); break; case HB_P_SEQRECOVER: @@ -934,102 +934,55 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* Jumps */ case HB_P_JUMPNEAR: - - lOffset = pCode[ w + 1 ]; - if( lOffset > 127 ) - lOffset -= 256 ; - w += lOffset; + w += (signed char) pCode[ w + 1 ]; break; case HB_P_JUMP: - - lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); - if( lOffset > SHRT_MAX ) - lOffset -= 65536; - w += lOffset; + w += HB_PCODE_MKSHORT( &( pCode[ w + 1 ] ) );; break; case HB_P_JUMPFAR: - lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536L ); - if( lOffset > 8388607L ) - lOffset -= 16777216L; - w += lOffset; + w += HB_PCODE_MKINT24( &pCode[ w + 1 ] ); break; case HB_P_JUMPFALSENEAR: if( ! hb_vmPopLogical() ) - { - lOffset = pCode[ w + 1 ]; - if( lOffset > 127 ) - lOffset -= 256; - - w += lOffset; - } + w += (signed char) pCode[ w + 1 ]; else w += 2; break; case HB_P_JUMPFALSE: if( ! hb_vmPopLogical() ) - { - lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); - if( lOffset > SHRT_MAX ) - lOffset -= 65536; - - w += lOffset; - } + w += HB_PCODE_MKSHORT( &pCode[ w + 1 ] ); else w += 3; break; case HB_P_JUMPFALSEFAR: if( ! hb_vmPopLogical() ) - { - lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 ); - if( lOffset > 8388607L ) - lOffset -= 16777216L; - - w += lOffset; - } + w += HB_PCODE_MKINT24( &pCode[ w + 1 ] ); else w += 4; break; case HB_P_JUMPTRUENEAR: if( hb_vmPopLogical() ) - { - lOffset = pCode[ w + 1 ]; - if( lOffset > 127 ) - lOffset -= 256; - - w += lOffset; - } + w += (signed char) pCode[ w + 1 ]; else w += 2; break; case HB_P_JUMPTRUE: if( hb_vmPopLogical() ) - { - lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); - if( lOffset > SHRT_MAX ) - lOffset -= 65536; - - w += lOffset; - } + w += HB_PCODE_MKSHORT( &pCode[ w + 1 ] ); else w += 3; break; case HB_P_JUMPTRUEFAR: if( hb_vmPopLogical() ) - { - lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 ); - if( lOffset > 8388607L ) - lOffset -= 16777216L; - - w += lOffset; - } + w += HB_PCODE_MKINT24( &pCode[ w + 1 ] ); else w += 4; break; @@ -1096,7 +1049,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) PHB_ITEM pStackTopItem = hb_stackTopItem(); pStackTopItem->type = HB_IT_INTEGER; - pStackTopItem->item.asInteger.value = ( int ) pCode[ w + 1 ]; + pStackTopItem->item.asInteger.value = ( signed char ) pCode[ w + 1 ]; pStackTopItem->item.asInteger.length = 10; hb_stackPush(); HB_TRACE(HB_TR_INFO, ("(HB_P_PUSHBYTE)")); @@ -1105,25 +1058,35 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_PUSHINT: - { - PHB_ITEM pStackTopItem = hb_stackTopItem(); - - pStackTopItem->type = HB_IT_INTEGER; - pStackTopItem->item.asInteger.value = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); - pStackTopItem->item.asInteger.length = 10; - hb_stackPush(); - HB_TRACE(HB_TR_INFO, ("(HB_P_PUSHINT)")); - w += 3; - } + HB_TRACE(HB_TR_INFO, ("(HB_P_PUSHINT)")); + hb_vmPushInteger( HB_PCODE_MKSHORT( &pCode[ w + 1 ] ) ); + w += 3; break; case HB_P_PUSHLONG: - hb_vmPushLongConst( * ( long * ) ( &pCode[ w + 1 ] ) ); + HB_TRACE( HB_TR_DEBUG, ("(HB_P_PUSHLONG)") ); +#if HB_INT_MAX >= INT32_MAX + hb_vmPushIntegerConst( ( int ) HB_PCODE_MKLONG( &pCode[ w + 1 ] ) ); +#else + hb_vmPushLongConst( ( long ) HB_PCODE_MKLONG( &pCode[ w + 1 ] ) ); +#endif w += 5; break; + case HB_P_PUSHLONGLONG: + HB_TRACE( HB_TR_DEBUG, ("(HB_P_PUSHLONGLONG)") ); +#if !defined( HB_LONG_LONG_OFF ) + hb_vmPushLongLongConst( HB_PCODE_MKLONGLONG( &pCode[ w + 1 ] ) ); +#else + hb_vmPushDoubleConst( HB_PCODE_MKLONGLONG( &pCode[ w + 1 ] ), + HB_DEFAULT_WIDTH, HB_DEFAULT_DECIMALS ); +#endif + w += 9; + + break; + case HB_P_PUSHDOUBLE: - hb_vmPushDoubleConst( * ( double * ) ( &pCode[ w + 1 ] ), + hb_vmPushDoubleConst( HB_PCODE_MKDOUBLE( &pCode[ w + 1 ] ), ( int ) * ( BYTE * ) &pCode[ w + 1 + sizeof( double ) ], ( int ) * ( BYTE * ) &pCode[ w + 1 + sizeof( double ) + sizeof( BYTE ) ] ); w += 1 + sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE ); @@ -1131,7 +1094,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_PUSHSTR: { - USHORT uiSize = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); + USHORT uiSize = HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); hb_vmPushStringPcode( ( char * ) pCode + w + 3, ( ULONG ) uiSize - 1 ); w += ( 3 + uiSize ); break; @@ -1150,7 +1113,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) * +7 -> start of table with referenced local variables */ hb_vmPushBlock( ( BYTE * ) ( pCode + w ), pSymbols ); - w += ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + w += HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); break; case HB_P_PUSHBLOCKSHORT: @@ -1167,12 +1130,12 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_PUSHSYM: - hb_vmPushSymbol( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_vmPushSymbol( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; case HB_P_PUSHSYMNEAR: - hb_vmPushSymbol( pSymbols + ( USHORT ) pCode[ w + 1 ] ); + hb_vmPushSymbol( pSymbols + pCode[ w + 1 ] ); w += 2; break; @@ -1182,7 +1145,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_PUSHALIASEDFIELD: - hb_vmPushAliasedField( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_vmPushAliasedField( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; @@ -1192,21 +1155,21 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_PUSHALIASEDVAR: - hb_vmPushAliasedVar( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_vmPushAliasedVar( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; case HB_P_PUSHFIELD: /* It pushes the current value of the given field onto the eval stack */ - hb_rddGetFieldValue( ( hb_stackTopItem() ), pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_rddGetFieldValue( ( hb_stackTopItem() ), pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); hb_stackPush(); HB_TRACE(HB_TR_INFO, ("(hb_vmPushField)")); w += 3; break; case HB_P_PUSHLOCAL: - hb_vmPushLocal( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmPushLocal( HB_PCODE_MKSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; @@ -1216,29 +1179,29 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_PUSHLOCALREF: - hb_vmPushLocalByRef( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmPushLocalByRef( HB_PCODE_MKSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; case HB_P_PUSHSTATIC: - hb_vmPushStatic( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmPushStatic( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; case HB_P_PUSHSTATICREF: - hb_vmPushStaticByRef( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmPushStaticByRef( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; case HB_P_PUSHMEMVAR: - hb_memvarGetValue( ( hb_stackTopItem() ), pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_memvarGetValue( ( hb_stackTopItem() ), pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); hb_stackPush(); HB_TRACE(HB_TR_INFO, ("(hb_vmPushMemvar)")); w += 3; break; case HB_P_PUSHMEMVARREF: - hb_memvarGetRefer( ( hb_stackTopItem() ), pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_memvarGetRefer( ( hb_stackTopItem() ), pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); hb_stackPush(); HB_TRACE(HB_TR_INFO, ("(hb_vmPushMemvarRef)")); w += 3; @@ -1247,7 +1210,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_PUSHVARIABLE: /* Push a value of variable of unknown type onto the eval stack */ - hb_vmPushVariable( pSymbols + pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmPushVariable( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; @@ -1274,7 +1237,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_POPALIASEDFIELD: - hb_vmPopAliasedField( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_vmPopAliasedField( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; @@ -1284,7 +1247,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_POPALIASEDVAR: - hb_vmPopAliasedVar( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_vmPopAliasedVar( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; @@ -1292,7 +1255,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* Pops a value from the eval stack and uses it to set * a new value of the given field */ - hb_rddPutFieldValue( ( hb_stackItemFromTop(-1) ), pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); + hb_rddPutFieldValue( ( hb_stackItemFromTop(-1) ), pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); hb_stackDec(); hb_itemClear( ( hb_stackTopItem() ) ); HB_TRACE(HB_TR_INFO, ("(hb_vmPopField)")); @@ -1300,7 +1263,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_POPLOCAL: - hb_vmPopLocal( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmPopLocal( HB_PCODE_MKSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; @@ -1310,13 +1273,13 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_POPSTATIC: - hb_vmPopStatic( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmPopStatic( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; break; case HB_P_POPMEMVAR: hb_stackDec(); - hb_memvarSetValue( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ), ( hb_stackTopItem() ) ); + hb_memvarSetValue( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ), ( hb_stackTopItem() ) ); hb_itemClear( ( hb_stackTopItem() ) ); HB_TRACE(HB_TR_INFO, ("(hb_vmPopMemvar)")); w += 3; @@ -1330,7 +1293,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* Pops a value from the eval stack and uses it to set * a new value of a variable of unknown type. */ - uiParams = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); + uiParams = HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); /* First try if passed symbol is a name of field * in a current workarea - if it is not a field (FAILURE) * then try the memvar variable (it will create PRIVATE @@ -1402,7 +1365,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) } else { - hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] = pSymbols + ( USHORT ) ( pCode[w + 1] + ( pCode[w + 2] * 256 ) ); + hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] = pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); w += 3; } } @@ -1604,7 +1567,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) * +5 -> pcode bytes */ hb_vmPushMacroBlock( ( BYTE * ) ( pCode + w ), pSymbols ); - w += ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + w += HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); break; } @@ -1658,7 +1621,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_MPUSHSTR: { - USHORT uiSize = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); + USHORT uiSize = HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); hb_vmPushString( ( char * ) ( pCode ) + w + 3, ( ULONG )( uiSize - 1 ) ); w += ( 3 + uiSize ); @@ -1668,7 +1631,6 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_LOCALNEARADDINT: HB_TRACE( HB_TR_DEBUG, ("HB_P_LOCALNEARADDINT") ); { - #define HB_PCODE_MKSHORT( p ) ( *( SHORT * )( p ) ) PHB_ITEM pLocal = hb_stackItemFromBase( pCode[ w + 1 ] ); short iAdd = HB_PCODE_MKSHORT( &( pCode[ w + 2 ] ) ); double dNewVal; @@ -1680,23 +1642,32 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) pLocal = hb_itemUnRef( pLocal ); } - if( pLocal->type & HB_IT_INTEGER ) + if( HB_IS_NUMINT( pLocal ) ) { - dNewVal = pLocal->item.asInteger.value + iAdd; - } - else if( pLocal->type & HB_IT_LONG ) - { - dNewVal = pLocal->item.asLong.value + iAdd; - } - else if( pLocal->type & HB_IT_DOUBLE ) - { - dNewVal = pLocal->item.asDouble.value + iAdd; + HB_LONG lNewVal, lVal; + + lVal = hb_itemGetNInt( pLocal ); + lNewVal = lVal + iAdd; + + if( iAdd >= 0 ? lNewVal >= lVal : lNewVal < lVal ) + { + hb_itemPutNInt( pLocal, lNewVal ); + break; + } + else + { + dNewVal = ( double ) lVal + ( double ) iAdd; + } } else if( HB_IS_DATE( pLocal ) ) { pLocal->item.asDate.value += iAdd; break; } + else if( pLocal->type & HB_IT_DOUBLE ) + { + dNewVal = pLocal->item.asDouble.value + iAdd; + } else { PHB_ITEM pAdd = hb_itemPutNI( NULL, ( int ) iAdd ); @@ -1712,28 +1683,13 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; } - if( pLocal->type & HB_IT_DOUBLE ) - { - pLocal->item.asDouble.value = dNewVal; - } - else if( SHRT_MIN <= dNewVal && dNewVal <= SHRT_MAX ) - { - pLocal->type = HB_IT_INTEGER; - pLocal->item.asInteger.value = ( int ) dNewVal; - } - else if( LONG_MIN <= dNewVal && dNewVal <= LONG_MAX ) - { - pLocal->type = HB_IT_LONG; - pLocal->item.asLong.value = ( long ) dNewVal; - } - else + if( !HB_IS_DOUBLE( pLocal ) ) { pLocal->type = HB_IT_DOUBLE; - pLocal->item.asDouble.value = dNewVal; - pLocal->item.asDouble.length = ( dNewVal >= 10000000000.0 || dNewVal <= -1000000000.0 ) ? 20 : 10; pLocal->item.asDouble.decimal = hb_set.HB_SET_DECIMALS; } - + pLocal->item.asDouble.value = dNewVal; + pLocal->item.asDouble.length = HB_DBL_LENGTH( dNewVal ); break; } @@ -1811,19 +1767,49 @@ static void hb_vmNegate( void ) if( HB_IS_INTEGER( pItem ) ) { - pItem->item.asInteger.value = -pItem->item.asInteger.value; - pItem->item.asInteger.length = 10; +#if -HB_INT_MAX > HB_INT_MIN + if ( pItem->item.asInteger.value < -HB_INT_MAX ) + { +#if HB_LONG_MAX > HB_INT_MAX + HB_LONG lValue = ( HB_LONG ) pItem->item.asInteger.value; + pItem->type = HB_IT_LONG; + pItem->item.asLong.value = -lValue; + pItem->item.asLong.length = HB_LONG_LENGTH( -lValue ); +#else + double dValue = ( double ) pItem->item.asInteger.value; + pItem->type = HB_IT_DOUBLE; + pItem->item.asDouble.value = -dValue; + pItem->item.asDouble.length = HB_DBL_LENGTH( -dValue ); +#endif + } + else +#endif + { + pItem->item.asInteger.value = -pItem->item.asInteger.value; + pItem->item.asInteger.length = HB_INT_LENGTH( pItem->item.asInteger.value ); + } } else if( HB_IS_LONG( pItem ) ) { - pItem->item.asLong.value = -pItem->item.asLong.value; - pItem->item.asLong.length = ( pItem->item.asLong.value <= -1000000000 ) ? 20 : 10; +#if -HB_LONG_MAX > HB_LONG_MIN + if ( pItem->item.asLong.value < -HB_LONG_MAX ) + { + double dValue = ( double ) pItem->item.asLong.value; + pItem->type = HB_IT_DOUBLE; + pItem->item.asDouble.value = -dValue; + pItem->item.asDouble.length = HB_DBL_LENGTH( -dValue ); + } + else +#endif + { + pItem->item.asLong.value = -pItem->item.asLong.value; + pItem->item.asLong.length = HB_LONG_LENGTH( pItem->item.asLong.value ); + } } else if( HB_IS_DOUBLE( pItem ) ) { pItem->item.asDouble.value = -pItem->item.asDouble.value; - /* NOTE: Yes, -999999999.0 is right instead of -1000000000.0 [vszakats] */ - pItem->item.asDouble.length = ( pItem->item.asDouble.value >= 10000000000.0 || pItem->item.asDouble.value <= -999999999.0 ) ? 20 : 10; + pItem->item.asDouble.length = HB_DBL_LENGTH( pItem->item.asDouble.value ); } else { @@ -1848,7 +1834,17 @@ static void hb_vmPlus( void ) pItem1 = hb_stackItemFromTop( -2 ); pItem2 = hb_stackItemFromTop( -1 ); - if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) + if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) ) + { + HB_LONG lNumber2 = hb_vmPopHBLong(); + HB_LONG lNumber1 = hb_vmPopHBLong(); + HB_LONG lResult = lNumber1 + lNumber2; + if ( lNumber2 >= 0 ? lResult >= lNumber1 : lResult < lNumber1 ) + hb_vmPushNumInt( lResult ); + else + hb_vmPushDouble( ( double ) lNumber1 + ( double ) lNumber2, 0 ); + } + else if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) { int iDec2, iDec1, iType2 = pItem2->type, iType1 = pItem2->type; double dNumber2 = hb_vmPopDouble( &iDec2 ); @@ -1915,7 +1911,17 @@ static void hb_vmMinus( void ) pItem1 = hb_stackItemFromTop( -2 ); pItem2 = hb_stackItemFromTop( -1 ); - if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) + if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) ) + { + HB_LONG lNumber2 = hb_vmPopHBLong(); + HB_LONG lNumber1 = hb_vmPopHBLong(); + HB_LONG lResult = lNumber1 - lNumber2; + if ( lNumber2 <= 0 ? lResult >= lNumber1 : lResult < lNumber1 ) + hb_vmPushNumInt( lResult ); + else + hb_vmPushDouble( ( double ) lNumber1 - ( double ) lNumber2, 0 ); + } + else if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) { int iDec2, iDec1, iType2 = pItem2->type, iType1 = pItem1->type; double dNumber2 = hb_vmPopDouble( &iDec2 ); @@ -1928,7 +1934,7 @@ static void hb_vmMinus( void ) long lDate2 = hb_vmPopDate(); long lDate1 = hb_vmPopDate(); - hb_vmPushLong( lDate1 - lDate2 ); + hb_vmPushNumInt( lDate1 - lDate2 ); } else if( HB_IS_DATE( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) { @@ -1988,7 +1994,17 @@ static void hb_vmMult( void ) pItem1 = hb_stackItemFromTop( -2 ); pItem2 = hb_stackItemFromTop( -1 ); - if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) + /* if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) ) + { + HB_LONG lNumber2 = hb_vmPopHBLong(); + HB_LONG lNumber1 = hb_vmPopHBLong(); + HB_LONG lResult = lNumber1 * lNumber2; + if ( lNumber2 == 0 || lResult / lNumber2 == lNumber1 ) + hb_vmPushNumInt( lResult ); + else + hb_vmPushDouble( ( double ) lNumber1 * ( double ) lNumber2, 0 ); + } + else */ if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) { int iDec2, iDec1, iType2 = pItem2->type, iType1 = pItem1->type; double d2 = hb_vmPopDouble( &iDec2 ); @@ -2023,7 +2039,27 @@ static void hb_vmDivide( void ) pItem1 = hb_stackItemFromTop( -2 ); pItem2 = hb_stackItemFromTop( -1 ); - if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) + if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) ) + { + HB_LONG lNumber2 = hb_vmPopHBLong(); + HB_LONG lNumber1 = hb_vmPopHBLong(); + + if ( lNumber2 == 0 ) + { + PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ZERODIV, 1340, NULL, "/", 2, pItem1, pItem2 ); + + if( pResult ) + { + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + } + } + else if ( lNumber1 % lNumber2 == 0 ) + hb_vmPushNumInt( lNumber1 / lNumber2 ); + else + hb_vmPushDouble( ( double ) lNumber1 / ( double ) lNumber2, 0 ); + } + else if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) { double d2 = hb_vmPopNumber(); double d1 = hb_vmPopNumber(); @@ -2053,7 +2089,6 @@ static void hb_vmDivide( void ) hb_vmPushDouble( d1 / d2, hb_set.HB_SET_DECIMALS ); } } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpDivide" ) ) hb_vmOperatorCall( pItem1, pItem2, "__OPDIVIDE" ); else @@ -2137,11 +2172,8 @@ static void hb_vmPower( void ) with the SET number of decimal places. */ hb_vmPushDouble( pow( d1, d2 ), hb_set.HB_SET_DECIMALS ); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpPower" ) ) hb_vmOperatorCall( pItem1, pItem2, "__OPPOWER" ); - /* else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpMod" ) ) - hb_vmOperatorCall( pItem1, pItem2, "__OPMOD" ); JFL 02/2002 */ else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1088, NULL, "^", 2, pItem1, pItem2 ); @@ -2156,30 +2188,6 @@ static void hb_vmPower( void ) } } -static void hb_vmIncDouble( PHB_ITEM pItem ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_vmIncDouble()")); - - switch( pItem->type & ~HB_IT_BYREF ) - { - case HB_IT_INTEGER: - pItem->item.asInteger.value++; - break; - - case HB_IT_LONG: - pItem->item.asLong.value++; - break; - - case HB_IT_DOUBLE: - pItem->item.asDouble.value++; - break; - - default: - hb_errInternal( HB_EI_VMPOPINVITEM, NULL, "hb_vmPopDouble()", NULL ); - break; - } -} - static void hb_vmInc( void ) { PHB_ITEM pItem; @@ -2188,15 +2196,34 @@ static void hb_vmInc( void ) pItem = hb_stackItemFromTop( -1 ); - if( HB_IS_NUMERIC( pItem ) ) - hb_vmIncDouble( pItem ); - - else if( HB_IS_DATE( pItem ) ) - hb_vmPushDate( hb_vmPopDate() + 1 ); - + if( HB_IS_DATE( pItem ) ) + pItem->item.asDate.value++; + else if( HB_IS_NUMINT( pItem ) ) + { + if( HB_IS_INTEGER( pItem ) && pItem->item.asInteger.value < HB_INT_MAX ) + { + pItem->item.asInteger.value++; + pItem->item.asInteger.length = HB_INT_LENGTH( pItem->item.asInteger.value ); + } + else if( HB_IS_LONG( pItem ) && pItem->item.asLong.value < HB_LONG_MAX ) + { + pItem->item.asLong.value++; + pItem->item.asLong.length = HB_LONG_LENGTH( pItem->item.asLong.value ); + } + else + { + int iType = pItem->type, iDec; + double dNumber = hb_vmPopDouble( &iDec ); + hb_vmPushNumType( ++dNumber, 0, iType, iType ); + } + } + else if( HB_IS_DOUBLE( pItem ) ) + { + pItem->item.asDouble.value++; + pItem->item.asDouble.length = HB_DBL_LENGTH( pItem->item.asDouble.value ); + } else if( HB_IS_OBJECT( pItem ) && hb_objHasMsg( pItem, "__OpInc" ) ) hb_vmOperatorCallUnary( hb_stackItemFromTop( -1 ), "__OPINC" ); - else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1086, NULL, "++", 1, pItem ); @@ -2210,30 +2237,6 @@ static void hb_vmInc( void ) } } -static void hb_vmDecDouble( PHB_ITEM pItem ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_vmDecDouble()")); - - switch( pItem->type & ~HB_IT_BYREF ) - { - case HB_IT_INTEGER: - pItem->item.asInteger.value--; - break; - - case HB_IT_LONG: - pItem->item.asLong.value--; - break; - - case HB_IT_DOUBLE: - pItem->item.asDouble.value--; - break; - - default: - hb_errInternal( HB_EI_VMPOPINVITEM, NULL, "hb_vmPopDouble()", NULL ); - break; - } -} - static void hb_vmDec( void ) { PHB_ITEM pItem; @@ -2242,15 +2245,34 @@ static void hb_vmDec( void ) pItem = hb_stackItemFromTop( -1 ); - if( HB_IS_NUMERIC( pItem ) ) - hb_vmDecDouble( pItem ); - - else if( HB_IS_DATE( pItem) ) - hb_vmPushDate( hb_vmPopDate() - 1 ); - + if( HB_IS_DATE( pItem ) ) + pItem->item.asDate.value--; + else if( HB_IS_NUMINT( pItem ) ) + { + if( HB_IS_INTEGER( pItem ) && pItem->item.asInteger.value > HB_INT_MIN ) + { + pItem->item.asInteger.value--; + pItem->item.asInteger.length = HB_INT_LENGTH( pItem->item.asInteger.value ); + } + else if( HB_IS_LONG( pItem ) && pItem->item.asLong.value > HB_LONG_MIN ) + { + pItem->item.asLong.value--; + pItem->item.asLong.length = HB_LONG_LENGTH( pItem->item.asLong.value ); + } + else + { + int iType = pItem->type, iDec; + double dNumber = hb_vmPopDouble( &iDec ); + hb_vmPushNumType( --dNumber, 0, iType, iType ); + } + } + else if( HB_IS_DOUBLE( pItem ) ) + { + pItem->item.asDouble.value--; + pItem->item.asDouble.length = HB_DBL_LENGTH( pItem->item.asDouble.value ); + } else if( HB_IS_OBJECT( pItem ) && hb_objHasMsg( pItem, "__OpDec" ) ) hb_vmOperatorCallUnary( pItem, "__OPDEC" ); - else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1087, NULL, "--", 1, pItem ); @@ -2301,14 +2323,12 @@ static void hb_vmEqual( BOOL bExact ) hb_stackPop(); hb_vmPushLogical( TRUE ); } - else if( HB_IS_NIL( pItem1 ) || HB_IS_NIL( pItem2 ) ) { hb_stackPop(); hb_stackPop(); hb_vmPushLogical( FALSE ); } - else if( HB_IS_STRING( pItem1 ) && HB_IS_STRING( pItem2 ) ) { int i = hb_itemStrCmp( pItem1, pItem2, bExact ); @@ -2316,7 +2336,8 @@ static void hb_vmEqual( BOOL bExact ) hb_stackPop(); hb_vmPushLogical( i == 0 ); } - + else if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) ) + hb_vmPushLogical( hb_vmPopHBLong() == hb_vmPopHBLong() ); else if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) hb_vmPushLogical( hb_vmPopNumber() == hb_vmPopNumber() ); else if( HB_IS_DATE( pItem1 ) && HB_IS_DATE( pItem2 ) ) @@ -2376,14 +2397,12 @@ static void hb_vmNotEqual( void ) hb_stackDec(); hb_vmPushLogical( FALSE ); } - else if( HB_IS_NIL( pItem1 ) || HB_IS_NIL( pItem2 ) ) { hb_stackPop(); hb_stackPop(); hb_vmPushLogical( TRUE ); } - else if( HB_IS_STRING( pItem1 ) && HB_IS_STRING( pItem2 ) ) { int i = hb_itemStrCmp( pItem1, pItem2, FALSE ); @@ -2391,7 +2410,8 @@ static void hb_vmNotEqual( void ) hb_stackPop(); hb_vmPushLogical( i != 0 ); } - + else if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) ) + hb_vmPushLogical( hb_vmPopHBLong() != hb_vmPopHBLong() ); else if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) ) hb_vmPushLogical( hb_vmPopNumber() != hb_vmPopNumber() ); else if( HB_IS_DATE( pItem1 ) && HB_IS_DATE( pItem2 ) ) @@ -2433,7 +2453,13 @@ static void hb_vmLess( void ) hb_stackPop(); hb_vmPushLogical( i < 0 ); } - else if( HB_IS_NUMERIC( hb_stackItemFromTop( - 1 ) ) && HB_IS_NUMERIC( hb_stackItemFromTop( -2 ) ) ) + else if( HB_IS_NUMINT( hb_stackItemFromTop( -1 ) ) && HB_IS_NUMINT( hb_stackItemFromTop( -2 ) ) ) + { + HB_LONG lNumber2 = hb_vmPopHBLong(); + HB_LONG lNumber1 = hb_vmPopHBLong(); + hb_vmPushLogical( lNumber1 < lNumber2 ); + } + else if( HB_IS_NUMERIC( hb_stackItemFromTop( -1 ) ) && HB_IS_NUMERIC( hb_stackItemFromTop( -2 ) ) ) { double dNumber2 = hb_vmPopNumber(); double dNumber1 = hb_vmPopNumber(); @@ -2480,6 +2506,12 @@ static void hb_vmLessEqual( void ) hb_stackPop(); hb_vmPushLogical( i <= 0 ); } + else if( HB_IS_NUMINT( hb_stackItemFromTop( -1 ) ) && HB_IS_NUMINT( hb_stackItemFromTop( -2 ) ) ) + { + HB_LONG lNumber2 = hb_vmPopHBLong(); + HB_LONG lNumber1 = hb_vmPopHBLong(); + hb_vmPushLogical( lNumber1 <= lNumber2 ); + } else if( HB_IS_NUMERIC( hb_stackItemFromTop( -1 ) ) && HB_IS_NUMERIC( hb_stackItemFromTop( -2 ) ) ) { double dNumber2 = hb_vmPopNumber(); @@ -2527,6 +2559,12 @@ static void hb_vmGreater( void ) hb_stackPop(); hb_vmPushLogical( i > 0 ); } + else if( HB_IS_NUMINT( hb_stackItemFromTop( -1 ) ) && HB_IS_NUMINT( hb_stackItemFromTop( -2 ) ) ) + { + HB_LONG lNumber2 = hb_vmPopHBLong(); + HB_LONG lNumber1 = hb_vmPopHBLong(); + hb_vmPushLogical( lNumber1 > lNumber2 ); + } else if( HB_IS_NUMERIC( hb_stackItemFromTop( -1 ) ) && HB_IS_NUMERIC( hb_stackItemFromTop( -2 ) ) ) { double dNumber2 = hb_vmPopNumber(); @@ -2574,6 +2612,12 @@ static void hb_vmGreaterEqual( void ) hb_stackPop(); hb_vmPushLogical( i >= 0 ); } + else if( HB_IS_NUMINT( hb_stackItemFromTop( -1 ) ) && HB_IS_NUMINT( hb_stackItemFromTop( -2 ) ) ) + { + HB_LONG lNumber2 = hb_vmPopHBLong(); + HB_LONG lNumber1 = hb_vmPopHBLong(); + hb_vmPushLogical( lNumber1 >= lNumber2 ); + } else if( HB_IS_NUMERIC( hb_stackItemFromTop( -1 ) ) && HB_IS_NUMERIC( hb_stackItemFromTop( -2 ) ) ) { double dNumber2 = hb_vmPopNumber(); @@ -2652,12 +2696,6 @@ static void hb_vmInstring( void ) static void hb_vmForTest( void ) /* Test to check the end point of the FOR */ { double dStep; - double dEnd; - double dCurrent; - - BOOL lEnd; - BOOL lCurrent; - BOOL lLogicalPassed = FALSE; HB_TRACE(HB_TR_DEBUG, ("hb_vmForTest()")); @@ -2697,40 +2735,26 @@ static void hb_vmForTest( void ) /* Test to check the end point of the FO if ( hb_stackItemFromTop( -1 )->type == HB_IT_LOGICAL ) { + BOOL lEnd; + BOOL lCurrent; + lEnd = hb_vmPopLogical(); - lLogicalPassed = TRUE; - } - else - dEnd = hb_vmPopNumber(); - - while( ( ! HB_IS_NUMERIC( hb_stackItemFromTop( -1 ) ) ) && ( ! HB_IS_LOGICAL( hb_stackItemFromTop( -1 ) ) ) ) - { - PHB_ITEM pItem1 = hb_stackItemFromTop( -1 ); - PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1073, NULL, "<", 1, pItem1 ); - - if( pResult ) + while( ! HB_IS_LOGICAL( hb_stackItemFromTop( -1 ) ) ) { - hb_stackPop(); - hb_vmPush( pResult ); - hb_itemRelease( pResult ); + PHB_ITEM pItem1 = hb_stackItemFromTop( -1 ); + PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1073, NULL, "<", 1, pItem1 ); + + if( pResult ) + { + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + } + else + /* NOTE: Return from the inside. */ + return; } - else - /* NOTE: Return from the inside. */ - return; - } - - if ( hb_stackItemFromTop( -1 )->type == HB_IT_LOGICAL ) - { lCurrent = hb_vmPopLogical(); - } - else - { - lLogicalPassed = FALSE; - dCurrent = hb_vmPopNumber(); - } - - if( lLogicalPassed ) - { if( dStep >= 0 ) /* Positive loop. Use LESS */ { hb_vmPushLogical( lCurrent <= lEnd ); @@ -2742,6 +2766,26 @@ static void hb_vmForTest( void ) /* Test to check the end point of the FO } else { + double dEnd; + double dCurrent; + + dEnd = hb_vmPopNumber(); + while( ! HB_IS_NUMERIC( hb_stackItemFromTop( -1 ) ) ) + { + PHB_ITEM pItem1 = hb_stackItemFromTop( -1 ); + PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1073, NULL, "<", 1, pItem1 ); + + if( pResult ) + { + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + } + else + /* NOTE: Return from the inside. */ + return; + } + dCurrent = hb_vmPopNumber(); if( dStep >= 0 ) /* Positive loop. Use LESS */ { hb_vmPushLogical( dCurrent <= dEnd ); @@ -3188,14 +3232,6 @@ static ERRCODE hb_vmSelectWorkarea( PHB_ITEM pAlias ) pAlias->type = HB_IT_NIL; break; - /* - These types were added for Clipper compatibility - */ - case HB_IT_NIL: - case HB_IT_BLOCK: - case HB_IT_LOGICAL: - case HB_IT_ARRAY: - case HB_IT_DOUBLE: /* Alias was evaluated from an expression, (nWorkArea)->field */ @@ -3226,6 +3262,20 @@ static ERRCODE hb_vmSelectWorkarea( PHB_ITEM pAlias ) } break; + /* + These types were added for Clipper compatibility + */ + case HB_IT_ARRAY: + case HB_IT_BLOCK: + hb_itemClear( pAlias ); + /* Fall through. */ + case HB_IT_NIL: + case HB_IT_LOGICAL: + case HB_IT_DATE: + hb_rddSelectWorkAreaNumber( -1 ); + pAlias->type = HB_IT_NIL; + break; + default: { PHB_ITEM pSubstVal = hb_errRT_BASE_Subst( EG_ARG, 1065, NULL, "&", 1, pAlias ); @@ -3466,7 +3516,7 @@ void HB_EXPORT hb_vmSend( USHORT uiParams ) PHB_FUNC pFunc = NULL; BOOL bDebugPrevState; ULONG ulClock = 0; - void *pMethod; + void *pMethod = NULL; BOOL bProfiler = hb_bProfiler; /* because profiler state may change */ HB_TRACE(HB_TR_DEBUG, ("hb_vmSend(%hu)", uiParams)); @@ -3548,8 +3598,8 @@ void HB_EXPORT hb_vmSend( USHORT uiParams ) } else { - PHB_BASEARRAY pSelfBase; - BOOL lPopSuper; + PHB_BASEARRAY pSelfBase = NULL; + BOOL lPopSuper = FALSE; if( HB_IS_BLOCK( pSelf ) ) { @@ -3565,7 +3615,6 @@ void HB_EXPORT hb_vmSend( USHORT uiParams ) } else if( HB_IS_OBJECT( pSelf ) ) /* Object passed */ { - lPopSuper = FALSE; pFunc = hb_objGetMethod( pSelf, pSym ); pSelfBase = pSelf->item.asArray.value; @@ -3589,7 +3638,7 @@ void HB_EXPORT hb_vmSend( USHORT uiParams ) hb_itemRelease( pRealSelf ) ; /* and release the fake one */ /* Push current SuperClass handle */ - lPopSuper = TRUE ; + lPopSuper = TRUE; if ( ! pSelf->item.asArray.value->puiClsTree ) { @@ -3789,6 +3838,8 @@ static void hb_vmStaticName( BYTE bIsGlobal, USHORT uiStatic, char * szStaticNam { HB_TRACE(HB_TR_DEBUG, ("hb_vmStaticName(%hu, %s)", uiStatic, szStaticName)); + HB_SYMBOL_UNUSED( bIsGlobal ); + s_bDebugging = TRUE; s_bDebugShowLines = FALSE; hb_vmPushSymbol( hb_dynsymFind( "__DBGENTRY" )->pSymbol ); @@ -3963,16 +4014,44 @@ void HB_EXPORT hb_vmPushNumType( double dNumber, int iDec, int iType1, int iType if( iDec || iType1 & HB_IT_DOUBLE || iType2 & HB_IT_DOUBLE ) hb_vmPushDouble( dNumber, iDec ); - else if( SHRT_MIN <= dNumber && dNumber <= SHRT_MAX ) + else if ( HB_DBL_LIM_INT( dNumber ) ) hb_vmPushInteger( ( int ) dNumber ); - else if( LONG_MIN <= dNumber && dNumber <= LONG_MAX ) - hb_vmPushLong( ( long ) dNumber ); + else if ( HB_DBL_LIM_LONG( dNumber ) ) + hb_vmPushHBLong( ( HB_LONG ) dNumber ); else hb_vmPushDouble( dNumber, hb_set.HB_SET_DECIMALS ); } +static int hb_vmCalcIntWidth( HB_LONG lNumber ) +{ + int iWidth; + + if( lNumber <= -1000000000L ) + { + iWidth = 20; + } + else + { + iWidth = 10; + while ( lNumber >= 1000000000L ) + { + iWidth++; + lNumber /= 10; + } + } + return iWidth; +} + +static void hb_vmPushNumInt( HB_LONG lNumber ) +{ + if( HB_LIM_INT( lNumber ) ) + hb_vmPushInteger( ( int ) lNumber ); + else + hb_vmPushHBLong( lNumber ); +} + void HB_EXPORT hb_vmPushInteger( int iNumber ) { PHB_ITEM pStackTopItem = hb_stackTopItem(); @@ -3981,19 +4060,39 @@ void HB_EXPORT hb_vmPushInteger( int iNumber ) pStackTopItem->type = HB_IT_INTEGER; pStackTopItem->item.asInteger.value = iNumber; - pStackTopItem->item.asInteger.length = 10; + pStackTopItem->item.asInteger.length = HB_INT_LENGTH( iNumber ); hb_stackPush(); } +#if HB_INT_MAX >= INT32_MAX +static void hb_vmPushIntegerConst( int iNumber ) +{ + PHB_ITEM pStackTopItem = hb_stackTopItem(); + + HB_TRACE(HB_TR_DEBUG, ("hb_vmPushIntegerConst(%d)", iNumber)); + + pStackTopItem->type = HB_IT_INTEGER; + pStackTopItem->item.asInteger.value = iNumber; + pStackTopItem->item.asInteger.length = hb_vmCalcIntWidth( iNumber ); + hb_stackPush(); +} +#endif + void HB_EXPORT hb_vmPushLong( long lNumber ) { PHB_ITEM pStackTopItem = hb_stackTopItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushLong(%ld)", lNumber)); +#if HB_INT_MAX >= LONG_MAX + pStackTopItem->type = HB_IT_INTEGER; + pStackTopItem->item.asInteger.value = ( int ) lNumber; + pStackTopItem->item.asInteger.length = HB_INT_LENGTH( lNumber ); +#else pStackTopItem->type = HB_IT_LONG; - pStackTopItem->item.asLong.value = lNumber; - pStackTopItem->item.asLong.length = 10; + pStackTopItem->item.asLong.value = ( HB_LONG ) lNumber; + pStackTopItem->item.asLong.length = HB_LONG_LENGTH( lNumber ); +#endif hb_stackPush(); } @@ -4003,31 +4102,55 @@ void hb_vmPushLongConst( long lNumber ) HB_TRACE(HB_TR_DEBUG, ("hb_vmPushLongConst(%ld)", lNumber)); +#if HB_INT_MAX >= LONG_MAX + pStackTopItem->type = HB_IT_INTEGER; + pStackTopItem->item.asInteger.value = ( int ) lNumber; + pStackTopItem->item.asInteger.length = hb_vmCalcIntWidth( lNumber ); +#else + pStackTopItem->type = HB_IT_LONG; + pStackTopItem->item.asLong.value = ( HB_LONG ) lNumber; + pStackTopItem->item.asLong.length = hb_vmCalcIntWidth( lNumber ); +#endif + hb_stackPush(); +} + +static void hb_vmPushHBLong( HB_LONG lNumber ) +{ + PHB_ITEM pStackTopItem = hb_stackTopItem(); + + HB_TRACE(HB_TR_DEBUG, ("hb_vmPushHBLong(%" PFHL "d)", lNumber)); + pStackTopItem->type = HB_IT_LONG; pStackTopItem->item.asLong.value = lNumber; - - if( lNumber >= 1000000000 ) - pStackTopItem->item.asLong.length = 11; - else if( lNumber <= -1000000000 ) - pStackTopItem->item.asLong.length = 20; - else - pStackTopItem->item.asLong.length = 10; + pStackTopItem->item.asLong.length = HB_LONG_LENGTH( lNumber ); hb_stackPush(); } +#if !defined( HB_LONG_LONG_OFF ) +static void hb_vmPushLongLongConst( LONGLONG llNumber ) +{ + PHB_ITEM pStackTopItem = hb_stackTopItem(); + + HB_TRACE(HB_TR_DEBUG, ("hb_vmPushLongLongConst(%" PFLL "d)", llNumber)); + + pStackTopItem->type = HB_IT_LONG; + pStackTopItem->item.asLong.value = ( HB_LONG ) llNumber; + pStackTopItem->item.asLong.length = hb_vmCalcIntWidth( llNumber ); + + hb_stackPush(); +} +#endif + void HB_EXPORT hb_vmPushDouble( double dNumber, int iDec ) { PHB_ITEM pStackTopItem = hb_stackTopItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushDouble(%lf, %d)", dNumber, iDec)); - if( dNumber == -0.0 ) - dNumber = 0.0; - pStackTopItem->type = HB_IT_DOUBLE; pStackTopItem->item.asDouble.value = dNumber; - pStackTopItem->item.asDouble.length = ( dNumber >= 10000000000.0 || dNumber <= -1000000000.0 ) ? 20 : 10; + pStackTopItem->item.asDouble.length = HB_DBL_LENGTH( dNumber ); if( iDec == HB_DEFAULT_DECIMALS ) pStackTopItem->item.asDouble.decimal = hb_set.HB_SET_DECIMALS; else @@ -4036,27 +4159,12 @@ void HB_EXPORT hb_vmPushDouble( double dNumber, int iDec ) hb_stackPush(); } -static int hb_vmCalcDoubleWidth( double dNumber, int iDec ) -{ - char buffer[ 260 ]; - - sprintf( buffer, "%.*f", 0, dNumber ); - - if( iDec == 0 ) - return strlen( buffer ) + 1; - else - return strlen( buffer ); -} - static void hb_vmPushDoubleConst( double dNumber, int iWidth, int iDec ) { PHB_ITEM pStackTopItem = hb_stackTopItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushDoubleConst(%lf, %d, %d)", dNumber, iWidth, iDec)); - if( dNumber == -0.0 ) - dNumber = 0.0; - pStackTopItem->type = HB_IT_DOUBLE; pStackTopItem->item.asDouble.value = dNumber; @@ -4065,24 +4173,10 @@ static void hb_vmPushDoubleConst( double dNumber, int iWidth, int iDec ) else pStackTopItem->item.asDouble.decimal = iDec; - /* NOTE: Part of these width calculations could be moved to the compiler for - maximum speed. */ - - if( dNumber >= 1000000000.0 ) - { - /* NOTE: If the width info is not provided by the pcode stream, - it will be determined at runtime with a relatively slow - method. [vszakats] */ - - if( iWidth == HB_DEFAULT_WIDTH ) - pStackTopItem->item.asDouble.length = hb_vmCalcDoubleWidth( dNumber, iDec ); - else - pStackTopItem->item.asDouble.length = iWidth; - } - else if( dNumber <= -1000000000.0 ) - pStackTopItem->item.asDouble.length = 20; + if( iWidth == HB_DEFAULT_WIDTH ) + pStackTopItem->item.asDouble.length = HB_DBL_LENGTH( dNumber ); else - pStackTopItem->item.asDouble.length = 10; + pStackTopItem->item.asDouble.length = iWidth; hb_stackPush(); } @@ -4199,11 +4293,11 @@ static void hb_vmPushBlock( BYTE * pCode, PHB_SYMB pSymbols ) pStackTopItem->type = HB_IT_BLOCK; - uiLocals = pCode[ 5 ] + ( pCode[ 6 ] * 256 ); + uiLocals = HB_PCODE_MKUSHORT( &( pCode[ 5 ] ) ); pStackTopItem->item.asBlock.value = hb_codeblockNew( pCode + 7 + uiLocals * 2, /* pcode buffer */ uiLocals, /* number of referenced local variables */ - ( USHORT * ) ( pCode + 7 ), /* table with referenced local variables */ + pCode + 7, /* table with referenced local variables */ pSymbols ); /* store the statics base of function where the codeblock was defined @@ -4211,7 +4305,7 @@ static void hb_vmPushBlock( BYTE * pCode, PHB_SYMB pSymbols ) pStackTopItem->item.asBlock.statics = hb_stack.iStatics; /* store the number of expected parameters */ - pStackTopItem->item.asBlock.paramcnt = pCode[ 3 ] + ( pCode[ 4 ] * 256 ); + pStackTopItem->item.asBlock.paramcnt = HB_PCODE_MKUSHORT( &( pCode[ 3 ] ) ); /* store the line number where the codeblock was defined */ pStackTopItem->item.asBlock.lineno = ( hb_stackBaseItem() )->item.asSymbol.lineno; @@ -4267,14 +4361,14 @@ static void hb_vmPushMacroBlock( BYTE * pCode, PHB_SYMB pSymbols ) pStackTopItem->type = HB_IT_BLOCK; - pStackTopItem->item.asBlock.value = hb_codeblockMacroNew( pCode + 5, pCode[ 1 ] + pCode[ 2 ] * 256 - 5 ); + pStackTopItem->item.asBlock.value = hb_codeblockMacroNew( pCode + 5, HB_PCODE_MKUSHORT( &( pCode[ 1 ] ) ) - 5 ); /* store the statics base of function where the codeblock was defined */ pStackTopItem->item.asBlock.statics = hb_stack.iStatics; /* store the number of expected parameters */ - pStackTopItem->item.asBlock.paramcnt = pCode[ 3 ] + ( pCode[ 4 ] * 256 ); + pStackTopItem->item.asBlock.paramcnt = HB_PCODE_MKUSHORT( &( pCode[ 3 ] ) ); /* store the line number where the codeblock was defined */ pStackTopItem->item.asBlock.lineno = ( hb_stackBaseItem() )->item.asSymbol.lineno; @@ -4312,9 +4406,15 @@ static void hb_vmPushAliasedField( PHB_SYMB pSym ) /* This was added for Clipper compatibility */ - if( ( pAlias->type == HB_IT_ARRAY ) || ( pAlias->type == HB_IT_LOGICAL ) || ( pAlias->type == HB_IT_NIL ) || ( pAlias->type == HB_IT_BLOCK ) ) + if( ( pAlias->type == HB_IT_ARRAY ) || ( pAlias->type == HB_IT_LOGICAL ) || + ( pAlias->type == HB_IT_NIL ) || ( pAlias->type == HB_IT_BLOCK ) || + ( pAlias->type == HB_IT_DATE ) ) { - hb_errRT_BASE_Subst( EG_ARG, 1065, NULL, "&", 1, pAlias ); + PHB_ITEM pFName = hb_itemNew( NULL ); + + hb_itemPutC( pFName, pSym->szName ); + hb_errRT_BASE_Subst( EG_ARG, 1065, NULL, "&", 2, pAlias, pFName ); + hb_itemRelease( pFName ); } else { @@ -4583,6 +4683,43 @@ static double hb_vmPopNumber( void ) /* NOTE: Type checking should be done by the caller. */ +static HB_LONG hb_vmPopHBLong( void ) +{ + PHB_ITEM pItem; + HB_LONG lNumber; + + HB_TRACE(HB_TR_DEBUG, ("hb_vmPopHBLong()")); + + pItem = hb_stackItemFromTop( -1 ); + hb_stackDec(); + + switch( pItem->type & ~HB_IT_BYREF ) + { + case HB_IT_INTEGER: + lNumber = ( HB_LONG ) pItem->item.asInteger.value; + break; + + case HB_IT_LONG: + lNumber = ( HB_LONG ) pItem->item.asLong.value; + break; + + case HB_IT_DOUBLE: + lNumber = ( HB_LONG ) pItem->item.asDouble.value; + break; + + default: + lNumber = 0; /* To avoid GCC -O2 warning */ + hb_errInternal( HB_EI_VMPOPINVITEM, NULL, "hb_vmPopNumber()", NULL ); + break; + } + + ( hb_stackTopItem() )->type = HB_IT_NIL; + + return lNumber; +} + +/* NOTE: Type checking should be done by the caller. */ + static double hb_vmPopDouble( int * piDec ) { PHB_ITEM pItem; diff --git a/harbour/source/vm/itemapi.c b/harbour/source/vm/itemapi.c index 14d5c00025..c7c6809e75 100644 --- a/harbour/source/vm/itemapi.c +++ b/harbour/source/vm/itemapi.c @@ -110,9 +110,6 @@ extern PHB_CODEPAGE hb_cdp_page; extern char *hb_vm_sNull; extern char *hb_vm_acAscii[256]; -/* DJGPP can sprintf a float that is almost 320 digits long */ -#define HB_MAX_DOUBLE_LENGTH 320 - PHB_ITEM HB_EXPORT hb_itemNew( PHB_ITEM pNull ) { HB_TRACE(HB_TR_DEBUG, ("hb_itemNew(%p)", pNull)); @@ -498,7 +495,7 @@ int HB_EXPORT hb_itemGetNI( PHB_ITEM pItem ) return 0; } -long HB_EXPORT hb_itemGetNL( PHB_ITEM pItem ) +LONG HB_EXPORT hb_itemGetNL( PHB_ITEM pItem ) { HB_TRACE(HB_TR_DEBUG, ("hb_itemGetNL(%p)", pItem)); @@ -507,22 +504,84 @@ long HB_EXPORT hb_itemGetNL( PHB_ITEM pItem ) switch( pItem->type ) { case HB_IT_LONG: - return pItem->item.asLong.value; + return ( LONG ) pItem->item.asLong.value; case HB_IT_INTEGER: - return ( long ) pItem->item.asInteger.value; + return ( LONG ) pItem->item.asInteger.value; case HB_IT_DOUBLE: - return ( long ) pItem->item.asDouble.value; - +#ifdef __GCC__ + return ( LONG ) ( ULONG ) pItem->item.asDouble.value; +#else + return ( LONG ) pItem->item.asDouble.value; +#endif case HB_IT_DATE: - return pItem->item.asDate.value; + return ( LONG ) pItem->item.asDate.value; } } return 0; } +HB_LONG HB_EXPORT hb_itemGetNInt( PHB_ITEM pItem ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_itemGetNL(%p)", pItem)); + + if( pItem ) + { + switch( pItem->type ) + { + case HB_IT_LONG: + return ( HB_LONG ) pItem->item.asLong.value; + + case HB_IT_INTEGER: + return ( LONG ) pItem->item.asInteger.value; + + case HB_IT_DOUBLE: +#ifdef __GCC__ + return ( HB_LONG ) ( HB_ULONG ) pItem->item.asDouble.value; +#else + return ( HB_LONG ) pItem->item.asDouble.value; +#endif + case HB_IT_DATE: + return ( HB_LONG ) pItem->item.asDate.value; + } + } + + return 0; +} + +#ifndef HB_LONG_LONG_OFF +LONGLONG HB_EXPORT hb_itemGetNLL( PHB_ITEM pItem ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_itemGetNL(%p)", pItem)); + + if( pItem ) + { + switch( pItem->type ) + { + case HB_IT_LONG: + return ( LONGLONG ) pItem->item.asLong.value; + + case HB_IT_INTEGER: + return ( LONGLONG ) pItem->item.asInteger.value; + + case HB_IT_DOUBLE: +#ifdef __GCC__ + return ( LONGLONG ) ( ULONGLONG ) pItem->item.asDouble.value; +#else + return ( LONGLONG ) pItem->item.asDouble.value; +#endif + + case HB_IT_DATE: + return ( LONGLONG ) pItem->item.asDate.value; + } + } + + return 0; +} +#endif + void * HB_EXPORT hb_itemGetPtr( PHB_ITEM pItem ) { HB_TRACE(HB_TR_DEBUG, ("hb_itemGetPtr(%p)", pItem)); @@ -567,9 +626,9 @@ PHB_ITEM HB_EXPORT hb_itemPutDS( PHB_ITEM pItem, char * szDate ) return pItem; } -PHB_ITEM HB_EXPORT hb_itemPutD( PHB_ITEM pItem, long lYear, long lMonth, long lDay ) +PHB_ITEM HB_EXPORT hb_itemPutD( PHB_ITEM pItem, int iYear, int iMonth, int iDay ) { - HB_TRACE(HB_TR_DEBUG, ("hb_itemPutD(%p, %04i, %02i, %02i)", pItem, lYear, lMonth, lDay)); + HB_TRACE(HB_TR_DEBUG, ("hb_itemPutD(%p, %04i, %02i, %02i)", pItem, iYear, iMonth, iDay)); if( pItem ) hb_itemClear( pItem ); @@ -577,7 +636,7 @@ PHB_ITEM HB_EXPORT hb_itemPutD( PHB_ITEM pItem, long lYear, long lMonth, long lD pItem = hb_itemNew( NULL ); pItem->type = HB_IT_DATE; - pItem->item.asDate.value = hb_dateEncode( lYear, lMonth, lDay ); + pItem->item.asDate.value = hb_dateEncode( iYear, iMonth, iDay ); return pItem; } @@ -622,7 +681,7 @@ PHB_ITEM HB_EXPORT hb_itemPutND( PHB_ITEM pItem, double dNumber ) pItem = hb_itemNew( NULL ); pItem->type = HB_IT_DOUBLE; - pItem->item.asDouble.length = ( dNumber >= 10000000000.0 || dNumber <= -1000000000.0 ) ? 20 : 10; + pItem->item.asDouble.length = HB_DBL_LENGTH( dNumber ); pItem->item.asDouble.decimal = hb_set.HB_SET_DECIMALS; pItem->item.asDouble.value = dNumber; @@ -639,13 +698,13 @@ PHB_ITEM HB_EXPORT hb_itemPutNI( PHB_ITEM pItem, int iNumber ) pItem = hb_itemNew( NULL ); pItem->type = HB_IT_INTEGER; - pItem->item.asInteger.length = 10; pItem->item.asInteger.value = iNumber; + pItem->item.asInteger.length = HB_INT_LENGTH( iNumber ); return pItem; } -PHB_ITEM HB_EXPORT hb_itemPutNL( PHB_ITEM pItem, long lNumber ) +PHB_ITEM HB_EXPORT hb_itemPutNL( PHB_ITEM pItem, LONG lNumber ) { HB_TRACE(HB_TR_DEBUG, ("hb_itemPutNL(%p, %ld)", pItem, lNumber)); @@ -654,29 +713,101 @@ PHB_ITEM HB_EXPORT hb_itemPutNL( PHB_ITEM pItem, long lNumber ) else pItem = hb_itemNew( NULL ); +#if HB_INT_MAX >= LONG_MAX + pItem->type = HB_IT_INTEGER; + pItem->item.asInteger.value = (int) lNumber; + pItem->item.asInteger.length = HB_INT_LENGTH( lNumber ); +#else pItem->type = HB_IT_LONG; - pItem->item.asLong.length = 10; - pItem->item.asLong.value = lNumber; + pItem->item.asLong.value = (HB_LONG) lNumber; + pItem->item.asLong.length = HB_LONG_LENGTH( lNumber ); +#endif return pItem; } +#ifndef HB_LONG_LONG_OFF +PHB_ITEM HB_EXPORT hb_itemPutNLL( PHB_ITEM pItem, LONGLONG llNumber ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_itemPutNL(%p, %" PFLL "d)", pItem, llNumber)); + + if( pItem ) + hb_itemClear( pItem ); + else + pItem = hb_itemNew( NULL ); + +#if HB_LONG_MAX >= LONGLONG_MAX + pItem->type = HB_IT_LONG; + pItem->item.asLong.value = (HB_LONG) llNumber; + pItem->item.asLong.length = HB_LONG_LENGTH( llNumber ); +#else + pItem->type = HB_IT_DOUBLE; + pItem->item.asDouble.value = ( double ) llNumber; + pItem->item.asDouble.length = HB_DBL_LENGTH( pItem->item.asDouble.value ); + pItem->item.asDouble.decimal = 0; +#endif + return pItem; +} +#endif + +PHB_ITEM HB_EXPORT hb_itemPutNInt( PHB_ITEM pItem, HB_LONG lNumber ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_itemPutNInt(%p, %" PFHL "d)", pItem, lNumber)); + + if( HB_LIM_INT( lNumber ) ) + { + hb_itemPutNI( pItem, ( int ) lNumber ); + } + else + { +#ifdef HB_LONG_LONG_OFF + hb_itemPutNL( pItem, ( long ) lNumber ); +#else + hb_itemPutNLL( pItem, ( LONGLONG ) lNumber ); +#endif + } + return pItem; +} + +PHB_ITEM HB_EXPORT hb_itemPutNIntLen( PHB_ITEM pItem, HB_LONG lNumber, int iWidth ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_itemPutNIntLen(%p, %" PFHL "d, %d)", pItem, lNumber, iWidth)); + + if( HB_LIM_INT( lNumber ) ) + { + hb_itemPutNILen( pItem, ( int ) lNumber, iWidth ); + } + else + { +#ifdef HB_LONG_LONG_OFF + hb_itemPutNLLen( pItem, ( long ) lNumber, iWidth ); +#else + hb_itemPutNLLLen( pItem, ( LONGLONG ) lNumber, iWidth ); +#endif + } + return pItem; +} + PHB_ITEM HB_EXPORT hb_itemPutNLen( PHB_ITEM pItem, double dNumber, int iWidth, int iDec ) { HB_TRACE(HB_TR_DEBUG, ("hb_itemPutNLen(%p, %lf, %d, %d)", pItem, dNumber, iWidth, iDec)); if( iWidth <= 0 || iWidth > 99 ) - iWidth = ( dNumber >= 10000000000.0 || dNumber <= -1000000000.0 ) ? 20 : 10; + iWidth = HB_DBL_LENGTH( dNumber ); if( iDec < 0 ) iDec = hb_set.HB_SET_DECIMALS; if( iDec > 0 ) return hb_itemPutNDLen( pItem, dNumber, iWidth, iDec ); - else if( SHRT_MIN <= dNumber && dNumber <= SHRT_MAX ) + else if ( HB_DBL_LIM_INT( dNumber ) ) return hb_itemPutNILen( pItem, ( int ) dNumber, iWidth ); - else if( LONG_MIN <= dNumber && dNumber <= LONG_MAX ) + else if ( HB_DBL_LIM_LONG( dNumber ) ) +#ifdef HB_LONG_LONG_OFF return hb_itemPutNLLen( pItem, ( long ) dNumber, iWidth ); +#else + return hb_itemPutNLLLen( pItem, ( LONGLONG ) dNumber, iWidth ); +#endif else return hb_itemPutNDLen( pItem, dNumber, iWidth, 0 ); } @@ -693,14 +824,14 @@ PHB_ITEM HB_EXPORT hb_itemPutNDLen( PHB_ITEM pItem, double dNumber, int iWidth, if( iWidth <= 0 || iWidth > 99 ) { #if (__BORLANDC__ > 1040) /* Use this only above Borland C++ 3.1 */ - /* Borland C compiled app crashes if a "NaN" double is compared with another double [martin vogel] */ - if (_isnan (dNumber)) - { - iWidth = 20; - } - else + /* Borland C compiled app crashes if a "NaN" double is compared with another double [martin vogel] */ + if (_isnan (dNumber)) + { + iWidth = 20; + } + else #endif - iWidth = ( dNumber >= 10000000000.0 || dNumber <= -1000000000.0 ) ? 20 : 10; + iWidth = HB_DBL_LENGTH( dNumber ); } if( iDec < 0 ) @@ -724,7 +855,7 @@ PHB_ITEM HB_EXPORT hb_itemPutNILen( PHB_ITEM pItem, int iNumber, int iWidth ) pItem = hb_itemNew( NULL ); if( iWidth <= 0 || iWidth > 99 ) - iWidth = 10; + iWidth = HB_INT_LENGTH( iNumber ); pItem->type = HB_IT_INTEGER; pItem->item.asInteger.length = iWidth; @@ -733,7 +864,7 @@ PHB_ITEM HB_EXPORT hb_itemPutNILen( PHB_ITEM pItem, int iNumber, int iWidth ) return pItem; } -PHB_ITEM HB_EXPORT hb_itemPutNLLen( PHB_ITEM pItem, long lNumber, int iWidth ) +PHB_ITEM HB_EXPORT hb_itemPutNLLen( PHB_ITEM pItem, LONG lNumber, int iWidth ) { HB_TRACE(HB_TR_DEBUG, ("hb_itemPutNLLen(%p, %ld, %d)", pItem, lNumber, iWidth)); @@ -742,16 +873,55 @@ PHB_ITEM HB_EXPORT hb_itemPutNLLen( PHB_ITEM pItem, long lNumber, int iWidth ) else pItem = hb_itemNew( NULL ); +#if HB_INT_MAX == LONG_MAX if( iWidth <= 0 || iWidth > 99 ) - iWidth = 10; + iWidth = HB_INT_LENGTH( lNumber ); + + pItem->type = HB_IT_INTEGER; + pItem->item.asInteger.value = (int) lNumber; + pItem->item.asInteger.length = iWidth; +#else + if( iWidth <= 0 || iWidth > 99 ) + iWidth = HB_LONG_LENGTH( lNumber ); pItem->type = HB_IT_LONG; + pItem->item.asLong.value = (HB_LONG) lNumber; pItem->item.asLong.length = iWidth; - pItem->item.asLong.value = lNumber; +#endif return pItem; } +#ifndef HB_LONG_LONG_OFF +PHB_ITEM HB_EXPORT hb_itemPutNLLLen( PHB_ITEM pItem, LONGLONG llNumber, int iWidth ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_itemPutNLLLen(%p, %" PFLL "d, %d)", pItem, llNumber, iWidth)); + + if( pItem ) + hb_itemClear( pItem ); + else + pItem = hb_itemNew( NULL ); + +#if HB_LONG_MAX >= LONGLONG_MAX + if( iWidth <= 0 || iWidth > 99 ) + iWidth = HB_LONG_LENGTH( llNumber ); + + pItem->type = HB_IT_LONG; + pItem->item.asLong.value = ( HB_LONG ) llNumber; + pItem->item.asLong.length = iWidth; +#else + pItem->type = HB_IT_DOUBLE; + pItem->item.asDouble.value = ( double ) llNumber; + if( iWidth <= 0 || iWidth > 99 ) + iWidth = HB_LONG_LENGTH( pItem->item.asDouble.value ); + pItem->item.asDouble.length = iWidth; + pItem->item.asDouble.decimal = 0; +#endif + + return pItem; +} +#endif + PHB_ITEM HB_EXPORT hb_itemPutPtr( PHB_ITEM pItem, void * pValue ) { HB_TRACE(HB_TR_DEBUG, ("hb_itemPutPtr(%p, %p)", pItem, pValue)); @@ -1119,155 +1289,264 @@ int HB_EXPORT hb_itemStrCmp( PHB_ITEM pFirst, PHB_ITEM pSecond, BOOL bForceExact BOOL HB_EXPORT hb_itemStrBuf( char *szResult, PHB_ITEM pNumber, int iSize, int iDec ) { - int iBytes; + int iPos, iDot; + BOOL fNeg; - if( HB_IS_DOUBLE( pNumber ) || iDec != 0 ) + if ( iDec < 0 ) + { + iDec = 0; + } + if ( iDec > 0 ) + { + iPos = iDot = iSize - iDec - 1; + } + else + { + iPos = iSize; + iDot = 0; + } + + if( HB_IS_DOUBLE( pNumber ) ) { double dNumber = hb_itemGetND( pNumber ); - #if defined(__WATCOMC__) && __WATCOMC__ > 1000 - #elif defined(__IBMCPP__) - /* The IBM VAC++ compiler is unable to compare non-finite numbers - and does not have a function to test if a number if finite. */ - static char s_dInfinity[16]; - static char s_dmInfinity[16]; - static char s_dNan[8]; - static char s_dmNan[8]; - static double s_bInfinityInit = FALSE; +/* TODO: look if finite()/_finite() or isinf()/_isinf and isnan()/_isnan + does exist for your compiler and add this to the check below */ - if( ! s_bInfinityInit ) - { - /* temporarily remove the math error handler */ - HB_MATH_HANDLERPROC fOldMathHandler = hb_mathSetHandler (NULL); - sprintf( s_dInfinity, "%e", -log( ( double ) 0 ) ); - strcpy( s_dmInfinity, "-" ); - strcat( s_dmInfinity, s_dInfinity ); - sprintf( s_dNan, "%e", -log( ( double ) - 1 ) ); - strcpy( s_dmNan, "-" ); - strcat( s_dmNan, s_dNan ); - /* restore the math error handler */ - hb_mathSetHandler (fOldMathHandler); - s_bInfinityInit = TRUE; - } - #elif defined(_MSC_VER) || defined(__DJGPP__) || defined(__GNUC__)|| defined(__MINGW32__) || defined(__RSXNT__) || defined(__EMX__) || (__BORLANDC__ > 1040) /* Use this only above Borland C++ 3.1 */ - /* Nothing to do here, because these platforms have a function - that returns 0 if the value is not a finite number */ - #else - /* This is for platforms that don't have a function that can test - if a number is finite, but can compare non-finite numbers. */ +#if defined(__RSXNT__) || defined(__EMX__) || defined( __XCC__ ) || defined( __POCC__ ) +# define HB_FINITE_DBL(d) ( isfinite(d)!=0 ) +#elif defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_MSC_VER) +# define HB_FINITE_DBL(d) ( _finite(d)!=0 ) +#elif defined( __GNUC__ ) || defined( __DJGPP__ ) || defined( __MINGW32__ ) || \ + defined( __LCC__ ) || defined( __MSC__ ) +# define HB_FINITE_DBL(d) ( finite(d)!=0 ) +#else + /* added infinity check for Borland C [martin vogel] */ + /* Borland C 5.5 has _finite() function, if it's necessary + we can reenable this code for older DOS BCC versions + Now this code is for generic C compilers undefined above + [druzus] */ + static BOOL s_bInfinityInit = FALSE; static double s_dInfinity = 0; - static double s_dNan = 0; - static double s_bInfinityInit = FALSE; if( ! s_bInfinityInit ) { - /* set math handler to NULL for evaluating log(0), - to avoid error messages [martin vogel]*/ - HB_MATH_HANDLERPROC fOldMathHandler = hb_mathSetHandler (NULL); + /* set math handler to NULL for evaluating log(0), + to avoid error messages [martin vogel]*/ + HB_MATH_HANDLERPROC fOldMathHandler = hb_mathSetHandler (NULL); s_dInfinity = -log( ( double ) 0 ); - s_dNan = -log( ( double ) - 1 ); - hb_mathSetHandler (fOldMathHandler); + hb_mathSetHandler (fOldMathHandler); s_bInfinityInit = TRUE; } - #endif - - #ifdef __IBMCPP__ - sprintf(szResult, "%e", dNumber); - #endif - if( pNumber->item.asDouble.length == 99 - #if defined(__WATCOMC__) && (__WATCOMC__ > 1000) - || !_finite( dNumber ) - #elif defined(_MSC_VER) || (__BORLANDC__ > 1040) /* Use this only above Borland C++ 3.1 */ - || !_finite(dNumber) - #elif defined(__RSXNT__) || defined(__EMX__) /* Must be ahead of __GNUC__ check! */ - || !isfinite( dNumber ) - #elif defined(__DJGPP__) || defined(__MINGW32__) || defined(__GNUC__) - || !finite( dNumber ) - #elif defined(__IBMCPP__) - || strcmp(szResult, s_dInfinity) || strcmp(szResult, s_dmInfinity) || strcmp(szResult, s_dNan) || strcmp(szResult, s_dmNan) - #else - || dNumber == s_dInfinity || dNumber == -s_dInfinity || dNumber == s_dNan || dNumber == -s_dNan - #endif - ) +# define HB_FINITE_DBL(d) ( (d) != s_dInfinity && (d) != -s_dInfinity ) +#endif + if( pNumber->item.asDouble.length == 99 || !HB_FINITE_DBL( dNumber ) ) { /* Numeric overflow */ - iBytes = iSize + 1; + iPos = -1; } else { - int iDecR; + double dInt, dFract, dDig, doBase = 10.0; + int iPrec, iFirst = -1; - if( HB_IS_DOUBLE( pNumber ) && iDec < pNumber->item.asDouble.decimal ) + //dNumber = hb_numRound( dNumber, iDec ); + +#ifdef HB_NUM_PRECISION + iPrec = HB_NUM_PRECISION; +#else + iPrec = 16; +#endif + + if ( dNumber < 0 ) { - dNumber = hb_numRound( dNumber, iDec ); - } - if( dNumber != 0.0 ) - { - iDecR = 15 - ( int ) log10( fabs( dNumber ) ); - if(( dNumber < 1 ) && ( dNumber > -1 )) iDecR++; + fNeg = TRUE; + dFract = modf( -dNumber, &dInt ); } else { - iDecR = iDec; + fNeg = FALSE; + dFract = modf( dNumber, &dInt ); } - if( iDecR >= 0 ) + + while ( iPos-- > 0 ) { - if( iDec == 0 ) + dDig = modf( dInt / doBase + 0.01, &dInt ) * doBase; + szResult[ iPos ] = '0' + ( char ) ( dDig + 0.01 ); + if ( szResult[ iPos ] != '0' ) + iFirst = iPos; + if ( dInt < 1 ) + break; + } + + if ( iPos > 0 ) + { + memset( szResult, ' ', iPos ); + } + + if ( iDec > 0 && iPos >= 0 ) + { + for ( iPos = iDot + 1; iPos < iSize; iPos++ ) { - iBytes = sprintf( szResult, "%*.0f", iSize, dNumber ); - } - else - { - if( iDec <= iDecR ) + dFract = modf( dFract * doBase, &dDig ); + szResult[ iPos ] = '0' + ( char ) ( dDig + 0.01 ); + if ( iFirst < 0 ) { - iBytes = sprintf( szResult, "%*.*f", iSize, iDec, dNumber ); + if ( szResult[ iPos ] != '0' ) + { + iFirst = iPos - 1; + } } - else + else if ( iPos - iFirst >= iPrec ) { - if( iDecR == 0 ) iDecR++; - iBytes = sprintf( szResult, "%*.*f%0*u", iSize-iDec+iDecR, iDecR, dNumber, iDec-iDecR, 0 ); + break; } } } - else + + /* now try to round the results and set 0 in places over defined + precision, the same is done by Clipper */ + if ( iPos >= 0 ) { - if( iDec == 0 ) + int iZer, iLast; + + if ( iFirst < 0 ) { - iBytes = sprintf( szResult, "%*.0f%0*u", iSize + iDecR , dNumber / pow( 10.0, ( double ) ( -iDecR ) ), -iDecR, 0 ); + iZer = 0; } else { - iBytes = sprintf( szResult, "%*.0f%0*u.%0*u", (iSize + iDecR - iDec - 1) > 0 ? iSize + iDecR - iDec - 1 : iSize - iDec - 1 , dNumber / pow( 10.0, ( double ) ( -iDecR ) ), -iDecR, 0, iDec, 0 ); + iZer = iSize - iFirst - iPrec - ( iDec > 0 ? 1 : 0 ); + } + dFract = modf( dFract * doBase, &dDig ); + iLast = ( int ) ( dDig + 0.01 ); + + /* hack for x.xxxx4999999999, f.e. 8.995 ~FL 8.994999999999999218.. */ + if ( iLast == 4 && iZer < 0 ) + { + for ( iPos = -iZer; iPos > 0; --iPos ) + { + dFract = modf( dFract * doBase, &dDig ); + if ( dDig + 0.01 < 9 && ( iPos != 1 || dDig < 2 ) ) + break; + } + if ( iPos == 0 ) + iLast = 5; + } + iLast = iLast >= 5 ? 1 : 0; + + iPos = iSize; + while ( iPos-- > 0 ) + { + if ( iDec == 0 || iPos != iDot ) + { + if ( iZer > 0 ) + { + if ( iDec == 0 || iPos <= iDot + 1 ) + { + iLast = szResult[ iPos ] >= '5' ? 1 : 0; + } + szResult[ iPos ] = '0'; + --iZer; + } + else if ( iLast > 0 ) + { + if ( szResult[ iPos ] == '9' ) + { + szResult[ iPos ] = '0'; + } + else + { + if ( szResult[ iPos ] < '0' ) /* '-' or ' ' */ + { + szResult[ iPos ] = '1'; + iFirst = iPos; + } + else + { + szResult[ iPos ]++; + if ( iFirst < 0 ) + { + iFirst = iPos; + } + } + break; + } + } + else + { + break; + } + } + } + if ( fNeg && iFirst >= 0 && iPos >= 0 ) + { + iPos = ( iDot > 0 && iFirst >= iDot ) ? iDot - 2 : iFirst - 1; + if ( iPos >= 0 ) + { + szResult[ iPos ] = '-'; + } } } } } else { + HB_LONG lNumber; + switch( pNumber->type & ~HB_IT_BYREF ) { case HB_IT_INTEGER: - iBytes = sprintf( szResult, "%*i", iSize, pNumber->item.asInteger.value ); + lNumber = pNumber->item.asInteger.value; break; case HB_IT_LONG: - iBytes = sprintf( szResult, "%*li", iSize, pNumber->item.asLong.value ); + lNumber = pNumber->item.asLong.value; + break; + + case HB_IT_DATE: + lNumber = pNumber->item.asDate.value; + break; + + case HB_IT_STRING: + lNumber = pNumber->item.asString.value[0]; break; default: - iBytes = 0; - szResult[ 0 ] = '\0'; /* null string */ + lNumber = 0; + iPos = -1; break; } + + fNeg = ( lNumber < 0 ); + while ( iPos-- > 0 ) + { + szResult[ iPos ] = '0' + ( char ) ( fNeg ? -( lNumber % 10 ) : ( lNumber % 10 ) ); + lNumber /= 10; + if ( lNumber == 0 ) + break; + } + if ( fNeg && iPos-- > 0 ) + szResult[ iPos ] = '-'; + + if ( iPos > 0 ) + memset( szResult, ' ', iPos ); + + if ( iDec > 0 && iPos >= 0 ) + memset( &szResult[iSize - iDec], '0', iDec ); } + szResult[ iSize ] = '\0'; /* Set to asterisks in case of overflow */ - if( iBytes > iSize ) + if( iPos < 0 ) { memset( szResult, '*', iSize ); - szResult[ iSize ] = '\0'; return FALSE; } + else if ( iDot > 0 ) + { + szResult[ iDot ] = '.'; + } return TRUE; } @@ -1344,7 +1623,7 @@ char * HB_EXPORT hb_itemStr( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec ) /* We at least have a width value */ int iSize = ( iDec > 0 ? iWidth + 1 + iDec : iWidth ); - szResult = ( char * ) hb_xgrab( HB_MAX_DOUBLE_LENGTH ); + szResult = ( char * ) hb_xgrab( iSize + 1 ); hb_itemStrBuf( szResult, pNumber, iSize, iDec ); } } @@ -1364,7 +1643,7 @@ char * HB_EXPORT hb_itemString( PHB_ITEM pItem, ULONG * ulLen, BOOL * bFreeReq ) HB_TRACE(HB_TR_DEBUG, ("hb_itemString(%p, %p, %p)", pItem, ulLen, bFreeReq)); - switch( pItem->type ) + switch( pItem->type & ~HB_IT_BYREF ) { case HB_IT_STRING: case HB_IT_MEMO: @@ -1417,11 +1696,7 @@ char * HB_EXPORT hb_itemString( PHB_ITEM pItem, ULONG * ulLen, BOOL * bFreeReq ) case HB_IT_POINTER: { -#ifndef HB_HAS_SNPRINTF - int size = 16; /* 8 bytes for address + 0x + \0 + padding */ -#else - int size = 11; /* 8 bytes for address + 0x + \0 */ -#endif + int size = ( sizeof( void * ) << 1 ) + 3; /* n bytes for address + 0x + \0 */ int n; BOOL bFail = TRUE; @@ -1452,7 +1727,6 @@ char * HB_EXPORT hb_itemString( PHB_ITEM pItem, ULONG * ulLen, BOOL * bFreeReq ) } break; - default: buffer = ""; * ulLen = 0; @@ -1466,54 +1740,49 @@ char * HB_EXPORT hb_itemString( PHB_ITEM pItem, ULONG * ulLen, BOOL * bFreeReq ) being padded. If date, convert to string using hb_dateFormat(). If numeric, convert to unpadded string. Return pointer to string and set string length */ -char * hb_itemPadConv( PHB_ITEM pItem, char * buffer, ULONG * pulSize ) +char HB_EXPORT * hb_itemPadConv( PHB_ITEM pItem, ULONG * pulSize, BOOL * bFreeReq ) { - char * szText; - - HB_TRACE(HB_TR_DEBUG, ("hb_itemPadConv(%p, %p, %p)", pItem, buffer, pulSize)); + HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_itemPadConv(%p, %p, %p)", pItem, pulSize, bFreeReq)); + /* to be clipper compatible don't convert HB_IT_BYREF items */ if( pItem ) { - if( HB_IS_STRING( pItem ) ) + switch( pItem->type ) { - szText = hb_itemGetCPtr( pItem ); - *pulSize = hb_itemGetCLen( pItem ); - } - else if( HB_IS_DATE( pItem ) ) - { - char szDate[ 9 ]; + case HB_IT_STRING: + case HB_IT_MEMO: + case HB_IT_DATE: + return hb_itemString( pItem, pulSize, bFreeReq ); - szText = hb_dateFormat( hb_pardsbuff( szDate, 1 ), buffer, hb_set.HB_SET_DATEFORMAT ); - *pulSize = strlen( szText ); - } - else if( HB_IS_INTEGER( pItem ) ) - { - sprintf( buffer, "%d", hb_itemGetNI( pItem ) ); - szText = buffer; - *pulSize = strlen( szText ); - } - else if( HB_IS_LONG( pItem ) ) - { - sprintf( buffer, "%ld", hb_itemGetNL( pItem ) ); - szText = buffer; - *pulSize = strlen( szText ); - } - else if( HB_IS_DOUBLE( pItem ) ) - { - int iDecimal; + case HB_IT_DOUBLE: + case HB_IT_INTEGER: + case HB_IT_LONG: + { + int i; + char * buffer = hb_itemString( pItem, pulSize, bFreeReq ); - hb_itemGetNLen( pItem, NULL, &iDecimal ); - sprintf( buffer, "%.*f", iDecimal, hb_itemGetND( pItem ) ); - szText = buffer; - *pulSize = strlen( szText ); + /* remove leading spaces if any, a little bit redundant but + * I don't want to complicate the API interface more. Druzus + */ + for ( i = 0; buffer[i] == ' '; i++ ); + + if ( i > 0 ) + { + int j = 0; + * pulSize -= i; + do + { + buffer[j++] = buffer[i]; + } + while ( buffer[i++] ); + } + return buffer; + } + default: + break; } - else - szText = NULL; } - else - szText = NULL; - - return szText; + return NULL; } PHB_ITEM HB_EXPORT hb_itemValToStr( PHB_ITEM pItem ) diff --git a/harbour/source/vm/macro.c b/harbour/source/vm/macro.c index b0f69be53f..c08e536bad 100644 --- a/harbour/source/vm/macro.c +++ b/harbour/source/vm/macro.c @@ -1238,18 +1238,38 @@ void hb_compGenPushSymbol( char * szSymbolName, BOOL bFunction, BOOL bAlias, HB_ } /* generates the pcode to push a long number on the virtual machine stack */ -void hb_compGenPushLong( long lNumber, HB_MACRO_DECL ) +void hb_compGenPushLong( HB_LONG lNumber, HB_MACRO_DECL ) { - if( lNumber ) + if( lNumber == 0 ) { - hb_compGenPCode1( HB_P_PUSHLONG, HB_MACRO_PARAM ); - hb_compGenPCode1( ( ( char * ) &lNumber )[ 0 ], HB_MACRO_PARAM ); - hb_compGenPCode1( ( ( char * ) &lNumber )[ 1 ], HB_MACRO_PARAM ); - hb_compGenPCode1( ( ( char * ) &lNumber )[ 2 ], HB_MACRO_PARAM ); - hb_compGenPCode1( ( ( char * ) &lNumber )[ 3 ], HB_MACRO_PARAM ); + hb_compGenPCode1( HB_P_ZERO, HB_MACRO_PARAM ); + } + else if( lNumber == 1 ) + { + hb_compGenPCode1( HB_P_ONE, HB_MACRO_PARAM ); + } + else if( HB_LIM_INT8( lNumber ) ) + { + hb_compGenPCode2( HB_P_PUSHBYTE, (BYTE) lNumber, HB_MACRO_PARAM ); + } + else if( HB_LIM_INT16( lNumber ) ) + { + hb_compGenPCode3( HB_P_PUSHINT, HB_LOBYTE( lNumber ), HB_HIBYTE( lNumber ), HB_MACRO_PARAM ); + } + else if( HB_LIM_INT32( lNumber ) ) + { + BYTE pBuffer[ 5 ]; + pBuffer[ 0 ] = HB_P_PUSHLONG; + HB_PUT_LE_UINT32( pBuffer + 1, lNumber ); + hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), HB_MACRO_PARAM ); } else - hb_compGenPCode1( HB_P_ZERO, HB_MACRO_PARAM ); + { + BYTE pBuffer[ 9 ]; + pBuffer[ 0 ] = HB_P_PUSHLONGLONG; + HB_PUT_LE_UINT64( pBuffer + 1, lNumber ); + hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), HB_MACRO_PARAM ); + } } @@ -1475,10 +1495,14 @@ void hb_compGenPushLogical( int iTrueFalse, HB_MACRO_DECL ) /* generates the pcode to push a double number on the virtual machine stack */ void hb_compGenPushDouble( double dNumber, BYTE bWidth, BYTE bDec, HB_MACRO_DECL ) { - hb_compGenPCode1( HB_P_PUSHDOUBLE, HB_MACRO_PARAM ); - hb_compGenPCodeN( ( BYTE * ) &dNumber, sizeof( double ), HB_MACRO_PARAM ); - hb_compGenPCode1( bWidth, HB_MACRO_PARAM ); - hb_compGenPCode1( bDec, HB_MACRO_PARAM ); + BYTE pBuffer[ sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE ) + 1 ]; + + pBuffer[ 0 ] = HB_P_PUSHDOUBLE; + HB_PUT_LE_DOUBLE( &( pBuffer[ 1 ] ), dNumber ); + pBuffer[ 1 + sizeof( double ) ] = bWidth; + pBuffer[ 1 + sizeof( double ) + sizeof( BYTE ) ] = bDec; + + hb_compGenPCodeN( pBuffer, 1 + sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE ), HB_MACRO_PARAM ); } void hb_compGenPushFunCall( char * szFunName, HB_MACRO_DECL ) diff --git a/harbour/source/vm/memvars.c b/harbour/source/vm/memvars.c index 25a2765cac..754a81be43 100644 --- a/harbour/source/vm/memvars.c +++ b/harbour/source/vm/memvars.c @@ -1441,7 +1441,7 @@ HB_FUNC( __MVSAVE ) } else /* NOTE: Undocumented error message in CA-Cl*pper 5.2e and 5.3x. [ckedem] */ - hb_errRT_BASE( EG_ARG, 2008, NULL, "__MSAVE", 3, hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); + hb_errRT_BASE( EG_ARG, 2008, NULL, "__MSAVE", HB_MIN( hb_pcount(), 3 ), hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ) ); } /* NOTE: There's an extension in Harbour, which makes it possible to only @@ -1583,7 +1583,7 @@ HB_FUNC( __MVRESTORE ) } else /* NOTE: Undocumented error message in CA-Cl*pper 5.2e and 5.3x. [ckedem] */ - hb_errRT_BASE( EG_ARG, 2007, NULL, "__MRESTORE", 2, hb_paramError( 1 ), hb_paramError( 2 ) ); + hb_errRT_BASE( EG_ARG, 2007, NULL, "__MRESTORE", HB_MIN( hb_pcount(), 2 ), hb_paramError( 1 ), hb_paramError( 2 ) ); } /* ----------------------------------------------------------------------- */ diff --git a/harbour/source/vm/runner.c b/harbour/source/vm/runner.c index b85946f729..c2949579bb 100644 --- a/harbour/source/vm/runner.c +++ b/harbour/source/vm/runner.c @@ -186,7 +186,7 @@ HB_FUNC( __HRBRUN ) HB_FUNC( __HRBLOAD ) { if( hb_pcount() >= 1 ) - hb_retnl( (LONG) hb_hrbLoad( hb_parc( 1 ) ) ); + hb_retptr( (void *) hb_hrbLoad( hb_parc( 1 ) ) ); else hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBLOAD", 0 ); } @@ -199,7 +199,7 @@ HB_FUNC( __HRBDO ) { int i; char **argv = NULL; - PHRB_BODY pHrbBody = (PHRB_BODY) hb_parnl( 1 ); + PHRB_BODY pHrbBody = (PHRB_BODY) hb_parptr( 1 ); if( pHrbBody ) { @@ -223,16 +223,16 @@ HB_FUNC( __HRBDO ) HB_FUNC( __HRBUNLOAD ) { if( hb_pcount() >= 1 ) - hb_hrbUnLoad( (PHRB_BODY) hb_parnl( 1 ) ); + hb_hrbUnLoad( (PHRB_BODY) hb_parptr( 1 ) ); else hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBUNLOAD", 0 ); } HB_FUNC( __HRBGETFU ) { - if( hb_pcount() > 1 && ISNUM( 1 ) && ISCHAR( 2 ) ) + if( hb_pcount() > 1 && ISPOINTER( 1 ) && ISCHAR( 2 ) ) { - PHRB_BODY pHrbBody = (PHRB_BODY) hb_parnl( 1 ); + PHRB_BODY pHrbBody = (PHRB_BODY) hb_parptr( 1 ); ULONG ulPos = 0; if( pHrbBody ) @@ -246,9 +246,9 @@ HB_FUNC( __HRBGETFU ) ulPos++; } if( ulPos < pHrbBody->ulSymbols ) - hb_retnl( (LONG) ( pHrbBody->pSymRead + ulPos ) ); + hb_retptr( ( void *) ( pHrbBody->pSymRead + ulPos ) ); else - hb_retnl( 0 ); + hb_retptr( NULL ); hb_xfree( szName ); } else @@ -264,7 +264,7 @@ HB_FUNC( __HRBDOFU ) if( argc >=1 ) { int i; - PHB_SYMB pSym = (PHB_SYMB) hb_parnl( 1 ); + PHB_SYMB pSym = (PHB_SYMB) hb_parptr( 1 ); if( pSym ) { @@ -537,9 +537,7 @@ static int hb_hrbFileReadHead( FILE * file, char * szFileName ) } hb_hrbFileRead( file, szFileName, cInt, 2, 1 ); - return ( ( BYTE ) cInt[ 0 ] ) + - ( ( BYTE ) cInt[ 1 ] ) * 0x100 ; - + return HB_PCODE_MKSHORT( cInt ); } /* ReadId @@ -598,10 +596,7 @@ static long hb_hrbFileReadLong( FILE * file, char * szFileName ) return 0; } else - return ( ( BYTE ) cLong[ 0 ] ) + - ( ( BYTE ) cLong[ 1 ] ) * 0x100 + - ( ( BYTE ) cLong[ 2 ] ) * 0x10000 + - ( ( BYTE ) cLong[ 3 ] ) * 0x1000000 ; + return HB_PCODE_MKLONG( cLong ); } diff --git a/harbour/tests/bldtest/bldtest.c b/harbour/tests/bldtest/bldtest.c index 7957e41387..53f7be7a76 100644 --- a/harbour/tests/bldtest/bldtest.c +++ b/harbour/tests/bldtest/bldtest.c @@ -3,7 +3,7 @@ int main() { char buf[16]; - int n, i, l, iRet = 0; + int n, i, l, f, iRet = 0; printf("\nStandard C types:\n"); printf("\t sizeof(void*)=%d\n", (int) sizeof(void*)); @@ -19,16 +19,15 @@ int main() printf("\nHarbour types:\n"); printf("\t sizeof(BYTE)=%d %s\n", (int) sizeof(BYTE ), sizeof(BYTE )==1 ? "OK" : "BAD" ); printf("\t sizeof(SHORT)=%d %s\n", (int) sizeof(SHORT ), sizeof(SHORT )==2 ? "OK" : "BAD" ); - printf("\t sizeof(UINT)=%d %s\n", (int) sizeof(UINT ), sizeof(UINT )==4 ? "OK" : "BAD" ); - printf("\t sizeof(LONG)=%d %s\n", (int) sizeof(LONG ), sizeof(LONG )==4 ? "OK" : "BAD" ); + printf("\t sizeof(UINT)=%d %s\n", (int) sizeof(UINT ), sizeof(UINT)==4 || sizeof(UINT)==8 ? "OK" : "BAD" ); + printf("\t sizeof(LONG)=%d %s\n", (int) sizeof(LONG ), sizeof(LONG)==4 || sizeof(LONG)==8 ? "OK" : "BAD" ); printf("\tsizeof(LONGLONG)=%d %s\n", (int) sizeof(LONGLONG), sizeof(LONGLONG)==8 ? "OK" : "BAD" ); printf("\t sizeof(double)=%d %s\n", (int) sizeof(double ), sizeof(double )==8 ? "OK" : "BAD" ); - if ( sizeof(BYTE )!=1 || - sizeof(SHORT )!=2 || - sizeof(LONG )!=4 || - sizeof(LONGLONG)!=8 || - sizeof(double )!=8 ) + if ( sizeof(BYTE)!=1 || sizeof(SHORT)!=2 || + (sizeof(LONG)!=4 && sizeof(LONG)!=8) || + (sizeof(LONGLONG)!=4 && sizeof(LONGLONG)!=8) || + sizeof(double)!=8 ) { iRet = 1; } @@ -50,28 +49,60 @@ int main() i == 4321 ? "little" : "unknown", i == l ? "OK" : "BAD" ); if( i != l ) + { iRet = 1; + } buf[0] = 0x12; buf[1] = 0x34; buf[2] = 0x56; buf[3] = 0x78; - i = ( HB_GET_BE_ULONG( buf ) == 0x12345678L && - HB_GET_LE_ULONG( buf ) == 0x78563412L ); + buf[4] = 0x65; + i = ( HB_GET_BE_UINT32( buf ) == 0x12345678L && + HB_GET_LE_UINT32( buf ) == 0x78563412L ); if ( ! i ) + { iRet = 1; + } printf( "byte order translation: %s\n", i ? "OK" : "BAD" ); + for ( l = 0; l < 4; l++ ) + { + n = HB_GET_BE_UINT16( &buf[l] ); + f = n == (buf[l] * 256 + buf[l+1]) ? 1 : 0; + if ( ! f ) + { + iRet = 1; + } + printf( "HB_GET_BE_UINT16(%x,%x) = %x -> %s\n", buf[l], buf[l+1], n, + f ? "OK" : "BAD" ); + + n = HB_GET_LE_UINT16( &buf[l] ); + f = n == (buf[l] + 256 * buf[l+1]) ? 1 : 0; + if ( ! f ) + { + iRet = 1; + } + printf( "HB_GET_LE_UINT16(%x,%x) = %x -> %s\n", buf[l], buf[l+1], n, + f ? "OK" : "BAD" ); + } + n = (char)255; printf( "n=%d -> (char) type is %ssinged %s\n", n, n < 0 ? "" : "un", n < 0 ? "OK" : "BAD" ); if ( n >= 0 ) + { iRet = 1; + } if ( iRet ) + { printf("\nHarbour cannot be compiled !!!\n"); + } else + { printf("\nBasic test is correct, try to compile Harbour.\n"); + } return iRet; } diff --git a/harbour/utils/hbtest/hbtest.prg b/harbour/utils/hbtest/hbtest.prg index 9ee991cf69..b3b8760796 100644 --- a/harbour/utils/hbtest/hbtest.prg +++ b/harbour/utils/hbtest/hbtest.prg @@ -179,7 +179,7 @@ STATIC FUNCTION Main_LAST() #endif TEST_LINE( MEMVARBLOCK( "mcString" ) , NIL ) #ifndef __XPP__ - TEST_LINE( __MSave( "*BADNAM*.MEM", "*", .T. ) , "E BASE 2006 Create error *BADNAM*.MEM F:DR" ) + TEST_LINE( __MSave( BADFNAME(), "*", .T. ) , "E BASE 2006 Create error " + BADFNAME() + " F:DR" ) #endif RETURN NIL @@ -285,7 +285,7 @@ STATIC FUNCTION TEST_BEGIN( cParam ) //rddSetDefault( "DBFCDX" ) #endif - dbCreate( "!TEMP!.DBF",; + dbCreate( "!TEMP!.dbf",; { { "TYPE_C" , "C", 15, 0 } ,; { "TYPE_C_E" , "C", 15, 0 } ,; { "TYPE_D" , "D", 8, 0 } ,; @@ -299,7 +299,7 @@ STATIC FUNCTION TEST_BEGIN( cParam ) { "TYPE_L" , "L", 1, 0 } ,; { "TYPE_L_E" , "L", 1, 0 } } ) - USE ( "!TEMP!.DBF" ) NEW ALIAS w_TEST EXCLUSIVE + USE ( "!TEMP!.dbf" ) NEW ALIAS w_TEST EXCLUSIVE dbAppend() @@ -406,8 +406,8 @@ STATIC FUNCTION TEST_END() dbSelectArea( "w_TEST" ) dbCloseArea() - fErase( "!TEMP!.DBF" ) - fErase( "!TEMP!.DBT" ) + fErase( "!TEMP!.dbf" ) + fErase( "!TEMP!.dbt" ) s_nEndTime := Seconds() @@ -603,6 +603,13 @@ FUNCTION HB_SToD( cDate ) #endif #endif +STATIC FUNCTION BADFNAME() +#ifdef __PLATFORM__Linux + return "*BADNAM/*.MEM" +#else + return "*BADNAM*.MEM" +#endif + + /* Don't change the position of this #include. */ #include "rt_init.ch" - diff --git a/harbour/utils/hbtest/rt_misc.prg b/harbour/utils/hbtest/rt_misc.prg index a061746e7e..3d163e1099 100644 --- a/harbour/utils/hbtest/rt_misc.prg +++ b/harbour/utils/hbtest/rt_misc.prg @@ -508,14 +508,11 @@ FUNCTION Main_MISC() /* NOTE: Cannot yet test the return value of the function on a DEFAULT-ed failure. */ - /* NOTE: The dot in the "*INVALID*." filename is intentional and serves - to hide different path handling, since Harbour is platform - independent. */ TEST_LINE( __CopyFile("$$COPYFR.TMP") , "E BASE 2010 Argument error __COPYFILE A:1:C:$$COPYFR.TMP " ) TEST_LINE( __CopyFile("$$COPYFR.TMP", "$$COPYTO.TMP") , NIL ) TEST_LINE( __CopyFile("NOT_HERE.$$$", "$$COPYTO.TMP") , "E BASE 2012 Open error NOT_HERE.$$$ F:DR" ) - TEST_LINE( __CopyFile("$$COPYFR.TMP", "*INVALID*.") , "E BASE 2012 Create error *INVALID*. F:DR" ) + TEST_LINE( __CopyFile("$$COPYFR.TMP", BADFNAME()) , "E BASE 2012 Create error " + BADFNAME() + " F:DR" ) FErase("$$COPYFR.TMP") FErase("$$COPYTO.TMP") @@ -593,11 +590,11 @@ FUNCTION Main_MISC() TEST_LINE( MemoRead("$$MEMOFI.TMP") , ""+Chr(26)+"" ) TEST_LINE( MemoWrit("$$MEMOFI.TMP",scStringW) , .T. ) TEST_LINE( MemoRead("$$MEMOFI.TMP") , ""+Chr(13)+""+Chr(10)+""+Chr(10)+""+Chr(9)+"" ) - TEST_LINE( MemoWrit("*INVALI*.TMP",scStringZ) , .F. ) + TEST_LINE( MemoWrit(BADFNAME2() ,scStringZ) , .F. ) #ifndef __XPP__ TEST_LINE( MemoRead() , "" ) #endif - TEST_LINE( MemoRead("*INVALI*.TMP") , "" ) + TEST_LINE( MemoRead( BADFNAME2() ) , "" ) FErase("$$MEMOFI.TMP") @@ -846,5 +843,22 @@ STATIC FUNCTION TESTFNAME( cFull ) #endif +STATIC FUNCTION BADFNAME() + /* NOTE: The dot in the "*INVALID*." filename is intentional and serves + to hide different path handling, since Harbour is platform + independent. */ +#ifdef __PLATFORM__Linux + return "*INVALID/*." +#else + return "*INVALID*." +#endif + +STATIC FUNCTION BADFNAME2() +#ifdef __PLATFORM__Linux + return "*INVALI/*.TMP" +#else + return "*INVALI*.TMP" +#endif + /* Don't change the position of this #include. */ #include "rt_init.ch" diff --git a/harbour/utils/hbtest/rt_str.prg b/harbour/utils/hbtest/rt_str.prg index 435a02cfb5..01dc846f91 100644 --- a/harbour/utils/hbtest/rt_str.prg +++ b/harbour/utils/hbtest/rt_str.prg @@ -472,7 +472,11 @@ FUNCTION Main_STR() /* REPLICATE() */ #ifdef __HARBOUR__ - TEST_LINE( Replicate("XXX", 2000000000) , "E BASE 1234 String overflow REPLICATE A:2:C:XXX;N:2000000000 F:S" ) + #ifdef __ARCH64BIT__ + TEST_LINE( Replicate("XXX", 9000000000000000000) , "E BASE 1234 String overflow REPLICATE A:2:C:XXX;N:9000000000000000000 F:S" ) + #else + TEST_LINE( Replicate("XXX", 2000000000) , "E BASE 1234 String overflow REPLICATE A:2:C:XXX;N:2000000000 F:S" ) + #endif #else TEST_LINE( Replicate("XXX", 30000) , "E BASE 1234 String overflow REPLICATE A:2:C:XXX;N:30000 F:S" ) #endif