home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
me34src.zip
/
me3
/
mc
/
mco_to_c.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-14
|
7KB
|
282 lines
/* mco_to_c.c :
* Convert compiled Mutt code into C code that can be compiled as part of an
* application. ie enable Mutt code to be linked into an application.
* Thanks to Todd Moody (sjuphil!tmoody@uu.psi.com) for the initial idea.
* C Durland 8/92 Public Domain
*
* Input: a .mco file.
*
* cc -I$HOME/c/util -o mco_to_c mco_to_c.c $HOME/c/util/util.a
*/
static char what[] = "@(#)mco_to_c 8/9/92 v1.4 5/29/93";
#define WHAT (&what[4])
#include <stdio.h>
#include <os.h>
#include <const.h>
#include "mm.h"
static int MMload_code();
static void dump_loader();
static void usage()
{
fdump_doc(stderr,
"mco_to_c: Convert a .mco file into C",
"Usage: mco_to_c <foo.mco>",
(char *)NULL);
}
main(argc, argv) int argc; char **argv;
{
if (argc != 2)
{
usage();
exit(1);
}
if (!MMload_code(argv[1], TRUE)) exit(1);
exit(0);
}
#define ABC 150 /* max number of addresses in I can get per read */
static int MMload_code(fname,complain) char *fname;
{
char *malloc();
FILE *fopen();
address entry_point;
char *block, *nmptr, *zit;
FILE *fptr;
int j, num_pgms, num_global_objects, mco_magic_number;
unsigned int code_size, nmoffset, global_var_space;
maddr code;
uint8 bytes[ABC*sizeof(address)], *qtr;
/* open the code file */
if ((fptr = fopen(fname, "rb")) == NULL)
{
if (complain) fprintf(stderr,"Can't open code file: %s\n", fname);
return FALSE;
}
/* read and parse the header !!! error check*/
fread((char *)bytes,1,BYTES_IN_HEADER,fptr);
mco_magic_number = GET_UINT8(&bytes[H_MAGIC_NUMBER]);
if (MM_MAGIC_NUMBER != mco_magic_number)
{
fdump_doc(stderr,
"Either:",
" This ain't a real .mco file or",
" it is old and needs to be recompiled or",
" this program is old and needs to be recompiled.",
(char *)NULL);
fclose(fptr);
return FALSE;
}
entry_point = GET_ADDRESS(&bytes[H_ENTRY_POINT]);
code_size = GET_UINT16 (&bytes[H_BYTES_OF_CODE]);
nmoffset = GET_UINT16 (&bytes[H_NAME_TABLE_OFFSET]);
num_pgms = GET_INT16 (&bytes[H_NUMBER_OF_PGMS]);
global_var_space = GET_UINT16 (&bytes[H_BYTES_OF_GVARS]);
num_global_objects = GET_UINT16 (&bytes[H_NUM_GLOBAL_OBJECTS]);
/* calculate size of code, name table and global vars */
if ((block = malloc(code_size)) == NULL)
{
fprintf(stderr,"Can't malloc code\n");
fclose(fptr);
return FALSE;
}
/* Get the code, strings and name table. !!! error check */
fread(block,1,code_size,fptr);
code = (maddr)block;
nmptr = block + nmoffset;
dump_doc(
"/* This file was generated by a program (mco_to_c).",
" * You probably don't want to mess with it.",
" * Public Domain",
(char *)NULL);
printf(" * Input file: \"%s\"\n */\n", fname);
printf("\n");
printf("#include <const.h>\n");
printf("#include <os.h>\n");
printf("#include <oman.h>\n");
printf("#include <mm.h>\n");
printf("\n");
printf("#define CODE_SIZE %u\n", code_size);
printf("#define SIZE_OF_GLOBAL_VARS %u\n", global_var_space);
printf("\n");
printf(
"static unsigned char the_code[CODE_SIZE + SIZE_OF_GLOBAL_VARS] = \n{");
{
unsigned char *ptr = code;
int i;
unsigned int n;
for (i = 0, n = code_size; n--; ptr++)
{
if (0 == i--) { printf("\n "); i = 15; }
printf("%3d,", *ptr);
}
}
printf("\n};\n\n");
printf("#define MCO_MAGIC_NUMBER 0x%x\t/* read from the .mco file */\n",
mco_magic_number);
printf("\n");
printf("#define NUM_PGMS %d\n", num_pgms);
printf("#define NUM_GLOBAL_OBJECTS %d\n", num_global_objects);
printf("\n");
printf("#define ENTRY_POINT_OFFSET 0x%x\n", entry_point);
printf("#define NAME_TABLE_OFFSET 0x%x\n", nmoffset);
printf("#define GLOBAL_VARS (the_code + 0x%x)\n", code_size);
printf("#define ENTRY_POINT (the_code + ENTRY_POINT_OFFSET)\n");
printf("\n");
if (0 == num_global_objects)
printf("static Object **global_objects = NULL;\n");
else
printf("static Object *global_objects[NUM_GLOBAL_OBJECTS];\n");
printf("\n");
printf("#if NUM_PGMS\n");
printf("static struct { unsigned char *pgm_name, *pgm_addr; } ");
printf("pgm_table[NUM_PGMS] = \n{\n");
/* add routine entry points (name, block_id, address) */
while (num_pgms)
{
j = (num_pgms < ABC) ? num_pgms : ABC; /* read as many as can/left */
num_pgms -= j; qtr = bytes;
fread(qtr,sizeof(address),j,fptr); /* !!! should test for NULL */
for (; j--; qtr += sizeof(address))
{
address z;
z = GET_ADDRESS(qtr); /* offset */
printf(" the_code + 0x%x, the_code + 0x%x,\t\t/* %s */\n",
(unsigned int)(nmptr - block), (unsigned int)z, nmptr);
while (*nmptr++ != '\0') ; /* point to next name */
}
}
printf("};\n");
printf("#endif /* NUM_PGMS */\n\n");
printf("#define BLOCK_NAME \"*built-in*\"\t/* Probably not a good choice */\n");
printf("\n");
dump_loader();
fclose(fptr);
return TRUE;
}
static void dump_loader()
{
dump_doc(
"int MMload_internal_code(code_ran) int *code_ran;",
"{",
" int block_id, j;",
" MMStkFrame mark;",
"",
" /* create the block name and block */",
" if (-1 ==",
" (block_id = MMadd_block(BLOCK_NAME, the_code, GLOBAL_VARS,",
" global_objects, NUM_GLOBAL_OBJECTS)))",
" return FALSE;",
"",
"#if NUM_PGMS",
" /* add routine entry points (name, block_id, address) */",
" for (j = 0; j < NUM_PGMS; j++)",
" {",
" if (!MMadd_pgm(pgm_table[j].pgm_name, block_id, pgm_table[j].pgm_addr))",
" return FALSE;",
" }",
"#endif /* NUM_PGMS */",
"",
" MMset_hooks();",
"",
" MMopen_frame(&mark);",
" MMclose_frame(&mark); /* no args */",
" MMset_block(block_id);",
"",
" *code_ran = MMexecode(ENTRY_POINT);",
"",
" return TRUE;",
"}",
(char *)NULL);
}
#if 0
/* !!! I could get the names out of the name table instead of having the
* pointers in pgm_table array. Save space.
*/
re-query-replace '^.*$' '"&",'
int MMload_internal_code(code_ran) int *code_ran;
{
#if 0
extern Object **MMglobal_object_table; /* in mm.c */
extern uint8 *MMglobal_vars; /* in mm.c */
#endif
int block_id, j;
MMStkFrame mark;
/* create the block name and block */
if (-1 ==
(block_id = MMadd_block(BLOCK_NAME, the_code, GLOBAL_VARS,
global_objects, NUM_GLOBAL_OBJECTS)))
return FALSE;
#if NUM_PGMS
/* add routine entry points (name, block_id, address) */
for (j = 0; j < NUM_PGMS; j++)
{
if (!MMadd_pgm(pgm_table[j].pgm_name, block_id, pgm_table[j].pgm_addr))
return FALSE;
}
#endif /* NUM_PGMS */
MMset_hooks();
MMopen_frame(&mark);
MMclose_frame(&mark); /* no args */
#if 0
MMglobal_object_table = global_objects;
MMglobal_vars = (uint8 *)GLOBAL_VARS;
#endif
MMset_block(block_id);
*code_ran = MMexecode(ENTRY_POINT);
return TRUE;
}
#endif