home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
database
/
makendx.zip
/
MAKENDX.C
next >
Wrap
C/C++ Source or Header
|
1988-01-19
|
5KB
|
211 lines
/*
MAKENDX.C
Extracted from MAKEDBF.C AS 14-Jan-88
e.g.:
makendx p_req name+addr+city c 58
Microsoft C 5.0: cl -Zpe -Ox -W3 -Gs makendx.c
Andrew Schulman, 12 Humboldt Street, Cambridge MA 02140, (617) 876-2102
*/
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <ctype.h>
#include <stdlib.h>
#include <dos.h>
#include <fcntl.h>
#define MAXKEYLEN 256
#define FILE_EXISTS(f) (!access(f, 0x00))
#define LOCAL static
#define VOID void
typedef unsigned char BYTE;
typedef struct
{
unsigned long rootnode;
unsigned long nextnode;
unsigned long pad1;
BYTE keylen, pad2;
BYTE keypernode, pad3;
BYTE numeric, pad4;
BYTE sizekeyentry;
char pad5[5];
char expression[MAXKEYLEN];
} NDX_HEAD;
typedef struct
{
BYTE numentries;
char pad1[3];
unsigned long nextbranch; /* 0 if leaf node */
unsigned long recordnum; /* if not a branch */
} PSEUDO_NDX_NODE;
LOCAL char *ndxerror = "MAKENDX ERROR:";
LOCAL char *ndxwarn = "MAKENDX WARNING:";
LOCAL char *write_error = "write to file";
#define PASCAL pascal
LOCAL VOID PASCAL makendx(char *name, char *key, char *typ, char *len);
LOCAL VOID PASCAL ndxmissingerror(char *s);
LOCAL VOID PASCAL help(void);
LOCAL VOID PASCAL backup(char *fname);
LOCAL VOID PASCAL doserror(char *s, char *f);
main(argc, argv)
int argc;
char *argv[];
{
if (argc<3) help();
makendx(argv[1], argv[2], argv[3], argv[4]);
exit(0);
}
LOCAL VOID PASCAL makendx(name, key, typ, len)
char *name, *key, *typ, *len;
{
NDX_HEAD ndx;
PSEUDO_NDX_NODE root;
char filename[80];
unsigned int f, count;
int type;
/***** MOSTLY ERROR CHECKING *****/
if (name) {
strcpy(filename,name);
if (! strchr(filename, '.')) strcat(filename, ".NDX");
backup(filename);
}
else {
ndxmissingerror("NDX filename");
return;
}
if (!key) {
ndxmissingerror("key expression");
return;
}
type = (typ) ? toupper(*typ) : 0;
if (! type) {
ndxmissingerror("expression type");
return;
}
/* can't index on logical or memo fields */
if (type=='L'||type=='M') {
printf("** %s Can't index on %c field! **\n", ndxerror, type);
return;
}
/***** END OF ERROR CHECKING: INTO REAL WORK *****/
/***** BUT THERE'S PLENTY OF ERROR CHECKING BELOW TOO!!! *****/
/* should be done at compile-time, not run-time! */
ndx.pad1 = ndx.pad2 = ndx.pad3 = ndx.pad4 =
ndx.pad5[0]=ndx.pad5[1]=ndx.pad5[2]=ndx.pad5[3]=ndx.pad5[4] = 0;
ndx.rootnode = 1;
ndx.nextnode = 2;
if (type=='C') /* character expression */
{
ndx.numeric = 0;
/* the length of the key is NOT the length of the key expression,
* but the length of the resulting dBase value. For instance,
* the length of the key DATE()-DATE is 8. The length of the key
* SUBSTR(CHARFIELD,3,5) would be 5 -- but how can this be determined
* without including a complete dBase expression parser???
*/
if (! (len && (ndx.keylen = atoi(len)))) {
ndxmissingerror("expression length");
return;
}
if (ndx.keylen > 100) {
printf("** %s Index too big (100 char max) **\n", ndxerror);
return;
}
}
else
{
ndx.numeric = 1;
ndx.keylen = 8; /* no reason to read len */
}
ndx.sizekeyentry = ndx.keylen + 9; /* even though spec says 8 */
ndx.keypernode = 508 / ndx.sizekeyentry;
memset(ndx.expression, 0, MAXKEYLEN);
if (strlen(key) < MAXKEYLEN) strcpy(ndx.expression, key);
else /* complain or something */ ;
if (_dos_creat(filename, _A_NORMAL, &f) != 0)
doserror("create file", filename);
/* write out anchor node (includes garbage at end) */
if (_dos_write(f, (void far *)&ndx, 512, &count) != 0)
doserror(write_error, filename);
/* write out root node (includes garbage at end) */
root.numentries = 0;
root.pad1[0]=root.pad1[1]=root.pad1[2]=0;
root.nextbranch = root.recordnum = 0;
if (_dos_write(f, (void far *)&root, 512, &count) != 0)
doserror(write_error, filename);
if (_dos_close(f) != 0)
doserror("close file", filename);
printf("Index file %s created with key %s (type %c) (length %d)\n",
strupr(filename), strupr(ndx.expression), type, ndx.keylen);
}
LOCAL VOID PASCAL ndxmissingerror(s)
char *s;
{
printf("** %s Missing %s **\n", ndxerror, s);
}
LOCAL VOID PASCAL doserror(s,f)
char *s, *f;
{
extern int errno;
printf("** %s Can't %s (%s) (DOS error #%d) **\n", ndxerror, s, f, errno);
exit(1);
}
LOCAL VOID PASCAL help()
{
printf("MAKENDX 1.0 (Andrew Schulman 1988)\n");
printf("creates dBase III Plus NDX files\n");
printf("usage: MAKENDX <filename> <ndx key> <ndx type> [length]\n");
exit(1);
}
LOCAL VOID PASCAL backup(fname)
char *fname;
{
char bakname[35];
strcpy(bakname, fname);
*(strchr(bakname, '.')) = '\0';
strcat(bakname, ".NDK");
if (!FILE_EXISTS(fname)) return;
else if (FILE_EXISTS(bakname)) unlink(bakname);
if (rename(fname, bakname)) /* return 0 on success */
doserror("create backup file", bakname);
}