#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "curses_inc.h"
#include "print.h"
#include <signal.h>
#ifdef SIGSTOP
#define _ULIBTI "/usr/share/lib/terminfo"
#else
#define _ULIBTI "/usr/lib/terminfo"
#endif
char *progname;
static enum printtypes printing = pr_none;
static int onecolumn = 0;
static int width = 60;
static int restrictterm = 1;
static int printed = 0;
static size_t caplen = 0;
void
pr_init(enum printtypes type)
{
printing = type;
}
void
pr_onecolumn(int onoff)
{
onecolumn = onoff;
}
void
pr_width(int nwidth)
{
if (nwidth > 0)
width = nwidth;
}
void
pr_caprestrict(int onoff)
{
restrictterm = onoff;
}
static char capbools[] =
"ambsbwdadbeoeshchshzinkmmimsncnsosptulxbxnxoxsxt";
static int ncapbools = sizeof (capbools) / sizeof (capbools[0]);
static char capnums[] =
"codBdCdFdNdTknlipbsgug";
static int ncapnums = sizeof (capnums) / sizeof (capnums[0]);
static char capstrs[] =
"ALDCDLDOICLERISFSRUPaealasbcbtcdcechclcmcsctcvdcdldmdsedeifshoi1i2i"
"cifimipisk0k1k2k3k4k5k6k7k8k9kbkdkekhklkokrkskul0l1l2l3l4l5l6l7l"
"8l9ndnlpcr1r2r3rcrfrpscsesosrsttetitsucueupusvbvevivs";
static int ncapstrs = sizeof (capstrs) / sizeof (capstrs[0]);
static int
findcapname(char *capname, char *caplist, int listsize)
{
int low = 0, mid, high = listsize - 2;
while (low <= high) {
mid = (low + high) / 4 * 2;
if (capname[0] == caplist[mid]) {
if (capname[1] == caplist[mid + 1])
return (1);
else if (capname[1] < caplist[mid + 1])
high = mid - 2;
else
low = mid + 2;
} else if (capname[0] < caplist[mid])
high = mid - 2;
else
low = mid + 2;
}
return (0);
}
void
pr_heading(char *term, char *synonyms)
{
int do_print = 0;
char buffer[512];
FILE *work_fp;
char tail[4];
char *terminfo;
terminfo = getenv("TERMINFO");
if (term == (char *)0)
term = "";
tail[0] = '/';
tail[1] = *term;
tail[2] = '/';
tail[3] = '\0';
if (terminfo != NULL)
(void) sprintf(buffer, "%s%s%s", terminfo, tail, term);
else
(void) sprintf(buffer, "%s%s%s", _ULIBTI, tail, term);
if ((work_fp = fopen(buffer, "rF")) == NULL) {
if (strncmp(buffer, _ULIBTI, strlen(_ULIBTI)) == 0) {
(void) fprintf(stderr, "Error: Term \"%s\" not "
"found in %s\n", term, _ULIBTI);
} else {
(void) sprintf(buffer, "%s%s%s", _ULIBTI, tail, term);
if ((work_fp = fopen(buffer, "rF")) == NULL) {
(void) fprintf(stderr, "Error: Term \"%s\" not "
"found in %s or %s\n", term, _ULIBTI,
getenv("TERMINFO"));
} else do_print = 1;
}
} else do_print = 1;
if (do_print && *term) {
(void) fclose(work_fp);
(void) printf("# Reconstructed via infocmp from file: "
"%s\n", buffer);
}
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("%s,\n", synonyms);
break;
case (int)pr_cap:
(void) printf("%s:\\\n", synonyms);
caplen = strlen(synonyms) + 1;
break;
case (int)pr_longnames:
(void) printf("Terminal type %s\n", term);
(void) printf(" %s\n", synonyms);
break;
}
}
void
pr_bheading(void)
{
if (printing == pr_longnames)
(void) printf("flags\n");
printed = 0;
}
void
pr_boolean(char *infoname, char *capname, char *fullname, int value)
{
int vlen;
size_t nlen;
if (printing == pr_cap && restrictterm &&
!findcapname(capname, capbools, ncapbools))
return;
if (onecolumn) {
if (value < 0)
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("\t%s@,\n", infoname);
break;
case (int)pr_cap:
(void) printf("\t:%s@:\\\n", capname);
caplen += 4 + strlen(capname);
break;
case (int)pr_longnames:
(void) printf(" %s@\n", fullname);
}
else
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("\t%s,\n", infoname);
break;
case (int)pr_cap:
(void) printf("\t:%s:\\\n", capname);
caplen += 3 + strlen(capname);
break;
case (int)pr_longnames:
(void) printf(" %s\n", fullname);
}
} else {
switch ((int)printing) {
case (int)pr_terminfo: nlen = strlen(infoname);
break;
case (int)pr_cap: nlen = strlen(capname);
break;
case (int)pr_longnames:
nlen = strlen(fullname);
break;
}
vlen = (value < 0) ? 1 : 0;
if ((printed > 0) && (printed + nlen + vlen + 1 > width)) {
switch ((int)printing) {
case (int)pr_terminfo:
case (int)pr_longnames:
(void) printf("\n");
break;
case (int)pr_cap:
(void) printf(":\\\n");
caplen += 1;
}
printed = 0;
}
if (printed == 0) {
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("\t");
printed = 8;
break;
case (int)pr_cap:
(void) printf("\t:");
printed = 9;
caplen += 2;
break;
case (int)pr_longnames:
(void) printf(" ");
printed = 2;
}
} else {
switch ((int)printing) {
case (int)pr_terminfo:
case (int)pr_longnames:
(void) printf(" ");
break;
case (int)pr_cap:
(void) printf(":");
caplen += 1;
}
printed++;
}
if (value < 0)
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("%s@,", infoname);
printed += nlen + 2;
break;
case (int)pr_cap:
(void) printf("%s@", capname);
printed += nlen + 1;
caplen += nlen + 1;
break;
case (int)pr_longnames:
(void) printf("%s@,", fullname);
printed += nlen + 2;
}
else
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("%s,", infoname);
printed += nlen + 1;
break;
case (int)pr_cap:
(void) printf("%s", capname);
printed += nlen;
caplen += nlen;
break;
case (int)pr_longnames:
(void) printf("%s,", fullname);
printed += nlen + 1;
}
}
}
void
pr_bfooting(void)
{
if (!onecolumn && (printed > 0))
switch ((int)printing) {
case (int)pr_terminfo:
case (int)pr_longnames:
(void) printf("\n");
break;
case (int)pr_cap:
(void) printf(":\\\n");
caplen += 1;
}
}
void
pr_nheading(void)
{
if (printing == pr_longnames)
(void) printf("\nnumbers\n");
printed = 0;
}
static int
digitlen(int value)
{
return (value >= 10000 ? 5 :
value >= 1000 ? 4 :
value >= 100 ? 3 :
value >= 10 ? 2 :
value >= 0 ? 1 : 0);
}
void
pr_number(char *infoname, char *capname, char *fullname, int value)
{
int vlen;
size_t nlen;
if (printing == pr_cap && restrictterm &&
!findcapname(capname, capnums, ncapnums))
return;
if (onecolumn) {
if (value < 0)
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("\t%s@,\n", infoname);
break;
case (int)pr_cap:
(void) printf("\t:%s@:\\\n", capname);
caplen += 4 + strlen(capname);
break;
case (int)pr_longnames:
(void) printf(" %s @\n", fullname);
}
else
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("\t%s#%d,\n", infoname,
value);
break;
case (int)pr_cap:
(void) printf("\t:%s#%d:\\\n",
capname, value);
caplen += 4 + strlen(capname) +
digitlen(value);
break;
case (int)pr_longnames:
(void) printf(" %s = %d\n", fullname,
value);
}
} else {
switch ((int)printing) {
case (int)pr_terminfo:
nlen = strlen(infoname);
break;
case (int)pr_cap:
nlen = strlen(capname);
break;
case (int)pr_longnames:
nlen = strlen(fullname);
break;
}
vlen = digitlen(value);
if ((printed > 0) && (printed + nlen + vlen + 2 > width)) {
switch ((int)printing) {
case (int)pr_terminfo:
case (int)pr_longnames:
(void) printf("\n");
break;
case (int)pr_cap:
(void) printf(":\\\n");
caplen += 1;
}
printed = 0;
}
if (printed == 0) {
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("\t");
printed = 8;
break;
case (int)pr_cap:
(void) printf("\t:");
printed = 9;
caplen += 2;
break;
case (int)pr_longnames:
(void) printf(" ");
printed = 2;
}
} else {
switch ((int)printing) {
case (int)pr_terminfo:
case (int)pr_longnames:
(void) printf(" ");
break;
case (int)pr_cap:
(void) printf(":");
caplen += 1;
}
printed++;
}
if (value < 0) {
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("%s@,", infoname);
printed += nlen + 2;
break;
case (int)pr_cap:
(void) printf("%s@", capname);
printed += nlen + 1;
caplen += nlen + 1;
break;
case (int)pr_longnames:
(void) printf("%s@,", fullname);
printed += nlen + 2;
}
} else
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("%s#%d,", infoname,
value);
printed += nlen + vlen + 2;
break;
case (int)pr_cap:
(void) printf("%s#%d", capname, value);
printed += nlen + vlen + 1;
caplen += nlen + vlen + 1;
break;
case (int)pr_longnames:
(void) printf("%s = %d,", fullname,
value);
printed += nlen + vlen + 4;
}
}
}
void
pr_nfooting(void)
{
if (!onecolumn && (printed > 0))
switch ((int)printing) {
case (int)pr_terminfo:
case (int)pr_longnames:
(void) printf("\n");
break;
case (int)pr_cap:
(void) printf(":\\\n");
caplen += 1;
}
}
void
pr_sheading(void)
{
if (printing == pr_longnames)
(void) printf("\nstrings\n");
printed = 0;
}
void
pr_string(char *infoname, char *capname, char *fullname, char *value)
{
char *evalue;
int badcapvalue;
size_t nlen, vlen;
if (printing == pr_cap) {
if (restrictterm && !findcapname(capname, capstrs, ncapstrs))
return;
if (value)
value = infotocap(value, &badcapvalue);
}
if (onecolumn) {
if (value == NULL)
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("\t%s@,\n", infoname);
break;
case (int)pr_cap:
(void) printf("\t:%s@:\\\n", capname);
caplen += 4 + strlen(capname);
break;
case (int)pr_longnames:
(void) printf(" %s@\n", fullname);
}
else
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("\t%s=", infoname);
tpr(stdout, value);
(void) printf(",\n");
break;
case (int)pr_cap:
(void) printf("\t:%s%s=",
badcapvalue ? "." : "", capname);
caplen += 3 + strlen(capname) +
(badcapvalue ? 1 : 0);
caplen += cpr(stdout, value);
(void) printf(":\\\n");
caplen += 1;
break;
case (int)pr_longnames:
(void) printf(" %s = '", fullname);
tpr(stdout, value);
(void) printf("'\n");
}
} else {
switch ((int)printing) {
case (int)pr_terminfo:
nlen = strlen(infoname);
break;
case (int)pr_cap:
nlen = strlen(capname);
if (badcapvalue)
nlen++;
break;
case (int)pr_longnames:
nlen = strlen(fullname);
}
if (value == NULL)
vlen = 1;
else
if (printing == pr_cap)
vlen = strlen(evalue = cexpand(value));
else
vlen = strlen(evalue = iexpand(value));
if ((printed > 0) && (printed + nlen + vlen + 1 > width)) {
switch ((int)printing) {
case (int)pr_terminfo:
case (int)pr_longnames:
(void) printf("\n");
break;
case (int)pr_cap:
(void) printf(":\\\n");
caplen += 1;
}
printed = 0;
}
if (printed == 0) {
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("\t");
printed = 8;
break;
case (int)pr_cap:
(void) printf("\t:");
printed = 9;
caplen += 2;
break;
case (int)pr_longnames:
(void) printf(" ");
printed = 2;
}
} else {
switch ((int)printing) {
case (int)pr_terminfo:
case (int)pr_longnames:
(void) printf(" ");
break;
case (int)pr_cap:
(void) printf(":");
caplen += 1;
}
printed++;
}
if (value == NULL) {
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("%s@,", infoname);
printed += nlen + 2;
break;
case (int)pr_cap:
(void) printf("%s@", capname);
printed += nlen + 1;
caplen += nlen + 1;
break;
case (int)pr_longnames:
(void) printf("%s@,", fullname);
printed += nlen + 2;
}
} else
switch ((int)printing) {
case (int)pr_terminfo:
(void) printf("%s=%s,", infoname,
evalue);
printed += nlen + vlen + 2;
break;
case (int)pr_cap:
if (badcapvalue) {
(void) printf(".");
caplen += 1;
}
(void) printf("%s=%s", capname,
evalue);
printed += nlen + vlen + 1;
caplen += nlen + vlen + 1;
break;
case (int)pr_longnames:
(void) printf("%s = '%s',", fullname,
evalue);
printed += nlen + vlen + 6;
}
}
}
void
pr_sfooting(void)
{
if (onecolumn) {
if (printing == pr_cap)
(void) printf("\n");
} else {
if (printed > 0)
switch ((int)printing) {
case (int)pr_terminfo:
case (int)pr_longnames:
(void) printf("\n");
break;
case (int)pr_cap:
(void) printf(":\n");
caplen += 1;
}
}
if (caplen >= 1024) {
(void) fprintf(stderr, "%s: WARNING: termcap entry is too "
"long!\n", progname);
}
if (printing == pr_longnames)
(void) printf("end of strings\n");
}