[C++-sig] c + python interchangable?

danny280279 at netscape.net danny280279 at netscape.net
Wed Jul 6 02:18:19 CEST 2005


Jason Kankiewicz <jkankiewicz at advpubtech.com> wrote:

>They're interchangeable in a sense because Python is implemented in C 
>and therefore any Python program must have an equivalent C 
>implementation. They're not interchangeable in a sense because Python is 
>an interpreted, dynamically-typed, garbage-collected language and not a 
>compiled, statically-typed, non-garbage-collected language like C.

So what your saying is (code here:)

#define DEBUG

#include 
#include 
#include 
#include 
#include 
#include 

are static links to code comapred to 

def debug

import
import
import

because to me they seem the same, or am i just being stupid?

if that's the case then are there any docs on hybrid programming, because then i could implement all of it in hybrid python/c.

>
>Python complements C by addressing its weaknesses. Python's greatest 
>weakness is speed but this can be addressed by re-coding the slowest 
>parts of a Python program in C (or C++ using Boost.Python or SWIG) as an 
>extension module. This "hybrid programming" approach should take much 
>less work and yield similar results to re-coding an entire Python 
>program in C.
>
my code for findfiles - this is to be renamed and reimplemented as search, a natural language command that can be integrated with package management software to do something like "search package install run". but this still doesn't do what the commands meant to:  Search (the net) (find)Package Install(package) Run(package), type the name of a package in your browser and it comes up with a site that contains that package:  this is a search for autotools (gnu) http://sources.redhat.com/autobook/ now if you could do that using the search command then you could get "search autotools install run" and it would directly go for the above url, query the site, download, and install the files, then run the application, actually here i think you get a docbook that can be run in yelp or something.

#define DEBUG

#include 
#include 
#include 
#include 
#include 
#include 

static ERROR CMDInit(OBJECTPTR, struct KernelBase *);
static ERROR CMDExpunge(void);

#define VER_FINDFILES 1.0

MODULE_HEADER = {
   MODULE_HEADER_V1, CMDInit, NULL, NULL, CMDExpunge,
   JMP_DEFAULT, 0, CPU_PC, VER_FINDFILES, VER_KERNEL,
   "",
   "",
   "",
   ""
};

static struct KernelBase *KernelBase;
static struct FileSystemBase *FileSystemBase;
static struct StringsBase *StringsBase;
static OBJECTPTR modFile = NULL, modStrings = NULL;
static OBJECTPTR FindFilesClass = NULL;
static FIELD FID_SrcFile, FID_DestFile;

struct FindFiles {
   OBJECT_HEADER       
   OBJECTID OutputID;
   LONG     Static;
   LONG     Operation;
   LONG     Response;
   LONG     Flags;

   PRIVATE_FIELDS
   UBYTE Location[300];   
   UBYTE Filter[40];      
   UBYTE Content[60];     
   UBYTE prvFile[160];    
   UBYTE Dest[300];
   BYTE  Stop;
   LONG  TotalChildren;      
   STRING ConfirmScript;
   STRING ErrorScript;
   UBYTE *DataBuffer;
   struct ChildEntry ChildList[10];
};

enum {
   FOP_NONE=0,
   FOP_COPY,
   FOP_MOVE,
   FOP_DELETE
};

enum {
   RSP_NONE=0,
   RSP_CANCEL,
   RSP_YES,
   RSP_YESALL,
   RSP_NO
};

static ERROR GET_ConfirmScript(struct FindFiles *, STRING *);
static ERROR GET_Dest(struct FindFiles *, STRING *);
static ERROR GET_ErrorScript(struct FindFiles *, STRING *);
static ERROR GET_File(struct FindFiles *, STRING *);
static ERROR GET_FileContent(struct FindFiles *, STRING *);
static ERROR GET_Filter(struct FindFiles *, STRING *);
static ERROR GET_Location(struct FindFiles *, STRING *);

static ERROR SET_ConfirmScript(struct FindFiles *, STRING);
static ERROR SET_Dest(struct FindFiles *, STRING);
static ERROR SET_ErrorScript(struct FindFiles *, STRING);
static ERROR SET_FileContent(struct FindFiles *, STRING);
static ERROR SET_Filter(struct FindFiles *, STRING);
static ERROR SET_Location(struct FindFiles *, STRING);

#define FF_FORCEDIR     0x00000001
#define FF_INCLUDEROOT  0x00000002
#define FF_XML          0x00000004
#define FF_NOACTIVATE   0x00000008 
#define FF_SCANLINKS    0x00000010 
#define FF_MATCHFOLDERS 0x00000020 
#define FF_IGNOREFILES  0x00000040 

