tcl_compat.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:16k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1999-2001
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: tcl_compat.c,v 11.39 2002/08/15 14:05:38 bostic Exp $";
  10. #endif /* not lint */
  11. #if CONFIG_TEST
  12. #ifndef NO_SYSTEM_INCLUDES
  13. #include <sys/types.h>
  14. #include <fcntl.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <tcl.h>
  18. #endif
  19. #define DB_DBM_HSEARCH 1
  20. #include "db_int.h"
  21. #include "dbinc/tcl_db.h"
  22. /*
  23.  * bdb_HCommand --
  24.  * Implements h* functions.
  25.  *
  26.  * PUBLIC: int bdb_HCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
  27.  */
  28. int
  29. bdb_HCommand(interp, objc, objv)
  30. Tcl_Interp *interp; /* Interpreter */
  31. int objc; /* How many arguments? */
  32. Tcl_Obj *CONST objv[]; /* The argument objects */
  33. {
  34. static char *hcmds[] = {
  35. "hcreate",
  36. "hdestroy",
  37. "hsearch",
  38. NULL
  39. };
  40. enum hcmds {
  41. HHCREATE,
  42. HHDESTROY,
  43. HHSEARCH
  44. };
  45. static char *srchacts[] = {
  46. "enter",
  47. "find",
  48. NULL
  49. };
  50. enum srchacts {
  51. ACT_ENTER,
  52. ACT_FIND
  53. };
  54. ENTRY item, *hres;
  55. ACTION action;
  56. int actindex, cmdindex, nelem, result, ret;
  57. Tcl_Obj *res;
  58. result = TCL_OK;
  59. /*
  60.  * Get the command name index from the object based on the cmds
  61.  * defined above.  This SHOULD NOT fail because we already checked
  62.  * in the 'berkdb' command.
  63.  */
  64. if (Tcl_GetIndexFromObj(interp,
  65.     objv[1], hcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
  66. return (IS_HELP(objv[1]));
  67. res = NULL;
  68. switch ((enum hcmds)cmdindex) {
  69. case HHCREATE:
  70. /*
  71.  * Must be 1 arg, nelem.  Error if not.
  72.  */
  73. if (objc != 3) {
  74. Tcl_WrongNumArgs(interp, 2, objv, "nelem");
  75. return (TCL_ERROR);
  76. }
  77. result = Tcl_GetIntFromObj(interp, objv[2], &nelem);
  78. if (result == TCL_OK) {
  79. _debug_check();
  80. ret = hcreate(nelem) == 0 ? 1: 0;
  81. _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "hcreate");
  82. }
  83. break;
  84. case HHSEARCH:
  85. /*
  86.  * 3 args for this.  Error if different.
  87.  */
  88. if (objc != 5) {
  89. Tcl_WrongNumArgs(interp, 2, objv, "key data action");
  90. return (TCL_ERROR);
  91. }
  92. item.key = Tcl_GetStringFromObj(objv[2], NULL);
  93. item.data = Tcl_GetStringFromObj(objv[3], NULL);
  94. if (Tcl_GetIndexFromObj(interp, objv[4], srchacts,
  95.     "action", TCL_EXACT, &actindex) != TCL_OK)
  96. return (IS_HELP(objv[4]));
  97. switch ((enum srchacts)actindex) {
  98. case ACT_ENTER:
  99. action = ENTER;
  100. break;
  101. default:
  102. case ACT_FIND:
  103. action = FIND;
  104. break;
  105. }
  106. _debug_check();
  107. hres = hsearch(item, action);
  108. if (hres == NULL)
  109. Tcl_SetResult(interp, "-1", TCL_STATIC);
  110. else if (action == FIND)
  111. Tcl_SetResult(interp, (char *)hres->data, TCL_STATIC);
  112. else
  113. /* action is ENTER */
  114. Tcl_SetResult(interp, "0", TCL_STATIC);
  115. break;
  116. case HHDESTROY:
  117. /*
  118.  * No args for this.  Error if there are some.
  119.  */
  120. if (objc != 2) {
  121. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  122. return (TCL_ERROR);
  123. }
  124. _debug_check();
  125. (void)hdestroy();
  126. res = Tcl_NewIntObj(0);
  127. break;
  128. }
  129. /*
  130.  * Only set result if we have a res.  Otherwise, lower
  131.  * functions have already done so.
  132.  */
  133. if (result == TCL_OK && res)
  134. Tcl_SetObjResult(interp, res);
  135. return (result);
  136. }
  137. /*
  138.  *
  139.  * bdb_NdbmOpen --
  140.  * Opens an ndbm database.
  141.  *
  142.  * PUBLIC: #if DB_DBM_HSEARCH != 0
  143.  * PUBLIC: int bdb_NdbmOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBM **));
  144.  * PUBLIC: #endif
  145.  */
  146. int
  147. bdb_NdbmOpen(interp, objc, objv, dbpp)
  148. Tcl_Interp *interp; /* Interpreter */
  149. int objc; /* How many arguments? */
  150. Tcl_Obj *CONST objv[]; /* The argument objects */
  151. DBM **dbpp; /* Dbm pointer */
  152. {
  153. static char *ndbopen[] = {
  154. "-create",
  155. "-mode",
  156. "-rdonly",
  157. "-truncate",
  158. "--",
  159. NULL
  160. };
  161. enum ndbopen {
  162. NDB_CREATE,
  163. NDB_MODE,
  164. NDB_RDONLY,
  165. NDB_TRUNC,
  166. NDB_ENDARG
  167. };
  168. u_int32_t open_flags;
  169. int endarg, i, mode, optindex, read_only, result, ret;
  170. char *arg, *db;
  171. result = TCL_OK;
  172. open_flags = 0;
  173. endarg = mode = 0;
  174. read_only = 0;
  175. if (objc < 2) {
  176. Tcl_WrongNumArgs(interp, 2, objv, "?args?");
  177. return (TCL_ERROR);
  178. }
  179. /*
  180.  * Get the option name index from the object based on the args
  181.  * defined above.
  182.  */
  183. i = 2;
  184. while (i < objc) {
  185. if (Tcl_GetIndexFromObj(interp, objv[i], ndbopen, "option",
  186.     TCL_EXACT, &optindex) != TCL_OK) {
  187. arg = Tcl_GetStringFromObj(objv[i], NULL);
  188. if (arg[0] == '-') {
  189. result = IS_HELP(objv[i]);
  190. goto error;
  191. } else
  192. Tcl_ResetResult(interp);
  193. break;
  194. }
  195. i++;
  196. switch ((enum ndbopen)optindex) {
  197. case NDB_CREATE:
  198. open_flags |= O_CREAT;
  199. break;
  200. case NDB_RDONLY:
  201. read_only = 1;
  202. break;
  203. case NDB_TRUNC:
  204. open_flags |= O_TRUNC;
  205. break;
  206. case NDB_MODE:
  207. if (i >= objc) {
  208. Tcl_WrongNumArgs(interp, 2, objv,
  209.     "?-mode mode?");
  210. result = TCL_ERROR;
  211. break;
  212. }
  213. /*
  214.  * Don't need to check result here because
  215.  * if TCL_ERROR, the error message is already
  216.  * set up, and we'll bail out below.  If ok,
  217.  * the mode is set and we go on.
  218.  */
  219. result = Tcl_GetIntFromObj(interp, objv[i++], &mode);
  220. break;
  221. case NDB_ENDARG:
  222. endarg = 1;
  223. break;
  224. } /* switch */
  225. /*
  226.  * If, at any time, parsing the args we get an error,
  227.  * bail out and return.
  228.  */
  229. if (result != TCL_OK)
  230. goto error;
  231. if (endarg)
  232. break;
  233. }
  234. if (result != TCL_OK)
  235. goto error;
  236. /*
  237.  * Any args we have left, (better be 0, or 1 left) is a
  238.  * file name.  If we have 0, then an in-memory db.  If
  239.  * there is 1, a db name.
  240.  */
  241. db = NULL;
  242. if (i != objc && i != objc - 1) {
  243. Tcl_WrongNumArgs(interp, 2, objv, "?args? ?file?");
  244. result = TCL_ERROR;
  245. goto error;
  246. }
  247. if (i != objc)
  248. db = Tcl_GetStringFromObj(objv[objc - 1], NULL);
  249. /*
  250.  * When we get here, we have already parsed all of our args
  251.  * and made all our calls to set up the database.  Everything
  252.  * is okay so far, no errors, if we get here.
  253.  *
  254.  * Now open the database.
  255.  */
  256. if (read_only)
  257. open_flags |= O_RDONLY;
  258. else
  259. open_flags |= O_RDWR;
  260. _debug_check();
  261. if ((*dbpp = dbm_open(db, open_flags, mode)) == NULL) {
  262. ret = Tcl_GetErrno();
  263. result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
  264.     "db open");
  265. goto error;
  266. }
  267. return (TCL_OK);
  268. error:
  269. *dbpp = NULL;
  270. return (result);
  271. }
  272. /*
  273.  * bdb_DbmCommand --
  274.  * Implements "dbm" commands.
  275.  *
  276.  * PUBLIC: #if DB_DBM_HSEARCH != 0
  277.  * PUBLIC: int bdb_DbmCommand
  278.  * PUBLIC:     __P((Tcl_Interp *, int, Tcl_Obj * CONST*, int, DBM *));
  279.  * PUBLIC: #endif
  280.  */
  281. int
  282. bdb_DbmCommand(interp, objc, objv, flag, dbm)
  283. Tcl_Interp *interp; /* Interpreter */
  284. int objc; /* How many arguments? */
  285. Tcl_Obj *CONST objv[]; /* The argument objects */
  286. int flag; /* Which db interface */
  287. DBM *dbm; /* DBM pointer */
  288. {
  289. static char *dbmcmds[] = {
  290. "dbmclose",
  291. "dbminit",
  292. "delete",
  293. "fetch",
  294. "firstkey",
  295. "nextkey",
  296. "store",
  297. NULL
  298. };
  299. enum dbmcmds {
  300. DBMCLOSE,
  301. DBMINIT,
  302. DBMDELETE,
  303. DBMFETCH,
  304. DBMFIRST,
  305. DBMNEXT,
  306. DBMSTORE
  307. };
  308. static char *stflag[] = {
  309. "insert", "replace",
  310. NULL
  311. };
  312. enum stflag {
  313. STINSERT, STREPLACE
  314. };
  315. datum key, data;
  316. void *dtmp, *ktmp;
  317. u_int32_t size;
  318. int cmdindex, freedata, freekey, stindex, result, ret;
  319. char *name, *t;
  320. result = TCL_OK;
  321. freekey = freedata = 0;
  322. /*
  323.  * Get the command name index from the object based on the cmds
  324.  * defined above.  This SHOULD NOT fail because we already checked
  325.  * in the 'berkdb' command.
  326.  */
  327. if (Tcl_GetIndexFromObj(interp,
  328.     objv[1], dbmcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
  329. return (IS_HELP(objv[1]));
  330. switch ((enum dbmcmds)cmdindex) {
  331. case DBMCLOSE:
  332. /*
  333.  * No arg for this.  Error if different.
  334.  */
  335. if (objc != 2) {
  336. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  337. return (TCL_ERROR);
  338. }
  339. _debug_check();
  340. if (flag == DBTCL_DBM)
  341. ret = dbmclose();
  342. else {
  343. Tcl_SetResult(interp,
  344.     "Bad interface flag for command", TCL_STATIC);
  345. return (TCL_ERROR);
  346. }
  347. _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "dbmclose");
  348. break;
  349. case DBMINIT:
  350. /*
  351.  * Must be 1 arg - file.
  352.  */
  353. if (objc != 3) {
  354. Tcl_WrongNumArgs(interp, 2, objv, "file");
  355. return (TCL_ERROR);
  356. }
  357. name = Tcl_GetStringFromObj(objv[2], NULL);
  358. if (flag == DBTCL_DBM)
  359. ret = dbminit(name);
  360. else {
  361. Tcl_SetResult(interp, "Bad interface flag for command",
  362.     TCL_STATIC);
  363. return (TCL_ERROR);
  364. }
  365. _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "dbminit");
  366. break;
  367. case DBMFETCH:
  368. /*
  369.  * 1 arg for this.  Error if different.
  370.  */
  371. if (objc != 3) {
  372. Tcl_WrongNumArgs(interp, 2, objv, "key");
  373. return (TCL_ERROR);
  374. }
  375. if ((ret = _CopyObjBytes(
  376.     interp, objv[2], &ktmp, &size, &freekey)) != 0) {
  377. result = _ReturnSetup(interp, ret,
  378.     DB_RETOK_STD(ret), "dbm fetch");
  379. goto out;
  380. }
  381. key.dsize = size;
  382. key.dptr = (char *)ktmp;
  383. _debug_check();
  384. if (flag == DBTCL_DBM)
  385. data = fetch(key);
  386. else if (flag == DBTCL_NDBM)
  387. data = dbm_fetch(dbm, key);
  388. else {
  389. Tcl_SetResult(interp,
  390.     "Bad interface flag for command", TCL_STATIC);
  391. result = TCL_ERROR;
  392. goto out;
  393. }
  394. if (data.dptr == NULL ||
  395.     (ret = __os_malloc(NULL, data.dsize + 1, &t)) != 0)
  396. Tcl_SetResult(interp, "-1", TCL_STATIC);
  397. else {
  398. memcpy(t, data.dptr, data.dsize);
  399. t[data.dsize] = '';
  400. Tcl_SetResult(interp, t, TCL_VOLATILE);
  401. __os_free(NULL, t);
  402. }
  403. break;
  404. case DBMSTORE:
  405. /*
  406.  * 2 args for this.  Error if different.
  407.  */
  408. if (objc != 4 && flag == DBTCL_DBM) {
  409. Tcl_WrongNumArgs(interp, 2, objv, "key data");
  410. return (TCL_ERROR);
  411. }
  412. if (objc != 5 && flag == DBTCL_NDBM) {
  413. Tcl_WrongNumArgs(interp, 2, objv, "key data action");
  414. return (TCL_ERROR);
  415. }
  416. if ((ret = _CopyObjBytes(
  417.     interp, objv[2], &ktmp, &size, &freekey)) != 0) {
  418. result = _ReturnSetup(interp, ret,
  419.     DB_RETOK_STD(ret), "dbm fetch");
  420. goto out;
  421. }
  422. key.dsize = size;
  423. key.dptr = (char *)ktmp;
  424. if ((ret = _CopyObjBytes(
  425.     interp, objv[3], &dtmp, &size, &freedata)) != 0) {
  426. result = _ReturnSetup(interp, ret,
  427.     DB_RETOK_STD(ret), "dbm fetch");
  428. goto out;
  429. }
  430. data.dsize = size;
  431. data.dptr = (char *)dtmp;
  432. _debug_check();
  433. if (flag == DBTCL_DBM)
  434. ret = store(key, data);
  435. else if (flag == DBTCL_NDBM) {
  436. if (Tcl_GetIndexFromObj(interp, objv[4], stflag,
  437.     "flag", TCL_EXACT, &stindex) != TCL_OK)
  438. return (IS_HELP(objv[4]));
  439. switch ((enum stflag)stindex) {
  440. case STINSERT:
  441. flag = DBM_INSERT;
  442. break;
  443. case STREPLACE:
  444. flag = DBM_REPLACE;
  445. break;
  446. }
  447. ret = dbm_store(dbm, key, data, flag);
  448. } else {
  449. Tcl_SetResult(interp,
  450.     "Bad interface flag for command", TCL_STATIC);
  451. return (TCL_ERROR);
  452. }
  453. _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "store");
  454. break;
  455. case DBMDELETE:
  456. /*
  457.  * 1 arg for this.  Error if different.
  458.  */
  459. if (objc != 3) {
  460. Tcl_WrongNumArgs(interp, 2, objv, "key");
  461. return (TCL_ERROR);
  462. }
  463. if ((ret = _CopyObjBytes(
  464.     interp, objv[2], &ktmp, &size, &freekey)) != 0) {
  465. result = _ReturnSetup(interp, ret,
  466.     DB_RETOK_STD(ret), "dbm fetch");
  467. goto out;
  468. }
  469. key.dsize = size;
  470. key.dptr = (char *)ktmp;
  471. _debug_check();
  472. if (flag == DBTCL_DBM)
  473. ret = delete(key);
  474. else if (flag == DBTCL_NDBM)
  475. ret = dbm_delete(dbm, key);
  476. else {
  477. Tcl_SetResult(interp,
  478.     "Bad interface flag for command", TCL_STATIC);
  479. return (TCL_ERROR);
  480. }
  481. _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "delete");
  482. break;
  483. case DBMFIRST:
  484. /*
  485.  * No arg for this.  Error if different.
  486.  */
  487. if (objc != 2) {
  488. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  489. return (TCL_ERROR);
  490. }
  491. _debug_check();
  492. if (flag == DBTCL_DBM)
  493. key = firstkey();
  494. else if (flag == DBTCL_NDBM)
  495. key = dbm_firstkey(dbm);
  496. else {
  497. Tcl_SetResult(interp,
  498.     "Bad interface flag for command", TCL_STATIC);
  499. return (TCL_ERROR);
  500. }
  501. if (key.dptr == NULL ||
  502.     (ret = __os_malloc(NULL, key.dsize + 1, &t)) != 0)
  503. Tcl_SetResult(interp, "-1", TCL_STATIC);
  504. else {
  505. memcpy(t, key.dptr, key.dsize);
  506. t[key.dsize] = '';
  507. Tcl_SetResult(interp, t, TCL_VOLATILE);
  508. __os_free(NULL, t);
  509. }
  510. break;
  511. case DBMNEXT:
  512. /*
  513.  * 0 or 1 arg for this.  Error if different.
  514.  */
  515. _debug_check();
  516. if (flag == DBTCL_DBM) {
  517. if (objc != 3) {
  518. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  519. return (TCL_ERROR);
  520. }
  521. if ((ret = _CopyObjBytes(
  522.     interp, objv[2], &ktmp, &size, &freekey)) != 0) {
  523. result = _ReturnSetup(interp, ret,
  524.     DB_RETOK_STD(ret), "dbm fetch");
  525. goto out;
  526. }
  527. key.dsize = size;
  528. key.dptr = (char *)ktmp;
  529. data = nextkey(key);
  530. } else if (flag == DBTCL_NDBM) {
  531. if (objc != 2) {
  532. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  533. return (TCL_ERROR);
  534. }
  535. data = dbm_nextkey(dbm);
  536. } else {
  537. Tcl_SetResult(interp,
  538.     "Bad interface flag for command", TCL_STATIC);
  539. return (TCL_ERROR);
  540. }
  541. if (data.dptr == NULL ||
  542.     (ret = __os_malloc(NULL, data.dsize + 1, &t)) != 0)
  543. Tcl_SetResult(interp, "-1", TCL_STATIC);
  544. else {
  545. memcpy(t, data.dptr, data.dsize);
  546. t[data.dsize] = '';
  547. Tcl_SetResult(interp, t, TCL_VOLATILE);
  548. __os_free(NULL, t);
  549. }
  550. break;
  551. }
  552. out:
  553. if (freedata)
  554. (void)__os_free(NULL, dtmp);
  555. if (freekey)
  556. (void)__os_free(NULL, ktmp);
  557. return (result);
  558. }
  559. /*
  560.  * ndbm_Cmd --
  561.  * Implements the "ndbm" widget.
  562.  *
  563.  * PUBLIC: int ndbm_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
  564.  */
  565. int
  566. ndbm_Cmd(clientData, interp, objc, objv)
  567. ClientData clientData; /* DB handle */
  568. Tcl_Interp *interp; /* Interpreter */
  569. int objc; /* How many arguments? */
  570. Tcl_Obj *CONST objv[]; /* The argument objects */
  571. {
  572. static char *ndbcmds[] = {
  573. "clearerr",
  574. "close",
  575. "delete",
  576. "dirfno",
  577. "error",
  578. "fetch",
  579. "firstkey",
  580. "nextkey",
  581. "pagfno",
  582. "rdonly",
  583. "store",
  584. NULL
  585. };
  586. enum ndbcmds {
  587. NDBCLRERR,
  588. NDBCLOSE,
  589. NDBDELETE,
  590. NDBDIRFNO,
  591. NDBERR,
  592. NDBFETCH,
  593. NDBFIRST,
  594. NDBNEXT,
  595. NDBPAGFNO,
  596. NDBRDONLY,
  597. NDBSTORE
  598. };
  599. DBM *dbp;
  600. DBTCL_INFO *dbip;
  601. Tcl_Obj *res;
  602. int cmdindex, result, ret;
  603. Tcl_ResetResult(interp);
  604. dbp = (DBM *)clientData;
  605. dbip = _PtrToInfo((void *)dbp);
  606. result = TCL_OK;
  607. if (objc <= 1) {
  608. Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
  609. return (TCL_ERROR);
  610. }
  611. if (dbp == NULL) {
  612. Tcl_SetResult(interp, "NULL db pointer", TCL_STATIC);
  613. return (TCL_ERROR);
  614. }
  615. if (dbip == NULL) {
  616. Tcl_SetResult(interp, "NULL db info pointer", TCL_STATIC);
  617. return (TCL_ERROR);
  618. }
  619. /*
  620.  * Get the command name index from the object based on the dbcmds
  621.  * defined above.
  622.  */
  623. if (Tcl_GetIndexFromObj(interp,
  624.     objv[1], ndbcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
  625. return (IS_HELP(objv[1]));
  626. res = NULL;
  627. switch ((enum ndbcmds)cmdindex) {
  628. case NDBCLOSE:
  629. _debug_check();
  630. dbm_close(dbp);
  631. (void)Tcl_DeleteCommand(interp, dbip->i_name);
  632. _DeleteInfo(dbip);
  633. res = Tcl_NewIntObj(0);
  634. break;
  635. case NDBDELETE:
  636. case NDBFETCH:
  637. case NDBFIRST:
  638. case NDBNEXT:
  639. case NDBSTORE:
  640. result = bdb_DbmCommand(interp, objc, objv, DBTCL_NDBM, dbp);
  641. break;
  642. case NDBCLRERR:
  643. /*
  644.  * No args for this.  Error if there are some.
  645.  */
  646. if (objc > 2) {
  647. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  648. return (TCL_ERROR);
  649. }
  650. _debug_check();
  651. ret = dbm_clearerr(dbp);
  652. if (ret)
  653. _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
  654.     "clearerr");
  655. else
  656. res = Tcl_NewIntObj(ret);
  657. break;
  658. case NDBDIRFNO:
  659. /*
  660.  * No args for this.  Error if there are some.
  661.  */
  662. if (objc > 2) {
  663. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  664. return (TCL_ERROR);
  665. }
  666. _debug_check();
  667. ret = dbm_dirfno(dbp);
  668. res = Tcl_NewIntObj(ret);
  669. break;
  670. case NDBPAGFNO:
  671. /*
  672.  * No args for this.  Error if there are some.
  673.  */
  674. if (objc > 2) {
  675. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  676. return (TCL_ERROR);
  677. }
  678. _debug_check();
  679. ret = dbm_pagfno(dbp);
  680. res = Tcl_NewIntObj(ret);
  681. break;
  682. case NDBERR:
  683. /*
  684.  * No args for this.  Error if there are some.
  685.  */
  686. if (objc > 2) {
  687. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  688. return (TCL_ERROR);
  689. }
  690. _debug_check();
  691. ret = dbm_error(dbp);
  692. Tcl_SetErrno(ret);
  693. Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_STATIC);
  694. break;
  695. case NDBRDONLY:
  696. /*
  697.  * No args for this.  Error if there are some.
  698.  */
  699. if (objc > 2) {
  700. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  701. return (TCL_ERROR);
  702. }
  703. _debug_check();
  704. ret = dbm_rdonly(dbp);
  705. if (ret)
  706. _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "rdonly");
  707. else
  708. res = Tcl_NewIntObj(ret);
  709. break;
  710. }
  711. /*
  712.  * Only set result if we have a res.  Otherwise, lower
  713.  * functions have already done so.
  714.  */
  715. if (result == TCL_OK && res)
  716. Tcl_SetObjResult(interp, res);
  717. return (result);
  718. }
  719. #endif /* CONFIG_TEST */