[comp.sys.next] More NeXT Bugs

jst@cca.ucsf.edu (Joe Stong) (09/23/89)

This time I'm posting the message here the same time I mail it to
the next folks.

This one is probably even testier than the last, sorry folks.

Again, I'm being asked to maintain a system through a rlogin connection.
I can only see "strings'ed" version of the .wn documents.
Is all the documentation really online?
Is there a sensible way for me to get at the .wn documents on an ascii
terminal?

All help appreciated.  Thanks in advance.

# From jst Fri Sep 22 16:37:14 1989
# To: bug_next@next.com
# Subject: optical disk bugs
# 
# 
# We are trying to back up files on our optical disk.
# 
# Karpinsi's attempts to use "dump" resulted in various hung copies of dump.
# 
# There is no online documentation (unix man page) for the od device driver.
# 
# It would be nice if you're accessing the od from a standard unix terminal
# (via rlogin) that it wouldn't put a dialogue box up on the main screen
# asking to insert a new disk.
# 
# We have a disk that allows itself to be inserted and written upon.
# It dumps tar with an I/O error about 41 megabytes into the 250MB 
# surface.  
# 
# We want to re-cycle the 0.8 distribution disk.  The system won't let us
# put it in, it says something like "wrong volume".  How do we re-label
# the disk if it won't even let us insert it.
# Sep 21 14:28:43 ccnext vmunix: Please insert new disk for volume 0
# Sep 21 14:28:43 ccnext vmunix: (press 'n' key if volume is not available)
# 
# The "su" command doesn't seem to run ANY .cshrc or .login, neither the
# one in my home directory nor root's home.  Where should I put the .cshrc?
# I'm su'ing to a secondary root account:
# jstr:xxx:0:1:jdkjfkjdkf:/home/jst:/bin/csh
# 
# There is various documentation in WriteNow format (.wn) files that I
# cannot read, because I'm using a standard ascii terminal.  Is there a
# way to convert this stuff so I can read it?
# 
# I discovered the "disk" command, only through the NetNews group,
# comp.sys.next .  It has an interestingly misleading help message, from
# which I might conclude that typing "disk -i /dev/rod0a" is a way to
# bring it up in interactive mode.  Pretty frightening, -i is INITIALIZE,
# and not interactive.
# 
# Getting into the "disk" command, we discover that ALL the bad blocks
# are taken on this floptical cartridge.   It continues to read and
# write on bad areas of the cartridge, but it takes a huge amount of time
# 10-40 seconds instead of 1/3second to write 8 sectors, and generates
# lots of errors.
# 
# The documentation about assigning badblocks indicates we should use
# block numbers out of /usr/adm/messages.  We get block numbers there
# that are sometimes larger than 250MB.
# Sep 22 14:43:29 ccnext vmunix: od0a: write failed (ECC)
# 	block 250448 phys block 250459 (19802:0:11)
# 
# The disk program is confusing about writing patterns.  Why does it
# ask, "random pattern" in the write command, when you actually use
# the "set" command to set the pattern to be written?
# 
# Why is there no major/minor number device assigned to the font and
# back porches of the od?   How about doing programs like disk with
# a script front end and some hardware interface programs, so a smart
# user could begin to decipher things without the OS source?
# 
# How do you increase the size of the badblock space on a floptical
# cartridge?  Should we throw this one away?  Back to-how do we
# recycle an old distribution cartridge?
# 
# Help!  We want to do a backup before we install 1.0!
# 

jst@cca.ucsf.edu (Joe Stong) (09/23/89)

Oh, and by the way

# disk /dev/rod0a
disk>bulk

Crashes the system, reliably.  "Golly" folks, what's happening? :-(

dorner@pequod.cso.uiuc.edu (Steve Dorner) (09/25/89)

In article <2412@ucsfcca.ucsf.edu> jst@cca.ucsf.edu (Joe Stong) writes:
>I can only see "strings'ed" version of the .wn documents.
>Is all the documentation really online?
>Is there a sensible way for me to get at the .wn documents on an ascii
>terminal?

I can't believe I'm the only person who has such a beastie, but I guess
I must be.  Here is my program for converting a WriteNow document to
troff.

CAVEATS:
	1) it has bugs
	2) it doesn't do headers, footers, or footnotes
	3) it sometimes gets confused about paragraph justification
	4) here is the "documentation":
		Usage: wn file | {nroff,troff}

It IS marginally better than strings(1) :-).

Steve
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	Makefile
#	wn.h
#	wn.c
#	table.h
#	roff.c
# This archive created: Wed Mar  9 09:15:56 1988
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
CFLAGS	=	-g

install	:	wn
	cp wn ../../bin

wn	:	wn.o roff.o
	cc $(CFLAGS) wn.o roff.o -o wn

wn.o	:	wn.h
roff.o	:	wn.h
SHAR_EOF
fi
if test -f 'wn.h'
then
	echo shar: "will not over-write existing file 'wn.h'"
else
cat << \SHAR_EOF > 'wn.h'
/***********************************************************************
* This program Copyright 1988 by Steven Dorner and the University of
* Illinois Board of Trustees
* 
* No warrantees expressed or implied.
* 
* This program may be redistributed, provided no charge is made for it.
***********************************************************************/
/***********************************************************************
This header file describes the contents of a WriteNow document
***********************************************************************/
#define A32BitInteger	long
#define A16BitInteger	short
#define A32BitFixedPointNumber	float
#define Byte		unsigned char
#define Boolean		unsigned char
#define Handle		A32BitInteger