static struct FieldDef FindFlags[] = {
   { "FORCEDIR",     FF_FORCEDIR },
   { "INCLUDEROOT",  FF_INCLUDEROOT },
   { "XML",          FF_XML },
   { "NOACTIVATE",   FF_NOACTIVATE },
   { "SCANLINKS",    FF_SCANLINKS },
   { "MATCHFOLDERS", FF_MATCHFOLDERS },
   { "IGNOREFILES",  FF_IGNOREFILES },
   { NULL, NULL }
};

static struct FieldDef OperationLookup[] = {
   { "NONE",   NULL },
   { "COPY",   FOP_COPY },
   { "MOVE",   FOP_MOVE },
   { "DELETE", FOP_DELETE },
   { NULL, NULL }
};

static struct FieldDef ResponseLookup[] = {
   { "CANCEL", RSP_CANCEL },
   { "YES",    RSP_YES },
   { "YESALL", RSP_YESALL },
   { "NO",     RSP_NO },
   { "NOALL",  RSP_CANCEL },
   { NULL, NULL }
};

static struct FieldArray FindFilesFields[] = {
   { "Output",        0, FDF_OBJECTID|FDF_RW,  0, NULL, NULL },
   { "Static",        0, FDF_LONG|FDF_RW,      0, NULL, NULL },
   { "Operation",     0, FDF_LONG|FDF_LOOKUP|FDF_RW, (LONG)&OperationLookup, NULL, NULL },
   { "Response",      0, FDF_LONG|FDF_LOOKUP|FDF_RW, (LONG)&ResponseLookup, NULL, NULL },
   { "Flags",         0, FDF_LONGFLAGS|FDF_RW, (LONG)&FindFlags, NULL, NULL },
   { "ConfirmScript", 0, FDF_STRING|FDF_RW, 0, GET_ConfirmScript, SET_ConfirmScript },
   { "Dest",          0, FDF_STRING|FDF_RW, 0, GET_Dest,          SET_Dest },
   { "ErrorScript",   0, FDF_STRING|FDF_RW, 0, GET_ErrorScript,   SET_ErrorScript },
   { "File",          0, FDF_STRING|FDF_R,  0, GET_File,          NULL },
   { "FileContent",   0, FDF_STRING|FDF_RW, 0, GET_FileContent,   SET_FileContent },
   { "Filter",        0, FDF_STRING|FDF_RW, 0, GET_Filter,        SET_Filter },
   { "Location",      0, FDF_STRING|FDF_RW, 0, GET_Location,      SET_Location },
   { "Src",           0, FDF_STRING|FDF_RW, 0, GET_Location,      SET_Location },
    END_FIELD
};

static ERROR FIND_Activate(struct FindFiles *, APTR);
static ERROR FIND_ClosingTag(struct FindFiles *, APTR);
static ERROR FIND_Deactivate(struct FindFiles *, APTR);
static ERROR FIND_Free(struct FindFiles *, APTR);
static ERROR FIND_Init(struct FindFiles *, APTR);

static struct ActionArray FindFilesActions[] = {
   { AC_Activate,      FIND_Activate },
   { AC_ClosingTag,    FIND_ClosingTag },
   { AC_Deactivate,    FIND_Deactivate },
   { AC_Free,          FIND_Free },
   { AC_Init,          FIND_Init },
   { NULL, NULL }
};

#define MT_AddLocation -1

struct mtAddLocation {
   STRING Location;
};

static struct FunctionField argsAddLocation[] = { { "Location", ARG_STRING }, { NULL, NULL } };

static ERROR FIND_AddLocation(struct FindFiles *, struct mtAddLocation *);

static struct MethodArray FindFilesMethods[] = {
   { MT_AddLocation, FIND_AddLocation, "AddLocation", argsAddLocation, sizeof(struct mtAddLocation) },
   { NULL, NULL, NULL, NULL }
};

static LONG ContentMatch(struct FindFiles *, STRING, STRING, UBYTE *);
static void FileMatched(struct FindFiles *, STRING, STRING, OBJECTPTR, struct DirInfo *);
static void OutputText(struct FindFiles *, STRING);
static void ScanLocation(struct FindFiles *, STRING, OBJECTPTR);
static void UserConfirmation(struct FindFiles *, STRING, STRING);
static void UserError(struct FindFiles *, STRING, ERROR);
static ERROR FileCopy(struct FindFiles *, STRING, STRING);
static ERROR FileDelete(struct FindFiles *, STRING);
static ERROR FileMove(struct FindFiles *, STRING, STRING);

static BYTE FindFilesUsage[] = {
"USAGE: findfiles [src]=filename [content]=filecontent [filter]=namefilter\n\
\n\
Use the FindFiles command to search for files in your system.  At a minimum you should supply the directory location from which you wish to start the search.  Optionally you can also search on file content and filter on file names.  Here is an example that searches for PNG files:\n\
\n\
  findfiles src=athene:pictures/ filter=*.png\n\
\n\
If you do not specify the starting location, the search will start from the home: location."
};

