home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / MAKEDE.ZIP / MAKEDEF.C next >
C/C++ Source or Header  |  1992-11-04  |  18KB  |  650 lines

  1. /****************************************************************************
  2.  
  3.    NAME    : MAKEDEF
  4.    FROM    : Reiner Kissel + Peter Reinhardt BASF AG Ludwigshafen
  5.  
  6. ****************************************************************************/
  7. char copyright[] = "MAKEDEF.EXE  Version November 1992";
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <stdarg.h>
  13. #include <io.h>
  14. #include "objutils.h"
  15.  
  16. /* ------ Defines --------*/
  17. #define EXTDEF     0x001
  18. #define PUBDEF     0x002
  19. #define COMDEF     0x004
  20. #define E_PDEF     0x008
  21. #define WRITTEN    0x010
  22.  
  23. #define MAXSTRING  256
  24.  
  25. /* ------ Global variables --------*/
  26. struct nam
  27. {
  28.    char * name;
  29.    int  flags;
  30.    struct nam *next;
  31. };
  32. typedef struct nam namen;
  33.  
  34. namen *start_namen = NULL;
  35. namen *start_com = NULL;
  36. namen *n, *zn;
  37.  
  38. OMFHEADER ObjRecHdr;
  39.  
  40. /* ----- Prototypes ------------*/
  41. int main(int, char **);
  42. void print_help(void);
  43. int get_name(FILE *fp_obj, int *reclen, namen **start_list, int flag);
  44. int get_index(FILE *fp_obj, int *reclen);
  45. int get_number(FILE *fp_obj, int *reclen);
  46. int get_length(FILE *fp_obj, int *reclen);
  47. void process_obj(char *objname, char *library, FILE *fp_def, int req_flag);
  48. void process_lib(char *libname, char *dllname, FILE *fp_def);
  49. void DumpSymbolDictionary(LIBHDR *LibHeader, FILE *InLibFH, FILE *fp_def);
  50. void PrintDefHeader(char *FileName, char *LibName, FILE *fp_def);
  51. void InsertInList(namen **start_list, char *pbuf, int flag);
  52.  
  53. /* ----- main ------------------*/
  54. int main(int argc, char **argv)
  55. {
  56.   FILE *fp_objlist;
  57.   char tmp[MAXSTRING];
  58.   FILE *fp_def = stdout;
  59.   int args;
  60.   int req_flag=0;
  61.   char *library = "";
  62.  
  63.   if (argc<2)
  64.     print_help();
  65.  
  66.   for(args = 1; args < argc; args++)
  67.   {
  68.     strupr(argv[args]);
  69.  
  70.     if (strlen(argv[args]) < 2 || argv[args][0] == '/')
  71.     {
  72.        if (stricmp(argv[args],"/L")==0)
  73.        {
  74.          ++args;
  75.          if (args<argc)
  76.            library=argv[args];
  77.        }
  78.        else if (stricmp(argv[args],"/D")==0)
  79.        {
  80.          ++args;
  81.          if (args<argc)
  82.          {
  83.            fp_def=fopen(argv[args],"w");
  84.            if (!fp_def)
  85.            {
  86.              fprintf(stderr,"Open error: Definition file %s\n",argv[args]);
  87.              exit(1);
  88.            }
  89.          }
  90.        }
  91.        else if (stricmp(argv[args],"/P")==0)
  92.          req_flag|=PUBDEF;
  93.        else if (stricmp(argv[args],"/C")==0)
  94.          req_flag|=COMDEF;
  95.        else if (stricmp(argv[args],"/E")==0)
  96.          req_flag|=EXTDEF;
  97.        else if (stricmp(argv[args],"/O")==0)
  98.        {
  99.           ++args;
  100.           if (args<argc)
  101.           {
  102.              fp_objlist=fopen(argv[args],"r");
  103.              if (!fp_objlist)
  104.              {
  105.                 fprintf(stderr,"Open error: Objectlist file %s\n",argv[args]);
  106.                 exit(1);
  107.              }
  108.              else
  109.              {
  110.                 while( 1 )
  111.                 {
  112.                    if( fgets( tmp, MAXSTRING - 1, fp_objlist ) == NULL )
  113.                      if( feof( fp_objlist ) )
  114.                          break;
  115.                    tmp[strlen(tmp) - 1] = '\0';
  116.                    process_obj(tmp, library, fp_def, req_flag);
  117.                 }
  118.              }
  119.              fclose(fp_objlist);
  120.           }
  121.        }
  122.        else if (stricmp(argv[args],"/B")==0)
  123.        {
  124.           ++args;
  125.           if (args<argc)
  126.           {
  127.              fp_objlist=fopen(argv[args],"r");
  128.              if (!fp_objlist)
  129.              {
  130.                 fprintf(stderr,"Open error: Librarylist file %s\n",argv[args]);
  131.                 exit(1);
  132.              }
  133.              else
  134.              {
  135.                 while( 1 )
  136.                 {
  137.                    if( fgets( tmp, MAXSTRING - 1, fp_objlist ) == NULL )
  138.                      if( feof( fp_objlist ) )
  139.                          break;
  140.                    tmp[strlen(tmp) - 1] = '\0';
  141.                    process_lib(tmp, library, fp_def);
  142.                 }
  143.              }
  144.              fclose(fp_objlist);
  145.           }
  146.        }
  147.        else
  148.          print_help();
  149.        continue;
  150.     }
  151.  
  152.     if (strstr(argv[args], ".OBJ"))
  153.        process_obj(argv[args], library, fp_def, req_flag);
  154.     else if (strstr(argv[args], ".LIB"))
  155.        process_lib(argv[args], library, fp_def);
  156.     else
  157.        print_help();
  158.  
  159.   } /* end args */
  160.  
  161.   for (n = start_com; n; )
  162.      {
  163.      zn = n;
  164.      n  = n->next;
  165.      free(zn->name);
  166.      free(zn);
  167.      }
  168.  
  169.   start_com = NULL;
  170.  
  171.   return 0;
  172. }
  173.  
  174. /*---------------------------------------------------------------------------*/
  175. void print_help(void)
  176. {
  177.   int i;
  178.   static char *text[]={copyright,
  179. "Analyse .OBJ or .LIB Files to produce a .DEF File with its Exports",
  180. "Syntax: MAKEDEF [/l libname] [/d deffile] [/o ol] [/b ll] <opt> objfile(s)",
  181. "  libname       default: basename of the first objecfile",
  182. "  deffile       default: stdout",
  183. "  ol : file with list of objects to process",
  184. "  ll : file with list of libraries to process (<opt> ignored)",
  185. "  opt:",
  186. "  /p : Export public names   (Global Vars initialized)",
  187. "  /c : Export communal names (Global Vars uninitialized or C++ static Vars)",
  188. "  /e : Emit external names as comments (External Funcs and Vars)",
  189. "  /? : This information",
  190. "The exported names in the produced .DEF file are in the order of the analysed",
  191. "objektfiles and their types. Comment headers show the object names and the",
  192. "Symbol types.",
  193. "Global function names (these are public and external) will allways be exported.",
  194. "Global initialized variables (option /p) should be exported to reference ",
  195. "___vtbl_ entries from Glockenspiel C++.",
  196. "Global uninitialized variables (option /c) will be exported once per name",
  197. "and regardless of their appearance in other .OBJ files (shown as a comment).",
  198. "External functions and variables (option /e) will only be emitted as comments",
  199. "for information.",
  200. NULL};
  201.  
  202.   for (i=0;text[i];i++)
  203.     fprintf(stderr,"%s\n",text[i]);
  204.  
  205.   exit(1);
  206. }
  207.  
  208. /*---------------------------------------------------------------------------*/
  209. int get_name(FILE *fp_obj, int *reclen, namen **start_list, int flag)
  210. {
  211.   int len;
  212.   int c = 0;
  213.   char *pbuf, *p;
  214.   namen **n,*zn;
  215.  
  216.   len = getc(fp_obj);
  217.   (*reclen)--;
  218.  
  219.   if (len == EOF)
  220.      return len;
  221.  
  222.   pbuf = malloc(len + 1);
  223.  
  224.   if (!pbuf)
  225.      {
  226.      fprintf(stderr,"malloc failure\n");
  227.      exit(1);
  228.      }
  229.  
  230.   (*reclen) -= len;
  231.  
  232.   if ((*reclen) <= 0)
  233.      {
  234.      fprintf(stderr,"*** %s ***: Unexpected end of records\n",
  235.              flag==PUBDEF ? "PUBDEF" : (flag==COMDEF ? "COMDEF" : "EXTDEF"));
  236.      exit(1);
  237.      }
  238.  
  239.   if (fread((void *)pbuf, len, 1, fp_obj) != 1)
  240.      {
  241.      free(pbuf);
  242.      return EOF;
  243.      }
  244.  
  245.   pbuf[len] = 0;
  246.  
  247.   InsertInList(start_list, pbuf, flag);
  248.  
  249.   return 0;
  250. }
  251.  
  252. /*---------------------------------------------------------------------------*/
  253. int get_index(FILE *fp_obj, int *reclen)
  254. {
  255.   int i,j;
  256.  
  257.   i = getc(fp_obj);
  258.   (*reclen)--;
  259.  
  260.   if (i & 0x80)
  261.      {
  262.      j = getc(fp_obj);
  263.      (*reclen)--;
  264.      }
  265.  
  266.   return i;
  267. }
  268.  
  269. /*---------------------------------------------------------------------------*/
  270. int get_number(FILE *fp_obj, int *reclen)
  271. {
  272.   fseek(fp_obj, 2, SEEK_CUR);
  273.   (*reclen)--;
  274.   (*reclen)--;
  275.  
  276.   return 0;
  277. }
  278.  
  279. /*---------------------------------------------------------------------------*/
  280. int get_length(FILE *fp_obj, int *reclen)
  281. {
  282.   int i;
  283.  
  284.   i = getc(fp_obj);
  285.   (*reclen)--;
  286.  
  287.   switch (i)
  288.      {
  289.      case 0x81:
  290.           fseek(fp_obj, 2, SEEK_CUR);
  291.           (*reclen)--;
  292.           (*reclen)--;
  293.           break;
  294.  
  295.      case 0x84:
  296.           fseek(fp_obj, 3, SEEK_CUR);
  297.           (*reclen)--;
  298.           (*reclen)--;
  299.           (*reclen)--;
  300.           break;
  301.  
  302.      case 0x88:
  303.           fseek(fp_obj, 4, SEEK_CUR);
  304.           (*reclen)--;
  305.           (*reclen)--;
  306.           (*reclen)--;
  307.           (*reclen)--;
  308.           break;
  309.      }
  310.  
  311.   return (i);
  312. }
  313.  
  314. /*---------------------------------------------------------------------------*/
  315. void process_obj(char *objname, char *library, FILE *fp_def, int req_flag)
  316. {
  317.     FILE *fp_obj;
  318.     int i,j;
  319.     int test_flag;
  320.     int rectyp,reclen;
  321.     int c,num,newdef;
  322.     int Ende = 0;
  323.     static int header_request = 1;
  324.  
  325.     fp_obj = fopen(objname,"rb");
  326.  
  327.     if (!fp_obj)
  328.        {
  329.        fprintf(stderr,"Object file %s not found\n",objname);
  330.        exit(1);
  331.        }
  332.  
  333.     if (header_request)
  334.        {
  335.        header_request=0;
  336.  
  337.        PrintDefHeader(objname, library, fp_def);
  338.        }
  339.  
  340.     fprintf(stderr,"Processing %s\n",objname);
  341.  
  342.     test_flag=0;
  343.  
  344.     while (!Ende)
  345.        {
  346.        if (fread((void *)&ObjRecHdr, sizeof(OMFHEADER), 1, fp_obj) != 1)
  347.           {
  348.           fprintf(stderr,"Unexpected EOF in objectheader.\n");
  349.           exit(1);
  350.           }
  351.  
  352.        // default = old obj-format
  353.        newdef = 0;
  354.        rectyp = ObjRecHdr.RecType;
  355.        reclen = ObjRecHdr.RecLength;
  356.  
  357.        switch (rectyp)
  358.           {
  359.           case 0x08C:                  /* EXTDEF OS/2 1.3 and OS/2 2.0 */
  360.                while (reclen > 1)
  361.                   {
  362.                   c = get_name(fp_obj,&reclen,&start_namen,EXTDEF);
  363.                   c = get_index(fp_obj,&reclen); /* Type index */
  364.                   }
  365.                break;
  366.  
  367.           case 0x091:                  /* PUBDEF  format from OS/2 2.0*/
  368.                newdef = 1;
  369.           case 0x090:                  /* PUBDEF  old format*/
  370.                c = get_index(fp_obj,&reclen);   /*Grp Idx*/
  371.                c = get_index(fp_obj,&reclen);   /*Seg Idx*/
  372.  
  373.                if (c == 0)                      /* cond. Frame */
  374.                   c = get_number(fp_obj,&reclen);
  375.  
  376.                while (reclen > 1)
  377.                   {
  378.                   c = get_name(fp_obj,&reclen,&start_namen,PUBDEF);
  379.                   c = get_number(fp_obj,&reclen);      /* Offset */
  380.  
  381.                   if (newdef)                          /* Offset 2 (32 Bit) */
  382.                      c = get_number(fp_obj,&reclen);
  383.  
  384.                   c = get_index(fp_obj,&reclen);       /* Type index */
  385.                   } /* while (reclen--) */
  386.  
  387.                break;
  388.  
  389.           case 0x0B0:                  /* COMDEF OS/2 1.3 and OS/2 2.0 */
  390.                if (!(req_flag&COMDEF))
  391.                   {
  392.                   fseek(fp_obj, (long)reclen - 1, SEEK_CUR);
  393.                   break;
  394.                   }
  395.  
  396.                while (reclen > 1)
  397.                   {
  398.                   test_flag |= COMDEF;
  399.                   c = get_name(fp_obj,&reclen,&start_com,COMDEF);
  400.                   c = get_index(fp_obj,&reclen);    /* Type index */
  401.                   c = getc(fp_obj);                 /* Data Seg Type */
  402.                   reclen--;
  403.  
  404.                   switch (c)
  405.                      {
  406.                      case 0x062:        /* (NEAR) */
  407.                           c = get_length(fp_obj,&reclen);
  408.                           break;
  409.  
  410.                      case 0x061:        /* (FAR)  */
  411.                           c = get_length(fp_obj,&reclen);
  412.                           c = get_length(fp_obj,&reclen);
  413.                           break;
  414.  
  415.                      default:
  416.                           fprintf(stderr,"Unexpected Data Seg Type %.2XH in RECTYP %.2XH\n",
  417.                                   c,rectyp);
  418.                           exit(1);
  419.                           break;
  420.                      }
  421.  
  422.                   } /* while (reclen > 1) */
  423.                break;
  424.  
  425.           case 0x8a:
  426.           case 0x8b:
  427.                Ende = 1;
  428.  
  429.           default:
  430.                fseek(fp_obj, (long)reclen - 1, SEEK_CUR);
  431.                break;
  432.  
  433.           } /* switch (rectyp) */
  434.  
  435.        if (getc(fp_obj) == EOF) /*checksum*/
  436.           {
  437.           fprintf(stderr,"Unexpected EOF in RECTYP %.2XH\n",rectyp);
  438.           exit(1);
  439.           }
  440.  
  441.        } /* while (!Ende) */
  442.  
  443.     fclose(fp_obj);
  444.  
  445.     for (n = start_namen; n; )
  446.        {
  447.        if (n->flags & EXTDEF && n->flags & PUBDEF)
  448.           test_flag |= E_PDEF;
  449.        else if (n->flags & req_flag & PUBDEF)
  450.           test_flag |= PUBDEF;
  451.        else if (n->flags & req_flag & EXTDEF)
  452.           test_flag |= EXTDEF;
  453.        n = n->next;
  454.        }
  455.  
  456.     if (test_flag)
  457.        fprintf(fp_def,"; OBJ-file: %s\n",objname);
  458.  
  459.     if (test_flag & E_PDEF)
  460.        {
  461.        fprintf(fp_def,";   Names External and Public (Global Functions):\n");
  462.        for (n = start_namen; n; )
  463.           {
  464.           if (n->flags & EXTDEF && n->flags & PUBDEF)
  465.              fprintf(fp_def,"\t%s\n",n->name);
  466.           n = n->next;
  467.           }
  468.        }
  469.  
  470.     if (test_flag & PUBDEF)
  471.        {
  472.        fprintf(fp_def,";   Names Public (Global Variables initialized):\n");
  473.        for (n = start_namen; n; )
  474.           {
  475.           if (n->flags & PUBDEF && !(n->flags & EXTDEF))
  476.           fprintf(fp_def,"\t%s\n",n->name);
  477.           n = n->next;
  478.           }
  479.        }
  480.  
  481.     if (test_flag & COMDEF)
  482.        {
  483.        fprintf(fp_def,";   Names Communal (Global Variables uninitialized):\n");
  484.        for (n = start_com; n; )
  485.           {
  486.           if (n->flags & COMDEF)
  487.              {
  488.              if (n->flags & WRITTEN)
  489.                 fprintf(fp_def,";\t%s\n",n->name);
  490.              else
  491.                 fprintf(fp_def,"\t%s\n",n->name);
  492.              n->flags = WRITTEN;
  493.              }
  494.           n = n->next;
  495.           }
  496.        }
  497.  
  498.     if (test_flag & EXTDEF)
  499.        fprintf(fp_def,";   Names External (External Functions and Variables):\n");
  500.  
  501.     for (n = start_namen; n; )
  502.        {
  503.        if (n->flags & req_flag & EXTDEF && !(n->flags & PUBDEF))
  504.           fprintf(fp_def,";\t%s\n",n->name);
  505.        zn = n;
  506.        n  = n->next;
  507.        free(zn->name);
  508.        free(zn);
  509.        }
  510.  
  511.     start_namen=NULL;
  512. }
  513.  
  514. /*---------------------------------------------------------------------------*/
  515. void process_lib(char *libname, char *dllname, FILE *fp_def)
  516. {
  517.     FILE *InLibFH;
  518.     LIBHDR LibHeader;
  519.     int i,j;
  520.     static int header_request = 1;
  521.  
  522.     if (header_request)
  523.        {
  524.        header_request = 0;
  525.        PrintDefHeader(libname, dllname, fp_def);
  526.        }
  527.  
  528.     if ((InLibFH = fopen(libname, "rb")) == NULL)
  529.         Output(Error, NOFILE, "Couldn't Open %s.\n", libname);
  530.  
  531.     fprintf(stderr,"Processing %s\n",libname);
  532.  
  533.     fprintf(fp_def,"; LIB-file: %s\n",libname);
  534.     fprintf(fp_def,";   Names External and Public (Global Functions):\n");
  535.  
  536.     GetLibHeader(&LibHeader, InLibFH);
  537.     DumpSymbolDictionary(&LibHeader, InLibFH, fp_def);
  538.  
  539.     for (n = start_namen; n; )
  540.        {
  541.        fprintf(fp_def,"\t%s\n",n->name);
  542.        zn = n;
  543.        n  = n->next;
  544.        free(zn->name);
  545.        free(zn);
  546.        }
  547.  
  548.     start_namen = NULL;
  549. }
  550.  
  551. /*---------------------------------------------------------------------------*/
  552. //  DumpSymbolDictionary  --  Print out an entire Symbol Dictionary
  553. void DumpSymbolDictionary(LIBHDR *LibHeader, FILE *InLibFH, FILE *fp_def)
  554. {
  555.     int BlockIdx, BucketIdx;
  556.     DICTENTRY DictEntry;
  557.     char *SymbolP;
  558.  
  559.     for (BlockIdx = 0; BlockIdx < LibHeader->NumDictBlocks; BlockIdx++) 
  560.        for (BucketIdx = 0; BucketIdx < NUMBUCKETS; BucketIdx++)
  561.           {
  562.           DictEntry = GetSymDictEntry(BlockIdx, BucketIdx, LibHeader, InLibFH);
  563.  
  564.           if (DictEntry.IsFound == false)
  565.              continue;
  566.  
  567.           // Get the symbol name
  568.           SymbolP = MakeASCIIZ(DictEntry.SymbolP);
  569.  
  570.           // discard modul entry (ends with !)
  571.           if (SymbolP[strlen(SymbolP) - 1] != '!')
  572.              InsertInList(&start_namen, SymbolP, EXTDEF | PUBDEF);
  573.           }
  574. }
  575.  
  576. /*---------------------------------------------------------------------------*/
  577. void PrintDefHeader(char *FileName, char *LibName, FILE *fp_def)
  578. {
  579.     int  i,j;
  580.     char *Name = LibName;
  581.  
  582.     if (*LibName == '\0')
  583.        {
  584.        Name = malloc(9);
  585.  
  586.        for (i = strlen(FileName); i && FileName[i] != '\\'; i--);
  587.           if (FileName[i] == '\\')
  588.              i++;
  589.  
  590.        for (j = 0; j < 8 && FileName[i] != '.' && FileName[i]; j++, i++)
  591.            Name[j] = FileName[i];
  592.  
  593.        Name[j] = '\0';
  594.        }
  595.  
  596.     fprintf(fp_def,"LIBRARY\t%s\tINITINSTANCE\n",Name);
  597.     fprintf(fp_def,"DESCRIPTION\t\'%s.DLL --- Copyright <Your Copyright>\'\n",Name);
  598.     fprintf(fp_def,"CODE\tSHARED\n");
  599.     fprintf(fp_def,"DATA\tNONSHARED\n");
  600.     fprintf(fp_def,"EXPORTS\n");
  601.  
  602.     if (*LibName == '\0')
  603.        free(Name);
  604. }
  605.  
  606. /*---------------------------------------------------------------------------*/
  607. void InsertInList(namen **start_list, char *pbuf, int flag)
  608. {
  609.   namen **n,*zn;
  610.  
  611.   for (n = start_list; (*n); n = &((*n)->next))
  612.      {
  613.      if (strcmp(pbuf,(*n)->name) > 0)
  614.         continue;
  615.  
  616.      if (strcmp(pbuf,(*n)->name) == 0)
  617.         {
  618.         (*n)->flags |= flag;
  619.         return;
  620.         }
  621.  
  622.      zn   = *n;
  623.      (*n) = NULL;
  624.      (*n) = malloc(sizeof(namen));
  625.  
  626.      if (!(*n))
  627.         {
  628.         fprintf(stderr,"malloc failure\n");
  629.         exit(1);
  630.         }
  631.  
  632.      (*n)->name  = pbuf;
  633.      (*n)->flags = flag;
  634.      (*n)->next  = zn;
  635.      return;
  636.      }
  637.  
  638.   (*n) = malloc(sizeof(namen));
  639.  
  640.   if (!(*n))
  641.      {
  642.      fprintf(stderr,"malloc failure\n");
  643.      exit(1);
  644.      }
  645.  
  646.   (*n)->name  = pbuf;
  647.   (*n)->flags = flag;
  648.   (*n)->next  = NULL;
  649. }
  650.