home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-08-11 | 72.5 KB | 1,876 lines |
- Newsgroups: comp.sources.misc
- From: jeff@joyce.cs.su.oz.au (Jeff Kingston)
- Subject: v38i081: lout - Lout document formatting system, v2.05, Part13/35
- Message-ID: <1993Aug10.032641.17059@sparky.sterling.com>
- X-Md4-Signature: f32e568b68d6bd0be32cbccfbce9c9fa
- Sender: kent@sparky.sterling.com (Kent Landfield)
- Organization: Sterling Software
- Date: Tue, 10 Aug 1993 03:26:41 GMT
- Approved: kent@sparky.sterling.com
-
- Submitted-by: jeff@joyce.cs.su.oz.au (Jeff Kingston)
- Posting-number: Volume 38, Issue 81
- Archive-name: lout/part13
- Environment: UNIX
- Supersedes: lout: Volume 37, Issue 99-128
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: doc/tr.impl/s5.0 z02.c z15.c z20.c
- # Wrapped by kent@sparky on Sun Aug 8 12:29:25 1993
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 13 (of 35)."'
- if test -f 'doc/tr.impl/s5.0' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/tr.impl/s5.0'\"
- else
- echo shar: Extracting \"'doc/tr.impl/s5.0'\" \(476 characters\)
- sed "s/^X//" >'doc/tr.impl/s5.0' <<'END_OF_FILE'
- X@Section
- X @Title { Galleys }
- X@Begin
- X@PP
- XWith objects and definitions under control, the author faced the problem
- Xof getting body text, footnotes, floating figures and tables,
- Xreferences, index entries, and entries in the table of contents into
- Xtheir places. The resulting investigation occupied three months of
- Xfull-time design work, and proceeded approximately as described in
- XSection {@NumberOf galleys}; the implementation occupied the years 1987-89.
- X@BeginSubSections
- END_OF_FILE
- if test 476 -ne `wc -c <'doc/tr.impl/s5.0'`; then
- echo shar: \"'doc/tr.impl/s5.0'\" unpacked with wrong size!
- fi
- # end of 'doc/tr.impl/s5.0'
- fi
- if test -f 'z02.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'z02.c'\"
- else
- echo shar: Extracting \"'z02.c'\" \(22154 characters\)
- sed "s/^X//" >'z02.c' <<'END_OF_FILE'
- X/*@z02.c:Lexical Analyser:Declarations@***************************************/
- X/* */
- X/* LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05) */
- X/* COPYRIGHT (C) 1993 Jeffrey H. Kingston */
- X/* */
- X/* Jeffrey H. Kingston (jeff@cs.su.oz.au) */
- X/* Basser Department of Computer Science */
- X/* The University of Sydney 2006 */
- X/* AUSTRALIA */
- X/* */
- X/* This program is free software; you can redistribute it and/or modify */
- X/* it under the terms of the GNU General Public License as published by */
- X/* the Free Software Foundation; either version 1, or (at your option) */
- X/* any later version. */
- X/* */
- X/* This program is distributed in the hope that it will be useful, */
- X/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- X/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- X/* GNU General Public License for more details. */
- X/* */
- X/* You should have received a copy of the GNU General Public License */
- X/* along with this program; if not, write to the Free Software */
- X/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- X/* */
- X/* FILE: z02.c */
- X/* MODULE: Lexical Analyser */
- X/* EXTERNS: LexLegalName(), LexInit(), LexPush(), LexPop(), */
- X/* LexNextTokenPos(), LexGetToken() */
- X/* */
- X/* Implementation note: this fast and cryptic lexical analyser is adapted */
- X/* from Waite, W. M.: The Cost of Lexical Analysis, in Software - Practice */
- X/* and Experience, v16, pp473-488 (May 1986). */
- X/* */
- X/*****************************************************************************/
- X#include "externs"
- X#define BUFFER_SIZE 8192 /* size of buffer for block read */
- X#define OTHER 0 /* punctuation or other character */
- X#define LETTER 1 /* letter type */
- X#define QUOTE 2 /* quoted string delimiter type */
- X#define ESCAPE 3 /* escape character inside strings */
- X#define COMMENT 4 /* comment delimiter type */
- X#define CSPACE 5 /* space character type */
- X#define TAB 6 /* tab character type */
- X#define NEWLINE 7 /* newline character type */
- X#define ENDFILE 8 /* end of file character type */
- X
- Xstatic unsigned char chtbl[256]; /* type table indexed by a FULL_CHAR */
- Xstatic FULL_CHAR *chpt; /* pointer to current text character */
- Xstatic FULL_CHAR *frst; /* address of first buffer character */
- Xstatic FULL_CHAR *limit; /* just past last char in buffer */
- Xstatic FULL_CHAR *buf; /* the character buffer start pos */
- Xstatic int blksize; /* size of block read; others too */
- Xstatic FULL_CHAR *startline; /* position in buff of last newline */
- Xstatic FILE_NUM this_file; /* number of currently open file */
- Xstatic FILE *fp; /* current input file */
- Xstatic FILE_POS file_pos; /* current file position */
- Xstatic short ftype; /* the type of the current file */
- Xstatic OBJECT next_token; /* next token if already read */
- Xstatic int offset; /* where to start reading in file */
- Xstatic FULL_CHAR *mem_block; /* file buffer */
- X
- Xstatic int top_stack; /* top of lexical analyser stack */
- Xstatic struct {
- X FULL_CHAR *chpt; /* pointer to current text character */
- X FULL_CHAR *frst; /* address of first buffer character */
- X FULL_CHAR *limit; /* just past last char in buffer */
- X FULL_CHAR *buf; /* the character buffer start pos */
- X int blksize; /* size of block read; others too */
- X FULL_CHAR *startline; /* position in buff of last newline */
- X FILE_NUM this_file; /* number of currently open file */
- X FILE *fp; /* current input file */
- X FILE_POS file_pos; /* current file position */
- X short ftype; /* the type of the current file */
- X OBJECT next_token; /* next token if already read */
- X int offset; /* where to start reading in file */
- X FULL_CHAR *mem_block; /* file buffer */
- X} lex_stack[MAX_LEX_STACK];
- X
- X/*@::LexLegalName(), LexInit()@***********************************************/
- X/* */
- X/* BOOLEAN LexLegalName(str) */
- X/* */
- X/* Check whether str is a valid name for a symbol table entry. */
- X/* Valid names have the BNF form */
- X/* */
- X/* <name> ::= <letter> { <letter> } */
- X/* <name> ::= <special> { <special> } */
- X/* <name> ::= <escape> { <letter> } */
- X/* */
- X/* The third form is inaccessible to users and is for internal use only. */
- X/* */
- X/*****************************************************************************/
- X
- XBOOLEAN LexLegalName(str)
- XFULL_CHAR *str;
- X{ int i; BOOLEAN res;
- X debug1(DLA, DDD, "LexLegalName( %s )", str);
- X switch( chtbl[str[0]] )
- X {
- X case ESCAPE:
- X case LETTER:
- X
- X for( i = 1; chtbl[str[i]] == LETTER; i++ );
- X res = str[i] == '\0';
- X break;
- X
- X
- X case OTHER:
- X
- X for( i = 1; chtbl[str[i]] == OTHER; i++ );
- X res = str[i] == '\0';
- X break;
- X
- X
- X default:
- X
- X res = FALSE;
- X break;
- X
- X }
- X debug1(DLA, DDD, "LexLegalName returning %s", bool(res));
- X return res;
- X} /* end LexLegalName */
- X
- X
- X/*****************************************************************************/
- X/* */
- X/* LexInit() */
- X/* */
- X/* Initialise character types. Those not touched are 0 (OTHER). */
- X/* The function initchtbl() assists in initializing the chtbl. */
- X/* */
- X/*****************************************************************************/
- X
- Xstatic initchtbl(val, str)
- Xint val; FULL_CHAR *str;
- X{ int i;
- X for( i = 0; str[i] != '\0'; i++ )
- X chtbl[ str[i] ] = val;
- X} /* end initchtbl */
- X
- XLexInit()
- X{ initchtbl(LETTER, STR_LETTERS_LOWER);
- X initchtbl(LETTER, STR_LETTERS_UPPER);
- X initchtbl(LETTER, STR_LETTERS_SYMSTART);
- X initchtbl(LETTER, STR_LETTERS_EXTRA0);
- X initchtbl(LETTER, STR_LETTERS_EXTRA1);
- X initchtbl(LETTER, STR_LETTERS_EXTRA2);
- X initchtbl(LETTER, STR_LETTERS_EXTRA3);
- X initchtbl(LETTER, STR_LETTERS_EXTRA4);
- X initchtbl(LETTER, STR_LETTERS_EXTRA5);
- X initchtbl(LETTER, STR_LETTERS_EXTRA6);
- X initchtbl(LETTER, STR_LETTERS_EXTRA7);
- X initchtbl(QUOTE, STR_QUOTE);
- X initchtbl(ESCAPE, STR_ESCAPE);
- X initchtbl(COMMENT, STR_COMMENT);
- X initchtbl(CSPACE, STR_SPACE);
- X initchtbl(TAB, STR_TAB);
- X initchtbl(NEWLINE, STR_NEWLINE);
- X chtbl['\0'] = ENDFILE;
- X} /* end LexInit */
- X
- X/*@::LexPush(), LexPop()@*****************************************************/
- X/* */
- X/* LexPush(x, offs, ftype) */
- X/* */
- X/* Start reading from the file sequence whose first file is x (subsequent */
- X/* files are obtained from NextFile). The first file (x) is to be fseeked */
- X/* to offs. When the sequence is done, ftype determines how to continue: */
- X/* */
- X/* ftype action */
- X/* */
- X/* SOURCE_FILE last input file ends, return @End \Input */
- X/* DATABASE_FILE database file, return @End \Input */
- X/* INCLUDE_FILE include file, must pop lexical analyser and continue */
- X/* */
- X/*****************************************************************************/
- X
- XLexPush(x, offs, ftyp)
- XFILE_NUM x; int offs; int ftyp;
- X{ char *malloc();
- X debug3(DLA, D, "LexPush(%s, %d, %s)", FileName(x), offs,
- X ftyp==SOURCE_FILE ? "source" : ftyp==INCLUDE_FILE ? "include" : "database");
- X if( top_stack >= MAX_LEX_STACK - 1 )
- X Error(FATAL, PosOfFile(x), "%s or %s file %s too deeply nested",
- X KW_INCLUDE, KW_DATABASE, FileName(x));
- X if( top_stack >= 0 ) /* save current state */
- X { lex_stack[top_stack].chpt = chpt;
- X lex_stack[top_stack].frst = frst;
- X lex_stack[top_stack].limit = limit;
- X lex_stack[top_stack].buf = buf;
- X lex_stack[top_stack].blksize = blksize;
- X lex_stack[top_stack].startline = startline;
- X lex_stack[top_stack].this_file = this_file;
- X lex_stack[top_stack].fp = fp;
- X lex_stack[top_stack].ftype = ftype;
- X lex_stack[top_stack].next_token = next_token;
- X lex_stack[top_stack].offset = offset;
- X lex_stack[top_stack].mem_block = mem_block;
- X FposCopy( lex_stack[top_stack].file_pos, file_pos );
- X }
- X top_stack += 1;
- X mem_block = (FULL_CHAR *) malloc((MAX_LINE+BUFFER_SIZE+2)*sizeof(FULL_CHAR));
- X if( mem_block == NULL ) Error(FATAL, PosOfFile(x),
- X "run out of memory when opening file %s", FileName(x));
- X buf = chpt = &mem_block[MAX_LINE];
- X this_file = x; offset = offs;
- X ftype = ftyp; next_token = nil;
- X *chpt = '\0'; fp = null;
- X} /* end LexPush */
- X
- X
- X/*****************************************************************************/
- X/* */
- X/* LexPop() - pop lexical analyser. */
- X/* */
- X/*****************************************************************************/
- X
- XLexPop()
- X{ debug0(DLA, D, "LexPop()");
- X assert( top_stack > 0, "LexPop: top_stack <= 0!" );
- X if( fp != null ) fclose(fp);
- X top_stack--;
- X free( (char *) mem_block);
- X mem_block = lex_stack[top_stack].mem_block;
- X chpt = lex_stack[top_stack].chpt;
- X frst = lex_stack[top_stack].frst;
- X limit = lex_stack[top_stack].limit;
- X buf = lex_stack[top_stack].buf;
- X blksize = lex_stack[top_stack].blksize;
- X startline = lex_stack[top_stack].startline;
- X this_file = lex_stack[top_stack].this_file;
- X fp = lex_stack[top_stack].fp;
- X ftype = lex_stack[top_stack].ftype;
- X next_token = lex_stack[top_stack].next_token;
- X offset = lex_stack[top_stack].offset;
- X FposCopy( file_pos, lex_stack[top_stack].file_pos );
- X} /* end LexPop */
- X
- X
- X/*@::setword(), LexNextTokenPos(), srcnext()@*********************************/
- X/* */
- X/* setword(typ, res, file_pos, str, len) */
- X/* */
- X/* Set variable res to a WORD or QWORD token containing string str, etc. */
- X/* */
- X/*****************************************************************************/
- X
- X#define setword(typ, res, file_pos, str, len) \
- X{ res = NewWord(typ, len, &file_pos); \
- X FposCopy(fpos(res), file_pos); \
- X for( c = 0; c < len; c++ ) string(res)[c] = str[c]; \
- X string(res)[c] = '\0'; \
- X}
- X
- X
- X/*****************************************************************************/
- X/* */
- X/* long LexNextTokenPos() */
- X/* */
- X/* Equivalent to ftell() on the (buffered) current lex file. */
- X/* */
- X/*****************************************************************************/
- X
- Xlong LexNextTokenPos()
- X{ long res;
- X if( next_token != nil )
- X Error(FATAL, &fpos(next_token), "illegal macro invokation in database");
- X res = ftell(fp) - (limit - chpt) - (buf - frst);
- X debug1(DLA, D, "LexNextTokenPos() returning %ld", res);
- X return res;
- X}
- X
- X
- X/*****************************************************************************/
- X/* */
- X/* static srcnext() */
- X/* */
- X/* Move to new line of input file. May need to recharge buffer. */
- X/* */
- X/*****************************************************************************/
- X
- Xstatic srcnext()
- X{ register FULL_CHAR *col;
- X debug4(DLA, DDD, "srcnext(); buf: %d, chpt: %d, frst: %d, limit: %d",
- X buf - mem_block, chpt - mem_block, frst - mem_block, limit - mem_block);
- X
- X /* if time to transfer last line to area preceding buffer, do so */
- X if( blksize != 0 && chpt < limit )
- X { debug0(DLA, DDD, "srcnext: transferring.");
- X col = buf;
- X while( (*--col = *--limit) != CH_NEWLINE );
- X frst = col + 1; limit++; blksize = 0;
- X }
- X
- X /* if buffer is empty, read next block */
- X /*** changed by JK 9/92 from "if( chpt == limit )" to fix long lines bug */
- X if( chpt >= limit )
- X { if( chpt > limit )
- X { col_num(file_pos) = 1;
- X Error(FATAL, &file_pos, "line is too long (or final newline missing)");
- X }
- X chpt = frst;
- X blksize = fread( (char *) buf, sizeof(char), BUFFER_SIZE, fp);
- X debug4(DLA, D, "srcnext: %d = fread(0x%x, %d, %d, fp)",
- X blksize, buf, sizeof(char), BUFFER_SIZE);
- X frst = buf; limit = buf + blksize; *limit = CH_NEWLINE;
- X }
- X
- X /* if nothing more to read, make this clear */
- X if( chpt >= limit )
- X { debug0(DLA, DDD, "srcnext: nothing more to read");
- X chpt = limit = buf; *limit = '\0';
- X }
- X debug4(DLA, DDD, "srcnext returning; buf: %d, chpt: %d, frst: %d, limit: %d",
- X buf - mem_block, chpt - mem_block, frst - mem_block, limit - mem_block);
- X} /* end srcnext */
- X
- X
- X/*@::LexGetToken()@***********************************************************/
- X/* */
- X/* OBJECT LexGetToken() */
- X/* */
- X/* Get next token from input. Look it up in symbol table. */
- X/* */
- X/*****************************************************************************/
- X
- XOBJECT LexGetToken()
- X{
- X FULL_CHAR *startpos; /* where the latest token started */
- X register FULL_CHAR *p, *q; /* pointer to current input char */
- X register int c; /* temporary character (really char) */
- X OBJECT res; /* result token */
- X int vcount, hcount; /* no. of newlines and spaces seen */
- X
- X if( next_token != nil )
- X { next_token = Delete(res = next_token, PARENT);
- X debug2(DLA, DD, "LexGetToken%s (in macro) returning %s",
- X EchoFilePos(&file_pos), EchoToken(res));
- X return res;
- X }
- X
- X res = nil; p = chpt;
- X vcount = hcount = 0;
- X do switch( chtbl[*p++] )
- X {
- X case ESCAPE:
- X
- X col_num(file_pos) = (startpos = p-1) - startline;
- X Error(WARN, &file_pos, "character %c outside quoted string", *startpos);
- X break;
- X
- X
- X case COMMENT:
- X
- X debug1(DLA, DDD, "LexGetToken%s: comment", EchoFilePos(&file_pos));
- X while( (c = *p++) != CH_NEWLINE && c != '\0' );
- X --p;
- X break;
- X
- X
- X case CSPACE:
- X
- X hcount++;
- X break;
- X
- X
- X case TAB:
- X
- X hcount += 8;
- X break;
- X
- X
- X case NEWLINE:
- X
- X chpt = p; srcnext();
- X line_num(file_pos)++;
- X col_num(file_pos) = 0;
- X vcount++; hcount = 0;
- X startline = (p = chpt) - 1;
- X break;
- X
- X
- X case ENDFILE:
- X
- X /* close current file, if any */
- X debug0(DLA, DDD, "LexGetToken: endfile");
- X if( fp != null )
- X { fclose(fp); fp = null;
- X this_file = ftype == SOURCE_FILE ? NextFile(this_file) : NO_FILE;
- X }
- X
- X /* open next file */
- X while( this_file != NO_FILE )
- X { file_num(file_pos) = this_file;
- X line_num(file_pos) = 1;
- X col_num(file_pos) = 0;
- X fp = OpenFile(this_file, FALSE, TRUE);
- X if( fp != null ) break;
- X Error(WARN, &file_pos, "cannot open %s", FileName(this_file));
- X this_file = ftype == SOURCE_FILE ? NextFile(this_file) : NO_FILE;
- X }
- X if( fp != null )
- X { if( offset != 0 )
- X { fseek(fp, (long) offset, 0);
- X offset = 0L;
- X }
- X frst = limit = chpt = buf;
- X blksize = 0; srcnext();
- X startline = (p = chpt) - 1;
- X hcount = 0;
- X }
- X
- X /* no next file, so take continuation */
- X else switch( ftype )
- X {
- X case SOURCE_FILE:
- X case DATABASE_FILE:
- X
- X /* input ends with "@End \Input" */
- X res = NewToken(END, &file_pos, 0, 0, END_PREC, nil);
- X next_token = NewToken(CLOSURE, &file_pos, 0,0, NO_PREC, StartSym);
- X --p; startline = p;
- X break;
- X
- X case INCLUDE_FILE:
- X
- X LexPop();
- X (p = chpt) - 1;
- X hcount = 0;
- X break;
- X
- X default: Error(INTERN, no_fpos, "ftype!");
- X
- X } /* end switch */
- X break;
- X
- X
- X case OTHER:
- X
- X col_num(file_pos) = (startpos = p-1) - startline;
- X while( chtbl[*p++] == OTHER );
- X c = p - startpos - 1;
- X do
- X { res = SearchSym(startpos, c);
- X --c; --p;
- X } while( c > 0 && res == nil );
- X goto MORE; /* 7 lines down */
- X break;
- X
- X
- X case LETTER:
- X
- X col_num(file_pos) = (startpos = p-1) - startline;
- X while( chtbl[*p++] == LETTER ); --p;
- X res = SearchSym(startpos, p - startpos);
- X
- X MORE: if( res == nil )
- X { setword(WORD, res, file_pos, startpos, p-startpos);
- X }
- X else if( type(res) == MACRO )
- X { if( recursive(res) )
- X { Error(WARN, &file_pos, "recursion in macro");
- X setword(WORD, res, file_pos, startpos, p-startpos);
- X }
- X else
- X { res = CopyTokenList( sym_body(res), &file_pos );
- X if( res != nil ) next_token = Delete(res, PARENT);
- X else hcount = 0;
- X }
- X }
- X else if( predefined(res) == 0 )
- X { res = NewToken(CLOSURE, &file_pos, 0, 0, precedence(res), res);
- X }
- X else if( predefined(res) == INCLUDE || predefined(res) == SYS_INCLUDE )
- X { OBJECT t, fname; FILE_NUM fnum; int len;
- X chpt = p;
- X t = LexGetToken();
- X if( type(t) != LBR )
- X { Error(WARN, &fpos(t), "%s expected after %s", KW_LBR, SymName(res));
- X Dispose(t);
- X res = nil;
- X break;
- X }
- X fname = Parse(&t, nil, FALSE, FALSE);
- X fname = ReplaceWithTidy(fname);
- X if( !is_word(type(fname)) )
- X { Error(WARN, &fpos(fname), "name of %s file expected here",
- X SymName(res));
- X Dispose(fname);
- X res = nil;
- X break;
- X }
- X len = StringLength(string(fname)) - StringLength(SOURCE_SUFFIX);
- X if( len >= 0 && StringEqual(&string(fname)[len], SOURCE_SUFFIX) )
- X StringCopy(&string(fname)[len], STR_EMPTY);
- X fnum = DefineFile(string(fname), STR_EMPTY, &fpos(fname),
- X INCLUDE_FILE,
- X predefined(res)==INCLUDE ? INCLUDE_PATH : SYSINCLUDE_PATH);
- X Dispose(fname);
- X LexPush(fnum, 0, INCLUDE_FILE);
- X res = LexGetToken();
- X p = chpt;
- X }
- X else res = NewToken(predefined(res), &file_pos,0,0,precedence(res),res);
- X break;
- X
- X
- X case QUOTE:
- X
- X col_num(file_pos) = (startpos = q = p) - 1 - startline;
- X do switch( chtbl[*q++ = *p++] )
- X {
- X case OTHER:
- X case LETTER:
- X case COMMENT:
- X case CSPACE:
- X case TAB: break;
- X
- X case NEWLINE:
- X case ENDFILE: --p;
- X Error(WARN, &file_pos, "unterminated string");
- X setword(QWORD, res, file_pos, startpos, q-1-startpos);
- X break;
- X
- X case QUOTE: setword(QWORD, res, file_pos, startpos, q-1-startpos);
- X break;
- X
- X case ESCAPE: q--;
- X if( chtbl[*p] == NEWLINE || chtbl[*p] == ENDFILE )
- X { Error(WARN, &file_pos, "unterminated string");
- X setword(QWORD, res, file_pos, startpos, q-startpos);
- X }
- X else if( octaldigit(*p) )
- X { int count, ch;
- X count = ch = 0;
- X do
- X { ch = ch * 8 + digitchartonum(*p++);
- X count++;
- X } while( octaldigit(*p) && count < 3 );
- X if( ch == '\0' ) Error(WARN, &file_pos,
- X "skipping null character \0 in string");
- X else *q++ = ch;
- X }
- X else *q++ = *p++;
- X break;
- X
- X default: Error(INTERN, &file_pos, "LexGetToken: quoted string");
- X break;
- X
- X } while( res == nil );
- X break;
- X
- X
- X default:
- X
- X Error(INTERN, &file_pos, "LexGetToken: bad chtbl[]");
- X break;
- X
- X } while( res == nil );
- X
- X if( p - startline >= MAX_LINE )
- X { col_num(file_pos) = 1;
- X Error(FATAL, &file_pos, "line is too long (or final newline missing)");
- X }
- X
- X chpt = p;
- X vspace(res) = vcount;
- X hspace(res) = hcount;
- X debug4(DLA, DD, "LexGetToken%s returning %s %s (@%d)",
- X EchoFilePos(&file_pos), Image(type(res)), EchoToken(res), (int) res);
- X return res;
- X} /* end LexGetToken */
- END_OF_FILE
- if test 22154 -ne `wc -c <'z02.c'`; then
- echo shar: \"'z02.c'\" unpacked with wrong size!
- fi
- # end of 'z02.c'
- fi
- if test -f 'z15.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'z15.c'\"
- else
- echo shar: Extracting \"'z15.c'\" \(23939 characters\)
- sed "s/^X//" >'z15.c' <<'END_OF_FILE'
- X/*@z15.c:Size Constraints:MinConstraint(), EnlargeToConstraint()@*************/
- X/* */
- X/* LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05) */
- X/* COPYRIGHT (C) 1993 Jeffrey H. Kingston */
- X/* */
- X/* Jeffrey H. Kingston (jeff@cs.su.oz.au) */
- X/* Basser Department of Computer Science */
- X/* The University of Sydney 2006 */
- X/* AUSTRALIA */
- X/* */
- X/* This program is free software; you can redistribute it and/or modify */
- X/* it under the terms of the GNU General Public License as published by */
- X/* the Free Software Foundation; either version 1, or (at your option) */
- X/* any later version. */
- X/* */
- X/* This program is distributed in the hope that it will be useful, */
- X/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- X/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- X/* GNU General Public License for more details. */
- X/* */
- X/* You should have received a copy of the GNU General Public License */
- X/* along with this program; if not, write to the Free Software */
- X/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- X/* */
- X/* FILE: z15.c */
- X/* MODULE: Size Constraints */
- X/* EXTERNS: MinConstraint(), EnlargeToConstraint(), */
- X/* ReflectConstraint(), SemiRotateConstraint(), */
- X/* RotateConstraint(), InvScaleConstraint(), Constrained(), */
- X/* EchoConstraint(), DebugConstrained() */
- X/* */
- X/*****************************************************************************/
- X#include <math.h>
- X#ifndef M_PI
- X#define M_PI 3.1415926535897931160E0
- X#endif
- X
- X#include "externs"
- X
- X
- X/*****************************************************************************/
- X/* */
- X/* MinConstraint(xc, yc) */
- X/* */
- X/* Replace *xc by the minimum of the two constraints *xc and *yc. */
- X/* */
- X/*****************************************************************************/
- X
- XMinConstraint(xc, yc)
- XCONSTRAINT *xc, *yc;
- X{ bc(*xc) = min(bc(*xc), bc(*yc));
- X bfc(*xc) = min(bfc(*xc), bfc(*yc));
- X fc(*xc) = min(fc(*xc), fc(*yc));
- X} /* end MinConstraint */
- X
- X
- X/*****************************************************************************/
- X/* */
- X/* EnlargeToConstraint(b, f, c) */
- X/* */
- X/* Enlarge *b,*f to its largest possible value within constraint *c. */
- X/* */
- X/*****************************************************************************/
- X
- XEnlargeToConstraint(b, f, c)
- XLENGTH *b, *f; CONSTRAINT *c;
- X{
- X *f = min(bfc(*c) - *b, fc(*c));
- X} /* end EnlargeToConstraint */
- X
- X
- X/*@::InvScaleConstraint(), ReflectConstraint(), etc.@*************************/
- X/* */
- X/* InvScaleConstraint(yc, sf, xc) */
- X/* */
- X/* Scale constraint xc to the inverse of the scale factor sf. */
- X/* */
- X/*****************************************************************************/
- X
- XInvScaleConstraint(yc, sf, xc)
- XCONSTRAINT *yc; LENGTH sf; CONSTRAINT *xc;
- X{ char buff[10];
- X ifdebug(DSC, D, sprintf(buff, "%.3f", (float) sf / SF));
- X debug2(DSC, D, "InvScaleConstraint(yc, %s, %s)", buff, EchoConstraint(xc));
- X assert( sf > 0, "InvScaleConstraint: sf <= 0!" );
- X bc(*yc) = bc(*xc) == MAX_LEN ? MAX_LEN : min(MAX_LEN, bc(*xc) * SF / sf);
- X bfc(*yc) = bfc(*xc) == MAX_LEN ? MAX_LEN : min(MAX_LEN, bfc(*xc) * SF / sf);
- X fc(*yc) = fc(*xc) == MAX_LEN ? MAX_LEN : min(MAX_LEN, fc(*xc) * SF / sf);
- X debug1(DSC, D, "InvScaleConstraint returning %s", EchoConstraint(yc));
- X} /* end InvScaleConstraint */
- X
- X
- X/*****************************************************************************/
- X/* */
- X/* ReflectConstraint(xc, yc) */
- X/* */
- X/* Set xc to the constraint which is yc with its back and forward reversed. */
- X/* */
- X/*****************************************************************************/
- X
- X#define ReflectConstraint(xc, yc) SetConstraint(xc, fc(yc), bfc(yc), bc(yc))
- X
- X
- X/*****************************************************************************/
- X/* */
- X/* static SemiRotateConstraint(xc, u, v, angle, yc) */
- X/* */
- X/* Used by RotateConstraint to calculate one rotated constraint. */
- X/* */
- X/*****************************************************************************/
- X
- Xstatic SemiRotateConstraint(xc, u, v, angle, yc)
- XCONSTRAINT *xc; LENGTH u, v; float angle; CONSTRAINT *yc;
- X{ float cs, sn; char buff[20];
- X ifdebug(DSC, D, sprintf(buff, "%.1f", angle * 360.0 / (2 * M_PI)));
- X debug4(DSC, D, "SemiRotateConstraint(xc, %s, %s, %sd, %s",
- X EchoLength(u), EchoLength(v), buff, EchoConstraint(yc));
- X cs = cos(angle); sn = sin(angle);
- X if( fabs(cs) < 1e-6 )
- X SetConstraint(*xc, MAX_LEN, MAX_LEN, MAX_LEN);
- X else
- X SetConstraint(*xc,
- X min(MAX_LEN, (bc(*yc) - u * sn) / cs),
- X min(MAX_LEN, (bfc(*yc) - u * sn - v * sn) / cs),
- X min(MAX_LEN, (fc(*yc) - v * sn) / cs) );
- X debug1(DSC, D, "SemiRotateConstraint returning %s", EchoConstraint(xc));
- X} /* end SemiRotateConstraint */
- X
- X
- X/*@::RotateConstraint()@******************************************************/
- X/* */
- X/* RotateConstraint(c, y, angle, hc, vc, dim) */
- X/* */
- X/* Take the object angle @Rotate y, which is supposed to be constrained */
- X/* horizontally by hc and vertically by vc, and determine a constraint */
- X/* (either horizontal or vertical, depending on dim) for y. */
- X/* */
- X/* The constraint returned is a trigonometric function of all these */
- X/* parameters, including the present size of y in dimension 1-dim. */
- X/* */
- X/*****************************************************************************/
- X
- XRotateConstraint(c, y, angle, hc, vc, dim)
- XCONSTRAINT *c; OBJECT y; LENGTH angle; CONSTRAINT *hc, *vc; int dim;
- X{ CONSTRAINT c1, c2, c3, dc; float theta, psi;
- X char buff[20];
- X ifdebug(DSC, D, sprintf(buff, "%.1f", (float) angle / DG ));
- X debug4(DSC, D, "RotateConstraint(c, y, %sd, %s, %s, %s)",
- X buff, EchoConstraint(hc), EchoConstraint(vc), dimen(dim));
- X
- X /* work out angle in radians between 0 and 2*PI */
- X theta = (float) angle * 2 * M_PI / (float) (DG * 360);
- X while( theta < 0 ) theta += 2 * M_PI;
- X while( theta >= 2 * M_PI ) theta -= 2 * M_PI;
- X assert( 0 <= theta && theta <= 2 * M_PI, "RotateConstraint: theta!" );
- X
- X /* determine theta, c1, and c2 depending on which quadrant we are in */
- X if( theta <= M_PI / 2.0 ) /* first quadrant */
- X { theta = theta;
- X CopyConstraint(c1, *hc);
- X CopyConstraint(c2, *vc);
- X }
- X else if ( theta <= M_PI ) /* second quadrant */
- X { theta -= M_PI / 2.0;
- X ReflectConstraint(c1, *vc);
- X CopyConstraint(c2, *hc);
- X }
- X else if ( theta <= 3.0 * M_PI / 2.0 ) /* third quadrant */
- X { theta -= M_PI;
- X ReflectConstraint(c1, *hc);
- X ReflectConstraint(c2, *vc);
- X }
- X else /* fourth quadrant */
- X { theta -= 3.0 * M_PI / 2.0;
- X CopyConstraint(c1, *vc);
- X ReflectConstraint(c2, *hc);
- X }
- X psi = M_PI / 2.0 - theta;
- X debug2(DSC, D, " c1: %s; c2: %s", EchoConstraint(&c1), EchoConstraint(&c2));
- X
- X /* return the minimum of the two constraints, rotated */
- X if( dim == COL )
- X { SemiRotateConstraint(c, back(y, ROW), fwd(y, ROW), theta, &c1);
- X ReflectConstraint(c3, c2);
- X SemiRotateConstraint(&dc, fwd(y, ROW), back(y, ROW), psi, &c3);
- X MinConstraint(c, &dc);
- X }
- X else
- X { SemiRotateConstraint(c, back(y, COL), fwd(y, COL), psi, &c1);
- X SemiRotateConstraint(&dc, fwd(y, COL), back(y, COL), theta, &c2);
- X MinConstraint(c, &dc);
- X }
- X
- X debug1(DSC, D, "RotateConstraint returning %s", EchoConstraint(c));
- X} /* end RotateConstraint */
- X
- X
- X/*@::CatConstrained()@********************************************************/
- X/* */
- X/* static CatConstrained(x, xc, ratm, y, dim) */
- X/* */
- X/* Calculate the size constraint of object x, as for Constrained below. */
- X/* y is the enclosing VCAT etc. object; ratm is TRUE if a ^ lies after */
- X/* x anywhere. dim is COL or ROW. */
- X/* */
- X/* The meaning of the key variables is as follows: */
- X/* */
- X/* be The amount by which back(x, dim) can increase from zero */
- X/* without having any impact on size(y, dim). Thereafter, */
- X/* any increase causes an equal increase in size(y, dim). */
- X/* */
- X/* fe The amount by which fwd(x, dim) can increase from zero */
- X/* without having any impact on size(y, dim). Thereafter, */
- X/* any increase causes an equal increase in size(y, dim). */
- X/* */
- X/* backy, The value that back(y, dim) and fwd(y, dim) would have if x */
- X/* fwdy was definite with size 0,0. They will in general be larger */
- X/* than the present values if x is indefinite, and smaller */
- X/* if x is definite, although it depends on marks and gaps. */
- X/* */
- X/*****************************************************************************/
- X
- Xstatic CatConstrained(x, xc, ratm, y, dim)
- XOBJECT x; CONSTRAINT *xc; BOOLEAN ratm; OBJECT y; int dim;
- X{ int side; /* the size of y that x is on: BACK, ON, FWD */
- X CONSTRAINT yc; /* constraints on y */
- X LENGTH backy, fwdy; /* back(y), fwd(y) would be if x was (0, 0) */
- X LENGTH be, fe; /* amount back(x), fwd(x) can be for free */
- X LENGTH beffect, feffect; /* scratch variables for calculations */
- X LENGTH seffect; /* scratch variables for calculations */
- X OBJECT link, sg, pg; /* link to x, its successor and predecessor */
- X OBJECT prec_def, sd; /* definite object preceding (succeeding) x */
- X int tb, tbf, tf, tbc, tbfc, tfc, mxy, myz;
- X
- X Constrained(y, &yc, dim);
- X if( constrained(yc) )
- X {
- X /* find the link of x, and its neighbours and their links */
- X link = UpDim(x, dim);
- X SetNeighbours(link, ratm, &pg, &prec_def, &sg, &sd, &side);
- X
- X /* amount of space available at x without changing the size of y */
- X be = pg == nil ? 0 : ExtraGap(fwd(prec_def, dim), 0, &gap(pg), BACK);
- X fe = sg == nil ? 0 : ExtraGap(0, back(sd, dim), &gap(sg), FWD);
- X
- X if( is_indefinite(type(x)) )
- X {
- X /* insert two lengths and delete one */
- X beffect = pg == nil ? 0 : MinGap(fwd(prec_def, dim), 0, 0, &gap(pg));
- X feffect = sg == nil ? 0 : MinGap(0, back(sd,dim), fwd(sd,dim), &gap(sg));
- X seffect = pg == nil ?
- X sg == nil ? 0 : back(sd, dim) :
- X sg == nil ? fwd(prec_def, dim) :
- X MinGap(fwd(prec_def, dim), back(sd, dim), fwd(sd, dim), &gap(sg));
- X
- X switch( side )
- X {
- X case BACK: backy = back(y, dim) + beffect + feffect - seffect;
- X fwdy = fwd(y, dim);
- X break;
- X
- X case ON: /* must be first, other cases prohibited */
- X backy = 0;
- X fwdy = fwd(y, dim) + feffect;
- X break;
- X
- X case FWD: backy = back(y, dim);
- X fwdy = fwd(y, dim) + beffect + feffect - seffect;
- X break;
- X }
- X }
- X
- X else /* x is definite */
- X
- X { beffect = pg == nil ? back(x, dim) :
- X MinGap(fwd(prec_def, dim), back(x,dim), fwd(x,dim), &gap(pg)) -
- X MinGap(fwd(prec_def, dim), 0, 0, &gap(pg));
- X
- X feffect = sg == nil ? fwd(x, dim) :
- X MinGap(fwd(x, dim), back(sd, dim), fwd(sd, dim), &gap(sg)) -
- X MinGap(0, back(sd, dim), fwd(sd, dim), &gap(sg));
- X
- X switch( side )
- X {
- X case BACK: backy = back(y, dim) - beffect - feffect;
- X fwdy = fwd(y, dim);
- X break;
- X
- X case ON: backy = back(y, dim) - beffect;
- X fwdy = fwd(y, dim) - feffect;
- X break;
- X
- X case FWD: backy = back(y, dim);
- X fwdy = fwd(y, dim) - beffect - feffect;
- X break;
- X }
- X }
- X
- X debug5(DSC, DDD, "side: %s, backy: %s, fwdy: %s, be: %s, fe: %s",
- X Image(side), EchoLength(backy), EchoLength(fwdy),
- X EchoLength(be), EchoLength(fe) );
- X
- X if( !FitsConstraint(backy, fwdy, yc) )
- X SetConstraint(*xc, -1, -1, -1);
- X else switch( side )
- X {
- X
- X case BACK:
- X
- X tbc = bc(yc) == MAX_LEN ? MAX_LEN : bc(yc) - backy;
- X tbfc = bfc(yc) == MAX_LEN ? MAX_LEN : bfc(yc) - backy - fwdy;
- X mxy = min(tbc, tbfc);
- X tb = min(MAX_LEN, be + mxy);
- X tbf = min(MAX_LEN, be + fe + mxy);
- X tf = min(MAX_LEN, fe + mxy);
- X SetConstraint(*xc, tb, tbf, tf);
- X break;
- X
- X
- X case ON:
- X
- X tbc = bc(yc) == MAX_LEN ? MAX_LEN : bc(yc) - backy;
- X tbfc = bfc(yc) == MAX_LEN ? MAX_LEN : bfc(yc) - backy - fwdy;
- X tfc = fc(yc) == MAX_LEN ? MAX_LEN : fc(yc) - fwdy;
- X mxy = min(tbc, tbfc);
- X myz = min(tfc, tbfc);
- X tb = min(MAX_LEN, be + mxy);
- X tbf = min(MAX_LEN, be + fe + tbfc);
- X tf = min(MAX_LEN, fe + myz);
- X SetConstraint(*xc, tb, tbf, tf);
- X break;
- X
- X
- X case FWD:
- X
- X tfc = fc(yc) == MAX_LEN ? MAX_LEN : fc(yc) - fwdy;
- X tbfc = bfc(yc) == MAX_LEN ? MAX_LEN : bfc(yc) - backy - fwdy;
- X mxy = min(tfc, tbfc);
- X tb = min(MAX_LEN, be + mxy);
- X tbf = min(MAX_LEN, be + fe + mxy);
- X tf = min(MAX_LEN, fe + mxy);
- X SetConstraint(*xc, tb, tbf, tf);
- X break;
- X
- X }
- X } /* end if( constrained ) */
- X else SetConstraint(*xc, MAX_LEN, MAX_LEN, MAX_LEN);
- X} /* end CatConstrained */
- X
- X
- X/*@::Constrained()@***********************************************************/
- X/* */
- X/* Constrained(x, xc, dim) */
- X/* */
- X/* Calculate the size constraint of object x, and return it in *xc. */
- X/* */
- X/*****************************************************************************/
- X
- XConstrained(x, xc, dim)
- XOBJECT x; CONSTRAINT *xc; int dim;
- X{ OBJECT y, link, lp, rp, z, tlink, g; CONSTRAINT yc, hc, vc;
- X BOOLEAN ratm; LENGTH xback, xfwd; int tb, tf, tbf, tbc, tfc;
- X debug2(DSC, DD, "[ Constrained( %s, xc, %s )", EchoObject(x), dimen(dim));
- X assert( Up(x) != x, "Constrained: x has no parent!" );
- X
- X /* find y, the parent of x */
- X link = UpDim(x, dim); ratm = FALSE;
- X for( tlink = NextDown(link); type(tlink) == LINK; tlink = NextDown(tlink) )
- X { Child(g, tlink);
- X if( type(g) == GAP_OBJ && mark(gap(g)) ) ratm = TRUE;
- X }
- X y = tlink;
- X debug1(DSC, DDD, "parent y = %s", Image(type(y)));
- X ifdebug(DSC, DDD, DebugObject(y));
- X
- X switch( type(y) )
- X {
- X case GRAPHIC:
- X case ONE_COL:
- X case ONE_ROW:
- X case HCONTRACT:
- X case VCONTRACT:
- X case HEXPAND:
- X case VEXPAND:
- X case PADJUST:
- X case HADJUST:
- X case VADJUST:
- X case SPLIT:
- X
- X Constrained(y, xc, dim);
- X break;
- X
- X
- X case VSCALE:
- X case HSCALE:
- X
- X if( (dim == COL) != (type(y) == HSCALE) ) Constrained(y, xc, dim);
- X else SetConstraint(*xc, MAX_LEN, MAX_LEN, MAX_LEN);
- X break;
- X
- X
- X case SCALE:
- X
- X Constrained(y, &yc, dim);
- X InvScaleConstraint(xc,
- X dim == COL ? bc(constraint(y)) : fc(constraint(y)), &yc);
- X break;
- X
- X
- X case ROTATE:
- X
- X Constrained(y, &hc, COL); Constrained(y, &vc, ROW);
- X RotateConstraint(xc, x, sparec(constraint(y)), &hc, &vc, dim);
- X break;
- X
- X
- X case WIDE:
- X case HIGH:
- X
- X Constrained(y, xc, dim);
- X if( (type(y)==WIDE) == (dim==COL) ) MinConstraint(xc, &constraint(y));
- X break;
- X
- X
- X case HEAD:
- X
- X if( dim == ROW ) SetConstraint(*xc, MAX_LEN, MAX_LEN, MAX_LEN);
- X else
- X { CopyConstraint(yc, constraint(y));
- X debug1(DSC, DD, " head: %s; val is:", EchoConstraint(&yc));
- X ifdebug(DSC, DD, DebugObject(y));
- X goto REST_OF_HEAD; /* a few lines down */
- X }
- X break;
- X
- X
- X case COL_THR:
- X case ROW_THR:
- X
- X assert( (type(y)==COL_THR) == (dim==COL), "Constrained: COL_THR!" );
- X Constrained(y, &yc, dim);
- X tb = bfc(yc) == MAX_LEN ? MAX_LEN : bfc(yc) - fwd(y, dim);
- X tb = min(bc(yc), tb);
- X tf = bfc(yc) == MAX_LEN ? MAX_LEN : bfc(yc) - back(y, dim);
- X tf = min(fc(yc), tf);
- X SetConstraint(*xc, tb, bfc(yc), tf);
- X break;
- X
- X
- X case VCAT:
- X case HCAT:
- X case ACAT:
- X
- X if( (type(y)==VCAT) == (dim==ROW) )
- X { CatConstrained(x, xc, ratm, y, dim);
- X break;
- X }
- X Constrained(y, &yc, dim);
- X if( !constrained(yc) ) SetConstraint(*xc, MAX_LEN, MAX_LEN, MAX_LEN);
- X else
- X {
- X REST_OF_HEAD:
- X /* let lp and rp be the links of the gaps delimiting */
- X /* the components joined to x (or parent if no such) */
- X for( lp = PrevDown(link); lp != y; lp = PrevDown(lp) )
- X { Child(z, lp);
- X if( type(z) == GAP_OBJ && !join(gap(z)) ) break;
- X }
- X for( rp = NextDown(link); rp != y; rp = NextDown(rp) )
- X { Child(z, rp);
- X if( type(z) == GAP_OBJ && !join(gap(z)) ) break;
- X }
- X if( lp == y && rp == y && !(type(y) == HEAD && seen_nojoin(y)) )
- X {
- X /* if whole object is joined, do this */
- X tb = bfc(yc) == MAX_LEN ? MAX_LEN : bfc(yc) - fwd(y, dim);
- X tb = min(bc(yc), tb);
- X tf = bfc(yc) == MAX_LEN ? MAX_LEN : bfc(yc) - back(y, dim);
- X tf = min(fc(yc), tf);
- X SetConstraint(*xc, tb, bfc(yc), tf);
- X }
- X else
- X {
- X /* if // or || is present, do this */
- X xback = xfwd = 0;
- X for(link = NextDown(lp); link != rp; link = NextDown(link) )
- X { Child(z, link);
- X if( type(z) == GAP_OBJ || is_index(type(z)) ) continue;
- X xback = max(xback, back(z, dim)); xfwd = max(xfwd, fwd(z, dim));
- X }
- X debug2(DSC, DD, " lp != rp; xback,xfwd = %s,%s",
- X EchoLength(xback), EchoLength(xfwd));
- X tbf = min(bfc(yc), fc(yc));
- X tbc = tbf == MAX_LEN ? MAX_LEN : tbf - xfwd;
- X tfc = tbf == MAX_LEN ? MAX_LEN : tbf - xback;
- X SetConstraint(*xc, tbc, tbf, tfc);
- X }
- X }
- X break;
- X
- X
- X default: Error(INTERN, &fpos(y), "Constrained: %s", Image(type(y)) );
- X break;
- X }
- X debug1(DSC, DD, "] Constrained returning %s", EchoConstraint(xc));
- X} /* end Constrained */
- X
- X
- X/*@::EchoConstraint(), DebugConstrained()@************************************/
- X/* */
- X/* FULL_CHAR *EchoConstraint(c) */
- X/* */
- X/* Returns a string showing constraint *c, in centimetres. */
- X/* */
- X/*****************************************************************************/
- X#if DEBUG_ON
- X
- XFULL_CHAR *EchoConstraint(c)
- XCONSTRAINT *c;
- X{ static char str[2][40];
- X static int i = 0;
- X i = (i+1) % 2;
- X sprintf(str[i], "<");
- X if( bc(*c)==MAX_LEN ) sprintf(&str[i][strlen(str[i])], "INF, ");
- X else sprintf(&str[i][strlen(str[i])], "%.3fc, ", (float) bc(*c)/CM);
- X if( bfc(*c)==MAX_LEN ) sprintf(&str[i][strlen(str[i])], "INF, ");
- X else sprintf(&str[i][strlen(str[i])], "%.3fc, ", (float) bfc(*c)/CM);
- X if( fc(*c)==MAX_LEN ) sprintf(&str[i][strlen(str[i])], "INF>");
- X else sprintf(&str[i][strlen(str[i])], "%.3fc>", (float) fc(*c)/CM);
- X return AsciiToFull(str[i]);
- X} /* end EchoConstraint */
- X
- X
- X/*****************************************************************************/
- X/* */
- X/* DebugConstrained(x) */
- X/* */
- X/* Calculate and print the constraints of all closures lying within */
- X/* sized object x. */
- X/* */
- X/*****************************************************************************/
- X
- XDebugConstrained(x)
- XOBJECT x;
- X{ OBJECT y, link;
- X CONSTRAINT c;
- X debug1(DSC, DDD, "DebugConstrained( %s )", EchoObject(x) );
- X switch( type(x) )
- X {
- X
- X case CROSS:
- X case ROTATE:
- X case INCGRAPHIC:
- X case SINCGRAPHIC:
- X case GRAPHIC:
- X case WORD:
- X case QWORD:
- X
- X break;
- X
- X
- X case CLOSURE:
- X
- X Constrained(x, &c, COL);
- X debug2(DSC, D, "Constrained( %s, &c, COL ) = %s",
- X EchoObject(x), EchoConstraint(&c));
- X Constrained(x, &c, ROW);
- X debug2(DSC, D, "Constrained( %s, &c, ROW ) = %s",
- X EchoObject(x), EchoConstraint(&c));
- X break;
- X
- X
- X case SPLIT:
- X
- X link = DownDim(x, COL); Child(y, link);
- X DebugConstrained(y);
- X break;
- X
- X
- X case HEAD:
- X case ONE_COL:
- X case ONE_ROW:
- X case HCONTRACT:
- X case VCONTRACT:
- X case HEXPAND:
- X case VEXPAND:
- X case PADJUST:
- X case HADJUST:
- X case VADJUST:
- X case HSCALE:
- X case VSCALE:
- X case SCALE:
- X case WIDE:
- X case HIGH:
- X
- X link = Down(x); Child(y, link);
- X DebugConstrained(y);
- X break;
- X
- X
- X case COL_THR:
- X case VCAT:
- X case HCAT:
- X case ACAT:
- X
- X for( link = Down(x); link != x; link =NextDown(link) )
- X { Child(y, link);
- X if( type(y) != GAP_OBJ && !is_index(type(y)) ) DebugConstrained(y);
- X }
- X break;
- X
- X
- X default:
- X
- X Error(INTERN, &fpos(x), "DebugConstrained: type(x)= %s", Image(type(x)) );
- X break;
- X
- X }
- X debug0(DSC, DDD, "DebugConstrained returning.");
- X} /* end DebugConstrained */
- X#endif
- END_OF_FILE
- if test 23939 -ne `wc -c <'z15.c'`; then
- echo shar: \"'z15.c'\" unpacked with wrong size!
- fi
- # end of 'z15.c'
- fi
- if test -f 'z20.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'z20.c'\"
- else
- echo shar: Extracting \"'z20.c'\" \(22867 characters\)
- sed "s/^X//" >'z20.c' <<'END_OF_FILE'
- X/*@z20.c:Galley Flushing:ParentFlush()@***************************************/
- X/* */
- X/* LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05) */
- X/* COPYRIGHT (C) 1993 Jeffrey H. Kingston */
- X/* */
- X/* Jeffrey H. Kingston (jeff@cs.su.oz.au) */
- X/* Basser Department of Computer Science */
- X/* The University of Sydney 2006 */
- X/* AUSTRALIA */
- X/* */
- X/* This program is free software; you can redistribute it and/or modify */
- X/* it under the terms of the GNU General Public License as published by */
- X/* the Free Software Foundation; either version 1, or (at your option) */
- X/* any later version. */
- X/* */
- X/* This program is distributed in the hope that it will be useful, */
- X/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- X/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- X/* GNU General Public License for more details. */
- X/* */
- X/* You should have received a copy of the GNU General Public License */
- X/* along with this program; if not, write to the Free Software */
- X/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- X/* */
- X/* FILE: z20.c */
- X/* MODULE: Galley Flushing */
- X/* EXTERNS: FlushGalley() */
- X/* */
- X/*****************************************************************************/
- X#include "externs"
- X
- X
- X/*****************************************************************************/
- X/* */
- X/* ParentFlush(dest_index, kill) */
- X/* */
- X/* Flush the galley which is the parent of dest_index, if likely to flush. */
- X/* If kill is TRUE, delete dest_index. */
- X/* */
- X/*****************************************************************************/
- X
- X#define ParentFlush(dest_index, kill) \
- Xif( prnt_flush ) \
- X{ debug0(DGF,D, " ParentFlush calling FlushGalley (prnt)"); \
- X Parent(prnt, Up(dest_index)); \
- X if( kill ) DeleteNode(dest_index); \
- X debug0(DGF, D, " calling FlushGalley from ParentFlush"); \
- X FlushGalley(prnt); \
- X prnt_flush = FALSE; \
- X} \
- Xelse if( kill ) DeleteNode(dest_index)
- X
- X
- X/*@::FlushGalley()@***********************************************************/
- X/* */
- X/* FlushGalley(hd) */
- X/* */
- X/* Flush galley hd as far as possible. It could be the root galley. */
- X/* */
- X/*****************************************************************************/
- X
- XFlushGalley(hd)
- XOBJECT hd;
- X{ OBJECT dest; /* the target galley hd empties into */
- X OBJECT dest_index; /* the index of dest */
- X OBJECT inners; /* list of galleys and PRECEDES to flush */
- X OBJECT link, y; /* for scanning through the components of hd */
- X
- X CONSTRAINT dest_constraint; /* the vertical size constraint on dest */
- X int f; /* candidate replacement value for dest_fwd */
- X
- X OBJECT dest_encl; /* the VCAT enclosing dest, if any */
- X int dest_side; /* if dest_encl != nil, the side dest is on */
- X BOOLEAN need_adjust; /* TRUE as soon as dest_encl needs adjusting */
- X LENGTH dest_back, dest_fwd; /* the current size of dest_encl or dest */
- X LENGTH frame_size; /* the total constraint of dest_encl */
- X OBJECT prec_gap; /* the gap preceding dest, if any, else nil */
- X OBJECT prec_def; /* the component preceding dest, if any */
- X OBJECT succ_gap; /* the gap following dest, if any, else nil */
- X OBJECT succ_def; /* the component following dest, if any */
- X OBJECT stop_link; /* most recently seen gap link of hd */
- X BOOLEAN prnt_flush; /* TRUE when the parent of hd needs a flush */
- X OBJECT zlink, z, tmp, prnt;
- X
- X debug1(DGF, D, "[ FlushGalley %s (hd)", SymName(actual(hd)));
- X prnt_flush = FALSE;
- X
- X RESUME:
- X assert( type(hd) == HEAD, "FlushGalley: type(hd) != HEAD!" );
- X debug1(DGF, D, " resuming FlushGalley %s, hd =", SymName(actual(hd)));
- X ifdebug(DGF, DD, DebugObject(hd));
- X assert( Up(hd) != hd, "FlushGalley: resume found no parent to hd!" );
- X
- X
- X /*@@************************************************************************/
- X /* */
- X /* The first step is to examine the parent of galley hd to determine the */
- X /* status of the galley. If this is not suitable for flushing, we do */
- X /* what we can to change the status. If still no good, return; so if */
- X /* this code does not return, then the galley is ready to flush into a */
- X /* destination in the normal way, and the following variables are set: */
- X /* */
- X /* dest_index the parent of the galley and index of its destination */
- X /* dest the destination of the galley, a @Galley object */
- X /* */
- X /***************************************************************************/
- X
- X Parent(dest_index, Up(hd));
- X switch( type(dest_index) )
- X {
- X
- X case DEAD:
- X
- X /* the galley has been killed off while this process was sleeping */
- X debug1(DGF, D, "] FlushGalley %s returning (DEAD)", SymName(actual(hd)));
- X debug1(DGF, D, " prnt_flush = %s", bool(prnt_flush));
- X return;
- X
- X
- X case UNATTACHED:
- X
- X /* the galley is currently not attached to a destination */
- X AttachGalley(hd, &inners);
- X Parent(dest_index, Up(hd));
- X if( type(dest_index)!=RECEIVING || actual(actual(dest_index))==InputSym )
- X { if( type(dest_index) != DEAD )
- X { ParentFlush(dest_index, FALSE);
- X if( inners != nil ) FlushInners(inners, nil);
- X }
- X debug1(DGF,D,"] FlushGalley %s retn, no attach", SymName(actual(hd)));
- X debug1(DGF, D, " prnt_flush = %s", bool(prnt_flush));
- X return;
- X }
- X
- X /* if hd is a forcing galley, close all predecessors */
- X if( actual(hd) != nil && force_target(actual(hd)) )
- X { Parent(prnt, Up(dest_index));
- X debug0(DGA, DD, " force: prnt =");
- X ifdebug(DGA, DD, DebugObject(prnt));
- X debug1(DGA, D," calling FreeGalley from FlushGalley(%s)",
- X SymName(actual(hd)));
- X FreeGalley(prnt, Up(dest_index), &inners, Up(dest_index), whereto(hd));
- X prnt_flush = TRUE;
- X debug0(DGA, DD, " force: after FreeGalley, prnt =");
- X ifdebug(DGA, DD, DebugObject(prnt));
- X }
- X else prnt_flush = prnt_flush || blocked(dest_index);
- X debug1(DGF, D, " prnt_flush = %s", bool(prnt_flush));
- X
- X if( inners != nil ) FlushInners(inners, nil);
- X goto RESUME;
- X break;
- X
- X
- X case RECEIVING:
- X
- X if( actual(actual(dest_index)) == InputSym )
- X { ParentFlush(dest_index, FALSE);
- X debug1(DGF, D, "] FlushGalley %s retn, input", SymName(actual(hd)));
- X debug1(DGF, D, " prnt_flush = %s", bool(prnt_flush));
- X return;
- X }
- X break;
- X
- X
- X default:
- X
- X Error(INTERN, &fpos(hd), "FlushGalley: %s ind!", Image(type(dest_index)));
- X break;
- X }
- X dest = actual(dest_index);
- X debug1(DGF, DD, " dest_index: %s", EchoObject(dest_index));
- X
- X
- X /*@@************************************************************************/
- X /* */
- X /* The second step is to examine the components of the galley one by one */
- X /* to determine if they can be promoted. Each component has the format */
- X /* */
- X /* { <index> } <object> */
- X /* */
- X /* and is always followed by a gap object (except the last component). */
- X /* An index indicates that the following object has some interesting */
- X /* feature, and it points to that feature inside the object. There are */
- X /* two possible actions for each component, in addition to accepting it: */
- X /* */
- X /* REJECT: The component does not fit, so detach the galley */
- X /* SUSPEND: The component is incomplete; go to sleep and wait */
- X /* */
- X /***************************************************************************/
- X
- X stop_link = dest_encl = inners = nil;
- X need_adjust = FALSE;
- X
- X /***************************************************************************/
- X /* */
- X /* Loop invariant */
- X /* */
- X /* The children of hd up to but not including Child(link) have been */
- X /* examined and pronounced to be promotable. */
- X /* */
- X /* stop_link is the link of the most recently encountered gap object of */
- X /* hd, or nil if no gap object has been encountered yet. */
- X /* */
- X /* if dest_encl is non-nil, then the destination is not external, */
- X /* dest_encl is its parent, and the following variables are defined: */
- X /* */
- X /* prec_gap gap object preceding dest (which must exist) */
- X /* prec_def first definite object preceding dest (must exist) */
- X /* dest_back back(dest_encl) including effect of accepted compts */
- X /* dest_fwd fwd(dest_encl) including effect of accepted compts */
- X /* dest_side BACK or FWD, i.e. which side of the mark dest is on */
- X /* dest_constraint the size constraint on dest */
- X /* frame_size size of frame enclosing dest_encl */
- X /* */
- X /* if dest_encl is nil, these variables are not defined. */
- X /* */
- X /* need_adjust is true if at least one definite component has been */
- X /* accepted for promotion and the destination is internal; hence, */
- X /* dest_encl is defined and its size needs to be adjusted. */
- X /* */
- X /* inners is the set of all PRECEDES and UNATTACHED indexes found. */
- X /* */
- X /***************************************************************************/
- X
- X for( link = Down(hd); link != hd; link = NextDown(link) )
- X {
- X Child(y, link);
- X if( type(y) == SPLIT ) Child(y, DownDim(y, ROW));
- X debug1(DGF, DD, " try to flush %s", EchoObject(y));
- X switch( type(y) )
- X {
- X
- X case GAP_OBJ:
- X
- X prec_gap = y;
- X stop_link = link;
- X if( !join(gap(y)) ) seen_nojoin(hd) = TRUE;
- X break;
- X
- X
- X case EXPAND_IND:
- X case GALL_PREC:
- X case GALL_FOLL:
- X case GALL_TARG:
- X case CROSS_PREC:
- X case CROSS_FOLL:
- X case CROSS_TARG:
- X
- X break;
- X
- X
- X case PRECEDES:
- X case UNATTACHED:
- X
- X if( inners == nil ) inners = New(ACAT);
- X Link(inners, y);
- X break;
- X
- X
- X case RECEIVING:
- X case RECEPTIVE:
- X
- X goto SUSPEND;
- X
- X
- X case FOLLOWS:
- X
- X Child(tmp, Down(y));
- X if( Up(tmp) == LastUp(tmp) )
- X { link = PrevDown(link);
- X DisposeChild(NextDown(link));
- X break;
- X }
- X Parent(tmp, Up(tmp));
- X assert(type(tmp) == PRECEDES, "Flush: PRECEDES!");
- X switch( CheckConstraint(tmp, dest_index) )
- X {
- X case CLEAR: DeleteNode(tmp);
- X link = PrevDown(link);
- X DisposeChild(NextDown(link));
- X break;
- X
- X case PROMOTE: break;
- X
- X case BLOCK: goto SUSPEND;
- X
- X case CLOSE: goto REJECT;
- X }
- X break;
- X
- X
- X case WORD:
- X case QWORD:
- X case ONE_COL:
- X case ONE_ROW:
- X case WIDE:
- X case HIGH:
- X case HSCALE:
- X case VSCALE:
- X case HCONTRACT:
- X case VCONTRACT:
- X case HEXPAND:
- X case VEXPAND:
- X case PADJUST:
- X case HADJUST:
- X case VADJUST:
- X case ROTATE:
- X case SCALE:
- X case INCGRAPHIC:
- X case SINCGRAPHIC:
- X case GRAPHIC:
- X case ACAT:
- X case HCAT:
- X case ROW_THR:
- X case CLOSURE:
- X case NULL_CLOS:
- X case CROSS:
- X
- X /* make sure y is not joined to a target below */
- X for( zlink = NextDown(link); zlink != hd; zlink = NextDown(zlink) )
- X { Child(z, zlink);
- X switch( type(z) )
- X {
- X case RECEPTIVE:
- X case RECEIVING: y = z;
- X goto SUSPEND;
- X break;
- X
- X case GAP_OBJ: if( !join(gap(z)) ) zlink = PrevDown(hd);
- X break;
- X
- X default: break;
- X }
- X }
- X
- X /* check size constraint */
- X if( !external(dest) )
- X {
- X /* initialise dest_encl etc if not done yet */
- X if( dest_encl == nil )
- X { assert( UpDim(dest,COL) == UpDim(dest,ROW), "FlushG: UpDims!" );
- X Parent(dest_encl, NextDown(Up(dest)));
- X assert( type(dest_encl) == VCAT, "FlushGalley: dest != VCAT!" );
- X SetNeighbours(Up(dest), FALSE, &prec_gap, &prec_def,
- X &succ_gap, &succ_def, &dest_side);
- X assert(prec_gap != nil || is_indefinite(type(y)),
- X "FlushGalley: prec_gap == nil && !is_indefinite(type(y))!" );
- X assert(succ_gap == nil, "FlushGalley: succ_gap != nil!" );
- X assert(dest_side == FWD || is_indefinite(type(y)),
- X "FlushGalley: dest_side != FWD || !is_indefinite(type(y))!");
- X dest_back = back(dest_encl, ROW);
- X dest_fwd = fwd(dest_encl, ROW);
- X Constrained(dest_encl, &dest_constraint, ROW);
- X frame_size = constrained(dest_constraint) ? bfc(dest_constraint) :0;
- X }
- X
- X if( !is_indefinite(type(y)) )
- X { /* calculate effect of adding y to dest */
- X f = dest_fwd + fwd(y, ROW) - fwd(prec_def, ROW) +
- X ActualGap(fwd(prec_def, ROW), back(y, ROW),
- X fwd(y, ROW), &gap(prec_gap), frame_size,
- X dest_back + dest_fwd - fwd(prec_def, ROW));
- X debug3(DGF, DD, " b,f: %s,%s; dest_encl: %s",
- X EchoLength(dest_back), EchoLength(f),
- X EchoConstraint(&dest_constraint));
- X
- X /* check new size against constraint */
- X if( !FitsConstraint(dest_back,f,dest_constraint) )
- X goto REJECT;
- X if( units(gap(prec_gap))==FRAME_UNIT && width(gap(prec_gap)) > FR )
- X goto REJECT;
- X
- X /* accept component */
- X dest_fwd = f; prec_def = y;
- X need_adjust = TRUE;
- X }
- X
- X } /* end if( !external(dest) ) */
- X
- X /* accept this component into dest */
- X debug1(DGF, D, " accept %s", EchoObject(y));
- X prnt_flush = prnt_flush || blocked(dest_index);
- X debug1(DGF, D, " prnt_flush = %s", bool(prnt_flush));
- X if( inners != nil )
- X { Promote(hd, NextDown(link), dest_index);
- X if( need_adjust )
- X { debug0(DSA, D, " calling AdjustSize from FlushGalley (ACCEPT)");
- X AdjustSize(dest_encl, dest_back, dest_fwd, ROW);
- X }
- X FlushInners(inners, hd);
- X goto RESUME;
- X }
- X break;
- X
- X
- X default:
- X
- X Error(INTERN, &fpos(y), "FlushGalley: %s", Image(type(y)));
- X break;
- X
- X } /* end switch */
- X
- X } /* end for */
- X
- X
- X /* EMPTY: */
- X
- X /* galley is now completely accepted; clean up and exit */
- X debug0(DGF, DD, " galley empty now");
- X if( inners != nil ) DisposeObject(inners);
- X if( Down(hd) != hd )
- X { Promote(hd, hd, dest_index);
- X if( need_adjust )
- X { debug0(DSA, D, " calling AdjustSize from FlushGalley (EMPTY)");
- X AdjustSize(dest_encl, dest_back, dest_fwd, ROW);
- X }
- X }
- X DetachGalley(hd);
- X debug0(DGF, D, " calling KillGalley from FlushGalley");
- X KillGalley(hd);
- X ParentFlush(dest_index, TRUE);
- X debug1(DGF,D,"] FlushGalley %s returning (emptied).", SymName(actual(hd)));
- X debug1(DGF, D, " prnt_flush = %s", bool(prnt_flush));
- X return;
- X
- X
- X REJECT:
- X
- X /* reject this component and move to a new dest */
- X debug1(DGF, D, " reject %s", EchoObject(y));
- X assert(actual(dest) != PrintSym, "FlushGalley: reject print!");
- X if( inners != nil ) DisposeObject(inners);
- X if( stop_link != nil )
- X { Promote(hd, stop_link, dest_index);
- X if( need_adjust )
- X { debug0(DSA, D, " calling AdjustSize from FlushGalley (REJECT)");
- X AdjustSize(dest_encl, dest_back, dest_fwd, ROW);
- X }
- X }
- X DetachGalley(hd);
- X assert( type(dest_index) == RECEIVING, "FlushGalley/REJECT: dest_index!" );
- X prnt_flush = prnt_flush || blocked(dest_index); /* **** bug fix **** */
- X DeleteNode(dest_index);
- X goto RESUME;
- X
- X
- X SUSPEND:
- X
- X /* suspend this component */
- X debug1(DGF, D, " suspend %s", EchoObject(y));
- X if( inners != nil ) DisposeObject(inners);
- X if( stop_link != nil )
- X { Promote(hd, stop_link, dest_index);
- X if( need_adjust )
- X { debug0(DSA, D, " calling AdjustSize from FlushGalley (SUSPEND)");
- X AdjustSize(dest_encl, dest_back, dest_fwd, ROW);
- X }
- X }
- X
- X /* check whether external galleys can remove the blockage */
- X if( type(y) == RECEPTIVE && ready_galls(hd) != nil && AllowCrossDb )
- X { OBJECT eg, val, index2, hd2, tag, seq, newsym;
- X BOOLEAN found, gall; FULL_CHAR newtag[MAX_LINE], newseq[MAX_LINE];
- X
- X /* get first ready galley in from cross reference database */
- X Child(eg, Down(ready_galls(hd)));
- X val = ReadFromFile(eg_fnum(eg), eg_fpos(eg), nil);
- X if( val == nil ) Error(FATAL, &fpos(y),
- X "Error in database file %s", FileName(eg_fnum(eg)));
- X assert( type(val) == CLOSURE, "AttachG: db CLOSURE!" );
- X index2 = New(UNATTACHED);
- X hd2 = New(HEAD);
- X FposCopy(fpos(hd2), fpos(val));
- X actual(hd2) = actual(val);
- X backward(hd2) = TargetSymbol(val, &whereto(hd2));
- X backward(hd2) = sized(hd2) = FALSE;
- X ready_galls(hd2) = nil;
- X must_expand(hd2) = TRUE;
- X Link(index2, hd2);
- X Link(hd2, val);
- X Link(Up(y), index2);
- X
- X /* set up the next ready galley for reading next time */
- X Child(tag, Down(eg)); Child(seq, LastDown(eg));
- X do /* skip duplicate seq values */
- X { found = DbRetrieveNext(OldCrossDb, &gall, &newsym,
- X newtag, newseq, &eg_fnum(eg), &eg_fpos(eg), &eg_cont(eg));
- X debug2(DGF, D, " ext gall found: %15s gall: %15s",
- X bool(gall), bool(found));
- X debug2(DGF, D, " ext gall new sym: %15s old sym: %15s",
- X SymName(newsym), SymName(eg_symbol(eg)));
- X debug2(DGF, D, " ext gall new tag: %15s old tag: %15s",
- X newtag, string(tag));
- X debug2(DGF, D, " ext gall new seq: %15s old seq: %15s",
- X newseq, string(seq));
- X if( found ) found = gall && newsym == eg_symbol(eg) &&
- X StringEqual(newtag, string(tag));
- X } while( found && StringEqual(newseq, string(seq)) );
- X if( found )
- X { DisposeChild(Up(tag));
- X DisposeChild(Up(seq));
- X tag = MakeWord(WORD, newtag, no_fpos);
- X seq = MakeWord(WORD, newseq, no_fpos);
- X Link(eg, tag); Link(eg, seq);
- X debug1(DGF,D, " another ext gall: into %s", SymName(newsym));
- X }
- X else
- X { DisposeChild(Up(eg));
- X debug1(DGF,D, " last ext gall into ", SymName(eg_symbol(eg)));
- X if( Down(ready_galls(hd)) == ready_galls(hd) )
- X { Dispose(ready_galls(hd));
- X ready_galls(hd) = nil;
- X debug0(DGF,D, " all ext galls exhausted");
- X }
- X }
- X
- X /* flush the ready galley found above, and resume */
- X debug2(DGF, D, " ext gall FlushGalley (%s into %s)",
- X SymName(actual(hd2)), SymName(whereto(hd2)));
- X debug0(DGF, D, " calling FlushGalley from FlushGalley/SUSPEND");
- X FlushGalley(hd2);
- X goto RESUME;
- X }
- X else if( type(y) == RECEPTIVE && trigger_externs(y) && AllowCrossDb )
- X { OBJECT sym, cr, ins, tag, seq, eg, cnt; BOOLEAN found;
- X FULL_CHAR newseq[MAX_LINE]; FILE_NUM tfnum; long tfpos, tcont;
- X debug1(DGF, D, " ext gall target %s", SymName(actual(actual(y))));
- X for( sym = FirstExternTarget(actual(actual(y)), &cnt);
- X sym != nil; sym = NextExternTarget(actual(actual(y)), &cnt) )
- X {
- X debug1(DGF, D, " ext gall gall_targ %s", SymName(sym));
- X cr = GallTargEval(sym, &fpos(actual(y)));
- X ins = New(GALL_TARG);
- X actual(ins) = cr;
- X Link(Up(y), ins);
- X Child(tag, LastDown(cr));
- X assert( is_word(type(tag)), "FlushGalley: cr is_word(type(tag))!" );
- X found = DbRetrieve(OldCrossDb, TRUE, sym, string(tag),
- X newseq, &tfnum, &tfpos, &tcont);
- X if( found )
- X { if( ready_galls(hd) == nil ) ready_galls(hd) = New(ACAT);
- X eg = New(EXT_GALL);
- X debug1(DGF, D, " ext gall retrieved: into %s", SymName(sym));
- X eg_fnum(eg) = tfnum;
- X eg_fpos(eg) = tfpos;
- X eg_symbol(eg) = sym;
- X eg_cont(eg) = tcont;
- X tag = MakeWord(WORD, string(tag), no_fpos);
- X Link(eg, tag);
- X seq = MakeWord(WORD, newseq, no_fpos);
- X Link(eg, seq);
- X Link(ready_galls(hd), eg);
- X }
- X }
- X trigger_externs(y) = FALSE;
- X if( ready_galls(hd) != nil ) goto RESUME;
- X } /* end if external galleys */
- X
- X /* if non-blocking, delete the index and resume */
- X if( type(y) == RECEPTIVE && non_blocking(y) )
- X { DeleteNode(y);
- X goto RESUME;
- X }
- X else if( type(y) == RECEIVING && non_blocking(y) )
- X {
- X if( Down(y) == y )
- X { DeleteNode(y);
- X }
- X else
- X { Child(z, Down(y));
- X DetachGalley(z);
- X }
- X goto RESUME;
- X }
- X
- X /* if all the above fail to remove the blockage, suspend */
- X blocked(y) = TRUE;
- X ParentFlush(dest_index, FALSE);
- X debug1(DGF, D, " prnt_flush = %s", bool(prnt_flush));
- X debug1(DGF, D, "] FlushGalley %s returning (suspend)", SymName(actual(hd)));
- X return;
- X
- X} /* end FlushGalley */
- END_OF_FILE
- if test 22867 -ne `wc -c <'z20.c'`; then
- echo shar: \"'z20.c'\" unpacked with wrong size!
- fi
- # end of 'z20.c'
- fi
- echo shar: End of archive 13 \(of 35\).
- cp /dev/null ark13isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 35 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-