📄 epr.c
字号:
* appropriate number of spaces (determined by tabspaces variables).
*/
{
register char *s;
int c, chrs, num;
int lmflg = 0; /* TRUE ==> printed left margin. */
int pmode; /* Printing mode. */
#define PRINTMODE 0 /* Normal printing character. */
#define TABMODE 1 /* Expand tabs. */
#define UPARROWMODE 2 /* Uparrow prefix. */
s = *sp; /* Local copy of pointer. */
chrs = 0; /* Carriage position (no margin). */
/* DBG(fprintf(dfp,"putline (%o)\n",s);) */
while (1) {
/* Dispatch on next character */
c = *s++ & 0377; /* Pick up a character. */
if (c == EOH) { /* Check for end-of-header. */
*sp = s; /* Update the string pointer. */
return (c); /* Return the terminator. */
}
if (c < SP || c == DEL) {
/* DBG(fprintf(dfp,"Ctrl %03o at %d\n",c,s - *sp);) */
switch (c) {
case CR: /* Terminators. */
case LF:
*sp = s; /* Update the string pointer. */
return (c); /* Return the terminator. */
case BS: /* Backspace -- backup if we can. */
if (chrs) {
putc(c, ofp);
chrs--;
}
continue; /* Proceed with the next char. */
case HT: /* Horizontal tab -- expand it. */
num = tabspaces - (chrs % tabspaces);
pmode = TABMODE;
break;
default: /* Other control characters. */
if (intl && validintl(c)) {
num = 1; /* Int'l mode -- printing char. */
pmode = PRINTMODE;
} else if (sflg) { /* Special header -- print it. */
num = 0; /* Part of an escape sequence? */
pmode = PRINTMODE;
} else if (cchar) {
num = 2; /* Uparrow mode -- prefix it. */
pmode = UPARROWMODE;
} else continue; /* Unwanted char -- ignore it. */
}
} else { /* Regular printing char. */
num = 1;
pmode = PRINTMODE;
}
/*
* If we get here we know we intend to print something.
* So, first we gotta print a left margin (if needed). Next,
* we check whether we're about to cross the right margin.
* If all's OK we print whatever we're trying to print.
*/
if (!lmflg) { /* Output blanks for left margin */
register int n = leftmar;
while (n--) putc(SP,ofp);
lmflg = 1;
}
chrs += num; /* update count */
if (chrs > cpl) { /* handle overflow line */
/* DBG(fprintf(dfp,"Line overflow. *sp %o, s %o, diff %d\n",
*sp,s,s - *sp);) */
if (!trunc) { /* fold line */
if (c != HT) s--; /* back up a char */
*sp = s; /* Return updated pointer. */
return (LL); /* Indicate long line. */
}
}
switch (pmode) { /* Dispatch on special print mode. */
case PRINTMODE: /* Normal printing char. */
putc(c, ofp);
break;
case TABMODE: /* Expand tabs. */
while (num--) putc(SP, ofp);
break;
case UPARROWMODE: /* Uparrow-prefix. */
putc('^', ofp);
if (c == DEL) {
putc('?', ofp);
} else {
putc(c + '@', ofp);
}
}
}
}
validintl (c)
char c;
/*
* Returns 1 if char c is one of the international characters for
* the Epson printer, 0 otherwise. (An international character is
* one that is assigned an Ascii code in the range 0 to 31 decimal,
* but that can be printed if in a special mode--Epson calls this
* mode "control code selection".)
*/
{
if (c < 6 || c == 16 || c == 17 || c >= 21 && c <= 31 && c != 27)
return (1);
else return (0);
}
pcl (argc, argv)
int argc; char **argv;
/*
* Parse command line and set option variables
*/
{
int n;
argc--;
argv++;
n = getopts (argc, argv);
DBG(fprintf(dfp,"getopts => %d, argc %d\n",n,argc);)
argc -= n;
argv += n;
if (nfiles = argc) nextf = argv;
}
getopts (argc, argv)
int argc; char **argv;
/*
* Set option variables according to the command line given in argc/argv.
* Return number of arguments processed.
*/
{
int cnt;
char *p;
cnt = argc;
while (argc) {
DBG(fprintf(dfp,"Processing %d %s\n",argc,*argv);)
p = *argv++; argc--;
if (*p == '-') { /* found a switch */
p++;
while (*p) dodash (*p++);
} else if (p[1] == '=') {
casecvt(p[0]);
if (p[0] == 'h') { /* collect header string */
char delim, *h, c;
p += 2;
delim = *p++;
h = header;
while ((c = *p++) != delim) {
if (c == EOS) {
if (argc == 0)
Abort ("No terminating quote in h=");
p = *argv++; argc--;
*h++ = SP; /* end of a substring in the
* command line before end of
* the end of the header is
* turned into a blank.
*/
}
else *h++ = c;
}
*h++ = EOS;
}
else doequal (p); /* found a keyword */
} else {
argc++; argv--;
break; /* file names follow */
}
}
return (cnt - argc);
}
dodash (c)
char c;
/*
* Process dash option given by c
*/
{
casecvt(c);
DBG(fprintf(dfp,"dodash(%c)\n",c);)
switch (c) {
case 'a': altset++; break;
case 'c': cchar++; break;
case 'f': ffeed++; break;
case 'h': nohead++; break;
case 'i': intl++; break;
case 'o': trunc++; break;
case 'p': pagpaus++; break;
case 's': nopcc++; break;
case '1': nopage1++; break;
case '8': space8++; break;
default:
Abort ("unrecognized switch option -%c",c);
}
}
doequal (s)
char *s;
/*
* Process a keyword=value option given by string s. Notice that there
* is no checking on the bounds of the values accepted by the
* parameters, although there certainly ought to be.
*/
{
char c;
c = *s;
casecvt(c);
s += 2;
switch (c) {
case 'b': tabspaces = atoi(s); break;
case 'c': cmode = country(s); break;
case 'f': optfile (s); break;
case 'l': lpp = atoi(s); break;
case 'm': leftmar = atoi(s); break;
case 'o': strcpy(outfile,s); break;
case 'p': pmode = getpmode (s); break;
case 'q': qmode = getpmode (s); break;
case 't': topmar = atoi(s); break;
case 'w': cpl = atoi(s); break;
default:
Abort ("unrecognized keyword %c=",c);
}
}
country (s)
char *s;
/*
* Matches string s against the list of country mnemonics and, if a
* match is found, returns the corresponding country code. Otherwise,
* returns 0 (default for USA). Only the first two characters of s
* are significant.
*/
{
int n;
char **p;
casecvt(s[0]); casecvt(s[1]); /* make lower case */
for (n = 0, p = cntries; *p; n++, p++) {
if (s[0] == (*p)[0] && s[1] == (*p)[1]) break;
}
if (*p == NULL) n = 0;
return (n);
}
getpmode (s)
char *s;
/*
* Constructs the printer mode from the string s and returns it.
*/
{
int n;
char c;
n = 0;
while (*s) {
c = *s;
casecvt(c);
switch (c) {
case 'b': n |= F_b; break; /* bold (ie, emphasized) */
case 'c': n |= F_c; break; /* condensed */
case 'd': n |= F_d; break; /* double strike */
case 'e': n |= F_e; break; /* enlarged */
case 'i': n |= F_i; break; /* italic */
case 'l': n |= F_l; break; /* elite */
case 'p': n |= F_p; break; /* proportional */
case 's': n |= F_s; break; /* subscript */
case 't': n |= F_t; break; /* top (superscript) */
case 'u': n |= F_u; break; /* underlined */
default:
Abort ("invalid printer mode specifier %c", *s);
}
s++;
}
return (n);
}
respmode(n)
int n; /* The user's mode spec. */
/*
* Resolve a printer mode spec by applying the Epson FX-80
* priority rules. In the descriptions below, "->" means overrides.
*/
{
/* Elite -> Proportional -> Emphasized -> Compressed */
if (n & F_l) n &= ~(F_p|F_b|F_c);
if (n & F_p) n &= ~(F_b|F_c);
if (n & F_b) n &= ~(F_c);
/* Proportional -> (Superscript, Subscript, Double Strike) */
if (n & F_p) n &= ~(F_t|F_s|F_d);
/*
* Superscript and Subscript are exclusive. This program (not
* the Epson FX-80) will give Subscript priority.
*/
if (n & F_s) n &= ~(F_t);
/* Superscript and Subscript imply Double Strike */
if (n & (F_t|F_s)) n |= F_d;
return (n); /* Return the resolved mode. */
}
optfile (filnam)
char *filnam;
/*
* Found f=filnam option. Take options from given file, make them
* appear like command line (build an argc and argv vector), and call
* getopts on the result.
*/
{
FILE *fp;
char buf[160], *p, *argv[16];
int c;
int argc;
fp = fopen (filnam, "r");
if (fp == NULL) {
fprintf (stderr, "File %s not found. ",filnam);
Abort ("Cannot process f= option.");
}
DBG(fprintf(dfp,"Indirect file %s\n",filnam);)
for (p = buf, argc = 0, c = 0; c != EOF; ) {
do c = getc (fp); while (isspace(c)); /* skip blanks */
if (c == EOF) break;
argv[argc++] = p; /* next argument */
do { /* save argument */
*p++ = c;
c = getc(fp);
} while (!isspace(c) && c != EOF);
*p++ = EOS;
DBG(fprintf(dfp,"Arg %d is '%s'\n",argc,argv[argc-1]);)
if (c == EOF) break;
}
DBG(fprintf(dfp,"EOF on optfile\n");)
fclose (fp);
getopts (argc, argv);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -