| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837 |
- MODULE D;
- (*
- * REPERTOIRE
- * Release 1.6
- * By Charles Bradford and Cole Brecheen
- * (c) Copyright 1985-1990 PMI
- * Green Bay Wisconsin
- * All rights reserved
- * (414) 468-6040
- *
- * $Header: D:/logfiles/demos/d.mov 1.2 03 Dec 1990 07:01:24 coleb $
- *
- *)
- (*
- Directory Management With D.MOD
- D.MOD is a sample director manager. Its purpose is
- to illustrate the use of Repertoire's Drectory module.
- See section 7.10. It makes more convenient the four most
- frequently performed operations in the PC/MS-DOS
- operating system: listing, deleting, renaming, and
- copying files. It lists directories using both the left
- and right sides of the screen; it allows prompted file
- erasure; it allows prompted renaming and directory-
- shifting of files; and it allows prompted file copying
- and moving with safety checks to prevent accidental
- erasures.
- Listing Directories.
- To list the entire current directory of the default
- drive using both sides of the screen, enter "d" and
- press <RETURN>. If the screen fills, the program
- suspends the listing until you press a key. Unlike the
- MS-DOS DIR /W (wide) command, which lists only file
- names, D provides complete information about each file.
- To list the entire current directory of a drive
- other than the default drive (say, the A: drive), type
- "d a" and press <RETURN>. Notice that D does not
- require a trailing colon to specify a drive letter--it
- assumes that any single-character program parameter is
- a drive letter. To list all files with extensions of
- .ltr in the subdirectory \letters, enter "d \letters\*.ltr"
- or "d letters\*.ltr". If \letters is not on the
- default drive, enter "d a:letters\*.ltr" or
- "d a:\letters\*.ltr". To list all the files in the
- \letters subdirectory, enter "d letters\". The
- trailing slash tells D to list a subdirectory instead
- of a file in the current directory named letters.
- D expands the power of the asterisk as an expansion
- character. For example, to list all files beginning
- with the letter A, regardless of extension, you need
- only enter "a*" as D's command-line parameter.
- Entering "art*xt" would list all files beginning with
- 'art' and ending (in the extension part of the name)
- with 'xt'. It would list ARTICLE.TXT, for example, or
- ARTWORK.EXT. Multiple asterisks are allowed in a
- single command.
- Erasing Files.
- Suppose you want to erase all documents in the
- \letters subdirectory on drive B: that are more than a
- year old. Using D, you can enter "d b:\letters\/e" and
- press <RETURN>. The trailing /e tells D to invoke its
- file-erasing function. D will display a full directory
- entry for the first file in the \letters subdirectory,
- followed by the prompt "Erase?" If the date indicates
- that the file is more than a year old, you can press Y
- to erase it. Press N to leave the file on the disk. D
- will continue to display directory entries and ask for
- permission to erase them until it can find no more
- matching files or until you press Q, for quit.
- Copying Files.
- D allows you to decide both whether to copy each
- matching file and whether to destroy any files of the
- same name on the destination disk. Suppose, for
- example, you want to make sure that two disks each have
- the same 30-file set of implementation modules for a
- large program you're developing. For each of the 30
- files, you have to determine which disk has either the
- larger or the more recent version of the file.
- On the DOS command line, enter "d a:*imp/c". The
- trailing /c tells D that it is to COPY matching files.
- The program will ask, "Copy to what drive:\path?"
- Enter "b" and press <RETURN>. No trailing colon is
- required. You can copy to the current drive by merely
- pressing <RETURN>. For each of the 30 implementation
- modules on drive A:, D will display complete directory
- information and ask, "Copy?" Press Y to copy the file,
- N to skip it, and Q to terminate the program.
- If you press Y, D will determine whether the
- destination disk contains a file of the same name. If
- it does, D will display complete directory information
- for that file and ask, "Destroy?" You can look at the
- date and, if the file on the destination disk is less
- recent than the file on the source disk, press Y. If
- you press N, D will prompt you to "Enter new name, or
- <RETURN> to skip." To copy the file to the destination
- disk under a different name, type in the new name and
- press <RETURN>. D will again determine whether the
- destination disk contains a file of the same name. If
- it doesn't, D will copy the file. If you only press
- <RETURN> when prompted for a new name, D will not copy
- the file on the source disk, and will go to the next
- matching file.
- After you've answered yes or no to D's prompts on
- each of the 30 .MOD files on drive A:, reverse the
- process by entering "d b:*.MOD/c" and entering "a" when
- asked "Copy to what drive:\path?" Each time D asks
- whether you want to destroy a file on drive A:, press N
- if the file is identical. At the end of the process
- you'll have the most recent 30-file set of
- implementation modules on each disk.
- Renaming Files.
- D allows you to rename files and move them between
- directories without recopying them using much the same
- syntax that you employ with its other functions. For
- example, to move selected files with .LTR extensions
- from the root directory of your hard disk to the \LTRS
- subdirectory, enter:
- C>d *ltr \ltrs\*ltr/r
- D will respond as follows:
- F1.LTR 50950 2-02-86 8:04p |Rename \ltrs\F1.ltr? no
- F3.LTR 23557 2-02-86 1:31p |Rename \ltrs\F3.ltr? yes
- F2.LTR 34821 2-02-86 2:59p |Rename \ltrs\F2.ltr? no
- C>_
- The trailing /r is the command that tells D to
- rename the files that match its first command-line
- parameter. D renames the files in accordance with the
- same rules used in the DOS RENAME operation, with the
- exception that D does not require separate asterisks on
- each side of the period.
- Moving Files
- A trailing /m modifies both the renaming and the
- copying operations. A trailing /m causes D first to
- determine whether the two file specifications are on
- different drives. If they are, D copies files to the
- destination drive just as it does when you use the /c
- command, but it also erases from the source drive any
- files that are successfully copied. If the files are on
- the same drive, a trailing /m causes D to erase any
- conflicting file names from the destination directory;
- the rename operation normally aborts if a file of the
- same name is in the destination directory.
- Batch Mode
- A trailing /b causes any yes/no prompt automatically
- to be answered Yes.
- *)
- IMPORT BigSets;
- IMPORT Drectory;
- IMPORT EnvironUtils;
- IMPORT ErrorManager;
- IMPORT ErrStrgs;
- IMPORT KbdInput;
- IMPORT LowLevel;
- IMPORT M2Strings;
- IMPORT Numbers;
- IMPORT HandleIO;
- IMPORT FAPI;
- IMPORT PosUtils;
- IMPORT StrConv;
- IMPORT StrEdit;
- IMPORT StringIO;
- IMPORT SYSTEM;
- IMPORT InitCompilerMods;
- CONST
- blank = ' ';
- null = '';
- VAR
- SecondStr, DirMask: ARRAY [0..79] OF CHAR;
- FileInfo: Drectory.FileInfoRec;
- BatchMode, exiting, moving, renaming, copying, deleting,
- OnTheLeft : BOOLEAN;
- SavedMessage : CARDINAL;
- TheDrive : CHAR;
- BytesPerSector, SectorsPerCluster,
- ClustersOnDisk: CARDINAL;
- KindOfDisk : Drectory.DiskTypes;
- ClusterSize : LONGINT;
- PROCEDURE yes() : BOOLEAN;
- VAR
- choice : CARDINAL;
- BEGIN
- (*yes*)
- IF BatchMode THEN
- StringIO.WriteStr(StringIO.outp, 'yes');
- RETURN TRUE;
- END;
- choice := KbdInput.KeyHit( KbdInput.YorN );
- IF KbdInput.CAPkey(choice) = ORD('Y') THEN
- StringIO.WriteStr(StringIO.outp, 'yes');
- RETURN TRUE;
- ELSE
- StringIO.WriteStr(StringIO.outp, 'no');
- IF KbdInput.CAPkey(choice) = ORD('Q') THEN
- exiting := TRUE;
- END;
- RETURN FALSE;
- END;
- END yes;
- PROCEDURE IsDriveLetter( TheStr: ARRAY OF CHAR ): BOOLEAN;
- BEGIN
- RETURN (M2Strings.Length(TheStr) = 1)
- AND ( (CAP(TheStr[0]) >= 'A') AND (CAP(TheStr[0]) <= 'Z'));
- END IsDriveLetter;
- PROCEDURE Punctuate( VAR TheStr: ARRAY OF CHAR );
- VAR
- index, PlaceCount: CARDINAL;
- BEGIN
- index := M2Strings.Length( TheStr );
- IF index > 0 THEN
- DEC( index );
- PlaceCount := 2;
- REPEAT
- IF PlaceCount > 0 THEN
- IF index > 0 THEN
- DEC( index );
- END;
- DEC( PlaceCount );
- ELSE
- PlaceCount := 2;
- M2Strings.Insert( ',', TheStr, index );
- DEC( index );
- END;
- UNTIL (index = 0) OR (NOT PosUtils.IsNumericChar(TheStr[index]));
- END;
- END Punctuate;
- PROCEDURE DifferentDrives( str1, str2: ARRAY OF CHAR ): BOOLEAN;
- VAR
- DriveChar1, DriveChar2: CHAR;
- BEGIN
- IF IsDriveLetter(str1) OR (str1[1] = ':') THEN
- DriveChar1 := CAP(str1[0]);
- ELSE
- DriveChar1 := CAP(Drectory.GetDefaultDrive());
- END;
- IF IsDriveLetter(str2) OR (str2[1] = ':') THEN
- DriveChar2 := CAP(str2[0]);
- ELSE
- DriveChar2 := CAP(Drectory.GetDefaultDrive());
- END;
- RETURN DriveChar1 # DriveChar2;
- END DifferentDrives;
- PROCEDURE MakeInfoStr( FileInfo: Drectory.FileInfoRec; VAR TheStr: ARRAY
- OF CHAR );
- VAR
- dumstr: ARRAY [0..79] OF CHAR;
- BEGIN
- StrEdit.AssignStr( FileInfo.name, TheStr );
- WHILE M2Strings.Length(TheStr) < 12 DO
- StrEdit.Append( TheStr, ' ' );
- END;
- IF Drectory.SubdirectoryFile IN FileInfo.attribute THEN
- StrEdit.Append( TheStr, ' <DIR>' );
- ELSE
- StrConv.LongIntegerToStr( FileInfo.size, 0, dumstr );
- IF FileInfo.size < 1000000 THEN
- (* No room for commas if the string is longer than 6 chars. *)
- Punctuate( dumstr );
- END;
- StrEdit.RightJustify( dumstr, 8 );
- StrEdit.Append( TheStr, dumstr );
- END;
- StrConv.DateToStr( FileInfo.month, FileInfo.day, FileInfo.year,
- dumstr );
- StrEdit.Append( TheStr, ' ' );
- StrEdit.Append( TheStr, dumstr );
- StrConv.TimeToStr( FileInfo.hour, FileInfo.minute, FileInfo.second,
- FileInfo.second, dumstr );
- M2Strings.Delete( dumstr, M2Strings.Length(dumstr) - 7, 6 );
- StrEdit.Append( TheStr, ' ' );
- StrEdit.Append( TheStr, dumstr );
- END MakeInfoStr;
- PROCEDURE SayNotFound();
- VAR
- BytesFree : LONGINT;
- label, BytesFreeStr : ARRAY [0..79] OF CHAR;
- BEGIN
- ErrStrgs.WriteErrToHandle( StringIO.ErrorOutp,
- Drectory.FreeDiskSpace(TheDrive,BytesFree) );
- StrConv.LongIntegerToStr(BytesFree, 1, BytesFreeStr);
- Punctuate( BytesFreeStr );
- Drectory.VolumeLabel(TheDrive, label);
- StringIO.WriteStr(StringIO.outp, 'File not found on ');
- StringIO.WriteStr(StringIO.outp, label);
- StringIO.WriteStr(StringIO.outp, '; ');
- StringIO.WriteStr(StringIO.outp, BytesFreeStr);
- StringIO.WriteEol(StringIO.outp, ' bytes free.');
- END SayNotFound;
- PROCEDURE WriteBarAndPrompt( FileInfoStr, ActionProposed,
- NewName: ARRAY OF CHAR );
- VAR
- tmpstr: ARRAY [0..79] OF CHAR;
- BEGIN
- StrEdit.AssignStr( FileInfoStr, tmpstr );
- StrEdit.Append( tmpstr, blank );
- StrEdit.Append( tmpstr, CHR(186) );
- StrEdit.Append( tmpstr, blank );
- StrEdit.Append( tmpstr, ActionProposed );
- IF M2Strings.Length(NewName) > 0 THEN
- StrEdit.Append( tmpstr, blank );
- StrEdit.Append( tmpstr, NewName );
- END;
- StrEdit.Append( tmpstr, '? ' );
- StringIO.WriteStr( StringIO.outp, tmpstr );
- END WriteBarAndPrompt;
- PROCEDURE ExpandAsterisk(VAR TheMask : ARRAY OF CHAR);
- VAR
- base, spot, indx : CARDINAL;
- BEGIN
- (*ExpandAsterisk*)
- indx := M2Strings.Pos('*',TheMask);
- WHILE indx<=HIGH(TheMask) DO
- TheMask[indx] := '?';
- base := indx;
- WHILE (base > 0)
- AND NOT (M2Strings.Pos( TheMask[base-1], ':\/' ) <= 2) DO
- DEC(base);
- END;
- spot := PosUtils.Positn( '.', TheMask, base );
- IF (spot>HIGH(TheMask)) THEN
- (*There's no period.*)
- StrEdit.InsertTimes('?', TheMask, indx, 12 - (M2Strings.Length(TheMask) - base) );
- TheMask[ base + 8 ] := '.';
- ELSIF (spot>indx) THEN
- (*Asterisk was in the filename part, not extension part.*)
- StrEdit.InsertTimes('?', TheMask, indx, 8 - (spot - base) );
- ELSE
- (*Asterisk was in the extension part.*)
- StrEdit.InsertTimes('?', TheMask, indx, 4 - (M2Strings.Length(TheMask) - spot) );
- END;
- indx := M2Strings.Pos('*',TheMask);
- END;
- END ExpandAsterisk;
- PROCEDURE PrepareDirMask(VAR TheStr : ARRAY OF CHAR);
- VAR
- spot : CARDINAL;
- BEGIN
- TheDrive := 'z';
- (*for default*)
- deleting := FALSE;
- copying := FALSE;
- renaming := FALSE;
- moving := FALSE;
- StrEdit.CrunchBlanks(TheStr);
- IF (M2Strings.Length(TheStr)>=2) THEN
- IF TheStr[M2Strings.Length(TheStr)-2]='/' THEN
- IF CAP( TheStr[M2Strings.Length(TheStr)-1] ) = 'B' THEN
- M2Strings.Delete(TheStr, M2Strings.Length(TheStr)-2, 2);
- StrEdit.CutTrailingChars(blank, TheStr);
- BatchMode := TRUE;
- ELSE
- BatchMode := FALSE;
- END;
- deleting := CAP( TheStr[M2Strings.Length(TheStr)-1] ) = 'E';
- copying := CAP( TheStr[M2Strings.Length(TheStr)-1] ) = 'C';
- renaming := CAP( TheStr[M2Strings.Length(TheStr)-1] ) = 'R';
- moving := CAP( TheStr[M2Strings.Length(TheStr)-1] ) = 'M';
- M2Strings.Delete(TheStr, M2Strings.Length(TheStr)-2, 2);
- StrEdit.CutTrailingChars(blank, TheStr);
- END;
- END;
- spot := M2Strings.Pos(blank,TheStr);
- IF spot<=HIGH(TheStr) THEN
- M2Strings.Copy(TheStr, spot+1, M2Strings.Length(TheStr)-1-spot, SecondStr);
- M2Strings.Delete(TheStr, spot, M2Strings.Length(SecondStr)+1);
- ELSE
- SecondStr := null;
- END;
- IF M2Strings.Length(TheStr) = 0 THEN
- StrEdit.AssignStr( '*.*',TheStr);
- ExpandAsterisk( TheStr );
- RETURN;
- END;
- IF M2Strings.Pos( '..', TheStr ) = ( HIGH(TheStr) - 1 ) THEN
- StrEdit.Append(TheStr, '\*.*');
- END;
- IF ((TheStr[M2Strings.Length(TheStr)-1]='\') OR
- (TheStr[M2Strings.Length(TheStr)-1]='/')) THEN
- StrEdit.Append(TheStr, '*.*');
- ELSIF IsDriveLetter(TheStr) THEN
- StrEdit.Append(TheStr, ':*.*');
- END;
- IF TheStr[1]=':' THEN
- TheDrive := TheStr[0];
- IF M2Strings.Length(TheStr)=2 THEN
- StrEdit.Append(TheStr, '*.*');
- END;
- END;
- ExpandAsterisk( TheStr );
- END PrepareDirMask;
- PROCEDURE SplitPathName(VAR PathName, TheMask : ARRAY OF CHAR);
- VAR
- TmpStr : ARRAY [0..79] OF CHAR;
- spot : CARDINAL;
- BEGIN
- (*SplitPathName*)
- IF IsDriveLetter(TheMask) THEN
- StrEdit.AssignStr( TheMask, PathName );
- StrEdit.Append( PathName, ':' );
- StrEdit.AssignStr( null, TheMask );
- RETURN;
- END;
- StrEdit.AssignStr( null, PathName);
- spot := 0;
- WHILE spot+1<=M2Strings.Length(TheMask) DO
- IF ((TheMask[spot]='\') OR (TheMask[spot]='/'
- ) OR (TheMask[spot]=':')) THEN
- M2Strings.Copy(TheMask, 0, spot+1, TmpStr);
- StrEdit.Append(PathName, TmpStr);
- M2Strings.Delete(TheMask, 0, 1+spot);
- spot := 0;
- ELSE
- INC(spot);
- END;
- END;
- END SplitPathName;
- PROCEDURE EraseOneFile( PathName, FileName: ARRAY OF CHAR ): BOOLEAN;
- VAR
- Fname : ARRAY [0..79] OF CHAR;
- BEGIN
- StrEdit.AssignStr( FileName, Fname );
- M2Strings.Insert(PathName, Fname, 0);
- IF Drectory.DeleteFile(Fname) = StringIO.NoError THEN
- RETURN TRUE;
- ELSE
- RETURN FALSE;
- END;
- END EraseOneFile;
- PROCEDURE EraseFiles();
- VAR
- PathName, Fname, TmpStr : ARRAY [0..79] OF CHAR;
- DirHandle: CARDINAL;
- BEGIN
- (*EraseFiles*)
- DirHandle := 0FFFFH;
- SavedMessage := Drectory.FindFirstFile( DirMask, DirHandle, FileInfo );
- IF SavedMessage # StringIO.NoError THEN
- SayNotFound();
- RETURN;
- END;
- SplitPathName(PathName, DirMask);
- REPEAT
- MakeInfoStr( FileInfo, TmpStr );
- IF NOT (Drectory.SubdirectoryFile IN FileInfo.attribute) THEN
- WriteBarAndPrompt( TmpStr, 'Erase', '' );
- IF yes() THEN
- IF NOT EraseOneFile( PathName, FileInfo.name ) THEN
- END;
- END;
- StringIO.WriteEol(StringIO.outp, null);
- END;
- SavedMessage := Drectory.FindNextFile( DirHandle, FileInfo );
- UNTIL (SavedMessage#StringIO.NoError) OR exiting;
- IF 0 # FAPI.DOSFINDCLOSE( DirHandle ) THEN END;
- END EraseFiles;
- PROCEDURE CopyFiles();
- VAR
- PathName1, PathName2 : ARRAY [0..79] OF CHAR;
- OldHandle, DirHandle : CARDINAL;
- OldHandleOpen : BOOLEAN;
- SavedMessage : CARDINAL;
- SavedFileMode : BITSET;
- TmpStr1, NewFullName, OldFullName : ARRAY [0..79] OF CHAR;
- PROCEDURE CheckDest( VAR PathName, FileName: ARRAY OF CHAR ): BOOLEAN;
- VAR
- TmpStr, NewFileName: ARRAY [0..79] OF CHAR;
- FinishedChecking : BOOLEAN;
- TmpFileInfo: Drectory.FileInfoRec;
- DirHandle: CARDINAL;
- BEGIN
- DirHandle := 0FFFFH;
- REPEAT
- FinishedChecking := TRUE;
- M2Strings.Concat(PathName, FileName, NewFileName);
- SavedMessage := Drectory.FindFirstFile(NewFileName, DirHandle,
- TmpFileInfo);
- IF NOT ((SavedMessage = StringIO.FileNotFound) OR (SavedMessage=
- StringIO.NoMoreFiles)) THEN
- IF SavedMessage # StringIO.NoError THEN
- ErrStrgs.WriteErrToHandle( StringIO.ErrorOutp,
- SavedMessage );
- ELSE
- MakeInfoStr( TmpFileInfo, TmpStr );
- StringIO.WriteEol(StringIO.outp, null);
- WriteBarAndPrompt( TmpStr, 'Destroy', '' );
- IF NOT yes() THEN
- StringIO.WriteEol(StringIO.outp, null);
- StringIO.WriteStr(StringIO.outp,
- 'Enter new name, or <RETURN> to skip: ');
- StringIO.ReadStr(StringIO.inp, FileName);
- IF M2Strings.Length(FileName)=0 THEN
- IF 0 # FAPI.DOSFINDCLOSE( DirHandle ) THEN END;
- RETURN FALSE;
- ELSE
- SplitPathName( PathName, FileName );
- FinishedChecking := FALSE;
- END;
- END;
- END;
- END;
- UNTIL FinishedChecking OR exiting;
- IF 0 # FAPI.DOSFINDCLOSE( DirHandle ) THEN END;
- RETURN TRUE;
- END CheckDest;
- BEGIN
- (*CopyFiles*)
- DirHandle := 0FFFFH;
- IF Drectory.FindFirstFile( DirMask, DirHandle, FileInfo )
- # StringIO.NoError THEN
- SayNotFound();
- RETURN;
- END;
- IF M2Strings.Length(SecondStr)=0 THEN
- StringIO.WriteStr(StringIO.outp, ' Copy to what drive:\path? ');
- StringIO.ReadStr(StringIO.inp, SecondStr );
- END;
- SplitPathName( PathName2, SecondStr );
- SplitPathName( PathName1, DirMask );
- REPEAT
- MakeInfoStr( FileInfo, TmpStr1 );
- IF NOT (Drectory.SubdirectoryFile IN FileInfo.attribute) THEN
- WriteBarAndPrompt( TmpStr1, 'Copy', '' );
- IF yes() THEN
- M2Strings.Concat(PathName1, FileInfo.name, OldFullName);
- SavedFileMode := HandleIO.DefaultFileMode;
- HandleIO.DefaultFileMode := BITSET{ 5 };
- (* Read-only access; deny no other access *)
- ErrStrgs.WriteErrToHandle( StringIO.ErrorOutp,
- HandleIO.OpenFile(OldHandle, OldFullName) );
- OldHandleOpen := TRUE;
- HandleIO.DefaultFileMode := SavedFileMode;
- IF M2Strings.Length(SecondStr) = 0 THEN
- StrEdit.AssignStr( FileInfo.name, TmpStr1 );
- ELSE
- StrEdit.AssignStr( SecondStr, TmpStr1 );
- END;
- IF CheckDest( PathName2, TmpStr1 ) THEN
- M2Strings.Concat(PathName2, TmpStr1, NewFullName);
- ErrStrgs.WriteErrToHandle( StringIO.ErrorOutp,
- Drectory.CopyFile(OldHandle, NewFullName));
- IF moving THEN
- ErrStrgs.WriteErrToHandle( StringIO.ErrorOutp,
- HandleIO.CloseHandle(OldHandle));
- OldHandleOpen := FALSE;
- IF NOT EraseOneFile( PathName1, FileInfo.name ) THEN
- HALT;
- END;
- END;
- END;
- IF OldHandleOpen THEN
- ErrStrgs.WriteErrToHandle( StringIO.ErrorOutp,
- HandleIO.CloseHandle(OldHandle));
- OldHandleOpen := FALSE;
- END;
- END;
- StringIO.WriteEol(StringIO.outp, null);
- END;
- SavedMessage := Drectory.FindNextFile( DirHandle, FileInfo );
- UNTIL (SavedMessage # StringIO.NoError) OR exiting;
- IF 0 # FAPI.DOSFINDCLOSE( DirHandle ) THEN END;
- END CopyFiles;
- PROCEDURE RenameFiles();
- VAR
- mask2, path2, path1 : ARRAY [0..79] OF CHAR;
- PROCEDURE GetNewName(VAR InfoStr, OldName, NewName : ARRAY OF CHAR);
- VAR
- TmpOld : ARRAY [0..79] OF CHAR;
- ndx : CARDINAL;
- BEGIN
- (*GetNewName*)
- StrEdit.AssignStr( null, NewName);
- M2Strings.Copy(InfoStr, 0, M2Strings.Pos(blank,InfoStr), OldName);
- StrEdit.AssignStr( OldName, TmpOld);
- ndx := M2Strings.Pos('.',TmpOld);
- IF ndx>HIGH(TmpOld) THEN
- StrEdit.Append(TmpOld, '*');
- ExpandAsterisk(TmpOld);
- ELSIF (ndx<8) THEN
- M2Strings.Insert('*', TmpOld, ndx);
- ExpandAsterisk(TmpOld);
- END;
- ndx := 0;
- REPEAT
- IF mask2[ndx]='?' THEN
- IF TmpOld[ndx]#'?' THEN
- StrEdit.Append(NewName, TmpOld[ndx]);
- END;
- ELSE
- StrEdit.Append(NewName, mask2[ndx]);
- END;
- INC(ndx);
- UNTIL (ndx>=M2Strings.Length(mask2));
- END GetNewName;
- VAR
- TmpStr1, TmpStr2, OldName, InfoStr, NewName : ARRAY [0..79] OF CHAR;
- DirHandle: CARDINAL;
- BEGIN
- (*RenameFiles*)
- DirHandle := 0FFFFH;
- IF Drectory.FindFirstFile(DirMask, DirHandle, FileInfo)
- # StringIO.NoError THEN
- SayNotFound();
- RETURN;
- END;
- IF M2Strings.Length(SecondStr)=0 THEN
- StringIO.WriteStr(StringIO.outp, ' New name: ');
- StringIO.ReadStr(StringIO.inp, mask2);
- ELSE
- StrEdit.AssignStr( SecondStr, mask2);
- END;
- IF M2Strings.Length(mask2)=0 THEN
- StrEdit.AssignStr( '\*.*', mask2);
- END;
- IF DifferentDrives( DirMask, mask2 ) THEN
- copying := TRUE;
- renaming := FALSE;
- RETURN;
- END;
- SplitPathName(path2, mask2);
- SplitPathName(path1, DirMask);
- IF M2Strings.Length(path2)=0 THEN
- StrEdit.AssignStr( path1, path2);
- END;
- ExpandAsterisk(mask2);
- REPEAT
- IF NOT (Drectory.SubdirectoryFile IN FileInfo.attribute) THEN
- MakeInfoStr( FileInfo, InfoStr );
- GetNewName(InfoStr, OldName, NewName);
- StrEdit.AssignStr( path2, TmpStr1);
- StrEdit.Append(TmpStr1, NewName);
- WriteBarAndPrompt( InfoStr, 'Rename', TmpStr1 );
- IF yes() THEN
- M2Strings.Concat(path1, OldName, TmpStr1);
- M2Strings.Concat(path2, NewName, TmpStr2);
- IF moving THEN
- IF Drectory.RenameFile(TmpStr1,TmpStr2) # StringIO.NoError THEN
- IF NOT EraseOneFile( path2, NewName ) THEN
- HALT;
- ELSE
- ErrStrgs.WriteErrToHandle( StringIO.ErrorOutp,
- Drectory.RenameFile(TmpStr1,TmpStr2));
- END;
- END;
- ELSE
- ErrStrgs.WriteErrToHandle( StringIO.ErrorOutp,
- Drectory.RenameFile(TmpStr1,TmpStr2));
- END;
- END;
- StringIO.WriteEol(StringIO.outp, null);
- ELSE
- StringIO.WriteStr(StringIO.outp, "Can't rename '");
- StringIO.WriteStr(StringIO.outp, FileInfo.name);
- StringIO.WriteEol(StringIO.outp, "' ");
- END;
- UNTIL (Drectory.FindNextFile(DirHandle, FileInfo) # StringIO.NoError)
- OR exiting;
- IF 0 # FAPI.DOSFINDCLOSE( DirHandle ) THEN END;
- END RenameFiles;
- PROCEDURE UpToClusterSize(VAR TheRealSize : LONGINT);
- VAR
- clusters, NewSize : LONGINT;
- BEGIN
- clusters := TheRealSize DIV ClusterSize;
- INC(clusters);
- NewSize := ClusterSize * clusters;
- IF (TheRealSize + ClusterSize) # NewSize THEN
- TheRealSize := NewSize;
- END;
- END UpToClusterSize;
- PROCEDURE ListFiles();
- VAR
- choice : CARDINAL;
- DirHandle, resultcode, linecnt : CARDINAL;
- VolLabel, ListedBytes, BytesFreeStr : ARRAY [0..16] OF CHAR;
- TmpStr, ThePath : ARRAY [0..79] OF CHAR;
- TmpNum, ByteCnt, BytesFree : LONGINT;
- dummy : BOOLEAN;
- BEGIN
- (*ListFiles*)
- ByteCnt := Numbers.Lc( 0 );
- OnTheLeft := TRUE;
- Drectory.VolumeLabel(TheDrive, VolLabel);
- ErrStrgs.WriteErrToHandle( StringIO.ErrorOutp,
- Drectory.GetCurrentDir(TheDrive,ThePath));
- DirHandle := 0FFFFH;
- SavedMessage := Drectory.FindFirstFile(DirMask, DirHandle, FileInfo);
- IF SavedMessage # StringIO.NoError THEN
- SayNotFound();
- RETURN;
- END;
- ErrStrgs.WriteErrToHandle( StringIO.ErrorOutp,
- Drectory.FreeDiskSpace(TheDrive,BytesFree));
- linecnt := 1;
- REPEAT
- TmpNum := FileInfo.size;
- UpToClusterSize(TmpNum);
- ByteCnt := ByteCnt + TmpNum;
- MakeInfoStr( FileInfo, TmpStr );
- IF OnTheLeft THEN
- StringIO.WriteStr(StringIO.outp, TmpStr);
- ELSE
- M2Strings.Insert(' ', TmpStr, 0);
- TmpStr[1] := CHR(186);
- StringIO.WriteStr(StringIO.outp, TmpStr);
- INC(linecnt);
- IF linecnt=26 THEN
- choice := KbdInput.KeyHit( KbdInput.AnyKeyNum );
- IF KbdInput.CAPkey(choice) = ORD('Q') THEN
- ErrorManager.StraightToDOS('');
- END;
- StringIO.WriteStr(StringIO.outp, '_');
- linecnt := 1;
- ELSE
- StringIO.WriteEol(StringIO.outp, null);
- END;
- END;
- OnTheLeft := NOT (OnTheLeft);
- SavedMessage := Drectory.FindNextFile( DirHandle, FileInfo );
- UNTIL SavedMessage # StringIO.NoError;
- IF NOT OnTheLeft THEN
- INC(linecnt);
- IF linecnt>=25 THEN
- choice := KbdInput.KeyHit( KbdInput.AnyKeyNum );
- IF KbdInput.CAPkey(choice) = ORD('Q') THEN
- ErrorManager.StraightToDOS('');
- END;
- END;
- StringIO.WriteEol(StringIO.outp, null);
- END;
- StrConv.LongIntegerToStr(ByteCnt, 1, ListedBytes);
- Punctuate( ListedBytes );
- StrConv.LongIntegerToStr(BytesFree, 1, BytesFreeStr);
- Punctuate( BytesFreeStr );
- M2Strings.Insert(';', ThePath, 0);
- M2Strings.Insert(VolLabel, ThePath, 0);
- M2Strings.Insert(' ', ThePath, 0);
- StrEdit.Append(ThePath, '; ');
- StrEdit.Append(ThePath, BytesFreeStr);
- StrEdit.Append(ThePath, ' free. Files above occupy ');
- StrEdit.Append(ThePath, ListedBytes);
- StrEdit.Append(ThePath, '.');
- StringIO.WriteStr(StringIO.outp, ThePath);
- IF linecnt<=23 THEN
- StringIO.WriteEol(StringIO.outp, null);
- END;
- IF 0 # FAPI.DOSFINDCLOSE( DirHandle ) THEN END;
- END ListFiles;
- BEGIN
- (*D*)
- exiting := FALSE;
- BigSets.AppendSet( KbdInput.YorN, "{'q', 'Q'}" );
- EnvironUtils.GetProgParams(DirMask);
- PrepareDirMask(DirMask);
- Drectory.GetDiskInfo( TheDrive, BytesPerSector, SectorsPerCluster,
- ClustersOnDisk, KindOfDisk );
- ClusterSize := Numbers.Lc( BytesPerSector * SectorsPerCluster );
- IF deleting THEN
- EraseFiles();
- ELSIF moving OR renaming THEN
- RenameFiles();
- IF copying THEN
- (* We do this because we may have discovered differing drive names. *)
- CopyFiles();
- END;
- ELSIF copying THEN
- CopyFiles();
- ELSE
- ListFiles();
- END;
- END D.
|