home *** CD-ROM | disk | FTP | other *** search
- MODULE Chop;
-
- (*
-
- Chop v0.92 by Terry Brown, 1991
-
- Chop filename [-sn] [-bn] [-cn] [-Bs|-As] [-in] [-Ps] [-p]
-
- -sn skip first n bytes, start from start if omitted
- -bn take only n byte chunks, take remainder of file if omitted
- -cn take only n chunks, take chunks to end of file if omitted
- -Bs after taking -bn bytes, take bytes until string s is reached
- -As after taking -bn bytes, take bytes until end of string s is reached
- -in buffer size n kilobytes, default 40, needs two of them
- -Ps string s is path and file name for output
- -p prompt before writing each file
-
- s must conatin no spaces, ? matches anything, and `hh is a hex constant
-
- watch for shells which pre-expand wild cards etc.
-
- Eg. Chop dh0:bigText -b10000 -B`0A`20 -Pdf0:textBit -p
-
- breaks bigText into roughly 10000 byte peices before lines starting with a
- space, saving them to df0:textBit.1, df0:textBit.2 etc., and giving you a
- chance to change disks before each write.
- (`0A`20 is hex for newline + space)
-
-
- *)
-
-
- FROM CommandLine IMPORT GetCL,CLStrings;
- FROM InOut IMPORT WriteString,WriteLn;
- IMPORT InOut; (* need Read from here and DOSFiles *)
- FROM LongInOut IMPORT WriteLongCard;
- FROM Memory IMPORT AllocMem,FreeMem,MemReqSet;
- FROM DOSFiles IMPORT Open,Close,FileHandle,ModeNewFile,ModeOldFile,
- Seek,OffsetBeginning,Read,Write,DeleteFile;
- FROM Strings IMPORT Copy,InitStringModule,Concat,CompareResults,
- Compare,Length,Delete,Insert;
- FROM Conversions IMPORT ConvertFromString,ConvertToString;
- FROM SYSTEM IMPORT ADDRESS,NULL;
-
- CONST
- maxArgs = 9;
- skpArg = "-s";
- szeArg = "-b";
- cntArg = "-c";
- bfrArg = "-B";
- aftArg = "-A";
- bufArg = "-i";
- preArg = "-P";
- pmtArg = "-p";
-
- multiWild = "*";
- singleWild = "?";
- hexPrecur = "`";
- defaultBuf = 40*1024;
-
- TYPE
- states = (srchI,endI,endN,done,writeI,writeN);
-
- VAR
- inFile,outFile : FileHandle;
- inFileNm,outFileNm : CLStrings;
- iBuf,nBuf,tBuf,
- iStrt,iEnd,
- nStrt,nEnd : ADDRESS;
- bufSize,skpSize,
- blkSize,blkCount,
- blkNum,actRead,
- actWrite,curSize : LONGCARD;
- split,before : BOOLEAN;
- splitStr : CLStrings;
- arg : ARRAY [1..maxArgs] OF CLStrings;
- args : CARDINAL;
- lcard : LONGCARD;
- lint : LONGINT;
- i,j,iOld : CARDINAL;
- bool,more,bufSwt,
- killSrch,prompt,
- falseMatch : BOOLEAN;
- s : CLStrings;
- c : CHAR;
- cPtr,matchStrt : POINTER TO CHAR;
- matchPos : CARDINAL;
- state : states;
-
- PROCEDURE ErrMsg;
-
- BEGIN
-
- WriteLn;
- WriteLn; WriteString("Chop v0.92 by Terry Brown, 1991");
- WriteLn;
- WriteLn; WriteString("Chop filename [-sn] [-bn] [-cn] [-Bs|-As] [-in] [-Ps] [-p]");
- WriteLn;
- WriteLn; WriteString("-sn skip first n bytes, start from start if omitted");
- WriteLn; WriteString("-bn take only n byte chunks, take remainder of file if omitted");
- WriteLn; WriteString("-cn take only n chunks, take chunks to end of file if omitted");
- WriteLn; WriteString("-Bs after taking -bn bytes, take bytes until string s is reached");
- WriteLn; WriteString("-As after taking -bn bytes, take bytes until end of string s is reached");
- WriteLn; WriteString("-in buffer size n kilobytes, default 40, needs two of them");
- WriteLn; WriteString("-Ps string s is path and file name for output");
- WriteLn; WriteString("-p prompt before writing each file");
- WriteLn;
- WriteLn; WriteString("s must conatin no spaces, ? matches anything, and `hh is a hex constant");
- WriteLn;
- WriteLn; WriteString("watch for shells which pre-expand wild cards etc.");
- WriteLn;
- WriteLn; WriteString("Eg. Chop dh0:bigText -b10000 -B`0A`20 -Pdf0:textBit -p");
- WriteLn;
- WriteLn; WriteString("breaks bigText into roughly 10000 byte peices before lines starting with a");
- WriteLn; WriteString("space, saving them to df0:textBit.1, df0:textBit.2 etc., and giving you a");
- WriteLn; WriteString("chance to change disks before each write.");
- WriteLn; WriteString("(`0A`20 is hex for newline + space)");
- WriteLn;
- END ErrMsg;
-
-
- PROCEDURE begins(a,b : CLStrings) : BOOLEAN;
-
- (* return true if string a matches string a begins with string b *)
-
- VAR
- s : CLStrings;
-
- BEGIN
-
- Copy(a,0,Length(b),s);
- IF Compare(s,b)=Equal THEN
- RETURN TRUE
- ELSE
- RETURN FALSE
- END;
-
- END begins;
-
-
- PROCEDURE nextOut(fn : CLStrings; n : LONGCARD) : FileHandle;
-
- VAR
- done : BOOLEAN;
- s : CLStrings;
- x : FileHandle;
- c : CHAR;
-
- BEGIN
-
- ConvertToString(n,10,FALSE,s,done);
- WHILE Length(s)<3 DO
- Insert("0",s,0);
- END;
- Concat(".",s,s);
- Concat(fn,s,s);
-
- IF prompt THEN
- WriteString("Hit RETURN to write file ");
- WriteString(s);
- InOut.Read(c);
- END;
-
- x:=Open(s,ModeNewFile);
- IF x=0 THEN
- WriteString("Couldn't open output file");
- WriteLn;
- END;
-
- RETURN x;
-
- END nextOut;
-
-
- PROCEDURE flush; (* rest of buffer *)
-
- BEGIN
-
- actWrite:=Write(outFile,iStrt,LONGCARD(iEnd-iStrt));
- curSize:=curSize+actWrite; (* everything we've got *)
-
- END flush;
-
-
- PROCEDURE switch;
-
- (* swap buffer and load next, if it exists *)
-
- BEGIN
-
- IF (nEnd=nBuf) THEN
- more:=FALSE; (* that's all of it *)
- ELSE
- tBuf:=iBuf; (* don't lose track of buffer *)
- iBuf:=nBuf;
- iStrt:=nStrt;
- iEnd:=nEnd;
- nBuf:=tBuf;
- IF iEnd=iBuf+ADDRESS(bufSize) THEN (* that was a full buffer *)
- actRead:=Read(inFile,nBuf,bufSize);
- nStrt:=nBuf; nEnd:=nBuf+ADDRESS(actRead);
- ELSE
- nStrt:=nBuf; nEnd:=nBuf;
- END; (* getting next buffer if possible *)
- END; (* buffer switching *)
-
- END switch;
-
-
- (* the program ************************************************************)
-
- BEGIN
-
- InitStringModule; (* why ? *)
-
- IF NOT GetCL(args,arg) OR (args<2) THEN
- ErrMsg;
- RETURN;
- END;
-
- FOR i:=1 TO args DO
- IF arg[i,Length(arg[i])-1]=CHR(10) THEN
- Delete(arg[i],Length(arg[i])-1,1);
- END;
- END;
-
- inFileNm:=arg[1];
- outFileNm:=inFileNm;
- prompt:=FALSE;
- skpSize:=0;
- blkSize:=0;
- blkCount:=0; (* indicates keep taking blocks until there's none left *)
- split:=FALSE;
- bufSize:=defaultBuf;
-
- i:=2;
-
- iOld:=maxArgs+10; (* make sure iOld<>i *)
-
- WHILE (i<=args) AND (iOld<>i) DO
-
- iOld:=i;
-
- IF begins(arg[i],skpArg) THEN
- Copy(arg[i],Length(skpArg),Length(arg[i])-Length(skpArg),s);
- ConvertFromString(s,10,FALSE,MAX(LONGCARD),lcard,bool);
- IF bool THEN skpSize:=lcard END;
- INC(i);
- END;
-
- IF begins(arg[i],szeArg) THEN
- Copy(arg[i],Length(szeArg),Length(arg[i])-Length(szeArg),s);
- ConvertFromString(s,10,FALSE,MAX(LONGCARD),lcard,bool);
- IF bool THEN blkSize:=lcard END;
- INC(i);
- END;
-
- IF begins(arg[i],cntArg) THEN
- Copy(arg[i],Length(cntArg),Length(arg[i])-Length(cntArg),s);
- ConvertFromString(s,10,FALSE,MAX(LONGCARD),lcard,bool);
- IF bool THEN blkCount:=lcard END;
- INC(i);
- END;
-
- IF begins(arg[i],preArg) THEN
- Copy(arg[i],Length(bfrArg),Length(arg[i])-Length(bfrArg),outFileNm);
- INC(i);
- END;
-
- IF begins(arg[i],pmtArg) THEN
- prompt:=TRUE;
- INC(i);
- END;
-
- IF begins(arg[i],bfrArg) THEN
- split:=TRUE; before:=TRUE;
- Copy(arg[i],Length(bfrArg),Length(arg[i])-Length(bfrArg),splitStr);
- INC(i);
- END;
-
- IF begins(arg[i],aftArg) THEN
- split:=TRUE; before:=FALSE;
- Copy(arg[i],Length(aftArg),Length(arg[i])-Length(aftArg),splitStr);
- INC(i);
- END;
-
- IF begins(arg[i],bufArg) THEN
- Copy(arg[i],Length(cntArg),Length(arg[i])-Length(cntArg),s);
- ConvertFromString(s,10,FALSE,MAX(LONGCARD),lcard,bool);
- IF bool THEN bufSize:=1024*lcard END;
- INC(i);
- END;
-
- END; (* WHILE args to parse *)
-
- IF i<args THEN (* not all command line arguments were used *)
- ErrMsg;
- RETURN;
- END;
-
- WriteString("inFile : "); WriteString(inFileNm); WriteLn;
- WriteString("skip : "); WriteLongCard(skpSize,10); WriteLn;
- WriteString("size : "); WriteLongCard(blkSize,10); WriteLn;
- WriteString("count : "); WriteLongCard(blkCount,10); WriteLn;
- IF split THEN
- IF before THEN
- WriteString("before : "); WriteString(splitStr); WriteLn;
- ELSE
- WriteString("after : "); WriteString(splitStr); WriteLn;
- END;
- END;
- WriteString("buffer : "); WriteLongCard(bufSize,10);
- WriteString(" (");
- WriteLongCard(2*bufSize,10); WriteString(" bytes total)");
- WriteLn;
- IF Compare(inFileNm,outFileNm)<>Equal THEN
- WriteString("prefix : "); WriteString(outFileNm); WriteLn;
- END;
- IF prompt THEN
- WriteString("Prompt before each file");WriteLn;
- END;
-
- WriteLn;
- WriteString("Continue ? (y/n) ");
- InOut.Read(c);
- IF (c<>"y") AND (c<>"Y") THEN RETURN END;
-
- IF split THEN (* pre-parse search string *)
- i:=0;
- WHILE INTEGER(i)<INTEGER(Length(splitStr))-2 DO
- IF splitStr[i]=hexPrecur THEN (* a hex thing *)
- Copy(splitStr,i+1,2,s);
- Delete(splitStr,i,2);
- ConvertFromString(s,16,FALSE,255,lcard,bool);
- splitStr[i]:=CHR(SHORT(lcard));
- END;
- INC(i); (* as usual, I forgot the first time *)
- END;
- END;
-
-
- IF prompt THEN
- InOut.Read(c); (* seems to need flushing *)
- END;
-
-
- (* start setup **************************************************************)
-
- inFile:=Open(inFileNm,ModeOldFile);
- IF inFile=0 THEN
- WriteString("Couldn't open input file");
- WriteLn;
- RETURN;
- END;
-
-
- iBuf:=AllocMem(bufSize,MemReqSet{});
- IF iBuf=0 THEN
- WriteString("Couldn't get mem for input buffer 1");
- WriteLn;
- Close(inFile);
- Close(outFile);
- RETURN;
- END;
-
- nBuf:=AllocMem(bufSize,MemReqSet{});
- IF nBuf=0 THEN
- WriteString("Couldn't get mem for input buffer 2");
- WriteLn;
- Close(inFile);
- Close(outFile);
- FreeMem(iBuf,bufSize);
- RETURN;
- END;
-
- (* load buffers ******************************************************)
-
-
- IF skpSize<>0 THEN
- lint:=Seek(inFile,LONGINT(skpSize),OffsetBeginning);
- IF lint=-1 THEN
- Close(inFile);
- Close(outFile);
- FreeMem(iBuf,bufSize);
- FreeMem(nBuf,bufSize);
- WriteString("Error skipping data - skipped whole file?");
- WriteLn;
- RETURN
- END;
- END;
-
- IF blkSize=0 THEN (* now just copy out rest of file *)
-
- blkNum:=1;
- outFile:=nextOut(outFileNm,blkNum);
- IF outFile=0 THEN
- Close(inFile);
- RETURN;
- END;
-
-
- REPEAT
- actRead:=Read(inFile,iBuf,bufSize);
- actWrite:=Write(outFile,iBuf,actRead);
- UNTIL actRead<>bufSize;
-
- Close(outFile);
-
- ELSE (* got to chop it up *)
-
- (* first, load both buffers *)
-
- actRead:=Read(inFile,iBuf,bufSize);
- iStrt:=iBuf; iEnd:=iBuf+ADDRESS(actRead);
- IF actRead=bufSize THEN
- actRead:=Read(inFile,nBuf,bufSize);
- nStrt:=nBuf; nEnd:=nBuf+ADDRESS(actRead);
- ELSE
- nStrt:=nBuf; nEnd:=nBuf;
- END;
-
- more:=TRUE; (* more available *)
- blkNum:=1;
-
-
- REPEAT
-
- outFile:=nextOut(outFileNm,blkNum);
- IF outFile=0 THEN
- Close(inFile);
- RETURN;
- END;
-
- curSize:=0; (* number of bytes out to the current block *)
-
- killSrch:=FALSE;
-
-
- WHILE (curSize<blkSize) AND more DO
- IF ADDRESS(blkSize-curSize)<=iEnd-iStrt THEN
- actWrite:=Write(outFile,iStrt,blkSize-curSize);
- curSize:=curSize+actWrite;
- iStrt:=iStrt+ADDRESS(actWrite);
- matchPos:=0;
-
- IF split THEN
-
- cPtr:=iStrt;
- matchPos:=0;
- state:=srchI;
-
- WHILE state<>done DO
-
- CASE state OF
-
- srchI :
- WHILE (cPtr^<>splitStr[matchPos]) AND more DO
- INC(cPtr);
- IF cPtr>=iEnd THEN
- flush;
- switch;
- cPtr:=iStrt;
- END;
- END;
- IF NOT more THEN
- state:=done; (* didn't find start of target *)
- ELSE
- matchStrt:=cPtr;
- state:=endI; (* found start *)
- END;
- | (* all for srchI *)
-
- endI :
- REPEAT
- INC(matchPos);
- INC(cPtr);
- UNTIL (cPtr=iEnd) OR (matchPos>=Length(splitStr)) OR (cPtr^<>splitStr[matchPos]);
- IF matchPos>=Length(splitStr) THEN
- state:=writeI;
- ELSE
- IF cPtr=iEnd THEN
- cPtr:=nStrt;
- state:=endN;
- ELSE (* not target *)
- state:=srchI;
- matchPos:=0;
- cPtr:=matchStrt;
- INC(cPtr);
- END;
- END;
- | (* end of search in iBuf *)
-
- endN :
- WHILE ((cPtr^=splitStr[matchPos]) OR (cPtr^=singleWild)) AND (matchPos<Length(splitStr)) AND (cPtr<nEnd) DO
- INC(cPtr);
- INC(matchPos);
- END;
- IF matchPos=Length(splitStr) THEN
- state:=writeN;
- ELSE
- IF cPtr=nEnd THEN
- WriteString("Out of range search for end of target");
- state:=srchI;
- cPtr:=matchStrt;
- INC(cPtr);
- ELSE (* not target *)
- state:=srchI;
- cPtr:=matchStrt;
- INC(cPtr);
- END;
- END;
- | (* end of endN *)
-
- writeI :
- IF before THEN
- actWrite:=Write(outFile,iStrt,LONGCARD(ADDRESS(matchStrt)-iStrt));
- iStrt:=matchStrt;
- state:=done;
- ELSE
- actWrite:=Write(outFile,iStrt,LONGCARD(ADDRESS(cPtr)-iStrt));
- iStrt:=cPtr;
- state:=done;
- END;
-
- | (* done i Write *)
-
- writeN :
- IF before THEN
- actWrite:=Write(outFile,iStrt,LONGCARD(ADDRESS(matchStrt)-iStrt));
- iStrt:=matchStrt;
- state:=done;
- ELSE
- flush; (* send all of iBuf *)
- actWrite:=Write(outFile,nBuf,LONGCARD(ADDRESS(cPtr)-nBuf));
- nStrt:=cPtr;
- switch;
- state:=done;
- END;
- | (* done n Write *)
-
- ELSE (* case shouldn't come here ! *)
-
- END; (* case *)
-
- END; (* when state=done *)
- END; (* if split *)
-
- ELSE (* not enough in buffer *)
- flush; (* give it what there is *)
- switch; (* see if theres more, will set more=FALSE if not *)
- END; (* sending buffer (or part of) to block *)
- END; (* making block *)
-
- Close(outFile);
-
- IF curSize=0 THEN (* whoops, created empty file *)
- ConvertToString(blkNum,10,FALSE,s,bool);
- WHILE Length(s)<3 DO
- Insert("0",s,0);
- END;
- Concat(".",s,s);
- Concat(outFileNm,s,s);
- IF NOT DeleteFile(s) THEN
- WriteLn;
- WriteString("Whoops, error deleting empty file.");
- WriteLn;
- END;
- END;
-
- INC (blkNum);
-
- IF (blkNum>blkCount) AND (blkCount<>0) THEN
- more:=FALSE; (* even if it's not *)
- END;
-
- UNTIL NOT more; (* all blocks made *)
-
- END; (* end of cut up *)
-
-
- Close(inFile);
-
- FreeMem(iBuf,bufSize);
- FreeMem(nBuf,bufSize);
-
- END Chop.
-