1
0
mirror of https://github.com/irssi/irssi.git synced 2024-12-04 14:46:39 -05:00

Merge pull request #521 from ailin-nemui/ax_curses2

remove curses terminal and ncurses macro
This commit is contained in:
ailin-nemui 2016-08-11 15:41:12 +02:00 committed by GitHub
commit 61fa6eb35b
10 changed files with 19 additions and 1575 deletions

10
INSTALL
View File

@ -59,17 +59,11 @@ configure options
Build without text frontend
If ncurses is installed in a non-standard path you can specify it with
--with-ncurses=/path. If anything else is in non-standard path, you can just
give the paths in CPPFLAGS and LIBS environment variable, eg.:
If anything is in non-standard path, you can just give the paths in
CPPFLAGS and LIBS environment variable, eg.:
CPPFLAGS=-I/opt/openssl/include LDFLAGS=-L/opt/openssl/lib ./configure
Irssi doesn't really need curses anymore, by default it uses
terminfo/termcap directly. The functions for using terminfo/termcap
however are usually only in curses library, some systems use libtermcap
as well. If you want to use only curses calls for some reason, use
--without-terminfo.
Perl problems

1
NEWS
View File

@ -23,6 +23,7 @@ v0.8.20-head 2016-xx-xx The Irssi team <staff@irssi.org>
- IP addresses are no longer stored when resolve_reverse_lookup is
used.
- /names and $[...] now uses utf8 string operations (#40, #411).
- Removed broken support for curses.
v0.8.19 2016-03-23 The Irssi team <staff@irssi.org>
- Fixed regression when joining and parting channels on IRCnet (#435)

View File

@ -61,15 +61,6 @@ AC_ARG_WITH(proxy,
fi,
want_irssiproxy=no)
AC_ARG_WITH(terminfo,
[ --without-terminfo Use curses backend instead of terminfo],
if test x$withval = xno; then
want_terminfo=no
else
want_terminfo=yes
fi,
want_terminfo=yes)
AC_ARG_WITH(modules,
[ --with-modules Specify what modules to build in binary],
if test x$withval != xyes -a x$withval != xno; then
@ -314,45 +305,19 @@ dnl **
dnl ** curses checks
dnl **
if test "x$want_textui" = "xyes"; then
AC_CHECK_CURSES
if test "x$want_textui" != "xno"; then
TEXTUI_LIBS="$CURSES_LIBS"
if test "x$has_curses" = "xtrue"; then
old_libs=$LIBS
LIBS="$LIBS $CURSES_LIBS"
if test $want_terminfo = no; then
AC_CHECK_FUNC(use_default_colors, AC_DEFINE(HAVE_NCURSES_USE_DEFAULT_COLORS))
AC_CHECK_FUNC(idcok, AC_DEFINE(HAVE_CURSES_IDCOK))
AC_CHECK_FUNC(resizeterm, AC_DEFINE(HAVE_CURSES_RESIZETERM))
AC_CHECK_FUNC(wresize, AC_DEFINE(HAVE_CURSES_WRESIZE))
fi
AC_CHECK_FUNC(setupterm,, [
want_termcap=yes
])
LIBS=$old_libs
else
AC_CHECK_LIB(tinfo, setupterm, [
TEXTUI_LIBS="-ltinfo"
want_terminfo=yes
], AC_CHECK_LIB(termlib, tgetent, [
TEXTUI_LIBS="-ltermlib"
want_termcap=yes
], AC_CHECK_LIB(termcap, tgetent, [
TEXTUI_LIBS="-ltermcap"
want_termcap=yes
], [
AC_ERROR(Terminfo/termcap not found - install libncurses-dev or ncurses-devel package)
want_textui=no
])))
fi
TEXTUI_NO_LIBS="$LIBS"
LIBS=
AC_SEARCH_LIBS([setupterm], [tinfo ncursesw ncurses], [want_textui=yes], [
AC_ERROR(Terminfo not found - install libncurses-dev or ncurses-devel package)
want_textui="no, Terminfo not found"
])
TEXTUI_LIBS="$LIBS"
AC_SUBST(TEXTUI_LIBS)
LIBS="$TEXTUI_NO_LIBS"
if test "x$want_termcap" = "xyes"; then
AC_CHECK_FUNC(tparm,, need_tparm=yes)
else
AC_DEFINE(HAVE_TERMINFO)
fi
fi
dnl **
@ -516,8 +481,6 @@ AM_CONDITIONAL(BUILD_TEXTUI, test "$want_textui" = "yes")
AM_CONDITIONAL(BUILD_IRSSIBOT, test "$want_irssibot" = "yes")
AM_CONDITIONAL(BUILD_IRSSIPROXY, test "$want_irssiproxy" = "yes")
AM_CONDITIONAL(HAVE_PERL, test "$want_perl" != "no")
AM_CONDITIONAL(NEED_TPARM, test "$need_tparm" = "yes")
AM_CONDITIONAL(USE_CURSES, test "$want_terminfo" != "yes" -a "$want_termcap" != "yes")
# move LIBS to PROG_LIBS so they're not tried to be used when linking eg. perl libraries
PROG_LIBS=$LIBS
@ -614,30 +577,19 @@ if test "x$want_dane" = "xyes"; then
fi
fi
if test "x$want_truecolor" = "xyes" -a "x$want_termcap" != "xyes" -a "x$want_terminfo" = "xyes" ; then
if test "x$want_truecolor" = "xyes"; then
AC_DEFINE([TERM_TRUECOLOR], [], [true color support in terminal])
else
want_truecolor=no
fi
AH_TEMPLATE(HAS_CURSES, [macros/curses checks])
AH_TEMPLATE(HAVE_CURSES_IDCOK)
AH_TEMPLATE(HAVE_CURSES_RESIZETERM)
AH_TEMPLATE(HAVE_CURSES_WRESIZE)
AH_TEMPLATE(HAVE_GMODULE)
AH_TEMPLATE(HAVE_NCURSES_USE_DEFAULT_COLORS, [our own curses checks])
AH_TEMPLATE(HAVE_SOCKS_H, [misc..])
AH_TEMPLATE(HAVE_STATIC_PERL)
AH_TEMPLATE(HAVE_TERMINFO, [terminfo/termcap])
AH_TEMPLATE(NO_COLOR_CURSES)
AH_TEMPLATE(PRIuUOFF_T, [printf()-format for uoff_t, eg. "u" or "lu" or "llu"])
AH_TEMPLATE(SCO_FLAVOR)
AH_TEMPLATE(UOFF_T_INT, [What type should be used for uoff_t])
AH_TEMPLATE(UOFF_T_LONG)
AH_TEMPLATE(UOFF_T_LONG_LONG)
AH_TEMPLATE(USE_NCURSES)
AH_TEMPLATE(USE_SUNOS_CURSES)
AH_TEMPLATE(USE_SYSV_CURSES)
AC_CONFIG_FILES([
Makefile
@ -691,16 +643,7 @@ fi
echo
if test "x$want_textui" = "xno"; then
text=no
elif test "x$want_termcap" = "xyes"; then
text="yes, using termcap"
elif test "x$want_terminfo" = "xyes"; then
text="yes, using terminfo"
else
text="yes, using curses"
fi
echo "Building text frontend ........... : $text"
echo "Building text frontend ........... : $want_textui"
echo "Building irssi bot ............... : $want_irssibot"
echo "Building irssi proxy ............. : $want_irssiproxy"
if test "x$have_gmodule" = "xyes"; then

View File

@ -1,298 +0,0 @@
dnl Curses detection: Munged from Midnight Commander's configure.in
dnl
dnl What it does:
dnl =============
dnl
dnl - Determine which version of curses is installed on your system
dnl and set the -I/-L/-l compiler entries and add a few preprocessor
dnl symbols
dnl - Do an AC_SUBST on the CURSES_INCLUDEDIR and CURSES_LIBS so that
dnl @CURSES_INCLUDEDIR@ and @CURSES_LIBS@ will be available in
dnl Makefile.in's
dnl - Modify the following configure variables (these are the only
dnl curses.m4 variables you can access from within configure.in)
dnl CURSES_INCLUDEDIR - contains -I's and possibly -DRENAMED_CURSES if
dnl an ncurses.h that's been renamed to curses.h
dnl is found.
dnl CURSES_LIBS - sets -L and -l's appropriately
dnl CFLAGS - if --with-sco, add -D_SVID3
dnl has_curses - exports result of tests to rest of configure
dnl
dnl Usage:
dnl ======
dnl 1) Add lines indicated below to acconfig.h
dnl 2) call AC_CHECK_CURSES after AC_PROG_CC in your configure.in
dnl 3) Instead of #include <curses.h> you should use the following to
dnl properly locate ncurses or curses header file
dnl
dnl #if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)
dnl #include <ncurses.h>
dnl #else
dnl #include <curses.h>
dnl #endif
dnl
dnl 4) Make sure to add @CURSES_INCLUDEDIR@ to your preprocessor flags
dnl 5) Make sure to add @CURSES_LIBS@ to your linker flags or LIBS
dnl
dnl Notes with automake:
dnl - call AM_CONDITIONAL(HAS_CURSES, test "$has_curses" = true) from
dnl configure.in
dnl - your Makefile.am can look something like this
dnl -----------------------------------------------
dnl INCLUDES= blah blah blah $(CURSES_INCLUDEDIR)
dnl if HAS_CURSES
dnl CURSES_TARGETS=name_of_curses_prog
dnl endif
dnl bin_PROGRAMS = other_programs $(CURSES_TARGETS)
dnl other_programs_SOURCES = blah blah blah
dnl name_of_curses_prog_SOURCES = blah blah blah
dnl other_programs_LDADD = blah
dnl name_of_curses_prog_LDADD = blah $(CURSES_LIBS)
dnl -----------------------------------------------
dnl
dnl
dnl The following lines should be added to acconfig.h:
dnl ==================================================
dnl
dnl /*=== Curses version detection defines ===*/
dnl /* Found some version of curses that we're going to use */
dnl #undef HAS_CURSES
dnl
dnl /* Use SunOS SysV curses? */
dnl #undef USE_SUNOS_CURSES
dnl
dnl /* Use old BSD curses - not used right now */
dnl #undef USE_BSD_CURSES
dnl
dnl /* Use SystemV curses? */
dnl #undef USE_SYSV_CURSES
dnl
dnl /* Use Ncurses? */
dnl #undef USE_NCURSES
dnl
dnl /* If you Curses does not have color define this one */
dnl #undef NO_COLOR_CURSES
dnl
dnl /* Define if you want to turn on SCO-specific code */
dnl #undef SCO_FLAVOR
dnl
dnl /* Set to reflect version of ncurses *
dnl * 0 = version 1.*
dnl * 1 = version 1.9.9g
dnl * 2 = version 4.0/4.1 */
dnl #undef NCURSES_970530
dnl
dnl /*=== End new stuff for acconfig.h ===*/
dnl
AC_DEFUN([AC_CHECK_CURSES],[
search_ncurses=true
screen_manager=""
has_curses=false
CFLAGS=${CFLAGS--O}
AC_SUBST(CURSES_LIBS)
AC_SUBST(CURSES_INCLUDEDIR)
AC_ARG_WITH(sco,
[ --with-sco Use this to turn on SCO-specific code],[
if test x$withval = xyes; then
AC_DEFINE(SCO_FLAVOR)
CFLAGS="$CFLAGS -D_SVID3"
fi
])
AC_ARG_WITH(sunos-curses,
[ --with-sunos-curses Used to force SunOS 4.x curses],[
if test x$withval = xyes; then
AC_USE_SUNOS_CURSES
fi
])
AC_ARG_WITH(osf1-curses,
[ --with-osf1-curses Used to force OSF/1 curses],[
if test x$withval = xyes; then
AC_USE_OSF1_CURSES
fi
])
AC_ARG_WITH(vcurses,
[[ --with-vcurses[=incdir] Used to force SysV curses]],
if test x$withval != xyes; then
CURSES_INCLUDEDIR="-I$withval"
fi
AC_USE_SYSV_CURSES
)
AC_ARG_WITH(ncurses,
[[ --with-ncurses[=dir] Compile with ncurses/locate base dir]],
if test x$withval = xno ; then
search_ncurses=false
elif test x$withval != xyes ; then
AC_NCURSES($withval/include, ncurses.h, -L$withval/lib -lncurses, -I$withval/include, [ncurses on $withval/include])
fi
)
if $search_ncurses
then
AC_SEARCH_NCURSES()
fi
])
AC_DEFUN([AC_USE_SUNOS_CURSES], [
search_ncurses=false
screen_manager="SunOS 4.x /usr/5include curses"
AC_MSG_RESULT(Using SunOS 4.x /usr/5include curses)
AC_DEFINE(USE_SUNOS_CURSES)
AC_DEFINE(HAS_CURSES)
has_curses=true
AC_DEFINE(NO_COLOR_CURSES)
AC_DEFINE(USE_SYSV_CURSES)
CURSES_INCLUDEDIR="-I/usr/5include"
CURSES_LIBS="/usr/5lib/libcurses.a /usr/5lib/libtermcap.a"
AC_MSG_RESULT(Please note that some screen refreshs may fail)
])
AC_DEFUN([AC_USE_OSF1_CURSES], [
AC_MSG_RESULT(Using OSF1 curses)
search_ncurses=false
screen_manager="OSF1 curses"
AC_DEFINE(HAS_CURSES)
has_curses=true
AC_DEFINE(NO_COLOR_CURSES)
AC_DEFINE(USE_SYSV_CURSES)
CURSES_LIBS="-lcurses"
])
AC_DEFUN([AC_USE_SYSV_CURSES], [
AC_MSG_RESULT(Using SysV curses)
AC_DEFINE(HAS_CURSES)
has_curses=true
AC_DEFINE(USE_SYSV_CURSES)
search_ncurses=false
screen_manager="SysV/curses"
CURSES_LIBS="-lcurses"
])
dnl AC_ARG_WITH(bsd-curses,
dnl [--with-bsd-curses Used to compile with bsd curses, not very fancy],
dnl search_ncurses=false
dnl screen_manager="Ultrix/cursesX"
dnl if test $system = ULTRIX
dnl then
dnl THIS_CURSES=cursesX
dnl else
dnl THIS_CURSES=curses
dnl fi
dnl
dnl CURSES_LIBS="-l$THIS_CURSES -ltermcap"
dnl AC_DEFINE(HAS_CURSES)
dnl has_curses=true
dnl AC_DEFINE(USE_BSD_CURSES)
dnl AC_MSG_RESULT(Please note that some screen refreshs may fail)
dnl AC_WARN(Use of the bsdcurses extension has some)
dnl AC_WARN(display/input problems.)
dnl AC_WARN(Reconsider using xcurses)
dnl)
dnl
dnl Parameters: directory filename curses_LIBS curses_INCLUDEDIR nicename
dnl
AC_DEFUN([AC_NCURSES], [
if $search_ncurses
then
if test -f $1/$2
then
AC_MSG_RESULT(Found ncurses on $1/$2)
CURSES_LIBS="$3"
AC_CHECK_LIB(ncurses, initscr, [
true;
], [
CHECKLIBS=`echo "$3"|sed 's/-lncurses/-lcurses/g'`
AC_CHECK_LIB(curses, initscr, [
CURSES_LIBS="$CHECKLIBS"
],, $CHECKLIBS)
], $CURSES_LIBS)
CURSES_INCLUDEDIR="$4"
search_ncurses=false
screen_manager="$5"
AC_DEFINE(HAS_CURSES)
has_curses=true
has_ncurses=true
AC_DEFINE(USE_NCURSES)
fi
fi
])
AC_DEFUN([AC_SEARCH_NCURSES], [
AC_CHECKING("location of ncurses.h file")
AC_NCURSES(/usr/include, ncurses.h, -lncurses,,
[ncurses in /usr/include])
AC_NCURSES(/usr/include/ncurses, ncurses.h, -lncurses, -I/usr/include/ncurses,
[ncurses in /usr/include/ncurses])
AC_NCURSES(/usr/local/include, ncurses.h, -L/usr/local/lib -lncurses, -I/usr/local/include,
[ncurses in /usr/local/include])
AC_NCURSES(/usr/local/include/ncurses, ncurses.h, -L/usr/local/lib -lncurses, -I/usr/local/include/ncurses,
[ncurses in /usr/local/include/ncurses])
AC_NCURSES(/usr/local/include/ncurses, curses.h, -L/usr/local/lib -lncurses, -I/usr/local/include/ncurses -DRENAMED_NCURSES,
[renamed ncurses in /usr/local/include/ncurses])
AC_NCURSES(/usr/include/ncurses, curses.h, -lncurses, -I/usr/include/ncurses -DRENAMED_NCURSES,
[renamed ncurses in /usr/include/ncurses])
dnl
dnl We couldn't find ncurses, try SysV curses
dnl
if $search_ncurses
then
AC_EGREP_HEADER(init_color, /usr/include/curses.h,
AC_USE_SYSV_CURSES)
AC_EGREP_CPP(USE_NCURSES,[
#include <curses.h>
#ifdef __NCURSES_H
#undef USE_NCURSES
USE_NCURSES
#endif
],[
CURSES_INCLUDEDIR="$CURSES_INCLUDEDIR -DRENAMED_NCURSES"
AC_DEFINE(HAS_CURSES)
has_curses=true
has_ncurses=true
AC_DEFINE(USE_NCURSES)
search_ncurses=false
screen_manager="ncurses installed as curses"
])
fi
dnl
dnl Try SunOS 4.x /usr/5{lib,include} ncurses
dnl The flags USE_SUNOS_CURSES, USE_BSD_CURSES and BUGGY_CURSES
dnl should be replaced by a more fine grained selection routine
dnl
if $search_ncurses
then
if test -f /usr/5include/curses.h
then
AC_USE_SUNOS_CURSES
fi
fi
dnl use whatever curses there happens to be
if $search_ncurses
then
if test -f /usr/include/curses.h
then
CURSES_LIBS="-lcurses"
AC_DEFINE(HAS_CURSES)
has_curses=true
search_ncurses=false
screen_manager="curses"
fi
fi
])

