summaryrefslogtreecommitdiff
path: root/dialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'dialog.c')
-rw-r--r--dialog.c500
1 files changed, 352 insertions, 148 deletions
diff --git a/dialog.c b/dialog.c
index 123878534c313..bab78a8a018e0 100644
--- a/dialog.c
+++ b/dialog.c
@@ -1,9 +1,9 @@
/*
- * $Id: dialog.c,v 1.231 2013/09/02 17:20:09 tom Exp $
+ * $Id: dialog.c,v 1.268 2018/06/21 09:16:05 tom Exp $
*
* cdialog - Display simple dialog boxes from shell scripts
*
- * Copyright 2000-2012,2013 Thomas E. Dickey
+ * Copyright 2000-2017,2018 Thomas E. Dickey
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License, version 2.1
@@ -109,6 +109,8 @@ typedef enum {
,o_prgbox
,o_print_maxsize
,o_print_size
+ ,o_print_text_only
+ ,o_print_text_size
,o_print_version
,o_programbox
,o_progressbox
@@ -151,10 +153,12 @@ typedef enum {
,o_editbox
,o_fselect
,o_timebox
+ ,o_week_start
#endif
#ifdef HAVE_XDIALOG2
,o_buildlist
,o_rangebox
+ ,o_reorder
,o_treeview
#endif
#if defined(HAVE_XDIALOG2) || defined(HAVE_WHIPTAIL)
@@ -164,6 +168,7 @@ typedef enum {
#ifdef HAVE_DLG_TRACE
,o_trace
#endif
+ ,o_iso_week
} eOptions;
/*
@@ -186,13 +191,26 @@ typedef struct {
callerFn *jumper;
} Mode;
-static bool *dialog_opts;
+static int known_opts = 0;
+static const char **dialog_opts;
static char **dialog_argv;
+static char **special_argv = 0;
+static int special_argc = 0;
+
static bool ignore_unknown = FALSE;
static const char *program = "dialog";
+#ifdef NO_LEAKS
+typedef struct _all_blobs {
+ struct _all_blobs *next;
+ void *blob;
+} AllBlobs;
+
+static AllBlobs *all_blobs;
+#endif
+
/*
* The options[] table is organized this way to make it simple to maintain
* a sorted list of options for the help-message.
@@ -272,6 +290,8 @@ static const Options options[] = {
{ "prgbox", o_prgbox, 2, "<text> <command> <height> <width>" },
{ "print-maxsize", o_print_maxsize, 1, "" },
{ "print-size", o_print_size, 1, "" },
+ { "print-text-only",o_print_text_only, 5, "<text> <height> <width>" },
+ { "print-text-size",o_print_text_size, 5, "<text> <height> <width>" },
{ "print-version", o_print_version, 5, "" },
{ "programbox", o_programbox, 2, "<text> <height> <width>" },
{ "progressbox", o_progressbox, 2, "<text> <height> <width>" },
@@ -320,12 +340,15 @@ static const Options options[] = {
{ "editbox", o_editbox, 2, "<file> <height> <width>" },
{ "fselect", o_fselect, 2, "<filepath> <height> <width>" },
{ "timebox", o_timebox, 2, "<text> <height> <width> <hour> <minute> <second>" },
+ { "week-start", o_week_start, 1, "<str>" },
+ { "iso-week", o_iso_week, 1, NULL },
#endif
#ifdef HAVE_XDIALOG2
- { "buildlist", o_buildlist, 2, "<text> <height> <width> <tag1> <item1> <status1>..." },
+ { "buildlist", o_buildlist, 2, "<text> <height> <width> <list-height> <tag1> <item1> <status1>..." },
{ "no-items", o_no_items, 1, "" },
{ "no-tags", o_no_tags, 1, "" },
{ "rangebox", o_rangebox, 2, "<text> <height> <width> <min-value> <max-value> <default-value>" },
+ { "reorder", o_reorder, 1, "" },
{ "treeview", o_treeview, 2, "<text> <height> <width> <list-height> <tag1> <item1> <status1> <depth1>..." },
#endif
#if defined(HAVE_XDIALOG2) || defined(HAVE_WHIPTAIL)
@@ -338,6 +361,76 @@ static const Options options[] = {
};
/* *INDENT-ON* */
+#ifdef NO_LEAKS
+static void
+ignore_leak(void *value)
+{
+ AllBlobs *next = dlg_calloc(AllBlobs, (size_t) 1);
+ if (next != 0) {
+ next->blob = value;
+ next->next = all_blobs;
+ all_blobs = next;
+ }
+}
+
+static void
+handle_leaks(void)
+{
+ while (all_blobs != 0) {
+ char *blob = all_blobs->blob;
+ AllBlobs *next = all_blobs->next;
+ free(blob);
+ free(all_blobs);
+ all_blobs = next;
+ }
+ free(dialog_opts);
+ if (special_argv != 0) {
+ free(special_argv[0]);
+ free(special_argv);
+ special_argv = 0;
+ special_argc = 0;
+ }
+}
+#else
+#define handle_leaks() /* nothing */
+#define ignore_leak(n) /* nothing */
+#endif
+
+#define OptionChars "\
+0123456789\
+-\
+abcdefghijklmnopqrstuvwxyz\
+"
+
+/*
+ * Check if the given string from main's argv is an option.
+ */
+static bool
+isOption(const char *arg)
+{
+ bool result = FALSE;
+
+ if (arg != 0) {
+ if (dialog_opts != 0) {
+ int n;
+ for (n = 0; dialog_opts[n] != 0; ++n) {
+ if (dialog_opts[n] == arg) {
+ result = TRUE;
+ break;
+ }
+ }
+ } else if (!strncmp(arg, "--", (size_t) 2) && isalpha(UCH(arg[2]))) {
+ if (strlen(arg) == (strspn) (arg, OptionChars)) {
+ result = TRUE;
+ } else {
+ handle_leaks();
+ dlg_exiterr("Invalid option \"%s\"", arg);
+ }
+ }
+ }
+ return result;
+}
+
/*
* Make an array showing which argv[] entries are options. Use "--" as a
* special token to escape the next argument, allowing it to begin with "--".
@@ -357,27 +450,51 @@ unescape_argv(int *argcp, char ***argvp)
int j, k;
int limit_includes = 20 + *argcp;
int count_includes = 0;
- bool changed = FALSE;
bool doalloc = FALSE;
char *filename;
+ const char **my_argv = 0;
+ int my_argc;
- dialog_opts = dlg_calloc(bool, (size_t) *argcp + 1);
- assert_ptr(dialog_opts, "unescape_argv");
+ DLG_TRACE(("# unescape_argv\n"));
+ for (k = 0; k < 2; ++k) {
+
+ my_argc = 0;
+ if (special_argv != 0) {
+ for (j = 0; special_argv[j] != 0; ++j) {
+ if (!strcmp(special_argv[j], "--")) {
+ break;
+ } else if (isOption(special_argv[j])) {
+ if (k != 0)
+ my_argv[my_argc] = special_argv[j];
+ my_argc++;
+ }
+ }
+ }
+
+ if (k == 0) {
+ my_argc += (*argcp + 1);
+ my_argv = dlg_calloc(const char *, (size_t) my_argc);
+ assert_ptr(my_argv, "unescape_argv");
+ }
+ }
for (j = 1; j < *argcp; j++) {
bool escaped = FALSE;
if (!strcmp((*argvp)[j], "--")) {
escaped = TRUE;
- changed = dlg_eat_argv(argcp, argvp, j, 1);
+ dlg_eat_argv(argcp, argvp, j, 1);
} else if (!strcmp((*argvp)[j], "--args")) {
fprintf(stderr, "Showing arguments at arg%d\n", j);
for (k = 0; k < *argcp; ++k) {
fprintf(stderr, " arg%d:%s\n", k, (*argvp)[k]);
}
- changed = dlg_eat_argv(argcp, argvp, j, 1);
+ dlg_eat_argv(argcp, argvp, j, 1);
+ --j;
} else if (!strcmp((*argvp)[j], "--file")) {
- if (++count_includes > limit_includes)
+ if (++count_includes > limit_includes) {
+ handle_leaks();
dlg_exiterr("Too many --file options");
+ }
if ((filename = (*argvp)[j + 1]) != 0) {
FILE *fp;
@@ -395,6 +512,7 @@ unescape_argv(int *argcp, char ***argvp)
}
if (fp) {
+ DLG_TRACE(("# opened --file %s ..\n", filename));
blob = NULL;
length = 0;
do {
@@ -405,50 +523,71 @@ unescape_argv(int *argcp, char ***argvp)
(size_t) BUFSIZ,
fp);
length += bytes_read;
- if (ferror(fp))
+ if (ferror(fp)) {
+ handle_leaks();
dlg_exiterr("error on filehandle in unescape_argv");
+ }
} while (bytes_read == BUFSIZ);
fclose(fp);
blob[length] = '\0';
+ ignore_leak(blob);
list = dlg_string_to_argv(blob);
- if ((added = dlg_count_argv(list)) != 0) {
- if (added > 2) {
- size_t need = (size_t) (*argcp + added + 1);
- if (doalloc) {
- *argvp = dlg_realloc(char *, need, *argvp);
- assert_ptr(*argvp, "unescape_argv");
- } else {
- char **newp = dlg_malloc(char *, need);
- assert_ptr(newp, "unescape_argv");
- for (n = 0; n < *argcp; ++n) {
- newp[n] = (*argvp)[n];
- }
- *argvp = newp;
- doalloc = TRUE;
+ added = dlg_count_argv(list);
+ if (added > 2) {
+ /* *argcp arguments before the expansion of --file
+ - 2 for the removal of '--file <filepath>'
+ + added for the arguments contained in <filepath>
+ + 1 for the terminating NULL pointer */
+ size_t need = (size_t) (*argcp + added - 1);
+ if (doalloc) {
+ *argvp = dlg_realloc(char *, need, *argvp);
+ assert_ptr(*argvp, "unescape_argv");
+ } else {
+ char **newp = dlg_malloc(char *, need);
+ ignore_leak(newp);
+ assert_ptr(newp, "unescape_argv");
+ for (n = 0; n < *argcp; ++n) {
+ newp[n] = (*argvp)[n];
}
- dialog_opts = dlg_realloc(bool, need, dialog_opts);
- assert_ptr(dialog_opts, "unescape_argv");
+ /* The new array is not NULL-terminated yet. */
+ *argvp = newp;
+ doalloc = TRUE;
}
- for (n = *argcp; n >= j + 2; --n) {
+ my_argv = dlg_realloc(const char *, need, my_argv);
+ assert_ptr(my_argv, "unescape_argv");
+
+ /* Shift the arguments after '--file <filepath>'
+ right by (added - 2) positions */
+ for (n = *argcp - 1; n >= j + 2; --n) {
(*argvp)[n + added - 2] = (*argvp)[n];
- dialog_opts[n + added - 2] = dialog_opts[n];
}
- for (n = 0; n < added; ++n) {
- (*argvp)[n + j] = list[n];
- dialog_opts[n + j] = FALSE;
+ } else if (added < 2) {
+ /* 0 or 1 argument read from the included file
+ -> shift the arguments after '--file <filepath>'
+ left by (2 - added) positions */
+ for (n = j + added; n + 2 - added < *argcp; ++n) {
+ (*argvp)[n] = (*argvp)[n + 2 - added];
}
- *argcp += added - 2;
- free(list);
}
+ /* Copy the inserted arguments to *argvp */
+ for (n = 0; n < added; ++n) {
+ (*argvp)[n + j] = list[n];
+ }
+ *argcp += added - 2;
+ (*argvp)[*argcp] = 0; /* Write the NULL terminator */
+ free(list); /* No-op if 'list' is NULL */
+ /* Force rescan starting from the first inserted argument */
+ --j;
+ DLG_TRACE(("# finished --file\n"));
+ continue;
} else {
+ handle_leaks();
dlg_exiterr("Cannot open --file %s", filename);
}
- (*argvp)[*argcp] = 0;
- ++j;
- continue;
} else {
+ handle_leaks();
dlg_exiterr("No value given for --file");
}
}
@@ -456,52 +595,18 @@ unescape_argv(int *argcp, char ***argvp)
&& (*argvp)[j] != 0
&& !strncmp((*argvp)[j], "--", (size_t) 2)
&& isalpha(UCH((*argvp)[j][2]))) {
- dialog_opts[j] = TRUE;
+ my_argv[my_argc++] = (*argvp)[j];
+ DLG_TRACE(("#\toption argv[%d]=%s\n", j, (*argvp)[j]));
}
}
- /* if we didn't find any "--" tokens, there's no reason to do the table
- * lookup in isOption()
- */
- if (!changed) {
- free(dialog_opts);
- dialog_opts = 0;
- }
- dialog_argv = (*argvp);
-}
+ my_argv[my_argc] = 0;
-#define OptionChars "\
-0123456789\
--\
-abcdefghijklmnopqrstuvwxyz\
-"
+ known_opts = my_argc;
+ dialog_opts = my_argv;
-/*
- * Check if the given string from main's argv is an option.
- */
-static bool
-isOption(const char *arg)
-{
- bool result = FALSE;
-
- if (arg != 0) {
- if (dialog_opts != 0) {
- int n;
- for (n = 1; dialog_argv[n] != 0; ++n) {
- if (dialog_argv[n] == arg) {
- result = dialog_opts[n];
- break;
- }
- }
- } else if (!strncmp(arg, "--", (size_t) 2) && isalpha(UCH(arg[2]))) {
- if (strlen(arg) == strspn(arg, OptionChars)) {
- result = TRUE;
- } else {
- dlg_exiterr("Invalid option \"%s\"", arg);
- }
- }
- }
- return result;
+ DLG_TRACE(("#\t%d options vs %d arguments\n", known_opts, *argcp));
+ dialog_argv = (*argvp);
}
static eOptions
@@ -526,6 +631,7 @@ lookupOption(const char *name, int pass)
static void
Usage(const char *msg)
{
+ handle_leaks();
dlg_exiterr("Error: %s.\nUse --help to list options.\n\n", msg);
}
@@ -553,19 +659,23 @@ howmany_tags(char *argv[], int group)
{
int result = 0;
int have;
- const char *format = "Expected %d arguments, found only %d";
char temp[80];
while (argv[0] != 0) {
if (isOption(argv[0]))
break;
if ((have = arg_rest(argv)) < group) {
+ const char *format = _("Expected %d arguments, found only %d");
sprintf(temp, format, group, have);
Usage(temp);
+ } else if ((have % group) != 0) {
+ const char *format = _("Expected %d arguments, found extra %d");
+ sprintf(temp, format, group, (have % group));
+ Usage(temp);
}
- argv += group;
- result++;
+ argv += have;
+ result += (have / group);
}
return result;
@@ -634,6 +744,7 @@ show_result(int ret)
if (dialog_vars.input_result != 0
&& dialog_vars.input_result[0] != '\0') {
fputs(dialog_vars.input_result, dialog_state.output);
+ DLG_TRACE(("# input_result:\n%s\n", dialog_vars.input_result));
either = TRUE;
}
if (either) {
@@ -872,7 +983,7 @@ call_buildlist(CALLARGS)
numeric_arg(av, 3),
numeric_arg(av, 4),
tags, av + 5,
- TRUE);
+ dialog_vars.reorder);
RestoreNoTags();
return result;
}
@@ -1099,10 +1210,10 @@ static const Mode modes[] =
{o_msgbox, 4, 4, call_msgbox},
{o_infobox, 4, 4, call_infobox},
{o_textbox, 4, 4, call_textbox},
- {o_menu, 7, 0, call_menu},
- {o_inputmenu, 7, 0, call_inputmenu},
- {o_checklist, 8, 0, call_checklist},
- {o_radiolist, 8, 0, call_radiolist},
+ {o_menu, 6, 0, call_menu},
+ {o_inputmenu, 6, 0, call_inputmenu},
+ {o_checklist, 7, 0, call_checklist},
+ {o_radiolist, 7, 0, call_radiolist},
{o_inputbox, 4, 5, call_inputbox},
{o_passwordbox, 4, 5, call_passwordbox},
#ifdef HAVE_DLG_GAUGE
@@ -1127,13 +1238,15 @@ static const Mode modes[] =
{o_tailboxbg, 4, 4, call_tailboxbg},
#endif
#ifdef HAVE_XDIALOG
- {o_buildlist, 4, 0, call_buildlist},
{o_calendar, 4, 7, call_calendar},
{o_dselect, 4, 5, call_dselect},
{o_editbox, 4, 4, call_editbox},
{o_fselect, 4, 5, call_fselect},
- {o_rangebox, 5, 7, call_rangebox},
{o_timebox, 4, 7, call_timebox},
+#endif
+#ifdef HAVE_XDIALOG2
+ {o_buildlist, 4, 0, call_buildlist},
+ {o_rangebox, 5, 7, call_rangebox},
{o_treeview, 4, 0, call_treeview},
#endif
};
@@ -1214,6 +1327,64 @@ button_code(const char *name)
}
/*
+ * If this is the last option, we do not want any error messages - just our
+ * output. Calling end_dialog() cancels the refresh() at the end of the
+ * program as well.
+ */
+static void
+IgnoreNonScreen(char **argv, int offset)
+{
+ if (argv[offset + 1] == 0) {
+ ignore_unknown = TRUE;
+ end_dialog();
+ }
+}
+
+static void
+PrintTextOnly(char **argv, int *offset, eOptions code)
+{
+ /* TODO - handle two optional numeric params */
+ char *text;
+ int height = 0;
+ int width = 0;
+ int height2 = 0;
+ int width2 = 0;
+ int next = arg_rest(argv + *offset);
+
+ if (LINES <= 0 && COLS <= 0)
+ dlg_ttysize(fileno(dialog_state.input), &LINES, &COLS);
+
+ text = strdup(optionString(argv, offset));
+ IgnoreNonScreen(argv, *offset);
+
+ if (next >= 1) {
+ next = MIN(next, 3);
+ height = numeric_arg(argv, *offset + 1);
+ if (next >= 2)
+ width = numeric_arg(argv, *offset + 2);
+ *offset += next - 1;
+ }
+
+ dlg_trim_string(text);
+ dlg_auto_size(NULL, text, &height2, &width2, height, width);
+
+ switch (code) {
+ case o_print_text_only:
+ dialog_state.text_only = TRUE;
+ dlg_print_autowrap(stdscr, text, height2, width2);
+ dialog_state.text_only = FALSE;
+ break;
+ case o_print_text_size:
+ fprintf(dialog_state.output, "%d %d\n",
+ dialog_state.text_height,
+ dialog_state.text_width);
+ break;
+ default:
+ break;
+ }
+}
+
+/*
* Print parts of a message
*/
static void
@@ -1276,7 +1447,7 @@ Help(void)
static const char *const tbl_1[] =
{
"cdialog (ComeOn Dialog!) version %s",
- "Copyright 2000-2012,2013 Thomas E. Dickey",
+ "Copyright 2000-2017,2018 Thomas E. Dickey",
"This is free software; see the source for copying conditions. There is NO",
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.",
"",
@@ -1330,13 +1501,15 @@ Help(void)
for (j = 0; j < limit; j++) {
if ((opts[j]->pass & 2) != 0
&& opts[j]->help != 0
- && lookupMode(opts[j]->code))
+ && lookupMode(opts[j]->code)) {
fprintf(dialog_state.output, " --%-12s %s\n", opts[j]->name,
opts[j]->help);
+ }
}
PrintList(tbl_3);
free(opts);
+ handle_leaks();
dlg_exit(DLG_EXIT_OK);
}
@@ -1355,13 +1528,13 @@ process_trace_option(char **argv, int *offset)
if (dialog_state.trace_output == 0) {
dlg_trace(optionString(argv, offset));
} else {
- dlg_trace_msg("# ignore extra --trace option\n");
+ DLG_TRACE(("# ignore extra --trace option\n"));
*offset += 1;
}
- dlg_trace_msg("# Parameters:\n");
+ DLG_TRACE(("# Parameters:\n"));
for (j = 0; argv[j] != 0; ++j) {
- dlg_trace_msg("# argv[%d] = %s\n", j, argv[j]);
+ DLG_TRACE(("#\targv[%d] = %s\n", j, argv[j]));
}
}
#endif
@@ -1375,12 +1548,13 @@ static int
process_common_options(int argc, char **argv, int offset, bool output)
{
bool done = FALSE;
+ eOptions code;
- dlg_trace_msg("# process_common_options, offset %d\n", offset);
+ DLG_TRACE(("# process_common_options, offset %d\n", offset));
while (offset < argc && !done) { /* Common options */
- dlg_trace_msg("#\targv[%d] = %s\n", offset, argv[offset]);
- switch (lookupOption(argv[offset], 1)) {
+ DLG_TRACE(("#\targv[%d] = %s\n", offset, argv[offset]));
+ switch (code = lookupOption(argv[offset], 1)) {
case o_title:
dialog_vars.title = optionString(argv, &offset);
break;
@@ -1485,17 +1659,13 @@ process_common_options(int argc, char **argv, int offset, bool output)
case o_print_size:
dialog_vars.print_siz = TRUE;
break;
+ case o_print_text_only:
+ case o_print_text_size:
+ PrintTextOnly(argv, &offset, code);
+ break;
case o_print_maxsize:
if (output) {
- /*
- * If this is the last option, we do not want any error
- * messages - just our output. Calling end_dialog() cancels
- * the refresh() at the end of the program as well.
- */
- if (argv[offset + 1] == 0) {
- ignore_unknown = TRUE;
- end_dialog();
- }
+ IgnoreNonScreen(argv, offset);
fflush(dialog_state.output);
fprintf(dialog_state.output, "MaxSize: %d, %d\n", SLINES, SCOLS);
}
@@ -1632,10 +1802,31 @@ process_common_options(int argc, char **argv, int offset, bool output)
dialog_vars.no_tags = TRUE;
break;
#endif
+#ifdef HAVE_XDIALOG2
+ case o_reorder:
+ dialog_vars.reorder = TRUE;
+ break;
+#endif
+#ifdef HAVE_XDIALOG
+ case o_week_start:
+ dialog_vars.week_start = optionString(argv, &offset);
+ break;
+#endif
+ case o_iso_week:
+ dialog_vars.iso_week = TRUE;
+ if (dialog_vars.week_start == 0) { /* Monday is implied */
+ static char default_1st[] = "1";
+ dialog_vars.week_start = default_1st;
+ }
+ break;
}
if (!done)
offset++;
}
+
+ if (dialog_state.aspect_ratio == 0)
+ dialog_state.aspect_ratio = DEFAULT_ASPECT_RATIO;
+
return offset;
}
@@ -1647,10 +1838,8 @@ static void
init_result(char *buffer)
{
static bool first = TRUE;
- static char **special_argv = 0;
- static int special_argc = 0;
- dlg_trace_msg("# init_result\n");
+ DLG_TRACE(("# init_result\n"));
/* clear everything we do not save for the next widget */
memset(&dialog_vars, 0, sizeof(dialog_vars));
@@ -1675,19 +1864,8 @@ init_result(char *buffer)
first = FALSE;
}
- /*
- * If we are not checking memory leaks, just do the parse of the
- * environment once.
- */
if (special_argv != 0) {
process_common_options(special_argc, special_argv, 0, FALSE);
-#ifdef NO_LEAKS
- free(special_argv[0]);
- free(special_argv);
- special_argv = 0;
- special_argc = 0;
- first = TRUE;
-#endif
}
}
@@ -1697,6 +1875,7 @@ main(int argc, char *argv[])
char temp[256];
bool esc_pressed = FALSE;
bool keep_tite = FALSE;
+ bool first_time = TRUE;
int offset = 1;
int offset_add;
int retval = DLG_EXIT_OK;
@@ -1717,6 +1896,7 @@ main(int argc, char *argv[])
(void) setlocale(LC_ALL, "");
#endif
+ init_result(my_buffer); /* honor $DIALOGOPTS */
unescape_argv(&argc, &argv);
program = argv[0];
dialog_state.output = stderr;
@@ -1742,13 +1922,17 @@ main(int argc, char *argv[])
break;
case o_input_fd:
if ((j = optionValue(argv, &offset)) < 0
- || (dialog_state.input = fdopen(j, "r")) == 0)
+ || (dialog_state.input = fdopen(j, "r")) == 0) {
+ handle_leaks();
dlg_exiterr("Cannot open input-fd\n");
+ }
break;
case o_output_fd:
if ((j = optionValue(argv, &offset)) < 0
- || (dialog_state.output = fdopen(j, "w")) == 0)
+ || (dialog_state.output = fdopen(j, "w")) == 0) {
+ handle_leaks();
dlg_exiterr("Cannot open output-fd\n");
+ }
break;
case o_keep_tite:
keep_tite = TRUE;
@@ -1756,7 +1940,7 @@ main(int argc, char *argv[])
case o_version:
dialog_state.output = stdout;
PrintVersion(dialog_state.output);
- exit(DLG_EXIT_OK);
+ dlg_exit(DLG_EXIT_OK);
break;
case o_help:
Help();
@@ -1780,26 +1964,25 @@ main(int argc, char *argv[])
++offset;
continue;
}
- dlg_trace_msg("# discarding %d parameters starting with argv[%d] (%s)\n",
- 1 + offset - base, base,
- argv[base]);
+ DLG_TRACE(("# discarding %d parameters starting with argv[%d] (%s)\n",
+ 1 + offset - base, base,
+ argv[base]));
for (j = base; j < argc; ++j) {
dialog_argv[j] = dialog_argv[j + 1 + (offset - base)];
- if (dialog_opts != 0)
- dialog_opts[j] = dialog_opts[j + 1 + (offset - base)];
}
argc -= (1 + offset - base);
offset = base;
}
offset = 1;
init_result(my_buffer);
+ dialog_vars.keep_tite = keep_tite; /* init_result() cleared global */
/*
* Dialog's output may be redirected (see above). Handle the special
* case of options that only report information without interaction.
*/
if (argc == 2) {
- switch (lookupOption(argv[1], 7)) {
+ switch (code = lookupOption(argv[1], 7)) {
case o_print_maxsize:
(void) initscr();
endwin();
@@ -1820,33 +2003,44 @@ main(int argc, char *argv[])
Help();
break;
}
- return DLG_EXIT_OK;
- }
-
- if (argc < 2) {
+ dlg_exit(DLG_EXIT_OK);
+ } else if (argc < 2) {
Help();
}
#ifdef HAVE_RC_FILE
- if (lookupOption(argv[1], 7) == o_create_rc) {
+ else if (lookupOption(argv[1], 7) == o_create_rc) {
if (argc != 3) {
sprintf(temp, "Expected a filename for %.50s", argv[1]);
Usage(temp);
}
- if (dlg_parse_rc() == -1) /* Read the configuration file */
+ if (dlg_parse_rc() == -1) { /* Read the configuration file */
+ handle_leaks();
dlg_exiterr("dialog: dlg_parse_rc");
+ }
dlg_create_rc(argv[2]);
- return DLG_EXIT_OK;
+ dlg_exit(DLG_EXIT_OK);
}
#endif
-
- dialog_vars.keep_tite = keep_tite; /* init_result() cleared global */
+ else {
+ /*
+ * Handle combinations of common options including --print-text-only
+ * which can be done before involving curses, in case we can exit
+ * without initializing curses (and writing to the terminal).
+ */
+ offset = process_common_options(argc, argv, offset, TRUE);
+ if (offset >= argc)
+ dlg_exit(DLG_EXIT_OK);
+ }
init_dialog(dialog_state.input, dialog_state.output);
while (offset < argc && !esc_pressed) {
- init_result(my_buffer);
-
- offset = process_common_options(argc, argv, offset, TRUE);
+ if (first_time) {
+ first_time = FALSE;
+ } else {
+ init_result(my_buffer);
+ offset = process_common_options(argc, argv, offset, TRUE);
+ }
if (argv[offset] == NULL) {
if (ignore_unknown)
@@ -1854,15 +2048,22 @@ main(int argc, char *argv[])
Usage("Expected a box option");
}
- if (lookupOption(argv[offset], 2) != o_checklist
- && dialog_vars.separate_output) {
- sprintf(temp, "Expected --checklist, not %.20s", argv[offset]);
- Usage(temp);
+ if (dialog_vars.separate_output) {
+ switch (lookupOption(argv[offset], 2)) {
+#ifdef HAVE_XDIALOG2
+ case o_buildlist:
+ case o_treeview:
+#endif
+ case o_checklist:
+ break;
+ default:
+ sprintf(temp,
+ "Unexpected widget with --separate-output %.20s",
+ argv[offset]);
+ Usage(temp);
+ }
}
- if (dialog_state.aspect_ratio == 0)
- dialog_state.aspect_ratio = DEFAULT_ASPECT_RATIO;
-
dlg_put_backtitle();
/* use a table to look for the requested mode, to avoid code duplication */
@@ -1917,15 +2118,17 @@ main(int argc, char *argv[])
} else {
argv[j] = strdup("?");
}
+ ignore_leak(argv[j]);
}
break;
}
}
+ DLG_TRACE(("# execute %s\n", argv[offset]));
retval = show_result((*(modePtr->jumper)) (dialog_vars.title,
argv + offset,
&offset_add));
- dlg_trace_msg("# widget returns %d\n", retval);
+ DLG_TRACE(("# widget returns %d\n", retval));
offset += offset_add;
if (dialog_vars.input_result != my_buffer) {
@@ -1972,5 +2175,6 @@ main(int argc, char *argv[])
(void) refresh();
end_dialog();
}
+ handle_leaks();
dlg_exit(retval);
}