puppylinux-woof-CE / gtkdialog

Script friendly gtk GUI builder
GNU General Public License v2.0
30 stars 18 forks source link

Allow shell input redirection `< /file` in action and input tags #127

Closed step- closed 2 years ago

step- commented 2 years ago

This is to fix one of my pet peeves with gtkdialog, that is, inside <action> and <input> tags the shell input redirection operator < triggers a syntax error and aborts gtkdialog.

Traditionally this limitation is worked around with shell pipes or temporary files. Take for example an action that aims at printing the line count of /etc/passwd as a bare number without further text. This command would do wc -l < /etc/passwd but when gtkdialog sees the command, e.g. <action>wc -l < /etc/passwd</action>, it prints "gtkdialog: Error in line 1, near token 'string': syntax error" and exits. So we must rewrite the command as <action>cat /etc/passwd | wc -l</action>, which forks an additional process. Enter this commit. Now shell input redirection is valid syntax, and gtkdialog keeps going. Bash <() and <<< is also valid syntax now.

Notes about this commit

  1. This syntax change is compatible with existing scripts simply because the new syntax could not be used before.
  2. This syntax change is only enabled within the context of <action> and <input> tags. It would be trivial to enable it for all tags but why?
  3. There must be at least one space between < and the / that follows because </ was and remains reserved for closing tags.

Test scriptlets

MAIN_DIALOG='<button><action>wc -l < /etc/passwd</action></button>' gtkdialog -c &
MAIN_DIALOG='<button><action>bash -c "wc -l <(cat /etc/passwd)"</action></button>' gtkdialog -c &
MAIN_DIALOG='<button><action>bash -c "wc -l <<< 12345"</action></button>' gtkdialog -c &
MAIN_DIALOG='<button><action>exec 3< /etc/passwd && wc -l <&3</action></button>' gtkdialog -c &
MAIN_DIALOG='<button><action>bash -c "x=\$(< /etc/passwd) && echo \${#x} characters"</action></button>' gtkdialog -c &

MAIN_DIALOG='<text><input>wc -l < /etc/passwd</input></text>' gtkdialog -c &

MAIN_DIALOG='<button><action>wc -l </etc/passwd</action></button>' gtkdialog -c &

MAIN_DIALOG='<button><action condition="command_is_true(wc -l < /etc/passwd >&2; echo true)">echo yes</action></button>' gtkdialog -c &

Notes about the gtkdialog lexer

  1. Line continuation with trailing backslash is not supported.
  2. Multiline string is only supported if double-quoted. Test with <edit><default>.
  3. Multiline string does not work in shell actions, that is, it's OK in <default> tags but not OK in shell <action> tags.
  4. Unquoted multiline string in <action> tag results in no action and no syntax error (subtle failure point).
  5. Double-quoted strings can include <. Quotes are passed to the underlying shell.
step- commented 2 years ago

Cool, thanks for merging!