home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / callmon / src / message_definition.c < prev   
C/C++ Source or Header  |  1996-08-06  |  6KB  |  246 lines

  1. /*  File:     MESSAGE_DEFINITION.C
  2.  *  Author:   Thierry Lelegard
  3.  *  Date:     24-JUL-1996
  4.  *
  5.  *  Abstract: This program generates a C or Ada definition file
  6.  *            for all constants that are defined in an object
  7.  *            file, like message files.
  8.  *
  9.  *  Arguments: -language object-file-name module-name
  10.  */
  11.  
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <fcntl.h>
  18. #include <ctype.h>
  19. #include <egsdef.h>
  20. #include <egsydef.h>
  21. #include <esdfdef.h>
  22. #include <eobjrecdef.h>
  23.  
  24.  
  25. /*
  26.  *  Languages properties.
  27.  */
  28.  
  29. typedef void (*fmt_start_t) (FILE* fp, char* module);
  30. typedef void (*fmt_symbol_t) (FILE* fp, long value, char* symbol, int length);
  31. typedef void (*fmt_end_t) (FILE* fp, char* module);
  32.  
  33. typedef struct {
  34.     char*        language;
  35.     char*        file_name_format;
  36.     char*        comment_start;
  37.     char*        comment_end;
  38.     fmt_start_t  fmt_start;
  39.     fmt_symbol_t fmt_symbol;
  40.     fmt_end_t    fmt_end;
  41. } language_t;
  42.  
  43. static void c_fmt_start (FILE* fp, char* module);
  44. static void c_fmt_symbol (FILE* fp, long value, char* symbol, int length);
  45. static void c_fmt_end (FILE* fp, char* module);
  46.  
  47. static void ada_fmt_start (FILE* fp, char* module);
  48. static void ada_fmt_symbol (FILE* fp, long value, char* symbol, int length);
  49. static void ada_fmt_end (FILE* fp, char* module);
  50.  
  51. static language_t languages [] = {
  52.     {"-c", "%s.H", "/* ", " */", c_fmt_start, c_fmt_symbol, c_fmt_end},
  53.     {"-ada", "%s_.ADA", "-- ", "", ada_fmt_start, ada_fmt_symbol, ada_fmt_end},
  54.     {NULL}};
  55.  
  56.  
  57. /*
  58.  *  C language routines
  59.  */
  60.  
  61. static void c_fmt_start (FILE* fp, char* module)
  62. {
  63.     fprintf (fp, "#ifndef %s_H_LOADED\n#define %s_H_LOADED 1\n",
  64.         module, module);
  65. }
  66.  
  67. static void c_fmt_symbol (FILE* fp, long value, char* symbol, int length)
  68. {
  69.     fprintf (fp, "#define %.*s 0x%08X\n", length, symbol, value);
  70. }
  71.  
  72. static void c_fmt_end (FILE* fp, char* module)
  73. {
  74.     fprintf (fp, "#endif /* %s_H_LOADED */\n", module);
  75. }
  76.  
  77.  
  78. /*
  79.  *  Ada language routines
  80.  */
  81.  
  82. static void ada_fmt_start (FILE* fp, char* module)
  83. {
  84.     fprintf (fp, "package %s is\n", module);
  85. }
  86.  
  87. static void ada_fmt_symbol (FILE* fp, long value, char* symbol, int length)
  88. {
  89.     fprintf (fp, "    ");
  90.     for (; length > 0; length--, symbol++) {
  91.         if (*symbol == '$') {
  92.             if (length > 1 && symbol [1] != '_')
  93.                 putc ('_', fp);
  94.         }
  95.         else if (*symbol == '_') {
  96.             if (length > 1 && symbol [1] != '_')
  97.                 putc ('_', fp);
  98.         }
  99.         else
  100.             putc (*symbol, fp);
  101.     }
  102.     fprintf (fp, " : constant := 16#%08X#;\n", value);
  103. }
  104.  
  105. static void ada_fmt_end (FILE* fp, char* module)
  106. {
  107.     fprintf (fp, "end %s;\n", module);
  108. }
  109.  
  110.  
  111. /*
  112.  *  Main program
  113.  */
  114.  
  115. int main (int argc, char** argv)
  116. {
  117.     char* language_name;
  118.     char* object_file;
  119.     char* module_name;
  120.     language_t* lang;
  121.     int obj;
  122.     FILE* out;
  123.     char out_file_name [255];
  124.     char object_record [EOBJ$C_MAXRECSIZ];
  125.     int record_size;
  126.     struct egsdef* egsd;
  127.     struct esdfdef* esdf;
  128.     char* end_record;
  129.     char* p;
  130.  
  131.     /* Check command line options */
  132.  
  133.     if (argc != 4) {
  134.         fprintf (stderr, "Arguments: -language object-file module-name\n");
  135.         exit (EXIT_FAILURE);
  136.     }
  137.  
  138.     language_name = argv [1];
  139.     object_file = argv [2];
  140.     module_name = argv [3];
  141.  
  142.     /* Look for the requested language */
  143.  
  144.     for (lang = languages; lang->language != NULL; lang++)
  145.         if (strcmp (lang->language, language_name) == 0)
  146.             break;
  147.  
  148.     if (lang->language == NULL) {
  149.         fprintf (stderr, "Unknown language %s\n", language_name);
  150.         exit (EXIT_FAILURE);
  151.     }
  152.  
  153.     /* Convert the module name to uppercase */
  154.  
  155.     for (p = module_name; *p != '\0'; p++)
  156.         if (islower (*p))
  157.             *p = toupper (*p);
  158.  
  159.     /* Open the object file in record mode */
  160.  
  161.     if ((obj = open (object_file, O_RDONLY, 0, "ctx=rec", "dna=.obj")) < 0) {
  162.         perror (object_file);
  163.         exit (EXIT_FAILURE);
  164.     }
  165.  
  166.     /* Open the output definition file */
  167.  
  168.     sprintf (out_file_name, lang->file_name_format, module_name);
  169.  
  170.     if ((out = fopen (out_file_name, "w")) == NULL) {
  171.         perror (out_file_name);
  172.         exit (EXIT_FAILURE);
  173.     }
  174.  
  175.     /* Generate introduction sequence */
  176.  
  177.     fprintf (out, "%s%s - Automatically generated file, do not modify%s\n\n",
  178.         lang->comment_start, out_file_name, lang->comment_end);
  179.  
  180.     lang->fmt_start (out, module_name);
  181.     fprintf (out, "\n");
  182.  
  183.     /* Read all object records */
  184.  
  185.     while ((record_size = read (obj, object_record, EOBJ$C_MAXRECSIZ)) > 0) {
  186.  
  187.         egsd = (struct egsdef*) object_record;
  188.         end_record = object_record + egsd->egsd$w_recsiz;
  189.  
  190.         /* Verify actual record size */
  191.  
  192.         if (record_size < egsd->egsd$w_recsiz) {
  193.             fprintf (stderr, "Invalid record in %s: %d bytes, expected %d\n",
  194.                 object_file, record_size, egsd->egsd$w_recsiz);
  195.             continue;
  196.         }
  197.  
  198.         /* Keep Global Symbol Directory records only */
  199.  
  200.         if (egsd->egsd$w_rectyp != EOBJ$C_EGSD)
  201.             continue;
  202.  
  203.         /* Get address of first subrecord */
  204.  
  205.         esdf = (struct esdfdef*) &egsd->egsd$w_gsdtyp;
  206.  
  207.         /* Loop on all subrecords of this record */
  208.  
  209.         while ((char*)esdf->esdf$t_name < end_record &&
  210.                (char*)esdf + esdf->esdf$w_size <= end_record) {
  211.  
  212.             /* Keep only symbol definitions of constants */
  213.  
  214.             if (esdf->esdf$w_gsdtyp == EGSD$C_SYM &&
  215.                 (esdf->esdf$w_flags & EGSY$M_DEF) != 0 &&
  216.                 (esdf->esdf$w_flags & EGSY$M_REL) == 0) {
  217.  
  218.                 /* Generate symbol definition */
  219.  
  220.                 lang->fmt_symbol (out, esdf->esdf$l_value,
  221.                     esdf->esdf$t_name, esdf->esdf$b_namlng);
  222.             }
  223.  
  224.             /* Point to next subrecord. Subrecords are always rounded
  225.              * up to quadword boundary. */
  226.  
  227.             if (esdf->esdf$w_size % 8 == 0)
  228.                 esdf = (struct esdfdef*) ((char*)esdf + esdf->esdf$w_size);
  229.             else
  230.                 esdf = (struct esdfdef*) ((char*)esdf + esdf->esdf$w_size +
  231.                     8 - esdf->esdf$w_size % 8);
  232.         }
  233.     }
  234.  
  235.     if (record_size < 0)
  236.         perror (object_file);
  237.  
  238.     /* Generate termination sequence */
  239.  
  240.     fprintf (out, "\n");
  241.     lang->fmt_end (out, module_name);
  242.  
  243.     fclose (out);
  244.     close (obj);
  245. }
  246.