static ERROR CMDInit(OBJECTPTR argModule, struct KernelBase *argKernelBase)
{
   KernelBase = argKernelBase;

   if (CreateObject(ID_MODULE, NULL, &modStrings, NULL,
      FID_Name|TSTRING,   "strings",
      FID_Version|TFLOAT, MODVERSION_STRINGS,
      TAGEND) IS ERR_Okay) {
      if (GetField(modStrings, FID_ModBase, FT_POINTER, &StringsBase) != ERR_Okay) {
         return(ObjectError(argModule, ERH_InitModule, ERR_GetField));
      }
   }
   else return(ObjectError(argModule, ERH_InitModule, ERR_CreateObject));

   if (CreateObject(ID_MODULE, NULL, &modFile, NULL,
      FID_Name|TSTRING,   "filesystem",
      FID_Version|TFLOAT, MODVERSION_FILESYSTEM,
      TAGEND) IS ERR_Okay) {
      if (GetField(modFile, FID_ModBase, FT_POINTER, &FileSystemBase) != ERR_Okay) {
         return(ObjectError(argModule, ERH_InitModule, ERR_GetField));
      }
   }
   else return(ObjectError(argModule, ERH_InitModule, ERR_CreateObject));

   ResolveFields("SrcFile",  &FID_SrcFile,
                 "DestFile", &FID_DestFile,
                 TAGEND);

   return(CreateObject(ID_CLASS, NULL, (OBJECTPTR *)&FindFilesClass, NULL,
      FID_BaseClassID|TLONG, ID_FINDFILES,
      FID_Version|TFLOAT,    VER_FINDFILES,
      FID_Name|TSTRING,      "FindFiles",
      FID_Category|TLONG,    CCF_COMMAND,
      FID_Usage|TSTRING,     FindFilesUsage,
      FID_Actions|TPTR,      FindFilesActions,
      FID_Methods|TPTR,      FindFilesMethods,
      FID_Fields|TPTR,       FindFilesFields,
      FID_Size|TLONG,        sizeof(struct FindFiles),
      TAGEND));
}

static ERROR CMDExpunge(void)
{
   if (FindFilesClass) { acFree(FindFilesClass); FindFilesClass = NULL; }
   if (modFile)        { acFree(modFile); modFile = NULL; }
   if (modStrings)     { acFree(modStrings); modStrings = NULL; }
   return(ERR_Okay);
}

static BYTE IsDirectory(STRING Path)
{
   WORD i;

   if (!Path) return(FALSE);

   for (i=0; Path[i]; i++);
   if ((Path[i-1] IS '/') OR (Path[i-1] IS '\\') OR (Path[i-1] IS ':')) return(TRUE);
   return(FALSE);
}

#define BUFFER_SIZE 4096

