home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
online
/
source
/
c
/
compilers
/
Tickle-4.0.sit.hqx
/
Tickle-4.0
/
src
/
tcl-cbtree.c
< prev
next >
Wrap
Text File
|
1993-11-19
|
10KB
|
501 lines
/*
** This source code was written by Tim Endres
** Email: time@ice.com.
** USMail: 8840 Main Street, Whitmore Lake, MI 48189
**
** Some portions of this application utilize sources
** that are copyrighted by ICE Engineering, Inc., and
** ICE Engineering retains all rights to those sources.
**
** Neither ICE Engineering, Inc., nor Tim Endres,
** warrants this source code for any reason, and neither
** party assumes any responsbility for the use of these
** sources, libraries, or applications. The user of these
** sources and binaries assumes all responsbilities for
** any resulting consequences.
*/
#pragma segment TCLCBTREE
#include "tickle.h"
#include "tcl.h"
#include "cdefs.h"
#include "db.h"
#include "btree.h"
extern int errno;
extern int macintoshErr;
typedef struct {
DB *db;
char name[32];
} CBTREE_NAMED_DB;
#define MAX_DBS 8
static int _max_dbs_ = 0;
static CBTREE_NAMED_DB *_dbs_ = NULL;
init_tcl_cbtree()
{
int i;
_dbs_ = (CBTREE_NAMED_DB *) malloc(sizeof(CBTREE_NAMED_DB) * MAX_DBS);
if (_dbs_ == NULL)
_max_dbs_ = 0;
else
_max_dbs_ = MAX_DBS;
for (i=0; i<_max_dbs_; ++i)
{
_dbs_[i].db = (DB *)0;
_dbs_[i].name[0] = '\0';
}
}
close_tcl_cbtree()
{
int i;
for (i=0; i<_max_dbs_; ++i)
{
if (_dbs_[i].db != (DB *)0)
(* _dbs_[i].db->close)(_dbs_[i].db);
}
}
int
tcl_btree_cmp(p1, p2)
char *p1, *p2;
{
/*fprintf(stderr, "my_btree_cmp: p1 x%lx '%s' p2 x%lx '%s'\n", p1, p1, p2, p2);*/
return strcmp(p1, p2);
}
int
Cmd_CBTOpen(clientData, interp, argc, argv)
char *clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
short wdRefNum;
int index, push_err, myerr;
#pragma unused (clientData)
if (argc != 3)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" dbName dbFileName\"", (char *) NULL);
return TCL_ERROR;
}
for (index = 0 ; index < _max_dbs_ ; ++index)
{
if (_dbs_[index].db == NULL)
break;
if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" duplicate DB name '",
argv[1], "'", (char *) NULL);
return TCL_ERROR;
}
}
if (index >= _max_dbs_)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" max DB's open", (char *) NULL);
return TCL_ERROR;
}
else
{
BTREEINFO openinfo;
myerr = TclMac_CWDCreateWD(&wdRefNum);
if (myerr != noErr)
{
Tcl_AppendResult(interp, "could not create working directory - ",
Tcl_MacGetError(interp, myerr), NULL);
return TCL_ERROR;
}
push_err = TclMac_CWDPushVol();
openinfo.flags = R_DUP;
openinfo.cachesize = 0;
openinfo.compare = tcl_btree_cmp; /* use strcmp() */
openinfo.lorder = BIG_ENDIAN;
openinfo.psize = 4096;
SetVol(NULL, wdRefNum);
_dbs_[index].db = btree_open(argv[2], O_RDWR | O_CREAT, 0666, &openinfo);
if (push_err == noErr)
TclMac_CWDPopVol();
TclMac_CWDDisposeWD(wdRefNum);
if (_dbs_[index].db == (DB *)0)
{
strcpy(_dbs_[index].name, "--CLOSED--");
Tcl_AppendResult(interp, "\"", argv[0], "\" error opening DB", (char *) NULL);
return TCL_ERROR;
}
else
{
strcpy(_dbs_[index].name, argv[1]);
return TCL_OK;
}
}
}
int
Cmd_CBTInsert(clientData, interp, argc, argv)
char *clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int index, result;
DBT key,
data;
#pragma unused (clientData)
if (argc != 4 && argc != 5)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" dbName key data ?replace?\"", (char *) NULL);
return TCL_ERROR;
}
for (index = 0 ; index < _max_dbs_ ; ++index)
{
if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
break;
}
if (index >= _max_dbs_)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" DB \"",
argv[1], "\" not found", (char *) NULL);
return TCL_ERROR;
}
else
{
key.data = argv[2];
key.size = strlen(argv[2]) + 1;
data.data = argv[3];
data.size = strlen(argv[3]) + 1;
result = (* _dbs_[index].db->put) ( _dbs_[index].db, &key, &data,
(argc == 4 ? R_PUT : R_NOOVERWRITE) );
if (result < 0)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" error storing data", (char *) NULL);
return TCL_ERROR;
}
else if (result > 0)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" key already exists", (char *) NULL);
return TCL_ERROR;
}
else
{
return TCL_OK;
}
}
}
int
Cmd_CBTGetKey(clientData, interp, argc, argv)
char *clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int index, result;
DBT key,
data;
#pragma unused (clientData)
if (argc != 3 && argc != 4)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" dbName key ?varName?\"", (char *) NULL);
return TCL_ERROR;
}
for (index = 0 ; index < _max_dbs_ ; ++index)
{
if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
break;
}
if (index >= _max_dbs_)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" DB \"",
argv[1], "\" not found", (char *) NULL);
return TCL_ERROR;
}
else
{
key.data = argv[2];
key.size = strlen(argv[2]) + 1;
result = (* _dbs_[index].db->get) ( _dbs_[index].db, &key, &data, 0 );
if (result < 0)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" key \"", argv[2],
"\" DB error", (char *) NULL);
return TCL_ERROR;
}
if (result > 0)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" key \"", argv[2],
"\" not found", (char *) NULL);
return TCL_ERROR;
}
else
{
if (argc == 4)
Tcl_SetVar(interp, argv[3], data.data, 0);
else
Tcl_AppendResult(interp, data.data, (char *) NULL);
return TCL_OK;
}
}
}
int
Cmd_CBTDelete(clientData, interp, argc, argv)
char *clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int index, result;
DBT key;
#pragma unused (clientData)
if (argc != 3)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" dbName key\"", (char *) NULL);
return TCL_ERROR;
}
for (index = 0 ; index < _max_dbs_ ; ++index)
{
if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
break;
}
if (index >= _max_dbs_)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" DB \"",
argv[1], "\" not found", (char *) NULL);
return TCL_ERROR;
}
else
{
key.data = argv[2];
key.size = strlen(argv[2]) + 1;
result = (* _dbs_[index].db->del) ( _dbs_[index].db, &key, 0);
if (result < 0)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" key \"", argv[2],
"\" DB error", (char *) NULL);
return TCL_ERROR;
}
if (result > 0)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" key \"", argv[2],
"\" not found", (char *) NULL);
return TCL_ERROR;
}
else
{
return TCL_OK;
}
}
}
int
Cmd_CBTSeq(clientData, interp, argc, argv)
char *clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int index, result;
DBT key, data;
char *dvarname;
char *kvarname;
unsigned long flags;
#pragma unused (clientData)
if (argc < 3 || argc > 6)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" dbName FIRST|LAST|NEXT|PREV|[SEEK key] ?kVarName? ?dVarName?\"", (char *) NULL);
return TCL_ERROR;
}
for (index = 0 ; index < _max_dbs_ ; ++index)
{
if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
break;
}
if (index >= _max_dbs_)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" DB \"",
argv[1], "\" not found", (char *) NULL);
return TCL_ERROR;
}
else
{
dvarname = NULL;
kvarname = NULL;
key.data = "";
key.size = 0;
if (strcmp(argv[2], "FIRST") == 0)
{
if (argc >= 4)
kvarname = argv[3];
if (argc >= 5)
dvarname = argv[4];
flags = R_FIRST;
}
else if (strcmp(argv[2], "LAST") == 0)
{
if (argc >= 4)
kvarname = argv[3];
if (argc >= 5)
dvarname = argv[4];
flags = R_LAST;
}
else if (strcmp(argv[2], "NEXT") == 0)
{
if (argc >= 4)
kvarname = argv[3];
if (argc >= 5)
dvarname = argv[4];
flags = R_NEXT;
}
else if (strcmp(argv[2], "PREV") == 0)
{
if (argc >= 4)
kvarname = argv[3];
if (argc >= 5)
dvarname = argv[4];
flags = R_PREV;
}
else if (strcmp(argv[2], "SEEK") == 0)
{
key.data = argv[3];
key.size = strlen(argv[3]) + 1;
if (argc >= 5)
kvarname = argv[4];
if (argc >= 6)
dvarname = argv[5];
flags = R_CURSOR;
}
result = (* _dbs_[index].db->seq) (_dbs_[index].db, &key, &data, flags);
if (result < 0)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" DB error", (char *) NULL);
return TCL_ERROR;
}
else if (result > 0)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" no more keys", (char *) NULL);
return TCL_ERROR;
}
else
{
if (kvarname != NULL)
Tcl_SetVar(interp, kvarname, key.data, 0);
else
Tcl_AppendResult(interp, "{", key.data, "}", (char *) NULL);
if (dvarname != NULL)
Tcl_SetVar(interp, dvarname, data.data, 0);
else
Tcl_AppendResult(interp, (kvarname != NULL ? "{" : " {"),
data.data, "}", (char *) NULL);
return TCL_OK;
}
}
}
int
Cmd_CBTClose(clientData, interp, argc, argv)
char *clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int index, result;
#pragma unused (clientData)
if (argc != 2)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" dbName\"", (char *) NULL);
return TCL_ERROR;
}
for (index = 0 ; index < _max_dbs_ ; ++index)
{
if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
break;
}
if (index >= _max_dbs_)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" DB \"",
argv[1], "\" not found", (char *) NULL);
return TCL_ERROR;
}
else
{
result = (* _dbs_[index].db->close) (_dbs_[index].db);
free(_dbs_[index].db);
_dbs_[index].db = (DB *)0;
strcpy(_dbs_[index].name, "--CLOSED--");
return TCL_OK;
}
}
Tcl_InitCBTREE(interp)
Tcl_Interp *interp;
{
Tcl_CreateCommand(interp, "cbt_open", Cmd_CBTOpen,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "cbt_close", Cmd_CBTClose,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "cbt_insert", Cmd_CBTInsert,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "cbt_getkey", Cmd_CBTGetKey,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "cbt_delete", Cmd_CBTDelete,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "cbt_seq", Cmd_CBTSeq,
(ClientData)NULL, (void (*)())NULL);
}