Mercurial > hg > xemacs-beta
comparison src/database.c @ 5125:b5df3737028a ben-lisp-object
merge
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Wed, 24 Feb 2010 01:58:04 -0600 |
parents | 623d57b7fbe8 97c45e3ad810 |
children | a9c41067dd88 |
comparison
equal
deleted
inserted
replaced
5124:623d57b7fbe8 | 5125:b5df3737028a |
---|---|
83 Lisp_Object Qqueue; | 83 Lisp_Object Qqueue; |
84 #endif | 84 #endif |
85 #endif /* HAVE_BERKELEY_DB */ | 85 #endif /* HAVE_BERKELEY_DB */ |
86 | 86 |
87 #ifdef HAVE_DBM | 87 #ifdef HAVE_DBM |
88 #if defined (CYGWIN) || defined (MINGW) | 88 # ifdef TRUST_NDBM_H_PROTOTYPES |
89 # include NDBM_H_FILE | |
90 # else /* not TRUST_NDBM_H_PROTOTYPES */ | |
91 | |
92 /* The prototypes in gdbm/ndbm.h currently are broken when compiling | |
93 using C++, since they are of the form `datum dbm_firstkey()', without any | |
94 args given. */ | |
89 | 95 |
90 #if defined(__cplusplus) || defined(c_plusplus) | 96 #if defined(__cplusplus) || defined(c_plusplus) |
91 extern "C" { | 97 extern "C" { |
92 #endif | 98 #endif |
93 | 99 |
94 /* As of Cygwin 1.7.0, the prototypes in ndbm.h are broken when compiling | |
95 using C++, since they are of the form `datum dbm_firstkey()', without any | |
96 args given. */ | |
97 /* Parameters to dbm_store for simple insertion or replacement. */ | 100 /* Parameters to dbm_store for simple insertion or replacement. */ |
98 #define DBM_INSERT 0 | 101 #define DBM_INSERT 0 |
99 #define DBM_REPLACE 1 | 102 #define DBM_REPLACE 1 |
100 | 103 |
101 | |
102 /* The data and key structure. This structure is defined for compatibility. */ | 104 /* The data and key structure. This structure is defined for compatibility. */ |
103 typedef struct { | 105 typedef struct |
104 char *dptr; | 106 { |
105 int dsize; | 107 char *dptr; |
106 } datum; | 108 int dsize; |
107 | 109 } datum; |
108 | 110 |
109 /* The file information header. This is good enough for most applications. */ | 111 /* The file information header. This is good enough for most applications. */ |
110 typedef struct {int dummy[10];} DBM; | 112 typedef struct {int dummy[10];} DBM; |
111 | 113 |
112 int dbm_clearerr(DBM *); | 114 int dbm_clearerr(DBM *); |
121 | 123 |
122 #if defined(__cplusplus) || defined(c_plusplus) | 124 #if defined(__cplusplus) || defined(c_plusplus) |
123 } | 125 } |
124 #endif | 126 #endif |
125 | 127 |
126 #else | 128 # endif /* (not) TRUST_NDBM_H_PROTOTYPES */ |
127 #include NDBM_H_FILE | |
128 #endif | |
129 Lisp_Object Qdbm; | 129 Lisp_Object Qdbm; |
130 #endif /* HAVE_DBM */ | 130 #endif /* HAVE_DBM */ |
131 | 131 |
132 Lisp_Object Vdatabase_coding_system; | 132 Lisp_Object Vdatabase_coding_system; |
133 | 133 |
215 int UNUSED (escapeflag)) | 215 int UNUSED (escapeflag)) |
216 { | 216 { |
217 Lisp_Database *db = XDATABASE (obj); | 217 Lisp_Database *db = XDATABASE (obj); |
218 | 218 |
219 if (print_readably) | 219 if (print_readably) |
220 printing_unreadable_object ("#<database 0x%x>", db->header.uid); | 220 printing_unreadable_lcrecord (obj, 0); |
221 | 221 |
222 write_fmt_string_lisp (printcharfun, "#<database \"%s\" (%s/%s/", | 222 write_fmt_string_lisp (printcharfun, "#<database \"%s\" (%s/%s/", |
223 3, db->fname, db->funcs->get_type (db), | 223 3, db->fname, db->funcs->get_type (db), |
224 db->funcs->get_subtype (db)); | 224 db->funcs->get_subtype (db)); |
225 | 225 |
319 for (keydatum = dbm_firstkey (db->dbm_handle); | 319 for (keydatum = dbm_firstkey (db->dbm_handle); |
320 keydatum.dptr != NULL; | 320 keydatum.dptr != NULL; |
321 keydatum = dbm_nextkey (db->dbm_handle)) | 321 keydatum = dbm_nextkey (db->dbm_handle)) |
322 { | 322 { |
323 valdatum = dbm_fetch (db->dbm_handle, keydatum); | 323 valdatum = dbm_fetch (db->dbm_handle, keydatum); |
324 key = make_ext_string ((Extbyte *) keydatum.dptr, keydatum.dsize, | 324 key = make_extstring ((Extbyte *) keydatum.dptr, keydatum.dsize, |
325 db->coding_system); | 325 db->coding_system); |
326 val = make_ext_string ((Extbyte *) valdatum.dptr, valdatum.dsize, | 326 val = make_extstring ((Extbyte *) valdatum.dptr, valdatum.dsize, |
327 db->coding_system); | 327 db->coding_system); |
328 call2 (func, key, val); | 328 call2 (func, key, val); |
329 } | 329 } |
330 } | 330 } |
331 | 331 |
332 static Lisp_Object | 332 static Lisp_Object |
333 dbm_get (Lisp_Database *db, Lisp_Object key) | 333 dbm_get (Lisp_Database *db, Lisp_Object key) |
334 { | 334 { |
335 datum keydatum, valdatum; | 335 datum keydatum, valdatum; |
336 | 336 |
337 TO_EXTERNAL_FORMAT (LISP_STRING, key, | 337 LISP_STRING_TO_SIZED_EXTERNAL (key, keydatum.dptr, keydatum.dsize, |
338 ALLOCA, (keydatum.dptr, keydatum.dsize), | 338 db->coding_system); |
339 db->coding_system); | |
340 valdatum = dbm_fetch (db->dbm_handle, keydatum); | 339 valdatum = dbm_fetch (db->dbm_handle, keydatum); |
341 | 340 |
342 return (valdatum.dptr | 341 return (valdatum.dptr |
343 ? make_ext_string ((Extbyte *) valdatum.dptr, valdatum.dsize, | 342 ? make_extstring ((Extbyte *) valdatum.dptr, valdatum.dsize, |
344 db->coding_system) | 343 db->coding_system) |
345 : Qnil); | 344 : Qnil); |
346 } | 345 } |
347 | 346 |
348 static int | 347 static int |
349 dbm_put (Lisp_Database *db, | 348 dbm_put (Lisp_Database *db, |
350 Lisp_Object key, Lisp_Object val, Lisp_Object replace) | 349 Lisp_Object key, Lisp_Object val, Lisp_Object replace) |
351 { | 350 { |
352 datum keydatum, valdatum; | 351 datum keydatum, valdatum; |
353 | 352 |
354 TO_EXTERNAL_FORMAT (LISP_STRING, val, | 353 LISP_STRING_TO_SIZED_EXTERNAL (val, valdatum.dptr, valdatum.dsize, |
355 ALLOCA, (valdatum.dptr, valdatum.dsize), | 354 db->coding_system); |
356 db->coding_system); | 355 LISP_STRING_TO_SIZED_EXTERNAL (key, keydatum.dptr, keydatum.dsize, |
357 TO_EXTERNAL_FORMAT (LISP_STRING, key, | 356 db->coding_system); |
358 ALLOCA, (keydatum.dptr, keydatum.dsize), | |
359 db->coding_system); | |
360 | 357 |
361 return !dbm_store (db->dbm_handle, keydatum, valdatum, | 358 return !dbm_store (db->dbm_handle, keydatum, valdatum, |
362 NILP (replace) ? DBM_INSERT : DBM_REPLACE); | 359 NILP (replace) ? DBM_INSERT : DBM_REPLACE); |
363 } | 360 } |
364 | 361 |
365 static int | 362 static int |
366 dbm_remove (Lisp_Database *db, Lisp_Object key) | 363 dbm_remove (Lisp_Database *db, Lisp_Object key) |
367 { | 364 { |
368 datum keydatum; | 365 datum keydatum; |
369 | 366 |
370 TO_EXTERNAL_FORMAT (LISP_STRING, key, | 367 LISP_STRING_TO_SIZED_EXTERNAL (key, keydatum.dptr, keydatum.dsize, |
371 ALLOCA, (keydatum.dptr, keydatum.dsize), | 368 db->coding_system); |
372 db->coding_system); | |
373 | 369 |
374 return dbm_delete (db->dbm_handle, keydatum); | 370 return dbm_delete (db->dbm_handle, keydatum); |
375 } | 371 } |
376 | 372 |
377 static Lisp_Object | 373 static Lisp_Object |
454 | 450 |
455 /* DB Version 2 requires DBT's to be zeroed before use. */ | 451 /* DB Version 2 requires DBT's to be zeroed before use. */ |
456 xzero (keydatum); | 452 xzero (keydatum); |
457 xzero (valdatum); | 453 xzero (valdatum); |
458 | 454 |
459 TO_EXTERNAL_FORMAT (LISP_STRING, key, | 455 LISP_STRING_TO_SIZED_EXTERNAL (key, keydatum.data, keydatum.size, |
460 ALLOCA, (keydatum.data, keydatum.size), | 456 db->coding_system); |
461 db->coding_system); | |
462 | 457 |
463 #if DB_VERSION_MAJOR == 1 | 458 #if DB_VERSION_MAJOR == 1 |
464 status = db->db_handle->get (db->db_handle, &keydatum, &valdatum, 0); | 459 status = db->db_handle->get (db->db_handle, &keydatum, &valdatum, 0); |
465 #else | 460 #else |
466 status = db->db_handle->get (db->db_handle, NULL, &keydatum, &valdatum, 0); | 461 status = db->db_handle->get (db->db_handle, NULL, &keydatum, &valdatum, 0); |
467 #endif /* DB_VERSION_MAJOR */ | 462 #endif /* DB_VERSION_MAJOR */ |
468 | 463 |
469 if (!status) | 464 if (!status) |
470 return make_ext_string ((const Extbyte *) valdatum.data, valdatum.size, | 465 return make_extstring ((const Extbyte *) valdatum.data, valdatum.size, |
471 db->coding_system); | 466 db->coding_system); |
472 | 467 |
473 #if DB_VERSION_MAJOR == 1 | 468 #if DB_VERSION_MAJOR == 1 |
474 db->dberrno = (status == 1) ? -1 : errno; | 469 db->dberrno = (status == 1) ? -1 : errno; |
475 #else | 470 #else |
490 | 485 |
491 /* DB Version 2 requires DBT's to be zeroed before use. */ | 486 /* DB Version 2 requires DBT's to be zeroed before use. */ |
492 xzero (keydatum); | 487 xzero (keydatum); |
493 xzero (valdatum); | 488 xzero (valdatum); |
494 | 489 |
495 TO_EXTERNAL_FORMAT (LISP_STRING, key, | 490 LISP_STRING_TO_SIZED_EXTERNAL (key, keydatum.data, keydatum.size, |
496 ALLOCA, (keydatum.data, keydatum.size), | 491 db->coding_system); |
497 db->coding_system); | 492 LISP_STRING_TO_SIZED_EXTERNAL (val, valdatum.data, valdatum.size, |
498 TO_EXTERNAL_FORMAT (LISP_STRING, val, | 493 db->coding_system); |
499 ALLOCA, (valdatum.data, valdatum.size), | |
500 db->coding_system); | |
501 #if DB_VERSION_MAJOR == 1 | 494 #if DB_VERSION_MAJOR == 1 |
502 status = db->db_handle->put (db->db_handle, &keydatum, &valdatum, | 495 status = db->db_handle->put (db->db_handle, &keydatum, &valdatum, |
503 NILP (replace) ? R_NOOVERWRITE : 0); | 496 NILP (replace) ? R_NOOVERWRITE : 0); |
504 db->dberrno = (status == 1) ? -1 : errno; | 497 db->dberrno = (status == 1) ? -1 : errno; |
505 #else | 498 #else |
518 int status; | 511 int status; |
519 | 512 |
520 /* DB Version 2 requires DBT's to be zeroed before use. */ | 513 /* DB Version 2 requires DBT's to be zeroed before use. */ |
521 xzero (keydatum); | 514 xzero (keydatum); |
522 | 515 |
523 TO_EXTERNAL_FORMAT (LISP_STRING, key, | 516 LISP_STRING_TO_SIZED_EXTERNAL (key, keydatum.data, keydatum.size, |
524 ALLOCA, (keydatum.data, keydatum.size), | 517 db->coding_system); |
525 db->coding_system); | |
526 | 518 |
527 #if DB_VERSION_MAJOR == 1 | 519 #if DB_VERSION_MAJOR == 1 |
528 status = db->db_handle->del (db->db_handle, &keydatum, 0); | 520 status = db->db_handle->del (db->db_handle, &keydatum, 0); |
529 #else | 521 #else |
530 status = db->db_handle->del (db->db_handle, NULL, &keydatum, 0); | 522 status = db->db_handle->del (db->db_handle, NULL, &keydatum, 0); |
556 #if DB_VERSION_MAJOR == 1 | 548 #if DB_VERSION_MAJOR == 1 |
557 for (status = dbp->seq (dbp, &keydatum, &valdatum, R_FIRST); | 549 for (status = dbp->seq (dbp, &keydatum, &valdatum, R_FIRST); |
558 status == 0; | 550 status == 0; |
559 status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT)) | 551 status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT)) |
560 { | 552 { |
561 key = make_ext_string ((const Extbyte *) keydatum.data, keydatum.size, | 553 key = make_extstring ((const Extbyte *) keydatum.data, keydatum.size, |
562 db->coding_system); | 554 db->coding_system); |
563 val = make_ext_string ((const Extbyte *) valdatum.data, valdatum.size, | 555 val = make_extstring ((const Extbyte *) valdatum.data, valdatum.size, |
564 db->coding_system); | 556 db->coding_system); |
565 call2 (func, key, val); | 557 call2 (func, key, val); |
566 } | 558 } |
567 #else | 559 #else |
568 { | 560 { |
575 #endif | 567 #endif |
576 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST); | 568 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST); |
577 status == 0; | 569 status == 0; |
578 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT)) | 570 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT)) |
579 { | 571 { |
580 key = make_ext_string ((const Extbyte *) keydatum.data, keydatum.size, | 572 key = make_extstring ((const Extbyte *) keydatum.data, keydatum.size, |
581 db->coding_system); | 573 db->coding_system); |
582 val = make_ext_string ((const Extbyte *) valdatum.data, valdatum.size, | 574 val = make_extstring ((const Extbyte *) valdatum.data, valdatum.size, |
583 db->coding_system); | 575 db->coding_system); |
584 call2 (func, key, val); | 576 call2 (func, key, val); |
585 } | 577 } |
586 dbcp->c_close (dbcp); | 578 dbcp->c_close (dbcp); |
587 } | 579 } |
645 { | 637 { |
646 /* This function can GC */ | 638 /* This function can GC */ |
647 int modemask; | 639 int modemask; |
648 int accessmask = 0; | 640 int accessmask = 0; |
649 Lisp_Database *db = NULL; | 641 Lisp_Database *db = NULL; |
650 char *filename; | 642 Extbyte *filename; |
651 struct gcpro gcpro1, gcpro2; | 643 struct gcpro gcpro1, gcpro2; |
652 | 644 |
653 CHECK_STRING (file); | 645 CHECK_STRING (file); |
654 GCPRO2 (file, access_); | 646 GCPRO2 (file, access_); |
655 file = Fexpand_file_name (file, Qnil); | 647 file = Fexpand_file_name (file, Qnil); |
656 UNGCPRO; | 648 UNGCPRO; |
657 | 649 |
658 TO_EXTERNAL_FORMAT (LISP_STRING, file, | 650 LISP_PATHNAME_CONVERT_OUT (file, filename); |
659 C_STRING_ALLOCA, filename, | |
660 Qfile_name); | |
661 | 651 |
662 if (NILP (access_)) | 652 if (NILP (access_)) |
663 { | 653 { |
664 accessmask = O_RDWR | O_CREAT; | 654 accessmask = O_RDWR | O_CREAT; |
665 } | 655 } |
666 else | 656 else |
667 { | 657 { |
668 char *acc; | 658 Ibyte *acc; |
669 CHECK_STRING (access_); | 659 CHECK_STRING (access_); |
670 acc = (char *) XSTRING_DATA (access_); | 660 acc = XSTRING_DATA (access_); |
671 | 661 |
672 if (strchr (acc, '+')) | 662 if (qxestrchr (acc, '+')) |
673 accessmask |= O_CREAT; | 663 accessmask |= O_CREAT; |
674 | 664 |
675 { | 665 { |
676 char *rp = strchr (acc, 'r'); | 666 int rp = !!qxestrchr (acc, 'r'); |
677 char *wp = strchr (acc, 'w'); | 667 int wp = !!qxestrchr (acc, 'w'); |
678 if (rp && wp) accessmask |= O_RDWR; | 668 if (rp && wp) accessmask |= O_RDWR; |
679 else if (wp) accessmask |= O_WRONLY; | 669 else if (wp) accessmask |= O_WRONLY; |
680 else accessmask |= O_RDONLY; | 670 else accessmask |= O_RDONLY; |
681 } | 671 } |
682 } | 672 } |