static ERROR FIND_Activate(struct FindFiles *Self, APTR Void)
{
   struct DirInfo list;
   OBJECTPTR output;
   STRING buffer;
   ERROR error;
   WORD len, i, k;

   if (!Self->Location) {
      if (SetField(Self, FID_Location, FT_STRING, "athene:") != ERR_Okay) {
         OutputText(Self, "Error: You have not given me a location.");
         return(ERR_FieldNotSet);
      }
   }

   if (Self->TotalChildren IS -1) {
      Self->TotalChildren = ARRAYSIZE(Self->ChildList);
      ListChildren(Self->Head.UniqueID, Self->ChildList, &Self->TotalChildren);
   }

   if (!Self->Response) Self->Response = RSP_YES;
   else {

      if (Self->Response IS RSP_CANCEL) return(ERR_Okay);
   }

   if ((Self->Operation IS FOP_DELETE) AND (Self->ConfirmScript)) {
      if (Self->Response != RSP_YESALL) {
         UserConfirmation(Self, Self->Location, Self->Location);
      }
      if ((Self->Response != RSP_YES) AND (Self->Response != RSP_YESALL)) {
         DPrintF("FindFiles:","User cancelled deletion of this file - response %d.", Self->Response);
         return(ERR_Okay);
      }
   }

   output = NULL;
   if (Self->OutputID) {
      if (AccessObject(Self->OutputID, 3000, &output) != ERR_Okay) {
         return(ObjectError(Self, ERH_Activate, ERR_AccessObject));
      }
      Action(AC_Clear, output, NULL);
   }

   DPrintF("~Activate()","[FindFiles:%d] Filter: %s, Location: %s, Content: %s, Operation: %s", GetUniqueID(Self), Self->Filter, Self->Location, Self->Content, OperationLookup[Self->Operation]);

   if (AllocMemory(BUFFER_SIZE, MEM_STRING|MEM_NOCLEAR, (APTR *)&buffer, NULL) IS ERR_Okay) {
      if (AllocMemory(BUFFER_SIZE, MEM_STRING|MEM_NOCLEAR, (APTR *)&Self->DataBuffer, NULL) IS ERR_Okay) {

         Self->Stop = FALSE;

         error = ERR_Okay;

         for (len=0; Self->Location[len]; len++) buffer[len] = Self->Location[len];
         buffer[len] = 0;

         if (IsDirectory(Self->Location) IS TRUE) {

            k = StrLength(Self->Dest);
            if (Self->Flags & FF_INCLUDEROOT) {
               if ((buffer[len-1] IS '/') OR (buffer[len-1] IS '\\')) {
                  i = len-1;
                  while ((i > 0) AND (buffer[i-1] != ':') AND (buffer[i-1] != '/') AND (buffer[i-1] != '\\')) i--;
                  StrCopy(buffer+i, Self->Dest+k, sizeof(Self->Dest)-k);
               }
            }

            #ifndef DEBUG
               DebugState(FALSE, -1);
            #endif

            ScanLocation(Self, buffer, output);

            #ifndef DEBUG
               DebugState(TRUE, -1);
            #endif

            Self->Dest[k] = 0;
         }
         else {

            while ((len > 0) AND (buffer[len-1] != '/') AND (buffer[len-1] != ':') AND (buffer[len-1] != '\\')) len--;

            if ((!Self->Filter[0]) OR (StrCompare(Self->Filter, buffer+len, 0, STR_WILDCARD) IS ERR_Okay)) {
               if (ContentMatch(Self, buffer, Self->Content, Self->DataBuffer) IS TRUE) {
                  UBYTE filename[256];
                  StrCopy(buffer+len, filename, sizeof(filename));
                  buffer[len] = 0;
                  ClearMemory(&list, sizeof(list));
                  FileMatched(Self, buffer, filename, output, &list);
               }
            }
         }

         FreeMemory(Self->DataBuffer);
         Self->DataBuffer = NULL;
      }
      else error = ObjectError(Self, ERH_Activate, ERR_AllocMemory);

      FreeMemory(buffer);
   }
   else error = ObjectError(Self, ERH_Activate, ERR_AllocMemory);

   if (output) ReleaseObject(output);

   StepBack();
   return(error);
}

static ERROR FIND_AddLocation(struct FindFiles *Self, struct mtAddLocation *Args)
{
   if ((!Args) OR (!Args->Location)) return(ERR_Args);



   return(ERR_Okay);
}

static ERROR FIND_ClosingTag(struct FindFiles *Self, APTR Void)
{
   Self->TotalChildren = ARRAYSIZE(Self->ChildList);
   ListChildren(Self->Head.UniqueID, Self->ChildList, &Self->TotalChildren);

   if (Self->Static IS FALSE) {
      Action(AC_Activate, Self, NULL);
      Action(AC_Free, Self, NULL);
   }

   return(ERR_Okay);
}

static ERROR FIND_Deactivate(struct FindFiles *Self, APTR Void)
{
   Self->Stop = TRUE;
   return(ERR_Okay);
}

static ERROR FIND_Free(struct FindFiles *Self, APTR Void)
{
   if (Self->ConfirmScript) {
      FreeMemory(Self->ConfirmScript);
      Self->ConfirmScript = NULL;
   }

   if (Self->ErrorScript) {
      FreeMemory(Self->ErrorScript);
      Self->ErrorScript = NULL;
   }

   return(ERR_Okay);
}

static ERROR FIND_Init(struct FindFiles *Self, APTR Void)
{
   Self->TotalChildren = -1;
   return(ERR_Okay);
}

static ERROR GET_ConfirmScript(struct FindFiles *Self, STRING *Value)
{
   if ((*Value = Self->ConfirmScript)) {
      *Value = Self->ConfirmScript;
      return(ERR_Okay);
   }
   else return(ERR_FieldNotSet);

   return(ERR_Okay);
}

static ERROR SET_ConfirmScript(struct FindFiles *Self, STRING Value)
{
   LONG i;

   if (Self->ConfirmScript) { FreeMemory(Self->ConfirmScript); Self->ConfirmScript = NULL; }

   if ((Value) AND (*Value)) {
      for (i=0; Value[i]; i++);
      if (AllocMemory(i+1, MEM_STRING|MEM_NOCLEAR, (void **)&Self->ConfirmScript, NULL) IS ERR_Okay) {
         for (i=0; Value[i]; i++) Self->ConfirmScript[i] = Value[i];
         Self->ConfirmScript[i] = 0;
         return(ERR_Okay);
      }
      else return(ObjectError(Self, ERH_SetField, ERR_AllocMemory));
   }
   return(ERR_Okay);
}

