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 >
C/C++ Source or Header  |  1995-01-14  |  7KB  |  282 lines

  1. /* mco_to_c.c :
  2.  * Convert compiled Mutt code into C code that can be compiled as part of an
  3.  *   application.  ie enable Mutt code to be linked into an application.
  4.  * Thanks to Todd Moody (sjuphil!tmoody@uu.psi.com) for the initial idea.
  5.  * C Durland 8/92    Public Domain
  6.  * 
  7.  * Input:  a .mco file.
  8.  * 
  9.  * cc -I$HOME/c/util -o mco_to_c mco_to_c.c $HOME/c/util/util.a
  10.  */
  11.  
  12. static char what[] = "@(#)mco_to_c 8/9/92 v1.4 5/29/93";
  13. #define WHAT (&what[4])
  14.  
  15. #include <stdio.h>
  16. #include <os.h>
  17. #include <const.h>
  18. #include "mm.h"
  19.  
  20. static int MMload_code();
  21. static void dump_loader();
  22.  
  23. static void usage()
  24. {
  25.   fdump_doc(stderr,
  26.     "mco_to_c:  Convert a .mco file into C",
  27.     "Usage:  mco_to_c <foo.mco>",
  28.     (char *)NULL);
  29. }
  30.  
  31. main(argc, argv) int argc; char **argv;
  32. {
  33.   if (argc != 2)
  34.   {
  35.     usage();
  36.     exit(1);
  37.   }
  38.   if (!MMload_code(argv[1], TRUE)) exit(1);
  39.   exit(0);
  40. }
  41.  
  42.  
  43.  
  44. #define ABC 150        /* max number of addresses in I can get per read */
  45.  
  46. static int MMload_code(fname,complain) char *fname;
  47. {
  48.   char *malloc();
  49.   FILE *fopen();
  50.  
  51.   address entry_point;
  52.   char *block, *nmptr, *zit;
  53.   FILE *fptr;
  54.   int j, num_pgms, num_global_objects, mco_magic_number;
  55.   unsigned int code_size, nmoffset, global_var_space;
  56.   maddr code;
  57.   uint8 bytes[ABC*sizeof(address)], *qtr;
  58.  
  59.         /* open the code file */
  60.   if ((fptr = fopen(fname, "rb")) == NULL)
  61.   {
  62.     if (complain) fprintf(stderr,"Can't open code file: %s\n", fname);
  63.     return FALSE;
  64.   }
  65.  
  66.         /* read and parse the header !!! error check*/
  67.   fread((char *)bytes,1,BYTES_IN_HEADER,fptr);
  68.  
  69.   mco_magic_number = GET_UINT8(&bytes[H_MAGIC_NUMBER]);
  70.   if (MM_MAGIC_NUMBER != mco_magic_number)
  71.   {
  72.     fdump_doc(stderr,
  73.     "Either:",
  74.     "  This ain't a real .mco file or",
  75.     "  it is old and needs to be recompiled or",
  76.     "  this program is old and needs to be recompiled.",
  77.     (char *)NULL);
  78.       
  79.     fclose(fptr);
  80.     return FALSE;
  81.   }
  82.  
  83.   entry_point =        GET_ADDRESS(&bytes[H_ENTRY_POINT]);
  84.   code_size =        GET_UINT16 (&bytes[H_BYTES_OF_CODE]);
  85.   nmoffset =        GET_UINT16 (&bytes[H_NAME_TABLE_OFFSET]);
  86.   num_pgms =        GET_INT16  (&bytes[H_NUMBER_OF_PGMS]);
  87.   global_var_space =    GET_UINT16 (&bytes[H_BYTES_OF_GVARS]);
  88.   num_global_objects =    GET_UINT16 (&bytes[H_NUM_GLOBAL_OBJECTS]);
  89.  
  90.     /* calculate size of code, name table and global vars */
  91.   if ((block = malloc(code_size)) == NULL)
  92.   {
  93.     fprintf(stderr,"Can't malloc code\n");
  94.     fclose(fptr);
  95.     return FALSE;
  96.   }
  97.  
  98.      /* Get the code, strings and name table.     !!! error check */
  99.   fread(block,1,code_size,fptr);
  100.   code        = (maddr)block;
  101.   nmptr        = block + nmoffset;
  102.  
  103.   dump_doc(
  104.     "/* This file was generated by a program (mco_to_c).",
  105.     " * You probably don't want to mess with it.",
  106.     " * Public Domain",
  107.     (char *)NULL);
  108.  
  109.   printf(" * Input file: \"%s\"\n */\n", fname);
  110.   printf("\n");
  111.  
  112.   printf("#include <const.h>\n");
  113.   printf("#include <os.h>\n");
  114.   printf("#include <oman.h>\n");
  115.   printf("#include <mm.h>\n");
  116.   printf("\n");
  117.  
  118.   printf("#define CODE_SIZE        %u\n", code_size);
  119.   printf("#define SIZE_OF_GLOBAL_VARS    %u\n", global_var_space);
  120.   printf("\n");
  121.  
  122.   printf(
  123.      "static unsigned char the_code[CODE_SIZE + SIZE_OF_GLOBAL_VARS] = \n{");
  124.   {
  125.     unsigned char *ptr = code;
  126.     int i;
  127.     unsigned int n;
  128.  
  129.     for (i = 0, n = code_size; n--; ptr++)
  130.     {
  131.       if (0 == i--) { printf("\n  "); i = 15; }
  132.       printf("%3d,", *ptr);
  133.     }
  134.   }
  135.   printf("\n};\n\n");
  136.   
  137.  
  138.   printf("#define MCO_MAGIC_NUMBER    0x%x\t/* read from the .mco file */\n",
  139.     mco_magic_number);
  140.   printf("\n");
  141.   printf("#define NUM_PGMS        %d\n", num_pgms);
  142.   printf("#define NUM_GLOBAL_OBJECTS    %d\n", num_global_objects);
  143.   printf("\n");
  144.   printf("#define ENTRY_POINT_OFFSET    0x%x\n", entry_point);
  145.   printf("#define NAME_TABLE_OFFSET    0x%x\n", nmoffset);
  146.  
  147.   printf("#define GLOBAL_VARS        (the_code + 0x%x)\n", code_size);
  148.   printf("#define ENTRY_POINT         (the_code + ENTRY_POINT_OFFSET)\n");
  149.   printf("\n");
  150.  
  151.   if (0 == num_global_objects)
  152.     printf("static Object **global_objects = NULL;\n");
  153.   else
  154.     printf("static Object *global_objects[NUM_GLOBAL_OBJECTS];\n");
  155.   printf("\n");
  156.  
  157.  
  158.   printf("#if NUM_PGMS\n");
  159.   printf("static struct { unsigned char *pgm_name, *pgm_addr; } ");
  160.   printf("pgm_table[NUM_PGMS] = \n{\n");
  161.  
  162.         /* add routine entry points (name, block_id, address) */
  163.   while (num_pgms)
  164.   {
  165.     j = (num_pgms < ABC) ? num_pgms : ABC;    /* read as many as can/left */
  166.     num_pgms -= j; qtr = bytes;
  167.     fread(qtr,sizeof(address),j,fptr);    /* !!! should test for NULL */
  168.     for (; j--; qtr += sizeof(address))
  169.     {
  170.       address z;
  171.  
  172.       z = GET_ADDRESS(qtr);    /* offset */
  173.       printf("  the_code + 0x%x, the_code + 0x%x,\t\t/* %s */\n",
  174.     (unsigned int)(nmptr - block), (unsigned int)z, nmptr);
  175.       while (*nmptr++ != '\0') ;    /* point to next name */
  176.     }
  177.   }
  178.   printf("};\n");
  179.   printf("#endif /* NUM_PGMS */\n\n");
  180.  
  181.  
  182.   printf("#define BLOCK_NAME        \"*built-in*\"\t/* Probably not a good choice */\n");
  183.   printf("\n");
  184.  
  185.  
  186.   dump_loader();
  187.  
  188.   fclose(fptr);
  189.  
  190.   return TRUE;
  191. }
  192.  
  193.  
  194. static void dump_loader()
  195. {
  196.   dump_doc(
  197. "int MMload_internal_code(code_ran) int *code_ran;",
  198. "{",
  199. "  int block_id, j;",
  200. "  MMStkFrame mark;",
  201. "",
  202. "        /* create the block name and block */",
  203. "  if (-1 ==",
  204. "    (block_id = MMadd_block(BLOCK_NAME, the_code, GLOBAL_VARS,",
  205. "         global_objects, NUM_GLOBAL_OBJECTS)))",
  206. "    return FALSE;",
  207. "",
  208. "#if NUM_PGMS",
  209. "        /* add routine entry points (name, block_id, address) */",
  210. "  for (j = 0; j < NUM_PGMS; j++)",
  211. "  {",
  212. "    if (!MMadd_pgm(pgm_table[j].pgm_name, block_id, pgm_table[j].pgm_addr))",
  213. "    return FALSE;",
  214. "  }",
  215. "#endif /* NUM_PGMS */",
  216. "",
  217. "  MMset_hooks();",
  218. "",
  219. "  MMopen_frame(&mark);",
  220. "  MMclose_frame(&mark);        /* no args */",
  221. "  MMset_block(block_id);",
  222. "",
  223. "  *code_ran = MMexecode(ENTRY_POINT);",
  224. "",
  225. "  return TRUE;",
  226. "}",
  227.   (char *)NULL);
  228. }
  229.  
  230.  
  231. #if 0
  232.  
  233. /* !!! I could get the names out of the name table instead of having the
  234.  * pointers in pgm_table array.  Save space.
  235.  */
  236.  
  237. re-query-replace '^.*$' '"&",'
  238.  
  239. int MMload_internal_code(code_ran) int *code_ran;
  240. {
  241. #if 0
  242.   extern Object **MMglobal_object_table;    /* in mm.c */
  243.   extern uint8 *MMglobal_vars;            /* in mm.c */
  244. #endif
  245.  
  246.   int block_id, j;
  247.   MMStkFrame mark;
  248.  
  249.         /* create the block name and block */
  250.   if (-1 ==
  251.     (block_id = MMadd_block(BLOCK_NAME, the_code, GLOBAL_VARS,
  252.          global_objects, NUM_GLOBAL_OBJECTS)))
  253.     return FALSE;
  254.  
  255. #if NUM_PGMS
  256.         /* add routine entry points (name, block_id, address) */
  257.   for (j = 0; j < NUM_PGMS; j++)
  258.   {
  259.     if (!MMadd_pgm(pgm_table[j].pgm_name, block_id, pgm_table[j].pgm_addr))
  260.     return FALSE;
  261.   }
  262. #endif /* NUM_PGMS */
  263.  
  264.   MMset_hooks();
  265.  
  266.   MMopen_frame(&mark);
  267.   MMclose_frame(&mark);        /* no args */
  268.  
  269. #if 0
  270.   MMglobal_object_table = global_objects;
  271.   MMglobal_vars = (uint8 *)GLOBAL_VARS;
  272. #endif
  273.  
  274.   MMset_block(block_id);
  275.  
  276.   *code_ran = MMexecode(ENTRY_POINT);
  277.  
  278.   return TRUE;
  279. }
  280.  
  281. #endif
  282.