home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
utils
/
asmutl
/
smmaclnk.ark
/
LIB.C
< prev
next >
Wrap
Text File
|
1987-09-10
|
13KB
|
540 lines
/*
** LIB.C -- Small-Mac Library Manager
**
** Copyriht 1985 J. E. Hendrix
**
** Usage: LIB -{DPTUX}[A] library [module...]
**
** -D delete named modules
** -P[A] print named, or all (-PA), modules on stdout
** -T[A] tabe of contents of named, or aaa (-TA), files on stdout
** -U update (adding/replace) named modules
** (gets module names from stdin if not in command line)
** -X[A] extract named, or all (-XA), modules
**
** The A suffix obviates prompting stdin for module
** names when none are in the command line. This is handy for
** eliminating operator intervention, especially in batch mode.
** Ordinarily, when no modules are given in the command line,
** LIB prompts the user (if stdin is not redirected) and
** accepts one module name at a time from stdin. If none
** are given (CR response to first prompt) and the command
** switch is -P, -T, or -X then all members of the library are
** processed.
**
** Drive Designators (e.g. B:):
** allowed with any library and module names
** new library and index go on same drive as old
** will default to the default drive
**
** Filename Extensions:
** do NOT specify with library or module names
** standard extensions are:
**
** .REL = relocatable object module
** .LIB = library of object modules
** .NDX = index to library
** .L$ = temporary new library
** .N$ = temporary new index
**
** Enter control-S to pause and control-C to abort.
*/
#include <stdio.h>
#include "notice.h"
#include "rel.h"
#define NOCCARGC /* no argument count passing */
#define NAMESIZE 15
#define MAXMODS 200
#define MODEXT ".REL"
#define LIBEXT ".LIB"
#define NDXEXT ".NDX"
#define L_EXT ".L$"
#define N_EXT ".N$"
#define HIGH 127 /* high-value byte */
char
cmd[5], /* command switch */
oldlib[NAMESIZE], /* old library name */
oldndx[NAMESIZE], /* old name index */
newlib[NAMESIZE], /* new library name (temporary) */
newndx[NAMESIZE], /* new index name (temporary) */
*modname; /* points to module name buffer */
int
*mptr, /* module name pointers */
*mdone, /* done with mdule? */
modules, /* count of modulesto process */
all, /* process all members? */
inndx, /* input index fd */
outndx, /* output index fd */
oldblock, /* block of next input member */
oldbyte, /* byte in block of next input member */
newblock, /* block of next output member */
newbyte; /* byte in block of next output member */
int item2, type2, field2, inrel2, inrem2, inch2;
char sym2[NAMESIZE];
main(argc,argv) int argc, argv[]; {
fputs("Small-Mac Library Manager, ", stderr); fputs(VERSION, stderr);
fputs(CRIGHT1, stderr);
mptr = calloc(MAXMODS, 2); /* allocate zeroed memory */
mdone = calloc(MAXMODS, 2);
if(getarg(1, cmd, 5, argc, argv) == EOF) usage ();
cmd[1] = toupper(cmd[1]);
cmd[2] = toupper(cmd[2]);
if(cmd[0] != '-' || (cmd[2] && cmd[2] != 'A') || strlen(cmd) > 3) usage();
if(getarg(2, oldlib, NAMESIZE, argc, argv) == EOF) usage();
extend(oldlib, LIBEXT, LIBEXT);
newfn(oldndx, oldlib, NDXEXT);
newfn(newlib, oldlib, L_EXT);
newfn(newndx, oldlib, N_EXT);
getmods(argc, argv); /* gather switches and module names */
switch(cmd[1]) {
case 'D': drop(); break;
case 'T': table(); break;
case 'U': update(); break;
case 'X': extract();break;
case 'P': print(); break;
default: usage();
}
}
/*
** add module to library
*/
addmod(name) char *name; {
char *cp, nam[NAMESIZE];
saverel(); /* saveREL variables */
strcpy(nam, name); extend(nam, MODEXT, MODEXT);
inrel = open(nam, "r");
cpymod(NO); /* do not already have header */
close(inrel);
restrel(); /* restore REL variables */
strcpy(nam, name);
if(nam[1] == ':') cp = nam + 2; else cp = nam;
cp[MAXSYM] = NULL;
}
/*
** close input library and index
*/
closein(mod1, mod2) char *mod1, *mod2 ; {
close(inrel);
close(inndx);
}
/*
** close output library and index
*/
closeup(mod1, mod2) char *mod1, *mod2 ; {
closein();
endrel();
close(outrel);
putndx(newblock, newbyte); /* index EFILE */
putndx(EOF, EOF); /* terminate new index */
close(outndx);
movfil(newlib, oldlib); /* take original names */
movfil(newndx, oldndx);
}
/*
** compare module names ignoring drive designators
*/
cmpmod(mod1, mod2) char *mod1, *mod2; {
char str1[NAMESIZE], str2[NAMESIZE];
if(mod1[1] == ':') mod1 += 2; strncpy(str1, mod1, MAXSYM);
if(mod2[1] == ':') mod2 += 2; strncpy(str2, mod2, MAXSYM);
return (strcmp(str1, str2));
}
/*
** copy one module from inrel to outrel
*/
cpymod(hdr) int hdr;{
if(outndx) putndx(newblock, newbyte); /* must not be extracting */
if(hdr && !putrel()) abort(7); /* already have input header */
do {
poll(YES);
if(getrel() == ERR || !putrel()) abort (7);
} while(item != EPROG);
fflush(outrel); /* must empty aux buffer for ctell() */
newblock = ctell(outrel); /* remember for next member */
newbyte = ctellc(outrel);
if(newbyte == 128) {++newblock; newbyte = 0;}
}
/*
** drop modules from library
*/
drop() {
char mod[NAMESIZE];
if(modules == 0) error("- Delete by Name Only");
openup();
while(nxtmod(mod)) {
if(match(mod, NO)) {
puts2("Deleted ", mod);
continue;
}
cpymod(YES);
}
missing();
closeup();
}
/*
** terminate REL or LIB file
*/
endrel() {
item = EFILE;
field = 0;
type = 0;
if(!putrel()) abort(7);
}
/*
** extract files from library
*/
extract() {
char modnam[NAMESIZE];
openin();
while(nxtmod(modnam)) {
if(match(modnam, YES)) {
extend(modnam, MODEXT, MODEXT);
outrel = open(modnam, "w");
cpymod(YES);
endrel();
close(outrel);
puts2("Created ", modnam);
}
}
missing();
closein();
}
/*
** get module names
*/
getmods(argc, argv) int argc, argv[]; {
char *cp, *mp, name[NAMESIZE], fn[NAMESIZE];
int err, eof, arg, i, j;
if(!(mp = modname = malloc(MAXMODS*10))) error("- Memory Overflow");
if((j = avail(NO)) >= 0 && j < 512) {
puts("- Limited Stack Space");
err = YES;
}
all = YES; /* default to all modules */
if(argc > 3) arg = 3; /* get module names from command line */
else {
arg = 0; /* get module names from stdin */
if(cmd[2] && (cmd[1] == 'P' || cmd[1] == 'T' || cmd[1] == 'X')) {
modname[0] = HIGH; /* high value */
modname[1] = NULL;
return;
}
}
err = eof = NO;
while(modules < MAXMODS-1) {
poll(YES);
if(arg) {
if(getarg(arg++, name, NAMESIZE, argc, argv)==EOF) {eof = YES; break;}
}
else {
if(!reqstr("Module Name: ", name, NAMESIZE)) {eof = YES; break;}
}
all = NO;
if(cp = strchr(name, '.')) {
fputs(name, stdout); puts2(" - Extension Forced to ", MODEXT);
*cp = NULL;
err = YES;
}
if(cp = strchr(name, ':')) {
if(cp == name+1) ++cp; /* set up next check */
else {
puts2(name, " - Invalid Format - Ignored");
goto ignore;
}
}
else cp = name; /* set up next check */
if(strlen(cp) > MAXSYM) {
strcpy(fn, cp);
fputs(fn, stdout);
fn[MAXSYM] = NULL;
puts2(" - Will be Truncated to ", fn);
err = YES; /* assembler does actual truncation */
}
if(cmd[1] == 'U') { /* REL file must exist */
strcpy(fn, name); extend(fn, MODEXT, MODEXT);
if(i = fopen(fn, "r")) fclose(i);
else {
puts2(name, " - Can't Find - Ignored");
goto ignore;
}
}
for(i = 0; i < modules; ++i) { /* find place for module */
if(cmpmod(mptr[i], name) > 0) { /* shift others up */
for(j = modules; j > i; --j) mptr[j] = mptr[j-1];
break;
}
if(cmpmod(name, mptr[i]) == 0) { /* already loaded */
puts2(mp, " - Duplicate Name - Ignored");
goto ignore;
}
}
mptr[i] = mp; /* load modname pointer */
strcpy(mp, name); /* load modname buffer */
while(*mp++); /* scoot to next address */
++modules; /* bump number of modules */
continue;
ignore:
err = YES;
}
mptr[modules] = mp; /* load terminal pointer */
*mp++ = HIGH; /* high value */
*mp = NULL;
if(!eof) error("- Too Many Modules Specified");
if(err) {
fputs("\nContinue? ", stderr);
fgets(name, NAMESIZE, stderr);
if(toupper(*name) != 'Y') exit(7);
}
}
/*
** read an entry from the old index
*/
getndx() {
if(read(inndx, &oldblock, 2) != 2 || /* next block */
read(inndx, &oldbyte, 2) != 2) /* next byte in block */
error("- Error Reading Index");
}
/*
** check if name matches module list
*/
match(name, quit) char *name; int quit; {
int i, done;
char *mp;
if(all) return(YES);
done = YES;
for(i = 0; i < modules; ++i) {
if(cmpmod(mptr[i], name) == 0) {
mdone[i] = YES;
return(YES);
}
if(!mdone[i]) done = NO;
}
if(quit && done) exit(0);
return(NO);
}
/*
** print "not in library" messages
*/
missing() {
int i;
for(i = 0; i < modules; ++i)
if(!mdone[i]) puts2(mptr[i], " Was Not in Library");
}
/*
** move file1 to file2
*/
movfil(file1, file2) char *file1, *file2; {
unlink(file2);
if(file2[1] == ':') file2 += 2;
if(rename(file1, file2)) error("- Can't Rename Files");
}
/*
** create new filename from old filename and specified extension
*/
newfn(dest, sour, ext) char *dest, *sour, *ext; {
while(*sour && *sour != '.') *dest++ = *sour++;
strcpy(dest, ext);
}
/*
** get next module name
*/
nxtmod(name) char *name; {
seek(); /* go straight to next member */
if(getrel() == PNAME) {
strcpy(name, symbol);
return (YES);
}
if(item == EFILE) {
*name++ = HIGH; /* high value */
*name = NULL;
return (NO);
}
error("- Corrupt Library of Index");
}
/*
** open library and index for input
*/
openin() {
while(!(inrel = fopen(oldlib, "r"))) {
puts("\nCreating New Library");
outrel = open(oldlib, "w");
item = EFILE;
putrel();
close(outrel);
outndx = open(oldndx, "w");
putndx(0, 0);
putndx(EOF, EOF);
close(outndx);
}
inndx = open(oldndx, "r");
}
/*
** open Libraries and indices for updating
*/
openup() {
openin();
outrel = open(newlib, "w");
outndx = open(newndx, "w");
auxbuf(outrel, 4096);
}
/*
** print files from library
*/
print() {
char modnam[NAMESIZE];
openin();
while(nxtmod(modnam)) {
if(match(modnam, YES)) {
while(YES) {
poll(YES);
if(item > ENAME) seerel();
getrel();
if(item == EPROG) break;
}
}
}
missing();
closein();
}
/*
** write an entry to the new index
*/
putndx(block, byte) int block, byte; {
if(write(outndx, &block, 2) != 2 || /* next block to index */
write(outndx, &byte, 2) != 2) /* next byte in block to index */
error("- Error Writing New Index");
}
/*
** restore REL variables
*/
restrel() {
item = item2;
type = type2;
field = field2;
strcpy(symbol, sym2);
inrel = inrel2;
inchunk = inch2;
inrem = inrem2;
}
/*
** save REL variables
*/
saverel() {
item2 = item;
type2 = type;
field2 = field;
strcpy(sym2, symbol);
inrel2 = inrel;
inch2 = inchunk;
inrem2 = inrem;
inrem = 0; /* force getrel() to read a byte */
}
/*
** seek to next member in old library
*/
extern int Uchrpos[]; /* lives in CSYSLIB */
seek() {
getndx();
if(oldblock == EOF) error("- Premature End of Index");
if(cseek(inrel, oldblock, 0) == EOF)
error("- Corrupt Library or Index");
Uchrpos[inrel] = oldbyte;
inrem = 0; /* force getrel() to read a byte */
}
/*
** print table of contents
*/
table() {
char name[NAMESIZE]; int i, j;
openin();
puts("");
i = 0;
while(nxtmod(name)) {
poll(YES);
if(match(name, YES)) {
fputs(name, stdout);
j = 9 - strlen(name);
while(j--) putchar(' ');
if (!(++i % 8)) puts("");
}
}
puts("");
missing();
closein();
}
/*
** update (add and replace) modules in alphanumeric order
*/
update() {
char mod[NAMESIZE]; int m;
openup();
m = 0; /* first in module list */
nxtmod(mod); /* first in old library */
while(YES) {
if(cmpmod(mptr[m], mod) > 0) { /* module > member */
cpymod(YES); /* copy rest of member */
nxtmod(mod); /* next in old library */
continue;
}
if(cmpmod(mptr[m], mod) < 0) { /* module < member */
addmod(mptr[m]); /* add new module */
puts2(" Added ", mptr[m]);
++m; /* next in module list */
continue;
}
if(*mod != HIGH) { /* equal and not at end */
addmod(mptr[m]); /* add new module */
++m; /* next in module list */
puts2("Replaced ", mod);
nxtmod(mod); /* next in old library */
continue;
}
break;
}
closeup();
}
/*
** abort with a usage message
*/
usage() {
error("Usage: LIB -{DPTUX}[A] library [module...]");
}
seup();
}
/*
** abort with a usage message
*/
usage() {
error("Usage: LIB -{DPTUX}