home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
database
/
liststr2.zip
/
LISTSTRU.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1987-02-21
|
11KB
|
255 lines
{ Name : LISTSTRU.PAS
Version : 1.0
2.0 -- with new SCS address
Created : 07/25/1985
Revised : 02/20/1987
Compiler : Turbo Pascal V 3.01a
Includes : none
Function : lists structure of dBASE III database file
Notes : use redirection for output to file or printer
Changes :
Additions :
Usage : LISTSTRU Filename.DBF > output file
Notes : 02/20/1987 -- this is a really old file but it works. There
are newer versions (in 'C') but Pascal
illustrates the structure of the header better.
}
{$G512,P512,D-} (* enable redirection *)
{$U+} (* supposed to be able to interrupt but you can't *)
program LISTSTRU(input,output);
type
FileNameType = string[64]; { 64 chars allows full path }
String255 = string[255];
String10 = string[10];
var
x : integer;
ch : char;
hold : string[5]; { temporary string }
last_update : string10; { last update date }
recs_in_file : real; { records in file }
bytes_in_header : real; { number of bytes in header }
bytes_in_record : real; { number of bytes in record }
bytes_read : integer; { bytes read from .DBF file }
f_name : string[10]; { field name }
f_type : char; { field type }
f_len : char; { field length }
f_dec : char; { field decimal places }
f_num : integer; { field number for display }
in_file : text; { input file }
{***************************************************************************}
{ get_last_update -- gets date of last database update and puts the result }
{ into last_update variable }
{***************************************************************************}
procedure get_last_update;
var
yr,
mon,
day : string[2];
begin
for x := 1 to 3 do
read(in_file,hold[x]);
str(ord(hold[1]):2,yr); { convert bytes to string representation }
str(ord(hold[2]):2,mon);
str(ord(hold[3]):2,day);
if mon[1] = ' ' then { replace any leading space with 0 }
mon[1] := '0';
if day[1] = ' ' then
day[1] := '0';
last_update := mon + '-' + day + '-19' + yr;
end;
{****************************************************************************}
{ get_recs_in_file -- gets the number of records in a file and stores result }
{ in recs_in_file variable }
{***************************************************************************}
procedure get_recs_in_file;
begin
for x := 1 to 4 do
read(in_file,hold[x]);
recs_in_file := ord(hold[1]) +
ord(hold[2]) shl 8 + { shift left 8 }
ord(hold[3]) * (256 * 256) + { shift left 16 }
ord(hold[4]) * (256 * 256 * 256); { shift left 24 }
end;
{***************************************************************************}
{ get_bytes_in_header -- gets number of bytes in the file header and stores }
{ the result in bytes_in_header variable }
{***************************************************************************}
procedure get_bytes_in_header;
begin
read(in_file,hold[1]);
read(in_file,hold[2]);
bytes_in_header := ord(hold[1]) +
ord(hold[2]) shl 8;
end;
{***************************************************************************}
{ get_bytes_in_record -- gets the number of bytes in each record and puts }
{ the result in bytes_in_record variable }
{***************************************************************************}
procedure get_bytes_in_record;
begin
read(in_file,hold[1]);
read(in_file,hold[2]);
bytes_in_record := ord(hold[1]) + ord(hold[2]) shl 8;
end;
{***************************************************************************}
{ skip_bytes -- reads bytes_to_skip bytes from the input file, used to skip }
{ various non-essential parts of the DBF header }
{***************************************************************************}
procedure skip_bytes(bytes_to_skip : integer);
begin
for x := 1 to bytes_to_skip do
read(in_file,ch);
end;
{****************************************************************************}
{ exist : returns TRUE if FileN exists else returns FALSE }
{****************************************************************************}
function Exist(FileN: FileNameType): boolean;
var F: file;
begin
{$I-}
assign(F,FileN);
reset(F);
{$I+}
if IOResult <> 0 then Exist := FALSE
else Exist := TRUE;
end;
{***************************************************************************}
{ usage -- displays err_mes and usage information then halts program }
{***************************************************************************}
procedure usage(err_mes : String255);
begin
clrscr;
writeln;
writeln('LISTSTRU -- list the structure of a dBASE III database file');
writeln(' from the operating system. Output can be redirected');
writeln(' to any device or used in pipes.');
writeln;
writeln(' Copyright 07-25-1985, 02-20-87 (yes we''re still here)');
writeln(' steiner computer services');
writeln(' 94 forrest street');
writeln(' plaistow, NH 03865');
writeln(' 603-382-1313');
writeln(' Write to the address above for a list of commercial dBASE');
writeln(' utilities available from steiner computer services');
writeln;
writeln(' This program is for non-commercial use only, may be freely copied');
writeln(' for personal use only, no guarantees etc. (you''ve read it before)');
writeln;
writeln(' Usage : LISTSTRU In_file.DBF > output.fil');
writeln(' output may be redirected to any device or used in pipes');
writeln;
writeln(' Error : ',err_mes);
halt(1); { set ERRORLEVEL to 1 for system interrogation }
end;
{****************************************************************************}
{ space -- returns x spaces ala dBASE III space() function }
{****************************************************************************}
function space(x : integer) : String255;
var
y : integer;
temp : String255;
begin
temp := '';
for y := 1 to x do begin
temp := temp + ' ';
end;
space := temp;
end;
{****************************************************************************}
{ f_trunc -- truncate the function name at the first 00 byte }
{****************************************************************************}
procedure f_trunc(var name : string10);
var
zero_pos,
x : integer;
begin
zero_pos := pos(chr(00),name);
if zero_pos <> 0 then
for x := zero_pos to 10 do
name[x] := ' ';
end;
{****************************************************************************}
{ main routine }
{****************************************************************************}
begin
if paramstr(1) = '' then begin { input file name entered ? }
usage('No input file specified ');end
else if not(exist(paramstr(1))) then begin { does the file exist ? }
usage('File not found -- '+ paramstr(1));end
else begin { yes then open it for input }
assign(in_file,paramstr(1));
reset(in_file);
end;
{ grab the information pertaining to the header and dbf statistics }
read(in_file,ch); { version number }
get_last_update; { get the rest of the stuff }
get_recs_in_file;
get_bytes_in_header;
get_bytes_in_record;
skip_bytes(20); { skip the reserved bytes }
{ write out the 'header header' }
writeln;
writeln('Structure for database : ', paramstr(1));
writeln('Number of data records : ', recs_in_file:10:0);
writeln('Date of last update : ', last_update);
writeln('Field Field name Type Width Dec');
writeln('----- ---------- ---- ----- ---');
bytes_read := 35; { insures that bytes_read will exceed
bytes_in_header when the last field
is read }
f_num := 1;
while bytes_read < bytes_in_header do begin
f_name := space(10); { blank the field information variables }
f_type := space(1);
f_len := space(1);
f_dec := space(1);
for x := 1 to 11 do { field name -- supposed to be 00 filled }
read(in_file,f_name[x]); { but occasionally contains chars after }
{ the first 00 byte, f_trunc removes all }
{ chars from f_name following first 00 }
f_trunc(f_name);
read(in_file,f_type); { field type }
skip_bytes(4); { skip field data address }
read(in_file,f_len); { field length in binary }
read(in_file,f_dec); { field decimal places in binary }
skip_bytes(14); { reserved bytes in the field descriptor }
write(f_num:5,' '); { field number }
write(f_name,' ');
case f_type of { convert the C,N,L,D,M to name of type }
'C' : write('Character ');
'N' : write('Numeric ');
'L' : write('Logical ');
'D' : write('Date ');
'M' : write('Memo ');
end;
write(ord(f_len):4);
if f_type = 'N' then { decimal places for numeric fields }
write(ord(f_dec):7);
writeln;
bytes_read := bytes_read + 32; { 32 bytes per descriptor }
f_num := f_num + 1; { f_num is the field number }
end;
writeln('** Total ** ',bytes_in_record:6:0);
end.