Read-only archive view · 1993-11-04 · 20,347 bytes · SHA-256 ED003B255DE994B4C991D32F1EBBBA4622252FB9A82E31619B76EFFA3A2A16CA
/* xbcmds.c is a module that combines the modules xbase.c and xbindex.c
xbindex is a proprietary index system, while dbase.c should work with any
xbase file system
*/
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <math.h>
#include "xbindex.h"
#include "xbase.h"
#include "xbcmds.h"
#if MSDOS
#include <malloc.h>
#endif
/* index info for global purposes */
/* xbase global variables */
extern select_rec * FAR _export s[max_area];
extern char FAR _export area;
extern long rec_num ;
extern int GRERROR ;
extern int DOSERROR ;
extern char IBMPC;
extern int rr ; /* records_read */
extern char *filemode ; /* filemode */
/* field types
extern char *character;
extern char date[date_size] ;
extern char numeric[19];
extern char *memo;
extern FILE *tofile ;
extern int scr_limit ;
extern long result ;
extern unsigned long memory;
extern order_array_type temporder ;
*/
/* index & dummy info */
extern IX_DESC *pci;
extern BLOCK spare_block;
#define KEY_SIZE 20
int ndum = KEY_SIZE + sizeof(NULLREC);
int fs = 20480;
ENTRY dume=
{
NULLREC,
{
0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xf0
}
};
int compf(ENTRY *p1, ENTRY *p2)
{
return(strcmp((char *)&p1->key,(char *)&p2->key));
}
int sizef(ENTRY *p1)
{
return(strlen(p1->key) + 1 + sizeof(RECPOS));
}
/* end of dummy vars */
char *dxfile;
FILE *idx_file;
char *xfile;
char found;
int keylen;
char *keystr;
rel r[max_area][max_index];
char deleted = TRUE ; /* set delete status TRUE or FALSE */
/* DLL entry */
int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine)
{
if (wHeapSize > 0)
UnlockData(0);
initbase();
initcmds();
return 1;
}
/* DLL exit */
int FAR PASCAL _export WEP (int nParam)
{
return 1;
}
/* begin xbase command functions */
void FAR PASCAL _export initcmds()
{
int i,j;
for (i=1;i<max_area;i++)
for (j=1;j<max_index;j++)
{
r[i][j].c.a=0;
r[i][j].c.i=0;
}
memset((char *)&spare_block,0,sizeof(BLOCK));
}
void FAR PASCAL _export relate(int c_area,int c_order,int p_area,int p_order)
{
r[c_area][c_order].c.a = p_area;
r[c_area][c_order].c.i = p_order;
}
void FAR PASCAL _export other_rel(char a)
{
/* the whole purpose here is to update the position of other index files
for an area if open - skipping the one just updated before this call
*/
int i,field_no;
for (i=1;i<max_index;i++)
{
if (i != SA->ord) /* skip if this is the current order */
{
if (s[a]->i[i].idx) /* check if index open */
{
field_no = s[a]->i[i].pix->dx.order;
strcpy((char *)s[a]->i[i].pe->key,
s[a]->fd[field_no]); /* copy field info and record pointer */
s[a]->i[i].pe->rptr = s[a]->i[s[a]->ord].pe->rptr;
}
}
}
}
void FAR PASCAL _export relation(char a, char o)
{
int i,j;
char save_area,save_order;
save_area = a;
save_order = o;
for (i=a;i<max_area;i++) /* start with the current area */
for (j=1;j<max_index;j++)
if (r[i][j].c.a != 0)
if (r[i][j].c.i != 0)
{
/* activate parent area */
area = r[i][j].c.a;
SA->ord = r[i][j].c.i;
rtrim(s[i]->i[j].pe->key);
strcpy((char *)SI.pe->key,s[i]->i[j].pe->key);
rec_num = find_key(SI.pe,SI.pix);
if (rec_num != 0)
{
goto_rec(rec_num);
other_rel(area);
}
}
area = save_area;
SA->ord = save_order;
}
void FAR PASCAL _export relationtemp(char a,char o)
{
char savarea,savorder;
if (!SI.idx) return;
savarea = a;
savorder = o;
setrelationships(a,o);
area = savarea;
SA->ord = savorder;
}
void FAR PASCAL _export setrelationships(char a,char o)
{
int ret;
if (r[a][o].c.a == 0) return; /* done */
/* activate parent area */
area = r[a][o].c.a;
SA->ord = r[a][o].c.i;
/* copy child key to parent key */
strcpy((char *)SI.pe->key,(char *)s[a]->i[o].pe->key);
ret = find_key(SI.pe,SI.pix);
if (ret)
{
goto_rec(SI.pe->rptr);
setrelationships(area,SA->ord);
}
}
int FAR PASCAL _export open_index(char *fn,int dupok)
{
int dupixok;
dupixok = dupok;
SI.idx = TRUE;
SI.pix = (IX_DESC *)calloc(1,sizeof(IX_DESC));
memchk((char *)SI.pix,"open_index","SI.pix",sizeof(IX_DESC));
SI.pe = (ENTRY *)calloc(1,sizeof(ENTRY));
memchk((char *)SI.pe,"open_index","SI.pe",sizeof(ENTRY));
if (openix(fn,SI.pix,compf,sizef)<0)
{
SI.idx = FALSE;
free(SI.pix);
free(SI.pe);
return(0);
}
else
{
rtrim(SA->fd[SA->ord]);
strcpy(SI.pe->key,SA->fd[SA->ord]);
SI.pe->rptr = SA->crn;
find_key(SI.pe,SI.pix);
}
return(1);
}
int FAR PASCAL _export close_index(IX_DESC *pix)
{
int ret;
ret = close_if(pix->ixfile);
if (ret)
{
SI.idx = FALSE;
free((void *)SI.pix);
free((void *)SI.pe);
}
return(ret);
}
void FAR PASCAL _export build_index(char * xfile, int order)
{
int i,ret;
if ((order < 0) || (order > SA->num_of_fields))
return;
if (!make_index(xfile,1,order))
{
return;
}
else
{
if (SA->hr->num_of_recs < 1)
return;
goto_rec(1); /* this ignores any indexes open */
if (open_index(xfile,1))
{
for (i=1;i<=SA->hr->num_of_recs;i++)
{
if (SA->del != is_deleted)
{
SI.pe->rptr = i;
rtrim(SA->fd[order]);
strcpy((char *)SI.pe->key,SA->fd[order]);
ret = add_key(SI.pe,SI.pix);
}
if (i < SA->hr->num_of_recs)
{
read_rec(area);
}
}
close_index(SI.pix);
}
}
}
void FAR PASCAL _export reindex(char *idxname)
{
char order;
dxname(idxname);
if (SI.idx)
{
order = SI.pix->dx.order;
close_index(SI.pix);
build_index(idxname,order);
open_index(idxname,1);
}
}
void FAR PASCAL _export select(char newarea)
{
area = newarea;
}
void FAR PASCAL _export order(char area, char neworder)
{
s[area]->ord = neworder;
}
void FAR PASCAL _export use(char * pstr1, char * pstr2, char indexed)
{
int checkbreak;
pstr1 = dbname(pstr1);
pstr2 = dxname(pstr2);
close_area(area);
if (strlen(pstr1) > 4)
{
/* SA not calloced unless file open sucessfully */
if (open_file(pstr1,area))
SI.idx = indexed;
}
else
{
return;
}
checkbreak = TRUE;
if (GRERROR != 0)
{
return;
}
else
{
SA->fok = TRUE;
read_header(area);
read_fields(area);
read_rec(area);
SA->crn = 1;
if (SI.idx)
{
if (!open_index(pstr2,1))
SI.idx = FALSE;
}
top();
}
}
void FAR PASCAL _export close_area(char area)
{
int i;
if (SA->fok)
{
for (i=1;i<max_index;i++)
if (s[area]->i[i].idx)
close_index(s[area]->i[i].pix);
close_file(area);
}
}
/* indexed function only */
int FAR PASCAL _export find(char *key)
{
int rec_num;
if (!SI.idx)
return(0);
first_key(SI.pe,SI.pix);
strcpy((char *)SI.pe->key,key);
rec_num = find_key(SI.pe,SI.pix);
if (rec_num != 0)
{
goto_rec(rec_num);
relation(area,SA->ord);
return(1);
}
return(0);
}
int FAR PASCAL _export top()
{
long offset;
long rec_num;
if (SA->fok)
{
if (SI.idx)
{
rec_num = first_key(SI.pe,SI.pix);
goto_rec(rec_num);
}
else
{
offset = (long)SA->hr->data_start;
fseek(SA->fp,offset,0);
read_rec(area);
SA->crn = 1;
}
}
else
{
return(0);
}
relation(area,SA->ord);
return(1);
}
int FAR PASCAL _export bottom()
{
long offset;
long rec_num;
if (SA->fok)
{
if (SI.idx)
{
last_key(SI.pe,SI.pix);
rec_num = prev_key(SI.pe,SI.pix);
goto_rec(rec_num);
}
else
{
offset = (long)SA->hr->data_start+((SA->hr->num_of_recs-1)
*SA->hr->cpr);
fseek(SA->fp,offset,0);
read_rec(area);
SA->crn = (short)SA->hr->num_of_recs;
}
}
else
{
return(0);
}
relation(area,SA->ord);
return(1);
}
int FAR PASCAL _export skip(int skipped)
{
long offset;
int stat;
stat = 0;
if (SA->fok)
{
if (SI.idx)
{
if (skipped == 1)
{
stat = next_key(SI.pe,SI.pix);
if (stat != EOIX)
{
goto_rec(SI.pe->rptr);
SA->crn = SI.pe->rptr;
}
}
else
{
if (skipped == -1)
{
stat = prev_key(SI.pe,SI.pix);
goto_rec(SI.pe->rptr);
SA->crn = SI.pe->rptr;
}
}
}
if (!SI.idx)
{
if ((SA->crn + skipped) > SA->hr->num_of_recs)
{
stat = bottom();
}
else
{
if ((SA->crn + skipped) < 1)
{
stat = top();
}
else
{
offset = (long)SA->hr->data_start+
((SA->crn+(skipped-1))*SA->hr->cpr);
SA->crn = SA->crn + skipped;
fseek(SA->fp,offset,0);
stat = read_rec(area);
}
}
}
}
relation(area,SA->ord);
return(stat);
}
int FAR PASCAL _export match(char * fld_str)
{
/* returns the index position of a fieldname */
int i;
for(i=1;i<=SA->num_of_fields;i++)
{
if (strnicmps(SA->fr[i]->field_name,fld_str)==0)
return(i);
}
return(0);
}
/* non-indexed only */
void FAR PASCAL _export locate(char * field, char * fld_data)
{
int i;
if (SI.idx)
return;
top();
i = match(field);
while((strnicmps(SA->fd[i],fld_data)!=0) && (!feof(SA->fp)))
skip(1);
return;
}
int FAR PASCAL _export edit_field_old(char *fld_str,char *newstr)
{
/* If the field the file is indexed on is changed then the index needs
to be updated too.
*/
char field_no,save_order;
if (!SA->fok)
return(0);
field_no = match((char *)fld_str);
if (field_no)
{
save_order = SA->ord;
order(area,field_no);
if ((SI.idx) && (field_no == SI.pix->dx.order))
{
rtrim(SA->fd[field_no]);
SI.pe->rptr = SA->crn;
strcpy((char *)SI.pe->key,SA->fd[field_no]);
if (!delete_key(SI.pe,SI.pix))
{
order(area,(char)save_order);
return(0);
}
}
strcpy((char *)SA->fd[field_no],(char *)newstr);
if ((SI.idx) && (field_no == SI.pix->dx.order))
{
SI.pe->rptr = SA->crn;
rtrim(SA->fd[field_no]);
strcpy((char *)SI.pe->key,SA->fd[field_no]);
if (!add_key(SI.pe,SI.pix))
{
order(area,save_order);
return(0);
}
}
}
else
return(0);
order(area,save_order);
return(1);
}
int FAR PASCAL _export edit_field(char *fld_str,char *newstr)
{
char field_no;
field_no = match((char *)fld_str);
if (field_no)
{
strcpy((char *)SA->fd[field_no],(char *)newstr);
return(1);
}
else
return(0);
}
int FAR PASCAL _export update_index(char *oldkey,char *newkey,char ord)
{
char old[MAXKEY];
char new[MAXKEY];
strcpy((char *)&old,oldkey);
strcpy((char *)&new,newkey);
/* insert the new key */
if (s[area]->i[ord].idx)
{
s[area]->i[ord].pe->rptr = SA->crn;
strcpy((char *)s[area]->i[ord].pe->key,new);
rtrim(s[area]->i[ord].pe->key);
if (!add_key(s[area]->i[ord].pe,s[area]->i[ord].pix))
{
return(0);
}
}
else
return(0);
/* delete the old key */
if (s[area]->i[ord].idx)
{
s[area]->i[ord].pe->rptr = SA->crn;
strcpy((char *)s[area]->i[ord].pe->key,old);
rtrim(s[area]->i[ord].pe->key);
if (!delete_key(s[area]->i[ord].pe,s[area]->i[ord].pix))
{
return(0);
}
}
else
return(0);
return(1);
}
int FAR PASCAL _export save_rec(char area)
{
char i;
if (!SA->fok)
return(0);
else
write_rec(area);
for (i=1;i<max_index;i++)
if (s[area]->i[i].idx)
if (strnicmps(SA->fd[s[area]->i[i].pix->dx.order],
s[area]->i[i].pe->key)!=0)
if (update_index(s[area]->i[i].pe->key,
SA->fd[s[area]->i[i].pix->dx.order],i))
return(1);
else
return(0);
return(1);
}
int FAR PASCAL _export append_blank(char area)
{
int i;
if (add_rec(area))
{ /* go to the appended record */
s[area]->crn = (short)s[area]->hr->num_of_recs;
goto_rec(s[area]->hr->num_of_recs);
}
else
return(0);
/* if the file is indexed we need to add the keys */
for (i=1;i<max_index;i++) /* all possible indexes */
if (s[area]->i[i].idx) /* if this index area is used */
{
strcpy((char *)s[area]->i[i].pe->key,
SA->fd[s[area]->i[i].pix->dx.order]);
rtrim(s[area]->i[i].pe->key);
s[area]->i[i].pe->rptr = SA->crn;
add_key(s[area]->i[i].pe,s[area]->i[i].pix);
/* add error routine */
}
return(1);
}
char FAR PASCAL _export delete_rec(char area)
{
int i;
if (!SA->fok)
return(FALSE);
else
del_rec(area);
for (i=1;i<max_index;i++)
if (s[area]->i[i].idx)
delete_key(s[area]->i[i].pe,s[area]->i[i].pix);
}
/*
void FAR PASCAL _export copy_for(var ok : boolean; var records_copied : int;
field_num : int)
{
i : int;
temp : char *;
operator : char;
{
ok = FALSE;
temp = trim(field_data[field_num]);
operator = cp[6][1];
case operator of
'=' : if cp[6][2] = '='
{
if temp = cp[7]
ok = TRUE;
}
else
if upstr(temp) = upstr(cp[7])
ok = TRUE;
'#' : if upstr(temp) <> upstr(cp[7])
ok = TRUE;
'<' : if cp[6][2] = '='
{
if upstr(temp) <= upstr(cp[7])
ok = TRUE
}
else
if upstr(temp) < upstr(cp[7])
ok = TRUE;
'>' : if cp[6][2] = '='
{
if upstr(temp) >= upstr(cp[7])
ok = TRUE
}
else
if upstr(temp) > upstr(cp[7])
ok = TRUE;
'D' : if delete_flag <> 'D'
ok = TRUE;
else
printf('invalid operator')
};
if ok
inc(records_copied);
};
*/
int FAR PASCAL _export copyfile(char *cp[])
{
long i;
char ok;
char header_terminator;
int num_of_fields; /* for local use only */
long num_of_recs;
field_rec field;
char eof_marker;
int records_copied;
int field_num;
char * tmpname;
records_copied = 0;
ok = TRUE;
if (strnicmps(cp[2],"TO")==0)
{
/* from file would be SA->fp */
cp[3] = dbname(cp[3]); /* to file */
tmpname = cp[3];
/* select 0 is reserved for temporary files */
if ((s[0]->fp=fopen(cp[3],"wb+"))==NULL) /* create "to" file */
return(0);
fseek(SA->fp,0,0); /* reset ptr to beg of infile */
read_header(area); /* copy header to new file */
num_of_recs = SA->hr->num_of_recs;
rr = fwrite((char *)SA->hr,sizeof(header_rec),1,s[0]->fp);
/* copy field information, then add terminator byte */
num_of_fields = SA->num_of_fields;
for (i=1;i<=num_of_fields;i++)
{
rr = fread((char *)&field,sizeof(field_rec),1,SA->fp);
rr = fwrite((char *)&field,sizeof(field_rec),1,s[0]->fp);
}
rr = fread(&header_terminator,1,1,SA->fp);
rr = fwrite(&header_terminator,1,1,s[0]->fp);
/* now we decide which records to copy */
if (strnicmps(cp[5]," ")==0)
field_num = 1;
else
field_num = match(cp[5]); /*field name*/
for (i=1;i<=SA->hr->num_of_recs;i++)
{
if ((strnicmps(cp[4],"FOR")!=0) && (strnicmps(cp[4],"WHILE")!=0))
rr = fread(SA->rd,SA->hr->cpr,1,SA->fp);
else
{
read_rec(area);
/* copy_for(ok,records_copied,field_num); */
}
if (ok)
rr = fwrite(SA->rd,(SA->hr->cpr),1,s[0]->fp);
}
rr = fread(&eof_marker,1,1,SA->fp);
rr = fwrite(&eof_marker,1,1,s[0]->fp);
/* adjust the SA->hr of the to file */
if ((strnicmps(cp[4],"FOR")==0) || (strnicmps(cp[4],"WHILE")==0))
{
fseek(s[0]->fp,0,0);
SA->hr->num_of_recs = records_copied;
rr = fwrite((char *)&SA->hr,sizeof(header_rec),1,s[0]->fp);
}
SA->hr->num_of_recs = num_of_recs; /*restore infile rec count*/
close_file(0);
}
return(1);
}