xref: /dflybsd-src/contrib/dialog/dialog.c (revision b2dabe2e739bd72461a68ac543307c2dedfb048c)
15382d832SPeter Avalos /*
2*a8e38dc0SAntonio Huete Jimenez  * $Id: dialog.c,v 1.289 2022/07/28 21:11:36 tom Exp $
35382d832SPeter Avalos  *
45382d832SPeter Avalos  *  cdialog - Display simple dialog boxes from shell scripts
55382d832SPeter Avalos  *
6*a8e38dc0SAntonio Huete Jimenez  *  Copyright 2000-2021,2022	Thomas E. Dickey
75382d832SPeter Avalos  *
85382d832SPeter Avalos  *  This program is free software; you can redistribute it and/or modify
95382d832SPeter Avalos  *  it under the terms of the GNU Lesser General Public License, version 2.1
105382d832SPeter Avalos  *  as published by the Free Software Foundation.
115382d832SPeter Avalos  *
125382d832SPeter Avalos  *  This program is distributed in the hope that it will be useful, but
135382d832SPeter Avalos  *  WITHOUT ANY WARRANTY; without even the implied warranty of
145382d832SPeter Avalos  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
155382d832SPeter Avalos  *  Lesser General Public License for more details.
165382d832SPeter Avalos  *
175382d832SPeter Avalos  *  You should have received a copy of the GNU Lesser General Public
185382d832SPeter Avalos  *  License along with this program; if not, write to
195382d832SPeter Avalos  *	Free Software Foundation, Inc.
205382d832SPeter Avalos  *	51 Franklin St., Fifth Floor
215382d832SPeter Avalos  *	Boston, MA 02110, USA.
225382d832SPeter Avalos  *
235382d832SPeter Avalos  *  An earlier version of this program lists as authors
245382d832SPeter Avalos  *	Savio Lam (lam836@cs.cuhk.hk)
255382d832SPeter Avalos  */
265382d832SPeter Avalos 
275940c9abSDaniel Fojt #include <dlg_internals.h>
285940c9abSDaniel Fojt 
29*a8e38dc0SAntonio Huete Jimenez #define USEMAX_ARGS	20
30*a8e38dc0SAntonio Huete Jimenez #define USEMAX_FILE	50
31*a8e38dc0SAntonio Huete Jimenez 
325382d832SPeter Avalos #define PASSARGS             t,       av,        offset_add
335382d832SPeter Avalos #define CALLARGS const char *t, char *av[], int *offset_add
345382d832SPeter Avalos typedef int (callerFn) (CALLARGS);
355382d832SPeter Avalos 
365382d832SPeter Avalos typedef enum {
375382d832SPeter Avalos     o_unknown = 0
385382d832SPeter Avalos     ,o_allow_close
395382d832SPeter Avalos     ,o_and_widget
405382d832SPeter Avalos     ,o_ascii_lines
41*a8e38dc0SAntonio Huete Jimenez     ,o_aspect_ratio
425382d832SPeter Avalos     ,o_auto_placement
435382d832SPeter Avalos     ,o_backtitle
44*a8e38dc0SAntonio Huete Jimenez     ,o_beep_signal
45*a8e38dc0SAntonio Huete Jimenez     ,o_beep_after_signal
46*a8e38dc0SAntonio Huete Jimenez     ,o_begin_set
475382d832SPeter Avalos     ,o_cancel_label
485382d832SPeter Avalos     ,o_checklist
49*a8e38dc0SAntonio Huete Jimenez     ,o_dlg_clear_screen
505382d832SPeter Avalos     ,o_colors
515382d832SPeter Avalos     ,o_column_separator
525382d832SPeter Avalos     ,o_cr_wrap
535382d832SPeter Avalos     ,o_create_rc
54*a8e38dc0SAntonio Huete Jimenez     ,o_cursor_off_label
555382d832SPeter Avalos     ,o_date_format
565382d832SPeter Avalos     ,o_default_button
575382d832SPeter Avalos     ,o_default_item
585382d832SPeter Avalos     ,o_defaultno
59*a8e38dc0SAntonio Huete Jimenez     ,o_erase_on_exit
605382d832SPeter Avalos     ,o_exit_label
615382d832SPeter Avalos     ,o_extra_button
625382d832SPeter Avalos     ,o_extra_label
635382d832SPeter Avalos     ,o_fixed_font
645382d832SPeter Avalos     ,o_form
655382d832SPeter Avalos     ,o_gauge
665382d832SPeter Avalos     ,o_help
675382d832SPeter Avalos     ,o_help_button
685382d832SPeter Avalos     ,o_help_file
695382d832SPeter Avalos     ,o_help_label
705382d832SPeter Avalos     ,o_help_line
715382d832SPeter Avalos     ,o_help_status
721ef6786aSJohn Marino     ,o_help_tags
735382d832SPeter Avalos     ,o_icon
745382d832SPeter Avalos     ,o_ignore
755382d832SPeter Avalos     ,o_infobox
765382d832SPeter Avalos     ,o_input_fd
775382d832SPeter Avalos     ,o_inputbox
785382d832SPeter Avalos     ,o_inputmenu
795382d832SPeter Avalos     ,o_insecure
805382d832SPeter Avalos     ,o_item_help
815382d832SPeter Avalos     ,o_keep_colors
825382d832SPeter Avalos     ,o_keep_tite
835382d832SPeter Avalos     ,o_keep_window
841ef6786aSJohn Marino     ,o_last_key
855382d832SPeter Avalos     ,o_max_input
865382d832SPeter Avalos     ,o_menu
875382d832SPeter Avalos     ,o_mixedform
885382d832SPeter Avalos     ,o_mixedgauge
895382d832SPeter Avalos     ,o_msgbox
905382d832SPeter Avalos     ,o_no_close
91*a8e38dc0SAntonio Huete Jimenez     ,o_nocollapse
925382d832SPeter Avalos     ,o_no_cr_wrap
93*a8e38dc0SAntonio Huete Jimenez     ,o_cant_kill
94*a8e38dc0SAntonio Huete Jimenez     ,o_no_hot_list
955382d832SPeter Avalos     ,o_no_label
965382d832SPeter Avalos     ,o_no_lines
975382d832SPeter Avalos     ,o_no_mouse
985382d832SPeter Avalos     ,o_no_nl_expand
99*a8e38dc0SAntonio Huete Jimenez     ,o_use_shadow
1005382d832SPeter Avalos     ,o_nocancel
1015382d832SPeter Avalos     ,o_nook
1025382d832SPeter Avalos     ,o_ok_label
1035382d832SPeter Avalos     ,o_output_fd
1045382d832SPeter Avalos     ,o_output_separator
1055382d832SPeter Avalos     ,o_passwordbox
1065382d832SPeter Avalos     ,o_passwordform
1075382d832SPeter Avalos     ,o_pause
1085382d832SPeter Avalos     ,o_prgbox
1095382d832SPeter Avalos     ,o_print_maxsize
110*a8e38dc0SAntonio Huete Jimenez     ,o_print_siz
111*a8e38dc0SAntonio Huete Jimenez     ,o_text_only
1125940c9abSDaniel Fojt     ,o_print_text_size
1135382d832SPeter Avalos     ,o_print_version
1145382d832SPeter Avalos     ,o_programbox
1155382d832SPeter Avalos     ,o_progressbox
1165382d832SPeter Avalos     ,o_quoted
1175382d832SPeter Avalos     ,o_radiolist
1185382d832SPeter Avalos     ,o_screen_center
119*a8e38dc0SAntonio Huete Jimenez     ,o_use_scrollbar
1205382d832SPeter Avalos     ,o_separate_output
121*a8e38dc0SAntonio Huete Jimenez     ,o_separate_str
1225382d832SPeter Avalos     ,o_single_quoted
1235382d832SPeter Avalos     ,o_size_err
124*a8e38dc0SAntonio Huete Jimenez     ,o_sleep_secs
1255382d832SPeter Avalos     ,o_smooth
126*a8e38dc0SAntonio Huete Jimenez     ,o_output_stderr
127*a8e38dc0SAntonio Huete Jimenez     ,o_output_stdout
1285382d832SPeter Avalos     ,o_tab_correct
1295382d832SPeter Avalos     ,o_tab_len
1305382d832SPeter Avalos     ,o_tailbox
1315382d832SPeter Avalos     ,o_tailboxbg
1325382d832SPeter Avalos     ,o_textbox
1335382d832SPeter Avalos     ,o_time_format
134*a8e38dc0SAntonio Huete Jimenez     ,o_timeout_secs
1355382d832SPeter Avalos     ,o_title
136*a8e38dc0SAntonio Huete Jimenez     ,o_trim_whitespace
1375382d832SPeter Avalos     ,o_under_mouse
1385382d832SPeter Avalos     ,o_version
1395382d832SPeter Avalos     ,o_visit_items
1405382d832SPeter Avalos     ,o_wmclass
1415382d832SPeter Avalos     ,o_yes_label
1425382d832SPeter Avalos     ,o_yesno
1435382d832SPeter Avalos #ifdef HAVE_WHIPTAIL
1445382d832SPeter Avalos     ,o_fullbutton
1455382d832SPeter Avalos     ,o_topleft
1465382d832SPeter Avalos #endif
1475382d832SPeter Avalos #ifdef HAVE_XDIALOG
1485382d832SPeter Avalos     ,o_calendar
1495382d832SPeter Avalos     ,o_dselect
1505382d832SPeter Avalos     ,o_editbox
1515382d832SPeter Avalos     ,o_fselect
1525382d832SPeter Avalos     ,o_timebox
1535940c9abSDaniel Fojt     ,o_week_start
1545382d832SPeter Avalos #endif
1555382d832SPeter Avalos #ifdef HAVE_XDIALOG2
1565382d832SPeter Avalos     ,o_buildlist
1575382d832SPeter Avalos     ,o_rangebox
1585940c9abSDaniel Fojt     ,o_reorder
1595382d832SPeter Avalos     ,o_treeview
1605382d832SPeter Avalos #endif
1615382d832SPeter Avalos #if defined(HAVE_XDIALOG2) || defined(HAVE_WHIPTAIL)
1625382d832SPeter Avalos     ,o_no_items
1635382d832SPeter Avalos     ,o_no_tags
1645382d832SPeter Avalos #endif
1655382d832SPeter Avalos #ifdef HAVE_DLG_TRACE
1665382d832SPeter Avalos     ,o_trace
1675382d832SPeter Avalos #endif
1685940c9abSDaniel Fojt     ,o_iso_week
1695382d832SPeter Avalos } eOptions;
1705382d832SPeter Avalos 
171*a8e38dc0SAntonio Huete Jimenez typedef enum {
172*a8e38dc0SAntonio Huete Jimenez     tUnknown
173*a8e38dc0SAntonio Huete Jimenez     ,tFalse
174*a8e38dc0SAntonio Huete Jimenez     ,tTrue
175*a8e38dc0SAntonio Huete Jimenez     ,tNumber
176*a8e38dc0SAntonio Huete Jimenez     ,tString
177*a8e38dc0SAntonio Huete Jimenez } tOptions;
178*a8e38dc0SAntonio Huete Jimenez 
1795382d832SPeter Avalos /*
1805382d832SPeter Avalos  * The bits in 'pass' are used to decide which options are applicable at
1815382d832SPeter Avalos  * different stages in the program:
1825382d832SPeter Avalos  *	1 flags before widgets
1835382d832SPeter Avalos  *	2 widgets
1845382d832SPeter Avalos  *	4 non-widget options
1855382d832SPeter Avalos  */
1865382d832SPeter Avalos typedef struct {
1875382d832SPeter Avalos     const char *name;
1885382d832SPeter Avalos     eOptions code;
189*a8e38dc0SAntonio Huete Jimenez     int vars;			/* 0=none, 1=state, 2=vars */
190*a8e38dc0SAntonio Huete Jimenez     tOptions type;		/* type for bool(true/false), number, string */
191*a8e38dc0SAntonio Huete Jimenez     unsigned offset;
1925382d832SPeter Avalos     int pass;			/* 1,2,4 or combination */
1935382d832SPeter Avalos     const char *help;		/* NULL to suppress, non-empty to display params */
1945382d832SPeter Avalos } Options;
1955382d832SPeter Avalos 
1965382d832SPeter Avalos typedef struct {
1975382d832SPeter Avalos     eOptions code;
1985382d832SPeter Avalos     int argmin, argmax;
1995382d832SPeter Avalos     callerFn *jumper;
2005382d832SPeter Avalos } Mode;
2015382d832SPeter Avalos 
202*a8e38dc0SAntonio Huete Jimenez /* use these macros for simple options in DIALOG_STATE */
203*a8e38dc0SAntonio Huete Jimenez #define ssF(name) o_##name, 1, tFalse,  offsetof(DIALOG_STATE,name)
204*a8e38dc0SAntonio Huete Jimenez #define ssT(name) o_##name, 1, tTrue,   offsetof(DIALOG_STATE,name)
205*a8e38dc0SAntonio Huete Jimenez #define ssN(name) o_##name, 1, tNumber, offsetof(DIALOG_STATE,name)
206*a8e38dc0SAntonio Huete Jimenez #define ssS(name) o_##name, 1, tString, offsetof(DIALOG_STATE,name)
207*a8e38dc0SAntonio Huete Jimenez 
208*a8e38dc0SAntonio Huete Jimenez /* use these macros for simple options in DIALOG_VARS */
209*a8e38dc0SAntonio Huete Jimenez #define svF(name) o_##name, 2, tFalse,  offsetof(DIALOG_VARS,name)
210*a8e38dc0SAntonio Huete Jimenez #define svT(name) o_##name, 2, tTrue,   offsetof(DIALOG_VARS,name)
211*a8e38dc0SAntonio Huete Jimenez #define svN(name) o_##name, 2, tNumber, offsetof(DIALOG_VARS,name)
212*a8e38dc0SAntonio Huete Jimenez #define svS(name) o_##name, 2, tString, offsetof(DIALOG_VARS,name)
213*a8e38dc0SAntonio Huete Jimenez 
214*a8e38dc0SAntonio Huete Jimenez /* use these macros for ignored options */
215*a8e38dc0SAntonio Huete Jimenez #define xxF(name) o_##name, 0, tFalse,  0
216*a8e38dc0SAntonio Huete Jimenez #define xxT(name) o_##name, 0, tTrue,   0
217*a8e38dc0SAntonio Huete Jimenez #define xxN(name) o_##name, 0, tNumber, 0
218*a8e38dc0SAntonio Huete Jimenez #define xxS(name) o_##name, 0, tString, 0
219*a8e38dc0SAntonio Huete Jimenez 
220*a8e38dc0SAntonio Huete Jimenez /* use this macro for widget options */
221*a8e38dc0SAntonio Huete Jimenez #define opW(name) o_##name, 0, 0, 0
222*a8e38dc0SAntonio Huete Jimenez 
223*a8e38dc0SAntonio Huete Jimenez /* use this macro for other options */
224*a8e38dc0SAntonio Huete Jimenez #define opO(name) o_##name, 0, 0, 0
225*a8e38dc0SAntonio Huete Jimenez 
2265940c9abSDaniel Fojt static int known_opts = 0;
2275940c9abSDaniel Fojt static const char **dialog_opts;
2285382d832SPeter Avalos static char **dialog_argv;
2295382d832SPeter Avalos 
2305940c9abSDaniel Fojt static char **special_argv = 0;
2315940c9abSDaniel Fojt static int special_argc = 0;
2325940c9abSDaniel Fojt 
2335382d832SPeter Avalos static bool ignore_unknown = FALSE;
2345382d832SPeter Avalos 
2355382d832SPeter Avalos static const char *program = "dialog";
2365382d832SPeter Avalos 
2375940c9abSDaniel Fojt #ifdef NO_LEAKS
2385940c9abSDaniel Fojt typedef struct _all_blobs {
2395940c9abSDaniel Fojt     struct _all_blobs *next;
2405940c9abSDaniel Fojt     void *blob;
2415940c9abSDaniel Fojt } AllBlobs;
2425940c9abSDaniel Fojt 
2435940c9abSDaniel Fojt static AllBlobs *all_blobs;
2445940c9abSDaniel Fojt #endif
2455940c9abSDaniel Fojt 
2465382d832SPeter Avalos /*
2475382d832SPeter Avalos  * The options[] table is organized this way to make it simple to maintain
2485382d832SPeter Avalos  * a sorted list of options for the help-message.
249*a8e38dc0SAntonio Huete Jimenez  *
250*a8e38dc0SAntonio Huete Jimenez  * Because Boolean options correspond to "true", --shadow is listed here while
251*a8e38dc0SAntonio Huete Jimenez  * --no-shadow is not.  The findOption and optionBool functions handle the
252*a8e38dc0SAntonio Huete Jimenez  * cases where "no" is added or removed from the option name to derive an
253*a8e38dc0SAntonio Huete Jimenez  * opposite setting.
2545382d832SPeter Avalos  */
2555382d832SPeter Avalos /* *INDENT-OFF* */
2565382d832SPeter Avalos static const Options options[] = {
257*a8e38dc0SAntonio Huete Jimenez     { "allow-close",	xxT(allow_close),	1, NULL },
258*a8e38dc0SAntonio Huete Jimenez     { "and-widget",	opO(and_widget),	4, NULL },
259*a8e38dc0SAntonio Huete Jimenez     { "ascii-lines",	svT(ascii_lines), 	1, "" },
260*a8e38dc0SAntonio Huete Jimenez     { "aspect",		ssN(aspect_ratio),	1, "<ratio>" },
261*a8e38dc0SAntonio Huete Jimenez     { "auto-placement", xxT(auto_placement),	1, NULL },
262*a8e38dc0SAntonio Huete Jimenez     { "backtitle",	svS(backtitle),		1, "<backtitle>" },
263*a8e38dc0SAntonio Huete Jimenez     { "beep",		svT(beep_signal),	1, "" },
264*a8e38dc0SAntonio Huete Jimenez     { "beep-after",	svT(beep_after_signal),	1, "" },
265*a8e38dc0SAntonio Huete Jimenez     { "begin",		svT(begin_set),		1, "<y> <x>" },
266*a8e38dc0SAntonio Huete Jimenez     { "cancel-label",	svS(cancel_label),	1, "<str>" },
267*a8e38dc0SAntonio Huete Jimenez     { "checklist",	opW(checklist),		2, "<text> <height> <width> <list height> <tag1> <item1> <status1>..." },
268*a8e38dc0SAntonio Huete Jimenez     { "clear",		svT(dlg_clear_screen),	1, "" },
269*a8e38dc0SAntonio Huete Jimenez     { "colors",		svT(colors),		1, "" },
270*a8e38dc0SAntonio Huete Jimenez     { "column-separator",svS(column_separator),	1, "<str>" },
271*a8e38dc0SAntonio Huete Jimenez     { "cr-wrap",	svT(cr_wrap),		1, "" },
272*a8e38dc0SAntonio Huete Jimenez     { "create-rc",	opO(create_rc),		1, NULL },
273*a8e38dc0SAntonio Huete Jimenez     { "cursor-off-label",svT(cursor_off_label),	1, "" },
274*a8e38dc0SAntonio Huete Jimenez     { "date-format",	svS(date_format),	1, "<str>" },
275*a8e38dc0SAntonio Huete Jimenez     { "default-button",	xxS(default_button),	1, "<str>" },
276*a8e38dc0SAntonio Huete Jimenez     { "default-item",	svS(default_item),	1, "<str>" },
277*a8e38dc0SAntonio Huete Jimenez     { "defaultno",	svT(defaultno),		1, "" },
278*a8e38dc0SAntonio Huete Jimenez     { "erase-on-exit",	svT(erase_on_exit),	1, "" },
279*a8e38dc0SAntonio Huete Jimenez     { "exit-label",	svS(exit_label),	1, "<str>" },
280*a8e38dc0SAntonio Huete Jimenez     { "extra-button",	svT(extra_button),	1, "" },
281*a8e38dc0SAntonio Huete Jimenez     { "extra-label",	svS(extra_label),	1, "<str>" },
282*a8e38dc0SAntonio Huete Jimenez     { "fixed-font",	xxT(fixed_font),	1, NULL },
283*a8e38dc0SAntonio Huete Jimenez     { "form",		opW(form),		2, "<text> <height> <width> <form height> <label1> <l_y1> <l_x1> <item1> <i_y1> <i_x1> <flen1> <ilen1>..." },
284*a8e38dc0SAntonio Huete Jimenez     { "gauge",		opW(gauge),		2, "<text> <height> <width> [<percent>]" },
285*a8e38dc0SAntonio Huete Jimenez     { "guage",		opW(gauge),		2, NULL },
286*a8e38dc0SAntonio Huete Jimenez     { "help",		opO(help),		4, "" },
287*a8e38dc0SAntonio Huete Jimenez     { "help-button",	svT(help_button),	1, "" },
288*a8e38dc0SAntonio Huete Jimenez     { "help-label",	svS(help_label),	1, "<str>" },
289*a8e38dc0SAntonio Huete Jimenez     { "help-status",	svT(help_status),	1, "" },
290*a8e38dc0SAntonio Huete Jimenez     { "help-tags",	svT(help_tags),		1, "" },
291*a8e38dc0SAntonio Huete Jimenez     { "hfile",		svS(help_file),		1, "<str>" },
292*a8e38dc0SAntonio Huete Jimenez     { "hline",		svS(help_line),		1, "<str>" },
293*a8e38dc0SAntonio Huete Jimenez     { "icon",		xxS(icon),		1, NULL },
294*a8e38dc0SAntonio Huete Jimenez     { "ignore",		opO(ignore),		1, "" },
295*a8e38dc0SAntonio Huete Jimenez     { "infobox",	opW(infobox),		2, "<text> <height> <width>" },
296*a8e38dc0SAntonio Huete Jimenez     { "input-fd",	opO(input_fd),		1, "<fd>" },
297*a8e38dc0SAntonio Huete Jimenez     { "inputbox",	opW(inputbox),		2, "<text> <height> <width> [<init>]" },
298*a8e38dc0SAntonio Huete Jimenez     { "inputmenu",	opW(inputmenu),		2, "<text> <height> <width> <menu height> <tag1> <item1>..." },
299*a8e38dc0SAntonio Huete Jimenez     { "insecure",	svT(insecure),		1, "" },
300*a8e38dc0SAntonio Huete Jimenez     { "item-help",	svT(item_help),		1, "" },
301*a8e38dc0SAntonio Huete Jimenez     { "keep-colors",	xxT(keep_colors),	1, NULL },
302*a8e38dc0SAntonio Huete Jimenez     { "keep-tite",	svT(keep_tite),		1, "" },
303*a8e38dc0SAntonio Huete Jimenez     { "keep-window",	svT(keep_window),	1, "" },
304*a8e38dc0SAntonio Huete Jimenez     { "last-key",	svT(last_key),		1, "" },
305*a8e38dc0SAntonio Huete Jimenez     { "max-input",	svN(max_input),		1, "<n>" },
306*a8e38dc0SAntonio Huete Jimenez     { "menu",		opW(menu),		2, "<text> <height> <width> <menu height> <tag1> <item1>..." },
307*a8e38dc0SAntonio Huete Jimenez     { "mixedform",	opW(mixedform),		2, "<text> <height> <width> <form height> <label1> <l_y1> <l_x1> <item1> <i_y1> <i_x1> <flen1> <ilen1> <itype>..." },
308*a8e38dc0SAntonio Huete Jimenez     { "mixedgauge",	opW(mixedgauge),	2, "<text> <height> <width> <percent> <tag1> <item1>..." },
309*a8e38dc0SAntonio Huete Jimenez     { "msgbox",		opW(msgbox),		2, "<text> <height> <width>" },
310*a8e38dc0SAntonio Huete Jimenez     { "no-cancel",	svT(nocancel),		1, "" },
311*a8e38dc0SAntonio Huete Jimenez     { "no-close",	xxT(no_close),		1, NULL },
312*a8e38dc0SAntonio Huete Jimenez     { "no-collapse",	svT(nocollapse),	1, "" },
313*a8e38dc0SAntonio Huete Jimenez     { "no-hot-list",	svT(no_hot_list),	1, "" },
314*a8e38dc0SAntonio Huete Jimenez     { "no-kill",	svT(cant_kill),		1, "" },
315*a8e38dc0SAntonio Huete Jimenez     { "no-label",	svS(no_label),		1, "<str>" },
316*a8e38dc0SAntonio Huete Jimenez     { "no-lines",	svT(no_lines), 		1, "" },
317*a8e38dc0SAntonio Huete Jimenez     { "no-mouse",	ssT(no_mouse),		1, "" },
318*a8e38dc0SAntonio Huete Jimenez     { "no-nl-expand",	svT(no_nl_expand),	1, "" },
319*a8e38dc0SAntonio Huete Jimenez     { "no-ok",		svT(nook),		1, "" },
320*a8e38dc0SAntonio Huete Jimenez     { "no-shadow",	ssF(use_shadow),	1, "" },
321*a8e38dc0SAntonio Huete Jimenez     { "ok-label",	svS(ok_label),		1, "<str>" },
322*a8e38dc0SAntonio Huete Jimenez     { "output-fd",	opO(output_fd),		1, "<fd>" },
323*a8e38dc0SAntonio Huete Jimenez     { "output-separator",svS(output_separator),	1, "<str>" },
324*a8e38dc0SAntonio Huete Jimenez     { "passwordbox",	opW(passwordbox),	2, "<text> <height> <width> [<init>]" },
325*a8e38dc0SAntonio Huete Jimenez     { "passwordform",	opW(passwordform),	2, "<text> <height> <width> <form height> <label1> <l_y1> <l_x1> <item1> <i_y1> <i_x1> <flen1> <ilen1>..." },
326*a8e38dc0SAntonio Huete Jimenez     { "pause",		opW(pause),		2, "<text> <height> <width> <seconds>" },
327*a8e38dc0SAntonio Huete Jimenez     { "prgbox",		opW(prgbox),		2, "<text> <command> <height> <width>" },
328*a8e38dc0SAntonio Huete Jimenez     { "print-maxsize",	opO(print_maxsize),	1, "" },
329*a8e38dc0SAntonio Huete Jimenez     { "print-size",	svT(print_siz),		1, "" },
330*a8e38dc0SAntonio Huete Jimenez     { "print-text-only",ssT(text_only),		5, "<text> <height> <width>" },
331*a8e38dc0SAntonio Huete Jimenez     { "print-text-size",opO(print_text_size),	5, "<text> <height> <width>" },
332*a8e38dc0SAntonio Huete Jimenez     { "print-version",	opO(print_version),	5, "" },
333*a8e38dc0SAntonio Huete Jimenez     { "programbox",	opW(programbox),	2, "<text> <height> <width>" },
334*a8e38dc0SAntonio Huete Jimenez     { "progressbox",	opW(progressbox),	2, "<text> <height> <width>" },
335*a8e38dc0SAntonio Huete Jimenez     { "quoted",		svT(quoted),		1, "" },
336*a8e38dc0SAntonio Huete Jimenez     { "radiolist",	opW(radiolist),		2, "<text> <height> <width> <list height> <tag1> <item1> <status1>..." },
337*a8e38dc0SAntonio Huete Jimenez     { "screen-center",	xxT(screen_center),	1, NULL },
338*a8e38dc0SAntonio Huete Jimenez     { "scrollbar",	ssT(use_scrollbar),	1, "" },
339*a8e38dc0SAntonio Huete Jimenez     { "separate-output",svT(separate_output),	1, "" },
340*a8e38dc0SAntonio Huete Jimenez     { "separate-widget",ssS(separate_str),	1, "<str>" },
341*a8e38dc0SAntonio Huete Jimenez     { "separator",	svS(output_separator),	1, NULL },
342*a8e38dc0SAntonio Huete Jimenez     { "single-quoted",	svT(single_quoted),	1, "" },
343*a8e38dc0SAntonio Huete Jimenez     { "size-err",	svT(size_err),		1, "" },
344*a8e38dc0SAntonio Huete Jimenez     { "sleep",		svN(sleep_secs),	1, "<secs>" },
345*a8e38dc0SAntonio Huete Jimenez     { "smooth",		xxT(smooth),		1, NULL },
346*a8e38dc0SAntonio Huete Jimenez     { "stderr",		opO(output_stderr),	1, "" },
347*a8e38dc0SAntonio Huete Jimenez     { "stdout",		opO(output_stdout),	1, "" },
348*a8e38dc0SAntonio Huete Jimenez     { "tab-correct",	svT(tab_correct),	1, "" },
349*a8e38dc0SAntonio Huete Jimenez     { "tab-len",	ssN(tab_len),		1, "<n>" },
350*a8e38dc0SAntonio Huete Jimenez     { "tailbox",	opW(tailbox),		2, "<file> <height> <width>" },
351*a8e38dc0SAntonio Huete Jimenez     { "tailboxbg",	opW(tailboxbg),		2, "<file> <height> <width>" },
352*a8e38dc0SAntonio Huete Jimenez     { "textbox",	opW(textbox),		2, "<file> <height> <width>" },
353*a8e38dc0SAntonio Huete Jimenez     { "time-format",	svS(time_format),	1, "<str>" },
354*a8e38dc0SAntonio Huete Jimenez     { "timeout",	svN(timeout_secs),	1, "<secs>" },
355*a8e38dc0SAntonio Huete Jimenez     { "title",		svS(title),		1, "<title>" },
356*a8e38dc0SAntonio Huete Jimenez     { "trim",		svT(trim_whitespace),	1, "" },
357*a8e38dc0SAntonio Huete Jimenez     { "under-mouse", 	xxT(under_mouse),	1, NULL },
358*a8e38dc0SAntonio Huete Jimenez     { "version",	opO(version),		5, "" },
359*a8e38dc0SAntonio Huete Jimenez     { "visit-items", 	ssT(visit_items),	1, "" },
360*a8e38dc0SAntonio Huete Jimenez     { "wmclass",	xxS(wmclass),		1, NULL },
361*a8e38dc0SAntonio Huete Jimenez     { "yes-label",	svS(yes_label),		1, "<str>" },
362*a8e38dc0SAntonio Huete Jimenez     { "yesno",		opW(yesno),		2, "<text> <height> <width>" },
3635382d832SPeter Avalos #ifdef HAVE_WHIPTAIL
364*a8e38dc0SAntonio Huete Jimenez     { "cancel-button",	svS(cancel_label),	1, NULL },
365*a8e38dc0SAntonio Huete Jimenez     { "fb",		xxT(fullbutton),	1, NULL },
366*a8e38dc0SAntonio Huete Jimenez     { "fullbutton",	xxT(fullbutton),	1, NULL },
367*a8e38dc0SAntonio Huete Jimenez     { "no-button",	svS(no_label),		1, NULL },
368*a8e38dc0SAntonio Huete Jimenez     { "ok-button",	svS(ok_label),		1, NULL },
369*a8e38dc0SAntonio Huete Jimenez     { "scrolltext",	ssT(use_scrollbar),	1, NULL },
370*a8e38dc0SAntonio Huete Jimenez     { "topleft",	svT(begin_set),		1, NULL },
371*a8e38dc0SAntonio Huete Jimenez     { "yes-button",	svS(yes_label),		1, NULL },
3725382d832SPeter Avalos #endif
3735382d832SPeter Avalos #ifdef HAVE_XDIALOG
374*a8e38dc0SAntonio Huete Jimenez     { "calendar",	opW(calendar),		2, "<text> <height> <width> <day> <month> <year>" },
375*a8e38dc0SAntonio Huete Jimenez     { "dselect",	opW(dselect),		2, "<directory> <height> <width>" },
376*a8e38dc0SAntonio Huete Jimenez     { "editbox",	opW(editbox),		2, "<file> <height> <width>" },
377*a8e38dc0SAntonio Huete Jimenez     { "fselect",	opW(fselect),		2, "<filepath> <height> <width>" },
378*a8e38dc0SAntonio Huete Jimenez     { "timebox",	opW(timebox),		2, "<text> <height> <width> <hour> <minute> <second>" },
379*a8e38dc0SAntonio Huete Jimenez     { "week-start",	svS(week_start),	1, "<str>" },
380*a8e38dc0SAntonio Huete Jimenez     { "iso-week",	svT(iso_week),		1, NULL },
3815382d832SPeter Avalos #endif
3825382d832SPeter Avalos #ifdef HAVE_XDIALOG2
383*a8e38dc0SAntonio Huete Jimenez     { "buildlist",	opW(buildlist),		2, "<text> <height> <width> <list-height> <tag1> <item1> <status1>..." },
384*a8e38dc0SAntonio Huete Jimenez     { "no-items", 	svT(no_items),		1, "" },
385*a8e38dc0SAntonio Huete Jimenez     { "no-tags", 	svT(no_tags),		1, "" },
386*a8e38dc0SAntonio Huete Jimenez     { "rangebox",	opW(rangebox),		2, "<text> <height> <width> <min-value> <max-value> <default-value>" },
387*a8e38dc0SAntonio Huete Jimenez     { "reorder", 	svT(reorder),		1, "" },
388*a8e38dc0SAntonio Huete Jimenez     { "treeview",	opW(treeview),		2, "<text> <height> <width> <list-height> <tag1> <item1> <status1> <depth1>..." },
3895382d832SPeter Avalos #endif
3905382d832SPeter Avalos #if defined(HAVE_XDIALOG2) || defined(HAVE_WHIPTAIL)
391*a8e38dc0SAntonio Huete Jimenez     { "noitem", 	svT(no_items),		1, NULL },
392*a8e38dc0SAntonio Huete Jimenez     { "notags", 	svT(no_tags),		1, NULL },
3935382d832SPeter Avalos #endif
3945382d832SPeter Avalos #ifdef HAVE_DLG_TRACE
395*a8e38dc0SAntonio Huete Jimenez     { "trace",		opO(trace),		1, "<file>" },
3965382d832SPeter Avalos #endif
3975382d832SPeter Avalos };
3985382d832SPeter Avalos /* *INDENT-ON* */
3995382d832SPeter Avalos 
4005940c9abSDaniel Fojt #ifdef NO_LEAKS
4015940c9abSDaniel Fojt static void
ignore_leak(void * value)4025940c9abSDaniel Fojt ignore_leak(void *value)
4035940c9abSDaniel Fojt {
4045940c9abSDaniel Fojt     AllBlobs *next = dlg_calloc(AllBlobs, (size_t) 1);
4055940c9abSDaniel Fojt     if (next != 0) {
4065940c9abSDaniel Fojt 	next->blob = value;
4075940c9abSDaniel Fojt 	next->next = all_blobs;
4085940c9abSDaniel Fojt 	all_blobs = next;
4095940c9abSDaniel Fojt     }
4105940c9abSDaniel Fojt }
4115940c9abSDaniel Fojt 
4125940c9abSDaniel Fojt static void
handle_leaks(void)4135940c9abSDaniel Fojt handle_leaks(void)
4145940c9abSDaniel Fojt {
4155940c9abSDaniel Fojt     while (all_blobs != 0) {
4165940c9abSDaniel Fojt 	char *blob = all_blobs->blob;
4175940c9abSDaniel Fojt 	AllBlobs *next = all_blobs->next;
4185940c9abSDaniel Fojt 	free(blob);
4195940c9abSDaniel Fojt 	free(all_blobs);
4205940c9abSDaniel Fojt 	all_blobs = next;
4215940c9abSDaniel Fojt     }
4225940c9abSDaniel Fojt     free(dialog_opts);
4235940c9abSDaniel Fojt     if (special_argv != 0) {
4245940c9abSDaniel Fojt 	free(special_argv[0]);
4255940c9abSDaniel Fojt 	free(special_argv);
4265940c9abSDaniel Fojt 	special_argv = 0;
4275940c9abSDaniel Fojt 	special_argc = 0;
4285940c9abSDaniel Fojt     }
4295940c9abSDaniel Fojt }
4305940c9abSDaniel Fojt #else
4315940c9abSDaniel Fojt #define handle_leaks()		/* nothing */
4325940c9abSDaniel Fojt #define ignore_leak(n)		/* nothing */
4335940c9abSDaniel Fojt #endif
4345940c9abSDaniel Fojt 
4355940c9abSDaniel Fojt #define OptionChars "\
4365940c9abSDaniel Fojt 0123456789\
4375940c9abSDaniel Fojt -\
4385940c9abSDaniel Fojt abcdefghijklmnopqrstuvwxyz\
4395940c9abSDaniel Fojt "
4405940c9abSDaniel Fojt 
4415940c9abSDaniel Fojt /*
4425940c9abSDaniel Fojt  * Check if the given string from main's argv is an option.
4435940c9abSDaniel Fojt  */
4445940c9abSDaniel Fojt static bool
isOption(const char * arg)4455940c9abSDaniel Fojt isOption(const char *arg)
4465940c9abSDaniel Fojt {
4475940c9abSDaniel Fojt     bool result = FALSE;
4485940c9abSDaniel Fojt 
4495940c9abSDaniel Fojt     if (arg != 0) {
4505940c9abSDaniel Fojt 	if (dialog_opts != 0) {
4515940c9abSDaniel Fojt 	    int n;
4525940c9abSDaniel Fojt 	    for (n = 0; dialog_opts[n] != 0; ++n) {
4535940c9abSDaniel Fojt 		if (dialog_opts[n] == arg) {
4545940c9abSDaniel Fojt 		    result = TRUE;
4555940c9abSDaniel Fojt 		    break;
4565940c9abSDaniel Fojt 		}
4575940c9abSDaniel Fojt 	    }
4585940c9abSDaniel Fojt 	} else if (!strncmp(arg, "--", (size_t) 2) && isalpha(UCH(arg[2]))) {
4595940c9abSDaniel Fojt 	    if (strlen(arg) == (strspn) (arg, OptionChars)) {
4605940c9abSDaniel Fojt 		result = TRUE;
4615940c9abSDaniel Fojt 	    } else {
4625940c9abSDaniel Fojt 		handle_leaks();
463*a8e38dc0SAntonio Huete Jimenez 		dlg_exiterr(_("Invalid option \"%s\""), arg);
4645940c9abSDaniel Fojt 	    }
4655940c9abSDaniel Fojt 	}
4665940c9abSDaniel Fojt     }
4675940c9abSDaniel Fojt     return result;
4685940c9abSDaniel Fojt }
4695940c9abSDaniel Fojt 
4705382d832SPeter Avalos /*
4715382d832SPeter Avalos  * Make an array showing which argv[] entries are options.  Use "--" as a
4725382d832SPeter Avalos  * special token to escape the next argument, allowing it to begin with "--".
4735382d832SPeter Avalos  * When we find a "--" argument, also remove it from argv[] and adjust argc.
4745382d832SPeter Avalos  * That appears to be an undocumented feature of the popt library.
4755382d832SPeter Avalos  *
4765382d832SPeter Avalos  * Also, if we see a "--file", expand it into the parameter list by reading the
4775382d832SPeter Avalos  * text from the given file and stripping quotes, treating whitespace outside
4785382d832SPeter Avalos  * quotes as a parameter delimiter.
4795382d832SPeter Avalos  *
4805382d832SPeter Avalos  * Finally, if we see a "--args", dump the current list of arguments to the
4815382d832SPeter Avalos  * standard error.  This is used for debugging complex --file combinations.
4825382d832SPeter Avalos  */
4835382d832SPeter Avalos static void
unescape_argv(int * argcp,char *** argvp)4845382d832SPeter Avalos unescape_argv(int *argcp, char ***argvp)
4855382d832SPeter Avalos {
4865382d832SPeter Avalos     int j, k;
4875382d832SPeter Avalos     int limit_includes = 20 + *argcp;
4885382d832SPeter Avalos     int count_includes = 0;
4895382d832SPeter Avalos     bool doalloc = FALSE;
4905382d832SPeter Avalos     char *filename;
4915940c9abSDaniel Fojt     const char **my_argv = 0;
4925940c9abSDaniel Fojt     int my_argc;
4935382d832SPeter Avalos 
4945940c9abSDaniel Fojt     DLG_TRACE(("# unescape_argv\n"));
4955940c9abSDaniel Fojt     for (k = 0; k < 2; ++k) {
4965940c9abSDaniel Fojt 
4975940c9abSDaniel Fojt 	my_argc = 0;
4985940c9abSDaniel Fojt 	if (special_argv != 0) {
4995940c9abSDaniel Fojt 	    for (j = 0; special_argv[j] != 0; ++j) {
5005940c9abSDaniel Fojt 		if (!strcmp(special_argv[j], "--")) {
5015940c9abSDaniel Fojt 		    break;
5025940c9abSDaniel Fojt 		} else if (isOption(special_argv[j])) {
5035940c9abSDaniel Fojt 		    if (k != 0)
5045940c9abSDaniel Fojt 			my_argv[my_argc] = special_argv[j];
5055940c9abSDaniel Fojt 		    my_argc++;
5065940c9abSDaniel Fojt 		}
5075940c9abSDaniel Fojt 	    }
5085940c9abSDaniel Fojt 	}
5095940c9abSDaniel Fojt 
5105940c9abSDaniel Fojt 	if (k == 0) {
5115940c9abSDaniel Fojt 	    my_argc += (*argcp + 1);
5125940c9abSDaniel Fojt 	    my_argv = dlg_calloc(const char *, (size_t) my_argc);
5135940c9abSDaniel Fojt 	    assert_ptr(my_argv, "unescape_argv");
5145940c9abSDaniel Fojt 	}
5155940c9abSDaniel Fojt     }
5165382d832SPeter Avalos 
5175382d832SPeter Avalos     for (j = 1; j < *argcp; j++) {
5185382d832SPeter Avalos 	bool escaped = FALSE;
5195382d832SPeter Avalos 	if (!strcmp((*argvp)[j], "--")) {
5205382d832SPeter Avalos 	    escaped = TRUE;
5215940c9abSDaniel Fojt 	    dlg_eat_argv(argcp, argvp, j, 1);
5225382d832SPeter Avalos 	} else if (!strcmp((*argvp)[j], "--args")) {
523*a8e38dc0SAntonio Huete Jimenez 	    fprintf(stderr, _("Showing arguments at arg%d\n"), j);
5245382d832SPeter Avalos 	    for (k = 0; k < *argcp; ++k) {
5255382d832SPeter Avalos 		fprintf(stderr, " arg%d:%s\n", k, (*argvp)[k]);
5265382d832SPeter Avalos 	    }
5275940c9abSDaniel Fojt 	    dlg_eat_argv(argcp, argvp, j, 1);
5281ef6786aSJohn Marino 	    --j;
5295382d832SPeter Avalos 	} else if (!strcmp((*argvp)[j], "--file")) {
5305940c9abSDaniel Fojt 	    if (++count_includes > limit_includes) {
5315940c9abSDaniel Fojt 		handle_leaks();
532*a8e38dc0SAntonio Huete Jimenez 		dlg_exiterr(_("Too many --file options"));
5335940c9abSDaniel Fojt 	    }
5345382d832SPeter Avalos 
5355382d832SPeter Avalos 	    if ((filename = (*argvp)[j + 1]) != 0) {
5365382d832SPeter Avalos 		FILE *fp;
5375382d832SPeter Avalos 		char **list;
5385382d832SPeter Avalos 
5395382d832SPeter Avalos 		if (*filename == '&') {
5405382d832SPeter Avalos 		    fp = fdopen(atoi(filename + sizeof(char)), "r");
5415382d832SPeter Avalos 		} else {
5425382d832SPeter Avalos 		    fp = fopen(filename, "r");
5435382d832SPeter Avalos 		}
5445382d832SPeter Avalos 
5455382d832SPeter Avalos 		if (fp) {
5465940c9abSDaniel Fojt 		    char *blob;
5475940c9abSDaniel Fojt 		    int added;
5485940c9abSDaniel Fojt 		    size_t bytes_read;
5495940c9abSDaniel Fojt 		    size_t length;
5505940c9abSDaniel Fojt 		    int n;
5515940c9abSDaniel Fojt 
5525940c9abSDaniel Fojt 		    DLG_TRACE(("# opened --file %s ..\n", filename));
5535382d832SPeter Avalos 		    blob = NULL;
5545382d832SPeter Avalos 		    length = 0;
5555382d832SPeter Avalos 		    do {
5565382d832SPeter Avalos 			blob = dlg_realloc(char, length + BUFSIZ + 1, blob);
5575382d832SPeter Avalos 			assert_ptr(blob, "unescape_argv");
5585382d832SPeter Avalos 			bytes_read = fread(blob + length,
5595382d832SPeter Avalos 					   sizeof(char),
5605382d832SPeter Avalos 					     (size_t) BUFSIZ,
5615382d832SPeter Avalos 					   fp);
5625382d832SPeter Avalos 			length += bytes_read;
5635940c9abSDaniel Fojt 			if (ferror(fp)) {
5645940c9abSDaniel Fojt 			    handle_leaks();
565*a8e38dc0SAntonio Huete Jimenez 			    dlg_exiterr(_("error on filehandle in unescape_argv"));
5665940c9abSDaniel Fojt 			}
5675382d832SPeter Avalos 		    } while (bytes_read == BUFSIZ);
5685382d832SPeter Avalos 		    fclose(fp);
5695382d832SPeter Avalos 
5705382d832SPeter Avalos 		    blob[length] = '\0';
5715940c9abSDaniel Fojt 		    ignore_leak(blob);
5725382d832SPeter Avalos 
5735382d832SPeter Avalos 		    list = dlg_string_to_argv(blob);
5741ef6786aSJohn Marino 		    added = dlg_count_argv(list);
5755382d832SPeter Avalos 		    if (added > 2) {
5761ef6786aSJohn Marino 			/* *argcp arguments before the expansion of --file
5771ef6786aSJohn Marino 			   - 2 for the removal of '--file <filepath>'
5781ef6786aSJohn Marino 			   + added for the arguments contained in <filepath>
5791ef6786aSJohn Marino 			   + 1 for the terminating NULL pointer */
5801ef6786aSJohn Marino 			size_t need = (size_t) (*argcp + added - 1);
5815382d832SPeter Avalos 			if (doalloc) {
5825382d832SPeter Avalos 			    *argvp = dlg_realloc(char *, need, *argvp);
5835382d832SPeter Avalos 			    assert_ptr(*argvp, "unescape_argv");
5845382d832SPeter Avalos 			} else {
5855382d832SPeter Avalos 			    char **newp = dlg_malloc(char *, need);
5865940c9abSDaniel Fojt 			    ignore_leak(newp);
5875382d832SPeter Avalos 			    assert_ptr(newp, "unescape_argv");
5885382d832SPeter Avalos 			    for (n = 0; n < *argcp; ++n) {
5895382d832SPeter Avalos 				newp[n] = (*argvp)[n];
5905382d832SPeter Avalos 			    }
5911ef6786aSJohn Marino 			    /* The new array is not NULL-terminated yet. */
5925382d832SPeter Avalos 			    *argvp = newp;
5935382d832SPeter Avalos 			    doalloc = TRUE;
5945382d832SPeter Avalos 			}
5955940c9abSDaniel Fojt 			my_argv = dlg_realloc(const char *, need, my_argv);
5965940c9abSDaniel Fojt 			assert_ptr(my_argv, "unescape_argv");
5971ef6786aSJohn Marino 
5981ef6786aSJohn Marino 			/* Shift the arguments after '--file <filepath>'
5991ef6786aSJohn Marino 			   right by (added - 2) positions */
6001ef6786aSJohn Marino 			for (n = *argcp - 1; n >= j + 2; --n) {
6015382d832SPeter Avalos 			    (*argvp)[n + added - 2] = (*argvp)[n];
6025382d832SPeter Avalos 			}
6031ef6786aSJohn Marino 		    } else if (added < 2) {
6041ef6786aSJohn Marino 			/* 0 or 1 argument read from the included file
6051ef6786aSJohn Marino 			   -> shift the arguments after '--file <filepath>'
6061ef6786aSJohn Marino 			   left by (2 - added) positions */
6071ef6786aSJohn Marino 			for (n = j + added; n + 2 - added < *argcp; ++n) {
6081ef6786aSJohn Marino 			    (*argvp)[n] = (*argvp)[n + 2 - added];
6091ef6786aSJohn Marino 			}
6101ef6786aSJohn Marino 		    }
6111ef6786aSJohn Marino 		    /* Copy the inserted arguments to *argvp */
6125382d832SPeter Avalos 		    for (n = 0; n < added; ++n) {
6135382d832SPeter Avalos 			(*argvp)[n + j] = list[n];
6145382d832SPeter Avalos 		    }
6155382d832SPeter Avalos 		    *argcp += added - 2;
6161ef6786aSJohn Marino 		    (*argvp)[*argcp] = 0;	/* Write the NULL terminator */
6171ef6786aSJohn Marino 		    free(list);	/* No-op if 'list' is NULL */
6181ef6786aSJohn Marino 		    /* Force rescan starting from the first inserted argument */
6191ef6786aSJohn Marino 		    --j;
6205940c9abSDaniel Fojt 		    DLG_TRACE(("# finished --file\n"));
6211ef6786aSJohn Marino 		    continue;
6225382d832SPeter Avalos 		} else {
6235940c9abSDaniel Fojt 		    handle_leaks();
624*a8e38dc0SAntonio Huete Jimenez 		    dlg_exiterr(_("Cannot open --file %s"), filename);
6255382d832SPeter Avalos 		}
6265382d832SPeter Avalos 	    } else {
6275940c9abSDaniel Fojt 		handle_leaks();
628*a8e38dc0SAntonio Huete Jimenez 		dlg_exiterr(_("No value given for --file"));
6295382d832SPeter Avalos 	    }
6305382d832SPeter Avalos 	}
6315382d832SPeter Avalos 	if (!escaped
6325382d832SPeter Avalos 	    && (*argvp)[j] != 0
6335382d832SPeter Avalos 	    && !strncmp((*argvp)[j], "--", (size_t) 2)
6345382d832SPeter Avalos 	    && isalpha(UCH((*argvp)[j][2]))) {
6355940c9abSDaniel Fojt 	    my_argv[my_argc++] = (*argvp)[j];
6365940c9abSDaniel Fojt 	    DLG_TRACE(("#\toption argv[%d]=%s\n", j, (*argvp)[j]));
6375382d832SPeter Avalos 	}
6385382d832SPeter Avalos     }
6395382d832SPeter Avalos 
6405940c9abSDaniel Fojt     my_argv[my_argc] = 0;
6415940c9abSDaniel Fojt 
6425940c9abSDaniel Fojt     known_opts = my_argc;
6435940c9abSDaniel Fojt     dialog_opts = my_argv;
6445940c9abSDaniel Fojt 
6455940c9abSDaniel Fojt     DLG_TRACE(("#\t%d options vs %d arguments\n", known_opts, *argcp));
6465382d832SPeter Avalos     dialog_argv = (*argvp);
6475382d832SPeter Avalos }
6485382d832SPeter Avalos 
649*a8e38dc0SAntonio Huete Jimenez static const Options *
findOption(const char * name,int pass,bool recur)650*a8e38dc0SAntonio Huete Jimenez findOption(const char *name, int pass, bool recur)
651*a8e38dc0SAntonio Huete Jimenez {
652*a8e38dc0SAntonio Huete Jimenez     const Options *result = NULL;
653*a8e38dc0SAntonio Huete Jimenez 
654*a8e38dc0SAntonio Huete Jimenez     if (!strncmp(name, "--", 2) && isalpha(UCH(name[2]))) {
655*a8e38dc0SAntonio Huete Jimenez 	unsigned n;
656*a8e38dc0SAntonio Huete Jimenez 
657*a8e38dc0SAntonio Huete Jimenez 	name += 2;		/* skip the "--" */
658*a8e38dc0SAntonio Huete Jimenez 	for (n = 0; n < TableSize(options); n++) {
659*a8e38dc0SAntonio Huete Jimenez 	    if ((pass & options[n].pass) != 0
660*a8e38dc0SAntonio Huete Jimenez 		&& !strcmp(name, options[n].name)) {
661*a8e38dc0SAntonio Huete Jimenez 		result = &options[n];
662*a8e38dc0SAntonio Huete Jimenez 		break;
663*a8e38dc0SAntonio Huete Jimenez 	    }
664*a8e38dc0SAntonio Huete Jimenez 	}
665*a8e38dc0SAntonio Huete Jimenez 	if (result == NULL && !recur) {
666*a8e38dc0SAntonio Huete Jimenez 	    char *temp = malloc(8 + strlen(name));
667*a8e38dc0SAntonio Huete Jimenez 	    if (temp != NULL) {
668*a8e38dc0SAntonio Huete Jimenez 		if (!strncmp(name, "no", 2)) {
669*a8e38dc0SAntonio Huete Jimenez 		    int skip = !strncmp(name, "no-", 3) ? 3 : 2;
670*a8e38dc0SAntonio Huete Jimenez 		    sprintf(temp, "--no-%s", name + skip);
671*a8e38dc0SAntonio Huete Jimenez 		    result = findOption(temp, pass, TRUE);
672*a8e38dc0SAntonio Huete Jimenez 		    if (result == NULL) {
673*a8e38dc0SAntonio Huete Jimenez 			sprintf(temp, "--%s", name + skip);
674*a8e38dc0SAntonio Huete Jimenez 			result = findOption(temp, pass, TRUE);
675*a8e38dc0SAntonio Huete Jimenez 		    }
676*a8e38dc0SAntonio Huete Jimenez 		}
677*a8e38dc0SAntonio Huete Jimenez 		if (result == NULL && strncmp(name, "no", 2)) {
678*a8e38dc0SAntonio Huete Jimenez 		    sprintf(temp, "--no-%s", name);
679*a8e38dc0SAntonio Huete Jimenez 		    result = findOption(temp, pass, TRUE);
680*a8e38dc0SAntonio Huete Jimenez 		}
681*a8e38dc0SAntonio Huete Jimenez 		free(temp);
682*a8e38dc0SAntonio Huete Jimenez 	    }
683*a8e38dc0SAntonio Huete Jimenez 	}
684*a8e38dc0SAntonio Huete Jimenez     }
685*a8e38dc0SAntonio Huete Jimenez     return result;
686*a8e38dc0SAntonio Huete Jimenez }
687*a8e38dc0SAntonio Huete Jimenez 
6885382d832SPeter Avalos static eOptions
lookupOption(const char * name,int pass)6895382d832SPeter Avalos lookupOption(const char *name, int pass)
6905382d832SPeter Avalos {
6915382d832SPeter Avalos     eOptions result = o_unknown;
692*a8e38dc0SAntonio Huete Jimenez     const Options *data = findOption(name, pass, FALSE);
693*a8e38dc0SAntonio Huete Jimenez     if (data != NULL) {
694*a8e38dc0SAntonio Huete Jimenez 	result = data->code;
6955382d832SPeter Avalos     }
6965382d832SPeter Avalos     return result;
6975382d832SPeter Avalos }
6985382d832SPeter Avalos 
6995382d832SPeter Avalos static void
Usage(const char * msg)7005382d832SPeter Avalos Usage(const char *msg)
7015382d832SPeter Avalos {
7025940c9abSDaniel Fojt     handle_leaks();
703*a8e38dc0SAntonio Huete Jimenez     dlg_exiterr(_("%s.\nUse --help to list options.\n\n"), msg);
7045382d832SPeter Avalos }
7055382d832SPeter Avalos 
7065382d832SPeter Avalos /*
7075382d832SPeter Avalos  * Count arguments, stopping at the end of the argument list, or on any of our
7085382d832SPeter Avalos  * "--" tokens.
7095382d832SPeter Avalos  */
7105382d832SPeter Avalos static int
arg_rest(char * argv[])7115382d832SPeter Avalos arg_rest(char *argv[])
7125382d832SPeter Avalos {
7135382d832SPeter Avalos     int i = 1;			/* argv[0] points to a "--" token */
7145382d832SPeter Avalos 
7155382d832SPeter Avalos     while (argv[i] != 0
7165382d832SPeter Avalos 	   && (!isOption(argv[i]) || lookupOption(argv[i], 7) == o_unknown))
7175382d832SPeter Avalos 	i++;
7185382d832SPeter Avalos     return i;
7195382d832SPeter Avalos }
7205382d832SPeter Avalos 
7215382d832SPeter Avalos /*
7225382d832SPeter Avalos  * In MultiWidget this function is needed to count how many tags
7235382d832SPeter Avalos  * a widget (menu, checklist, radiolist) has
7245382d832SPeter Avalos  */
7255382d832SPeter Avalos static int
howmany_tags(char * argv[],int group)7265382d832SPeter Avalos howmany_tags(char *argv[], int group)
7275382d832SPeter Avalos {
7285382d832SPeter Avalos     int result = 0;
7295382d832SPeter Avalos     char temp[80];
7305382d832SPeter Avalos 
7315382d832SPeter Avalos     while (argv[0] != 0) {
7325940c9abSDaniel Fojt 	int have;
7335940c9abSDaniel Fojt 
7345382d832SPeter Avalos 	if (isOption(argv[0]))
7355382d832SPeter Avalos 	    break;
7365382d832SPeter Avalos 	if ((have = arg_rest(argv)) < group) {
7375940c9abSDaniel Fojt 	    const char *format = _("Expected %d arguments, found only %d");
7385382d832SPeter Avalos 	    sprintf(temp, format, group, have);
7395382d832SPeter Avalos 	    Usage(temp);
7405940c9abSDaniel Fojt 	} else if ((have % group) != 0) {
7415940c9abSDaniel Fojt 	    const char *format = _("Expected %d arguments, found extra %d");
7425940c9abSDaniel Fojt 	    sprintf(temp, format, group, (have % group));
7435940c9abSDaniel Fojt 	    Usage(temp);
7445382d832SPeter Avalos 	}
7455382d832SPeter Avalos 
7465940c9abSDaniel Fojt 	argv += have;
7475940c9abSDaniel Fojt 	result += (have / group);
7485382d832SPeter Avalos     }
7495382d832SPeter Avalos 
7505382d832SPeter Avalos     return result;
7515382d832SPeter Avalos }
7525382d832SPeter Avalos 
7535382d832SPeter Avalos static int
numeric_arg(char ** av,int n)7545382d832SPeter Avalos numeric_arg(char **av, int n)
7555382d832SPeter Avalos {
7565382d832SPeter Avalos     int result = 0;
7575382d832SPeter Avalos 
7585382d832SPeter Avalos     if (n < dlg_count_argv(av)) {
7595382d832SPeter Avalos 	char *last = 0;
7605382d832SPeter Avalos 	result = (int) strtol(av[n], &last, 10);
7615382d832SPeter Avalos 
7625382d832SPeter Avalos 	if (last == 0 || *last != 0) {
7635940c9abSDaniel Fojt 	    char msg[80];
7645940c9abSDaniel Fojt 
765*a8e38dc0SAntonio Huete Jimenez 	    sprintf(msg, _("Expected a number for token %d of %.*s"), n,
766*a8e38dc0SAntonio Huete Jimenez 		    USEMAX_ARGS, av[0]);
7675382d832SPeter Avalos 	    Usage(msg);
7685382d832SPeter Avalos 	}
7695382d832SPeter Avalos     }
7705382d832SPeter Avalos     return result;
7715382d832SPeter Avalos }
7725382d832SPeter Avalos 
7735382d832SPeter Avalos static char *
optional_str(char ** av,int n,char * dft)7745382d832SPeter Avalos optional_str(char **av, int n, char *dft)
7755382d832SPeter Avalos {
7765382d832SPeter Avalos     char *ret = dft;
7775382d832SPeter Avalos     if (arg_rest(av) > n)
7785382d832SPeter Avalos 	ret = av[n];
7795382d832SPeter Avalos     return ret;
7805382d832SPeter Avalos }
7815382d832SPeter Avalos 
7825382d832SPeter Avalos #if defined(HAVE_DLG_GAUGE) || defined(HAVE_XDIALOG)
7835382d832SPeter Avalos static int
optional_num(char ** av,int n,int dft)7845382d832SPeter Avalos optional_num(char **av, int n, int dft)
7855382d832SPeter Avalos {
7865382d832SPeter Avalos     int ret = dft;
7875382d832SPeter Avalos     if (arg_rest(av) > n)
7885382d832SPeter Avalos 	ret = numeric_arg(av, n);
7895382d832SPeter Avalos     return ret;
7905382d832SPeter Avalos }
7915382d832SPeter Avalos #endif
7925382d832SPeter Avalos 
7935382d832SPeter Avalos /*
7945382d832SPeter Avalos  * On AIX 4.x, we have to flush the output right away since there is a bug in
7955382d832SPeter Avalos  * the curses package which discards stdout even when we've used newterm to
7965382d832SPeter Avalos  * redirect output to /dev/tty.
7975382d832SPeter Avalos  */
7985382d832SPeter Avalos static int
show_result(int ret)7995382d832SPeter Avalos show_result(int ret)
8005382d832SPeter Avalos {
8015382d832SPeter Avalos     bool either = FALSE;
8025382d832SPeter Avalos 
8035382d832SPeter Avalos     switch (ret) {
8045382d832SPeter Avalos     case DLG_EXIT_OK:
8055382d832SPeter Avalos     case DLG_EXIT_EXTRA:
8065382d832SPeter Avalos     case DLG_EXIT_HELP:
8075382d832SPeter Avalos     case DLG_EXIT_ITEM_HELP:
8085382d832SPeter Avalos 	if ((dialog_state.output_count > 1) && !dialog_vars.separate_output) {
8095382d832SPeter Avalos 	    fputs((dialog_state.separate_str
8105382d832SPeter Avalos 		   ? dialog_state.separate_str
8115382d832SPeter Avalos 		   : DEFAULT_SEPARATE_STR),
8125382d832SPeter Avalos 		  dialog_state.output);
8135382d832SPeter Avalos 	    either = TRUE;
8145382d832SPeter Avalos 	}
8155382d832SPeter Avalos 	if (dialog_vars.input_result != 0
8165382d832SPeter Avalos 	    && dialog_vars.input_result[0] != '\0') {
8175382d832SPeter Avalos 	    fputs(dialog_vars.input_result, dialog_state.output);
8185940c9abSDaniel Fojt 	    DLG_TRACE(("# input_result:\n%s\n", dialog_vars.input_result));
8195382d832SPeter Avalos 	    either = TRUE;
8205382d832SPeter Avalos 	}
8215382d832SPeter Avalos 	if (either) {
8225382d832SPeter Avalos 	    fflush(dialog_state.output);
8235382d832SPeter Avalos 	}
8245382d832SPeter Avalos 	break;
8255382d832SPeter Avalos     }
8265382d832SPeter Avalos     return ret;
8275382d832SPeter Avalos }
8285382d832SPeter Avalos 
8295382d832SPeter Avalos /*
8305382d832SPeter Avalos  * These are the widget callers.
8315382d832SPeter Avalos  */
8325382d832SPeter Avalos 
8335382d832SPeter Avalos static int
call_yesno(CALLARGS)8345382d832SPeter Avalos call_yesno(CALLARGS)
8355382d832SPeter Avalos {
8365382d832SPeter Avalos     *offset_add = 4;
8375382d832SPeter Avalos     return dialog_yesno(t,
8385382d832SPeter Avalos 			av[1],
8395382d832SPeter Avalos 			numeric_arg(av, 2),
8405382d832SPeter Avalos 			numeric_arg(av, 3));
8415382d832SPeter Avalos }
8425382d832SPeter Avalos 
8435382d832SPeter Avalos static int
call_msgbox(CALLARGS)8445382d832SPeter Avalos call_msgbox(CALLARGS)
8455382d832SPeter Avalos {
8465382d832SPeter Avalos     *offset_add = 4;
8475382d832SPeter Avalos     return dialog_msgbox(t,
8485382d832SPeter Avalos 			 av[1],
8495382d832SPeter Avalos 			 numeric_arg(av, 2),
8505382d832SPeter Avalos 			 numeric_arg(av, 3), 1);
8515382d832SPeter Avalos }
8525382d832SPeter Avalos 
8535382d832SPeter Avalos static int
call_infobox(CALLARGS)8545382d832SPeter Avalos call_infobox(CALLARGS)
8555382d832SPeter Avalos {
8565382d832SPeter Avalos     *offset_add = 4;
8575382d832SPeter Avalos     return dialog_msgbox(t,
8585382d832SPeter Avalos 			 av[1],
8595382d832SPeter Avalos 			 numeric_arg(av, 2),
8605382d832SPeter Avalos 			 numeric_arg(av, 3), 0);
8615382d832SPeter Avalos }
8625382d832SPeter Avalos 
8635382d832SPeter Avalos static int
call_textbox(CALLARGS)8645382d832SPeter Avalos call_textbox(CALLARGS)
8655382d832SPeter Avalos {
8665382d832SPeter Avalos     *offset_add = 4;
8675382d832SPeter Avalos     return dialog_textbox(t,
8685382d832SPeter Avalos 			  av[1],
8695382d832SPeter Avalos 			  numeric_arg(av, 2),
8705382d832SPeter Avalos 			  numeric_arg(av, 3));
8715382d832SPeter Avalos }
8725382d832SPeter Avalos 
8735382d832SPeter Avalos static int
call_menu(CALLARGS)8745382d832SPeter Avalos call_menu(CALLARGS)
8755382d832SPeter Avalos {
8765382d832SPeter Avalos     int tags = howmany_tags(av + 5, MENUBOX_TAGS);
8775382d832SPeter Avalos     *offset_add = 5 + tags * MENUBOX_TAGS;
8785382d832SPeter Avalos 
8795382d832SPeter Avalos     return dialog_menu(t,
8805382d832SPeter Avalos 		       av[1],
8815382d832SPeter Avalos 		       numeric_arg(av, 2),
8825382d832SPeter Avalos 		       numeric_arg(av, 3),
8835382d832SPeter Avalos 		       numeric_arg(av, 4),
8845382d832SPeter Avalos 		       tags, av + 5);
8855382d832SPeter Avalos }
8865382d832SPeter Avalos 
8875382d832SPeter Avalos static int
call_inputmenu(CALLARGS)8885382d832SPeter Avalos call_inputmenu(CALLARGS)
8895382d832SPeter Avalos {
8905382d832SPeter Avalos     int tags = howmany_tags(av + 5, MENUBOX_TAGS);
8915382d832SPeter Avalos     bool free_extra_label = FALSE;
8925382d832SPeter Avalos     int result;
8935382d832SPeter Avalos 
8945382d832SPeter Avalos     dialog_vars.input_menu = TRUE;
8955382d832SPeter Avalos 
8965382d832SPeter Avalos     if (dialog_vars.extra_label == 0) {
8975382d832SPeter Avalos 	free_extra_label = TRUE;
8985382d832SPeter Avalos 	dialog_vars.extra_label = dlg_strclone(_("Rename"));
8995382d832SPeter Avalos     }
9005382d832SPeter Avalos 
9015382d832SPeter Avalos     dialog_vars.extra_button = TRUE;
9025382d832SPeter Avalos 
9035382d832SPeter Avalos     *offset_add = 5 + tags * MENUBOX_TAGS;
9045382d832SPeter Avalos     result = dialog_menu(t,
9055382d832SPeter Avalos 			 av[1],
9065382d832SPeter Avalos 			 numeric_arg(av, 2),
9075382d832SPeter Avalos 			 numeric_arg(av, 3),
9085382d832SPeter Avalos 			 numeric_arg(av, 4),
9095382d832SPeter Avalos 			 tags, av + 5);
9105382d832SPeter Avalos     if (free_extra_label) {
9115382d832SPeter Avalos 	free(dialog_vars.extra_label);
9125382d832SPeter Avalos 	dialog_vars.extra_label = 0;
9135382d832SPeter Avalos     }
9145382d832SPeter Avalos     return result;
9155382d832SPeter Avalos }
9165382d832SPeter Avalos 
9175382d832SPeter Avalos static int
call_checklist(CALLARGS)9185382d832SPeter Avalos call_checklist(CALLARGS)
9195382d832SPeter Avalos {
9205382d832SPeter Avalos     int tags = howmany_tags(av + 5, CHECKBOX_TAGS);
9215382d832SPeter Avalos     int code;
9225382d832SPeter Avalos 
9235382d832SPeter Avalos     *offset_add = 5 + tags * CHECKBOX_TAGS;
9245382d832SPeter Avalos     code = dialog_checklist(t,
9255382d832SPeter Avalos 			    av[1],
9265382d832SPeter Avalos 			    numeric_arg(av, 2),
9275382d832SPeter Avalos 			    numeric_arg(av, 3),
9285382d832SPeter Avalos 			    numeric_arg(av, 4),
9295382d832SPeter Avalos 			    tags, av + 5, FLAG_CHECK);
9305382d832SPeter Avalos     return code;
9315382d832SPeter Avalos }
9325382d832SPeter Avalos 
9335382d832SPeter Avalos static int
call_radiolist(CALLARGS)9345382d832SPeter Avalos call_radiolist(CALLARGS)
9355382d832SPeter Avalos {
9365382d832SPeter Avalos     int tags = howmany_tags(av + 5, CHECKBOX_TAGS);
9375382d832SPeter Avalos     *offset_add = 5 + tags * CHECKBOX_TAGS;
9385382d832SPeter Avalos     return dialog_checklist(t,
9395382d832SPeter Avalos 			    av[1],
9405382d832SPeter Avalos 			    numeric_arg(av, 2),
9415382d832SPeter Avalos 			    numeric_arg(av, 3),
9425382d832SPeter Avalos 			    numeric_arg(av, 4),
9435382d832SPeter Avalos 			    tags, av + 5, FLAG_RADIO);
9445382d832SPeter Avalos }
9455382d832SPeter Avalos 
9465382d832SPeter Avalos static int
call_inputbox(CALLARGS)9475382d832SPeter Avalos call_inputbox(CALLARGS)
9485382d832SPeter Avalos {
9495382d832SPeter Avalos     *offset_add = arg_rest(av);
9505382d832SPeter Avalos     return dialog_inputbox(t,
9515382d832SPeter Avalos 			   av[1],
9525382d832SPeter Avalos 			   numeric_arg(av, 2),
9535382d832SPeter Avalos 			   numeric_arg(av, 3),
9545382d832SPeter Avalos 			   optional_str(av, 4, 0), 0);
9555382d832SPeter Avalos }
9565382d832SPeter Avalos 
9575382d832SPeter Avalos static int
call_passwordbox(CALLARGS)9585382d832SPeter Avalos call_passwordbox(CALLARGS)
9595382d832SPeter Avalos {
9605382d832SPeter Avalos     *offset_add = arg_rest(av);
9615382d832SPeter Avalos     return dialog_inputbox(t,
9625382d832SPeter Avalos 			   av[1],
9635382d832SPeter Avalos 			   numeric_arg(av, 2),
9645382d832SPeter Avalos 			   numeric_arg(av, 3),
9655382d832SPeter Avalos 			   optional_str(av, 4, 0), 1);
9665382d832SPeter Avalos }
9675382d832SPeter Avalos 
9685382d832SPeter Avalos #ifdef HAVE_XDIALOG
9695382d832SPeter Avalos static int
call_calendar(CALLARGS)9705382d832SPeter Avalos call_calendar(CALLARGS)
9715382d832SPeter Avalos {
9725382d832SPeter Avalos     *offset_add = arg_rest(av);
9735382d832SPeter Avalos     return dialog_calendar(t,
9745382d832SPeter Avalos 			   av[1],
9755382d832SPeter Avalos 			   numeric_arg(av, 2),
9765382d832SPeter Avalos 			   numeric_arg(av, 3),
9775382d832SPeter Avalos 			   optional_num(av, 4, -1),
9785382d832SPeter Avalos 			   optional_num(av, 5, -1),
9795382d832SPeter Avalos 			   optional_num(av, 6, -1));
9805382d832SPeter Avalos }
9815382d832SPeter Avalos 
9825382d832SPeter Avalos static int
call_dselect(CALLARGS)9835382d832SPeter Avalos call_dselect(CALLARGS)
9845382d832SPeter Avalos {
9855382d832SPeter Avalos     *offset_add = arg_rest(av);
9865382d832SPeter Avalos     return dialog_dselect(t,
9875382d832SPeter Avalos 			  av[1],
9885382d832SPeter Avalos 			  numeric_arg(av, 2),
9895382d832SPeter Avalos 			  numeric_arg(av, 3));
9905382d832SPeter Avalos }
9915382d832SPeter Avalos 
9925382d832SPeter Avalos static int
call_editbox(CALLARGS)9935382d832SPeter Avalos call_editbox(CALLARGS)
9945382d832SPeter Avalos {
9955382d832SPeter Avalos     *offset_add = 4;
9965382d832SPeter Avalos     return dialog_editbox(t,
9975382d832SPeter Avalos 			  av[1],
9985382d832SPeter Avalos 			  numeric_arg(av, 2),
9995382d832SPeter Avalos 			  numeric_arg(av, 3));
10005382d832SPeter Avalos }
10015382d832SPeter Avalos 
10025382d832SPeter Avalos static int
call_fselect(CALLARGS)10035382d832SPeter Avalos call_fselect(CALLARGS)
10045382d832SPeter Avalos {
10055382d832SPeter Avalos     *offset_add = arg_rest(av);
10065382d832SPeter Avalos     return dialog_fselect(t,
10075382d832SPeter Avalos 			  av[1],
10085382d832SPeter Avalos 			  numeric_arg(av, 2),
10095382d832SPeter Avalos 			  numeric_arg(av, 3));
10105382d832SPeter Avalos }
10115382d832SPeter Avalos 
10125382d832SPeter Avalos static int
call_timebox(CALLARGS)10135382d832SPeter Avalos call_timebox(CALLARGS)
10145382d832SPeter Avalos {
10155382d832SPeter Avalos     *offset_add = arg_rest(av);
10165382d832SPeter Avalos     return dialog_timebox(t,
10175382d832SPeter Avalos 			  av[1],
10185382d832SPeter Avalos 			  numeric_arg(av, 2),
10195382d832SPeter Avalos 			  numeric_arg(av, 3),
10205382d832SPeter Avalos 			  optional_num(av, 4, -1),
10215382d832SPeter Avalos 			  optional_num(av, 5, -1),
10225382d832SPeter Avalos 			  optional_num(av, 6, -1));
10235382d832SPeter Avalos }
10245382d832SPeter Avalos #endif /* HAVE_XDIALOG */
10255382d832SPeter Avalos 
10265382d832SPeter Avalos /* dialog 1.2 widgets */
10275382d832SPeter Avalos #ifdef HAVE_XDIALOG2
10285382d832SPeter Avalos 
10295382d832SPeter Avalos #define DisableNoTags() \
10305382d832SPeter Avalos 	bool save_no_tags = dialog_vars.no_tags; \
10315382d832SPeter Avalos 	bool save_no_items = dialog_vars.no_items; \
10325382d832SPeter Avalos 	dialog_vars.no_tags = TRUE; \
10335382d832SPeter Avalos 	dialog_vars.no_items = FALSE
10345382d832SPeter Avalos 
10355382d832SPeter Avalos #define RestoreNoTags() \
10365382d832SPeter Avalos 	dialog_vars.no_tags = save_no_tags; \
10375382d832SPeter Avalos 	dialog_vars.no_items = save_no_items
10385382d832SPeter Avalos 
10395382d832SPeter Avalos static int
call_buildlist(CALLARGS)10405382d832SPeter Avalos call_buildlist(CALLARGS)
10415382d832SPeter Avalos {
10425382d832SPeter Avalos     int tags = howmany_tags(av + 5, CHECKBOX_TAGS);
10435382d832SPeter Avalos     int result;
10445382d832SPeter Avalos 
10455382d832SPeter Avalos     DisableNoTags();
10465382d832SPeter Avalos 
10475382d832SPeter Avalos     *offset_add = 5 + tags * CHECKBOX_TAGS;
10485382d832SPeter Avalos     result = dialog_buildlist(t,
10495382d832SPeter Avalos 			      av[1],
10505382d832SPeter Avalos 			      numeric_arg(av, 2),
10515382d832SPeter Avalos 			      numeric_arg(av, 3),
10525382d832SPeter Avalos 			      numeric_arg(av, 4),
10535382d832SPeter Avalos 			      tags, av + 5,
10545940c9abSDaniel Fojt 			      dialog_vars.reorder);
10555382d832SPeter Avalos     RestoreNoTags();
10565382d832SPeter Avalos     return result;
10575382d832SPeter Avalos }
10585382d832SPeter Avalos 
10595382d832SPeter Avalos static int
call_rangebox(CALLARGS)10605382d832SPeter Avalos call_rangebox(CALLARGS)
10615382d832SPeter Avalos {
10625382d832SPeter Avalos     int min_value;
10635382d832SPeter Avalos 
10645382d832SPeter Avalos     *offset_add = arg_rest(av);
10655382d832SPeter Avalos     min_value = numeric_arg(av, 4);
10665382d832SPeter Avalos     return dialog_rangebox(t,
10675382d832SPeter Avalos 			   av[1],
10685382d832SPeter Avalos 			   numeric_arg(av, 2),
10695382d832SPeter Avalos 			   numeric_arg(av, 3),
10705382d832SPeter Avalos 			   min_value,
10715382d832SPeter Avalos 			   numeric_arg(av, 5),
10725382d832SPeter Avalos 			   (*offset_add > 6) ? numeric_arg(av, 6) : min_value);
10735382d832SPeter Avalos }
10745382d832SPeter Avalos 
10755382d832SPeter Avalos static int
call_treeview(CALLARGS)10765382d832SPeter Avalos call_treeview(CALLARGS)
10775382d832SPeter Avalos {
10785382d832SPeter Avalos     int tags = howmany_tags(av + 5, TREEVIEW_TAGS);
10795382d832SPeter Avalos     int result;
10805382d832SPeter Avalos 
10815382d832SPeter Avalos     DisableNoTags();
10825382d832SPeter Avalos 
10835382d832SPeter Avalos     *offset_add = arg_rest(av);
10845382d832SPeter Avalos     result = dialog_treeview(t,
10855382d832SPeter Avalos 			     av[1],
10865382d832SPeter Avalos 			     numeric_arg(av, 2),
10875382d832SPeter Avalos 			     numeric_arg(av, 3),
10885382d832SPeter Avalos 			     numeric_arg(av, 4),
10895382d832SPeter Avalos 			     tags, av + 5, FLAG_RADIO);
10905382d832SPeter Avalos     RestoreNoTags();
10915382d832SPeter Avalos     return result;
10925382d832SPeter Avalos }
10935382d832SPeter Avalos #endif /* HAVE_XDIALOG */
10945382d832SPeter Avalos 
10955382d832SPeter Avalos #ifdef HAVE_DLG_FORMBOX
10965382d832SPeter Avalos static int
call_form(CALLARGS)10975382d832SPeter Avalos call_form(CALLARGS)
10985382d832SPeter Avalos {
10995382d832SPeter Avalos     int group = FORMBOX_TAGS;
11005382d832SPeter Avalos     int tags = howmany_tags(av + 5, group);
11015382d832SPeter Avalos     *offset_add = 5 + tags * group;
11025382d832SPeter Avalos 
11035382d832SPeter Avalos     return dialog_form(t,
11045382d832SPeter Avalos 		       av[1],
11055382d832SPeter Avalos 		       numeric_arg(av, 2),
11065382d832SPeter Avalos 		       numeric_arg(av, 3),
11075382d832SPeter Avalos 		       numeric_arg(av, 4),
11085382d832SPeter Avalos 		       tags, av + 5);
11095382d832SPeter Avalos }
11105382d832SPeter Avalos 
11115382d832SPeter Avalos static int
call_password_form(CALLARGS)11125382d832SPeter Avalos call_password_form(CALLARGS)
11135382d832SPeter Avalos {
11145382d832SPeter Avalos     unsigned save = dialog_vars.formitem_type;
11155382d832SPeter Avalos     int result;
11165382d832SPeter Avalos 
11175382d832SPeter Avalos     dialog_vars.formitem_type = 1;
11185382d832SPeter Avalos     result = call_form(PASSARGS);
11195382d832SPeter Avalos     dialog_vars.formitem_type = save;
11205382d832SPeter Avalos 
11215382d832SPeter Avalos     return result;
11225382d832SPeter Avalos }
11235382d832SPeter Avalos #endif /* HAVE_DLG_FORMBOX */
11245382d832SPeter Avalos 
11255382d832SPeter Avalos #ifdef HAVE_DLG_MIXEDFORM
11265382d832SPeter Avalos static int
call_mixed_form(CALLARGS)11275382d832SPeter Avalos call_mixed_form(CALLARGS)
11285382d832SPeter Avalos {
11295382d832SPeter Avalos     int group = MIXEDFORM_TAGS;
11305382d832SPeter Avalos     int tags = howmany_tags(av + 5, group);
11315382d832SPeter Avalos     *offset_add = 5 + tags * group;
11325382d832SPeter Avalos 
11335382d832SPeter Avalos     return dialog_mixedform(t,
11345382d832SPeter Avalos 			    av[1],
11355382d832SPeter Avalos 			    numeric_arg(av, 2),
11365382d832SPeter Avalos 			    numeric_arg(av, 3),
11375382d832SPeter Avalos 			    numeric_arg(av, 4),
11385382d832SPeter Avalos 			    tags, av + 5);
11395382d832SPeter Avalos }
11405382d832SPeter Avalos #endif /* HAVE_DLG_MIXEDFORM */
11415382d832SPeter Avalos 
11425382d832SPeter Avalos #ifdef HAVE_DLG_GAUGE
11435382d832SPeter Avalos static int
call_gauge(CALLARGS)11445382d832SPeter Avalos call_gauge(CALLARGS)
11455382d832SPeter Avalos {
11465382d832SPeter Avalos     *offset_add = arg_rest(av);
11475382d832SPeter Avalos     return dialog_gauge(t,
11485382d832SPeter Avalos 			av[1],
11495382d832SPeter Avalos 			numeric_arg(av, 2),
11505382d832SPeter Avalos 			numeric_arg(av, 3),
11515382d832SPeter Avalos 			optional_num(av, 4, 0));
11525382d832SPeter Avalos }
11535382d832SPeter Avalos 
11545382d832SPeter Avalos static int
call_pause(CALLARGS)11555382d832SPeter Avalos call_pause(CALLARGS)
11565382d832SPeter Avalos {
11575382d832SPeter Avalos     *offset_add = arg_rest(av);
11585382d832SPeter Avalos     return dialog_pause(t,
11595382d832SPeter Avalos 			av[1],
11605382d832SPeter Avalos 			numeric_arg(av, 2),
11615382d832SPeter Avalos 			numeric_arg(av, 3),
11625382d832SPeter Avalos 			numeric_arg(av, 4));
11635382d832SPeter Avalos }
11645382d832SPeter Avalos #endif
11655382d832SPeter Avalos 
11665382d832SPeter Avalos #ifdef HAVE_MIXEDGAUGE
11675382d832SPeter Avalos static int
call_mixed_gauge(CALLARGS)11685382d832SPeter Avalos call_mixed_gauge(CALLARGS)
11695382d832SPeter Avalos {
11705382d832SPeter Avalos #define MIXEDGAUGE_BASE 5
11715382d832SPeter Avalos     int tags = howmany_tags(av + MIXEDGAUGE_BASE, MIXEDGAUGE_TAGS);
11725382d832SPeter Avalos     *offset_add = MIXEDGAUGE_BASE + tags * MIXEDGAUGE_TAGS;
11735382d832SPeter Avalos     return dialog_mixedgauge(t,
11745382d832SPeter Avalos 			     av[1],
11755382d832SPeter Avalos 			     numeric_arg(av, 2),
11765382d832SPeter Avalos 			     numeric_arg(av, 3),
11775382d832SPeter Avalos 			     numeric_arg(av, 4),
11785382d832SPeter Avalos 			     tags, av + MIXEDGAUGE_BASE);
11795382d832SPeter Avalos }
11805382d832SPeter Avalos #endif
11815382d832SPeter Avalos 
11825382d832SPeter Avalos #ifdef HAVE_DLG_GAUGE
11835382d832SPeter Avalos static int
call_prgbox(CALLARGS)11845382d832SPeter Avalos call_prgbox(CALLARGS)
11855382d832SPeter Avalos {
11865382d832SPeter Avalos     *offset_add = arg_rest(av);
11875382d832SPeter Avalos     /* the original version does not accept a prompt string, but for
11885382d832SPeter Avalos      * consistency we allow it.
11895382d832SPeter Avalos      */
11905382d832SPeter Avalos     return ((*offset_add == 5)
11915382d832SPeter Avalos 	    ? dialog_prgbox(t,
11925382d832SPeter Avalos 			    av[1],
11935382d832SPeter Avalos 			    av[2],
11945382d832SPeter Avalos 			    numeric_arg(av, 3),
11955382d832SPeter Avalos 			    numeric_arg(av, 4), TRUE)
11965382d832SPeter Avalos 	    : dialog_prgbox(t,
11975382d832SPeter Avalos 			    "",
11985382d832SPeter Avalos 			    av[1],
11995382d832SPeter Avalos 			    numeric_arg(av, 2),
12005382d832SPeter Avalos 			    numeric_arg(av, 3), TRUE));
12015382d832SPeter Avalos }
12025382d832SPeter Avalos #endif
12035382d832SPeter Avalos 
12045382d832SPeter Avalos #ifdef HAVE_DLG_GAUGE
12055382d832SPeter Avalos static int
call_programbox(CALLARGS)12065382d832SPeter Avalos call_programbox(CALLARGS)
12075382d832SPeter Avalos {
12085382d832SPeter Avalos     int result;
12095382d832SPeter Avalos 
12105382d832SPeter Avalos     *offset_add = arg_rest(av);
12115382d832SPeter Avalos     /* this function is a compromise between --prgbox and --progressbox.
12125382d832SPeter Avalos      */
12135382d832SPeter Avalos     result = ((*offset_add == 4)
12145382d832SPeter Avalos 	      ? dlg_progressbox(t,
12155382d832SPeter Avalos 				av[1],
12165382d832SPeter Avalos 				numeric_arg(av, 2),
12175382d832SPeter Avalos 				numeric_arg(av, 3),
12185382d832SPeter Avalos 				TRUE,
12195382d832SPeter Avalos 				dialog_state.pipe_input)
12205382d832SPeter Avalos 	      : dlg_progressbox(t,
12215382d832SPeter Avalos 				"",
12225382d832SPeter Avalos 				numeric_arg(av, 1),
12235382d832SPeter Avalos 				numeric_arg(av, 2),
12245382d832SPeter Avalos 				TRUE,
12255382d832SPeter Avalos 				dialog_state.pipe_input));
12265382d832SPeter Avalos     dialog_state.pipe_input = 0;
12275382d832SPeter Avalos     return result;
12285382d832SPeter Avalos }
12295382d832SPeter Avalos #endif
12305382d832SPeter Avalos 
12315382d832SPeter Avalos #ifdef HAVE_DLG_GAUGE
12325382d832SPeter Avalos static int
call_progressbox(CALLARGS)12335382d832SPeter Avalos call_progressbox(CALLARGS)
12345382d832SPeter Avalos {
12355382d832SPeter Avalos     *offset_add = arg_rest(av);
12365382d832SPeter Avalos     /* the original version does not accept a prompt string, but for
12375382d832SPeter Avalos      * consistency we allow it.
12385382d832SPeter Avalos      */
12395382d832SPeter Avalos     return ((*offset_add == 4)
12405382d832SPeter Avalos 	    ? dialog_progressbox(t,
12415382d832SPeter Avalos 				 av[1],
12425382d832SPeter Avalos 				 numeric_arg(av, 2),
12435382d832SPeter Avalos 				 numeric_arg(av, 3))
12445382d832SPeter Avalos 	    : dialog_progressbox(t,
12455382d832SPeter Avalos 				 "",
12465382d832SPeter Avalos 				 numeric_arg(av, 1),
12475382d832SPeter Avalos 				 numeric_arg(av, 2)));
12485382d832SPeter Avalos }
12495382d832SPeter Avalos #endif
12505382d832SPeter Avalos 
12515382d832SPeter Avalos #ifdef HAVE_DLG_TAILBOX
12525382d832SPeter Avalos static int
call_tailbox(CALLARGS)12535382d832SPeter Avalos call_tailbox(CALLARGS)
12545382d832SPeter Avalos {
12555382d832SPeter Avalos     *offset_add = 4;
12565382d832SPeter Avalos     return dialog_tailbox(t,
12575382d832SPeter Avalos 			  av[1],
12585382d832SPeter Avalos 			  numeric_arg(av, 2),
12595382d832SPeter Avalos 			  numeric_arg(av, 3),
12605382d832SPeter Avalos 			  FALSE);
12615382d832SPeter Avalos }
12625382d832SPeter Avalos 
12635382d832SPeter Avalos static int
call_tailboxbg(CALLARGS)12645382d832SPeter Avalos call_tailboxbg(CALLARGS)
12655382d832SPeter Avalos {
12665382d832SPeter Avalos     *offset_add = 4;
12675382d832SPeter Avalos     return dialog_tailbox(t,
12685382d832SPeter Avalos 			  av[1],
12695382d832SPeter Avalos 			  numeric_arg(av, 2),
12705382d832SPeter Avalos 			  numeric_arg(av, 3),
12715382d832SPeter Avalos 			  TRUE);
12725382d832SPeter Avalos }
12735382d832SPeter Avalos #endif
12745382d832SPeter Avalos /* *INDENT-OFF* */
12755382d832SPeter Avalos static const Mode modes[] =
12765382d832SPeter Avalos {
12775382d832SPeter Avalos     {o_yesno,           4, 4, call_yesno},
12785382d832SPeter Avalos     {o_msgbox,          4, 4, call_msgbox},
12795382d832SPeter Avalos     {o_infobox,         4, 4, call_infobox},
12805382d832SPeter Avalos     {o_textbox,         4, 4, call_textbox},
12811ef6786aSJohn Marino     {o_menu,            6, 0, call_menu},
12821ef6786aSJohn Marino     {o_inputmenu,       6, 0, call_inputmenu},
12831ef6786aSJohn Marino     {o_checklist,       7, 0, call_checklist},
12841ef6786aSJohn Marino     {o_radiolist,       7, 0, call_radiolist},
12855382d832SPeter Avalos     {o_inputbox,        4, 5, call_inputbox},
12865382d832SPeter Avalos     {o_passwordbox,     4, 5, call_passwordbox},
12875382d832SPeter Avalos #ifdef HAVE_DLG_GAUGE
12885382d832SPeter Avalos     {o_gauge,           4, 5, call_gauge},
12895382d832SPeter Avalos     {o_pause,           5, 5, call_pause},
12905382d832SPeter Avalos     {o_prgbox,          4, 5, call_prgbox},
12915382d832SPeter Avalos     {o_programbox,      3, 4, call_programbox},
12925382d832SPeter Avalos     {o_progressbox,     3, 4, call_progressbox},
12935382d832SPeter Avalos #endif
12945382d832SPeter Avalos #ifdef HAVE_DLG_FORMBOX
12955382d832SPeter Avalos     {o_passwordform,   13, 0, call_password_form},
12965382d832SPeter Avalos     {o_form,           13, 0, call_form},
12975382d832SPeter Avalos #endif
12985382d832SPeter Avalos #ifdef HAVE_MIXEDGAUGE
12995382d832SPeter Avalos     {o_mixedgauge,      MIXEDGAUGE_BASE, 0, call_mixed_gauge},
13005382d832SPeter Avalos #endif
13015382d832SPeter Avalos #ifdef HAVE_DLG_MIXEDFORM
13025382d832SPeter Avalos     {o_mixedform,      13, 0, call_mixed_form},
13035382d832SPeter Avalos #endif
13045382d832SPeter Avalos #ifdef HAVE_DLG_TAILBOX
13055382d832SPeter Avalos     {o_tailbox,         4, 4, call_tailbox},
13065382d832SPeter Avalos     {o_tailboxbg,       4, 4, call_tailboxbg},
13075382d832SPeter Avalos #endif
13085382d832SPeter Avalos #ifdef HAVE_XDIALOG
13095382d832SPeter Avalos     {o_calendar,        4, 7, call_calendar},
13105382d832SPeter Avalos     {o_dselect,         4, 5, call_dselect},
13115382d832SPeter Avalos     {o_editbox,         4, 4, call_editbox},
13125382d832SPeter Avalos     {o_fselect,         4, 5, call_fselect},
13135382d832SPeter Avalos     {o_timebox,         4, 7, call_timebox},
13145940c9abSDaniel Fojt #endif
13155940c9abSDaniel Fojt #ifdef HAVE_XDIALOG2
13165940c9abSDaniel Fojt     {o_buildlist,       4, 0, call_buildlist},
13175940c9abSDaniel Fojt     {o_rangebox,        5, 7, call_rangebox},
13185382d832SPeter Avalos     {o_treeview,        4, 0, call_treeview},
13195382d832SPeter Avalos #endif
13205382d832SPeter Avalos };
13215382d832SPeter Avalos /* *INDENT-ON* */
13225382d832SPeter Avalos 
13235382d832SPeter Avalos static char *
optionString(char ** argv,int * num)13245382d832SPeter Avalos optionString(char **argv, int *num)
13255382d832SPeter Avalos {
13265382d832SPeter Avalos     int next = *num + 1;
13275382d832SPeter Avalos     char *result = argv[next];
13285382d832SPeter Avalos     if (result == 0) {
13295382d832SPeter Avalos 	char temp[80];
1330*a8e38dc0SAntonio Huete Jimenez 	sprintf(temp, ("Expected a string-parameter for %.*s"), USEMAX_ARGS,
1331*a8e38dc0SAntonio Huete Jimenez 		argv[*num]);
13325382d832SPeter Avalos 	Usage(temp);
13335382d832SPeter Avalos     }
13345382d832SPeter Avalos     *num = next;
13355382d832SPeter Avalos     return result;
13365382d832SPeter Avalos }
13375382d832SPeter Avalos 
13385382d832SPeter Avalos static int
optionValue(char ** argv,int * num)13395382d832SPeter Avalos optionValue(char **argv, int *num)
13405382d832SPeter Avalos {
13415382d832SPeter Avalos     int next = *num + 1;
13425382d832SPeter Avalos     char *src = argv[next];
13435382d832SPeter Avalos     char *tmp = 0;
13445382d832SPeter Avalos     int result = 0;
13455382d832SPeter Avalos 
13465382d832SPeter Avalos     if (src != 0) {
13475382d832SPeter Avalos 	result = (int) strtol(src, &tmp, 0);
13485382d832SPeter Avalos 	if (tmp == 0 || *tmp != 0)
13495382d832SPeter Avalos 	    src = 0;
13505382d832SPeter Avalos     }
13515382d832SPeter Avalos 
13525382d832SPeter Avalos     if (src == 0) {
13535382d832SPeter Avalos 	char temp[80];
1354*a8e38dc0SAntonio Huete Jimenez 	sprintf(temp, _("Expected a numeric-parameter for %.*s"),
1355*a8e38dc0SAntonio Huete Jimenez 		USEMAX_ARGS, argv[*num]);
13565382d832SPeter Avalos 	Usage(temp);
13575382d832SPeter Avalos     }
13585382d832SPeter Avalos     *num = next;
13595382d832SPeter Avalos     return result;
13605382d832SPeter Avalos }
13615382d832SPeter Avalos 
1362*a8e38dc0SAntonio Huete Jimenez /*
1363*a8e38dc0SAntonio Huete Jimenez  * In findOption, we made provision for adding/removing a "no" prefix from
1364*a8e38dc0SAntonio Huete Jimenez  * any boolean option.  This function determines the actual true/false result.
1365*a8e38dc0SAntonio Huete Jimenez  */
1366*a8e38dc0SAntonio Huete Jimenez static bool
optionBool(const char * actual,const Options * data)1367*a8e38dc0SAntonio Huete Jimenez optionBool(const char *actual, const Options * data)
1368*a8e38dc0SAntonio Huete Jimenez {
1369*a8e38dc0SAntonio Huete Jimenez     bool normal = (data->type == tTrue) ? TRUE : FALSE;
1370*a8e38dc0SAntonio Huete Jimenez     bool result = !strcmp(actual + 2, data->name) ? normal : !normal;
1371*a8e38dc0SAntonio Huete Jimenez     if (result != normal) {
1372*a8e38dc0SAntonio Huete Jimenez 	int want_no = (strncmp(actual + 2, "no", 2) == 0);
1373*a8e38dc0SAntonio Huete Jimenez 	int have_no = (strncmp(data->name, "no", 2) == 0);
1374*a8e38dc0SAntonio Huete Jimenez 	if (have_no == want_no)
1375*a8e38dc0SAntonio Huete Jimenez 	    result = normal;
1376*a8e38dc0SAntonio Huete Jimenez     }
1377*a8e38dc0SAntonio Huete Jimenez     return result;
1378*a8e38dc0SAntonio Huete Jimenez }
1379*a8e38dc0SAntonio Huete Jimenez 
13805382d832SPeter Avalos /* Return exit-code for a named button */
13815382d832SPeter Avalos static int
button_code(const char * name)13825382d832SPeter Avalos button_code(const char *name)
13835382d832SPeter Avalos {
13845382d832SPeter Avalos     /* *INDENT-OFF* */
13855382d832SPeter Avalos     static struct {
13865382d832SPeter Avalos 	const char *name;
13875382d832SPeter Avalos 	int code;
13885382d832SPeter Avalos     } table[] = {
13895382d832SPeter Avalos 	{ "ok",	    DLG_EXIT_OK },
13905382d832SPeter Avalos 	{ "yes",    DLG_EXIT_OK },
13915382d832SPeter Avalos 	{ "cancel", DLG_EXIT_CANCEL },
13925382d832SPeter Avalos 	{ "no",	    DLG_EXIT_CANCEL },
13935382d832SPeter Avalos 	{ "help",   DLG_EXIT_HELP },
13945382d832SPeter Avalos 	{ "extra",  DLG_EXIT_EXTRA },
13955382d832SPeter Avalos     };
13965382d832SPeter Avalos     /* *INDENT-ON* */
13975382d832SPeter Avalos 
13985382d832SPeter Avalos     int code = DLG_EXIT_ERROR;
13995382d832SPeter Avalos     size_t i;
14005382d832SPeter Avalos 
14015940c9abSDaniel Fojt     for (i = 0; i < TableSize(table); i++) {
14025382d832SPeter Avalos 	if (!dlg_strcmp(name, table[i].name)) {
14035382d832SPeter Avalos 	    code = table[i].code;
14045382d832SPeter Avalos 	    break;
14055382d832SPeter Avalos 	}
14065382d832SPeter Avalos     }
14075382d832SPeter Avalos 
14085382d832SPeter Avalos     if (code == DLG_EXIT_ERROR) {
14095382d832SPeter Avalos 	char temp[80];
1410*a8e38dc0SAntonio Huete Jimenez 	sprintf(temp, _("Button name \"%.*s\" unknown"), USEMAX_ARGS, name);
14115382d832SPeter Avalos 	Usage(temp);
14125382d832SPeter Avalos     }
14135382d832SPeter Avalos 
14145382d832SPeter Avalos     return code;
14155382d832SPeter Avalos }
14165382d832SPeter Avalos 
14175382d832SPeter Avalos /*
14185940c9abSDaniel Fojt  * If this is the last option, we do not want any error messages - just our
14195940c9abSDaniel Fojt  * output.  Calling end_dialog() cancels the refresh() at the end of the
14205940c9abSDaniel Fojt  * program as well.
14215940c9abSDaniel Fojt  */
14225940c9abSDaniel Fojt static void
IgnoreNonScreen(char ** argv,int offset)14235940c9abSDaniel Fojt IgnoreNonScreen(char **argv, int offset)
14245940c9abSDaniel Fojt {
14255940c9abSDaniel Fojt     if (argv[offset + 1] == 0) {
14265940c9abSDaniel Fojt 	ignore_unknown = TRUE;
14275940c9abSDaniel Fojt 	end_dialog();
14285940c9abSDaniel Fojt     }
14295940c9abSDaniel Fojt }
14305940c9abSDaniel Fojt 
14315940c9abSDaniel Fojt static void
PrintTextOnly(char ** argv,int * offset,eOptions code)14325940c9abSDaniel Fojt PrintTextOnly(char **argv, int *offset, eOptions code)
14335940c9abSDaniel Fojt {
14345940c9abSDaniel Fojt     /* TODO - handle two optional numeric params */
14355940c9abSDaniel Fojt     char *text;
14365940c9abSDaniel Fojt     int height = 0;
14375940c9abSDaniel Fojt     int width = 0;
14385940c9abSDaniel Fojt     int height2 = 0;
14395940c9abSDaniel Fojt     int width2 = 0;
14405940c9abSDaniel Fojt     int next = arg_rest(argv + *offset);
14415940c9abSDaniel Fojt 
14425940c9abSDaniel Fojt     if (LINES <= 0 && COLS <= 0) {
14435940c9abSDaniel Fojt 	dlg_ttysize(fileno(dialog_state.input),
14445940c9abSDaniel Fojt 		    &dialog_state.screen_height,
14455940c9abSDaniel Fojt 		    &dialog_state.screen_width);
14465940c9abSDaniel Fojt     }
14475940c9abSDaniel Fojt 
14485940c9abSDaniel Fojt     text = strdup(optionString(argv, offset));
14495940c9abSDaniel Fojt     IgnoreNonScreen(argv, *offset);
14505940c9abSDaniel Fojt 
14515940c9abSDaniel Fojt     if (next >= 1) {
14525940c9abSDaniel Fojt 	next = MIN(next, 3);
14535940c9abSDaniel Fojt 	height = numeric_arg(argv, *offset + 1);
14545940c9abSDaniel Fojt 	if (next >= 2)
14555940c9abSDaniel Fojt 	    width = numeric_arg(argv, *offset + 2);
14565940c9abSDaniel Fojt 	*offset += next - 1;
14575940c9abSDaniel Fojt     }
14585940c9abSDaniel Fojt 
14595940c9abSDaniel Fojt     dlg_trim_string(text);
14605940c9abSDaniel Fojt     dlg_auto_size(NULL, text, &height2, &width2, height, width);
14615940c9abSDaniel Fojt 
14625940c9abSDaniel Fojt     switch (code) {
1463*a8e38dc0SAntonio Huete Jimenez     case o_text_only:
14645940c9abSDaniel Fojt 	dialog_state.text_only = TRUE;
14655940c9abSDaniel Fojt 	dlg_print_autowrap(stdscr, text, height2, width2);
14665940c9abSDaniel Fojt 	dialog_state.text_only = FALSE;
14675940c9abSDaniel Fojt 	break;
14685940c9abSDaniel Fojt     case o_print_text_size:
14695940c9abSDaniel Fojt 	fprintf(dialog_state.output, "%d %d\n",
14705940c9abSDaniel Fojt 		dialog_state.text_height,
14715940c9abSDaniel Fojt 		dialog_state.text_width);
14725940c9abSDaniel Fojt 	break;
14735940c9abSDaniel Fojt     default:
14745940c9abSDaniel Fojt 	break;
14755940c9abSDaniel Fojt     }
14765940c9abSDaniel Fojt }
14775940c9abSDaniel Fojt 
14785940c9abSDaniel Fojt /*
14795382d832SPeter Avalos  * Print parts of a message
14805382d832SPeter Avalos  */
14815382d832SPeter Avalos static void
PrintList(const char * const * list)14825382d832SPeter Avalos PrintList(const char *const *list)
14835382d832SPeter Avalos {
14845382d832SPeter Avalos     const char *leaf = strrchr(program, '/');
14855382d832SPeter Avalos     unsigned n = 0;
14865382d832SPeter Avalos 
14875382d832SPeter Avalos     if (leaf != 0)
14885382d832SPeter Avalos 	leaf++;
14895382d832SPeter Avalos     else
14905382d832SPeter Avalos 	leaf = program;
14915382d832SPeter Avalos 
14925382d832SPeter Avalos     while (*list != 0) {
14935382d832SPeter Avalos 	fprintf(dialog_state.output, *list, n ? leaf : dialog_version());
14945382d832SPeter Avalos 	(void) fputc('\n', dialog_state.output);
14955382d832SPeter Avalos 	n = 1;
14965382d832SPeter Avalos 	list++;
14975382d832SPeter Avalos     }
14985382d832SPeter Avalos }
14995382d832SPeter Avalos 
15005382d832SPeter Avalos static const Mode *
lookupMode(eOptions code)15015382d832SPeter Avalos lookupMode(eOptions code)
15025382d832SPeter Avalos {
15035382d832SPeter Avalos     const Mode *modePtr = 0;
15045382d832SPeter Avalos     unsigned n;
15055382d832SPeter Avalos 
15065940c9abSDaniel Fojt     for (n = 0; n < TableSize(modes); n++) {
15075382d832SPeter Avalos 	if (modes[n].code == code) {
15085382d832SPeter Avalos 	    modePtr = &modes[n];
15095382d832SPeter Avalos 	    break;
15105382d832SPeter Avalos 	}
15115382d832SPeter Avalos     }
15125382d832SPeter Avalos     return modePtr;
15135382d832SPeter Avalos }
15145382d832SPeter Avalos 
15155382d832SPeter Avalos static int
compare_opts(const void * a,const void * b)15165382d832SPeter Avalos compare_opts(const void *a, const void *b)
15175382d832SPeter Avalos {
15185382d832SPeter Avalos     Options *const *p = (Options * const *) a;
15195382d832SPeter Avalos     Options *const *q = (Options * const *) b;
15205382d832SPeter Avalos     return strcmp((*p)->name, (*q)->name);
15215382d832SPeter Avalos }
15225382d832SPeter Avalos 
15235382d832SPeter Avalos /*
15245382d832SPeter Avalos  * Print program's version.
15255382d832SPeter Avalos  */
15265382d832SPeter Avalos static void
PrintVersion(FILE * fp)15275382d832SPeter Avalos PrintVersion(FILE *fp)
15285382d832SPeter Avalos {
15295382d832SPeter Avalos     fprintf(fp, "Version: %s\n", dialog_version());
15305382d832SPeter Avalos }
15315382d832SPeter Avalos 
15325382d832SPeter Avalos /*
15335382d832SPeter Avalos  * Print program help-message
15345382d832SPeter Avalos  */
15355382d832SPeter Avalos static void
Help(void)15365382d832SPeter Avalos Help(void)
15375382d832SPeter Avalos {
15385382d832SPeter Avalos     static const char *const tbl_1[] =
15395382d832SPeter Avalos     {
15405382d832SPeter Avalos 	"cdialog (ComeOn Dialog!) version %s",
1541*a8e38dc0SAntonio Huete Jimenez 	"Copyright 2000-2021,2022 Thomas E. Dickey",
15425382d832SPeter Avalos 	"This is free software; see the source for copying conditions.  There is NO",
15435382d832SPeter Avalos 	"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.",
15445382d832SPeter Avalos 	"",
15455382d832SPeter Avalos 	"* Display dialog boxes from shell scripts *",
15465382d832SPeter Avalos 	"",
15475382d832SPeter Avalos 	"Usage: %s <options> { --and-widget <options> }",
15485382d832SPeter Avalos 	"where options are \"common\" options, followed by \"box\" options",
15495382d832SPeter Avalos 	"",
15505382d832SPeter Avalos #ifdef HAVE_RC_FILE
15515382d832SPeter Avalos 	"Special options:",
15525382d832SPeter Avalos 	"  [--create-rc \"file\"]",
15535382d832SPeter Avalos #endif
15545382d832SPeter Avalos 	0
15555382d832SPeter Avalos     }, *const tbl_3[] =
15565382d832SPeter Avalos     {
15575382d832SPeter Avalos 	"",
15585382d832SPeter Avalos 	"Auto-size with height and width = 0. Maximize with height and width = -1.",
15595382d832SPeter Avalos 	"Global-auto-size if also menu_height/list_height = 0.",
15605382d832SPeter Avalos 	0
15615382d832SPeter Avalos     };
15625940c9abSDaniel Fojt     size_t limit = TableSize(options);
15635382d832SPeter Avalos     size_t j, k;
15645382d832SPeter Avalos     const Options **opts;
15655382d832SPeter Avalos 
15665382d832SPeter Avalos     end_dialog();
15675382d832SPeter Avalos     dialog_state.output = stdout;
15685382d832SPeter Avalos 
15695382d832SPeter Avalos     opts = dlg_calloc(const Options *, limit);
15705382d832SPeter Avalos     assert_ptr(opts, "Help");
15715382d832SPeter Avalos     for (j = 0; j < limit; ++j) {
15725382d832SPeter Avalos 	opts[j] = &(options[j]);
15735382d832SPeter Avalos     }
15745382d832SPeter Avalos     qsort(opts, limit, sizeof(Options *), compare_opts);
15755382d832SPeter Avalos 
15765382d832SPeter Avalos     PrintList(tbl_1);
15775382d832SPeter Avalos     fprintf(dialog_state.output, "Common options:\n ");
15785382d832SPeter Avalos     for (j = k = 0; j < limit; j++) {
15795382d832SPeter Avalos 	if ((opts[j]->pass & 1)
15805382d832SPeter Avalos 	    && opts[j]->help != 0) {
15815382d832SPeter Avalos 	    size_t len = 6 + strlen(opts[j]->name) + strlen(opts[j]->help);
15825382d832SPeter Avalos 	    k += len;
15835382d832SPeter Avalos 	    if (k > 75) {
15845382d832SPeter Avalos 		fprintf(dialog_state.output, "\n ");
15855382d832SPeter Avalos 		k = len;
15865382d832SPeter Avalos 	    }
15875382d832SPeter Avalos 	    fprintf(dialog_state.output, " [--%s%s%s]", opts[j]->name,
15885382d832SPeter Avalos 		    *(opts[j]->help) ? " " : "", opts[j]->help);
15895382d832SPeter Avalos 	}
15905382d832SPeter Avalos     }
15915382d832SPeter Avalos     fprintf(dialog_state.output, "\nBox options:\n");
15925382d832SPeter Avalos     for (j = 0; j < limit; j++) {
15935382d832SPeter Avalos 	if ((opts[j]->pass & 2) != 0
15945382d832SPeter Avalos 	    && opts[j]->help != 0
15955940c9abSDaniel Fojt 	    && lookupMode(opts[j]->code)) {
15965382d832SPeter Avalos 	    fprintf(dialog_state.output, "  --%-12s %s\n", opts[j]->name,
15975382d832SPeter Avalos 		    opts[j]->help);
15985382d832SPeter Avalos 	}
15995940c9abSDaniel Fojt     }
16005382d832SPeter Avalos     PrintList(tbl_3);
16015382d832SPeter Avalos 
16025382d832SPeter Avalos     free(opts);
16035940c9abSDaniel Fojt     handle_leaks();
16045382d832SPeter Avalos     dlg_exit(DLG_EXIT_OK);
16055382d832SPeter Avalos }
16065382d832SPeter Avalos 
16075382d832SPeter Avalos #ifdef HAVE_DLG_TRACE
16085382d832SPeter Avalos /*
16095382d832SPeter Avalos  * Only the first call to dlg_trace will open a trace file.  But each time
16105382d832SPeter Avalos  * --trace is parsed, we show the whole parameter list as it is at that moment,
16115382d832SPeter Avalos  * counting discarded parameters.  The only way to capture the whole parameter
16125382d832SPeter Avalos  * list is if --trace is the first option.
16135382d832SPeter Avalos  */
16145382d832SPeter Avalos static void
process_trace_option(char ** argv,int * offset)16155382d832SPeter Avalos process_trace_option(char **argv, int *offset)
16165382d832SPeter Avalos {
16175382d832SPeter Avalos     int j;
16185382d832SPeter Avalos 
16195382d832SPeter Avalos     if (dialog_state.trace_output == 0) {
16205382d832SPeter Avalos 	dlg_trace(optionString(argv, offset));
16215382d832SPeter Avalos     } else {
16225940c9abSDaniel Fojt 	DLG_TRACE(("# ignore extra --trace option\n"));
16235382d832SPeter Avalos 	*offset += 1;
16245382d832SPeter Avalos     }
16255382d832SPeter Avalos 
16265940c9abSDaniel Fojt     DLG_TRACE(("# Parameters:\n"));
16275382d832SPeter Avalos     for (j = 0; argv[j] != 0; ++j) {
16285940c9abSDaniel Fojt 	DLG_TRACE(("#\targv[%d] = %s\n", j, argv[j]));
16295382d832SPeter Avalos     }
16305382d832SPeter Avalos }
16315382d832SPeter Avalos #endif
16325382d832SPeter Avalos 
16335382d832SPeter Avalos /*
16345382d832SPeter Avalos  * "Common" options apply to all widgets more/less.  Most of the common options
16355382d832SPeter Avalos  * set values in dialog_vars, a few set dialog_state and a couple write to the
16365382d832SPeter Avalos  * output stream.
16375382d832SPeter Avalos  */
16385382d832SPeter Avalos static int
process_common_options(int argc,char ** argv,int offset,int output)16395940c9abSDaniel Fojt process_common_options(int argc, char **argv, int offset, int output)
16405382d832SPeter Avalos {
1641*a8e38dc0SAntonio Huete Jimenez     const Options *data = NULL;
16425382d832SPeter Avalos     bool done = FALSE;
16435382d832SPeter Avalos 
1644*a8e38dc0SAntonio Huete Jimenez     DLG_TRACE(("# process_common_options, offset %d:%d\n", offset, argc));
16455382d832SPeter Avalos 
1646*a8e38dc0SAntonio Huete Jimenez     while (!done && offset < argc) {
1647*a8e38dc0SAntonio Huete Jimenez 	static char empty[] = "";
1648*a8e38dc0SAntonio Huete Jimenez 	eOptions code = o_unknown;
1649*a8e38dc0SAntonio Huete Jimenez 	char *sval = empty;
1650*a8e38dc0SAntonio Huete Jimenez 	bool bval;
1651*a8e38dc0SAntonio Huete Jimenez 	int nval;
1652*a8e38dc0SAntonio Huete Jimenez 	char *target;
1653*a8e38dc0SAntonio Huete Jimenez 
16545940c9abSDaniel Fojt 	DLG_TRACE(("#\targv[%d] = %s\n", offset, argv[offset]));
1655*a8e38dc0SAntonio Huete Jimenez 	if ((data = findOption(argv[offset], 1, FALSE)) == NULL) {
1656*a8e38dc0SAntonio Huete Jimenez 	    done = TRUE;
1657*a8e38dc0SAntonio Huete Jimenez 	    continue;
1658*a8e38dc0SAntonio Huete Jimenez 	}
1659*a8e38dc0SAntonio Huete Jimenez 
1660*a8e38dc0SAntonio Huete Jimenez 	switch (data->vars) {
1661*a8e38dc0SAntonio Huete Jimenez 	default:
1662*a8e38dc0SAntonio Huete Jimenez 	    target = NULL;
16635382d832SPeter Avalos 	    break;
1664*a8e38dc0SAntonio Huete Jimenez 	case 1:
1665*a8e38dc0SAntonio Huete Jimenez 	    target = (char *) &dialog_state;
16665382d832SPeter Avalos 	    break;
1667*a8e38dc0SAntonio Huete Jimenez 	case 2:
1668*a8e38dc0SAntonio Huete Jimenez 	    target = (char *) &dialog_vars;
16695382d832SPeter Avalos 	    break;
1670*a8e38dc0SAntonio Huete Jimenez 	}
1671*a8e38dc0SAntonio Huete Jimenez 
1672*a8e38dc0SAntonio Huete Jimenez #define TraceTarget \
1673*a8e38dc0SAntonio Huete Jimenez 	    ((target == (char *) &dialog_state) \
1674*a8e38dc0SAntonio Huete Jimenez 	     ? "dialog_state" \
1675*a8e38dc0SAntonio Huete Jimenez 	     : "dialog_vars")
1676*a8e38dc0SAntonio Huete Jimenez #define TraceBVal (bval ? "TRUE" : "FALSE")
1677*a8e38dc0SAntonio Huete Jimenez #define TraceDone(fmt,value) \
1678*a8e38dc0SAntonio Huete Jimenez 	DLG_TRACE(("#\t.. set %s.%s = %"fmt"\n", TraceTarget, data->name, value))
1679*a8e38dc0SAntonio Huete Jimenez #define TraceLate(fmt,value) \
1680*a8e38dc0SAntonio Huete Jimenez 	DLG_TRACE(("#\t.. defer setting %s = %"fmt"\n", data->name, value))
1681*a8e38dc0SAntonio Huete Jimenez 
1682*a8e38dc0SAntonio Huete Jimenez 	code = data->code;
1683*a8e38dc0SAntonio Huete Jimenez 	switch (data->type) {
1684*a8e38dc0SAntonio Huete Jimenez 	default:
16855382d832SPeter Avalos 	    break;
1686*a8e38dc0SAntonio Huete Jimenez 	case tFalse:
1687*a8e38dc0SAntonio Huete Jimenez 	case tTrue:
1688*a8e38dc0SAntonio Huete Jimenez 	    bval = optionBool(argv[offset], data);
1689*a8e38dc0SAntonio Huete Jimenez 	    if (target != NULL) {
1690*a8e38dc0SAntonio Huete Jimenez 		*(bool *) (target + data->offset) = bval;
1691*a8e38dc0SAntonio Huete Jimenez 		TraceDone("s", TraceBVal);
1692*a8e38dc0SAntonio Huete Jimenez 	    } else {
1693*a8e38dc0SAntonio Huete Jimenez 		TraceLate("s", TraceBVal);
1694*a8e38dc0SAntonio Huete Jimenez 	    }
16955382d832SPeter Avalos 	    break;
1696*a8e38dc0SAntonio Huete Jimenez 	case tNumber:
1697*a8e38dc0SAntonio Huete Jimenez 	    nval = optionValue(argv, &offset);
1698*a8e38dc0SAntonio Huete Jimenez 	    if (target != NULL) {
1699*a8e38dc0SAntonio Huete Jimenez 		*(int *) (void *) (target + data->offset) = nval;
1700*a8e38dc0SAntonio Huete Jimenez 		TraceDone("d", nval);
1701*a8e38dc0SAntonio Huete Jimenez 	    } else {
1702*a8e38dc0SAntonio Huete Jimenez 		TraceLate("d", nval);
1703*a8e38dc0SAntonio Huete Jimenez 	    }
17045382d832SPeter Avalos 	    break;
1705*a8e38dc0SAntonio Huete Jimenez 	case tString:
1706*a8e38dc0SAntonio Huete Jimenez 	    sval = optionString(argv, &offset);
1707*a8e38dc0SAntonio Huete Jimenez 	    if (target != NULL) {
1708*a8e38dc0SAntonio Huete Jimenez 		*(char **) (void *) (target + data->offset) = sval;
1709*a8e38dc0SAntonio Huete Jimenez 		TraceDone("s", sval);
1710*a8e38dc0SAntonio Huete Jimenez 	    } else {
1711*a8e38dc0SAntonio Huete Jimenez 		TraceLate("s", sval);
1712*a8e38dc0SAntonio Huete Jimenez 	    }
17135382d832SPeter Avalos 	    break;
1714*a8e38dc0SAntonio Huete Jimenez 	}
1715*a8e38dc0SAntonio Huete Jimenez 
1716*a8e38dc0SAntonio Huete Jimenez 	switch (code) {
17175382d832SPeter Avalos 	case o_defaultno:
17185382d832SPeter Avalos 	    dialog_vars.default_button = DLG_EXIT_CANCEL;
17195382d832SPeter Avalos 	    break;
17205382d832SPeter Avalos 	case o_default_button:
1721*a8e38dc0SAntonio Huete Jimenez 	    dialog_vars.default_button = button_code(sval);
17225382d832SPeter Avalos 	    dialog_vars.defaultno = dialog_vars.default_button == DLG_EXIT_CANCEL;
17235382d832SPeter Avalos 	    break;
1724*a8e38dc0SAntonio Huete Jimenez 	case o_text_only:
17255940c9abSDaniel Fojt 	case o_print_text_size:
17265940c9abSDaniel Fojt 	    PrintTextOnly(argv, &offset, code);
17275940c9abSDaniel Fojt 	    break;
17285382d832SPeter Avalos 	case o_print_maxsize:
17295382d832SPeter Avalos 	    if (output) {
17305940c9abSDaniel Fojt 		IgnoreNonScreen(argv, offset);
17315382d832SPeter Avalos 		fflush(dialog_state.output);
17325382d832SPeter Avalos 		fprintf(dialog_state.output, "MaxSize: %d, %d\n", SLINES, SCOLS);
17335382d832SPeter Avalos 	    }
17345382d832SPeter Avalos 	    break;
17355382d832SPeter Avalos 	case o_print_version:
17365382d832SPeter Avalos 	    if (output) {
17375382d832SPeter Avalos 		PrintVersion(dialog_state.output);
17385382d832SPeter Avalos 	    }
17395382d832SPeter Avalos 	    break;
17405382d832SPeter Avalos 	case o_visit_items:
17415382d832SPeter Avalos 	    dialog_state.visit_cols = 1;
17425382d832SPeter Avalos 	    break;
1743*a8e38dc0SAntonio Huete Jimenez 	case o_begin_set:
1744*a8e38dc0SAntonio Huete Jimenez #ifdef HAVE_WHIPTAIL
1745*a8e38dc0SAntonio Huete Jimenez 	    if (!strcmp(argv[offset], "--topleft")) {
1746*a8e38dc0SAntonio Huete Jimenez 		dialog_vars.begin_y = 0;
1747*a8e38dc0SAntonio Huete Jimenez 		dialog_vars.begin_x = 0;
1748*a8e38dc0SAntonio Huete Jimenez 	    } else
1749*a8e38dc0SAntonio Huete Jimenez #endif
1750*a8e38dc0SAntonio Huete Jimenez 	    {
17515382d832SPeter Avalos 		dialog_vars.begin_y = optionValue(argv, &offset);
17525382d832SPeter Avalos 		dialog_vars.begin_x = optionValue(argv, &offset);
1753*a8e38dc0SAntonio Huete Jimenez 	    }
17545382d832SPeter Avalos 	    break;
17555382d832SPeter Avalos 	case o_ascii_lines:
17565382d832SPeter Avalos 	    dialog_vars.no_lines = FALSE;
17575382d832SPeter Avalos 	    break;
17585382d832SPeter Avalos 	case o_no_lines:
17595382d832SPeter Avalos 	    dialog_vars.ascii_lines = FALSE;
17605382d832SPeter Avalos 	    break;
17615382d832SPeter Avalos 	case o_no_mouse:
17625382d832SPeter Avalos 	    mouse_close();
17635382d832SPeter Avalos 	    break;
17645382d832SPeter Avalos 	case o_unknown:
1765*a8e38dc0SAntonio Huete Jimenez 	    done = !ignore_unknown;
1766*a8e38dc0SAntonio Huete Jimenez 	default:
17675382d832SPeter Avalos 	    break;
17685382d832SPeter Avalos #ifdef HAVE_DLG_TRACE
17695382d832SPeter Avalos 	case o_trace:
17705382d832SPeter Avalos 	    process_trace_option(argv, &offset);
17715382d832SPeter Avalos 	    break;
17725382d832SPeter Avalos #endif
17735940c9abSDaniel Fojt 	case o_iso_week:
17745940c9abSDaniel Fojt 	    if (dialog_vars.week_start == 0) {	/* Monday is implied */
17755940c9abSDaniel Fojt 		static char default_1st[] = "1";
17765940c9abSDaniel Fojt 		dialog_vars.week_start = default_1st;
17775940c9abSDaniel Fojt 	    }
17785940c9abSDaniel Fojt 	    break;
17795382d832SPeter Avalos 	}
17805382d832SPeter Avalos 	if (!done)
17815382d832SPeter Avalos 	    offset++;
17825382d832SPeter Avalos     }
17835940c9abSDaniel Fojt 
17845940c9abSDaniel Fojt     if (dialog_state.aspect_ratio == 0)
17855940c9abSDaniel Fojt 	dialog_state.aspect_ratio = DEFAULT_ASPECT_RATIO;
17865940c9abSDaniel Fojt 
17875382d832SPeter Avalos     return offset;
17885382d832SPeter Avalos }
17895382d832SPeter Avalos 
17905382d832SPeter Avalos /*
17915382d832SPeter Avalos  * Initialize options at the start of a series of common options culminating
17925382d832SPeter Avalos  * in a widget.
17935382d832SPeter Avalos  */
17945382d832SPeter Avalos static void
init_result(char * buffer)17955382d832SPeter Avalos init_result(char *buffer)
17965382d832SPeter Avalos {
17975382d832SPeter Avalos     static bool first = TRUE;
17985382d832SPeter Avalos 
17995940c9abSDaniel Fojt     DLG_TRACE(("# init_result\n"));
18005382d832SPeter Avalos 
18015382d832SPeter Avalos     /* clear everything we do not save for the next widget */
18025382d832SPeter Avalos     memset(&dialog_vars, 0, sizeof(dialog_vars));
18035382d832SPeter Avalos 
18045382d832SPeter Avalos     dialog_vars.input_result = buffer;
18055382d832SPeter Avalos     dialog_vars.input_result[0] = '\0';
18065382d832SPeter Avalos 
18075382d832SPeter Avalos     dialog_vars.default_button = -1;
18085382d832SPeter Avalos 
18095382d832SPeter Avalos     /*
18105382d832SPeter Avalos      * The first time this is called, check for common options given by an
18115382d832SPeter Avalos      * environment variable.
18125382d832SPeter Avalos      */
18135382d832SPeter Avalos     if (first) {
1814*a8e38dc0SAntonio Huete Jimenez 	char *env = dlg_getenv_str("DIALOGOPTS");
18155382d832SPeter Avalos 	if (env != 0)
18165382d832SPeter Avalos 	    env = dlg_strclone(env);
18175382d832SPeter Avalos 	if (env != 0) {
18185382d832SPeter Avalos 	    special_argv = dlg_string_to_argv(env);
18195382d832SPeter Avalos 	    special_argc = dlg_count_argv(special_argv);
18205382d832SPeter Avalos 	}
18215382d832SPeter Avalos 	first = FALSE;
18225382d832SPeter Avalos     }
18235382d832SPeter Avalos 
18245382d832SPeter Avalos     if (special_argv != 0) {
18255382d832SPeter Avalos 	process_common_options(special_argc, special_argv, 0, FALSE);
18265382d832SPeter Avalos     }
18275382d832SPeter Avalos }
18285382d832SPeter Avalos 
18295382d832SPeter Avalos int
main(int argc,char * argv[])18305382d832SPeter Avalos main(int argc, char *argv[])
18315382d832SPeter Avalos {
18325382d832SPeter Avalos     char temp[256];
18335382d832SPeter Avalos     bool esc_pressed = FALSE;
18345382d832SPeter Avalos     bool keep_tite = FALSE;
18355940c9abSDaniel Fojt     int initial = 1;
18365382d832SPeter Avalos     int offset = 1;
1837*a8e38dc0SAntonio Huete Jimenez     int offset_add = 0;
18385382d832SPeter Avalos     int retval = DLG_EXIT_OK;
18395940c9abSDaniel Fojt     int j;
18405382d832SPeter Avalos     eOptions code;
18415382d832SPeter Avalos     char my_buffer[MAX_LEN + 1];
18425382d832SPeter Avalos 
18435382d832SPeter Avalos     memset(&dialog_state, 0, sizeof(dialog_state));
18445382d832SPeter Avalos     memset(&dialog_vars, 0, sizeof(dialog_vars));
18455382d832SPeter Avalos 
18465382d832SPeter Avalos #if defined(ENABLE_NLS)
18475382d832SPeter Avalos     /* initialize locale support */
18485382d832SPeter Avalos     setlocale(LC_ALL, "");
18495382d832SPeter Avalos     bindtextdomain(NLS_TEXTDOMAIN, LOCALEDIR);
18505382d832SPeter Avalos     textdomain(NLS_TEXTDOMAIN);
18515382d832SPeter Avalos #elif defined(HAVE_SETLOCALE)
18525382d832SPeter Avalos     (void) setlocale(LC_ALL, "");
18535382d832SPeter Avalos #endif
18545382d832SPeter Avalos 
18555940c9abSDaniel Fojt     init_result(my_buffer);	/* honor $DIALOGOPTS */
18565382d832SPeter Avalos     unescape_argv(&argc, &argv);
18575382d832SPeter Avalos     program = argv[0];
18585382d832SPeter Avalos     dialog_state.output = stderr;
18595382d832SPeter Avalos     dialog_state.input = stdin;
18605382d832SPeter Avalos 
18615382d832SPeter Avalos     /*
18625382d832SPeter Avalos      * Look for the last --stdout, --stderr or --output-fd option, and use
18635382d832SPeter Avalos      * that.  We can only write to one of them.  If --stdout is used, that
18645382d832SPeter Avalos      * can interfere with initializing the curses library, so we want to
18655382d832SPeter Avalos      * know explicitly if it is used.
18665382d832SPeter Avalos      *
18675382d832SPeter Avalos      * Also, look for any --version or --help message, processing those
18685382d832SPeter Avalos      * immediately.
18695382d832SPeter Avalos      */
18705382d832SPeter Avalos     while (offset < argc) {
18715382d832SPeter Avalos 	int base = offset;
18725382d832SPeter Avalos 	switch (lookupOption(argv[offset], 7)) {
1873*a8e38dc0SAntonio Huete Jimenez 	case o_output_stdout:
18745382d832SPeter Avalos 	    dialog_state.output = stdout;
18755382d832SPeter Avalos 	    break;
1876*a8e38dc0SAntonio Huete Jimenez 	case o_output_stderr:
18775382d832SPeter Avalos 	    dialog_state.output = stderr;
18785382d832SPeter Avalos 	    break;
18795382d832SPeter Avalos 	case o_input_fd:
18805382d832SPeter Avalos 	    if ((j = optionValue(argv, &offset)) < 0
18815940c9abSDaniel Fojt 		|| (dialog_state.input = fdopen(j, "r")) == 0) {
18825940c9abSDaniel Fojt 		handle_leaks();
1883*a8e38dc0SAntonio Huete Jimenez 		dlg_exiterr(_("Cannot open input-fd\n"));
18845940c9abSDaniel Fojt 	    }
18855382d832SPeter Avalos 	    break;
18865382d832SPeter Avalos 	case o_output_fd:
18875382d832SPeter Avalos 	    if ((j = optionValue(argv, &offset)) < 0
18885940c9abSDaniel Fojt 		|| (dialog_state.output = fdopen(j, "w")) == 0) {
18895940c9abSDaniel Fojt 		handle_leaks();
1890*a8e38dc0SAntonio Huete Jimenez 		dlg_exiterr(_("Cannot open output-fd\n"));
18915940c9abSDaniel Fojt 	    }
18925382d832SPeter Avalos 	    break;
18935382d832SPeter Avalos 	case o_keep_tite:
18945382d832SPeter Avalos 	    keep_tite = TRUE;
18955382d832SPeter Avalos 	    break;
18965382d832SPeter Avalos 	case o_version:
18975382d832SPeter Avalos 	    dialog_state.output = stdout;
18985382d832SPeter Avalos 	    PrintVersion(dialog_state.output);
18995940c9abSDaniel Fojt 	    dlg_exit(DLG_EXIT_OK);
19005382d832SPeter Avalos 	    break;
19015382d832SPeter Avalos 	case o_help:
19025382d832SPeter Avalos 	    Help();
19035382d832SPeter Avalos 	    break;
19045382d832SPeter Avalos #ifdef HAVE_DLG_TRACE
19055382d832SPeter Avalos 	case o_trace:
19065382d832SPeter Avalos 	    /*
19075382d832SPeter Avalos 	     * Process/remove the --trace option if it is the first option.
19085382d832SPeter Avalos 	     * Otherwise, process it in more/less expected order as a
19095382d832SPeter Avalos 	     * "common" option.
19105382d832SPeter Avalos 	     */
19115382d832SPeter Avalos 	    if (base == 1) {
19125382d832SPeter Avalos 		process_trace_option(argv, &offset);
19135382d832SPeter Avalos 		break;
19145382d832SPeter Avalos 	    } else {
19155382d832SPeter Avalos 		++offset;
19165382d832SPeter Avalos 		continue;
19175382d832SPeter Avalos 	    }
19185382d832SPeter Avalos #endif
19195382d832SPeter Avalos 	default:
19205382d832SPeter Avalos 	    ++offset;
19215382d832SPeter Avalos 	    continue;
19225382d832SPeter Avalos 	}
19235940c9abSDaniel Fojt 	DLG_TRACE(("# discarding %d parameters starting with argv[%d] (%s)\n",
19245382d832SPeter Avalos 		   1 + offset - base, base,
19255940c9abSDaniel Fojt 		   argv[base]));
19265382d832SPeter Avalos 	for (j = base; j < argc; ++j) {
19275382d832SPeter Avalos 	    dialog_argv[j] = dialog_argv[j + 1 + (offset - base)];
19285382d832SPeter Avalos 	}
19295382d832SPeter Avalos 	argc -= (1 + offset - base);
19305382d832SPeter Avalos 	offset = base;
19315382d832SPeter Avalos     }
19325382d832SPeter Avalos     offset = 1;
19335382d832SPeter Avalos     init_result(my_buffer);
1934*a8e38dc0SAntonio Huete Jimenez     dialog_vars.keep_tite |= keep_tite;		/* init_result() cleared global */
19355382d832SPeter Avalos 
19365382d832SPeter Avalos     /*
19375382d832SPeter Avalos      * Dialog's output may be redirected (see above).  Handle the special
19385382d832SPeter Avalos      * case of options that only report information without interaction.
19395382d832SPeter Avalos      */
19405382d832SPeter Avalos     if (argc == 2) {
1941*a8e38dc0SAntonio Huete Jimenez 	switch (lookupOption(argv[1], 7)) {
19425382d832SPeter Avalos 	case o_print_maxsize:
19435382d832SPeter Avalos 	    (void) initscr();
19445382d832SPeter Avalos 	    endwin();
19455382d832SPeter Avalos 	    fflush(dialog_state.output);
19465382d832SPeter Avalos 	    fprintf(dialog_state.output, "MaxSize: %d, %d\n", SLINES, SCOLS);
19475382d832SPeter Avalos 	    break;
19485382d832SPeter Avalos 	case o_print_version:
19495382d832SPeter Avalos 	    PrintVersion(dialog_state.output);
19505382d832SPeter Avalos 	    break;
1951*a8e38dc0SAntonio Huete Jimenez 	case o_dlg_clear_screen:
19525382d832SPeter Avalos 	    initscr();
19535382d832SPeter Avalos 	    refresh();
1954*a8e38dc0SAntonio Huete Jimenez 	    dlg_keep_tite((dialog_state.output == stdout) ? stderr : stdout);
19555382d832SPeter Avalos 	    endwin();
19565382d832SPeter Avalos 	    break;
19575382d832SPeter Avalos 	case o_ignore:
19585382d832SPeter Avalos 	    break;
19595382d832SPeter Avalos 	default:
19605382d832SPeter Avalos 	    Help();
19615382d832SPeter Avalos 	    break;
19625382d832SPeter Avalos 	}
19635940c9abSDaniel Fojt 	dlg_exit(DLG_EXIT_OK);
19645940c9abSDaniel Fojt     } else if (argc < 2) {
19655382d832SPeter Avalos 	Help();
19665382d832SPeter Avalos     }
19675382d832SPeter Avalos #ifdef HAVE_RC_FILE
19685940c9abSDaniel Fojt     else if (lookupOption(argv[1], 7) == o_create_rc) {
19695382d832SPeter Avalos 	if (argc != 3) {
1970*a8e38dc0SAntonio Huete Jimenez 	    sprintf(temp, _("Expected a filename for %.*s"), USEMAX_FILE,
1971*a8e38dc0SAntonio Huete Jimenez 		    argv[1]);
19725382d832SPeter Avalos 	    Usage(temp);
19735382d832SPeter Avalos 	}
1974*a8e38dc0SAntonio Huete Jimenez #ifdef HAVE_COLOR
1975*a8e38dc0SAntonio Huete Jimenez 	dialog_state.use_colors = USE_COLORS;	/* use colors by default? */
1976*a8e38dc0SAntonio Huete Jimenez 	dialog_state.use_shadow = USE_SHADOW;	/* shadow dialog boxes by default? */
1977*a8e38dc0SAntonio Huete Jimenez #endif
19785940c9abSDaniel Fojt 	if (dlg_parse_rc() == -1) {	/* Read the configuration file */
19795940c9abSDaniel Fojt 	    handle_leaks();
19805382d832SPeter Avalos 	    dlg_exiterr("dialog: dlg_parse_rc");
19815940c9abSDaniel Fojt 	}
19825382d832SPeter Avalos 	dlg_create_rc(argv[2]);
19835940c9abSDaniel Fojt 	dlg_exit(DLG_EXIT_OK);
19845382d832SPeter Avalos     }
1985*a8e38dc0SAntonio Huete Jimenez #endif /* HAVE_RC_FILE */
19865940c9abSDaniel Fojt     else {
19875940c9abSDaniel Fojt 	/*
19885940c9abSDaniel Fojt 	 * Handle combinations of common options including --print-text-only
19895940c9abSDaniel Fojt 	 * which can be done before involving curses, in case we can exit
19905940c9abSDaniel Fojt 	 * without initializing curses (and writing to the terminal).
19915940c9abSDaniel Fojt 	 */
19925940c9abSDaniel Fojt 	initial = process_common_options(argc, argv, offset, TRUE);
19935940c9abSDaniel Fojt 	if (initial >= argc)
19945940c9abSDaniel Fojt 	    dlg_exit(DLG_EXIT_OK);
19955940c9abSDaniel Fojt     }
19965382d832SPeter Avalos 
19975382d832SPeter Avalos     init_dialog(dialog_state.input, dialog_state.output);
19985382d832SPeter Avalos 
19995382d832SPeter Avalos     while (offset < argc && !esc_pressed) {
20005940c9abSDaniel Fojt 	int have;
20015940c9abSDaniel Fojt 	const Mode *modePtr;
20025382d832SPeter Avalos 
20035940c9abSDaniel Fojt 	init_result(my_buffer);
20045940c9abSDaniel Fojt 	offset = process_common_options(argc, argv, offset, offset > initial);
20055382d832SPeter Avalos 
20065382d832SPeter Avalos 	if (argv[offset] == NULL) {
20075382d832SPeter Avalos 	    if (ignore_unknown)
20085382d832SPeter Avalos 		break;
2009*a8e38dc0SAntonio Huete Jimenez 	    Usage(_("Expected a box option"));
20105382d832SPeter Avalos 	}
20115382d832SPeter Avalos 
20121ef6786aSJohn Marino 	if (dialog_vars.separate_output) {
20131ef6786aSJohn Marino 	    switch (lookupOption(argv[offset], 2)) {
20141ef6786aSJohn Marino #ifdef HAVE_XDIALOG2
20151ef6786aSJohn Marino 	    case o_buildlist:
20161ef6786aSJohn Marino 	    case o_treeview:
20171ef6786aSJohn Marino #endif
20181ef6786aSJohn Marino 	    case o_checklist:
20191ef6786aSJohn Marino 		break;
20201ef6786aSJohn Marino 	    default:
20211ef6786aSJohn Marino 		sprintf(temp,
2022*a8e38dc0SAntonio Huete Jimenez 			_("Unexpected widget with --separate-output %.*s"),
2023*a8e38dc0SAntonio Huete Jimenez 			USEMAX_ARGS, argv[offset]);
20245382d832SPeter Avalos 		Usage(temp);
20255382d832SPeter Avalos 	    }
20261ef6786aSJohn Marino 	}
20275382d832SPeter Avalos 
20285382d832SPeter Avalos 	dlg_put_backtitle();
20295382d832SPeter Avalos 
20305382d832SPeter Avalos 	/* use a table to look for the requested mode, to avoid code duplication */
20315382d832SPeter Avalos 
20325382d832SPeter Avalos 	modePtr = 0;
20335382d832SPeter Avalos 	if ((code = lookupOption(argv[offset], 2)) != o_unknown)
20345382d832SPeter Avalos 	    modePtr = lookupMode(code);
20355382d832SPeter Avalos 	if (modePtr == 0) {
2036*a8e38dc0SAntonio Huete Jimenez 	    sprintf(temp,
2037*a8e38dc0SAntonio Huete Jimenez 		    (lookupOption(argv[offset], 7) != o_unknown
2038*a8e38dc0SAntonio Huete Jimenez 		     ? _("Unexpected option %.*s")
2039*a8e38dc0SAntonio Huete Jimenez 		     : _("Unknown option %.*s")),
2040*a8e38dc0SAntonio Huete Jimenez 		    USEMAX_ARGS,
20415382d832SPeter Avalos 		    argv[offset]);
20425382d832SPeter Avalos 	    Usage(temp);
20435382d832SPeter Avalos 	}
20445382d832SPeter Avalos 
20455382d832SPeter Avalos 	have = arg_rest(&argv[offset]);
20465382d832SPeter Avalos 	if (have < modePtr->argmin) {
2047*a8e38dc0SAntonio Huete Jimenez 	    sprintf(temp, _("Expected at least %d tokens for %.*s, have %d"),
2048*a8e38dc0SAntonio Huete Jimenez 		    USEMAX_ARGS,
20495382d832SPeter Avalos 		    modePtr->argmin - 1, argv[offset],
20505382d832SPeter Avalos 		    have - 1);
20515382d832SPeter Avalos 	    Usage(temp);
20525382d832SPeter Avalos 	}
20535382d832SPeter Avalos 	if (modePtr->argmax && have > modePtr->argmax) {
20545382d832SPeter Avalos 	    sprintf(temp,
2055*a8e38dc0SAntonio Huete Jimenez 		    _("Expected no more than %d tokens for %.*s, have %d"),
2056*a8e38dc0SAntonio Huete Jimenez 		    USEMAX_ARGS,
20575382d832SPeter Avalos 		    modePtr->argmax - 1, argv[offset],
20585382d832SPeter Avalos 		    have - 1);
20595382d832SPeter Avalos 	    Usage(temp);
20605382d832SPeter Avalos 	}
20615382d832SPeter Avalos 
20625382d832SPeter Avalos 	/*
20635382d832SPeter Avalos 	 * Trim whitespace from non-title option values, e.g., the ones that
20645382d832SPeter Avalos 	 * will be used as captions or prompts.   Do that only for the widget
20655382d832SPeter Avalos 	 * we are about to process, since the "--trim" option is reset before
20665382d832SPeter Avalos 	 * accumulating options for each widget.
20675382d832SPeter Avalos 	 */
20685382d832SPeter Avalos 	for (j = offset + 1; j <= offset + have; j++) {
20695382d832SPeter Avalos 	    switch (lookupOption(argv[j - 1], 7)) {
20705382d832SPeter Avalos 	    case o_unknown:
20715382d832SPeter Avalos 	    case o_title:
20725382d832SPeter Avalos 	    case o_backtitle:
20735382d832SPeter Avalos 	    case o_help_line:
20745382d832SPeter Avalos 	    case o_help_file:
20755382d832SPeter Avalos 		break;
20765382d832SPeter Avalos 	    default:
20775382d832SPeter Avalos 		if (argv[j] != 0) {
20785382d832SPeter Avalos 		    char *argv_j = strdup(argv[j]);
20795382d832SPeter Avalos 		    if (argv_j != 0) {
20805382d832SPeter Avalos 			dlg_trim_string(argv_j);
20815382d832SPeter Avalos 			argv[j] = argv_j;
20825382d832SPeter Avalos 		    } else {
20835382d832SPeter Avalos 			argv[j] = strdup("?");
20845382d832SPeter Avalos 		    }
20855940c9abSDaniel Fojt 		    ignore_leak(argv[j]);
20865382d832SPeter Avalos 		}
20875382d832SPeter Avalos 		break;
20885382d832SPeter Avalos 	    }
20895382d832SPeter Avalos 	}
20905382d832SPeter Avalos 
20915940c9abSDaniel Fojt 	DLG_TRACE(("# execute %s\n", argv[offset]));
20925382d832SPeter Avalos 	retval = show_result((*(modePtr->jumper)) (dialog_vars.title,
20935382d832SPeter Avalos 						   argv + offset,
20945382d832SPeter Avalos 						   &offset_add));
20955940c9abSDaniel Fojt 	DLG_TRACE(("# widget returns %d\n", retval));
20965382d832SPeter Avalos 	offset += offset_add;
20975382d832SPeter Avalos 
20985382d832SPeter Avalos 	if (dialog_vars.input_result != my_buffer) {
20995382d832SPeter Avalos 	    free(dialog_vars.input_result);
21005382d832SPeter Avalos 	    dialog_vars.input_result = 0;
21015382d832SPeter Avalos 	}
21025382d832SPeter Avalos 
21035382d832SPeter Avalos 	if (retval == DLG_EXIT_ESC) {
21045382d832SPeter Avalos 	    esc_pressed = TRUE;
21055382d832SPeter Avalos 	} else {
21065382d832SPeter Avalos 
21075382d832SPeter Avalos 	    if (dialog_vars.beep_after_signal)
21085382d832SPeter Avalos 		(void) beep();
21095382d832SPeter Avalos 
21105382d832SPeter Avalos 	    if (dialog_vars.sleep_secs)
21115382d832SPeter Avalos 		(void) napms(dialog_vars.sleep_secs * 1000);
21125382d832SPeter Avalos 
21135382d832SPeter Avalos 	    if (offset < argc) {
21145382d832SPeter Avalos 		switch (lookupOption(argv[offset], 7)) {
21155382d832SPeter Avalos 		case o_and_widget:
21165382d832SPeter Avalos 		    offset++;
21175382d832SPeter Avalos 		    break;
21185382d832SPeter Avalos 		case o_unknown:
2119*a8e38dc0SAntonio Huete Jimenez 		    sprintf(temp, _("Expected --and-widget, not %.*s"),
2120*a8e38dc0SAntonio Huete Jimenez 			    USEMAX_ARGS, argv[offset]);
21215382d832SPeter Avalos 		    Usage(temp);
21225382d832SPeter Avalos 		    break;
21235382d832SPeter Avalos 		default:
21245382d832SPeter Avalos 		    /* if we got a cancel, etc., stop chaining */
21255382d832SPeter Avalos 		    if (retval != DLG_EXIT_OK)
21265382d832SPeter Avalos 			esc_pressed = TRUE;
21275382d832SPeter Avalos 		    else
21285382d832SPeter Avalos 			dialog_vars.dlg_clear_screen = TRUE;
21295382d832SPeter Avalos 		    break;
21305382d832SPeter Avalos 		}
21315382d832SPeter Avalos 	    }
21325382d832SPeter Avalos 	    if (dialog_vars.dlg_clear_screen)
21335382d832SPeter Avalos 		dlg_clear();
21345382d832SPeter Avalos 	}
21355382d832SPeter Avalos     }
21365382d832SPeter Avalos 
21375382d832SPeter Avalos     dlg_killall_bg(&retval);
21385382d832SPeter Avalos     if (dialog_state.screen_initialized) {
21395382d832SPeter Avalos 	(void) refresh();
21405382d832SPeter Avalos 	end_dialog();
21415382d832SPeter Avalos     }
21425940c9abSDaniel Fojt     handle_leaks();
21435382d832SPeter Avalos     dlg_exit(retval);
21445382d832SPeter Avalos }
2145