static ERROR GET_Dest(struct FindFiles *Self, STRING *Value)
{
   if (Self->Dest[0]) {
      *Value = Self->Dest;
      return(ERR_Okay);
   }
   else return(ERR_FieldNotSet);
}

static ERROR SET_Dest(struct FindFiles *Self, STRING Value)
{
   WORD i;

   if (Value) {
      for (i=0; (i < sizeof(Self->Dest)-1) AND (Value[i]); i++) Self->Dest[i] = Value[i];
      Self->Dest[i] = 0;
   }
   else Self->Dest[0] = 0;

   return(ERR_Okay);
}

static ERROR GET_ErrorScript(struct FindFiles *Self, STRING *Value)
{
   if ((*Value = Self->ErrorScript)) {
      *Value = Self->ErrorScript;
      return(ERR_Okay);
   }
   else return(ERR_FieldNotSet);
}

static ERROR SET_ErrorScript(struct FindFiles *Self, STRING Value)
{
   LONG i;

   if (Self->ErrorScript) { FreeMemory(Self->ErrorScript); Self->ErrorScript = NULL; }

   if ((Value) AND (*Value)) {
      for (i=0; Value[i]; i++);
      if (AllocMemory(i+1, MEM_STRING|MEM_NOCLEAR, (void **)&Self->ErrorScript, NULL) IS ERR_Okay) {
         for (i=0; Value[i]; i++) Self->ErrorScript[i] = Value[i];
         Self->ErrorScript[i] = 0;
         return(ERR_Okay);
      }
      else return(ObjectError(Self, ERH_SetField, ERR_AllocMemory));
   }
   return(ERR_Okay);
}

static ERROR GET_File(struct FindFiles *Self, STRING *Value)
{
   if ((*Value = Self->prvFile)) return(ERR_Okay);
   else return(ERR_FieldNotSet);
}

static ERROR GET_FileContent(struct FindFiles *Self, STRING *Value)
{
   if (Self->Content[0]) {
      *Value = Self->Content;
      return(ERR_Okay);
   }
   else {
      *Value = NULL;
      return(ERR_FieldNotSet);
   }
}

static ERROR SET_FileContent(struct FindFiles *Self, STRING Value)
{
   WORD i;

   if (Value) {
      for (i=0; (i < sizeof(Self->Content)-1) AND (Value[i]); i++) Self->Content[i] = Value[i];
      Self->Content[i] = 0;
   }
   else Self->Content[0] = 0;

   return(ERR_Okay);
}

static ERROR GET_Filter(struct FindFiles *Self, STRING *Value)
{
   if (Self->Filter[0]) {
      *Value = Self->Filter;
      return(ERR_Okay);
   }
   else {
      *Value = NULL;
      return(ERR_FieldNotSet);
   }
}

static ERROR SET_Filter(struct FindFiles *Self, STRING Value)
{
   WORD i;

   if (Value) {
      for (i=0; (i < sizeof(Self->Filter)-1) AND (Value[i]); i++) Self->Filter[i] = Value[i];
      Self->Filter[i] = 0;
   }
   else Self->Filter[0] = 0;

   return(ERR_Okay);
}

static ERROR GET_Location(struct FindFiles *Self, STRING *Value)
{
   if (Self->Location[0]) {
      *Value = Self->Location;
      return(ERR_Okay);
   }
   else {
      *Value = NULL;
      return(ERR_FieldNotSet);
   }
   return(ERR_Okay);
}

static ERROR SET_Location(struct FindFiles *Self, STRING Value)
{
   WORD i;

   if ((Value) AND (*Value)) {
      for (i=0; (i < sizeof(Self->Location)-2) AND (Value[i]); i++) Self->Location[i] = Value[i];
      if (Self->Flags & FF_FORCEDIR) if ((Value[i-1] != '/') AND (Value[i-1] != ':') AND (Value[i-1] != '\\')) Self->Location[i++] = '/';
      Self->Location[i] = 0;
   }
   else Self->Location[0] = 0;

   return(ERR_Okay);
}

static void OutputText(struct FindFiles *Self, STRING Buffer)
{
   struct acDataChannel channel;

   if (Self->OutputID) {
      /*** Send the data to the output object ***/

      ActionMsg(AC_Clear, Self->OutputID, NULL);

      channel.ObjectID     = GetUniqueID(Self);
      channel.DataType     = DATA_TEXT;
      channel.Version      = 1;
      channel.TotalEntries = 1;
      channel.Buffer       = Buffer;
      channel.Size         = StrLength(Buffer) + 1;
      ActionMsg(AC_DataChannel, Self->OutputID, &channel);
   }
}