typedef struct rect Rect;
typedef struct point Point;
typedef A32BitInteger HandleDiskAddress;
typedef struct docinfo DocInfoType;
typedef struct pagelo PageLOType;
typedef struct collo ColLOType;
typedef struct paper PaperType;
typedef struct border BorderType;
typedef struct edgepair EdgePair;
typedef struct textedge TextEdge;
typedef struct docsize DocSizeType;

struct point
{
    A16BitInteger v;
    A16BitInteger h;
};

struct rect
{
    Point top;
    Point bottom;
};

struct textedge
{
     HandleDiskAddress	tBlockTE;
     A16BitInteger	offsetTE;
     Point		topTE;
     A16BitInteger	heightTE;
};

struct edgepair
{
    TextEdge	startSelect;
    TextEdge	endSelect;
};

struct paper
{
    A16BitInteger	pHeight;
    A16BitInteger	pWidth;

};

struct border
{
    A32BitFixedPointNumber	leftBorder;
    A32BitFixedPointNumber	rightBorder;
    Boolean			nonStdPaper;
    Boolean			altBorders;
};
struct collo
{
    Byte		maxColumn;
    Byte		column;
    A16BitInteger	widthOfColumns;
    A16BitInteger	leftEdge;
};

struct pagelo
{
    Boolean		autoFootNote;
    Boolean		fractWidths;
    BorderType		borders;
    ColLOType		colLayout;
    A16BitInteger	docVRes;
    A16BitInteger	docHRes;
    A16BitInteger	firstPageNumber;
    A16BitInteger	pageSlop;
    PaperType		paperSize;
    Rect		printableRect;
    A16BitInteger	rulerReduction;
    A32BitInteger	unused8;
};
    
struct docsize
{
    A32BitInteger	startDiskAdr;
    A32BitInteger	cleanEOF;
    A32BitInteger	ourEOF;
    A32BitInteger	fileEOF;
    A32BitInteger	nextDiskAdr;
};

struct docinfo
{
  /* Handles whose contents must be copied during document copy */
    HandleDiskAddress docMap;
    HandleDiskAddress headFootMap;
    HandleDiskAddress footNMap;
    HandleDiskAddress docWords;
    HandleDiskAddress docPrintRecord;
    Handle screenLayout;
    Handle docDate;
    Handle docTime;
    Handle hScrollBar;
    Handle vScrollBar;
    A32BitInteger unused3;

  /* Variables whose value should not be changed during document copy */
    A32BitInteger docDirID;
    A16BitInteger docRefNum;
    A16BitInteger docVRefNum;
    A32BitInteger unused6;
    Byte docKind;

  /* Variables that are copied directly during document copy */
    Byte docView;
    Boolean dontSaveChanges;
    Boolean doSmartPaste;
    Boolean graphicSelected;
    Boolean markersVis;
    Boolean newDoc;
    Boolean returnInserted;
    Boolean selectVis;
    Boolean spaceVis;
    Boolean squeezeWhenBurn;
    Boolean wordsSelected;
    Boolean writeProtected;
    Byte unused2;

  /* Other variables alphabetically */
    Rect docRect;
    A32BitInteger docVExtension;
    A16BitInteger footHeight;
    Rect graphicRect;
    A16BitInteger headHeight;
    A32BitInteger lastPxlsTilWind;
    PageLOType pageLayout;
    EdgePair selectionEdges;
    A16BitInteger systemName;
    A32BitInteger wastedBytes;
    A32BitInteger unused7;

  /* Variables whose value is not changed by undo */
    Boolean backupExists;
    Boolean docSqueezed;
    DocSizeType docSize;
};

typedef struct map MapType;
typedef struct mapelement MapElement;
struct map
{
    A16BitInteger byteCount;
    MapElement *mapArray;
};

struct mapelement
{
    HandleDiskAddress mapData;
    A16BitInteger textHeight;
};

#define NOTTEXT		0x80000000
#define	RULERCHANGE	0x40000000
#define FONTCHANGE	0x20000000
#define FORCEDPAGE	0x10000000
#define SPCHECKED	0x08000000
#define NONRES		0x04000000
#define MAYBESHARE	0x02000000
#define DONTSPLIT	0x01000000

typedef struct textblock TextBlock;
struct textblock
{
    A16BitInteger byteCount;
    Byte *characters;
};
#define FmtFont		0xFF /* Font, size, or style change */
#define FmtGraphics	0xFE /* Embedded graphics */
#define FmtMarker	0xFD /* Page number, date, time, and footnote marker */
#define FmtRuler	0xFC /* Paragraph ruler formats */
#define Fmt4Unused	0xFB /* Reserved for future use */
#define FmtTabFill	0xFA /* Tab fill */
#define FmtY		0xF9 /* Subscript or superscript */
#define Fmt1Unused	0xF8 /* Reserved for future use */
#define FmtEndFmt	0xF7 /* End of additional data */
#define FmtFooter	0xF6 /* Footer definition */
#define FmtHeader	0xF5 /* Header definition */
#define FmtFootnote	0xF4 /* Footnote definition */
#define FmtSoftHyphen	0xF3 /* Soft hyphen */
#define Fmt2Unused	0xF2 /* Reserved for future use */
#define Fmt3Unused	0xF1 /* Reserved for future use */
#define LiteralCode	0xF0 /* Used to represent characters F0 to FF */

typedef struct fss FSSType;
struct fss
{
    A16BitInteger fontID;
    Byte fontSize;
    Byte fontStyle;
};

#define MAXTABS 50
typedef struct ruler RulerType;
struct ruler
{
    A16BitInteger leftMargin;
    A16BitInteger rightMargin;
    A16BitInteger paraIndent;
    Byte justification;
    Byte lineSpacing;
    A16BitInteger tabStops[MAXTABS];
};

#define IDPNumMarker  0
#define IDDateMarker  1
#define IDTimeMarker  2
#define IDFNumMarker  3

