Good morning again,

Thank you for answering.

I am using ghc 5.04.1 I compiled myself on a linux box (Mandrake 8.2) .

I'm sending you the source code. Compiled it with the following commands :

ghc -ffi -c GetFNamesBckp.hs -o GetFNamesBckp.o

gcc -I/opt/installed/ghc-5.04.1/lib/ghc-5.04.1/include -c cGetFNamesBckp.c -o 
cGetFNamesBckp.o

ghc -no-hs-main GetFNamesBckp_stub.o GetFNamesBckp.o cGetFNamesBckp.o

If you comment out the "foreign export" command on line 11 in 
GetFNamesBckp.hs and do :

ghc --make Main.hs

Then the executable works ! That's why I thought it had to do with FFI and 
memory allocation.

Thank you

Francis Girard
Le Conquet
France

Le 24 Octobre 2002 09:28, Simon Peyton-Jones a �crit :
> It's certainly a bug of some kind.  Please say what version of GHC you
> are using.  If it's the latest one (5.04.1), please send us the source
> code.
>
> Thanks
>
> Simon
>
> | -----Original Message-----
> | From: Francis Girard [mailto:francis.girard@;free.fr]
> | Sent: 24 October 2002 04:02
> | To: [EMAIL PROTECTED]
> | Subject: EVACUATED object entered! (when doing FFI)
> |
> | Good morning,
> |
> | I wrote a very small program, and it executed ok.
> | I wanted to export a function in "C", and therefore wrote a "C"
>
> wrapper
>
> | function over it to invoke peekCString and peekArray on the input;
>
> newCString
>
> | and newArray on the output.
> |
> | I then did a small "C" driver program. Everything compiled and linked
> | correctly.
> |
> | But at execution the program prints :
> |
> | EVACUATED object entered!
> |
> | as soon as "startupHaskell" is invoked (i.e. even before I call my
>
> foreign
>
> | exported function !)
> |
> | What is the meaning of this message ?
> |
> | Thank you
> |
> | Francis Girard
> | Le Conquet
> | France
> |
> |
> | _______________________________________________
> | Glasgow-haskell-users mailing list
> | [EMAIL PROTECTED]
> | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
-- GetFNamesBckp.hs

module GetFNamesBckp where

import Directory
import List

import Foreign
import Foreign.C

foreign export ccall getFNamesToZipC :: Int -> (Ptr CString) -> IO (Ptr CString)

----------------------------------------------------------------------------
-- Function getFNamesToZip
----------------------------------------------------------------------------
getFNamesToZipC :: Int -> (Ptr CString) -> IO (Ptr CString)
getFNamesToZipC nLen vFs 
  = do cfs <- peekArray nLen vFs
       hfs <- peekCStringArr cfs
       hzs <- getFNamesToZip hfs
       czs <- createCStringArr hzs
       vZs <- newArray czs
       return vZs
       where
       peekCStringArr :: [CString] -> IO [String]
       peekCStringArr [] = return []
       peekCStringArr (cf:cfs) = do hf <- peekCString cf
                                    hfs <- peekCStringArr cfs
                                    return (hf : hfs)
       createCStringArr :: [String] -> IO [CString]
       createCStringArr [] = do sentinel <- newCString "//"
                                return [sentinel]
       createCStringArr (hf:hfs) = do cf <- newCString hf
                                      cfs <- createCStringArr hfs
                                      return (cf : cfs)

getFNamesToZip :: [FilePath] -> IO [FilePath]
getFNamesToZip (f:fs) 
  = do isAFile <- doesFileExist f
       isADir <- doesDirectoryExist f
       if (isAFile)
         then do ll <- getFNamesToZip fs
                 if (isFileToZip f) then return ([f] ++ ll) else return ll
         else if (isADir) && (isDirToZip f)
           then do subdir <- getDirectoryContents f
                   let subfs = [joinDirSubDir f sf | sf <- subdir, sf /= ".", sf /= ".."]
                   l1 <- getFNamesToZip subfs
                   l2 <- getFNamesToZip fs
                   return (l1 ++ l2)
           else getFNamesToZip fs
getFNamesToZip [] = return []

joinDirSubDir :: FilePath -> FilePath -> FilePath
joinDirSubDir d sd
  | (last d) == '/' = d ++ sd
  | otherwise       = (d ++ "/") ++ sd
                            
----------------------------------------------------------------------------
-- Function globFilePattern
----------------------------------------------------------------------------
globFilePattern :: String -> String -> Bool
globFilePattern [] ('*':csPattern) = globFilePattern [] csPattern
globFilePattern [] [] = True
globFilePattern (_:_) [] = False
globFilePattern [] (_:_) = False
globFilePattern (cToMatch:csToMatch) ('*':csPattern)
  | globFilePattern csToMatch csPattern = True
  | otherwise                   = globFilePattern csToMatch ('*':csPattern)
globFilePattern (cToMatch:csToMatch) (cPattern:csPattern)
  | cToMatch == cPattern        = globFilePattern csToMatch csPattern
  | otherwise                   = False

