|
|
BSD 4.3tahoe
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
static char rcsid[] = "$Header: /var/lib/cvsd/repos/CSRG/43BSDTahoe/new/B/src/bed/line.c,v 1.1.1.1 2018/04/24 16:12:58 root Exp $";
/*
* B editor -- Routines for treating the parse tree as a sequence of lines.
*
* WARNING: The routines in this file (and many others!) assume that a
* `newline' can only occur in the zero'th representation string of a node
* (i.e., rp[0]).
*/
#include "b.h"
#include "bobj.h"
#include "node.h"
#include "gram.h"
#include "supr.h"
/*
* Compute equality of subtrees, based on common descent.
* Strings are not checked for characterwise equality, but must
* be the same pointer; other nodes must have the same symbol and
* their children must be equal in this sense (equal pointers are
* always used as a shortcut).
*
* (Used by screen update algorithm only.)
*/
Visible bool
eqlines(n1, n2)
node n1;
node n2;
{
register node nn1;
register node nn2;
register int w1;
register int w2;
register int nch;
register int i;
if (n1 == n2)
return Yes;
if (Type(n1) != Nod || Type(n2) != Nod)
return No;
if (symbol(n1) != symbol(n2))
return No;
nch = nchildren(n1);
Assert(nch == nchildren(n2));
for (i = 1; i <= nch; ++i) {
nn1 = child(n1, i);
nn2 = child(n2, i);
w1 = width(nn1);
w2 = width(nn2);
if (w1 >= 0 && w2 >= 0) {
if (!eqlines(nn1, nn2))
return No;
}
else {
if (nn1 == nn2)
return Yes;
if (fwidth(noderepr(nn1)[0]) < 0 || fwidth(noderepr(nn2)[0]) < 0)
return linelen(n1) == linelen(n2);
return eqlines(nn1, nn2);
}
}
return Yes;
}
/*
* Compute the length of the line beginning at the current node.
*/
Visible int
linelen(n)
node n;
{
register node nn;
register string *rp = noderepr(n);
register int w;
register int nch = nchildren(n);
register int i;
register int len = fwidth(rp[0]);
if (len < 0)
len = 0;
for (i = 1; i <= nch; ++i) {
nn = child(n, i);
w = width(nn);
if (w >= 0)
len += w;
else {
n = nn;
i = 0;
nch = nchildren(n);
rp = noderepr(n);
}
w = Fwidth(rp[i]);
if (w < 0)
break;
len += w;
}
return len;
}
/*
* Move the focus to the next line.
* NB: This is a building block for use in the 'show' module;
* it cannot set ep->mode or call higher() properly!
*/
Visible bool
nextline(pp)
register path *pp;
{
register node n;
register node nn;
register int w;
register int nch;
register int i = 0;
for (;;) {
n = tree(*pp);
if (width(n) < 0) {
nch = nchildren(n);
while (++i <= nch) {
nn = child(n, i);
w = width(nn);
if (w < 0) {
downi(pp, i) || Abort();
n = tree(*pp);
if (fwidth(noderepr(n)[0]) < 0)
return Yes;
nch = nchildren(n);
i = 0;
}
}
}
/* Must go upward in the tree */
i = ichild(*pp);
if (!up(pp))
return No;
}
}
/*
* Compute the current line number. If the current node begins with
* a `newline', add one because the first character is actually
* on the next line.
*/
Visible int
lineno(ep)
register environ *ep;
{
register int y;
y = -focoffset(ep);
if (y < 0)
y = 0;
if (focchar(ep) == '\n')
++y;
return y + Ycoord(ep->focus);
}
/*
* Similarly, compute the current column number.
* (Hope the abovementioned trick isn't necessary.)
*/
Visible int
colno(ep)
environ *ep;
{
int x= focoffset(ep);
if (x < 0)
x= 0; /* In fact, give up */
return x + Xcoord(ep->focus);
}
/*
* Make the focus exactly one line wide (if at all possible).
*/
Visible Procedure
oneline(ep)
register environ *ep;
{
register node n;
node nn;
register string *rp;
register int s1;
register int s2;
register int len;
int ich;
int nch;
ich = 1;
while (width(tree(ep->focus)) >= 0) {
ich = ichild(ep->focus);
if (!up(&ep->focus)) {
ep->mode = WHOLE;
higher(ep);
return;
}
}
higher(ep);
n = tree(ep->focus);
nch = nchildren(n);
rp = noderepr(n);
for (s1 = 2*ich-1; s1 >= 1; --s1) {
if (s1&1)
len = fwidth(rp[s1/2]);
else {
nn = child(n, s1/2);
len = width(nn);
}
if (len < 0)
break;
}
for (s2 = 2*ich+1; s2 <= 2*nch+1; ++s2) {
if (s2&1)
len = fwidth(rp[s2/2]);
else {
nn = child(n, s2/2);
len = width(nn);
}
if (len < 0)
break;
}
ep->mode = SUBSET;
ep->s1 = s1+1;
ep->s2 = s2-1;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.