133965Sjdp/****************************************************************************
2218822Sdim * Copyright 2018-2019,2020 Thomas E. Dickey                                *
3218822Sdim * Copyright 1998-2016,2017 Free Software Foundation, Inc.                  *
433965Sjdp *                                                                          *
533965Sjdp * Permission is hereby granted, free of charge, to any person obtaining a  *
633965Sjdp * copy of this software and associated documentation files (the            *
733965Sjdp * "Software"), to deal in the Software without restriction, including      *
833965Sjdp * without limitation the rights to use, copy, modify, merge, publish,      *
933965Sjdp * distribute, distribute with modifications, sublicense, and/or sell       *
1033965Sjdp * copies of the Software, and to permit persons to whom the Software is    *
1133965Sjdp * furnished to do so, subject to the following conditions:                 *
1233965Sjdp *                                                                          *
1333965Sjdp * The above copyright notice and this permission notice shall be included  *
1433965Sjdp * in all copies or substantial portions of the Software.                   *
1533965Sjdp *                                                                          *
1633965Sjdp * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1733965Sjdp * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1833965Sjdp * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19218822Sdim * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
2033965Sjdp * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2133965Sjdp * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2233965Sjdp * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2333965Sjdp *                                                                          *
2433965Sjdp * Except as contained in this notice, the name(s) of the above copyright   *
2533965Sjdp * holders shall not be used in advertising or otherwise to promote the     *
2633965Sjdp * sale, use or other dealings in this Software without prior written       *
2733965Sjdp * authorization.                                                           *
2833965Sjdp ****************************************************************************/
2933965Sjdp
3033965Sjdp/****************************************************************************
3133965Sjdp *  Author: Thomas E. Dickey                    1996-on                     *
32218822Sdim ****************************************************************************/
3333965Sjdp
3438889Sjdp#include <curses.priv.h>
3538889Sjdp#include <tic.h>
3638889Sjdp
3738889Sjdp#if HAVE_NC_FREEALL
3838889Sjdp
3938889Sjdp#if HAVE_LIBDBMALLOC
4038889Sjdpextern int malloc_errfd;	/* FIXME */
4138889Sjdp#endif
4238889Sjdp
4338889SjdpMODULE_ID("$Id: lib_freeall.c,v 1.72 2020/02/02 23:34:34 tom Exp $")
4438889Sjdp
45218822Sdim/*
4638889Sjdp * Free all ncurses data.  This is used for testing only (there's no practical
47218822Sdim * use for it as an extension).
48218822Sdim */
49218822SdimNCURSES_EXPORT(void)
50218822SdimNCURSES_SP_NAME(_nc_freeall) (NCURSES_SP_DCL0)
51218822Sdim{
5238889Sjdp    static va_list empty_va;
5338889Sjdp
5433965Sjdp    T((T_CALLED("_nc_freeall()")));
5533965Sjdp#if NO_LEAKS
5633965Sjdp    _nc_globals.leak_checking = TRUE;
5733965Sjdp    if (SP_PARM != 0) {
5833965Sjdp	if (SP_PARM->_oldnum_list != 0) {
5933965Sjdp	    FreeAndNull(SP_PARM->_oldnum_list);
6033965Sjdp	}
6133965Sjdp	if (SP_PARM->_panelHook.destroy != 0) {
6233965Sjdp	    SP_PARM->_panelHook.destroy(SP_PARM->_panelHook.stdscr_pseudo_panel);
6333965Sjdp	}
6433965Sjdp#if NCURSES_EXT_COLORS
6533965Sjdp	_nc_new_pair_leaks(SP_PARM);
66130561Sobrien#endif
67130561Sobrien    }
68130561Sobrien#endif
69130561Sobrien    if (SP_PARM != 0) {
70130561Sobrien	_nc_lock_global(curses);
71130561Sobrien
7233965Sjdp	while (WindowList(SP_PARM) != 0) {
7333965Sjdp	    WINDOWLIST *p, *q;
7433965Sjdp	    bool deleted = FALSE;
7533965Sjdp
7633965Sjdp	    /* Delete only windows that're not a parent */
7733965Sjdp	    for (each_window(SP_PARM, p)) {
7833965Sjdp		WINDOW *p_win = &(p->win);
7933965Sjdp		bool found = FALSE;
8033965Sjdp
8133965Sjdp#ifndef USE_SP_WINDOWLIST
8277298Sobrien		if (p->screen != SP_PARM)
8377298Sobrien		    continue;
8477298Sobrien#endif
85130561Sobrien
86130561Sobrien		for (each_window(SP_PARM, q)) {
87218822Sdim		    WINDOW *q_win = &(q->win);
8833965Sjdp
8933965Sjdp#ifndef USE_SP_WINDOWLIST
9033965Sjdp		    if (q->screen != SP_PARM)
9133965Sjdp			continue;
9233965Sjdp#endif
9333965Sjdp
9433965Sjdp		    if ((p != q)
9533965Sjdp			&& (q_win->_flags & _SUBWIN)
9633965Sjdp			&& (p_win == q_win->_parent)) {
9738889Sjdp			found = TRUE;
9838889Sjdp			break;
9938889Sjdp		    }
10038889Sjdp		}
101218822Sdim
102218822Sdim		if (!found) {
103218822Sdim		    if (delwin(p_win) != ERR)
104218822Sdim			deleted = TRUE;
105218822Sdim		    break;
106218822Sdim		}
10733965Sjdp	    }
10833965Sjdp
10933965Sjdp	    /*
11033965Sjdp	     * Don't continue to loop if the list is trashed.
11133965Sjdp	     */
11233965Sjdp	    if (!deleted)
11389857Sobrien		break;
11489857Sobrien	}
11589857Sobrien	delscreen(SP_PARM);
11689857Sobrien	_nc_unlock_global(curses);
11789857Sobrien    }
11889857Sobrien
11989857Sobrien    (void) _nc_printf_string(0, empty_va);
12089857Sobrien#ifdef TRACE
12133965Sjdp    (void) _nc_trace_buf(-1, (size_t) 0);
12233965Sjdp#endif
12333965Sjdp#if USE_WIDEC_SUPPORT
12433965Sjdp    FreeIfNeeded(_nc_wacs);
12533965Sjdp#endif
12633965Sjdp    _nc_leaks_tinfo();
127218822Sdim
12833965Sjdp#if HAVE_LIBDBMALLOC
12933965Sjdp    malloc_dump(malloc_errfd);
13033965Sjdp#elif HAVE_LIBDMALLOC
13133965Sjdp#elif HAVE_LIBMPATROL
13233965Sjdp    __mp_summary();
133218822Sdim#elif HAVE_PURIFY
13433965Sjdp    purify_all_inuse();
135130561Sobrien#endif
136130561Sobrien    returnVoid;
137130561Sobrien}
138218822Sdim
139130561Sobrien#if NCURSES_SP_FUNCS
14033965SjdpNCURSES_EXPORT(void)
141_nc_freeall(void)
142{
143    NCURSES_SP_NAME(_nc_freeall) (CURRENT_SCREEN);
144}
145#endif
146
147NCURSES_EXPORT(void)
148NCURSES_SP_NAME(_nc_free_and_exit) (NCURSES_SP_DCLx int code)
149{
150    T((T_CALLED("_nc_free_and_exit(%d)"), code));
151    NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
152    NCURSES_SP_NAME(_nc_freeall) (NCURSES_SP_ARG);
153#ifdef TRACE
154    curses_trace(0);		/* close trace file, freeing its setbuf */
155    {
156	static va_list fake;
157	free(_nc_varargs("?", fake));
158    }
159#endif
160    exit(code);
161}
162
163#else /* !HAVE_NC_FREEALL */
164NCURSES_EXPORT(void)
165_nc_freeall(void)
166{
167}
168
169NCURSES_EXPORT(void)
170NCURSES_SP_NAME(_nc_free_and_exit) (NCURSES_SP_DCLx int code)
171{
172    if (SP_PARM) {
173	delscreen(SP_PARM);
174	if (SP_PARM->_term)
175	    NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx SP_PARM->_term);
176    }
177    exit(code);
178}
179#endif /* HAVE_NC_FREEALL */
180
181#if NCURSES_SP_FUNCS
182NCURSES_EXPORT(void)
183_nc_free_and_exit(int code)
184{
185    NCURSES_SP_NAME(_nc_free_and_exit) (CURRENT_SCREEN, code);
186}
187#endif
188
189NCURSES_EXPORT(void)
190exit_curses(int code)
191{
192#if NO_LEAKS
193#if NCURSES_SP_FUNCS
194    NCURSES_SP_NAME(_nc_free_and_exit) (CURRENT_SCREEN, code);
195#else
196    _nc_free_and_exit(code);	/* deprecated... */
197#endif
198#endif
199    exit(code);
200}
201