----------------------------------------------------------------------------
-- Function globFilePatternV
----------------------------------------------------------------------------
globFilePatternV :: String -> [String] -> Bool
globFilePatternV csToMatch [] = False
globFilePatternV csToMatch (p:ps)
  | globFilePattern csToMatch p = True
  | otherwise                   = globFilePatternV csToMatch ps

----------------------------------------------------------------------------
-- Function isFileToZip and isDirToZip
----------------------------------------------------------------------------
isFileToZip :: FilePath -> Bool
isFileToZip f =  isFileToZipAI f getAddRegVec getIgnRegVec

isFileToZipAI :: FilePath -> [FilePath] -> [FilePath] -> Bool
isFileToZipAI f vAdd vIgn = (globFilePatternV f vAdd) && not (globFilePatternV f vIgn)
  
isDirToZip :: FilePath -> Bool
isDirToZip f = isFileToZipAI f (getAddRegVec ++ (getBaseDirVR getAddRegVec)) (getIgnRegVec)

getBaseDir :: FilePath -> FilePath 
getBaseDir "/" = []
getBaseDir f = (rev . getFromSlash . rev) f
  where rev :: FilePath -> FilePath
        rev [] = []
        rev (c:cs) = (rev cs) ++ [c]
        getFromSlash :: FilePath -> FilePath
        getFromSlash [] = []
        getFromSlash "/" = "/"
        getFromSlash ('/':cs) = cs
        getFromSlash (_:cs) = getFromSlash cs

getBaseDirR :: FilePath -> [FilePath]
getBaseDirR [] = []
getBaseDirR f = getBaseDirR(getBaseDir f) ++ [getBaseDir f]

getBaseDirV :: [FilePath] -> [FilePath]
getBaseDirV = elimDup . map getBaseDir

getBaseDirVR :: [FilePath] -> [FilePath]
getBaseDirVR = elimEmp . elimDup . foldr (++) [] . map getBaseDirR
               where elimEmp :: [FilePath] -> [FilePath]
                     elimEmp [] = []
                     elimEmp ("":fs) = elimEmp fs
                     elimEmp fs = fs

elimDup :: Ord a => [a] -> [a]
elimDup = foldr (++) [] .  map (take 1) . group . sort

----------------------------------------------------------------------------
-- Functions getAddRegVec and getIgnRegVec
----------------------------------------------------------------------------
getAddRegVec :: [String]
getAddRegVec
  =  ["/home/francis/francis_cal.*",
      "/home/francis/francis_cal.vcs",
      "/home/francis/Mail/*",
      "/home/francis/.aspell.fr.*",
      "/home/francis/.bash_history",
      "/home/francis/.lyx/*",
      "/home/francis/.bash_logout",
      "/home/francis/.bash_profile",
      "/home/francis/.bashrc",
      "/home/francis/.jedit/*",
      "/home/francis/.menu/*",
      "/home/francis/.xemacs/*",
      "/home/francis/PERSONNEL/*"]

getIgnRegVec :: [String]
getIgnRegVec 
  =  ["*.o",
      "*.so",
      "*.a",
      "*.hi",
      "*.pyc",
      "*/FT-BOULOT*",
      "*~"]

-- Main.hs

module Main where

import GetFNamesBckp

main :: IO ()
main = do putStrLn "Computing which files to zip ..."
          vFNames <- getFNamesToZip ["/"]
          putStrLn "******************* RESULTS"
          printVec vFNames
          return ()

printVec :: [String] -> IO()
printVec [] = return ()
printVec (a:as) = do putStrLn a
                     printVec as


// cGetFNamesBckp.c

#include <stdio.h>
#include "GetFNamesBckp_stub.h"

extern void __stginit_GetFNamesBckp(void);

int main( int argc, char** argv)
{
  char* vsBaseDir = NULL;
  char** vsBaseDirs = NULL;
  char** vsNamesToZip = NULL;
  char** it = NULL;
  
  fprintf( stderr, "coucou0\n" );
  startupHaskell(argc, argv, __stginit_GetFNamesBckp);
  
  /* I did ugly explicit mallocs here because I was affraid
     to give memory on the C stack to Haskell. I thought the
     problem was coming from dangling pointers somewhere */
  vsBaseDirs = (char**) malloc(sizeof(char*));
  vsBaseDir = ( char* ) malloc( strlen("/") + 1 );
  strcpy( vsBaseDir, "/" );
  vsBaseDirs[0] = vsBaseDir; 
  
  fprintf( stderr, "coucou1\n" );
  vsNamesToZip = getFNamesToZipC(1, vsBaseDirs);
  fprintf( stderr, "coucou2\n" );
  for( it = vsNamesToZip; strcmp(*it, "//") != 0; it++ )
    printf("%s\n", *it);
  fprintf( stderr, "coucou3\n" );
  shutdownHaskell();
  fprintf( stderr, "coucou4\n" );
  return 0;
}

Reply via email to