@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@SCRIBBLEGBLj SCRIBBLECRL.ALLOC CRLAUXIL C N !"#AME 20 /* length of a file name */ #endif #ifdef UNIX #define BUFFRECS 1024 /* I/O buffer size in bytes */ #define BUFFSIZL2 C CHARIO C LC SUB /* -------------------------------------------------- */ /* program constants */ #define MAXLINES 100 /* max # of linAUXILTOOC I$%&'()*+,-COMMANDSC C./0123456COMMTOO C ^789:;<=>?@ABINPUT CRL%CDEFGE 1024 /* I/O buffer size in bytes */ #define RECSIZE 1 /* I/O record size */ #define LENFILENAME 30 /* length of a file naes/page */ #define MAXTOKENS 50 /* max # of tokens/line */ #define MAXMESSAGE 150 /* max # of chars in error message */ #deOUTPUT CRLBHIJKLMNOPSC SUBQCRAYON H JRSTUVWXYZ[CRAYON C f\]^_`abcdefghme */ #endif /* -------------------------------------------------- */ /* programming conventions */ #define repeat whfine STACKSIZE 2048 /* amount of stack space to reserve */ #ifdef CPM #define BUFFRECS 8 /* i/o buffer size in records */ PRINTER C {ijklmnopqrstuvwxDRIVER C vyz{|}~QUEUE CRL PENCIL C >/* SCRIBBLE.GBL -- Global Definitions for Scribble written January 1981 by Craig A. Finseth Copyright (c) 1981 by Mark of ile (TRUE) #define TRUE 1 #define FALSE 0 #define NULL 0 #define MICA unsigned #define FLAG char #define STRING char#define BUFFSIZE (128*8) /* i/o buffer size in bytes */ #define RECSIZE 128 /* i/o record size in bytes */ #define LENFILENCC SUBDIFF C HL2 COMlL2 C the Unicorn */ /* compilation flags */ #define CPM /* CP/M only */ /* #define UNIX */ /* UNIX only */ #define LARGE #define LINEHEIGHT dev.stdvert #define CHARRES dev.micahoriz #define CHARWIDTH dev.stdhoriz /* ASCII characters */ #de'@' #define HEADERCENTER 0203 /* ~^C */ #define HEADERRIGHT 0222 /* ~^R */ #define HEADERLINE 0214 /* ~^L */ /* optioF 0364 /* ~t */ #define EXITON 0330 /* ~X eXit unusual attributes */ #define EXITOFF 0370 /* ~x */ #define JUSTIFY /* right margin */ MICA lspace; /* line spacing */ FLAG howjustify; /* how is the line justified? */ MICA column; /*define UNNBOFF 0365 /* ~u */ #define UNALLON 0301 /* ~A underscore everything */ #define UNALLOFF 0341 /* ~a */ #defineed)48000) /* largest legal mica mesurment */ #endif /* -------------------------------------------------- */ /* allocatorfine NUL 0 #define BELL '\7' #define BS '\8' #define TAB '\t' #define LF '\12' #define FF '\14' #define CR '\15' #define ns for argument routines */ #define ARGFLUSH 'f' #define RETURN 'r' #define PRINT 'p' #define HOLD 'h' #define SAM 0212 /* ~^J */ #define HORIZSPACE 0210 /* ~^H */ #define VERTSPACE 0226 /* ~^V */ #define TOKBREAK 0240 /* ~SP */ column that you were in */ struct buftok { /* for each token, its length and a */ MICA length; /* ptr to it */ ST UNANON 0316 /* ~N underscore alphanumeric */ #define UNANOFF 0356 /* ~n */ #define ITALON 0311 /* ~I italics */ #def */ int *Acap, *Abegin, *Aend, Asize; #define SPACE int SPACE *PageSpace, *EndSpace, *DefSpace; /* -------------------SP ' ' #define DEL '\177' #define NL '\n' #define EOF '\32' /* -------------------------------------------------- */ /*PLE 'd' /* measurement */ #define INCH 2540 /* 2540 mica/inch (2540 = 2 x 2 x 5 x 127) */ #define HALFINCH 1270 /* 1/* -------------------------------------------------- */ /* token types */ #define EOFT '\32' #define WHITESPACE ' ' RING *line; } toks[MAXTOKENS]; } lin, linsave; struct { /* page information */ MICA ptop; /* margins */ MICA pline ITALOFF 0351 /* ~i */ #define BITALON 0320 /* ~P bold italics */ #define BITALOFF 0360 /* ~p */ #define SUPERON 03------------------------------- */ /* line structures */ #define LINEDATA struct linestruct struct linestruct { /* buf output file description */ #define SENTENCEBREAK 0177 /* ^? */ #define BOLDON 0302 /* ~B */ #define BOLDOFF 0342 //2" */ #define CENTIMETER 1000 /* 1000 mica/cm */ #define PICA 423 /* 1/3 */ /* 1/6" */ #define POINT 35 /* 5/18 */ /* 1/1#define NEWLINE '\n' #define TOKEN 'A' #define TOKENBREAK 'B' #define FLUSH 'F' #define DELIM '(' #define COMMAND eft; MICA pright; MICA pbottom; LINEDATA *page[MAXLINES];/* each line */ MICA vertical[MAXLINES]; /* its height */ int23 /* ~S superscripts */ #define SUPEROFF 0363 /* ~s */ #define SUBON 0324 /* ~T subscripts (why not?) */ #define SUBOFfered line and ancillary info. */ int numtoks; /* number of token used */ MICA lleft; /* left margin */ MICA lright; * ~b */ #define ROMANON 0322 /* ~R */ #define ROMANOFF 0362 /* ~r */ #define UNNBON 0325 /* ~U underscore tokens */ #2 pica or 1/72" */ #ifdef CPM #define MAXMICA 48000 /* largest possible mica measurement */ #else #define MAXMICA ((unsign numlines; /* number of lines */ MICA cumvert; /* how much space we've used up */ int footerline; /* where footnotes st;/* where tabs are */ MICA headerspace; /* vertical space to leave after header */ MICA footerspace; /* and before footer fileprev; } file; char inputbuffer[BUFFSIZE]; #ifdef CPM char tokentype; /* type of the current token */ char typearrahe output device */ char dname[16]; /* name of the device */ MICA dwidth; /* width of the printing surface */ MICA dheimber of characters in the buffer */ char ibuffer[MAXINPLEN+1]; } inp, inpsave[MAXINPNUM]; #define TOKMAXLEN 100 struct {top; /* margins */ MICA sleft; MICA sright; MICA sbottom; MICA above; /* space to leave before an environment */ Mart */ MICA footerplace; /* where on the page footnotes starts */ int endline; /* where the footer starts */ FLAG isfoo*/ char prefjust; /* preferred justification style 'b' both or 'l' left */ char footstyle; /* where footnotes gy[256]; /* types for each character */ #else int tokentype; /* type of the current token */ int typearray[256]; /* typeght; /* height of the print surface */ MICA micahoriz; /* size of smallest horizontal increment */ MICA micavert; /* si /* current input token */ int tbuflen; char tbuffer[TOKMAXLEN+1]; } tok; #define INBUFFER struct inbuffer INBUFICA below; /* space to leave after an environment */ FLAG levindent; /* do nested Level environments indent? */ FLAG levhtnote; /* in footnote mode? */ LINEDATA **lastline; /* ptr to the last line loaded */ int lastindex; /* index of the lasto: 'i' inline, 'b' bottom, 'e' end */ MICA indent; /* amount to indent paragraphs */ MICA spread; /* number of s for each character */ #endif FLAG unget; /* TRUE if you are ungetting */ /* ------------------------------------------ze of smallest vertical incrment */ FLAG isprop; /* does it have a proportial width font? */ char fontnum; /* if isprop,FER { /* input buffer descriptor */ int fd; /* file descriptor or -1 for string */ char *curchar; /* ptr to current chang; /* are Level paragraphs outdented? */ int endsize; /* amount to leave for end space */ } sty; /* --------------- line loaded */ } pag; /* -------------------------------------------------- */ /* input tokenizer stuff */ #define Mlines between paragraphs */ MICA spacing; /* line spacing */ FLAG footpush; /* are refs superscripts or bracketed? */ -------- */ /* defaults and personal style */ #define MAXTABS 32 /* max # of tabs */ struct { MICA tabcolumns[MAXTABS] which width table to use */ MICA stdhoriz; /* width of a canonical character */ MICA stdvert; /* height of a single spaaracter */ unsigned blocknum; unsigned linenum; char filedesc[LENFILENAME]; /* descriptive name of thingie */ INBUFFER *----------------------------------- */ /* device structures */ #define SSPACE 128-54 struct printdesc { /* describes tAXINPLEN 300 #define MAXINPNUM 2 char inpnum; /* stack ptr */ struct { /* input token buffer */ int ibuflen; /* nu FLAG scriptpush; /* do sub and superscripts get extra space? */ FLAG ischapter; /* does @chapter command exist? */ MICA sced line */ FLAG isfile; /* do plain file output? */ char prtcode; /* printer type code for crayon */ MICA paperoffsetreleft; /* left margin for middle of paragraph */ MICA eleft; /* one of the two previous */ MICA eright; /* right marg /* output goes: c=console, p=printer, f=file */ FLAG outnotinited; /* output file needs initilization */ int outfd; charG *entname; TITLELIST *entnextptr; } *titlehead, *titletail; /* variables */ #define VALLIST struct vallist struct va finistr, /* ... clean up after */ donewline, /* ... do a newline */ boldon, /* ... turn on boldface */ bolr closechar; /* character to append for in-line environ.s */ ENVIRON *envprev; /* previous environment */ } env; /* ---; /* height paper is assumed to start at */ FLAG backspace; /* Does backspace work */ FLAG barecr; /* does bare CR work in */ MICA linespacing; /* height of the line */ FLAG isfill; /* do we fill lines? */ FLAG iswrap; /* do we wrap long *outchar; /* ptr to current character */ char outputbuffer[BUFFSIZE]; /* -----------------------------------------------llist { STRING *valname; /* ptr to name of variable */ char valtype; /* type: 's' string, 'n' number */ int value; Vdoff, /* turn off boldface */ italon, /* turn on italiacs */ italoff; /* turn off italiacs */ char strspc[SSPACE----------------------------------------------- */ /* list structures */ /* titles for Table of Contents */ #define TIT*/ FLAG formfeed; /* does form feed work */ char synctype; /* Type of waiting to do: NONE, ETX/ACK, ^S^Q */ FLAG needt lines? */ char justifytype; /* 'b', 'l', 'r', or 'c' */ FLAG iswhiteintact; /* do we pass whitespace through unscathed? *--- */ /* environment */ #define ENVIRON struct envrn struct envrn { char *name; /* name of current enviornment */ ALLIST *valnextptr; } *valhead, *valtail; /* end notes */ #define NOTELIST struct notelist struct notelist { int not]; /* where strings are stored */ } dev; FLAG devinited; /* have the -dev, -p, or -c options been used? */ MICA widthtaLELIST struct titlelist struct titlelist { char enttype; /* type: 'c' chap, 's' sec, 'b' subsec, 'a' appendix, 'n' appenran; /* Do character translation on output? */ char trannum; /* Translation table number */ struct comstr { /* Various / int (*paraproc)(); /* procedure to execute on paragraph break */ int (*closeproc)(); /* procedure to execute on exit frochar howclose; /* how to close it {),],},>, or 'e') */ MICA preveleft; /* left margin of enclosing environment */ MICA cuenum; /* the note number */ STRING *noteptr; /* the text of the note */ NOTELIST *notenextptr; } *notehead, *notetail; ble[128]; /* size of each char. non-printing=0 */ /* -------------------------------------------------- */ char whereto; dix section, 'p' paragraph */ int entpage; /* page number */ int entnum; /* the section, chapter, etc. number */ STRINstrings to send */ char idx; /* index into space */ char len; /* length */ } initstr, /* ... set things up */m environ. */ int itemlevel; /* nesting depth for @itemize */ int enumcount; /* paragraph number for @enumerate */ cha /* index entries */ #define INDLIST struct indlist struct indlist { STRING *indname; /* the name of the entry */ int UTMAXLEN]; } put; int minpage; /* minimum room left (for accumulating statistics) */ int pagesize; /* sizes of the spe argument is terminated */ char saveclose; /* saves GetArg's state */ FLAG curscript; /* NUL=neither, `p`=in super, `b`=in itle, *subtitle, *paratitle, *apptitle, *asectitle; VALLIST *pagevar; /* current page number */ int pagenum; FLAG header indpage; /* the page number */ INDLIST *indnextptr; } *indhead; /* -------------------------------------------------- *ace */ #define LEVELMAX 10 int level[LEVELMAX]; #ifdef UNIX #define isupper(tchar) (tchar>='A' && tchar<='Z') #define isub */ FLAG issuper; /* superscript on line? */ FLAG issub; /* subscript on line? */ STRING *headeven; /* headers */ mode; /* are we accumulating a header? */ MICA heacumlen; /* its accumulated length */ int heacumnum; /* its accumulated n/ /* storage and scratch struct */ FLAG newl; /* was the last thing a Newline? */ FLAG nofootnotes; /* no footnotes onslower(tchar) (tchar>='a' && tchar<='z') #define isdigit(tchar) (tchar>='0' && tchar<='9') #define isalpha(tchar) (isupper(tchSTRING *headodd; STRING *footeven; STRING *footodd; /* used for accumulating a literal string to insert in the output file MAINUMINIbSCRIBBL SATSIG; PUTINI PUPUTCHOPUTNU;PUTST6PUTFINɦSINISCCOMSCOMqSCOMPGԣSCOMPTOoSCTOӡumber of entries */ FLAG openneeded; /* are we waiting for an open delimiter to begin an environment? */ FLAG argquote this page yet */ int footnum; /* current footnote number */ int blankpages; /* number of blank pages to leave */ /ar) || islower(tchar)) #define tolower(tchar) (isupper(tchar)?tchar-'A'+'a':tchar) #define toupper(tchar) (islower(tchar)?tcha*/ #define PUTMAXLEN 200 struct { int plevel; /* for deciding when to write the buffer */ char *pptr; char pbuffer[PSFRE SLENGT3SNTO]SNTOSSTORSSTOgSPARTOκEINImEFIN{EPOEPUSnMEMGEMEMFREŲMEMSPACd; /* was the argument in quotes? */ FLAG getarginitialized; /* in the middle of an argument? */ char getargclose; /* how th* sectioning variables */ VALLIST *chapter, *section, *subsection, *paragraph, *appendix, *asection; VALLIST *chaptitle, *sectr-'a'+'A':tchar) #endif /* END OF SCRIBBLE.GBL */ etArg's state */ FLAG curscript; /* NUL=neither, `p`=in super, `b`=in "t!"v"x!"z"|!"~>2>2>2>2>2!"!"">2!"!"!"!!n!"!!n!QTWZ!9Scribble Version 1.3 Copyright (C) 1981 by Mark of the Unicorn Inc. Usage is: scribble {-dev 2*Xn}ª*i!!9~#foí$`is{2'*-0n}.͝n}?͝n}!͝`is>!%! ^#Vr+s!j!m͐~#fo|! cs`is"!p!s͐~#fo|-! ps`is"!v͐~#fo|ʇ͐IGETTOIGETTYPDOSENBREAKTOLPUTWHILGETLENLGETCOBREAKLIPPUTVERFLUSHWHLNEWLINIAPPTOSATSIGLHDRCENLHDRRIGLHDRLININEXTT"!!n!"!!n!"!!n!"!!n!"!!n!"!!s!>} {-c | -t | -l | -p | -o } -t-c-l-p-oNo file specified for -o. Using default file. -devNo device specified for 2$`is{2$3G!9IHNTZ`flrx~  $,/6>LT |`i6f! ^#Vr+s~#fo! s#r! ^#Vr+sÄ!y"!͐~#fo|͐ ! 6n! ^#Vr+s~#fo!O"6!9DM`is{2>V>ʹ> b>ʼ> n>>(z>ʂ>TINITPUTEXIAINISINIMULCOMSCCOMIINIDINIASUBSPAASPACOINIPINILINIEINIENVININUMINIHEADERISCRIBBLBREAKLIPRIN"!!s!"!!s!"! !s! "!!s!"!*!s!+-dev. Using default device. Unknown option '' No input file specified. Jfim{~ +.;BOW_fIGETTOINEXTTOIGETTYPIUNGEIAPPTOSCOMMANU s#r! ^#Vr+s!"͐~#fon}-!͐~#fo!"͐~#fo! s#rû͐|>!! ͐@†>ʰ>’>ʿ>ž>>ª>>B¶>`in}*c} `i6 *f}*]TNOPRINTINTABLEOFEFINIFINDFINLFINPFINOFINTFIN]"pagechaptersectionsubsectionparagraphappendixappendixsectionchaptertitlesectiontitlesubsectiontitleparaz} #,/3;DUbnzSETVASCTO@ !"r >(>7>@4>=C SS>2S &,258;>AIMQ *#"+"*6͐! n&*͕*" *!"`in}ˆ͐! s#r͐`in&$'*-0369<?BE<HKN`in}*c} `i6 *}N*c}N*g|N**g!J!9~#fo*c}s!*g|s*g!r!9~#fo*}͝!9DM!͐ ڈ! ! "" `is! s! s#r! s#r! s#r! ^#Vr+sgraphtitleappendixtitleappendixsectiontitle'sw %)26?CLPY]fjswPUTINIPUTCHPUTFIN( !9DM! n&  $TINTERRZ!9DM*!.!F*E*p|!!#*V!2' environment.Exiting but in a ' TINTERRMOVMEMEMFREq !9D^#Vr+s6-͐! s#r͐ `͐͐ ! s#r! ^#Vr+s͐ 0s͐6͐@TMEMG!9DM͐͐&TOUPPE!9DM͐|!&͐|.!&͐n}ʟ͐n}ʟ͐n&͐"*#"+! ns*6Put buffer overflow!PUTINIPUTSTSNTOPUTFINL!9DM͐`iM*p|'!TK*p`is#r!!V*p͐ !9Popping the base environment!%=HMEMGEMOVMEB ESNTO> !9DM!`is#r͐͐͐5!9*3!9DM͐SPARTO?!9DMn&ʆ͐n&͐n&ͩ&! ^#Vr+s! ^#Vr+s.͐n& %6@KX`kxSCCOM#!͐ `i͐ ! 9 ,4=APUTINIPUTCHPUTFINI !9DM͐|͐n}D! ^#V!9DM!`is#r!͐!V͐"p!9-AALLOTINTERRTPUTIFINOFINEXIn}--!͐#!͐$7ISDIGITERROSPARTO !9DM͐n}$͐͐n&PUT@!Copyright (c) 1981 by Mark of the Unicorn Inc. TOPOFMEENDEXMOVME !9DM9DM͐͐&MEMGESTRLESTRCPH !9DM͐#`is#r͐͐ ͐?!9COPYRIGAINITASUBSPAAALLOþAFREX_ACOALE_AFINDNűALEASPACAPRTWRL _APRNN _ACH= _AERRO r+sn&"  *>BEIUSSCRIBBL6 *+"0!"!2!put!).T!9DM͐* `is#r͐|o!* *͝Y!\! !͐v!9Out of memory.in page|N!v͐!y͐͐ ?͐nѯg͐# '.Invalid number '-36?Cn !"pTERRO""͉͐"**)"*6#6**s#r!! Á!9"&n 4=MEMFRE!9DM͐STRLE!9DM͐SNTO!9DM͐|5! OLOWE\!9DM͐n&͐n&5!&! ^#Vr+s! ^#Vr+sn}!&$,QSCCOM# spacein end space'8;?QTWZ^beltAFRE!9DM͐* !9DM͐" v|AALLOMOVME !9DM͐##͐`is#rz7!Ñ͐"͐""**)"*6#6**!*!* ! s#r`is#r*! s#r͐*I!͐!͐~#fo *͐**~#fo)͐!& ͐"!& !9'<Ra{ !9DM͐͐͐*B͐*L!! ^#Vr+s͐͐~#fos#r*|͐"!͐!Bad ptr"%;GVY]vz}AB_AERROv **P**P**~#foщ*s#r!͐!͐Ñ!9"/5MOVME_AERRO_ACOALE_AFINDNN!9DM!!͐?!"͐~#fo|!f!a ͐~#fo`i~#fo͐~#fos#r'͐~#fo|$! ~#fo͐~#fo++~#fo+?MOVMEAB_AERRO !9DM!!͐`iw#w*! s#r͐*ʷ͐*c͐ freed1@CGs_ACH!9DM*~#fo`is#r**~#fo)~#fo! s#rz_*~#fo͐s#r|\_)*P*~#fo|_!h!&!&Memory Bashed$3BNQUTINTERR!9DM͐*|8!7*~#fo|L!@*`is#r͐###͉! s#r*~#fo͐ҳ |°͐ |°!͐!s#r'I! ~#fo͐~#fo )s#rg͐*|!'͐*!͉ !C͐?!G~#fo|n! Õ͐~#fo|`i~#fo͐~#fos#r! ~#fo͐~#fo)s#r8͐?!9Memory munge*~#fo͐ͣ&w!9;RWZ]uAB_ACH !9DM*`is#r**~#fo)"**D*"!7k*`is#r͐~#fo͐*͐)"͐͐~#fos#r ͐ | !"͐͐s#r!͐͐?!T͐͐*![͐͐*? !9Abegin = , Aend = , Acap = d "ETadhlyMOVME#!9DM!!͐TPUTTPUTTNABTPUr!9DM!*~#foҼ*͐}**~#fo)͐ڼ**~#fo)"**¢*"|¹͐"!& D*~#fo|!͐##7!9Corrupt Space%06BEI)5MOVME_AERRO !9DM!!at , , ** Last obj ends on Aend + -- allocated, free -- ** total = Asize + 2'+/7;?GKtw{/* AUXIL.C -- Scribble auxilliary routines written January 1981 by Craig A. Finseth Copyright (c) 1981 by Mark of the Unic/ char *cmd; { if (getarginited && GetArg(ARGFLUSH)) TError("Extra arguments to '",cmd,"'."); getarginited=FALSE; } SFree(token); return; } if (token) SFree(token); } INextTok(); } } FLAG ArgOn(cmd) /* start uIGetType()==EOFT) { IUnGet(); getarginted=FALSE; } token=IGetBuf(); if (what==ARGFLUSH) SFree(token); IPopBuf(); oc=CloseStan; env.enumcount=1; env.itemlevel=0; env.closechar=NUL; } /* ---------------------------------------------e == *IGetTok()) { getarginited=FALSE; return(NULL); } if (what==SAMPLE) return(*IGetTok()); argquoted=TRUE; orn Inc. */ #include "scribble.gbl" #ifndef CPM STRING *GetArg(); unsigned GetNumArg(); char MulComp(); FLAG Test();STRING * GetArg(what) /* return an argument, token by token */ char what; /* FLUSH, RETURN, SAMPLE (return delim) */ { p a GetArg */ char *cmd; { char *IGetTok(); if (getarginited) TIntError("ArgOnned"); INextTok(); if (IGetType()==EO return(token); } PushArg() /* save GetArg's state */ { saveclose=getargclose; getarginited=FALSE; } PopArg()----- */ /* Argument routines */ FlushArg(name) /* get rid of the argument */ char *name; { char *IGetTok(); STR IUnGet(); token=GetOneArg(what); INextTok(); return(token); } else if (what==SAMPLE) return(NUL); IPushBuf(); #endif EnvInit() /* initialize environment */ { int ParaStan(), CloseStan(); env.name="text"; env.howclose=NULchar *IGetTok(); STRING *token; if (!getarginited) return(NULL); argquoted=FALSE; while (IsType(WHITESPACE,NEWLINE,HFT) { IUnGet(); return(FALSE); } if ((getargclose=MatchOpen(*IGetTok()))==NUL) { TError("Missing argument to '",cm /* restore the state */ { getargclose=saveclose; getarginited=TRUE; } #ifdef LARGE MICA GetDimArg() /* processING *token; INextTok(); repeat { while (IGetType()!=COMMAND) if (IGetType()==EOFT) { IUnGet(); return; while (IsType(TOKEN,COMMAND,DELIM,NUL) || (IGetType()==TOKENBREAK && !MulComp(IGetTok(),"=",",") && !MulComp(IGetTok(),"/"; env.preveleft=pag.pleft; env.eleft=env.cureleft=pag.pleft; env.eright=pag.pright; env.linespacing=sty.spacing; env.iEADERCENTER,HEADERRIGHT,HEADERLINE, NUL) || MulComp(IGetTok(),"=",",") || MulComp(IGetTok(),"/",";")) { INextTok(); } d,"'."); return(FALSE); } getarginited=TRUE; INextTok(); return(TRUE); } ArgOff(cmd) /* finish up a GetArg * a dimensioned, numeric argument */ { unsigned n; MICA m; STRING *token; n=GetNumArg(); if (!(token=GetArg(RETURN)) } else INextTok(); INextTok(); if (SCComp(IGetTok(),"end")) { if (SCompToC(token=GetOneArg(RETURN),name)) { ,";"))) { if (IGetType()==DELIM && *IGetTok()==getargclose) break; if (what==RETURN) IAppTok(); INextTok(); } if (sfill=TRUE; env.iswrap=TRUE; env.justifytype=sty.prefjust; env.iswhiteintact=FALSE; env.paraproc=ParaStan; env.closepr if (IGetType()==EOFT) { IUnGet(); getarginited=FALSE; return(NULL); } if (IGetType()==DELIM) { if (getargclos) { TError("Missing dimension.",NULL,NULL); return(0); } switch (Index(token,"in inch inches cm mm point points pica TError("Missing single argument.",NULL,NULL); return(SCToS(IGetTok())); } if (arg==RETURN || arg==PRINT) IPushBuf(); ImArg() /* process a number in the argument */ { unsigned n; STRING *token; if (token=GetArg(RETURN)) { n=SSToN(to return(TRUE); } FLAG InLine(token,trialname,onchar,offchar) /* do an inline environment */ char *token; char *trialnC(token),"'."); m=0; } m*=n; SFree(token); return(m); } #endif #ifdef LARGE FLAG GetFlagArg() /* process NT) { /* print it on the console */ token=IGetBuf(); IPopBuf(); TPuts(SSToC(token)); SFree(token); } return(TRUpicas em ems char chars character characters line lines micas ")) { case 0: case 1: case 2: m=INCH; break; case 3: NextTok(); newl=FALSE; while (IGetType()!=EOFT && (IGetType()!=DELIM || *IGetTok()!=howend)) { if (IGetType()==NEWLINE) {ken); SFree(token); return(n); } else { TError("Missing numeric argument.",NULL,NULL); return(0); } } #ename; char onchar, offchar; { int CloseInLine(); if (SCComp(token,trialname)) { Put(onchar); EPush(); env.name=an "Yes" or "No" argument */ { STRING *token; FLAG arg; token=GetArg(RETURN); if (token && SCompToC(token,"yes")) argE); } /* -------------------------------------------------- */ /* standard environment routines */ FLAG GetOpen() m=CENTIMETER; break; case 4: m=CENTIMETER/10; break; case 5: case 6: m=POINT; break; case 7: case 8: m if (newl) { TError("Warning: Argument terminated by paragraph break.", NULL,NULL); break; } newl=Tdif STRING * GetOneArg(arg) /* return the argument as a single token */ char arg; /* HOLD, PRINT, RETURN, ARGFLUSH *trialname; env.closeproc=CloseInLine; env.closechar=offchar; if (!GetOpen()) Put(offchar); return(TRUE); } retu=TRUE; else if (token && SCompToC(token,"no")) arg=FALSE; else { TError("'Yes' or 'No' argument required. '",SSToC(token) /* pick up the opening delimiter */ { char *IGetTok(); openneeded=FALSE; INextTok(); if (IGetType()!=DELIM || (env.=PICA; break; case 9: case 10: m=Width('m'); break; case 11: case 12: case 13: case 14: m=CHARWIDTH; break; RUE; } else newl=FALSE; if (arg!=ARGFLUSH) IAppTok(); INextTok(); } newl=FALSE; if (IGetType()==EOFT) IUnGet/ { char howend; char *IGetTok(); STRING *token; INextTok(); howend=MatchOpen(*IGetTok()); if (howend==NUL) { rn(FALSE); } char MulComp(token,name1,name2) /* do a compare on more than one thing */ char *token; char *name1, *name, "' was given."); arg=FALSE; } if (token) SFree(token); return(arg); } #endif #ifdef LARGE unsigned GetNuhowclose=MatchOpen(*IGetTok()))==NUL) { TError("Bad opening character '",IGetTok(),"'."); EPop(); return(FALSE); } case 15: case 16: m=LINEHEIGHT; break; case 17: m=1; break; default: TError("Unknown unit of measure '",SSTo(); if (arg==RETURN) { /* return the argument */ token=IGetBuf(); IPopBuf(); return(token); } else if (arg==PRI2; { if (SCComp(token,name1)) return(1); else if (SCComp(token,name2)) return(2); return(NUL); } char MulTest(tokenItem() /* itemize paragraph */ { char chr; env.eleft=env.preveleft; chr= env.itemlevel&1 ? '-' : '*'; Put(chr); l'; env.paraproc=NULL; env.closeproc=CloseStan; env.preveleft=env.eleft; return(TRUE); } return(FALSE); } ef LARGE CloseLevel() /* Level environment closer */ { int *indx; for (indx= &level[0]; *indx; ++indx); if (indx> &oc=ParaStan; } StartEnv() /* start an environment */ { if (openneeded && !GetOpen()) return; BreakLine(); PPutVersty.indent); } /* -------------------------------------------------- */ /* Routines that close out environments */ Cl,name1,name2) /* do a Test on more than one thing */ char *token; char *name1, *name2; { if (Test(token,name1)) return(1)BreakTok(); LPutWhite(env.cureleft-(env.preveleft+Width(chr))); } #ifdef LARGE ParaLevel() /* Level environment */ {/* -------------------------------------------------- */ /* routines to handle paragraph breaks */ ParaEnum() /* enumerlevel[0]) *(--indx)=NULL; CloseStan(); } #endif CloseSec() /* sectioning environment closer */ { Put(env.closechart(sty.above); if (env.paraproc) (*env.paraproc)(); if (env.isfill) FlushWhite(); } FLAG Test(token,trialname) /* testoseCase() /* close out a Case statement */ { INextTok(); PopArg(); while (GetArg(ARGFLUSH)); EPop(); } CloseFoo; else if (Test(token,name2)) return(2); return(NUL); } NormalEnv(tname,whitep,fillp,just) /* set up a "normal" environ int *indx; ParaOut(); for (indx= &level[0]; *(indx+1); ++indx) PutNum(NULL,(*indx)-1,"."); PutNum(NULL,(*indx)++,".")ate paragraphs */ { MICA amt; char nums[10]; env.eleft=env.preveleft; SNToC(env.enumcount++,nums); strcat(nums,".")); BreakLine(); PPutVert(2*LINEHEIGHT); EPop(); } CloseStan() /* standard environment closer */ { BreakLine(); for an environment and do some set up */ char *token; char *trialname; { int CloseStan(); if (SCComp(token,trialnamets() /* close footnote environments */ { if (sty.footstyle=='i') Put(']'); else { BreakLine(); PNoFootnote(); Iment */ char *tname, just; FLAG whitep, fillp; { int ParaStan(); EPush(); env.name=tname; env.howclose=NUL; env; BreakTok(); LPutWhite(2*CHARWIDTH); if (sty.levhang) env.cureleft=LGetCol(); } #endif ParaOut() /* outdented p; PutStr(nums); amt=LGetLength(nums,env.preveleft); BreakTok(); LPutWhite(env.cureleft-(env.preveleft+amt)); } Para PPutVert(sty.below); EPop(); } /* END OF AUXIL.C */  ParaStan() /* standard paragraph breaker */ { LPutWhite()) { EPush(); env.name=trialname; env.iswhiteintact=FALSE; env.isfill=TRUE; env.iswrap=TRUE; env.justifytype='PopBuf(); } EPop(); } CloseInLine() /* in-line environment closer */ { Put(env.closechar); EPop(); } #ifd.iswhiteintact=whitep; env.isfill=fillp; env.iswrap=TRUE; env.justifytype=just; env.linespacing=LINEHEIGHT; env.parapraragraphs */ { env.eleft=env.preveleft; LPutWhite(0); } ParaStan() /* standard paragraph breaker */ { LPutWhite( while (indhead) { PutInit(); if (indhead->indname) { BreakLine(); PutStr(SSToC(indhead->indname)); Put(SP)ToC(notehead->noteptr),"endnotes"); Scribble(); BreakLine(); notehead=notehead->notenextptr; } BreakLine(); EPop case 'b': LPutWhite(6*CHARWIDTH); subsection->value=titlehead->entnum; break; case 'p': LPutWhite(9*CHARWIDteven=SCToS("\203- @Value(Page) -\222\214"); footodd=SCToS("\203- @Value(Page) -\222\214"); } PrintNotes() /* print an-INCH; PutStr("Table of Contents"); BreakLine(); PPutVert(2*LINEHEIGHT); env.justifytype='l'; oldtype='c'; while; } else Put(','); PutNum(" ",indhead->indpage,NULL); PutFini(); indhead=indhead->indnextptr; } BreakLine()(); } #ifdef LARGE PrintIndex() /* print the index */ { int ParaStan(); if (!indhead) return; TPuts("\n\nIndTH); paragraph->value=titlehead->entnum; break; case 'a': PutStr("Appendix "); appendix->value=titlehead->enty trailing footnotes */ { int ParaStan(); if (!notehead) return; NormalEnv("notes",FALSE,TRUE,sty.prefjust); env.pr (titlehead) { type=titlehead->enttype; if (oldtype!=type || type=='c' || type=='a') { BreakLine(); PPutVert(LINEH/* AUXILTOO.C -- More Scribble auxilliary routines written January 1981 by Craig A. Finseth Copyright (c) 1981 by Mark of ; EPop(); } #endif TableOfContents() /* generate the table of contents */ { char type, oldtype; MICA LGetCol(); ex\n\n "); PNewPage(); PPutVert(4*LINEHEIGHT); NormalEnv("index",TRUE,FALSE,'c'); env.preveleft=env.cureleft=envnum; break; case 'n': LPutWhite(3*CHARWIDTH); asection->value=titlehead->entnum; } SecStart(type); Tempeveleft=env.eleft=env.cureleft=pag.pleft; env.eright=pag.pright; BreakLine(); PPutVert(LINEHEIGHT); LPutToken(SCToS("-EIGHT); } oldtype=type; env.eleft=env.preveleft; switch(type) { case 'c': PutStr("Chapter "); chapter-the Unicorn Inc. */ #include "scribble.gbl" #ifdef UNIX MICA Width(); char MatchOpen(); FLAG IsNum(), IsType(); #end if (!titlehead) return; TPuts("\n\nTable of Contents\n\n "); PNewPage(); PPutVert(4*LINEHEIGHT); NormalEnv(.eleft=pag.pleft; env.eright=pag.pright; PutStr("Index"); BreakLine(); PPutVert(2*LINEHEIGHT); env.justifytype='l'; late(type); BreakTok(); PutStr(SSToC(titlehead->entname)); BreakTok(); if (LGetCol()>env.eright-HALFINCH) BreakLine(---------")); BreakLine(); while (notehead) { PPutVert(LINEHEIGHT); PutNum(NULL,notehead->notenum,". "); IUse(SS>value=titlehead->entnum; break; case 's': LPutWhite(3*CHARWIDTH); section->value=titlehead->entnum; break; if HeaderInit() /* initialize pageheadings */ { headeven=SCToS("\203\222\214"); headodd=SCToS("\203\222\214"); foo"contents",FALSE,FALSE,'c'); env.preveleft=env.eleft=pag.pleft; env.cureleft=env.preveleft+3*INCH/2; env.eright=pag.pright); LPutWhite(env.eright+HALFINCH-LGetCol()); env.iswrap=FALSE; PutNum(NULL,titlehead->entpage,NULL); BreakLine(); n(SSToN(vptr->value)); return(vptr->value); } int Index(token,str) /* look up token in str */ STRING *token; char SComp(ptr->valname,name); ptr=ptr->valnextptr); return(ptr); } FlushWhite() /* flush whitespace after paragraph breakse name */ char *name, *suffix; FLAG force; { char *indx; for (indx=name; *indx && *indx!='.'; ++indx); if (force) *ok(); LBreakLine(); } BreakTok() /* process a token break */ { STRING *token; char *SSToC(); if (*SSToC(tokenare we any of these? */ int args; { int *argp; for (argp= &args; *argp; ++argp) if (*argp==IGetType()) return(TRUE); env.iswrap=TRUE; titlehead=titlehead->entnextptr; } EPop(); } /* -------------------------------------------------*str; { int indx; char *cptr; indx=0; while (*str--) { cptr=SSToC(token)-1; do { ++str; ++cptr; } w */ { do { INextTok(); } while (IsType(WHITESPACE,NEWLINE,NUL)); IUnGet(); } int GetNumVal(name) /* return aindx=NUL; if (*indx==NUL) strcat(name,suffix); } SecStart(level) /* initialize the sectioning counters */ char level;=IGetBuf())!=NUL) { IClearBuf(); LPutToken(token); } else SFree(token); } DoSent() /* Process an sentence brreturn(FALSE); } char MatchOpen(a) /* return the matching close character */ char a; { switch (a) { case '(': - */ TITLELIST * AddToC() /* add a Table of Contents entry */ { TITLELIST *tptr; MemSpace(EndSpace); tptr=MemGhile (tolower(*str)==tolower(*cptr)); if (*str==SP && !*cptr) break; while (*str++ != SP); ++indx; } return(indx); numeric value or zero */ STRING *name; { VALLIST *vptr; if (!(vptr=FindVar(name))) return(0); if (vptr->valtype=='s' { if (level=='p') return; paragraph->value=0; SetVar("paragraphtitle",'s',SCToS("")); if (level=='b') return; subseceak if desired */ { STRING *token; char *SSToC(); if (islower(*SSToC(token=IGetBuf()))) Put(SENTENCEBREAK); SFree(tok return(')'); case '[': return(']'); case '{': return('}'); case '<': return('>'); case '"': return('"'); et(sizeof(*tptr)); if (!titlehead) titletail=titlehead=tptr; else { titletail->entnextptr=tptr; titletail=tptr; } } FLAG IsNum(str) /* does the string look like a number? */ STRING *str; { char *cptr; cptr=SSToC(str); if && !IsNum(vptr->value)) { TError("Non-numeric value '",SSToC(name),"'."); return(0); } if (vptr->valtype=='s') returtion->value=0; SetVar("subsectiontitle",'s',SCToS("")); if (level=='s' || level=='n') return; asection->value=0; SetVar(en); } VALLIST * FindVar(name) /* find a variable */ STRING *name; { VALLIST *ptr; for (ptr=valhead; ptr && ! case '`': case '\'': return('\''); default: return(NUL); } } ProcessSuffix(name,suffix,force) /* munge a fil tptr->entnextptr=NULL; tptr->entname=GetOneArg(RETURN); MemSpace(PageSpace); return(tptr); } BreakLine() { BreakT (*cptr=='+' || *cptr=='-') cptr++; while (*cptr && isdigit(*cptr)) cptr++; return(!*cptr); } FLAG IsType(args) /* "appendixsectiontitle",'s',SCToS("")); section->value=0; SetVar("sectiontitle",'s',SCToS("")); } VALLIST * SetVar(name----------------------------- */ TBell() /* ring the bell */ { TPut(BELL); } TError(a,b,c) /* print an error mes (what=='n') PutNum(tmp,asection->value,NULL); if (what=='s' || what=='b' || what=='p') PutNum(tmp,section->value,NULL); if TPut(*str++); } /* end of AUXILTOO.C */ "); if (a) TPuts(a); if (b) TPuts(b); if (c) TPuts(c); TPuts("\nerror wa; vptr->value=val; return(vptr); } MICA TabWidth(col) /* return the width of a Tab */ MICA col; { int i; /* print an internal error message */ char *msg; { TPuts("\nInternal Error: "); TPuts(msg); TPuts("\nerror was on lin,type,val) /* set a variable to a value, creating */ char *name; /* it if necessary */ char type; int val; { VALLIsage */ char *a, *b, *c; { TPuts("\nError: "); if (a) TPuts(a); if (b) TPuts(b); if (c) TPuts(c); TPuts("\nerror wa(what=='b' || what=='p') PutNum(".",subsection->value,NULL); if (what=='p') PutNum(".",paragraph->value,NULL); PutFini(); for (i=0; i=MAXTABS) ? dev.stdhoriz : (sty.tabcolumns[i]-col)); } Tee "); TPutn(IGetLine()); TPuts(" of "); TPuts(IGetFile()); TNL(); } TNL() /* send a Newline */ { putchar('\n'ST *vptr; STRING *token; token=SCToS(name); if (!(vptr=FindVar(token))) { vptr=MemGet(sizeof(*vptr)); if (!valheads on line "); TPutn(IGetLine()); TPuts(" of "); TPuts(IGetFile()); TNL(); } TFini() /* finish up writing things } MICA Width(chr) /* return the width of the character */ char chr; /* chr cannot be a Tab */ { if (chr>=SP && mplate(what) /* outputs a section number */ char what; { char *tmp; PutInit(); if (sty.ischapter) { if (what==); } TPut(chr) /* put a character */ char chr; { putchar(chr); } TPutn(n) /* print n on the terminal */ u) valtail=valhead=vptr; else { valtail->valnextptr=vptr; valtail=vptr; } vptr->valnextptr=NULL; vptr->valna*/ { } char TGetChr() /* get a character */ { char chr; #ifdef CPM chr=bios(3); #endif #ifdef UNIX chr=getchr<=DEL) if (dev.isprop) return(widthtable[chr]); else return(dev.stdhoriz); return(0); } /* ---------------------'a' || what=='n') Put('A'-1+appendix->value); else PutNum(NULL,chapter->value,NULL); tmp="."; } else tmp=NULL; ifnsigned n; { if (n>9) TPutn(n/10); putchar(n%10+'0'); } TPuts(str) /* put a string */ char *str; { while (*str)me=token; } else { if (vptr->valtype=='s' && vptr->value) SFree(vptr->value); SFree(token); } vptr->valtype=typechar(); #endif if (chr==3) exit(1); return(chr); } TInit() /* initialize the terminal */ { } TIntError(msg) TError("Incorrect Environment Closing. Tried to end a '", SSToC(token),"' environment."); TPuts("A '"); TPutsONMENTS */ if (CheckEnv(tkn)) return; /* BEGIN and END */ if (SCComp(tkn,"begin")) { token=GetOneArg(RETURN); ile(); return; } if (SCComp(tkn,"device")) { DSetType('n',SSToC(token=GetOneArg(RETURN))); SFree(token); return;icorn Inc. */ #include "scribble.gbl" #ifdef UNIX FLAG CheckVar(), CheckEnv(), CheckSec(); #endif SCommand(tkn) return; if (InLine(tkn,"t",ROMANON,ROMANOFF)) return; if (InLine(tkn,"u",UNNBON,UNNBOFF)) return; if (InLine(tkn,"ux",UNAL(env.name); TPuts("' environment is open, and it should be closed with '"); if (env.howclose=='e') TPuts("@end"); ef (SCompToC(token,"comment")) { SFree(token); FlushArg("comment"); return; } openneeded=FALSE; if (CheckEn } if (SCComp(tkn,"message")) { TNL(); GetOneArg(PRINT); return; } /* HEADINGS, FOOTINGS, and FOOTNOTES */ /* process a command */ char *tkn; { STRING *token, *token2; char which; INDLIST *iptr, *iptr2, *iptrold; NOTELIST *nLON,UNALLOFF)) return; if (InLine(tkn,"un",UNANON,UNANOFF)) return; /* I/O Commands */ if (SCComp(tkn,"comment")) { lse TPut(env.howclose); TPuts("'.\n"); } SFree(token); return; } /* INLINE Environment */ if (InLine(tknv(token)) env.howclose='e'; else TError("Unknown environment '",SSToC(token),"'."); SFree(token); return; } if (SC if (which=MulComp(tkn,"pageheading","pagefooting")) { DoHeading(which); return; } if (SCComp(tkn,"note") || (sty.fptr; MICA LGetCol(), amt; int CloseFoots(); if (SCComp(tkn,"\\")) { if (SCComp(env.name,"description")) { BreakToGetOneArg(ARGFLUSH); return; } if (SCComp(tkn,"include")) { token=GetOneArg(RETURN); IInclude(SSToC(token)); SF,"+",SUPERON,SUPEROFF)) return; if (InLine(tkn,"-",SUBON,SUBOFF)) return; if (InLine(tkn,"b",BOLDON,BOLDOFF)) return; if (Comp(tkn,"end")) { token=GetOneArg(RETURN); if (env.howclose=='e' && SCComp(env.name,token)) (*env.closeproc)(); else {ootstyle=='e' && SCComp(tkn,"foot"))) { if (sty.footpush) { PutInit(); Put(SUPERON); PutNum(NULL,++footnum,NULL);k(); if (LGetCol()>=env.cureleft) BreakLine(); else LPutWhite(env.cureleft-LGetCol()); } return; } /* ENVIRree(token); if (!MulComp(token,"con:","tty:")) { TPuts("\nIncluding "); TPuts(IGetFile()); TNL(); } Scribb/* COMMANDS.C -- Scribble command interpeter written January 1981 by Craig A. Finseth Copyright (c) 1981 by Mark of the UnInLine(tkn,"i",ITALON,ITALOFF)) return; if (InLine(tkn,"p",BITALON,BITALOFF)) return; if (InLine(tkn,"r",ROMANON,ROMANOFF)) Put(SUPEROFF); PutFini(); } else PutNum("[",++footnum,"]"); MemSpace(EndSpace); nptr=MemGet(sizeof(*nptr)) } while (iptr && !iptr->indname); } if (iptr==indhead) { iptr2->indnextptr=indhead; indhead=iptr2; } (SCComp(tkn,"index")) { MemSpace(EndSpace); iptr2=MemGet(sizeof(*iptr)); iptr2->indpage=(pagenum==0)? 1 : pagenum; FOUND */ TError("Unknown command '",tkn,"'."); openneeded=FALSE; IAppTok(); } FLAG CheckVar(tkn) /* do the var } else PutNum("[",++footnum,"]"); IPushBuf(); PFootnote(); NormalEnv("footnote",FALSE,TRUE,sty.prefjust); env. /* WHITESPACE COMMANDS */ if (SCComp(tkn,"newpage")) { BreakLine(); PNewPage(); return; } #ifdef LARGE if ; if (!notehead) notetail=notehead=nptr; else notetail->notenextptr=nptr; notetail=nptr; nptr->notenum=footnum; n else { iptr2->indnextptr=iptrold->indnextptr; iptrold->indnextptr=iptr2; } } iptr2->indname=token; token=GetOneArg(RETURN); if (!indhead) { indhead=iptr2; iptr2->indnextptr=NULL; } else { iptr=iptrold=iniable processing commands */ char *tkn; { STRING *token, *token2, *sptr; char which, *secstr, *SSToC(); int oldval, valcloseproc= &CloseFoots; env.preveleft=env.eleft=env.cureleft=pag.pleft; env.eright=pag.pright; if (nofootnotes) { (SCComp(tkn,"blankpage")) { ArgOn("@BlankPage"); blankpages+=GetNumArg(); ArgOff("@BlankPage"); return; } #endifptr->noteptr=GetOneArg(RETURN); nptr->notenextptr=NULL; MemSpace(PageSpace); return; } if (SCComp(tkn,"foot")) { MemSpace(PageSpace); return; } #endif /* CHAPTERS, SECTIONS, and SUBSECTIONS */ if (CheckSec(tkn)) return; /* Vdhead; while (iptr && SCompGT(token,iptr->indname)) { iptrold=iptr; iptr=iptr->indnextptr; } if (iptr && ; VALLIST *vptr; if (SCComp(tkn,"string")) { token=NULL; if (!ArgOn("@String") || !(token=GetArg(RETURN)) || !( nofootnotes=FALSE; PPutVert(LINEHEIGHT); LPutToken(SCToS("----------")); BreakLine(); } PPutVert(LINEHEIGHT) #ifdef LARGE if (SCComp(tkn,"blankspace")) { BreakLine(); ArgOn("@BlankSpace"); amt=GetDimArg(); ArgOff("@BlankS if (sty.footstyle=='i') { EPush(); env.closeproc= &CloseFoots; env.name="footnote"; Put('['); return; ARIABLE STORING AND PRINTING */ if (CheckVar(tkn)) return; /* CASE */ #ifdef LARGE if (SCComp(tkn,"case")) { DoCaSComp(token,iptr->indname)) { SFree(token); token=NULL; do { iptrold=iptr; iptr=iptr->indnextptr; token2=GetArg(RETURN))) { if (token) SFree(token); TError("@String requires two arguments.",NULL,NULL); return(TRUE); PutNum(NULL,footnum,". "); if (!GetOpen()) { PNoFootnote(); IPopBuf(); } return; } #ifdef LARGE ifpace"); PPutVert(amt); return; } #endif if (SCComp(tkn,"w")) { GetOneArg(HOLD); return; } /* COMMAND NOT} if (sty.footpush) { PutInit(); Put(SUPERON); PutNum(NULL,++footnum,NULL); Put(SUPEROFF); PutFini(); se(); return; } #endif /* STYLE */ #ifdef LARGE if (SCComp(tkn,"style")) { DoStyle(); return; } #endif ; } if (argquoted) sptr=token2; else { if (!(vptr=FindVar(token2))) { TError("@String: Variable not found '",ltype=='n') PutNum(NULL,vptr->value,NULL); else TError("@Ref: '",SSToC(token), "' does not contain a number."); } (token2); oldval=GetNumVal(token); if (which=='+') oldval+=val; else if (which=='-') oldval-=val; else oldval=val;L,vptr->value,NULL); SFree(token); return(TRUE); } if (SCComp(tkn,"set")) { token=NULL; if (!ArgOn("@Set") || !(vptr) PutStr(vptr->value); SFree(token); return; } } /* END OF COMMANDS.C */  secstr="chapter section subsectSSToC(token2),"'."); sptr=token2; } else { SFree(token2); if (vptr->valtype=='s') sptr=SCToS(SSToC(vptr- else Template("csbpan"[val]); SFree(token); return(TRUE); } if (SCComp(tkn,"title")) { vptr=NULL; switch (Ind SetVar(SSToC(token),'n',oldval); SFree(token); ArgOff("@Set"); return(TRUE); } secstr="chapter section subsect(token=GetArg(RETURN)) || !(token2=GetArg(RETURN))) { if (token) SFree(token); TError("@Set requires two arguments.>value)); else sptr=SNToS(vptr->value); } } SetVar(SSToC(token),'s',sptr); SFree(token); ArgOff("@String"ex((token=GetOneArg(RETURN)),secstr)) { case 0: vptr=chaptitle; break; case 1: vptr=sectitle; break; ion paragraph appendix appendixsection "; if (SCComp(tkn,"ref")) { val=Index((token=GetOneArg(RETURN)),secstr); if (val>/* COMMTOO.C -- Scribble command interpeter, continued written March 1981 by Craig A. Finseth Copyright (c) 1981 by Mark o",NULL,NULL); return(TRUE); } which= *SSToC(token2); if (which=='+' || which=='-') { sptr=SCToS(SSToC(token2)+); return(TRUE); } if (SCComp(tkn,"value")) { token=GetOneArg(RETURN); vptr=FindVar(token); if (!vptr) TError("case 2: vptr=subtitle; break; case 3: vptr=paratitle; break; case 4: vptr=apptitle; break; case5) { vptr=FindVar(token); if (!vptr) TError("@Ref: Variable not found '", SSToC(token),"'."); else if (vptr->vaf the Unicorn Inc. */ #include "scribble.gbl" FLAG CheckEnv(tkn) /* deal with environments */ char *tkn; { char 1); SFree(token2); token2=sptr; } if (IsNum(token2)) val=SSToN(token2); else val=GetNumVal(token2); SFree@Value: Variable not found '",SSToC(token),"'."); else if (vptr->valtype=='s') PutStr(SSToC(vptr->value)); else PutNum(NUL 5: vptr=asectitle; break; default: TError("@Title: Unknown option '",SSToC(token),"'."); break; } if which; int *indx; int ParaOut(), ParaEnum(), ParaItem(), ParaStan(), CloseSec(); #ifdef LARGE int ParaLevel(), CloseLevelaraproc=ParaItem; env.itemlevel++; StartEnv(); return(TRUE); } #ifdef LARGE if (Test(tkn,"level")) { for (indxv.cureleft+2*CHARWIDTH; env.eleft=env.cureleft+=6*CHARWIDTH; env.justifytype=sty.prefjust; env.enumcount=1; env.para,"unnumbered","majorheading")) || Test(tkn,"heading")) { env.isfill=FALSE; env.justifytype='c'; env.closeproc=Closeion","undent")) { if (which==1) { env.eleft=env.cureleft+=(env.eright-env.cureleft)/4; env.linespacing=LINEHEIGHT; pe=sty.prefjust; env.paraproc=ParaStan; StartEnv(); return(TRUE); } if (Test(tkn,"text")) { env.justifytype=sty(); #endif if ((which=MulTest(tkn,"address","flushleft")) || Test(tkn,"closing")) { env.isfill=FALSE; env.iswrap=FALS= &level[0]; *indx; ++indx); if (sty.levindent && indx> &level[0]) { if (env.cureleft==env.preveleft) env.cureleft+=HALFIproc=ParaEnum; StartEnv(); return(TRUE); } if (MulTest(tkn,"format","verbatim")) { env.linespacing=LINEHEIGHT; Sec; env.closechar=BOLDOFF; BreakLine(); if (which==1) PNewPage(); StartEnv(); PPutVert((which ? 6 : 4)*LINEHEIGH } else env.eleft=env.cureleft+=sty.indent; env.justifytype=sty.prefjust; env.paraproc=ParaOut; StartEnv(); retu.prefjust; env.paraproc=ParaStan; env.linespacing=sty.spacing; StartEnv(); return(TRUE); } if (Test(tkn,"verse"E; env.iswhiteintact=TRUE; if (which!=2) env.preveleft=env.eleft=env.cureleft= (pag.pright+pag.pleft)/2; StartEnv()NCH; env.preveleft=env.eleft=env.cureleft; } env.justifytype=sty.prefjust; env.paraproc=ParaStan; *indx=1; *env.isfill=FALSE; env.iswrap=FALSE; env.iswhiteintact=TRUE; StartEnv(); return(TRUE); } if (Test(tkn,"itemize")T); Put(BOLDON); return(TRUE); } if (MulTest(tkn,"prefacesection","subheading")) { env.isfill=FALSE; env.closeprn(TRUE); } if (MulTest(tkn,"display","example")) { env.eleft=env.cureleft+=HALFINCH; env.eright-=HALFINCH/2; env.)) { env.eleft=env.preveleft+=3*CHARWIDTH; env.cureleft=env.preveleft+2*CHARWIDTH; env.eright-=10*CHARWIDTH; env.lin; return(TRUE); } if (which=MulTest(tkn,"center","flushright")) { env.isfill=FALSE; env.iswrap=FALSE; env.iswhi(indx+1)=NULL; env.paraproc=ParaLevel; env.closeproc=CloseLevel; StartEnv(); return(TRUE); } #endif if (Test(t) { env.preveleft=env.cureleft+2*CHARWIDTH; env.eleft=env.cureleft+=5*CHARWIDTH; env.justifytype=sty.prefjust; env.proc=CloseSec; env.closechar=UNALLOFF; StartEnv(); PPutVert(4*LINEHEIGHT); Put(UNALLON); return(TRUE); } retuisfill=FALSE; env.iswhiteintact=TRUE; StartEnv(); return(TRUE); } if (Test(tkn,"enumerate")) { env.preveleft=enespacing=LINEHEIGHT; env.isfill=FALSE; env.paraproc=ParaOut; StartEnv(); return(TRUE); } if ((which=MulTest(tknteintact=TRUE; env.justifytype= (which==1)? 'c' : 'r'; StartEnv(); return(TRUE); } if (which=MulTest(tkn,"descriptkn,"quotation")) { env.eleft=env.cureleft+=HALFINCH; env.eright-=HALFINCH; env.linespacing=LINEHEIGHT; env.justifytyrn(FALSE); } FLAG CheckSec(tkn) /* deal with sectioning commands */ char *tkn; { TITLELIST *tptr; STRING *token; BreakLine(); PPutVert(4*LINEHEIGHT); EPush(); env.isfill=FALSE; env.justifytype='l'; PutInit(); Put(UNALLON)name)); Put(BOLDOFF); PutFini(); BreakLine(); PPutVert(3*LINEHEIGHT); EPop(); return(TRUE); } if (which=Mptr->entpage=pagenum; PPutVert(LINEHEIGHT); EPop(); return(TRUE); } return(FALSE); } #ifdef LARGE DoCase()e); BreakLine(); PNewPage(); PPutVert(6*LINEHEIGHT); tptr->entpage=pagenum; TPuts(" ("); if (which==1) T'; tptr->entnum= ++(subsection->value); SetVar("subsectiontitle",'s',SCToS(SSToC(tptr->entname))); paragraph->value= char which; if (which=MulComp(tkn,"chapter","appendix")) { if (!sty.ischapter) { TError("@Chapter and @Appendix ha; Template((which==1) ? 's' : 'n'); Put(SP); PutStr(SSToC(tptr->entname)); Put(UNALLOFF); PutFini(); BreakLineulComp(tkn,"section","appendixsection")) { tptr=AddToC(); if (which==1) { tptr->enttype='s'; tptr->entnum= ++(sect /* process the @Case command */ { STRING *token; VALLIST *vptr; char dlm; int CloseCase(); if (!ArgOn("@Case"))Putn(chapter->value); else TPut('A'-1+appendix->value); TPut(')'); EPush(); env.isfill=FALSE; env.justifytype='0; } else { tptr->enttype='p'; tptr->entnum= ++(paragraph->value); SetVar("paragraphtitle",'s',SCToS(SSToC(tpve been disabled.",NULL,NULL); return(TRUE); } tptr=AddToC(); if (which==1) { tptr->enttype='c'; tptr->e(); tptr->entpage=pagenum; TPuts(" ("); if (which==1) TPutn(chapter->value); else TPut('A'-1+appendix->value); ion->value); SetVar("sectiontitle",'s',SCToS(SSToC(tptr->entname))); } else { tptr->enttype='n'; tptr->entnum return; vptr=FindVar(token=GetArg(RETURN)); if (!vptr || vptr->valtype!='s') { TError("Undefined or non-string selector c'; PutInit(); Put(BOLDON); if (which==1) { PutStr("Chapter "); Template('c'); } else { PutStr("Appetr->entname))); } BreakLine(); PPutVert(2*LINEHEIGHT); EPush(); env.isfill=FALSE; env.justifytype='l'; Pntnum= ++(chapter->value); SetVar("chaptertitle",'s',SCToS(SSToC(tptr->entname))); } else { tptr->enttype='a'; TPut('.'); TPutn((which==1) ? section->value : asection->value); TPut(')'); PPutVert(2*LINEHEIGHT); EPop(); r= ++(asection->value); SetVar("appendixsectiontitle",'s',SCToS(SSToC(tptr->entname))); } SecStart(tptr->enttype); variable for @Case '", SSToC(token),"'."); SFree(token); ArgOff("@Case"); return; } SFree(token); while (tokndix "); Template('a'); } PutFini(); BreakLine(); PPutVert(LINEHEIGHT); PutInit(); PutStr(SSToC(tptr->entutInit(); Template((which==1) ? 'b' : 'p'); Put(SP); PutStr(SSToC(tptr->entname)); PutFini(); BreakLine(); t tptr->entnum= ++(appendix->value); SetVar("appendixtitle",'s',SCToS(SSToC(tptr->entname))); } SecStart(tptr->enttypeturn(TRUE); } if (which=MulComp(tkn,"subsection","paragraph")) { tptr=AddToC(); if (which==1) { tptr->enttype='ben=GetArg(RETURN)) { if ((SCompToC(vptr->value,"") && SCompToC(token,"null")) || SComp(token,vptr->value) || SCompToC(to case 9: /* justification */ env.justifytype=sty.prefjust=(GetFlagArg() ? 'b' : 'l'); break; case 10: /* lsty.below=GetDimArg(); break; case 2: /* bottom margin */ pag.pbottom=dev.dheight-(sty.sbottom=GetDimArg()); .dwidth-(sty.sright=GetDimArg()); break; case 18: /* script push */ sty.scriptpush=GetFlagArg(); break; ca} } #endif #ifdef LARGE DoStyle() /* process the @Style command */ { STRING *token, *token2; ArgOn("@Style"); case 1: sty.footstyle='b'; break; case 2: sty.footstyle='i'; break; default: TError("Unknown vken,"else")) { SFree(token); if (dlm=GetArg(SAMPLE)) { PushArg(); EPush(); env.name="case"; env.howceft margin */ env.preveleft=env.eleft=env.cureleft=pag.pleft=GetDimArg(); break; case 11: /* level hang */ stbreak; case 3: /* chapter */ sty.ischapter=GetFlagArg(); break; case 4: /* footer spacing */ sty.footese 19: /* spacing */ env.linespacing=sty.spacing=GetDimArg(); break; case 20: /* spread */ sty.spread=Get while (token=GetArg(RETURN)) { switch (Index(token,"above below bottommargin chapters footerspacing footpush headerspacing ialue for Note clause of @Style '", SSToC(token2),"'."); break; } SFree(token2); break; case 15: /lose=MatchOpen(dlm); env.closeproc=CloseCase; return; } else { if (!(token=GetArg(RETURN))) { TErry.levhang=GetFlagArg(); break; case 12: /* level indent */ sty.levindent=GetFlagArg(); break; case 13: rspace=GetDimArg(); break; case 5: /* foot push */ sty.footpush=GetFlagArg(); break; case 6: /* headerDimArg(); break; case 21: /* top margin */ pag.ptop=GetDimArg(); break; default: TError("Unknown argumndent indentation justification leftmargin levelhang levelindent linewidth notes paperlength paperwidth rightmargin scriptpush s* paper length */ pag.pbottom=(dev.dheight=GetDimArg())-sty.sbottom; break; case 16: /* paper width */ env.eror("Unexpected end of @Case argument",NULL,NULL); return; } while (GetArg(ARGFLUSH)); IUse(SSToC(token),"c /* line width */ env.eright=pag.pright=pag.pleft+GetDimArg(); break; case 14: /* notes */ if (!(token2=GetAr spacing */ sty.headerspace=GetDimArg(); break; case 7: case 8: /* indent */ sty.indent=GetDimArg(); break;ent to @Style '",SSToC(token),"'."); ArgOff("@Style"); break; } SFree(token); } } #endif DoHeading(whichpacing spread topmargin ")) { case 0: /* above */ sty.above=GetDimArg(); break; case 1: /* below */ ight=pag.pright=(dev.dwidth=GetDimArg())-sty.sright; break; case 17: /* right margin */ env.eright=pag.pright=devase"); Scribble(); SFree(token); return; } } else if (!GetArg(ARGFLUSH)) return; SFree(token); g(RETURN))) break; switch (Index(token2,"endnote footnote inline ")) { case 0: sty.footstyle='e'; break; ) /* process a page heading command */ char which; { STRING *token, *lhead, *chead, *rhead, *nhead, *ptrs; char where, *urn; } /* END OF COMMTOO.C */  case 5: where='o'; break; default: TError("Unknown argument to @PageHeadi(ptr,"\214"); strcat(ptr,SSToC(nhead)); SFree(lhead); SFree(chead); SFree(rhead); SFree(nhead); if (which==1) { !9DM͐`is#r͐s{;͐! ~#fo͐ +W$͐n}ʃʃ ʷ "͐͐ case 4: where='e'; break; case 5: where='o'; break; default: TError("Unknown argument to @PageHeadiptr; where='b'; lhead=SCToS(""); rhead=SCToS(""); chead=SCToS(""); nhead=SCToS(""); ArgOn(which==1 ? "@PageHeading if (where=='b' || where=='e') { SFree(headeven); headeven=SCToS(ptr); } if (where=='b' || where=='o') { SFҜ`i^#Vr+s! ! ! 8`i^#Vr+s6 8 ͐6͐8͐͐͐+n} `i^#Vr+s! ng or @PageFooting '", SSToC(token),"'."); SFree(token); ArgOff(which==1 ? "@PageHeading" : "@PageFooting"); br" : "@PageFooting"); while (token=GetArg(RETURN)) { switch (Index(token,"left line right center even odd ")) { case ree(headodd); headodd=SCToS(ptr); } } else { if (where=='b' || where=='e') { SFree(footeven); footeven=S! ! 8`i^#Vr+sn& 8$ !9#*3ORU`ejoty~  269eak; } SFree(token); } ptr=MemGet(SLength(lhead)+SLength(chead)+SLength(rhead)+SLength(nhead)+ (3+1)); strcpyPUT@!Copyright (c) 1981 by Mark of the Unicorn Inc. TINTERRSTRCAU *\*"\+0: SFree(lhead); lhead=GetArg(RETURN); break; case 1: SFree(nhead); nhead=GetArg(RETURN); break; cCOPYRIGIAPPTOTICLEARBICONSINIFINɃIGETBUIIGETFILjIGETLINwIGETTO˄IGETTYPőIINCLUDŠIINIԪISETTYPINEXTCHCToS(ptr); } if (where=='b' || where=='o') { SFree(footodd); footodd=SCToS(ptr); } } MemFree(ptr); ret<CLOSTINTERR !9DM*P|!*P*l|r!{*l`is#r͐|r͐~#fo|]͐~#fo͐~#fo`is(ptr,SSToC(lhead)); strcat(ptr,"\203"); strcat(ptr,SSToC(chead)); strcat(ptr,"\222"); strcat(ptr,SSToC(rhead)); strcat/!>!"\!!^Input buffer overflow. $8!"\>2^TGETCHTBELTPUTNTPUTGase 2: SFree(rhead); rhead=GetArg(RETURN); break; case 3: SFree(chead); chead=GetArg(RETURN); break; ! INEXTTO IPOPBU IPUSHBUR IUNGEԫ IUSŸ DINIM DFINɎ DSETTYPŖ DREA~P#r:!9Exiting from include file or string. '*.ANZpSCTO!^ !X*V!Æ*V#"VÆÆ*6!9Current token overflow.#&.CFI`ejorz".15?TWn!͐z͐?n6n"R*T"T!9File read error.,;ITXhINEXTCHCLOSSEEREAMOVME#Vr+s**`>2͐!*9CONFIG.DATA:CONFIG.DATCan't find the configuration file, CONFIG.DAT header reco #5>ICLEARBISETTYPIINCLUD !9DM!">2>2[!F!!!B!!}! s#rzo!! !!!`i͐ !. n}ʠ!. n}p¯͐! s#r^!. n}c͐! s! *n&MEMGEMOVMESCOMPTOSTRCPICONSINPROCESSOPETERROSTRCAINEXTCHINEXTTO$q{~MOVME7*[&5!/!\![5n&/k0MOVMEICLEARB> *[&9!/!MEMFRETINTERR!9DM*o}0>2oÏ*Rn&on}2n}FK0*Rn}2!"*n}tA! ! rddevice descriptions Device '' not found, using default device descriptionDefault or console device not defined. spacing !! !A!z!a!A!Z!A!A!9!0{2{2o> 2y {2{2x({2ϔ{2{2({2{2({2{2#r^͐! s#r͐͐(!!͐!ϕ͐ !ϕ̓0|(! ^#Vr+s͐͐^!̓0!9DM*l+|I!"l!"V>2Xs!! s#r!͐!P͐"l!I͐ |™!N͐ [~4o&/k!\4:>2oMEMGEMOVMESTRCPINEXTTOl!9DM!`is#r!͐sÀ*l|*P|*P}Ҙ*P*l`is#r͐~#fo|͐~#fo`is#rá!͐~#fo͐~#fo !!n͐tableScribble parameters1&)04CJN]`dlp&69=GKOeh~"KYfSE>@2({2̔{2ʔ({2{2>2>2>2>2o!"l͐ 4FXj|G!9DM͐`is#r͐͐>͐o!͐! s#r͐|ʈ!!͐!ϕ͐ Ø!! *}!<!͐*蕯g?!P͐|!S!X !!n!}"Pn"R7͐`i !!a`i!`i"P|!f`i!i*R6@!{!!P͐"l͐"R͐!X !"V!"P !93PaDSETTYP0!9DM>2O͐! n&!~#fo *l`is#r!!P*l͐Æ*dA!!2"p*Rn&on*n}Yp*#"+*RnsEREATPUTEXI!9DM!͐͐|Q͐ ͐͐͐ r!t ͐ ! ! s`i^#Vr+s!9 <REATERRO !9DM*R#"R*P|*R!mҋ!!n*P`is#rz]!! !J!!! ͐ !_!p! **k ͉"! 6#6͐|M͐)p~#fo*ks#r! ^X `i!Xn"R!"T!"V!!9con:tty:console input.mss'.Can't open file 'file 3GNgt} n}2O!OPETPUTEXIDREASCCOMMOVMECLOS^!9DM*O}+i!!r! s#rzo Fatal: Unable to read from configuration file. &.@ORV_cgo *}*X*))*s#r**" &7LYPUBREAKLIEPO"NORMALELSTARTLPU` >2!"!"!l!!!Y*"["]"Y*"_>2d! he!9DM*|(*͐ `is#r*d}q*͐**͉q *1ڋ!!"*))!LNEWLINjLSTARTLɵLGETLINLPUTTOKŽLPUTWHI PINIԸ PFIN PFOOTNOL PFREt PNEWPAG0PNOFOOTΌPPUTIԴPPUTLINźPPUTVER`i~#fo͐n} ͣl͐n&u͐s#r5͐͐Ð!9 E[fjr}LSTARTLPPUTLIN, ! >2MOVME!!!!!"MOVME!!!ader+/MTBREAKTOLPUTWHI. *}!*"*+"BREAKTOLGETCOLPUTWHI  s#r*͐++++##~#fo|͐##~#fo|͐++++~#fo! *+"! ^#V{_zWr+s͐͐s#r͐#xOINI<OFIN1OPUTPAGzOPUTLINOCNTBR OPUTVERԉOPUTHOR_OPUGOPUT0OPUTCOsWPUWFLUS2 **}b'>l2 (B!"*]"*]"*_"*e}2*a"*}p͝}2*}b͝}2MEMGLNEWLIN*SFREMEMFRE !9DM͐ ͐~#fo+))`is#r͐͐ r!9DM*}*͉! s#r**͉! s#r͐͐͐͐*͉`is#r`i~#fo#͐ s#r*#"*͐! "͐ ! s#r͐n}ʦ! ^#Vr+sn}ʁʎʛʛã>2>p2ã>2>b2EMOVMELGETCOLSTARTL!9DM*|%!È*2?! s#r͐`is#r͐͐!͐##~#fo|_͐##~#fo`i^#V{_zWr+s-͐!9?N\pxWIDTE*>*+))##~#fo|͐*)s#r*))͐s#r*͐"! *"*+"!9 '`LGETCOBREAKTOBREAKLI]ìã>2ãQ!9Too many tokens for a single line#&27Gilo{~6FYmrw|LSTARTLLPUT@!Copyright (c) 1981 by Mark of the Unicorn Inc. !"!"{2{2LBREAKL ͐  s#r*["] ͐È!9#JbqLSTARTLLGETLENSSTOPPUTLINTINTERRWIDTCOPYRIGLINITLFINrLSTARTHŏLHDRCENLHDRRIG\LHDRLINeLENDHEALFOOTNO,LNOFOOT\LBREAKLɆLFREűLGETCORLGETLEN>*! C*&1<WIDTTABWIDT !9DM͐| !Ð! ^#Vr+s͐`is#r! ^#Vr+sn}GETCOTINTERR !9DM*|"*1?!u !"*))͐s#r*#"+))##w#w*͐*T+͐)͐#)~#fos#r͐)͐#)~#fos#r`i^#Vr+sï*T+"Y)"W*W͐s#r*T+)͐s#$'!"W*>2V!"W**|g}o|7*:*`is#r͐n!͐!$'>2V*P҇͐ `i^#Vr+sc*R*N *P`is#r͐d͐ `i^#Vr+sá*P}f*}! **!9DM*L+)`is#r͐!S͐~#fo|F͐~#fo`i^#Vr+s*P)`is#r͐!җ͐~#fo|ʊ͐~#f͐"Nà͐!!9 BEdSTRCPPROCESSCREATPUTEXI!9DM>2Q! n}"Too many tokens for a single line /26\*"*"*ߕ*Õ"**ŕ"!"L!"N!d"P*"R!dr*R͐"RÆ*L"Y)"W*W͐s#r*L#"L+)͐s#r*N͐"N!9Too many linesWarning: Footnote pag"T>2!"W*+"#Ҙ*!"! n}2V!9headerfooter!HQbeh /5FPSV !9Scribble intermediate output for: &.15=EMUpxOPUTVEROPUTHOROPUWIDTOCNTBRo`i^#Vr+sa!9 *7CQn{MIASPACOPUTPAGPFRETPUTPUTPPUTVERSLENGTLSTARTHIUSSSTOSCRIBBLLENDHEAPc5! n}pA! n}2PÑ>f2P͐`i! n}͝!`i`i "R|! !V"T!9.finUnable"T>2V!"W!"MIASPACOPUTPAGPFRETPUTTPUT**"*L= !e wrap not handled properly[^bf{EPPUTVERPPUTILGETLIN !9DM*͉`is#r*͐_dilLNOFOOT>2V!"WTINTERRPNEWPAGTERRO !9DM! ~#fo*͉s#r! OPUTSSTOOPUTCO!9DM͐)~#fo! s#r͐ |V͐)~#fov͐)~#fo*NEWPAG-!9DM*V! s>2V**"*Lj *###^#Vr+ to open output file. (3?O_fox{WPUWFLUSCLOS+ *P}f)!*R &OPUTO**!*!*͕* !*͕! Largest page used out of bytes. E<*`is#r*}U*}U͐*! s* ! n}ʆ*}ʆ͐!9 1BJRcgs{PPUTI~#fo͐*)s#r*P*Lh!*N͐*Rښ*V}ʗ!!! *V}G*P+"P`is#r͐͐ ##~#fo! 6 ͐ n}cʢrbÜ͐ ~#fo͐  ~#fo͉Ü͐ ~#fo͐  ~#fos"! *!"L"N!d"P"T*"R!"W**|g}o|**`is#r͐!͐!PUOPUTLINOPUTVER!9DM*Q}]*P}f]*}]!!ϕ! ! !>2Q`iw#w͐*Lnd space used out of bytes.$58;>BSW[cgkwLFOOTNO>2V!"W LFRE!9DM*W|ʒ*W~#fo|’*Y)~#fo`is#r͐͐Gà*N͐͐*RҒ*Y)͐s#r*N͐Ü*P}f|*}|͐  ~#fo͐ ~#foy! ͐ ~#fo͐  ~#fo`is#r͐ ͐|g} 6 *P}c`! n&`!! n&ú*P}p! n&ڍ!! n&ú*P}fº*}ʮ! n&ں*F]dOPU!9DM͐$͐|'è*P}fd*}d!͐͐|g}oè͐*! ?! n}«͐͐ҫ͐͐ ! n}͐͐ ͐͐! ! ^#Vr+so ! 6Ù! 6͐ ~#fo͐  ~#fo͐ ~#fo͐  ~#fo`is#r`iw#w͐! ! ! n&"+:JY^gwOPU2!9DM͐n}0! ^#Vr+sn&*.OPUk͉*͉`is#r͐|ʨ! ! `i^#Vr+sÃ!9"%.6=L^bOPUWIDT !9DM͐  ͐))~#fo! ^#Vr+sì͐  ͐ ~#fo+))##~#fo! s#rzJ͐*P}f[*}n! ! ͉! s#r͐ ! s#r͐ ! s#r͐?|g}o͐! s#r͐͐͐! s#r͐ ͐ͯ! !9DM͐n&`is#r͐n͐#nѯgW! s#r͐͐b`i^#Vr+sn&<!9J\`WFLUS2!'͐|*õ*P}fg*}g!͐͐|g}oõ! ! s#r͉͉͐͐͐`icc auxil.c -e8900 cc auxiltoo.c -e8900 cc commands.c -e8900 cc commtoo.c -e8900 l2 scribble auxil auxiltoo commands commtoo v!!9<?PTn}$+^pz'2O\eiu~:BGs! ~#fo͐s#r͐͐! s#rÜ! w#w! w#w͐͐ ~#fo+͐  ͐))##~#fo! s#r͐|͐9DM*T#"T+! ns*T!U0+.WRITTERRO !9DM*T!V"w*T!V`is#rs#r͐|ʵ! `i^#Vr+sØ!9%(19@OaelPUTWPU !9DM! n}3*}-*P}f3!input output -l alloc  character string that turns it on; otherwise,!WXof characters, and that you wish to use for text iQY`hlso!9DM͐~#fo+! s#r͐`is#r͐|_͐ ͐))##~#fo|S! ^#Vr+s`i^#Vr+s#͐f!9! n}*͐  ͐#))##~#fo|*! n& ! n}͐  ͐#))##~#fo|k͐#! ?Á͐!V*R͐p!!!V"T!9Output file write error. M\gkTALL 0x1A /* ^Z */ #define EXIT 0x3 /* ^C */ #define FLAG char #define MICA unsigned #define repeat while (1) * ^F */ #define BEL 0x7 /* ^G */ #define BS 0x8 /* ^H */ #define TAB 0x9 /* ^I */ #define LF 0xA /* ^J */ #defix */ #define JUSTIFY '\212' /* ~^J */ #define HORIZSPACE '\210' /* ~^H */ #define VERTSPACE '\226' /* ~^V */ #define */ #define UNANON '\316' /* ~N underscore alphanumeric */ #define UNANOFF '\356' /* ~n */ #define ITALON '\311' /* ~I i#define ENDLIST (-1) #define INPUT 0 #define ABSOLUTE 0 #define DEFAULT 0 /* Special command characters */ #dene FF 0xC /* ^L */ #define CR 0xD /* ^M */ #define SO 0xE /* ^N */ #define SI 0xF /* ^O */ #define DC1 0x11 /MAXMICA 48000 /* largest possible mica measurement */ /* Printing options */ FLAG pausep; /* pause for page changes? */* CRAYON.H Global declarations for CRAYON.C and drivers Copyright (C) 1981 by Mark of the Unicorn, Inc. Created 81.3.12 talics */ #define ITALOFF '\351' /* ~i */ #define BITALON '\320' /* ~P bold italics */ #define BITALOFF '\360' /* ~p */ #fine SENTENCEBREAK '\177' /* ^? */ #define TOKENBREAK '\240' /* ~ */ #define BOLDON '\302' /* ~B */ #define BOLDOFF '\* ^Q */ #define DC3 0x13 /* ^S */ #define ESC 0x1B /* ESC */ #define RS 0x1E /* ^^ */ #define US 0x1F /* ^_ */ / FLAG quietp; /* turns off user interaction */ int startpage, /* page to start printing on */ curpage; /* cuGyro This file contains the global declarations for the Scribble printer driver. */ #define TRUE (-1) #define FALdefine SUPERON '\323' /* ~S superscripts */ #define SUPEROFF '\363' /* ~s */ #define SUBON '\324' /* ~T subscripts (why no342' /* ~b */ #define ROMANON '\322' /* ~R */ #define ROMANOFF '\362' /* ~r */ #define UNNBON '\325' /* ~U underscore tok#define DEL 0x7F /* DEL */ #define EOF 0x1A /* CP/M end of text marker */ #define ABORTFILE 0x7 /* ^G */ #define ABORrrent page */ /* For communication with driver */ #define BOLD 'B' #define UNDERSCORE 'U' #define ITALIC 'I' #defiSE 0 #define NULL 0 #define ERROR (-1) #define NUL 0x0 /* ^@ */ #define ETX 0x3 /* ^C */ #define ACK 0x6 /t?) */ #define SUBOFF '\364' /* ~t */ #define EXITON '\330' /* ~X eXit unusual attributes */ #define EXITOFF '\370' /* ~ens */ #define UNNBOFF '\365' /* ~u */ #define UNALLON '\301' /* ~A underscore everything */ #define UNALLOFF '\341' /* ~ane HORIZONTAL 'H' #define VERTICAL 'V' #define OVP 'O' #define BIDIREC 'D' #define CENTCHAR 'C' /* Input line bufACKWARD (-1) FLAG warned; /* you have been warned */ /* Underline map */ struct { int ulon, uloff; } ulmap[128]; /* .. two columns right */ #define BUFBLKS 64 /* 4K input buffer */ struct fbuf { char fname[20]; int fchan, fnleprinter type of the console */ /* Character width tables */ int fmicro; /* the first micro-spacing table record */ int int inchars, intokens; FLAG forcetok; /* force new token on next char? */ FLAG superp, subp; /* super- or sub-script? le output port */ int prtinp; /* Printer input(??) port */ int prtoutp; /* printer output port */ int modinp; /* modfer */ #define ILINEMAX 256 /* chars in input line buffer */ #define ITOKENMAX 128 /* tokens in input line */ char iline[ int nuls; FLAG ulonp; FLAG boldp, italicp, ulitalp; /* Output line buffer */ struct { char ochar; int ohpos; FLAG ft; char *fnextp, fbuff[BUFBLKS][128]; } inputbuf; char *title, *portname; /**************** Printer globals ***** maxmicro; /* the number of micro spacing records */ /* Character translation tables */ int ftran; /* the first transl*/ #define ATTRMAX 16 /* max depth of attribute stack */ struct token attrstack[ATTRMAX]; int attrsp; /* stack pointeem input port */ int modoutp; /* modem output port */ /* Terminal type descriptions */ int fterm; /* first terminal ILINEMAX]; struct token { int tokbegin; /* index in line */ int tokwidth; /* width of token */ int toklead; /* lobold, oital; } outline[200]; int olen; /**************** Device globals ****************/ int datfd; /* CONFIG.DA***********/ int phpos, pvpos; /* current position */ int pageh, pagev; /* page size */ int charh, linev; /* std cation record */ /* The size of the data file */ int hmax; /* number of records including header */ int cpuspeed; r */ struct justdesc { int jlefttok; /* token on which justification begins */ int jspace; /* amount of whitespacerecord */ int ourterm; /* the default terminal type */ int simterm; /* terminal type to simulate */ /* Printer descreading whitespace */ char tokscript; /* normal, super, or sub */ char tokuscore; /* underscored? */ FLAG tokbold; /T header and data records */ #define PORT 2 #define MICRO 3 #define PRINT 4 struct header { /* Input/output poharacter cell */ int spaceh; /* width of ' ' */ FLAG hackdone; /* paper hack done? */ #define FORWARD 1 #define B/* cpu speed in 100KHz */ } hdr; #define SSPACE 128-54 struct printdesc { /* describes the output device */ char dnam to add */ int jnbrk; /* number of token breaks */ } just; /* this will have to be a list to get .. */ FLAG justp; iptions */ int fprint; /* first printer record */ int ourprint; /* the default printer type */ int conprint; /* the * boldface? */ FLAG tokital; /* italic? */ char tokjust; /* justify on left of this token? */ } itokens[ITOKENMAX]; rt descriptions */ int fport; /* the first port record */ int coninp; /* console input port */ int conoutp; /* consoe[16]; /* name of the device */ MICA dwidth; /* width of the printing surface */ MICA dheight; /* height of the print sine VANILLA 1 /* no microspacing, standard controls */ #define DIABLO 2 /* 1620 & anything compatible */ #define EPSON p after */ donewline, /* ... do a newline */ boldon, /* ... turn on boldface */ boldoff, /* turn off boldface *Synchronization control */ #define NOSYNC 1 #define ETX_ACK 2 #define XON_XOFF 3 #define SYNCBUFSIZE 60 #define SEQSTART 0d to start at */ FLAG backspace; /* Does backspace work */ FLAG barecr; /* does bare CR work */ FLAG formfeed; /* doeataport; /* Data port, or bios call number */ char datamask; /* Mask to AND data with */ FLAG sbiosp; /* Use the bios urface */ MICA micahoriz; /* size of smallest horizontal increment */ MICA micavert; /* size of smallest vertical increme3 /* MX-80 (microvert) */ #define IDS460 4 /* IDS 460 proportional */ #define SPINWRITER 5 /* Spinwriter & friends */ #/ italon, /* turn on italics */ italoff; /* turn off italics */ char strspc[SSPACE]; /* where strings are stored *x100 #define SEQEND (SEQSTART + 0x20) FLAG syncok; /* for XON/XOFF: OK to send character? */ int synccnt; /* for Es form feed work */ char synctype; /* Type of waiting to do: NONE, ETX/ACK, ^S^Q */ FLAG needtran; /* Do character transcall numbered by the status port if non-zero */ char statport; /* Status port, or bios cnt */ FLAG isprop; /* does it have a proportional width font? */ char fontnum; /* if isprop, which width table to use */define CUSTOM 6 /* user custom subroutines */ #define QUME 7 /* Qume & friends */ #define CEN737 8 /* Centronics 737 / } dev; MICA widtab[128]; /* Character width table */ char trantbl[128]; /* Character translation table */ chaTX/ACK: no of chars sent so far */ int syncnbufs; /* for ETX/ACK: no of buffers sent */ /**************** Globals for lation on output? */ char trannum; /* Translation table number */ struct str { /* Various strings to send */ char idxall number */ char readymask; /* Mask to AND status with */ char polarity; /* (Status AND mask == ) if ready */ } MICA stdhoriz; /* width of a canonical character */ MICA stdvert; /* height of a single spaced line */ FLAG isfile; */ /**************** Output globals ****************/ struct portdesc { char pname[16]; /* Zero terminated port namr tsect[128]; int dhpos, dvpos; int dbold, dital; #define NOCHAR (-1) int dbufchar; /* Control code types */ #defprinter drivers ****************/ #define UNINITIALIZED 0x8000 int drvhpos, drvvpos; /* current horizontal, vertical pos; /* index into space */ char len; /* length */ } initstr, /* ... set things up */ finistr, /* ... clean u iport, oport; /* Output queue */ #define QUEUE_SIZE 192 /* Size of output queue */ int oqueue [QUEUE_SIZE + 4]; /* /* do plain file output? */ char prtcode; /* printer type code for crayon */ MICA paperoffset; /* height paper is assumee */ FLAG dbiosp; /* Use the bios call numbered by the data port if non-zero */ char dition */ int drvhpitch, drvvpitch; /* current pitch of printer */ int drvdirec; /* current print direction */ FLAGe = 1; for (iarg = 1; iarg < argc; ++iarg) { if (*argv[iarg] == '-') { optname = argv[iarg] + 1; if (isdigit (*optns code interprets the command line and the Scribble output file, and calls the low-level abstraction to do the printing. */ break; } Fatal (fmt, a1, a2, a3, a4, a5) /* lose, lose */ char *fmt; int a1, a2, a3, a4, a5; { printf (fmt, a1, a2optname, "Quiet")) quietp = TRUE; else if (match (optname, "Title") || match (optname, "T")) { title = argv[+ drvshiftp; /* is printer shifted? */ /* End of CRAYON.H -- globals for Scribble print program */ us port, or bios came)) ntimes = atoi (optname); else if (match (optname, "Page")) { startpage = atoi (argv[++iarg]); if (!quietp) p #include "crayon.h" main (argc, argv) int argc; char **argv; { int ntimes, itime, iarg; char *optname; struct, a3, a4, a5); exit (1); } PrintFile (fname, ntimes) char *fname; int ntimes; { char devname[80], i, c, tfname[2+iarg]; if (!quietp) printf ("Title string is '%s'.\n", title); } else printf ("Unknown command line option: '%s'\rintf ("Starting at page %d.\n", startpage); } else if (match (optname, "Pause")) { pausep = TRUE; puts ("Pau { char *fname; int fntimes; } files[20]; int nfiles; puts ("Crayon Version 1.3, Copyright (C) 1981 by Mark of t0]; FLAG done; strcpy (&tfname, fname); dfltext (&tfname, "FIN"); if (IOpen (&tfname, INPUT) < 0) { printf ("Can'tn", argv[iarg]); } else { files[nfiles].fname = argv[iarg]; files[nfiles].fntimes = ntimes; ++nfilessing for manual insertion of each page.\n"); } else if (match (optname, "Port")) { portname = argv[++iarg]; ihe Unicorn Inc.\n"); ntimes = 1; nfiles = 0; pausep = FALSE; title = ""; portname = NULL; quietp = FALSE; startpag open input file '%s'.\n", &tfname); return; } for (i = 32; i; --i) INext(); if (IChar() != ':') Fatal ("I only un/* CRAYON.C Top level of Scribble print driver Copyright (C) 1981 by Mark of the Unicorn Inc. Created 81.3.12 Gyro Thi; } } for (iarg = 0; iarg < nfiles; ++iarg) if (PrintFile (files[iarg].fname, files[iarg].fntimes) == ABORTALL) f (!quietp) printf ("Using the '%s' port(s).\n", portname); } else if (match (optname, "Q") || match (derstand Scribble intermediate output files."); INext(); for (i=0; INext() != EOF; ++i) devname[i] = IChar(); devname[i-2] input line */ { if (ReadLine()) { PrintLine(); return (TRUE); } return (FALSE); } ReadLine () /* read t inch; inch = PUnMica (2540, HORIZONTAL); PMoveH (inch); PPrtStr (IName ()); PMoveH (inch / 2); PPrtStr (title); ase BOLDON: attrtok = AttrPush(); attrtok->tokbold = TRUE; ForceTok(); break; case ROMANON: attrtok = AttAttrInit(); while (!done && DoLine()) if (TKbRdy()) switch (c = TGetKb()) { case ABORTFILE: puts ("Aborti(curpage >= startpage) PMoveV (tdist); break; default: done = TRUE; break; } if (!done) INext(); } do = NUL; INext(); if (!quietp) { if (ntimes == 1) printf ("Printing '%s' on device '%s' -- OK? ", &tfname, &dehe line and build data structure */ { FLAG done; FLAG sbrkprev; /* was previous char a SENTENCEBREAK? */ char inchar, PCR(); PMoveV (PLineV()); PMoveH (inch * 2); PPrtStr ("Crayon version 1.2"); /* vsn of this prog. */ PCR(); } NexrPush(); attrtok->tokbold = FALSE; attrtok->tokital = FALSE; ForceTok(); break; case UNNBON: case UNALLON:ng this file.\n"); done = c; break; case ABORTALL: puts ("Aborting all files.\n"); done = c; break;ne = sbrkprev = FALSE; repeat { PSendChk(); inchar = IChar(); switch (inchar) { case CR: INext(); case vname); else printf ("Printing %d copies of '%s' on device '%s' -- OK? ", ntimes, &tfname, &devname); if (!Ask (""brklevel, IChar(); struct token *temptok, *attrtok; int tdist; inchars = intokens = 0; superp = subp = FALSE; justptPage() /* process page boundary */ { ++curpage; if (curpage < startpage && !quietp) printf (" [%d]", curpage); else case UNANON: attrtok = AttrPush(); attrtok->tokuscore = inchar; ForceTok(); break; case ITALON: attrt case EXIT: exit (1); default: break; } IRew(); while (INext() != EOF); /* skip file header */ LF: case FF: done = TRUE; break; case EOF: return (FALSE); break; case VERTSPACE: done = TRUE; )) { puts (" -- skipping file.\n\n"); return (ABORTFILE); } } PInit (&devname, portname, !pausep); if (PVPos( = FALSE; ForceTok(); done = FALSE; while (!done) { PSendChk(); switch (IChar()) { case LF: if (curpage > { if (!quietp) printf (" %d", curpage); PNewPage(); if (pausep) PagePause(); } } DoLine() /* process anok = AttrPush(); attrtok->tokital = TRUE; ForceTok(); break; case BITALON: attrtok = AttrPush(); attrtok- INext(); PNewPage(); } PFini(); IClose (); return (done); } FileHeader() /* print file header */ { intbreak; case HORIZSPACE: ForceTok(); temptok = GetTok(); temptok->toklead += GetDist (HORIZONTAL); break; c) != 0) { FileHeader(); PFF(); } done = FALSE; while (ntimes-- > 0 && !done) { curpage = 0; NextPage(); = startpage) PLF(); break; case FF: NextPage(); break; case VERTSPACE: tdist = GetDist (VERTICAL); if >tokbold = TRUE; attrtok->tokital = TRUE; ForceTok(); break; case SUPERON: superp = TRUE; attrtok = AttrPs], sizeof(attrstack[0])); itokens[intokens].tokbegin = inchars; itokens[intokens].tokwidth = 0; itokens[intokenk; default: temptok = GetTok(); iline[inchars++] = inchar; temptok->tokwidth += PWidChar (inchar); break; sert fresh page; type any character when ready --> "); getchar(); putchar ('\n'); } PrintLine() /* output the accu case UNNBOFF: case ROMANOFF: case BOLDOFF: case EXITOFF: AttrPop(); ForceTok(); break; case JUSTIFY: rstack[0].tokital = attrstack[0].tokjust = FALSE; } AttrPush() /* push attribute stack */ { if (attrsp >= ATTush(); attrtok->tokscript = inchar; ForceTok(); break; case SUBON: subp = TRUE; attrtok = AttrPush(); s].toklead = 0; ++intokens; forcetok = FALSE; } return (&itokens[intokens-1]); } GetDist (direc) /* get a di } if (done) break; sbrkprev = inchar == SENTENCEBREAK; INext(); } if (sbrkprev && justp) just.jspace += PWidSenmulated line */ { int tvert; if (curpage < startpage) return; if (justp) JustLine(); tvert = max (1, PLineV() / 2); justp = TRUE; just.jlefttok = intokens; just.jspace = GetDist (HORIZONTAL); just.jnbrk = 0; break; case TRMAX) Fatal ("Character attributes nested too deeply.\n"); else { movmem (&attrstack[attrsp], &attrstack[attrsp+1], attrtok->tokscript = inchar; ForceTok(); break; case EXITON: attrtok = AttrPush(); attrtok->tokscript = FALSstance from the input stream */ int direc; { unsigned tdist; tdist = (INext() << 8) + INext(); if (tdist > MAXMICA) t(); itokens[intokens].tokbegin = inchars; return (TRUE); } ForceTok() /* break current token */ { forcetok = T if (superp) { PMoveV (-tvert); PrintScript (SUPERON); PCR(); PMoveV (tvert); } PrintScript (FALSE); PCR(); OKENBREAK: ForceTok(); temptok = GetTok(); temptok->tokjust = TRUE; temptok->toklead += PWidChar (' '); ++ju sizeof(attrstack[0])); ++attrsp; } return (&attrstack[attrsp]); } AttrPop() { if (attrsp <= 0) Fatal ("AttrE; attrtok->tokuscore = FALSE; attrtok->tokbold = FALSE; attrtok->tokital = FALSE; attrtok->tokjust = FALSE; Fatal ("Invalid mica value in intermediate file.\n"); return (PUnMica (tdist, direc)); } AttrInit() /* initializeRUE; } GetTok() /* make a new token if needed */ { if (forcetok) { movmem (&attrstack[attrsp], &itokens[intoken if (subp) { PMoveV (tvert); PrintScript (SUBON); PCR(); PMoveV (-tvert); } } PrintScript (script) /* prst.jnbrk; break; case SENTENCEBREAK: ForceTok(); temptok = GetTok(); temptok->toklead += PWidSent(); breaPop: stack underflow\n"); --attrsp; } PagePause() /* pause, get fresh page from user */ { PForce(); puts ("\nIn ForceTok(); break; case SUBOFF: case SUPEROFF: case BITALOFF: case ITALOFF: case UNANOFF: case UNALLOFF: the attribute stack */ { attrsp = 0; attrstack[0].tokscript = attrstack[0].tokuscore = attrstack[0].tokbold = attint all of super, normal, or subscripts */ char script; { int thmove, itok; thmove = 0; for (itok=0; itok < intokensdChk(); } /* Buffered file input routines */ IOpen (name, mode) /* open file in */ char *name; int((just.jspace * 17) & 0x7FFF) % njust; /* random num */ oddcnt = totspace % njust; PSendChk(); for (itok = just.jlefttok; buf = &inputbuf; if (!buf || !buf->fchan) return; seek (buf->fchan, 0, ABSOLUTE); buf->fnleft = 0; INext (buf); tr (UNDERSCORE, itokens[itok].tokuscore); PSetAttr (BOLD, itokens[itok].tokbold); PSetAttr (ITALIC, itokens[itok].tokital); utbuf; if (!buf->fchan) return (ERROR); ++(buf->fnextp); if (--(buf->fnleft) <= 0) { nread = read (buf->fchan, &buf->fb; ++itok) { if (itokens[itok].tokscript == script) { PMoveH (thmove); PrintTok (itok, script); PSendChk(); th mode; { int tfd; struct fbuf *buf; buf = &inputbuf; /* someday this might allocate */ tfd = open (name, mode); itok < intokens; ++itok) if (itokens[itok].tokjust) itokens[itok].toklead += evenspace; PSendChk(); for (itok = just.jl} IClose() /* close the file */ { struct fbuf *buf; buf = &inputbuf; if (!buf || !buf->fchan) return (ERROR for (ichar = itokens[itok].tokbegin; ichar < itokens[itok+1].tokbegin; ++ichar) PPrtChar (iline[ichar]); PSetAuff, BUFBLKS); if (nread < 0) { IClose(); return (ERROR); } buf->fnleft = nread * 128; buf->fnextp = &buf->move = 0; } else thmove += itokens[itok].tokwidth + itokens[itok].toklead; } } PrintTok (itok, script) /* prinif (tfd < 0) return (ERROR); buf->fchan = tfd; strcpy (&buf->fname, name); buf->fnleft = 0; INext (buf); return (buf);efttok; oddstart > 0; ++itok) if (itokens[itok].tokjust) --oddstart; PSendChk(); for (; oddcnt > 0; ++itok) { if (itok); close (buf->fchan); buf->fchan = NULL; } match (s1, s2) /* case-independent string equality */ char *s1, *s2;ttr (UNDERSCORE, FALSE); } JustLine() /* justify the line */ { int totspace, njust; int itok, evenspace, oddstartfbuff; } return (*(buf->fnextp)); } IName() /* return file name */ { struct fbuf *buf; buf = &inputbuf; t a token */ int itok; char script; { int ichar; if (itok != 0 && !script && itokens[itok-1].tokuscore == UN } IChar() /* return current char */ { struct fbuf *buf; buf = &inputbuf; if (!buf->fchan) return (ERROR); >= intokens) itok = just.jlefttok; if (itokens[itok].tokjust) { --oddcnt; ++itokens[itok].toklead; } } PSen { while (TRUE) { if (toupper (*s1) != toupper (*s2)) return (FALSE); if (!*s1++ || !*s2++) return (TRUE); } } , oddcnt; totspace = just.jspace; njust = just.jnbrk; if (!njust) return; evenspace = totspace / njust; oddstart = if (!buf || !buf->fchan) return (""); return (&buf->fname); } IRew() /* rewind file */ { struct fbuf *buf; ALLON && itokens[itok].tokuscore == UNALLON) PSetAttr (UNDERSCORE, UNALLON); PMoveH (itokens[itok].toklead); PSetAt return (*(buf->fnextp)); } INext() /* get next char & return */ { struct fbuf *buf; int nread; buf = &inp Ask (q) /* ask a yes/no question */ char *q; { puts (q); repeat { switch (toupper (TGetKb())) { case ' ':olen = 0; warned = FALSE; } PFini() /* turn things off */ { PCR(); PNewPage(); if (hackdone) PMoveV (PUnMicao This code implements a generalized printer abstraction for use by Crayon or Pencil. */ #include "crayon.h" FLA(c >= ' ' && c <= '~') return (DWidChar (c)); else if (c & 0x80) return (1 + PWidChar (c & 0x7F)); else return (1 + PWi of CRAYON.C -- Scribble print driver top level */ uf *buf; buf = &inputbuf; if (!buf || !buf->fchan) return (ERROR if (c != ' ') { outline[olen].ochar = c; outline[olen].ohpos = phpos; outline[olen].obold = boldp; outline[o case 'Y': puts ("Yes\n"); return (TRUE); case DEL: case BS: case BEL: case 'N': puts ("No\n"); r (dev.paperoffset, VERTICAL)); PForce(); DFini(); } PPrtChar (c) /* print a character */ char c; { FLAG ulreaG PInit (device, portname, hackp) /* initialize printer */ char *device, *portname; FLAG hackp; /* do paper hack? */ { dChar (c ^ 0x40)); } PPrtStr (s) /* print a NUL-term string */ char *s; { while (*s) PPrtChar (*s++); } PWlen].oital = italicp && !ulitalp; ++olen; } phpos += PWidChar (c); } else if (c & 0x80) { PPrtChar ('~'); /*eturn (FALSE); default: puts ("\nAnswer 'Y' or 'N' --> "); break; } } } dfltext (fn, ext) /* default lly; if ((ulonp || italicp) && (ulonp == UNALLON || ((ulonp == UNNBON || (italicp && ulitalp)) && c != DInit (device, portname, hackp); phpos = 0; if (hackp) pvpos = PUnMica (dev.paperoffset, VERTICAL); else pvpos = 0; haidStr (s) /* width of string */ char *s; { int wid; for (wid = 0; *s; ++s) wid += PWidChar (*s); return (wid); not supporting full meta convention */ PPrtChar (c & 0x7F); } else { PPrtChar ('^'); PPrtChar (c ^ 0x40); } fn's extension to ext */ char *fn, *ext; { while (*fn) if (*fn++ == '.') return; *fn++ = '.'; strcpy (fn, ext); } ' ') || (ulonp == UNANON && (isalpha (c) || isdigit (c))))) { ulreally = TRUE; /* underscore italics for now */ ckdone = hackp; ulonp = FALSE; nuls = 0; ulmap[0].uloff = -1; boldp = italicp = FALSE; ulitalp = !DrvInfo (ITALIC); } PWidSent() /* width of end-of-sentence */ { return (DWidChar (DEL)); } PMoveH (dh) /* create horizontal w/* PRINTER.C Printer abstraction and support routines Copyright (C) 1981 by Mark of the Unicorn, Inc. Created 81.3.18 Gyrif (ulreally) ulmap[nuls].uloff = phpos; PSendChk(); } PWidChar (c) /* width of c when printed */ char c; { if /* "Terminal abstraction" */ TKbRdy() { return (bios (2)); } TGetKb() { return (bios (3)); } /* End if (phpos != ulmap[nuls].uloff) ulmap[++nuls].ulon = phpos; } else ulreally = FALSE; if (c >= ' ' && c <= '~') {hitespace */ int dh; { if (ulonp == UNALLON && ulmap[nuls].uloff != phpos) ulmap[++nuls].ulon = phpos; phpos += dh; D: if (dev.boldon.len || DrvInfo (OVP)) boldp = state; else PWarnOnce(); break; case ITALIC: if (dev.italon.len )) >> 5; return (temp); } if (direc == HORIZONTAL) tstd = dev.micahoriz; else if (direc == VERTICAL) tstd = dev.micaverned) return; puts ("This device, as currently defined, cannot overprint.\n"); warned = TRUE; } PFlush() /* outputemp >> 7; /* mica * 6 / 127 */ temp = (temp + (temp & 8)) >> 4; return (temp); } if (dev.micavert == 53 && dire where are we? */ { return (pvpos % pagev); } PCharH() /* width of canonical char */ { return (charh); } if (ulonp == UNALLON) ulmap[nuls].uloff = phpos; } PMoveV (dv) /* vertical move */ int dv; { PFlush(); pvpos || DrvInfo (OVP)) italicp = state; else PWarnOnce(); break; default: Fatal ("PSetAttr: unknown attribute\n"); brrt; else Fatal ("PUnMica: bad direc?"); if (mica > 32767) temp = mica / (tstd >> 1); else temp = (mica << 1) / tstd; rett line, with underline and bold */ { int iul, i, starti, uswidth, direc; if (!olen) return; DSetV (pvpos); pvpos %= c == VERTICAL) { temp = mica + (mica >> 2) /* 1/48 in */ - (mica >> 5) /* mica * 12 / 635 */ - (mica >> 7) PLineV() /* height of line */ { return (linev); } PPageH() /* width of page */ { return (pageh); } += dv; } PForce() /* actually get the carriage there */ { PFlush(); DSetH (phpos); DSetV (pvpos); pvpos %= peak; } } PCR() /* do carriage return */ { PFlush(); phpos = 0; } PLF() /* do a line feed */ { Purn ((temp >> 1) + (temp & 1)); } PSetAttr (attr, state) /* turn on or off a character attribute */ char attr; FLAG pagev; direc = PPickDirec (outline[0].ohpos, outline[olen-1].ohpos); starti = (direc == FORWARD) ? 0 : olen - 1; for (i = - (mica >> 9); temp = (temp + (temp & 32)) >> 6; return (temp); } if (dev.micavert == 35 && direc == VERTICAL)PPageV() /* height of page */ { return (pagev); } PSendChk() /* maybe send output character */ { if (OStKnowagev; DForce(); } int PUnMica (mica, direc) /* convert mica to internal units */ unsigned mica, direc; { unsigneMoveV (linev); } PFF() /* do a form feed */ { PMoveV (pagev - (pvpos % pagev)); } PNewPage() /* FF if nostate; { switch (attr) { case UNDERSCORE: if (DrvInfo (OVP)) ulonp = state; else PWarnOnce(); break; case BOLstarti; i >= 0 && i < olen; i += direc) { DSetH (outline[i].ohpos); DSetAttr (BOLD, outline[i].obold); DSetAttr (ITAL { temp = mica - (mica >> 4) /* 1/72 in. (Epson) */ - (mica >> 5) + (mica >> 10); temp = (temp + (temp & 16n()) OSendChk(); } /******** Internal calls ********/ PWarnOnce() /* warn user about losing device */ { if (wad tstd, temp; if (dev.micahoriz == 21 && direc == HORIZONTAL) { temp = mica - (mica >> 2); /* 1/120 in */ temp += t at TOF */ { if (pvpos % pagev) PFF(); } PHPos() /* where are we? */ { return (phpos); } PVPos() /*IC, outline[i].oital); DPrtChar (outline[i].ochar); if (outline[i].obold && !DrvInfo (BOLD) && DrvInfo (CENTCHAR)) { ; DPrtChar ('_'); if (direc == FORWARD) { if (ulpos >= ulend) break; ulpos += min (uswidth, ulend - ulpos); } } PUnderScr() /* do underscores for the current line */ { int i, starti, uswidth, ulstart, ulend, ulpos, direc; v.needtran) { ReadRec (hdr.ftran + dev.trannum); movmem (&tsect, &trantbl, 128); } OInit (portname); close (datfd);d via reprint */ { int bstart, bend, starti, i, direc; for (bstart = 0; bstart < olen; ++bstart) if (outline[bstart]."); movmem (&tsect, &hdr, sizeof(hdr)); if (device == DEFAULT) DfltPrt(); else if (!FindRec (PRINT, device)) { printf ( DMoveH (direc); /* bold with small offset */ DPrtChar (outline[i].ochar); } PSendChk(); } if (!DrvInfo (BOLD } else { if (ulpos <= ulstart) break; ulpos -= min (uswidth, ulpos - ulstart); } PSendChk(); } direc = PPickDirec (ulmap[1].ulon, ulmap[nuls].uloff); starti = (direc == FORWARD) ? 1 : nuls; uswidth = DWidChar ('_') charh = PUnMica (dev.stdhoriz, HORIZONTAL); linev = PUnMica (dev.stdvert, VERTICAL); pageh = PUnMica (dev.dwidth, HORIZONobold) break; if (bstart >= olen) return; for (bend = olen; !outline[bend-1].obold; --bend); direc = PPickDirec (outline[b"Can't find device '%s'; using default.\n", device); DfltPrt(); } movmem (&tsect, &dev, sizeof (dev)); if (dev.isprop)) && !DrvInfo (CENTCHAR)) PReBold(); PUnderScr(); olen = nuls = 0; } int PPickDirec (leftend, rightend) /* pick op} nuls = 0; } /**************** Generalized Device driver code ****************/ DInit (device, portname, hackp) ; for (i = starti; i >= 1 && i <= nuls; i += direc) { ulstart = ulmap[i].ulon; ulend = ulmap[i].uloff - uswidth; ulTAL); pagev = PUnMica (dev.dheight, VERTICAL); spaceh = DWidChar (' '); if (hackp) dvpos = PUnMica (dev.paperoffset, VERTIstart].ohpos, outline[bend-1].ohpos); starti = (direc == FORWARD) ? bstart : bend - 1; for (i = starti; i >= bstart && i < sizeof(attrstack[0])); ++attrsp; } return (&attrstack[attrsp]); } AttrPop() { if (attrsp <= 0) Fatal ("Attrtimal direction */ int leftend, rightend; { if (DrvInfo (BIDIREC) && abs (DHPos() - rightend) < abs (DHPos() - lefte char *device, *portname; FLAG hackp; { int i; if (((datfd = open ("config.dat", INPUT)) < 0 && (datfd = open ("pos = (direc == FORWARD) ? ulstart : ulend; if (ulstart > ulend) ulpos = (ulstart + ulend) / 2; repeat { DSetH (ulpos)CAL); else dvpos = 0; dhpos = 0; DrvInit (dvpos); dbufchar = NOCHAR; } DFini() { DForce(); DrvFini(); OFin bend; i += direc) if (outline[i].obold) { DSetH (outline[i].ohpos); DPrtChar (outline[i].ochar); PSendChk(); movmem (&tsect, &widtab[64], 128); for (i = 0; i < 128; ++i) widtab[i] = PUnMica (widtab[i], HORIZONTAL); } if (dend)) return (BACKWARD); /* nb: that's -1 */ else return (FORWARD); /* and that's +1 */ } PReBold() /* bola:config.dat", INPUT)) < 0) || read (datfd, &tsect, 1) < 1) Fatal ("Can't open the system database file (CONFIG.DAT)\ni(); } DSetH (hpos) /* move to hpos (absolute) */ int hpos; { dhpos = hpos; } DSetV (vpos) /* move to ortname; { char tport[20]; if (portname != DEFAULT) { if (!FindRec (PORT, portname)) { sprintf (&tport, "%s Out",val ? &dev.boldon : &dev.boldoff); } dbold = val; break; case ITALIC: if (dital != val && dev.italon.len) { &oqueue); } OPutNum (n) /* send a number in ASCII */ int n; { if (n >= 10) OPutNum (n / 10); OPutChar (n % 10 a character */ char c; { int offset; offset = DrvInfo (CENTCHAR) ? DWidChar (c) / 2 : 0; DMoveH (offset); DFlush( (hdr.prtinp); else Fatal ("No default input port defined (one is required for synchronization).\n"); movmem (&tsect, &ipovpos (absolute) */ int vpos; { DMoveV (vpos - (dvpos % pagev)); } DMoveH (delh) /* move by delh (relative) */ i portname); if (!FindRec (PORT, &tport)) Fatal ("Can't find port '%s' or '%s'.", portname, &tport); } } else DFlush(); OPutCmd (val ? &dev.italon : &dev.italoff); } dital = val; break; } } DForce() { DFlush();+ '0'); } OPutCmd (cmd) /* output a control string */ struct str *cmd; { char *chr, *endchr; int i; chr = &); DMoveH (-offset); dbufchar = dev.needtran ? trantbl[c] : c; } int DWidChar (c) /* width of c when printed */ rt, sizeof (iport)); } IQInit (&oqueue, QUEUE_SIZE); syncok = TRUE; synccnt = 0; syncnbufs = 0; } OFini() { nt delh; { dhpos += delh; } DMoveV (delv) /* move by delv (relative) */ int delv; { if (delv < 0) Fatal ("DMovif (hdr.prtoutp) ReadRec (hdr.prtoutp); else Fatal ("No default output port defined!\n"); movmem (&tsect, &oport, sizeof (op OFlush(); } DFlush() /* flush buffer */ { DrvPrtMove (dbufchar, dhpos, dvpos); dvpos %= pagev; dbufchar = Ndev.strspc[cmd->idx]; endchr = &dev.strspc[cmd->idx + cmd->len]; OUnInter (cmd->len); while (chr < endchr) OPutChar (*chr+ char c; { return (dev.isprop ? widtab[c] : charh); } DSetAttr (attr, val) /* set innate attribute if possible */ i OFlush(); } OFlush() /* flush output buffer */ { while (!IQEmpty (&oqueue)) OSendChk(); } OPutChar (c) eV: can't move up!\n"); dvpos += delv; } int DHPos() /* return current horizontal location */ { return (dhpos);ort)); if (dev.synctype != NOSYNC) { if (portname != DEFAULT) { sprintf (&tport, "%s In", portname); if (!FindRec (OCHAR; } /**************** Output queue maintainer and port drivers ****************/ OInit (portname) char *p+); } OPutSeq (list) /* send an uninterruptible sequence */ int list; { int *argptr, nargs; argptr = &list; nt attr; FLAG val; { switch (attr) { case BOLD: if (dbold != val && dev.boldon.len) { DFlush(); OPutCmd (/* output a character */ char c; { while (IQFull (&oqueue)) OSendChk(); OSendChk(); /* at least once */ IQShove (c, } int DVPos() /* return current vertical location */ { return (dvpos % pagev); } DPrtChar (c) /* printPORT, &tport)) Fatal ("Can't find port '%s', required for synchronization.", &tport); } else if (hdr.prtinp) ReadRec for (nargs = 0; *argptr++ != ENDLIST; ++nargs); OUnInter (nargs); argptr = &list; while (nargs--) OPutChar (*argptr++); ; return (((iport.sbiosp ? bios (iport.statport) : inp (iport.statport)) & iport.readymask) == iport.polarity); } ++syncnbufs; synccnt = 0; } if (PIRdy() && PIGet() == ACK && syncnbufs > 0) --syncnbufs; return (syncnbufs < lrec; ++frec) { ReadRec (frec); if (match (name, &tsect)) return (TRUE); } return (FALSE); } ReadRec (rec) output status known? */ { return (!(oport.sbiosp && !oport.statport)); } FLAG OReady (c) /* ready for this char, c); else outp (oport.dataport, c); } /******** Utility routines for reading database ********/ FLAG FindRec ( } OUnInter (seqlen) /* guarantee nchars uninterrupted */ int seqlen; { if (seqlen < 0 || seqlen >= 32) Fatal (" char PIGet() /* get char from printer */ { return ((iport.dbiosp ? bios (iport.dataport) : inp (iport.dataport)) < 2 && PORdy()); default: Fatal ("Invalid synchronization code: '%d'", dev.synctype); break; } } OSend (c) /* read a CONFIG.DAT record */ int rec; { if (seek (datfd, rec, ABSOLUTE) < 0 || read (datfd, &tsect, 1) < 1) Facter? */ int c; { int seqlen; if (c >= SEQSTART && c < SEQEND) seqlen = c - SEQSTART; else seqlen = 1; switch (type,name) /* Locate a record by class and name */ int type; /* returns success flag */ char *name; { int frec, lrecOUnInter: %d chars is too many!\n", seqlen); while (IQFull (&oqueue)) OSendChk(); IQShove (SEQSTART + seqlen, &oqueue); } & iport.datamask); } FLAG PORdy() /* printer ready for character */ { if (oport.sbiosp && !oport.statport) ret /* send a character */ int c; { if (c >= SEQSTART && c < SEQEND) return; /* ignore seq codes */ POPut (c); ++synccnatal ("Read error in system database file (CONFIG.DAT)\n"); } DfltPrt() /* read definition of default printer */ { dev.synctype) { case NOSYNC: return (PORdy()); case XON_XOFF: if (PIRdy()) syncok = (PIGet() != DC3); return (sy; switch (type) { case PORT: frec = hdr.fport; lrec = hdr.fterm; break; case PRINT: frec = hdr.fprint; OSendChk() /* send a command if ready */ { while (!IQEmpty (&oqueue) && OReady (IQPeek (&oqueue))) { OSend (IQGrurn (TRUE); return (((oport.sbiosp ? bios (oport.statport) : inp (oport.statport)) & oport.readymask) == oport.polarityt; } FLAG PIRdy() /* char available from printer input? */ { if (iport.sbiosp && !iport.statport) return (TRUE) if (hdr.ourprint == 0) Fatal ("No default printer defined!\n"); ReadRec (hdr.ourprint); if (!tsect[0]) Fatal ("Invalid defancok && PORdy()); case ETX_ACK: if (synccnt + seqlen > SYNCBUFSIZ) { if (!PORdy()) return (FALSE); POPut (ETX); lrec = hdr.fmicro; break; default: Fatal ("FindRec: Invalid record type."); return (FALSE); } for (frec=0; frec ab (&oqueue)); if (!OStKnown()) break; } /* break if we don't really know status */ } FLAG OStKnown() /* is); } POPut (c) /* send char to printer */ char c; { c &= oport.datamask; if (oport.dbiosp) bios (oport.dataportult printer definition (record deleted).\n"); } /* End of PRINTER.C -- vanilla printer driver */  FLAG FindRec ( case CUSTOM: CusFini(); break; case QUME: QmFini(); break; */ case CEN737: CenFini(); break; } OPutCm EPSON: EpInit (vpos); break; case IDS460: IDSInit (vpos); break; case SPINWRITER: SpInit (vpos); break; ME: return (QmInfo (what)); break; */ case CEN737: return (CenInfo (what)); break; } } /**************** os, vpos); break; */ case CEN737: CenPrtMove (c, hpos, vpos); break; } } FLAG DrvInfo (what) /* ask aboud (dev.finistr); } DrvPrtMove (c, hpos, vpos) /* print c and move to hpos, vpos */ int c, hpos, vpos; { switch (dev/* case CUSTOM: CusInit (vpos); break; case QUME: QmInit (vpos); break; */ case CEN737: CenInit (vpos); breVanilla driver ****************/ VInit (vpos) int vpos; { if (dev.barecr) OPutChar (CR); drvhpos = 0; drvvpos = vpos/* DRIVER.C Specialized printer drivers Copyright 1981 by Mark of the Unicorn, Inc. Created 81.6.1 Gyro This file contt printer */ int what; { switch (dev.prtcode) { case VANILLA: return (VInfo (what)); break; case DIABLO: re.prtcode) { case VANILLA: VPrtMove (c, hpos, vpos); break; case DIABLO: DbPrtMove (c, hpos, vpos); break; cak; } } DrvFini() { switch (dev.prtcode) { case VANILLA: VFini(); break; case DIABLO: DbFini(); ; } VFini() { } VPrtMove (c, hpos, vpos) int c, hpos, vpos; { int delh, delv; if (c != NOCHAR) { OPuains the drivers for various kinds of printers. */ #include "crayon.h" DrvInit (vpos) int vpos; { OPutCmd (&dev.inturn (DbInfo (what)); break; case EPSON: return (EpInfo (what)); break; case IDS460: return (IDSInfo (what)); ase EPSON: EpPrtMove (c, hpos, vpos); break; case IDS460: IDSPrtMove (c, hpos, vpos); break; case SPINWRITER: break; case EPSON: EpFini(); break; case IDS460: IDSFini(); break; case SPINWRITER: SpFini(); break; /*tChar (c); drvhpos += DWidChar (c); } delh = hpos - drvhpos; delv = vpos - drvvpos; if (delh < 0) { if (delv) { itstr); switch (dev.prtcode) { case VANILLA: VInit (vpos); break; case DIABLO: DbInit (vpos); break; case break; case SPINWRITER: return (SpInfo (what)); break; /* case CUSTOM: return (CusInfo (what)); break; case QU SpPrtMove (c, hpos, vpos); break; /* case CUSTOM: CusPrtMove (c, hpos, vpos); break; case QUME: QmPrtMove (c, hp OPutCmd (&dev.donewline); delv -= linev; delh = hpos; } else if (dev.barecr && (!dev.backspace vpos; { int delh; delh = hpos - drvhpos; if (c != NOCHAR) { if ((!DbSpcOk (delh) && !DbTabOk (hpos) && abs (del request\n"); } } /**************** Diablo driver ****************/ DbInit (vpos) int vpos; { drvvpos = vpospcOk (delh) /* can we move this far by spaces? */ int delh; { return (drvhpitch != 0 && abs (delh) % drvhpitch == pagev; } FLAG VInfo (what) /* ask about printer */ int what; { switch (what) { case OVP: /* can it ovee (delh) if (delh * drvdirec > 0) { OPutChar (' '); delh -= drvhpitch * drvdirec; } else { OPutChar || -delh > hpos + 1)) { OPutChar (CR); delh = hpos; } else if (dev.backspace) while (delh < 0) { OPutChar h) <= 125) || (abs (delh) == spaceh && !dev.isprop)) DbSHPitch (abs (delh)); DbSDirec ((delh < 0) ? BACKWARD : ; OPutChar (CR); drvhpos = 0; drvhpitch = drvvpitch = drvdirec = UNINITIALIZED; drvshiftp = TRUE; DbSHPitch (spaceh); 0 && abs (delh) / drvhpitch < 7); } DbTabOk (hpos) /* can we get here with abs horiz tab? */ int hpos; { rprint? */ return (dev.barecr || dev.backspace); case CENTCHAR: /* does it center characters? */ case BIDIREC: /*(BS); delh += drvhpitch * drvdirec; } return; } if (abs (delh) > 125 || DbTabOk (hpos)) { if (drvhpitch =(BS); delh += spaceh; } } if (dev.formfeed) /* reconstruct form feeds */ while (delv > (vpos % pagev)) { /*FORWARD); DbSShift ((c & 128) ? TRUE : FALSE); OPutChar (c & 127); drvhpos += drvhpitch * drvdirec; } DbMoveH (hpo DbSVPitch (linev); DbSDirec (FORWARD); DbSShift (FALSE); } DbFini() { DbSHPitch (spaceh); DbSVPitch (linev); return (drvhpitch != 0 && hpos % drvhpitch == 0 && hpos / drvhpitch <= 125); } DbMoveV (vpos) /* vertica does it need explicit bidirection? */ return (FALSE); case BOLD: /* can it boldface innately? */ return (dev.boldon.= 0 || hpos / drvhpitch > 125) DbSHPitch ((hpos / spaceh <= 125) ? spaceh : 13); DbHTab (hpos / drvhpitch); delh = h believe it or not! */ OPutChar (FF); delv -= pagev - (vpos - delv) % pagev; } while ((delv -= linev) >= 0) { Os); DbMoveV (vpos); } DbMoveH (hpos) /* horizontal move */ int hpos; { int delh; delh = hpos - drvhpos; DbSDirec (FORWARD); DbSShift (FALSE); } DbPrtMove (c, hpos, vpos) /* print c and move to hpos, vpos */ int c, hpos, l move */ int vpos; { int delv; delv = vpos - drvvpos; if (!delv) return; drvvpos = vpos % pagev; while (delv) {len != 0); case ITALIC: /* can it italic innately? */ return (dev.italon.len != 0); default: Fatal ("VInfo: unknownpos % drvhpitch; } if (delh) { DbSHPitch (abs (delh)); OPutChar ((delh * drvdirec < 0) ? BS : ' '); } } DbSPutCmd (&dev.donewline); delh=hpos; } while ((delh -= spaceh) >= 0) OPutChar (' '); drvhpos = hpos; drvvpos = vpos %if (!delh) return; drvhpos = hpos; if (DbSpcOk (delh) && (abs (delh) / drvhpitch < 4 || !DbTabOk (hpos))) { whil DbSVPitch (min (delv, 125)); OPutChar (LF); delv -= drvvpitch; } } DbSHPitch (hpitch) /* set horizontal pi; drvhpos += DWidChar (c); } delh = hpos - drvhpos; delv = vpos - drvvpos; if (delh < 0 && !delv) { OPutChar (Ce innately? */ return (dev.boldon.len != 0); case ITALIC: /* can it italic innately? */ return (dev.italon.len != 0);os; drvhpos = 0; drvvpitch = UNINITIALIZED; OPutChar (CR); } IDSFini() { IDSSVPitch (linev); } IDSPrtMoveo pos */ int pos; { OPutSeq (ESC, TAB, pos + 1, ENDLIST); } DbSShift (shiftp) /* shift on or off (only for NEC 551e OVP: /* can it overprint? */ return (TRUE); case CENTCHAR: /* does it center characters? */ case BIDIREC: /* tch */ int hpitch; { if (hpitch == drvhpitch) return; OPutSeq (ESC, US, hpitch + 1, ENDLIST); drvhpitch = hpitch; } R); delh = hpos; } while (delv) { EpSVPitch (min (delv, 85)); OPutCmd (&dev.donewline); delv -= drvvpitch; d default: Fatal ("DbInfo: unknown request\n"); } } /**************** Epson driver ****************/ EpInit (vp (c, hpos, vpos) int c, hpos, vpos; { int delh, delv; if (c != NOCHAR) { OPutChar (c); drvhpos += DWidChar (c); 5/25) */ FLAG shiftp; { if (drvshiftp == shiftp) return; OPutChar (shiftp ? SO : SI); drvshiftp = shiftp; } FLAGdoes it need explicit bidirection? */ return (FALSE); case BOLD: /* can it boldface innately? */ return (dev.boldon.l DbSVPitch (vpitch) /* set vertical pitch */ int vpitch; { if (vpitch == drvvpitch) return; OPutSeq (ESC, RS, vpitchelh = hpos; } while ((delh -= spaceh) >= 0) OPutChar (' '); drvhpos = hpos; drvvpos = vpos % pagev; } EpSVPitch os) int vpos; { OPutChar (CR); drvhpos = 0; drvvpos = vpos; drvvpitch = UNINITIALIZED; } EpFini() { EpSVPit } delh = hpos - drvhpos; delv = vpos - drvvpos; while (delv) { IDSSVPitch (min (delv, 255)); OPutCmd (&dev.donewl DbInfo (what) int what; { switch (what) { case OVP: /* can it overprint? */ case CENTCHAR: /* does it centeen != 0); case ITALIC: /* can it italic innately? */ return (dev.italon.len != 0); default: Fatal ("EpInfo: unknown + 1, ENDLIST); drvvpitch = vpitch; } DbSDirec (direc) /* set print direction */ int direc; { if (direc == drvdi(vpitch) /* set vertical pitch */ int vpitch; { if (drvvpitch == vpitch) return; OPutSeq (ESC, 'A', vpitch, ESC, '2', Ech (linev); } EpPrtMove (c, hpos, vpos) int c, hpos, vpos; { int delh, delv; if (c != NOCHAR) { OPutChar (c)ine); delv -= drvvpitch; delh = hpos; } if (delh < 0) { OPutChar (CR); delh = hpos; } if (delh % spaceh) {r characters? */ case BIDIREC: /* does it need explicit bidirection? */ return (TRUE); case BOLD: /* can it boldfac request\n"); } } /**************** IDS 460 driver ****************/ IDSInit (vpos) int vpos; { drvvpos = vprec) return; OPutSeq (ESC, (direc == FORWARD) ? '5' : '6', ENDLIST); drvdirec = direc; } DbHTab (pos) /* abs tab tNDLIST); drvvpitch = vpitch; } FLAG EpInfo (what) /* ask about printer */ int what; { switch (what) { cas IDSHTab (hpos); delh = 0; } while (delh >= spaceh) { OPutChar (' '); delh -= spaceh; } drvhpos = hpos; && !dev.isprop)) SpSHPitch (abs (delh)); SpSDirec ((delh < 0) ? BACKWARD : FORWARD); SpSShift ((c & 128) ? TRUE : FAch = drvvpitch = drvdirec = UNINITIALIZED; drvshiftp = TRUE; SpSHPitch (spaceh); SpSVPitch (linev); SpSDirec (FORWARD); hpos; { return (hpos % (dev.isprop ? 10 : charh) == 0); } SpMoveV (vpos) /* vertical move */ int vpos; { int d/ return (TRUE); case CENTCHAR: /* does it center characters? */ case BIDIREC: /* does it need explicit bidirection } return; } if (abs (delh) > 15 || SpTabOk (hpos)) { SpHTab (hpos / (dev.isprop ? 10 : charh)); delh = hpos % drvvpos = vpos % pagev; } IDSSVPitch (vpitch) int vpitch; { if (drvvpitch != vpitch) { OUnInter (6); OPutChar LSE); OPutChar (c & 127); drvhpos += drvhpitch * drvdirec; } SpMoveH (hpos); SpMoveV (vpos); } SpMoveH (hpos SpSShift (FALSE); } SpFini() { SpSHPitch (spaceh); SpSVPitch (linev); SpSDirec (FORWARD); SpSShift (FALSE); elv; delv = vpos - drvvpos; if (!delv) return; drvvpos = vpos % pagev; /* this ought to do abs vertical tab ??? */ ? */ return (FALSE); case BOLD: /* can it boldface innately? */ return (dev.boldon.len != 0); case ITALIC: /* ca(dev.isprop ? 10 : charh); } if (delh) { SpSHPitch (abs (delh)); OPutChar ((delh * drvdirec < 0) ? BS : ' '); } (ESC); OPutChar ('B'); OPutNum (vpitch); OPutChar (CR); drvvpitch = vpitch; } } IDSHTab (pos) /* abs ho) /* horizontal move */ int hpos; { int delh; delh = hpos - drvhpos; if (!delh) return; drvhpos = hpos; if (S} SpPrtMove (c, hpos, vpos) /* print c and move to hpos, vpos */ int c, hpos, vpos; { int delh; delh = hpos - drvwhile (delv) { SpSVPitch (min (delv, 16)); OPutChar (LF); delv -= drvvpitch; } } SpSHPitch (hpitch) /* set n it italic innately? */ return (dev.italon.len != 0); default: Fatal ("IDSInfo: unknown request\n"); } } /*} SpSpcOk (delh) /* can we move this far by spaces? */ int delh; { return (drvhpitch != 0 && abs (delh) % drrizontal tab to */ int pos; { OUnInter (7); OPutChar (ESC); OPutChar ('G'); OPutNum (pos); OPutChar (CR); }pSpcOk (delh) && (abs (delh) / drvhpitch < 4 || !SpTabOk (hpos))) { while (delh) if (delh * drvdirec > 0) { hpos; if (c != NOCHAR) { if ((!SpSpcOk (delh) && !SpTabOk (hpos) && abs (delh) <= 15) || (abs (delh) == spaceh horizontal pitch */ int hpitch; { if (hpitch == drvhpitch) return; OPutSeq (ESC, ']', hpitch + '@', ENDLIST); drvhpitch*************** Spinwriter driver ****************/ SpInit (vpos) int vpos; { drvvpos = vpos; drvhpos = 0; drvhpitvhpitch == 0 && abs (delh) / drvhpitch < 10); } SpTabOk (hpos) /* can we get here with abs horiz tab? */ int FLAG IDSInfo (what) /* ask about printer */ int what; { switch (what) { case OVP: /* can it overprint? * OPutChar (' '); delh -= drvhpitch * drvdirec; } else { OPutChar (BS); delh += drvhpitch * drvdirec; = hpitch; } SpSVPitch (vpitch) /* set vertical pitch */ int vpitch; { if (vpitch == drvvpitch) return; OPutSeq while (delh >= spaceh) { OPutChar (' '); delh -= spaceh; } while (delh > 0) { OPutSeq (ESC, min (delh, 6), ENDLI******/ CenInit (vpos) int vpos; { OPutChar (CR); drvhpos = 0; drvvpos = vpos; } CenFini() { } CenPrtIQINIIQGRAbIQSHOVIQEMPT(IQFULSIQPEECQINICQGRAqCQSHOVCQEMPT1CQFUL\CQPEE } FLAG SpInfo (what) int what; { switch (what) { case OVP: /* can it overprint? */ case CENTCHAR: /*n.len != 0); default: Fatal ("CenInfo: unknown request\n"); } } /* End of DRIVER.C -- specialized printer drive(ESC, ']', vpitch + 'O', ENDLIST); drvvpitch = vpitch; } SpSDirec (direc) /* set print direction */ int direc; { ST); delh -= min (delh, 6); } drvhpos = hpos; drvvpos = vpos % pagev; } FLAG CenInfo (what) /* ask about prMove (c, hpos, vpos) int c, hpos, vpos; { int delh, delv; if (c != NOCHAR) { OPutChar (c); drvhpos += DWidChar ( does it center characters? */ case BIDIREC: /* does it need explicit bidirection? */ return (TRUE); case BOLD: /* rs */  delh = hpos - drvhpos; delv = vpos - drvvpos; while (delv >= linev) { OPutChar (LF); delv -= linev; } if (direc == drvdirec) return; OPutSeq (ESC, (direc == FORWARD) ? '>' : '<', ENDLIST); drvdirec = direc; } SpHTab (pinter */ int what; { switch (what) { case OVP: /* can it overprint? */ return (TRUE); case CENTCHAR: /* doc); } delh = hpos - drvhpos; delv = vpos - drvvpos; while (delv >= linev) { OPutChar (LF); delv -= linev; } can it boldface innately? */ return (dev.boldon.len != 0); case ITALIC: /* can it italic innately? */ return (dev.itaos) /* abs tab to pos */ int pos; { OPutSeq (ESC, pos / 32 + 'P', pos % 32 + '@', ENDLIST); } SpSShift (shiftp) es it center characters? */ case BIDIREC: /* does it need explicit bidirection? */ return (FALSE); case BOLD: /* caif (delv == linev / 2) OPutSeq (ESC, 28, ENDLIST);/* half line feed */ if (delh < 0) { OPutChar (CR); delh = hpos; } lon.len != 0); default: Fatal ("SpInfo: unknown request\n"); } } /**************** Centronics driver ********** /* shift on or off */ FLAG shiftp; { if (drvshiftp == shiftp) return; OPutChar (shiftp ? SO : SI); drvshiftp = shiftp;n it boldface innately? */ return (dev.boldon.len != 0); case ITALIC: /* can it italic innately? */ return (dev.italoX!9DM͐͐##͐͐s#rs#rs#r͐͐~#fo͐)++s#rW!9DM͐~#fo͐~#rogram prints an ASCII file using the definitions in CONFIG.DAT. */ #include "crayon.h" #define MAXTABS 32 /* max #r *devname; /* device to print on */ int headingp; /* print heading on each page? */ int leftmar, rightmar; /* text mar~#fo͐~#foA͐͐~#fos#rn&N͐^#Vr+sn&"?Z!9DM͐##~#fo͐~#foB͐##͐eferences */ FLAG scriptpush; /* do supper/sub scripts get more space */ FLAG ischapter; /* does @chapter command exist */foB͐͐~#fos#r~#foS͐^#Vr+s~#fo"@]!9DM͐##~#fo͐~#foB͐##͐~#fo of tabs */ struct { MICA tabcolumns[MAXTABS];/* where tabs are */ MICA headerspace; /* vertical space to leave after headgins */ int cleftmar, crightmar; /* margins as entered from command line */ int perfskip; /* amount to skip around page pe~#fos#rP͐##^#Vr+s͐s$@&!9DM͐~#fo͐##~#fo͝g!9DM͐##~#fo#͐~#fo MICA stop; /* margins */ MICA sleft; MICA sright; MICA sbottom; MICA above; /* space to leave before an environmes#rQ͐##^#Vr+s͐s#r$@&!9DM͐~#fo͐##~#fo͝h!9DM͐##~#fo##͐~#fo͝d͐er */ MICA footerspace; /* and before footer */ char prefjust; /* preferred justification style 'b' both or 'l'rfs */ main (argc, argv) int argc; char **argv; { int ntimes, itab, iarg, tabwidth; char *optname; struct { c͐##~#fo͐~#fo͝c͐~#fo͐~#fo͝$EF!9DM͐~#fo͐~#fo6͐~#fonnt */ MICA below; /* space to leave after an environment */ FLAG levindent; /* do nested Level environments indent? */ ##~#fo͐~#fo͝d͐~#fo͐~#fo͝%FI!9DM͐~#fo͐~#fo7͐~#fo~#foE͐ left */ char footstyle; /* where footnotes go: 'i' inline, 'b' bottom, 'e' end */ MICA indent; /* amount to ind/* PENCIL.C Generalized random-file printer Copyright (C) 1981 by Mark of the Unicorn Inc. Created 81.7.31 Gyro This p char *fname; int fntimes; } files[20]; int nfiles; puts ("Pencil Version 1.3, Copyright (C) 1981 by Mark of the Un&@͐~#fo#n&"4FLAG levhang; /* are Level paragraphs outdented? */ int endsize; /* space to reserve for enddata */ } scribrec; cha~#fo##~#fo"5V!9DM͐͐##͐͐s#rs#rs#r͐͐~#fo͐+s#rT!9DM͐ent paragraphs */ MICA spread; /* number of lines between paragraphs */ MICA linespacing; FLAG footpush; /* footnote ricorn Inc.\n"); ntimes = 1; nfiles = 0; pausep = FALSE; title = ""; portname = DEFAULT; devname = DEFAULT; quietp ghtmar = atoi (argv[++iarg]); if (!quietp) printf ("Right margin set to %d characters.\n", crightmar); } else if ((!quietp) printf ("Starting at page %d.\n", startpage); } else if (match (optname, "Pause")) { pausep = TRUE; me, files[iarg].fntimes) == ABORTALL) break; } PrintFile (fname, ntimes) char *fname; int ntimes; { char c; ; if (!quietp) printf("Left margin set to %d characters.\n", cleftmar); } else if (match (optname, "NH") = ntimes; ++nfiles; } } if (((datfd = open ("config.dat", INPUT)) < 0 && (datfd = open ("a:config.dat", INPUT= FALSE; startpage = 1; headingp = TRUE; cleftmar = crightmar = -1; perfskip = 3; tabwidth = DEFAULT; for (iarg = 1;match (optname, "Tab") || match (optname, "Tabs")) { tabwidth = atoi (argv[++iarg]); if (!quietp) printf ("T puts ("Pausing for manual insertion of each page.\n"); } else if (match (optname, "Port")) { portname = argv[++iaFLAG done; if (IOpen (fname, INPUT) < 0) { printf ("Can't open input file '%s'.\n", fname); return; } if (!quiet || match (optname, "NoHeading")) { if (!quietp) puts ("Not printing page headings.\n"); headingp = FALSE; )) < 0)) Fatal ("Can't open the system database file (CONFIG.DAT)\n"); seek (datfd, 2, ABSOLUTE); read (datfd, tsect, 1); iarg < argc; ++iarg) { if (*argv[iarg] == '-') { optname = argv[iarg] + 1; if (isdigit (*optname)) ntimes = atoi (opab stops set every %d characters.\n", tabwidth); } else if (match (optname, "T") || match (optname, "Title"))rg]; if (!quietp) printf ("Using the '%s' port(s).\n", portname); } else if (match (optname, "Q") p) { if (ntimes == 1) printf ("Printing '%s' -- OK? ", fname); else printf ("Printing %d copies of '%s' -- OK? ", ntim } else if (match (optname, "NS") || match (optname, "NoSkip")) { if (!quietp) puts ("Not skipping page per movmem (tsect, scribrec, sizeof (scribrec)); close (datfd); if (tabwidth != DEFAULT) for (itab = 0; itab < MAXTABS; ++tname); else if (match (optname, "Dev")) { devname = argv[++iarg]; if (!quietp) printf ("Using the '%s' device.\n" { title = argv[++iarg]; if (!quietp) printf ("Title string is '%s'.\n", title); } else printf ("Unknown comm|| match (optname, "Quiet")) quietp = TRUE; else if (match (optname, "R") || match (optname, "Right")) { cries, fname); if (!Ask ("")) { puts (" -- skipping file.\n\n"); return (ABORTFILE); } } PInit (devname, portnaforations.\n"); perfskip = 0; } else if (match (optname, "Page")) { startpage = atoi (argv[++iarg]); if itab) scribrec.tabcolumns[itab] = itab * tabwidth; for (iarg = 0; iarg < nfiles; ++iarg) if (PrintFile (files[iarg].fna, devname); } else if (match (optname, "L") || match (optname, "Left")) { cleftmar = atoi (argv[++iarg])and line option: '%s'\n", argv[iarg]); } else { files[nfiles].fname = argv[iarg]; files[nfiles].fntimes me, !pausep); if (cleftmar == -1) leftmar = PUnMica (scribrec.sleft, HORIZONTAL); else leftmar = cleftmar * PCharH(); if (f (scribrec.tabcolumns[itab] * PCharH() + leftmar > PHPos()) { PMoveH (scribrec.tabcolumns[itab] * PCharH() + lefts page boundary */ { int prevh; ++curpage; if (!quietp) printf (" %d", curpage); prevh = PHPos(); PCR(); PNewPag done = c; break; case EXIT: exit (1); default: break; } INext(); } IRew(); PNewPa PMoveH (leftmar); PSetAttr (UNDERSCORE, UNNBON); sprintf (str, "File: %s", IName()); PPrtStr (str); PMoveH ((PPageHcrightmar == -1) rightmar = PUnMica (scribrec.sright, HORIZONTAL); else rightmar = crightmar * PCharH(); if (PVPos() != 0) {mar - PHPos()); break; } if (itab >= MAXTABS) PMoveH (PCharH()); break; case FF: PFF(); NextPage(); be(); if (pausep) PagePause(); if (headingp && perfskip > 0) { if (perfskip >= 3) PLF(); PageHeader(); } PMoveV ge(); } PFini(); IClose(); return (done); } FileHeader() /* print file header */ { int inch; inch = P() - PWidStr (title) - rightmar + leftmar) / 2 - PHPos()); PPrtStr (title); sprintf (str, "Page: %d", curpage); PMoveH (PP FileHeader(); PFF(); } done = FALSE; while (ntimes-- > 0 && !done) { curpage = 0; NextPage(); DoChar (Creak; case CR: PCR(); PMoveH (leftmar); break; case LF: PLF(); if (PVPos() >= PPageV() - perfskip * PLineV())(perfskip * PLineV() - PVPos()); PMoveH (prevh); } DoChar (ochar) /* process a char */ char ochar; { int itab; cc crayon.c -e6100 cc printer.c -e6100 cc driver.c -e6100 l2 crayon printer driver -l queue cc pencil.c -e6100 l2 pencil prUnMica (2540, HORIZONTAL); PMoveH (inch); PPrtStr (IName ()); PMoveH (inch / 2); PPrtStr (title); PCR(); PMoveV (PLiageH() - PWidStr (str) - rightmar - PHPos()); PPrtStr (str); PSetAttr (UNDERSCORE, FALSE); PCR(); } /* End of PENCIR); while (!done && IChar() != EOF) { DoChar (IChar()); if (TKbRdy()) switch (c = TGetKb()) { case ABORTFI NextPage(); break; default: if (PHPos() + PWidChar (ochar) > PPageH() - rightmar) { DoChar (CR); DoChar (LF); switch (ochar) { case BS: PMoveH (-PCharH()); break; case TAB: for (itab = 0; itab < MAXTABS; ++itab) iinter driver -l crayon queue WWSome printers require a synchronization protocol in order͔6!9|W!&Hc4c!!EneV()); PMoveH (inch * 2); PPrtStr ("Pencil version 1.2"); /* vsn of this prog. */ PCR(); } NextPage() /* procesL.C -- print a standard ASCII file */ leftmar > PHPos()) { PMoveH (scribrec.tabcolumns[itab] * PCharH() + leftLE: puts ("\nAborting this file.\n"); done = c; break; case ABORTALL: puts ("\nAborting all files.\n"); } PPrtChar (ochar); break; } } PageHeader() /* print the page header */ { char str[80], *c; int len; ecial set of defines that provide an interesting, and perhaps more readable, control structure. The program is included in thne one line at a time untill a region of difference is encountered and then an exaustive search is done for the smallest regio input files */ /* Forward function declarations */ char *FMore(); FLAG FEOF(), FMatch(); /* The program */ main(argc variables */ #define BUFFSIZ 8192 #define MAXLINES 50 char iobuff[BUFSIZ], *ofd; /* Declarations for C buffered output */ e Scribble package as an interesting and perhaps usefull "bonus". */ #include "bdscio.h" /* Universal defines */ #defin of difference that ends in two lines which are the same. The size of regions of matching is printed, the entire contents o,argv) /* Source commpare program */ int argc; char *argv[]; { printf("DIFF Version 1.1 Copyright (c) 1981 by Mark of th/* DIFF.C - Source compare by lines (Differences) Copyright (c) 1981 by Mark of the Unicorn Inc. Created by Jason T. Linha struct fbuff { /* The file buffer structure */ int fd; /* C I/O package file descriptor */ char *eptr, *mptr; /* pone TRUE (-1) #define FALSE 0 #define NULL 0 #define NUL '\0' #define CR '\r' #define LF '\n' #define EOF '\32' #definf both versions of regions of difference is printed. The program also accepts "-p" on the command line to direct the output toe Unicorn Inc.\n"); /* argument decoding */ if argc==3 then ofd=1; elseif argc==4 && !strcmp("-P",argv[3]) then rt 4/29/81 Updated to version 1.1 7/19/80 JTL This program is a simple source compare program that works by lines. Twinters into buff */ char buff[BUFFSIZ]; /* Character buffering */ struct lbuff { /* Line buffering */ char *lptr; /*e FLAG char #define loop WHILE (1) { #define endloop } #define if IF ( #define then ) { #define elseif } ELSE IF ( the CP/M list device and "-o " to direct the output to the named file. The program is written in BDS-C using a sp ofd=2; elseif argc==5 && !strcmp("-O",argv[3]) then ofd=iobuff; if fcreat(argv[4],ofd)<0 then Fatal("Unable to openo input files, specified on the command line, are commpared one line at a time for regions of difference. The comparison is do Location of line in memory */ int lhash; /* Hash of line's contents */ } line[MAXLINES]; } f1, f2; /* Allow for two #define else } ELSE { #define endif } #define while IF (!( #define until IF (( #define remain )) BREAK /* Global output file."); endif else Fatal("Usage: 'diff file_one file_two (-p | -o file)'"); endif /* Initialize input **************\n"); tmp=0; loop while tmp<=depth remain; FPrint(0,tmp); ++tmp; endloop fprintf(ofd,"**********\n")FMatch(depth+1,level+1) remain; if level=MAXLINES-1 then Fatal("Files differ by more than %d{ struct fbuff *fdesc; int thash; char *cptr; /* This function fills in amt more lines in the line table,d %d lines.\n",depth); endif if FEOF() then return; endif /* For every line in each file, compare it and the /* Open the input files, checking for possible errors, initialize the buffer pointers and fill the initial region of difference */ loop while !FEOF() remain; DoRgn(); endloop /* Close files, finish up output */ FFinit(depth,level); } /* The File abstraction */ /* The 'F' or File abstraction maintains a buffer of two input fi lines.",MAXLINES); endif /* Make tmp be the length in the first file */ if FMatch(level,depth) && FMatch(level+1,dep lines are read from the file buffer and their hash values stored in the line table. */ fdesc=(file==0)? &f1 :next line with every previous line in the other file, looking for a two line match */ depth=level=0; loop line table. */ if (f1.fd=open(name1,0))<0 then Fatal("Unable to open '%s'.",name1); endif if (f2.fd=open(name2,0))<0 th(); fprintf(ofd,"Comparison complete.\n"); if ofd>3 then putc(EOF,ofd); fflush(ofd); fclose(ofd); endif; } Dles with special line hash values to allow for very fast line comparisons. An array of MAXLINES lines of informationth+1) then tmp=level; level=depth; depth=tmp; endif /* Print the region of difference */ fprintf(ofd,"****** &f2; loop while amt>0 remain; fdesc->line[MAXLINES-amt].lptr=cptr=fdesc->eptr; /* Check for end of file */ if cp while depthline[MAXLINES-amt].lhash=0; else /* Calculate hash value */ thash=0; loop /* Wtr-128*ramt); } FNext(amt1,amt2) /* Move down amt line in each file */ int amt1, amt2; { /* The routine moves th>line; elin = &fdesc->line[last]; dist = fdesc->line[0].lptr - fdesc->buff; /* Now fix up the existing line pointers { /* Returns TRUE if you are at the end of file on both input files */ return(f1.line[0].lptr==NULL && f2.linsc->eptr=cptr; --amt; endloop } char * FMore(fdesc,last) /* Read in more of a file */ struct fbuff *fdesc; int l? &f1 : &f2; if fdesc->line[lev].lptr==NULL then fprintf(ofd,"%d> EOF\n",file+1); else fprintf(ofd,"%d> %s\n",file+1,fatch out for using up the buffer */ if cptr >= fdesc->mptr then cptr=FMore(fdesc,MAXLINES-amt); endif whilee files up amt1 and amt2 lines, moves up the existing lines to replace old lines and then read in new li*/ loop while slin<=elin remain; slin->lptr-=dist; ++slin; endloop /* Calculate amount more to be read */ size[0].lptr==NULL); } FFini() /* Close the files */ { close(f1.fd); close(f2.fd); } Fatal(mesg,arg) /* Print a ast; { struct lbuff *slin, *elin; int size, dist, ramt; /* This routine reads more text into the data buffdesc->line[lev].lptr); endif } FLAG FMatch(lev1,lev2) /* compare two lines for a match */ int lev1, lev2; { / *cptr!=EOF remain; while *cptr!=CR || *(cptr+1)!=LF remain; thash += *cptr++; endloop /* Put nulls at thnes to replace them. */ movmem(&f1.line[amt1],&f1.line[0],sizeof(f1.line[0])*(MAXLINES-amt1)); FFill(0,amt1); movmem(&f2.le = (BUFFSIZ-size)/128; ramt=read(fdesc->fd,fdesc->mptr-dist,size); if ramt<0 then Fatal("File read error"); endif fdesc->fatal error message */ char *mesg, *arg; { printf("Fatal: "); printf(mesg,arg); printf("\n"); exit(1); } /* END er, preserving the text pointed to by lines that are in use. */ size=fdesc->mptr - fdesc->line[0].lptr; /* Firs* Returns TRUE if the two lines are the same Uses the line hash to speed comarison */ return(f1.line[lev1].lhash==f2.le end of the line so they will print correctly */ if *cptr==EOF then *cptr=NUL; cptr=NULL; else *ine[amt2],&f2.line[0],sizeof(f2.line[0])*(MAXLINES-amt2)); FFill(1,amt2); } FPrint(file,lev) /* print a line */ int fimptr+=ramt*128-dist; /* Check for end of file condition */ if ramtmptr=EOF; endif return(fdesc->mpOF DIFF.C - source commpare program */  /* Prints a specified line, prints 'EOF' on end of file */ fdesc=(file==0)t move text to be saved to the begining of the buffer */ movmem(fdesc->line[0].lptr,fdesc->buff,size); slin = fdesc-ine[lev2].lhash && !strcmp(f1.line[lev1].lptr,f2.line[lev2].lptr)); } FLAG FEOF() /* Check for double end of file */cptr++ = NUL; ++cptr; endif /* Save the hash value */ fdesc->line[MAXLINES-amt].lhash=thash; endif fdele, lev; { struct fbuff *fdesc; /* Prints a specified line, prints 'EOF' on end of file */ fdesc=(file==0)*K͞+86OP'+FÎr ͖ 8{ Ăy0 2͵ ^#V#*~#fo^#*~#fo^#V#*n^#* !9DM!T(͐͐ʹ G*8++|ͩ*K}mMark of the Unicorn Linker fo»ǻ2ú/Ɩc Û ǻ2 ǻ2» ǻ29K# ! !*3K`is#r͐~#fo! s#r͐*3K!9K#*%K͐"%K!9K"x *%K"%K6!9"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r ~#fo`i^#Vr+s)~#fo! K̀(D ! ~#fo͐)~#fo! W)í ͐|ʀ ! ~#fo͐)~#fo*H#"H+kH̀(í n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|zr BDS C, vsn. 2.1 !9DM{2 K{2 K{2K{2K{2K>2K!"H!"H!! K̀(!"-K͐͐͞3"3K3"5K͹ !"F! K0ǻ2» ú ǻ2 ǻ2d²ƜceCM.CCCC.CCCCan't open C.CCC C.CCC: read error! !9DM`iw#w͐*H ! ͐kH͐kH!9K"+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_! ~#fo͐)~#fo*H#"H+kÌ(`i^#Vr+s*K} !H! K̀(* K} ! ! *H#"H+kÌ(* K} 7||7ɯ2qZZ)z|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyOJ!"8*-K"/K!"1KMAIN!9DM͐!+ T(!6 T(!!! 6#6`i6#6͐͐ҹ ! ~#fo͐)~#fon1ǻ25D4 #?5??5@o6ͼ2)26TD bb4 5 ?55@o6ͼ2Ն5h6|! ͐kH! W) ͐kH!W)͐|͝F! s#r͐n} ͐J! s#r! ͱ ͐ n}!~7z?` :>ª@w#.¶66*>?w#> w#.7:77! ! *H#"H+kÌ(!9Usage is: l2 {program files} -l {library files} [-w] -L-W-WA-WS-M-m argument)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o}-G !d ! ~#fo͐)~#fo(|4 ! w#wD !g ! ~#fo͐)~#fo(|_ >2KD !j ! ~#fo͐)~#fo(|3Ն6D445h626+5T 5(51-"( 715ɵQOz!@¤ *7K͐~#fo͐ *8+++| !T(͐T(!7T(! ^#Vr+sQ !9K"`i^#Vr+s !9CRLCan't op!a{   `OE!y6$ -7rBo&))T])))!y missing. Unknown option: '%s' DEFFMDEFFDEFF2MDEFF2!9DM*3K"%K*K}j * K} ! ! !9K"| ! !!*3K!#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"! {2K{2KD !n ! ~#fo͐)~#fo(|¿ {2K{2KD !r ! ~#fo͐)~#fo(|& `i^#Vr+s͐ !u !!en %s << Loading %s >> Duplicate program function '', not linked. !9DM`iw#w͐*Hy͐6`i^#Vr+sU|ʫad error! !9DM! ͱ ! ^#Vr+s~#fo`is#r! ͱ ͐~#fo͐! s#r!͐!9K"|! !͐Kڐ!!*%K"7K͐*7K!9K#͐ҽ!&! ** Out of memory -- switching to disk mode ** Disk write error!w#w*F#"F͐!9MAIN!9DMF`is#r͐n}a͐͐R|W͐g`ip1!g!9!9DM͐ͱ !!K"!́!9 **** Beginning second disk pass **** COMOVLDisk write error! !9DM!!F!9K#s#r*8+++|*1K͐"1K*8++|<͐ *%K͐4*%K͐ "%K!9!9DM͐ +|gA͐ ͐ +`is#r͐#~#!T(*HkI3*H#"H+6y*%K*3K*/K")K*'K|*)K"'K!9Enter the name of a file to be searched: !9 -- read error!!9DM͐ 6*8+++|ʆ*%K*3K*/K! s#r*8+|q͐͐ ~#fo͏͐ ͐ Module won't fit in memory at all! -- read error! !9DM!T͐kI͐kI!9K"|͐kI͐^#Vr+s!9DM͐|͐~#fo`is#r͐͐s#r͐! s#r×!9w*K}!\!H!`!H!H!!*8+|r! n}r!`i!9K#!! !9K#!!+K!9K#`in}i͐"'Ko!"'KÄ!!!9Kfo͐ڱ͐#~#fo͐͐s#rA͐#~#fo͐ ! s#r͐n}*͐6!! ^#Vr+s͐#~#fo! s#r͐#͐!9DM! w#w`iw#w͐*F͐ k8 n}s͐|O!T(͐ k8T(!T(! 6#6`i^#Vr+ss#rÚ͐ ~#fo! s#r͐͐|)###! s#r͐͐n}!!k! s#r͐`is#r͐n}"͐#͐J!XW)K͐kI!gW)!!F!9K#!{!`iw#w͐*FC͐ k8 n}7͐ k!K͊"|͝|B*%K*3K*3K!K&#|B!K'|J!d!!K"!́COMOVLDisk write error! !9DM*"F! s#r͐n}ʥ! pÎ! ^#Vr+s͐~#fo! s#r͐!9-- read error! !9DM*8++| *%K͐ ~#fos#r͐ n}A*8+|A͐ ͐#͐s#r!9!9DM͐n}h!! s#r*F+ k8`is#r͐Æ!9*** Missing functions: !9DM`iw#w͐*F͐ k8 n}͐ k8 6`i^#Vr+s÷!s#r! ^#V!r+s`iͱ `i^#Vr+s͐~#fo! s#r͐! s#r͐͐ `is#r`i^#Vr+s~#fo! s#r͐͐8!! s#rz7͐͋*7K͐ k8`i^#Vr+s!9K"!9CRLCan't open %s << Scanning %s >> -- Re3K`is#r! KJ! s#r*K}M* K}͐6*͐#6#6`i^#V!r+s6*3K`is#r͐#͐ ~#fos#r*3K`is#r`i^#V*5Kڐ*8+|$!T(!"8*8+++|X*%K*3K*3K!K&#|X!!*/K*%K*3K"/K*3K"%K*%K͐*5!8ڵ͐͐R|¢õ`i^#V{ _zWr+s|͐!8 *F k8`is#r͐͐O ͐ ͐ 6͐ "8*-K"/K!T(*K}+!!H8!!H!H!K͊"͹ wʹ G*%K*3K*3K!K&#|!K'|!! s#r͐*%K! s#r*8++|! ^#Vr+sz͐ ͐͐͐͐`i^#Vr+s~#foRæ! ~#fo͐r+s*'Ks#r`i^#Vr+s`i^#Vr+s*)Ks#r`i^#Vr+s*'K*+Ks#rd͐#͐ ~#fos#r!9!9DM!U! *F͐ Ҕ!!7×!!0s#r͐ ͐f+`i^#Vr+sJ!!9!9DM͐ ͐͐͐W)!!!9DM͐+| P&|g}o͐n}͝|g}o}2MP*LP&|g}o͐n}͝|g}o}2NP*KP&|g}o}2KP*LP&|g}o}2LPѯgW!*KP*Lr͐͐&! 9!9DM͐ -&!'͐ ~#fo|&͐ ~#fo͐-(! s#r͐͐ ͐ ~#fo!9DM!;͐g.*F!O͐g.*)K!j͐g.*'K!͐g.*'K*+K!͐g.*1K!͐g.*5K#fo͐-(`is#r͐͐͐͐~#fo4! ~#fo͐s#r͐~#fo͐s#r! ~#fo͐!8͹)!!H!EL!H+|!!`iw#w͐*Fr!EL͐ k8 ~#fo;!!EL! f+!EL͐ "!"c4!x4a:$$$.sub!9DM͐!͐͜4s#r͐~#fo#|P"!!͐͐~#fo4͐##w#w͐wPѯgW *NP} *MP} !*MP}5 *NP}5 !*MP}J *NP}J !Z!9DM͐͐ns͐#n}† ͐n&|g}o͐ 4͐ ~#fo͐s#r! ~#fo͐s#r! ~#fo͐s#r͐ ~#fo+'͐ ##^#Vr+s͐ w#w`is#r*8+|2͐*%K͉!͐g.!9 Link statistics: Number of functions: %d Code ends at: 0x%x s#r͉͐! s#r͐|0%͐͐͐~#fo4! s#r͐#|$͐&͐##~#fo͐s#r͐͐%͐k8͗,͐+++|0!EL!5͗,f͐ k8|)Y!EL! f+!EL! f+`i^#Vr+sù͐|#w͐!9DM͐͐V5s#r͐~#fo#|¸"!͐##w#w͐w#w͐!9DM͐~#fo~5!9DM͐#!sï ! ^#Vr+s! ^#Vr+sn&|g}o|W !9DM͐^#Vr+sn&|g}o| ù !9DM͐n&|g}o|!͐n}!͐ ͐ ~#fo5+'!'͉͐! s#r͐|r'͐͐ ͐ ~#fo5͐r'!'! ~#fo Externals begin at: 0x%x Externals end at: 0x%x Jump table bytes saved: 0x%x Link space remaining: %dK !9DM͐n͐?&! ~#fo͐?s#r8%! w#w͐~#fo¼%!͐͐~#fo4! s#r͐#|‚%͐Ï!EL!7͗,*K}ʟ!EĹ!EL!f+!EL,!EL<.*K}!9!H!EL!H+|!=!!EĹ!EL!f+#͐ +|<#! ~#fo͐##~#fo?͐~#fos#r͉͐`is#r͐͐##~#foʩ#!͐͐~#fó5#|ʣ!! ^#Vr+s ͐͐n&|g}os! ^#Vr+s6!9DM`i6#6͐|!͐͐?|g}o! s#r! ~#fo)s#r͐͐ ͐ ͐k4͐ ~#fo͐s#r͐k͐'!9!9DM͐~#fo|&(!}2͐n}.2͐͐n&͕.s! ^#Vr+s! ^#Vr+s6.͐͐̀(!9DM! ^#Vr+sn}2KP! ^#Vr+sn}2LP*K&͐##^#Vr+s͐w#w͐Ҽ%͐͐?&͐)! s#r͐͐͐4͐~#fo͐s#!EL,!EL<.!9SYMCan't create .SYM file LNKCan't create .LNK file !9DM͐ ~#fo͐ ~#foͩ#!͐͐~#fo4#|©#!#͐͐)s#r͐##͐s#r͐#!9!9DM͐#!&͐~͐͐~#fo5&(!!!9DM͐͐L(͐P(͐!9DM͐n}~(! ^#Vr+sn&N6\(`i͗,Ì.!9!9DM! n&}2|ʼ.! n&.! n&!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+#Vr+s! ns&!9DM! ^#Vr+sn`is{,`in} ,͐! f+͐`in&f+#|,!,ß,!,!9!9͐͐ ͉͐ͬ2`is͐ ͐͐ )͐ͬ2`in&#&G3!9!9DM! n&0ͯ{3! n&9ͯ!*!9~#foڟ**͐ ͐͐͐͐'2! ~#fo͐s#r]*`i~#fo͐s#r7*! ~#fo1! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+s0͐6! ! s#r! n}1! ^#Vr+s!ҏ1! ^#Vr+s! n}ʆ1!9DM͐`is#r! ^#Vr+s! ^#Vr+sns{ʸ(Ò(͐ÿ(!9!9DM`iw#w! ~#fo͐n! ~#fo͐n}")!sn`is{2`in}%2! ! s#r! 6#6! s! s! s͐n}-W/! ^#Vr+s! 4͐n}0g/! 4͐n&P3}ʄ/! 3DM͐-!3.͐##~#fo/-!3.͐##~#fo`is#r͐͐͐~#fo5͐|-!3.͐!9DM`iw#w͐~#fon&P3}3͐ ?͐^#Vr+snѯg`is#rÍ3͐3!9**+ 6  #F#͉s#r)!9!9DM͐͐V5s#rz9+!͐͐s#r͐##6#6͐~#fo!9DM͐+|†+! n&horizontal pitch */ int hpitch; { if (hpitch == drvhpitch) return; OPutSeq (ESC, ']', hpitch + '@', ENDLIST); drvhpitch ~#fo`i^#Vr+sn})!N)(! ~#fo͐n! ~#fo͐nѯgWN)!9!y9DM! `i.`iT(!9!Ç/!! s#r! ^#Vr+sn`is{./! 3! s#r! 4! ^#Vr+sn`is`in&͕.}D/U70X@0OI0Cʏ0S01͐~+?`is#r͐##~#fo| .!͐͐͐4͐##~#fo͐s#r͐~#fo͐s#r!!͐~#x 4~#47*|DM**]4A4><54~# x54 > link if it runs out of memory. [81.4.13] Symbol table is now in the order that the e DISK1 2 /* overflow; finish building table */ #define DISK2 3 /* use table to do window link */ int phase; /* functresolved in favor of the base. */ /**************** Globals ****************/ /* #define SDOS 7:O*o` , FNxg>Goy6$sub»%»0úÛ causes symbols to be read from .sym and produces a segment linked at . It functions occur in memory; this seems more useful. Also, link stats are added on the end; ion table */ struct funct { char fname[9]; FLAG flinkedp; /* in memory already? */ char *faddr; /* address of first r/* L2.C New linker for BDS C Written 1980 by Scott W. Layson This code is in the public domain. This is an improved l /* comment this out for CP/M */*/ /* #define OVERLAYS /* comment this out for shorter version */*/ /* #define MARC /* f also defaults the name of the overlay function to that of the first .crl file (to override, pef link if not linked */ } ftab [300]; int nfuncts; /* no. of functions in table */ #define LINKED 1 /* (flinkedp) ff next char in buffer */ char buff [128]; } ibuf, obuf; /* BDS C i/o buffer */ char symbuf[BUFSIZ]; /* seek opcodes *t of externals */ union ptr acodend; /* actual code-end address */ unsigned extspc; /* size of externals */ unsigned origfunct); phase = INMEM; buforg = origin; jtsaved = 0; } cmdline (argc, argv) /* process command line */ int argc;ses CM.CCC */ char mainfunct[10]; FLAG ovlp; /* make overlay? */ char symsfile [15]; /* file to load symbols from (for oprog(); linklibs(); if (phase == DISK1) rescan(); else wrtcom(); if (symsp) wrtsyms(); } setup (argc, argv) /* unction really here */ #define EXTERNAL 2 /* function defined in separate symbol table */ char fdir [512]; /* CRL file fu/ #define ABSOLUTE 0 #define RELATIVE 1 #define INPUT 0 #define TRUE (-1) #define FALSE 0 #define NULL 0 /* 8080 inin; /* origin of code */ unsigned buforg; /* origin of code buffer */ unsigned jtsaved; /* bytes of jump table saved */ char **argv; { int i, progp; if (argc < 1) { puts ("Usage is:\n"); puts (" l2 {program files} -l {library filesverlays) */ /* useful things to have defined */ struct inst { char opcode; char *address; }; union ptr { unsignedinitialize function table, etc. */ int argc; char **argv; { symsp = appstatsp = sepstatsp = maxmemp = marcp = FALSE; ovnction directory */ /* command line parameters etc. */ int nprogs, nlibs; char progfiles [30] [15]; /* program file names *structions */ #define LHLD 0x2A #define LXIH 0x21 #define SPHL 0xF9 #define JMP 0xC3 #define CALL 0xCD /* strcmp7 local char *lspace; /* space to link in */ char *lspcend; /* end of link area */ char *lodstart; /* beginning of current } [-w]\n"); exit (1); } progp = TRUE; for (i=1; i < argc; ++i) { if (argv[i][0] == '-') { if (!strcmp (argv[i], u; /* an int */ unsigned *w; /* a word ptr */ char *b; /* a byte ptr */ struct inst *i; /* an instruction ptr */ lp = FALSE; nprogs = 0; nlibs = 0; strcpy (&mainfunct, "MAIN"); origin = 0x100; cmdline (argc, argv); lspace = endex/ char libfiles [20] [15]; /* library file names */ FLAG symsp, /* write symbols to .sym file? */ appstatsp, /* appends, made global for speed */ char _c1, _c2, _end1, _end2; /**************** End of Globals ****************/ main (argfile */ /* i/o buffer */ struct iobuf { int fd; int isect; /* currently buffered sector */ int nextc; /* index o "-L")) progp = FALSE; else if (!strcmp (argv[i], "-W")) symsp = TRUE; else if (!strcmp (argv[i], "-WA")) symsp = appsta }; /* Link control variables */ union ptr codend; /* last used byte of code buffer + 1 */ union ptr exts; /* start(); lspcend = topofmem() - 1024; loadccc(); nfuncts = 0; #ifdef OVERLAYS if (ovlp) loadsyms(); #endif intern (&main stats to .sym file? */ sepstatsp; /* write stats to .lnk file? */ FLAG maxmemp, /* punt MARC shell? */ marcp; /* uc, argv) int argc; char **argv; { puts ("Mark of the Unicorn Linker for BDS C, vsn. 2.1\n"); setup (argc, argv); linktsp = TRUE; else if (!strcmp (argv[i], "-WS")) symsp = sepstatsp = TRUE; else if (!strcmp (argv[i], "-M")) { if (++open %s\n", progfiles[i]); continue; } printf ("\n<< Loading %s >>\n", &progfiles[i]); readprog (i==0); for (di128) < 128) /* read a sector */ Fatal ("C.CCC: read error!\n"); temp.b = lspace + 0x17; len = *temp.w; /* how lonfname); puts ("\n"); foundp = TRUE; } return (foundp); } rescan() /* perform second disk phase */ { strcpy (&progfiles[nprogs++], argv[i]); else strcpy (&libfiles[nlibs++], argv[i]); } } if (ovlp) strcpy (&mainfunctfile= argc) Fatal ("-m argument missing.\n"); strcpy (&mainfunct, argv[++i]); } #ifdef OVERLAYS else if (!strcmp (rtmp.b=&fdir; *dirtmp.b != 0x80;) { fnct = intern (dirtmp.b); /* for each module */ skip7 (&dirtmp); /* in directog is it? */ cread (&ibuf, lspace + 128, len - 128); /* read rest */ codend.b += len; cclose (&ibuf); } else codendint i; for (i=0; i < nfuncts; ++i) if (ftab[i].flinkedp == LINKED) ftab[i].flinkedp = FALSE; phase = DISK2; buforg =, &progfiles[0]); strcpy (&libfiles[nlibs++], marcp ? "DEFFM" : "DEFF"); strcpy (&libfiles[nlibs++], marcp ? "DEFF2M" : "DEFbfiles[nlibs]); scanlib (nlibs++); } acodend.b = codend.b - lspace + buforg; /* save that number! */ if (!exts.b) extargv[i], "-OVL")) { ovlp = TRUE; if (i + 2 >= argc) Fatal ("-ovl argument missing.\n"); strcpy (&symsfile, argv[+ry */ if (!fnct->flinkedp) linkmod (fnct, lodstart + *dirtmp.w - 0x205); else if (phase != DISK2) { puts ("Dup.i++->opcode = JMP; } linkprog() /* link in all program files */ { int i; union ptr dirtmp; struct funct *fnct; origin; puts ("\n\n**** Beginning second disk pass ****\n"); if (!ovlp) makeext (&progfiles[0], "COM"); else makeext (&prF2"); } loadccc() /* load C.CCC (runtime library) */ { union ptr temp; unsigned len; codend.b = lspace; ifs.b = acodend.b; } missingp() /* are any functions missing? print them out */ { int i, foundp; foundp = FALSE;+i]); sscanf (argv[++i], "%x", &origin); } #endif #ifdef MARC else if (!strcmp (argv[i], "-MARC")) { maxmemlicate program function '"); puts (&fnct->fname); puts ("', not linked.\n"); } dirtmp.w++; } /* in for (i=0; i= lspcend) Fatal ("Module won't fit in memory at all!\n">faddr = finalloc.b; } else finalloc.b = fnct->faddr; body.b = modstart.b + strlen(modstart.b) + 3; /* loc. of function dir.b=&fdir; *dir.b != 0x80; nextd (&dir)); /* find end of dir */ ++dir.b; len = *dir.w - 0x205; readobj (len); } rt) /* link in a module */ struct funct *fnct; union ptr modstart; /* loc. of module in memory */ { union ptr temp; } readprog (mainp) /* read in a program file */ FLAG mainp; { char extp; /* was -e used? */ char *extsnctions */ if (!ftab[i].flinkedp && (dirtmp.b = dirsearch (&ftab[i].fname))) { readfunct (dirtmp.b); linkmod (); } lodstart = codend.b; if (cread (&ibuf, lodstart, len) < len) Fatal ("-- read error!\n"); } scanlib (ifile) body */ jump.i = body.i + (*modstart.b ? 1 : 0); for (temp.b = modstart.b; *temp.b; skip7(&temp)) { jump.i->address = inteadobj (len) /* read in an object (program or lib funct) */ unsigned len; { if (phase == DISK1 || codend.b + len >= ls, jump, /* jump table temp */ body, /* loc. of function in memory */ code, /* loc. of code proper in memtmp; union ptr dir; unsigned len; if (cread (&ibuf, &fdir, 512) < 512) /* read directory */ Fatal ("-- read error!\&ftab[i], lodstart); } } cclose (&ibuf); } readfunct (direntry) /* read a function (from a library) */ unionint ifile; { int i; union ptr dirtmp; makeext (&libfiles[ifile], "CRL"); if (copen (&ibuf, libfiles[ifile]) < 0) { ern (temp.b); ++jump.i; } ++temp.b; flen = *temp.w; code.b = jump.b; temp.b = body.b + flen; /* loc. of reloc ppcend) { if (phase == INMEM) { puts ("\n** Out of memory -- switching to disk mode **\n"); phase = DISK1; } if. */ finalloc; /* runtime loc. of function */ unsigned flen, nrelocs, jtsiz, offset; fnct->flinkedp = LINKED; ifn"); if (phase == INMEM && mainp) { cread (&ibuf, &extp, 1); cread (&ibuf, &extstmp, 2); cread (&ibuf, &extspc, 2); ptr direntry; { unsigned start, len; skip7 (&direntry); start = *direntry.w++; skip7 (&direntry); len = *direntry. printf ("Can't open %s\n", libfiles[ifile]); return; } printf ("\n<< Scanning %s >>\n", &libfiles[ifile]); if (cread arameters */ nrelocs = *temp.w++; jtsiz = code.b - body.b; offset = code.b - codend.b; if (phase != DISK1) while (nre (phase == DISK2) { if (cwrite (&obuf, lspace, codend.b - lspace) == -1) Fatal ("Disk write error!\n"); } buforg (phase != DISK2) { finalloc.b = codend.b - lspace + buforg; if (phase == INMEM) chase (fnct->faddr, finalloc.b); fnct- if (extp) exts.b = extstmp; else exts.b = 0; /* will be set later */ } else cseek (&ibuf, 5, RELATIVE); for (w - start; if (cseek (&ibuf, start, ABSOLUTE) < 0) Fatal (" -- read error!"); readobj (len); } linkmod (fnct, modstarlocs--) relocate (*temp.w++, body.b, jtsiz, finalloc.b, offset, flen); flen -= jtsiz; if (phase != DISK2) jtsaved(ptrp) /* move this pointer to the next dir entry */ union ptr *ptrp; { skip7 (ptrp); ++(*ptrp).w; } chase (heab[nfuncts-1]; fptr >= ftab; --fptr) if (!strcmp7 (name, fptr->fname)) break; if (fptr < ftab) { fptr = &ftab[nfuncts]; ++ = exts.u + extspc; } else temp.i->address = fptr->faddr; /* that's a JMP */ #ifdef MARC if (maxmemp) { temp.b = lla case */ else { ref.b = instr.i->address + body.u; if (instr.i->opcode == LHLD) { instr.i->opcode = LXIH; --ren"); cclose (&obuf); stats (STDOUT); } hackccc() /* store various goodies in C.CCC code */ { union ptr temp; += jtsiz; if (phase != DISK1) movmem (code.b, codend.b, flen); codend.b += flen; } relocate (param, body, jtsiz, basd, loc) /* chase chain of refs to function */ union ptr head; unsigned loc; { union ptr temp; while (head.w) { t strcpy7 (fptr->fname, name); str7tont (fptr->fname); fptr->flinkedp = FALSE; fptr->faddr = NULL; ++nfuncts; } space + 0x258; temp.i->opcode = CALL; temp.i->address = 0x50; } #endif } wrtsyms() /* write out symbol tablf.b; } fnct = ref.i->address; instr.i->address = fnct->faddr; /* link in */ if (!fnct->flinkedp && phase == INME struct funct *fptr; temp.b = lspace; fptr = intern (&mainfunct); if (!ovlp) { if (!marcp) { temp.i->opcode = LHLe, offset, flen) /* do a relocation!! */ unsigned param, jtsiz, base, offset, flen; union ptr body; { union ptr instr, emp.w = *head.w; *head.w = loc; head.u = temp.u; } } wrtcom() /* write out com file (from in-mem link) */ { return (fptr); } dirsearch (name) /* search directory for a function */ char *name; { union ptr temp; for (te */ { int i, fd, compar(); qsort (&ftab, nfuncts, sizeof(*ftab), &compar); makeext (&progfiles[0], "SYM"); if (fcreM) fnct->faddr = instr.b + 1 - offset; /* new list head */ } } intern (name) /* intern a function name in the tD; temp.i->address = 6; (++temp.i)->opcode = SPHL; temp.b = lspace + 0xF; /* main function address */ temp.i-> /* instruction involved */ ref; /* jump table link */ struct funct *fnct; if (param == 1) return; /* don't r hackccc(); if (!ovlp) makeext (&progfiles[0], "COM"); else makeext (&progfiles[0], "OVL"); if (!ccreat (&obuf, &progfilemp.b = &fdir; *temp.b != 0x80; nextd (&temp)) if (!strcmp7 (name, temp.b)) return (temp.b); return (NULL); } nextd at (&progfiles[0], &symbuf) < 0) Fatal ("Can't create .SYM file\n"); for (i=0; i < nfuncts; ++i) { puthex (ftab[i].faddrable */ char *name; { struct funct *fptr; if (*name == 0x9D) name = "MAIN"; /* Why, Leor, WHY??? */ for (fptr = &ftaaddress = fptr->faddr; } temp.b = lspace + 0x15; *temp.w++ = exts.u; ++temp.w; *temp.w++ = acodend.u; *temp.weloc jt skip */ instr.b = body.b + param - 1; if (instr.i->address >= jtsiz) instr.i->address += base - jtsiz; /* vaniles[0]) < 0 || cwrite (&obuf, lspace, codend.b - lspace) == -1 || cflush (&obuf) < 0) Fatal ("Disk write error!\, &symbuf); putc (' ', &symbuf); fputs (&ftab[i].fname, &symbuf); if (i % 4 == 3) fputs ("\n", &symbuf); else { Link statistics:\n"); fprintf (chan, " Number of functions: %d\n", nfuncts); fprintf (chan, " Code ends at: 0x%x\n", acode"%x%s\t%x%s\t%x%s\t%x%s\n", &(ftab[nfuncts].faddr), &(ftab[nfuncts].fname), &(ftab[nfuncts+1].faddr), &(ftab[nfunc (_end1 && _end2) return (0); } } strcpy7 (s1, s2) /* copy s2 into s1 */ char *s1, *s2; { do { *s1 = *s2; ble entries by name */ struct funct *f1, *f2; { /* return (strcmp (&f1->fname, &f2->fname)); alphabetical order */ return } *fname++ = '.'; strcpy (fname, ext); } strcmp7 (s1, s2) /* compare two bit-7-terminated strings */ char *s1,if (strlen (&ftab[i].fname) < 3) putc ('\t', &symbuf); putc ('\t', &symbuf); } } if (i % 4) fputs ("\n", &symbuf); nd.u); fprintf (chan, " Externals begin at: 0x%x\n", exts.u); fprintf (chan, " Externals end at: 0x%x\n", exts.u + extspc)ts+1].fname), &(ftab[nfuncts+2].faddr), &(ftab[nfuncts+2].fname), &(ftab[nfuncts+3].faddr), &(ftab[nfuncts+3].fnam if (!*(s2+1)) { /* works even if */ *s1 |= 0x80; /* s2 is null-term */ break; } ++s1; } while (!(*s2+(f1->faddr > f2->faddr); /* memory order */ } #ifdef OVERLAYS loadsyms() /* load base symbol table (for overlay) */ *s2; /* also works for non-null NUL-term strings */ { /* char c1, c2, end1, end2; (These are now global for speed) */ if (appstatsp) stats (&symbuf); putc (CPMEOF, &symbuf); fflush (&symbuf); fclose (&symbuf); if (sepstatsp) { makee; fprintf (chan, " Jump table bytes saved: 0x%x\n", jtsaved); temp = lspcend; if (phase == INMEM) fprintf (chan, e)); nread /= 2; if (nread < 4) done = TRUE; while (nread-- > 0) ftab[nfuncts++].flinkedp = EXTERNAL; } fclose (&s+ & 0x80)); } skip7 (ptr7) /* move this pointer past a string */ char **ptr7; { while (!(*(*ptr7)++ & 0x80)); } { /* symbol table must be empty! */ int nread; FLAG done; char *c; makeext (&symsfile, "SYM"); if (fopen (&srepeat { _c1 = *s1++; _c2 = *s2++; _end1 = (_c1 & 0x80) | !*s1; _end2 = (_c2 & 0x80) | !*s2; if ((_c1 &= 0x7F) _c2 || (_end2 && !_end1)) return (1); if (_end1 && !_end2) return (-1); if); putc (CPMEOF, &symbuf); fflush (&symbuf); fclose (&symbuf); } } compar (f1, f2) /* compare two symbol ta/ char *fname, *ext; { while (*fname && (*fname != '.')) { *fname = toupper (*fname); /* upcase as well */ ++fname; s++; } *s = *s & 0x7F; *++s = NUL; } puthex (n, obuf) /* output a hex word, with leading 0s */ unsigned n; nes deal with reading and writing large blocks of characters, when they do not fit neatly in sectors. At the moment, only seqaracter (input only!) */ struct iobuf *buf; unsigned nbytes, code; { int newsect; if (buf < 0) return (-1); if (codEND OF L2.C */ { /* works even if */ *s1 |= 0x80; /* s2 is null-term */ break; } ++s1; } while (!(*s2+en (fname, INPUT); if (buf->fd == -1) return (-1); read (buf->fd, &buf->buff, 1); buf->isect = 0; buf->nextc = 0; retu char *obuf; { int i, nyb; for (i = 3; i >= 0; --i) { nyb = (n >> (i * 4)) & 0xF; nyb += (nyb > 9) ? 'A' - 10 : 'uential output is supported; input is fully random. */ #define TRUE (-1) #define FALSE 0 #define NULL 0 /* i/o buffee == RELATIVE) nbytes += buf->isect * 128 + buf->nextc; newsect = nbytes / 128; if (newsect != buf->isect && (seek (burn (buf); } ccreat (buf, fname) /* create a file for char output */ struct iobuf *buf; char *fname; { buf->fd = 0'; putc (nyb, obuf); } } Fatal (arg1, arg2, arg3, arg4) /* lose, lose */ char *arg1, *arg2, *arg3, *arg4; { pr */ struct iobuf { int fd; int isect; /* currently buffered sector */ int nextc; /* index of next char in buffer */ f->fd, newsect, ABSOLUTE) == -1 || read (buf->fd, &buf->buff, 1) == -1)) return (-1); buf->nextc = nbytes % 128; buf->creat (fname); if (buf->fd == -1) return (-1); buf->isect = 0; buf->nextc = 0; return (buf); } cclose (buf) /*rintf (arg1, arg2, arg3, arg4); exit (1); } exit (status) /* exit the program */ int status; { if (status == 1) char buff [128]; }; /* seek opcodes */ #define ABSOLUTE 0 #define RELATIVE 1 #define INPUT 0 #define OUTPUT 1 #d/* CHARIO.C Character-oriented file I/O Written 1980 by Scott W. Layson This code is in the public domain. These routiisect = newsect; return (nbytes); } cread (buf, dest, nbytes) /* read some bytes into dest */ struct iobuf *buf; ch close the file assoc. with buf */ struct iobuf *buf; { close (buf->fd); } cseek (buf, nbytes, code) /* seek to a ch { #ifdef SDOS unlink ("a:$$$$.cmd"); #else unlink ("a:$$$.sub"); #endif } bios (1); /* bye! */ } /* efine UPDATE 2 copen (buf, fname) /* open a file for char input */ struct iobuf *buf; char *fname; { buf->fd = opar *dest; unsigned nbytes; { int navail, nsects, nleft, nread1, nread2; if (buf < 0) return (-1); navail = umin (nbytite (buf->fd, &buf->buff, 1) < 1) return (-1); return (1); } umin (a, b) /* unsigned min */ unsigned a, b; { = nfill; nbytes -= nfill; source += nfill; } if (buf->nextc == 128) { ++(buf->isect); buf->nextc = 0; if (wr buf->nextc = 0; if (nread2 < 1) return (navail + nread1 * 128); } nleft = nbytes % 128; movmem (&buf->buff, dest, ncc l2.c -e3800 cc chario.c l2 l2 chario -wa ChaIChaTKbRdTGetKexiINexIRePNewPagPFinIClosFileHeaes, 128 - buf->nextc); movmem (&buf->buff[buf->nextc], dest, navail); nbytes -= navail; buf->nextc += navail; dest += na return ((a < b) ? a : b); } /* End of CHARIO.C -- Character oriented file I/O */ s) /* write some bytes from source ite (buf->fd, &buf->buff, 1) < 1) return (-1); } nsects = nbytes / 128; if (nsects && write (buf->fd, source, nsects) nextc += nleft; return (navail + nbytes); } cwrite (buf, source, nbytes) /* write some bytes from source vail; nsects = nbytes / 128; if (nsects) { nread1 = read (buf->fd, dest, nsects); if (nread1 == -1) return (navail); nsects) return (-1); nbytes %= 128; movmem (source + nsects * 128, &buf->buff, nbytes); buf->nextc += nbytes; return*/ struct iobuf *buf; char *source; unsigned nbytes; { unsigned nleft, nfill, nsects; if (buf < 0) return (-1); buf->isect += nread1; if (nread1 < nsects) return (navail + nread1 * 128); dest += nread1 * 128; } else nread1 = 0; (nsects * 128 + nbytes); } cflush (buf) /* flush an output buffer */ struct iobuf *buf; { if (buf->nextc && wrif (buf->nextc) { nfill = umin (nbytes, 128 - buf->nextc); movmem (source, &buf->buff[buf->nextc], nfill); buf->nextc + if (buf->nextc == 128) { nread2 = read (buf->fd, &buf->buff, 1); if (nread2 == -1) return (navail); ++(buf->isect);