Category : Word Processors
Archive   : CAWF.ZIP
Filename : PASS2.C

 
Output of file : PASS2.C contained in archive : CAWF.ZIP
/*
* pass2.c - cawf(1) pass 2 function
*/

/*
* Copyright (c) 1991 Purdue University Research Foundation,
* West Lafayette, Indiana 47907. All rights reserved.
*
* Written by Victor A. Abell , Purdue
* University Computing Center. Not derived from licensed software;
* derived from awf(1) by Henry Spencer of the University of Toronto.
*
* Permission is granted to anyone to use this software for any
* purpose on any computer system, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The author is not responsible for any consequences of use of
* this software, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either
* by explicit claim or by omission. Credits must appear in the
* documentation.
*
* 3. Altered versions must be plainly marked as such, and must not
* be misrepresented as being the original software. Credits must
* appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/

#include "cawf.h"
#ifdef UNIX
#ifdef USG
#include
#else
#include
#endif
#else
#include
#endif
#include

/*
* Pass2(line) - process the nroff commands in a line and break
* text into words for pass 3
*/

void
Pass2(line)
char *line;
{
char buf[MAXLINE]; /* working buffer */
char c; /* character buffer */
double d; /* temporary double */
double exscale; /* expression scaling factor */
double expr[MAXEXP]; /* expressions */
char exsign[MAXEXP]; /* expression signs */
int i, j, k; /* temporary indexes */
int inword; /* word processing status */
int nexpr; /* number of expressions */
char nm[4]; /* name */
int nsp; /* number of spaces */
char op; /* expression term operator */
char opstack[MAXSP]; /* expression operation stack */
char period; /* end of word status */
char *s1, *s2, *s3, *s4, *s5; /* temporary string pointers */
double sexpr[MAXEXP]; /* signed expressions */
int sp; /* expression stack pointer */
char ssign; /* expression's starting sign */
int tabpos; /* tab position */
double tscale; /* term scaling factor */
double tval; /* term value */
double val; /* term value */
double valstack[MAXSP]; /* expression value stack */
char xbuf[MAXLINE]; /* expansion buffer */

if (line == NULL) {
/*
* End of macro expansion.
*/
Pass3(DOBREAK, "need", NULL, 999); /* flush page */
return;
}
/*
* Adjust line number.
*/
if (Lockil == 0)
P2il++;
/*
* Empty line - "^[ \t]*$".
*/
if (regexec(Pat[6].pat, line)) {
Pass3(DOBREAK, "space", NULL, 0);
return;
}
/*
* Line begins with white space.
*/
if (*line == ' ' || *line == '\t') {
Pass3(DOBREAK, "flush", NULL, 0);
Pass3(0, "", NULL, 0);
}
/*
* Line contains text (not an nroff command).
*/
if (*line != '.') {
if (Font[0] == 'R' && Backc == 0 && Aftnxt == NULL
&& regexec(Pat[7].pat, line) == 0) {
/*
* The font is Roman, there is no "\\c" or "after next"
* trap pending and and the line has no '\\', '\t', '-',
* or " " (regular expression "\\|\t|-| ").
*
* Output each word of the line as " ".
*/
for (s1 = line;;) {
while (*s1 && *s1 == ' ')
s1++;
if (*s1 == '\0')
break;
for (s2 = s1, s3 = buf; *s2 && *s2 != ' ';)
*s3++ = Trtbl[(int)*s2++];
*s3 = '\0';
Pass3((s2 - s1), buf, NULL, 0);
s1 = *s2 ? ++s2 : s2;
}
/*
* Line terminates with punctuation and optional
* bracketing (regular expression "[.!?:][\])'\"*]*$").
*/
if (regexec(Pat[8].pat, line))
Pass3(NOBREAK, "gap", NULL, 2);
if (Centering > 0) {
Pass3(DOBREAK,"center", NULL, 0);
Centering--;
} else if (Fill == 0)
Pass3(DOBREAK, "flush", NULL, 0);

return;
}
/*
* Line must be scanned a character at a time.
*/
inword = nsp = tabpos = 0;
period = '\0';
for (s1 = line;; s1++) {
/*
* Space or TAB causes state transition.
*/
if (*s1 == '\0' || *s1 == ' ' || *s1 == '\t') {
if (inword) {
if (!Backc) {
Word[Wordx] = '\0';
Pass3(Wordl, Word, NULL, 0);
if (Uhyph) {
Pass3(NOBREAK, "nohyphen",
NULL, 0);
}
}
inword = 0;
nsp = 0;
}
if (*s1 == '\0')
break;
} else {
if (inword == 0) {
if (Backc == 0) {
Wordl = Wordx = 0;
Uhyph = 0;
}
Backc = 0;
inword = 1;
if (nsp > 1) {
Pass3(NOBREAK, "gap", NULL,
nsp);
}
}
}
/*
* Process a character.
*/
switch (*s1) {
/*
* Space
*/
case ' ':
nsp++;
period = '\0';
break;
/*
* TAB
*/
case '\t':

tabpos++;
if (tabpos <= Ntabs) {
Pass3(NOBREAK, "tabto", NULL,
Tabs[tabpos-1]);
}
nsp = 0;
period = '\0';
break;
/*
* Hyphen if word is being assembled
*/
case '-':
if (Wordl <= 0)
goto ordinary_char;
if ((i = Findhy(NULL, 0, 0)) < 0) {
Error(WARN, LINE, " no hyphen for font ",
Font);
return;
}
Word[Wordx] = '\0';
Pass3(Wordl, Word, NULL, Hychar[i].len);
Pass3(NOBREAK, "userhyphen", Hychar[i].str,
Hychar[i].len);
Wordl = Wordx = 0;
period = '\0';
Uhyph = 1;
break;
/*
* Backslash
*/
case '\\':
s1++;
switch(*s1) {
/*
* Change font - "\\fN"
*/
case 'f':
s1 = Asmcode(&s1, nm);
if (nm[0] == 'P') {
Font[0] = Prevfont;
break;
}
for (i = 0; Fcode[i].nm; i++) {
if (Fcode[i].nm == nm[0])
break;
}
if (Fcode[i].nm == '\0'
|| nm[1] != '\0') {
Error(WARN, LINE, " unknown font ",
nm);
break;
}
if (Fcode[i].status != '1') {
Error(WARN, LINE,
" font undefined ", nm);
break;
} else {
Prevfont = Font[0];
Font[0] = nm[0];
}
break;
/*
* Positive horizontal motion - "\\h\\n(NN" or
* "\\h\\nN"
*/
case 'h':
if (s1[1] != '\\' || s1[2] != 'n') {
Error(WARN, LINE,
" no \\n after \\h", NULL);
break;
}
s1 +=2;
s1 = Asmcode(&s1, nm);
if ((i = Findnum(nm, 0, 0)) < 0)
goto unknown_num;
if ((j = Numb[i].val) < 0) {
Error(WARN, LINE, " \\h < 0 ",
NULL);
break;
}
if (j == 0)
break;
if ((strlen(s1+1) + j + 1) >= MAXLINE)
goto line_too_long;
for (s2 = &xbuf[1]; j; j--)
*s2++ = ' ';
(void) strcpy(s2, s1+1);
s1 = xbuf;
break;
/*
* Save current position in register if "\\k"
*/
case 'k':
s1 = Asmcode(&s1, nm);
if ((i = Findnum(nm, 0, 0)) < 0)
i = Findnum(nm, 0, 1);
Numb[i].val =
(int)((double)Outll * Scalen);
break;
/*
* Interpolate number - "\\n(NN" or "\\nN"
*/
case 'n':
s1 = Asmcode(&s1, nm);
if ((i = Findnum(nm, 0, 0)) < 0) {
unknown_num:
Error(WARN, LINE,
" unknown number register ",
nm);
break;
}
(void) sprintf(buf, "%d",
Numb[i].val);
if ((strlen(buf) + strlen(s1+1) + 1)
>= MAXLINE) {
line_too_long:
Error(WARN, LINE, " line too long",
NULL);
break;
}
(void) sprintf(buf, "%d%s",
Numb[i].val, s1+1);
(void) strcpy(&xbuf[1], buf);
s1 = xbuf;
break;
/*
* Change size - "\\s[+-][0-9]" - NOP
*/
case 's':
s1++;
if (*s1 == '+' || *s1 == '-')
s1++;
while (*s1 && isdigit(*s1))
s1++;
s1--;
break;
/*
* Continue - "\\c"
*/
case 'c':
Backc = 1;
break;
/*
* Interpolate string - "\\*(NN" or "\\*N"
*/
case '*':
s1 = Asmcode(&s1, nm);
s2 = Findstr(nm, NULL, 0);
if (*s2 != '\0') {
if ((strlen(s2) + strlen(s1+1) + 1)
>= MAXLINE)
goto line_too_long;
(void) sprintf(buf, "%s%s",
s2, s1+1);
(void) strcpy(&xbuf[1], buf);
s1 = xbuf;
}
break;
/*
* Discretionary hyphen - "\\%"
*/
case '%':
if (Wordl <= 0)
break;
if ((i = Findhy(NULL, 0, 0)) < 0) {
Error(WARN, LINE,
" np hyphen for font ", Font);
break;
}
Word[Wordx] = '\0';
Pass3(Wordl, Word, NULL, Hychar[i].len);
Pass3(NOBREAK, "hyphen", Hychar[i].str,
Hychar[i].len);
Wordl = Wordx = 0;
Uhyph = 1;
break;
/*
* None of the above - may be special character
* name.
*/
default:
s2 = --s1;
s1 = Asmcode(&s1, nm);
if ((i = Findchar(nm, 0, 0, 0)) < 0) {
s1 = s2;
goto ordinary_char;
}
if (strcmp(nm, "em") == 0
&& Wordx > 0) {
/*
* "\\(em" is a special case when a word
* has been assembled, because of
* hyphenation.
*/
Word[Wordx] = '\0';
Pass3(Wordl, Word, NULL,
Schar[i].len);
Pass3(NOBREAK, "userhyphen",
Schar[i].str, Schar[i].len);
Wordl = Wordx = 0;
period = '\0';
Uhyph = 1;
}
/*
* Interpolate a special character
*/
if (Str2word(Schar[i].str,
strlen(Schar[i].str)) != 0)
return;
Wordl += Schar[i].len;
period = '\0';
}
break;
/*
* Ordinary character
*/
default:
ordinary_char:
if (Str2word(s1, 1) != 0)
return;
Wordl++;
if (*s1 == '.' || *s1 == '!'
|| *s1 == '?' || *s1 == ':')
period = '.';
else if (period == '.') {
nm[0] = *s1;
nm[1] = '\0';
if (regexec(Pat[13].pat, nm) == 0)
period = '\0';
}
}
}
/*
* End of line processing
*/
if (!Backc) {
if (period == '.')
Pass3(NOBREAK, "gap", NULL, 2);
if (Centering > 0) {
Pass3(DOBREAK, "center", NULL, 0);
Centering--;
} else if (!Fill)
Pass3(DOBREAK, "flush", NULL, 0);
}
if (Aftnxt == NULL)
return;
/* else fall through to process an "after next trap */
}
/*
* Special -man macro handling.
*/
if (Marg == MANMACROS) {
/*
* A text line - "^[^.]" - is only processed when there is an
* "after next" directive.
*/
if (*line != '.') {
if (Aftnxt != NULL) {
if (regexec(Pat[9].pat, Aftnxt)) /* ",fP" */
Font[0] = Prevfont;
if (regexec(Pat[10].pat, Aftnxt)) /* ",tP" */
Pass3(DOBREAK, "toindent", NULL, 0);
Free(&Aftnxt);
}
return;
}
/*
* Special footer handling - "^.lF"
*/
if (line[1] == 'l' && line[2] == 'F') {
s1 = Findstr("by", NULL, 0);
s2 = Findstr("nb", NULL, 0);
if (*s1 == '\0' || *s2 == '\0')
(void) sprintf(buf, "%s%s", s1, s2);
else
(void) sprintf(buf, "%s; %s", s1, s2);
Pass3(NOBREAK, "LF", buf, 0);
return;
}
}
/*
* Special -ms macro handling.
*/
if (Marg == MSMACROS) {
/*
* A text line - "^[^.]" - is only processed when there is an
* "after next" directive.
*/
if (*line != '.') {
if (Aftnxt != NULL) {
if (regexec(Pat[10].pat, Aftnxt)) /* ",tP" */
Pass3(DOBREAK, "toindent", NULL, 0);
Free(&Aftnxt);
}
return;
}
/*
* Numbered headings - "^\.nH"
*/
if (line[1] == 'n' && line[2] == 'H') {
s1 = Field(2, line, 0);
if (s1 != NULL) {
i = atoi(s1) - 1;
if (i < 0) {
for (j = 0; j < MAXNHNR; j++) {
Nhnr[j] = 0;
}
i = 0;
} else if (i >= MAXNHNR) {
(void) sprintf(buf, " over NH limit (%d)",
MAXNHNR);
Error(WARN, LINE, buf, NULL);
}
} else
i = 0;
Nhnr[i]++;
for (j = i + 1; j < MAXNHNR; j++) {
Nhnr[j] = 0;
}
s1 = buf;
for (j = 0; j <= i; j++) {
(void) sprintf(s1, "%d.", Nhnr[j]);
s1 = buf + strlen(buf);
}
(void) Findstr("Nh", buf, 1);
return;
}
}
/*
* Remaining lines should begin with a '.' unless an "after next"
* trap has failed.
*/
if (line[0] != '.') {
if (Aftnxt != NULL)
Error(WARN, LINE, " failed .it: ", Aftnxt);
else
Error(WARN, LINE, " unrecognized line ", NULL);
return;
}
/*
* Evaluate expressions for "^\.(ta|ll|ls|in|ti|po|ne|sp|pl|nr)"
* Then process the commands.
*/
if (regexec(Pat[11].pat, &line[1])) {
/*
* Establish default scale factor.
*/
if ((line[1] == 'n' && line[2] == 'e')
|| (line[1] == 's' && line[2] == 'p')
|| (line[1] == 'p' && line[2] == 'l'))
exscale = Scalev;
else if (line[1] == 'n' && line[2] == 'r')
exscale = Scaleu;
else
exscale = Scalen;
/*
* Determine starting argument.
*/
if (line[1] == 'n' && line[2] == 'r')
s1 = Field(2, &line[3], 0);
else
s1 = Field(1, &line[3], 0);
/*
* Evaluate expressions.
*/
for (nexpr = 0; s1 != NULL &&*s1 != '\0'; ) {
while (*s1 == ' ' || *s1 == '\t')
s1++;
if (*s1 == '+' || *s1 == '-')
ssign = *s1++;
else
ssign = '\0';
/*
* Process terms.
*/
val = 0.0;
sp = -1;
c = '+';
s1--;
while (c == '+' || c == '*' || c == '%'
|| c == ')' || c == '-' || c == '/') {
op = c;
s1++;
tscale = exscale;
tval = 0.0;
/*
* Pop stack on right parenthesis.
*/
if (op == ')') {
tval = val;
if (sp >= 0) {
val = valstack[sp];
op = opstack[sp];
sp--;
} else {
Error(WARN, LINE,
" expression stack underflow", NULL);
return;
}
tscale = Scaleu;
/*
* Push stack on left parenthesis.
*/
} else if (*s1 == '(') {
sp++;
if (sp >= MAXSP) {
Error(WARN, LINE,
" expression stack overflow", NULL);
return;
}
valstack[sp] = val;
opstack[sp] = op;
val = 0.0;
c = '+';
continue;
} else if (*s1 == '\\') {
s1++;
switch(*s1) {
/*
* "\\"" begins a comment.
*/
case '"':
while (*s1)
s1++;
break;
/*
* Crude width calculation for "\\w"
*/
case 'w':
s2 = ++s1;
if (*s1) {
s1++;
while (*s1 && *s1 != *s2)
s1++;
tval = (double) (s1 - s2 - 1) * Scalen;
if (*s1)
s1++;
}
break;
/*
* Interpolate number register if "\\n".
*/
case 'n':
s1 = Asmcode(&s1, nm);
if ((i = Findnum(nm, 0, 0)) >= 0)
tval = Numb[i].val;
s1++;
}
/*
* Assemble numeric value.
*/
} else if (*s1 == '.' || isdigit(*s1)) {
for (i = 0; isdigit(*s1) || *s1 == '.'; s1++) {
if (*s1 == '.') {
i = 10;
continue;
}
d = (double) (*s1 - '0');
if (i) {
tval = tval + (d / (double) i);
i = i * 10;
} else
tval = (tval * 10.0) + d;
}
} else {
/*
* It's not an expression. Ignore extra scale.
*/
if ((i = Findscale(*s1, 0.0, 0)) < 0) {
(void) sprintf(buf,
" \"%s\" isn't an expression", s1);
Error(WARN, LINE, buf, NULL);
}
s1++;
}
/*
* Add term to expression value.
*/
if ((i = Findscale(*s1, 0.0, 0)) >= 0) {
tval *= Scale[i].val;
s1++;
} else
tval *= tscale;
switch (op) {
case '+':
val += tval;
break;
case '-':
val -= tval;
break;
case '*':
val *= tval;
break;
case '/':
case '%':
i = (int) val;
j = (int) tval;
if (j == 0) {
Error(WARN, LINE,
(*s1 == '/') ? "div" : "mod",
" by 0");
return;
}
if (op == '/')
val = (double) (i / j);
else
val = (double) (i % j);
break;
}
c = *s1;
}
/*
* Save expression value and sign.
*/
if (nexpr >= MAXEXP) {
(void) sprintf(buf,
" at expression limit of %d", MAXEXP);
Error(WARN, LINE, buf, NULL);
return;
}
exsign[nexpr] = ssign;
expr[nexpr] = val;
if (ssign == '-')
sexpr[nexpr] = -1.0 * val;
else
sexpr[nexpr] = val;
nexpr++;
while (*s1 == ' ' || *s1 == '\t')
s1++;
}
/*
* Set parameters "(ll|ls|in|ti|po|pl)"
*/
if (regexec(Pat[12].pat, &line[1])) {
nm[0] = line[1];
nm[1] = line[2];
if ((i = Findparms(nm)) < 0) {
Error(WARN, LINE,
" can't find parameter register ", nm);
return;
}
if (nexpr == 0 || exscale == 0.0)
j = Parms[i].prev;
else if (exsign[0] == '\0'
|| (nm[0] == 't' && nm[1] == 'i'))
j = (int)(sexpr[0] / exscale);
else
j = Parms[i].val + (int)(sexpr[0] / exscale);
Parms[i].prev = Parms[i].val;
Parms[i].val = j;
nm[0] = (nexpr) ? exsign[0] : '\0'; /* for .ti */
nm[1] = '\0';
Pass3(DOBREAK, Parms[i].cmd, nm, j);
return;
}
if (line[1] == 'n') {
switch(line[2]) {
/*
* Need - "^\.ne "
*/
case 'e':
if (nexpr && Scalev > 0.0)
i = (int) ((expr[0]/Scalev) + 0.99);
else
i = 0;
Pass3(DOBREAK, "need", NULL, i);
return;
/*
* Number - "^\.nr "
*/
case 'r':
if ((s1 = Field(2, line, 0)) == NULL) {
Error(WARN, LINE, " bad number register",
NULL);
return;
}
if ((i = Findnum(s1, 0, 0)) < 0)
i = Findnum(s1, 0, 1);
if (nexpr < 1) {
Numb[i].val = 0;
return;
}
if (exsign[0] == '\0')
Numb[i].val = (int) expr[0];
else
Numb[i].val += (int) sexpr[0];
return;
}
}
/*
* Space - "^\.sp "
*/
if (line[1] == 's' && line[2] == 'p') {
if (nexpr == 0)
i = 1;
else
i = (int)((expr[0] / Scalev) + 0.99);
while (i--)
Pass3(DOBREAK, "space", NULL, 0);
return;
}
/*
* Tab positions - "^\.ta . . ."
*/
if (line[1] == 't' && line[2] == 'a') {
tval = 0.0;
for (j = 0; j < nexpr; j++) {
if (exsign[j] == '\0')
tval = expr[j];
else
tval += sexpr[j];
Tabs[j] = (int) (tval / Scalen);
}
Ntabs = nexpr;
return;
}
}
/*
* Remaining lines begin with a '.'.
*/

/*
* Adjust - "^\.ad"
*/
if (line[1] == 'a' && line[2] == 'd') {
Pass3(NOBREAK, "both", NULL, 0);
return;
}
if (line[1] == 'b') {
switch (line[2]) {
/*
* Break - "^\.br"
*/
case 'r':
Pass3(DOBREAK, "flush", NULL, 0);
return;
/*
* Begin new page - "^\.bp"
*/
case 'p':
Pass3(DOBREAK, "need", NULL, 999);
return;
}
}
/*
* Center - "^\.ce"
*/
if (line[1] == 'c' && line[2] == 'e') {
if ((s2 = Field(2, line, 0)) != NULL)
Centering = atoi(s2);
else
Centering = 1;
return;
}
if (line[1] == 'd') {
switch (line[2]) {
/*
* Diversion on and off - "^\.di"
*/
case 'i':
Pass3(DOBREAK, "flush", NULL, 0);
Divert ^= 1;
return;
/*
* Define string - "^\.ds"
*/
case 's':

common_ds:

if (Asmname(&line[3], nm) == 0) {
no_name:
Error(WARN, LINE, " no name", NULL);
return;
}
s3 = Field(3, line, 0);
s4 = Findstr(nm, s3, 1);

if (Hdft) {
/*
* Look for names LH, LF, CH, CF, RH, RF.
*/
if ((nm[0]=='L' || nm[0]=='C' || nm[0]=='R')
&& (nm[1]=='F' || nm[1]=='H')) {
(void) sprintf(buf, "%s", nm);
Pass3(NOBREAK, buf, s4, 0);
}
}
return;
}
}
if (line[1] == 'f') {
/*
* Fill - "^\.fi"
*/
if (line[2] == 'i') {
Fill = 1;
Pass3(DOBREAK, "flush", NULL, 0);
return;
}
/*
* Font - "^\.ft "
*/
if (line[2] == 't') {
if (line[3] == '\0' || line[4] == '\0')
line[4] = 'P';
if (line[4] == 'P') {
Font[0] = Prevfont;
return;
}
for (i = 0; Fcode[i].nm; i++) {
if (Fcode[i].nm == line[4])
break;
}
if (Fcode[i].status == '\0') {
Error(WARN, LINE, " bad font code", NULL);
return;
}
Prevfont = Font[0];
Font[0] = line[4];
return;
}
}
/*
* Input trap - "^\.it [1 ]"
*/
if (line[1] == 'i' && line[2] == 't') {
if ((s2 = Field(2, line, 0)) == NULL) {
Free(&Aftnxt);
return;
}
if ((i = atoi(s2)) != 1) {
Error(WARN, LINE, " first .it arg must be 1", NULL);
return;
}
if ((s3 = Field(3, line, 0)) == NULL)
Free(&Aftnxt);
else {
(void) sprintf(buf, "%s,%s",
(Aftnxt == NULL) ? "" : Aftnxt, s3);
Free(&Aftnxt);
Aftnxt = Newstr(buf);
}
return;
}
/*
* "^\.i0", "^\.lg" and "^\.li" - do nothing
*/
if ((line[1] == 'i' && line[2] == '0')
|| (line[1] == 'l' && line[2] == 'g')
|| (line[1] == 'l' && line[2] == 'i'))
return;
if (line[1] == 'n') {
switch (line[2]) {
/*
* No adjust "^\.na"
*/
case 'a':
Pass3(NOBREAK, "left", NULL, 0);
return;
/*
* No fill - "^\.nf"
*/
case 'f':
Fill = 0;
Pass3(DOBREAK, "flush", NULL, 0);
return;
/*
* No space - "^\.ns"
*/
case 's':
Pass3(NOBREAK, "nospace", NULL, 0);
return;
}
}
/*
* Point size - "^\.ps"
*/
if (line[1] == 'p' && line[2] == 's')
return;
if (line[1] == 'r') {
switch (line[2]) {
/*
* Remove macro or string - "^\.rm"
*/
case 'm':
if (Asmname(&line[3], nm) == 0)
goto no_name;
if ((i = Findmacro(nm, 0)) >= 0) {
Delmacro(i);
return;
}
(void) Findstr(nm, NULL, 0);
if (Sx < 0) {
Error(WARN, LINE, " no macro/string", NULL);
return;
}
Delstr(Sx);
return;
/*
* Remove register - "^\.rr"
*/
case 'r':
if (Asmname(&line[3], nm) == 0)
goto no_name;
if ((i = Findnum(nm, 0, 0)) < 0) {
Error(WARN, LINE, " no register", NULL);
return;
}
Delnum(i);
return;
/*
* Resume space - "^\.rs"
*/
case 's':
Pass3(NOBREAK, "yesspace", NULL, 0);
return;
}
}
if (line[1] == 't') {
switch (line[2]) {
/*
* Message - "^\.tm"
*/
case 'm':
Pass3(MESSAGE, Inname,
(line[3] == ' ') ? &line[4] : &line[3], NR);
return;
/*
* Translate - "^\.tr abcd..."
*/
case 'r':
if (line[3] != ' ') {
Error(WARN, LINE, " unknown translation",
NULL);
return;
}
for (s1 = &line[4]; *s1; s1 += 2)
Trtbl[(int)*s1] = (*(s1+1)) ? *(s1+1) : ' ';
return;
}
}
/*
* Vertical spacing - "^\.vs" (do nothing)
*/
if (line[1] == 'v' && line[2] == 's')
return;
if (line[1] == '^') {
switch(line[2]) {
/*
* Initialization - "^\.\^b (fh|HF|NH) [01]"
*
* fh = first page header status
* HF = header/footer status
* NH = initialize number headers
*/
case 'b':
if ((s1 = Field(2, line, 0)) == NULL)
return;
if ((s2 = Field(3, line, 0)) == NULL)
i = 0;
else
i = atoi(s2);
if (s1[0] == 'f' && s1[1] == 'h')
Pass3(NOBREAK, "fph", NULL, i);
else if (s1[0] == 'H' && s1[1] == 'F')
Hdft = i;
else if (s1[0] == 'N' && s1[1] == 'H') {
for (i = 0; i < MAXNHNR; i++)
Nhnr[i] = 0;
} else
Error(WARN, LINE, " unknown initialization",
NULL);
return;
/*
* Character definitions - "^\.\^c"
*/
case 'c':

s2 = Field(2, line, 0);
i = atoi(Field(3, line, 0));
s4 = Field(4, line, 0);
if (i < 0 || i > MAXLINE/2 || *s2 == '\0') {
Error(WARN, LINE, " bad character definition",
NULL);
return;
}
if (s4 == NULL)
s4 = "";
else if (*s4 == '"')
s4++;
s1 = buf;
while ((s5 = strchr(s4, '\\')) != NULL) {
while (s5 > s4)
*s1++ = *s4++;
s4 = ++s5;
if (*s5 == '\\')
*s1++ = '\\';
else if (*s5 == 'b')
*s1++ = '\b';
if (*s4)
s4++;
}
while (*s1++ = *s4++)
;
if (*s2 == 'h' && *(s2+1) == 'y')
(void) Findhy(buf, i, 1);
else
(void) Findchar(s2, i, buf, 1);
return;
/*
* Debug - "^\.\^d"
*/
case 'd':
return;
/*
* Finalization - "\.\^e"
*/
case 'e':
return;
/*
* Font is OK - "\.\^f "
*/
case 'f':
if (line[3] != '\0' && line[4] != '\0') {
for (i = 0; Fcode[i].nm; i++) {
if (line[4] == Fcode[i].nm) {
Fcode[i].status = '1';
return;
}
}
}
Error(WARN, LINE, " unknown font", NULL);
return;
/*
* Resolutions - "\.\^r cpi horizontal vertical"
*/
case 'r':
if ((i = atoi(Field(3, line, 0))) <= 0
|| (j = atoi(Field(4, line, 0))) <= 0) {
Error(WARN, LINE, " bad cpi resolutions",
NULL);
return;
}
tval = (double) (240.0 / (double) i);
if (Findscale('m', tval, 1) < 0)
Error(FATAL, LINE, " missing Scal['m']",
NULL);
Scalen = tval;
if (Scalen <= 0.0) {
(void) sprintf(buf, " bad Scale['n'] (%f)",
Scalen);
Error(FATAL, LINE, buf, NULL);
}
if (Findscale('n', tval, 1) < 0)
Error(FATAL, LINE, " missing Scale['n']",
NULL);
Scalev = (double) (240.0 / (double) j);
if (Scalev <= 0.0) {
(void) sprintf(buf, " bad Scale['v'] (%f)",
Scalen);
Error(FATAL, LINE, buf, NULL);
}
if (Findscale('v', Scalev, 1) < 0)
Error(FATAL, LINE, " missing Scale['v']",
NULL);
return;
/*
* Error file - "^\.\^x "
*/
case 'x':
return;
/*
* Set line number and file name - "^\.\^# "
*
* Lock line number and file name - "^\.\^= "
*/
case '#':
case '=':
if ((s1 = Field(2, line, 0)) != NULL)
P2il = atoi(s1) - 1;
else
P2il = 0;
Lockil = (line[2] == '#') ? 0 : 1;
Free(&P2name);
if (Field(3, line, 1) != NULL) {
P2name = F;
F = NULL;
} else
P2name = NULL;
return;
}
}
/*
* Comment - "^\.\\"
*/
if (line[1] == '\\')
return;
/*
* Unknown command starting with a '.'.
*/
Error(WARN, LINE, " unknown command", NULL);
return;
}