#define FontTimes	20
#define FontCourier	22

#define StyleBold	0x1
#define StyleItalic	0x2
#define StyleUline	0x4
#define CanDoStyleMask	(StyleBold | StyleItalic | StyleUline)

#define JLeft		0
#define JJust		1
#define JCenter		2
#define JRight		3
SHAR_EOF
fi
if test -f 'wn.c'
then
	echo shar: "will not over-write existing file 'wn.c'"
else
cat << \SHAR_EOF > 'wn.c'
/***********************************************************************
* This program Copyright 1988 by Steven Dorner and the University of
* Illinois Board of Trustees
* 
* No warrantees expressed or implied.
* 
* This program may be redistributed, provided no charge is made for it.
***********************************************************************/
#include <stdio.h>
#include <signal.h>
#include "wn.h"
unsigned long GetInteger();
FILE *TheFile;

main(argc,argv)
int argc;
char **argv;
{
    DocInfoType theDI;
    A32BitInteger magic;
    A32BitInteger version;

    for (argc--,argv++; argc; argc--,argv++)
    {
	if ((TheFile=fopen(*argv,"r"))==NULL)
	{
	    fprintf(stderr,"Couldn't open %s.\n",*argv);
	    continue;
	}
	DoBegin();
	magic = GetInteger(4);
	version = GetInteger(4);
	GetDI(&theDI);
	SetHFTraps(theDI.headHeight+theDI.pageLayout.pageSlop,theDI.footHeight);
	Go(theDI.docMap);
	DoEnd();
	fclose(TheFile);
    }
}

Go(theMapAddr)
HandleDiskAddress theMapAddr;
{
    A32BitInteger theOffset;
    MapType theMap;

    theOffset = theMapAddr & 0xffffff;
    SeekTo(theOffset);
    GetMap(&theMap);
    GoMap(&theMap);
}

GoMap(theMap)
MapType *theMap;
{
    int mapCount;
    MapElement *theElement;

    mapCount = theMap->byteCount / 6;
    for (theElement=theMap->mapArray;mapCount;mapCount--,theElement++)
    {
	if (!(theElement->mapData & NOTTEXT))
	    GoTextElement(theElement);
    }
}

GetMap(theMap)
MapType *theMap;
{
    char *malloc();
    int mapCount;
    MapElement *theElement;

    theMap->byteCount = GetInteger(sizeof(theMap->byteCount));
    mapCount = theMap->byteCount/6;
    theMap->mapArray = (MapElement *) malloc(mapCount*sizeof(MapElement));
    for (theElement=theMap->mapArray ; mapCount ; mapCount--,theElement++)
	GetMapE(theElement);
}

GetMapE(theElement)
MapElement *theElement;
{
    theElement->mapData = GetInteger(sizeof(theElement->mapData));
    theElement->textHeight = GetInteger(sizeof(theElement->textHeight));
}

SeekTo(theOffset)
long theOffset;
{
    if (fseek(TheFile,theOffset,0)<0)
    {
	fprintf(stderr,"Seek failed.\n");
	exit(1);
    }
}
unsigned long
GetInteger(count)
int count;
{
    unsigned long theValue=0;
    int theChar;
    int got;

    for (got=0;got<count;got++)
    {
	theValue *= 256;
	theChar = getc(TheFile);
	if (theChar == EOF)
	{
	    fprintf(stderr,"unexpected EOF\n");
	    exit(1);
	}
	theValue += (unsigned) theChar;
    }

    /*printf("%*x\n",2*count,theValue);*/
    return(theValue);
}


GetDI(it)
DocInfoType *it;
{
    it->docMap = GetInteger(sizeof(HandleDiskAddress));
    it->headFootMap = GetInteger(sizeof(HandleDiskAddress));
    it->footNMap = GetInteger(sizeof(HandleDiskAddress));
    it->docWords = GetInteger(sizeof(HandleDiskAddress));
    it->docPrintRecord = GetInteger(sizeof(HandleDiskAddress));
    it->screenLayout = GetInteger(sizeof(Handle));
    it->docDate = GetInteger(sizeof(Handle));
    it->docTime = GetInteger(sizeof(Handle));
    it->hScrollBar = GetInteger(sizeof(Handle));
    it->vScrollBar = GetInteger(sizeof(Handle));
    it->unused3 = GetInteger(sizeof(A32BitInteger));
    it->docDirID = GetInteger(sizeof(A32BitInteger));
    it->docRefNum = GetInteger(sizeof(A16BitInteger));
    it->docVRefNum = GetInteger(sizeof(A16BitInteger));
    it->unused6 = GetInteger(sizeof(A32BitInteger));
    it->docKind = GetInteger(sizeof(Byte));
    it->docView = GetInteger(sizeof(Byte));
    it->dontSaveChanges = GetInteger(sizeof(Boolean));
    it->doSmartPaste = GetInteger(sizeof(Boolean));
    it->graphicSelected = GetInteger(sizeof(Boolean));
    it->markersVis = GetInteger(sizeof(Boolean));
    it->newDoc = GetInteger(sizeof(Boolean));
    it->returnInserted = GetInteger(sizeof(Boolean));
    it->selectVis = GetInteger(sizeof(Boolean));
    it->spaceVis = GetInteger(sizeof(Boolean));
    it->squeezeWhenBurn = GetInteger(sizeof(Boolean));
    it->wordsSelected = GetInteger(sizeof(Boolean));
    it->writeProtected = GetInteger(sizeof(Boolean));
    it->unused2 = GetInteger(sizeof(Byte));
    GetRect(&it->docRect);
    it->docVExtension = GetInteger(sizeof(A32BitInteger));
    it->footHeight = GetInteger(sizeof(A16BitInteger));
    GetRect(&it->graphicRect);
    it->headHeight = GetInteger(sizeof(A16BitInteger));
    it->lastPxlsTilWind = GetInteger(sizeof(A32BitInteger));
    GetPL(&it->pageLayout);
    GetEP(&it->selectionEdges);
    it->systemName = GetInteger(sizeof(A16BitInteger));
    it->wastedBytes = GetInteger(sizeof(A32BitInteger));
    it->unused7 = GetInteger(sizeof(A32BitInteger));
    it->backupExists = GetInteger(sizeof(Boolean));
    it->docSqueezed = GetInteger(sizeof(Boolean));
    GetDS(&it->docSize);
}
GetPoint(it)
Point *it;
{
    it->v = GetInteger(sizeof(A16BitInteger));
    it->h = GetInteger(sizeof(A16BitInteger));
}

