brf (04/13/83)
/* B B A N - A Better Banner Program - 27apr82 version */ #include <stdio.h> /* table of character translation patterns */ char ctbl[128][7] = { /* stolen from banner */ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /*below 040*/ 0,000,000,000,000,000,000, /* */ 034,034,034,010,0,034,034, /*!*/ 0167,0167,042,0,0,0,0, /*"*/ 024,024,0177,024,0177,024,024, /*#*/ 076,0111,0110,076,011,0111,076, /*$*/ 0161,0122,0164,010,027,045,0107, /*%*/ 030,044,030,070,0105,0102,071, /*&*/ 034,034,010,020,0,0,0, /*'*/ 014,020,040,040,040,020,014, /*(*/ 030,4,2,2,2,4,030, /*)*/ 0,042,024,0177,024,042,0, /***/ 0,010,010,076,010,010,0, /*+*/ 0,0,0,034,034,010,020, /*,*/ 0,0,0,076,0,0,0, /*-*/ 0,0,0,0,034,034,034, /*.*/ 1,2,4,010,020,040,0100, /*/*/ 034,042,0101,0101,0101,042,034, /*0*/ 010,030,050,010,010,010,076, /*1*/ 076,0101,1,076,0100,0100,0177, /*2*/ 076,0101,1,076,1,0101,076, /*3*/ 0100,0102,0102,0102,0177,2,2, /*4*/ 0177,0100,0100,0176,1,0101,076, /*5*/ 076,0101,0100,0176,0101,0101,076, /*6*/ 0177,0102,04,010,020,020,020, /*7*/ 076,0101,0101,076,0101,0101,076, /*8*/ 076,0101,0101,077,1,0101,076, /*9*/ 010,034,010,0,010,034,010, /*:*/ 034,034,0,034,034,010,020, /*;*/ 020,010,4,2,4,010,020, /*<*/ 0,0,076,0,076,0,0, /*=*/ 4,010,020,040,020,010,4, /*>*/ 076,0101,1,016,010,0,010, /*?*/ 076,0101,0135,0135,0136,0100,076, /*@*/ 010,024,042,0101,0177,0101,0101, /*A*/ 0176,0101,0101,0176,0101,0101,0176, /*B*/ 076,0101,0100,0100,0100,0101,076, /*C*/ 0176,0101,0101,0101,0101,0101,0176, /*D*/ 0177,0100,0100,0174,0100,0100,0177, /*E*/ 0177,0100,0100,0174,0100,0100,0100, /*F*/ 076,0101,0100,0117,0101,0101,076, /*G*/ 0101,0101,0101,0177,0101,0101,0101, /*H*/ 034,010,010,010,010,010,034, /*I*/ 1,1,1,1,0101,0101,076, /*J*/ 0102,0104,0110,0160,0110,0104,0102, /*K*/ 0100,0100,0100,0100,0100,0100,0177, /*L*/ 0101,0143,0125,0111,0101,0101,0101, /*M*/ 0101,0141,0121,0111,0105,0103,0101, /*N*/ 0177,0101,0101,0101,0101,0101,0177, /*O*/ 0176,0101,0101,0176,0100,0100,0100, /*P*/ 076,0101,0101,0101,0105,0102,075, /*Q*/ 0176,0101,0101,0176,0104,0102,0101, /*R*/ 076,0101,0100,076,1,0101,076, /*S*/ 0177,010,010,010,010,010,010, /*T*/ 0101,0101,0101,0101,0101,0101,076, /*U*/ 0101,0101,0101,0101,042,024,010, /*V*/ 0101,0111,0111,0111,0111,0111,066, /*W*/ 0101,042,024,010,024,042,0101, /*X*/ 0101,042,024,010,010,010,010, /*Y*/ 0177,2,4,010,020,040,0177, /*Z*/ 076,040,040,040,040,040,076,/*[*/ 0100,040,020,010,004,002,001, /*\*/ 076,2,2,2,2,2,076, /*]*/ 010,024,042,0,0,0,0, /*^*/ 0,000,000,000,000,000,0177, /*_*/ 034,034,010,04,0,0,0, /*`*/ 0,014,022,041,077,041,041, /*A*/ 0,076,041,076,041,041,076, /*B*/ 0,036,041,040,040,041,036, /*C*/ 0,076,041,041,041,041,076, /*D*/ 0,077,040,076,040,040,077, /*E*/ 0,077,040,076,040,040,040, /*F*/ 0,036,041,040,047,041,036, /*G*/ 0,041,041,077,041,041,041, /*H*/ 0,004,004,004,004,004,004, /*I*/ 0,001,001,001,001,041,036, /*J*/ 0,041,042,074,044,042,041, /*K*/ 0,040,040,040,040,040,077, /*L*/ 0,041,063,055,041,041,041, /*M*/ 0,041,061,051,045,043,041, /*N*/ 0,036,041,041,041,041,036, /*O*/ 0,076,041,041,076,040,040, /*P*/ 0,036,041,041,045,042,035, /*Q*/ 0,076,041,041,076,042,041, /*R*/ 0,036,040,036,001,041,036, /*S*/ 0,037,004,004,004,004,004, /*T*/ 0,041,041,041,041,041,036, /*U*/ 0,041,041,041,041,022,014, /*V*/ 0,041,041,041,055,063,041, /*W*/ 0,041,022,014,014,022,041, /*X*/ 0,021,012,004,004,004,004, /*Y*/ 0,077,002,004,010,020,077, /*Z*/ 034,040,040,0140,040,040,034, /*{*/ 010,010,010,0,010,010,010, /*|*/ 034,2,2,3,2,2,034, /*}*/ 060,0111,06,0,0,0,0, /*~*/ 0,000,000,000,000,000,000 /*DEL*/ }; /* string sizes that fit selected printer widths: flag/size/-w=> 72 80 81 120 132 158 174 217 225 -hj 8 9 10 10 15 16 19 21 27 28 -ho 9 8 8 9 13 14 17 19 24 25 -fj 15 4 5 5 8 8 10 11 14 15 -fo 16 4 5 5 7 8 9 10 13 14 note: -jn "lower case" is similar to -on "CAPS" */ /* table of parameter default values */ int dw = 80; /* page width, print positions */ int di = 0; /* indent, print positions */ int db = 0; /* print <pb> blank lines before arg */ /* negative numbers require use of col */ int dnp = 0200; /* contrast: 0200 -> pos, 0 -> neg */ int doj = 0; /* spacing: 0 -> open, 1 -> jammed */ int dclr = 8; /* justification: 8 -> left, 1 -> center, 0 -> right */ int dtv = 0; /* vert size: 0 -> normal, 7 -> double */ int dfh = 0; /* hor size: 0 -> normal, 7 -> double */ int dex = 1; /* echo: 1 -> expand, 0 -> copy thru */ int dau = 1; /* mark case: 1 -> caps, 0 -> asis */ int dkd = 0; /* mark string: 0 -> pmark, 1 -> self */ char dmark[31] = ""; /* marking chars - used serially */ /* parameters to use for current line */ int pw, pi, pb, pnp, poj, pclr, ptv, pfh, pex, pau, pkd; char *pms, pmark[31]; /* global variables */ char *arg, ioarg1[121], ioarg2[121]; /* arg pointer, input areas */ int aargc; char **aargv; int vx, strl; char *chp, *esp, *imk, *mkp, *chh, mk; /* e.g: bban -nk " BBAN " BBANBBANBBANBBANBBANBBANBBANBBANBBANBBANBBANBBANBBANBB BANBBANBBA BAN ANBBAN BANBB NBBAN BANBBANBBA ANBBANBBAN BANBB NB ANBBA BBAN B NBBA BANB ANBBANBBAN NBBANBBANB ANBBA BB NBBAN BAN BAN BAN B NBB NBBANBBANB BBANBBANBB BBA BAN BANBB NB AN BA BBANBBANBB BANBBANBBA BBANB AN BANBB NB BB NBB N BANBBANBBA ANBBANBBAN BANBB NB ANBBA BB NBBAN BA BBAN ANBBANBBAN NBBANBBANB NBB BBA BBANB AN BANBB NBBANBBANB BBANBBANBBANBBANBBANBBANBBANBBANBBANBBANBBANBBANBBANBB */ main(argc, argv) int argc; char **argv; { int firstarg, i, ival, xvx, cwd; char *p, *q, ol[226], *ols; /* check for proper usage */ if(argc < 2) { printf("Usage: bban [-abcdefghijklmnopqrstuvwx] textarg [-] [...]\n"); exit(1); } /* make cmd line args available to other routines */ aargc = argc; aargv = argv; /* set parameters to default values */ pw = dw; pi = di; pb = db; pnp = dnp; poj = doj; pclr = dclr; ptv = dtv; pfh = dfh; pex = dex; pau = dau; pkd = dkd; pms = dmark; imk = pms; /* loop on args from cmd line or std input */ firstarg = 1; while(aqarg() != NULL) { if(*arg == '-') { /* analyze flag args */ p = arg; /* note q flag in loop condition */ while(*++p != '\0' && *p != 'q' && *p != 'Q') switch(*p) { case 'w': case 'W': if((ival = gint(&p)) >= 1 && ival <= 225) pw = ival; else printf("W flag needs numeric 1:225, e.g: -w80\n"); break; case 'i': case 'I': if((ival = gint(&p)) >= 0) pi = ival; else printf("I flag needs numeric >= 0, e.g: -i0\n"); break; case 'b': case 'B': pb = gint(&p); /* extra vertical spacing */ break; case 'n': case 'N': pnp = 0; /* contrast -> negative */ break; case 'p': case 'P': pnp = 0200; /* contrast -> positive */ break; case 'o': case 'O': poj = 0; /* spacing -> open */ break; case 'j': case 'J': poj = 1; /* spacing -> jammed */ break; case 'c': case 'C': pclr = 1; /* justification -> center */ break; case 'l': case 'L': pclr = 8; /* justification -> left */ break; case 'r': case 'R': pclr = 0; /* justification -> right */ break; case 't': case 'T': ptv = 7; /* height -> double */ break; case 'v': case 'V': ptv = 0; /* height -> normal */ break; case 'f': case 'F': pfh = 7; /* width -> double */ break; case 'h': case 'H': pfh = 0; /* width -> normal */ break; case 'e': case 'E': pex = 0; /* echo only - don't expand */ break; case 'x': case 'X': pex = 1; /* expand to banner size */ break; case 'g': case 'G': firstarg = 1; /* reset global defaults */ break; case 'a': case 'A': pau = 0; /* use chars asis for mark */ break; case 'u': case 'U': pau = 1; /* use upper case for mark */ break; case 'k': case 'K': pkd = 1; /* use string to mark itself */ break; case 'd': case 'D': pkd = 0; /* revert to default mark string */ break; case 's': case 'S': pmark[0] = '\0'; /* mark with self */ pms = pmark; pkd = 0; break; case 'm': case 'M': if(aqarg() == NULL) { printf("M flag needs mark string, e.g: -m ABC\n"); break; } for(i = 0; i < 30; i++) { if(*arg == '\0') break; if((pmark[i] = *arg++) <= 040 || pmark[i] == 0177) i--; } pmark[i] = '\0'; pms = pmark; imk = pms; pkd = 0; break; default: /* there ain't many left! */ printf("Illegal flag \"%c\", ignored\n",*p); } if(firstarg) { /* reset defaults to first flag arg */ dw = pw; di = pi; db = pb; dnp = pnp; doj = poj; dclr = pclr; dtv = ptv; dfh = pfh; dex = pex; dau = pau; dkd = pkd; p = dmark; q = pmark; while(*p++ = *q++); pms = dmark; } } else { /* non-flag argument - print it */ /* determine string length and page positioning */ cwd = (pex) ? 9 + pfh - poj : 1; if(pw - pi < cwd) { printf("-i%d and -w%d allow inadequate space\n",pi,pw); continue; } for(i = 0; i < pb; i++) printf("\n"); for(i = 0; i > pb; i--) printf("7"); /* esc-7 */ for (strl = 0; arg[strl]; strl++); if(strl * cwd > pw - pi) strl = (pw - pi) / cwd; ols = ol + pi + ((pw - pi - strl * cwd) >> pclr); for(p = ol; p < ols; p++) *p = ' '; /* blank l.h. margin */ if(pex) { /* expand chars to banner size */ if(pkd) { /* mark w/string itself */ p = arg; for(i = 0; i < 30; i++) { if(*p == '\0') break; pmark[i] = *p++; if(pmark[i] <= 040 || pmark[i] == 0177) i--; else if(pau && pmark[i] >= 'a' && pmark[i] <= 'z') pmark[i] -= ('a' - 'A'); } pmark[i] = '\0'; pms = pmark; imk = pms; } /* loop for each horizontal slice of chars */ for(vx = poj; vx <= 8; vx++) { for(xvx = 0; xvx <= ((vx & ptv) != 0); xvx++) { esp = ol; /* loc of newline */ chp = ols; /* start of 1st char */ doline(); /* format one line */ *esp = '\0'; printf("%s\n",ol); /* VOLA!! */ *esp = ' '; if(*imk == '\0' || *++imk == '\0') imk = pms; } } } else { /* echo without expansion */ esp = ol; chp = ols; for(i = 0; i < strl; i++) { *chp = arg[i]; if(*chp++ != ' ') esp = chp; } *esp = '\0'; printf("%s\n",ol); } /* reset parms to defaults */ pw = dw; pi = di; pb = db; pnp = dnp; poj = doj; pclr = dclr; ptv = dtv; pfh = dfh; pex = dex; pau = dau; pkd = dkd; if(pms != dmark) { pms = dmark; imk = pms; } } firstarg = 0; } for(i = 0; i < pb; i++) printf("\n"); } doline() { int cx, hx, xhx, chs; mkp = imk; for(cx = 0; cx < strl; cx++) { /* loop on chars */ chh = arg + cx; chs = (vx & 7) ? ctbl[*chh][vx - 1] : 0; /* convert mark to upper case */ mk = (pau && *chh >= 'a' && *chh <= 'z') ? *chh - ('a' - 'A') : *chh; for(hx = poj; hx <= 8; hx++) { /* vert slice */ for(xhx = 0; xhx <= ((hx & pfh) != 0); xhx++) { if(*pms) { /* cycle mark string */ mk = *mkp; if(*++mkp == '\0') mkp = pms; } *chp = ((chs << hx & 0200) == pnp) ? mk : ' '; if(*chp++ != ' ') esp = chp; } } } } aqarg() { static int dashsw = 0; if(--aargc > 0) { /* more cmd line args */ if(**++aargv != '-' || *(*aargv+1) != '\0') { arg = *aargv; dashsw = 0; return(1); } else { /* lone dash - std input */ dashsw = 1; if(redarg()) return(1); printf("EOF on std input\n"); return(NULL); } } else { /* read input if dash last */ if(dashsw) return(redarg()); arg = ioarg1; ioarg1[0] = '\0'; return(NULL); } } redarg() { static int c = 1, bufsw = 1; register int i; arg = (bufsw ^= 1) ? ioarg1 : ioarg2; arg[0] = '\0'; if(c == EOF) return(NULL); for(i = 0; i < 120; i++) { arg[i] = (c = getchar()); if(c == '\n' || c == EOF) break; } arg[i] = '\0'; if(c == EOF) return(NULL); if(c == '\n') return(1); while((c = getchar()) != '\n' && c != EOF); return(1); } gint(pp) char **pp; { int dsw = 0, rslt = 0; if(*(*pp+1) == '-') { dsw = 1; (*pp)++; } while(*(*pp+1) >= '0' && *(*pp+1) <= '9') { (*pp)++; rslt = 10 * rslt + **pp - '0'; } if(dsw) return(-rslt); return(rslt); }