static LONG ContentMatch(struct FindFiles *Self, STRING Location, STRING Content, UBYTE *DataBuffer)
{
   struct acRead read;
   struct File *file;
   LONG size;
   WORD k, j;

   if ((!Content) OR (!*Content)) return(TRUE);

   if (CreateObject(ID_FILE, NULL, &file, NULL,
      FID_Location|TSTRING, Location,
      FID_Flags|TLONG,      FL_READ,
      TAGEND) IS ERR_Okay) {

      if ((file->Flags & FL_SYMLINK) AND (!(Self->Flags & FF_SCANLINKS))) {
         acFree(file);
         return(FALSE);
      }

      GetField(file, FID_Size, FT_LONG, &size);
      k = 0;
      while (size > 0) {
         read.Buffer = DataBuffer;
         if (size < BUFFER_SIZE) read.Length = size;
         else read.Length = BUFFER_SIZE;
         Action(AC_Read, file, &read);
         for (j=0; (j < size) AND (j < BUFFER_SIZE); j++) {
            if (lcase(DataBuffer[j]) != lcase(Content[k])) k = 0;
            else {
               k++;
               if (!Content[k]) {
                  acFree(file);
                  return(TRUE);
               }
            }
         }

         ProcessMessages(NULL, NULL);
         if (Self->Stop IS TRUE) break;

         size -= BUFFER_SIZE;
      }
      acFree(file);
   }

   return(FALSE);
}

static void FileMatched(struct FindFiles *Self, STRING Path, STRING Filename, OBJECTPTR Output, struct DirInfo *Info)
{
   UBYTE buffer[256];
   OBJECTPTR object;
   WORD j, pathlen, filelen, fullpath_len;

   for (pathlen=0; Path[pathlen]; pathlen++);
   for (filelen=0; Filename[filelen]; filelen++);

   fullpath_len = StrCopy(Path, Self->prvFile, sizeof(Self->prvFile));
   StrCopy(Filename, Self->prvFile + fullpath_len, sizeof(Self->prvFile) - fullpath_len);

   if (Output) {
      if (Self->Flags & FF_XML) {
         StrFormat(buffer, sizeof(buffer), "<file icon=\"%s\">%s<folder>%s</folder><size sort=\"%.10d\">%d</size><date>%4d%2d%2d %d:%d:%d</date></file>", GetFileIcon(Self->prvFile), Filename, Path, (LONG)Info->Size, (LONG)Info->Size, Info->Time.Year, Info->Time.Month, Info->Time.Day, Info->Time.Hour, Info->Time.Minute, Info->Time.Second);
         ActionTags(AC_DataChannel, Output, Self->Head.UniqueID, DATA_XML, 1, buffer, StrLength(buffer)+1, 1);
      }
      else ActionTags(AC_DataChannel, Output, Self->Head.UniqueID, DATA_TEXT, 1, Self->prvFile, StrLength(Self->prvFile) + 1, 1);
   }

   if ((Self->TotalChildren > 0) AND (!(Self->Flags & FF_NOACTIVATE))) {
      
      for (j=0; j < Self->TotalChildren; j++) {
         if (AccessObject(Self->ChildList[j].ObjectID, 0, &object) IS ERR_Okay) {
            acActivate(object);
            ReleaseObject(object);
         }
      }
   }

   if (Self->Operation) {
      switch (Self->Operation) {
         case FOP_DELETE:
            FileDelete(Self, Self->prvFile);
            break;

         case FOP_COPY:
            FileCopy(Self, Self->prvFile, Filename);
            break;

         case FOP_MOVE:
            FileMove(Self, Self->prvFile, Filename);
            break;
      }
   }
}

