{==============================================================}
{			IXINIT.PAS			       }
{Copyright (C) 1986 David E. Cortesi--see notice in IXMAIN.PAS.}
{ This include file directs initializing, primarily reading an }
{ an existing index document to initialize the trees.	       }
{   The output file is, and the input is expected to be, an    }
{ index document as made by this program.  Blank lines aside,  }
{ every line of an index document is (must be) composed of:    }
{	* a MARGIN of zero or more spaces		       }
{	* a TERM of printable characters		       }
{	* two (or more) spaces to mark the end of the term     }
{	* zero or more NUMBERS or ranges 1-9		       }
{ The numbers may be signed, and may have spaces and commas    }
{ between them. 					       }
{ History:						       }
{ minor cleanup 11/4/86 				       }
{ drop trailing comma on input term 11/2/86		       }
{ initial code 6/2/86					       }
{==============================================================}
var
    lineno : integer; { line numbers for diagnostics }
    margin : integer; { margin of last-in or next-out term }
    interm : str;   { term last-in or next-out }
    pagref : ppage; { list of "page" structures in/out }

{------ diagnose an error in the input file and abort ---------}
procedure badfile(e:integer);
begin
    writeln;
    write('Error in line',lineno:5,' of input -- ');
    case e of
	1 : write('term must be printable characters');
	2 : write('term must shorter than ',strmax,' letters');
	3 : write('found nondigit where number expected');
	4 : write('page number too large');
	5 : write('improper range of numbers');
	6 : write('subterms nested too deeply');
    end;
    writeln;
    HALT
end;

{------ read and collect one signed integer, assuming that ----}
{------ there should be a number coming next from nextinch ----}
function nextpage:integer;
var n : nchar; s : boolean; x : real;
begin
    n := nextinch;
    s := false;
    if (n = ord('-')) then begin
	s := true;
	n := nextinch;
    end;
    if (not (chr(n) in digitset)) then badfile(3);
    x := 0.0;
    repeat
	x := (x * 10.0) + (n - ord('0'));
	n := nextinch
    until (not (chr(n) in digitset));
    pushinch(n);
    if (x > 32767.0) then badfile(4);
    if (s) then x := -x;
    nextpage := trunc(x)
end;

{------ read and collect one line of input file ---------------}
procedure nextline;
var j : strlength; p : ppage; n : nchar;
begin
    interm[1] := null;
    pagref := NIL;

    repeat
	lineno := lineno + 1;
	margin := 0;
	repeat
	    n := nextinch;
	    margin := margin + 1
	until (n <> asciiblank);
	margin := margin - 1 { note size of margin }
    until (n <> asciicr); { discard null lines }

    if (n = asciieof) then margin := -1 { note eof }
    else begin
	if (not n in [asciiblank..asciidel]) then badfile(1);
	j := 0;
	repeat
	    j := j + 1;
	    interm[j] := n;
	    n := nextinch
	until ( (j=strmax) or
		(n < asciiblank) or
		((n = asciiblank) and (n = interm[j])) );
	if ((j=strmax) and (n<>asciiblank)) then badfile(2);
	if (n = asciicr) then j := j+1;
	if ( (j > 1) and (interm[j-1] = ord(',')) ) then j := j-1;
	interm[j] := null;
	while (n = asciiblank) do n := nextinch;
	while (n <> asciicr) do begin
	    if (pagref = nil) then
		begin new(pagref); p := pagref end
	    else
		begin new(p^.next); p := p^.next end;
	    p^.next := nil;
	    pushinch(n);
	    p^.num1 := nextpage;
	    n := nextinch;
	    if (n = ord('-')) then begin {range X-Y}
		p^.num2 := nextpage;
		if (p^.num2 <= p^.num1) then badfile(5);
		n := nextinch
	    end
	    else p^.num2 := p^.num1;
	    while (chr(n) in [',',' ']) do n := nextinch;
	end
    end
end;

{------ read consecutive lines of existing index at margin ---}
{------ level M and make a binary tree of them.  When the ----}
{------ margin moves in, recurse to build a subtree.  When ---}
{------ it moves back out, stop. -----------------------------}
function initree(m: integer): tree;
var t,p : tree;
begin
    t := nil;
    while (margin >= m) do begin
	if (margin = m) { true first time for sure } then begin
	    p := insert(interm,t);
	    p^.pages := pagref;
	    nextline
	end
	else begin
	    indlevel := indlevel + 1;
	    if (indlevel > maxnests) then badfile(6);
	    p^.subtree := initree(margin);
	    indlevel := indlevel - 1;
	end
    end;
    initree := t
end;

{------ control initialization sequence, calling initializers -}
{------ in other "modules" as they exist ----------------------}
procedure initall;
begin
    initdone := false;
    indlevel := 0;
    initstrg;	{ set up string storage }
    if (initinp) then begin
	write('[reading existing index INDEX.INP ... ');
	lineno := 0;
	nextline;
	maintree := initree(margin);
	writeln('finished]')
    end
    else begin
	writeln('[no existing index document]');
	maintree := nil
    end;
    initdone := true
end;
)
    end
    else begin
	writeln('[no existing index document]');
	maintree := nil
    end;
    initdo