home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
DBASEOS2.ZIP
/
RDDBASE.C
next >
Wrap
C/C++ Source or Header
|
1990-05-01
|
9KB
|
319 lines
/* ---------- "C source to read dBASE files" ---------- */
/* Here is the C code that allows you to read a DBASE-III file. I verified
that it works under Microsoft C v4.0. Hope it does every thing you need.
I am not sure where it came from, so hopefully I am not violating anyones
copyrights :-). Have fun.
Greg Twaites
SICOM Inc.
!ihnp4!sun!sunburn!sicom!twaites
*/
/* */
/* */
/* changed IO and MEMORY calls to OS/2 calls by Joe McVerry 919-846-2014 */
/* */
/* compiled with MSC 5.1 - use the /AL or some form of far pointer allocation*/
/* */
/* */
/*
* These functions are used to read dbase files.
*
* These functions are provided by Valour Software as a gift.
*
* The program is for test purposes only. No warranty is expressed nor
* implied. USE AT YOUR OWN RISK!
*
*
*/
#define LINT_ARGS
#define INCL_BASE
#include <os2.h>
#include <dos.h>
#include <stdio.h>
HFILE dbfile;
PHFILE p_file = &dbfile;
USHORT f_result;
PUSHORT pf_result = &f_result;
long rec_selector;
short subrec_selector;
long fld_selector;
short subfld_selector;
typedef struct dbase_head {
unsigned char version; /*03 for dbIII and 83 for dbIII w/memo file*/
unsigned char l_update[3]; /*yymmdd for last update*/
unsigned long count; /*number of records in file*/
unsigned int header; /*length of the header
*includes the \r at end
*/
unsigned int lrecl; /*length of a record
*includes the delete
*byte
*/
unsigned char reserv[20];
} DBASE_HEAD;
typedef struct dbase_fld {
char name[11]; /*field name*/
char type; /*field type*/
#define DB_FLD_CHAR 'C'
#define DB_FLD_NUM 'N'
#define DB_FLD_LOGIC 'L'
#define DB_FLD_MEMO 'M'
#define DB_FLD_DATE 'D'
/* A-T uses large data model but drop it for now */
char far *data_ptr; /*pointer into buffer*/
unsigned char length; /*field length*/
unsigned char dec_point; /*field decimal point*/
unsigned char fill[14];
} DBASE_FIELD;
typedef struct fld_list {
struct fld_list *next;
DBASE_FIELD *fld;
char *data;
} FLD_LIST;
DBASE_HEAD dbhead={0};
FLD_LIST *db_fld_root=0;
char *Buffer;
char buf_work[255];
int rc;
/*------------------------------------------------------------code-------*/
main(argc,argv)
int argc;
char *argv[];
{
if(argc!=2)
{
printf("Usage is db_dump filename.dbf");
exit(100);
}
rc = DosOpen(argv[1],
p_file,pf_result,(ULONG)0,0,0x01,0x00c0,(ULONG)0);
if(rc)
{
printf("Dos open error %3.3d for file %s ",rc,argv[1]);
exit(150);
}
db3_read_dic();
db3_print_recs(dbhead.count);
printf("\n\n\t\t\tProcessing complete");
DosClose(dbfile);
exit(0);
}
/******************************************************
db3_read_dic()
This function is called with a file name to
read to create a record type to support the
dbase file
******************************************************/
db3_read_dic()
{
int len;
int fields;
DBASE_FIELD *fld;
int alloc_size;
if(p_file == NULL) {
printf("open failed");
exit(200);
}
rc = DosRead(dbfile,&dbhead,sizeof(DBASE_HEAD),&len);
if (rc)
{
printf("\n\aUnable to read file rc = %3.3d",rc);
exit(205);
}
if( (dbhead.version!=3 && dbhead.version!=0x83) )
{
printf("\n\aVersion %d not supported",dbhead.version);
exit(300);
}
printf("update year %3d\n",dbhead.l_update[0]);
printf("update mon %3d\n",dbhead.l_update[1]);
printf("update day %3d\n",dbhead.l_update[2]);
printf("number of recs %3d\n",dbhead.count);
printf("header length %3d\n",dbhead.header);
printf("record length %3d\n",dbhead.lrecl);
fields=(dbhead.header-1)/32-1;
/* allocate space for file buffer area */
rc = DosAllocSeg(dbhead.lrecl,(PSEL)&rec_selector,0);
if (rc)
{
printf("\n\aUnable to allocate memory rc = %3.3d",rc);
exit(400);
}
FP_SEG(Buffer) = rec_selector;
FP_OFF(Buffer) = 0;
/* allocate space and sub area for record buffer area
reuse selector but don't corrupt it again or you're in big trouble */
alloc_size = (fields+1) * sizeof(FLD_LIST);
rc = DosAllocSeg(alloc_size,(PSEL)&rec_selector,0);
if (rc)
{
printf("\n\aUnable to allocate record memory rc = %3.3d",rc);
exit(500);
}
DosSubSet(rec_selector,1,alloc_size);
if (rc)
{
printf("\n\aUnable to set suballocated record memory rc = %3.3d",rc);
exit(505);
}
// allocate space for data to stored in
alloc_size = (fields+1) * sizeof(DBASE_FIELD);
rc = DosAllocSeg(alloc_size,(PSEL)&fld_selector,0);
if (rc)
{
printf("\n\aUnable to allocate field memory rc = %3.3d",rc);
exit(600);
}
DosSubSet(fld_selector,1,alloc_size);
if (rc)
{
printf("\n\aUnable to set suballocated field memory rc = %3.3d",rc);
exit(605);
}
printf("\nField Name\tType\tLength\tDecimal Pos\n");
while(fields--) {
rc = DosSubAlloc(fld_selector,(PUSHORT)&subfld_selector,sizeof(DBASE_FIELD));
if (rc)
{
printf("\n\aUnable to suballocate field memory rc = %3.3d",rc);
exit(610);
}
FP_SEG(fld) = fld_selector;
FP_OFF(fld) = subfld_selector;
rc = DosRead(dbfile,fld,sizeof(DBASE_FIELD),&len);
if (rc)
{
printf("\n\aUnable to read file rc = %3.3d",rc);
exit(620);
}
printf("%-10s\t %c\t %3d\t %3d\n",fld->name,fld->type,
fld->length,fld->dec_point);
stack_field(fld);
}
rc = DosRead(dbfile,Buffer,1,&len); /*read the silly little \r character*/
if (rc)
{
printf("\n\aUnable to read file rc = %3.3d",rc);
exit(630);
}
return;
}
/******************************************************
db3_print_recs()
Read records and print the data
******************************************************/
db3_print_recs(cnt)
int cnt;
{
int bytes;
while(cnt) {
rc=DosRead(dbfile,Buffer,dbhead.lrecl,&bytes);
if (rc)
{
printf("\n\aUnable to read file rc = %3.3d",rc);
exit(700);
}
if(bytes!=dbhead.lrecl)
break;
if(Buffer[0]!='*') {
db3_print();
cnt--;
}
}
return;
}
/******************************************************
db3_print()
Print a single record
******************************************************/
db3_print()
{
FLD_LIST *list, *temp;
temp=db_fld_root;
printf("\n");
while(temp) {
memcpy(buf_work,temp->data,temp->fld->length);
buf_work[temp->fld->length]='\0';
printf("%-10s=%s\n",temp->fld->name,buf_work);
temp=temp->next;
}
return;
}
/******************************************************
stack_field()
Add a field to the linked list of fields
******************************************************/
stack_field(fld)
DBASE_FIELD *fld;
{
FLD_LIST *list, *temp;
long fld_selector;
rc = DosSubAlloc(rec_selector,(PUSHORT)&subrec_selector,sizeof(FLD_LIST));
if (rc)
{
printf("\n\aUnable to suballocate record memory rc = %3.3d",rc);
exit(800);
}
FP_SEG(list) = rec_selector;
FP_OFF(list) = subrec_selector;
list->next = NULL;
list->fld=fld;
if(!db_fld_root) {
list->data=Buffer+1; /*skip delete byte*/
db_fld_root=list;
return;
}
temp=db_fld_root;
while(temp->next)
temp=temp->next;
temp->next=list;
list->data=temp->data + temp->fld->length;
return;
}
/* End of text from inmet:comp.sys.ibm.pc */