View File

@ -4,8 +4,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/core/ \
-I$(top_srcdir)/src/fe-common/core/ \
$(GLIB_CFLAGS) \
$(CURSES_INCLUDEDIR)
$(GLIB_CFLAGS)
irssi_DEPENDENCIES = \
@COMMON_LIBS@ \
@ -22,25 +21,11 @@ irssi_LDADD = \
@PROG_LIBS@ \
@TEXTUI_LIBS@
tparm_sources = \
tparm.c
terminfo_sources = \
term-terminfo.c \
terminfo-core.c
curses_sources = \
term-curses.c
if NEED_TPARM
use_tparm_sources = $(tparm_sources)
endif
if USE_CURSES
use_term_sources = $(curses_sources)
else
use_term_sources = $(terminfo_sources)
endif
irssi_SOURCES = \
gui-entry.c \
@ -57,7 +42,6 @@ irssi_SOURCES = \
statusbar-items.c \
term.c \
term-dummy.c \
$(use_tparm_sources) \
$(use_term_sources) \
textbuffer.c \
textbuffer-commands.c \
@ -85,6 +69,4 @@ noinst_HEADERS = \
module-formats.h
EXTRA_DIST = \
$(tparm_sources) \
$(terminfo_sources) \
$(curses_sources)
$(terminfo_sources)

