Mercurial > hg > xemacs-beta
annotate src/README.global-renaming @ 5127:a9c41067dd88 ben-lisp-object
more cleanups, terminology clarification, lots of doc work
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Introduction to Allocation):
* internals/internals.texi (Integers and Characters):
* internals/internals.texi (Allocation from Frob Blocks):
* internals/internals.texi (lrecords):
* internals/internals.texi (Low-level allocation):
Rewrite section on allocation of Lisp objects to reflect the new
reality. Remove references to nonexistent XSETINT and XSETCHAR.
modules/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c (allocate_pgconn):
* postgresql/postgresql.c (allocate_pgresult):
* postgresql/postgresql.h (struct Lisp_PGconn):
* postgresql/postgresql.h (struct Lisp_PGresult):
* ldap/eldap.c (allocate_ldap):
* ldap/eldap.h (struct Lisp_LDAP):
Same changes as in src/ dir. See large log there in ChangeLog,
but basically:
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
../hlo/src/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (old_alloc_sized_lcrecord):
* alloc.c (very_old_free_lcrecord):
* alloc.c (copy_lisp_object):
* alloc.c (zero_sized_lisp_object):
* alloc.c (zero_nonsized_lisp_object):
* alloc.c (lisp_object_storage_size):
* alloc.c (free_normal_lisp_object):
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC):
* alloc.c (ALLOC_FROB_BLOCK_LISP_OBJECT):
* alloc.c (Fcons):
* alloc.c (noseeum_cons):
* alloc.c (make_float):
* alloc.c (make_bignum):
* alloc.c (make_bignum_bg):
* alloc.c (make_ratio):
* alloc.c (make_ratio_bg):
* alloc.c (make_ratio_rt):
* alloc.c (make_bigfloat):
* alloc.c (make_bigfloat_bf):
* alloc.c (size_vector):
* alloc.c (make_compiled_function):
* alloc.c (Fmake_symbol):
* alloc.c (allocate_extent):
* alloc.c (allocate_event):
* alloc.c (make_key_data):
* alloc.c (make_button_data):
* alloc.c (make_motion_data):
* alloc.c (make_process_data):
* alloc.c (make_timeout_data):
* alloc.c (make_magic_data):
* alloc.c (make_magic_eval_data):
* alloc.c (make_eval_data):
* alloc.c (make_misc_user_data):
* alloc.c (Fmake_marker):
* alloc.c (noseeum_make_marker):
* alloc.c (size_string_direct_data):
* alloc.c (make_uninit_string):
* alloc.c (make_string_nocopy):
* alloc.c (mark_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (sweep_lcrecords_1):
* alloc.c (malloced_storage_size):
* buffer.c (allocate_buffer):
* buffer.c (compute_buffer_usage):
* buffer.c (DEFVAR_BUFFER_LOCAL_1):
* buffer.c (nuke_all_buffer_slots):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.h (struct buffer_text):
* buffer.h (struct buffer):
* bytecode.c:
* bytecode.c (make_compiled_function_args):
* bytecode.c (size_compiled_function_args):
* bytecode.h (struct compiled_function_args):
* casetab.c (allocate_case_table):
* casetab.h (struct Lisp_Case_Table):
* charset.h (struct Lisp_Charset):
* chartab.c (fill_char_table):
* chartab.c (Fmake_char_table):
* chartab.c (make_char_table_entry):
* chartab.c (copy_char_table_entry):
* chartab.c (Fcopy_char_table):
* chartab.c (put_char_table):
* chartab.h (struct Lisp_Char_Table_Entry):
* chartab.h (struct Lisp_Char_Table):
* console-gtk-impl.h (struct gtk_device):
* console-gtk-impl.h (struct gtk_frame):
* console-impl.h (struct console):
* console-msw-impl.h (struct Lisp_Devmode):
* console-msw-impl.h (struct mswindows_device):
* console-msw-impl.h (struct msprinter_device):
* console-msw-impl.h (struct mswindows_frame):
* console-msw-impl.h (struct mswindows_dialog_id):
* console-stream-impl.h (struct stream_console):
* console-stream.c (stream_init_console):
* console-tty-impl.h (struct tty_console):
* console-tty-impl.h (struct tty_device):
* console-tty.c (allocate_tty_console_struct):
* console-x-impl.h (struct x_device):
* console-x-impl.h (struct x_frame):
* console.c (allocate_console):
* console.c (nuke_all_console_slots):
* console.c (DEFVAR_CONSOLE_LOCAL_1):
* console.c (common_init_complex_vars_of_console):
* data.c (make_weak_list):
* data.c (make_weak_box):
* data.c (make_ephemeron):
* database.c:
* database.c (struct Lisp_Database):
* database.c (allocate_database):
* database.c (finalize_database):
* device-gtk.c (allocate_gtk_device_struct):
* device-impl.h (struct device):
* device-msw.c:
* device-msw.c (mswindows_init_device):
* device-msw.c (msprinter_init_device):
* device-msw.c (finalize_devmode):
* device-msw.c (allocate_devmode):
* device-tty.c (allocate_tty_device_struct):
* device-x.c (allocate_x_device_struct):
* device.c:
* device.c (nuke_all_device_slots):
* device.c (allocate_device):
* dialog-msw.c (handle_question_dialog_box):
* elhash.c:
* elhash.c (struct Lisp_Hash_Table):
* elhash.c (finalize_hash_table):
* elhash.c (make_general_lisp_hash_table):
* elhash.c (Fcopy_hash_table):
* elhash.h (htentry):
* emacs.c (main_1):
* eval.c:
* eval.c (size_multiple_value):
* event-stream.c (finalize_command_builder):
* event-stream.c (allocate_command_builder):
* event-stream.c (free_command_builder):
* event-stream.c (event_stream_generate_wakeup):
* event-stream.c (event_stream_resignal_wakeup):
* event-stream.c (event_stream_disable_wakeup):
* event-stream.c (event_stream_wakeup_pending_p):
* events.h (struct Lisp_Timeout):
* events.h (struct command_builder):
* extents-impl.h:
* extents-impl.h (struct extent_auxiliary):
* extents-impl.h (struct extent_info):
* extents-impl.h (set_extent_no_chase_aux_field):
* extents-impl.h (set_extent_no_chase_normal_field):
* extents.c:
* extents.c (gap_array_marker):
* extents.c (gap_array):
* extents.c (extent_list_marker):
* extents.c (extent_list):
* extents.c (stack_of_extents):
* extents.c (gap_array_make_marker):
* extents.c (extent_list_make_marker):
* extents.c (allocate_extent_list):
* extents.c (SLOT):
* extents.c (mark_extent_auxiliary):
* extents.c (allocate_extent_auxiliary):
* extents.c (attach_extent_auxiliary):
* extents.c (size_gap_array):
* extents.c (finalize_extent_info):
* extents.c (allocate_extent_info):
* extents.c (uninit_buffer_extents):
* extents.c (allocate_soe):
* extents.c (copy_extent):
* extents.c (vars_of_extents):
* extents.h:
* faces.c (allocate_face):
* faces.h (struct Lisp_Face):
* faces.h (struct face_cachel):
* file-coding.c:
* file-coding.c (finalize_coding_system):
* file-coding.c (sizeof_coding_system):
* file-coding.c (Fcopy_coding_system):
* file-coding.h (struct Lisp_Coding_System):
* file-coding.h (MARKED_SLOT):
* fns.c (size_bit_vector):
* font-mgr.c:
* font-mgr.c (finalize_fc_pattern):
* font-mgr.c (print_fc_pattern):
* font-mgr.c (Ffc_pattern_p):
* font-mgr.c (Ffc_pattern_create):
* font-mgr.c (Ffc_name_parse):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* font-mgr.c (Ffc_pattern_add):
* font-mgr.c (Ffc_pattern_del):
* font-mgr.c (Ffc_pattern_get):
* font-mgr.c (fc_config_create_using):
* font-mgr.c (fc_strlist_to_lisp_using):
* font-mgr.c (fontset_to_list):
* font-mgr.c (Ffc_config_p):
* font-mgr.c (Ffc_config_up_to_date):
* font-mgr.c (Ffc_config_build_fonts):
* font-mgr.c (Ffc_config_get_cache):
* font-mgr.c (Ffc_config_get_fonts):
* font-mgr.c (Ffc_config_set_current):
* font-mgr.c (Ffc_config_get_blanks):
* font-mgr.c (Ffc_config_get_rescan_interval):
* font-mgr.c (Ffc_config_set_rescan_interval):
* font-mgr.c (Ffc_config_app_font_add_file):
* font-mgr.c (Ffc_config_app_font_add_dir):
* font-mgr.c (Ffc_config_app_font_clear):
* font-mgr.c (size):
* font-mgr.c (Ffc_config_substitute):
* font-mgr.c (Ffc_font_render_prepare):
* font-mgr.c (Ffc_font_match):
* font-mgr.c (Ffc_font_sort):
* font-mgr.c (finalize_fc_config):
* font-mgr.c (print_fc_config):
* font-mgr.h:
* font-mgr.h (struct fc_pattern):
* font-mgr.h (XFC_PATTERN):
* font-mgr.h (struct fc_config):
* font-mgr.h (XFC_CONFIG):
* frame-gtk.c (allocate_gtk_frame_struct):
* frame-impl.h (struct frame):
* frame-msw.c (mswindows_init_frame_1):
* frame-x.c (allocate_x_frame_struct):
* frame.c (nuke_all_frame_slots):
* frame.c (allocate_frame_core):
* gc.c:
* gc.c (GC_CHECK_NOT_FREE):
* glyphs.c (finalize_image_instance):
* glyphs.c (allocate_image_instance):
* glyphs.c (Fcolorize_image_instance):
* glyphs.c (allocate_glyph):
* glyphs.c (unmap_subwindow_instance_cache_mapper):
* glyphs.c (register_ignored_expose):
* glyphs.h (struct Lisp_Image_Instance):
* glyphs.h (struct Lisp_Glyph):
* glyphs.h (struct glyph_cachel):
* glyphs.h (struct expose_ignore):
* gui.c (allocate_gui_item):
* gui.h (struct Lisp_Gui_Item):
* keymap.c (struct Lisp_Keymap):
* keymap.c (make_keymap):
* lisp.h:
* lisp.h (struct Lisp_String_Direct_Data):
* lisp.h (struct Lisp_String_Indirect_Data):
* lisp.h (struct Lisp_Vector):
* lisp.h (struct Lisp_Bit_Vector):
* lisp.h (DECLARE_INLINE_LISP_BIT_VECTOR):
* lisp.h (struct weak_box):
* lisp.h (struct ephemeron):
* lisp.h (struct weak_list):
* lrecord.h:
* lrecord.h (struct lrecord_implementation):
* lrecord.h (MC_ALLOC_CALL_FINALIZER):
* lrecord.h (struct lcrecord_list):
* lstream.c (finalize_lstream):
* lstream.c (sizeof_lstream):
* lstream.c (Lstream_new):
* lstream.c (Lstream_delete):
* lstream.h (struct lstream):
* marker.c:
* marker.c (finalize_marker):
* marker.c (compute_buffer_marker_usage):
* mule-charset.c:
* mule-charset.c (make_charset):
* mule-charset.c (compute_charset_usage):
* objects-impl.h (struct Lisp_Color_Instance):
* objects-impl.h (struct Lisp_Font_Instance):
* objects-tty-impl.h (struct tty_color_instance_data):
* objects-tty-impl.h (struct tty_font_instance_data):
* objects-tty.c (tty_initialize_color_instance):
* objects-tty.c (tty_initialize_font_instance):
* objects.c (finalize_color_instance):
* objects.c (Fmake_color_instance):
* objects.c (finalize_font_instance):
* objects.c (Fmake_font_instance):
* objects.c (reinit_vars_of_objects):
* opaque.c:
* opaque.c (sizeof_opaque):
* opaque.c (make_opaque_ptr):
* opaque.c (free_opaque_ptr):
* opaque.h:
* opaque.h (Lisp_Opaque):
* opaque.h (Lisp_Opaque_Ptr):
* print.c (printing_unreadable_lcrecord):
* print.c (external_object_printer):
* print.c (debug_p4):
* process.c (finalize_process):
* process.c (make_process_internal):
* procimpl.h (struct Lisp_Process):
* rangetab.c (Fmake_range_table):
* rangetab.c (Fcopy_range_table):
* rangetab.h (struct Lisp_Range_Table):
* scrollbar.c:
* scrollbar.c (create_scrollbar_instance):
* scrollbar.c (compute_scrollbar_instance_usage):
* scrollbar.h (struct scrollbar_instance):
* specifier.c (finalize_specifier):
* specifier.c (sizeof_specifier):
* specifier.c (set_specifier_caching):
* specifier.h (struct Lisp_Specifier):
* specifier.h (struct specifier_caching):
* symeval.h:
* symeval.h (SYMBOL_VALUE_MAGIC_P):
* symeval.h (DEFVAR_SYMVAL_FWD):
* symsinit.h:
* syntax.c (init_buffer_syntax_cache):
* syntax.h (struct syntax_cache):
* toolbar.c:
* toolbar.c (allocate_toolbar_button):
* toolbar.c (update_toolbar_button):
* toolbar.h (struct toolbar_button):
* tooltalk.c (struct Lisp_Tooltalk_Message):
* tooltalk.c (make_tooltalk_message):
* tooltalk.c (struct Lisp_Tooltalk_Pattern):
* tooltalk.c (make_tooltalk_pattern):
* ui-gtk.c:
* ui-gtk.c (allocate_ffi_data):
* ui-gtk.c (emacs_gtk_object_finalizer):
* ui-gtk.c (allocate_emacs_gtk_object_data):
* ui-gtk.c (allocate_emacs_gtk_boxed_data):
* ui-gtk.h:
* window-impl.h (struct window):
* window-impl.h (struct window_mirror):
* window.c (finalize_window):
* window.c (allocate_window):
* window.c (new_window_mirror):
* window.c (mark_window_as_deleted):
* window.c (make_dummy_parent):
* window.c (compute_window_mirror_usage):
* window.c (compute_window_usage):
Overall point of this change and previous ones in this repository:
(1) Introduce new, clearer terminology: everything other than int
or char is a "record" object, which comes in two types: "normal
objects" and "frob-block objects". Fix up all places that
referred to frob-block objects as "simple", "basic", etc.
(2) Provide an advertised interface for doing operations on Lisp
objects, including creating new types, that is clean and
consistent in its naming, uses the above-referenced terms and
avoids referencing "lrecords", "old lcrecords", etc., which should
hide under the surface.
(3) Make the size_in_bytes and finalizer methods take a
Lisp_Object rather than a void * for consistency with other methods.
(4) Separate finalizer method into finalizer and disksaver, so
that normal finalize methods don't have to worry about disksaving.
Other specifics:
(1) Renaming:
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
implementation->basic_p -> implementation->frob_block_p
ALLOCATE_FIXED_TYPE_AND_SET_IMPL -> ALLOC_FROB_BLOCK_LISP_OBJECT
*FCCONFIG*, wrap_fcconfig -> *FC_CONFIG*, wrap_fc_config
*FCPATTERN*, wrap_fcpattern -> *FC_PATTERN*, wrap_fc_pattern
(the last two changes make the naming of these macros consistent
with the naming of all other macros, since the objects are named
fc-config and fc-pattern with a hyphen)
(2) Lots of documentation fixes in lrecord.h.
(3) Eliminate macros for copying, freeing, zeroing objects, getting
their storage size. Instead, new functions:
zero_sized_lisp_object()
zero_nonsized_lisp_object()
lisp_object_storage_size()
free_normal_lisp_object()
(copy_lisp_object() already exists)
LISP_OBJECT_FROB_BLOCK_P() (actually a macro)
Eliminated:
free_lrecord()
zero_lrecord()
copy_lrecord()
copy_sized_lrecord()
old_copy_lcrecord()
old_copy_sized_lcrecord()
old_zero_lcrecord()
old_zero_sized_lcrecord()
LISP_OBJECT_STORAGE_SIZE()
COPY_SIZED_LISP_OBJECT()
COPY_SIZED_LCRECORD()
COPY_LISP_OBJECT()
ZERO_LISP_OBJECT()
FREE_LISP_OBJECT()
(4) Catch the remaining places where lrecord stuff was used directly
and use the advertised interface, e.g. alloc_sized_lrecord() ->
ALLOC_SIZED_LISP_OBJECT().
(5) Make certain statically-declared pseudo-objects
(buffer_local_flags, console_local_flags) have their lheader
initialized correctly, so things like copy_lisp_object() can work
on them. Make extent_auxiliary_defaults a proper heap object
Vextent_auxiliary_defaults, and make extent auxiliaries dumpable
so that this object can be dumped. allocate_extent_auxiliary()
now just creates the object, and attach_extent_auxiliary()
creates an extent auxiliary and attaches to an extent, like the
old allocate_extent_auxiliary().
(6) Create EXTENT_AUXILIARY_SLOTS macro, similar to the foo-slots.h
files but in a macro instead of a file. The purpose is to avoid
duplication when iterating over all the slots in an extent auxiliary.
Use it.
(7) In lstream.c, don't zero out object after allocation because
allocation routines take care of this.
(8) In marker.c, fix a mistake in computing marker overhead.
(9) In print.c, clean up printing_unreadable_lcrecord(),
external_object_printer() to avoid lots of ifdef NEW_GC's.
(10) Separate toolbar-button allocation into a separate
allocate_toolbar_button() function for use in the example code
in lrecord.h.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 05 Mar 2010 04:08:17 -0600 |
parents | 48eed784e93a |
children | 2aa9cd456ae7 |
rev | line source |
---|---|
868 | 1 README.global-renaming |
2 | |
3 This file documents the generic scripts that have been used to implement | |
4 the recent type renamings, e.g. the "great integral type renaming" and the | |
5 "text/char type renaming". More information about these changes can be | |
6 found in the Internals manual. | |
7 | |
8 A sample script to do such renaming is this (used in the great integral | |
9 type renaming): | |
10 | |
11 ----------------------------------- cut ------------------------------------ | |
12 files="*.[ch] s/*.h m/*.h config.h.in ../configure.in Makefile.in.in ../lib-src/*.[ch] ../lwlib/*.[ch]" | |
13 gr Memory_Count Bytecount $files | |
14 gr Lstream_Data_Count Bytecount $files | |
15 gr Element_Count Elemcount $files | |
16 gr Hash_Code Hashcode $files | |
17 gr extcount bytecount $files | |
18 gr bufpos charbpos $files | |
19 gr bytind bytebpos $files | |
20 gr memind membpos $files | |
21 gr bufbyte intbyte $files | |
22 gr Extcount Bytecount $files | |
23 gr Bufpos Charbpos $files | |
24 gr Bytind Bytebpos $files | |
25 gr Memind Membpos $files | |
26 gr Bufbyte Intbyte $files | |
27 gr EXTCOUNT BYTECOUNT $files | |
28 gr BUFPOS CHARBPOS $files | |
29 gr BYTIND BYTEBPOS $files | |
30 gr MEMIND MEMBPOS $files | |
31 gr BUFBYTE INTBYTE $files | |
32 gr MEMORY_COUNT BYTECOUNT $files | |
33 gr LSTREAM_DATA_COUNT BYTECOUNT $files | |
34 gr ELEMENT_COUNT ELEMCOUNT $files | |
35 gr HASH_CODE HASHCODE $files | |
36 ----------------------------------- cut ------------------------------------ | |
37 | |
38 | |
39 `fixtypes.sh' is a Bourne-shell script; it uses 'gr': | |
40 | |
41 | |
42 ----------------------------------- cut ------------------------------------ | |
43 #!/bin/sh | |
44 | |
45 # Usage is like this: | |
46 | |
47 # gr FROM TO FILES ... | |
48 | |
49 # globally replace FROM with TO in FILES. FROM and TO are regular expressions. | |
50 # backup files are stored in the `backup' directory. | |
51 from="$1" | |
52 to="$2" | |
53 shift 2 | |
54 echo ${1+"$@"} | xargs global-replace "s/$from/$to/g" | |
55 ----------------------------------- cut ------------------------------------ | |
56 | |
57 | |
58 `gr' in turn uses a Perl script to do its real work, `global-replace', | |
59 which follows: | |
60 | |
61 | |
62 ----------------------------------- cut ------------------------------------ | |
63 : #-*- Perl -*- | |
64 | |
65 ### global-replace --- modify the contents of a file by a Perl expression | |
66 | |
67 ## Copyright (C) 1999 Martin Buchholz. | |
68 ## Copyright (C) 2001, 2002 Ben Wing. | |
69 | |
70 ## Authors: Martin Buchholz <martin@xemacs.org>, Ben Wing <ben@xemacs.org> | |
71 ## Maintainer: Ben Wing <ben@xemacs.org> | |
72 ## Current Version: 1.2, March 12, 2002 | |
73 | |
74 # This program is free software; you can redistribute it and/or modify | |
75 # it under the terms of the GNU General Public License as published by | |
76 # the Free Software Foundation; either version 2, or (at your option) | |
77 # any later version. | |
78 # | |
79 # This program is distributed in the hope that it will be useful, but | |
80 # WITHOUT ANY WARRANTY; without even the implied warranty of | |
81 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
82 # General Public License for more details. | |
83 # | |
84 # You should have received a copy of the GNU General Public License | |
85 # along with XEmacs; see the file COPYING. If not, write to the Free | |
86 # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
87 # 02111-1307, USA. | |
88 | |
89 eval 'exec perl -w -S $0 ${1+"$@"}' | |
90 if 0; | |
91 | |
92 use strict; | |
93 use FileHandle; | |
94 use Carp; | |
95 use Getopt::Long; | |
96 use File::Basename; | |
97 | |
98 (my $myName = $0) =~ s@.*/@@; my $usage=" | |
99 Usage: $myName [--help] [--backup-dir=DIR] [--line-mode] [--hunk-mode] | |
100 PERLEXPR FILE ... | |
101 | |
102 Globally modify a file, either line by line or in one big hunk. | |
103 | |
104 Typical usage is like this: | |
105 | |
106 [with GNU print, GNU xargs: guaranteed to handle spaces, quotes, etc. | |
107 in file names] | |
108 | |
109 find . -name '*.[ch]' -print0 | xargs -0 $0 's/\bCONST\b/const/g'\n | |
110 | |
111 [with non-GNU print, xargs] | |
112 | |
113 find . -name '*.[ch]' -print | xargs $0 's/\bCONST\b/const/g'\n | |
114 | |
115 | |
116 The file is read in, either line by line (with --line-mode specified) | |
117 or in one big hunk (with --hunk-mode specified; it's the default), and | |
118 the Perl expression is then evalled with \$_ set to the line or hunk of | |
119 text, including the terminating newline if there is one. It should | |
120 destructively modify the value there, storing the changed result in \$_. | |
121 | |
122 Files in which any modifications are made are backed up to the directory | |
123 specified using --backup-dir, or to `backup.orig' by default. To disable | |
124 this, use --backup-dir= with no argument. | |
125 | |
126 Hunk mode is the default because it is MUCH MUCH faster than line-by-line. | |
127 Use line-by-line only when it matters, e.g. you want to do a replacement | |
128 only once per line (the default without the `g' argument). Conversely, | |
129 when using hunk mode, *ALWAYS* use `g'; otherwise, you will only make one | |
130 replacement in the entire file! | |
131 "; | |
132 | |
133 my %options = (); | |
134 $Getopt::Long::ignorecase = 0; | |
135 &GetOptions ( | |
136 \%options, | |
137 'help', 'backup-dir=s', 'line-mode', 'hunk-mode', | |
138 ); | |
139 | |
140 | |
141 die $usage if $options{"help"} or @ARGV <= 1; | |
142 my $code = shift; | |
143 | |
144 die $usage if grep (-d || ! -w, @ARGV); | |
145 | |
146 sub SafeOpen { | |
147 open ((my $fh = new FileHandle), $_[0]); | |
148 confess "Can't open $_[0]: $!" if ! defined $fh; | |
149 return $fh; | |
150 } | |
151 | |
152 sub SafeClose { | |
153 close $_[0] or confess "Can't close $_[0]: $!"; | |
154 } | |
155 | |
156 sub FileContents { | |
157 my $fh = SafeOpen ("< $_[0]"); | |
158 my $olddollarslash = $/; | |
159 local $/ = undef; | |
160 my $contents = <$fh>; | |
161 $/ = $olddollarslash; | |
162 return $contents; | |
163 } | |
164 | |
165 sub WriteStringToFile { | |
166 my $fh = SafeOpen ("> $_[0]"); | |
167 binmode $fh; | |
168 print $fh $_[1] or confess "$_[0]: $!\n"; | |
169 SafeClose $fh; | |
170 } | |
171 | |
172 foreach my $file (@ARGV) { | |
173 my $changed_p = 0; | |
174 my $new_contents = ""; | |
175 if ($options{"line-mode"}) { | |
176 my $fh = SafeOpen $file; | |
177 while (<$fh>) { | |
178 my $save_line = $_; | |
179 eval $code; | |
180 $changed_p = 1 if $save_line ne $_; | |
181 $new_contents .= $_; | |
182 } | |
183 } else { | |
184 my $orig_contents = $_ = FileContents $file; | |
185 eval $code; | |
186 if ($_ ne $orig_contents) { | |
187 $changed_p = 1; | |
188 $new_contents = $_; | |
189 } | |
190 } | |
191 | |
192 if ($changed_p) { | |
193 my $backdir = $options{"backup-dir"}; | |
194 $backdir = "backup.orig" if !defined ($backdir); | |
195 if ($backdir) { | |
196 my ($name, $path, $suffix) = fileparse ($file, ""); | |
197 my $backfulldir = $path . $backdir; | |
198 my $backfile = "$backfulldir/$name"; | |
199 mkdir $backfulldir, 0755 unless -d $backfulldir; | |
200 print "modifying $file (original saved in $backfile)\n"; | |
201 rename $file, $backfile; | |
202 } | |
203 WriteStringToFile ($file, $new_contents); | |
204 } | |
205 } | |
206 ----------------------------------- cut ------------------------------------ |