[net.micro.6809] Microware C utility

jejones@ea.UUCP (10/28/84)

[If people can post hex dumps of Macintosh programs to net.sources, ...?]

The following program lets one split a Microware C library file into its
component pieces. This has various uses, and in particular lets one insert
one's own versions of functions. (The header file at the beginning is one
that I use continually, out of revulsion at the thought of using ints for
boolean quantities. At least I can hide the fact...)

						Down with Funky Stuff,
						James Jones

------------------------------TEAR HERE------------------------------
# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# bool.h LibSplit.c

echo x - bool.h
sed 's/^	//' > "bool.h" << '//E*O*F bool.h//'
	/*
	 * bool.h -- a header for those of us who think that C really
	 * should have a Boolean type...
	 */
	
	typedef int bool;
	
	#define TRUE	1
	#define FALSE	0
//E*O*F bool.h//

echo x - LibSplit.c
sed 's/^	//' > "LibSplit.c" << '//E*O*F LibSplit.c//'
	/*
	 * LibSplit -- split library files into their component "modules"
	 *
	 * usage: LibSplit libfile [module ...]
	 *
	 * semantics: LibSplit will read the specified library file and
	 * split out its component "modules." If "module" names are
	 * explicitly given on the command line, then only those "modules"
	 * will be extracted; otherwise, all "modules" from the library
	 * file will be extracted. Each selected "module" is written into
	 * a separate file named after the "module."
	 */
	
	#include <stdio.h>
	#include <bool.h>
	
	/*
	 * We are only concerned with library file structure inasmuch as it
	 * permits us to chop a file into its components. Thus you will not
	 * see here as much detail as in, say, rdump; only the needed stuff.
	 */
	
	#define ROFSYNC	0x62cd2387	/* ROF "sync bytes" */
					/* ("magic number" to Unixoids) */
	#define SYMLEN	9		/* maximum symbol length */
	#define MAXNAME	16		/* maximum "module" name length */
	
	/* definition/reference */
	
	typedef struct {
		char		r_flag;	/* type/location */
		unsigned	r_offset;
	} def_ref;
	
	/* "module" header structure */
	
	typedef struct {
		long		h_sync;		/* should == ROFSYNC */
		unsigned	h_tylan;	/* type/language/attr/revision */
		char		h_valid;	/* asm valid? */
		char		h_date[5];	/* creation date */
		char		h_edit;		/* edition # */
		char		h_spare;
						/* next, sizes of: */
		unsigned	h_glbl,		/* globals */
				h_dglbl,	/* direct page globals */
				h_data,		/* data */
				h_ddata,	/* direct page data */
				h_ocode;	/* code */
		unsigned	h_stack,
				h_entry;
	}	binhead;
	
	binhead	header;
	FILE	*LibFP, *ModFP;
	bool	GetCurr;
	
	main(argc, argv)
	int	argc;
	char	*argv[];
	{
		int	i, NMods;
		bool	GetAll;
		char	ModName[MAXNAME + 1];
		char	*LibFName;
	
		if (argc < 2) {
			fprintf(stderr, "usage: LibSplit libfile [module ...]\n");
			exit(1);
		}
		if (GetAll = (argc == 2))
			NMods = 30000;
		else
			NMods = argc - 2;
	
		LibFName = argv[1];
	
		if ((LibFP = fopen(LibFName, "r")) == NULL) {
			fprintf(stderr, "LibSplit: can't open %s\n", LibFName);
			exit(1);
		}
	
		while (NMods > 0) {
			if (fread(&header, sizeof(header), 1, LibFP) < 1)
				break;
			if (header.h_sync != ROFSYNC) {
				fprintf(stderr, "%s is not a library file\n", LibFName);
				exit(1);
			}
	
			GetName(ModName);
			if (GetAll)
				GetCurr = TRUE;
			else {
				GetCurr = FALSE;
				for (i = 2; i < argc; i++) {
					if (strcmp(ModName, argv[i]) == 0) {
						GetCurr = TRUE;
						break;
					}
				}
			}
	
			if (GetCurr) {
				NMods--;
				if ((ModFP = fopen(ModName, "w")) == NULL) {
					fprintf(stderr, "LibSplit: can't create %s\n",
						ModName);
					exit(1);
				}
				fwrite(&header, sizeof(header), 1, ModFP);
				PutName(ModName);
			}
	
			CopyGlobalDefs();
			CopyCode();
			CopyExtRefs();
			CopyRefs();	/* local references */
	
			if (GetCurr)
				fclose(ModFP);
		}
	
		fclose(LibFP);
	
	}
	
	CopyGlobalDefs()
	{
		int	GCount, Offset;
		char	GSym[SYMLEN + 1], flag;
	
		GCount = getw(LibFP);
		if (GetCurr)
			putw(GCount, ModFP);
	
		for (; GCount > 0; GCount--) {
			GetName(GSym);
			if (GetCurr) {
				PutName(GSym);
				putc((flag = getc(LibFP)), ModFP);
				putw((Offset = getw(LibFP)), ModFP);
			} else
				fseek(LibFP, (long)(sizeof(char) + sizeof(int)), 1);
		}
	
	}
	
	CopyCode()
	{
		int	HowMuch;
		char	buffer[BUFSIZ];
	
		HowMuch = header.h_ocode + header.h_ddata + header.h_data;
	
		if (GetCurr) {
			for (; HowMuch >= BUFSIZ; HowMuch -= BUFSIZ) {
				fread(buffer, 1, BUFSIZ, LibFP);
				fwrite(buffer, 1, BUFSIZ, ModFP);
			}
	
			if (HowMuch > 0) {
				fread(buffer, 1, HowMuch, LibFP);
				fwrite(buffer, 1, HowMuch, ModFP);
			}
		} else
			fseek(LibFP, (long) HowMuch, 1);
	
	}
	
	CopyExtRefs()
	{
		int	ECount;
		char	ESym[SYMLEN + 1];
	
		putw((ECount = getw(LibFP)), ModFP);
	
		for (; ECount > 0; ECount--) {
			GetName(ESym);
			if (GetCurr)
				PutName(ESym);
			CopyRefs();
		}
	
	}
	
	CopyRefs()
	{
		int	RCount;
		def_ref	ref;
	
		RCount = getw(LibFP);
		if (GetCurr) {
			putw(RCount, ModFP);
			for (; RCount > 0; RCount--) {
				fread(&ref, sizeof(ref), 1, LibFP);
				fwrite(&ref, sizeof(ref), 1, ModFP);
			}
		} else
			fseek(LibFP, (long) (RCount * sizeof(ref)), 1);
	
	}
	
	GetName(s)
	char	*s;
	{
		while (*(s++) = getc(LibFP))
			;
	}
	
	PutName(s)
	char	*s;
	{
		fputs(s, ModFP);
		putc('\0', ModFP);
	}
//E*O*F LibSplit.c//

exit 0