static void ScanLocation(struct FindFiles *Self, STRING Buffer, OBJECTPTR output)
{
   struct DirInfo *info;
   LONG k, bufferlen, count, flags;
   WORD root, len, insert, dest_created;
   ERROR error;

   if (Self->Dest[0]) DPrintF("ScanLocation()","%s TO %s", Buffer, Self->Dest);
   else DPrintF("ScanLocation()","%s", Buffer);

   if ((Buffer[0] IS ':') OR (!Buffer[0])) root = TRUE;
   else root = FALSE;

   if (Self->Stop IS TRUE) return;

   for (len=0; Buffer[len]; len++);

   count = 0;
   dest_created = FALSE;
   flags = RDF_FILE|RDF_SIZE|RDF_DATE|RDF_PERMISSIONS;
   if (Self->Flags & FF_MATCHFOLDERS) flags |= RDF_DIRECTORY|RDF_QUALIFY;
   if (Self->Flags & FF_IGNOREFILES) flags &= ~RDF_FILE;
   
   if (OpenDirectory(Buffer, flags, &info) IS ERR_Okay) {
      while (ScanDirectory(info) IS ERR_Okay) {
         count++;
         ProcessMessages(NULL, NULL);

         for (k=0; info->Name[k]; k++) Buffer[len+k] = info->Name[k];
         Buffer[len+k] = 0;
         bufferlen = len+k;

         if (StrCompare(Self->Filter, info->Name, 0, STR_WILDCARD) != ERR_Okay) {
            #ifdef DEBUG
               DPrintF("ScanDir:","File \"%s\" does not match filter \"%s\"", info->Name, Self->Filter);
            #endif
            continue;
         }

         if (info->Flags & RDF_FILE) {
            if (ContentMatch(Self, Buffer, Self->Content, Self->DataBuffer) IS FALSE) {
               #ifdef DEBUG
                  DPrintF("ScanDir:","Content of file %s is not a match.", info->Name);
               #endif
               continue;
            }
         }

         if (Self->Operation IS FOP_MOVE) {
            if (dest_created IS FALSE) {
               dest_created = TRUE;
               if (IsDirectory(Self->Dest)) MakeDirectory(Self->Dest, info->Permissions | PERMIT_USER);
            }
         }

         Buffer[len] = 0;

         FileMatched(Self, Buffer, info->Name, output, info);

         if (Self->Response IS RSP_CANCEL) Self->Stop = TRUE;

         if (Self->Stop IS TRUE) break;
      }

      Buffer[len] = 0;
      CloseDirectory(info);
   }

   if (Self->Stop IS TRUE) {
      #ifdef DEBUG
      DPrintF("ScanDirectory:","Stopping search.");
      #endif
      return;
   }

   if (OpenDirectory(Buffer, RDF_DIRECTORY|RDF_QUALIFY, &info) IS ERR_Okay) {

      insert = -1;
      if (Self->Dest[0]) {
         for (insert=0; Self->Dest[insert]; insert++);
         if ((Self->Dest[insert-1] != '/') AND (Self->Dest[insert-1] != '\\') AND
             (Self->Dest[insert-1] != ':')) {
            insert = -1;
         }
      }

      while (ScanDirectory(info) IS ERR_Okay) {
         count++;
         if (info->Flags & RDF_LINK) continue; 
         
         ProcessMessages(NULL, NULL);

         if (root IS TRUE) {
            for (k=0; info->Name[k]; k++) Buffer[k] = info->Name[k];
            Buffer[k] = 0;
         }
         else {
            for (k=0; info->Name[k]; k++) Buffer[len+k] = info->Name[k];
            Buffer[len+k] = 0;
         }

         if (insert != -1) {
            StrCopy(info->Name, Self->Dest+insert, sizeof(Self->Dest) - insert);
         }

         ScanLocation(Self, Buffer, output);
         if (Self->Stop IS TRUE) break;

         if (insert != -1) Self->Dest[insert] = 0;
      }
      CloseDirectory(info);
   }
   #ifdef DEBUG
   else DPrintF("ScanDirectory()","No folders in %s", Buffer);
   #endif

   Buffer[len] = 0;

   if ((!count) AND ((Self->Operation IS FOP_COPY) OR (Self->Operation IS FOP_MOVE))) {
      if (IsDirectory(Self->Dest)) {
        
        BYTE save;
         for (len=0; Self->Dest[len]; len++);
         save = Self->Dest[len-1];
         Self->Dest[len-1] = 0;

        //DPrintF("ScanDirectory:","Empty dir \"%s\" TO \"%s\"", Buffer, Self->Dest);

         if (Self->Operation IS FOP_COPY) error = CopyLocation(Buffer, Self->Dest);
         else error = MoveLocation(Buffer, Self->Dest);

         Self->Dest[len-1] = save;

         if (error != ERR_Okay) {
            DPrintF("ScanDirectory:","Error %d returned.", error);
            Self->Stop = TRUE;
            Self->Response = RSP_CANCEL;
            UserError(Self, Buffer, error);
            return;
         }
      }

      ProcessMessages(NULL, NULL); 
   }
   else {
      
      if ((Self->Operation IS FOP_DELETE) AND (!Self->Filter[0]) AND (!Self->Content[0])) {
         DeleteFile(Buffer);
      }
      else if ((Self->Operation IS FOP_MOVE) AND (!Self->Filter[0]) AND (!Self->Content[0])) {
         DeleteFile(Buffer);
      }

      if (!count) ProcessMessages(NULL, NULL); 
   }
}