GetRect(it)
Rect *it;
{
    GetPoint(&it->top);
    GetPoint(&it->bottom);
}

GetTE(it)
TextEdge *it;
{
    it->tBlockTE = GetInteger(sizeof(HandleDiskAddress));
    it->offsetTE = GetInteger(sizeof(A16BitInteger));
    GetPoint(&it->topTE);
    it->heightTE = GetInteger(sizeof(A16BitInteger));
}

GetEP(it)
EdgePair *it;
{
    GetTE(&it->startSelect);
    GetTE(&it->endSelect);
}

GetPaper(it)
PaperType *it;
{
    it->pHeight = GetInteger(sizeof(A16BitInteger));
    it->pWidth = GetInteger(sizeof(A16BitInteger));

}

GetBorder(it)
BorderType *it;
{
    it->leftBorder = GetInteger(sizeof(A32BitFixedPointNumber));
    it->rightBorder = GetInteger(sizeof(A32BitFixedPointNumber));
    it->nonStdPaper = GetInteger(sizeof(Boolean));
    it->altBorders = GetInteger(sizeof(Boolean));
}

GetCL(it)
ColLOType *it;
{
    it->maxColumn = GetInteger(sizeof(Byte));
    it->column = GetInteger(sizeof(Byte));
    it->widthOfColumns = GetInteger(sizeof(A16BitInteger));
    it->leftEdge = GetInteger(sizeof(A16BitInteger));
}

GetPL(it)
PageLOType *it;
{
    it->autoFootNote = GetInteger(sizeof(Boolean));
    it->fractWidths = GetInteger(sizeof(Boolean));
    GetBorder(&it->borders);
    GetCL(&it->colLayout);
    it->docVRes = GetInteger(sizeof(A16BitInteger));
    it->docHRes = GetInteger(sizeof(A16BitInteger));
    it->firstPageNumber = GetInteger(sizeof(A16BitInteger));
    it->pageSlop = GetInteger(sizeof(A16BitInteger));
    GetPaper(&it->paperSize);
    GetRect(&it->printableRect);
    it->rulerReduction = GetInteger(sizeof(A16BitInteger));
    it->unused8 = GetInteger(sizeof(A32BitInteger));
}

GetDS(it)
DocSizeType *it;
{
    it->startDiskAdr = GetInteger(sizeof(A32BitInteger));
    it->cleanEOF = GetInteger(sizeof(A32BitInteger));
    it->ourEOF = GetInteger(sizeof(A32BitInteger));
    it->fileEOF = GetInteger(sizeof(A32BitInteger));
    it->nextDiskAdr = GetInteger(sizeof(A32BitInteger));
}

GoTextElement(theElement)
MapElement *theElement;
{
    A16BitInteger byteCount;
    unsigned char *buffer;
    unsigned char *theChar;
    unsigned char dataChar;
    char *malloc();

    SeekTo(theElement->mapData & 0xffffff);
    byteCount = GetInteger(sizeof(byteCount));
    if (!byteCount)
	return;
    theChar = buffer = (unsigned char *) malloc(byteCount);
    if (!fread(buffer,byteCount,1,TheFile))
    {
	fprintf(stderr,"read error.\n");
	kill(getpid(),SIGQUIT);
	exit(1);
    }
    if (theElement->mapData & FORCEDPAGE)
	DoNewPage();
    while (theChar - buffer < byteCount)
    {
	switch(*theChar)
	{
	    case FmtFont:	/* Font, size, or style change */
		GoFontChange(&theChar);
		break;
	    case FmtGraphics:	/* Embedded graphics */
		SkipFmt(&theChar);
		break;
	    case FmtMarker:	/* Page #, date, time, and footnote marker */
		GoMarker(&theChar);
		break;
	    case FmtRuler:	/* Paragraph ruler formats */
		GoRulerChange(&theChar);
		break;
	    case Fmt4Unused:	/* Reserved for future use */
		SkipFmt(&theChar);
		break;
	    case FmtTabFill:	/* Tab fill */
		SkipFmt(&theChar);
		break;
	    case FmtY:		/* Subscript or superscript */
		SkipFmt(&theChar);
		break;
	    case Fmt1Unused:	/* Reserved for future use */
		SkipFmt(&theChar);
		break;
	    case FmtFooter:	/* Footer definition */
		break;
	    case FmtHeader:	/* Header definition */
		break;
	    case FmtFootnote:	/* Footnote definition */
		break;
	    case FmtSoftHyphen:	/* Soft hyphen */
		break;
	    case Fmt2Unused:	/* Reserved for future use */
		break;
	    case Fmt3Unused:	/* Reserved for future use */
		break;
	    case LiteralCode:	/* Used to represent characters F0 to FF */
		dataChar = *++theChar;
		dataChar += LiteralCode;
		DoDataChar(dataChar);
		break;
	    default:
		DoDataChar(*theChar);
		break;
	}
	theChar++;
    }
    free(buffer);
}

