Page 1 of 1

A straight FILE-FIND - function ?

Posted: Fri Jul 25, 2008 8:43 am
by ukoenig
Hello,

i'm busy, to create a new easy to use 3 step - MAKE-utility.

1. define a project-name.
2. select HARBOUR or xHARBOUR.
3. select your project path.

thats all

I want a automatic find of the
installed FWH, xHARBOUR, HARBOUR, BORLAND-files.

------ Start of the MAKE-script

#Borland make sample, (c) FiveTech Software 2005

HBDIR=d:\xharbour
BCDIR=d:\bcc55
FWDIR=d:\fwh

-----------------------------

At first i have _ for drives :

aDrives( [<nType>] ) --> aDrives


than in a loop of the aDrives-array for the files :

aFindFile( <cFileName>, <cPath>, <aResult> ) --> aResult

I tested aFindfile() as stand-alone prog., but don't get it working
bound-error and so on.

aResult1 := {} // Borland
aResult2 := {} // Harbour
aResult3 := {} // FWH

// <cFileName> File to search.
// <cPath> Path of beginning of the search.
// <aResult> Array where the result of the search will be stored.

aFindFile( "BCC32.exe", "c:", aResult1 ) // starting from c:
msgalert( aResult1[1][1] ) ?????
aFindFile( "HARBOUR.exe", "c:", aResult2 )
msgalert( aResult2[1][1] ) ?????
aFindFile( "FIVEH.lib", "c:", aResult3 )
msgalert( aResult3[1][1] ) ?????

somebody knows, how the structure of the return-array looks ?
i couldn't find a sample.

is there another way ( maybe a API-function )
_ for the directory infos ?

Best Regards
Uwe :lol:

Posted: Fri Jul 25, 2008 9:05 am
by Otto
Hello Uwe,
I sent you my snipkeeper. Please have a look into it.
Regards,
Otto

Posted: Sat Jul 26, 2008 10:32 pm
by Jeff Barnes
Hi Otto.

Could you send me a copy as well?

FiveWin / FiveLinux Make

Posted: Sun Jul 27, 2008 3:27 am
by xProgrammer
Hi all

I'm working on a FiveLinux make utility. To this end I have written a FILES class and worked on some shell scripts including providing the date and time of compilation as a define for the xHarbour compiler so you can know exactly when any executable file was compiled. I have shown that I can happily compile and link FiveLinux applications from my FiveLinux utility.

DOS/Windows batch files aren't as capable as shell scripts (I think) so a FiveWin version might need the utility to a bit more work in terms of generating a batch file to run or run each step.

My current shell script is as follows:

Code: Select all

#!/bin/bash
# m.sh

builddate=$(date +"%d/%m/%Y@%T")
strBD=""
strBD+='-dkBDATE="'
strBD+=${builddate}
strBD+='"'
echo date string is ${strBD}

