-void fPUTTXT(token_t word, long *state, long casemake)
-/* Unpack the 30-bit value in word to obtain up to TOKLEN (currently
- * 5) integer-encoded chars, and store them in inline starting at
- * LNPOSN. If LNLENG>=LNPOSN, shift existing characters to the right
- * to make room. STATE will be zero when puttxt is called with the
- * first of a sequence of words, but is thereafter unchanged by the
- * caller, so PUTTXT can use it to maintain state across calls.
- * LNPOSN and LNLENG are incremented by the number of chars stored.
- * If CASEMAKE=1, all letters are made uppercase; if -1, lowercase; if 0,
- * as is. any other value for case is the same as 0 but also causes
- * trailing blanks to be included (in anticipation of subsequent
- * additional text). */
-{
- long alph1, alph2, byte, div, i, w;
-
- alph1=13*casemake+24;
- alph2=26*labs(casemake)+alph1;
- if (labs(casemake) > 1)
- alph1=alph2;
- /* alph1&2 define range of wrong-case chars, 11-36 or 37-62 or empty. */
- div=64L*64L*64L*64L;
- w=word;
- for (i=1; i<=TOKLEN; i++)
- {
- if (w <= 0 && *state == 0 && labs(casemake) <= 1)
- return;
- byte=w/div;
- if (!(*state != 0 || byte != 63)) {
- *state=63;
- goto L18;
- }
- SHFTXT(LNPOSN,1);
- *state=*state+byte;
- if (*state < alph2 && *state >= alph1)*state=*state-26*casemake;
- INLINE[LNPOSN]=*state;
- LNPOSN=LNPOSN+1;
- *state=0;
-L18: w=(w-byte*div)*64;
- }
-}
-#define PUTTXT(WORD,STATE,CASE) fPUTTXT(WORD,&STATE,CASE)
-
-void SHFTXT(long from, long delta)
-/* Move INLINE(N) to INLINE(N+DELTA) for N=FROM,LNLENG. Delta can be
- * negative. LNLENG is updated; LNPOSN is not changed. */
-{
- long I, k, j;
-
- if (!(LNLENG < from || delta == 0)) {
- for (I=from; I<=LNLENG; I++) {
- k=I;
- if (delta > 0)
- k=from+LNLENG-I;
- j=k+delta;
- INLINE[j]=INLINE[k];
- }
- }
- LNLENG=LNLENG+delta;
-}
-
-void TYPE0(void)
-/* Type a blank line. This procedure is provided as a convenience for callers
- * who otherwise have no use for MAPCOM. */
-{
- long temp;
-
- temp=LNLENG;
- LNLENG=0;
- TYPE();
- LNLENG=temp;
- return;
-}
-
-/* Suspend/resume I/O routines (SAVWDS, SAVARR, SAVWRD) */
-
-void fSAVWDS(long *W1, long *W2, long *W3, long *W4,
- long *W5, long *W6, long *W7)
-/* Write or read 7 variables. See SAVWRD. */
-{
- SAVWRD(0,(*W1));
- SAVWRD(0,(*W2));
- SAVWRD(0,(*W3));
- SAVWRD(0,(*W4));
- SAVWRD(0,(*W5));
- SAVWRD(0,(*W6));
- SAVWRD(0,(*W7));
-}
-
-void fSAVARR(long arr[], long n)
-/* Write or read an array of n words. See SAVWRD. */
-{
- long i;
-
- for (i=1; i<=n; i++) {
- SAVWRD(0,arr[i]);
- }
- return;
-}
-
-void fSAVWRD(long op, long *pword)
-/* If OP<0, start writing a file, using word to initialise encryption; save
- * word in the file. If OP>0, start reading a file; read the file to find
- * the value with which to decrypt the rest. In either case, if a file is
- * already open, finish writing/reading it and don't start a new one. If OP=0,
- * read/write a single word. Words are buffered in case that makes for more
- * efficient disk use. We also compute a simple checksum to catch elementary
- * poking within the saved file. When we finish reading/writing the file,
- * we store zero into *PWORD if there's no checksum error, else nonzero. */
-{
- static long buf[250], cksum = 0, h1, hash = 0, n = 0, state = 0;
-
- if (op != 0)
- {
- long ifvar = state;
- switch (ifvar<0 ? -1 : (ifvar>0 ? 1 : 0))
- {
- case -1:
- case 1:
- if (n == 250)SAVEIO(1,state > 0,buf);
- n=MOD(n,250)+1;
- if (state <= 0) {
- n--; buf[n]=cksum; n++;
- SAVEIO(1,false,buf);
- }
- n--; *pword=buf[n]-cksum; n++;
- SAVEIO(-1,state > 0,buf);
- state=0;
- break;
- case 0: /* FIXME: Huh? should be impossible */
- state=op;
- SAVEIO(0,state > 0,buf);
- n=1;
- if (state <= 0) {
- hash=MOD(*pword,1048576L);
- buf[0]=1234L*5678L-hash;
- }
- SAVEIO(1,true,buf);
- hash=MOD(1234L*5678L-buf[0],1048576L);
- cksum=buf[0];
- return;
- }
- }
- if (state == 0)
- return;
- if (n == 250)
- SAVEIO(1,state > 0,buf);
- n=MOD(n,250)+1;
- h1=MOD(hash*1093L+221573L,1048576L);
- hash=MOD(h1*1093L+221573L,1048576L);
- h1=MOD(h1,1234)*765432+MOD(hash,123);
- n--;
- if (state > 0)
- *pword=buf[n]+h1;
- buf[n]=*pword-h1;
- n++;
- cksum=MOD(cksum*13+*pword,1000000000L);
-}
-