Mercurial > hg > xemacs-beta
annotate src/database.c @ 2720:6fa9919a9a0b
[xemacs-hg @ 2005-04-08 23:10:01 by crestani]
ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
New configure flag: `MC_ALLOC':
* configure.ac (XE_COMPLEX_ARG_ENABLE): Add `--enable-mc-alloc' as
a new configure flag.
* configure.in (AC_INIT_PARSE_ARGS): Add `--mc-alloc' as a new
configure flag.
* configure.usage: Add description for `mc-alloc'.
DUMP_IN_EXEC:
* Makefile.in.in: Condition the installation of a separate dump
file on !DUMP_ON_EXEC.
* configure.ac (XE_COMPLEX_ARG_ENABLE): Add
`--enable-dump-in-exec' as a new configure flag.
* configure.ac: DUMP_IN_EXEC is define as default for PDUMP but
not default for MC_ALLOC.
* configure.in (AC_INIT_PARSE_ARGS): Add `--dump-in-exec' as a
new configure flag.
* configure.in: DUMP_IN_EXEC is define as default for PDUMP but
not default for MC_ALLOC.
* configure.usage: Add description for `dump-in-exec'.
lib-src/ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
DUMP_IN_EXEC:
* Makefile.in.in: Only compile insert-data-in-exec if
DUMP_IN_EXEC is defined.
lisp/ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
MEMORY_USAGE_STATS
* diagnose.el: Add new lisp function to pretty print statistics
about the new allocator.
* diagnose.el (show-mc-alloc-memory-usage): New.
modules/ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
Remove Lcrecords:
* postgresql/postgresql.c (allocate_pgconn): Allocate with new
allocator.
* postgresql/postgresql.c (allocate_pgresult): Allocate PGresult
with new allocator.
* postgresql/postgresql.h (struct Lisp_PGconn): Add
lrecord_header.
* postgresql/postgresql.h (struct Lisp_PGresult): Add
lrecord_header.
* ldap/eldap.c (allocate_ldap): Allocate with new allocator.
* ldap/eldap.h (struct Lisp_LDAP): Add lrecord_header.
nt/ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
New configure flag: `MC_ALLOC':
* config.inc.samp: Add new flag `MC_ALLOC'.
* xemacs.mak: Add flag and configuration output for `MC_ALLOC'.
New files:
* xemacs.dsp: Add source files mc-alloc.c and mc-alloc.h.
* xemacs.mak: Add new object file mc-alloc.obj to dependencies.
src/ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
New configure flag: `MC_ALLOC':
* config.h.in: Add new flag `MC_ALLOC'.
New files:
* Makefile.in.in: Add new object file mc-alloc.o.
* depend: Add new files to dependencies.
* mc-alloc.c: New.
* mc-alloc.h: New.
Running the new allocator from XEmacs:
* alloc.c (deadbeef_memory): Moved to mc-alloc.c.
* emacs.c (main_1): Initialize the new allocator and add
syms_of_mc_alloc.
* symsinit.h: Add syms_of_mc_alloc.
New lrecord allocation and free functions:
* alloc.c (alloc_lrecord): New. Allocates an lrecord, includes
type checking and initializing of the lrecord_header.
* alloc.c (noseeum_alloc_lrecord): Same as above, but increments
the NOSEEUM cons counter.
* alloc.c (free_lrecord): New. Calls the finalizer and frees the
lrecord.
* lrecord.h: Add lrecord allocation prototypes and comments.
Remove old lrecord FROB block allocation:
* alloc.c (allocate_lisp_storage): Former function to expand
heap. Not needed anymore, remove.
* alloc.c: Completely remove `Fixed-size type macros'
* alloc.c (release_breathing_space): Remove.
* alloc.c (memory_full): Remove release_breathing_space.
* alloc.c (refill_memory_reserve): Remove.
* alloc.c (TYPE_ALLOC_SIZE): Remove.
* alloc.c (DECLARE_FIXED_TYPE_ALLOC): Remove.
* alloc.c (ALLOCATE_FIXED_TYPE_FROM_BLOCK): Remove.
* alloc.c (ALLOCATE_FIXED_TYPE_1): Remove.
* alloc.c (ALLOCATE_FIXED_TYPE): Remove.
* alloc.c (NOSEEUM_ALLOCATE_FIXED_TYPE): Remove.
* alloc.c (struct Lisp_Free): Remove.
* alloc.c (LRECORD_FREE_P): Remove.
* alloc.c (MARK_LRECORD_AS_FREE): Remove.
* alloc.c (MARK_LRECORD_AS_NOT_FREE): Remove.
* alloc.c (PUT_FIXED_TYPE_ON_FREE_LIST): Remove.
* alloc.c (FREE_FIXED_TYPE): Remove.
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC): Remove.
Allocate old lrecords with new allocator:
* alloc.c: DECLARE_FIXED_TYPE_ALLOC removed for all lrecords
defined in alloc.c.
* alloc.c (Fcons): Allocate with new allocator.
* alloc.c (noseeum_cons): Allocate with new allocator.
* alloc.c (make_float): Allocate with new allocator.
* alloc.c (make_bignum): Allocate with new allocator.
* alloc.c (make_bignum_bg): Allocate with new allocator.
* alloc.c (make_ratio): Allocate with new allocator.
* alloc.c (make_ratio_bg): Allocate with new allocator.
* alloc.c (make_ratio_rt): Allocate with new allocator.
* alloc.c (make_bigfloat): Allocate with new allocator.
* alloc.c (make_bigfloat_bf): Allocate with new allocator.
* alloc.c (make_compiled_function): Allocate with new allocator.
* alloc.c (Fmake_symbol): Allocate with new allocator.
* alloc.c (allocate_extent): Allocate with new allocator.
* alloc.c (allocate_event): Allocate with new allocator.
* alloc.c (make_key_data): Allocate with new allocator.
* alloc.c (make_button_data): Allocate with new allocator.
* alloc.c (make_motion_data): Allocate with new allocator.
* alloc.c (make_process_data): Allocate with new allocator.
* alloc.c (make_timeout_data): Allocate with new allocator.
* alloc.c (make_magic_data): Allocate with new allocator.
* alloc.c (make_magic_eval_data): Allocate with new allocator.
* alloc.c (make_eval_data): Allocate with new allocator.
* alloc.c (make_misc_user_data): Allocate with new allocator.
* alloc.c (Fmake_marker): Allocate with new allocator.
* alloc.c (noseeum_make_marker): Allocate with new allocator.
* alloc.c (make_uninit_string): Allocate with new allocator.
* alloc.c (resize_string): Allocate with new allocator.
* alloc.c (make_string_nocopy): Allocate with new allocator.
Garbage Collection:
* alloc.c (GC_CHECK_NOT_FREE): Remove obsolete assertions.
* alloc.c (SWEEP_FIXED_TYPE_BLOCK): Remove.
* alloc.c (SWEEP_FIXED_TYPE_BLOCK_1): Remove.
* alloc.c (sweep_conses): Remove.
* alloc.c (free_cons): Use new allocator to free.
* alloc.c (sweep_compiled_functions): Remove.
* alloc.c (sweep_floats): Remove.
* alloc.c (sweep_bignums): Remove.
* alloc.c (sweep_ratios): Remove.
* alloc.c (sweep_bigfloats): Remove.
* alloc.c (sweep_symbols): Remove.
* alloc.c (sweep_extents): Remove.
* alloc.c (sweep_events): Remove.
* alloc.c (sweep_key_data): Remove.
* alloc.c (free_key_data): Use new allocator to free.
* alloc.c (sweep_button_data): Remove.
* alloc.c (free_button_data): Use new allocator to free.
* alloc.c (sweep_motion_data): Remove.
* alloc.c (free_motion_data): Use new allocator to free.
* alloc.c (sweep_process_data): Remove.
* alloc.c (free_process_data): Use new allocator to free.
* alloc.c (sweep_timeout_data): Remove.
* alloc.c (free_timeout_data): Use new allocator to free.
* alloc.c (sweep_magic_data): Remove.
* alloc.c (free_magic_data): Use new allocator to free.
* alloc.c (sweep_magic_eval_data): Remove.
* alloc.c (free_magic_eval_data): Use new allocator to free.
* alloc.c (sweep_eval_data): Remove.
* alloc.c (free_eval_data): Use new allocator to free.
* alloc.c (sweep_misc_user_data): Remove.
* alloc.c (free_misc_user_data): Use new allocator to free.
* alloc.c (sweep_markers): Remove.
* alloc.c (free_marker): Use new allocator to free.
* alloc.c (garbage_collect_1): Remove release_breathing_space.
* alloc.c (gc_sweep): Remove all the old lcrecord and lrecord
related stuff. Sweeping now works like this: compact string
chars, finalize, sweep.
* alloc.c (common_init_alloc_early): Remove old lrecord
initializations, remove breathing_space.
* emacs.c (Fdump_emacs): Remove release_breathing_space.
* lisp.h: Remove prototype for release_breathing_space.
* lisp.h: Adjust the special cons mark makros.
Lrecord Finalizer:
* alloc.c: Add finalizer to lrecord definition.
* alloc.c (finalize_string): Add finalizer for string.
* bytecode.c: Add finalizer to lrecord definition.
* bytecode.c (finalize_compiled_function): Add finalizer for
compiled function.
* marker.c: Add finalizer to lrecord definition.
* marker.c (finalize_marker): Add finalizer for marker.
These changes build the interface to mc-alloc:
* lrecord.h (MC_ALLOC_CALL_FINALIZER): Tell mc-alloc how to
finalize lrecords.
* lrecord.h (MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE): Tell
mc-alloc how to finalize for disksave.
Unify lrecords and lcrecords:
* lisp.h (struct Lisp_String): Adjust string union hack to
new lrecord header.
* lrecord.h: Adjust comments.
* lrecord.h (struct lrecord_header): The new lrecord header
includes type, lisp-readonly, free, and uid.
* lrecord.h (set_lheader_implementation): Adjust to new
lrecord_header.
* lrecord.h (struct lrecord_implementation): The field basic_p
for indication of an old lrecord is not needed anymore, remove.
* lrecord.h (MAKE_LRECORD_IMPLEMENTATION): Remove basic_p.
* lrecord.h (MAKE_EXTERNAL_LRECORD_IMPLEMENTATION): Remove
basic_p.
* lrecord.h (copy_sized_lrecord): Remove distinction between
old lrecords and lcrecords.
* lrecord.h (copy_lrecord): Remove distinction between old
lrecords and lcrecords.
* lrecord.h (zero_sized_lrecord): Remove distinction between
old lrecords and lcrecords.
* lrecord.h (zero_lrecord): Remove distinction between old
lrecords and lcrecords.
Remove lcrecords and lcrecord lists:
* alloc.c (basic_alloc_lcrecord): Not needed anymore, remove.
* alloc.c (very_old_free_lcrecord): Not needed anymore, remove.
* alloc.c (copy_lisp_object): No more distinction between
lrecords and lcrecords.
* alloc.c (all_lcrecords): Not needed anymore, remove.
* alloc.c (make_vector_internal): Allocate as lrecord.
* alloc.c (make_bit_vector_internal): Allocate as lrecord.
* alloc.c: Completely remove `lcrecord lists'.
* alloc.c (free_description): Remove.
* alloc.c (lcrecord_list_description): Remove.
* alloc.c (mark_lcrecord_list): Remove.
* alloc.c (make_lcrecord_list): Remove.
* alloc.c (alloc_managed_lcrecord): Remove.
* alloc.c (free_managed_lcrecord): Remove.
* alloc.c (alloc_automanaged_lcrecord): Remove.
* alloc.c (free_lcrecord): Remove.
* alloc.c (lcrecord_stats): Remove.
* alloc.c (tick_lcrecord_stats): Remove.
* alloc.c (disksave_object_finalization_1): Add call to
mc_finalize_for_disksave. Remove the lcrecord way to visit all
objects.
* alloc.c (kkcc_marking): Remove XD_FLAG_FREE_LISP_OBJECT
* alloc.c (sweep_lcrecords_1): Remove.
* alloc.c (common_init_alloc_early): Remove everything related
to lcrecords, remove old lrecord initializations,
* alloc.c (init_lcrecord_lists): Not needed anymore, remove.
* alloc.c (reinit_alloc_early): Remove everything related to
lcrecords.
* alloc.c (init_alloc_once_early): Remove everything related to
lcrecords.
* buffer.c (allocate_buffer): Allocate as lrecord.
* buffer.c (nuke_all_buffer_slots): Use lrecord functions.
* buffer.c (common_init_complex_vars_of_buffer): Allocate as
lrecord.
* buffer.h (struct buffer): Add lrecord_header.
* casetab.c (allocate_case_table): Allocate as lrecord.
* casetab.h (struct Lisp_Case_Table): Add lrecord_header.
* charset.h (struct Lisp_Charset): Add lrecord_header.
* chartab.c (fill_char_table): Use lrecord functions.
* chartab.c (Fmake_char_table): Allocate as lrecord.
* chartab.c (make_char_table_entry): Allocate as lrecord.
* chartab.c (copy_char_table_entry): Allocate as lrecord.
* chartab.c (Fcopy_char_table): Allocate as lrecord.
* chartab.c (put_char_table): Use lrecord functions.
* chartab.h (struct Lisp_Char_Table_Entry): Add lrecord_header.
* chartab.h (struct Lisp_Char_Table): Add lrecord_header.
* console-impl.h (struct console): Add lrecord_header.
* console-msw-impl.h (struct Lisp_Devmode): Add lrecord_header.
* console-msw-impl.h (struct mswindows_dialog_id): Add
lrecord_header.
* console.c (allocate_console): Allocate as lrecord.
* console.c (nuke_all_console_slots): Use lrecord functions.
* console.c (common_init_complex_vars_of_console): Allocate as
lrecord.
* data.c (make_weak_list): Allocate as lrecord.
* data.c (make_weak_box): Allocate as lrecord.
* data.c (make_ephemeron): Allocate as lrecord.
* database.c (struct Lisp_Database): Add lrecord_header.
* database.c (allocate_database): Allocate as lrecord.
* device-impl.h (struct device): Add lrecord_header.
* device-msw.c (allocate_devmode): Allocate as lrecord.
* device.c (nuke_all_device_slots): Use lrecord functions.
* device.c (allocate_device): Allocate as lrecord.
* dialog-msw.c (handle_question_dialog_box): Allocate as lrecord.
* elhash.c (struct Lisp_Hash_Table): Add lrecord_header.
* elhash.c (make_general_lisp_hash_table): Allocate as lrecord.
* elhash.c (Fcopy_hash_table): Allocate as lrecord.
* event-stream.c: Lcrecord lists Vcommand_builder_free_list and
Vtimeout_free_list are no longer needed. Remove.
* event-stream.c (allocate_command_builder): Allocate as lrecord.
* event-stream.c (free_command_builder): Use lrecord functions.
* event-stream.c (event_stream_generate_wakeup): Allocate as
lrecord.
* event-stream.c (event_stream_resignal_wakeup): Use lrecord
functions.
* event-stream.c (event_stream_disable_wakeup): Use lrecord
functions.
* event-stream.c (reinit_vars_of_event_stream): Lcrecord lists
remove.
* events.h (struct Lisp_Timeout): Add lrecord_header.
* events.h (struct command_builder): Add lrecord_header.
* extents-impl.h (struct extent_auxiliary): Add lrecord_header.
* extents-impl.h (struct extent_info): Add lrecord_header.
* extents.c (allocate_extent_auxiliary): Allocate as lrecord.
* extents.c (allocate_extent_info): Allocate as lrecord.
* extents.c (copy_extent): Allocate as lrecord.
* faces.c (allocate_face): Allocate as lrecord.
* faces.h (struct Lisp_Face): Add lrecord_header.
* file-coding.c (allocate_coding_system): Allocate as lrecord.
* file-coding.c (Fcopy_coding_system): Allocate as lrecord.
* file-coding.h (struct Lisp_Coding_System): Add lrecord_header.
* fns.c (Ffillarray): Allocate as lrecord.
* frame-impl.h (struct frame): Add lrecord_header.
* frame.c (nuke_all_frame_slots): Use lrecord functions.
* frame.c (allocate_frame_core): Allocate as lrecord.
* glyphs.c (allocate_image_instance): Allocate as lrecord.
* glyphs.c (Fcolorize_image_instance): Allocate as lrecord.
* glyphs.c (allocate_glyph): Allocate as lrecord.
* glyphs.h (struct Lisp_Image_Instance): Add lrecord_header.
* glyphs.h (struct Lisp_Glyph): Add lrecord_header.
* gui.c (allocate_gui_item): Allocate as lrecord.
* gui.h (struct Lisp_Gui_Item): Add lrecord_header.
* keymap.c (struct Lisp_Keymap): Add lrecord_header.
* keymap.c (make_keymap): Allocate as lrecord.
* lisp.h (struct Lisp_Vector): Add lrecord_header.
* lisp.h (struct Lisp_Bit_Vector): Add lrecord_header.
* lisp.h (struct weak_box): Add lrecord_header.
* lisp.h (struct ephemeron): Add lrecord_header.
* lisp.h (struct weak_list): Add lrecord_header.
* lrecord.h (struct lcrecord_header): Not used, remove.
* lrecord.h (struct free_lcrecord_header): Not used, remove.
* lrecord.h (struct lcrecord_list): Not needed anymore, remove.
* lrecord.h (lcrecord_list): Not needed anymore, remove.
* lrecord.h: (enum data_description_entry_flags): Remove
XD_FLAG_FREE_LISP_OBJECT.
* lstream.c: Lrecord list Vlstream_free_list remove.
* lstream.c (Lstream_new): Allocate as lrecord.
* lstream.c (Lstream_delete): Use lrecod functions.
* lstream.c (reinit_vars_of_lstream): Vlstream_free_list
initialization remove.
* lstream.h (struct lstream): Add lrecord_header.
* emacs.c (main_1): Remove lstream initialization.
* mule-charset.c (make_charset): Allocate as lrecord.
* objects-impl.h (struct Lisp_Color_Instance): Add
lrecord_header.
* objects-impl.h (struct Lisp_Font_Instance): Add lrecord_header.
* objects.c (Fmake_color_instance): Allocate as lrecord.
* objects.c (Fmake_font_instance): Allocate as lrecord.
* objects.c (reinit_vars_of_objects): Allocate as lrecord.
* opaque.c: Lcreord list Vopaque_ptr_list remove.
* opaque.c (make_opaque): Allocate as lrecord.
* opaque.c (make_opaque_ptr): Allocate as lrecord.
* opaque.c (free_opaque_ptr): Use lrecord functions.
* opaque.c (reinit_opaque_early):
* opaque.c (init_opaque_once_early): Vopaque_ptr_list
initialization remove.
* opaque.h (Lisp_Opaque): Add lrecord_header.
* opaque.h (Lisp_Opaque_Ptr): Add lrecord_header.
* emacs.c (main_1): Remove opaque variable initialization.
* print.c (default_object_printer): Use new lrecord_header.
* print.c (print_internal): Use new lrecord_header.
* print.c (debug_p4): Use new lrecord_header.
* process.c (make_process_internal): Allocate as lrecord.
* procimpl.h (struct Lisp_Process): Add lrecord_header.
* rangetab.c (Fmake_range_table): Allocate as lrecord.
* rangetab.c (Fcopy_range_table): Allocate as lrecord.
* rangetab.h (struct Lisp_Range_Table): Add lrecord_header.
* scrollbar.c (create_scrollbar_instance): Allocate as lrecord.
* scrollbar.h (struct scrollbar_instance): Add lrecord_header.
* specifier.c (make_specifier_internal): Allocate as lrecord.
* specifier.h (struct Lisp_Specifier): Add lrecord_header.
* symbols.c:
* symbols.c (Fmake_variable_buffer_local): Allocate as lrecord.
* symbols.c (Fdontusethis_set_symbol_value_handler): Allocate
as lrecord.
* symbols.c (Fdefvaralias): Allocate as lrecord.
* symeval.h (struct symbol_value_magic): Add lrecord_header.
* toolbar.c (update_toolbar_button): Allocate as lrecord.
* toolbar.h (struct toolbar_button): Add lrecord_header.
* tooltalk.c (struct Lisp_Tooltalk_Message): Add lrecord_header.
* tooltalk.c (make_tooltalk_message): Allocate as lrecord.
* tooltalk.c (struct Lisp_Tooltalk_Pattern): Add lrecord_header.
* tooltalk.c (make_tooltalk_pattern): Allocate as lrecord.
* ui-gtk.c (allocate_ffi_data): Allocate as lrecord.
* ui-gtk.c (allocate_emacs_gtk_object_data): Allocate as lrecord.
* ui-gtk.c (allocate_emacs_gtk_boxed_data): Allocate as lrecord.
* ui-gtk.h (structs): Add lrecord_header.
* window-impl.h (struct window): Add lrecord_header.
* window-impl.h (struct window_mirror): Add lrecord_header.
* window.c (allocate_window): Allocate as lrecord.
* window.c (new_window_mirror): Allocate as lrecord.
* window.c (make_dummy_parent): Allocate as lrecord.
MEMORY_USAGE_STATS
* alloc.c (fixed_type_block_overhead): Not used anymore, remove.
* buffer.c (compute_buffer_usage): Get storage size from new
allocator.
* marker.c (compute_buffer_marker_usage): Get storage size from
new allocator.
* mule-charset.c (compute_charset_usage): Get storage size from
new allocator.
* scrollbar-gtk.c (gtk_compute_scrollbar_instance_usage): Get
storage size from new allocator.
* scrollbar-msw.c (mswindows_compute_scrollbar_instance_usage):
Get storage size from new allocator.
* scrollbar-x.c (x_compute_scrollbar_instance_usage): Get
storage size from new allocator.
* scrollbar.c (compute_scrollbar_instance_usage): Get storage
size from new allocator.
* unicode.c (compute_from_unicode_table_size_1): Get storage
size from new allocator.
* unicode.c (compute_to_unicode_table_size_1): Get storage size
from new allocator.
* window.c (compute_window_mirror_usage): Get storage size from
new allocator.
* window.c (compute_window_usage): Get storage size from new
allocator.
MC_ALLOC_TYPE_STATS:
* alloc.c (alloc_lrecord): Bump lrecord count.
* alloc.c (noseeum_alloc_lrecord): Bump lrecord count.
* alloc.c (struct lrecord_stats): Storage for counts.
* alloc.c (init_lrecord_stats): Zero statistics.
* alloc.c (inc_lrecord_stats): Increase the statistic.
* alloc.c (dec_lrecord_stats): Decrease the statistic.
* alloc.c (gc_plist_hack): Used to print the information.
* alloc.c (Fgarbage_collect): Return the collected information.
* mc-alloc.c (remove_cell): Decrease lrecord count.
* mc-alloc.h: Set flag MC_ALLOC_TYPE_STATS.
* emacs.c (main_1): Init lrecord statistics.
* lrecord.h: Add prototypes for *_lrecord_stats.
Strings:
* alloc.c (Fmake_string): Initialize ascii_begin to zero.
* alloc.c (gc_count_num_short_string_in_use): Remove.
* alloc.c (gc_count_string_total_size): Remove.
* alloc.c (gc_count_short_string_total_size): Remove.
* alloc.c (debug_string_purity): Remove.
* alloc.c (debug_string_purity_print): Remove.
* alloc.c (sweep_strings): Remove.
Remove static C-readonly Lisp objects:
* alloc.c (c_readonly): Not needed anymore, remove.
* alloc.c (GC_CHECK_LHEADER_INVARIANTS): Remove some obsolete
lheader invariants assertions.
* buffer.c (DEFVAR_BUFFER_LOCAL_1): Allocate dynamically.
* console.c (DEFVAR_CONSOLE_LOCAL_1): Allocate dynamically.
* gpmevent.c: Indirection via MC_ALLOC_Freceive_gpm_event.
* gpmevent.c (Fgpm_enable): Allocate dynamically.
* gpmevent.c (syms_of_gpmevent): Allocate dynamically.
* lisp.h (C_READONLY): Not needed anymore, remove.
* lisp.h (DEFUN): Allocate dynamically.
* lrecord.h (C_READONLY_RECORD_HEADER_P): Not needed anymore,
remove.
* lrecord.h (SET_C_READONLY_RECORD_HEADER): Not needed anymore,
remove.
* symbols.c (guts_of_unbound_marker):
* symeval.h (defsubr): Allocate dynamically.
* symeval.h (DEFSUBR_MACRO): Allocate dynamically.
* symeval.h (DEFVAR_ SYMVAL_FWD): Allocate dynamically.
* tests.c (TESTS_DEFSUBR): Allocate dynamically.
Definition of mcpro:
* lisp.h: Add mcpro prototypes.
* alloc.c (common_init_alloc_early): Add initialization for
mcpros.
* alloc.c (mcpro_description_1): New.
* alloc.c (mcpro_description): New.
* alloc.c (mcpros_description_1): New.
* alloc.c (mcpros_description): New.
* alloc.c (mcpro_one_name_description_1): New.
* alloc.c (mcpro_one_name_description): New.
* alloc.c (mcpro_names_description_1): New.
* alloc.c (mcpro_names_description): New.
* alloc.c (mcpros): New.
* alloc.c (mcpro_names): New.
* alloc.c (mcpro_1): New.
* alloc.c (mc_pro): New.
* alloc.c (garbage_collect_1): Add mcpros to root set.
Usage of mcpro:
* alloc.c (make_string_nocopy): Add string to root set.
* symbols.c (init_symbols_once_early): Add Qunbound to root set.
Changes to the Portable Dumper:
* alloc.c (FREE_OR_REALLOC_BEGIN): Since dumped objects can be
freed with the new allocator, remove assertion for !DUMPEDP.
* dumper.c: Adjust comments, increase PDUMP_HASHSIZE.
* dumper.c (pdump_make_hash): Shift address only 2 bytes, to
avoid collisions.
* dumper.c (pdump_objects_unmark): No more mark bits within
the object, remove.
* dumper.c (mc_addr_elt): New. Element data structure for mc
hash table.
* dumper.c (pdump_mc_hash): New hash table: `lookup table'.
* dumper.c (pdump_get_mc_addr): New. Lookup for hash table.
* dumper.c (pdump_get_indirect_mc_addr): New. Lookup for
convertibles.
* dumper.c (pdump_put_mc_addr): New. Putter for hash table.
* dumper.c (pdump_dump_mc_data): New. Writes the table for
relocation at load time to the dump file.
* dumper.c (pdump_scan_lisp_objects_by_alignment): New.
Visits all dumped Lisp objects.
* dumper.c (pdump_scan_non_lisp_objects_by_alignment): New.
Visits all other dumped objects.
* dumper.c (pdump_reloc_one_mc): New. Updates all pointers
of an object by using the hash table pdump_mc_hash.
* dumper.c (pdump_reloc_one): Replaced by pdump_reloc_one_mc.
* dumper.c (pdump): Change the structure of the dump file, add
the mc post dump relocation table to dump file.
* dumper.c (pdump_load_finish): Hand all dumped objects to the
new allocator and use the mc post dump relocation table for
relocating the dumped objects at dump file load time, free not
longer used data structures.
* dumper.c (pdump_load): Free the dump file.
* dumper.h: Remove pdump_objects_unmark.
* lrecord.h (DUMPEDP): Dumped objects can be freed, remove.
DUMP_IN_EXEC:
* Makefile.in.in: Linking for and with dump in executable only if
DUMP_IN_EXEC is defined.
* config.h.in: Add new flag `DUMP_IN_EXEC'
* emacs.c: Condition dump-data.h on DUMP_IN_EXEC.
* emacs.c (main_1): Flag `-si' only works if dump image is
written into executable.
Miscellanious
* lrecord.h (enum lrecord_type): Added numbers to all types,
very handy for debugging.
* xemacs.def.in.in: Add mc-alloc functions to make them visible
to the modules.
author | crestani |
---|---|
date | Fri, 08 Apr 2005 23:11:35 +0000 |
parents | 5e4893b16f7c |
children | 1e7cc382eb16 |
rev | line source |
---|---|
428 | 1 /* Database access routines |
2 Copyright (C) 1996, William M. Perry | |
793 | 3 Copyright (C) 2001, 2002 Ben Wing. |
428 | 4 |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: Not in FSF. */ | |
23 | |
24 /* Written by Bill Perry */ | |
25 /* Substantially rewritten by Martin Buchholz */ | |
26 /* db 2.x support added by Andreas Jaeger */ | |
771 | 27 /* Mule-ized 6-22-00 Ben Wing */ |
428 | 28 |
29 #include <config.h> | |
30 #include "lisp.h" | |
771 | 31 |
428 | 32 #include "sysfile.h" |
33 #include "buffer.h" | |
34 | |
35 #ifndef HAVE_DATABASE | |
36 #error HAVE_DATABASE not defined!! | |
37 #endif | |
38 | |
39 #include "database.h" /* Our include file */ | |
40 | |
41 #ifdef HAVE_BERKELEY_DB | |
42 /* Work around Berkeley DB's use of int types which are defined | |
43 slightly differently in the not quite yet standard <inttypes.h>. | |
44 See db.h for details of why we're resorting to this... */ | |
45 /* glibc 2.1 doesn't have this problem with DB 2.x */ | |
46 #if !(defined __GLIBC__ && __GLIBC_MINOR__ >= 1) | |
47 #ifdef HAVE_INTTYPES_H | |
48 #define __BIT_TYPES_DEFINED__ | |
49 #include <inttypes.h> | |
2495 | 50 #if !defined(__FreeBSD__) && !defined(__NetBSD__) |
428 | 51 typedef uint8_t u_int8_t; |
52 typedef uint16_t u_int16_t; | |
53 typedef uint32_t u_int32_t; | |
54 #ifdef WE_DONT_NEED_QUADS | |
55 typedef uint64_t u_int64_t; | |
56 #endif /* WE_DONT_NEED_QUADS */ | |
1453 | 57 #endif /* __FreeBSD__ */ |
428 | 58 #endif /* HAVE_INTTYPES_H */ |
59 #endif /* !(defined __GLIBC__ && __GLIBC_MINOR__ >= 1) */ | |
1460 | 60 /* Berkeley DB wants __STDC__ to be defined; else if does `#define const' */ |
61 #if ! defined (__STDC__) && ! defined(__cplusplus) | |
62 #define __STDC__ 0 | |
63 #endif | |
442 | 64 #include DB_H_FILE /* Berkeley db's header file */ |
428 | 65 #ifndef DB_VERSION_MAJOR |
66 # define DB_VERSION_MAJOR 1 | |
67 #endif /* DB_VERSION_MAJOR */ | |
1141 | 68 #ifndef DB_VERSION_MINOR |
69 # define DB_VERSION_MINOR 0 | |
70 #endif /* DB_VERSION_MINOR */ | |
428 | 71 Lisp_Object Qberkeley_db; |
72 Lisp_Object Qhash, Qbtree, Qrecno, Qunknown; | |
448 | 73 #if DB_VERSION_MAJOR > 2 |
74 Lisp_Object Qqueue; | |
75 #endif | |
428 | 76 #endif /* HAVE_BERKELEY_DB */ |
77 | |
78 #ifdef HAVE_DBM | |
79 #include <ndbm.h> | |
80 Lisp_Object Qdbm; | |
81 #endif /* HAVE_DBM */ | |
82 | |
83 Lisp_Object Vdatabase_coding_system; | |
84 | |
85 Lisp_Object Qdatabasep; | |
86 | |
87 typedef struct | |
88 { | |
89 Lisp_Object (*get_subtype) (Lisp_Database *); | |
90 Lisp_Object (*get_type) (Lisp_Database *); | |
91 Lisp_Object (*get) (Lisp_Database *, Lisp_Object); | |
92 int (*put) (Lisp_Database *, Lisp_Object, Lisp_Object, Lisp_Object); | |
93 int (*rem) (Lisp_Database *, Lisp_Object); | |
94 void (*map) (Lisp_Database *, Lisp_Object); | |
95 void (*close) (Lisp_Database *); | |
96 Lisp_Object (*last_error) (Lisp_Database *); | |
97 } DB_FUNCS; | |
98 | |
99 struct Lisp_Database | |
100 { | |
2720 | 101 #ifdef MC_ALLOC |
102 struct lrecord_header header; | |
103 #else /* MC_ALLOC */ | |
428 | 104 struct lcrecord_header header; |
2720 | 105 #endif /* MC_ALLOC */ |
428 | 106 Lisp_Object fname; |
107 int mode; | |
108 int access_; | |
109 int dberrno; | |
110 int live_p; | |
111 #ifdef HAVE_DBM | |
112 DBM *dbm_handle; | |
113 #endif | |
114 #ifdef HAVE_BERKELEY_DB | |
115 DB *db_handle; | |
116 #endif | |
117 DB_FUNCS *funcs; | |
118 Lisp_Object coding_system; | |
119 }; | |
120 | |
121 #define XDATABASE(x) XRECORD (x, database, Lisp_Database) | |
617 | 122 #define wrap_database(p) wrap_record (p, database) |
428 | 123 #define DATABASEP(x) RECORDP (x, database) |
124 #define CHECK_DATABASE(x) CHECK_RECORD (x, database) | |
125 #define CONCHECK_DATABASE(x) CONCHECK_RECORD (x, database) | |
126 #define DATABASE_LIVE_P(x) (x->live_p) | |
127 | |
128 #define CHECK_LIVE_DATABASE(db) do { \ | |
129 CHECK_DATABASE (db); \ | |
130 if (!DATABASE_LIVE_P (XDATABASE(db))) \ | |
563 | 131 invalid_operation ("Attempting to access closed database", db); \ |
428 | 132 } while (0) |
133 | |
134 | |
135 static Lisp_Database * | |
136 allocate_database (void) | |
137 { | |
2720 | 138 #ifdef MC_ALLOC |
139 Lisp_Database *db = alloc_lrecord_type (Lisp_Database, &lrecord_database); | |
140 #else /* not MC_ALLOC */ | |
428 | 141 Lisp_Database *db = alloc_lcrecord_type (Lisp_Database, &lrecord_database); |
2720 | 142 #endif /* not MC_ALLOC */ |
428 | 143 |
144 db->fname = Qnil; | |
145 db->live_p = 0; | |
146 #ifdef HAVE_BERKELEY_DB | |
147 db->db_handle = NULL; | |
148 #endif | |
149 #ifdef HAVE_DBM | |
150 db->dbm_handle = NULL; | |
151 #endif | |
152 db->access_ = 0; | |
153 db->mode = 0; | |
154 db->dberrno = 0; | |
771 | 155 db->coding_system = Qnil; |
428 | 156 return db; |
157 } | |
158 | |
1204 | 159 static const struct memory_description database_description[] = { |
934 | 160 { XD_LISP_OBJECT, offsetof (struct Lisp_Database, fname) }, |
161 { XD_END} | |
162 }; | |
163 | |
428 | 164 static Lisp_Object |
444 | 165 mark_database (Lisp_Object object) |
428 | 166 { |
444 | 167 Lisp_Database *db = XDATABASE (object); |
428 | 168 return db->fname; |
169 } | |
170 | |
171 static void | |
2286 | 172 print_database (Lisp_Object obj, Lisp_Object printcharfun, |
173 int UNUSED (escapeflag)) | |
428 | 174 { |
175 Lisp_Database *db = XDATABASE (obj); | |
176 | |
177 if (print_readably) | |
563 | 178 printing_unreadable_object ("#<database 0x%x>", db->header.uid); |
428 | 179 |
793 | 180 write_fmt_string_lisp (printcharfun, "#<database \"%s\" (%s/%s/", |
181 3, db->fname, db->funcs->get_type (db), | |
182 db->funcs->get_subtype (db)); | |
183 | |
184 write_fmt_string (printcharfun, "%s) 0x%x>", | |
185 (!DATABASE_LIVE_P (db) ? "closed" : | |
186 (db->access_ & O_WRONLY) ? "writeonly" : | |
187 (db->access_ & O_RDWR) ? "readwrite" : "readonly"), | |
188 db->header.uid); | |
428 | 189 } |
190 | |
191 static void | |
192 finalize_database (void *header, int for_disksave) | |
193 { | |
194 Lisp_Database *db = (Lisp_Database *) header; | |
195 | |
196 if (for_disksave) | |
197 { | |
563 | 198 invalid_operation |
793 | 199 ("Can't dump an emacs containing database objects", |
200 wrap_database (db)); | |
428 | 201 } |
202 db->funcs->close (db); | |
203 } | |
204 | |
934 | 205 DEFINE_LRECORD_IMPLEMENTATION ("database", database, |
206 0, /*dumpable-flag*/ | |
207 mark_database, print_database, | |
208 finalize_database, 0, 0, | |
209 database_description, | |
210 Lisp_Database); | |
428 | 211 |
212 DEFUN ("close-database", Fclose_database, 1, 1, 0, /* | |
213 Close database DATABASE. | |
214 */ | |
215 (database)) | |
216 { | |
217 Lisp_Database *db; | |
218 CHECK_LIVE_DATABASE (database); | |
219 db = XDATABASE (database); | |
220 db->funcs->close (db); | |
221 db->live_p = 0; | |
222 return Qnil; | |
223 } | |
224 | |
225 DEFUN ("database-type", Fdatabase_type, 1, 1, 0, /* | |
226 Return the type of database DATABASE. | |
227 */ | |
228 (database)) | |
229 { | |
230 CHECK_DATABASE (database); | |
231 | |
232 return XDATABASE (database)->funcs->get_type (XDATABASE (database)); | |
233 } | |
234 | |
235 DEFUN ("database-subtype", Fdatabase_subtype, 1, 1, 0, /* | |
236 Return the subtype of database DATABASE, if any. | |
237 */ | |
238 (database)) | |
239 { | |
240 CHECK_DATABASE (database); | |
241 | |
242 return XDATABASE (database)->funcs->get_subtype (XDATABASE (database)); | |
243 } | |
244 | |
245 DEFUN ("database-live-p", Fdatabase_live_p, 1, 1, 0, /* | |
444 | 246 Return t if OBJECT is an active database. |
428 | 247 */ |
444 | 248 (object)) |
428 | 249 { |
444 | 250 return DATABASEP (object) && DATABASE_LIVE_P (XDATABASE (object)) ? |
251 Qt : Qnil; | |
428 | 252 } |
253 | |
254 DEFUN ("database-file-name", Fdatabase_file_name, 1, 1, 0, /* | |
255 Return the filename associated with the database DATABASE. | |
256 */ | |
257 (database)) | |
258 { | |
259 CHECK_DATABASE (database); | |
260 | |
261 return XDATABASE (database)->fname; | |
262 } | |
263 | |
264 DEFUN ("databasep", Fdatabasep, 1, 1, 0, /* | |
444 | 265 Return t if OBJECT is a database. |
428 | 266 */ |
444 | 267 (object)) |
428 | 268 { |
444 | 269 return DATABASEP (object) ? Qt : Qnil; |
428 | 270 } |
271 | |
272 #ifdef HAVE_DBM | |
273 static void | |
274 dbm_map (Lisp_Database *db, Lisp_Object func) | |
275 { | |
276 datum keydatum, valdatum; | |
277 Lisp_Object key, val; | |
278 | |
279 for (keydatum = dbm_firstkey (db->dbm_handle); | |
280 keydatum.dptr != NULL; | |
281 keydatum = dbm_nextkey (db->dbm_handle)) | |
282 { | |
283 valdatum = dbm_fetch (db->dbm_handle, keydatum); | |
771 | 284 key = make_ext_string (keydatum.dptr, keydatum.dsize, |
285 db->coding_system); | |
286 val = make_ext_string (valdatum.dptr, valdatum.dsize, | |
287 db->coding_system); | |
428 | 288 call2 (func, key, val); |
289 } | |
290 } | |
291 | |
292 static Lisp_Object | |
293 dbm_get (Lisp_Database *db, Lisp_Object key) | |
294 { | |
295 datum keydatum, valdatum; | |
296 | |
771 | 297 TO_EXTERNAL_FORMAT (LISP_STRING, key, |
298 ALLOCA, (keydatum.dptr, keydatum.dsize), | |
299 db->coding_system); | |
428 | 300 valdatum = dbm_fetch (db->dbm_handle, keydatum); |
301 | |
302 return (valdatum.dptr | |
771 | 303 ? make_ext_string (valdatum.dptr, valdatum.dsize, |
304 db->coding_system) | |
428 | 305 : Qnil); |
306 } | |
307 | |
308 static int | |
309 dbm_put (Lisp_Database *db, | |
310 Lisp_Object key, Lisp_Object val, Lisp_Object replace) | |
311 { | |
312 datum keydatum, valdatum; | |
313 | |
771 | 314 TO_EXTERNAL_FORMAT (LISP_STRING, val, |
315 ALLOCA, (valdatum.dptr, valdatum.dsize), | |
316 db->coding_system); | |
317 TO_EXTERNAL_FORMAT (LISP_STRING, key, | |
318 ALLOCA, (keydatum.dptr, keydatum.dsize), | |
319 db->coding_system); | |
428 | 320 |
321 return !dbm_store (db->dbm_handle, keydatum, valdatum, | |
322 NILP (replace) ? DBM_INSERT : DBM_REPLACE); | |
323 } | |
324 | |
325 static int | |
326 dbm_remove (Lisp_Database *db, Lisp_Object key) | |
327 { | |
328 datum keydatum; | |
329 | |
771 | 330 TO_EXTERNAL_FORMAT (LISP_STRING, key, |
331 ALLOCA, (keydatum.dptr, keydatum.dsize), | |
332 db->coding_system); | |
428 | 333 |
334 return dbm_delete (db->dbm_handle, keydatum); | |
335 } | |
336 | |
337 static Lisp_Object | |
2494 | 338 dbm_type (Lisp_Database *UNUSED (db)) |
428 | 339 { |
340 return Qdbm; | |
341 } | |
342 | |
343 static Lisp_Object | |
2494 | 344 dbm_subtype (Lisp_Database *UNUSED (db)) |
428 | 345 { |
346 return Qnil; | |
347 } | |
348 | |
349 static Lisp_Object | |
350 dbm_lasterr (Lisp_Database *db) | |
351 { | |
352 return lisp_strerror (db->dberrno); | |
353 } | |
354 | |
355 static void | |
356 dbm_closeit (Lisp_Database *db) | |
357 { | |
358 if (db->dbm_handle) | |
359 { | |
360 dbm_close (db->dbm_handle); | |
361 db->dbm_handle = NULL; | |
362 } | |
363 } | |
364 | |
365 static DB_FUNCS ndbm_func_block = | |
366 { | |
367 dbm_subtype, | |
368 dbm_type, | |
369 dbm_get, | |
370 dbm_put, | |
371 dbm_remove, | |
372 dbm_map, | |
373 dbm_closeit, | |
374 dbm_lasterr | |
375 }; | |
376 #endif /* HAVE_DBM */ | |
377 | |
378 #ifdef HAVE_BERKELEY_DB | |
379 static Lisp_Object | |
2286 | 380 berkdb_type (Lisp_Database *UNUSED (db)) |
428 | 381 { |
382 return Qberkeley_db; | |
383 } | |
384 | |
385 static Lisp_Object | |
386 berkdb_subtype (Lisp_Database *db) | |
387 { | |
388 if (!db->db_handle) | |
389 return Qnil; | |
390 | |
391 switch (db->db_handle->type) | |
392 { | |
393 case DB_BTREE: return Qbtree; | |
394 case DB_HASH: return Qhash; | |
395 case DB_RECNO: return Qrecno; | |
448 | 396 #if DB_VERSION_MAJOR > 2 |
397 case DB_QUEUE: return Qqueue; | |
398 #endif | |
428 | 399 default: return Qunknown; |
400 } | |
401 } | |
402 | |
403 static Lisp_Object | |
404 berkdb_lasterr (Lisp_Database *db) | |
405 { | |
406 return lisp_strerror (db->dberrno); | |
407 } | |
408 | |
409 static Lisp_Object | |
410 berkdb_get (Lisp_Database *db, Lisp_Object key) | |
411 { | |
412 DBT keydatum, valdatum; | |
413 int status = 0; | |
414 | |
415 /* DB Version 2 requires DBT's to be zeroed before use. */ | |
416 xzero (keydatum); | |
417 xzero (valdatum); | |
418 | |
771 | 419 TO_EXTERNAL_FORMAT (LISP_STRING, key, |
420 ALLOCA, (keydatum.data, keydatum.size), | |
421 db->coding_system); | |
428 | 422 |
423 #if DB_VERSION_MAJOR == 1 | |
424 status = db->db_handle->get (db->db_handle, &keydatum, &valdatum, 0); | |
425 #else | |
426 status = db->db_handle->get (db->db_handle, NULL, &keydatum, &valdatum, 0); | |
427 #endif /* DB_VERSION_MAJOR */ | |
428 | |
429 if (!status) | |
1645 | 430 return make_ext_string ((const Extbyte *) valdatum.data, valdatum.size, |
771 | 431 db->coding_system); |
428 | 432 |
433 #if DB_VERSION_MAJOR == 1 | |
434 db->dberrno = (status == 1) ? -1 : errno; | |
435 #else | |
436 db->dberrno = (status < 0) ? -1 : errno; | |
437 #endif /* DB_VERSION_MAJOR */ | |
438 | |
439 return Qnil; | |
440 } | |
441 | |
442 static int | |
443 berkdb_put (Lisp_Database *db, | |
444 Lisp_Object key, | |
445 Lisp_Object val, | |
446 Lisp_Object replace) | |
447 { | |
448 DBT keydatum, valdatum; | |
449 int status = 0; | |
450 | |
451 /* DB Version 2 requires DBT's to be zeroed before use. */ | |
452 xzero (keydatum); | |
453 xzero (valdatum); | |
454 | |
771 | 455 TO_EXTERNAL_FORMAT (LISP_STRING, key, |
456 ALLOCA, (keydatum.data, keydatum.size), | |
457 db->coding_system); | |
458 TO_EXTERNAL_FORMAT (LISP_STRING, val, | |
459 ALLOCA, (valdatum.data, valdatum.size), | |
460 db->coding_system); | |
428 | 461 #if DB_VERSION_MAJOR == 1 |
462 status = db->db_handle->put (db->db_handle, &keydatum, &valdatum, | |
463 NILP (replace) ? R_NOOVERWRITE : 0); | |
464 db->dberrno = (status == 1) ? -1 : errno; | |
465 #else | |
466 status = db->db_handle->put (db->db_handle, NULL, &keydatum, &valdatum, | |
467 NILP (replace) ? DB_NOOVERWRITE : 0); | |
468 db->dberrno = (status < 0) ? -1 : errno; | |
469 #endif/* DV_VERSION_MAJOR = 2 */ | |
470 | |
471 return status; | |
472 } | |
473 | |
474 static int | |
475 berkdb_remove (Lisp_Database *db, Lisp_Object key) | |
476 { | |
477 DBT keydatum; | |
478 int status; | |
479 | |
480 /* DB Version 2 requires DBT's to be zeroed before use. */ | |
481 xzero (keydatum); | |
482 | |
771 | 483 TO_EXTERNAL_FORMAT (LISP_STRING, key, |
484 ALLOCA, (keydatum.data, keydatum.size), | |
485 db->coding_system); | |
428 | 486 |
487 #if DB_VERSION_MAJOR == 1 | |
488 status = db->db_handle->del (db->db_handle, &keydatum, 0); | |
489 #else | |
490 status = db->db_handle->del (db->db_handle, NULL, &keydatum, 0); | |
491 #endif /* DB_VERSION_MAJOR */ | |
492 | |
493 if (!status) | |
494 return 0; | |
495 | |
496 #if DB_VERSION_MAJOR == 1 | |
497 db->dberrno = (status == 1) ? -1 : errno; | |
498 #else | |
499 db->dberrno = (status < 0) ? -1 : errno; | |
500 #endif /* DB_VERSION_MAJOR */ | |
501 | |
502 return 1; | |
503 } | |
504 | |
505 static void | |
506 berkdb_map (Lisp_Database *db, Lisp_Object func) | |
507 { | |
508 DBT keydatum, valdatum; | |
509 Lisp_Object key, val; | |
510 DB *dbp = db->db_handle; | |
511 int status; | |
512 | |
513 xzero (keydatum); | |
514 xzero (valdatum); | |
515 | |
516 #if DB_VERSION_MAJOR == 1 | |
517 for (status = dbp->seq (dbp, &keydatum, &valdatum, R_FIRST); | |
518 status == 0; | |
519 status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT)) | |
520 { | |
2646 | 521 key = make_ext_string ((const Extbyte *) keydatum.data, keydatum.size, |
771 | 522 db->coding_system); |
2646 | 523 val = make_ext_string ((const Extbyte *) valdatum.data, valdatum.size, |
771 | 524 db->coding_system); |
428 | 525 call2 (func, key, val); |
526 } | |
527 #else | |
528 { | |
529 DBC *dbcp; | |
530 | |
531 #if DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >=6 | |
532 status = dbp->cursor (dbp, NULL, &dbcp, 0); | |
533 #else | |
534 status = dbp->cursor (dbp, NULL, &dbcp); | |
440 | 535 #endif |
428 | 536 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST); |
537 status == 0; | |
538 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT)) | |
539 { | |
1645 | 540 key = make_ext_string ((const Extbyte *) keydatum.data, keydatum.size, |
771 | 541 db->coding_system); |
1645 | 542 val = make_ext_string ((const Extbyte *) valdatum.data, valdatum.size, |
771 | 543 db->coding_system); |
428 | 544 call2 (func, key, val); |
545 } | |
546 dbcp->c_close (dbcp); | |
547 } | |
548 #endif /* DB_VERSION_MAJOR */ | |
549 } | |
550 | |
551 static void | |
552 berkdb_close (Lisp_Database *db) | |
553 { | |
554 if (db->db_handle) | |
555 { | |
556 #if DB_VERSION_MAJOR == 1 | |
557 db->db_handle->sync (db->db_handle, 0); | |
558 db->db_handle->close (db->db_handle); | |
559 #else | |
560 db->db_handle->sync (db->db_handle, 0); | |
561 db->db_handle->close (db->db_handle, 0); | |
562 #endif /* DB_VERSION_MAJOR */ | |
563 db->db_handle = NULL; | |
564 } | |
565 } | |
566 | |
567 static DB_FUNCS berk_func_block = | |
568 { | |
569 berkdb_subtype, | |
570 berkdb_type, | |
571 berkdb_get, | |
572 berkdb_put, | |
573 berkdb_remove, | |
574 berkdb_map, | |
575 berkdb_close, | |
576 berkdb_lasterr | |
577 }; | |
578 #endif /* HAVE_BERKELEY_DB */ | |
579 | |
580 DEFUN ("database-last-error", Fdatabase_last_error, 0, 1, 0, /* | |
581 Return the last error associated with DATABASE. | |
582 */ | |
583 (database)) | |
584 { | |
585 if (NILP (database)) | |
586 return lisp_strerror (errno); | |
587 | |
588 CHECK_DATABASE (database); | |
589 | |
590 return XDATABASE (database)->funcs->last_error (XDATABASE (database)); | |
591 } | |
592 | |
771 | 593 DEFUN ("open-database", Fopen_database, 1, 6, 0, /* |
428 | 594 Return a new database object opened on FILE. |
595 Optional arguments TYPE and SUBTYPE specify the database type. | |
596 Optional argument ACCESS specifies the access rights, which may be any | |
597 combination of 'r' 'w' and '+', for read, write, and creation flags. | |
598 Optional argument MODE gives the permissions to use when opening FILE, | |
599 and defaults to 0755. | |
771 | 600 Optional argument CODESYS specifies the coding system used to encode/decode |
601 data passed to/from the database, and defaults to the value of the | |
602 variable `database-coding-system'. | |
428 | 603 */ |
771 | 604 (file, type, subtype, access_, mode, codesys)) |
428 | 605 { |
606 /* This function can GC */ | |
607 int modemask; | |
608 int accessmask = 0; | |
609 Lisp_Database *db = NULL; | |
610 char *filename; | |
611 struct gcpro gcpro1, gcpro2; | |
612 | |
613 CHECK_STRING (file); | |
614 GCPRO2 (file, access_); | |
615 file = Fexpand_file_name (file, Qnil); | |
616 UNGCPRO; | |
617 | |
440 | 618 TO_EXTERNAL_FORMAT (LISP_STRING, file, |
619 C_STRING_ALLOCA, filename, | |
620 Qfile_name); | |
428 | 621 |
622 if (NILP (access_)) | |
623 { | |
624 accessmask = O_RDWR | O_CREAT; | |
625 } | |
626 else | |
627 { | |
628 char *acc; | |
629 CHECK_STRING (access_); | |
630 acc = (char *) XSTRING_DATA (access_); | |
631 | |
632 if (strchr (acc, '+')) | |
633 accessmask |= O_CREAT; | |
634 | |
635 { | |
636 char *rp = strchr (acc, 'r'); | |
637 char *wp = strchr (acc, 'w'); | |
638 if (rp && wp) accessmask |= O_RDWR; | |
639 else if (wp) accessmask |= O_WRONLY; | |
640 else accessmask |= O_RDONLY; | |
641 } | |
642 } | |
643 | |
644 if (NILP (mode)) | |
645 { | |
646 modemask = 0755; /* rwxr-xr-x */ | |
647 } | |
648 else | |
649 { | |
650 CHECK_INT (mode); | |
651 modemask = XINT (mode); | |
652 } | |
653 | |
771 | 654 if (NILP (codesys)) |
655 codesys = Vdatabase_coding_system; | |
656 | |
657 codesys = get_coding_system_for_text_file (Vdatabase_coding_system, 1); | |
658 | |
428 | 659 #ifdef HAVE_DBM |
660 if (NILP (type) || EQ (type, Qdbm)) | |
661 { | |
662 DBM *dbase = dbm_open (filename, accessmask, modemask); | |
663 if (!dbase) | |
664 return Qnil; | |
665 | |
666 db = allocate_database (); | |
667 db->dbm_handle = dbase; | |
668 db->funcs = &ndbm_func_block; | |
771 | 669 db->coding_system = codesys; |
428 | 670 goto db_done; |
671 } | |
672 #endif /* HAVE_DBM */ | |
673 | |
674 #ifdef HAVE_BERKELEY_DB | |
675 if (NILP (type) || EQ (type, Qberkeley_db)) | |
676 { | |
677 DBTYPE real_subtype; | |
678 DB *dbase; | |
679 #if DB_VERSION_MAJOR != 1 | |
680 int status; | |
681 #endif | |
682 | |
683 if (EQ (subtype, Qhash) || NILP (subtype)) | |
684 real_subtype = DB_HASH; | |
685 else if (EQ (subtype, Qbtree)) | |
686 real_subtype = DB_BTREE; | |
687 else if (EQ (subtype, Qrecno)) | |
688 real_subtype = DB_RECNO; | |
448 | 689 #if DB_VERSION_MAJOR > 2 |
690 else if (EQ (subtype, Qqueue)) | |
691 real_subtype = DB_QUEUE; | |
692 #endif | |
428 | 693 else |
563 | 694 invalid_constant ("Unsupported subtype", subtype); |
428 | 695 |
696 #if DB_VERSION_MAJOR == 1 | |
697 dbase = dbopen (filename, accessmask, modemask, real_subtype, NULL); | |
698 if (!dbase) | |
699 return Qnil; | |
700 #else | |
701 /* Berkeley DB Version 2 has only the accessmask DB_CREATE and DB_RDONLY, | |
702 other flags shouldn't be set */ | |
703 if (NILP (access_)) | |
704 accessmask = DB_CREATE; | |
705 else | |
706 { | |
707 char *acc; | |
708 CHECK_STRING (access_); | |
709 acc = (char *) XSTRING_DATA (access_); | |
710 accessmask = 0; | |
711 | |
712 if (strchr (acc, '+')) | |
713 accessmask |= DB_CREATE; | |
714 | |
715 if (strchr (acc, 'r') && !strchr (acc, 'w')) | |
716 accessmask |= DB_RDONLY; | |
717 } | |
448 | 718 #if DB_VERSION_MAJOR == 2 |
428 | 719 status = db_open (filename, real_subtype, accessmask, |
720 modemask, NULL , NULL, &dbase); | |
721 if (status) | |
722 return Qnil; | |
448 | 723 #else |
724 status = db_create (&dbase, NULL, 0); | |
725 if (status) | |
726 return Qnil; | |
1141 | 727 #if DB_VERSION_MAJOR < 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1) |
448 | 728 status = dbase->open (dbase, filename, NULL, |
729 real_subtype, accessmask, modemask); | |
1141 | 730 #else /* DB_VERSION >= 4.1 */ |
1377 | 731 /* You can't use DB_AUTO_COMMIT unless you have a txn environment. */ |
1141 | 732 status = dbase->open (dbase, NULL, filename, NULL, real_subtype, |
1377 | 733 accessmask, modemask); |
1141 | 734 #endif /* DB_VERSION < 4.1 */ |
448 | 735 if (status) |
736 { | |
737 dbase->close (dbase, 0); | |
738 return Qnil; | |
739 } | |
740 #endif /* DB_VERSION_MAJOR > 2 */ | |
741 /* Normalize into system specific file modes. Only for printing */ | |
742 accessmask = accessmask & DB_RDONLY ? O_RDONLY : O_RDWR; | |
428 | 743 #endif /* DB_VERSION_MAJOR */ |
744 | |
745 db = allocate_database (); | |
746 db->db_handle = dbase; | |
747 db->funcs = &berk_func_block; | |
771 | 748 db->coding_system = codesys; |
428 | 749 goto db_done; |
750 } | |
751 #endif /* HAVE_BERKELEY_DB */ | |
752 | |
563 | 753 invalid_constant ("Unsupported database type", type); |
428 | 754 return Qnil; |
755 | |
756 db_done: | |
757 db->live_p = 1; | |
758 db->fname = file; | |
759 db->mode = modemask; | |
760 db->access_ = accessmask; | |
761 | |
793 | 762 return wrap_database (db); |
428 | 763 } |
764 | |
765 DEFUN ("put-database", Fput_database, 3, 4, 0, /* | |
766 Store KEY and VALUE in DATABASE. | |
767 If optional fourth arg REPLACE is non-nil, | |
768 replace any existing entry in the database. | |
769 */ | |
770 (key, value, database, replace)) | |
771 { | |
772 CHECK_LIVE_DATABASE (database); | |
773 CHECK_STRING (key); | |
774 CHECK_STRING (value); | |
775 { | |
776 Lisp_Database *db = XDATABASE (database); | |
777 int status = db->funcs->put (db, key, value, replace); | |
778 return status ? Qt : Qnil; | |
779 } | |
780 } | |
781 | |
782 DEFUN ("remove-database", Fremove_database, 2, 2, 0, /* | |
783 Remove KEY from DATABASE. | |
784 */ | |
785 (key, database)) | |
786 { | |
787 CHECK_LIVE_DATABASE (database); | |
788 CHECK_STRING (key); | |
789 { | |
790 Lisp_Database *db = XDATABASE (database); | |
791 int status = db->funcs->rem (db, key); | |
792 return status ? Qt : Qnil; | |
793 } | |
794 } | |
795 | |
796 DEFUN ("get-database", Fget_database, 2, 3, 0, /* | |
797 Return value for KEY in DATABASE. | |
798 If there is no corresponding value, return DEFAULT (defaults to nil). | |
799 */ | |
800 (key, database, default_)) | |
801 { | |
802 CHECK_LIVE_DATABASE (database); | |
803 CHECK_STRING (key); | |
804 { | |
805 Lisp_Database *db = XDATABASE (database); | |
806 Lisp_Object retval = db->funcs->get (db, key); | |
807 return NILP (retval) ? default_ : retval; | |
808 } | |
809 } | |
810 | |
811 DEFUN ("map-database", Fmapdatabase, 2, 2, 0, /* | |
812 Map FUNCTION over entries in DATABASE, calling it with two args, | |
813 each key and value in the database. | |
814 */ | |
815 (function, database)) | |
816 { | |
817 CHECK_LIVE_DATABASE (database); | |
818 | |
819 XDATABASE (database)->funcs->map (XDATABASE (database), function); | |
820 | |
821 return Qnil; | |
822 } | |
823 | |
824 void | |
825 syms_of_database (void) | |
826 { | |
442 | 827 INIT_LRECORD_IMPLEMENTATION (database); |
828 | |
563 | 829 DEFSYMBOL (Qdatabasep); |
428 | 830 #ifdef HAVE_DBM |
563 | 831 DEFSYMBOL (Qdbm); |
428 | 832 #endif |
833 #ifdef HAVE_BERKELEY_DB | |
563 | 834 DEFSYMBOL (Qberkeley_db); |
835 DEFSYMBOL (Qhash); | |
836 DEFSYMBOL (Qbtree); | |
837 DEFSYMBOL (Qrecno); | |
448 | 838 #if DB_VERSION_MAJOR > 2 |
563 | 839 DEFSYMBOL (Qqueue); |
448 | 840 #endif |
563 | 841 DEFSYMBOL (Qunknown); |
428 | 842 #endif |
843 | |
844 DEFSUBR (Fopen_database); | |
845 DEFSUBR (Fdatabasep); | |
846 DEFSUBR (Fmapdatabase); | |
847 DEFSUBR (Fput_database); | |
848 DEFSUBR (Fget_database); | |
849 DEFSUBR (Fremove_database); | |
850 DEFSUBR (Fdatabase_type); | |
851 DEFSUBR (Fdatabase_subtype); | |
852 DEFSUBR (Fdatabase_last_error); | |
853 DEFSUBR (Fdatabase_live_p); | |
854 DEFSUBR (Fdatabase_file_name); | |
855 DEFSUBR (Fclose_database); | |
856 } | |
857 | |
858 void | |
859 vars_of_database (void) | |
860 { | |
861 #ifdef HAVE_DBM | |
862 Fprovide (Qdbm); | |
863 #endif | |
864 #ifdef HAVE_BERKELEY_DB | |
865 Fprovide (Qberkeley_db); | |
866 #endif | |
867 | |
868 DEFVAR_LISP ("database-coding-system", &Vdatabase_coding_system /* | |
771 | 869 Default coding system used to convert data in database files. |
428 | 870 */ ); |
771 | 871 Vdatabase_coding_system = Qnative; |
428 | 872 } |