gecko-dev/db/test/tcl_ndbm.c
1998-10-15 03:56:37 +00:00

245 lines
6.1 KiB
C

/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996, 1997, 1998
* Sleepycat Software. All rights reserved.
*/
#include "config.h"
#ifndef lint
static const char sccsid[] = "@(#)tcl_ndbm.c 10.12 (Sleepycat) 4/27/98";
#endif /* not lint */
/*
* This file is divided up into 2 sets of functions:
* 1. The ndbmopen command and its support functions.
* 2. The ndbmwidget commands.
*/
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#endif
#include <tcl.h>
#define DB_DBM_HSEARCH 1
#include "db_int.h"
#include "dbtest.h"
#include "test_ext.h"
/*
* ndbmopen_cmd --
* Implements dbm_open (the ndbm interface) for dbtest. ndbm_open
* creates a widget that implements all the commands found off in the
* historical ndbm interface.
*/
#define NDBMOPEN_USAGE "ndbm_open file flags mode"
int
ndbmopen_cmd(notused, interp, argc, argv)
ClientData notused;
Tcl_Interp *interp;
int argc;
char *argv[];
{
static int db_number = 0;
DBM *dbm;
u_int32_t flags;
int mode, oflags, tclint;
char dbname[50], *name;
notused = NULL;
/* Check number of arguments. */
USAGE_GE(argc, 4, NDBMOPEN_USAGE, 0);
name = strcmp(argv[1], "NULL") == 0 ? NULL : argv[1];
debug_check();
/* Check flags and mode. */
if (Tcl_GetInt(interp, argv[2], &tclint) != TCL_OK)
goto usage;
flags = (u_int32_t)tclint;
if (Tcl_GetInt(interp, argv[3], &mode) != TCL_OK) {
usage: Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "\nUsage: ", NDBMOPEN_USAGE, NULL);
return (TCL_OK);
}
oflags = 0;
if (flags & DB_RDONLY)
oflags |= O_RDONLY;
else
oflags |= O_RDWR;
if (flags & DB_CREATE)
oflags |= O_CREAT;
if (flags & DB_TRUNCATE)
oflags |= O_TRUNC;
/* Call dbm_open. */
if ((dbm = dbm_open(name, oflags, mode)) == NULL) {
Tcl_SetResult(interp, "ndbm_open: ", TCL_STATIC);
Tcl_AppendResult(interp, Tcl_PosixError(interp), NULL);
return (TCL_OK);
}
/* Create widget command. */
/* Create new command name. */
sprintf(&dbname[0], "ndbm%d", db_number);
db_number++;
Tcl_CreateCommand(interp, dbname, ndbmwidget_cmd,
(ClientData)dbm, NULL);
Tcl_SetResult(interp, dbname, TCL_VOLATILE);
return (TCL_OK);
}
/*
* ndbmwidget --
* Since ndbm_open creates a widget, we need a command that then
* handles all the widget commands. This is that command. If we
* ever add new "methods" we add new widget commands here.
*/
#define NDBMWIDGET_USAGE "ndbmN option ?arg arg ...?"
#define NDBMCLEAR_USAGE "ndbmN clearerr"
#define NDBMCLOSE_USAGE "ndbmN close"
#define NDBMDEL_USAGE "ndbmN delete key"
#define NDBMDIRFNO_USAGE "ndbmM dirfno"
#define NDBMERROR_USAGE "ndbmN error"
#define NDBMFETCH_USAGE "ndbmN fetch key"
#define NDBMFIRST_USAGE "ndbmN firstkey"
#define NDBMNEXT_USAGE "ndbmN nextkey"
#define NDBMPAGFNO_USAGE "ndbmM pagfno"
#define NDBMRDONLY_USAGE "ndbmM rdonly"
#define NDBMSTORE_USAGE "ndbmN store key datum flags"
int
ndbmwidget_cmd(cd_dbm, interp, argc, argv)
ClientData cd_dbm;
Tcl_Interp *interp;
int argc;
char *argv[];
{
DBM *dbm;
datum data, key;
int flags, ret;
char *cmd, fdval[16];
COMPQUIET(cmd, NULL);
USAGE_GE(argc, 2, NDBMWIDGET_USAGE, 0);
Tcl_SetResult(interp, "0", TCL_STATIC);
dbm = (DBM *)cd_dbm;
if (strcmp(argv[1], "clearerr") == 0) {
USAGE(argc, 2, NDBMCLEAR_USAGE, 0);
debug_check();
ret = dbm_clearerr(dbm);
cmd = "dbm_clearerr:";
} else if (strcmp(argv[1], "close") == 0) {
USAGE(argc, 2, NDBMCLOSE_USAGE, 0);
debug_check();
dbm_close(dbm);
(void)Tcl_DeleteCommand(interp, argv[0]);
ret = 0;
} else if (strcmp(argv[1], "delete") == 0) {
USAGE(argc, 3, NDBMDEL_USAGE, 0);
key.dptr = argv[2];
key.dsize = strlen(argv[2]) + 1;
debug_check();
ret = dbm_delete(dbm, key);
cmd = "dbm_delete:";
} else if (strcmp(argv[1], "dirfno") == 0) {
USAGE(argc, 2, NDBMDIRFNO_USAGE, 0);
ret = dbm_dirfno(dbm);
sprintf(fdval, "%d", ret);
Tcl_SetResult(interp, fdval, TCL_VOLATILE);
return (TCL_OK);
} else if (strcmp(argv[1], "error") == 0) {
USAGE(argc, 2, NDBMERROR_USAGE, 0);
debug_check();
errno = dbm_error(dbm);
Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_STATIC);
return (TCL_OK);
} else if (strcmp(argv[1], "fetch") == 0) {
USAGE(argc, 3, NDBMFETCH_USAGE, 0);
key.dptr = argv[2];
key.dsize = strlen(argv[2]) + 1;
debug_check();
data = dbm_fetch(dbm, key);
if (data.dptr == NULL)
Tcl_SetResult(interp, "-1", TCL_STATIC);
else
Tcl_SetResult(interp, data.dptr, TCL_VOLATILE);
return (TCL_OK);
} else if (strcmp(argv[1], "firstkey") == 0) {
USAGE(argc, 2, NDBMFIRST_USAGE, 0);
debug_check();
key = dbm_firstkey(dbm);
if (key.dptr == NULL)
Tcl_SetResult(interp, "-1", TCL_STATIC);
else
Tcl_SetResult(interp, key.dptr, TCL_VOLATILE);
return (TCL_OK);
} else if (strcmp(argv[1], "nextkey") == 0) {
USAGE(argc, 2, NDBMNEXT_USAGE, 0);
debug_check();
data = dbm_nextkey(dbm);
if (data.dptr == NULL)
Tcl_SetResult(interp, "-1", TCL_STATIC);
else
Tcl_SetResult(interp, data.dptr, TCL_VOLATILE);
return (TCL_OK);
} else if (strcmp(argv[1], "pagfno") == 0) {
USAGE(argc, 2, NDBMPAGFNO_USAGE, 0);
ret = dbm_pagfno(dbm);
sprintf(fdval, "%d", ret);
Tcl_SetResult(interp, fdval, TCL_VOLATILE);
return (TCL_OK);
} else if (strcmp(argv[1], "rdonly") == 0) {
USAGE(argc, 2, NDBMRDONLY_USAGE, 0);
if (dbm_rdonly(dbm))
Tcl_SetResult(interp, "1", TCL_STATIC);
else
Tcl_SetResult(interp, "0", TCL_STATIC);
return (TCL_OK);
} else if (strcmp(argv[1], "store") == 0) {
USAGE(argc, 5, NDBMSTORE_USAGE, 0);
if (Tcl_GetInt(interp, argv[4], &flags) != TCL_OK)
return (TCL_ERROR);
key.dptr = argv[2];
key.dsize = strlen(argv[2]) + 1;
data.dptr = argv[3];
data.dsize = strlen(argv[3]) + 1;
debug_check();
ret = dbm_store(dbm, key, data, flags);
cmd = "dbm_store:";
} else {
Tcl_SetResult(interp, NDBMWIDGET_USAGE, TCL_STATIC);
return (TCL_ERROR);
}
if (ret == 0)
Tcl_SetResult(interp, "0", TCL_STATIC);
else if (ret > 0)
Tcl_SetResult(interp, "Not found", TCL_STATIC);
else {
Tcl_SetResult(interp, cmd, TCL_STATIC);
Tcl_AppendResult(interp, Tcl_PosixError(interp), 0);
}
return (TCL_OK);
}