diff options
Diffstat (limited to 'dialog.c')
-rw-r--r-- | dialog.c | 500 |
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); } |