[comp.sources.amiga] disklib

ain@j.cc.purdue.edu (Patrick White) (06/27/88)

Submitted by:	snyderw@life.pawl.rpi.edu
Summary:	Generate disk library listings from $$DES$$ files in the directories.
Poster Boy:	Patrick White	(ain@j.cc.purdue.edu)
Archive Name:	sources/amiga/volume5/disklib.d.sh.Z binaries/amiga/volume8/disklib.d.sh.Z
Tested.
 
NOTES:
   This is really two programs -- lib and tolib.
   The $$DES$$ file for these programs is in the docs, along with a brief
description of the format of a $$DES$$ file (basically none).
 
 
-- Pat White   (co-moderator comp.sources/binaries.amiga)
ARPA/UUCP: j.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM  PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906
 
========================================
 
#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	lib.doc
#	DESformat
#	$$DES$$
# This archive created: Wed Jun 22 12:22:25 1988
# By:	Patrick White (PUCC Land, USA)
echo shar: extracting lib.doc '(8301 characters)'
cat << \SHAR_EOF > lib.doc

			Lib, ToLib

		Disk Library Documentation System

	By Wilson Snyder		(c) January 1988

	This package contains two programs, Lib which is used to
	print information on the disk, and ToLib which does simple
	translation on Fred Fish's README.list## files.  (Or, on
	later disk Contents files.)

	This program is PUBLIC DOMAIN, but if you wish to support
	a college student working on software, your donations are
	greatly appreciated.

	NOTICE:

	This program was written as a service to the amiga
	users.  This program may be used by all parties, including
	sale (see below) as long as the author's name and address
	remains intact in the program and documentation.
	Distribution of this program by parties selling it
	as part of a commercial for-profit package of over $10
	must contact the address below before such a package is sold.

	I make no warranties over this program, performance,
	etc.  And any costs incurred by this program, or its
	actions are placed on the user.

	PLEASE FORWARD INPROVEMENTS MADE TO THIS PROGRAM TO:

	Wilson Snyder, 15 Davis Parkway, South Burlington, VT 05403

				LIB

Usage:
	LIB [directoryname] [-s[ize]] [-h[eader]]
	TOLIB (input_contents_file) (outputfile) ["the disk name"]
	[] optional, () required.

Description:

	  Lib searches the disk tree starting at the directory name
	provided, or the root of the current disk if no directory
	is provided.  The program prints out each directory in
	sorted order, with the size if the -s option is used, and
	with page headers if the -h option is used.
	If a file named $$DES$$ is found in any one of the directories
	the contents of the file are printed out using simple
	word justification and page numbering (-h option).

	  ToLib converts a contents or readme.list file to a single
	file containing several $$DES$$ files-in-one for each
	entry in the contents file.  The computer assumes that the
	program name starts in the first column, and that the
	description of the file is indented by a tab or space from the
	first column.  When the program encounters a new program name
	it prints the optional diskname.  After the program is finished
	I load the file into my editor, and chop the file into $$DES$$
	files under each subdirectory, and a $$DES$$ file for the root.

Why:

	  Fred Fish provides a excellent service to the Amiga
	community, but he must distribute information as he gets it,
	and has to pack many different types of programs on each
	disk.  When I receive his disks I prefer to seperate the
	programs by topic, onto one disk per topic.  Fred provides
	a contents file on his disks, but since I want the description
	information on my topic disks, I would have to use a editor
	to delete the description from the distribution disk and place
	it onto a contents file on each topic disk.
	  This program offers another solution.  When I recieve a new
	Fred Fish (or other PD?!) disk, I run the TOLIB program which
	changes the contents file into a form ready to be split into
	sub files.  I then put the description for each file into that
	file's directory so that copying the directory [ALL] will also
	copy the description for that program.
	  Now, when I want a list of the contents of my disks I can
	just run the LIB program on each disk, and it will produce a
	file simular to the Contents file, but much more accurate as
	it will display files even without descriptions, and will not
	display descriptions for files that do not exist on the disk.
	(Thus deleting/moving the directory of the program automatically
	deletes/moves the description.)