View File

@ -1,415 +0,0 @@
/*
term-curses.c : irssi
Copyright (C) 1999-2001 Timo Sirainen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "module.h"
#include "signals.h"
#include "settings.h"
#include "term.h"
#include "mainwindows.h"
#if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)
# include <ncurses.h>
#else
# include <curses.h>
#endif
#include <termios.h>
#include <signal.h>
#ifndef COLOR_PAIRS
# define COLOR_PAIRS 64
#endif
#if defined (TIOCGWINSZ) && defined (HAVE_CURSES_RESIZETERM)
# define USE_RESIZE_TERM
#endif
#ifndef _POSIX_VDISABLE
# define _POSIX_VDISABLE 0
#endif
struct _TERM_WINDOW {
int x, y;
int width, height;
WINDOW *win;
};
TERM_WINDOW *root_window;
static int curs_x, curs_y;
static int freeze_refresh;
static struct termios old_tio;
static int init_curses(void)
{
char ansi_tab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
int num;
struct termios tio;
if (!initscr())
return FALSE;
cbreak(); noecho(); idlok(stdscr, 1);
#ifdef HAVE_CURSES_IDCOK
/*idcok(stdscr, 1); - disabled currently, causes redrawing problems with NetBSD */
#endif
intrflush(stdscr, FALSE); nodelay(stdscr, TRUE);
/* Disable INTR, QUIT, VDSUSP and SUSP keys */
if (tcgetattr(0, &old_tio) == 0) {
memcpy(&tio, &old_tio, sizeof(tio));
tio.c_cc[VINTR] = _POSIX_VDISABLE;
tio.c_cc[VQUIT] = _POSIX_VDISABLE;
#ifdef VDSUSP
tio.c_cc[VDSUSP] = _POSIX_VDISABLE;
#endif
#ifdef VSUSP
tio.c_cc[VSUSP] = _POSIX_VDISABLE;
#endif
tcsetattr(0, TCSADRAIN, &tio);
}
if (has_colors())
start_color();
else if (term_use_colors)
term_use_colors = FALSE;
#ifdef HAVE_NCURSES_USE_DEFAULT_COLORS
/* this lets us to use the "default" background color for colors <= 7 so
background pixmaps etc. show up right */
use_default_colors();
for (num = 1; num < COLOR_PAIRS; num++)
init_pair(num, ansi_tab[num & 7], num <= 7 ? -1 : ansi_tab[num >> 3]);
init_pair(63, 0, -1); /* hm.. not THAT good idea, but probably more
people want dark grey than white on white.. */
#else
for (num = 1; num < COLOR_PAIRS; num++)
init_pair(num, ansi_tab[num & 7], ansi_tab[num >> 3]);
init_pair(63, 0, 0);
#endif
clear();
return TRUE;
}
static int term_init_int(void)
{
int ret;
ret = init_curses();
if (!ret) return 0;
curs_x = curs_y = 0;
freeze_refresh = 0;
root_window = g_new0(TERM_WINDOW, 1);
root_window->win = stdscr;
term_width = COLS;
term_height = LINES;
return ret;
}
static void term_deinit_int(void)
{
tcsetattr(0, TCSADRAIN, &old_tio);
endwin();
g_free_and_null(root_window);
}
int term_init(void)
{
if (!term_init_int())
return FALSE;
settings_add_int("lookandfeel", "default_color", 7);
term_common_init();
return TRUE;
}
void term_deinit(void)
{
term_common_deinit();
term_deinit_int();
}
/* Resize terminal - if width or height is negative,
the new size is unknown and should be figured out somehow */
void term_resize(int width, int height)
{
#ifdef HAVE_CURSES_RESIZETERM
if (width < 0 || height < 0) {
#endif
term_deinit_int();
term_init_int();
#ifdef HAVE_CURSES_RESIZETERM
} else if (term_width != width || term_height != height) {
term_width = width;
term_height = height;
resizeterm(term_height, term_width);
}
#endif
}
void term_resize_final(int width, int height)
{
#ifdef HAVE_CURSES_RESIZETERM
if (width < 0 || height < 0)
mainwindows_recreate();
#else
mainwindows_recreate();
#endif
}
/* Returns TRUE if terminal has colors */
int term_has_colors(void)
{
return has_colors();
}
/* Force the colors on any way you can */
void term_force_colors(int set)
{
/* don't do anything with curses */
}
/* Clear screen */
void term_clear(void)
{
term_set_color(root_window, 0);
clear();
}
/* Beep */
void term_beep(void)
{
beep();
}
/* Create a new window in terminal */
TERM_WINDOW *term_window_create(int x, int y, int width, int height)
{
TERM_WINDOW *window;
window = g_new0(TERM_WINDOW, 1);
window->x = x; window->y = y;
window->width = width; window->height = height;
window->win = newwin(height, width, y, x);
if (window->win == NULL)
g_error("newwin() failed: %d,%d %d,%d", x, y, width, height);
idlok(window->win, 1);
return window;
}
/* Destroy a terminal window */
void term_window_destroy(TERM_WINDOW *window)
{
delwin(window->win);
g_free(window);
}
/* Move/resize a window */
void term_window_move(TERM_WINDOW *window, int x, int y,
int width, int height)
{
/* some checks to make sure the window is visible in screen,
otherwise curses could get nasty and not show our window anymore. */
if (width < 1) width = 1;
if (height < 1) height = 1;
if (x+width > term_width) x = term_width-width;
if (y+height > term_height) y = term_height-height;
#ifdef HAVE_CURSES_WRESIZE
if (window->width != width || window->height != height)
wresize(window->win, height, width);
if (window->x != x || window->y != y)
mvwin(window->win, y, x);
#else
if (window->width != width || window->height != height ||
window->x != x || window->y != y) {
delwin(window->win);
window->win = newwin(height, width, y, x);
idlok(window->win, 1);
}
#endif
window->x = x; window->y = y;
window->width = width; window->height = height;
}
/* Clear window */
void term_window_clear(TERM_WINDOW *window)
{
werase(window->win);
}
/* Scroll window up/down */
void term_window_scroll(TERM_WINDOW *window, int count)
{
scrollok(window->win, TRUE);
wscrl(window->win, count);
scrollok(window->win, FALSE);
}
static int get_attr(int color)
{
int attr;
if ((color & FG_MASK) >> 4)
color = (color & ~FG_MASK) | term_color256map[color & FG_MASK];
if ((color & BG_MASK) >> (BG_SHIFT + 4))
color = (color & ~BG_MASK) | (term_color256map[(color & BG_MASK) >> BG_SHIFT] << BG_SHIFT);
if (!term_use_colors)
attr = (color & (0x7 << BG_SHIFT)) ? A_REVERSE : 0;
else if ((color & ((0xf << BG_SHIFT) | 0xf)) == 8 || (color & (FG_MASK | BG_MASK | ATTR_RESETFG)) == 0)
attr = COLOR_PAIR(63);
else if ((color & ((0x7 << BG_SHIFT) | 0x7)) == 0)
attr = A_NORMAL;
else {
if (color & ATTR_RESETFG) {
color &= ~FG_MASK;
color |= settings_get_int("default_color");
}
attr = COLOR_PAIR((color&0x7) | ((color&(0x7<<BG_SHIFT))>>BG_SHIFT<<3));
}
if ((color & 0x8) || (color & ATTR_BOLD)) attr |= A_BOLD;
if (color & ATTR_BLINK) attr |= A_BLINK;
if (color & ATTR_UNDERLINE) attr |= A_UNDERLINE;
if (color & ATTR_REVERSE) attr |= A_REVERSE;
#ifdef A_ITALIC
if (color & ATTR_ITALIC) attr |= A_ITALIC;
#endif
return attr;
}
/* Change active color */
void term_set_color(TERM_WINDOW *window, int col)
{
wattrset(window->win, get_attr(col));
wbkgdset(window->win, ' ' | get_attr(col));
}
void term_move(TERM_WINDOW *window, int x, int y)
{
wmove(window->win, y, x);
}
void term_addch(TERM_WINDOW *window, char chr)
{
waddch(window->win, chr);
}
void term_add_unichar(TERM_WINDOW *window, unichar chr)
{
#ifdef WIDEC_CURSES
cchar_t wch;
wchar_t temp[2];
temp[0] = chr;
temp[1] = 0;
if (setcchar(&wch, temp, A_NORMAL, 0, NULL) == OK)
wadd_wch(window->win, &wch);
else
#endif
waddch(window->win, chr);
}
void term_addstr(TERM_WINDOW *window, const char *str)
{
waddstr(window->win, (const char *) str);
}
void term_clrtoeol(TERM_WINDOW *window)
{
wclrtoeol(window->win);
}
void term_move_cursor(int x, int y)
{
curs_x = x;
curs_y = y;
}
void term_refresh_freeze(void)
{
freeze_refresh++;
}
void term_refresh_thaw(void)
{
if (freeze_refresh > 0) {
freeze_refresh--;
if (freeze_refresh == 0) term_refresh(NULL);
}
}
void term_refresh(TERM_WINDOW *window)
{
if (window != NULL)
wnoutrefresh(window->win);
if (freeze_refresh == 0) {
move(curs_y, curs_x);
wnoutrefresh(stdscr);
doupdate();
}
}
void term_stop(void)
{
term_deinit_int();
kill(getpid(), SIGTSTP);
term_init_int();
irssi_redraw();
}
void term_set_input_type(int type)
{
}
void term_gets(GArray *buffer, int *line_count)
{
#ifdef WIDEC_CURSES
wint_t key;
#else
int key;
#endif
for (;;) {
#ifdef WIDEC_CURSES
if (get_wch(&key) == ERR)
#else
if ((key = getch()) == ERR)
#endif
break;
#ifdef KEY_RESIZE
if (key == KEY_RESIZE)
continue;
#endif
g_array_append_val(buffer, key);
if (key == '\r' || key == '\n')
(*line_count)++;
}
}

