remco@tnoibbc.ibbc.tno.nl (Remco Bruyne) (02/14/90)
Posting-number: Volume 10, Issue 67 Submitted-by: remco@tnoibbc.ibbc.tno.nl (Remco Bruyne) Archive-name: c_cover/part02 Hello, This the second shar file for the cassette cover printing program. please read the info in the mail forming the first part. Remco Bruijne. -------------cut here--------- #!/bin/sh # This is a shell archive. Remove anything before above line, # then unpack it by saving it in a file and typing "sh file". # - Files are being checked using wc. When an error has been found a # message will be generated. # - Files already existing will not be overwritten. The new file will # be given anothe random name. A message will then be generated. # - The exact protections of the files being shared are maintained. # Before sharing the file protections are saved and restored when # unshared. # # Shar file created : Wed Feb 7 15:33:49 MET 1990 # Shar file contains : CASSETTE.DAT DOC.TXT Makefile README rdparams.c readcover.c select.c show.c string.c subs.c xdefs.h # echo x - CASSETTE.DAT if test -f CASSETTE.DAT then echo CASSETTE.DAT exists, putting output in $$CASSETTE.DAT OUT=$$CASSETTE.DAT else OUT=CASSETTE.DAT fi sed 's/^X//' > $OUT <<'@//E*O*F CASSETTE.DAT //' X# X# X# FILE CONTAINING ALL LAY-OUT PARAMETERS FOR THE COVER X# X# ALLE NUMBERS ARE IN TENTHS OF MILLIMETERS ! X# X# (SORRY FOR THE INCH-USERS :-)) X# X# USE TAB STOPS ON EVERY 4th POSITION X# X# X900 205 # CodeXPos en CodeYPos X3 # CodeLen XHelvetica-Bold # CodeFont X17 # CodeFSize X# X250 90 # TsXPos en TsYPos X600 90 # NrXPos en NrYPos XHelvetica-Bold # TsNrFont X10 # TsNrFSize X# X50 240 # BT1XPos en BT1YPos X50 187 # BT2XPos en BT2YPos X35 # BTLen XHelvetica # BTFont X11 # BTFSize X# X25 925 # FrAXPos en FrAYPos X525 925 # FrBXPos en FrBYPos XHelvetica-Bold # FrABFont X10 # FrABFSize X# X70 925 # FrTl1XPos en FrTl1YPos X570 925 # FrTl2XPos en FrTl2YPos XHelvetica # FrTlFont X8 # FrTlFSize X# X25 875 # Tl1XPos en Tl1YPos X525 875 # Tl2XPos en Tl2YPos X35 # TlLen X30 # TlLDist XHelvetica # TlFont X7 # TlFSize X# X80 # CtTlXDist X5 # CtLen X# X30 #FTlSepX1 X970 #FTlSepX2 X915 #FTlSepY X# X520 #FVSepX X910 #FVSepY1 X305 #FVSepY2 @//E*O*F CASSETTE.DAT // chars=`wc -c < CASSETTE.DAT | awk '{ print $1}'` if test $chars != 996 then echo 'CASSETTE.DAT' is $chars characters, echo should be 996 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi echo x - DOC.TXT if test -f DOC.TXT then echo DOC.TXT exists, putting output in $$DOC.TXT OUT=$$DOC.TXT else OUT=DOC.TXT fi sed 's/^X//' > $OUT <<'@//E*O*F DOC.TXT //' X-------------------------------------------------------------------------- XThis file gives a very short description of how the cassette cover program Xworks. Before you start the program,it is a good idea to create a separate Xdirectory (folder) from where you run the program. This is, because a data Xfile is created for every cassette cover you enter. X XWhen you start the program, you get a menu with 8 choices. The menu looks Xas follows: X X 1) Show a list of cassettecovers X 2) Delete cover(s) X 3) Create a new cover X 4) Read in an existing cover X 5) Edit a read-in cover X 6) Show read-in cover on the screen X 7) Print cover(s) to Postscript-file X 8) Quit X XIn case you dislike the menu, choose 8 to quit immediately ... X X-------------------- XOption 1, Show a list of cassettecovers; this one should be clear. X X-------------------- XOption 2, Delete cover(s),also works very simple. A list of covers is pre- Xsented,on which the user may select one or more covers to be deleted. The Xlist of covers is in a rather free format. The following lists are legal: X 5 (selects cover 5 for deleting) X * (selects all covers) X 3,6, 2;9 (selects 3,6,2 and 9) X 2-6, 10 (2-6 is range, including 6) Xinstead of ',' you may use TAB, SPACE, semicolon, dot. X XWhen you entered the list of covers to be deleted, the program shows you Xthe selected titles and asks if you are sure that you want to delete these Xtitles. X X-------------------- XOption 3, Create a new cover. You are required to enter things like: X - A short description with which the casette cover is stored into X the database of covers. X - Back code (see README) X - Titles of side A and B X - Tape type X - Noise reduction system X X-------------------- XOption 4, Read in an existing cover. Before you can use the options 5 and X6, a cover must be read from the 'database'. This is called the 'current' Xcover. When you just created a new cover, this cover automatically becomes Xthe current cover. When you start the program, there is NO current cover. XSo when you want to change or display a cover, Option 3 or 4 is necessary. X X-------------------- XOption 5, Edit a read-in cover. This option allows you to change the X'current' cover (see Option 4). X X-------------------- XOption 6, Show read-in cover on the screen. This option displays the 'cur- Xrent' cover (see Opt 4). X X-------------------- XOption 7, Print cover(s) to Postscript-file. The function of this option Xshould be clear.The user may specify one or more covers to be printed. The Xformat of the list is the same as with option 2. X XA maximum of four covers will fit on an A4-page.I hope this won't give any Xproblems with american paper sizes. XThe program produces a postscript file as output.The name of this file is: XCOVERS.PS. The name may be changed in the file output.c. X-------------------- X XPlease also read the README file (or at least have a glance at it). XRemco Bruijne @//E*O*F DOC.TXT // chars=`wc -c < DOC.TXT | awk '{ print $1}'` if test $chars != 2961 then echo 'DOC.TXT' is $chars characters, echo should be 2961 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi echo x - Makefile if test -f Makefile then echo Makefile exists, putting output in $$Makefile OUT=$$Makefile else OUT=Makefile fi sed 's/^X//' > $OUT <<'@//E*O*F Makefile //' X# CFLAGS = -DATARI X XOBS = c_cover.o new_it.o string.o subs.o menu.o catalog.o data.o \ X list.o del.o select.o edit.o mktmp.o output.o show.o readcover.o \ X rdparams.o params.o creat.o X Xc_cover: $(OBS) X cc -s -o c_cover $(OBS) X X X Xdata.o: xdefs.h Xcatalog.o: xdefs.h Xnew_it.o: xdefs.h Xc_cover.o: defines.h xdefs.h Xmenu.o: defines.h xdefs.h Xlist.o: defines.h xdefs.h Xdel.o: defines.h xdefs.h Xselect.o: defines.h xdefs.h Xedit.o: defines.h xdefs.h Xcreat.o: defines.h xdefs.h Xmktmp.o: xdefs.h Xsubs.o: defines.h xdefs.h Xoutput.o: defines.h xdefs.h Xshow.o: defines.h xdefs.h Xreadcover.o: defines.h xdefs.h Xrdparams.o: defines.h xdefs.h @//E*O*F Makefile // chars=`wc -c < Makefile | awk '{ print $1}'` if test $chars != 646 then echo 'Makefile' is $chars characters, echo should be 646 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi echo x - README if test -f README then echo README exists, putting output in $$README OUT=$$README else OUT=README fi sed 's/^X//' > $OUT <<'@//E*O*F README //' X>------------------------- jan 1990 ------------------------ X XCASSCOVER is a program for printing music cassette labels. X XThe output is produced in the form of a postscript file, but Xit is possible to add a module for other types of output. XEach section of this file starts with '>' for easy skipping Xuninteresting things.End of file is marked with EOF (in case Xyou want to skip everything). X XThe program can easily be adapted for printing labels for Xcompact disks or data cartridges. Gosh! This almost looks Xlike an advertisement! X X------------------------------------------------------------ X X XCOPYRIGHT :-) X>----------------------------------------------------------- XThe program is in the Public Domain:it may be copied freely, Xbut never for commercial purposes. The code may be used with Xthe same restrictions. The README file must always accompany Xthe package and the references to the author should remain Xintact. Finally, this program is delivered without warranty; XUse it at your own risk. X------------------------------------------------------------ X X XGENERAL X>----------------------------------------------------------- XThe filosophy while writing the program was not to create an Xadvanced userinterface, but rather to write the program in a Xway that it compiles and runs on as many platforms (we used Xto call this 'machines') as possible, without changing code. XSome userinterface aspects are not very friendly (to say the Xleast), but nevertheless it is reasonably simple to obtain Xthe results the program was meant for: printed covers for Xmusic cassettes. X------------------------------------------------------------ X X XABOUT THE CODE (you could just type 'make' and skip this...) X>----------------------------------------------------------- XAt first, the idea was just to write a quick hack which pro- Xduced covers,but you know how it works: when you start using Xa program, you feel the need to enhance the features. OK, so Xit worked out this way. The result is that the code is some- Xtimes a little -how do you say that?- hairy ? XAdd to this the fact that I wanted to use only dynamically Xallocated memory for storing cover info. Just for practice. XNormally, I would make this kind of program more 'ad hoc'. XOk, Now you have read my bad excuses: X HOWTOWORKWITHTHEPROGRAM. X------------------------------------------------------------ X X XHOW DOES IT WORK ? X>----------------------------------------------------------- XRead the file: DOC.TXT, which is an ASCII file. Notice that Xit might be a good idea to go over this README file first. X------------------------------------------------------------ X X XHOW TO COMPILE THE PROGRAM X>----------------------------------------------------------- XOn UNIX systems or an Atari ST with MWC C:type 'make' and it Xshould compile and run without any problems. XOn other systems (like MS-DOS with Microsoft C), compile the XC-files and link them together with the standard C-library. XUnfortunately, MSC doesn't understand UNIX makefiles. Making Xan MSC makefile is left as an exercise to the reader :-). X XIn the file 'defines.h' you may want to change the defini- Xtion of SCRLINES,which is the maximum number of lines on the Xscreen (most ttys: 24). XAlso, you may want to change the pathname to the parameter Xfile. The program looks at two different places to find this Xfile: PARAMFILE1 and PARAMFILE2. The best idea is to leave XPARAMFILE1 as it is. This enables a user to create his own Xparamfile in his local directory (or folder in atari terms), Xbut when a user wants to use the 'predefined' paramfile, Xthe program will try to open PARAMFILE2. X XWHAT IS THE PARAMFILE FOR? XThe paramfile (named CASSETTE.DAT) offers the users the Xflexibility to customize the cassette cover. See also the Xnext section. X XThe file output.c contains the source code of the functions Xthat generates the postscript file. It shows you that post- Xscript is not my native language. English also isn't, as you Xmay have noticed by now. X------------------------------------------------------------ X X X XTHE PARAMETER/CONFIGURATION FILE X>----------------------------------------------------------- XThe parameter file (CASSETTE.DAT) allows a user to customize Xthe cassette covers which are produced by the program. This Xsection describes the format of this file. XAll geometrical parameters are in tenths of millimeters, but Xyou may easily change this into, for example, tenths of an Xinch by changing the definition of the multiplication factor X'tmm' in the file output.c X XA description of EVERY line of the conf. file follows below: XAll positions are with reference to the lower left corner of Xthe cover. What is the lower left corner ? The # indicates Xthe position of the lower left corner as I defined it :-). X X +-------------------------------+ X |a |b | X | ---------- | ---------- | X | ---------- | ---------- | X | ---------- L ---------- | X | | | X | | | X | | | X |-------------------------------| X | BACKTITLE CODE | X |-------------------------------| X | | X |# TAPESORT NOISE-SYS | X +-------------------------------+ X XOK, here we go: X XPosition of the CODE: X 900 205 # CodeXPos and CodeYPos X (90 millimeter to the right, 20.5 millimeter to the top) X XMaximum length of the CODE (in characters): X 3 # CodeLen X XPostscript font in which the CODE is printed: X Helvetica-Bold # CodeFont X XSize of this font: X 17 # CodeFSize X X---------- X XPosition of TapeSort and noise Reduction system indications: X 250 90 # TsXPos and TsYPos X 600 90 # NrXPos and NrYPos X XThe font and size in which these two are printed: X Helvetica-Bold # TsNrFont X 10 # TsNrFSize X X---------- X XPosition of 'BACKTITLE' for sides A and B: X 50 240 # BT1XPos and BT1YPos X 50 187 # BT2XPos and BT2YPos X XLength, font and fontsize thereof: X 35 # BTLen X Helvetica # BTFont X 11 # BTFSize X X---------- X XPosition, font and fontsize of the 'a' and 'b' on the front: X 25 925 # FrAXPos and FrAYPos X 525 925 # FrBXPos and FrBYPos X Helvetica-Bold # FrABFont X 10 # FrABFSize X XPosition, Font and fontsize titles following 'a' and 'b' in Xpicture: (text printed here is the same as the BACKTITLES). X 70 925 # FrTl1XPos and FrTl1YPos X 570 925 # FrTl2XPos and FrTl2YPos X Helvetica # FrTlFont X 8 # FrTlFSize X X---------- X XPosition of the first track of sides A and B respectively: X 25 875 # Tl1XPos and Tl1YPos X 525 875 # Tl2XPos and Tl2YPos X XMaximum lenght of the title of a track (in characters): X 35 # TlLen X XThe vertical distance to next track title (= line distance): X 30 # TlLDist X XFont and fontsize of the track titles: X(track titles are indicated as '----------' in the picture) X Helvetica # TlFont X 7 # TlFSize X X---------- X XAmount of space to be left open (left of a track title) for Xtape counter reading: X 80 # CtTlXDist X XMaximum number of characters of a counter reading X 5 # CtLen X X---------- X XHorizontal separation line on the front (not in the picture, Xbut is drawn under 'a' and 'b'). The line runs from X1 to X2 Xon height Y. X 30 #FTlSepX1 X 970 #FTlSepX2 X 915 #FTlSepY X XVertical separation line on the front (indicated with 'L' in Xthe picture): The line runs from Y1 to Y2 at position X. X 520 #FVSepX X 910 #FVSepY1 X 305 #FVSepY2 X------------------------------------------------------------ X X XSTORAGE FILES: X>----------------------------------------------------------- XThe cassette cover information is stored in a number of Xfiles. The file CATALOG.CAS contains a catalogue of the co- Xvers that are in the 'database'. The information of a cover Xis stored in a file COVERxxx.COV, where xxx is a combination Xof three letters. The first entered cover is COVERAAA.COV, Xthe second is COVERAAB.COV etc. The link between a cover and Xa file is defined in the catalogue file CATALOG.CAS. X XBecause creating a number of covers results in as many files X(plus one, CATALOG.CAS), it is wise to put your cassette Xcover files in a separate directory. Unless you like chaos, Xof course. X------------------------------------------------------------ X X XAND FINALLY: X>----------------------------------------------------------- XI hope you will like this program. When you make enhance- Xments or bugfixes, could you please send them to me? My net Xaddress is: remco@tnoibbc.ibbc.tno.nl. X XThe EOF is not here yet (got you when you wanted to skip the Xentire file!). X XAs I stated in the beginning of this file: you may use this Xprogram free. But please, if you like it: let me know by Xmeans of sending me a postcard so that I know spending my Xtime was worthwhile. X XMy home address is: X Remco Bruijne X Lodewijk van Hamelstraat 15 X 2264 DA LEIDSCHENDAM X The Netherlands X XOn the other hand: if you think the program is completely Xuseless or written so lousy that it shouldn't even be fed to Xa compiler,please also let me know, so that I can stop doing Xthings like this and making a fool of myself :-). X XENJOY IT! X XRemco X XPS: at least I *did* spend some time on writing this file... X------------------------------------------------------------ XPPS, just before EOF was reached: I also have a program for X printing 3 1/2" floppy labels. It is written as a DBman X version 2.0 application on an Atari ST. Output is pro- X duced for a NEC P6+ Pinwriter (which is a fantastic X printer, by the way). XEOF @//E*O*F README // chars=`wc -c < README | awk '{ print $1}'` if test $chars != 9594 then echo 'README' is $chars characters, echo should be 9594 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi echo x - rdparams.c if test -f rdparams.c then echo rdparams.c exists, putting output in $$rdparams.c OUT=$$rdparams.c else OUT=rdparams.c fi sed 's/^X//' > $OUT <<'@//E*O*F rdparams.c //' X#include <stdio.h> X#include "xdefs.h" X#include "defines.h" X Xstatic char ParamFile1[] = PARAMFILE1; Xstatic char ParamFile2[] = PARAMFILE2; Xstatic char *ParamFile; Xstatic int LCount; /* line counter */ Xstatic FILE *PFp; /* Param file pointer */ X Xextern void ReadInt(); Xextern void ReadCoord(); Xextern void ReadString(); Xextern void GetLine(); X Xvoid XInitParams() X{ X if((PFp = fopen(ParamFile1, "r")) == NULL) { X if((PFp = fopen(ParamFile2, "r")) == NULL) { X Panic("Can't open parameter file %s\n or %s for reading\n", X ParamFile1, ParamFile2); X } else { X ParamFile = ParamFile2; X } X } else { X ParamFile = ParamFile1; X } X X LCount = 0; X ReadCoord(&CodeXPos, &CodeYPos); X ReadInt(&CodeLen); X ReadString(&CodeFont); X ReadInt(&CodeFSize); X X ReadCoord(&TsXPos, &TsYPos); X ReadCoord(&NrXPos, &NrYPos); X ReadString(&TsNrFont); X ReadInt(&TsNrFSize); X X ReadCoord(&BT1XPos, &BT1YPos); X ReadCoord(&BT2XPos, &BT2YPos); X ReadInt(&BTLen); X ReadString(&BTFont); X ReadInt(&BTFSize); X X ReadCoord(&FrAXPos, &FrAYPos); X ReadCoord(&FrBXPos, &FrBYPos); X ReadString(&FrABFont); X ReadInt(&FrABFSize); X X ReadCoord(&FrTl1XPos, &FrTl1YPos); X ReadCoord(&FrTl2XPos, &FrTl2YPos); X ReadString(&FrTlFont); X ReadInt(&FrTlFSize); X X ReadCoord(&Tl1XPos, &Tl1YPos); X ReadCoord(&Tl2XPos, &Tl2YPos); X ReadInt(&TlLen); X ReadInt(&TlLDist); X ReadString(&TlFont); X ReadInt(&TlFSize); X X ReadInt(&CtTlXDist); X ReadInt(&CtLen); X X ReadInt(&FTlSepX1); X ReadInt(&FTlSepX2); X ReadInt(&FTlSepY); X X ReadInt(&FVSepX); X ReadInt(&FVSepY1); X ReadInt(&FVSepY2); X X fclose(PFp); X} X Xstatic char LBuf[100]; X Xstatic void XReadInt(Num) Xint *Num; X{ X GetLine(); X *Num = atoi(LBuf); X return; X} X X Xstatic void XReadCoord(Num1, Num2) Xint *Num1; Xint *Num2; X{ X char *Cp; X X GetLine(); X *Num1 = atoi(LBuf); X X /* X * Find start of second number X */ X Cp = LBuf; X /* X * Skip number first X */ X while(*Cp >= '0' && *Cp <= '9') X Cp++; X X /* X * Find next number X */ X while(*Cp != '\n' && *Cp != '\0' && !(*Cp >= '0' && *Cp <= '9')) { X switch(*Cp) { X case ',': X case ';': X case ' ': X case '\t': X Cp++; X continue; X X default: X Panic("Illegal character %c in line %d of file %s", *Cp, X LCount, ParamFile); X } X } X if(*Cp == '\n' || *Cp == '\0') { X Panic("Line %d in parameter file %s too short; second param expected", X LCount, ParamFile); X } X *Num2 = atoi(Cp); X return; X} X X X X Xstatic void XReadString(StringP) Xchar **StringP; X{ X char *Cp; X X GetLine(); X X /* X * Delete comment X */ X Cp = LBuf; X while(*Cp != '#' && *Cp != '\n' && *Cp != '\0') X Cp++; X X *Cp = '\0'; X *StringP = NewString(LBuf); X return; X} X X Xstatic void XGetLine() X{ X LBuf[0] = '#'; X while(LBuf[0] == '#') { X if(fgets(LBuf, 80, PFp) == NULL) X Panic("Premature END-OF-FILE in file %s\n", ParamFile); X X LCount++; X } X return; X} @//E*O*F rdparams.c // chars=`wc -c < rdparams.c | awk '{ print $1}'` if test $chars != 2767 then echo 'rdparams.c' is $chars characters, echo should be 2767 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi echo x - readcover.c if test -f readcover.c then echo readcover.c exists, putting output in $$readcover.c OUT=$$readcover.c else OUT=readcover.c fi sed 's/^X//' > $OUT <<'@//E*O*F readcover.c //' X#include <stdio.h> X#include "defines.h" X#include "xdefs.h" X Xvoid XReadACover() X{ X char Buf[100]; X int Num; X X ClearCurr(); X X ListCovers(ALL); X printf(" Which cover do you want to retrieve ? ..."); fflush(stdout); X gets(Buf); X Num = atoi(Buf); X X if(Num == 0) return; /* no number entered ... */ X if(Num > NCatItems) { X Attention("Cover number %d is too high, %d maximum ...", X Num, NCatItems); X return; X } X X CurIt = FirstCatIt; X while(--Num) X CurIt = CurIt->Next; X X /* X * We have the right item now !! X */ X ReadCover(CurIt, CurCass); X return; X} X X#define LINELEN 80 X#define NOCOVFILE "File %s, Line %d is no cover file" X X Xvoid XReadCover(It, Cass) XCATITEM *It; XCASS *Cass; X{ X FILE *Fp; X char Buf[LINELEN]; X char *Cp; X char Side; X SONG *NewS; X SONG *SongP; X SONG **List; X int LineNum = 1; X X /* X * Open file X */ X if((Fp = fopen(It->FileName, "r")) == NULL) { X Panic("Cannot open cover file %s for reading", It->FileName); X } X X /* X * Check if the first line contains a magic X */ X if(fgets(Buf, LINELEN-1, Fp) == NULL) X Panic(NOCOVFILE, It->FileName, LineNum); X X X NullEnd(Buf, LINELEN-1); X if(StringDiff(Buf, CASSMAGIC)) X Panic(NOCOVFILE, It->FileName, LineNum); X X while(fgets(Buf, LINELEN-1, Fp) != NULL) { X NullEnd(Buf, LINELEN-1); X LineNum++; X Cp = Buf; X if(*Cp++ != '#') X Panic(NOCOVFILE, It->FileName, LineNum); X X switch(*Cp++) { X case 'S': /* TAPETYPE */ X Cass->TapeType = *Cp; X break; X X case 'N': /* NOISEREDUCTION SYSTEM */ X Cass->NoiseReduction = *Cp; X break; X X case 'C': /* CODE ON BACK OF COVER */ X Cass->BackCode = NewString(Cp); X break; X X case 'T': /* BACKTITLE 1 AND 2 */ X if(*Cp++ == '1') { X Cass->BackTl1 = NewString(Cp); X } else { X Cass->BackTl2 = NewString(Cp); X } X break; X X case 'c': /* TAPECOUNT OF SONG */ X Side = *Cp++; X X /* X * So a new song must be allocated. X */ X NewS = NewSong(); X NewS->Next = (SONG *)0; X X NewS->Count = NewString(Cp); X X /* X * Now link it into the right list. X */ X if(Side == '1') X List = &(Cass->Side1); X else X List = &(Cass->Side2); X X X if(*List == (SONG *)0) { /* the very first song ! */ X *List = NewS; X } else { X /* X * Now first find the end of the list X */ X SongP = *List; X while(SongP->Next != (SONG *)0) /* find end of songlist */ { X SongP = SongP->Next; X } X X SongP->Next = NewS; X } X X X /* X * New song is linked at the end of the right list. X * Now read a line which MUST contain a songtitle X */ X LineNum++; X if(fgets(Buf, LINELEN-1, Fp) == NULL) X Panic("Cover file %s illegal; title expected!", It->FileName); X X NullEnd(Buf, LINELEN-1); X if(Buf[0] != '#' || Buf[1] != Side) X Panic("Cover file %s illegal; title expected!", It->FileName); X X NewS->Title = NewString(Buf+2); X break; X X default: X Panic("Illegal line in cover file: %s", Buf); X } X } X} @//E*O*F readcover.c // chars=`wc -c < readcover.c | awk '{ print $1}'` if test $chars != 2886 then echo 'readcover.c' is $chars characters, echo should be 2886 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi echo x - select.c if test -f select.c then echo select.c exists, putting output in $$select.c OUT=$$select.c else OUT=select.c fi sed 's/^X//' > $OUT <<'@//E*O*F select.c //' X#include <stdio.h> X#include "xdefs.h" X#include "defines.h" X X#define NUM(p) ((p) >= '0' && (p) <= '9') X X#define TO_NUM1 1 X#define NUM1 2 X#define CHECK_IF_RANGE 3 X#define TO_NUM2 4 X#define NUM2 5 X X/*----------------------------------------------*\ X | Select the items of which the numbers are | X | typed in. The format is very simple: | X | | X | 2,3,8-10,20,22 | X | | X | The dash indicates a range. | X | The comma is a separator, but SPACE, ';', | X | '.' and TAB are also OK | X | Space may be inserted anywhere except in a | X | number (this would cause it to be read as 2 | X | smaller numbers | X\*----------------------------------------------*/ XDoSelect(What, MaxNum) Xint What; Xint MaxNum; X{ X char Buf[200]; X char c; X char *Cp; X int Num1; X int Num2; X int Mode; X int i; X X gets(Buf); X Cp = Buf; X while(*Cp != '\n' && *Cp != '\r' && *Cp != '\0') X Cp++; X X *Cp++ = '.'; *Cp = '\0'; /* Put . at end of string */ X X Cp = Buf; X X /* X * When we typed a '*' at the beginning of the X * line, all numbers are selected X */ X if(*Cp == '*') { /* ALL numbers selected */ X for(i = 1; i <= MaxNum; i++) X Select(What, i, MaxNum); X return(0); X } X X Mode = TO_NUM1; X X while((c = *Cp++) != '\0') { X switch(Mode) { X case TO_NUM1: X if(AnyChar(c, "\t .,;")) /* Skip separators */ X continue; X X if(!NUM(c)) X return(-1); X X Num1 = 0; X Mode = NUM1; X Cp--; /* rewind one character */ X break; X X case NUM1: X if(NUM(c)) { X Num1 *= 10; X Num1 += c - '0'; X break; X } X if(AnyChar(c, " \t")) { /* is this a range ? */ X Mode = CHECK_IF_RANGE; /* if no range, do num1 */ X break; X } X if(c == '-') { /* range specification */ X Mode = TO_NUM2; X break; X } X if(AnyChar(c, ",.;")) { /* number separator */ X Select(What, Num1, MaxNum); X Mode = TO_NUM1; X break; X } X return(-1); /* illegal character */ X X case CHECK_IF_RANGE: X if(AnyChar(c, " \t")) X break; X if(c == '-') { X Mode = TO_NUM2; X break; X } X if(AnyChar(c, ",.;") || NUM(c)) { X X Select(What, Num1, MaxNum); /* did not do this yet */ X /* X * When a number, 'backspace' one char X */ X if(NUM(c)) X Cp--; X Mode = TO_NUM1; X break; X } X return(-1); X X case TO_NUM2: X if(AnyChar(c, "\t .,;")) /* Skip separators */ X continue; X X if(!NUM(c)) X return(-1); X X Num2 = 0; X Mode = NUM2; X Cp--; /* rewind one character */ X break; X X case NUM2: X if(NUM(c)) { X Num2 *= 10; X Num2 += c - '0'; X break; X } X if(AnyChar(c, ",.;")) { /* number separator */ X for(i = Num1; i <= Num2; i++) X Select(What, i, MaxNum); X Mode = TO_NUM1; X break; X } X return(-1); /* illegal character */ X } X } X return(0); X} X X X X X/*------------------------------*\ X | Select the specified item | X\*------------------------------*/ Xvoid XSelect(What, Num, MaxNum) Xint What; Xint Num; Xint MaxNum; X{ X CATITEM *ItPt; X SONG *SongP; X X if(Num > MaxNum || Num <= 0) { X return; X } X X Num--; X if(What == CAT_ITEMS) { X ItPt = FirstCatIt; X X while(Num--) X ItPt = ItPt->Next; X X ItPt->Status |= SELECTED; X } else { X if(What == SONGS1) { X SongP = CurCass->Side1; X } else { X SongP = CurCass->Side2; X } X while(Num--) X SongP = SongP->Next; X X SongP->Status |= SELECTED; X } X return; X} X X X X/*------------------------------*\ X | Deselect all selected items | X\*------------------------------*/ Xvoid XUnSelect(What) Xint What; X{ X CATITEM *ItPt; X X if(What == CAT_ITEMS) { X ItPt = FirstCatIt; X while(ItPt != (CATITEM *)0) { X ItPt->Status &= ~SELECTED; X ItPt = ItPt->Next; X } X } X return; X} @//E*O*F select.c // chars=`wc -c < select.c | awk '{ print $1}'` if test $chars != 3591 then echo 'select.c' is $chars characters, echo should be 3591 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi echo x - show.c if test -f show.c then echo show.c exists, putting output in $$show.c OUT=$$show.c else OUT=show.c fi sed 's/^X//' > $OUT <<'@//E*O*F show.c //' X#include <stdio.h> X#include "defines.h" X#include "xdefs.h" X X X Xvoid XShowCover() X{ X int NSongs1, NSongs2; X X if(CurIt == (CATITEM *)0) { X Attention("First retrieve the cover you wish to display"); X return; X } X X /* X * Show global data of this cover X */ X NLines(SCRLINES - 6 - 1); X ShowGlobal(CurIt, CurCass); X NLines(1); X RetCont(); X X NSongs1 = CountSongs(CurCass->Side1); X NSongs2 = CountSongs(CurCass->Side2); X X /* X * When all songs fit on one screen, do so, else on two screens. X * -1 and -1 are for the headers printed by ShowSongs(), X * First -1 for NLines(1) separator between side 1 and 2 X * -1 and -1 for NLines(1) and for RetCont(). X */ X if(NSongs1 + NSongs2 < (SCRLINES -1 -1 -1 -1 -1)) { X NLines(SCRLINES - (NSongs1+1) -1 - (NSongs2+1) -1); X ShowSongs(CurCass->Side1, 1); X NLines(1); X ShowSongs(CurCass->Side2, 2); X NLines(1); X RetCont(); X return; X } X X /* X * Show Songs of Side 1 X */ X NLines(SCRLINES - NSongs1-1 - 1); X ShowSongs(CurCass->Side1, 1); X NLines(1); X RetCont(); X X /* X * Show Songs of Side 2 X */ X NLines(SCRLINES - NSongs2-1 - 1); X ShowSongs(CurCass->Side2, 2); X NLines(1); X RetCont(); X return; X} X Xvoid XShowGlobal(It, Cas) XCATITEM *It; XCASS *Cas; X{ X printf(" description: %s\n", It->Description); X NLines(1); X printf(" Tape type: "); X switch(Cas->TapeType) { X case FEO3: X printf("FERRO; "); X break; X X case CRO2: X printf("CHROME; "); X break; X X case FECR: X printf("FECR; "); X break; X X case METAL: X printf("METAL; "); X break; X X default: X printf("UNKNOWN; "); X break; X } X X printf("Noise reduction: "); X switch(Cas->NoiseReduction) { X case DOLBY_B: X printf("DOLBY B;"); X break; X case DOLBY_C: X printf("DOLBY C;"); X break; X case DBX: X printf("DBX;"); X break; X case HXPRO: X printf("HX-PRO;"); X break; X case NO_NR: X printf("NONE"); X break; X default: X printf("UNKNOWN;"); X break; X } X X printf(" Back code : %s\n", Cas->BackCode); X printf(" Back title 1: %s\n", Cas->BackTl1); X printf(" Back title 2: %s\n", Cas->BackTl2); X NLines(1); X return; X} X X Xvoid XShowSongs(Song, Side) XSONG *Song; Xint Side; X{ X int Count = 0; X X printf(" TITLES ON SIDE %d:\n", Side); X while(Song != (SONG *)0) { X Count++; X /* X * Check if counter is given X */ X if(*(Song->Count) == '\0') { X printf("%2d) %s\n", Count, Song->Title); X } else { X printf("%2d) %5s: %s\n", Count, Song->Count, Song->Title); X } X Song = Song->Next; X } X return; X} @//E*O*F show.c // chars=`wc -c < show.c | awk '{ print $1}'` if test $chars != 2406 then echo 'show.c' is $chars characters, echo should be 2406 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi echo x - string.c if test -f string.c then echo string.c exists, putting output in $$string.c OUT=$$string.c else OUT=string.c fi sed 's/^X//' > $OUT <<'@//E*O*F string.c //' X/*------------------------------------------*\ X | Return the length of string s, EXCLUDING | X | the \0 at the end of it. | X\*------------------------------------------*/ XStringLen(s) Xchar *s; X{ X int Count = 0; X X while(*s++ != '\0') X Count++; X X return(Count); X} X X X X X/*----------------------------------------------*\ X | Copy a string From to string To including | X | the \0 at the end of string From. | X\*----------------------------------------------*/ XStringCopy(From, To) Xregister char *From; Xregister char *To; X{ X while((*To++ = *From++) != '\0'); X return; X} X X X X X/*----------------------------------------------*\ X | Ret 0 when strings equal, 1 when different | X\*----------------------------------------------*/ XStringDiff(s1, s2) Xchar *s1; Xchar *s2; X{ X while(*s1 == *s2) { X if(*s1 == '\0') { /* and thus *s2 == '\0' */ X return(0); X } X s1++; s2++; X } X return(1); /* strings differ */ X} X X X X/*----------------------------------------------*\ X | Ret 0 when strings equal, 1 when different | X | Not more than Len chars are compared | X\*----------------------------------------------*/ XStringNDiff(s1, s2, Len) Xchar *s1; Xchar *s2; Xint Len; X{ X while(*s1 == *s2) { X Len--; X if(*s1 == '\0' || Len == 0) { /* and thus *s2 == '\0' */ X return(0); X } X s2 += 1; X s1 += 1; X } X return(1); /* strings differ */ X} X X X X/*--------------------------------------*\ X | Put a '\0' at the end of string s | X\*--------------------------------------*/ Xvoid XNullEnd(s, MaxLen) Xregister char *s; Xregister int MaxLen; X{ X while(*s != '\n' && *s != '\r' && *s != '\0' && MaxLen--) X s++; X X *s = '\0'; X return; X} X X X X X X X/*--------------------------------------*\ X | Check if arg CheckChar is any of the | X | characters in array List. | X\*--------------------------------------*/ XAnyChar(CheckChar, List) Xchar CheckChar; Xchar *List; X{ X while(*List != '\0') { X if(CheckChar == *List) X return(1); X X List++; X } X return(0); X} @//E*O*F string.c // chars=`wc -c < string.c | awk '{ print $1}'` if test $chars != 1927 then echo 'string.c' is $chars characters, echo should be 1927 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi echo x - subs.c if test -f subs.c then echo subs.c exists, putting output in $$subs.c OUT=$$subs.c else OUT=subs.c fi sed 's/^X//' > $OUT <<'@//E*O*F subs.c //' X#include <stdio.h> X#include "defines.h" X#include "xdefs.h" X Xextern void SaveSongs(); X Xvoid XPanic(s1, s2, s3, s4, s5, s6) Xchar *s1, *s2, *s3, *s4, *s5, *s6; X{ X ClearScreen(); X printf("ERROR: "); X printf(s1, s2, s3, s4, s5, s6); X printf("\n\n\n"); X exit(1); X} X X X Xvoid XAttention(s1, s2, s3, s4, s5) Xchar *s1, *s2, *s3, *s4, *s5; X{ X NLines((SCRLINES-3)/2 + 3); X printf("ATTENTION: "); X printf(s1, s2, s3, s4, s5); X NLines((SCRLINES-3)/2); X RetCont(); X} X X X X X Xvoid XRetCont() X{ X char Buf[100]; X X printf("Hit <RETURN> to continue ..."); fflush(stdout); X gets(Buf); X return; X} X X X XConfirm() X{ X char Buf[80]; X char c; X X gets(Buf); X c = Buf[0]; X if(c == 'y' || c == 'j' || c == 'Y' || c == 'J' ) X return(1); X return(0); X} X X X Xvoid XSaveCover(It, Cass) XCATITEM *It; XCASS *Cass; X{ X FILE *Fp; X X if(It == (CATITEM *)0 || Cass == (CASS *)0) { X Attention("There is no cover to save"); X return; X } X X if(It->FileName == (char *)0 || *(It->FileName) == '\0') { X Attention("There is no cover to save"); X return; X } X X if((Fp = fopen(It->FileName, "w")) == NULL) { X Attention("Can't write cover information to disk !!"); X return; X } X X /* X * Write magic string first X */ X fprintf(Fp, "%s\n", CASSMAGIC); X X fprintf(Fp, "#S%c\n", Cass->TapeType); X fprintf(Fp, "#N%c\n", Cass->NoiseReduction); X fprintf(Fp, "#C%s\n", Cass->BackCode); /* String may be empty */ X fprintf(Fp, "#T1%s\n", Cass->BackTl1); X fprintf(Fp, "#T2%s\n", Cass->BackTl2); X X SaveSongs(Fp, 1, Cass->Side1); X SaveSongs(Fp, 2, Cass->Side2); X X fclose(Fp); X return; X} X X X Xstatic void XSaveSongs(Fp, Side, SongP) XFILE *Fp; Xint Side; XSONG *SongP; X{ X while(SongP != (SONG *)0) { X fprintf(Fp, "#c%d%s\n", Side, SongP->Count); X fprintf(Fp, "#%d%s\n", Side, SongP->Title); X SongP = SongP->Next; X } X return; X} X X X X X/* X * Return a pointer to a song PREVIOUS !!! to Num-est song X * So Num may NOT be 0 or 1! X */ XSONG * XFindSong(Song, Num) XSONG *Song; Xint Num; X{ X X if(Num == 0 || Num == 1) X Panic("FindSong Num = %d\n", Num); X X --Num; X while(--Num && Song != (SONG *)0) { X Song = Song->Next; X } X return(Song); X} X XCountSongs(Song) XSONG *Song; X{ X int Count = 0; X while(Song != (SONG *)0) { X Count++; X Song = Song->Next; X } X return(Count); X} X Xvoid XClearCurr() X{ X if(CurIt == (CATITEM *)0) return; X ClearCass(CurCass); X CurIt = (CATITEM *)0; X return; X} X X Xvoid XClearCass(Cas) XCASS *Cas; X{ X SONG *SongP; X SONG *List; X X free(Cas->BackCode); X Cas->BackCode = (char *)0; X X free(Cas->BackTl1); X Cas->BackTl1 = (char *)0; X X free(Cas->BackTl2); X Cas->BackTl2 = (char *)0; X X /* X * Clear songs of side 1 X */ X List = Cas->Side1; X X /* X * While there are next songs ... X */ X while(List != (SONG *)0 && List->Next != (SONG *)0) { X SongP = List->Next; /* SongP points to song to be freed */ X X free(SongP->Count); /* free count string */ X SongP->Count = (char *)0; X X free(SongP->Title); /* free title string */ X SongP->Title = (char *)0; X X List->Next = SongP->Next; /* Delete SongP from linked list .. */ X free(SongP); /* And free song */ X } X X if(List != (SONG *)0) { X /* X * now free the last one X */ X free(List->Count); X List->Count = (char *)0; X free(List->Title); X List->Title = (char *)0; X free(List); X Cas->Side1 = (SONG *)0; X } X X X /* X * Clear songs of side 2 X */ X List = Cas->Side2; X X /* X * While there are next songs ... X */ X while(List != (SONG *)0 && List->Next != (SONG *)0) { X SongP = List->Next; /* SongP points to song to be freed */ X X free(SongP->Count); /* free count string */ X SongP->Count = (char *)0; X free(SongP->Title); /* free title string */ X SongP->Title = (char *)0; X X List->Next = SongP->Next; /* Delete SongP from linked list .. */ X free(SongP); /* And free song */ X } X X if(List != (SONG *)0) { X /* X * now free the last one X */ X free(List->Count); X List->Count = (char *)0; X X free(List->Title); X List->Title = (char *)0; X X free(List); X Cas->Side2 = (SONG *)0; X } X return; X} X X X Xvoid XClearScreen() X{ X /* X * Brrrr.. X */ X NLines(SCRLINES); X return; X} X X X Xvoid XNLines(Count) Xint Count; X{ X if(Count <= 0) { X Attention("NLines(Count): Count <= 0!!!"); X return; X } X X while(Count--) X printf("\n"); X X return; X} @//E*O*F subs.c // chars=`wc -c < subs.c | awk '{ print $1}'` if test $chars != 4498 then echo 'subs.c' is $chars characters, echo should be 4498 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi echo x - xdefs.h if test -f xdefs.h then echo xdefs.h exists, putting output in $$xdefs.h OUT=$$xdefs.h else OUT=xdefs.h fi sed 's/^X//' > $OUT <<'@//E*O*F xdefs.h //' X#ifndef XDEFS_H X#define XDEFS_H X Xtypedef unsigned short flag; X X Xtypedef struct cat_item CATITEM; X Xstruct cat_item { X char *FileName; X char *Description; X flag Status; X CATITEM *Next; X}; X X Xtypedef struct song SONG; X Xstruct song { X char *Count; X char *Title; X flag Status; X SONG *Next; X}; X Xtypedef struct { X char TapeType; X char NoiseReduction; X char *BackCode; X char *BackTl1; X char *BackTl2; X SONG *Side1; X SONG *Side2; X} CASS; X X X Xtypedef struct { X char *Text; X int Func; X} MLINE; X X X Xtypedef struct { X char *MenuTitle; X int NEntries; X MLINE *Entry; X} MENUITEM; X Xextern char *NewString(); Xextern CATITEM *NewCatItem(); Xextern CASS *NewCass(); Xextern SONG *NewSong(); Xextern SONG *FindSong(); X Xextern void InDescription(); Xextern void InTapeType(); Xextern void InNoiseRed(); Xextern void InBackCode(); Xextern void RetCont(); Xextern void ClearCass(); Xextern void ClearScreen(); Xextern void NLines(); Xextern void AddCatItem(); Xextern void Select(); Xextern void ReadCover(); Xextern void ListCovers(); Xextern void SaveCover(); Xextern void ShowGlobal(); Xextern void ShowSongs(); Xextern void ClearCurr(); Xextern void UnSelect(); Xextern void ShowGlobal(); Xextern void NullEnd(); Xextern void Panic(); Xextern void Attention(); X Xextern MENUITEM MainMenu; Xextern MENUITEM TapeMenu; Xextern MENUITEM NoiseMenu; X X Xextern CATITEM *FirstCatIt; Xextern CATITEM *LastCatIt; Xextern int NCatItems; Xextern CASS CurCass[]; Xextern CATITEM *CurIt; X Xextern char LineBuf[]; Xextern char Buf[]; X X X X/* X * Now follow the declarations of all parameters concerning the layout X */ Xextern int CodeXPos; /* Backcode parameter 1 */ Xextern int CodeYPos; /* Backcode parameter 1 */ Xextern int CodeLen; /* Backcode parameter 2 */ Xextern char *CodeFont; /* Backcode parameter 3 */ Xextern int CodeFSize; /* Backcode parameter 4 */ X Xextern int TsXPos; /* Tapetype xpos, parameter 5 */ Xextern int TsYPos; /* Tapetype ypos, parameter 5 */ Xextern int NrXPos; /* NoiseRed xpos, parameter 6 */ Xextern int NrYPos; /* NoiseRed ypos, parameter 6 */ Xextern char *TsNrFont; /* tapetype&NoiseRed font, p 7 */ Xextern int TsNrFSize; /* ts & NoiseRed fontsize, p 8 */ X Xextern int BT1XPos; /* Backtitle 1 xpos, param 9 */ Xextern int BT1YPos; /* Backtitle 1 ypos, param 9 */ Xextern int BT2XPos; /* Backtitle 2 xpos, param 10 */ Xextern int BT2YPos; /* Backtitle 2 ypos, param 10 */ Xextern int BTLen; /* Backtitle Length, param 11 */ Xextern char *BTFont; /* Backtitle font, param 12 */ Xextern int BTFSize; /* Backtitel fontsize, param 13 */ X Xextern int FrAXPos; /* Front A, xpos, param 14 */ Xextern int FrAYPos; /* Front A, ypos, param 14 */ Xextern int FrBXPos; /* Front B, xpos, param 15 */ Xextern int FrBYPos; /* Front B, ypos, param 15 */ Xextern char *FrABFont; /* Front A&B, font, param 16 */ Xextern int FrABFSize; /* Front A&B, fontsize, par 17 */ X Xextern int FrTl1XPos; /* Front title 1 xpos, par 18 */ Xextern int FrTl1YPos; /* Front title 1 ypos, par 18 */ Xextern int FrTl2XPos; /* Front title 2 xpos, par 19 */ Xextern int FrTl2YPos; /* Front title 2 ypos, par 19 */ Xextern char *FrTlFont; /* Fronttitle font, param 20 */ Xextern int FrTlFSize; /* Fronttitle fontsiz, param 21 */ X Xextern int Tl1XPos; /* Title 1 xpos, param 22 */ Xextern int Tl1YPos; /* Title 1 ypos, param 22 */ Xextern int Tl2XPos; /* Title 2 xpos, param 23 */ Xextern int Tl2YPos; /* Title 2 ypos, param 23 */ Xextern int TlLen; /* length of title, par 24 */ Xextern int TlLDist; /* line spacing titles, par 25 */ Xextern char *TlFont; /* Title font, parameter 26 */ Xextern int TlFSize; /* and fontsize, parameter 27 */ X Xextern int CtTlXDist; /* Dist between tl and ct,par28 */ Xextern int CtLen; /* countlength, parameter 29 */ X Xextern int FTlSepX1; /* horizontal line front xfrom */ Xextern int FTlSepX2; /* horizontal line front xto */ Xextern int FTlSepY; /* horizontal line front y */ X Xextern int FVSepX; /* front separation line x */ Xextern int FVSepY1; /* front separation line yfrom */ Xextern int FVSepY2; /* front separation line yto */ X X X X X#endif XDEFS_H @//E*O*F xdefs.h // chars=`wc -c < xdefs.h | awk '{ print $1}'` if test $chars != 4212 then echo 'xdefs.h' is $chars characters, echo should be 4212 characters\! else chmod u=rw-,g=r--,o=r-- $OUT fi # End of shell archive exit 0 -------------cut here--------- -- --------------------------------------------------------------------------- Remco Bruijne USENET: remco@tnoibbc.ibbc.tno.nl PHONE: +31 15 606437 ---------------------------------------------------------------------------