SkipFmt(thePointer)
unsigned char **thePointer;
{
    register unsigned char *theChar;

    for (theChar= *thePointer; *theChar != FmtEndFmt ; theChar++);

    *thePointer = theChar;	/* update pointer */
}

#define SETDATACHAR()\
    if ((dataChar = *theChar++)==LiteralCode)\
	dataChar += *theChar++

GoMarker(thePointer)
unsigned char **thePointer;
{
    unsigned char dataChar;
    unsigned char *theChar = *thePointer + 1;

    SETDATACHAR();
    DoMarker(dataChar);

    while (*theChar != FmtEndFmt) theChar++;

    *thePointer = theChar;	/* update pointer */
}

GoFontChange(thePointer)
unsigned char **thePointer;
{
    unsigned char dataChar;
    register unsigned char *theChar = *thePointer + 1;
    FSSType theFont;

    SETDATACHAR();
    theFont.fontID = dataChar * 256;
    SETDATACHAR();
    theFont.fontID += dataChar;
    SETDATACHAR();
    theFont.fontSize = dataChar;
    SETDATACHAR();
    theFont.fontStyle = dataChar;

    DoFontChange(&theFont);

    while (*theChar != FmtEndFmt) theChar++;

    *thePointer = theChar;
}

GoRulerChange(thePointer)
unsigned char **thePointer;
{
    unsigned char dataChar;
    RulerType theRuler;
    unsigned char *theChar;

    theChar = *thePointer + 1;
    SETDATACHAR();
    theRuler.leftMargin = dataChar * 256;
    SETDATACHAR();
    theRuler.leftMargin += dataChar;
    SETDATACHAR();
    theRuler.rightMargin = dataChar * 256;
    SETDATACHAR();
    theRuler.rightMargin += dataChar;
    SETDATACHAR();
    theRuler.paraIndent = dataChar * 256;
    SETDATACHAR();
    theRuler.paraIndent += dataChar;
    SETDATACHAR();
    theRuler.justification = dataChar;
    SETDATACHAR();
    theRuler.lineSpacing = dataChar;
    GetTabs(&theChar,theRuler.tabStops);

    DoRulerChange(&theRuler);

    *thePointer = theChar;
}

GetTabs(thePointer,tabStops)
unsigned char **thePointer;
A16BitInteger tabStops[];
{
    unsigned char *theChar;
    A16BitInteger *theStop;
    int byteCount=0;

    theChar = *thePointer;
    theStop = tabStops;
    *theStop = 0;

    for (; *theChar != FmtEndFmt ; theChar++)
    {
	*theStop += *theChar;
	if (*theChar != LiteralCode)
	{
	    if ((byteCount++ % 2)==1)
		*++theStop = 0;
	    else
		*theStop *= 256;
	}
    }

    *thePointer = theChar;
}
SHAR_EOF
fi
if test -f 'table.h'
then
	echo shar: "will not over-write existing file 'table.h'"
else
cat << \SHAR_EOF > 'table.h'
/* borrowed from mw2troff */
/*
    This file is Copyright (c) 1984, 1985 by Michael Caplinger
    and Van Jacobson.  They may be freely redistributed & modified provided
      a) this copyright notice is retained, unmodified, in all copies & all
	 derivatives.
      b) they are not redistributed for profit.
*/