/*
* Str2word(s, len) - copy len characters from string to Word[]
*
* entry:
* s = pointer to string
* len = number of characters to copy
*
* exit:
* return = 0 if characters copied
* 1 if error detected (warning message issued)
*/

Str2word(s, len)
char *s;
int len;
{
for (; len > 0; len--, s++) {
switch (Font[0]) {
case 'B':
if (Fontout == 'e') {
if ((Wordx + 2) >= MAXLINE) {
word_too_long:
Error(WARN, LINE, " word too long",
NULL);
return(1);
}
Word[Wordx++] = ESC;
Word[Wordx++] = 'B';
}
if ((Wordx + 1) >= MAXLINE)
goto word_too_long;
Word[Wordx++] = Trtbl[(int)*s];
if (Fontout == 'b') {
if ((Wordx + 4) >= MAXLINE)
goto word_too_long;
Word[Wordx++] = '\b';
Word[Wordx++] = Trtbl[(int)*s];
Word[Wordx++] = '\b';
Word[Wordx++] = Trtbl[(int)*s];
}
break;
case 'I':
if (isalnum(*s)) {
if (Fontout == 'e') {
if ((Wordx + 2) >= MAXLINE)
goto word_too_long;
Word[Wordx++] = ESC;
Word[Wordx++] = 'I';
} else if (Fontout == 'b') {
if ((Wordx + 2) >= MAXLINE)
goto word_too_long;
Word[Wordx++] = '_';
Word[Wordx++] = '\b';
}
if ((Wordx + 1) >= MAXLINE)
goto word_too_long;
Word[Wordx++] = Trtbl[(int)*s];
break;
}
/* else fall through */
default:
if ((Wordx + 1) >= MAXLINE)
goto word_too_long;
Word[Wordx++] = Trtbl[(int)*s];
}
}
return(0);
}


  3 Responses to “Category : Word Processors
Archive   : CAWF.ZIP
Filename : PASS2.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/