home *** CD-ROM | disk | FTP | other *** search
-
- /*******************************************************************
- $CRT 01 Jun 1996 : hb
-
- $AUT Holger Burkarth
- $DAT >>find.c<< 08 Mar 1997 19:37:42 - (C) ProDAD
- *******************************************************************/
-
- //##ex mcpp:cppc -gs -o pos:pos/Ex/find p:pLib/StartCode.o p:/pOS_RKRM/pDos/find.c p:pLib/StdIO.o -l pOSStub -l pOS
-
- /***********************************************************
- pOS programing example - Copyright (C) 1995-97 proDAD
-
- This code was written as an easy to understand example,
- how to program pOS features. It is provided 'as-is',
- without any express or implied warranty.
-
- Permission is hereby granted to use, copy and modify
- this source code for any purpose, without fee, subject
- to the following conditions:
-
- (1) This notice may not be removed or altered from any
- source distribution.
-
- (2) Altered source versions must be plainly marked as
- such, and must not be misrepresented as being
- the original source code.
-
- (3) If only executable code is distributed, then the
- accompanying documentation have to state that
- "this software is based in part on examples of
- the pOS developer packet".
-
- (4) Permission for use of this code is granted only
- if the user accepts full responsibility for any
- undesirable consequences. proDAD accept NO LIABILITY
- for damages of any kind.
-
- ©proDAD
- ***********************************************************/
-
- /*\
- *** Example:
- *** struct pOS_DosArgs
- *** struct pOS_AnchorPath
- *** struct pOS_PatternMatching
- *** struct pOS_FileHandle
- ***
- *** pOS_ReadDosArgs
- *** pOS_PathMatchFirst
- *** pOS_CURRANCHORPATH
- *** pOS_PathMatchNext
- *** pOS_PathMatchEnd
- *** pOS_DeleteDosArgs
- *** pOS_ConstructPattern
- *** pOS_ParsePatternA
- *** pOS_PrintDosErr
- *** pOS_DestructPattern
- *** pOS_AllocMem
- *** pOS_OpenFile
- *** pOS_FileGets
- *** pOS_MatchPattern
- *** pOS_CheckBreakSignal
- *** pOS_CloseFile
- *** pOS_FreeMem
- ***
- \*/
-
- #define __COMPUTER_AMIGA 1
- #define NOMYDEBUG
-
- #include "p:pExec/Types.h"
- #include "p:pDOS/ArgTags.h"
- #include "p:pDOS/ScanDir.h"
- #include "p:pDOS/Files.h"
- #include "p:pDOS/DosSig.h"
- #include "p:pDOS/DosErrors.h"
- #include "p:pDOS/FIB.h"
- #include "p:pDOS/Lock.h"
- #include "p:proto/pLibExt.h"
- #include "p:proto/pExec2.h"
- #include "p:proto/pDOS2.h"
-
- #ifdef _____ME_____
- #include "grund/inc_string.h"
- #include "grund/inc_stdio.h"
- #else
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <string.h>
- #include <stdio.h>
- #ifdef __cplusplus
- }
- #endif
- #endif
-
-
- const CHAR *HelpText=
- "$H(PATTERN)"
- "Suchmuster, a#? sucht alle Files/Dirs, die mit 'a' beginnen"
- "$H(DIR)"
- "zu durchsuchende Verzeichnis(es)"
- "$H(FILES)"
- "Schaltet die Suche nach Files ein\n"
- "Falls kein FILES und DIRS angegeben wird,\n"
- "so werden nur Files gesucht."
- "$H(DIRS)"
- "Schaltet die Suche nach Directories ein"
- "$H(ALL)"
- "Erweitert die Suche auf Unterverzeichnisse"
- "$H(MA)"
- "Falls ein DIR ein MultiAssign ist, werden\n"
- "alle Möglichkeiten in die Suche einbezogen."
- "$H(DEPTH)"
- "Schränkt die Unterverzeichnis-Suche ein.\n"
- "Dieser Parameter wird nur in Verbindung mit ALL\n"
- "verwendet."
- "$H(SHOW)"
- "Zeigt den aktuellen Pfad an."
- "$H(PROMPT)"
- "Ausgabe-Schablone definieren. Z.B PROMPT=\"type %s*N\"\n"
- "Bei 'SEARCH' wird die gefundene Zeile in %ld ausgegeben."
- "$H(SEARCH)"
- "Sucht im File nach einem Muster.\n"
- "SEARCH=\"#?hallo#?\"\n"
- " => sucht die Buchstabenabfolge 'hallo' bzw. 'HALLO'"
- "$H(BINARY)"
- "Sucht bei SEARCH nach Null-Bytes als Zeilenende. Sonst wird\n"
- "ein LF als Zeilenende interpretiert."
- ;
-
- const CHAR *PrgHeader=
- "Files/Dirs finder\n"
- "find a#? b: all\n"
- " => sucht alle Dateien, die mit 'a' beginnen, in Laufwerk b\n"
- "Der Befehl kann jederzeit mit Ctrl-C unterbrochen werden."
- ;
-
- const CHAR *PrgVerText=
- "$VER: 1.2 ("__DATE2__") (Copyright 1996-97 by proDAD) (Created by Holger Burkarth)";
-
-
- ULONG SearchFile(const pOS_FileLock*,const CHAR*,const pOS_PatternMatching*);
- ULONG SearchLFFile(const pOS_FileLock*,const CHAR*,const pOS_PatternMatching*);
- ULONG SearchBinFile(const pOS_FileLock*,const CHAR*,const pOS_PatternMatching*);
-
-
-
- /*----------------------------------
- -----------------------------------*/
- #ifdef __cplusplus
- extern "C"
- #endif
-
- VOID main()
- {
- pOS_DosArgs* Args;
- UWORD Err=0;
- ULONG Ops[11]={0,0,0,0,0,0,16,0,0,0,0};
-
- Args=pOS_ReadDosArgs(
- // 0 1 2 3 4 5
- "PATTERN/A, DIR=DIRECTORY/A/M, FILES/S, DIRS/S, ALL/S, MA=MULTIASSIGN/S, "
- // 6 7 8 9 10
- "DEPTH/N/K, SHOW/S, PROMPT/K, SEARCH/K, BIN=BINARY/S",
- Ops,sizeof(Ops)/sizeof(ULONG),
-
- ARGTAG_PrgHeaderText, (ULONG)PrgHeader, /* kurze Programm-Beschreibung */
- ARGTAG_HelpText, (ULONG)HelpText, /* Help-Texte */
- ARGTAG_PrgVerText, (ULONG)PrgVerText, /* VER-String */
- ARGTAG_VarName, (ULONG)"shell/find", /* Variable für die Default-Paramenter */
- TAG_END);
-
- if(Args) {
- struct { /* zusammengesetzte Struct, damit ap_Buf sinnvoll eingesetzt werden kann */
- pOS_AnchorPath AP;
- CHAR Path[pOS_DosPathName_MAX];
- } Scan;
- pOS_PatternMatching PM;
- SLONG Error=DOSERR_None;
- ULONG PFlg=APF_PrtError; /* Scan-Errors werden autom. nach pr_CES ausgegeben */
- ULONG FoundCnt=0;
- __CONST__ CHAR **DirNames=(CHAR**)Ops[1]; /* DIR ist ein Multi-Paramenter */
- static const CHAR *const PathFmt="\r%s\033[K"; /* Cursor an den Zeilenanfang und gesamte Zeile leeren */
- static const CHAR *const CRLFmt="\r\033[K"; /* Clear-Line */
-
- pOS_ConstructPattern(&PM);
-
- if(Ops[5]) PFlg |= APF_MultiAssign; /* MA erlauben */
- if(Ops[9]) { /* SEARCH */
- if(Ops[3]) { /* DIRS */
- Ops[3]=0;
- printf("Argument 'SEARCH' excludes 'DIRS'.\n");
- }
- if(!pOS_ParsePattern(&PM,(CHAR*)Ops[9],0)) { /* Internes Pattern-Format erzeugen */
- Error=(pOS_DosErrors)PM.pmt_Parse.ptmt_Error;
- Err=DOSFAIL_FAIL;
- pOS_PrintDosErr(NULL,(CHAR*)Ops[9],Error); /* Error ausgeben */
- }
- }
- else if(Ops[10]) { // !SEARCH && BIN
- printf("Argument BIN ist nur sinnvoll in Verbindung mit SEARCH.\n");
- }
-
- if(Ops[2]==0 && Ops[3]==0) Ops[2]=1; /* default => FILES */
-
- /*\
- *** ap_BufLen!=0, so wird der aktuelle Pfad autom. in ap_Buf aufgebaut.
- *** ap_BreakBits=DOSSIGF_CTRL_C => erlaubt ein ^C zum Abbruch,
- *** Error ist nach ^C auf DOSERR_ProgAborted gesetzt
- \*/
- Scan.AP.ap_BreakBits=DOSSIGF_CTRL_C;
- Scan.AP.ap_BufLen=pOS_DosPathName_MAX;
-
- if(Ops[7]) printf("\033[0 p"); // *** Cursor OFF (speed up)
-
- if(Error==DOSERR_None) {
- for(; *DirNames ;++DirNames) {
- UWORD Depth=*((ULONG*)Ops[6]);
- UBYTE NeedLF=FALSE;
-
- /*\
- *** Init. für den Scanner. Es ist ebenfalls möglich den Pfad+Pattern als
- *** Pfad zu übergeben.
- \*/
- if(!(Error=pOS_PathMatchFirst(NULL,*DirNames,&Scan.AP,(CHAR*)Ops[0],PFlg))) {
- if(!Ops[8]) printf("Search <%s> ...\n",*DirNames);
-
- /*\
- *** Ersten bzw. nächsten Eintrag ermitteln. Die Pattern-Filterung wirkt sich
- *** nicht auf dieses Funktion aus, es werden immer alle Dateien ermittelt.
- *** Erst mittels (ap_Flags & APF_IsWild) wird geprüft, ob der Pattern-Vergleich
- *** positiv war. Am Directory-Ende wird als Error DOSERR_NoMoreEntries zurückgegeben.
- ***
- *** Der define pOS_CURRANCHORPATH() ermittelt das aktuelle Objekt. (read only)
- ***
- *** Nach jedem pOS_PathMatchNext() ist die Daten-Struct Obj->an_FIB gesetzt.
- \*/
- while(!(Error=pOS_PathMatchNext(&Scan.AP)) ) {
- const pOS_AnchorPathObj *const Obj=pOS_CURRANCHORPATH(&Scan.AP);
-
- if(Ops[7] && (Ops[9]==0 || (Scan.AP.ap_Flags & APF_IsWild)) ) {
- printf(PathFmt,Scan.AP.ap_Buf);
- NeedLF=TRUE;
- }
-
- /*\
- *** Ist das aktuelle Objekt ein DIR, so wird das 'APF_DoEnterDir' - Flag
- *** autom. gesetzt und als Kennung für den nächsten pOS_PathMatchNext()
- *** Durchlauf verwendet. Immer wenn das 'APF_DoEnterDir'-Flag gesetzt ist,
- *** wird in dieses DIR verzweigt. Ein gesetztes 'APF_ReturnDir'-Flag
- *** signalisiert, daß das DIR vollständig gelesen wurde und mit dem 'Parent'-Dir
- *** fortgefahren wird.
- \*/
- if(Scan.AP.ap_Flags & APF_DoEnterDir) {
- if(Ops[3] && (Scan.AP.ap_Flags & APF_IsWild)) { // DIRS
- if(NeedLF) {printf(CRLFmt); NeedLF=FALSE; }
- printf(Ops[8] ? (CHAR*)Ops[8]:"Found DIR %s\n",Scan.AP.ap_Buf);
- ++FoundCnt;
- }
- }
- else {
- if(Ops[2] && (Scan.AP.ap_Flags & APF_IsWild)) { // FILES
- if(Ops[9]) { // SEARCH
- ULONG Line;
- /*\
- *** Das Öffnen eines Files erfolgt über den Parent-Lock wesnetlich schneller,
- *** als über den gesamten Pfad. In jedem pOS_AnchorPathObj-Objekt ist immer der
- *** dazugehörige Lock vermerkt.
- \*/
- if(Ops[10]) Line=SearchBinFile(Obj->an_Lock,Obj->an_FIB.fib_FileName,&PM);
- else Line=SearchLFFile(Obj->an_Lock,Obj->an_FIB.fib_FileName,&PM);
- if(Line) {
- if(NeedLF) {printf(CRLFmt); NeedLF=FALSE; }
- if(Line==~0) { /* User-Abort Ctrl-C */
- Scan.AP.ap_FoundBreak |= DOSSIGF_CTRL_C; /* auto-abort in pOS_PathMatchNext */
- }
- else {
- printf(Ops[8] ? (CHAR*)Ops[8]:"Found FILE %s LINE %ld\n",Scan.AP.ap_Buf,Line);
- ++FoundCnt;
- }
- }
- }
- else {
- if(NeedLF) {printf(CRLFmt); NeedLF=FALSE; }
- printf(Ops[8] ? (CHAR*)Ops[8]:"Found FILE %s\n",Scan.AP.ap_Buf);
- ++FoundCnt;
- }
- }
- }
- if(!Ops[4]) Scan.AP.ap_Flags &= ~APF_DoEnterDir; // *** ALL
-
- if(Scan.AP.ap_Flags & APF_DoEnterDir) {
- if(Depth==0) {
- Scan.AP.ap_Flags &= ~APF_DoEnterDir;
- if(NeedLF) {printf(CRLFmt); NeedLF=FALSE; }
- if(!Ops[8]) printf("Max Depth, abort deep-scan\n");
- }
- else --Depth;
- }
- if(Scan.AP.ap_Flags & APF_ReturnDir) ++Depth;
- }
- }
-
- /*\
- *** Nach einem pOS_PathMatchFirst() muß immer pOS_PathMatchEnd() aufgerufen werden.
- *** (auch im Fehlerfall)
- \*/
- pOS_PathMatchEnd(&Scan.AP);
-
- if(NeedLF) {printf(CRLFmt); NeedLF=FALSE; }
-
- if(Error && Error!=DOSERR_NoMoreEntries) {
- Err=DOSFAIL_ERROR; /* größerer Fehler aufgetreten */
- break;
- }
- }
- }
- if(Ops[7]) printf("\033[1 p"); // *** Cursor ON
-
- if(Err==0 && FoundCnt==0) Err=DOSFAIL_WARN; /* es wurde kein passendes File/Dir gefunden */
-
- pOS_DestructPattern(&PM); /* Pattern-Datas freigeben */
- pOS_DeleteDosArgs(Args); /* Args freigeben */
- }
- else Err=DOSFAIL_FAIL; /* vollkommen fehlgeschlagen */
-
- // pOS_ExitProcess(Err);
- }
-
-
- #if 0
- /*----------------------------------
- Sucht im File nach einem Muster und ermittelt die Zeilennummer.
- -----------------------------------*/
- ULONG SearchFile(const pOS_FileLock* lk,const CHAR* name,
- const pOS_PatternMatching* pm)
- {
- pOS_FileHandle* FH;
- const size_t BufSize=2048;
- UBYTE *Buffer;
- BOOL Flg=FALSE;
- ULONG Line=0;
-
- /*\
- *** Das File wird relativ zum Lock geöffnet (geht schneller).
- *** Die Fuktion pOS_MatchPattern durchsucht jede Textzeile nach dem Muster.
- \*/
- if(Buffer=(UBYTE*)pOS_AllocMem(BufSize,MEMF_PUBLIC)) {
- if(FH=pOS_OpenFile(lk,name,FILEHDMOD_Read)) {
- while(pOS_FileGets(FH,Buffer,BufSize-1)) {
- ++Line;
- if(pOS_MatchPattern(pm->pmt_First,Buffer)) {
- Flg=TRUE;
- break;
- }
- /*\
- *** Der User hat Ctrl-C gedrückt, das C-Flag wird autom. zurückgesetzt, so daß
- *** ein zweiter Aufruf keinen Break anzeigt.
- \*/
- if(pOS_CheckBreakSignal()) {
- Flg=TRUE; Line=~0;
- break;
- }
- }
- pOS_CloseFile(FH);
- }
- else printf("Cannot open file <...%s>\n",name);
- pOS_FreeMem(Buffer,BufSize);
- }
- else printf("Cannot allocate buffer.\n");
- return(Flg ? Line:0);
- }
- #endif
-
-
- /*----------------------------------
- -----------------------------------*/
- ULONG SearchBinFile(const pOS_FileLock* lk,const CHAR* name,
- const pOS_PatternMatching* pm)
- {
- pOS_FileHandle* FH;
- size_t Pos,BufSize;
- UBYTE *Buffer,*Buf;
- BOOL Flg=FALSE;
- ULONG Line=0;
-
- if(FH=pOS_OpenFile(lk,name,FILEHDMOD_Read)) {
- BufSize=FH->fh_Size;
- if(BufSize>1) {
- if(Buffer=(UBYTE*)pOS_AllocMem(BufSize+1,MEMF_PUBLIC)) {
- if(BufSize==pOS_ReadFile(FH,Buffer,BufSize)) {
- Buffer[BufSize]='\0'; // *** End-Marke
- for(Buf=Buffer; Line<BufSize; Line+=Pos,Buf+=Pos) {
- Pos=strlen(Buf)+1;
- if(pOS_MatchPattern(pm->pmt_First,Buf)) {
- Flg=TRUE;
- break;
- }
-
- if(pOS_CheckBreakSignal()) {
- Flg=TRUE; Line=~0;
- break;
- }
- }
- }
- else printf("Read-Error in <%s>\n",name);
-
- pOS_FreeMem(Buffer,BufSize+1);
- }
- else printf("Cannot allocate buffer. [%ld Bytes]\n",BufSize);
- }
- else printf("File <%s> is too small.\n",name);
- pOS_CloseFile(FH);
- }
- else printf("Cannot open file <...%s>\n",name);
- return(Flg ? Line:0);
- }
-
- /*----------------------------------
- -----------------------------------*/
- ULONG SearchLFFile(const pOS_FileLock* lk,const CHAR* name,
- const pOS_PatternMatching* pm)
- {
- pOS_FileHandle* FH;
- size_t Pos,BufSize;
- UBYTE *Buffer,*Buf,*Buf2;
- BOOL Flg=FALSE;
- ULONG Line;
-
- if(FH=pOS_OpenFile(lk,name,FILEHDMOD_Read)) {
- BufSize=FH->fh_Size;
- if(BufSize>1) {
- if(Buffer=(UBYTE*)pOS_AllocMem(BufSize+1,MEMF_PUBLIC)) {
- if(BufSize==pOS_ReadFile(FH,Buffer,BufSize)) {
- Buffer[BufSize]='\0'; // *** End-Marke
-
- /*\
- *** Alle LF und CR in \0 umwandeln.
- \*/
- for(Buf=Buffer; (ULONG)Buf<(ULONG)&Buffer[BufSize]; Buf=Buf2+1) {
- Buf2=strpbrk(Buf,"\n\r");
- if(Buf2) Buf2[0]='\0';
- else break;
- }
-
- for(Buf=Buffer,Line=0; Line<BufSize; Line+=Pos,Buf+=Pos) {
- Pos=strlen(Buf)+1;
- if(pOS_MatchPattern(pm->pmt_First,Buf)) {
- Flg=TRUE;
- break;
- }
-
- if(pOS_CheckBreakSignal()) {
- Flg=TRUE; Line=~0;
- break;
- }
- }
- }
- else printf("Read-Error in <%s>\n",name);
-
- pOS_FreeMem(Buffer,BufSize+1);
- }
- else printf("Cannot allocate buffer. [%ld Bytes]\n",BufSize);
- }
- else printf("File <%s> is too small.\n",name);
- pOS_CloseFile(FH);
- }
- else printf("Cannot open file <...%s>\n",name);
- return(Flg ? Line:0);
- }
-
-