char *ctrans[] = {
	"\\(sq",	/* 0 */
	"\\(sq",	/* 1 */
	"\\(sq",	/* 2 */
	"\\(sq",	/* 3 */
	"\\(sq",	/* 4 */
	"\\(sq",	/* 5 */
	"\\(sq",	/* 6 */
	"\\(sq",	/* 7 */
	"\b",		/* 8 */
	"\t",		/* 9 */
	"\n",		/* 10 */
	"\\(sq",	/* 11 */
	"\f",		/* 12 */
	"\n",		/* 13 */
	"\\(sq",	/* 14 */
	"\\(sq",	/* 15 */
	"\\(sq",	/* 16 */
	"\\(sq",	/* 17 */
	"\\(sq",	/* 18 */
	"\\(sq",	/* 19 */
	"\\(sq",	/* 20 */
	"\\(sq",	/* 21 */
	"\\(sq",	/* 22 */
	"\\(sq",	/* 23 */
	"\\(sq",	/* 24 */
	"\\(sq",	/* 25 */
	"\\(sq",	/* 26 */
	"\\(sq",	/* 27 */
	"\\(sq",	/* 28 */
	"\\(sq",	/* 29 */
	"\\(sq",	/* 30 */
	"\\(sq",	/* 31 */
	" ",	/* 32 */
	"!",	/* 33 */
	"\"",	/* 34 */
	"#",	/* 35 */
	"$",	/* 36 */
	"%",	/* 37 */
	"&",	/* 38 */
	"'",	/* 39 */
	"(",	/* 40 */
	")",	/* 41 */
	"*",	/* 42 */
	"+",	/* 43 */
	",",	/* 44 */
	"\\-",	/* 45 */
	".",	/* 46 */
	"/",	/* 47 */
	"0",	/* 48 */
	"1",	/* 49 */
	"2",	/* 50 */
	"3",	/* 51 */
	"4",	/* 52 */
	"5",	/* 53 */
	"6",	/* 54 */
	"7",	/* 55 */
	"8",	/* 56 */
	"9",	/* 57 */
	":",	/* 58 */
	";",	/* 59 */
	"<",	/* 60 */
	"=",	/* 61 */
	">",	/* 62 */
	"?",	/* 63 */
	"@",	/* 64 */
	"A",	/* 65 */
	"B",	/* 66 */
	"C",	/* 67 */
	"D",	/* 68 */
	"E",	/* 69 */
	"F",	/* 70 */
	"G",	/* 71 */
	"H",	/* 72 */
	"I",	/* 73 */
	"J",	/* 74 */
	"K",	/* 75 */
	"L",	/* 76 */
	"M",	/* 77 */
	"N",	/* 78 */
	"O",	/* 79 */
	"P",	/* 80 */
	"Q",	/* 81 */
	"R",	/* 82 */
	"S",	/* 83 */
	"T",	/* 84 */
	"U",	/* 85 */
	"V",	/* 86 */
	"W",	/* 87 */
	"X",	/* 88 */
	"Y",	/* 89 */
	"Z",	/* 90 */
	"[",	/* 91 */
	"\\\\",	/* 92 */
	"]",	/* 93 */
	"^",	/* 94 -  hat accent */
	"_",	/* 95 */
	"\\(aa",	/* 96 -  acute accent */
	"a",	/* 97 */
	"b",	/* 98 */
	"c",	/* 99 */
	"d",	/* 100 */
	"e",	/* 101 */
	"f",	/* 102 */
	"g",	/* 103 */
	"h",	/* 104 */
	"i",	/* 105 */
	"j",	/* 106 */
	"k",	/* 107 */
	"l",	/* 108 */
	"m",	/* 109 */
	"n",	/* 110 */
	"o",	/* 111 */
	"p",	/* 112 */
	"q",	/* 113 */
	"r",	/* 114 */
	"s",	/* 115 */
	"t",	/* 116 */
	"u",	/* 117 */
	"v",	/* 118 */
	"w",	/* 119 */
	"x",	/* 120 */
	"y",	/* 121 */
	"z",	/* 122 */
	"{",	/* 123 */
	"|",	/* 124 */
	"}",	/* 125 */
	"~",		/* 126 -  circumflex accent */
	"\\(sq",	/* 127 */
	"\\zA\\v'-1m'.\\h'-0.1m'.\\v'+1m'",	/* 128 -  upper A with omlat */
	"\\zA\\u\\(de\\d",	/* 129 -  upper circle A (A) */
	"C",		/* 130 -  upper C with cedilla */
	"\\o.E'.",	/* 131 -  upper E accent grave */
	"\\zN\\u~\\d",	/* 132 -  upper N with circumflex */
	"\\zO\\v'-1m'.\\h'-0.1m'.\\v'+1m'",	/* 133 -  upper O with omlat */
	"\\zU\\v'-1m'.\\h'-0.1m'.\\v'+1m'",	/* 134 -  upper U with omlat */
	"\\o.a'.",	/* 135 -  lower a accent grave */
	"\\o.a`.",	/* 136 -  lower a accent acute */
	"\\o.a^.",	/* 137 -  lower a with hat */
	"\\za\\u.\\h'-0.1m'.\\d",	/* 138 -  lower a with omlat */
	"\\o.a~.",	/* 139 -  lower a with circumflex */
	"\\o'a\\(de'",	/* 140 -  lower a with circle */
	"c",		/* 141 -  c with cedilla */
	"\\o.e'.",	/* 142 -  lower e accent grave */
	"\\o.e`.",	/* 143 -  lower e accent acute */
	"\\o.e^.",	/* 144 -  lower e with hat */
	"\\ze\\u.\\h'-0.1m'.\\d",	/* 145 -  lower e with omlat */
	"\\o.i'.",	/* 146 -  lower i accent grave */
	"\\o.i`.",	/* 147 -  lower i accent acute */
	"\\o.i^.",	/* 148 -  lower i with hat */
	"\\zi\\u.\\h'-0.1m'.\\d",	/* 149 - lower i with omlat */
	"\\o.n~.",	/* 150 -  lower n with circumflex */
	"\\o.o'.",	/* 151 -  lower o accent grave */
	"\\o.o`.",	/* 152 -  lower o accent acute */
	"\\o.o^.",	/* 153 -  lower o with hat */
	"\\zo\\u.\\h'-0.1m'.\\d",	/* 154 -  lower o with omlat */
	"\\o.o~.",	/* 155 -  lower o with circumflex */
	"\\o.u'.",	/* 156 -  lower u accent grave */
	"\\o.u`.",	/* 157 -  lower u accent acute */
	"\\o.u^.",	/* 158 -  lower u with hat */
	"\\zu\\u.\\h'-0.1m'.\\d",	/* 159 -  lower u with omlat */
	"\\(dg",	/* 160 -  dagger */
	"\\(de",	/* 161 -  degrees (shift option 8) */
	"\\o'c/'",	/* 162 -  cents */
	"\\f2\\o'L-'\\fP",	/* 163 -  pounds (currency) */
	"\\(sc",	/* 164 -  section mark */
	"\\(bu",	/* 165 -  bullet */
	"\\(rh",	/* 166 -  paragraph */
	"\\(*b",	/* 167 -  beta (german "ss") */
	"\\(rg",	/* 168 -  registered */
	"\\(co",	/* 169 -  copyright */
	"\\u\\s-4TM\\s0\\d",	/* 170 -  trademark */
	"\\(ag",	/* 171 -  grave accent */
	"\\u.\\h'-0.1m'.\\d",	/* 172 -  oomlat accent */
	"\\(!=",	/* 173 -  not equal */
	"\\f2A\\fP\\h'-0.2m'E",		/* 174 -  upper AE ligature */
	"\\zO/",	/* 175 -  slash upper O (O) */
	"\\(if",	/* 176 -  infinity */
	"\\(+-",	/* 177 -  plus minus (shift option =) */
	"\\(<=",	/* 178 -  <= */
	"\\(>=",	/* 179 -  >= */
	"\\o'Y\\s-2=\\s0'",	/* 180 -  yen */
	"\\(*m",	/* 181 -  lower mu */
	"\\(pd",	/* 182 -  "partial" */
	"\\(*S",	/* 183 -  upper sigma */
	"\\(*P",	/* 184 -  upper PI (P) */
	"\\(*p",	/* 185 -  lower pi */
	"\\(is",	/* 186 -  integral sign */
	"\\u\\za\\(ul\\d'",	/* 187 -  underbar lowercase a */
	"\\u\\zo\\(ul\\d'",	/* 188 -  underbar lowercase o */
	"\\(*W",	/* 189 -  upper omega */
	"a\\h'-0.2m'e",		/* 190 -  lower ae ligature */
	"\\o'o/'",	/* 191 -  slashed lower o */
	"?",		/* 192 -  upside down ? (?) */
	"\\(*i",	/* 193 -  lower case i */
	"\\(no",	/* 194 -  negation */
	"\\(sr",	/* 195 -  square root or check mark */
	"\\z\\(is\\s-2\\(ci\\s0",	/* 196 -  contour integral */
	"\\(~=",	/* 197 -  approx */
	"\\(*D",	/* 198 -  triangle (upper delta) */
	"\\s-2<\\h'-0.3m'<\\s0",	/* 199 -  open double angle brackets */
	"\\s-2>\\h'-0.3m'>\\s0",	/* 200 -  close double angles */
	"...",		/* 201 -  elipses (3 dots) */
	"\\ ",		/* 202 -  unpaddable space */
	"\\o'`A'",	/* 203 -  `A */
	"\\o'~A'",	/* 203 -  A with circumflex */
	"\\o'~O'",	/* 203 -  O with circumflex */
	"O\\h'-0.1m'E",		/* 206 -  upper OE ligature */
	"o\\h'-0.1m'e",		/* 207 -  lower oe ligature */
	"\\(hy",	/* 208 -  hyphen */
	"\\(em",	/* 209 -  m dash (shift option -) */
	"``",		/* 210 -  back double quote */
	"''",		/* 211 -  close double quote */
	"`",		/* 212 -  back single quote */
	"'",		/* 213 -  close single quote */
	"\\(di",	/* 214 -  divide */
	"\\(gr",	/* 215 -  diamond (V) */
	"\\zy\\u.\\h'-0.1m'.\\d",	/* 216 -  y with omlat */
	"\\(sq",	/* 217 */
	"\\(sq",	/* 218 */
	"\\(sq",	/* 219 */
	"\\(sq",	/* 220 */
	"\\(sq",	/* 221 */
	"\\(sq",	/* 222 */
	"\\(sq",	/* 223 */
	"\\(sq",	/* 224 */
	"\\(sq",	/* 225 */
	"\\(sq",	/* 226 */
	"\\(sq",	/* 227 */
	"\\(sq",	/* 228 */
	"\\(sq",	/* 229 */
	"\\(sq",	/* 230 */
	"\\(sq",	/* 231 */
	"\\(sq",	/* 232 */
	"\\(sq",	/* 233 */
	"\\(sq",	/* 234 */
	"\\(sq",	/* 235 */
	"\\(sq",	/* 236 */
	"\\(sq",	/* 237 */
	"\\(sq",	/* 238 */
	"\\(sq",	/* 239 */
	"\\(sq",	/* 240 */
	"\\(sq",	/* 241 */
	"\\(sq",	/* 242 */
	"\\(sq",	/* 243 */
	"\\(sq",	/* 244 */
	"\\(sq",	/* 245 */
	"\\(sq",	/* 246 */
	"\\(sq",	/* 247 */
	"\\(sq",	/* 248 */
	"\\(sq",	/* 249 */
	"\\(sq",	/* 250 -  box (option h) */
	"\\(sq",	/* 251 -  box (option k) */
	"\\(sq",	/* 252 */
	"\\(sq",	/* 253 */
	"\\(sq",	/* 254 */
	"\\(sq",	/* 255 */
	0 };
