Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!princeton!orsvax1!pyrnj!caip!lll-crg!lll-lcc!vecpyr!atari!dyer From: dyer@atari.UUcp (Landon Dyer) Newsgroups: net.micro.amiga Subject: Amig* to ST conversion source Message-ID: <175@atari.UUcp> Date: Tue, 8-Apr-86 01:36:54 EST Article-I.D.: atari.175 Posted: Tue Apr 8 01:36:54 1986 Date-Received: Fri, 11-Apr-86 01:21:35 EST Organization: Atari Corp., Sunnyvale CA Lines: 1115 Keywords: Atari ST, Amig* This is the source code for the Amiga to ST object code converter that was posted a week or so ago. Expect to do some work to make it run on anything but a PC. The documentation is not being re-posted here. Contact me directly if you need it. -Landon "If business is war, then I'm a prisoner of business!" "People are for computers." {lll-crg!vecpyr, hoptoad}!atari!dyer ---------------- remove this line and everything above it ---------------- # # This is a shar file. Cut at the lines at the top and bottom and # run the file through sh(1) to extract the source files. # echo x - README sed 's/^X//' >README <<'*-*-END-of-README-*-*' X XThis is the source for CONVERT.EXE, intended to run under M*DOS. XIt has been compiled with Lattic* C version 2.something, but oth- Xer C compilers should have no problems compiling it. X XAbout the source code -- well, it works. On M*DOS. So far. This Xis actually the kind of program one never wants the world to see, X"no -- I could /never/ let the world see that I code like that!" XWell, here it is anyway. It was a quick hack.... X XThe file "makefile.pc" is a makefile for a public domain version Xof MAKE, which is incompatible with UN*X make(1). If you have a Xdifferent make, expect to have to edit the makefile. X XThere is byte-order dependent code in (at least) "convert.c". XPorting to a 68000 based S*n or the ST should be easy, though. X XThe source for "qsort.c" has not been included. You will need to Xfind your own quicksort routine, as the version I've got I can't Xdistribute the source for. The 4.2 BSD version work right the very Xfirst time (impressive!) X X XLandon Dyer XAtari Corp. *-*-END-of-README-*-* echo x - convert.h sed 's/^X//' >convert.h <<'*-*-END-of-convert.h-*-*' X/* convert.h */ X X#define DEBUG(x) if(debug)printf(x); X#define BUFFERSIZE 0x4000 X#define OK 0 X#define ERROR (-1) X X X/* X * Block types. X */ X#define HUNKUNIT 999 X#define HUNKNAME 1000 X#define HUNKCODE 1001 X#define HUNKDATA 1002 X#define HUNKBSS 1003 X#define HUNKR32 1004 X#define HUNKR16 1005 X#define HUNKR8 1006 X#define HUNKEXT 1007 X#define HUNKSYMBOL 1008 X#define HUNKDEBUG 1009 X#define HUNKEND 1010 X#define HUNKHEADER 1011 X#define HUNKOVERLAY 1013 X#define HUNKBREAK 1014 X X X/* X * Hunk types. X */ X#define TEXT 0 X#define DATA 1 X#define BSS 2 X X X/* X * Information about hunks: X */ X#define Hinfo struct hinfo XHinfo { X long hsize; /* hunk size (bytes) */ X long hpos; /* position of hunk info in file (or -1L) */ X long haddr; /* starting address of hunk */ X long hrsize; /* size of relocation information (bytes) */ X int htype; /* hunk type (TEXT, DATA, BSS, or -1) */ X int hunkno; /* hunk number */ X long *hrel; /* -> relocation information (or NULL) */ X Hinfo *hnext; /* -> next hunk in order of saddr (or NULL) */ X}; *-*-END-of-convert.h-*-* echo x - convertm.c sed 's/^X//' >convertm.c <<'*-*-END-of-convertm.c-*-*' X/* convertm.c */ X#include X X/* X * CVT - convert Amig*-format loadfiles to GEMDOS. X * X * THIS PROGRAM IS (C)1985 LANDON M. DYER AND MAY BE X * DISTRIBUTED ONLY IF THE FOLLOWING CONDITIONS ARE MET: X * 1. YOU DO NOT MAKE A PROFIT ON IT. X * 2. IF YOU HAVE THE SOURCE CODE, YOU GIVE THAT AWAY, TOO. X * 3. YOU INCLUDE THIS NOTICE IN THE SOURCE AND OBJECT CODE. X * X *---- X * 25-Nov-1985 lmd Hacked it up (from earlier file-dump hacks). X * X */ Xchar *version = "0.50"; Xchar *date = "25-Nov-1985"; X X#define STRINGSIZ 256 X#define READ 0 X#define WRITE 1 X Xint debug = 0; Xint printing = 0; X X X/* X * Handle commandline X */ Xmain(argc, argv) Xint argc; Xchar **argv; X{ X int argno; X int fd, ofd; X char *s, ofn[STRINGSIZ], ifn[STRINGSIZ]; X X /* X * No instructions: X * print info about use and X * exit with bad return code. X */ X if (argc <= 1) X { X s = "-----------------------------------------------------------------\n"; X fprintf(stderr, s); X fprintf(stderr, "CVT version %s %s\n", version, date); X fprintf(stderr, "THIS PROGRAM IS (C)1985 LANDON M. DYER AND MAY BE DISTRIBUTED\n"); X fprintf(stderr, "ONLY IF THE FOLLOWING CONDITIONS ARE MET:\n"); X fprintf(stderr, "\t1. YOU DO NOT MAKE A PROFIT ON IT.\n"); X fprintf(stderr, "\t2. IF YOU HAVE THE SOURCE CODE, YOU GIVE THAT AWAY, TOO.\n"); X fprintf(stderr, "\t3. YOU INCLUDE THIS NOTICE IN THE SOURCE AND OBJECT CODE.\n"); X fprintf(stderr, s); X fprintf(stderr, "Usage:\n"); X fprintf(stderr, "CVT [-d] [-p] inputfile[.LN] [inputfile...]\n"); X fprintf(stderr, " ==> file.PRG output files.\n"); X exit(1); X } X X X for (argno = 1; argno < argc; ++argno) X if (*argv[argno] == '-') X for (s = &argv[argno][1]; *s; ++s) X switch(*s) X { X case 'p': X case 'P': X printing = 1; X printf("CVT version %s %s\n", version, date); X break; X X case 'd': X case 'D': X debug = 1; X fprintf(stderr, "~ Debugging ON\n"); X break; X X default: X fprintf(stderr, "Unknown option: %s\n", argv[argno]); X exit(1); X } X else { X strcpy(ifn, argv[argno]); /* file[.LN] (soft ext.) */ X fext(ifn, ".ln", 0); X strcpy(ofn, argv[argno]); /* file[.PRG] (hard ext.) */ X fext(ofn, ".prg", 1); X X fd = ebinopen(ifn, READ); X ofd = ebinopen(ofn, WRITE); X X if (printing) X printf("%s ==> %s\n", ifn, ofn); X X convert(fd, ofd); /* convert, then close */ X close(fd); X close(ofd); X } X} X X X/* X * Panic and give up. X */ Xpanic(s) Xchar *s; X{ X fprintf(stderr, "Panic: %s\n", s); X exit(1); X} *-*-END-of-convertm.c-*-* echo x - convert.c sed 's/^X//' >convert.c <<'*-*-END-of-convert.c-*-*' X/* convert.c */ X#include X#include "convert.h" X Xextern int debug; /* 1: print debugging messages */ Xextern int printing; /* 1: print conversion statistics */ X XHinfo *ahinfo(); X X X/* hunk information */ XHinfo **hunk; /* -> vector of ptrs to Hinfo structs */ XHinfo *firsthunk; /* -> first hunk */ Xint nhunks; /* #hunks in input file */ Xint curhunk; /* current hunk# */ Xint hvalid; /* state variable (to bump curhunk) */ Xlong filpos; /* position in input file */ Xlong siz[3]; /* segment sizes */ X X/* relocation (fixup) information */ Xlong rsize; /* total size of all relocation information */ Xlong *rbuf; /* -> buffer for relocation information */ Xlong *rpos; /* current position in relocation info buffer */ X Xchar buf[BUFFERSIZE]; /* buffer for copying stuff */ X X X/* X * Convert AMIG* binary loadfile to GEMDOS .PRG executable. X */ Xconvert(ifd, ofd) Xint ifd, ofd; X{ X /* init globals */ X hunk = (Hinfo **)NULL; X firsthunk = (Hinfo *)NULL; X hvalid = nhunks = curhunk = 0; X filpos = 0L; X rsize = 0L; X X pass1(ifd); X if (curhunk < nhunks) X panic("Bugcheck: not enough hunks in input body."); X bind(); X X if ((rbuf = (long *)malloc((int)rsize)) == NULL) X allerr(); X rpos = rbuf; X X output(ifd, ofd); X reloc(ifd, ofd); X release(); X} X X X/* X * Parse hunks in AMIG* binary loadfile, X * gather information about it. X */ Xpass1(ifd) Xint ifd; X{ X long lw, junk; X Hinfo *h; X XDEBUG("~ pass1()\n"); X X for(;;) X { X if (readlong(ifd, &lw) == EOF) X break; X X switch ((int)lw) X { X case HUNKUNIT: X case HUNKNAME: X DEBUG("~\tHUNKUNIT or HUNKNAME\n"); X getlong(ifd, &lw); X skip(ifd, lw * 4); X break; X X case HUNKCODE: X chkhunk(); X h = hunk[curhunk]; X getlong(ifd, &lw); /* get size (in longs) */ X lw *= 4; X h->hsize = lw; X h->hpos = filpos; X h->htype = TEXT; X skip(ifd, lw); X if (debug) dumphinfo(h); X break; X X case HUNKDATA: X chkhunk(); X h = hunk[curhunk]; X getlong(ifd, &lw); /* get size (in longs) */ X lw *= 4; X h->hsize = lw; X h->hpos = filpos; X h->htype = DATA; X skip(ifd, lw); X if (debug) dumphinfo(h); X break; X X case HUNKBSS: X chkhunk(); X h = hunk[curhunk]; X getlong(ifd, &lw); /* get size (in longs) */ X h->hsize = lw * 4; X h->htype = BSS; X if (debug) dumphinfo(h); X break; X X case HUNKR32: X h = hunk[curhunk]; X for (;;) X { X getlong(ifd, &lw); X if (!lw) break; X lw = (lw + 1) * 4; X h->hrsize += lw + 4; X skip(ifd, lw); X } X h->hrsize += 4; X rsize += h->hrsize + 4; X if(debug)printf("~\thrsize = %ld\n", h->hrsize); X break; X X case HUNKR16: X panic("16-bit relocation not supported."); X break; X X case HUNKR8: X panic("8-bit relocation not supported."); X break; X X case HUNKEXT: X panic("External symbols not supported."); X break; X X case HUNKSYMBOL: X panic("Symbols not supported."); X break; X X case HUNKDEBUG: X panic("Debug blocks not supported."); X break; X X case HUNKEND: X if (hvalid) X { X hvalid = 0; X ++curhunk; X } X if(debug)printf("~HUNKEND, curhunk = %d\n", curhunk); X break; X X case HUNKHEADER: X header(ifd); X break; X X case HUNKOVERLAY: X panic("Overlays not supported."); X break; X X case HUNKBREAK: X panic("Breaks (overlays) not supported."); X break; X } X } X} X X X/* X * Sanity check about hunk adjacency (which may not be a X * problem) and hunk number range. X */ Xchkhunk() X{ X if (hvalid) X panic("Bugcheck: two adjacent hunks w/o HUNKEND!"); X if (curhunk >= nhunks) X panic("Bugcheck: too many hunks!"); X hvalid = 1; X} X X X/* X * Read hunk header, X * get info for global vars. X * X */ Xheader(fd) Xint fd; X{ X long lw, *p; X long htabsize, firsthunk, lasthunk; X unsigned int i, j; X X /* X * Skip library names. X */ X for (;;) X { X getlong(fd, &lw); X if (!lw) break; X skip(fd, lw*4); X } X X /* more random header info */ X getlong(fd, &htabsize); X getlong(fd, &firsthunk); X getlong(fd, &lasthunk); X if (debug) X printf("~\thtabsize = %ld\n\tfirsthunk = %ld\n\tlasthunk = %ld\n", X htabsize, firsthunk, lasthunk); X X /* alloc space for hunk database */ X nhunks = (unsigned)(lasthunk - firsthunk + 1); X hunk = (Hinfo **)malloc(nhunks * sizeof(Hinfo)); X if (hunk == NULL) X allerr(); X X for (j = 0; j < nhunks; ++j) X { X hunk[j] = ahinfo(); X hunk[j]->hunkno = j; X getlong(fd, &hunk[j]->hsize); X if(debug) printf("~\t%d hsize = %ld ($%lx)\n", X j, hunk[j]->hsize, hunk[j]->hsize); X } X} X X X/* X * Compute hunk order and starting addresses. X */ Xbind() X{ X int typ, hnk; X long addr; X Hinfo *hptr; X XDEBUG("~ bind()\n"); X addr = 0L; X hptr = firsthunk; X for (typ = 0; typ < 3; ++typ) X { X siz[typ] = 0L; X for (hnk = 0; hnk < nhunks; ++hnk) X if (hunk[hnk]->htype == typ) X { X if (firsthunk == (Hinfo *)NULL) X hptr = firsthunk = hunk[hnk]; X else { X hptr->hnext = hunk[hnk]; X hptr = hunk[hnk]; X } X siz[typ] += hptr->hsize; X hptr->haddr = addr; X addr += hptr->hsize; X if(debug) X printf("~\thunk[%d]->haddr = $%lx\n", hnk, hptr->haddr); X } X } X X if(printing) X printf("text %ld ($%lx), data %ld ($%lx), bss %ld ($%lx)\n", X siz[0], siz[0], siz[1], siz[1], siz[2], siz[2]); X} X X X/* X * Generate the GEMDOS output file. X */ Xoutput(ifd, ofd) Xint ifd, ofd; X{ X int i; X Hinfo *hu; X XDEBUG("~ output()\n"); X /* X * Write .PRG header. X */ X writeword(ofd, 0x601a); X for (i = 0; i < 3; i++) X writelong(ofd, siz[i]); X for (i = 0; i < 7; i++) X writeword(ofd, 0x0000); X X for (hu = firsthunk; hu != NULL; hu = hu->hnext) X if (hu->htype == TEXT || hu->htype == DATA) X { X lseek(ifd, hu->hpos, 0); X randw(ifd, hu->hsize, ofd); X X if (hu->hrsize) X { X lseek(ifd, 4L, 1); X *rpos++ = hu->hunkno; X if (read(ifd, rpos, (int)hu->hrsize) != (int)hu->hrsize) X panic("Reloc info read error."); Xif(debug)printf("~ relocsiz = %ld\n", hu->hrsize); X rpos += hu->hrsize >> 2; X } X } X} X X X/* X * Generate relocation information X * (at the end of the output file). X */ Xreloc(ifd, ofd) Xint ifd, ofd; X{ X int cmplong(); X long cvt2long(); X long *rp, *drp; X char *crp, c; X int i, hno, nel; X long count, base, lw, addr; XDEBUG("~ reloc()\n"); X Xif (debug) X { X i = 0; X for (crp = (char *)rbuf; crp < (char *)rpos; crp += 4) X { X if (!i) printf("~ "); X printf("%02x%02x%02x%02x", X crp[0]&0xff, crp[1]&0xff, crp[2]&0xff, crp[3]&0xff); X if (++i >= 8) X { X printf("\n"); X i = 0; X } else putchar(' '); X } X putchar('\n'); X } X X /* X * Go back into the .PRG file and add X * hunk starting-offsets to the longwords X * that must be fixed up. X * 28L is the size of the GEMDOS .PRG header. X */ X for (rp = rbuf; rp < rpos;) X { X hno = *rp++; Xif(debug)printf("~ hno = %d\n", hno); X for (;;) X { X *rp = cvt2long(*rp); X if (!(count = *rp++)) break; X *rp = cvt2long(*rp); X base = hunk[(int)*rp++]->haddr; Xif(debug)printf("~ count = %ld, base = $%0lx\n", count, base); X while (count--) X { X *rp = cvt2long(*rp); Xif(debug)printf("~ seek(ifd) = %ld, seek(ofd) = %ld ", X hunk[hno]->hpos + *rp, X hunk[hno]->haddr + *rp + 28L); X lseek(ifd, hunk[hno]->hpos + *rp, 0); X lseek(ofd, hunk[hno]->haddr + *rp++ + 28L, 0); X readlong(ifd, &lw); X lw += base; X writelong(ofd, lw); Xif(debug)printf("lw = $%0lx\n", lw); X } X } X } X X X /* X * Compute and sort fixup offsets. X */ X nel = 0; X drp = rbuf; X for (rp = rbuf; rp < rpos;) X { X hno = *rp++; X for (;;) X { X if (!(count = *rp++)) break; X ++rp; X while (count--) X { X *drp++ = hunk[hno]->haddr + *rp++; X ++nel; X } X } X } X rpos = drp; X qsort(rbuf, nel, 4, cmplong); X X/* print sorted info */ Xif(debug) X { X i = 0; X for (rp = rbuf; rp < rpos; ++rp) X { X if (!i) printf("~ "); X printf("%08lx", *rp); X if (++i >= 8) X { X printf("\n"); X i = 0; X } else putchar(' '); X } X putchar('\n'); X } X X X /* X * Write GEMDOS relocation information X */ X lseek(ofd, 0L, 2); /* to end of file */ X rp = rbuf; X while (rp < rpos) X { X /* write offset to first fixup */ X if (rp == rbuf) X { X writelong(ofd, *rp); X addr = *rp++; Xif(debug)printf("$%lx\n", addr); X continue; X } X X if (addr >= *rp) panic("Bad relocation information."); X c = 254; X lw = *rp - addr; X addr = *rp++; Xif(debug)printf("$%lx:", lw); X while (lw > 254) X { X write(ofd, &c, 1); X lw -= 254L; Xif(debug)putchar('+'); X } X c = (char)lw; X write(ofd, &c, 1); Xif(debug)printf("$%x\n", (int)lw); X } X X /* X * Terminate relocation list X */ X c = 0; X write(ofd, &c, 1); X} X X X/* X * Compare two longs X * for qsort(). X */ Xcmplong(l1, l2) Xlong *l1, *l2; X{ X return *l1 - *l2; X} X X X/* X * Allocate (and initialize) a Hinfo node. X */ XHinfo *ahinfo() X{ X Hinfo *h; X X if (curhunk >= nhunks) X panic("curhunk >= nhunks, too many hunks!"); X X if ((h = (Hinfo *)malloc(sizeof(Hinfo))) == NULL) X allerr(); X h->hsize = 0L; X h->hpos = 0L; X h->haddr = 0L; X h->hrsize = 0L; X h->htype = -1; X h->hrel = (long *)NULL; X h->hnext = (Hinfo *)NULL; X X return h; X} X X X/* X * Release memory used by hunk database. X */ Xrelease() X{ X int i; X X for (i = 0; i < nhunks; ++i) X { X if (hunk[i]->hrel != NULL) X free(hunk[i]->hrel); X free(hunk[i]); X } X free(hunk); X} X X X/* X * Skip some of the input file X */ Xskip(fd, count) Xint fd; Xlong count; X{ X filpos += count; X lseek(fd, count, 1); X} X X X/* X * Out of memory (malloc() didn't work); X * complain and die. X */ Xallerr() X{ X panic("Allocation failure, heap exhausted, I give up!\n"); X} X X X/* X * Print information about an Hinfo node. X */ Xdumphinfo(h) XHinfo *h; X{ X printf("~\thsize = %ld ($%lx), hpos = %ld, haddr = %ld ($%lx)\n", X h->hsize, h->hsize, h->hpos, h->haddr, h->haddr); X printf("~\thtype = %d ", h->htype); X printf("hrel = $%lx, hnext = $%lx\n", X (long)h->hrel, (long)h->hnext); X} X X X/* X * Convert 68000 long to local long X */ Xlong cvt2long(lw) Xlong lw; X{ X char *out, *in; X long olw; X X /* X * 8086/VAX conversion X */ X in = (char *)&lw; X out = (char *)&olw; X out[0] = in[3]; X out[1] = in[2]; X out[2] = in[1]; X out[3] = in[0]; X return olw; X} *-*-END-of-convert.c-*-* echo x - longio.c sed 's/^X//' >longio.c <<'*-*-END-of-longio.c-*-*' X#include X#include "convert.h" X Xextern long filpos; Xextern int debug; Xextern int printing; Xextern char buf[]; X X X/* X * Get a longword or complain about premature EOF X * X */ Xgetlong(fd, p_lw) Xint fd; Xlong *p_lw; X{ X if (readlong(fd, p_lw) == EOF) X panic("Premature EOF getting longword"); X return OK; X} X X X/* X * Read 68000 longword from file, X * stuff it into '*p_lw' in the X * host machine's longword format. X * X */ Xreadlong(fd, p_lw) Xint fd; Xlong *p_lw; X{ X char buf[4], *out; X int i; X X out = (char *)p_lw; X if (read(fd, buf, 4) != 4) /* probably end of file */ X return EOF; X X filpos += 4; X /* X * 8086/8088 conversion X * hh hl lh ll ==> ll lh hl hh X */ X out[0] = buf[3]; X out[1] = buf[2]; X out[2] = buf[1]; X out[3] = buf[0]; X} X X X/* X * Write word to file, X * in 68000 format. X */ Xwriteword(fd, w) Xint fd; Xunsigned int w; X{ X char buf[2], *out; X X out = (char *)&w; X buf[0] = out[1]; X buf[1] = out[0]; X if (write(fd, buf, 2) != 2) X panic("Write error (word)"); X} X X X/* X * Write longword to file, in X * 68000 format. X */ Xwritelong(fd, lw) Xint fd; Xlong lw; X{ X char buf[4], *out; X int i; X X out = (char *)&lw; X buf[0] = out[3]; X buf[1] = out[2]; X buf[2] = out[1]; X buf[3] = out[0]; X X if (write(fd, buf, 4) != 4) X panic("Write error (longword)"); X} X X X/* X * Read-and-write (copy from one X * file to another). X */ Xrandw(ifd, count, ofd) Xint ifd; Xlong count; Xint ofd; X{ Xif(debug)printf("~ randw(%d, %ld, %d)\n", ifd, count, ofd); X for (; count > BUFFERSIZE; count -= BUFFERSIZE) X randw(ifd, BUFFERSIZE, ofd); X if (read(ifd, buf, (int)count) != (int)count) X panic("Read error."); X if (write(ofd, buf, (int)count) != (int)count) X panic("Write error."); X} X X X/* X * Write single byte to file X */ Xemit(c, fd) Xint c; Xint fd; X{ X char cc; X X cc = (char)c; X if (write(fd, &cc, 1) != 1) X panic("Emit write error."); X} *-*-END-of-longio.c-*-* echo x - binfio.c sed 's/^X//' >binfio.c <<'*-*-END-of-binfio.c-*-*' X#include X X#define MSDOS 1 X#define VAXVMS 2 X#define UNIX42 3 X#define SYSV 4 X X#define READ 0 X#define WRITE 1 X#define MACHINE MSDOS X Xebinopen(name, mode) Xchar *name; Xint mode; X{ X int fn; X X if((fn = binopen(name, mode)) != -1) return fn; X fprintf(stderr, "Cannot %s: %s\n", X mode == 1 ? "create" : "open", X name); X exit(1); X} X X Xbinopen(name, mode) Xchar *name; Xint mode; X{ X#if MACHINE == VAXVMS X if(mode == WRITE) return creat(name, 0666); X else return open(name, mode); X#endif X X#if MACHINE == MSDOS X#define UNCOOKED 0x8000 /* pure binary i/o */ X if(mode == WRITE) return creat(name, 0666 | UNCOOKED); X else return open(name, mode | UNCOOKED); X#endif X X#if MACHINE == UNIX42 X))))) force-compiler-error X#endif X X#if MACHINE == SYSV X))))) force-compiler-error X#endif X} *-*-END-of-binfio.c-*-* echo x - efopen.c sed 's/^X//' >efopen.c <<'*-*-END-of-efopen.c-*-*' X#include X X/* X * Attempt to open a file with the given access mode. X * Return its file descriptor, or if the open fails, print an error X * message and exit. X */ XFILE *efopen(name, mode) Xchar *name, *mode; X{ X FILE *fp, *fopen(); X char *msg; X X if ((fp = fopen(name, mode)) != NULL) X return fp; X X fprintf(stderr, "Cannot %s: '%s'\n", X strcmp(mode, "w") ? "open" : "create", name); X exit(1); X} X X X/* X * Manipulate file extensions. X * 'name' must be large enough to hold any possible filename. X * If 'stripp' is nonzero, any old extension will be removed. Then, if the X * file does not already have an extension, 'extension' is appended to the X * filename. X */ Xchar *fext(name, extension, stripp) Xchar *name, *extension; Xint stripp; X{ X char *s, *beg; X X /* go past pathname */ X for (beg = name + strlen(name) - 1; beg > name; --beg) X if (stpchr("/\\", *beg)) X { X ++beg; X break; X } X X if (stripp) /* strip extension */ X { X for (s = beg; *s && *s != '.'; ++s) X ; X *s = '\0'; X } X X for (s = beg; *s != '.'; ++s) /* add extension */ X if (!*s) X { X strcat(beg, extension); X break; X } X return name; X} *-*-END-of-efopen.c-*-* echo x - convert.mak sed 's/^X//' >convert.mak <<'*-*-END-of-convert.mak-*-*' X!---- X! X! This is the makefile for CVT.EXE for the IBM-PC. If you don't X! have MAKE, then don't sweat it -- you can use the binaries or compile X! it by hand. X! X! Bugs, comments, letter bombs to: X! X! Landon Dyer G.DYER@SU-SCORE.ARPA X! Atari Corp. ... {hoptoad, lll-crg!vecpyr}!atari!dyer X! 1196 Borregas Ave X! Sunnyvale, CA 94088 X! X!---- X! X! No warranty is expressed or implied. This is public domain software, X! free for the asking. You may modify it however you wish, but you are X! not permitted to sell this work, or any modification of it. X! X!---- X! X! You will need your OWN quicksort, as the version I use is from 4.2BSD, X! and I'm not sure if it's legal to distribute it. X! X!---- X X! X! Change these to reflect where the libraries and so on are on your system. X! (This is for Lattice C 2.11 or something like that). X! XBIN = \bin\ XCRUN = \bin\cs XCLIB = \bin\lcs X XSUBRS = binfio.obj efopen.obj XCONVERTOBJS = convertm.obj convert.obj longio.obj qsort.obj #(SUBRS) X Xcvt.exe : #(CONVERTOBJS) X link #(BIN)cs #(CONVERTOBJS),cvt,,#(BIN)lcs X Xconvertm.obj : convertm.c X lc1 convertm X lc2 convertm X Xconvert.obj : convert.c X lc1 convert X lc2 convert X Xqsort.obj : qsort.c X lc1 qsort X lc2 qsort X Xlongio.obj : longio.c X lc1 longio X lc2 longio X X! X! Random tools (I port these from X! system to system...): X! Xbinfio.obj : binfio.c X lc1 binfio X lc2 binfio X Xefopen.obj : efopen.c X lc1 efopen X lc2 efopen X X! X! Copy CONVERT source to transfer disk X! Xtransfer : X copy convert.h a: X copy convert.c a: X copy convert.mak a: X copy convert.man a: X copy convert.obj a: X copy cvt.exe a: X copy convertm.c a: X copy convertm.obj a: X copy longio.c a: X copy longio.obj a: X copy binfio.c a: X copy binfio.obj a: X copy efopen.c a: X copy efopen.obj a: X! copy qsort.c a: ! I can't distribute source for this!!! X copy qsort.obj a: X copy \bin\make.bat a: X copy \bin\makeexe.exe a: *-*-END-of-convert.mak-*-* exit ---------------- remove this line and everything below it ----------------