home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
145.lha
/
sonixpeek.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-21
|
9KB
|
411 lines
/*
* SONIXPEEK.C (C) Copyright Eddy Carroll, 1988
*
* Scans one or more Aegis Sonix files building a list of unique
* instruments used within those files. At the end, a list of the
* instruments found is printed (can be redirected to a file if
* desired).
*
* Usage: SonixPeek {-i} {-n} {-ofile} {-xdirectory} filename
*
* If filename is a sonix file, then only that file is scanned. If
* filename is a directory, then all the files in that directory which
* contain Sonix files are scanned.
*
* If the -i (interactive) flag is present, then after each file is
* found, the user is asked whether it should be included or not when
* building the list of instruments.
*
* If the -o flag is present, then the list of instruments is stored
* in the specified file, rather than being displayed on the screen.
*
* If the -x flag is present, then the output is given in the form
* of an executable file which consists of a line for each instrument
* found of the form COPY <instrument> TO <directory>, where <directory>
* is given immediately after the -x switch.
*
* If the -n flag is present, then the list of instruments found in each
* file, when a directory is being searched, is not printed.
*
* Note: Compile with Aztec C V3.20 or later. Should also compile with
* Lattice C.
*/
#include <libraries/dos.h>
#define EOL '\012'
#define EOF '\037'
#define TAB '\011'
#define CR '\015'
#define MAXINS 1000 /* Only 200 instruments allowed */
#define MAXFILENUM 200 /* No more than 200 scores allowed */
/* IFF defines */
#define MakeID(a,b,c,d) (long)((long)(a)<<24 | (long)(b)<<16 | (c)<<8 | (d))
#define FORM MakeID('F','O','R','M')
#define SMUS MakeID('S','M','U','S')
#define NAME MakeID('N','A','M','E')
#define SNX1 MakeID('S','N','X','1')
#define INS1 MakeID('I','N','S','1')
#define TRAK MakeID('T','R','A','K')
#define roundup(a) ((a + 1L) & ~1L)
int interactive = 0 ; /* TRUE if interactive selection of files */
int multi = 0; /* TRUE if a directory specified instead of file */
int supress = 0; /* TRUE if listing of instruments is supressed */
char *dirname = NULL; /* Directory to copy to for -x option */
char *rname = NULL; /* Real filename of directory or single file */
char *suffix[] =
{".ss", ".instr"}; /* For creating 'copy' batch file */
LONG Examine(), ExNext(), Read(), Write();
LONG Lock(), CurrentDir();
char *malloc();
int numins = 1; /* Current number of instruments */
char *ins[MAXINS]; /* Room for 1000 instruments */
int numfiles = 0; /* Current number of files */
char *files[MAXFILENUM]; /* Room for 200 files */
struct FileInfoBlock *stdin, *stdout; /* File pointers */
struct FileInfoBlock *Open(), *Output(), *Input(), *infile, *outfile;
struct FileInfoBlock myfib;
/*
* Output string to file
*
*/
void fprint(f, s)
struct FileInfoBlock *f;
char *s;
{
char *p;
for (p = s; *p; p++)
;
Write(f, s, (long)(p - s));
}
/*
* Output string to stdout
*
*/
void print(s)
char *s;
{
fprint(stdout,s);
}
/*
* Abort program due to error
*
*/
void abort(string,code)
char *string;
int code;
{
print(string);
if (outfile != stdout && outfile)
Close(outfile);
exit(code);
}
#define P print
/*
* Prints help message to standard output
*
*/
void help()
{
P("\nSonixPeek Instrument Lister (C) Eddy Carroll, March 1988\n\n");
P("Usage: SonixPeek {-i} {-n} {-ofile} {-xdirectory} filename\n\n");
P("Filename is the Aegis Sonix file for which the instruments are to\n");
P("be listed. If it is a directory, then all the Sonix files in\n");
P("that directory are checked, and a sorted list of the instruments\n");
P("contained in all of them is prepared. The flags operate as follows:\n\n");
P(" -i For a directory search, get user to verify whether or not\n");
P(" to include each Sonix file (interactively).\n\n");
P(" -n Don't list instruments as they are found (for directories only).\n\n");
P(" -o Redirect sorted output to named file.\n\n");
P(" -x Format output as an execute file which will copy all the\n");
P(" instruments found to the named directory\n\n");
}
/*** Start of actual program ***/
main(argc, argv)
int argc;
char *argv[];
{
void addinstrument(), skip(), dumpins();
char ch, charin(), ch1, ch2;
int argc2, i;
LONG mylock, oldlock;
char *fname, nextfile[40], *p;
stdin = Input();
outfile = stdout = Output();
infile = 0;
/* Scan command line for possible switches */
for (argc2 = 1; argc2 < argc && *argv[argc2] == '-'; argc2++) {
switch (tolower(*(argv[argc2]+1))) {
case 'i': interactive = 1;
break;
case 'n': supress = 1;
break;
case 'o': if ((outfile = Open(argv[argc2]+2,MODE_NEWFILE)) == 0)
abort("Can't open output file\n", 20);
break;
case 'x': dirname = argv[argc2] + 2;
break;
default: print("Unknown option ");
print(argv[argc2]);
print("ignored\n");
break;
}
}
/* If missing filename, or filename == '?', print instructions */
if (argc2 != (argc-1) || *argv[argc2] == '?') {
help();
abort(NULL,0);
}
fname = argv[argc2];
if ((mylock = Lock(fname,ACCESS_READ)) == 0L)
abort("Can't open input file.\n",20);
Examine(mylock,&myfib);
rname = malloc(strlen(myfib.fib_FileName)+1);
strcpy(rname,myfib.fib_FileName); /* Save filename for later */
if (myfib.fib_DirEntryType > 0L) {
multi = 1;
oldlock = CurrentDir(mylock);
while (ExNext(mylock, &myfib))
if (myfib.fib_DirEntryType < 0L)
scan(&(myfib.fib_FileName));
oldlock = CurrentDir(oldlock);
} else
scan(fname);
dumpins();
if (outfile != stdout)
Close(outfile);
UnLock(mylock);
exit(0);
}
/*
* Scans filename for instruments. If found, they are added to the
* list of instruments already in memory. Returns 0 for success, -1
* if invalid file.
*
*/
int scan(filename)
char *filename;
{
LONG header[3];
char instr[50];
char response[50];
if ((infile = Open(filename,MODE_OLDFILE)) == 0L) {
print("Can't open file ");
print(filename);
print(" for input\n");
return(-1);
}
if (Read(infile,header,8L) != 8L || header[0] != FORM) {
Close(infile);
return(-1);
}
if (Read(infile,header,4L) != 4L || header[0] != SMUS) {
Close(infile);
return(-1);
}
if (interactive) {
print("Include file ");
print(filename);
print(" (CR = no)? ");
Read(stdin, response, 50L);
if (tolower(*response) != 'y')
return(-1);
} else if (multi && !supress) {
print("\nFile ");
print(filename);
print(":\n");
}
files[numfiles] = malloc(strlen(filename) + 1);
strcpy(files[numfiles++], filename);
while (Read(infile,header,8L) == 8L) {
if (header[0] != INS1) {
skip(infile,header[1]);
} else {
skip(infile,4L); /* skip position of instrument parameter */
(void)Read(infile, instr, roundup(header[1]) - 4L);
instr[header[1] - 4L] = '\0';
addinstrument(instr);
}
}
Close(infile);
return(0);
}
void skip(file,size)
struct FileInfoBlock *file;
LONG size;
{
char s[256];
LONG len = 1L;
size = roundup(size);
while (size > 256L && len) {
len = Read(file, s, 256L);
size -= 256L;
}
(void)Read(file, s, size);
}
/*
* Adds instrument of length len into list of instruments, but only
* if its not already present in the list.
*
*/
void addinstrument(instr)
char *instr;
{
int pos, i;
if (pos = matchins(instr)) {
for (i = numins++; i > pos; i--)
ins[i] = ins[i-1];
ins[pos] = malloc(strlen(instr)+1);
strcpy(ins[pos], instr);
}
if (multi && !supress) {
print(" ");
print(instr);
print("\n");
}
}
/*
* Compares string p to string s, ignoring case of alpha chars.
* Returns -ve if p < s, 0 if p = s, +ve if p > s.
*
*/
int mystrcmp(p,s)
char *p, *s;
{
while (*p && *s && tolower(*p) == tolower(*s))
p++, s++;
return(tolower(*p) - tolower(*s));
}
/*
* Searches instrument array for a match with given instrument.
* Returns 0 if found, else position in array to insert new element.
*
*/
int matchins(instr)
char *instr;
{
int i, z;
char *p, *s;
if (numins < 2)
return (1); /* Must be first entry */
for (i = 1; i < numins; i++) {
if ((z = mystrcmp(instr, ins[i])) <= 0) {
if (z)
return(i); /* If less, insert here */
else
return(0); /* If equal, don't insert */
}
}
return (i); /* Must be at end of list, so return last item */
}
/*
* Dumps instrument list to outfile
*
*/
void dumpins()
{
int tofile, i, j;
if (numins <= 1) {
print("No instruments found.\n");
return;
}
if (numfiles == 0)
return;
fprint(outfile,";\n; Sorted list of instruments\n");
fprint(outfile, "; --------------------------\n;\n");
if (numfiles == 1) {
fprint(outfile, "; Taken from file ");
fprint(outfile, files[0]);
fprint(outfile, "\n");
} else {
fprint(outfile,"; Taken from these files:\n;\n");
for (i = 0; i < numfiles; i++) {
fprint(outfile, "; ");
fprint(outfile,files[i]);
fprint(outfile,"\n");
}
}
fprint(outfile,";\n");
for (i = 1; i < numins; i++) {
for (j = (dirname != 0); j >= 0; j--) {
if (dirname) {
fprint(outfile, "copy ");
} else {
fprint(outfile," ");
}
fprint(outfile,ins[i]);
if (dirname) {
fprint(outfile,suffix[j]);
fprint(outfile, " to ");
fprint(outfile, dirname);
}
fprint(outfile,"\n");
}
}
}