figlet/figlet.c
2023-03-14 21:12:15 +01:00

268 lines
5.6 KiB
C

#include "FIGlib.h"
#ifdef TIOCGWINSZ
/****************************************************************************
get_columns
Determines the number of columns of /dev/tty. Returns the number of
columns, or -1 if error. May return 0 if columns unknown.
Requires include files <fcntl.h> and <sys/ioctl.h>.
by Glenn Chappell & Ian Chai 14 Apr 1993
****************************************************************************/
int get_columns()
{
struct winsize ws;
int fd,result;
if ((fd = open("/dev/tty",O_WRONLY))<0) return -1;
result = ioctl(fd,TIOCGWINSZ,&ws);
close(fd);
return result?-1:ws.ws_col;
}
#endif /* ifdef TIOCGWINSZ */
/****************************************************************************
getparams
Handles all command-line parameters. Puts all parameters within
bounds.
****************************************************************************/
void getparams()
{
extern char *optarg;
extern int optind;
int c; /* "Should" be a char -- need int for "!= -1" test*/
int columns,infoprint;
char *controlname,*env;
env = getenv("FIGLET_FONTDIR");
if (env!=NULL) {
fontdirname = env;
}
infoprint = -1;
while ((c = getopt(Myargc,Myargv,"ADEXLRI:xlcrpntvm:w:d:f:C:NFskSWo"))!= -1) {
/* Note: -F is not a legal option -- prints a special err message. */
switch (c) {
case 'A':
cmdinput = 1;
break;
case 'D':
deutschflag = 1;
break;
case 'E':
deutschflag = 0;
break;
case 'X':
right2left = -1;
break;
case 'L':
right2left = 0;
break;
case 'R':
right2left = 1;
break;
case 'x':
justification = -1;
break;
case 'l':
justification = 0;
break;
case 'c':
justification = 1;
break;
case 'r':
justification = 2;
break;
case 'p':
paragraphflag = 1;
break;
case 'n':
paragraphflag = 0;
break;
case 's':
smushoverride = SMO_NO;
break;
case 'k':
smushmode = SM_KERN;
smushoverride = SMO_YES;
break;
case 'S':
smushmode = SM_SMUSH;
smushoverride = SMO_FORCE;
break;
case 'o':
smushmode = SM_SMUSH;
smushoverride = SMO_YES;
break;
case 'W':
smushmode = 0;
smushoverride = SMO_YES;
break;
case 't':
#ifdef TIOCGWINSZ
columns = get_columns();
if (columns>0) {
outputwidth = columns;
}
#else /* ifdef TIOCGWINSZ */
fprintf(stderr,
"%s: \"-t\" is disabled, since ioctl is not fully implemented.\n",
myname);
#endif /* ifdef TIOCGWINSZ */
break;
case 'v':
infoprint = 0;
break;
case 'I':
infoprint = atoi(optarg);
break;
case 'm':
smushmode = atoi(optarg);
if (smushmode < -1) {
smushoverride = SMO_NO;
break;
}
if (smushmode == 0) smushmode = SM_KERN;
else if (smushmode == -1) smushmode = 0;
else smushmode = (smushmode & 63) | SM_SMUSH;
smushoverride = SMO_YES;
break;
case 'w':
columns = atoi(optarg);
if (columns>0) {
outputwidth = columns;
}
break;
case 'd':
fontdirname = optarg;
break;
case 'f':
fontname = optarg;
if (suffixcmp(fontname,FONTFILESUFFIX)) {
fontname[MYSTRLEN(fontname)-FSUFFIXLEN] = '\0';
}
#ifdef TLF_FONTS
else if (suffixcmp(fontname,TOILETFILESUFFIX)) {
fontname[MYSTRLEN(fontname)-TSUFFIXLEN] = '\0';
}
#endif
break;
case 'C':
controlname = optarg;
if (suffixcmp(controlname, CONTROLFILESUFFIX)) {
controlname[MYSTRLEN(controlname)-CSUFFIXLEN] = '\0';
}
(*cfilelistend) = (cfnamenode*)myalloc(sizeof(cfnamenode));
(*cfilelistend)->thename = controlname;
cfilelistend = &(*cfilelistend)->next;
(*cfilelistend) = NULL;
break;
case 'N':
clearcfilelist();
multibyte = 0;
gn[0] = 0;
gn[1] = 0x80;
gn[2] = gn[3] = 0;
gndbl[0] = gndbl[1] = gndbl[2] = gndbl[3] = 0;
gl = 0;
gr = 1;
break;
case 'F': /* Not a legal option */
fprintf(stderr,"%s: illegal option -- F\n",myname);
printusage(stderr);
fprintf(stderr,
"\nBecause of numerous incompatibilities, the"
" \"-F\" option has been\n"
"removed. It has been replaced by the \"figlist\""
" program, which is now\n"
"included in the basic FIGlet package. \"figlist\""
" is also available\n"
"from http://www.figlet.org/"
"under UNIX utilities.\n");
exit(1);
break;
default:
printusage(stderr);
exit(1);
}
}
if (optind!=Myargc) cmdinput = 1; /* force cmdinput if more arguments */
if (infoprint>=0) {
printinfo(infoprint);
exit(0);
}
}
/****************************************************************************
main
The main program, of course.
Reads characters 1 by 1 from stdin, and makes lines out of them using
addchar. Handles line breaking, (which accounts for most of the
complexity in this function).
****************************************************************************/
int main(argc,argv)
int argc;
char *argv[];
{
inchr c,c2;
int last_was_eol_flag;
fig_init(argc, argv);
getparams();
readcontrolfiles();
readfont();
linealloc();
last_was_eol_flag = 0;
#ifdef TLF_FONTS
toiletfont = 0;
#endif
while ((c = getinchr())!=EOF) {
if (c=='\n'&&paragraphflag&&!last_was_eol_flag) {
ungetinchr(c2 = getinchr());
c = ((isascii(c2)&&isspace(c2))?'\n':' ');
}
last_was_eol_flag = (isascii(c)&&isspace(c)&&c!='\t'&&c!=' ');
if (deutschflag) {
if (c>='[' && c<=']') {
c = deutsch[c-'['];
}
else if (c >='{' && c <= '~') {
c = deutsch[c-'{'+3];
}
}
c = handlemapping(c);
if (isascii(c)&&isspace(c)) {
c = (c=='\t'||c==' ') ? ' ' : '\n';
}
if ((c>'\0' && c<' ' && c!='\n') || c==127) continue;
fig_puts(c);
}
if (outlinelen!=0) {
fig_flush();
}
return 0;
}