program indexer; {$I+,R-,A-,B-}
{==============================================================}
{		Book Indexing Assistant Program 	       }
{ Turbo Pascal version of: november 3, 1986		       }
{ Copyright (C) 1986 by, and inquiries by mail to:	       }
{		David E. Cortesi			       }
{		2340 Tasso Street			       }
{		Palo Alto, CA 94301			       }
{ All rights reserved.	Distribution for profit forbidden      }
{ without explicit permission.	Distribution by individuals    }
{ and nonprofit organizations permitted provided this notice   }
{ is retained and author credit is given in printed materials. }
{							       }
{ This program assists you in constructing an index for a book.}
{ See the accompanying documentation file for further info.    }
{ Note the R- compile switch: the program OUGHT to work with   }
{ R+ (range checking), I pulled off enough errors, but since   }
{ they were mostly trivial I turned off checking so that if any}
{ are left they won't crash the user.                          }
{							       }
{ Main file. History:					       }
{ bugs fixed and merge program added 11/3/86		       }
{ initial writing 5/31 -- 6/6/86			       }
{==============================================================}

const
    null = 0;		{ the null, end-of-string	       }
    asciibel = 7;	{ names for ascii characters	       }
    asciibs = 8;
    asciitab = 9;
    asciilf = 10;
    asciicr = 13;
    asciieof = 26;
    asciiesc = 27;
    asciiblank = 32;
    asciidel = 127;
    alnumset : set of char = ['0'..'9','A'..'Z','a'..'z'];
    alphset : set of char = ['A'..'Z','a'..'z'];
    allowset : set of char = ['a'..'z'];
    digitset : set of char = ['0'..'9'];
    digsign : set of char = ['0'..'9','-'];

    maxnests = 9;	{ allows up to 9 levels of subterms }
    maxdepth = 20;	{ max depth of a tree (2^19th nodes)   }
    strmax = 65;	{ max size of a string, 64 data plus 00}

    sblksize = 2046;	{ block size of a string buffer        }
    sblkmax = 10;	{ allow up to 20K -- use more in MSDOS!}

type
    strindex = 1..strmax;	{ indices over strings	       }
    strlength= 0..strmax;	{ lengths of strings	       }
    relation = (less,equal,more); { result of comparisons      }
    nchar = 0..255;		{ numeric characters are bytes }
    str = packed array[strindex] of nchar; { independent string}
    stref = record		{ an indirect string is an     }
	nb : 1..sblkmax;	{ index into SBLKPTRS and an   }
	bo : 1..sblksize	{ offset into that strblock    }
    end;

    ppage = ^page;
    page = record		{ page reference to a term:    }
	next : ppage;		{ ..linked in a chain, with    }
	num1, num2  : integer	{ ..one or a range of nums     }
	end;
    sides = (left, right);	{ names of children of tree    }
    tdepth = 0..maxdepth;	{ range of depths, nil = 0     }
    tree = ^node;
    node = record		{ one node of a binary tree    }
	cnodes : array[sides] of tree; { children of this node }
	cdepth : array[sides] of tdepth; { ..and their depths  }
	subtree : tree; 	{ subtree of sub-terms	       }
	term,			{ index term as typed, and     }
	dict   : stref; 	{ upcase for dictionary comps  }
	pages  : ppage; 	{ head of chain of page-refs   }
    end;
    walk = record		{ status of a walk over a tree }
	top	: tdepth;	{ index of top of stack        }
	curr	: tree; 	{ node on which walk now steps }
	stack	: array[1..maxdepth] of tree; {pending nodes }
    end;

var
    maintree : tree;		{ root of the term-tree        }
    indlevel : integer;
    workterm, workdict, scratch : str;
    initdone : boolean;
    space : real;

procedure disaster(which:integer); forward;

{==============================================================}
{ Sections of code out-of-line to allow compilation in CP/M    }
{==============================================================}
{$I IXTEXT.PAS textfile I/O stuff }
{$I IXSTRG.PAS support for string storage }
{xI IXDIAG.PAS nullify the "$" when diag not needed}
{$I IXTREE.PAS support for tree creation }
{$I IXWALK.PAS logic of inorder tree walk }
{$I IXINIT.PAS phase 0: initialize, load existing index }
{$I IXDOIT.PAS phase 1: keyboard interaction }
{$I IXDONE.PAS phase 2: writing the output index document }

{------ only one disaster coded just now, running out of -----}
{------ string block space in stput --------------------------}
procedure disaster;
begin
    writeln; writeln('[Out of string space!]');
    if (initdone) then begin
	writeln('[Trying to write output file.]');
	finish;
	writeln('[Output file complete.]')
    end;
    HALT
end;

{==============================================================}
{ The main program, at last.....			       }
{==============================================================}
begin
    initdone := false;
    writeln('[index aid, revision of 11/3/86]');
    writeln('[copyright (c) 1986 David E. Cortesi]');
    initall; writeln('[initialized]'); writeln;
    keyinto(maintree);
    finish;
    writeln;
    space := MemAvail;
    if (space < 0) then space := 65536.0 + space;
    writeln('[normal end,',space:6:0,' storage left.]');
end.
 MemAvail;
    if (space < 0) then space := 