SHAR_EOF
fi
if test -f 'roff.c'
then
	echo shar: "will not over-write existing file 'roff.c'"
else
cat << \SHAR_EOF > 'roff.c'
/***********************************************************************
* This program Copyright 1988 by Steven Dorner and the University of
* Illinois Board of Trustees
* 
* No warrantees expressed or implied.
* 
* This program may be redistributed, provided no charge is made for it.
***********************************************************************/
#include <stdio.h>
#include <ctype.h>
#include "wn.h"
#include "table.h"
FSSType NewFont;
FSSType OldFont;
RulerType OldRuler;
RulerType NewRuler;

int InALine = 0;
int InAPara = 0;
int ChangedFont = 1;
int ChangedRuler = 1;
int FooterHeight;
char *FontName();
A16BitInteger FontID();
#define HADJUST(x)	(x>72 ? x-72 : 0)
#define MAXLINE		64
typedef struct fontentry FontEntry;
struct fontentry
{
    int id;		/* the font id */
    char *name[4];	/* font names */
};

FontEntry FontTable[] =
{
    FontTimes,		"R",	"B",	"I",	"(BI",
    /*FontCourier,	"(PR",	"(PB",	"I",	"(BI",*/
    0,			0,	0,	0,	0
};


DoBegin()
{
    printf(".lg 0\n");		/* turn off troff ligatures */
    /* be sure old ruler and font are different from new ruler and font */
    OldRuler.leftMargin = 100000;
    OldFont.fontID = 255;
}

SetHFTraps(headHeight,footHeight)
int headHeight, footHeight;
{
    /* header */
    printf(".wh 0 hh\n");
    printf(".de hh\n.sp %dp\n..\n",headHeight);
    /* footer */
    printf(".wh %dp ff\n",-footHeight);
    printf(".de ff\n.bp\n..\n");
    FooterHeight = footHeight;
}