The Future:

	  To make life easy for those who split up the programs on
	the Fred Fish disks, I Propose that Fred distribute his disks
	with the $$DES$$ files.  Thus, people who donate to the library
	can just give Fred a $$DES$$ file, which he may edit.  Once
	he has copied all of the programs he wishes onto a distribution
	disk, he need only run the LIB program to produce a master
	contents file for the benefit of users without the LIB program,
	and also for quick viewing of the contents.  Information on the
	disk itself, for example the words "Disk ### of the freely..."
	can simply be placed on the root $$DES$$ file.


Example:

	This is a dump of one of my games disks:
	(Envoked with "LIB >output df1: -h -s")
	Information in ALL CAPS added for information.


Page 1                                                         Games 2
^- PAGE NUMBER						DISK NAME --^

Games 2
^- ROOT NAME

	Disk 1 of Public Domain Games.
	^- $$DES$$ file of root

        Canfield
                Total size 27912 bytes.
	^- $$DES$$ not found, just printed the size.

        Conquest
		V---  $$DES$$ file,  words "Fred Fish 24" added by TOLIB.
                Fred Fish 24 
                You control an interstellar empire, decide which star 
                systems to explore, which planets to colonize, etc.  
                The computer will also be building its own empire and 
                competing with you for resources.  The one with the 
                greatest population at the end wins.  First distributed 
                in executable form only on disk number AM010.  This 
                distribution includes source. 
                Author:  ported to Amiga by Rob Shimbo 
                
                Total size 331234 bytes.

        Cosmo
                Fred Fish 40 
                An "asteriods" clone.  Suggested $6 donation. 
                Author:  John Harris 
                
                Total size 20604 bytes.

        DietAid
                Fred Fish 36 
                Diet planning aid to allow the user to compile lists of 
                ingredients (recipes) and automatically compute calorie 
                totals, etc.  This is a shareware program ($10 
                suggested) that was submitted by the author for 
                inclusion in the library. 
                Author: Terry Gintz 
                
                Total size 102856 bytes.

        Klondike
                Total size 25077 bytes.
        Puzzle
                Fred Fish 32 
                Simulation of puzzle with moving square tiles.  
                Executable only. 
                Author: Bill Beogelein 
                
                Total size 9121 bytes.

        Reversi
                Fred Fish 38 
                Program to play reversi game.  Version 6.1. 
                Author:  Manuel Almudevar 
                
                Total size 47180 bytes.

Page 2                                                         Games 2
^----- PAGE BREAK

        Rocket
                Fred Fish 82 
                Another interesting Workbench display hack.  This one 
                is really a game in disguise.  Binary only. 
                Author:  Peter da Silva 
                
                Total size 8027 bytes.

        Sword
                Fred Fish 32 
                Sword of Fallen Angel.  Text adventure game written in 
                AmigaBasic. 
                Author: Andry Rachmat 
                
                Total size 141277 bytes.

        TunnelVision
                Fred Fish 36 
                Another fine ABasiC game from David Addison.  This is  
                a maze game with a 3-D perspective view from inside the 
                maze. 
                Author: David Addison 
                
		V--- DIRECTORIES UNDER TUNNELVISION
                devs
                        Total size 232 bytes.
                s
                        Total size 134 bytes.
		V--- TUNNELVISION SIZE
                Total size 53246 bytes.

	V--- TOTAL ROOT SIZE
        Total size 766534 bytes.

Limitations / Suggestions:

	1.	Each program must be in its own subdirectory, this is
		standard for the Fred Fish series, and the way I wish
		to keep my disks.

	2.	The text output formatter is simple, no frills.

	3.	The TOLIB program just does simple processing, spliting
		up the output must be done by hand.  This could be
		automated at some point.

	4.	Command line options do not exist for page length,
		margins, etc.

	5.	A option could be added to LIB to show all of the files
		on the disk.

	6.	A header could be added providing information on the
		disk, percent full, time, date, etc.

	7.	No control-C trap exists.
SHAR_EOF
if test 8301 -ne "`wc -c lib.doc`"
then
echo shar: error transmitting lib.doc '(should have been 8301 characters)'
fi
echo shar: extracting DESformat '(634 characters)'
cat << \SHAR_EOF > DESformat
	Sorry for the ommission of the $$DES$$ file format for my LIB 
