aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfonso S. Siciliano <asiciliano@FreeBSD.org>2022-09-25 13:04:33 +0000
committerAlfonso S. Siciliano <asiciliano@FreeBSD.org>2022-09-25 13:04:33 +0000
commit9f24fda5a8e7ab8243e71473c7e2dc98b4877e64 (patch)
treecf0c83c2ef1a564eb8bd492fde38c52a9fcdfca0
parent2c9fd7655ba54e7239f528e1af9fe09662de9b03 (diff)
downloadsrc-vendor/bsddialog.tar.gz
src-vendor/bsddialog.zip
contrib/bsddialog: Import version 0.4vendor/bsddialog/0.4vendor/bsddialog
Improvements and changes to integrate bsddialog(1) with scripts in BASE. Overview: * New options. --and-widget, --keep-tite, --calendar. * Change output format. Menus and --print-maxsize. * Redefine sizing. Fixed rows, cols and menurows became at the most. * Add DIAGNOSTICS. Error messages for bad arguments and options. * Add keys. Space for --menu, fast keys for --msgbox and --yesno. * Text. Change default text modification, add --cr-wrap. See /usr/src/contrib/bsddialog/CHANGELOG '2022-09-24 Version 0.4' for more detailed information.
-rw-r--r--.gitignore27
-rw-r--r--CHANGELOG70
-rw-r--r--GNUMakefile4
-rw-r--r--Makefile4
-rw-r--r--README.md26
-rw-r--r--bsddialog.1170
-rw-r--r--bsddialog.c1353
-rw-r--r--examples_library/calendar.c55
-rwxr-xr-xexamples_library/compile2
-rw-r--r--examples_library/form.c4
-rw-r--r--examples_utility/calendar.sh34
-rwxr-xr-xexamples_utility/timebox.sh3
-rw-r--r--lib/GNUMakefile10
-rw-r--r--lib/Makefile6
-rw-r--r--lib/barbox.c2
-rw-r--r--lib/bsddialog.333
-rw-r--r--lib/bsddialog.h10
-rw-r--r--lib/calendarbox.c520
-rw-r--r--lib/formbox.c29
-rw-r--r--lib/lib_util.c14
-rw-r--r--lib/lib_util.h3
-rw-r--r--lib/libbsddialog.c4
-rw-r--r--lib/menubox.c50
-rw-r--r--lib/messagebox.c42
-rw-r--r--lib/theme.c1
-rw-r--r--lib/timebox.c20
-rw-r--r--util_theme.c79
-rw-r--r--util_theme.h7
28 files changed, 1735 insertions, 847 deletions
diff --git a/.gitignore b/.gitignore
index 10a6663fbb47..8b8ec9d4ae0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,29 +1,24 @@
bsddialog
+.depend*
*.o
-*~
+*.so*
*.a
-examples_library/buildlist
+*.gz
+*.core
+*~
+BSDDIALOG.geany
+BSDDIALOG.tags
+examples_library/calendar
examples_library/checklist
examples_library/datebox
examples_library/form
-examples_library/formw
-examples_library/margin
+examples_library/infobox
examples_library/menu
examples_library/mixedlist
-examples_library/radiolist
-examples_library/theme
-examples_library/treeview
-examples_library/infobox
examples_library/msgbox
examples_library/pause
+examples_library/radiolist
examples_library/rangebox
-examples_library/sade
+examples_library/theme
examples_library/timebox
examples_library/yesno
-examples_library/u_msgbox
-*.gz
-lib/libbsddialog.so*
-BSDDIALOG.geany
-BSDDIALOG.tags
-*.core
-freebsd-lab/
diff --git a/CHANGELOG b/CHANGELOG
index d6de6928c111..883fe1016d01 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,17 +1,68 @@
+2022-09-24 Version 0.4
+
+ Utility:
+ * add: --normal-screen to set normal mode.
+ * add: --alternate-screen to set alternate mode.
+ * add: --keep-tite as --alternate-screen alias.
+ * add: --and-dialog to build other dialogs.
+ * add: --and-widget as --and-dialog alias.
+ * add: --no-names (--no-tags becames its alias).
+ * add: --no-descriptions (--no-items becames its alias).
+ * add: --help-print-name (--help-tags becames its alias).
+ * add: --item-bottom-desc (--item-help becames its alias).
+ * add: --cr-wrap (was partially implemented) to keep '\n' with "\n".
+ * add: --text-unchanged to avoid default modification.
+ * add: --tab-escape enables "\t" in text.
+ * add: --clear-screen to clear the screen.
+ * add: --clear-dialog to clear the dialog (was --clear).
+ * add: --calendar dialog to select a date.
+ * add: DIAGNOSTICS messages for bad arguments number.
+ * add: DIAGNOSTICS messages for missing and unexpected options.
+ * change: --clear becames alias for --clear-screen.
+ * change: --print-maxsize format output.
+ * change: --menu, --radiolist, --checklist and --treeview output.
+ - no printed items with Cancel or ESC.
+ - --separator prints <sepstr> before each item except HELP.
+ - --separator and --separate-output print <sepstr> after each item.
+ - quoted item name/desc only when needed.
+ - --menu avoids to print selected item after focused HELP item.
+ * change: text default modification.
+ - without a "\n": '\t' -> space, '\n' -> '\n', trim spaces.
+ - with a "\n": '\t' -> space, '\n' -> space, "\n" -> '\n', no trim.
+ - delete '\n' after "\n" (also with --cr-wrap).
+ * change: --datebox input and output format yy/mm/dd -> dd/mm/yy.
+ * delete: --no-collapse (partially implemented).
+ * delete: --no-nl-expand (partially implemented).
+ * delete: --trim (partially implemented).
+
+ Library:
+ * add: bsddialog_msgbox() HOME, END, PPAGE and NPAGE keys.
+ * add: bsddialog_yesno() HOME, END, PPAGE and NPAGE keys.
+ * add: bsddialog_menu() SPACE key (equivalent to ENTER).
+ * add: bsddialog_calendar() to select a date.
+ * change: rename enum bsddialog_grouptype -> enum bsddialog_menutype.
+ * change: fixed-menurows becames at most menurows (depending on text).
+ * change: fixed-rows becames at most rows, min(rows, screenH - shadow).
+ * change: fixed-cols becames at most cols, min(cols, screenW - shadow).
+ * delete: undocumented internal bsddialog_menuitem.depth factor (was 2).
+
+
2022-08-29 Version 0.3
Utility:
* add: --textbox accepts options for the first button.
- * add: --columns-per-row option for text autosizing.
- * add: --load-theme option to read and set a custom theme at runtime.
- * add: --save-theme option to save current theme.
- * add: --bikeshed option for random settings.
+ * add: --columns-per-row for text autosizing.
+ * add: --load-theme to read and set a custom theme at runtime.
+ * add: --save-theme to save current theme.
+ * add: --bikeshed for random settings.
* add: --switch-buttons enables focus switching: buttons / input
components. Available for: --form, --inputbox, --mixedform,
--passwordform, --passwordbox, --timebox and --datebox.
* change: rename --esc-cancelvalue to --esc-return-cancel.
* change: form field value is printed like multibyte charachter string,
previously widechar string.
+ * change: --timebox output with zero padding.
+ * change: --datebox output mm and dd with zero padding.
* fix: --hline with empty string.
* fix: avoid to overlay the backtitle by setting a top margin.
* fix: avoid to overlay down shadow with menus and forms bottomdesc
@@ -25,8 +76,8 @@
* add: conf.text.cols_per_row to set a ratio for text autosizing.
* add: timebox and datebox arrows and focus background for boxes.
* add: timebox and datebox UP key to switch focus.
- * add: bsddialog_init_notheme() in bsddialo_theme.h.
- * add: bsddialog_hascolors() in bsddialo_theme.h.
+ * add: bsddialog_init_notheme() in bsddialog.h.
+ * add: bsddialog_hascolors() in bsddialog_theme.h.
* add: theme.form.bottomdesccolor and theme.menu.bottomdesccolor.
* add: conf.button.always_active to disable buttons/input-boxes switch.
* add: dynamic buttons margin.
@@ -60,8 +111,8 @@
- add: formheight autosizing.
- add: dynamic item position.
* fix: bsddialog_gauge() with fd < 0.
- * fix: internal segmentation fault with disabled shadow.
* fix: bsddialog_gauge() refresh new text.
+ * fix: internal segmentation fault with disabled shadow.
* fix: center position without shadow.
* fix: bsddialog_infobox() with zero text length.
* fix: text wrapping with more than 1024 words.
@@ -92,7 +143,7 @@
* change: theme.button.[left|right]ch -> theme.button.[left|right]delim.
* change: theme.button.space -> theme.button.hmargin.
* change: theme.menu.arrowcolor -> theme.dialog.arrowcolor.
- * change: default menu item depth 4 -> 2.
+ * change: internal bsddialog_menuitem.depth factor 4 -> 2.
* fix: disable HOME, PPAGE, END and NPAGE keys in bsddialog_form().
* fix: visible cursor for timebox.c and form.c in VM VirtualBox.
* fix: mixedlist, center position of separator with big pad.
@@ -106,7 +157,7 @@
2022-01-27 Version 0.1
- * Common-Options: --ascii-lines, --backtitle <backtitle>, --begin-x <x>,
+ * Options: --ascii-lines, --backtitle <backtitle>, --begin-x <x>,
--begin-y <y>, --cancel-label <label>, --clear, --colors, --cr-wrap,
--date-format <format>, --defaultno, --default-button <label>,
--default-no, --default-item <name>, --disable-esc,
@@ -131,4 +182,3 @@
--passwordbox, --passwordform, --pause, --radiolist, --rangebox,
--textbox, --timebox, --treeview, --yesno.
* Manuals: bsddialog.1, bsddialog.3.
-
diff --git a/GNUMakefile b/GNUMakefile
index d57c6248d02d..7da4d64deecf 100644
--- a/GNUMakefile
+++ b/GNUMakefile
@@ -8,8 +8,8 @@ SOURCES= bsddialog.c util_theme.c
OBJECTS= $(SOURCES:.c=.o)
LIBPATH= ./lib
LIBBSDDIALOG= $(LIBPATH)/libbsddialog.so
-CFLAGS= -Wall -Wextra -Wno-unused-parameter -I$(LIBPATH)
-LDFLAGS= -Wl,-rpath=$(LIBPATH) -L$(LIBPATH) -lbsddialog
+CFLAGS= -Wall -Wextra -I$(LIBPATH)
+LDFLAGS= -ltinfo -Wl,-rpath=$(LIBPATH) -L$(LIBPATH) -lbsddialog
RM = rm -f
all : $(OUTPUT)
diff --git a/Makefile b/Makefile
index 344233581d30..28162c5e90b3 100644
--- a/Makefile
+++ b/Makefile
@@ -9,13 +9,13 @@ OBJECTS= ${SOURCES:.c=.o}
LIBPATH= ${.CURDIR}/lib
LIBBSDDIALOG= ${LIBPATH}/libbsddialog.so
-CFLAGS+= -I${LIBPATH} -std=gnu99 -Wall -Wextra -Werror -Wno-unused-parameter
+CFLAGS+= -I${LIBPATH} -std=gnu99 -Wall -Wextra -Werror
# `make -DDEBUG`
.if defined(DEBUG)
CFLAGS= -g -Wall -I${LIBPATH}
LIBDEBUG= -DDEBUG
.endif
-LDFLAGS+= -Wl,-rpath=${LIBPATH} -L${LIBPATH} -lbsddialog
+LDFLAGS+= -ltinfow -Wl,-rpath=${LIBPATH} -L${LIBPATH} -lbsddialog
BINDIR= /usr/local/bin
MAN= ${OUTPUT}.1
diff --git a/README.md b/README.md
index 016995b232ae..59af7072e7f5 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,8 @@
-# BSDDialog 0.3
+# BSDDialog 0.4
This project provides **bsddialog** and **libbsddialog**, an utility
and a library to build scripts and tools with TUI dialogs and widgets.
-
-
-## Intro
-
-Briefly:
-<https://www.freebsd.org/status/report-2021-04-2021-06/bsddialog/>
-
-Utility:
-<https://alfonsosiciliano.gitlab.io/posts/2021-12-07-bsddialog.html>
-
-Library:
-<https://alfonsosiciliano.gitlab.io/posts/2022-01-16-libbsddialog.html>
-
-Screenshots:
-<https://www.flickr.com/photos/alfonsosiciliano/albums/72157720215006074>
+[Screenshots](https://www.flickr.com/photos/alfonsosiciliano/albums/72157720215006074).
## Getting Started
@@ -48,9 +34,9 @@ Output:
**Dialogs:**
---checklist, --datebox, --form, --gauge, --inputbox, --menu, --mixedform,
---mixedgauge, --msgbox, --passwordbox, --passwordform, --pause, --radiolist,
---rangebox, --textbox, --timebox, --treeview, --yesno.
+--calendar, --checklist, --datebox, --form, --gauge, --infobox, --inputbox,
+--menu, --mixedform, --mixedgauge, --msgbox, --passwordbox, --passwordform,
+--pause, --radiolist, --rangebox, --textbox, --timebox, --treeview, --yesno.
**Manual**
@@ -72,6 +58,7 @@ Output:
and [Examples](https://gitlab.com/alfix/bsddialog/-/tree/main/examples_utility)
in the _Public Domain_ to build new projects:
```
+% sh ./examples_utility/calendar.sh
% sh ./examples_utility/checklist.sh
% sh ./examples_utility/form.sh
% sh ./examples_utility/gauge.sh
@@ -109,6 +96,7 @@ in the _Public Domain_ to build new projects:
```
% cd examples_library
% sh compile
+% ./calendar
% ./checklist
% ./datebox
% ./form
diff --git a/bsddialog.1 b/bsddialog.1
index 0bf8dd9dc3af..759fe6dc3fff 100644
--- a/bsddialog.1
+++ b/bsddialog.1
@@ -1,4 +1,5 @@
.\"
+.\"
.\" Copyright (c) 2021-2022 Alfonso Sabato Siciliano
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -22,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 29, 2022
+.Dd September 23, 2022
.Dt BSDDIALOG 1
.Os
.Sh NAME
@@ -34,12 +35,19 @@
.Nm
.Fl Fl version
.Nm
-.Op Fl Fl common-option
+.Op Fl Fl option
.Fl Fl dialog
.Ar text
.Ar rows
.Ar cols
-.Op Ar dialog-parameter
+.Op Ar dialog-argument
+.Nm
+.Fl Fl dialog1
+.Ar ...
+.Oo Fl Fl and-dialog
+.Fl Fl dialog2
+.Ar ...
+.Oc ...
.Sh DESCRIPTION
The
.Nm bsddialog
@@ -51,21 +59,24 @@ The options
and
.Fl Fl version
print the list of options and the version, respectively, then exit.
+.Fl Fl and-dialog
+builds another dialog unless the previous one returns Error, ESC or Cancel.
.Pp
-The following options are available for each dialog.
.Ar text
-is a message printed inside the dialog, except for
-.Fl Fl textbox
-described later.
+is a message printed inside the dialog.
.Ar rows
and
.Ar cols
are the height and width, 0 for autosize and -1 for fullscreen.
+.Pp
The possible input got from the user interface is printed to standard error.
-.Ss Common options
+.Ss Options
The following options can change the default behavior of the utility and are
common to some dialog.
.Bl -tag -width Ds
+.It Fl Fl alternate-screen
+If available set alternate screen mode, see
+.Xr terminfo 5 .
.It Fl Fl ascii-lines
Ascii characters to draw lines.
.It Fl Fl backtitle Ar backtitle
@@ -85,8 +96,10 @@ Zero padding with time or date output.
Label for the
.Dq Cancel
button.
-.It Fl Fl clear
+.It Fl Fl clear-dialog
Hide the dialog at exit.
+.It Fl Fl clear-screen
+Clear the screen, after the dialog exit if a dialog is built.
.It Fl Fl colors
Enable highlights for text, the following sequences are considered escapes:
.Bl -column -compact
@@ -125,13 +138,19 @@ restore normal text.
Try to set the number of columns for a row of text with autosizing; default
.Dv 10 .
.It Fl Fl cr-wrap
-Replace new line with a space in
-.Ar text .
+Keep new line in
+.Ar text
+also if it constains a
+.Dq \en ,
+see
+.Fl Fl text-unchanged .
.It Fl Fl date-format Ar format
String accepted by
.Xr strftime 3
to customize the output of
-.Fl Fl datebox .
+.Fl Fl datebox
+and
+.Fl Fl calendar
.It Fl Fl default-button Ar label
Focus on the button with
.Ar label
@@ -146,18 +165,12 @@ Focus on
or
.Dq \&No
button on startup.
-.It Fl Fl defaultno
-Equivalent to
-.Fl Fl default-no .
.It Fl Fl disable-esc
Disable ESC key to quit.
.It Fl Fl esc-return-cancel
-Exits with the
+ESC key returns
.Dq Cancel
-button value if the ESC key is pressed.
-.It Fl Fl exit-label Ar label
-Equivalent to
-.Fl Fl ok-label .
+button value.
.It Fl Fl extra-button
Add a button with
.Dq Extra
@@ -184,14 +197,14 @@ Set
for
.Dq Help
button.
+.It Fl Fl help-print-name
+Print the name of the focused item if the Help button is pressed also
+with
+.Fl Fl item-bottom-desc .
.It Fl Fl help-status
Print also the selected items if the
.Dq Help
button is pressed.
-.It Fl Fl help-tags
-Print the name of the focused item if the Help button is pressed also
-with
-.Fl Fl item-help .
.It Fl Fl hfile Ar filename
Open
.Ar filename
@@ -208,11 +221,11 @@ Do not exit with unknown options.
Print
.Sq *
to hide passwords while typing; whitespace otherwise.
+.It Fl Fl item-bottom-desc
+Set a help string for each item of a Checklist, Form, Menu, Mixedform,
+Passwordform, Radiolist and Treeview to display at the bottom screen side.
.It Fl Fl item-depth
Specify a margin for items, available for Checklist, Menu and Radiolist.
-.It Fl Fl item-help
-Set a help string for each element of a Checklist, Form, Menu, Mixedform,
-Passwordform, Radiolist and Treeview to display at the bottom screen side.
.It Fl Fl item-prefix
Set a string to prefix each item of a Checklist, Menu, Radiolist or Treeview.
.It Fl Fl load-theme Ar file
@@ -228,59 +241,46 @@ default 2048.
Do not show
.Dq Cancel
button.
-.It Fl Fl no-collapse
-Do not replace a TAB character with a space in
-.Ar text .
-.It Fl Fl no-items
+.It Fl Fl no-descriptions
Do not display items desciption, for Checklist, Menu, Radiolist or Treeview.
-.It Fl Fl no-label Ar label
-Equivalent to
-.Fl Fl cancel-label .
.It Fl Fl no-lines
Do not draw borders and lines.
-.It Fl Fl no-nl-expand
-do not consider the sequence
-.Dq \en
-like new line.
+.It Fl Fl no-names
+Do not display items name, for Checklist, Menu and Radiolist.
.It Fl Fl no-ok
Do not draw
.Dq OK
button.
.It Fl Fl no-shadow
No not draw the shadow of the dialog.
-.It Fl Fl no-tags
-Do not display items name, for Checklist, Menu and Radiolist.
-.It Fl Fl nocancel
-Equivalent to
-.Fl Fl no-cancel .
-.It Fl Fl nook
-Equivalent to
-.Fl Fl no-ok .
.It Fl Fl ok-label Ar label
Set
.Ar label
for
.Dq OK
button.
+.It Fl Fl normal-screen
+If available set normal screen mode, see
+.Xr terminfo 5 .
.It Fl Fl output-fd Ar fd
Print input from user interface to the specified file descriptor.
.It Fl Fl output-separator Ar sep
Set a sepator for the items in output, default whitespace.
.It Fl Fl print-maxsize
Screen size.
+This option can be used without a dialog.
.It Fl Fl print-size
Print Dialog height and widget at exit.
.It Fl Fl print-version
Print version.
+This option can be used without a dialog.
.It Fl Fl quoted
Quote items in output, default only when necessary.
.It Fl Fl save-theme Ar file
Save the current theme.
+This option can be used without a dialog.
.It Fl Fl separate-output
Separate selected items with a new line and avoid to quote.
-.It Fl Fl separator Ar sep
-Equivalent to
-.Fl Fl output-separator .
.It Fl Fl shadow
Show a pseudo shadow for the dialog, enabled by default.
.It Fl Fl single-quoted
@@ -302,12 +302,29 @@ Suitable for:
.Fl Fl mixedform ,
.Fl Fl passwordbox ,
.Fl Fl passwordform ,
-.Fl Fl timebox
+.Fl Fl timebox ,
+.Fl Fl calendar
and
.Fl Fl datebox .
+.It Fl Fl tab-escape
+Replace
+.Dq \et
+with a tab in
+.Ar text .
.It Fl Fl tab-len Ar spaces
Number of spaces to print a TAB in
.Ar text .
+.It Fl Fl text-unchanged
+By default the
+.Ar text
+is changed before to be printed.
+If it contains at least a
+.Dq \en
+each new line and TAB is converted to a space, subsequent spaces are merged.
+Otherwise new line characters are preserved and a TAB becomes a space.
+This option disable the
+.Ar text
+modification.
.It Fl Fl theme Ar theme
Set a graphical style: blackwhite, bsddialog, flat or dialog.
.It Fl Fl time-format Ar format
@@ -317,16 +334,12 @@ to customize the output of
.Fl Fl timebox .
.It Fl Fl title Ar title
Dialog title.
-.It Fl Fl trim
-remove consecutive spaces in
-.Ar text .
-.It Fl Fl yes-label Ar label
-Equivalent to
-.Fl Fl ok-label .
.El
.Ss Dialogs
The following dialogs are available:
.Bl -tag -width Ds
+.It Fl Fl calendar Ar text Ar rows Ar cols Op Ar day Ar month Ar year
+Dialog to select a date.
.It Fl Fl checklist Ar text Ar rows Ar cols Ar menurows Oo Ar name Ar desc \
Ar status Oc ...
Checklist to select some item from a list via the SPACE key.
@@ -342,7 +355,7 @@ or
The names of the selected items are printed to standard error.
.Ar menurows
is the graphical height of the list, 0 for autosize.
-.It Fl Fl datebox Ar text Ar rows Ar cols Op Ar year Ar month Ar day
+.It Fl Fl datebox Ar text Ar rows Ar cols Op Ar day Ar month Ar year
Dialog to select a date.
.It Fl Fl form Ar text Ar rows Ar cols Ar formrows Oo Ar label Ar ylabel \
Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar maxletters Oc ...
@@ -393,7 +406,7 @@ Dialog to get a string in input,
.Ar init
is the default value.
.It Fl Fl menu Ar text Ar rows Ar cols Ar menurows Oo Ar name desc Oc ...
-Builds a menu to select an item from a list.
+Builds a menu to select an item from a list, Space key is equivalent to Enter.
An item has a
.Ar name
and a
@@ -461,6 +474,7 @@ a blank line,
Dialog to diplay a message without the
.Dq Cancel
button.
+UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to navigate the text.
.It Fl Fl passwordbox Ar text Ar rows Ar cols Op Ar init
Dialog to get a password,
.Ar init
@@ -522,6 +536,7 @@ buttons are renamed
.Dq Yes
and
.Dq \&No .
+UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to navigate the text.
.El
.Sh EXIT STATUS
The
@@ -574,6 +589,10 @@ Checklist:
Form:
.Dl bsddialog --form Form 0 0 0 L1: 0 0 X 0 4 20 25 L2: 1 0 Y 1 4 20 25
.Pp
+Multi-dialog:
+.Dl bsddialog --normal-screen --begin-y 1 --yesno Continue? 0 0 \e \
+--and-dialog --begin-y 10 --infobox Yes 0 0
+.Pp
Bikeshed:
.Dl bsddialog --bikeshed --inputbox Example 0 0
.Pp
@@ -614,6 +633,27 @@ do
i=`expr $i + 1`
done | bsddialog --title Gauge --gauge "Starting..." 10 70
.Ed
+.Sh COMPATIBILITY
+Outdated options are retained for compatibility, properly equivalent options are
+used:
+.Bd -literal -offset indent -compact
+Obsolete Equivalent
+--and-widget --and-dialog
+--calendar <text> 2 <cols> --calendar <text> 0 <cols>
+--clear --clear-screen
+--defaultno --default-no
+--exit-label --ok-label
+--help-tags --help-print-name
+--item-help --item-bottom-desc
+--keep-tite --alternate-screen
+--no-items --no-descriptions
+--no-label --cancel-label
+--no-tags --no-names
+--nocancel --no-cancel
+--nook --no-ok
+--separator --output-separator
+--yes-label --ok-label
+.Ed
.Sh SEE ALSO
.Xr bsddialog 3
.Sh HISTORY
@@ -633,7 +673,8 @@ provides a subset of the functionality described in the
manual.
The following features were reimplemented:
.Pp
-Common options:
+Options:
+.Fl Fl and-widget ,
.Fl Fl ascii-lines ,
.Fl Fl backtitle ,
.Fl Fl cancel-label ,
@@ -658,14 +699,13 @@ Common options:
.Fl Fl ignore ,
.Fl Fl insecure ,
.Fl Fl item-help ,
+.Fl Fl keep-tite ,
.Fl Fl max-input ,
.Fl Fl no-cancel ,
.Fl Fl nocancel ,
-.Fl Fl no-collapse ,
.Fl Fl no-items ,
.Fl Fl no-label ,
.Fl Fl no-lines ,
-.Fl Fl no-nl-expand ,
.Fl Fl no-ok ,
.Fl Fl nook ,
.Fl Fl no-shadow ,
@@ -687,11 +727,11 @@ Common options:
.Fl Fl tab-len ,
.Fl Fl time-format ,
.Fl Fl title ,
-.Fl Fl trim ,
.Fl Fl version ,
.Fl Fl yes-label .
.Pp
Dialogs:
+.Fl Fl calendar ,
.Fl Fl checklist ,
.Fl Fl form ,
.Fl Fl gauge ,
@@ -715,8 +755,10 @@ Some feature differs in input, output, or behavior.
Compatibility is not a priority for future development.
.Sh THANKS TO
.An Baptiste Daroussin
-.Aq Mt bapt@FreeBSD.org
-and
+.Aq Mt bapt@FreeBSD.org ,
.An \&Ed Maste
.Aq Mt emaste@FreeBSD.org
+and
+.An Juraj Lutter
+.Aq Mt otis@FreeBSD.org
for suggestions, help, and testing.
diff --git a/bsddialog.c b/bsddialog.c
index bfd6d8dbc5b7..b9b2810dc62f 100644
--- a/bsddialog.c
+++ b/bsddialog.c
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <term.h>
#include <time.h>
#include <unistd.h>
@@ -41,17 +42,18 @@
#include "util_theme.h"
-#define BSDDIALOG_VERSION "0.3"
-
enum OPTS {
- /* Common options */
- ASCII_LINES = '?' + 1,
+ /* Options */
+ ALTERNATE_SCREEN = '?' + 1,
+ AND_DIALOG,
+ ASCII_LINES,
BACKTITLE,
BEGIN_X,
BEGIN_Y,
BIKESHED,
CANCEL_LABEL,
- CLEAR,
+ CLEAR_DIALOG,
+ CLEAR_SCREEN,
COLORS,
COLUMNS_PER_ROW,
CR_WRAP,
@@ -66,29 +68,27 @@ enum OPTS {
EXTRA_LABEL,
GENERIC_BUTTON1,
GENERIC_BUTTON2,
- HELP,
HELP_BUTTON,
HELP_LABEL,
+ HELP_PRINT_NAME,
HELP_STATUS,
- HELP_TAGS,
HFILE,
HLINE,
HMSG,
IGNORE,
INSECURE,
+ ITEM_BOTTOM_DESC,
ITEM_DEPTH,
- ITEM_HELP,
ITEM_PREFIX,
LOAD_THEME,
MAX_INPUT,
NO_CANCEL,
- NO_COLLAPSE,
- NO_ITEMS,
+ NO_DESCRIPTIONS,
NO_LINES,
- NO_NL_EXPAND,
+ NO_NAMES,
NO_OK,
NO_SHADOW,
- NO_TAGS,
+ NORMAL_SCREEN,
OK_LABEL,
OUTPUT_FD,
OUTPUT_SEPARATOR,
@@ -104,13 +104,14 @@ enum OPTS {
STDERR,
STDOUT,
SWITCH_BUTTONS,
+ TAB_ESCAPE,
TAB_LEN,
+ TEXT_UNCHANGED,
THEME,
TIME_FORMAT,
TITLE,
- TRIM,
- VERSION,
/* Dialogs */
+ CALENDAR,
CHECKLIST,
DATEBOX,
FORM,
@@ -132,28 +133,156 @@ enum OPTS {
YESNO
};
+/* options descriptor */
+static struct option longopts[] = {
+ /* Options */
+ {"alternate-screen", no_argument, NULL, ALTERNATE_SCREEN},
+ {"and-dialog", no_argument, NULL, AND_DIALOG},
+ {"and-widget", no_argument, NULL, AND_DIALOG},
+ {"ascii-lines", no_argument, NULL, ASCII_LINES},
+ {"backtitle", required_argument, NULL, BACKTITLE},
+ {"begin-x", required_argument, NULL, BEGIN_X},
+ {"begin-y", required_argument, NULL, BEGIN_Y},
+ {"bikeshed", no_argument, NULL, BIKESHED},
+ {"cancel-label", required_argument, NULL, CANCEL_LABEL},
+ {"clear", no_argument, NULL, CLEAR_SCREEN},
+ {"clear-dialog", no_argument, NULL, CLEAR_DIALOG},
+ {"clear-screen", no_argument, NULL, CLEAR_SCREEN},
+ {"colors", no_argument, NULL, COLORS},
+ {"columns-per-row", required_argument, NULL, COLUMNS_PER_ROW},
+ {"cr-wrap", no_argument, NULL, CR_WRAP},
+ {"date-format", required_argument, NULL, DATE_FORMAT},
+ {"defaultno", no_argument, NULL, DEFAULT_NO},
+ {"default-button", required_argument, NULL, DEFAULT_BUTTON},
+ {"default-item", required_argument, NULL, DEFAULT_ITEM},
+ {"default-no", no_argument, NULL, DEFAULT_NO},
+ {"disable-esc", no_argument, NULL, DISABLE_ESC},
+ {"esc-return-cancel", no_argument, NULL, ESC_RETURNCANCEL},
+ {"exit-label", required_argument, NULL, EXIT_LABEL},
+ {"extra-button", no_argument, NULL, EXTRA_BUTTON},
+ {"extra-label", required_argument, NULL, EXTRA_LABEL},
+ {"generic-button1", required_argument, NULL, GENERIC_BUTTON1},
+ {"generic-button2", required_argument, NULL, GENERIC_BUTTON2},
+ {"help-button", no_argument, NULL, HELP_BUTTON},
+ {"help-label", required_argument, NULL, HELP_LABEL},
+ {"help-print-name", no_argument, NULL, HELP_PRINT_NAME},
+ {"help-status", no_argument, NULL, HELP_STATUS},
+ {"help-tags", no_argument, NULL, HELP_PRINT_NAME},
+ {"hfile", required_argument, NULL, HFILE},
+ {"hline", required_argument, NULL, HLINE},
+ {"hmsg", required_argument, NULL, HMSG},
+ {"ignore", no_argument, NULL, IGNORE},
+ {"insecure", no_argument, NULL, INSECURE},
+ {"item-bottom-desc", no_argument, NULL, ITEM_BOTTOM_DESC},
+ {"item-depth", no_argument, NULL, ITEM_DEPTH},
+ {"item-help", no_argument, NULL, ITEM_BOTTOM_DESC},
+ {"item-prefix", no_argument, NULL, ITEM_PREFIX},
+ {"keep-tite", no_argument, NULL, ALTERNATE_SCREEN},
+ {"load-theme", required_argument, NULL, LOAD_THEME},
+ {"max-input", required_argument, NULL, MAX_INPUT},
+ {"no-cancel", no_argument, NULL, NO_CANCEL},
+ {"nocancel", no_argument, NULL, NO_CANCEL},
+ {"no-descriptions", no_argument, NULL, NO_DESCRIPTIONS},
+ {"no-items", no_argument, NULL, NO_DESCRIPTIONS},
+ {"no-label", required_argument, NULL, CANCEL_LABEL},
+ {"no-lines", no_argument, NULL, NO_LINES},
+ {"no-names", no_argument, NULL, NO_NAMES},
+ {"no-ok", no_argument, NULL, NO_OK},
+ {"nook ", no_argument, NULL, NO_OK},
+ {"no-shadow", no_argument, NULL, NO_SHADOW},
+ {"no-tags", no_argument, NULL, NO_NAMES},
+ {"normal-screen", no_argument, NULL, NORMAL_SCREEN},
+ {"ok-label", required_argument, NULL, OK_LABEL},
+ {"output-fd", required_argument, NULL, OUTPUT_FD},
+ {"output-separator", required_argument, NULL, OUTPUT_SEPARATOR},
+ {"print-maxsize", no_argument, NULL, PRINT_MAXSIZE},
+ {"print-size", no_argument, NULL, PRINT_SIZE},
+ {"print-version", no_argument, NULL, PRINT_VERSION},
+ {"quoted", no_argument, NULL, QUOTED},
+ {"save-theme", required_argument, NULL, SAVE_THEME},
+ {"separate-output", no_argument, NULL, SEPARATE_OUTPUT},
+ {"separator", required_argument, NULL, OUTPUT_SEPARATOR},
+ {"shadow", no_argument, NULL, SHADOW},
+ {"single-quoted", no_argument, NULL, SINGLE_QUOTED},
+ {"sleep", required_argument, NULL, SLEEP},
+ {"stderr", no_argument, NULL, STDERR},
+ {"stdout", no_argument, NULL, STDOUT},
+ {"switch-buttons", no_argument, NULL, SWITCH_BUTTONS},
+ {"tab-escape", no_argument, NULL, TAB_ESCAPE},
+ {"tab-len", required_argument, NULL, TAB_LEN},
+ {"text-unchanged", no_argument, NULL, TEXT_UNCHANGED},
+ {"theme", required_argument, NULL, THEME},
+ {"time-format", required_argument, NULL, TIME_FORMAT},
+ {"title", required_argument, NULL, TITLE},
+ {"yes-label", required_argument, NULL, OK_LABEL},
+ /* Dialogs */
+ {"calendar", no_argument, NULL, CALENDAR},
+ {"checklist", no_argument, NULL, CHECKLIST},
+ {"datebox", no_argument, NULL, DATEBOX},
+ {"form", no_argument, NULL, FORM},
+ {"gauge", no_argument, NULL, GAUGE},
+ {"infobox", no_argument, NULL, INFOBOX},
+ {"inputbox", no_argument, NULL, INPUTBOX},
+ {"menu", no_argument, NULL, MENU},
+ {"mixedform", no_argument, NULL, MIXEDFORM},
+ {"mixedgauge", no_argument, NULL, MIXEDGAUGE},
+ {"msgbox", no_argument, NULL, MSGBOX},
+ {"passwordbox", no_argument, NULL, PASSWORDBOX},
+ {"passwordform", no_argument, NULL, PASSWORDFORM},
+ {"pause", no_argument, NULL, PAUSE},
+ {"radiolist", no_argument, NULL, RADIOLIST},
+ {"rangebox", no_argument, NULL, RANGEBOX},
+ {"textbox", no_argument, NULL, TEXTBOX},
+ {"timebox", no_argument, NULL, TIMEBOX},
+ {"treeview", no_argument, NULL, TREEVIEW},
+ {"yesno", no_argument, NULL, YESNO},
+ /* END */
+ { NULL, 0, NULL, 0}
+};
+
/* Menus options */
-static bool item_prefix_opt, item_bottomdesc_opt, item_output_sepnl_opt;
-static bool item_singlequote_opt, list_items_on_opt, item_tag_help_opt;
-static bool item_always_quote_opt, item_depth_opt;
-static char *item_output_sep_opt, *item_default_opt;
+static bool item_prefix_opt;
+static bool item_bottomdesc_opt;
+static bool item_output_sepnl_opt;
+static bool item_singlequote_opt;
+static bool list_items_on_opt;
+static bool item_help_print_name_opt;
+static bool item_always_quote_opt;
+static bool item_depth_opt;
+static char *item_output_sep_opt;
+static char *item_default_opt;
/* Date and Time options */
-static char *date_fmt_opt, *time_fmt_opt;
+static char *date_fmt_opt;
+static char *time_fmt_opt;
/* Forms options */
static int unsigned max_input_form_opt;
/* General options */
+static bool esc_return_cancel_opt;
+static bool ignore_opt;
static int output_fd_opt;
-bool bikeshed_opt;
+static int getH_opt;
+static int getW_opt;
+/* Text option */
+static bool cr_wrap_opt;
+static bool tab_escape_opt;
+static bool text_unchanged_opt;
+/* Theme and Screen options*/
+static bool bikeshed_opt;
+static enum bsddialog_default_theme theme_opt;
+static char *backtitle_opt;
+static bool clear_screen_opt;
+static char *loadthemefile;
+static char *savethemefile;
+static const char *screen_mode_opt;
/* Functions */
-static void sigint_handler(int sig);
-static void
-custom_text(bool cr_wrap, bool no_collapse, bool no_nl_expand, bool trim,
- char *text, char *buf);
-static void errorexit(char *errbuf);
+#define UNUSED_PAR(x) UNUSED_ ## x __attribute__((__unused__))
+static void custom_text(char *text, char *buf);
+static void usage(void);
/* Dialogs */
#define BUILDER_ARGS struct bsddialog_conf *conf, char* text, int rows, \
- int cols, int argc, char **argv, char *errbuf
+ int cols, int argc, char **argv
+static int calendar_builder(BUILDER_ARGS);
static int checklist_builder(BUILDER_ARGS);
static int datebox_builder(BUILDER_ARGS);
static int form_builder(BUILDER_ARGS);
@@ -174,258 +303,233 @@ static int timebox_builder(BUILDER_ARGS);
static int treeview_builder(BUILDER_ARGS);
static int yesno_builder(BUILDER_ARGS);
+/* init, exit and internals */
+static bool in_bsddialog_mode;
+static bool mandatory_dialog;
+static int (*dialogbuilder)(BUILDER_ARGS);
+
+static void exit_error(const char *errstr, bool with_usage)
+{
+ if (in_bsddialog_mode)
+ bsddialog_end();
+
+ printf("Error: %s.\n\n", errstr);
+ if (with_usage) {
+ printf("See \'bsddialog --help\' or \'man 1 bsddialog\' ");
+ printf("for more information.\n");
+ }
+
+ exit (255);
+}
+
+static void sigint_handler(int UNUSED_PAR(sig))
+{
+ bsddialog_end();
+
+ exit(255);
+}
+
+static void start_bsddialog_mode(void)
+{
+ if (in_bsddialog_mode)
+ return;
+
+ if (bsddialog_init() != BSDDIALOG_OK)
+ exit_error(bsddialog_geterror(), false);
+
+ in_bsddialog_mode = true;
+ signal(SIGINT, sigint_handler);
+}
+
+static void error_args(const char *dialog, int argc, char **argv)
+{
+ int i;
+
+ if (in_bsddialog_mode)
+ bsddialog_end();
+
+ printf("Error: %s unexpected argument%s:", dialog,
+ argc > 1 ? "s" : "");
+ for (i = 0; i < argc; i++)
+ printf(" \"%s\"", argv[i]);
+ printf(".\n\n");
+ printf("See \'bsddialog --help\' or \'man 1 bsddialog\' ");
+ printf("for more information.\n");
+
+ exit (255);
+}
+
static void usage(void)
{
printf("usage: bsddialog --help\n");
printf(" bsddialog --version\n");
- printf(" bsddialog [--<common-opts>] --<dialog> <text> <rows> "
- "<cols> [--<dialog-opts>]\n");
+ printf(" bsddialog [--<opt>] --<dialog> <text> <rows> <cols> "
+ "[<arg>]\n");
+ printf(" bsddialog --<dialog1> ... [--and-dialog --<dialog2> "
+ "...] ...\n");
printf("\n");
- printf("Common Options:\n");
- printf("--ascii-lines, --backtitle <backtitle>, --begin-x <x>, "
- "--begin-y <y>, --bikeshed, --cancel-label <label>, --clear, "
- "--colors, --columns-per-row <columns>, --cr-wrap, "
- "--date-format <format>, --default-button <label>, "
- "--default-item <name>, --default-no, --disable-esc, "
- "--esc-return-cancel, --exit-label <label>, --extra-button, "
- "--extra-label <label>, --generic-button1 <label>, "
- "--generic-button2 <label>, --help, --help-button, "
- "--help-label <label>, --help-status, --help-tags, --hfile <file>, "
- "--hline <string>, --hmsg <string>, --ignore, --insecure, "
- "--item-depth, --item-help, --item-prefix, --load-theme <file>, "
- "--max-input <size>, --no-cancel, --no-collapse, --no-items, "
- "--no-label <label>, --no-lines, --no-nl-expand, --no-ok, "
- "--no-shadow, --no-tags, --ok-label <label>, --output-fd <fd>, "
- "--output-separator <sep>, --print-maxsize, --print-size, "
- "--print-version, --quoted, --save-theme <file>, "
- "--separate-output, --separator <sep>, --shadow, --single-quoted, "
- "--sleep <secs>, --stderr, --stdout, --tab-len <spaces>, "
- "--switch-buttons, --theme <blackwhite|bsddialog|flat|dialog>, "
- "--time-format <format>, --title <title>, --trim, --version, "
- "--yes-label <label>.\n");
+ printf("Options:\n");
+ printf(" --alternate-screen, --ascii-lines, --backtitle <backtitle>,"
+ " --begin-x <x>,\n --begin-y <y>, --bikeshed, --calendar,"
+ " --cancel-label <label>, --clear-dialog,\n --clear-screen,"
+ " --colors, --columns-per-row <columns>, --cr-wrap,\n"
+ " --date-format <format>, --default-button <label>,"
+ " --default-item <name>,\n --default-no, --disable-esc,"
+ " --esc-return-cancel, --exit-label <label>,\n --extra-button,"
+ " --extra-label <label>, --generic-button1 <label>,\n"
+ " --generic-button2 <label>, --help-button, --help-label <label>,\n"
+ " --help-print-name, --help-status, --hfile <file>,"
+ " --hline <string>,\n --hmsg <string>, --ignore, --insecure,"
+ " --item-bottom-desc, --item-depth,\n --item-prefix,"
+ " --load-theme <file>, --max-input <size>, --no-cancel,\n"
+ " --no-descriptions, --no-label <label>, --no-lines, --no-names,"
+ " --no-ok,\n --no-shadow, --normal-screen, --ok-label <label>,"
+ " --output-fd <fd>,\n --output-separator <sep>, --print-maxsize,"
+ " --print-size, --print-version,\n --quoted, --save-theme <file>,"
+ " --separate-output, --separator <sep>, --shadow,\n"
+ " --single-quoted, --sleep <secs>, --stderr, --stdout,"
+ " --tab-escape,\n --tab-len <spaces>, --text-unchanged,"
+ " --switch-buttons,\n --theme <blackwhite|bsddialog|flat|dialog>,"
+ " --time-format <format>,\n --title <title>,"
+ " --yes-label <label>.\n");
printf("\n");
printf("Dialogs:\n");
- printf("--checklist <text> <rows> <cols> <menurows> [<name> <desc> "
+ printf(" --calendar <text> <rows> <cols> [<dd> <mm> <yy>]\n");
+ printf(" --checklist <text> <rows> <cols> <menurows> [<name> <desc> "
"<on|off>] ...\n");
- printf("--datebox <text> <rows> <cols> [<yy> <mm> <dd>]\n");
- printf("--form <text> <rows> <cols> <formrows> [<label> <ylabel> "
+ printf(" --datebox <text> <rows> <cols> [<dd> <mm> <yy>]\n");
+ printf(" --form <text> <rows> <cols> <formrows> [<label> <ylabel> "
"<xlabel> <init> <yfield> <xfield> <fieldlen> <maxletters>] "
"...\n");
- printf("--gauge <text> <rows> <cols> [<perc>]\n");
- printf("--infobox <text> <rows> <cols>\n");
- printf("--inputbox <text> <rows> <cols> [init]\n");
- printf("--menu <text> <rows> <cols> <menurows> [<name> <desc>] ...\n");
- printf("--mixedform <text> <rows> <cols> <formrows> [<label> <ylabel> "
+ printf(" --gauge <text> <rows> <cols> [<perc>]\n");
+ printf(" --infobox <text> <rows> <cols>\n");
+ printf(" --inputbox <text> <rows> <cols> [init]\n");
+ printf(" --menu <text> <rows> <cols> <menurows> [<name> <desc>] ...\n");
+ printf(" --mixedform <text> <rows> <cols> <formrows> [<label> <ylabel> "
"<xlabel> <init> <yfield> <xfield> <fieldlen> <maxletters> "
"<0|1|2>] ...\n");
- printf("--mixedgauge <text> <rows> <cols> <mainperc> [<minilabel> "
+ printf(" --mixedgauge <text> <rows> <cols> <mainperc> [<minilabel> "
"<miniperc>] ...\n");
- printf("--msgbox <text> <rows> <cols>\n");
- printf("--passwordbox <text> <rows> <cols> [init]\n");
- printf("--passwordform <text> <rows> <cols> <formrows> [<label> "
+ printf(" --msgbox <text> <rows> <cols>\n");
+ printf(" --passwordbox <text> <rows> <cols> [init]\n");
+ printf(" --passwordform <text> <rows> <cols> <formrows> [<label> "
"<ylabel> <xlabel> <init> <yfield> <xfield> <fieldlen> "
"<maxletters>] ...\n");
- printf("--pause <text> <rows> <cols> <secs>\n");
- printf("--radiolist <text> <rows> <cols> <menurows> [<name> <desc> "
+ printf(" --pause <text> <rows> <cols> <secs>\n");
+ printf(" --radiolist <text> <rows> <cols> <menurows> [<name> <desc> "
"<on|off>] ...\n");
- printf("--rangebox <text> <rows> <cols> <min> <max> [<init>]\n");
- printf("--textbox <file> <rows> <cols>\n");
- printf("--timebox <text> <rows> <cols> [<hh> <mm> <ss>]\n");
- printf("--treeview <text> <rows> <cols> <menurows> [<depth> <name> "
+ printf(" --rangebox <text> <rows> <cols> <min> <max> [<init>]\n");
+ printf(" --textbox <file> <rows> <cols>\n");
+ printf(" --timebox <text> <rows> <cols> [<hh> <mm> <ss>]\n");
+ printf(" --treeview <text> <rows> <cols> <menurows> [<depth> <name> "
"<desc> <on|off>] ...\n");
- printf("--yesno <text> <rows> <cols>\n");
+ printf(" --yesno <text> <rows> <cols>\n");
printf("\n");
printf("See 'man 1 bsddialog' for more information.\n");
}
-int main(int argc, char *argv[argc])
+static int parseargs(int argc, char **argv, struct bsddialog_conf *conf)
{
- bool cr_wrap_opt, no_collapse_opt, no_nl_expand_opt, trim_opt;
- bool esc_return_cancel_opt, ignore_opt, print_maxsize_opt;
- bool textfromfile;
- int input, rows, cols, retval, getH, getW;
- int (*dialogbuilder)(BUILDER_ARGS) = NULL;
- enum bsddialog_default_theme theme_opt;
- char *text, *backtitle_opt, *loadthemefile, *savethemefile;
- char errorbuilder[1024];
+ int arg, parsed, i;
struct winsize ws;
- struct bsddialog_conf conf;
- setlocale(LC_ALL, "");
+ bsddialog_initconf(conf);
+ conf->key.enable_esc = true;
+ conf->menu.on_without_ok = true;
+ conf->form.value_without_ok = true;
+ conf->button.always_active = true;
- bsddialog_initconf(&conf);
- conf.key.enable_esc = true;
- conf.menu.on_without_ok = true;
- conf.form.value_without_ok = true;
- conf.button.always_active = true;
+ dialogbuilder = NULL;
backtitle_opt = NULL;
- theme_opt = BSDDIALOG_THEME_FLAT;
+ theme_opt = -1;
output_fd_opt = STDERR_FILENO;
- print_maxsize_opt = false;
ignore_opt = false;
- cr_wrap_opt = no_collapse_opt = no_nl_expand_opt = trim_opt = false;
+ cr_wrap_opt = false;
+ tab_escape_opt = false;
+ text_unchanged_opt = false;
esc_return_cancel_opt = false;
- textfromfile = false;
bikeshed_opt = false;
- errorbuilder[0] = '\0';
savethemefile = NULL;
loadthemefile = NULL;
-
- item_output_sepnl_opt = item_singlequote_opt = false;
- item_prefix_opt = item_bottomdesc_opt = item_depth_opt = false;
- list_items_on_opt = item_tag_help_opt = false;
+ clear_screen_opt = false;
+ screen_mode_opt = NULL;
+
+ item_output_sepnl_opt = false;
+ item_singlequote_opt = false;
+ item_prefix_opt = false;
+ item_bottomdesc_opt = false;
+ item_depth_opt = false;
+ list_items_on_opt = false;
+ item_help_print_name_opt = false;
item_always_quote_opt = false;
item_output_sep_opt = NULL;
item_default_opt = NULL;
- date_fmt_opt = time_fmt_opt = NULL;
-
- max_input_form_opt = 0;
-
- /* options descriptor */
- struct option longopts[] = {
- /* common options */
- {"ascii-lines", no_argument, NULL, ASCII_LINES},
- {"backtitle", required_argument, NULL, BACKTITLE},
- {"begin-x", required_argument, NULL, BEGIN_X},
- {"begin-y", required_argument, NULL, BEGIN_Y},
- {"bikeshed", no_argument, NULL, BIKESHED},
- {"cancel-label", required_argument, NULL, CANCEL_LABEL},
- {"clear", no_argument, NULL, CLEAR},
- {"colors", no_argument, NULL, COLORS},
- {"cr-wrap", no_argument, NULL, CR_WRAP},
- {"date-format", required_argument, NULL, DATE_FORMAT},
- {"defaultno", no_argument, NULL, DEFAULT_NO},
- {"default-button", required_argument, NULL, DEFAULT_BUTTON},
- {"default-item", required_argument, NULL, DEFAULT_ITEM},
- {"default-no", no_argument, NULL, DEFAULT_NO},
- {"disable-esc", no_argument, NULL, DISABLE_ESC},
- {"esc-return-cancel",no_argument, NULL, ESC_RETURNCANCEL},
- {"exit-label", required_argument, NULL, EXIT_LABEL},
- {"extra-button", no_argument, NULL, EXTRA_BUTTON},
- {"extra-label", required_argument, NULL, EXTRA_LABEL},
- {"generic-button1", required_argument, NULL, GENERIC_BUTTON1},
- {"generic-button2", required_argument, NULL, GENERIC_BUTTON2},
- {"help", no_argument, NULL, HELP},
- {"help-button", no_argument, NULL, HELP_BUTTON},
- {"help-label", required_argument, NULL, HELP_LABEL},
- {"help-status", no_argument, NULL, HELP_STATUS},
- {"help-tags", no_argument, NULL, HELP_TAGS},
- {"hfile", required_argument, NULL, HFILE},
- {"hline", required_argument, NULL, HLINE},
- {"hmsg", required_argument, NULL, HMSG},
- {"ignore", no_argument, NULL, IGNORE},
- {"insecure", no_argument, NULL, INSECURE},
- {"item-depth", no_argument, NULL, ITEM_DEPTH},
- {"item-help", no_argument, NULL, ITEM_HELP},
- {"item-prefix", no_argument, NULL, ITEM_PREFIX},
- {"load-theme", required_argument, NULL, LOAD_THEME},
- {"max-input", required_argument, NULL, MAX_INPUT},
- {"no-cancel", no_argument, NULL, NO_CANCEL},
- {"nocancel", no_argument, NULL, NO_CANCEL},
- {"no-collapse", no_argument, NULL, NO_COLLAPSE},
- {"no-items", no_argument, NULL, NO_ITEMS},
- {"no-label", required_argument, NULL, CANCEL_LABEL},
- {"no-lines", no_argument, NULL, NO_LINES},
- {"no-nl-expand", no_argument, NULL, NO_NL_EXPAND},
- {"no-ok", no_argument, NULL, NO_OK},
- {"nook ", no_argument, NULL, NO_OK},
- {"no-shadow", no_argument, NULL, NO_SHADOW},
- {"no-tags", no_argument, NULL, NO_TAGS},
- {"ok-label", required_argument, NULL, OK_LABEL},
- {"output-fd", required_argument, NULL, OUTPUT_FD},
- {"output-separator", required_argument, NULL, OUTPUT_SEPARATOR},
- {"print-maxsize", no_argument, NULL, PRINT_MAXSIZE},
- {"print-size", no_argument, NULL, PRINT_SIZE},
- {"print-version", no_argument, NULL, PRINT_VERSION},
- {"quoted", no_argument, NULL, QUOTED},
- {"columns-per-row", required_argument, NULL, COLUMNS_PER_ROW},
- {"save-theme", required_argument, NULL, SAVE_THEME},
- {"separate-output", no_argument, NULL, SEPARATE_OUTPUT},
- {"separator", required_argument, NULL, OUTPUT_SEPARATOR},
- {"shadow", no_argument, NULL, SHADOW},
- {"single-quoted", no_argument, NULL, SINGLE_QUOTED},
- {"sleep", required_argument, NULL, SLEEP},
- {"stderr", no_argument, NULL, STDERR},
- {"stdout", no_argument, NULL, STDOUT},
- {"switch-buttons", no_argument, NULL, SWITCH_BUTTONS},
- {"tab-len", required_argument, NULL, TAB_LEN},
- {"theme", required_argument, NULL, THEME},
- {"time-format", required_argument, NULL, TIME_FORMAT},
- {"title", required_argument, NULL, TITLE},
- {"trim", no_argument, NULL, TRIM},
- {"version", no_argument, NULL, VERSION},
- {"yes-label", required_argument, NULL, OK_LABEL},
- /* Dialogs */
- {"checklist", no_argument, NULL, CHECKLIST},
- {"datebox", no_argument, NULL, DATEBOX},
- {"form", no_argument, NULL, FORM},
- {"gauge", no_argument, NULL, GAUGE},
- {"infobox", no_argument, NULL, INFOBOX},
- {"inputbox", no_argument, NULL, INPUTBOX},
- {"menu", no_argument, NULL, MENU},
- {"mixedform", no_argument, NULL, MIXEDFORM},
- {"mixedgauge", no_argument, NULL, MIXEDGAUGE},
- {"msgbox", no_argument, NULL, MSGBOX},
- {"passwordbox", no_argument, NULL, PASSWORDBOX},
- {"passwordform", no_argument, NULL, PASSWORDFORM},
- {"pause", no_argument, NULL, PAUSE},
- {"radiolist", no_argument, NULL, RADIOLIST},
- {"rangebox", no_argument, NULL, RANGEBOX},
- {"textbox", no_argument, NULL, TEXTBOX},
- {"timebox", no_argument, NULL, TIMEBOX},
- {"treeview", no_argument, NULL, TREEVIEW},
- {"yesno", no_argument, NULL, YESNO},
- /* END */
- { NULL, 0, NULL, 0}
- };
-
- while ((input = getopt_long(argc, argv, "", longopts, NULL)) != -1) {
- switch (input) {
- /* Common options */
+ date_fmt_opt = NULL;
+ time_fmt_opt = NULL;
+
+ max_input_form_opt = 2048;
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "--and-dialog") == 0 ||
+ strcmp(argv[i], "--and-widget") == 0) {
+ argc = i + 1;
+ break;
+ }
+ }
+ parsed = argc;
+ while ((arg = getopt_long(argc, argv, "", longopts, NULL)) != -1) {
+ switch (arg) {
+ /* Options */
+ case ALTERNATE_SCREEN:
+ screen_mode_opt = "smcup";
+ break;
+ case AND_DIALOG:
+ if (dialogbuilder == NULL)
+ exit_error("--and-dialog without previous "
+ "--<dialog>", true);
+ break;
case ASCII_LINES:
- conf.ascii_lines = true;
+ conf->ascii_lines = true;
break;
case BACKTITLE:
backtitle_opt = optarg;
- if (conf.y == BSDDIALOG_CENTER)
- conf.auto_topmargin = 2;
+ if (conf->y == BSDDIALOG_CENTER)
+ conf->auto_topmargin = 2;
break;
case BEGIN_X:
- conf.x = (int)strtol(optarg, NULL, 10);
- if (conf.x < BSDDIALOG_CENTER) {
- printf("Error: --begin-x %d < %d",
- conf.x, BSDDIALOG_CENTER);
- return (255);
- }
+ conf->x = (int)strtol(optarg, NULL, 10);
+ if (conf->x < BSDDIALOG_CENTER)
+ exit_error("--begin-x < -1", false);
break;
case BEGIN_Y:
- conf.y = (int)strtol(optarg, NULL, 10);
- if (conf.y < BSDDIALOG_CENTER) {
- printf("Error: --begin-y %d < %d",
- conf.y, BSDDIALOG_CENTER);
- return (255);
- }
- conf.auto_topmargin = 0;
+ conf->y = (int)strtol(optarg, NULL, 10);
+ if (conf->y < BSDDIALOG_CENTER)
+ exit_error("--begin-y < -1", false);
+ conf->auto_topmargin = 0;
break;
case BIKESHED:
bikeshed_opt = true;
break;
case CANCEL_LABEL:
- conf.button.cancel_label = optarg;
+ conf->button.cancel_label = optarg;
break;
- case CLEAR:
- conf.clear = true;
+ case CLEAR_DIALOG:
+ conf->clear = true;
+ break;
+ case CLEAR_SCREEN:
+ mandatory_dialog = false;
+ clear_screen_opt = true;
break;
case COLORS:
- conf.text.highlight = true;
+ conf->text.highlight = true;
break;
case COLUMNS_PER_ROW:
- conf.text.cols_per_row =
+ conf->text.cols_per_row =
(u_int)strtoul(optarg, NULL, 10);
break;
case CR_WRAP:
@@ -435,72 +539,69 @@ int main(int argc, char *argv[argc])
date_fmt_opt = optarg;
break;
case DEFAULT_BUTTON:
- conf.button.default_label = optarg;
+ conf->button.default_label = optarg;
break;
case DEFAULT_ITEM:
item_default_opt = optarg;
break;
case DEFAULT_NO:
- conf.button.default_cancel = true;
+ conf->button.default_cancel = true;
break;
case DISABLE_ESC:
- conf.key.enable_esc = false;
+ conf->key.enable_esc = false;
break;
case ESC_RETURNCANCEL:
esc_return_cancel_opt = true;
break;
case EXIT_LABEL:
- conf.button.ok_label = optarg;
+ conf->button.ok_label = optarg;
break;
case EXTRA_BUTTON:
- conf.button.with_extra = true;
+ conf->button.with_extra = true;
break;
case EXTRA_LABEL:
- conf.button.extra_label = optarg;
+ conf->button.extra_label = optarg;
break;
case GENERIC_BUTTON1:
- conf.button.generic1_label = optarg;
+ conf->button.generic1_label = optarg;
break;
case GENERIC_BUTTON2:
- conf.button.generic2_label = optarg;
+ conf->button.generic2_label = optarg;
break;
- case HELP:
- usage();
- return (BSDDIALOG_OK);
case HELP_BUTTON:
- conf.button.with_help = true;
+ conf->button.with_help = true;
break;
case HELP_LABEL:
- conf.button.help_label = optarg;
+ conf->button.help_label = optarg;
+ break;
+ case HELP_PRINT_NAME:
+ item_help_print_name_opt = true;
break;
case HELP_STATUS:
list_items_on_opt = true;
break;
- case HELP_TAGS:
- item_tag_help_opt = true;
- break;
case HFILE:
- conf.key.f1_file = optarg;
+ conf->key.f1_file = optarg;
break;
case HLINE:
if (optarg[0] != '\0')
- conf.bottomtitle = optarg;
+ conf->bottomtitle = optarg;
break;
case HMSG:
- conf.key.f1_message = optarg;
+ conf->key.f1_message = optarg;
break;
case IGNORE:
ignore_opt = true;
break;
case INSECURE:
- conf.form.securech = '*';
+ conf->form.securech = '*';
+ break;
+ case ITEM_BOTTOM_DESC:
+ item_bottomdesc_opt = true;
break;
case ITEM_DEPTH:
item_depth_opt = true;
break;
- case ITEM_HELP:
- item_bottomdesc_opt = true;
- break;
case ITEM_PREFIX:
item_prefix_opt = true;
break;
@@ -510,32 +611,29 @@ int main(int argc, char *argv[argc])
case MAX_INPUT:
max_input_form_opt = (u_int)strtoul(optarg, NULL, 10);
break;
- case NO_ITEMS:
- conf.menu.no_desc = true;
- break;
case NO_CANCEL:
- conf.button.without_cancel = true;
+ conf->button.without_cancel = true;
break;
- case NO_COLLAPSE:
- no_collapse_opt = true;
+ case NO_DESCRIPTIONS:
+ conf->menu.no_desc = true;
break;
case NO_LINES:
- conf.no_lines = true;
+ conf->no_lines = true;
break;
- case NO_NL_EXPAND:
- no_nl_expand_opt = true;
+ case NO_NAMES:
+ conf->menu.no_name = true;
break;
case NO_OK:
- conf.button.without_ok = true;
- break;
- case NO_TAGS:
- conf.menu.no_name = true;
+ conf->button.without_ok = true;
break;
case NO_SHADOW:
- conf.shadow = false;
+ conf->shadow = false;
+ break;
+ case NORMAL_SCREEN:
+ screen_mode_opt = "rmcup";
break;
case OK_LABEL:
- conf.button.ok_label = optarg;
+ conf->button.ok_label = optarg;
break;
case OUTPUT_FD:
output_fd_opt = (int)strtol(optarg, NULL, 10);
@@ -547,29 +645,35 @@ int main(int argc, char *argv[argc])
item_always_quote_opt = true;
break;
case PRINT_MAXSIZE:
- print_maxsize_opt = true;
+ mandatory_dialog = false;
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
+ dprintf(output_fd_opt, "MaxSize: %d, %d\n",
+ ws.ws_row, ws.ws_col);
break;
case PRINT_SIZE:
- conf.get_height = &getH;
- conf.get_width = &getW;
+ conf->get_height = &getH_opt;
+ conf->get_width = &getW_opt;
break;
case PRINT_VERSION:
- printf("bsddialog version %s\n", BSDDIALOG_VERSION);
+ mandatory_dialog = false;
+ dprintf(output_fd_opt, "Version: %s\n",
+ LIBBSDDIALOG_VERSION);
break;
case SAVE_THEME:
+ mandatory_dialog = false;
savethemefile = optarg;
break;
case SEPARATE_OUTPUT:
item_output_sepnl_opt = true;
break;
case SHADOW:
- conf.shadow = true;
+ conf->shadow = true;
break;
case SINGLE_QUOTED:
item_singlequote_opt = true;
break;
case SLEEP:
- conf.sleep = (u_int)strtoul(optarg, NULL, 10);
+ conf->sleep = (u_int)strtoul(optarg, NULL, 10);
break;
case STDERR:
output_fd_opt = STDERR_FILENO;
@@ -578,10 +682,16 @@ int main(int argc, char *argv[argc])
output_fd_opt = STDOUT_FILENO;
break;
case SWITCH_BUTTONS:
- conf.button.always_active = false;
+ conf->button.always_active = false;
+ break;
+ case TAB_ESCAPE:
+ tab_escape_opt = true;
break;
case TAB_LEN:
- conf.text.tablen = (u_int)strtoul(optarg, NULL, 10);
+ conf->text.tablen = (u_int)strtoul(optarg, NULL, 10);
+ break;
+ case TEXT_UNCHANGED:
+ text_unchanged_opt = true;
break;
case THEME:
if (strcasecmp(optarg, "bsddialog") == 0)
@@ -592,245 +702,313 @@ int main(int argc, char *argv[argc])
theme_opt = BSDDIALOG_THEME_FLAT;
else if (strcasecmp(optarg, "dialog") == 0)
theme_opt = BSDDIALOG_THEME_DIALOG;
- else {
- printf("Error: unknown theme\n");
- return (255);
- }
+ else
+ exit_error("--theme: <unknown> theme", false);
break;
case TIME_FORMAT:
time_fmt_opt = optarg;
break;
case TITLE:
- conf.title = optarg;
- break;
- case TRIM:
- trim_opt = true;
+ conf->title = optarg;
break;
- case VERSION:
- printf("bsddialog %s (libbsddialog %s)\n",
- BSDDIALOG_VERSION, LIBBSDDIALOG_VERSION);
- return (BSDDIALOG_OK);
/* Dialogs */
+ case CALENDAR:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --calendar", true);
+ dialogbuilder = calendar_builder;
+ break;
case CHECKLIST:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --checklist", true);
dialogbuilder = checklist_builder;
- conf.auto_downmargin = 1;
+ conf->auto_downmargin = 1;
break;
case DATEBOX:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --datebox", true);
dialogbuilder = datebox_builder;
break;
case FORM:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --form", true);
dialogbuilder = form_builder;
- conf.auto_downmargin = 1;
+ conf->auto_downmargin = 1;
break;
case GAUGE:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --gauge", true);
dialogbuilder = gauge_builder;
break;
case INFOBOX:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --infobox", true);
dialogbuilder = infobox_builder;
break;
case INPUTBOX:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --inputbox", true);
dialogbuilder = inputbox_builder;
- conf.auto_downmargin = 1;
+ conf->auto_downmargin = 1;
break;
case MENU:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --menu", true);
dialogbuilder = menu_builder;
- conf.auto_downmargin = 1;
+ conf->auto_downmargin = 1;
break;
case MIXEDFORM:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --mixedform", true);
dialogbuilder = mixedform_builder;
- conf.auto_downmargin = 1;
+ conf->auto_downmargin = 1;
break;
case MIXEDGAUGE:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --mixedgauge", true);
dialogbuilder = mixedgauge_builder;
break;
case MSGBOX:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --msgbox", true);
dialogbuilder = msgbox_builder;
break;
case PAUSE:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --pause", true);
dialogbuilder = pause_builder;
break;
case PASSWORDBOX:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --passwordbox", true);
dialogbuilder = passwordbox_builder;
- conf.auto_downmargin = 1;
+ conf->auto_downmargin = 1;
break;
case PASSWORDFORM:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --passwordform", true);
dialogbuilder = passwordform_builder;
- conf.auto_downmargin = 1;
+ conf->auto_downmargin = 1;
break;
case RADIOLIST:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --radiolist", true);
dialogbuilder = radiolist_builder;
- conf.auto_downmargin = 1;
+ conf->auto_downmargin = 1;
break;
case RANGEBOX:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --rangebox", true);
dialogbuilder = rangebox_builder;
break;
case TEXTBOX:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --textbox", true);
dialogbuilder = textbox_builder;
- textfromfile = true;
break;
case TIMEBOX:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --timebox", true);
dialogbuilder = timebox_builder;
break;
case TREEVIEW:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --treeview", true);
dialogbuilder = treeview_builder;
- conf.auto_downmargin = 1;
+ conf->auto_downmargin = 1;
break;
case YESNO:
+ if (dialogbuilder != NULL)
+ exit_error("unexpected --yesno", true);
dialogbuilder = yesno_builder;
break;
- /* Error */
- default:
+ default: /* Error */
if (ignore_opt == true)
break;
- usage();
- return (255);
+ exit_error("--ignore to continue", true);
}
}
- argc -= optind;
- argv += optind;
-
- if (print_maxsize_opt) {
- ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
- dprintf(output_fd_opt, "Screen size: (%d - %d)\n",
- ws.ws_row, ws.ws_col);
- if (argc == 0)
- return (BSDDIALOG_OK);
- }
- if (argc < 3) {
- usage();
- return (255);
- }
- if (textfromfile) /* textbox */
- text = argv[0];
- else {
- if ((text = malloc(strlen(argv[0]) + 1)) == NULL) {
- printf("Error: cannot allocate memory for text\n");
- return (255);
- }
- custom_text(cr_wrap_opt, no_collapse_opt, no_nl_expand_opt,
- trim_opt, argv[0], text);
- }
- rows = (int)strtol(argv[1], NULL, 10);
- cols = (int)strtol(argv[2], NULL, 10);
- argc -= 3;
- argv += 3;
-
- /* bsddialog terminal mode */
- if (bsddialog_init() != 0) {
- printf("Error: %s\n", bsddialog_geterror());
- return (255);
- }
+ return (parsed);
+}
- signal(SIGINT, sigint_handler);
+int main(int argc, char *argv[argc])
+{
+ int i, rows, cols, retval, parsed, nargc, firstoptind;
+ char *text, **nargv, *pn;
+ struct bsddialog_conf conf;
- if (theme_opt != BSDDIALOG_THEME_FLAT)
- if (bsddialog_set_default_theme(theme_opt) != BSDDIALOG_OK)
- errorexit(NULL);
- if (loadthemefile != NULL)
- if (loadtheme(loadthemefile, errorbuilder) != BSDDIALOG_OK)
- errorexit(errorbuilder);
- if (bikeshed_opt)
- if (bikeshed(&conf, errorbuilder) != BSDDIALOG_OK)
- errorexit(errorbuilder);
-
- if (backtitle_opt != NULL)
- if( bsddialog_backtitle(&conf, backtitle_opt))
- errorexit(NULL);
-
- if (dialogbuilder != NULL) {
- retval = dialogbuilder(&conf, text, rows, cols, argc, argv,
- errorbuilder);
- if (retval == BSDDIALOG_ERROR)
- errorexit(errorbuilder);
- } else
- retval = BSDDIALOG_OK;
+ setlocale(LC_ALL, "");
- if (savethemefile != NULL)
- if (savetheme(savethemefile, errorbuilder, BSDDIALOG_VERSION) !=
- BSDDIALOG_OK)
- errorexit(errorbuilder);
+ in_bsddialog_mode = false;
+ mandatory_dialog = true;
+ firstoptind = optind;
+ pn = argv[0];
+ retval = BSDDIALOG_OK;
- bsddialog_end();
- /* end bsddialog terminal mode */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "--version") == 0) {
+ printf("Version: %s\n", LIBBSDDIALOG_VERSION);
+ return (BSDDIALOG_OK);
+ }
+ if (strcmp(argv[i], "--help") == 0) {
+ usage();
+ return (BSDDIALOG_OK);
+ }
+ }
- if (textfromfile == false)
- free(text);
+ while (true) {
+ parsed = parseargs(argc, argv, &conf);
+ nargc = argc - parsed;
+ nargv = argv + parsed;
+ argc = parsed - optind;
+ argv += optind;
- if (conf.get_height != NULL && conf.get_width != NULL)
- dprintf(output_fd_opt, "Dialog size: (%d - %d)\n",
- *conf.get_height, *conf.get_width);
+ if (mandatory_dialog && dialogbuilder == NULL)
+ exit_error("expected a --<dialog>", true);
- if (retval == BSDDIALOG_ESC && esc_return_cancel_opt)
- retval = BSDDIALOG_CANCEL;
+ if (dialogbuilder == NULL && argc > 0)
+ error_args("(no --<dialog>)", argc, argv);
- return (retval);
-}
+ /* --print-maxsize or --print-version */
+ if (mandatory_dialog == false && savethemefile == NULL &&
+ clear_screen_opt == false)
+ return (BSDDIALOG_OK);
-void sigint_handler(int sig)
-{
- bsddialog_end();
+ /* --<dialog>, --save-theme or clear-screen */
+ if (dialogbuilder != NULL) {
+ if (argc < 3)
+ exit_error("expected <text> <rows> <cols>",
+ true);
+ if ((text = strdup(argv[0])) == NULL)
+ exit_error("cannot allocate text", false);
+ if (dialogbuilder != textbox_builder)
+ custom_text(argv[0], text);
+ rows = (int)strtol(argv[1], NULL, 10);
+ cols = (int)strtol(argv[2], NULL, 10);
+ argc -= 3;
+ argv += 3;
+ }
- exit(255);
-}
+ /* bsddialog terminal mode (first iteration) */
+ start_bsddialog_mode();
+
+ if (screen_mode_opt != NULL) {
+ screen_mode_opt = tigetstr(screen_mode_opt);
+ if (screen_mode_opt != NULL &&
+ screen_mode_opt != (char*)-1) {
+ tputs(screen_mode_opt, 1, putchar);
+ fflush(stdout);
+ /* only to refresh, useless in the library */
+ bsddialog_clearterminal();
+ }
+ }
-void errorexit(char *errbuf)
-{
- bsddialog_end();
+ /* theme */
+ if (theme_opt >= 0)
+ bsddialog_set_default_theme(theme_opt);
+ if (loadthemefile != NULL)
+ loadtheme(loadthemefile);
+ if (bikeshed_opt)
+ bikeshed(&conf);
+ if (savethemefile != NULL)
+ savetheme(savethemefile, LIBBSDDIALOG_VERSION);
+
+ /* backtitle and dialog */
+ if (dialogbuilder == NULL)
+ break;
+ if (backtitle_opt != NULL)
+ if(bsddialog_backtitle(&conf, backtitle_opt))
+ exit_error(bsddialog_geterror(), false);
+ retval = dialogbuilder(&conf, text, rows, cols, argc, argv);
+ free(text);
+ if (retval == BSDDIALOG_ERROR)
+ exit_error(bsddialog_geterror(), false);
+ if (retval == BSDDIALOG_ESC && esc_return_cancel_opt)
+ retval = BSDDIALOG_CANCEL;
+ if (conf.get_height != NULL && conf.get_width != NULL)
+ dprintf(output_fd_opt, "DialogSize: %d, %d\n",
+ *conf.get_height, *conf.get_width);
+ if (clear_screen_opt)
+ bsddialog_clearterminal();
+ clear_screen_opt = false;
+ /* --and-dialog ends loop with Cancel or ESC */
+ if (retval == BSDDIALOG_CANCEL || retval == BSDDIALOG_ESC)
+ break;
+ argc = nargc;
+ argv = nargv;
+ if (argc <= 0)
+ break;
+ /* prepare next parseargs() call */
+ argc++;
+ argv--;
+ argv[0] = pn;
+ optind = firstoptind;
+ }
- if (errbuf != NULL && errbuf[0] != '\0')
- printf("Error: %s\n", errbuf);
- else
- printf("Error: %s\n", bsddialog_geterror());
+ if (in_bsddialog_mode) {
+ /* --clear-screen can be a single option */
+ if (clear_screen_opt)
+ bsddialog_clearterminal();
+ bsddialog_end();
+ }
+ /* end bsddialog terminal mode */
- exit(255);
+ return (retval);
}
-void
-custom_text(bool cr_wrap, bool no_collapse, bool no_nl_expand, bool trim,
- char *text, char *buf)
+void custom_text(char *text, char *buf)
{
+ bool trim, crwrap;
int i, j;
+ if (strstr(text, "\\n") == NULL) {
+ /* "hasnl" mode */
+ trim = true;
+ crwrap = true;
+ } else {
+ trim = false;
+ crwrap = cr_wrap_opt;
+ }
+ if (text_unchanged_opt) {
+ trim = false;
+ crwrap = true;
+ }
+
i = j = 0;
while (text[i] != '\0') {
switch (text[i]) {
case '\\':
buf[j] = '\\';
switch (text[i+1]) {
- case '\\':
- i++;
- break;
- case 'n':
- if (no_nl_expand) {
- j++;
- buf[j] = 'n';
- } else
- buf[j] = '\n';
+ case 'n': /* implicitly in "hasnl" mode */
+ buf[j] = '\n';
i++;
+ if (text[i+1] == '\n')
+ i++;
break;
case 't':
- if (no_collapse) {
+ if (tab_escape_opt) {
+ buf[j] = '\t';
+ } else {
j++;
buf[j] = 't';
- } else
- buf[j] = '\t';
+ }
i++;
break;
}
break;
case '\n':
- buf[j] = cr_wrap ? ' ' : '\n';
+ buf[j] = crwrap ? '\n' : ' ';
break;
case '\t':
- buf[j] = no_collapse ? '\t' : ' ';
+ buf[j] = text_unchanged_opt ? '\t' : ' ';
break;
default:
buf[j] = text[i];
}
i++;
- j += (buf[j] == ' ' && trim && j > 0 && buf[j-1] == ' ') ?
- 0 : 1;
+ if (!trim || buf[j] != ' ' || j == 0 || buf[j-1] != ' ')
+ j++;
}
buf[j] = '\0';
}
@@ -841,12 +1019,13 @@ int gauge_builder(BUILDER_ARGS)
int output;
unsigned int perc;
- if (argc > 0) {
- perc = argc > 0 ? (u_int)strtoul(argv[0], NULL, 10) : 0;
+ perc = 0;
+ if (argc == 1) {
+ perc = (u_int)strtoul(argv[0], NULL, 10);
perc = perc > 100 ? 100 : perc;
+ } else if (argc > 1) {
+ error_args("--gauge", argc - 1, argv + 1);
}
- else
- perc = 0;
output = bsddialog_gauge(conf, text, rows, cols, perc, STDIN_FILENO,
"XXX");
@@ -856,11 +1035,10 @@ int gauge_builder(BUILDER_ARGS)
int infobox_builder(BUILDER_ARGS)
{
- int output;
-
- output = bsddialog_infobox(conf, text, rows, cols);
+ if (argc > 0)
+ error_args("--infobox", argc, argv);
- return (output);
+ return (bsddialog_infobox(conf, text, rows, cols));
}
int mixedgauge_builder(BUILDER_ARGS)
@@ -869,10 +1047,8 @@ int mixedgauge_builder(BUILDER_ARGS)
unsigned int i, mainperc, nminibars;
const char **minilabels;
- if (argc < 1 || (((argc-1) % 2) != 0) ) {
- strcpy(errbuf, "bad --mixedgauge arguments\n");
- return (BSDDIALOG_ERROR);
- }
+ if (argc < 1 || (((argc-1) % 2) != 0) )
+ exit_error("bad --mixedgauge arguments", true);
mainperc = (u_int)strtoul(argv[0], NULL, 10);
mainperc = mainperc > 100 ? 100 : mainperc;
@@ -880,14 +1056,10 @@ int mixedgauge_builder(BUILDER_ARGS)
argv++;
nminibars = argc / 2;
- if ((minilabels = calloc(nminibars, sizeof(char*))) == NULL) {
- strcpy(errbuf, "Cannot allocate memory for minilabels\n");
- return BSDDIALOG_ERROR;
- }
- if ((minipercs = calloc(nminibars, sizeof(int))) == NULL) {
- strcpy(errbuf, "Cannot allocate memory for minipercs\n");
- return BSDDIALOG_ERROR;
- }
+ if ((minilabels = calloc(nminibars, sizeof(char*))) == NULL)
+ exit_error("Cannot allocate memory for minilabels", false);
+ if ((minipercs = calloc(nminibars, sizeof(int))) == NULL)
+ exit_error("Cannot allocate memory for minipercs", false);
for (i = 0; i < nminibars; i++) {
minilabels[i] = argv[i * 2];
@@ -902,11 +1074,10 @@ int mixedgauge_builder(BUILDER_ARGS)
int msgbox_builder(BUILDER_ARGS)
{
- int output;
+ if (argc > 0)
+ error_args("--msgbox", argc, argv);
- output = bsddialog_msgbox(conf, text, rows, cols);
-
- return (output);
+ return (bsddialog_msgbox(conf, text, rows, cols));
}
int pause_builder(BUILDER_ARGS)
@@ -914,10 +1085,10 @@ int pause_builder(BUILDER_ARGS)
int output;
unsigned int secs;
- if (argc < 1) {
- strcpy(errbuf, "missing <seconds> for --pause\n");
- return (BSDDIALOG_ERROR);
- }
+ if (argc == 0)
+ exit_error("--pause missing <seconds>", true);
+ if (argc > 1)
+ error_args("--pause", argc - 1, argv + 1);
secs = (u_int)strtoul(argv[0], NULL, 10);
output = bsddialog_pause(conf, text, rows, cols, secs);
@@ -929,25 +1100,22 @@ int rangebox_builder(BUILDER_ARGS)
{
int output, min, max, value;
- if (argc < 2) {
- strcpy(errbuf, "usage --rangebox <text> <rows> <cols> "
- "<min> <max> [<init>]\n");
- return (BSDDIALOG_ERROR);
- }
+ if (argc < 2)
+ exit_error("--rangebox missing <min> <max> [<init>]", true);
+ if (argc > 3)
+ error_args("--rangebox", argc - 3, argv + 3);
min = (int)strtol(argv[0], NULL, 10);
max = (int)strtol(argv[1], NULL, 10);
- if (argc > 2) {
+ if (argc == 3) {
value = (int)strtol(argv[2], NULL, 10);
value = value < min ? min : value;
value = value > max ? max : value;
- }
- else
+ } else
value = min;
output = bsddialog_rangebox(conf, text, rows, cols, min, max, &value);
-
dprintf(output_fd_opt, "%d", value);
return (output);
@@ -955,46 +1123,54 @@ int rangebox_builder(BUILDER_ARGS)
int textbox_builder(BUILDER_ARGS)
{
- int output;
-
- output = bsddialog_textbox(conf, text, rows, cols);
+ if (argc > 0)
+ error_args("--textbox", argc, argv);
- return (output);
+ return (bsddialog_textbox(conf, text, rows, cols));
}
int yesno_builder(BUILDER_ARGS)
{
- int output;
+ if (argc > 0)
+ error_args("--yesno", argc, argv);
- output = bsddialog_yesno(conf, text, rows, cols);
-
- return (output);
+ return (bsddialog_yesno(conf, text, rows, cols));
}
-/* DATE and TIME */
-int datebox_builder(BUILDER_ARGS)
+/* CALENDAR, DATE and TIME */
+static int date(BUILDER_ARGS, bool is_datebox)
{
- int output;
+ int ret;
unsigned int yy, mm, dd;
time_t cal;
struct tm *localtm;
char stringdate[1024];
+ const char *name;
+ name = is_datebox ? "--datebox" : "--calendar";
time(&cal);
localtm = localtime(&cal);
yy = localtm->tm_year + 1900;
mm = localtm->tm_mon + 1;
dd = localtm->tm_mday;
- if (argc == 3) {
- yy = (u_int)strtoul(argv[0], NULL, 10);
+ if (argc > 3) {
+ error_args(name, argc - 3, argv + 3);
+ } else if (argc == 3) {
+ dd = (u_int)strtoul(argv[0], NULL, 10);
mm = (u_int)strtoul(argv[1], NULL, 10);
- dd = (u_int)strtoul(argv[2], NULL, 10);
+ yy = (u_int)strtoul(argv[2], NULL, 10);
+ if (yy < 1900)
+ yy = 1900;
+ /* max yy check is in lib */
}
- output = bsddialog_datebox(conf, text, rows, cols, &yy, &mm, &dd);
- if (output != BSDDIALOG_OK)
- return (output);
+ if (is_datebox)
+ ret = bsddialog_datebox(conf, text, rows, cols, &yy, &mm, &dd);
+ else
+ ret = bsddialog_calendar(conf, text, rows, cols, &yy, &mm, &dd);
+ if (ret != BSDDIALOG_OK)
+ return (ret);
if (date_fmt_opt != NULL) {
time(&cal);
@@ -1005,12 +1181,36 @@ int datebox_builder(BUILDER_ARGS)
strftime(stringdate, 1024, date_fmt_opt, localtm);
dprintf(output_fd_opt, "%s", stringdate);
} else if (bikeshed_opt && (dd % 2 == 0)) {
- dprintf(output_fd_opt, "%u/%u/%u", yy, mm, dd);
+ dprintf(output_fd_opt, "%u/%u/%u", dd, mm, yy);
} else {
- dprintf(output_fd_opt, "%u/%02u/%02u", yy, mm, dd);
+ dprintf(output_fd_opt, "%02u/%02u/%u", dd, mm, yy);
}
- return (output);
+ return (ret);
+}
+
+int calendar_builder(BUILDER_ARGS)
+{
+ if (rows == 2) {
+ /*
+ * (bsdconfig/share/dialog.subr:1352) f_dialog_calendar_size()
+ * computes height 2 for `dialog --calendar' in
+ * (bsdconfig/usermgmt/share/user_input.subr:517)
+ * f_dialog_input_expire_password() and
+ * (bsdconfig/usermgmt/share/user_input.subr:660)
+ * f_dialog_input_expire_account().
+ * Use height auto-sizing that is min height like dialog,
+ * documented in bsddialog(1).
+ */
+ rows = 0;
+ }
+
+ return (date(conf, text, rows, cols, argc, argv, false));
+}
+
+int datebox_builder(BUILDER_ARGS)
+{
+ return (date(conf, text, rows, cols, argc, argv, true));
}
int timebox_builder(BUILDER_ARGS)
@@ -1027,7 +1227,9 @@ int timebox_builder(BUILDER_ARGS)
mm = localtm->tm_min;
ss = localtm->tm_sec;
- if (argc == 3) {
+ if (argc > 3) {
+ error_args("--timebox", argc - 3, argv + 3);
+ } else if (argc == 3) {
hh = (u_int)strtoul(argv[0], NULL, 10);
mm = (u_int)strtoul(argv[1], NULL, 10);
ss = (u_int)strtoul(argv[2], NULL, 10);
@@ -1055,9 +1257,9 @@ int timebox_builder(BUILDER_ARGS)
}
/* MENU */
-static int
-get_menu_items(char *errbuf, int argc, char **argv, bool setprefix,
- bool setdepth, bool setname, bool setdesc, bool setstatus, bool sethelp,
+static void
+get_menu_items(int argc, char **argv, bool setprefix, bool setdepth,
+ bool setname, bool setdesc, bool setstatus, bool sethelp,
unsigned int *nitems, struct bsddialog_menuitem **items, int *focusitem)
{
unsigned int i, j, sizeitem;
@@ -1071,17 +1273,14 @@ get_menu_items(char *errbuf, int argc, char **argv, bool setprefix,
sizeitem += setdesc ? 1 : 0;
sizeitem += setstatus ? 1 : 0;
sizeitem += sethelp ? 1 : 0;
- if ((argc % sizeitem) != 0) {
- strcpy(errbuf, "bad number of arguments for this menu\n");
- return (BSDDIALOG_ERROR);
- }
+ if ((argc % sizeitem) != 0)
+ exit_error("\"menu\" bad arguments items number", true);
+
*nitems = argc / sizeitem;
*items = calloc(*nitems, sizeof(struct bsddialog_menuitem));
- if (items == NULL) {
- strcpy(errbuf, "cannot allocate memory menu items\n");
- return (BSDDIALOG_ERROR);
- }
+ if (items == NULL)
+ exit_error("cannot allocate memory \"menu\" items", false);
j = 0;
for (i = 0; i < *nitems; i++) {
@@ -1101,71 +1300,86 @@ get_menu_items(char *errbuf, int argc, char **argv, bool setprefix,
if (strcmp((*items)[i].name, item_default_opt) == 0)
*focusitem = i;
}
-
- return (BSDDIALOG_OK);
}
static void
print_menu_items(int output, int nitems, struct bsddialog_menuitem *items,
- int focusitem)
+ int focusitem, bool ismenu)
{
- bool sep, toquote;
+ bool sep, sepfirst, seplast, toquote;
int i;
- char *sepstr, quotech;
- const char *focusname;
+ char quotech;
+ const char *focusname, *sepstr;
sep = false;
quotech = item_singlequote_opt ? '\'' : '"';
- sepstr = item_output_sep_opt != NULL ? item_output_sep_opt : " ";
- if (output != BSDDIALOG_OK && output != BSDDIALOG_ERROR &&
- focusitem >= 0) {
- focusname = items[focusitem].name;
+ if (output == BSDDIALOG_ERROR || output == BSDDIALOG_CANCEL ||
+ output == BSDDIALOG_ESC)
+ return;
- if (output == BSDDIALOG_HELP) {
- dprintf(output_fd_opt, "HELP ");
+ if (output == BSDDIALOG_HELP) {
+ dprintf(output_fd_opt, "HELP ");
- if (item_bottomdesc_opt && item_tag_help_opt == false)
+ if (focusitem >= 0) {
+ focusname = items[focusitem].name;
+ if (item_bottomdesc_opt &&
+ item_help_print_name_opt == false)
focusname = items[focusitem].bottomdesc;
- }
-
- toquote = item_always_quote_opt ||
- (item_output_sepnl_opt == false &&
- strchr(focusname, ' ') != NULL);
- if (toquote)
- dprintf(output_fd_opt, "%c", quotech);
- dprintf(output_fd_opt, "%s", focusname);
- if (toquote)
- dprintf(output_fd_opt, "%c", quotech);
+ toquote = false;
+ if (strchr(focusname, ' ') != NULL) {
+ toquote = item_always_quote_opt;
+ if (ismenu == false &&
+ item_output_sepnl_opt == false)
+ toquote = true;
+ }
+ if (toquote) {
+ dprintf(output_fd_opt, "%c%s%c",
+ quotech, focusname, quotech);
+ } else
+ dprintf(output_fd_opt, "%s", focusname);
+ }
+ if (ismenu || list_items_on_opt == false)
+ return;
sep = true;
}
- if (output != BSDDIALOG_OK &&
- !(output == BSDDIALOG_HELP && list_items_on_opt))
- return;
+ sepfirst = false;
+ if ((sepstr = item_output_sep_opt) == NULL)
+ sepstr = item_output_sepnl_opt ? "\n" : " ";
+ else
+ sepfirst = true;
+
+ seplast = false;
+ if (item_output_sepnl_opt) {
+ sepfirst = false;
+ seplast = true;
+ }
for (i = 0; i < nitems; i++) {
if (items[i].on == false)
continue;
- if (sep == true) {
+ if (sep || sepfirst)
dprintf(output_fd_opt, "%s", sepstr);
- if (item_output_sepnl_opt)
- dprintf(output_fd_opt, "\n");
- }
- sep = true;
+ sep = false;
- toquote = item_always_quote_opt ||
- (item_output_sepnl_opt == false &&
- strchr(items[i].name, ' ') != NULL);
-
- if (toquote)
- dprintf(output_fd_opt, "%c", quotech);
- dprintf(output_fd_opt, "%s", items[i].name);
+ toquote = false;
+ if (strchr(items[i].name, ' ') != NULL) {
+ toquote = item_always_quote_opt;
+ if (ismenu == false && item_output_sepnl_opt == false)
+ toquote = true;
+ }
if (toquote)
- dprintf(output_fd_opt, "%c", quotech);
+ dprintf(output_fd_opt, "%c%s%c",
+ quotech, items[i].name, quotech);
+ else
+ dprintf(output_fd_opt, "%s", items[i].name);
+
+ if (seplast)
+ dprintf(output_fd_opt, "%s", sepstr);
}
}
@@ -1175,23 +1389,17 @@ int checklist_builder(BUILDER_ARGS)
unsigned int menurows, nitems;
struct bsddialog_menuitem *items;
- if (argc < 1) {
- strcpy(errbuf, "<menurows> not provided");
- return (BSDDIALOG_ERROR);
- }
-
+ if (argc < 1)
+ exit_error("--checklist missing <menurows>", true);
menurows = (u_int)strtoul(argv[0], NULL, 10);
- output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_opt,
- item_depth_opt, true, true, true, item_bottomdesc_opt, &nitems,
- &items, &focusitem);
- if (output != 0)
- return (output);
+ get_menu_items(argc-1, argv+1, item_prefix_opt, item_depth_opt, true,
+ true, true, item_bottomdesc_opt, &nitems, &items, &focusitem);
output = bsddialog_checklist(conf, text, rows, cols, menurows, nitems,
items, &focusitem);
- print_menu_items(output, nitems, items, focusitem);
+ print_menu_items(output, nitems, items, focusitem, false);
free(items);
@@ -1204,23 +1412,17 @@ int menu_builder(BUILDER_ARGS)
unsigned int menurows, nitems;
struct bsddialog_menuitem *items;
- if (argc < 1) {
- strcpy(errbuf, "<menurows> not provided");
- return (BSDDIALOG_ERROR);
- }
-
+ if (argc < 1)
+ exit_error("--menu missing <menurows>", true);
menurows = (u_int)strtoul(argv[0], NULL, 10);
- output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_opt,
- item_depth_opt, true, true, false, item_bottomdesc_opt, &nitems,
- &items, &focusitem);
- if (output != 0)
- return (output);
+ get_menu_items(argc-1, argv+1, item_prefix_opt, item_depth_opt, true,
+ true, false, item_bottomdesc_opt, &nitems, &items, &focusitem);
output = bsddialog_menu(conf, text, rows, cols, menurows, nitems,
items, &focusitem);
- print_menu_items(output, nitems, items, focusitem);
+ print_menu_items(output, nitems, items, focusitem, true);
free(items);
@@ -1233,23 +1435,17 @@ int radiolist_builder(BUILDER_ARGS)
unsigned int menurows, nitems;
struct bsddialog_menuitem *items;
- if (argc < 1) {
- strcpy(errbuf, "<menurows> not provided");
- return (BSDDIALOG_ERROR);
- }
-
+ if (argc < 1)
+ exit_error("--radiolist missing <menurows>", true);
menurows = (u_int)strtoul(argv[0], NULL, 10);
- output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_opt,
- item_depth_opt, true, true, true, item_bottomdesc_opt, &nitems,
- &items, &focusitem);
- if (output != 0)
- return (output);
+ get_menu_items(argc-1, argv+1, item_prefix_opt, item_depth_opt, true,
+ true, true, item_bottomdesc_opt, &nitems, &items, &focusitem);
output = bsddialog_radiolist(conf, text, rows, cols, menurows, nitems,
items, &focusitem);
- print_menu_items(output, nitems, items, focusitem);
+ print_menu_items(output, nitems, items, focusitem, false);
free(items);
@@ -1262,18 +1458,12 @@ int treeview_builder(BUILDER_ARGS)
unsigned int menurows, nitems;
struct bsddialog_menuitem *items;
- if (argc < 1) {
- strcpy(errbuf, "<menurows> not provided");
- return (BSDDIALOG_ERROR);
- }
-
+ if (argc < 1)
+ exit_error("--treeview missing <menurows>", true);
menurows = (u_int)strtoul(argv[0], NULL, 10);
- output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_opt,
- true, true, true, true, item_bottomdesc_opt, &nitems, &items,
- &focusitem);
- if (output != 0)
- return (output);
+ get_menu_items(argc-1, argv+1, item_prefix_opt, true, true, true, true,
+ item_bottomdesc_opt, &nitems, &items, &focusitem);
conf->menu.no_name = true;
conf->menu.align_left = true;
@@ -1281,7 +1471,7 @@ int treeview_builder(BUILDER_ARGS)
output = bsddialog_radiolist(conf, text, rows, cols, menurows, nitems,
items, &focusitem);
- print_menu_items(output, nitems, items, focusitem);
+ print_menu_items(output, nitems, items, focusitem, false);
free(items);
@@ -1289,18 +1479,6 @@ int treeview_builder(BUILDER_ARGS)
}
/* FORM */
-static int
-alloc_formitems(int nitems, struct bsddialog_formitem **items, char *errbuf)
-{
- *items = calloc(nitems, sizeof(struct bsddialog_formitem));
- if (items == NULL) {
- strcpy(errbuf, "cannot allocate memory for form items\n");
- return (BSDDIALOG_ERROR);
- }
-
- return (BSDDIALOG_OK);
-}
-
static void
print_form_items(int output, int nitems, struct bsddialog_formitem *items)
{
@@ -1321,20 +1499,19 @@ int form_builder(BUILDER_ARGS)
unsigned int i, j, flags, formheight, nitems, sizeitem;
struct bsddialog_formitem *items;
- sizeitem = item_bottomdesc_opt ? 9 : 8;
- if (argc < 1 || (argc - 1) % sizeitem != 0) {
- strcpy(errbuf, "bad number of arguments for this form\n");
- return (BSDDIALOG_ERROR);
- }
-
+ if (argc < 1)
+ exit_error("--form missing <formheight>", true);
formheight = (u_int)strtoul(argv[0], NULL, 10);
argc--;
argv++;
+ sizeitem = item_bottomdesc_opt ? 9 : 8;
+ if (argc % sizeitem != 0)
+ exit_error("--form bad number of arguments items", true);
nitems = argc / sizeitem;
- if (alloc_formitems(nitems, &items, errbuf) != BSDDIALOG_OK)
- return (BSDDIALOG_ERROR);
+ if ((items = calloc(nitems, sizeof(struct bsddialog_formitem))) == NULL)
+ exit_error("cannot allocate memory for form items", false);
j = 0;
for (i = 0; i < nitems; i++) {
items[i].label = argv[j++];
@@ -1369,6 +1546,9 @@ int inputbox_builder(BUILDER_ARGS)
int output;
struct bsddialog_formitem item;
+ if (argc > 1)
+ error_args("--inputbox", argc - 1, argv + 1);
+
item.label = "";
item.ylabel = 0;
item.xlabel = 0;
@@ -1376,7 +1556,7 @@ int inputbox_builder(BUILDER_ARGS)
item.yfield = 0;
item.xfield = 0;
item.fieldlen = 1;
- item.maxvaluelen = max_input_form_opt > 0 ? max_input_form_opt : 2048;
+ item.maxvaluelen = max_input_form_opt;
item.flags = BSDDIALOG_FIELDNOCOLOR;
item.flags |= BSDDIALOG_FIELDCURSOREND;
item.flags |= BSDDIALOG_FIELDEXTEND;
@@ -1394,20 +1574,19 @@ int mixedform_builder(BUILDER_ARGS)
unsigned int i, j, formheight, nitems, sizeitem;
struct bsddialog_formitem *items;
- sizeitem = item_bottomdesc_opt ? 10 : 9;
- if (argc < 1 || (argc-1) % sizeitem != 0) {
- strcpy(errbuf, "bad number of arguments for this form\n");
- return (BSDDIALOG_ERROR);
- }
-
+ if (argc < 1)
+ exit_error("--mixedform missing <formheight>", true);
formheight = (u_int)strtoul(argv[0], NULL, 10);
argc--;
argv++;
+ sizeitem = item_bottomdesc_opt ? 10 : 9;
+ if (argc % sizeitem != 0)
+ exit_error("--mixedform bad number of arguments items", true);
nitems = argc / sizeitem;
- if (alloc_formitems(nitems, &items, errbuf) != BSDDIALOG_OK)
- return (BSDDIALOG_ERROR);
+ if ((items = calloc(nitems, sizeof(struct bsddialog_formitem))) == NULL)
+ exit_error("cannot allocate memory for form items", false);
j = 0;
for (i = 0; i < nitems; i++) {
items[i].label = argv[j++];
@@ -1435,6 +1614,9 @@ int passwordbox_builder(BUILDER_ARGS)
int output;
struct bsddialog_formitem item;
+ if (argc > 1)
+ error_args("--passwordbox", argc - 1, argv + 1);
+
item.label = "";
item.ylabel = 0;
item.xlabel = 0;
@@ -1442,7 +1624,7 @@ int passwordbox_builder(BUILDER_ARGS)
item.yfield = 0;
item.xfield = 0;
item.fieldlen = 1;
- item.maxvaluelen = max_input_form_opt > 0 ? max_input_form_opt : 2048;
+ item.maxvaluelen = max_input_form_opt;
item.flags = BSDDIALOG_FIELDHIDDEN;
item.flags |= BSDDIALOG_FIELDNOCOLOR;
item.flags |= BSDDIALOG_FIELDCURSOREND;
@@ -1461,21 +1643,20 @@ int passwordform_builder(BUILDER_ARGS)
unsigned int i, j, flags, formheight, nitems, sizeitem;
struct bsddialog_formitem *items;
- sizeitem = item_bottomdesc_opt ? 9 : 8;
- if (argc < 1 || (argc - 1) % sizeitem != 0) {
- strcpy(errbuf, "bad number of arguments for this form\n");
- return (BSDDIALOG_ERROR);
- }
-
+ if (argc < 1)
+ exit_error("--passwordform missing <formheight>", true);
formheight = (u_int)strtoul(argv[0], NULL, 10);
- flags = BSDDIALOG_FIELDHIDDEN;
argc--;
argv++;
+ sizeitem = item_bottomdesc_opt ? 9 : 8;
+ if (argc % sizeitem != 0)
+ exit_error("--passwordform bad arguments items number", true);
+ flags = BSDDIALOG_FIELDHIDDEN;
nitems = argc / sizeitem;
- if (alloc_formitems(nitems, &items, errbuf) != BSDDIALOG_OK)
- return (BSDDIALOG_ERROR);
+ if ((items = calloc(nitems, sizeof(struct bsddialog_formitem))) == NULL)
+ exit_error("cannot allocate memory for form items", false);
j = 0;
for (i = 0; i < nitems; i++) {
items[i].label = argv[j++];
diff --git a/examples_library/calendar.c b/examples_library/calendar.c
new file mode 100644
index 000000000000..33e38c69a81b
--- /dev/null
+++ b/examples_library/calendar.c
@@ -0,0 +1,55 @@
+/*-
+ * SPDX-License-Identifier: CC0-1.0
+ *
+ * Written in 2022 by Alfonso Sabato Siciliano.
+ * To the extent possible under law, the author has dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty, see:
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <bsddialog.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+int main()
+{
+ int output;
+ unsigned int yy, mm, dd;
+ struct bsddialog_conf conf;
+ time_t cal;
+ struct tm *localtm;
+
+ time(&cal);
+ localtm = localtime(&cal);
+ yy = localtm->tm_year + 1900;
+ mm = localtm->tm_mon + 1;
+ dd = localtm->tm_mday;
+
+ if (bsddialog_init() == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
+ bsddialog_initconf(&conf);
+ conf.title = "calendar";
+ output = bsddialog_calendar(&conf, "Example", 18, 40, &yy, &mm, &dd);
+
+ bsddialog_end();
+
+ switch (output) {
+ case BSDDIALOG_OK:
+ printf("Date: %u/%u/%u", yy, mm, dd);
+ break;
+ case BSDDIALOG_CANCEL:
+ printf("Cancel");
+ break;
+ case BSDDIALOG_ERROR:
+ printf("Error: %s", bsddialog_geterror());
+ break;
+ }
+ printf("\n");
+
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/compile b/examples_library/compile
index 6f2c23b8ca75..4cb6d23bd6a6 100755
--- a/examples_library/compile
+++ b/examples_library/compile
@@ -10,7 +10,7 @@
libpath=../lib
examples="menu checklist radiolist mixedlist theme infobox yesno msgbox \
- datebox form timebox rangebox pause"
+ datebox form timebox rangebox pause calendar"
rm -f $examples
diff --git a/examples_library/form.c b/examples_library/form.c
index 56d8a8052a72..4780fb68d121 100644
--- a/examples_library/form.c
+++ b/examples_library/form.c
@@ -27,7 +27,7 @@ int main()
{"Password:", 2, 0, "", 2, 10, 30, 50, NULL, H, "desc 3"}
};
- /* Optional, unless for unicode/multicolum charachters */
+ /* Optional, unless for unicode/multi-column characters */
setlocale(LC_ALL, "");
if (bsddialog_init() == BSDDIALOG_ERROR) {
@@ -56,4 +56,4 @@ int main()
}
return (output);
-} \ No newline at end of file
+}
diff --git a/examples_utility/calendar.sh b/examples_utility/calendar.sh
new file mode 100644
index 000000000000..a7ce4f1bb1d5
--- /dev/null
+++ b/examples_utility/calendar.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#-
+# SPDX-License-Identifier: CC0-1.0
+#
+# Written in 2022 by Alfonso Sabato Siciliano.
+#
+# To the extent possible under law, the author has dedicated all copyright
+# and related and neighboring rights to this software to the public domain
+# worldwide. This software is distributed without any warranty, see:
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
+
+: ${BSDDIALOG_ERROR=255}
+: ${BSDDIALOG_OK=0}
+: ${BSDDIALOG_CANCEL=1}
+: ${BSDDIALOG_ESC=5}
+
+DATE=$(./bsddialog --title " calendar " --date-format "%x" \
+ --calendar "Hello World!" 20 40 \
+3>&1 1>&2 2>&3 3>&-)
+
+case $? in
+ $BSDDIALOG_ERROR )
+ exit 1
+ ;;
+ $BSDDIALOG_ESC )
+ echo "[ESC]"
+ ;;
+ $BSDDIALOG_CANCEL )
+ echo "[Cancel]"
+ ;;
+ $BSDDIALOG_OK )
+ echo "[OK] $DATE"
+ ;;
+esac
diff --git a/examples_utility/timebox.sh b/examples_utility/timebox.sh
index 81d24d558dc9..233434b29195 100755
--- a/examples_utility/timebox.sh
+++ b/examples_utility/timebox.sh
@@ -14,8 +14,7 @@
: ${BSDDIALOG_CANCEL=1}
: ${BSDDIALOG_ESC=5}
-TIME=$(./bsddialog --title " timebox " \
- --timebox "Tab / Left / Right to move\nUp / Down to select" 10 40 \
+TIME=$(./bsddialog --title " timebox " --timebox "Hello World!" 8 25 \
3>&1 1>&2 2>&3 3>&-)
case $? in
diff --git a/lib/GNUMakefile b/lib/GNUMakefile
index 1d55d6edd60d..3c31c78fdf88 100644
--- a/lib/GNUMakefile
+++ b/lib/GNUMakefile
@@ -3,15 +3,15 @@
#
# Written in 2021 by Alfonso Sabato Siciliano
-VERSION = 0.3
+VERSION = 0.4
LIBRARY = bsddialog
LIBRARY_SO = lib${LIBRARY:=.so}
HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
-SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \
- messagebox.c textbox.c theme.c timebox.c
+SOURCES = barbox.c calendarbox.c formbox.c infobox.c libbsddialog.c \
+ lib_util.c menubox.c messagebox.c textbox.c theme.c timebox.c
OBJECTS = $(SOURCES:.c=.o)
-CFLAGS = -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE -D_GNU_SOURCE -Wall -Wextra -Wno-implicit-fallthrough \
- -Werror -fpic
+CFLAGS = -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE -D_GNU_SOURCE -Wall -Wextra \
+ -Wno-implicit-fallthrough -Werror -fpic
LDFLAGS = -lncursesw -ltinfo
LIBFLAG = -shared
diff --git a/lib/Makefile b/lib/Makefile
index 5c535c5483f1..0f536fb38743 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -3,13 +3,13 @@
#
# Written in 2021 by Alfonso Sabato Siciliano
-VERSION = 0.3
+VERSION = 0.4
LIBRARY = bsddialog
LIBRARY_SO = lib${LIBRARY:=.so}
LIBRARY_A = lib${LIBRARY:=.a}
HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
-SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \
- messagebox.c textbox.c theme.c timebox.c
+SOURCES = barbox.c calendarbox.c formbox.c infobox.c libbsddialog.c \
+ lib_util.c menubox.c messagebox.c textbox.c theme.c timebox.c
OBJECTS = ${SOURCES:.c=.o}
CFLAGS += -D_XOPEN_SOURCE_EXTENDED -fPIC -Wall -Wextra
LDFLAGS += -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \
diff --git a/lib/barbox.c b/lib/barbox.c
index b6bfe32fc0aa..71759839a709 100644
--- a/lib/barbox.c
+++ b/lib/barbox.c
@@ -327,7 +327,7 @@ do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
wrefresh(bar);
- /* getch(); port ncurses shows nothing */
+ /* getch(); alternate mode (port devel/ncurses) shows nothing */
delwin(bar);
end_dialog(conf, shadow, widget, textpad);
diff --git a/lib/bsddialog.3 b/lib/bsddialog.3
index 12db1f039d59..9cc68a90ff62 100644
--- a/lib/bsddialog.3
+++ b/lib/bsddialog.3
@@ -22,11 +22,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 29, 2022
+.Dd September 23, 2022
.Dt BSDDIALOG 3
.Os
.Sh NAME
.Nm bsddialog_backtitle ,
+.Nm bsddialog_calendar ,
.Nm bsddialog_clearterminal ,
.Nm bsddialog_color ,
.Nm bsddialog_color_attrs ,
@@ -62,6 +63,16 @@
.Ft int
.Fn bsddialog_backtitle "struct bsddialog_conf *conf" "const char *backtitle"
.Ft int
+.Fo bsddialog_calendar
+.Fa "struct bsddialog_conf *conf"
+.Fa "const char *text"
+.Fa "int rows"
+.Fa "int cols"
+.Fa "unsigned int *yy"
+.Fa "unsigned int *mm"
+.Fa "unsigned int *dd"
+.Fc
+.Ft int
.Fo bsddialog_checklist
.Fa "struct bsddialog_conf *conf"
.Fa "const char *text"
@@ -75,7 +86,7 @@
.Ft int
.Fn bsddialog_clearterminal "void"
.Ft int
-.Fo bsddialog_datebox"
+.Fo bsddialog_datebox
.Fa "struct bsddialog_conf *conf"
.Fa "const char *text"
.Fa "int rows"
@@ -476,7 +487,8 @@ function.
buttons always active, avoidind focus switch between buttons and input fields or
input boxes in
.Fn bsddialog_form ,
-.Fn bsddialog_datebox
+.Fn bsddialog_datebox ,
+.Fn bsddialog_calendar
and
.Fn bsddialog_timebox .
.It Fa conf.button.without_ok
@@ -515,7 +527,10 @@ to true,
and
.Fa conf.x
to
-.Dv BSDDIALOG_CENTER .
+.Dv BSDDIALOG_CENTER ,
+.Fa conf.text.cols_per_row
+to
+.Dv 10 .
.Pp
.Fn bsddialog_infobox
builds a dialog without buttons and returns instantly.
@@ -531,8 +546,10 @@ builds a dialog waiting until the timeout in
.Fa seconds
expires or a button is pressed.
.Pp
+.Fn bsddialog_calendar
+and
.Fn bsddialog_datebox
-builds a dialog to select a date,
+build a dialog to select a date,
.Fa yy ,
.Fa mm ,
and
@@ -606,14 +623,14 @@ builds a dialog with collections of checklists, radiolists and separators.
A collection is a set defined like:
.Pp
.Bd -literal -offset indent -compact
-enum bsddialog_grouptype {
+enum bsddialog_menutype {
BSDDIALOG_CHECKLIST,
BSDDIALOG_RADIOLIST,
BSDDIALOG_SEPARATOR,
};
struct bsddialog_menugroup {
- enum bsddialog_grouptype type;
+ enum bsddialog_menutype type;
unsigned int nitems;
struct bsddialog_menuitem *items;
};
@@ -1013,7 +1030,7 @@ struct bsddialog_menuitem check[2] = {
struct bsddialog_menuitem sep[1] = {
{ "3", true, 0, "Radiolist", "(desc)", "" }
};
-struct bsddialog_menuitem radio[5] = {
+struct bsddialog_menuitem radio[2] = {
{ "4", true, 0, "Name 1", "Desc 1", "Radio Bottom Desc 1" },
{ "5", false, 0, "Name 2", "Desc 2", "Radio Bottom Desc 2" }
};
diff --git a/lib/bsddialog.h b/lib/bsddialog.h
index 6f13da3fa667..ce6aac6d4632 100644
--- a/lib/bsddialog.h
+++ b/lib/bsddialog.h
@@ -30,7 +30,7 @@
#include <stdbool.h>
-#define LIBBSDDIALOG_VERSION "0.3"
+#define LIBBSDDIALOG_VERSION "0.4"
/* Exit status */
#define BSDDIALOG_ERROR -1
@@ -136,14 +136,14 @@ struct bsddialog_menuitem {
const char *bottomdesc;
};
-enum bsddialog_grouptype {
+enum bsddialog_menutype {
BSDDIALOG_CHECKLIST,
BSDDIALOG_RADIOLIST,
BSDDIALOG_SEPARATOR,
};
struct bsddialog_menugroup {
- enum bsddialog_grouptype type;
+ enum bsddialog_menutype type;
unsigned int nitems;
struct bsddialog_menuitem *items;
};
@@ -174,6 +174,10 @@ const char *bsddialog_geterror(void);
/* Dialogs */
int
+bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd);
+
+int
bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows,
int cols, unsigned int menurows, unsigned int nitems,
struct bsddialog_menuitem *items, int *focusitem);
diff --git a/lib/calendarbox.c b/lib/calendarbox.c
new file mode 100644
index 000000000000..3b55b26a13b8
--- /dev/null
+++ b/lib/calendarbox.c
@@ -0,0 +1,520 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Alfonso Sabato Siciliano
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+
+#include <curses.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bsddialog.h"
+#include "bsddialog_theme.h"
+#include "lib_util.h"
+
+#define MINHCAL 13
+#define MINWCAL 36 /* 34 calendar, 1 + 1 margins */
+#define MINYEAR 1900
+#define MAXYEAR 999999999
+
+static int month_days(int yy, int mm)
+{
+ int days;
+
+ if (mm == 2)
+ days = ISLEAP(yy) ? 29 : 28;
+ else if (mm == 4 || mm == 6 || mm == 9 || mm == 11)
+ days = 30;
+ else
+ days = 31;
+
+ return (days);
+}
+
+enum operation {
+ UP_DAY,
+ DOWN_DAY,
+ LEFT_DAY,
+ RIGHT_DAY,
+ UP_MONTH,
+ DOWN_MONTH,
+ UP_YEAR,
+ DOWN_YEAR
+};
+
+static void datectl(enum operation op, int *yy, int *mm, int *dd)
+{
+ int ndays;
+
+ ndays = month_days(*yy, *mm);
+
+ switch (op) {
+ case UP_DAY:
+ if (*dd > 7)
+ *dd -= 7;
+ else {
+ if (*mm == 1) {
+ *yy -= 1;
+ *mm = 12;
+ } else
+ *mm -= 1;
+ ndays = month_days(*yy, *mm);
+ *dd = ndays - abs(7 - *dd);
+ }
+ break;
+ case DOWN_DAY:
+ if (*dd + 7 < ndays)
+ *dd += 7;
+ else {
+ if (*mm == 12) {
+ *yy += 1;
+ *mm = 1;
+ } else
+ *mm += 1;
+ *dd = *dd + 7 - ndays;
+ }
+ break;
+ case LEFT_DAY:
+ if (*dd > 1)
+ *dd -= 1;
+ else {
+ if (*mm == 1) {
+ *yy -= 1;
+ *mm = 12;
+ } else
+ *mm -= 1;
+ *dd = month_days(*yy, *mm);
+ }
+ break;
+ case RIGHT_DAY:
+ if (*dd < ndays)
+ *dd += 1;
+ else {
+ if (*mm == 12) {
+ *yy += 1;
+ *mm = 1;
+ } else
+ *mm += 1;
+ *dd = 1;
+ }
+ break;
+ case UP_MONTH:
+ if (*mm == 1) {
+ *mm = 12;
+ *yy -= 1;
+ } else
+ *mm -= 1;
+ ndays = month_days(*yy, *mm);
+ if (*dd > ndays)
+ *dd = ndays;
+ break;
+ case DOWN_MONTH:
+ if (*mm == 12) {
+ *mm = 1;
+ *yy += 1;
+ } else
+ *mm += 1;
+ ndays = month_days(*yy, *mm);
+ if (*dd > ndays)
+ *dd = ndays;
+ break;
+ case UP_YEAR:
+ *yy -= 1;
+ ndays = month_days(*yy, *mm);
+ if (*dd > ndays)
+ *dd = ndays;
+ break;
+ case DOWN_YEAR:
+ *yy += 1;
+ ndays = month_days(*yy, *mm);
+ if (*dd > ndays)
+ *dd = ndays;
+ break;
+ }
+
+ if (*yy < MINYEAR) {
+ *yy = MINYEAR;
+ *mm = 1;
+ *dd = 1;
+ }
+ if (*yy > MAXYEAR) {
+ *yy = MAXYEAR;
+ *mm = 12;
+ *dd = 31;
+ }
+}
+
+static int week_day(int yy, int mm, int dd)
+{
+ int wd;
+
+ dd += mm < 3 ? yy-- : yy - 2;
+ wd = 23*mm/9 + dd + 4 + yy/4 - yy/100 + yy/400;
+ wd %= 7;
+
+ return (wd);
+}
+
+static void
+print_calendar(struct bsddialog_conf *conf, WINDOW *win, int yy, int mm, int dd,
+ bool active)
+{
+ int ndays, i, y, x, wd, h, w;
+
+ getmaxyx(win, h, w);
+ wclear(win);
+ draw_borders(conf, win, h, w, RAISED);
+ if (active) {
+ wattron(win, t.dialog.arrowcolor);
+ mvwhline(win, 0, 15, conf->ascii_lines ? '^' : ACS_UARROW, 4);
+ mvwhline(win, h-1, 15, conf->ascii_lines ? 'v' : ACS_DARROW, 4);
+ mvwvline(win, 3, 0, conf->ascii_lines ? '<' : ACS_LARROW, 3);
+ mvwvline(win, 3, w-1, conf->ascii_lines ? '>' : ACS_RARROW, 3);
+ wattroff(win, t.dialog.arrowcolor);
+ }
+
+ mvwaddstr(win, 1, 5, "Sun Mon Tue Wed Thu Fri Sat");
+ ndays = month_days(yy, mm);
+ y = 2;
+ wd = week_day(yy, mm, 1);
+ for (i = 1; i <= ndays; i++) {
+ x = 5 + (4 * wd); /* x has to be 6 with week number */
+ wmove(win, y, x);
+ mvwprintw(win, y, x, "%2d", i);
+ if (i == dd) {
+ wattron(win, t.menu.f_namecolor);
+ mvwprintw(win, y, x, "%2d", i);
+ wattroff(win, t.menu.f_namecolor);
+ }
+ wd++;
+ if (wd > 6) {
+ wd = 0;
+ y++;
+ }
+ }
+
+ wrefresh(win);
+}
+
+static void
+drawsquare(struct bsddialog_conf *conf, WINDOW *win, const char *fmt,
+ const void *value, bool focus)
+{
+ int h, w;
+
+ getmaxyx(win, h, w);
+ draw_borders(conf, win, h, w, RAISED);
+ if (focus) {
+ wattron(win, t.dialog.arrowcolor);
+ mvwhline(win, 0, 7, conf->ascii_lines ? '^' : ACS_UARROW, 3);
+ mvwhline(win, 2, 7, conf->ascii_lines ? 'v' : ACS_DARROW, 3);
+ wattroff(win, t.dialog.arrowcolor);
+ }
+
+ if (focus)
+ wattron(win, t.menu.f_namecolor);
+ if (strchr(fmt, 's') != NULL)
+ mvwprintw(win, 1, 1, fmt, (const char*)value);
+ else
+ mvwprintw(win, 1, 1, fmt, *((const int*)value));
+ if (focus)
+ wattroff(win, t.menu.f_namecolor);
+
+ wrefresh(win);
+}
+
+static int
+calendar_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
+ int *w, const char *text, struct buttons bs)
+{
+ int htext, wtext;
+
+ if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
+ if (text_size(conf, rows, cols, text, &bs, MINHCAL, MINWCAL,
+ &htext, &wtext) != 0)
+ return (BSDDIALOG_ERROR);
+ }
+
+ if (cols == BSDDIALOG_AUTOSIZE)
+ *w = widget_min_width(conf, wtext, MINWCAL, &bs);
+
+ if (rows == BSDDIALOG_AUTOSIZE)
+ *h = widget_min_height(conf, htext, MINHCAL, true);
+
+ return (0);
+}
+
+static int calendar_checksize(int rows, int cols, struct buttons bs)
+{
+ int mincols;
+
+ mincols = MAX(MINWCAL, buttons_min_width(bs));
+ mincols += VBORDERS;
+
+ if (cols < mincols)
+ RETURN_ERROR("Few cols for this calendar (at least 38)");
+
+ if (rows < MINHCAL + 2 + 2) /* 2 buttons + 2 borders */
+ RETURN_ERROR("Few rows for calendar (at least 17)");
+
+ return (0);
+}
+
+int
+bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd)
+{
+ bool loop, focusbuttons;
+ int retval, y, x, h, w, sel, ycal, xcal, year, month, day;
+ wint_t input;
+ WINDOW *widget, *textpad, *shadow, *yearwin, *monthwin, *daywin;
+ struct buttons bs;
+ const char *m[12] = {
+ "January", "February", "March", "April", "May", "June", "July",
+ "August", "September", "October", "November", "December"
+ };
+
+ if (yy == NULL || mm == NULL || dd == NULL)
+ RETURN_ERROR("yy / mm / dd cannot be NULL");
+
+ year = *yy > MAXYEAR ? MAXYEAR : *yy;
+ if (year < MINYEAR)
+ year = MINYEAR;
+ month = *mm > 12 ? 12 : *mm;
+ if (month == 0)
+ month = 1;
+ day = *dd == 0 ? 1 : *dd;
+ if(day > month_days(year, month))
+ day = month_days(year, month);
+
+ get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
+
+ if (set_widget_size(conf, rows, cols, &h, &w) != 0)
+ return (BSDDIALOG_ERROR);
+ if (calendar_autosize(conf, rows, cols, &h, &w, text, bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (calendar_checksize(h, w, bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (set_widget_position(conf, &y, &x, h, w) != 0)
+ return (BSDDIALOG_ERROR);
+
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
+ true) != 0)
+ return (BSDDIALOG_ERROR);
+
+ pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-17, x+w-2);
+ doupdate();
+
+ ycal = y + h - 15;
+ xcal = x + w/2 - 17;
+ mvwaddstr(widget, h - 16, w/2 - 17, "Month");
+ monthwin = new_boxed_window(conf, ycal, xcal, 3, 17, RAISED);
+ mvwaddstr(widget, h - 16, w/2, "Year");
+ yearwin = new_boxed_window(conf, ycal, xcal + 17, 3, 17, RAISED);
+ daywin = new_boxed_window(conf, ycal + 3, xcal, 9, 34, RAISED);
+
+ wrefresh(widget);
+
+ sel = -1;
+ loop = focusbuttons = true;
+ while (loop) {
+ drawsquare(conf, monthwin, "%15s", m[month - 1], sel == 0);
+ drawsquare(conf, yearwin, "%15d", &year, sel == 1);
+ print_calendar(conf, daywin, year, month, day, sel == 2);
+
+ if (get_wch(&input) == ERR)
+ continue;
+ switch(input) {
+ case KEY_ENTER:
+ case 10: /* Enter */
+ if (focusbuttons || conf->button.always_active) {
+ retval = bs.value[bs.curr];
+ loop = false;
+ }
+ break;
+ case 27: /* Esc */
+ if (conf->key.enable_esc) {
+ retval = BSDDIALOG_ESC;
+ loop = false;
+ }
+ break;
+ case '\t': /* TAB */
+ if (focusbuttons) {
+ bs.curr++;
+ if (bs.curr >= (int)bs.nbuttons) {
+ focusbuttons = false;
+ sel = 0;
+ bs.curr = conf->button.always_active ?
+ 0 : -1;
+ }
+ } else {
+ sel++;
+ if (sel > 2) {
+ focusbuttons = true;
+ sel = -1;
+ bs.curr = 0;
+ }
+ }
+ draw_buttons(widget, bs, true);
+ wrefresh(widget);
+ break;
+ case KEY_RIGHT:
+ if (focusbuttons) {
+ bs.curr++;
+ if (bs.curr >= (int)bs.nbuttons) {
+ focusbuttons = false;
+ sel = 0;
+ bs.curr = conf->button.always_active ?
+ 0 : -1;
+ }
+ } else if (sel == 2) {
+ datectl(RIGHT_DAY, &year, &month, &day);
+ } else { /* Month or Year*/
+ sel++;
+ }
+ draw_buttons(widget, bs, true);
+ wrefresh(widget);
+ break;
+ case KEY_LEFT:
+ if (focusbuttons) {
+ bs.curr--;
+ if (bs.curr < 0) {
+ focusbuttons = false;
+ sel = 2;
+ bs.curr = conf->button.always_active ?
+ 0 : -1;
+ }
+ } else if (sel == 2) {
+ datectl(LEFT_DAY, &year, &month, &day);
+ } else if (sel == 1) {
+ sel = 0;
+ } else { /* sel = 0, Month */
+ focusbuttons = true;
+ sel = -1;
+ bs.curr = 0;
+ }
+ draw_buttons(widget, bs, true);
+ wrefresh(widget);
+ break;
+ case KEY_UP:
+ if (focusbuttons) {
+ sel = 2;
+ focusbuttons = false;
+ bs.curr = conf->button.always_active ? 0 : -1;
+ draw_buttons(widget, bs, true);
+ wrefresh(widget);
+ } else if (sel == 0) {
+ datectl(UP_MONTH, &year, &month, &day);
+ } else if (sel == 1) {
+ datectl(UP_YEAR, &year, &month, &day);
+ } else { /* sel = 2 */
+ datectl(UP_DAY, &year, &month, &day);
+ }
+ break;
+ case KEY_DOWN:
+ if (focusbuttons) {
+ break;
+ } else if (sel == 0) {
+ datectl(DOWN_MONTH, &year, &month, &day);
+ } else if (sel == 1) {
+ datectl(DOWN_YEAR, &year, &month, &day);
+ } else { /* sel = 2 */
+ datectl(DOWN_DAY, &year, &month, &day);
+ }
+ break;
+ case KEY_HOME:
+ datectl(UP_MONTH, &year, &month, &day);
+ break;
+ case KEY_END:
+ datectl(DOWN_MONTH, &year, &month, &day);
+ break;
+ case KEY_PPAGE:
+ datectl(UP_YEAR, &year, &month, &day);
+ break;
+ case KEY_NPAGE:
+ datectl(DOWN_YEAR, &year, &month, &day);
+ break;
+ case KEY_F(1):
+ if (conf->key.f1_file == NULL &&
+ conf->key.f1_message == NULL)
+ break;
+ if (f1help(conf) != 0)
+ return (BSDDIALOG_ERROR);
+ /* No break, screen size can change */
+ case KEY_RESIZE:
+ /* Important for decreasing screen */
+ hide_widget(y, x, h, w, conf->shadow);
+ refresh();
+
+ if (set_widget_size(conf, rows, cols, &h, &w) != 0)
+ return (BSDDIALOG_ERROR);
+ if (calendar_autosize(conf, rows, cols, &h, &w, text,
+ bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (calendar_checksize(h, w, bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (set_widget_position(conf, &y, &x, h, w) != 0)
+ return (BSDDIALOG_ERROR);
+
+ if (update_dialog(conf, shadow, widget, y, x, h, w,
+ textpad, text, &bs, true) != 0)
+ return (BSDDIALOG_ERROR);
+ pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-17, x+w-2);
+ doupdate();
+
+ ycal = y + h - 15;
+ xcal = x + w/2 - 17;
+ mvwaddstr(widget, h - 16, w/2 - 17, "Month");
+ mvwin(monthwin, ycal, xcal);
+ mvwaddstr(widget, h - 16, w/2, "Year");
+ mvwin(yearwin, ycal, xcal + 17);
+ mvwin(daywin, ycal + 3, xcal);
+ wrefresh(widget);
+
+ /* Important to avoid grey lines expanding screen */
+ refresh();
+ break;
+ default:
+ if (shortcut_buttons(input, &bs)) {
+ retval = bs.value[bs.curr];
+ loop = false;
+ }
+ }
+ }
+
+ if (retval == BSDDIALOG_OK) {
+ *yy = year;
+ *mm = month;
+ *dd = day;
+ }
+
+ delwin(yearwin);
+ delwin(monthwin);
+ delwin(daywin);
+ end_dialog(conf, shadow, widget, textpad);
+
+ return (retval);
+} \ No newline at end of file
diff --git a/lib/formbox.c b/lib/formbox.c
index cd29919417be..5b1d2ab61de2 100644
--- a/lib/formbox.c
+++ b/lib/formbox.c
@@ -424,34 +424,25 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
} else
notext += *menurows;
- /* cols autosize, rows autosize, rows fullscreen, menu particularity */
- if (cols == BSDDIALOG_AUTOSIZE || rows <= BSDDIALOG_AUTOSIZE) {
- if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4,
- &htext, &wtext) != 0)
- return (BSDDIALOG_ERROR);
- }
+ if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4, &htext,
+ &wtext) != 0)
+ return (BSDDIALOG_ERROR);
if (cols == BSDDIALOG_AUTOSIZE)
*w = widget_min_width(conf, wtext, linelen + 4, &bs);
if (rows == BSDDIALOG_AUTOSIZE) {
- if (*menurows == 0) {
+ if (*menurows == BSDDIALOG_AUTOSIZE) {
menusize = widget_max_height(conf) - HBORDERS -
2 /*buttons*/ - htext;
menusize = MIN(menusize, nitems + 2);
*menurows = menusize - 2 < 0 ? 0 : menusize - 2;
- }
- else /* h autosize with fixed menurows */
+ } else /* h autosize with fixed menurows */
menusize = *menurows + 2;
*h = widget_min_height(conf, htext, menusize, true);
- /*
- * avoid menurows overflow and
- * with rows=AUTOSIZE menurows!=0 becomes max-menurows
- */
- *menurows = MIN(*h - 6 - htext, (int)*menurows);
- } else {
- if (*menurows == 0) {
+ } else { /* fixed rows */
+ if (*menurows == BSDDIALOG_AUTOSIZE) {
if (*h - 6 - htext <= 0)
*menurows = 0; /* form_checksize() will check */
else
@@ -459,6 +450,12 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
}
}
+ /* avoid menurows overflow and menurows becomes at most menurows */
+ if (*h - 6 - htext <= 0)
+ *menurows = 0; /* form_checksize() will check */
+ else
+ *menurows = MIN(*h - 6 - htext, (int)*menurows);
+
return (0);
}
diff --git a/lib/lib_util.c b/lib/lib_util.c
index fcdf4c3d8769..d8c0f1d21b42 100644
--- a/lib/lib_util.c
+++ b/lib/lib_util.c
@@ -921,11 +921,8 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
*h = maxheight;
else if (rows < BSDDIALOG_FULLSCREEN)
RETURN_ERROR("Negative (less than -1) height");
- else if (rows > BSDDIALOG_AUTOSIZE) {
- if ((*h = rows) > maxheight)
- RETURN_ERROR("Height too big (> terminal height - "
- "shadow)");
- }
+ else if (rows > BSDDIALOG_AUTOSIZE) /* fixed rows */
+ *h = MIN(rows, maxheight); /* rows is at most maxheight */
/* rows == AUTOSIZE: each widget has to set its size */
if ((maxwidth = widget_max_width(conf)) == BSDDIALOG_ERROR)
@@ -935,11 +932,8 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
*w = maxwidth;
else if (cols < BSDDIALOG_FULLSCREEN)
RETURN_ERROR("Negative (less than -1) width");
- else if (cols > BSDDIALOG_AUTOSIZE) {
- if ((*w = cols) > maxwidth)
- RETURN_ERROR("Width too big (> terminal width - "
- "shadow)");
- }
+ else if (cols > BSDDIALOG_AUTOSIZE) /* fixed cols */
+ *w = MIN(cols, maxwidth); /* cols is at most maxwidth */
/* cols == AUTOSIZE: each widget has to set its size */
return (0);
diff --git a/lib/lib_util.h b/lib/lib_util.h
index 238d3fda4675..17ea0e0d1368 100644
--- a/lib/lib_util.h
+++ b/lib/lib_util.h
@@ -43,6 +43,9 @@ extern bool hastermcolors;
refresh(); \
} while (0)
+/* date */
+#define ISLEAP(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
+
/* unicode */
unsigned int strcols(const char *mbstring);
int str_props(const char *mbstring, unsigned int *cols, bool *has_multi_col);
diff --git a/lib/libbsddialog.c b/lib/libbsddialog.c
index 1a8188b0e7d3..73c1f5c2dd57 100644
--- a/lib/libbsddialog.c
+++ b/lib/libbsddialog.c
@@ -99,7 +99,9 @@ int bsddialog_end(void)
int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle)
{
- mvaddstr(0, 1, backtitle);
+ move(0, 1);
+ clrtoeol();
+ addstr(backtitle);
if (conf->no_lines != true)
mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE,
SCREENCOLS - 2);
diff --git a/lib/menubox.c b/lib/menubox.c
index 28b9c8a0923b..bd06a9e37df2 100644
--- a/lib/menubox.c
+++ b/lib/menubox.c
@@ -36,7 +36,6 @@
#include "bsddialog_theme.h"
#include "lib_util.h"
-#define DEPTH 2
#define MIN_HEIGHT VBORDERS + 6 /* 2 buttons 1 text 3 menu */
enum menumode {
@@ -277,7 +276,7 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
colorname = focus ? t.menu.f_namecolor : t.menu.namecolor;
if (conf->menu.no_name == false) {
wattron(pad, colorname);
- mvwaddstr(pad, y, pos.xname + item->depth * DEPTH, item->name);
+ mvwaddstr(pad, y, pos.xname + item->depth, item->name);
wattroff(pad, colorname);
}
@@ -290,8 +289,7 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
if (conf->menu.no_desc == false) {
wattron(pad, colordesc);
if (conf->menu.no_name)
- mvwaddstr(pad, y, pos.xname + item->depth * DEPTH,
- item->desc);
+ mvwaddstr(pad, y, pos.xname + item->depth, item->desc);
else
mvwaddstr(pad, y, pos.xdesc, item->desc);
wattroff(pad, colordesc);
@@ -307,7 +305,7 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
mbtowc(&shortcut, item->desc, MB_CUR_MAX);
else
mbtowc(&shortcut, item->name, MB_CUR_MAX);
- mvwaddwch(pad, y, pos.xname + item->depth * DEPTH, shortcut);
+ mvwaddwch(pad, y, pos.xname + item->depth, shortcut);
wattroff(pad, colorshortcut);
}
@@ -362,34 +360,25 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
} else
notext += *menurows;
- /* cols autosize, rows autosize, rows fullscreen, menu particularity */
- if (cols == BSDDIALOG_AUTOSIZE || rows <= BSDDIALOG_AUTOSIZE) {
- if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4,
- &htext, &wtext) != 0)
- return (BSDDIALOG_ERROR);
- }
+ if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4, &htext,
+ &wtext) != 0)
+ return (BSDDIALOG_ERROR);
if (cols == BSDDIALOG_AUTOSIZE)
*w = widget_min_width(conf, wtext, linelen + 4, &bs);
if (rows == BSDDIALOG_AUTOSIZE) {
- if (*menurows == 0) {
+ if (*menurows == BSDDIALOG_AUTOSIZE) {
menusize = widget_max_height(conf) - HBORDERS -
2 /*buttons*/ - htext;
menusize = MIN(menusize, nitems + 2);
*menurows = menusize - 2 < 0 ? 0 : menusize - 2;
- }
- else /* h autosize with fixed menurows */
+ } else /* h autosize with fixed menurows */
menusize = *menurows + 2;
*h = widget_min_height(conf, htext, menusize, true);
- /*
- * avoid menurows overflow and
- * with rows=AUTOSIZE menurows!=0 becomes max-menurows
- */
- *menurows = MIN(*h - 6 - htext, (int)*menurows);
- } else {
- if (*menurows == 0) {
+ } else { /* fixed rows */
+ if (*menurows == BSDDIALOG_AUTOSIZE) {
if (*h - 6 - htext <= 0)
*menurows = 0; /* menu_checksize() will check */
else
@@ -397,6 +386,12 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
}
}
+ /* avoid menurows overflow and menurows becomes at most menurows */
+ if (*h - 6 - htext <= 0)
+ *menurows = 0; /* menu_checksize() will check */
+ else
+ *menurows = MIN(*h - 6 - htext, (int)*menurows);
+
return (0);
}
@@ -475,7 +470,6 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
}
pos.maxname = conf->menu.no_name ? 0 : pos.maxname;
pos.maxdesc = conf->menu.no_desc ? 0 : pos.maxdesc;
- pos.maxdepth = DEPTH * pos.maxdepth;
pos.xselector = pos.maxprefix + (pos.maxprefix != 0 ? 1 : 0);
pos.xname = pos.xselector + pos.selectorlen +
@@ -696,11 +690,15 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
movefocus = next != abs;
break;
case ' ': /* Space */
- if (pritems[abs].type == MENUMODE)
- break;
- else if (pritems[abs].type == CHECKLISTMODE)
+ if (pritems[abs].type == MENUMODE) {
+ retval = bs.value[bs.curr];
+ pritems[abs].on = true;
+ set_on_output(conf, retval, ngroups, groups,
+ pritems);
+ loop = false;
+ } else if (pritems[abs].type == CHECKLISTMODE) {
pritems[abs].on = !pritems[abs].on;
- else { /* RADIOLISTMODE */
+ } else { /* RADIOLISTMODE */
for (i = abs - pritems[abs].index;
i < totnitems &&
pritems[i].group == pritems[abs].group;
diff --git a/lib/messagebox.c b/lib/messagebox.c
index 06753be20c3d..7063ea9d273e 100644
--- a/lib/messagebox.c
+++ b/lib/messagebox.c
@@ -103,7 +103,7 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
struct buttons bs)
{
bool hastext, loop;
- int y, x, h, w, retval, ytextpad, htextpad, unused;
+ int y, x, h, w, retval, ytextpad, htextpad, printrows, unused;
WINDOW *widget, *textpad, *shadow;
wint_t input;
@@ -120,12 +120,13 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
true) != 0)
return (BSDDIALOG_ERROR);
+ printrows = h - 4;
ytextpad = 0;
getmaxyx(textpad, htextpad, unused);
unused++; /* fix unused error */
- textupdate(widget, textpad, htextpad, ytextpad, hastext);
loop = true;
while (loop) {
+ textupdate(widget, textpad, htextpad, ytextpad, hastext);
doupdate();
if (get_wch(&input) == ERR)
continue;
@@ -160,6 +161,30 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
wnoutrefresh(widget);
}
break;
+ case KEY_UP:
+ if (ytextpad > 0)
+ ytextpad--;
+ break;
+ case KEY_DOWN:
+ if (ytextpad + printrows < htextpad)
+ ytextpad++;
+ break;
+ case KEY_HOME:
+ ytextpad = 0;
+ break;
+ case KEY_END:
+ ytextpad = htextpad - printrows;
+ ytextpad = ytextpad < 0 ? 0 : ytextpad;
+ break;
+ case KEY_PPAGE:
+ ytextpad -= printrows;
+ ytextpad = ytextpad < 0 ? 0 : ytextpad;
+ break;
+ case KEY_NPAGE:
+ ytextpad += printrows;
+ if (ytextpad + printrows > htextpad)
+ ytextpad = htextpad - printrows;
+ break;
case KEY_F(1):
if (conf->key.f1_file == NULL &&
conf->key.f1_message == NULL)
@@ -186,6 +211,7 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
textpad, text, &bs, true) != 0)
return (BSDDIALOG_ERROR);
+ printrows = h - 4;
getmaxyx(textpad, htextpad, unused);
ytextpad = 0;
textupdate(widget, textpad, htextpad, ytextpad, hastext);
@@ -193,18 +219,6 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
/* Important to fix grey lines expanding screen */
refresh();
break;
- case KEY_UP:
- if (ytextpad == 0)
- break;
- ytextpad--;
- textupdate(widget, textpad, htextpad, ytextpad, hastext);
- break;
- case KEY_DOWN:
- if (ytextpad + h - 4 >= htextpad)
- break;
- ytextpad++;
- textupdate(widget, textpad, htextpad, ytextpad, hastext);
- break;
default:
if (shortcut_buttons(input, &bs)) {
retval = bs.value[bs.curr];
diff --git a/lib/theme.c b/lib/theme.c
index 40310d58cda4..6e53eb356825 100644
--- a/lib/theme.c
+++ b/lib/theme.c
@@ -258,7 +258,6 @@ int bsddialog_set_theme(struct bsddialog_theme *theme)
int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)
{
-
if (newtheme == BSDDIALOG_THEME_FLAT) {
bsddialog_set_theme(&dialogtheme);
t.dialog.lineraisecolor = t.dialog.linelowercolor;
diff --git a/lib/timebox.c b/lib/timebox.c
index 529563b49bca..53989bb97157 100644
--- a/lib/timebox.c
+++ b/lib/timebox.c
@@ -39,7 +39,7 @@
#define MINWTIME 14 /* 3 windows and their borders */
static void
-drawquare(struct bsddialog_conf *conf, WINDOW *win, const char *fmt,
+drawsquare(struct bsddialog_conf *conf, WINDOW *win, const char *fmt,
const void *value, bool focus)
{
int h, l, w;
@@ -167,7 +167,7 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
loop = focusbuttons = true;
while (loop) {
for (i = 0; i < 3; i++)
- drawquare(conf, c[i].win, "%02d", &c[i].value,
+ drawsquare(conf, c[i].win, "%02d", &c[i].value,
sel == i);
if (get_wch(&input) == ERR)
@@ -341,8 +341,6 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
{ "October", 31 }, { "November", 30 }, { "December", 31 }
};
-#define ISLEAF(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
-
for (i = 0 ; i < 3; i++) {
if (c[i].value > c[i].max)
c[i].value = c[i].max;
@@ -350,7 +348,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
c[i].value = 1;
}
c[2].max = m[c[1].value -1].days;
- if (c[1].value == 2 && ISLEAF(c[0].value))
+ if (c[1].value == 2 && ISLEAP(c[0].value))
c[2].max = 29;
if (c[2].value > c[2].max)
c[2].value = c[2].max;
@@ -385,10 +383,10 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
sel = -1;
loop = focusbuttons = true;
while (loop) {
- drawquare(conf, c[0].win, "%4d", &c[0].value, sel == 0);
- drawquare(conf, c[1].win, "%9s", m[c[1].value-1].name,
+ drawsquare(conf, c[0].win, "%4d", &c[0].value, sel == 0);
+ drawsquare(conf, c[1].win, "%9s", m[c[1].value-1].name,
sel == 1);
- drawquare(conf, c[2].win, "%02d", &c[2].value, sel == 2);
+ drawsquare(conf, c[2].win, "%02d", &c[2].value, sel == 2);
if (get_wch(&input) == ERR)
continue;
@@ -456,7 +454,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
/* if mount change */
c[2].max = m[c[1].value -1].days;
/* if year change */
- if (c[1].value == 2 && ISLEAF(c[0].value))
+ if (c[1].value == 2 && ISLEAP(c[0].value))
c[2].max = 29;
/* set new day */
if (c[2].value > c[2].max)
@@ -471,7 +469,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
/* if mount change */
c[2].max = m[c[1].value -1].days;
/* if year change */
- if (c[1].value == 2 && ISLEAF(c[0].value))
+ if (c[1].value == 2 && ISLEAP(c[0].value))
c[2].max = 29;
/* set new day */
if (c[2].value > c[2].max)
@@ -539,4 +537,4 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
end_dialog(conf, shadow, widget, textpad);
return (retval);
-}
+} \ No newline at end of file
diff --git a/util_theme.c b/util_theme.c
index e003e2c3d05f..caf62852e9f3 100644
--- a/util_theme.c
+++ b/util_theme.c
@@ -100,7 +100,7 @@ static struct property p[NPROPERTY] = {
{ "theme.button.f_shortcutcolor", COLOR, &t.button.f_shortcutcolor}
};
-static char *color[8] = {
+static const char *color[8] = {
"black",
"red",
"green",
@@ -111,7 +111,15 @@ static char *color[8] = {
"white"
};
-int savetheme(const char *file, char *errbuf, const char *version)
+#define EXIT_FMTERROR(fmt, ...) do { \
+ bsddialog_end(); \
+ printf("Error: "); \
+ printf(fmt, __VA_ARGS__); \
+ printf(".\n"); \
+ exit (255); \
+} while (0)
+
+void savetheme(const char *file, const char *version)
{
int i;
unsigned int flags;
@@ -119,20 +127,14 @@ int savetheme(const char *file, char *errbuf, const char *version)
time_t clock;
FILE *fp;
- if (bsddialog_get_theme(&t) != BSDDIALOG_OK) {
- sprintf(errbuf, "Cannot save theme: %s", bsddialog_geterror());
- return (BSDDIALOG_ERROR);
- }
+ if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
+ EXIT_FMTERROR("cannot save theme: %s", bsddialog_geterror());
- if(time(&clock) < 0) {
- sprintf(errbuf, "Cannot save profile (getting current time)");
- return (BSDDIALOG_ERROR);
- }
+ if(time(&clock) < 0)
+ EXIT_FMTERROR("%s", "cannot save profile getting current time");
- if ((fp = fopen(file, "w")) == NULL) {
- sprintf(errbuf, "Cannot open %s to save profile", file);
- return (BSDDIALOG_ERROR);
- }
+ if ((fp = fopen(file, "w")) == NULL)
+ EXIT_FMTERROR("cannot open %s to save profile", file);
fprintf(fp, "### bsddialog theme - %s", ctime(&clock));
fputs("# Refer to bsddialog(3) manual for theme.* properties\n", fp);
@@ -167,11 +169,15 @@ int savetheme(const char *file, char *errbuf, const char *version)
}
fclose(fp);
+}
- return (BSDDIALOG_OK);
+void setdeftheme(enum bsddialog_default_theme theme)
+{
+ if (bsddialog_set_default_theme(theme) != BSDDIALOG_OK)
+ EXIT_FMTERROR("%s", bsddialog_geterror());
}
-int loadtheme(const char *file, char *errbuf)
+void loadtheme(const char *file)
{
bool boolvalue;
char charvalue, *value;
@@ -181,21 +187,16 @@ int loadtheme(const char *file, char *errbuf)
enum bsddialog_color bg, fg;
FILE *fp;
- if (bsddialog_get_theme(&t) != BSDDIALOG_OK) {
- sprintf(errbuf, "Cannot get current theme: %s",
+ if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
+ EXIT_FMTERROR("Cannot get current theme: %s",
bsddialog_geterror());
- return (BSDDIALOG_ERROR);
- }
- if((fp = fopen(file, "r")) == NULL) {
- sprintf(errbuf, "Cannot open theme \"%s\"", file);
- return (BSDDIALOG_ERROR);
- }
+ if((fp = fopen(file, "r")) == NULL)
+ EXIT_FMTERROR("Cannot open theme \"%s\"", file);
-#define RETURN_ERROR(name, error) do { \
- sprintf(errbuf, "%s for \"%s\"", error, name); \
+#define EXIT_ERROR(name, error) do { \
fclose(fp); \
- return (BSDDIALOG_ERROR); \
+ EXIT_FMTERROR("%s for \"%s\"", error, name); \
} while (0)
while(fgets(line, BUFSIZ, fp) != NULL) {
@@ -211,7 +212,7 @@ int loadtheme(const char *file, char *errbuf)
if (i >= NPROPERTY) {
if (strcmp(name, "version") == 0)
continue;
- RETURN_ERROR(name, "Unknown theme property name");
+ EXIT_ERROR(name, "Unknown theme property name");
}
switch (p[i].type) {
case CHAR:
@@ -219,17 +220,17 @@ int loadtheme(const char *file, char *errbuf)
value[0] == '\0')
value++;
if (sscanf(value, "%c", &charvalue) != 1)
- RETURN_ERROR(p[i].name, "Cannot get a char");
+ EXIT_ERROR(p[i].name, "Cannot get a char");
*((int*)p[i].value) = charvalue;
break;
case INT:
if (sscanf(value, "%d", &intvalue) != 1)
- RETURN_ERROR(p[i].name, "Cannot get a int");
+ EXIT_ERROR(p[i].name, "Cannot get a int");
*((int*)p[i].value) = intvalue;
break;
case UINT:
if (sscanf(value, "%u", &uintvalue) != 1)
- RETURN_ERROR(p[i].name, "Cannot get a uint");
+ EXIT_ERROR(p[i].name, "Cannot get a uint");
*((unsigned int*)p[i].value) = uintvalue;
break;
case BOOL:
@@ -239,19 +240,19 @@ int loadtheme(const char *file, char *errbuf)
break;
case COLOR:
if (sscanf(value, "%s %s", c1, c2) != 2)
- RETURN_ERROR(p[i].name, "Cannot get 2 colors");
+ EXIT_ERROR(p[i].name, "Cannot get 2 colors");
/* Foreground */
for (j = 0; j < 8 ; j++)
if ((strstr(c1, color[j])) != NULL)
break;
if ((fg = j) > 7)
- RETURN_ERROR(p[i].name, "Bad foreground");
+ EXIT_ERROR(p[i].name, "Bad foreground");
/* Background */
for (j = 0; j < 8 ; j++)
if ((value = strstr(c2, color[j])) != NULL)
break;
if ((bg = j) > 7)
- RETURN_ERROR(p[i].name, "Bad background");
+ EXIT_ERROR(p[i].name, "Bad background");
/* Flags */
flags = 0;
if (strstr(value, "bold") != NULL)
@@ -268,11 +269,9 @@ int loadtheme(const char *file, char *errbuf)
fclose(fp);
bsddialog_set_theme(&t);
-
- return (BSDDIALOG_OK);
}
-int bikeshed(struct bsddialog_conf *conf, char *errbuf)
+void bikeshed(struct bsddialog_conf *conf)
{
int margin, i;
int colors[8] = {0, 0, 0, 0 ,0 ,0 , 0, 0};
@@ -284,7 +283,7 @@ int bikeshed(struct bsddialog_conf *conf, char *errbuf)
/* theme */
if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
- return (BSDDIALOG_ERROR);
+ EXIT_FMTERROR("%s", bsddialog_geterror());
for (i = 0; i < 6; i++) {
do {
@@ -339,7 +338,7 @@ int bikeshed(struct bsddialog_conf *conf, char *errbuf)
t.button.shortcutcolor = bsddialog_color(col[1], col[5], 0);
if (bsddialog_set_theme(&t))
- return (BSDDIALOG_ERROR);
+ EXIT_FMTERROR("%s", bsddialog_geterror());
/* conf */
conf->button.always_active = (rand() % 2 == 0) ? true : false;
@@ -351,6 +350,4 @@ int bikeshed(struct bsddialog_conf *conf, char *errbuf)
memset(title + strlen(title), ' ', margin);
conf->title = title;
}
-
- return (BSDDIALOG_OK);
}
diff --git a/util_theme.h b/util_theme.h
index fd9b32db1204..bf51447dfb2c 100644
--- a/util_theme.h
+++ b/util_theme.h
@@ -28,8 +28,9 @@
#ifndef _BSDDIALOG_UTILITY_THEME_H_
#define _BSDDIALOG_UTILITY_THEME_H_
-int savetheme(const char *file, char *errbuf, const char *version);
-int loadtheme(const char *file, char *errbuf);
-int bikeshed(struct bsddialog_conf *conf, char *errbuf);
+void savetheme(const char *file, const char *version);
+void loadtheme(const char *file);
+void setdeftheme(enum bsddialog_default_theme theme);
+void bikeshed(struct bsddialog_conf *conf);
#endif