if [ $# = 0 ]; then
   echo syntax: ./m.sh project
   echo where project is the name of the Five Linux project [.flp] file
   exit
fi

check_errs()
{
  # Parameter 1 is the return code
  # Parameter 2 is text to display on failure.
  if [ "${1}" -ne "0" ]; then
    echo "ERROR # ${1} : ${2}"
    exit ${1}
  fi
}

compile_prg()
{
  # Parameter 1 is the module name  
  echo compiling $1.prg xHarbour code to C code
  ./../../xharbour/bin/harbour $1.prg -n -I./../include -I./../../xharbour/include -q0 ${strBD}
  check_errs $? "compiling ${1}.prg"
  echo compiling $1.c to object code
  gcc $1.c -c -I./../include -I./../../xharbour/include `pkg-config --cflags gtk+-2.0`
  check_errs $? "compiling ${1}.c"
  rm $1.c
}

. ${1}.flp
echo
echo Building ${appname}
echo


objects=""
for m in ${sources}
do
  compile_prg ${m}
  objects+=" ${m}.o"
done
libs="-lfivex -lfivec -lcommon -lvm -lrtl -lrdd -lmacro -llang -lcodepage -lpp -ldbfntx -ldbfcdx -ldbffpt -lhbsix -lhsx -lpcrepos -lusrrdd -ltip -lct -lcgi -lgtnul -lgtstd -lgtcgi -lgtcrs -lhbodbc -ldebug -lm -lgpm -lncurses"
ldirs="-L./../lib -L./../../xharbour/lib"
cfigs="`pkg-config --libs gtk+-2.0` `pkg-config --libs libglade-2.0` `pkg-config --libs libgnomeprintui-2.2`"

echo linking to create ${output}
gcc ${objects} -o${output} ${ldirs} ${cfigs} -Wl,--start-group ${libs} -Wl,--end-group

echo removing object files
for m in ${sources}
do
  rm ${m}.o
done

echo done!
The project (.flp) file is what varies. It is included by the line

Code: Select all

. ${1}.flp
it's name having been passed in as the parameter to the shell script. This file looks like this:

Code: Select all

#!/bin/bash

appname="mSYS Medical Software"
output="mSYS"
sources="mSYS 
mTEMLIST 
xOBJECTS 
PATIENT_Class 
PATFILE_Class 
EXTEND5 
DOCTOR_Classes 
OSTEO_Class 
SINGLE_Class
xPATIENT_Class 
PRINTERS
RECORD_Class"
which can be generated easily by the utility. Please note that the utility isn't finished yet. But the main thing is to perfect the FILES class (I have some issues with UPDATE option on BROWSEs under FiveLinux).

A utility that could also handle both FiveLinux and FiveWin would be nice (ie same source code)

My FILES class as it stands is as follows:

Code: Select all

CLASS FILES

DATA sDir              /** string: absolute directory name of directory to list */
DATA aDirs             /** array: of directory names of above directory */
DATA aFDirInfo         /** array: of contents of above directory */
DATA lEntries          /** logical: aFDirInfo has real entries rather than just a dummy entry so browse doesn't crash */
DATA brw_FILE_LIST     /** object: file list browse object */
DATA bInclude          /** code block: evaluated to determine if a file entry should be included */
DATA sSelectedFile     /** string: the name of the selected file */
DATA lSelectionMade    /** logical: a file has been selected */


METHOD New() CONSTRUCTOR
METHOD GetList( plUpdateDirs )
METHOD Select( psWhat, psFullName )
METHOD ChooseDir( piLevel )
METHOD Select_Clicked()

ENDCLASS

METHOD New() CLASS FILES

::aFDirInfo := ARRAY( 0 )

RETURN self


METHOD GetList( plUpdateDirs ) CLASS FILES

LOCAL sTokenEnv        /** string: work variable for tokeniser */
LOCAL iDirDepth        /** integer: depth of directory */
LOCAL aDirInfo         /** array: of directory contents unsorted and unfiltered */
LOCAL aEntry           /** array: used for building ::aFDirInfo entries*/
LOCAL lInclude         /** logical: should this entry be included in the filtered list */

IF plUpdateDirs
   ::aDirs := ARRAY( 0 )
   AAdd( ::aDirs, "/" )
   ::sDir := CurDirX()
   TokenInit( @::sDir, "/", 0, @sTokenEnv )
   DO WHILE .NOT. TokenEnd( @sTokenEnv )
      sToken := TokenNext( @::sDir, , @sTokenEnv )
      AAdd( ::aDirs, sToken )
   ENDDO
ENDIF
// ? "Length of aDirs", LEN( ::aDirs )
// ? "aDirs[1]", ::aDirs[1]
// ? "aDirs[2]", ::aDirs[2]

aDirInfo := Directory( ::sDir + "*", "d" )
// MsgInfo( "raw entries = " + STR( LEN( aDirInfo ) ) )
// ::aFDirInfo := ARRAY( 0 )
ASize( ::aFDirInfo, 0 )
FOR ii = 1 TO LEN( aDirInfo )
   // ? aDirInfo[ii][1], aDirInfo[ii][5]
   IF aDirInfo[ii][5] = "D"
      aENTRY := ARRAY( 0 )
      AADD( aEntry, aDirInfo[ii][1] )
      AADD( aEntry, "(dir)" )
      AADD( ::aFDirInfo, aEntry )
     ELSE
      // IF RIGHT( aDirInfo[ii][1], 4 ) = ".flp"
      lInclude := Eval( ::bInclude, aDirInfo[ii][1] )
      IF lInclude
         aENTRY := ARRAY( 0 )
         AADD( aEntry, aDirInfo[ii][1] )
         AADD( aEntry, "(file)" )
         AADD( ::aFDirInfo, aEntry )
      ENDIF
   ENDIF
NEXT

ASORT( ::aFDirInfo, , , { |x, y| ( x[2] < y[2] ) .OR. ( (x[2] = y[2] ) .AND. ( UPPER( x[1] ) < UPPER( y[1] ) ) ) } )
IF LEN( ::aFDirInfo ) < 1
   aENTRY := ARRAY( 0 )
   AAdd( aENTRY, "" )
   AAdd( aENTRY, "" )
   AAdd( ::aFDirInfo, aENTRY )
   ::lEntries := .F.
  ELSE
   ::lEntries := .T.
ENDIF
RETURN nil

METHOD Select( psWhat, psFullName ) CLASS FILES

LOCAL dlg_SELECT_FILE  /** string: file selection dialog */
LOCAL btn_SELECT   /** object (button): select button on dlg_SELECT_FILE */
LOCAL sTitle       /** string: dialog title */
LOCAL iNextCol     /** integer: horizontal position of next directory button */
LOCAL iDirDepth    /** integer: number of directory levels */
LOCAL ii           /** integer: loop counter */
LOCAL oThisButton  /** object (button): store buttons so their properties can be manipulated */
LOCAL sThisLabel   /** string: directory name = label for this button */
LOCAL iThisWidth   /** integer: calculated required button width */
LOCAL lLoop        /** logical: loop controller */

sTitle := "Open " + psWhat
lLoop := .T.
DO WHILE lLoop
   DEFINE DIALOG dlg_SELECT_FILE TITLE sTitle SIZE 600, 800
   iNextCol := 4
   iDirDepth := LEN( ::aDirs )
   FOR ii = 1 TO iDirDepth
      sThisLabel := ::aDirs[ii]
      iThisWidth := ( ( LEN( sThisLabel ) + 2 ) * 8 )
      @ 60, iNextCol BUTTON oThisButton PROMPT sThisLabel SIZE iThisWidth, 27 ;
         ACTION ( ::ChooseDir( o:cargo ), ::brw_FILE_LIST:SetArray( ::aFDirInfo ), dlg_SELECT_FILE:Refresh() ) OF dlg_SELECT_FILE PIXEL
      iNextCol += (iThisWidth + 6 )
      oThisButton:cargo := ii
   NEXT
   @ 9, 0.4 BROWSE ::brw_FILE_LIST ;
      FIELDS ::aFDirInfo[::brw_FILE_LIST:nAt][2], ::aFDirInfo[::brw_FILE_LIST:nAt][1]  ;
      HEADERS "Type", "File Name" SIZE 460, 510 OF dlg_SELECT_FILE
   BrwSetColWidths( ::brw_FILE_LIST , { 60, 380 } )
   ::brw_FILE_LIST:iLength := LEN( ::aFDirInfo )
   ::brw_FILE_LIST:SetArray( ::aFDirInfo )
   ::brw_FILE_LIST:bLDblClick := { | nRow, nCol | btn_SELECT:Click() }
   @ 700, 10 BUTTON btn_SELECT PROMPT "Select" ;
      ACTION ( lLoop := ::Select_Clicked( ::sDir + ::aFDirInfo[::brw_FILE_LIST:nAt][1] ),  ;
      IF( !lLoop,  dlg_SELECT_FILE:End(), dlg_SELECT_FILE:End() ) ) ;
      WHEN ::lEntries OF dlg_SELECT_FILE PIXEL UPDATE
// ACTION ( lLoop := ::Select_Clicked( ::sDir + ::aFDirInfo[::brw_FILE_LIST:nAt][1] ),  IF( lLoop, dlg_SELECT_FILE:Refresh(), dlg_SELECT_FILE:End() ) ) ;
//   ACTION ( ::Select_Clicked( ::sDir + ::aFDirInfo[::brw_FILE_LIST:nAt][1] ),  dlg_SELECT_FILE:End() ) ;
   @ 700, 110 BUTTON "Cancel" ;
      ACTION ( lLoop := .F., dlg_SELECT_FILE:End() ) ;
      OF dlg_SELECT_FILE PIXEL
      ACTIVATE DIALOG dlg_SELECT_FILE CENTERED
ENDDO
RETURN nil

METHOD ChooseDir( piLevel ) CLASS FILES

LOCAL sDirName

sDirName := "/"
IF piLevel > 1
   FOR ii = 2 TO piLevel
      sDirName += ::aDirs[ii] + "/"
   NEXT
ENDIF
// MsgInfo( sDirName )
::sDir := sDirName
DirChange( ::sDir )
::GetList( .F. )
::brw_FILE_LIST:iLength := LEN( ::aFDirInfo )
::brw_FILE_LIST:SetArray( ::aFDirInfo )
RETURN nil

METHOD Select_Clicked( xProjectFile ) CLASS FILES

IF ::aFDirInfo[::brw_FILE_LIST:nAt][2] = "(dir)"
   ::sDir += ::aFDirInfo[::brw_FILE_LIST:nAt][1] + "/"
   DirChange( ::sDir )
   ::GetList( .T. )
   ::brw_FILE_LIST:iLength := LEN( ::aFDirInfo )
   ::brw_FILE_LIST:SetArray( ::aFDirInfo )
   ::lSelectionMade := .F.
   RETURN .T.
  ELSE
   ::sSelectedFile := xProjectFile
   ::lSelectionMade := .T.
   RETURN .F.
ENDIF 
It wouldn't take much I believe to get it working with FiveWin. I have been playing around with TWBrowse and have added a DATA iLength. You can probably just delete those lines for FiveWin. Plaese note that whilst this code runs it isn't finished or properly documented yet.

With this class opening an (existing) project file is as simple as:

Code: Select all

FUNCTION ProjectOpen()

LOCAL oFindProject

oFindProject := FILES():New()
oFindProject:bInclude := { | x | RIGHT( UPPER( x ), 4 ) = ".FLP" }
oFindProject:GetList( .T. )
oFindProject:Select( "Project File" )

RETURN nil
and compiling it can be done as follows:

Code: Select all

FUNCTION Compile( xProject )

LOCAL sOsCommand

sOsCommand := "./m.sh " + xProject + " > " + xProject + ".flb" 
RUN ( sOsCommand )
MsgInfo( MemoRead( xProject + ".flb" ) )

RETURN nil
Note that I use the -q0 option so that extra compiler messages (such as line number progress) are suppressed.

Maybe some of this is of help? I am happy to contribute if I can help.

Regards
Douf
(xProgrammer)