program.  TOLIB creates these files.  The $$DES$$ file is simply any text
file that should be printed out when the LIB program is run.  The format that
I personally use is:

	Disk From (Fred Fish #)
	A program which does everything.  Other notes.  Info.
	Author

	The program does not care about the format, except that continuations
onto the next lines should be proceded by a &.   This allows the computer
to rejustify the words to make them fit within the margins. (So the & has
the effect of making the justification routine ignore the following
newline character.)
SHAR_EOF
if test 634 -ne "`wc -c DESformat`"
then
echo shar: error transmitting DESformat '(should have been 634 characters)'
fi
echo shar: extracting $$DES$$ '(191 characters)'
cat << \SHAR_EOF > $$DES$$
Two programs, Lib and ToLib, designed to make program descriptions easier &
to use by placing them with the program in it's subdirectory.  First &
ever public release.
Author: Wilson Snyder.
SHAR_EOF
if test 191 -ne "`wc -c $$DES$$`"
then
echo shar: error transmitting $$DES$$ '(should have been 191 characters)'
fi
#	End of shell archive
exit 0

ain@j.cc.purdue.edu (Patrick White) (06/27/88)

Submitted by:	snyderw@life.pawl.rpi.edu
Summary:	Generate disk library listings from $$DES$$ files in the directories.
Poster Boy:	Patrick White	(ain@j.cc.purdue.edu)
Archive Name:	sources/amiga/volume5/disklib.s.sh.Z
Tested.
 
NOTES:
   This is really two programs -- lib and tolib.
   The $$DES$$ file for these programs is in the docs, along with a brief
description of the format of a $$DES$$ file (basically none).
 
 
-- Pat White   (co-moderator comp.sources/binaries.amiga)
ARPA/UUCP: j.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM  PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906
 
========================================
 
#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	lib.c
#	tolib.c
# This archive created: Wed Jun 22 12:20:29 1988
# By:	Patrick White (PUCC Land, USA)
echo shar: extracting lib.c '(12961 characters)'
cat << \SHAR_EOF > lib.c
/***************************************************************
*
*			Lib.c
*
*		Disk Library Documentation System
*			Main Program
*
*	By Wilson Snyder		(c) January 1988
*
****************************************************************
*
*	NOTICE:
*
*	This program was written as a service to the amiga
*	users.  This program may be used by all parties, including
*	sale (see below) as long as the author's name and address
*	remains intact in the program and documentation.
*	Distribution of this program by parties selling it
*	as part of a commercial for-profit package of over $10
*	must contact the address below before such a package is sold.
*
*	I make no warranties over this program, performance,
*	etc.  And any costs incurred by this program, or its
*	actions are placed on the user.
*
*	PLEASE FORWARD INPROVEMENTS MADE TO THIS PROGRAM TO:
*
*	Wilson Snyder, 15 Davis Parkway, South Burlington, VT 05403
*
****************************************************************
*
*	AddName and base for Process taken from the TSIZE
*	utility written by the excellent work of the
*	Software Distillery.
*
****************************************************************/

#include "libraries/dosextens.h"
#include "ctype.h"
#include "stdio.h"

#define VERSION	"AMIGA-LIB.  Version 1.0.2.  By Wilson Snyder"
#define DESC "$$DES$$"

#define PERSUB	8	/* Characters to indent per subdirectory */
#define INFOIND 8	/* Indent for description and filesize */
#define RM	75	/* Right margin */
#define LM	0	/* Left margin */
#define TM	1	/* Top margin */
#define HM	2	/* Header margin (lines after header) */
#define LINES	60	/* Lines per page */

BPTR	Lock();		/* Define functions... */
BOOL	Examine();
BOOL	ExNext();

char	path [256];		/* Current search path */
char	header [80];		/* Header for top line */
BOOL	prtsize = FALSE;	/* Print the path size information */
BOOL	prtheader = FALSE;	/* Print the header and page breaks */

struct Sortem {		/* Linked list for insertion sort of directory names */
	char	FileName[108];	/* Directory name */
	struct Sortem *Next;	/* Pointer to next */
	};

/***************************************************************
*			ADDNAME
*
*	Add filename to the end of the current path.
*
*	Routine taken from from TSIZE utility by the Software Distillery.
***************************************************************/

int	AddName(name, len)
	register char *name;
	int len;
	{
	register char *p;	/* current position in path */
	register int i = 0;	/* added length counter */
	char ch;		/* last character of current path */

	p = path + len;

	/* add a slash between path and name if legal */
	if (len != 0 && (ch = path[len-1]) != '/' && ch != ':') {
		*p++ = '/';
		i++;
		}

	/* copy name to end of path (including null terminator) */
	while (*p++ = *name++) i++;

	/* return new length of path */
	return (len + i);
	}


/***************************************************************
*			FILECMP
*	Compare two filenames for sort routine (case insensitive.)
***************************************************************/

int	filecmp(a,b)
	char *a,*b;
	{
	for (;toupper(*a)==toupper(*b);a++,b++)
		if (*a=='\0') return (0);
	return (toupper(*a)-toupper(*b));
	}


/***************************************************************
*			INDENT
*	Indent a number of spaces.  Outputted to stdout.
***************************************************************/

void	Indent(num)
	int num;
	{
	while (num--)	putchar (' ');
	}

/***************************************************************
*			HEADER
*	Print header every so many lines.
***************************************************************/

void	Header(inc)
	int inc;
	{
	static int linecount;		/* Number of lines down */
	static int page;		/* Current page number */
	int t;				/* Temp */

	if (inc)
		linecount += inc;
	else	{
		/* 0 increment resets information */
		linecount = 0;
		page = 0;
		}

	if (linecount>LINES && prtheader) {
		/* Time to print the header */
		putchar ('\f');
		page++;
		for (t=TM;t;t--)	putchar ('\n');
		printf (header,page);
		for (t=HM;t;t--)	putchar ('\n');
		linecount = TM + HM + 1;
		}
	}


/***************************************************************
*			ROOT
*	Print information for the page header
***************************************************************/

BOOL	Root()
	{
	struct FileInfoBlock *info;	/* pointer to file info */
	BPTR lock;			/* pointer to file lock */
	int t,loc;			/* temp stuff */

	/* allocate an info block (must be longword alligned) */
	if (!(info = (struct FileInfoBlock *)
		AllocMem(sizeof(struct FileInfoBlock), 0))) {
			printf ("Out of memory.\n");
			return (TRUE);
			}

	/* try to obtain lock on current file */
	if (!(lock = Lock(path, ACCESS_READ))) {
		printf ("Invalid file or directory, '%s'.\n", path);
		FreeMem(info, sizeof(struct FileInfoBlock));
		return (TRUE);
		}

	/* get information on file or directory associated with lock */
	if (!Examine(lock, info)) {
		printf ("Error examining locked file or directory.\n");
		UnLock(lock);
		FreeMem(info, sizeof(struct FileInfoBlock));
		return (TRUE);
		}

	/* Make sure user specified a directory, not a file */
	if (info->fib_DirEntryType <= 0) {
		printf ("Must specify a directory, not a file.\n");
		UnLock(lock);
		FreeMem(info, sizeof(struct FileInfoBlock));
		return (TRUE);
		}

	/* Build Header line (will be used with printf) */
	loc = 0;
	for (t=LM;t;t--)	header[loc++] = ' ';
	strcpy (&header[loc], "Page %-4d");
	loc += 9;
	for (t=RM-loc-strlen(info->fib_FileName);t;t--)	header[loc++] = ' ';
	strcpy (&header[loc],info->fib_FileName);
	loc += strlen(info->fib_FileName);
	header[loc++] = '\n';
	header[loc] = '\0';

	/* Initalize header printer, then force header printing */
	Header (0);
	Header (LINES+2);

	UnLock(lock);
	FreeMem(info, sizeof(struct FileInfoBlock));
	return (FALSE);
	}


/***************************************************************
*			BOTTOM
*	Display size information at bottom of directory.
***************************************************************/

void	Bottom (depth,size,found)
	int depth;
	long size;
	BOOL found;
	{
	if (prtsize) {
		Indent (depth*PERSUB+INFOIND+LM);
		printf ("Total size %ld bytes.\n", size);
		if (found) printf ("\n");
		Header (2);
		}
	}

/***************************************************************
*			DISPLAY
*	Display information from the DESC file in the directory.
***************************************************************/

BOOL	Display (depth,dirname)
	int depth;
	char *dirname;
	{
	FILE *desc;		/* DESCription file info */
	BOOL found;		/* Found a description file */
	int lineloc;		/* Location on the output line */
	int wordlen;		/* Length of word in the buffer */
	char wordstore[RM+10];	/* Storage for current word */
	BOOL Cont;		/* & encountered, ignore return */
	BOOL Long;		/* Long line/word just printed */
	char ch;		/* Character from file */
	int t,lm;		/* temp */

	/* Print directory name */
	Header (2);
	Indent (depth*PERSUB+LM);
	printf ("%s\n", dirname);

	/* Add DESC filename to path, attempt to open the file */
	t = strlen(path);
	AddName (DESC,t);
	found = ((desc=fopen(path,"r"))!=0);

	/* If found, justify the file on the way out */
	if (found) {
		lm = depth*PERSUB+INFOIND+LM;
		lineloc = lm;
		Indent (lm);
		wordlen = 0;
		Cont = FALSE;
		Long = FALSE;
		/* Process one character at a time */
		while ((ch=getc(desc))!=EOF) {
			/* Ignore return if proceded by a & */
			if ((ch=='\n') && Cont) {
				Cont = FALSE;
				continue;
				}
			if (Cont) {	/* & not proceded by a return */
				wordstore[wordlen++] = '&';
				Cont = FALSE;
				}
			/* Dump out the current word */
			if (ch==' ' || ch=='\n') {
				wordstore[wordlen] = '\0';
				printf ("%s ",wordstore);
				lineloc += wordlen + 1;
				wordlen = 0;
				if (Long || ch=='\n') {
					putchar ('\n');
					Header(1);
					Indent (lm);
					lineloc = lm;
					Long = FALSE;
					}
				continue;
				}
			/* Force return if line goes over right margin */
			if (((wordlen+lineloc)>RM) || (wordlen>(RM-lm))) {
				if (wordlen>(RM-lm)) {
					wordstore[wordlen] = '\0';
					printf ("%s",wordstore);
					wordlen = 0;
					Long = TRUE;
					}
				putchar ('\n');
				Header(1);
				Indent (lm);
				lineloc = lm;
				}
			/* Check for continuation character */
			if (ch=='&')	Cont = TRUE;
			else	wordstore[wordlen++] = ch;
			}
		fclose (desc);
		/* Dump out any remaining word in the buffer */
		if (wordlen) {
			wordstore[wordlen] = '\0';
			puts (wordstore);
			putchar ('\n');
			Header (1);
			lineloc=0;
			}
		if (lineloc>lm)	putchar('\n');
		putchar('\n');
		}

	/* Restore path, return status if file was found */
	path[t] = '\0';
	return (found);
	}


/*************************************************************
*			PROCESS
*
*	Find the size of a directory tree by adding the sizes
*	of all files in the directory and all of its subdirectories.
*
*	General directory searching concept taken from TSIZE
*	utility by the Software Distillery.
************************************************************/

long	Process(len,depth)
	int len;	/* Length of path name */
	int depth;	/* Number of directories down */
	{
	struct FileInfoBlock *info = NULL;	/* pointer to file info */
	struct Sortem *sort_top = NULL;		/* top of sort list */
	struct Sortem *sort_cur = NULL;		/* current sort list loc */
	struct Sortem *sort_tmp = NULL;		/* current sort temp loc */
	struct Sortem *sort_last= NULL;		/* last sort temp loc */
	long size = 0;				/* running total of file size */
	BPTR lock;				/* pointer to file lock */
	BOOL found;				/* found DESC file */

	/* Try to obtain lock on current directory */
	if (!(lock = Lock(path, ACCESS_READ))) {
		printf ("Invalid directory, '%s'.\n", path);
		goto EXIT;
		}

	/* Allocate an info block (must be longword alligned) */
	if (!(info = (struct FileInfoBlock *)
		AllocMem(sizeof(struct FileInfoBlock), 0))) {
			printf ("Out of memory.\n");
			goto EXIT;
			}

	/* Get information on file or directory associated with lock */
	if (!Examine(lock, info)) {
		printf ("Error examining locked directory.\n");
		goto EXIT;
		}

	/* This should not happen, but... */
	if (info->fib_DirEntryType <= 0)  {
		printf ("Locked a file, not directory.\n");
		goto EXIT;
		}

	/* Display top of directory header */
	found = Display (depth,info->fib_FileName);

	/* Read this directory */
	while (ExNext(lock, info)) {
		/* This is a directory */
		if (info->fib_DirEntryType > 0)	{
			/* sub-directory, allocate sortem node */
			if (!(sort_cur = (struct Sortem *)
					AllocMem(sizeof(struct Sortem), 0))) {
				printf ("Out of memory.\n");
				break;
				}
			strcpy(sort_cur->FileName,info->fib_FileName);
			sort_cur->Next = NULL;

			/* Alphabetical insertion sort */
			/* Find insertion location for new node */
			for (sort_tmp = sort_top; sort_tmp; 
				sort_tmp = sort_tmp->Next) {
				if (filecmp(sort_tmp->FileName,info->fib_FileName)>0)
					break;
				sort_last = sort_tmp;
				}

			/* Insert the node */
			if (sort_tmp==sort_top) {
				sort_cur->Next = sort_top;
				sort_top = sort_cur;
				}
			else	if (!sort_tmp) {
				sort_cur->Next = NULL;
				sort_last->Next = sort_cur;
				}
				else {
					sort_cur->Next = sort_last->Next;
					sort_last->Next = sort_cur;
					}
			sort_cur = NULL;
			}
		else 	/* found a file, just add size */
			size += info->fib_Size;
		}

	/* Transverse sorted list, process then deallocate the node */
	for (sort_tmp = sort_top; sort_tmp; sort_tmp = sort_last) {
		size += Process(AddName(sort_tmp->FileName, len),depth+1);
		sort_last = sort_tmp->Next;
		FreeMem(sort_tmp, sizeof(struct Sortem));
		}

	/* Repair path */
	path[len] = '\0';

	/* Print bottom of directory information */
	Bottom (depth, size, found);

	EXIT:
	if (info) FreeMem(info, sizeof(struct FileInfoBlock));
	if (lock) UnLock(lock);
	return(size);
	}

/***************************************************************
*			MAIN
***************************************************************/

main(argc, argv)
	int argc;
	char *argv[];
	{
	int len;	/* Length of file name given on command line */
	int t;		/* Temp variable */

	/* Help information */
	if (argv[1][0]=='?') {
		printf ("%s\nUseage: %s [Read-Path] [-size]\n",
			VERSION, argv[0]);
		exit (0);
		}

	/* parse command line (len used as temp param counter) */
	for (len=1;len<argc;len++)
		if (argv[len][0]=='-') {	/* switch */
			switch (toupper(argv[len][1])) {
				case 'S':	/* Size Flag */
					prtsize = TRUE;
					break;
				case 'H':	/* Header Flag */
					prtheader = TRUE;
					break;
				/* ADD OTHER SWITCHES HERE */
				default:
					printf ("Bad Switch.\n");
				}

			/* Drop this argument */
			argc--;
			for (t=len;t<argc;t++)	argv[t] = argv[t+1];
			}

	/* Process pathname */
	if (argc>1)
		len = AddName(argv[1], 0);
	else	len = AddName(":", 0);

	/* Check root info, exit if invalid */
	if (Root()) return(20);

	/* Process root directory */
	(void)Process(len,0);

	EXIT:
	return(0);
	}
SHAR_EOF
if test 12961 -ne "`wc -c lib.c`"
then
echo shar: error transmitting lib.c '(should have been 12961 characters)'
fi
echo shar: extracting tolib.c '(4042 characters)'
cat << \SHAR_EOF > tolib.c
/***************************************************************
*
*			ToLib.c
*
*		Disk Library Documentation System
*		Convert README.list files to LIB system
*
*	By Wilson Snyder		(c) January 1988
*
****************************************************************
*
*	NOTICE:
*
*	This program was written as a service to the amiga
*	users.  This program may be used by all parties, including
*	sale (see below) as long as the author's name and address
*	remains intact in the program and documentation.
*	Distribution of this program by parties selling it
*	as part of a commercial for-profit package of over $10
*	must contact the address below before such a package is sold.
*
*	I make no warranties over this program, performance,
*	etc.  And any costs incurred by this program, or its
*	actions are placed on the user.
*
*	PLEASE FORWARD INPROVEMENTS MADE TO THIS PROGRAM TO:
*
*	Wilson Snyder, 15 Davis Parkway, South Burlington, VT 05403
*
***************************************************************/

#include "exec/types.h"
#include "stdio.h"

#define VERSION	"AMIGA-TOLIB.  Version 1.0.0.  By Wilson Snyder"

#define BRK	70	/* Where to break up long, continous lines */
#define BRKTIT	40	/* Where to break title */
#define	SPACEEQ	3	/* Spaces seperating filename and description */

void	main(argc, argv)
	int argc;
	char *argv [];
	{
	FILE *InFile,*OutFile;		/* Files for reading and writing */
	unsigned char cntr=0;		/* Insert line break every BRK chars */
	int spaces;			/* Number spaces encountered */
	int mode; /* 0=line begin, 1=space drop, 2=coping, 3=title extract */
	BOOL linelast;			/* Copied text on the last line */
	char ch;			/* Current read character */

	/* Print usage information */
	if (argv[1][0]=='?') {
		printf ("%s\nUseage: %s Input-File Output-File [header]\n",
			VERSION, argv[0]);
		exit (0);
		}

	/* Open input file */
	if (!(InFile = fopen (argv[1],"r"))) {
		printf ("Bad input file.\n");
		exit (0);
		}

	/* Open output file */
	if (!(OutFile = fopen (argv[2],"w"))) {
		printf ("Bad output file.\n");
		fclose (InFile);
		exit (0);
		}


	mode = 0;
	cntr = 0;
	linelast = FALSE;

	/* Begin the copy */
	while ((ch=getc(InFile))!=EOF) {
	    /* Newline, reset mode to 0, */
	    if (ch=='\n') {
		linelast = (mode==1 || mode==2);
		if (linelast) {
			/* output continuation if text printed on last line */
			putc(' ',OutFile);
			putc('&',OutFile);
			}
		putc (ch,OutFile);
		mode = 0;
		continue;
		}
		
	    switch (mode) {
		case 0:	/* Beginning of Line */
			cntr = 0;
			/* If begins with space or tab is a text line */
			if (ch==' ' || ch=='\t') {
				mode = 1;	/* Skip leading spaces */
				}
			else	{
				/* Otherwise is a new title */
				if (linelast)	putc ('\n',OutFile);
				if (argc>3)	{
					/* Print optional disk title */
					fputs (argv[3],OutFile);
					putc ('\n',OutFile);
					}
				spaces = 0;
				mode = 3;	/* Copy title */
				putc(ch,OutFile);
				}
			break;

		case 1:	/* Skipping leading spaces or tabs before text */
			if (ch==' ' || ch=='\t')	break;	/* drop it */
			putc (ch,OutFile);
			cntr = 1;
			mode = 2;	/* now copy remainder */
			break;

		case 2:	/* Coping to EOL */
			cntr++;
			if (cntr>BRK) {
				putc('&',OutFile);
				putc('\n',OutFile);
				cntr = 0;
				}
			putc (ch,OutFile);
			break;

		case 3:	/* Copying title until tab or several spaces */
			cntr++;
			/* count spaces, after SPACEEQ start text copy */
			if (ch==' ')
				spaces++;
			/* End of title, found a tab or line over length */
			if ((spaces>=SPACEEQ) || ch=='\t' || cntr>=BRKTIT) {
				putc ('\n', OutFile);
				mode = 1;	/* skip rest */
				break;
				}
			if (ch==' ') break;

			/* Write title info after stored spaces*/
			while (spaces--)	putc (' ', OutFile);
			spaces = 0;
			if (ch!=' ') putc (ch, OutFile);
			if (cntr>=BRKTIT)	mode = 1;	/* Chr limit */
			break;

		default:
			/* Bad state */
			printf ("Internal mode error\n");
			fclose (InFile);
			fclose (OutFile);
			exit(20);
		}
	    }

	/* All done. */
	fclose (InFile);
	fclose (OutFile);
	}
SHAR_EOF
if test 4042 -ne "`wc -c tolib.c`"
then
echo shar: error transmitting tolib.c '(should have been 4042 characters)'
fi
#	End of shell archive
exit 0