View File

@ -17,7 +17,6 @@ inline static int term_putchar(int c)
char *tparm();
int tputs();
#ifdef HAVE_TERMINFO
int setupterm();
char *tigetstr();
int tigetnum();
@ -25,15 +24,6 @@ int tigetflag();
#define term_getstr(x, buffer) tigetstr(x.ti_name)
#define term_getnum(x) tigetnum(x.ti_name);
#define term_getflag(x) tigetflag(x.ti_name);
#else
int tgetent();
char *tgetstr();
int tgetnum();
int tgetflag();
#define term_getstr(x, buffer) tgetstr(x.tc_name, &buffer)
#define term_getnum(x) tgetnum(x.tc_name)
#define term_getflag(x) tgetflag(x.tc_name)
#endif
#define CAP_TYPE_FLAG 0
#define CAP_TYPE_INT 1
@ -415,9 +405,6 @@ static void term_fill_capabilities(TERM_REC *term)
char *sval;
void *ptr;
#ifndef HAVE_TERMINFO
char *tptr = term->buffer2;
#endif
for (i = 0; i < sizeof(tcaps)/sizeof(tcaps[0]); i++) {
ptr = G_STRUCT_MEMBER_P(term, tcaps[i].offset);
@ -583,9 +570,7 @@ void terminfo_stop(TERM_REC *term)
static int term_setup(TERM_REC *term)
{
GString *str;
#ifdef HAVE_TERMINFO
int err;
#endif
char *term_env;
term_env = getenv("TERM");
@ -594,18 +579,10 @@ static int term_setup(TERM_REC *term)
return 0;
}
#ifdef HAVE_TERMINFO
if (setupterm(term_env, 1, &err) != 0) {
fprintf(stderr, "setupterm() failed for TERM=%s: %d\n", term_env, err);
return 0;
}
#else
if (tgetent(term->buffer1, term_env) < 1)
{
fprintf(stderr, "Termcap not found for TERM=%s\n", term_env);
return 0;
}
#endif
term_fill_capabilities(term);

View File

@ -1,740 +0,0 @@
/*
* tparm.c
*
* By Ross Ridge
* Public Domain
* 92/02/01 07:30:36
*
*/
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifndef MAX_PUSHED
#define MAX_PUSHED 32
#endif
#define ARG 1
#define NUM 2
#define INTEGER 1
#define STRING 2
#define MAX_LINE 640
typedef void* anyptr;
typedef struct stack_str {
int type;
int argnum;
int value;
} stack;
static stack S[MAX_PUSHED];
static stack vars['z'-'a'+1];
static int pos = 0;
static struct arg_str {
int type;
int integer;
char *string;
} arg_list[10];
static int argcnt;
static va_list tparm_args;
static int pusharg(int arg)
{
if (pos == MAX_PUSHED)
return 1;
S[pos].type = ARG;
S[pos++].argnum = arg;
return 0;
}
static int pushnum(int num)
{
if (pos == MAX_PUSHED)
return 1;
S[pos].type = NUM;
S[pos++].value = num;
return 0;
}
/* VARARGS2 */
static int getarg(int argnum, int type, anyptr p)
{
while (argcnt < argnum) {
arg_list[argcnt].type = INTEGER;
arg_list[argcnt++].integer = (int) va_arg(tparm_args, int);
}
if (argcnt > argnum) {
if (arg_list[argnum].type != type)
return 1;
else if (type == STRING)
*(char **)p = arg_list[argnum].string;
else
*(int *)p = arg_list[argnum].integer;
} else {
arg_list[argcnt].type = type;
if (type == STRING)
*(char **)p = arg_list[argcnt++].string
= (char *) va_arg(tparm_args, char *);
else
*(int *)p = arg_list[argcnt++].integer = (int) va_arg(tparm_args, int);
}
return 0;
}
static int popstring(char **str)
{
if (pos-- == 0)
return 1;
if (S[pos].type != ARG)
return 1;
return(getarg(S[pos].argnum, STRING, (anyptr) str));
}
static int popnum(int *num)
{
if (pos-- == 0)
return 1;
switch (S[pos].type) {
case ARG:
return (getarg(S[pos].argnum, INTEGER, (anyptr) num));
case NUM:
*num = S[pos].value;
return 0;
}
return 1;
}
static int cvtchar(const char *sp, char *c)
{
switch(*sp) {
case '\\':
switch(*++sp) {
case '\'':
case '$':
case '\\':
case '%':
*c = *sp;
return 2;
case '\0':
*c = '\\';
return 1;
case '0':
if (sp[1] == '0' && sp[2] == '0') {
*c = '\0';
return 4;
}
*c = '\200'; /* '\0' ???? */
return 2;
default:
*c = *sp;
return 2;
}
default:
*c = *sp;
return 1;
}
}
static int termcap;
/* sigh... this has got to be the ugliest code I've ever written.
Trying to handle everything has its cost, I guess.
It actually isn't to hard to figure out if a given % code is supposed
to be interpeted with its termcap or terminfo meaning since almost
all terminfo codes are invalid unless something has been pushed on
the stack and termcap strings will never push things on the stack
(%p isn't used by termcap). So where we have a choice we make the
decision by whether or not somthing has been pushed on the stack.
The static variable termcap keeps track of this; it starts out set
to 1 and is incremented as each argument processed by a termcap % code,
however if something is pushed on the stack it's set to 0 and the
rest of the % codes are interpeted as terminfo % codes. Another way
of putting it is that if termcap equals one we haven't decided either
way yet, if it equals zero we're looking for terminfo codes, and if
its greater than 1 we're looking for termcap codes.
Terminfo % codes:
%% output a '%'
%[[:][-+# ][width][.precision]][doxXs]
output pop according to the printf format
%c output pop as a char
%'c' push character constant c.
%{n} push decimal constant n.
%p[1-9] push parameter [1-9]
%g[a-z] push variable [a-z]
%P[a-z] put pop in variable [a-z]
%l push the length of pop (a string)
%+ add pop to pop and push the result
%- subtract pop from pop and push the result
%* multiply pop and pop and push the result
%& bitwise and pop and pop and push the result
%| bitwise or pop and pop and push the result
%^ bitwise xor pop and pop and push the result
%~ push the bitwise not of pop
%= compare if pop and pop are equal and push the result
%> compare if pop is less than pop and push the result
%< compare if pop is greater than pop and push the result
%A logical and pop and pop and push the result
%O logical or pop and pop and push the result
%! push the logical not of pop
%? condition %t if_true [%e if_false] %;
if condition evaulates as true then evaluate if_true,
else evaluate if_false. elseif's can be done:
%? cond %t true [%e cond2 %t true2] ... [%e condN %t trueN] [%e false] %;
%i add one to parameters 1 and 2. (ANSI)
Termcap Codes:
%% output a %
%. output parameter as a character
%d output parameter as a decimal number
%2 output parameter in printf format %02d
%3 output parameter in printf format %03d
%+x add the character x to parameter and output it as a character
(UW) %-x subtract parameter FROM the character x and output it as a char
(UW) %ax add the character x to parameter
(GNU) %a[+*-/=][cp]x
GNU arithmetic.
(UW) %sx subtract parameter FROM the character x
%>xy if parameter > character x then add character y to parameter
%B convert to BCD (parameter = (parameter/10)*16 + parameter%16)
%D Delta Data encode (parameter = parameter - 2*(parameter%16))
%i increment the first two parameters by one
%n xor the first two parameters by 0140
(GNU) %m xor the first two parameters by 0177
%r swap the first two parameters
(GNU) %b backup to previous parameter
(GNU) %f skip this parameter
Note the two definitions of %a, the GNU definition is used if the characters
after the 'a' are valid, otherwise the UW definition is used.
(GNU) used by GNU Emacs termcap libraries
(UW) used by the University of Waterloo (MFCF) termcap libraries
*/
char *tparm(const char *str, ...) {
static char OOPS[] = "OOPS";
static char buf[MAX_LINE];
register const char *sp;
register char *dp;
register char *fmt;
char conv_char;
char scan_for;
int scan_depth = 0, if_depth;
static int i, j;
static char *s, c;
char fmt_buf[MAX_LINE];
char sbuf[MAX_LINE];
va_start(tparm_args, str);
sp = str;
dp = buf;
scan_for = 0;
if_depth = 0;
argcnt = 0;
pos = 0;
termcap = 1;
while (*sp != '\0') {
switch(*sp) {
case '\\':
if (scan_for) {
if (*++sp != '\0')
sp++;
break;
}
*dp++ = *sp++;
if (*sp != '\0')
*dp++ = *sp++;
break;
case '%':
sp++;
if (scan_for) {
if (*sp == scan_for && if_depth == scan_depth) {
if (scan_for == ';')
if_depth--;
scan_for = 0;
} else if (*sp == '?')
if_depth++;
else if (*sp == ';') {
if (if_depth == 0)
return OOPS;
else
if_depth--;
}
sp++;
break;
}
fmt = NULL;
switch(*sp) {
case '%':
*dp++ = *sp++;
break;
case '+':
if (!termcap) {
if (popnum(&j) || popnum(&i))
return OOPS;
i += j;
if (pushnum(i))
return OOPS;
sp++;
break;
}
;/* FALLTHROUGH */
case 'C':
if (*sp == 'C') {
if (getarg(termcap - 1, INTEGER, &i))
return OOPS;
if (i >= 96) {
i /= 96;
if (i == '$')
*dp++ = '\\';
*dp++ = i;
}
}
fmt = "%c";
/* FALLTHROUGH */
case 'a':
if (!termcap)
return OOPS;
if (getarg(termcap - 1, INTEGER, (anyptr) &i))
return OOPS;
if (*++sp == '\0')
return OOPS;
if ((sp[1] == 'p' || sp[1] == 'c')
&& sp[2] != '\0' && fmt == NULL) {
/* GNU aritmitic parameter, what they
really need is terminfo. */
int val, lc;
if (sp[1] == 'p'
&& getarg(termcap - 1 + sp[2] - '@',
INTEGER, (anyptr) &val))
return OOPS;
if (sp[1] == 'c') {
lc = cvtchar(sp + 2, &c) + 2;
/* Mask out 8th bit so \200 can be
used for \0 as per GNU doc's */
val = c & 0177;
} else
lc = 2;
switch(sp[0]) {
case '=':
break;
case '+':
val = i + val;
break;
case '-':
val = i - val;
break;
case '*':
val = i * val;
break;
case '/':
val = i / val;
break;
default:
/* Not really GNU's %a after all... */
lc = cvtchar(sp, &c);
val = c + i;
break;
}
arg_list[termcap - 1].integer = val;
sp += lc;
break;
}
sp += cvtchar(sp, &c);
arg_list[termcap - 1].integer = c + i;
if (fmt == NULL)
break;
sp--;
/* FALLTHROUGH */
case '-':
if (!termcap) {
if (popnum(&j) || popnum(&i))
return OOPS;
i -= j;
if (pushnum(i))
return OOPS;
sp++;
break;
}
fmt = "%c";
/* FALLTHROUGH */
case 's':
if (termcap && (fmt == NULL || *sp == '-')) {
if (getarg(termcap - 1, INTEGER, &i))
return OOPS;
if (*++sp == '\0')
return OOPS;
sp += cvtchar(sp, &c);
arg_list[termcap - 1].integer = c - i;
if (fmt == NULL)
break;
sp--;
}
if (!termcap)
return OOPS;
;/* FALLTHROUGH */
case '.':
if (termcap && fmt == NULL)
fmt = "%c";
;/* FALLTHROUGH */
case 'd':
if (termcap && fmt == NULL)
fmt = "%d";
;/* FALLTHROUGH */
case '2':
if (termcap && fmt == NULL)
fmt = "%02d";
;/* FALLTHROUGH */
case '3':
if (termcap && fmt == NULL)
fmt = "%03d";
;/* FALLTHROUGH */
case ':': case ' ': case '#': case 'u':
case 'x': case 'X': case 'o': case 'c':
case '0': case '1': case '4': case '5':
case '6': case '7': case '8': case '9':
if (fmt == NULL) {
if (termcap)
return OOPS;
if (*sp == ':')
sp++;
fmt = fmt_buf;
*fmt++ = '%';
while(*sp != 's' && *sp != 'x' && *sp != 'X' && *sp != 'd' && *sp != 'o' && *sp != 'c' && *sp != 'u') {
if (*sp == '\0')
return OOPS;
*fmt++ = *sp++;
}
*fmt++ = *sp;
*fmt = '\0';
fmt = fmt_buf;
}
conv_char = fmt[strlen(fmt) - 1];
if (conv_char == 's') {
if (popstring(&s))
return OOPS;
sprintf(sbuf, fmt, s);
} else {
if (termcap) {
if (getarg(termcap++ - 1,
INTEGER, &i))
return OOPS;
} else
if (popnum(&i))
return OOPS;
if (i == 0 && conv_char == 'c')
*sbuf = 0;
else
sprintf(sbuf, fmt, i);
}
sp++;
fmt = sbuf;
while(*fmt != '\0') {
if (*fmt == '$')
*dp++ = '\\';
*dp++ = *fmt++;
}
break;
case 'r':
if (!termcap || getarg(1, INTEGER, &i))
return OOPS;
arg_list[1].integer = arg_list[0].integer;
arg_list[0].integer = i;
sp++;
break;
case 'i':
if (getarg(1, INTEGER, &i)
|| arg_list[0].type != INTEGER)
return OOPS;
arg_list[1].integer++;
arg_list[0].integer++;
sp++;
break;
case 'n':
if (!termcap || getarg(1, INTEGER, &i))
return OOPS;
arg_list[0].integer ^= 0140;
arg_list[1].integer ^= 0140;
sp++;
break;
case '>':
if (!termcap) {
if (popnum(&j) || popnum(&i))
return OOPS;
i = (i > j);
if (pushnum(i))
return OOPS;
sp++;
break;
}
if (getarg(termcap-1, INTEGER, &i))
return OOPS;
sp += cvtchar(sp, &c);
if (i > c) {
sp += cvtchar(sp, &c);
arg_list[termcap-1].integer += c;
} else
sp += cvtchar(sp, &c);
sp++;
break;
case 'B':
if (!termcap || getarg(termcap-1, INTEGER, &i))
return OOPS;
arg_list[termcap-1].integer = 16*(i/10)+i%10;
sp++;
break;
case 'D':
if (!termcap || getarg(termcap-1, INTEGER, &i))
return OOPS;
arg_list[termcap-1].integer = i - 2 * (i % 16);
sp++;
break;
case 'p':
if (termcap > 1)
return OOPS;
if (*++sp == '\0')
return OOPS;
if (*sp == '0')
i = 9;
else
i = *sp - '1';
if (i < 0 || i > 9)
return OOPS;
if (pusharg(i))
return OOPS;
termcap = 0;
sp++;
break;
case 'P':
if (termcap || *++sp == '\0')
return OOPS;
i = *sp++ - 'a';
if (i < 0 || i > 25)
return OOPS;
if (pos-- == 0)
return OOPS;
switch(vars[i].type = S[pos].type) {
case ARG:
vars[i].argnum = S[pos].argnum;
break;
case NUM:
vars[i].value = S[pos].value;
break;
}
break;
case 'g':
if (termcap || *++sp == '\0')
return OOPS;
i = *sp++ - 'a';
if (i < 0 || i > 25)
return OOPS;
switch(vars[i].type) {
case ARG:
if (pusharg(vars[i].argnum))
return OOPS;
break;
case NUM:
if (pushnum(vars[i].value))
return OOPS;
break;
}
break;
case '\'':
if (termcap > 1)
return OOPS;
if (*++sp == '\0')
return OOPS;
sp += cvtchar(sp, &c);
if (pushnum(c) || *sp++ != '\'')
return OOPS;
termcap = 0;
break;
case '{':
if (termcap > 1)
return OOPS;
i = 0;
sp++;
while(isdigit((int) (unsigned char) *sp))
i = 10 * i + *sp++ - '0';
if (*sp++ != '}' || pushnum(i))
return OOPS;
termcap = 0;
break;
case 'l':
if (termcap || popstring(&s))
return OOPS;
i = strlen(s);
if (pushnum(i))
return OOPS;
sp++;
break;
case '*':
if (termcap || popnum(&j) || popnum(&i))
return OOPS;
i *= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case '/':
if (termcap || popnum(&j) || popnum(&i))
return OOPS;
i /= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case 'm':
if (termcap) {
if (getarg(1, INTEGER, &i))
return OOPS;
arg_list[0].integer ^= 0177;
arg_list[1].integer ^= 0177;
sp++;
break;
}
if (popnum(&j) || popnum(&i))
return OOPS;
i %= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case '&':
if (popnum(&j) || popnum(&i))
return OOPS;
i &= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case '|':
if (popnum(&j) || popnum(&i))
return OOPS;
i |= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case '^':
if (popnum(&j) || popnum(&i))
return OOPS;
i ^= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case '=':
if (popnum(&j) || popnum(&i))
return OOPS;
i = (i == j);
if (pushnum(i))
return OOPS;
sp++;
break;
case '<':
if (popnum(&j) || popnum(&i))
return OOPS;
i = (i < j);
if (pushnum(i))
return OOPS;
sp++;
break;
case 'A':
if (popnum(&j) || popnum(&i))
return OOPS;
i = (i && j);
if (pushnum(i))
return OOPS;
sp++;
break;
case 'O':
if (popnum(&j) || popnum(&i))
return OOPS;
i = (i || j);
if (pushnum(i))
return OOPS;
sp++;
break;
case '!':
if (popnum(&i))
return OOPS;
i = !i;
if (pushnum(i))
return OOPS;
sp++;
break;
case '~':
if (popnum(&i))
return OOPS;
i = ~i;
if (pushnum(i))
return OOPS;
sp++;
break;
case '?':
if (termcap > 1)
return OOPS;
termcap = 0;
if_depth++;
sp++;
break;
case 't':
if (popnum(&i) || if_depth == 0)
return OOPS;
if (!i) {
scan_for = 'e';
scan_depth = if_depth;
}
sp++;
break;
case 'e':
if (if_depth == 0)
return OOPS;
scan_for = ';';
scan_depth = if_depth;
sp++;
break;
case ';':
if (if_depth-- == 0)
return OOPS;
sp++;
break;
case 'b':
if (--termcap < 1)
return OOPS;
sp++;
break;
case 'f':
if (!termcap++)
return OOPS;
sp++;
break;
}
break;
default:
if (scan_for)
sp++;
else
*dp++ = *sp++;
break;
}
}
va_end(tparm_args);
*dp = '\0';
return buf;
}

View File

@ -127,7 +127,7 @@ am_v_pl__show_gen = $(am__v_pl__show_gen_$(V))
am_v_pl__hide_gen = $(am__v_pl__hide_gen_$(V))
am__v_pl__show_gen_ = $(am__v_pl__show_gen_$(AM_DEFAULT_VERBOSITY))
am__v_pl__hide_gen_ = $(am__v_pl__hide_gen_$(AM_DEFAULT_VERBOSITY))
am__v_pl__show_gen_0 = echo " GEN " $$dir ;
am__v_pl__show_gen_0 = echo " GEN " $$dir ;
am__v_pl__hide_gen_0 = > /dev/null
am__v_pl__show_gen_1 =
am__v_pl__hide_gen_1 =

View File

@ -3,7 +3,7 @@ my $verb = $AM_DEFAULT_VERBOSITY;
{ package MY;
sub _center {
my $z = shift;
length $z == 2 ? " $z " : length $z == 4 ? " $z " : " $z "
(length $z == 2 ? " $z " : length $z == 4 ? " $z " : " $z ").' '
}
sub _silent_cmd {
my $z = shift;