home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / turbo_c / tcc_misc.arc / TCOD.C < prev    next >
C/C++ Source or Header  |  1987-06-09  |  5KB  |  155 lines

  1. /*
  2.  *  TCOD:   This quick-and-dirty utility will create a .COD file which 
  3.  *    contains a mixed assembly and Turbo-C source code listing. The
  4.  *    result is similar to that obtained by using the "-Fc" option flag
  5.  *    with Microsoft C v3.0 or v4.0.  This utility has been tested with
  6.  *    Turbo-C v1.00.
  7.  *
  8.  *    To compile this utility:
  9.  *        "tcc -G -O -Z -w tcod.c"
  10.  *        
  11.  *    To obtain a listing of foo.c:
  12.  *        "tcc -S <all other flags> foo.c"
  13.  *        "tcod foo"
  14.  *        
  15.  *    To build an implicit rule for use with MAKE, place the  following
  16.  *    lines into BUILTINS.MAK
  17.  *    .c.cod:
  18.  *       tcc -S $<
  19.  *       tcod $*
  20.  *       del $*.ASM
  21.  *
  22.  *    Beware:  If an included file contains code, we will find "; Line"
  23.  *       comments in the ASM file pointing to the line number of the 
  24.  *       included file.  Unfortunately, we will not have any way to
  25.  *       determine that the code originated from a different source file.
  26.  *       We can do nothing about this.  Let the buyer beware!  I think the
  27.  *       rule here is... don't put code in include files!!
  28.  *
  29.  *    Placed in the public domain 5/19/87 by Lenox Brassell.
  30.  *    [CompuServe PPN: 76224,75].
  31.  *
  32.  *    Modified by Dean McCrory to strip the extension upon startup.
  33.  *    Also changed function headers to match the old format since the new
  34.  *    format is not supported by most compilers.
  35.  */          
  36.  
  37.  
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41.  
  42. static char self[] = "TCOD";  /* Now this code is "self-aware". */
  43.                               /* It knows its own name. */
  44.  
  45. #define PATHNAMELEN  64
  46. typedef char PATHNAME [PATHNAMELEN];
  47.  
  48. /* Input and output streams */
  49. static FILE *asm_stream;   /* Input stream for ?.ASM */
  50. static FILE *c_stream;     /* Input stream for ?.C */
  51. static FILE *merge_stream; /* Output stream for ?.COD */
  52.  
  53.  
  54. /* Input/output buffer for a singe line of the ASM/COD file */
  55. /* We use a leading tab to make the COD output prettier */
  56. #define ASM_LINEMAX  256
  57. static char tab_asm_line[ASM_LINEMAX+2] = "\t";
  58. #define asm_line &tab_asm_line[1]
  59.  
  60. /*  This tag indicates that we should look for the given source code line. */
  61. static char c_tag[] = "; Line ";
  62. #define LINE_LEN  (sizeof(c_tag) - 1)  /* Don't compare the '\0' */
  63. #define C_LINE_COMMENT(s)  ((*(s)==';') && strncmp((s),c_tag,LINE_LEN)==0)
  64.  
  65.  
  66. /* Function prototypes */
  67. static FILE *fopen_by_extension (char *, char *, char *);
  68. static char *seek_c_line (int);
  69.  
  70.  
  71. void main (argc, argv)
  72.    int argc;
  73.    char *argv[];
  74. {
  75.    char *rootname;
  76.    char *c_line;
  77.    int line_number;
  78.  
  79.    if (argc != 2)
  80.       {
  81.       fprintf (stderr, "%s: Usage is \"%s FILENAME\".\n", self,self);
  82.       exit (1);
  83.       }
  84.  
  85.    rootname = strchr (argv[1], '.');   /* search for a period */
  86.    if (rootname != NULL)
  87.       *rootname = '\0';                /* cut string off at period */
  88.  
  89.    rootname = argv[1];
  90.    asm_stream = fopen_by_extension (rootname, ".ASM", "r");
  91.    c_stream = fopen_by_extension (rootname, ".C", "r");
  92.    merge_stream = fopen_by_extension (rootname, ".COD", "w");
  93.  
  94.    /* For each line of ASM source: */
  95.    while (fgets (asm_line,ASM_LINEMAX,asm_stream) != NULL)
  96.       {
  97.       if (C_LINE_COMMENT(asm_line))
  98.          {
  99.          line_number = atoi (asm_line+LINE_LEN);
  100.          c_line = seek_c_line (line_number);
  101.          if (c_line != NULL)
  102.             fputs (c_line, merge_stream);
  103.          else /* Humph!  We can't find the source line. */
  104.             fputs (asm_line, merge_stream);
  105.          }
  106.       else
  107.          fputs (tab_asm_line, merge_stream);
  108.       }
  109.  
  110.    exit (0);
  111. }
  112.  
  113. static FILE *fopen_by_extension (rootname, extension, mode)
  114.    char *rootname;
  115.    char *extension;
  116.    char *mode;
  117. {
  118.    PATHNAME pathname;
  119.    FILE *stream;
  120.     
  121.    stream = fopen (strcat (strcpy (pathname, rootname), extension), mode);
  122.    if (stream == NULL)
  123.       {
  124.       fprintf (stderr, "%s: Cannot open \"%s\"\n", self, pathname);
  125.       perror (pathname);
  126.       exit (1);
  127.       }
  128.  
  129.    return (stream);
  130. }
  131.  
  132.  
  133. #define C_LINE_MAX   256
  134. static char *seek_c_line (line_number)
  135.    int line_number;
  136. {
  137.    static char c_line [C_LINE_MAX+2] = ";";
  138.    static int current_line = 1;
  139.  
  140.    if (line_number < current_line)
  141.       {
  142.       rewind (c_stream);   
  143.       current_line = 1;
  144.       }
  145.  
  146.    while (fgets (c_line+1, C_LINE_MAX, c_stream) != NULL)
  147.       {
  148.       if (current_line++ == line_number)
  149.          return (c_line);
  150.       }
  151.  
  152.    return (NULL);
  153. }
  154.       
  155.