From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25906 invoked by alias); 15 Apr 2012 19:42:57 -0000 Received: (qmail 25888 invoked by uid 22791); 15 Apr 2012 19:42:53 -0000 X-SWARE-Spam-Status: No, hits=0.0 required=5.0 tests=AWL,BAYES_00,KHOP_DYNAMIC2,RDNS_DYNAMIC,TW_RG X-Spam-Check-By: sourceware.org Received: from 173-13-178-50-sfba.hfc.comcastbusiness.net (HELO sebabeach.org) (173.13.178.50) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 15 Apr 2012 19:42:38 +0000 Received: by sebabeach.org (Postfix, from userid 500) id 6718E11F7BD; Sun, 15 Apr 2012 12:42:37 -0700 (PDT) From: Doug Evans To: gdb-patches@sourceware.org Subject: [patch] Create cleanups.[ch] Date: Sun, 15 Apr 2012 20:27:00 -0000 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-04/txt/msg00396.txt.bz2 Hi. Since cleanups are a big enough source of issues, I want to separate them out. This patch moves the core cleanup API into its own file. It makes no other changes. I have at least one more patch to go, but I want to get this done first. Regression tested on amd64-linux. I will check this in in a few days if there are no objections. Note: While one might want to also move things like make_cleanup_unpush_target into cleanups.c, I would rather not. Functions like this are not part of the core cleanup API, they just use it. OTOH, more generic functions like make_cleanup_restore_integer are generic enough utilities that I'd be ok if they got moved over (akin to null_cleanup). But I have not done so in this patch. 2012-04-15 Doug Evans * cleanups.h: New file. * cleanups.c: New file. * Makefile.in (SFILES): Add cleanups.c (HFILES_NO_SRCDIR): Add cleanups.h (COMMON_OBS): Add cleanups.o * defs.h (struct cleanup): Moved to cleanups.h (do_cleanups,do_final_cleanups): Ditto. (discard_cleanups,discard_final_cleanups): Ditto (make_cleanup,make_cleanup_dtor,make_final_cleanup): Ditto. (save_cleanups,save_final_cleanups): Ditto. (restore_cleanups,restore_final_cleanups): Ditto. (null_cleanup): Ditto. (make_my_cleanup,make_my_cleanup2): Delete. (discard_my_cleanups,save_my_cleanups,restore_my_cleanups): Delete. * utils.c (cleanup_chain,final_cleanup_chain): Moved to cleanups.c. (do_cleanups,do_final_cleanups): Ditto. (discard_cleanups,discard_final_cleanups): Ditto (make_cleanup,make_cleanup_dtor,make_final_cleanup): Ditto. (save_cleanups,save_final_cleanups): Ditto. (restore_cleanups,restore_final_cleanups): Ditto. (null_cleanup): Ditto. (make_my_cleanup,make_my_cleanup2): Ditto, and make static. All uses rewritten to use proper interface. (discard_my_cleanups,save_my_cleanups,restore_my_cleanups): Ditto. Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.1199 diff -u -p -r1.1199 Makefile.in --- Makefile.in 14 Apr 2012 05:24:53 -0000 1.1199 +++ Makefile.in 15 Apr 2012 19:23:28 -0000 @@ -690,7 +690,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr bfd-target.c \ block.c blockframe.c breakpoint.c buildsym.c \ c-exp.y c-lang.c c-typeprint.c c-valprint.c \ - charset.c cli-out.c coffread.c coff-pe-read.c \ + charset.c cleanups.c cli-out.c coffread.c coff-pe-read.c \ complaints.c completer.c continuations.c corefile.c corelow.c \ cp-abi.c cp-support.c cp-namespace.c cp-valprint.c \ d-lang.c d-valprint.c \ @@ -783,7 +783,7 @@ objfiles.h vec.h disasm.h mips-tdep.h se gdb_curses.h bfd-target.h memattr.h inferior.h ax.h dummy-frame.h \ inflow.h fbsd-nat.h ia64-libunwind-tdep.h completer.h inf-ttrace.h \ solib-target.h gdb_vfork.h alpha-tdep.h dwarf2expr.h \ -m2-lang.h stack.h charset.h addrmap.h command.h solist.h source.h \ +m2-lang.h stack.h charset.h cleanups.h addrmap.h command.h solist.h source.h \ target.h prologue-value.h cp-abi.h tui/tui-hooks.h tui/tui.h \ tui/tui-file.h tui/tui-command.h tui/tui-disasm.h tui/tui-wingeneral.h \ tui/tui-windata.h tui/tui-data.h tui/tui-win.h tui/tui-stack.h \ @@ -858,7 +858,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $ auxv.o \ agent.o \ bfd-target.o \ - blockframe.o breakpoint.o findvar.o regcache.o \ + blockframe.o breakpoint.o findvar.o regcache.o cleanups.o \ charset.o continuations.o corelow.o disasm.o dummy-frame.o dfp.o \ source.o value.o eval.o valops.o valarith.o valprint.o printcmd.o \ block.o symtab.o psymtab.o symfile.o symmisc.o linespec.o dictionary.o \ Index: cleanups.c =================================================================== RCS file: cleanups.c diff -N cleanups.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ cleanups.c 15 Apr 2012 19:23:28 -0000 @@ -0,0 +1,210 @@ +/* Cleanup routines for GDB, the GNU debugger. + + Copyright (C) 1986, 1988-2012 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" + +/* Chain of cleanup actions established with make_cleanup, + to be executed if an error happens. */ + +/* Cleaned up after a failed command. */ +static struct cleanup *cleanup_chain; + +/* Cleaned up when gdb exits. */ +static struct cleanup *final_cleanup_chain; + +static struct cleanup * +make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function, + void *arg, void (*free_arg) (void *)) +{ + struct cleanup *new + = (struct cleanup *) xmalloc (sizeof (struct cleanup)); + struct cleanup *old_chain = *pmy_chain; + + new->next = *pmy_chain; + new->function = function; + new->free_arg = free_arg; + new->arg = arg; + *pmy_chain = new; + + return old_chain; +} + +static struct cleanup * +make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, + void *arg) +{ + return make_my_cleanup2 (pmy_chain, function, arg, NULL); +} + +/* Add a new cleanup to the cleanup_chain, + and return the previous chain pointer + to be passed later to do_cleanups or discard_cleanups. + Args are FUNCTION to clean up with, and ARG to pass to it. */ + +struct cleanup * +make_cleanup (make_cleanup_ftype *function, void *arg) +{ + return make_my_cleanup (&cleanup_chain, function, arg); +} + +/* Same as make_cleanup except also includes TDOR, a destructor to free ARG. + DTOR is invoked when the cleanup is performed or when it is discarded. */ + +struct cleanup * +make_cleanup_dtor (make_cleanup_ftype *function, void *arg, + void (*dtor) (void *)) +{ + return make_my_cleanup2 (&cleanup_chain, + function, arg, dtor); +} + +/* Same as make_cleanup except the cleanup is added to final_cleanup_chain. */ + +struct cleanup * +make_final_cleanup (make_cleanup_ftype *function, void *arg) +{ + return make_my_cleanup (&final_cleanup_chain, function, arg); +} + +static void +do_my_cleanups (struct cleanup **pmy_chain, + struct cleanup *old_chain) +{ + struct cleanup *ptr; + + while ((ptr = *pmy_chain) != old_chain) + { + *pmy_chain = ptr->next; /* Do this first in case of recursion. */ + (*ptr->function) (ptr->arg); + if (ptr->free_arg) + (*ptr->free_arg) (ptr->arg); + xfree (ptr); + } +} + +/* Discard cleanups and do the actions they describe + until we get back to the point OLD_CHAIN in the cleanup_chain. */ + +void +do_cleanups (struct cleanup *old_chain) +{ + do_my_cleanups (&cleanup_chain, old_chain); +} + +/* Discard cleanups and do the actions they describe + until we get back to the point OLD_CHAIN in the final_cleanup_chain. */ + +void +do_final_cleanups (struct cleanup *old_chain) +{ + do_my_cleanups (&final_cleanup_chain, old_chain); +} + +static void +discard_my_cleanups (struct cleanup **pmy_chain, + struct cleanup *old_chain) +{ + struct cleanup *ptr; + + while ((ptr = *pmy_chain) != old_chain) + { + *pmy_chain = ptr->next; + if (ptr->free_arg) + (*ptr->free_arg) (ptr->arg); + xfree (ptr); + } +} + +/* Discard cleanups, not doing the actions they describe, + until we get back to the point OLD_CHAIN in the cleanup chain. */ + +void +discard_cleanups (struct cleanup *old_chain) +{ + discard_my_cleanups (&cleanup_chain, old_chain); +} + +/* Discard final cleanups, not doing the actions they describe, + until we get back to the point OLD_CHAIN in the final cleanup chain. */ + +void +discard_final_cleanups (struct cleanup *old_chain) +{ + discard_my_cleanups (&final_cleanup_chain, old_chain); +} + +static struct cleanup * +save_my_cleanups (struct cleanup **pmy_chain) +{ + struct cleanup *old_chain = *pmy_chain; + + *pmy_chain = 0; + return old_chain; +} + +/* Set the cleanup_chain to 0, and return the old cleanup_chain. */ + +struct cleanup * +save_cleanups (void) +{ + return save_my_cleanups (&cleanup_chain); +} + +/* Set the final_cleanup_chain to 0, and return the old + final_cleanup_chain. */ + +struct cleanup * +save_final_cleanups (void) +{ + return save_my_cleanups (&final_cleanup_chain); +} + +static void +restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain) +{ + *pmy_chain = chain; +} + +/* Restore the cleanup chain from a previously saved chain. */ + +void +restore_cleanups (struct cleanup *chain) +{ + restore_my_cleanups (&cleanup_chain, chain); +} + +/* Restore the final cleanup chain from a previously saved chain. */ + +void +restore_final_cleanups (struct cleanup *chain) +{ + restore_my_cleanups (&final_cleanup_chain, chain); +} + +/* Provide a known function that does nothing, to use as a base for + a possibly long chain of cleanups. This is useful where we + use the cleanup chain for handling normal cleanups as well as dealing + with cleanups that need to be done as a result of a call to error(). + In such cases, we may not be certain where the first cleanup is, unless + we have a do-nothing one to always use as the base. */ + +void +null_cleanup (void *arg) +{ +} Index: cleanups.h =================================================================== RCS file: cleanups.h diff -N cleanups.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ cleanups.h 15 Apr 2012 19:23:28 -0000 @@ -0,0 +1,86 @@ +/* Cleanups. + Copyright (C) 1986, 1988-2005, 2007-2012 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef CLEANUPS_H +#define CLEANUPS_H + +/* The cleanup list records things that have to be undone + if an error happens (descriptors to be closed, memory to be freed, etc.) + Each link in the chain records a function to call and an + argument to give it. + + Use make_cleanup to add an element to the cleanup chain. + Use do_cleanups to do all cleanup actions back to a given + point in the chain. Use discard_cleanups to remove cleanups + from the chain back to a given point, not doing them. + + If the argument is pointer to allocated memory, then you need + to additionally set the 'free_arg' member to a function that will + free that memory. This function will be called both when the cleanup + is executed and when it's discarded. */ + +struct cleanup + { + struct cleanup *next; + void (*function) (void *); + void (*free_arg) (void *); + void *arg; + }; + +/* NOTE: cagney/2000-03-04: This typedef is strictly for the + make_cleanup function declarations below. Do not use this typedef + as a cast when passing functions into the make_cleanup() code. + Instead either use a bounce function or add a wrapper function. + Calling a f(char*) function with f(void*) is non-portable. */ +typedef void (make_cleanup_ftype) (void *); + +/* WARNING: The result of the "make cleanup" routines is not the intuitive + choice of being a handle on the just-created cleanup. Instead it is an + opaque handle of the cleanup mechanism and represents all cleanups created + from that point onwards. + The result is guaranteed to be non-NULL though. */ + +extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *); + +extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *, + void (*dtor) (void *)); + +extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); + +/* A special value to pass to do_cleanups and do_final_cleanups + to tell them to do all cleanups. */ +#define ALL_CLEANUPS ((struct cleanup *)0) + +extern void do_cleanups (struct cleanup *); +extern void do_final_cleanups (struct cleanup *); + +extern void discard_cleanups (struct cleanup *); +extern void discard_final_cleanups (struct cleanup *); + +extern struct cleanup *save_cleanups (void); +extern struct cleanup *save_final_cleanups (void); + +extern void restore_cleanups (struct cleanup *); +extern void restore_final_cleanups (struct cleanup *); + +/* A no-op cleanup. + This is useful when you want to establish a known reference point + to pass to do_cleanups. */ +extern void null_cleanup (void *); + +#endif /* CLEANUPS_H */ Index: defs.h =================================================================== RCS file: /cvs/src/src/gdb/defs.h,v retrieving revision 1.311 diff -u -p -r1.311 defs.h --- defs.h 5 Mar 2012 11:33:35 -0000 1.311 +++ defs.h 15 Apr 2012 19:23:28 -0000 @@ -251,29 +251,6 @@ enum return_value_convention RETURN_VALUE_ABI_PRESERVES_ADDRESS, }; -/* the cleanup list records things that have to be undone - if an error happens (descriptors to be closed, memory to be freed, etc.) - Each link in the chain records a function to call and an - argument to give it. - - Use make_cleanup to add an element to the cleanup chain. - Use do_cleanups to do all cleanup actions back to a given - point in the chain. Use discard_cleanups to remove cleanups - from the chain back to a given point, not doing them. - - If the argument is pointer to allocated memory, then you need - to additionally set the 'free_arg' member to a function that will - free that memory. This function will be called both when the cleanup - is executed and when it's discarded. */ - -struct cleanup - { - struct cleanup *next; - void (*function) (void *); - void (*free_arg) (void *); - void *arg; - }; - /* vec.h-style vectors of strings want a typedef for char * or const char *. */ typedef char * char_ptr; @@ -313,26 +290,9 @@ extern void set_display_time (int); extern void set_display_space (int); -#define ALL_CLEANUPS ((struct cleanup *)0) - -extern void do_cleanups (struct cleanup *); -extern void do_final_cleanups (struct cleanup *); - -extern void discard_cleanups (struct cleanup *); -extern void discard_final_cleanups (struct cleanup *); -extern void discard_my_cleanups (struct cleanup **, struct cleanup *); - -/* NOTE: cagney/2000-03-04: This typedef is strictly for the - make_cleanup function declarations below. Do not use this typedef - as a cast when passing functions into the make_cleanup() code. - Instead either use a bounce function or add a wrapper function. - Calling a f(char*) function with f(void*) is non-portable. */ -typedef void (make_cleanup_ftype) (void *); +/* Cleanup utilities. */ -extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *); - -extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *, - void (*dtor) (void *)); +#include "cleanups.h" extern struct cleanup *make_cleanup_freeargv (char **); @@ -374,29 +334,10 @@ extern struct cleanup *make_cleanup_valu struct so_list; extern struct cleanup *make_cleanup_free_so (struct so_list *so); -extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); - -extern struct cleanup *make_my_cleanup (struct cleanup **, - make_cleanup_ftype *, void *); - extern struct cleanup *make_cleanup_htab_delete (htab_t htab); -extern struct cleanup *make_my_cleanup2 (struct cleanup **, - make_cleanup_ftype *, void *, - void (*free_arg) (void *)); - -extern struct cleanup *save_cleanups (void); -extern struct cleanup *save_final_cleanups (void); -extern struct cleanup *save_my_cleanups (struct cleanup **); - -extern void restore_cleanups (struct cleanup *); -extern void restore_final_cleanups (struct cleanup *); -extern void restore_my_cleanups (struct cleanup **, struct cleanup *); - extern void free_current_contents (void *); -extern void null_cleanup (void *); - extern struct cleanup *make_command_stats_cleanup (int); extern int myread (int, char *, int); Index: utils.c =================================================================== RCS file: /cvs/src/src/gdb/utils.c,v retrieving revision 1.274 diff -u -p -r1.274 utils.c --- utils.c 7 Feb 2012 04:48:22 -0000 1.274 +++ utils.c 15 Apr 2012 19:23:28 -0000 @@ -99,8 +99,6 @@ static void vfprintf_maybe_filtered (str static void fputs_maybe_filtered (const char *, struct ui_file *, int); -static void do_my_cleanups (struct cleanup **, struct cleanup *); - static void prompt_for_continue (void); static void set_screen_size (void); @@ -110,12 +108,6 @@ static void set_width (void); static int debug_timestamp = 0; -/* Chain of cleanup actions established with make_cleanup, - to be executed if an error happens. */ - -static struct cleanup *cleanup_chain; /* cleaned up after a failed command */ -static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */ - /* Nonzero if we have job control. */ int job_control; @@ -172,31 +164,11 @@ show_pagination_enabled (struct ui_file } +/* Cleanup utilities. -/* Add a new cleanup to the cleanup_chain, - and return the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. - Args are FUNCTION to clean up with, and ARG to pass to it. */ - -struct cleanup * -make_cleanup (make_cleanup_ftype *function, void *arg) -{ - return make_my_cleanup (&cleanup_chain, function, arg); -} - -struct cleanup * -make_cleanup_dtor (make_cleanup_ftype *function, void *arg, - void (*dtor) (void *)) -{ - return make_my_cleanup2 (&cleanup_chain, - function, arg, dtor); -} - -struct cleanup * -make_final_cleanup (make_cleanup_ftype *function, void *arg) -{ - return make_my_cleanup (&final_cleanup_chain, function, arg); -} + These are not defined in cleanups.c (nor declared in cleanups.h) + because while they use the "cleanup API" they are not part of the + "cleanup API". */ static void do_freeargv (void *arg) @@ -207,7 +179,7 @@ do_freeargv (void *arg) struct cleanup * make_cleanup_freeargv (char **arg) { - return make_my_cleanup (&cleanup_chain, do_freeargv, arg); + return make_cleanup (do_freeargv, arg); } static void @@ -219,7 +191,7 @@ do_dyn_string_delete (void *arg) struct cleanup * make_cleanup_dyn_string_delete (dyn_string_t arg) { - return make_my_cleanup (&cleanup_chain, do_dyn_string_delete, arg); + return make_cleanup (do_dyn_string_delete, arg); } static void @@ -296,7 +268,7 @@ do_ui_file_delete (void *arg) struct cleanup * make_cleanup_ui_file_delete (struct ui_file *arg) { - return make_my_cleanup (&cleanup_chain, do_ui_file_delete, arg); + return make_cleanup (do_ui_file_delete, arg); } /* Helper function for make_cleanup_ui_out_redirect_pop. */ @@ -316,7 +288,7 @@ do_ui_out_redirect_pop (void *arg) struct cleanup * make_cleanup_ui_out_redirect_pop (struct ui_out *uiout) { - return make_my_cleanup (&cleanup_chain, do_ui_out_redirect_pop, uiout); + return make_cleanup (do_ui_out_redirect_pop, uiout); } static void @@ -328,7 +300,7 @@ do_free_section_addr_info (void *arg) struct cleanup * make_cleanup_free_section_addr_info (struct section_addr_info *addrs) { - return make_my_cleanup (&cleanup_chain, do_free_section_addr_info, addrs); + return make_cleanup (do_free_section_addr_info, addrs); } struct restore_integer_closure @@ -357,8 +329,7 @@ make_cleanup_restore_integer (int *varia c->variable = variable; c->value = *variable; - return make_my_cleanup2 (&cleanup_chain, restore_integer, (void *)c, - xfree); + return make_cleanup_dtor (restore_integer, (void *) c, xfree); } /* Remember the current value of *VARIABLE and make it restored when @@ -385,7 +356,7 @@ do_unpush_target (void *arg) struct cleanup * make_cleanup_unpush_target (struct target_ops *ops) { - return make_my_cleanup (&cleanup_chain, do_unpush_target, ops); + return make_cleanup (do_unpush_target, ops); } /* Helper for make_cleanup_htab_delete compile time checking the types. */ @@ -448,7 +419,7 @@ do_value_free_to_mark (void *value) struct cleanup * make_cleanup_value_free_to_mark (struct value *mark) { - return make_my_cleanup (&cleanup_chain, do_value_free_to_mark, mark); + return make_cleanup (do_value_free_to_mark, mark); } /* Helper for make_cleanup_value_free. */ @@ -464,7 +435,7 @@ do_value_free (void *value) struct cleanup * make_cleanup_value_free (struct value *value) { - return make_my_cleanup (&cleanup_chain, do_value_free, value); + return make_cleanup (do_value_free, value); } /* Helper for make_cleanup_free_so. */ @@ -482,133 +453,7 @@ do_free_so (void *arg) struct cleanup * make_cleanup_free_so (struct so_list *so) { - return make_my_cleanup (&cleanup_chain, do_free_so, so); -} - -struct cleanup * -make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function, - void *arg, void (*free_arg) (void *)) -{ - struct cleanup *new - = (struct cleanup *) xmalloc (sizeof (struct cleanup)); - struct cleanup *old_chain = *pmy_chain; - - new->next = *pmy_chain; - new->function = function; - new->free_arg = free_arg; - new->arg = arg; - *pmy_chain = new; - - return old_chain; -} - -struct cleanup * -make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, - void *arg) -{ - return make_my_cleanup2 (pmy_chain, function, arg, NULL); -} - -/* Discard cleanups and do the actions they describe - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -do_cleanups (struct cleanup *old_chain) -{ - do_my_cleanups (&cleanup_chain, old_chain); -} - -void -do_final_cleanups (struct cleanup *old_chain) -{ - do_my_cleanups (&final_cleanup_chain, old_chain); -} - -static void -do_my_cleanups (struct cleanup **pmy_chain, - struct cleanup *old_chain) -{ - struct cleanup *ptr; - - while ((ptr = *pmy_chain) != old_chain) - { - *pmy_chain = ptr->next; /* Do this first in case of recursion. */ - (*ptr->function) (ptr->arg); - if (ptr->free_arg) - (*ptr->free_arg) (ptr->arg); - xfree (ptr); - } -} - -/* Discard cleanups, not doing the actions they describe, - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -discard_cleanups (struct cleanup *old_chain) -{ - discard_my_cleanups (&cleanup_chain, old_chain); -} - -void -discard_final_cleanups (struct cleanup *old_chain) -{ - discard_my_cleanups (&final_cleanup_chain, old_chain); -} - -void -discard_my_cleanups (struct cleanup **pmy_chain, - struct cleanup *old_chain) -{ - struct cleanup *ptr; - - while ((ptr = *pmy_chain) != old_chain) - { - *pmy_chain = ptr->next; - if (ptr->free_arg) - (*ptr->free_arg) (ptr->arg); - xfree (ptr); - } -} - -/* Set the cleanup_chain to 0, and return the old cleanup chain. */ -struct cleanup * -save_cleanups (void) -{ - return save_my_cleanups (&cleanup_chain); -} - -struct cleanup * -save_final_cleanups (void) -{ - return save_my_cleanups (&final_cleanup_chain); -} - -struct cleanup * -save_my_cleanups (struct cleanup **pmy_chain) -{ - struct cleanup *old_chain = *pmy_chain; - - *pmy_chain = 0; - return old_chain; -} - -/* Restore the cleanup chain from a previously saved chain. */ -void -restore_cleanups (struct cleanup *chain) -{ - restore_my_cleanups (&cleanup_chain, chain); -} - -void -restore_final_cleanups (struct cleanup *chain) -{ - restore_my_cleanups (&final_cleanup_chain, chain); -} - -void -restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain) -{ - *pmy_chain = chain; + return make_cleanup (do_free_so, so); } /* This function is useful for cleanups. @@ -634,18 +479,6 @@ free_current_contents (void *ptr) } } -/* Provide a known function that does nothing, to use as a base for - a possibly long chain of cleanups. This is useful where we - use the cleanup chain for handling normal cleanups as well as dealing - with cleanups that need to be done as a result of a call to error(). - In such cases, we may not be certain where the first cleanup is, unless - we have a do-nothing one to always use as the base. */ - -void -null_cleanup (void *arg) -{ -} - /* If nonzero, display time usage both at startup and for each command. */ static int display_time;