home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frostbyte's 1980s DOS Shareware Collection
/
floppyshareware.zip
/
floppyshareware
/
USCX
/
TURBO-06.ZIP
/
LU.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1985-02-23
|
17KB
|
513 lines
program LibraryUtility;
{
written 10/09/84 by Steve Freeman
This program was written to function as Gary Novosielski's LU. As such it
will function as a utility to manipulate library members under any operating
system which will support TURBO Pascal. Minor rewrites may be necessary for
other versions of Pascal.
This program is placed into the Public Domain by the author and, as a Public
Domain program, may NOT be used for commercial purposes.
Notes by John Plocher
The program only uses a subset of the info stored in the library:
--- Makeup of a library entry header ---
status : (Unused, in use, and deleted)
name : (Name of member stored in library)
ext : (Type " " " " " )
index : (where in lib this member is stored)
length_of_member : (it's length )
CRC : *** NOT IMPLEMENTED ***
CreationDate : *** NOT IMPLEMENTED ***
LastChangeDate : *** NOT IMPLEMENTED ***
CreationTime : *** NOT IMPLEMENTED ***
LastChangeTime : *** NOT IMPLEMENTED ***
PadCount : (used internally by LU)
filler : ( room for expansion )
Modification history
Version Date Who Comments
------- ---- --- --------
1.22 1/12/85 John Plocher Made library selection part of
the program loop - No need to
re-run LU to work on other
libraries. Changed active/total
entries used display to reflect
the fact that the library itself
always uses the first entry and
thus shouldn't be counted.
1.21 1/12/85 John Plocher Fixed MakeName bug where a
filetype < 3 chars was incorrectly
handled. See MakeName comments.
1.20 1/12/85 John Plocher Added windows and function keys
1.10 1/11/85 John Plocher Rewrote to use screen in an
intelegent manner with all
data visable at one time.
Also reformatted source code in
a readable format.
1.00 10/ 9/84 Steve Freeman Initial coding
}
const V {ersion} = '1.23';
BufferSize = 127; { maximum size of data buffer - 1 }
EntriesPerBuffer = 4; { (BufferSize+1)/32 }
maxent = 128; { maximum dir entries this program will take }
Hell_Freezes_Over= False; { Main driver loop termination... }
esc = ^[;
BS = ^H;
HI = ^['p';
LO = ^['q';
CURSOR_OFF = ^['x5';
CURSOR_ON = ^['y5';
FK1 = #$F1; { function key values }
FK2 = #$F2;
FK3 = #$F3;
FK4 = #$F4;
FK5 = #$F5;
FK6 = #$F6;
FK7 = #$F7;
type TimeType = integer;
FileNameType = array[1..11] of char;
LibFileType = file;
EntryType = record
status : byte;
name : array[1..8] of char;
ext : array[1..3] of char;
index : integer;
length_of_member : integer;
CRC : integer;
CreationDate : integer;
LastChangeDate : integer;
CreationTime : TimeType;
LastChangeTime : TimeType;
PadCount : byte;
filler : array[27..31] of byte;
end;
EntryPtr = ^EntryType;
hexstr = string[4];
string10 = string[10];
filename = string[12];
maxstr = string[255];
var buffer : array[0..BufferSize] of byte;
library,
file2 : file;
SizeFile : file of byte;
DirectoryChanged : boolean;
LibName,
fname : filename;
LibSize,
NumEntries : integer;
LibEntry : EntryType;
Dir : array[0..maxent] of EntryPtr;
active,
unused,
deleted : integer;
w_table : record x1,x2,y1,y2,
currx,curry : integer;
overwrote : array[0..2048] of integer;
end;
screen : array[0..2048] of integer absolute $F000:0000;
{$I lu-1.pas } { Window handlers and status line drivers }
function Confirm: boolean;
var c: char;
begin
w_write_s(' Confirm operation (Y/N): ');
repeat
read(kbd,c);
c := upcase(c);
until (c in ['Y','N']);
w_write_c(c);
confirm := (c = 'Y')
end;
function hex(num: integer): hexstr;
var i, j: integer;
h: string[16];
str: hexstr;
begin
str := '0000'; h := '0123456789ABCDEF'; j := num;
for i:=4 downto 1 do begin
str[i] := h[(j and 15)+1];
j := j shr 4;
end;
hex := str;
end;
procedure MakeName(f: filename; var name: FileNameType);
var dotpos,
endname,
i : integer;
begin
name := ' ';
for i:=1 to length(f) do
f[i] := upcase(f[i]);
dotpos := pos('.',f);
if dotpos > 0 then begin
endname := dotpos-1;
for i:=1 to 3 do
if (f[ dotpos+i ] <> ' ')
AND (DOTPOS + I <= LENGTH(F))then (* ONLY copy chars if they *)
(* are actually there! - jmp *)
name[8+i] := f[dotpos+i];
end
else
endname := length(f);
for i:=1 to endname do
name[i] := f[i];
end;
procedure PutName(f: filename; n: integer);
var i: integer;
name: FileNameType;
begin
MakeName(f,name);
for i:=1 to 8 do
Dir[n]^.name[i] := name[i];
for i:=1 to 3 do
Dir[n]^.ext[i] := name[i+8];
end;
function FindMember(f: filename): integer;
var member, dotpos, endname, i, k: integer;
lookup: FileNameType;
found: boolean;
function NamesMatch(entry: integer): boolean;
var match: boolean;
begin
NamesMatch := true;
with Dir[entry]^ do begin
for k:=1 to 8 do
if name[k]<>lookup[k] then
NamesMatch := false;
for k:=1 to 3 do
if ext[k]<>lookup[8+k] then
NamesMatch := false;
end;
end;
begin
MakeName(f,lookup);
found := false; i := 1;
while not(found) and (i<NumEntries) do
if NamesMatch(i) then
found := true
else
i := i + 1;
if (active=1) or not(found) then
FindMember := 0
else
FindMember := i
end;
function Parse(f: filename): filename;
var i: integer;
begin
if f <> '' then begin
for i:=1 to length(f) do
f[i]:=upcase(f[i]);
i := pos('.',f);
if i>0 then
f:=copy(f,1,i-1);
f := f + '.LBR';
end;
Parse := f;
end;
procedure WriteDirectoryToDisk(var lib: LibFileType);
var member, i: integer;
begin
reset(lib);
member := 0;
while member < NumEntries do begin
for i:=0 to EntriesPerBuffer-1 do
move(Dir[member+i]^,buffer[32*i],32);
blockwrite(lib,buffer,1);
member := member + 4
end;
DirectoryChanged := false
end;
procedure ZeroEntry(n: integer);
begin
fillchar(Dir[n]^,32,chr(0)); {clear the record}
fillchar(Dir[n]^.name[1],11,' '); {clear file name}
Dir[n]^.status := -1; {mark unused}
end;
procedure SortDir;
var i, j: integer;
function larger(a, b: integer): boolean;
var ok, x: integer;
c1, c2: char;
begin
ok := 0; x := 1;
if (Dir[a]^.status <> 0) and (Dir[b]^.status <> 0) then ok := 2;
if (Dir[a]^.status <> 0) and (ok = 0) then ok := 1;
if (Dir[b]^.status <> 0) and (ok = 0) then ok := 2;
while (x < 12) and (ok=0) do begin
c1 := Dir[a]^.name[x];
c2 := Dir[b]^.name[x];
if c1 > c2 then ok := 1;
if c1 < c2 then ok := 2;
x := x + 1
end;
if ok=1 then
larger := true
else
larger := false
end;
procedure swap(x, y: integer);
var temp: EntryPtr;
begin
temp := Dir[x];
Dir[x] := Dir[y];
Dir[y] := temp
end;
begin
for i:=1 to NumEntries-1 do
if Dir[i]^.status <> 0 then
ZeroEntry(i);
for i:=1 to NumEntries-2 do begin
for j:=i+1 to NumEntries-1 do
if larger(i,j) then
swap(i,j);
end;
end;
procedure CreateDirectory;
var i: integer;
begin
w_make(15,65,10,14);
rewrite(library);
w_write_s(' Creating a new library. Name = ');
w_write_s(LibName); w_writeln;
w_write_s(' How many entries? '); readln(i); w_writeln;
NumEntries := i + 1; {add 1 for Directory entry}
i := NumEntries MOD 4;
if i <> 0 then
NumEntries := NumEntries + (4 - i);
for i:=0 to NumEntries-1 do begin
new(Dir[i]);
ZeroEntry(i);
end;
Dir[0]^.status := 0; {directory entry is always used}
Dir[0]^.length_of_member := NumEntries DIV 4;
active := 1;
unused := NumEntries - 1;
deleted := 0;
WriteDirectoryToDisk(library);
w_write_s(' Library created and initialized.');
delay(1000);
LibSize := (1 + filesize(library)) DIV 8; {in kilobytes}
w_delete;
end;
procedure GetDirectory;
var i, offset: integer;
begin
offset := 0;
DirectoryChanged := false;
LibSize := (1 + filesize(library)) DIV 8; {in kilobytes}
blockread(library,buffer,1);
new(Dir[0]); {make space for directory header}
move(buffer[0],Dir[0]^,32); {move header entry}
NumEntries := (128 * Dir[0]^.length_of_member) DIV 32;
for i:=1 to NumEntries-1 do begin
if (i MOD EntriesPerBuffer) = 0 then begin {read next block}
blockread(library,buffer,1);
offset := offset + EntriesPerBuffer;
end;
new(Dir[i]);
move(buffer[32*(i-offset)],Dir[i]^,32);
end;
active := 1;
unused := 0;
deleted := 0;
for i:=1 to NumEntries-1 do
if Dir[i]^.status=0 then
active := active + 1
else
if Dir[i]^.status=$FE then
deleted := deleted + 1
else
unused := unused + 1;
end;
procedure OpenLibrary;
begin
assign(library,LibName);
{$I-} reset(library) {$I+};
if IOresult=0 then
GetDirectory
else
CreateDirectory;
end;
procedure Directory;
var i, j: integer;
begin
gotoxy(3,6); write(#$BA,' name index length CRC');
gotoxy(41,6); write(#$B3,' name index length CRC ',#$BA);
gotoxy(3,7); write(#$C7); for i := 5 to 79 do write(#$C4); write(#$B6);
gotoxy(41,7); write(#$C5);
gotoxy(41,5); write(#$D1);
for i:=1 to NumEntries-1 do
with Dir[i]^ do begin
if odd(i) then begin gotoxy(3,8+(i-1) div 2); write(#$BA); end
else begin gotoxy(41,8+ (i-1) div 2); write(#$B3); end;
if status <> $FF then begin
if status=$FE then
write('*')
else write(' ');
for j:=1 to 8 do
write(name[j]);
write('.');
for j:=1 to 3 do
write(ext[j]);
write(' ',index:8,length_of_member:8,' ',hex(CRC));
end
else write(' <empty> ');
gotoxy(79,8+(i-1) div 2);
write(#$BA);
end; (* with *)
gotoxy(41,8+(i-1) div 2);
write(#$B3);
gotoxy(79,8+(i-1) div 2);
write(#$BA);
gotoxy(3,9+(i-1) div 2); write(#$C8);
for i := 5 to 41 do write(#$CD);
write(#$CF);
for i := 43 to 79 do write(#$CD);
write(#$BC);
end;
{$I lu-2.pas } { command handlers - removed to include file for space reasons }
procedure NewLib;
var str : filename;
x : integer;
begin
clrscr;
gotoxy(3,1);
write(#$C9); for x := 4 to 25 do write(#$CD); write(#$BB);
gotoxy(3,2); write(#$BA,' Library Utility (LU) ', #$BA);
gotoxy(3,3); write(#$BA);gotoxy(26,3); write(#$BA);
gotoxy(3,4); write(#$BA,' version ',V,' ', #$BA);
gotoxy(3,5); write(#$C8);
for x := 4 to 25 do write(#$CD); write(#$BC);
w_make(10,70,6,15);
w_gotoxy(2,2);
w_write_s('What library file do you want to use? ');
w_writeln;
w_writeln;
w_write_s(' Library name format is <filename>[.lbr]'); w_writeln;
w_writeln;
w_write_s(' The extention ".LBR" is assumed in all cases'); w_writeln;
w_write_s(' A null filename (just press <CR>) exits the program.');
w_gotoxy(40,2);
readln(str); w_writeln;
LibName := Parse(str);
if length(LibName)=0 then begin
gotoxy(1,23);
halt;
end;
w_delete;
end;
procedure Menu;
var selection: char;
x : integer;
begin
OpenLibrary;
{ draw character graphics on screen -- set up display 'form' }
gotoxy(26,1); write(#$CB); for x :=27 to 78 do write(#$CD); write(#$BB);
gotoxy(27,2);
write(' Name: ',LibName,'':14-length(LibName),#$B3);
gotoxy(79,2); write(#$BA);
gotoxy(26,3);write(#$C7);gotoxy(79,3);write(#$B6);
gotoxy(27,3); for x := 27 to 78 do write(#$C4);
gotoxy(79,4); write(#$BA); gotoxy(3,5); write(#$CC);
for x := 4 to 25 do write(#$CD); write(#$CA);
for x :=27 to 78 do write(#$CD); write(#$B9);
gotoxy(49,1); write(#$D1); gotoxy(63,1); write(#$D1);
gotoxy(49,3); write(#$C5); gotoxy(63,3); write(#$C5);
gotoxy(49,5); write(#$CF); gotoxy(63,5); write(#$CF);
repeat
write(CURSOR_OFF);
if w_table.x1 <> -1 then begin
delay(2000);
w_delete;
end;
LibSize := (1 + filesize(library)) DIV 8; {in kilobytes}
{ Update info on screen which could have changed cuz of last cmd }
gotoxy(27,4);
write( ' Size: ',LibSize:3,'K bytes ',#$B3);
gotoxy(50,2);
write(' Total: ',active+deleted+unused - 1:3,' ',#$B3);
gotoxy(50,4);
write( ' Active: ',active - 1:3,' ',#$B3);
gotoxy(64,2);
write(' Erased: ',deleted:3,' ');
gotoxy(64,4);
write( ' Unused: ',unused:3);
{ turn on status line for function key input }
set_status('1 Extract ','2 Add ','3 Erase ',
'4 Unerase ','5 Pack ','6 Help ','7 Quit ');
Directory; { show updated library directory }
repeat
read(kbd,selection);
selection := upcase(selection);
until (selection in ['X','A','E','U','P','?','H','Q',
FK1,FK2,FK3,FK4,FK5,FK6,FK7]);
clear_status;
write(CURSOR_ON);
case selection of
'A',FK2: Add;
'X',FK1: Extract;
'H','?',FK6: Help;
'E',FK3: Delete; (* erase *)
'P',FK5: Reorganize; (* pack *)
'U',FK4: Undelete;
'Q',FK7:;
end;
until selection in ['Q',FK7];
if DirectoryChanged then WriteDirectoryToDisk(library);
close(library);
end;
begin {Main}
w_table.x1 := -1;
repeat
NewLib;
Menu;
until Hell_Freezes_Over;
end.