home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
database
/
db_dbug2.zip
/
DB_FILES.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1986-11-20
|
16KB
|
470 lines
{program DB_FILES
This is one of a series of utilities intended for analyzing dBASE III .PRG
files. This program prints out the structure of all .DBF files, and the
keys of the associated .ndx files, used in each .PRG of any given tree.
Written by Curtis H. Hoffmann
version A1 11/05/86
A1 11/05/86 Initial Release
}
const
blanks= ' ';
type
name = string[12];
stt = string[255];
datetype = string[8];
regtype = record
ax,bx,cx,dx,bp,si,di,ds,es,flags: integer
end;
var
file_in, file_out : text;
all_files, abo : char;
in_file, ofl : string[8];
out_file : string[12];
mac_name : string[13];
progs, dbf, ndx : array[1..100] of string[12];
macro : array[1..100] of string[15];
mac_var : array[1..100] of string[10];
ndx_stack : array[1..100] of integer;
dbf_to_ndx : array[1..100] of integer;
sele_stack : array[1..10] of integer;
prog_stack, line_stack : array[1..20] of integer;
ps, sp, ln_cnt, dp, np, d_p, sx, mp : integer;
st, outstring, temp_st, path : string[255];
next_word, this_word : string[10];
more_words, skip_line, pass_one, a_d : boolean;
function time: datetype;
var reg: regtype;
h,m,s,w: datetype;
i: integer;
begin
reg.ax:=$2c00;
intr($21,reg);
str(hi(reg.cx):2,h);
str(lo(reg.cx):2,m);
str(hi(reg.dx):2,s);
w:=h+':'+m+':'+s;
for i:=1 to length(w) do if w[i]=' ' then w[i]:='0';
time:=w;
end;
function date: datetype;
var reg: regtype;
y,m,d,w: datetype;
i: integer;
begin
reg.ax:=$2a00;
intr($21,reg);
str(reg.cx:4,y);
delete(y,1,2);
str(hi(reg.dx):2,m);
str(lo(reg.dx):2,d);
w:=m+'/'+d+'/'+y;
for i:=1 to length(w) do if w[i]=' ' then w[i]:='0';
date:=w;
end;
function exist(filename: name): boolean; {Do requested files exist?}
var fil: file;
begin
assign(fil, filename);
{$I-}
reset(fil);
{$I+}
exist:=(IOresult=0);
close(fil);
end;
function standard_io(h :name): boolean; {Is requested file PRN or CON?}
begin
if ((h='prn') or (h='PRN')) or ((h='con') or (h='CON')) then
standard_io:=true
else standard_io:=false;
end;
procedure get_started; {Request I/O files, open them}
var ow: char;
j: integer;
begin
abo:='N'; clrscr; gotoxy(10,10);
write('Input .PRG file to check first : '); read(in_file); gotoxy(10,12);
write('File to dump output to (prn for printer): '); read(out_file); gotoxy(10,14);
write('Check all files, or just this one (A/O) : '); readln(all_files);
all_files:=upcase(all_files);
if not exist(in_file+'.prg') then begin
writeln(in_file+'.PRG does not exist, program aborted'); abo:='Y'; end
else begin
for j:=1 to length(in_file) do
if (in_file[j]>='a') and (in_file[j]<='z') then
in_file[j]:=upcase(in_file[j]);
assign(file_in, in_file+'.prg'); reset(file_in);
end;
textcolor(12);
if not standard_io(out_file) then if exist(out_file) then begin
write(out_file+' exists, overwrite it (Y/N)?: '); readln(ow);
if upcase(ow)<>'Y' then begin write('Program aborted'); abo:='Y'; end;
end;
textcolor(14);
progs[1]:=in_file;
if abo<>'Y' then begin assign(file_out, out_file); rewrite(file_out); end;
end;
procedure init; {Initialize variables}
var i: integer;
begin
ln_cnt:=0; dp:=0; getdir(0,path); np:=0; mp:=0;
sp:=1; ps:=1; prog_stack[sp]:=1; sx:=1;
for i:=1 to 20 do line_stack[i]:=0;
end;
procedure push_stack; {Put current .PRG in stack,}
var y: integer; {print out filename, variable list}
v: boolean; {then open next called filename}
begin
line_stack[ps]:=ln_cnt; ps:=ps+1; y:=1;
while (y<=sp) and (next_word<>progs[y]) do y:=y+1;
if y>sp then begin sp:=sp+1; progs[sp]:=next_word; end;
prog_stack[ps]:=y; close(file_in);
assign(file_in, progs[prog_stack[ps]]+'.prg'); reset(file_in);
ln_cnt:=0;
end;
procedure pop_stack; {Print current filename and list}
var y: integer; {of newly released variables, then}
v: boolean; {close current file and open top}
begin {file in the stack}
ps:=ps-1;
if ps>0 then begin
ln_cnt:=line_stack[ps];
close(file_in);
assign(file_in, progs[prog_stack[ps]]+'.prg'); reset(file_in);
gotoxy(10,20); write('Working on '+progs[prog_stack[ps]]+' ');
for y:=1 to ln_cnt do readln(file_in, st);
end;
end;
function ltrim(var stg: stt): stt; {Remove leading blanks}
begin
while (stg[1]=' ') and (length(stg)>0) do stg:=copy(stg,2,length(stg));
ltrim:=stg;
end;
function digi_len(ipic: real): integer;
var uv: integer;
begin
uv:=1;
while ipic/10>1 do begin
uv:=uv+1; ipic:=ipic/10;
end;
digi_len:=uv;
end;
procedure dbf_header;
var df, fg, numb_rec, dd1, dd2, dd3: integer;
ch, field_length, field_type, dec_length: char;
field_name: string[10];
up_date: string[8];
end_header, end_name: boolean;
procedure get_field;
begin
fg:=10; end_name:=false;
if length(field_name)=0 then fg:=11;
for df:=1 to fg do begin
read(file_in,ch); if ord(ch)=0 then end_name:=true;
if not end_name then field_name:=field_name+ch;
end;
end;
procedure f_date;
var kk: string[2];
ii: integer;
begin
up_date:=''; str(dd2,kk); up_date:=copy(blanks,1,2-length(kk))+kk+'/';
str(dd3,kk); up_date:=up_date+copy(blanks,1,2-length(kk))+kk+'/';
str(dd1,kk); up_date:=up_date+kk;
for ii:=1 to 8 do if up_date[ii]=' ' then up_date[ii]:='0';
end;
begin
end_header:=false; numb_rec:=0;
read(file_in,ch);
read(file_in,ch); dd1:=ord(ch); read(file_in,ch); dd2:=ord(ch); read(file_in,ch); dd3:=ord(ch);
read(file_in,ch); numb_rec:=ord(ch); read(file_in,ch); numb_rec:=numb_rec+256*ord(ch);
write(file_out,copy(blanks,1,17-length(dbf[ps])),'# Records= ',numb_rec,copy(blanks,1,10-digi_len(numb_rec)));
f_date; writeln(file_out,'Last Updated: ',up_date);
for df:=1 to 26 do read(file_in,ch); field_name:='';
while not end_header do begin
get_field; read(file_in,field_type); for df:=1 to 4 do read(file_in,ch);
read(file_in,field_length); read(file_in,dec_length); read(file_in,ch);
while (ord(ch)<>13) and ((ord(ch)<32) or (ord(ch)>127)) do read(file_in,ch);
if ord(ch)=13 then end_header:=true;
write(file_out,' ',field_name,copy(blanks,1,12-length(field_name)),field_type,' ',ord(field_length));
if field_type='N' then writeln(file_out,' ',ord(dec_length)) else writeln(file_out);
field_name:=ch;
end;
end;
procedure ndx_header;
var df: integer;
ch: char;
begin
write(file_out,' ');
for df:=1 to 25 do read(file_in,ch);
while ord(ch)<>0 do begin
write(file_out,ch); read(file_in,ch);
end;
writeln(file_out);
end;
function get_word(var line: stt): stt; {Put first, and second, in line}
var word: string[20]; {words in current sentence into}
begin {This_word and Next_word}
st:=ltrim(st); word:='';
while (length(st)>0) and (st[1]<>' ') do begin
if (st[1]>='a') and (st[1]<='z') then word:=word+upcase(st[1])
else word:=word+st[1];
st:=copy(st,2,length(st));
end;
get_word:=word;
end;
function mac(yy: name): boolean;
var yt: integer;
begin
mac:=false;
for yt:=1 to length(yy) do if yy[yt]='&' then mac:=true;
end;
procedure parse; {Break sentence up into seperate}
begin {words to be operated on}
st:=ltrim(st);
if length(this_word)>0 then begin
this_word:=next_word; next_word:=get_word(st); end
else begin
this_word:=get_word(st); next_word:=get_word(st);
end;
more_words:=false;
if (length(st)>0) or (length(this_word)>0) then more_words:=true;
end;
procedure first_char; {Check to see if sentence is}
begin {a comment or empty}
skip_line:=false; st:=ltrim(st);
if (length(st)=0) or (st[1]='*') then skip_line:=true;
end;
procedure add_mac;
var s: integer;
mac_strip: string[15];
begin
s:=1; while next_word[s]<>'&' do s:=s+1; mac_strip:=copy(next_word,s+1,length(next_word));
if mp=0 then begin
mp:=1; macro[1]:=mac_name; mac_var[1]:=mac_strip;
end;
s:=1;
while (s<=mp) and (mac_name<>macro[s]) do s:=s+1;
if s>mp then begin
mp:=mp+1; macro[mp]:=mac_name; mac_var[mp]:=mac_strip;
end;
end;
procedure add_dbf;
var j, e: integer;
begin
if mac(next_word) then begin
mac_name:='d'+next_word; add_mac;
end
else begin
if dp=0 then begin
dp:=1; dbf[1]:=next_word; dbf_to_ndx[1]:=1; sele_stack[sx]:=1;
end
else begin
j:=1;
while j<=dp do begin
if dbf[j]=next_word then begin
if a_d then sele_stack[sx]:=dbf_to_ndx[j]; j:=dp+5;
end
else if next_word<dbf[j] then begin
dp:=dp+1; e:=dp;
while e>j do begin
dbf[e]:=dbf[e-1]; dbf_to_ndx[e]:=dbf_to_ndx[e-1]; e:=e-1;
end;
dbf[j]:=next_word;
if a_d then begin dbf_to_ndx[j]:=dp; sele_stack[sx]:=dp; end
else dbf_to_ndx[j]:=0;
end
else j:=j+1;
end;
if j<>dp+5 then begin
dp:=dp+1; dbf[dp]:=next_word; sele_stack[sx]:=dp; dbf_to_ndx[dp]:=dp;
end;
end;
end;
end;
procedure add_ndx;
var j: integer;
e: integer;
v: char;
begin
while ((this_word<>'TO') and (copy(this_word,1,4)<>'INDE')) and more_words do parse;
if (this_word='TO') or (copy(this_word,1,4)='INDE') then while length(next_word)>0 do begin
v:=copy(next_word,length(next_word),1);
if v=',' then next_word:=copy(next_word,1,length(next_word)-1);
if mac(next_word) then begin
mac_name:='x'+next_word; add_mac;
end
else begin
if np=0 then begin
np:=1; ndx[1]:=next_word; ndx_stack[1]:=sele_stack[sx];
end
else begin
j:=1;
while j<=np do begin
if (ndx[j]=next_word) and (sele_stack[sx]=ndx_stack[j]) then j:=np+5
else if ndx[j]>next_word then begin
np:=np+1; e:=np; while e>j do begin
ndx[e]:=ndx[e-1]; ndx_stack[e]:=ndx_stack[e-1]; e:=e-1;
end;
ndx[j]:=next_word; ndx_stack[j]:=sele_stack[sx]; j:=np+5;
end
else j:=j+1;
end;
if j<>np+5 then begin
np:=np+1; ndx[np]:=next_word; ndx_stack[np]:=sele_stack[sx];
end;
end;
end;
parse;
end;
end;
procedure check_macro;
var i, j: integer;
chr: char;
w2: string[255];
w1: string[15];
begin
w2:='';
if next_word='=' then begin
st:=ltrim(st);
if (st[1]='"') or (ord(st[1])=39) then begin
chr:=st[1]; st:=copy(st,2,length(st)); j:=1;
while (st[j]<>chr) and (j<=length(st)) do j:=j+1;
w2:=copy(st,1,j-1); i:=1;
while i<=mp do begin
w1:=copy(macro[i],2,length(macro[i]));
if this_word=mac_var[i] then begin
j:=1;
while (w1[j]<>'&') and (j<=length(w1)) do j:=j+1;
next_word:=copy(w1,1,j-1)+w2;
if copy(macro[i],1,1)='d' then add_dbf
else begin
this_word:='TO'; st:=''; add_ndx;
end;
end;
i:=i+1;
end;
end;
end;
end;
procedure what_cmd; {Identify the current dBASE}
var o: integer; {command and perform the}
tw, nw: string[4]; {appropriate function}
begin
tw:=this_word; nw:=next_word; a_d:=true;
if pass_one and (all_files='A') then if (tw='DO') then if (nw<>'CASE') and (nw<>'WHIL') then push_stack;
if pass_one then begin
if (tw='USE') and (length(nw)>0) then begin
add_dbf; add_ndx;
end;
if (tw='APPE') and (nw='FROM') then begin
a_d:=false; parse; add_dbf;
end;
if ((tw='SET') and (nw='INDE')) or (tw='INDE') then begin
while (this_word<>'TO') and (more_words) do parse; add_ndx;
end;
if (tw='SELE') then begin
sx:=0; if (length(nw)=1) then sx:=ord(nw)-64;
if (sx<1) or (sx>10) then sx:=1;
end;
end
else if (tw='STOR') or (nw='=') then check_macro;
more_words:=false;
end;
procedure get_line; {Get new sentence and prepare}
var bb: integer; {for parsing}
cc: string[3];
nn: string[255];
dq: boolean;
begin
nn:=''; cc:=''; this_word:=''; next_word:=''; more_words:=true;
readln(file_in,st); dq:=false;
for bb:=1 to length(st) do begin
cc:=st[bb];
if (cc='"') or (ord(cc)=39) then dq:=true;
if (cc=',') or ((ord(cc)<31) or (ord(cc)>127)) then cc:=' ';
if (cc='=') and (not dq) then cc:=' '+cc+' ';
nn:=nn+cc;
end;
st:=nn;
ln_cnt:=ln_cnt+1; first_char;
if not skip_line then while more_words begin
parse; what_cmd;
end;
end;
begin {Main Body of the Program}
get_started; init; pass_one:=true;
{If abo=Y then the program is to be aborted for some reason}
if abo<>'Y' then begin
writeln(file_out,' dBASE III Program Datafile Structure Report for directory '+path);
write(file_out,'Starting with: '+in_file+'.PRG'+copy(blanks,1,8-length(in_file)));
writeln(file_out,' run at ',time,' on ',date);
writeln(file_out);
outstring:=' ';
while ps>0 do begin
while not eof(file_in) do get_line;
pop_stack;
end;
pass_one:=false;
for ps:=1 to sp do begin
gotoxy(10,20); write('Searching ',progs[ps],' ');
close(file_in); assign(file_in,progs[ps]+'.prg'); reset(file_in);
while not eof(file_in) do get_line;
end;
for ps:=1 to dp do begin
write(file_out,dbf[ps]);
if exist(dbf[ps]+'.dbf') then begin
close(file_in); assign(file_in,dbf[ps]+'.dbf'); reset(file_in);
dbf_header;
end;
writeln(file_out);writeln(file_out,'*** Index Files ***');
for sx:=1 to np do if dbf_to_ndx[ps]=ndx_stack[sx] then begin
write(file_out,ndx[sx]+copy(blanks,1,8-length(ndx[sx])));
if exist(ndx[sx]+'.ndx') then begin
close(file_in); assign(file_in,ndx[sx]+'.ndx'); reset(file_in);
ndx_header;
end;
end;
writeln(file_out); writeln(file_out,'=============================================================');
writeln(file_out);
end;
end;
close(file_in); close(file_out);
end.