home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Between Heaven & Hell 2
/
BetweenHeavenHell.cdr
/
500
/
470
/
rccl006
< prev
next >
Wrap
Text File
|
1987-03-02
|
10KB
|
477 lines
/*
* DBOT Version 1.0 Author : Vincent Hayward
* School of Electrical Engineering
* Purdue University
* Dir : db
* File : dbot.c
* Remarks : All the functions of the library are there.
* Usage : make install
*/
/*LINTLIBRARY*/
#include <stdio.h>
#include <sys/types.h>
#include "../h/rccl.h"
#include "../h/umac.h"
#define BEGIN 0 /* seek options */
#define RELAT 1 /* .... */
#define ENDOF 3 /* .... */
#define RW 2 /* open ....... */
#define BUFS 1024 /* best r/w buf */
#define FREE 0 /* entry not allocated */
#define HOLE -1 /* entry removed */
#define MAGICD 0123 /* magic number data b */
#define LABS 16 /* label size */
#define MAX 85 /* 85 * sizeof(TRID) == 2040 */
typedef struct { /* transform identity */
char label[LABS]; /* name */
time_t ttime; /* birth date */
long addr; /* address */
}TRID;
typedef struct { /* internal storage represention */
float px, py, pz, ox, oy, oz, ax, ay, az;
} DBTR, *DBTR_PTR;
/*
* core image of the file header
*/
static struct head {
int magic;
int nb;
TRID table[MAX];
} hd;
char *ctime();
time_t time();
long lseek();
#define READS(f, p)\
if (read(f, (char *)&p, sizeof(p)) < 0) {\
fprintf(stderr, "read error on data base file\n");\
return(-1);}
#define WRITES(f, p)\
if (write(f, (char *)&p, sizeof(p)) < 0) {\
fprintf(stderr, "write error on data base file\n");\
return(-1);}
#define SEEK(f, a, n)\
if (lseek(f, a, n) < 0) {\
fprintf(stderr, "seek error on data base file\n");\
return(-1);}
#define ISDB(h)\
if (h .magic != MAGICD) {\
fprintf(stderr, "bad magic number\n");\
return(-1);}
/*
* creates a new data base file, which contains at least a table
* of MAX TRID records.
* All the records are initialize with a 0 creation or change time.
*
* A 'FREE' teach time means free entry in table.
* Each time an entry is added, all the addr pointers of the 'FREE'
* entries are set to the size of the file.
* When an entry is removed, a HOLE is created.
* The labels are C strings and therefore cannot contain more
* than LABS -1 chars.
*/
/*
* create an empty data base
*/
makedb(name) /*::*/
char *name;
{
int fd, i, j;
if ((fd = creat(name, 0644)) < 0) {
fprintf(stderr, "could'nt creat transform data base file\n");
return(-1);
}
if ((fd = open(name, RW)) < 0) {
fprintf(stderr, "open error on data base file");
return(-1);
}
for (i = 0; i < MAX; ++i) {
for (j = 0; j < LABS; ++j) {
hd.table[i].label[j] = '\0';
}
hd.table[i].ttime = FREE;
hd.table[i].addr = sizeof(hd);
}
hd.magic = MAGICD;
hd.nb = 0;
WRITES(fd, hd);
return(fd);
}
/*
* sequential search of the entries in the table
* return
* index in the table,
* -2 if not found,
* -1 if io error
*/
static search(n, fd) /*##*/
char *n;
int fd;
{
int i;
SEEK(fd, 0L, BEGIN);
READS(fd, hd);
ISDB(hd);
for (i = 0; i < MAX; ++i) {
if (hd.table[i].ttime == FREE || hd.table[i].ttime == HOLE) {
continue;
}
if (strncmp(n, hd.table[i].label, LABS - 1) == 0) {
return(i);
}
}
return(-2);
}
/*
* save a transform in the data base
* 1) look if exits, if yes prompts the user if can change change
* 2) tries to fill holes
* 3) extent if no hole
*
* return
* 1 if change aborted by user
* 0 if store successful
* -1 if io error
*/
savetr(t, fd) /*::*/
TRSF_PTR t;
int fd;
{
int q, i, j;
DBTR dbt;
char *m;
i = search(t->name, fd);
if (i == -1) {
fprintf(stderr, "search error\n");
return(-1);
}
if (i >= 0) {
printf("savetr : %s created : %s",
hd.table[i].label, ctime(&hd.table[i].ttime));
printf("change ? ");
QUERY(q);
if (q == 'n') {
return(1);
}
(void) time(&hd.table[i].ttime);
m = "savetr : %s changed at %s";
}
else {
q = NO;
for (i = 0; i < MAX; ++i) {
if (hd.table[i].ttime == HOLE) {
(void) time(&hd.table[i].ttime);
m = "savetr : %s Added at %s";
q = YES;
++hd.nb;
break;
}
}
if (!q) {
q = NO;
for (i = 0; i < MAX; ++i) {
if (hd.table[i].ttime == FREE) {
(void) time(&hd.table[i].ttime);
m = "savetr : %s added at %s";
q = YES;
++hd.nb;
break;
}
}
if (!q) {
fprintf(stderr, "data base file saturated\n");
return(-1);
}
for (j = 0; j < MAX; ++j) {
if (hd.table[j].ttime == FREE) {
hd.table[j].addr += sizeof(DBTR);
}
}
}
}
strcpyn(hd.table[i].label, t->name, LABS);
printf(m, hd.table[i].label, ctime(&hd.table[i].ttime));
SEEK(fd, hd.table[i].addr, BEGIN);
cnvtrdb(&dbt, t);
WRITES(fd, dbt);
SEEK(fd, 0L, BEGIN);
WRITES(fd, hd);
return(0);
}
/*
* get a transform out of the data base
*
* return
* 0 if found
* -2 if not found
* -1 if io error
*/
gettr(t, fd) /*::*/
TRSF_PTR t;
int fd;
{
int i;
DBTR dbt;
i = search(t->name, fd);
if (i == -1) {
fprintf(stderr, "search error\n");
return(-1);
}
if (i >= 0) {
SEEK(fd, hd.table[i].addr, BEGIN);
READS(fd, dbt);
cnvdbtr(t, &dbt);
printf("gettr : %s last change : %s",
hd.table[i].label, ctime(&hd.table[i].ttime));
return(0);
}
else {
printf("gettr : %s not found\n", t->name);
return(-2);
}
}
/*
* remove a transform out of the data base
*
* return
* 0 is successful
* -2 if not found
* -1 if io error
*/
remtr(n, fd) /*::*/
char *n;
int fd;
{
int i;
i = search(n, fd);
if (i == -1) {
fprintf(stderr, "search error\n");
return(-1);
}
if (i >= 0) {
hd.table[i].ttime = HOLE;
--hd.nb;
SEEK(fd, 0L, BEGIN);
WRITES(fd, hd);
printf("remtr : %s removed\n", n);
return(0);
}
else {
printf("remtr : %s not found\n", n);
return(-2);
}
}
/*
* print the content of the data base
*
* return
* 0 if ok
* -1 if io error
*/
dumpdb(fd, v) /*::*/
int fd;
bool v;
{
TRSF tr;
DBTR dbt;
int i;
SEEK(fd, 0L, BEGIN);
READS(fd, hd);
ISDB(hd);
printf("dump : %d entries\n", hd.nb);
for (i = 0; i < MAX; ++i) {
if (hd.table[i].ttime != FREE && hd.table[i].ttime != HOLE) {
printf("%d ", (hd.table[i].addr - sizeof(hd)) / sizeof(DBTR));
printf("%s , %s", hd.table[i].label, ctime(&hd.table[i].ttime));
if(v) {
SEEK(fd, hd.table[i].addr, BEGIN);
READS(fd, dbt);
cnvdbtr(&tr, &dbt);
printf("%8.3f %8.3f %8.3f %8.3f\n",
tr.n.x, tr.o.x, tr.a.x, tr.p.x);
printf("%8.3f %8.3f %8.3f %8.3f\n",
tr.n.y, tr.o.y, tr.a.y, tr.p.y);
printf("%8.3f %8.3f %8.3f %8.3f\n",
tr.n.z, tr.o.z, tr.a.z, tr.p.z);
}
}
}
return(0);
}
/*
* compact the data base in place, for that make a copy of it
*
* return
* 0 if ok
* -1 if io error
*/
static struct head hdc;
compactdb(name)
char *name;
{
char temp[40];
int fd, fdt;
char bd[BUFS];
int n;
DBTR dbt;
int i, j, inc;
char *sprintf();
if ((fd = open(name, RW)) < 0) {
fprintf(stderr, "open error on data base file %s\n", name);
return(-1);
}
(void) sprintf(temp, "%d.cdb", getpid());
if ((fdt = creat(temp, 0644)) < 0) {
fprintf(stderr, "can't creat data base file %s\n", temp);
return(-1);
}
if ((fdt = open(temp, RW)) < 0) {
fprintf(stderr, "open error on data base file %s\n", temp);
return(-1);
}
SEEK(fd, 0L, BEGIN);
while ((n = read(fd, bd, BUFS)) > 0) {
if (write(fdt, bd, n) < 0) {
fprintf(stderr, "can't duplicate data base file\n");
return(-1);
}
}
fd = makedb(name);
SEEK(fdt, 0L, BEGIN);
READS(fdt, hdc);
j = 0;
inc = 0;
for (i = 0; i < MAX; ++i) {
if (hdc.table[i].ttime != HOLE && hdc.table[i].ttime != FREE) {
SEEK(fdt, hdc.table[i].addr, BEGIN);
READS(fdt, dbt);
WRITES(fd, dbt);
hd.table[j].addr += inc;
inc += sizeof(DBTR);
hd.table[j].ttime = hdc.table[i].ttime;
strcpyn(hd.table[j].label, hdc.table[i].label, LABS);
++hd.nb;
++j;
}
}
for (;j < MAX; ++j) {
hd.table[j].addr += inc;
}
SEEK(fd, 0L, BEGIN);
WRITES(fd, hd);
if (unlink(temp) < 0) {
fprintf(stderr, "could'nt unlink\n");
return(-1);
}
return(0);
}
/*
* convert a regular transform into data base format
*/
static cnvtrdb(d, t) /*##*/
DBTR_PTR d;
TRSF_PTR t;
{
d->px = t->p.x;
d->py = t->p.y;
d->pz = t->p.z;
d->ax = t->a.x;
d->ay = t->a.y;
d->az = t->a.z;
d->ox = t->o.x;
d->oy = t->o.y;
d->oz = t->o.z;
}
/*
* convert a data base format transform into regular
*/
static cnvdbtr(t, d) /*##*/
DBTR_PTR d;
TRSF_PTR t;
{
t->p.x = d->px;
t->p.y = d->py;
t->p.z = d->pz;
t->a.x = d->ax;
t->a.y = d->ay;
t->a.z = d->az;
t->o.x = d->ox;
t->o.y = d->oy;
t->o.z = d->oz;
t->n.x = t->o.y * t->a.z - t->o.z * t->a.y;
t->n.y = t->o.z * t->a.x - t->o.x * t->a.z;
t->n.z = t->o.x * t->a.y - t->o.y * t->a.x;
}
/*
* copy n chars of a string
*/
static strcpyn(s1, s2, n) /*##*/
char *s1, *s2;
int n;
{
while (*s1++ = *s2++) {
if (--n == 0) {
*--s1 = '\0';
return;
}
}
}