[comp.sources.misc] v06i046: tape - an audio tape data base program

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (03/05/89)

Posting-number: Volume 6, Issue 46
Submitted-by: bleckmd@jacobs.CS.ORST.EDU (david bleckmann)
Archive-name: tape

Hopefully I have followed all protocol, here is my submission:
[That long a signature isn't quite correct protocol, but... ok.  ++bsa]

 <------- ____  
  &&&    /    \  __ _____,
    `-- |  o   \'  `  &&/   David Bleckmann
       `|      | o  },-'    UUCP: {tektronix,hp-pcd}!orstcs
         \____( )__/                           !jacobs.cs.orst.edu!bleckmd    
         ,'    \'   \       Internet/CSNet: bleckmd@jacobs.cs.orst.edu
 /~~~~~~|.      |   .}~~~\    or:bleckmd%jacobs.cs.orst.edu@orstcs.cs.orst.edu
  ,-----( .     |   .}--.   
        | .    /\___/          US Mail: 861 SW Adams #3
         `----^,\ \                     Corvallis, OR 97333
                \_/   ACK!



-----------------------------------------------

Tape data base program.  See README.DOC for complete description.
Basically used for cataloging and alphabetizing a large number
of audio (or other) tapes.  Runs on UNIX systems (at least BSD)
and hopefully MS DOS as well.

---- Cut Here and unpack ----
#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#	Packed Sun Feb 12 15:08:40 PST 1989 by jacobs.CS.ORST.EDU!bleckmd
#	from directory /mnt/dave/src/tape
#
#	Run the following text with /bin/sh to create:
#	  Makefile
#	  README.DOC
#	  alpha.c
#	  dave.t
#	  header.h
#	  io.c
#	  main.c
#	  tape.prj
#
if test -f Makefile; then echo "File Makefile exists"; else
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
XOBJ= main.o io.o alpha.o
XSRC= header.h main.c io.c alpha.c
X
X#For system V get rid of -ltermcap
XLIB= -lcurses -ltermcap
X
X#Output file
XEXE= tape
X
Xall: $(OBJ)
X	cc -o $(EXE) $(OBJ) $(LIB)
X
X$(OBJ):header.h
X
Xclean:
X	rm -f $(OBJ) core make.out
X
Xkill:
X	rm -f $(OBJ) core make.out $(EXE)
X
X#local dependancy, not very useful ;-)
Xprint:
X	lpr -Porstcs $(SRC)
SHAR_EOF
chmod 0640 Makefile || echo "restore of Makefile fails"
set `wc -c Makefile`;Sum=$1
if test "$Sum" != "347"
then echo original size 347, current size $Sum;fi
fi
if test -f README.DOC; then echo "File README.DOC exists"; else
echo "x - extracting README.DOC (Text)"
sed 's/^X//' << 'SHAR_EOF' > README.DOC &&
XTape organiser - By David Bleckmann
X
XUse to organize tapes in a manner so that a certain tape side
Xcan be found quickly and easily.  
X
XA problem with a large tape collection is that it is often hard
Xto order your tapes so that you can find a particular album by
Xa particular artist.  One way to try to solve this problem is
Xto alphabetize your tapes according to the artist on the first
Xside.  However, if the artist on the second side is different
Xyou are forced to remember which tape side goes with which.
X
XI currently have 130 double sided 90 min tapes.  What I have done
Xis number them sequentially in approximately the order I record 
Xthem.  Thus, when I record a new tape it receives the next highest
Xnumber.  I find this very helpful in my searches to discover which
Xtape I am missing, or even to realize I am missing a tape.  By
Xkeeping a record of the tapes I can often remember where I last
Xhad a particular tape or who I lent it to.
X
XIn order to find a particular album by artist I wrote this 
Xprogram.  It keeps a record of tapes and can print out a list
Xof sides organized by tape number or by Alphabetized artist
Xname.  It will even alphabetize by last name of the artist,
Xif used correctly (or to ignore a leading 'the').
X
XI wrote it on a PC and then transported it to UNIX.  To transfer
Xfrom one system to another edit header.h.  There are some other
Xoptions you can set in there.
X
X
XFILES:
X------------------------------------------------
X
XMakefile	| Unix makefile, doesn't work on PC
X
Xheader.h	| Header file
Xmain.c		| Main programming functions
Xalpha.c		| Functions to do with alphabetizing
Xio.c		| Functions that have to do with i/o
X
XTAPE.EXE	| PC exe file; don't try to run elsewhere!
Xtape.prj	| project file for TURBO C
Xdave.t		| test tape file (actually my list of tapes :-)
X
XDescription of some of the commands:
X-----------------------------------------------------------
X
XNote:	These command Names are the default ones.  They can be changed
X	by editing header.h
X
X'r'	Read in data from a file.  Use with files created with this program.
X	Can also be done from command line, eg:
X	tape data.t
X
X'a'	Add tape.  Entering 0 for a tape number exits.  Hitting return for 
X	tape number adds the number or the last tape in memory plus one.
X	A title for a side is usually in the format:
X
X	Artist Name:Album Title
X
X	Where the ':' is the delimiter (can be changed in header.h).
X	If the album has no title, or is not appropriate, delete from
X	the colon on.
X
X's'	Save data base.  Files usually end in '.t'
X
X'w'	Write data base.  Save as above.
X
X'e'	Edit.  Self explanatory.  Allows changing of a particular tape side
X	or number.
X
X'l'	List tapes.
X
X'L'	List tapes, but do not alpha decode (see 'Correct Alpha Mismatch')
X
X'p'	Print file.  Choice of two output formats (at current time)
X
X'D'	Delete tape.
X
X'C'	Clear all tapes.
X
X'o'	Order tapes in numerical order or alphabetized to side 1.
X
X'A'	Correct alpha mismatch.  In order that the tape side may 
X	be alphabetized according to a part of the title other than
X	the first word, this command will rearrange the title so
X	that the program will do this.  For example a title such
X	as:
X
X	John Smith:I Bite the Songs
X
X	Would be properly changed to:
X
X	Smith|John:I Bite the Songs
X
X	Thus the '|' symbol indicates that the artist name should be
X	rearranged to form the actual name.  Whenever any title is printed
X	(except with 'L' above) the program will 'alpha-decode' the title
X	which basically places any text between the '|' and the first ':'
X	(these can also be changed from default in header.h) at the front
X	of the line, followed by a space, the text previous to the '|',
X	and if the encoded title has a ':', everything following the ':'.
X
X	To encode, select the command 'A', specify how you wish to search
X	for your tapes you wish to change.  Once selected program will
X	enter the 'correct' mode.  Use the left arrow and right arrow in
X	MSDOS, and 'h' and 'l' in UNIX to move cursor and position it 
X	underneath the 'space' you wish to flip the artist name around.
X	Hit space bar to insert '|' and flip name, return to make no
X	change, and 'Q' to exit.
X
X	Example:
X
X	To alphabetize -
X	The Music of Cosmos
X
X	to Cosmos move the cursor to the space between 'of' and 'Cosmos'
X	and hit the space bar.
X
X	To produce:
X	Cosmos|The Music of
X
X'Q'	Quit.
X
X-----------------------------------------------------------
X
XDisclaimer:  Use at your own risk.  Any problems you have with this
X    program are yours, and are not my responsibility.  If you have 
X    fixes or improvements send them to me at:
X
X    bleckmd@jacobs.cs.orst.edu
SHAR_EOF
chmod 0640 README.DOC || echo "restore of README.DOC fails"
set `wc -c README.DOC`;Sum=$1
if test "$Sum" != "4574"
then echo original size 4574, current size $Sum;fi
fi
if test -f alpha.c; then echo "File alpha.c exists"; else
echo "x - extracting alpha.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > alpha.c &&
X#include "header.h"
X
Xint nindex(s, c)	/*returns the position of the char c in the string s*/
Xchar *s, c;
X{
Xint n;
X
X    n=0;
X
X    while(*s!=c && *s!='\0')
X    {
X	n++;
X	s++;
X    }
X
X    if (*s=='\0')
X	return(-1);	/* -1 if not found */
X
X    return(n);
X}
X
Xint allblank(s)	/* returns TRUE if no chars in string s */
Xchar *s;
X{
X    while (*s!='\0')
X	if (!isspace(*s++))
X	    return FALSE;
X
X    return TRUE;
X}
X
Xchar *decode(p2, p1)	/*undoes alpha coding*/
Xchar *p2, *p1;
X{
Xint vb, colen;
X
X    if ((vb=nindex(p1, VERT_BAR))!=-1)
X    {
X	colen=nindex(p1+vb, COLEN);
X	colen=(colen!=-1) ? colen+vb : strlen(p1);
X	strncpy(p2, p1+vb+1, colen-vb-1);
X	p2[colen-vb-1]=' ';
X	p2[colen-vb]='\0';
X	strncat(p2, p1, vb);
X	strcat(p2, p1+colen);
X    }
X    else
X	strcpy(p2, p1);
X
X    return(p2);
X}
X
Xvoid alpha_out(fp, t, count)
XFILE *fp;
Xstruct tape *t[];
Xint count;
X{
Xint t_mark[MAX_NUM_TAPES][2], least_num, least_side, a, b;
Xstring tmp;
X
X/* we need to fprint to fp an alphabetized list of tiles, and */
X/* of course we do this inefficiently ;-).  We keep track of  */
X/* what titles we have printed out so far in t_mark[] and     */
X/* then print out the least of the remaining tapes.           */
X
X    for(a=0; a<count; a++)
X	t_mark[a][0]=t_mark[a][1]=0;
X
X    for(;;)
X    {
X	least_num=count;	/*indicates we don't have least yet*/
X	least_side=1;
X	for(a=0; a<count; a++) 		/* a == tape number */
X	    for(b=1; b<=2; b++)		/* b == side        */
X
X 	        if(!t_mark[a][b-1] &&
X		    (least_num==count ||
X		        strcmp(Sx(t[a],b), Sx(t[least_num],least_side))<0))
X		{
X		    least_num=a;
X		    least_side=b;
X		}
X
X        if (least_num==count)	/* we must be done with the lot */
X	    break;		/* so exit the for(;;) */
X
X        if (!allblank(Sx(t[least_num], least_side)))
X            fprintf(fp, "Tape %-4d Side %c: %s\n", t[least_num]->num,
X			SIDECHAR(least_side),
X		        decode(tmp, Sx(t[least_num],least_side)));
X
X        t_mark[least_num][least_side-1]=1;	/* mark this one as printed */
X    }
X}
X
Xint mvcur(cur, new)	/*returns new cursor position*/
Xint cur, new;
X{
Xint a;
X
X    if (new < cur)
X	for(a=cur; a>new; a--)
X	    BACKSPACE();
X
X    if (new > cur)
X	for(a=cur; a<new; a++)
X	    putchar(SPACE);
X
X    return new;
X}
X
Xint correct(s)	/*returns 1 if changes made, 0 if not*/
X		/*-1 if Quit is incountered*/
Xchar *s;
X{
Xint curpos, colenpos, a, b;
Xstring tmp;
X
X#ifdef MS_DOS
X    printf("\nUse <- and -> , hit space to insert a '%c'\n", VERT_BAR);
X    printf("Return for no change; Q to quit\n\n");
X
X    fflush(stdin);
X    printf("%s\n",  s);
X
X    colenpos=(a=nindex(s, COLEN))==-1 ? strlen(s) : a ;
X
X    if ((curpos=nindex(s, SPACE))==-1 || colenpos<curpos)
X    {
X	printf("No spaces found - No changes made.\n");
X	return 0;
X    }
X
X    mvcur(0, curpos);
X
X    do {
X	while(!kbhit())
X	    ;
X
X        if ((b=getch())=='\0')	/*a function key is hit*/
X	    b=getch()+128;
X
X	if (b=='Q')
X	    return(-1); 
X
X        if (b==205)	/* -> */
X        {
X	    a=nindex(s+curpos+1, SPACE)+curpos+1;
X	    if (a!=-1 && a<colenpos)
X		curpos=mvcur(curpos, a);
X	}
X
X        if (b==203)	/* <- */
X	{
X	    b=curpos;	/* last known space */
X	    a=0;
X	    while ((a=nindex(s+a+1, SPACE)+a+1)<curpos && a!=-1)
X		b=a;
X
X            curpos=mvcur(curpos, b);  /**/
X	}
X
X        if (b==SPACE)	/* Alpha encode word */
X	{
X	    a=nindex(s+curpos, COLEN);
X	    strncpy(tmp, s+curpos+1,
X			 (a=(a!=-1)?a+curpos:strlen(s)) - curpos - 1);
X	    tmp[a-curpos-1]=VERT_BAR;
X	    tmp[a-curpos]='\0';
X            strncat(tmp, s, curpos);
X	    strcat(tmp, s+a);
X
X	    strcpy(s, tmp);
X	    printf("\n%s\n", s);
X	    return(1);
X	}
X
X    } while (b!=CR);
X
X    return 0;	/* CR hit, no changes made */
X#else
X    printf("\nUse '%c' and '%c', hit space to insert a '%c'\n", 
X		LEFTCHAR, RIGHTCHAR, VERT_BAR);
X    printf("Return for no change; Q to quit\n\n");
X
X    noecho();
X    cbreak();
X
X    fflush(stdin);
X    printf("%s\n",  s);
X
X    colenpos=(a=nindex(s, COLEN))==-1 ? strlen(s) : a ;
X
X    if ((curpos=nindex(s, SPACE))==-1 || colenpos<curpos)
X    {
X	printf("No spaces found - No changes made.\n");
X	echo();
X	nocbreak();
X	return 0;
X    }
X
X    mvcur(0, curpos);
X
X    do {
X	b=getchar();
X
X        if (b==RIGHTCHAR)	/* -> */
X        {
X	    a=nindex(s+curpos+1, SPACE)+curpos+1;
X	    if (a!=-1 && a<colenpos)
X		curpos=mvcur(curpos, a);
X	}
X
X        if (b==LEFTCHAR)	/* <- */
X	{
X	    b=curpos;	/* last known space */
X	    a=0;
X	    while ((a=nindex(s+a+1, SPACE)+a+1)<curpos && a!=-1)
X		b=a;
X
X            curpos=mvcur(curpos, b);  /**/
X	}
X
X	if (b=='Q') 	/* Quit */
X	{
X	    echo();
X	    nocbreak();
X	    return(-1);
X	}
X
X        if (b==SPACE)	/* Alpha encode word */
X	{
X	    a=nindex(s+curpos, COLEN);
X	    strncpy(tmp, s+curpos+1,
X			 (a=(a!=-1)?a+curpos:strlen(s)) - curpos - 1);
X	    tmp[a-curpos-1]=VERT_BAR;
X	    tmp[a-curpos]='\0';
X            strncat(tmp, s, curpos);
X	    strcat(tmp, s+a);
X
X	    strcpy(s, tmp);
X	    printf("\n%s\n", s);
X
X	    echo();
X	    nocbreak();
X	    return(1);
X	}
X
X    } while (b!=CR);
X
X    echo();
X    nocbreak();
X    return 0;	/* CR hit, no changes made */
X#endif
X}
X
SHAR_EOF
chmod 0640 alpha.c || echo "restore of alpha.c fails"
set `wc -c alpha.c`;Sum=$1
if test "$Sum" != "5018"
then echo original size 5018, current size $Sum;fi
fi
if test -f dave.t; then echo "File dave.t exists"; else
echo "x - extracting dave.t (Text)"
sed 's/^X//' << 'SHAR_EOF' > dave.t &&
X1
XJarre|Jean-Michel:Oxygene
XJarre|Jean-Michel:Equinoxe
X2
XEurithmics:1984
XJarre|Jean-Michel:Les Chants Magnetiques
X3
XMen Without Hats:Rhythem of Youth
XTangerine Dream:Warsaw in the Sun
X4
XJHS Band
XTangerine Dream:Wavelength
X5
XJarre|Jean-Michel:L'Essential Jean-Michel Jarre
XTangerine Dream:Flashpoint
X6
XTangerine Dream:Firestarter
XTangerine Dream:Exit
X7
XJarre|Jean-Michel:Zoolook
XTangerine Dream:Cyclone
X8
XJethro Tull:Under Wraps
XDalek, I Love You
X9
XNuman|Gary:Replicas
XNuman|Gary:Pleasure Principle
X10
XDepeche Mode:Some Great Reward
XDepeche Mode:Black Celebration
X11
XTalking Heads:Fear of Music
XGarrison|Michael:Prisms
X12
XTears for Fears:Various Remix Tape #1
X
X13
XGraduate:Acting My Age
XMcKenzie|Bob and Doug
X14
XTangerine Dream:Stratosfear
XGarrison|Michael:Point of Inpact
X15
XTangerine Dream:Poland
X
X16
XTangerine Dream:Tangram
XTangerine Dream:Quichette
X17
XJones|Howard:Human's Lib
XDream Academy|The
X18
XFrankie Goes to Hollywood:Welcome to the Pleasure Dome
X
X19
XJones|Howard:Dream Into Action
XJones|Howard:The 12" Album
X20
XLive Aid
XJohn Valby
X21
XBerlin:Love Life
XBerlin:Pleasure Victim
X22
XDolby|Thomas:Rare Remixes
XManheim Steamroller:Freshaire III
X23
XAnderson|Laurie:United States
X
X24
XAnderson|Laurie:United States
X
X25
XAnderson|Laurie:United States
X
X26
XModern English:Ricochet Days
XDead or Alive:Youthquake
X27
XJethro Tull:Thick as a Brick
XDepeche Mode:People are People
X28
XTears for Fears:Songs From the Big Chair
XTears for Fears:The Hurting
X29
XJethro Tull:Stormwatch
XVangelis:China
X30
XTalking Heads:Little Creatures
XVega|Suzanne
X31
XTalking Heads:Speaking in Tounges
XTalking Heads:More Songs About Buildings and Food
X32
XDepeche Mode:Speak and Spell
XDepeche Mode:A Broken Frame
X33
XDepeche Mode:Constuction Time Again
X
X34
XJones|Howard:Remix Tape 1
X
X35
XJones|Howard:San Deigo Interview
XDolby|Thomas:The Flat Earth
X36
XJarre|Jean-Michel:Rendez-Vous
XManheim Steamroller:Fresh Aire VI
X37
XU2:Unforgetable Fire
XU2:War
X38
XAnderson|Laurie:Mister Heartbreak
XAnderson|Laurie:Home of the Brave
X39
XSimple Minds:Life in a Day
XEcho and the Bunnymen:Heaven up Here
X40
XJethro Tull:Aqualung
XSpinal Tap|Soundtrack to This is
X41
XGarrison|Michael:Eclipse
XTangerine Dream:White Eagle
X42
XReal Life:Flame
XReal Life:Heartland
X43
XU2:Boy
XBowie|David:Let's Dance
X44
XRepo Man|Soundtrack to
XIdol|Billy:Whiplash Smile
X45
XAltered Images:Pinky Blue
XCure|The:Concert-The Cure Live
X46
XTangerine Dream:70-80 (tape 1)
X
X47
XTangerine Dream:70-80 (tape 2)
X
X48
XKitaro:Silk Road I
XKitaro:Silk Road II
X49
XKitaro:Full Moon Story
XKitaro:Astral Voyage
X50
XKitaro:In Person
XKitaro:Asia Tour Super Live
X51
XKitaro:Tunhuang
XAshra:Blackouts
X52
XTangerine Dream:Le Parc
XTangerine Dream:Heartbreakers
X53
XDire Straits:Brothers in Arms
X
X54
XJarre|Jean-Michel:The Concerts in China
X
X55
XNuman|Gary:The Fury
XNuman|Gary:Strange Charm
X56
XSimon and Garfunkel:Greatest Hits
XVarious CD Samples
X57
XABC:How to be a Zillionaire
XSimple Minds: Once Upon a Time
X58
XRush:Power Windows
XVan Halen
X59
XFlock of Seagulls
XFlock of Seagulls:Listen
X60
XSmiths|The
XSmiths|The:Meat is Murder
X61
XU2:Under a Blood Red Sky
XU2:October
X62
XMozart:Symphony 41 & 40
X
X63
XVollenwieder|Andreas:Behind the Gardens...
XVollenwieder|Andreas:Cavern Magica
X64
XWinston|George:December
XWindom Hill:Sampler '84
X65
XGreenpeace
X
X66
XDire Straits:Alchemy - Live
X
X67
XIdol|Billy
XIdol|Billy:Rebel Yell
X68
XThompson Twins:Here's to Future Days
XBowie|David:Tonight
X69
XTangerine Dream:Green Desert
XTangerine Dream:Legend
X70
XEtosha:Private Music in the Land of Dry Water
XCosmos|The Music of
X71
XDif Juz:Who Says So
XLadyhawk
X72
XBush|Kate:Hounds of Love
XBush|Kate:The Dreaming
X73
XArt of Noise|The:Into Battle with the Art of Noise
XArt of Noise|The:Who's Afraid of the Art of Noise?
X74
XArt of Noise|The:Various Remixes
XThis Mortal Coil:It'll End in Tears
X75
XTears for Fears:Memories
XTears for Fears:Remixes Tape 2
X76
XDalis Car:The Waking Hour
XKarn|Mick:Titles
X77
XNuman|Gary:Warriors
XNuman|Gary:Beserker
X78
XJethro Tull:Songs from the Woods
XJethro Tull:Minstrel in the Gallery
X79
XJethro Tull:M.U. The Best of Jethro Tull
XJethro Tull:A
X80
XCocteau Twins:Head Over Heals
XCocteau Twins:Treasure
X81
XNuman and the Tubeway Army|Gary:First Album
XNuman|Gary:Telekon
X82
XNuman|Gary:I, Assassin
XNuman|Gary:Dance
X83
XAha:Hunting High and Low
XSigue Sigue Sputnik:Faunt It
X84
XGenesis:Invisible Touch
XGabriael|Peter:So
X85
XStawberry Switchblade
XStawberry Switchblade:(12")
X86
XCour Field|The
XModern English:Ricochet Days
X87
XUnderground Mixes
XToy Dolls:Dig That Grove Baby
X88
XCure|The:Standing on a Beach - The Singles
X
X89
XSkinny Puppy:Bites
XSkinny Puppy:Mind:The Perpetual Intercourse
X90
XBauhaus:1979-1983
X
X91
XJones|Howard:One to One
XBerlin:Count Three and Pray
X92
XManheim Streamroller:Fresh Aire I
XVangelis:Albedo 0.39
X93
XFrankie Goes to Hollywood:Liverpool
XPop|Iggy:Blah-Blah-Blah
X94
XWindom Hill|An Evening With
X4AD Various
X95
XSmiths|The:The Queen is Dead
X
X96
XDead Can Dance
XDead Can Dance:Spleen and Ideal
X97
XTears for Fears:Penthouse/Omni Magazine Concert
X
X98
XSiouxsie and the Banshies:Nocturne
X
X99
XCindytalk:Camouflage Heart
XXymox|Clan of:Medusa
X100
XThis Mortal Coil:Filigree and Shadow
X
X101
XBolshoi|The:Friends
XCure|The:The Head on the Door
X102
XDead Kennedys:Fresh Fruit for Rotten Vegetables
XSuicidal Tendecies
X103
XSiouxsie and the Banshies:Through the Looking Glass
XSiouxsie and the Banshies:Tinderbox
X104
XTrisomie 21:Chapter IV
XSisters of Mercy:Floodland
X105
XNuman|Gary:White Noise
X
X106
XAnderson|Laurie:Home of the Brave Interview
X
X107
XWire:The Ideal Copy
XLove and Rockets:Earth Sun Moon
X108
XLonely is an Eyesore
XRobyn Hitchcock:Element of Light
X109
XNuman|Gary:Exhibition
X
X110
XDif Juz:Extractions
XKarn|Mick:Dreanms of Reason
X111
XBreathless:Three Times and Waving
XBreathless:The Glass Bead Game
X112
XNuman|Gary:Exhibition
X
X113
XNuman|Gary:Exhibition
XNuman|Gary:Exhibition (et al)
X114
XNelson|Bill:The Love that Whirls
XNelson|Bill:La Belle et la Bete
X116
XByrne|Brian Eno and David:My Life in the Bush with Ghosts
XBudd|Harold:The Pavilion of Dreams
X117
XRoxy Music:Avalon
X
X118
XM:Pop Muzic
XNegativeland:Escape from Noise
X119
XTalking Heads:Remain in Light
XGabrial|Peter:Security
X120
XCheese
X
X121
XBush|Kate:Never for Ever
X
SHAR_EOF
chmod 0640 dave.t || echo "restore of dave.t fails"
set `wc -c dave.t`;Sum=$1
if test "$Sum" != "6076"
then echo original size 6076, current size $Sum;fi
fi
if test -f header.h; then echo "File header.h exists"; else
echo "x - extracting header.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > header.h &&
X/*header.h				*/
X/*include file for tape sorting program	*/
X/*by David Bleckmann			*/
X
X/*#define MS_DOS	/*define if on compiling on turbo C*/
X
X#include <stdio.h>
X#include <ctype.h>
X
X#ifdef MS_DOS
X#include <string.h>
X#include <conio.h>
X#else
X/*for system V you may need to change <strings.h> to <string.h>*/
X#include <strings.h>
X#include <curses.h>
X#endif
X
X#define SIDEAB  	/*define if sides to be accessed as A or B rather*/
X			/*than side 1 or 2.			*/
X
X/* The following are used as defines so that the user can set up */
X/* the program as he/she would like, i.e. change the command key */
X/* letters, etc.  It is permissible to make changes, but	 */
X/* certainly isn't necesarry.				 	 */
X
X
X#define MAX_NUM_TAPES 300
X#define STR_LEN 80
X#define SCRHT 11	/* number of tapes that fits on one screen */
X
X#define VERT_BAR '|'
X#define COLEN    ':'
X#define SPACE	' '
X#ifndef MS_DOS
X#define CR	'\12'
X#else
X#define CR	'\15'
X#endif
X
X/* COMMAND DEFINES */
X#define READCOM 	'r'
X#define ADDCOM          'a'
X#define WR1COM  	's'
X#define WR2COM 		'w'
X#define EDITCOM		'e'
X#define LISTCOM 	'l'
X#define LIST2COM	'L'
X#define PRINTCOM	'p'
X#define DELCOM		'D'
X#define CLEARCOM	'C'
X#define RECOVCOM	'R'
X#define ORDCOM		'o'
X#define ALPHACOM	'A'
X#define QUITCOM		'Q'
X
X#ifndef MS_DOS
X/*LEFTCHAR and RIGHTCHAR are used in the Unix version of ALPHACOM*/
X#define LEFTCHAR 'h'
X#define RIGHTCHAR 'l'
X#endif
X
X/* All further lines should probably not be changed	*/
X/*--------------------------------------------------------------------*/
X
X#ifndef TRUE	/* sometimes not defined */
X#define TRUE 1
X#endif
X#ifndef FALSE
X#define FALSE 0
X#endif
X
X
X#ifdef SIDEAB
X#define SIDECHAR(pdq) ((pdq)!=2?'A':'B')
X#define SIDE1CHAR 'A'
X#define SIDE2CHAR 'B'
X#else
X#define SIDECHAR(pdq) ((pdq)!=2?'1':'2')
X#define SIDE1CHAR '1'
X#define SIDE2CHAR '2'
X#endif
X
X#ifdef MS_DOS
X#define BACKSPACE() gotoxy(wherex()-1, wherey())
X#else
X#define BS	'\10'
X#define BACKSPACE() putchar(BS)
X
X/* For some reason TC's strncmp is strnicmp, thus the following macro */
X#define strnicmp(aaa, bbb, ccc) strncmp(aaa, bbb, ccc)
X#endif
X
X/* Side X macro; refers to the side yyy in the  struct tape *xxx */
X#define Sx(xxx, yyy) ((yyy)==2 ? (xxx)->s2 : (xxx)->s1)
X
Xtypedef char string[STR_LEN];
X
Xstruct tape {
X    int num;
X    string s1;
X    string s2;
X};
X
X
SHAR_EOF
chmod 0640 header.h || echo "restore of header.h fails"
set `wc -c header.h`;Sum=$1
if test "$Sum" != "2282"
then echo original size 2282, current size $Sum;fi
fi
if test -f io.c; then echo "File io.c exists"; else
echo "x - extracting io.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > io.c &&
X#include "header.h"
X
Xchar *crstrip(s)	/*strips off a '\n' off the end of a string if */
Xchar *s;   		/*there is one.				       */
X{
Xint a;
X
X    if (s != NULL  &&  s[a=strlen(s)-1] == '\n')
X	s[a]= '\0';
X
X    return s;
X}
X
Xint get_tape(t, fname)	/*returns count or -1 if error*/
Xstruct tape *t[];
Xchar *fname;
X{
XFILE *fp;
Xint a, b;
Xstring tmp;
Xchar *malloc();
X
X    if ((fp=fopen(fname, "r"))==NULL)
X    {
X	fprintf(stderr, "can't open file\n");
X	return(-1);
X    }
X    for (a=0; t[a]!=NULL; a++)
X    {
X	if (fgets(tmp, 80, fp)==NULL)	/* NULL implies EOF */
X	{
X	    fclose(fp);
X	    return(a);
X	}
X
X        if((t[a]->num=atoi(tmp)) == 0)
X	{
X	    fprintf(stderr, "\"%s\" not tape number\n", tmp);
X	    fclose(fp);
X	    return(-1);
X	}
X	crstrip(fgets(t[a]->s1, 80, fp));
X	crstrip(fgets(t[a]->s2, 80, fp));
X    }
X
X    for(; a<MAX_NUM_TAPES && fgets(tmp, 80, fp)!=NULL; a++)
X    {
X        if((b=atoi(tmp)) == 0)
X	{
X	    t[a]=NULL;
X	    fprintf(stderr, "\"%s\" not tape number\n", tmp);
X	    fclose(fp);
X	    return(-1);
X	}
X	t[a]=(struct tape *) malloc(sizeof(struct tape));
X	t[a]->num=b;
X	crstrip(fgets(t[a]->s1, 80, fp));
X	crstrip(fgets(t[a]->s2, 80, fp));
X    }
X/* found EOF */
X    fclose(fp);
X    return(a);
X}
X
X
Xint save_tape(t, fname, count)
Xstruct tape *t[];
Xchar *fname;
Xint count;
X{
XFILE *fp;
Xint a;
X
X    if ((fp=fopen(fname, "w"))==NULL)
X    {
X	fprintf(stderr, "can't open file\n");
X	return(-1);
X    }
X    for(a=0; a<count; a++)
X	fprintf(fp, "%d\n%s\n%s\n", t[a]->num, t[a]->s1, t[a]->s2);
X    fclose(fp);
X    return(a);
X}
SHAR_EOF
chmod 0640 io.c || echo "restore of io.c fails"
set `wc -c io.c`;Sum=$1
if test "$Sum" != "1518"
then echo original size 1518, current size $Sum;fi
fi
if test -f main.c; then echo "File main.c exists"; else
echo "x - extracting main.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > main.c &&
X#include "header.h"
X
X#define DB(xxx) /* fprintf(stderr, "Debug #%d", (xxx)); fflush(stdout); fflush(stderr) /**/
X
Xvoid greeting()
X{
X#ifdef MS_DOS
X    clrscr();
X#else
X    system("clear");
X#endif
X    printf("\n");
X    printf("Tape organizer 0.0 ---   By David Bleckmann \n ");
X    printf("\n");
X    printf("Created 1988 \n");
X    printf("\n");
X    printf("\n");
X    printf("Use/modify however you wish, but please give me credit for\n");
X    printf("my work.\n");
X    /* and excuse me for my "ammature" programming skills :-) */
X    printf("\n");
X    printf("Send all criticizism/improvements to me at my UUCP/internet address:\n");
X    printf("\n");
X    printf("\tbleckmd@jacobs.cs.orst.edu\n");
X    printf("\t{tektronix, hp-pcd}!orstcs!jacobs.cs.orst.edu!bleckmd\n");
X    printf("\n");
X    printf("\n");
X    printf("Use 'H', 'h', or '?' for help menu\n\n");
X
X}
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
Xstruct tape *t[MAX_NUM_TAPES];
Xint a, b, c, count;
Xstring fname, tmp, tmp1, tmp2;
Xint save_tape(), get_tape(), correct();
Xvoid clr_to_null(), alpha_out();
Xchar *decode(), *malloc();
Xextern int allblank();
X
XFILE *fp;
X
X    count=0;
X
X
X#ifndef MS_DOS
X    initscr();
X#endif
X
X    for (a=0; a<MAX_NUM_TAPES; a++)
X	t[a]= NULL;			/*clear all tape elements to NULL*/
X
X
X    switch(argc)
X    {
X	case 1:
X	    greeting();
X	    break;
X
X	case 2:
X	    if ((count=get_tape(t, argv[1])) == -1)  /* return -1 if error */
X	    {
X		greeting();
X		fprintf(stderr, "file error\n%s not loaded.\n", argv[1]);
X	    }
X	    else
X	    {
X		greeting();
X		printf("File %s Loaded\n", argv[1]);
X            }
X	    break;
X
X	default:
X	    fprintf(stderr,
X		"Usage: %s [tapefile]\n where tapefile was created using %s\n",
X		argv[0], argv[0]);
X
X#ifndef MS_DOS
X	    nocbreak();
X	    endwin();
X#endif
X	    exit(1);
X    }
X
X    for(;;)
X    {
X	printf("\nCommand:");
X	gets(tmp);
X
X	switch (*tmp)  {
X
X	case '?':
X	case 'h':
X	case 'H':	/*help command! (yes we have one)*/
X	    printf("command list:\n");
X	    printf("\t%c: read in file\n", READCOM);
X	    printf("\t%c,%c: write to file\n", WR1COM, WR2COM);
X	    printf("\t%c: add tape data\n", ADDCOM);
X	    printf("\t%c: edit tape\n", EDITCOM);
X            printf("\t%c: list tapes\n", LISTCOM);
X	    printf("\t%c: print out tapes\n", PRINTCOM);
X	    printf("\t%c: delete a tape\n", DELCOM);
X            printf("\t%c: clear all tapes (careful!)\n", CLEARCOM);
X	    printf("\t%c: order tapes\n", ORDCOM);
X	    printf("\t%c: correct alpha mismatch\n", ALPHACOM);
X	    printf("\t%c: quit\n", QUITCOM);
X	    break;
X
X	case READCOM:
X	    printf("file to read from:");
X	    gets(fname);
X	    if ((a=get_tape(t, fname)) == -1)  /* returns -1 on error */
X		fprintf(stderr, "file error\n");
X	    else {
X		count=a;
X		printf("file read in: %d entries\n\n", count);
X		/*gets(tmp, STR_LEN);*/
X	    }
X	    break;
X
X	case WR1COM:
X	case WR2COM:
X	    printf("file to save to:");
X	    gets(fname);
X	    if (save_tape(t, fname, count)==-1)  /* return -1 on error */
X		printf("Error: file not saved\n");
X	    break;
X
X	case ADDCOM:
X	    printf("enter 0 to quit...\n\n");
X	    for(;;)
X	    {
X		if (count>=MAX_NUM_TAPES)
X		{
X		    printf("Can't have more than %d tapes\n", MAX_NUM_TAPES-1);
X		    break;
X		}
X		printf("tape number=");
X		gets(tmp);
X		if (tmp[0] == '\0' && count > 0)
X		{
X		    a=t[count-1]->num+1;
X		    printf("%d\n", a);
X		}
X		else if ((a=atoi(tmp))==0)
X		    break;
X		t[count]=(struct tape *) malloc(sizeof(struct tape));
X		t[count]->num=a;
X		printf("side %c:", SIDE1CHAR);
X		gets(t[count]->s1);
X		printf("side %c:", SIDE2CHAR);
X		gets(t[count]->s2);
X		++count;	/*update current number of tapes*/
X		putchar('\n');
X	    }	/*end of 'a'*/
X	    break;
X
X	case EDITCOM:
X	    printf("Enter tape #:");
X	    gets(tmp);
X	    if ((a=atoi(tmp))>0)
X	    {
X		for(b=0; b<count && t[b]->num!=a; b++)
X		    ;
X		if (b==count)
X		{
X		    printf("tape not found\n");
X		    break;
X		}
X		printf("%d:\n%c: %s\n%c: %s\n\n", t[b]->num, SIDE1CHAR,
X		    t[b]->s1, SIDE2CHAR, t[b]->s2);
X
X#ifndef SIDEAB
X		printf("Edit: (1) Side 1, (2) Side 2, or (3) number:");
X
X		switch (a=atoi(gets(tmp))) {
X
X		case 3:
X		    printf("\nNew Num:");
X		    if ((a=atoi(gets(tmp)))>0)
X			t[b]->num=a;
X
X		    break;
X
X		case 2:
X		case 1:
X		    printf("\nNew Title for side %d:\n", a);
X		    gets(Sx(t[b], a));
X		    break;
X		} /*end of switch*/
X	        printf("%d:\n1: %s\n2: %s\n\n", t[b]->num,
X		        decode(tmp1, t[b]->s1), decode(tmp2, t[b]->s2));
X#else
X		printf("Edit: (A) Side A, (B) Side B, or (N) number:");
X
X		switch (a= *gets(tmp)) {
X
X		case 'N':
X		case '3':
X		case 'n':
X		    printf("\nNew Num:");
X		    if ((a=atoi(gets(tmp)))>0)
X			t[b]->num=a;
X
X		    break;
X
X		case 'a':
X		case 'A':
X		case 'b':
X		case 'B':
X		    a=(a=='a' || a=='A') ? 1 : 2 ;
X		    printf("\nNew Title for side %c:\n", SIDECHAR(a));
X		    gets(Sx(t[b], a));
X		    break;
X		} /*end of switch*/
X	        printf("%d:\nA: %s\nB: %s\n\n", t[b]->num,
X		        decode(tmp1, t[b]->s1), decode(tmp2, t[b]->s2));
X#endif
X
X	    } /*end of if (a>0)*/
X	    break;
X
X	case LIST2COM:
X	    c=FALSE;
X	    for(a=0; a<count; a+=SCRHT)
X	    {
X	      for(b=a; b<a+SCRHT && b<count; b++)
X		printf("%d\t%s\n\t%s\n", t[b]->num, t[b]->s1,
X				    t[b]->s2);
X              if (!c && b<count)
X	      {
X#ifndef MS_DOS
X		  cbreak();
X#endif
X		  printf("More (Quit, Continuous)?");
X		  *tmp=getchar();
X#ifndef MS_DOS
X		  nocbreak();
X#endif
X		  putchar('\n');
X		  if (*tmp=='q' || *tmp=='Q')
X		      break;
X		  if (*tmp=='c' || *tmp=='C')
X		      c=TRUE;
X              }
X	    }
X            break;
X
X	case LISTCOM:
X	    c=FALSE;
X	    for(a=0; a<count; a+=SCRHT)
X	    {
X	      for(b=a; b<a+SCRHT && b<count; b++)
X		printf("%d\t%s\n\t%s\n", t[b]->num, decode(tmp1, t[b]->s1),
X				    decode(tmp2,t[b]->s2));
X              if (!c && b<count)
X	      {
X#ifndef MS_DOS
X		  cbreak();
X#endif
X		  printf("More (Quit, Continuous)?");
X		  *tmp=getch();
X#ifndef MS_DOS
X		  nocbreak();
X#endif
X		  putchar('\n');
X		  if (*tmp=='q' || *tmp=='Q')
X		      break;
X		  if (*tmp=='c' || *tmp=='C')
X		      c=TRUE;
X              }
X	    }
X            break;
X
X        case PRINTCOM:
X#ifdef MS_DOS
X	    printf("Enter output device:\n(i.e. enter LPT1 to go to printer)");
X#else
X	    printf("Enter output file:\n");
X#endif
X	    printf("\n>");
X	    gets(tmp);
X	    if ((fp=fopen(tmp, "w")) == NULL)
X	    {
X		fprintf(stderr, "Cannot open file\n");
X		break;
X            }
X
X            printf("\nPrint Format:\n");
X	    printf("\t1: Standard output (just like '%c')\n", LISTCOM);
X	    printf("\t2: Alphabetized index (num;side:Artist)\n");
X	    printf("Choice:");
X	    gets(tmp);
X
X            switch (atoi(tmp)) {
X
X            case 1:
X	        for(a=0; a<count; a++)
X#ifndef SIDEAB
X		    fprintf(fp,
X			  /*don't print side2 if there ain't any*/
X			    allblank(t[a]->s2) ? "Tape %4d side 1:%s\n"
X				  : "Tape %4d side 1:%s\n          side 2:%s\n",
X					t[a]->num,
X					decode(tmp1, t[a]->s1),
X				        decode(tmp2,t[a]->s2));
X#else
X		    fprintf(fp,
X			  /*don't print side2 if there ain't any*/
X			    allblank(t[a]->s2) ? "Tape %4d side A:%s\n"
X				  : "Tape %4d side A:%s\n          side B:%s\n",
X					t[a]->num,
X					decode(tmp1, t[a]->s1),
X				        decode(tmp2,t[a]->s2));
X#endif
X                break;
X
X            case 2:
X		alpha_out(fp, t, count);
X		break;
X
X	    } /*end of switch*/
X
X            fclose(fp);
X            break;
X
X	case CLEARCOM:
X	    printf("Are you Sure(y/n)?");
X	    gets(tmp);
X	    if (*tmp=='y' || *tmp=='Y')
X	        count=0;
X	    break;
X
X        case RECOVCOM:	/*undocumented way of un-'C'ing...just enter a count*/
X	    printf("Debug option - set new count\nEnter new number of tapes:");
X	    if ((a=atoi(gets(tmp))) != 0)
X                count=a;
X	    break;
X
X        case DELCOM:	/* Delete a tape */
X	    printf("Delete tape\nEnter tape #:");
X	    gets(tmp);
X	    if ((a=atoi(tmp))>0)
X	    {
X		for(b=0; b<count && t[b]->num!=a; b++)
X		    ;
X		if (b==count)
X		{
X		    printf("tape not found\n");
X		    break;
X		}
X		printf("Tape: %d\nSide %c: %s\nSide %c: %s\nDelete (y/n)?",
X			t[b]->num, SIDE1CHAR, t[b]->s1, SIDE2CHAR, t[b]->s2);
X		gets(tmp);
X		if (tmp[0]=='y' || tmp[0]=='Y')
X		{
X		    for(a=b; a<count-1; a++)
X                        t[a]=t[a+1];
X		    t[a]=NULL;
X		    count--;
X		    printf("Tape deleted.\n");
X		}
X		else
X		    printf("Tape not deleted.\n");
X            }
X	    break;
X
X        case ORDCOM:	/*order tapes*/
X	    printf("\nOrder with respect to:\n");
X	    printf("\t1. Number\n\t2. Alphabetized to side %c\nChoice:",
X		   SIDE1CHAR);
X	    gets(tmp);
X	    if ((a=atoi(tmp))==1 || a==2)
X	    {
X                a=(a==1);	/*a is true if to be sorted numerically*/
X		printf("Sorting....");
X		fflush(stdout);
X
X                do {
X		    b=0;	/*time for an inefficient bubble sort :-)*/
X		    for(c=0; c<count-1; c++)
X		        if (a ? t[c]->num > t[c+1]->num
X			      : strcmp(t[c]->s1, t[c+1]->s1) > 0)
X                        {
X			    struct tape *tmp;
X			    tmp=t[c];
X			    t[c]=t[c+1];
X			    t[c+1]=tmp;
X			    b=1;
X		        }
X		} while (b);
X
X                printf("Done.\n");
X	    }
X	    break;
X
X        case ALPHACOM:
X	    printf("correct Alpha mismatch\n");
X	    printf("1. Search for \"The\"\n");
X	    printf("2. Name Search.\n");
X	    printf("3. Specific Tape and Side.\n\n");
X	    printf("Enter choice:");
X	    gets(tmp);
X
X	    switch (a=atoi(tmp)) {
X	      case 1:
X		strcpy(tmp, "The");
X	      case 2:
X		if (a!=1)
X		{
X		    printf("Enter name to search for:");
X		    gets(tmp);
X		}
X		c=strlen(tmp);
X
X		for(a=0; a<count; a++)
X		  for(b=1; b<=2; b++)
X		    if (strnicmp(Sx(t[a], b), tmp, c) == 0)
X			if (correct(Sx(t[a], b)) == -1)
X			    goto qhit;
X	qhit:
X                break;
X
X              case 3:
X	        printf("Enter tape number:");
X	        gets(tmp);
X                if ((a=atoi(tmp))<1)
X	            break;
X
X                for(c=0; t[c]->num!=a && c<count; c++)
X		    ;
X	        if (c==count)
X	        {
X		    printf("Tape not found\n");
X		    break;
X	        }
X
X                printf("Enter side:");
X	        gets(tmp);
X		if (islower(*tmp))
X		    *tmp=toupper(*tmp);
X
X	        if (*tmp!=SIDE1CHAR && *tmp!=SIDE2CHAR)
X		    break;
X
X                correct(*tmp!=SIDE1CHAR ? t[c]->s2 : t[c]->s1);
X	        break;
X            } /* end of switch(a=atoi(tmp)) */
X	    break;
X
X	case QUITCOM:
X	    printf("\nBye !\n");
X
X#ifndef MS_DOS
X    	    nocbreak();
X	    endwin();
X#endif
X	    exit(0);
X
X	default:
X	    fprintf(stderr, "error???\nUse 'H' for help\n");
X
X	}	/*end of command switch*/
X    }	/*end of for(;;)*/
X
X}	/*end of main()*/
X
SHAR_EOF
chmod 0640 main.c || echo "restore of main.c fails"
set `wc -c main.c`;Sum=$1
if test "$Sum" != "10479"
then echo original size 10479, current size $Sum;fi
fi
if test -f tape.prj; then echo "File tape.prj exists"; else
echo "x - extracting tape.prj (Text)"
sed 's/^X//' << 'SHAR_EOF' > tape.prj &&
Xmain (header.h)
Xio (header.h)
Xalpha (header.h)
SHAR_EOF
chmod 0640 tape.prj || echo "restore of tape.prj fails"
set `wc -c tape.prj`;Sum=$1
if test "$Sum" != "47"
then echo original size 47, current size $Sum;fi
fi
exit 0