static ERROR FileCopy(struct FindFiles *Self, STRING Location, STRING File)
{
   UBYTE dest[300];
   LONG type;
   ERROR error;
   WORD i;

   if (!Self->Dest[0]) return(ERR_Okay);

   i = StrCopy(Self->Dest, dest, sizeof(dest)-1);

   if ((dest[i-1] IS '/') OR (dest[i-1] IS '\\') OR (dest[i-1] IS ':')) {
      i += StrCopy(File, dest+i, sizeof(dest)-i);
   }

   if ((Self->ConfirmScript) AND (Self->Response != RSP_YESALL)) {
      if ((AnalyseLocation(dest, &type) IS ERR_Okay) AND ((type IS LOC_FILE) OR (type IS LOC_DIRECTORY))) {
         UserConfirmation(Self, Location, dest);
      }
   }

   if ((Self->Response != RSP_YES) AND (Self->Response != RSP_YESALL)) {
      DPrintF("FindFiles:","Skipping file %s, response %d", Location, Self->Response);
      return(ERR_Okay);
   }

   error = CopyLocation(Location, dest);

   if (error) {
      Self->Stop = TRUE;
      Self->Response = RSP_CANCEL;
      UserError(Self, Location, error);
   }

   return(ERR_Okay);
}

static ERROR FileDelete(struct FindFiles *Self, STRING Location)
{
   ERROR error;

   if ((Self->Response IS RSP_CANCEL) OR (Self->Stop IS TRUE)) return(ERR_Okay);

   error = DeleteFile(Location);

   if (error) UserError(Self, Location, error);

   return(ERR_Okay);
}

static ERROR FileMove(struct FindFiles *Self, STRING Location, STRING File)
{
   UBYTE dest[300];
   LONG type;
   ERROR error;
   WORD i;

   DPrintF("FileMove()","%s, File: %s", Location, File);

   if (!Self->Dest[0]) return(ERR_Okay);

   i = StrCopy(Self->Dest, dest, sizeof(dest)-1);

   if ((dest[i-1] IS '/') OR (dest[i-1] IS '\\') OR (dest[i-1] IS ':')) {
      i += StrCopy(File, dest+i, sizeof(dest)-i);
   }

   if ((Self->ConfirmScript) AND (Self->Response != RSP_YESALL)) {
      if ((AnalyseLocation(dest, &type) IS ERR_Okay) AND ((type IS LOC_FILE) OR (type IS LOC_DIRECTORY))) {
         UserConfirmation(Self, Location, dest);
      }
   }

   if ((Self->Response != RSP_YES) AND (Self->Response != RSP_YESALL)) {
      DPrintF("FindFiles:","Skipping file %s, response %d", Location, Self->Response);
      return(ERR_Okay);
   }

   error = MoveLocation(Location, dest);

   if (error) {
      Self->Stop = TRUE;
      Self->Response = RSP_CANCEL;
      UserError(Self, Location, error);
   }

   return(ERR_Okay);
}

static void UserConfirmation(struct FindFiles *Self, STRING SrcFile, STRING DestFile)
{
   OBJECTPTR script;

   if (Self->Response IS RSP_YESALL) return;

   if (!Self->ConfirmScript) {
      Self->Response = RSP_YES;
      return;
   }

   Self->Response = RSP_CANCEL;
   if (CreateObject(ID_SCRIPT, NF_CHILD, &script, NULL,
         FID_Location|TSTRING,   Self->ConfirmScript,
         FID_SrcFile|TUNLISTED,  SrcFile,
         FID_DestFile|TUNLISTED, DestFile,
         TAGEND) IS ERR_Okay) {
      acActivate(script);
      acFree(script);
   }
}

static void UserError(struct FindFiles *Self, STRING Location, ERROR ErrorCode)
{
   OBJECTPTR script;

   if (!Self->ErrorScript) return;

   if (CreateObject(ID_SCRIPT, NF_CHILD, &script, NULL,
         FID_Location|TSTRING, Self->ErrorScript,
         FID_File|TUNLISTED,   Location,
         TAGEND) IS ERR_Okay) {
      acActivate(script);
      acFree(script);
   }
}

I know that this is going to take up a bit of space and time but I mean if I can implement this easier the way I want to then so much the better.  It would be easier for someone like yourself to use too, if you were to type "wget http://url/package" "gunzip package" "cd dir" "./configure" "make" "make clean" "make install" "package", compared to "search package install run" using natural language commands that you expect to be there.  That's the hope anyway, but as you can see this just finds files on your local system, and doesn't do any of the stuff that I wanted it to, I did mainly lift it from gnu find but i've got another load of dirs under the same command dir 1 is for wget, 1 is for findfiles (the file I sent you), 1 is for nlp code so that find/search are accepted as the actual commands in bash instead of all of the above, etc etc so now I'm going to do it right and send that to gnu.  Any docs you can point me in the direction of?  


__________________________________________________________________
Switch to Netscape Internet Service.
As low as $9.95 a month -- Sign up today at http://isp.netscape.com/register

Netscape. Just the Net You Need.

New! Netscape Toolbar for Internet Explorer
Search from anywhere on the Web and block those annoying pop-ups.
Download now at http://channels.netscape.com/ns/search/install.jsp


More information about the Cplusplus-sig mailing list