[hackers] [PATCH 2/2] Add tput(1)

From: Lucas Gabriel Vuotto <l.vuotto92_AT_gmail.com>
Date: Sun, 22 May 2016 16:01:45 -0300

Signed-off-by: Lucas Gabriel Vuotto <l.vuotto92_AT_gmail.com>
---
 Makefile                    |   1 +
 TODO                        |   2 +-
 libterminfo/Makefile        |   6 +-
 libterminfo/mkcapstbl.h.awk |  19 +++++++
 tput.c                      | 134 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 160 insertions(+), 2 deletions(-)
 create mode 100644 libterminfo/mkcapstbl.h.awk
 create mode 100644 tput.c
diff --git a/Makefile b/Makefile
index c639d69..54b02ad 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -91,6 +91,7 @@ BIN = \
 	swapon            \
 	switch_root       \
 	sysctl            \
+	tput              \
 	truncate          \
 	umount            \
 	unshare           \
diff --git a/TODO b/TODO
index 21f5c20..3ef3e31 100644
--- a/TODO
+++ b/TODO
_AT_@ -26,7 +26,6 @@ setcap
 tabs
 taskset
 top
-tput
 vmstat
 
 Misc
_AT_@ -34,3 +33,4 @@ Misc
 
 Beautify passwd(1).
 last(1) manpage.
+tput(1) manpage.
diff --git a/libterminfo/Makefile b/libterminfo/Makefile
index 0fff6ab..ad55688 100644
--- a/libterminfo/Makefile
+++ b/libterminfo/Makefile
_AT_@ -1,4 +1,4 @@
-all: damned-caps.h damned-capsutil.h
+all: damned-caps.h damned-capsutil.h capstbl.h
 
 damned-caps.h: mkcaps.h.awk
 	rm -f $_AT_
_AT_@ -8,3 +8,7 @@ damned-caps.h: mkcaps.h.awk
 damned-capsutil.h: mkcapsutil.h.awk
 	rm -f $_AT_
 	awk -f $< ncurses-5.9/Caps >$_AT_
+
+capstbl.h: mkcapstbl.h.awk
+	rm -f $_AT_
+	awk -f $< ncurses-5.9/Caps >$_AT_
diff --git a/libterminfo/mkcapstbl.h.awk b/libterminfo/mkcapstbl.h.awk
new file mode 100644
index 0000000..57925ca
--- /dev/null
+++ b/libterminfo/mkcapstbl.h.awk
_AT_@ -0,0 +1,19 @@
+#!/usr/bin/env awk
+
+BEGIN {
+	print "static struct {"
+	print "\tconst char *name;"
+	print "\tconst char *varname;"
+	print "\tCapname cn;"
+	print "} tbl[] = {"
+}
+
+/^# %%-STOP-HERE-%%$/ { exit }
+/^#/ { next }
+{
+	print "\t{ \"" $2 "\", \"" $1 "\", TI_" $2 " },"
+}
+
+END {
+	print "};"
+}
diff --git a/tput.c b/tput.c
new file mode 100644
index 0000000..21e96de
--- /dev/null
+++ b/tput.c
_AT_@ -0,0 +1,134 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "terminfo.h"
+#include "util.h"
+
+/* needs libterminfo/caps.h, included from terminfo.h */
+#include "libterminfo/capstbl.h"
+
+static char *dummyargs[] = { NULL };
+static char *params[9];
+
+static int
+docap(int cap, char **p)
+{
+	char *o;
+	size_t l;
+	int i, r = 0;
+
+	for (i = 0; p[i]; i++)
+		params[i] = p[i];
+	for (; i < 9; i++);
+		params[i] = NULL;
+
+	o = tparse(cap,
+	           params[0], params[1], params[2],
+	           params[3], params[4], params[5],
+	           params[6], params[7], params[8]);
+	if (!o)
+		return -2;
+	l = strlen(o);
+	if (fwrite(o, sizeof(char), l, stdout) != l)
+		r = -1;
+	free(o);
+
+	return r;
+}
+
+static void
+doclear(void)
+{
+	docap(TI_clear, dummyargs);
+}
+
+static void
+doinit(void)
+{
+	/* TODO: do something about iprog and if */
+	docap(TI_is1, dummyargs);
+	docap(TI_is2, dummyargs);
+	docap(TI_mgc, dummyargs);
+	docap(TI_smgl, dummyargs);
+	docap(TI_smgr, dummyargs);
+	docap(TI_tbc, dummyargs);
+	docap(TI_hts, dummyargs);
+	docap(TI_is3, dummyargs);
+}
+
+static void
+doreset(void)
+{
+	if (docap(TI_rs1, dummyargs) < 0)
+		docap(TI_is1, dummyargs);
+	if (docap(TI_rs2, dummyargs) < 0)
+		docap(TI_is2, dummyargs);
+	docap(TI_mgc, dummyargs);
+	docap(TI_smgl, dummyargs);
+	docap(TI_smgr, dummyargs);
+	docap(TI_tbc, dummyargs);
+	docap(TI_hts, dummyargs);
+	if (docap(TI_rs3, dummyargs) < 0)
+		docap(TI_is3, dummyargs);
+}
+
+static void
+usage(void)
+{
+	eprintf("usage: %s [-T term] <clear|init|reset|cap> [capargs...]\n", argv0);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	char *term = NULL;
+	int cap = -1, i;
+
+	ARGBEGIN {
+	case 'T':
+		term = EARGF(usage());
+		if (setenv("TERM", term, 1) < 0)
+			eprintf("couldn't change terminal type\n", argv0);
+		break;
+	default:
+		usage();
+	} ARGEND;
+
+	if (argc == 0)
+		usage();
+
+	if (setupterminfo() < 0)
+		enprintf(3, "couldn't init terminfo\n");
+
+	if (!strcmp("clear", *argv)) {
+		doclear();
+		return 0;
+	} else if (!strcmp("init", *argv)) {
+		doinit();
+		return 0;
+	} else if (!strcmp("reset", *argv)) {
+		doreset();
+		return 0;
+	}
+
+	for (i = 0; i < LEN(tbl) && cap < 0; i++) {
+		if (!strcmp(tbl[i].name, *argv) || !strcmp(tbl[i].varname, *argv))
+			cap = tbl[i].cn;
+	}
+	if (cap < 0)
+		enprintf(4, "unknown operand `%s'\n", *argv);
+
+	switch(docap(cap, argv + 1)) {
+	case -2:
+		enprintf(4, "unknown capability `%s'\n", *argv);
+		break;
+	case -1:
+		enprintf(5, "an error ocurred writing to output:");
+		break;
+	}
+
+	return 0;
+}
-- 
2.7.3
Received on Sun May 22 2016 - 21:01:45 CEST

This archive was generated by hypermail 2.3.0 : Sun May 22 2016 - 21:12:16 CEST