DoEnd()
{
}

DoFontChange(theChange)
FSSType *theChange;
{
    NewFont.fontID = FontID(theChange->fontID);
    NewFont.fontSize = theChange->fontSize;
    NewFont.fontStyle = theChange->fontStyle & CanDoStyleMask;
    ChangedFont = 1;
}

DoDataChar(theChar)
unsigned char theChar;
{
    switch (theChar)
    {
	case '\r':
	    if (InALine)
		puts("\n.br");
	    else
		puts(".sp");
	    if (ChangedRuler)
		ChangeTheRuler();
	    InAPara = InALine = 0;
	    break;
	default:
	    if (!InAPara && ChangedRuler)
		ChangeTheRuler();
	    if (ChangedFont)
		ChangeTheFont();

	    if (!InAPara && NewRuler.leftMargin != NewRuler.paraIndent)
	    {
		NewLine();
		printf("'ti %dp\n",NewRuler.paraIndent-NewRuler.leftMargin);
	    }

	    if (!InALine && isspace(theChar))
		fputs("\\&",stdout);
	    if (NewFont.fontStyle & StyleUline)
		printf("\\o'_%s'",ctrans[theChar]);
	    else
		fputs(ctrans[theChar],stdout);
	    InAPara = InALine = 1;
	    break;
    }
}

DoMarker(theMarker)
unsigned int theMarker;
{
    switch(theMarker)
    {
	case IDPNumMarker:
	    if (!InAPara && ChangedRuler)
		ChangeTheRuler();
	    if (ChangedFont)
		ChangeTheFont();
	    fputs("\\n%",stdout);
	    InALine = InAPara = 1;
	    break;
	case IDDateMarker:
	    if (!InAPara && ChangedRuler)
		ChangeTheRuler();
	    if (ChangedFont)
		ChangeTheFont();
	    fputs("\\n(mo/\\n(dy/\\n(yr",stdout);
	    InALine = InAPara = 1;
	    break;
	case IDTimeMarker:
	    fputs("Dropping time marker.\n",stderr);
	    break;
	case IDFNumMarker:
	    fputs("Dropping footnote marker.\n",stderr);
	    break;
    }
}

DoRulerChange(theRuler)
RulerType *theRuler;
{
    bcopy(theRuler,&NewRuler,sizeof(NewRuler));
    ChangedRuler = 1;
}

ChangeTheFont()
{
    ChangedFont = 0;		/* reset flag */

    if (!bcmp(&NewFont,&OldFont,sizeof(OldFont)))
	return;

    printf("\\f%s",FontName());	/* this will do plain, bold, italic as well */
    printf("\\s%d",(NewFont.fontSize*10)/12);
    bcopy(&NewFont,&OldFont,sizeof(OldFont));
    InALine = 1;
}

ChangeTheRuler()
{
    A16BitInteger *theTS;

    ChangedRuler = 0;
    if (!bcmp(&NewRuler,&OldRuler,sizeof(NewRuler)))
	return;

    NewLine();
    printf("'vs %d\n",NewRuler.lineSpacing);
    printf("'ad %s\n",NewRuler.justification==JLeft ? "l" :
		       ((NewRuler.justification==JJust ? "b" :
		       (NewRuler.justification==JCenter ? "c" : "r"))));
    printf("'in %dp\n",HADJUST(NewRuler.leftMargin));
    printf("'ll %dp\n",HADJUST(NewRuler.rightMargin));
    if (*(theTS = NewRuler.tabStops) ||
	NewRuler.paraIndent<NewRuler.leftMargin)
    {
	printf("'ta");
	if (NewRuler.paraIndent < NewRuler.leftMargin)
	    printf(" %dp",NewRuler.leftMargin-NewRuler.paraIndent);
	for (;*theTS;theTS++)
	{
	    switch (*theTS & 0x3)
	    {
		case 1:
		    printf(" %dpC",((*theTS>>2) & 0x3fff) -
			(NewRuler.leftMargin));
		    break;
		case 2:
		    printf(" %dpR",((*theTS>>2) & 0x3fff) -
			(NewRuler.leftMargin));
		    break;
		default:
		    printf(" %dp",((*theTS>>2) & 0x3fff) -
			(NewRuler.leftMargin));
		    break;
	    }
	}
	putchar('\n');
    }
    bcopy(&NewRuler,&OldRuler,sizeof(RulerType));
}

DoNewPage()
{
    NewLine();
    puts(".ff");
}

char *
FontName()
{
    FontEntry *theEntry;

    for (theEntry=FontTable; theEntry->name[1] ; theEntry++)
	if (theEntry->id==NewFont.fontID)
	    return (theEntry->name[NewFont.fontStyle & 0x3]);
    return (FontTable[0].name[NewFont.fontStyle & 0x3]);
}

A16BitInteger
FontID(theID)
A16BitInteger theID;
{
    FontEntry *theEntry;

    for (theEntry=FontTable; theEntry->name[1] ; theEntry++)
	if (theEntry->id==theID)
	    return (theEntry->id);
    /*fprintf(stderr,"Font id %d not mapped.\n",theID,FontTable[0].id);*/
    return (FontTable[0].id);
}
	    
NewLine()
{
    if (InALine)
    {
	putchar('\n');
	InALine = 0;
    }
}
SHAR_EOF
fi
exit 0
#	End of shell archive

-- 
Steve Dorner, U of Illinois Computing Services Office
Internet: s-dorner@uiuc.edu  UUCP: {convex,uunet}!uiucuxc!dorner
IfUMust:  (217) 244-1765