home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 312_01 / cf2mak.awk < prev    next >
Text File  |  1990-04-22  |  15KB  |  331 lines

  1. #  HEADER:        ;
  2. #  TITLE:         Intel Bind (Link) Configuration file object file extractor
  3. #  DATE:          09/20/1989;
  4. #  VERSION:       1.8;
  5. #  DESCRIPTION:   "An AWK program which scans a bind-configuration
  6. #                 file and builds a batch file which will in turn
  7. #                 produce a make-file.  Requires the services of a
  8. #                 source-file dependency generator (such as cincdep)."
  9. #  KEYWORDS:      Makefile, make, include, dependency generator;
  10. #  SYSTEM:        MS-DOS;
  11. #  WARNINGS:      "Your CF file must contain all of the object files which
  12. #                 you want scanned.  PolyAwk will generate false matches
  13. #                 to lines beginning with non-ASCII (i.e. 128..256) chars."
  14. #  FILENAME:      CF2MAK.AWK;
  15. #  SEE-ALSO:      CINCDEP.AWK, TLR2MAK.AWK, AINCDEP.AWK, PINCDEP.AWK;
  16. #  AUTHORS:       James Yehle;
  17. #  COMPILERS:     PolyAWK, Mortice Kern AWK, Rob Duff's PC-AWK 2.0;
  18. #
  19. #-----------------------------------------------------------------------------
  20. #
  21. #  Cf2mak.awk              Last modified  Sep 20, 1989  13:03
  22. #
  23. #     Scans an Intel bind configuration file to produce a batch file
  24. #     which will call dependency generator(s) to build a set of
  25. #     make-file dependency lists, and eventually a full make-file.
  26. #
  27. #  Jim Yehle
  28. #
  29. # . . . Revision history . . . . . . . . . . . . . . . . . . . . . . . . . . .
  30. #
  31. #  1.8  Sep 19 89         JRY  Added target-file, i.e. "object(name)", name
  32. #                               extractor.. uses iRMX default if absent.
  33. #  1.7  Sep 10 89         JRY  Added legal-filename-char regular expression
  34. #  1.6  Aug 28 89         JRY  Added "verbose" CO output as debug level 1.
  35. #  1.5  Jul 24 89         JRY  Removed source & include pathnames from command-
  36. #                               line (it was getting too long for in DOS) and
  37. #                               made them into internal variables.  Added ASM
  38. #                               and PL/M source/include pathnames (which defi-
  39. #                               nitely wouldn't have fit onto the command line),
  40. #                               along with code to call those two languages'
  41. #                               dependency generators.  Expanded "cc" & "ccf"
  42. #                               to support multiple languages, not just C.
  43. #                               removed them from command-line as well.
  44. #  1.4  Jun 20 89         JRY  Added "lcf=" and "ccf=" command-line parameters 
  45. #  1.3  Jun 7  89         JRY  Added "incpath=", "cc=" & "cl=" command-line
  46. #                               parameters (and get_cl_param() to handle 'em)
  47. #  1.2  May 30 89         JRY  Added "srcpath=" command-line parameter,
  48. #                               added executable-file dependency list to top
  49. #                               of depencency-file (outfile)
  50. #  1.1  Cinco di Mayo 89  JRY  Closed file after checking if it exists
  51. #  1.0  Apr 21 89         JRY  Initial creation
  52. # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  53. #
  54. #  Usage is:
  55. #    awk -f cf2mak.awk filename.cf outfile=[path]filename
  56. #        lc=command lcf=[p][n][e] [>batchfile]
  57. #     where outfile gets the conglomerated dependency generators' output
  58. #     Order of command-line parameters (save for "-f ..." 
  59. #      and ">batchfile") is irrelevant, but identifiers must be in lower case.
  60. #     lc is the compile command (no spaces allowed)
  61. #     lcf controls which components of the source file's name get
  62. #         included in the link command line: p = directory path,
  63. #         n = name, e = extension.
  64. # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  65. #
  66. #  Takes an Intel bind configuration file as input.
  67. #  Generates an executable-dependency list at the start of outfile,
  68. #  followed by the link command and the primary (executable) file name.
  69. #  Extracts all "filename.obj" file names.
  70. #  Generates a batch file line, for each object file found, of the form:
  71. #   comdpre srcfile "incpath="incpath "objname="file.obj
  72. #     "cc="cc "ccf="ccf comdmid outfile comdpost
  73. #  unless the source file can't be found, in which case it makes this batch file line:
  74. #   comdpre "__NOFILE__ objname="file.obj "cc= ccf= " comdmid outfile comdpost
  75. #  The search for the source file covers C, assembly, and PL/M path and extensions.
  76. #
  77. #-----------------------------------------------------------------------------
  78. #
  79. BEGIN {
  80.    # Set various strings used in building batch-file command lines
  81.  
  82.    #  Cf2mak supports several languages.  Each language must have
  83.    #   1) a source file name extension (to replace ".obj" in searches)
  84.    #   2) a source directory pathname (stuck on front of file name during search)
  85.    #   3) an include-file directory whose name to pass to a dependency scanner
  86.    #   4) a compiler command to pass to dependency scanner (no spaces allowed)
  87.    #   5) controls for filename pathname/extension inclusion in compile command line
  88.    #   6) a dependency generator awk program
  89.  
  90. # ------------- User-customized section ------------------------------
  91.    # Language 1 is C
  92.    ext[1] = ".c"
  93.    path[1]    = "s:\\c\\"
  94.    ipath[1]   = "s:\\c\\inc\\"
  95.    cc[1] = "ccd"
  96.    ccf[1] = "n"
  97.    depgen[1] = "d:\\source\\awk\\cincdep.awk"
  98.    # Language 2 is PL/M
  99.    ext[2] = ".plm"
  100.    path[2]  = "s:\\plm\\"
  101.    ipath[2] = "s:\\plm\\inc\\"
  102.    cc[2] = "plmld"
  103.    ccf[2] = "n"
  104.    depgen[2] = "d:\\source\\awk\\pincdep.awk"
  105.    # Language 3 is assembly
  106.    ext[3] = ".a28"
  107.    path[3]  = "s:\\asm\\"
  108.    ipath[3] = "s:\\asm\\inc\\"
  109.    cc[3] = "asm"
  110.    ccf[3] = "n"
  111.    depgen[3] = "d:\\source\\awk\\aincdep.awk"
  112.  
  113.    #    allpre      Leading line(s) of entire batch file
  114.    #    allpost     Trailing line(s) of entire batch file
  115.    #    comment     Comment-line lead-in: DOS "REM" or "ECHO", iRMX ";"
  116.    #    comdpre     Command line prefix
  117.    #    comdmid     Command line midle: between source & output file names
  118.    #    comdpost    Command line suffix
  119.    #    exe_ext     Executable file extension (e.g. ".exe" or ".com" for DOS)
  120.    #    linecont    Line-continuation EOL char: snake " /", unix make "\"
  121.    #    fname_chars Regular expression specifying any single legal char
  122.    #                which can appear in a file name.  Must exclude 
  123.    #                directory path separator character! (DOS \, UNIX /)
  124.    allpre = "echo off"
  125.    allpost = "echo on"
  126.    comment = "echo "
  127.    comdpre = "awk -f "
  128.    comdmid = " >>"
  129.    comdpost = ""
  130.    exe_ext = "" 
  131.    linecont = " \\"
  132.    fname_chars = "[^\\\\ :]" # Unix "[^/ ]"; used to use "[A-Za-z0-9_]"
  133. # ------------ End of user-customized section ------------------------
  134. #
  135.    co = "CON"   # Console-out: MS-DOS "CON", iRMX ":co:", unix "/dev/tty"
  136.    debug = 0    # 0=off, 1=verbose, 2=main-level debug, 3= adds functions
  137.  
  138.    print "cf2mak.awk  Bind configuration object-file extractor  v 1.8" > co
  139.  
  140.    outfile = get_cl_param( "outfile=", 0)
  141.    lc = get_cl_param( "lc=", 0)
  142.    lcf = get_cl_param( "lcf=", 0)
  143.  
  144.    print allpre
  145.    if (debug) print allpre >co
  146. }
  147. #
  148. /^[ \t]*[^;&]/ {
  149.    # Strip all comments, i.e. anything after ';' or '&' in a line
  150.    gsub( /[ \t]*[;&].*$/, "")
  151.    for (f = 1; f <= NF; ++f) {
  152.       split( $f, linefields, ",")
  153.       for (j in linefields) {
  154.          if ( linefields[j] ~ /\.[Oo][Bb][Jj]/ ) {
  155.             # Trim all white space from the field
  156.             gsub( /[ \t]/, "", linefields[j])
  157.             # Object file name has been extracted (into linefields[j])
  158.             fullobjname = linefields[j]
  159.             if (debug>1) print "NR " NR ", fullobjname = " fullobjname >co
  160.             # Add object file name to list of 'em
  161.             for (flix=1; flix in flist; flix++)
  162.                ;
  163.             flist[flix] = fullobjname
  164.             # Split object file name into Path, Name & Extension components
  165.             split_filename( linefields[j], objnameparts, fname_chars)
  166.             # Generate one batch file line
  167.             look_for_source_file( objnameparts["name"], fullobjname)
  168.          }
  169.          else if ( linefields[j] ~ /\.[Ll][Ii][Bb]/ ) {
  170.             gsub( /[ \t]/, "", linefields[j])
  171.             libname = linefields[j]
  172.             if (debug>1) print "NR " NR ", libname = " libname >co
  173.             for (flix=1; flix in flist; flix++)
  174.                ;
  175.             flist[flix] = libname
  176.          }
  177.       }
  178.    }
  179.  
  180. }
  181. /[Oo][Bb][Jj][Ee][Cc][Tt][ \t]*\(/ {
  182.    targetname = $0
  183.    sub( /^.*[Oo][Bb][Jj][Ee][Cc][Tt][ \t]*\([ \t]*/, "", targetname)
  184.    sub( /[ \t]*\).*$/, "", targetname)
  185.    if (debug>1) print "OBJECT() found: targetname = " targetname >co
  186. }
  187. /[Oo][Jj][ \t]*\(/ {
  188.    targetname = $0
  189.    sub( /^.*[Oo][Jj][ \t]*\([ \t]*/, "", targetname)
  190.    sub( /[ \t]*\).*$/, "", targetname)
  191.    if (debug>1) print "OJ() found: targetname = " targetname >co
  192. }
  193. #
  194. END {
  195.    print allpost
  196.    if (debug) print allpost >co
  197.  
  198.    # Generate executable-file dependency list (into outfile)
  199.    if (targetname=="") { # use irmx default
  200.       targetname==FILENAME
  201.       sub( /\.[Cc][Ff]/, exe_ext, targetname)
  202.    }
  203.    # Split primary link-configuration file name into Path, Name, and Extension
  204.    split_filename( targetname, exefile, fname_chars)
  205.    if (debug>1) 
  206.       printf( "exefile[\"path\"],[\"name\"],[\"ext\"]: \"%s\",\"%s\",\"%s\"",
  207.                exefile["path"], exefile["name"], exefile["ext"]             )>co
  208.    # Print primary (executable) file name before list (left of colon)
  209.    primarydependent = sprintf( "%s%s%s", exefile["path"],
  210.                                exefile["name"], exefile["ext"])
  211.    printf( "%s:", primarydependent) >outfile
  212.    if (debug) printf( "%s:", primarydependent) >co
  213.    linelen = length(primarydependent) + 1
  214.    for (i=1; i in flist; i++) {
  215.       # If line will be too long, put out a line-continuation char and newline
  216.       if (linelen + 1 + length(flist[i]) + length(linecont)  > 79) {
  217.          printf( "%s\n", linecont) >outfile
  218.          if (debug) printf( "%s\n", linecont) >co
  219.          # On the new line, tab out to underneath the first included file name
  220.          for (linelen=0; linelen<length(primarydependent)+1; ++linelen) {
  221.             printf(" ") >outfile
  222.             if (debug) printf(" ") >co
  223.          }
  224.       }
  225.       printf( " %s",  flist[i] ) >outfile
  226.       if (debug) printf( " %s",  flist[i] ) >co
  227.       linelen += length(flist[i]) + 1
  228.    }
  229.    # Build the link command line's only parameter: the filename
  230.    #  depending on options specified in lcf command-line param
  231.    link_comd_filename = sprintf( "%s%s%s",
  232.                                  lcf ~ /[Pp]/? exefile["path"] : "",
  233.                                  lcf ~ /[Nn]/? exefile["name"] : "",
  234.                                  lcf ~ /[Ee]/? exefile["ext"]  : "" );
  235.    printf( "\n\t%s %s\n\n", lc, link_comd_filename) >outfile
  236.    if (debug) printf( "\n\t%s %s\n\n", lc, link_comd_filename) >co
  237.  
  238. }
  239. #
  240. function look_for_source_file( name,    # File name: without path nor extension
  241.                                objname, # Object file's full name (for batch line)
  242.                                srcname, # Local var: complete source file name
  243.                                lang     # Local var: loop index
  244. )
  245. #  Looks for source file name, using dir path/extension for each language
  246. #  Generates a batch file dependency generator line for proper language
  247. #  if file name found; otherwise makes a __NOFILE__ line for language #1
  248. {
  249.    if (debug>2) 
  250.       print "look_for_source_file(name=" name ", objname=" objname ")" >co
  251.    for (lang in ext) { # For each language supported
  252.       # Build source file name
  253.       #  using this language's directory pathname and extension
  254.       srcname = path[lang] name ext[lang]
  255.       if (debug>2) 
  256.          print "look_for_source_file(), lang #" lang ": srcname = " srcname >co
  257.       # See if the file exists, by reading 1st line of it
  258.       # (getline returns -1 on error.. assume that means file not found)
  259.       if (getline <srcname != -1) { # caution.. getline fills $0, $1 ...
  260.          # File found.. Build the normal batch file line
  261.          printf( "%s %s %s ", comdpre, depgen[lang], srcname)
  262.          if (debug) printf( "%s %s %s ", comdpre, depgen[lang], srcname) >co
  263.          printf( "incpath=%s objname=%s ", ipath[lang], objname)
  264.          if (debug) printf( "incpath=%s objname=%s ", ipath[lang], objname) >co
  265.          printf( "cc=%s ccf=%s ", cc[lang], ccf[lang] )
  266.          if (debug) printf( "cc=%s ccf=%s ", cc[lang], ccf[lang] ) >co
  267.          printf( "%s %s %s\n", comdmid, outfile, comdpost)
  268.          if (debug) printf( "%s %s %s\n", comdmid, outfile, comdpost) >co
  269.          close( srcname)
  270.          return
  271.       }
  272.       else {
  273.          if (debug>2)
  274.             print "look_for_source_file(): " srcname " not found." >co
  275.          continue;
  276.       }
  277.    }
  278.    # File not found--all language extensions/paths tried
  279.    print comment "CF2MAK.AWK Warning: \"" name "\" source file not found."
  280.    print "CF2MAK.AWK Warning: \"" name "\" source file not found." > co
  281.    print comdpre " " depgen[1] " __NOFILE__ objname=" objname " cc= ccf= " comdmid outfile comdpost
  282.    if (debug) print comdpre " " depgen[1] " __NOFILE__ objname=" objname " cc= ccf= " comdmid outfile comdpost >co
  283.    close( srcname) # just in case it was opened
  284. }
  285. #
  286. function get_cl_param( parname,  # Which parameter ya lookin' fer? (e.g. "blah=")
  287.                        optional) # Is it an optional parameter?
  288. # Search the ARGV[] array for a command-line parameter beginning w/ parname
  289. # If optional is 0, aborts program if not found
  290. # Returns the string to the right of the '='
  291. {
  292.    for (i in ARGV)
  293.       if (match(ARGV[i],parname))
  294.          return substr(ARGV[i],length(parname)+1)
  295.  
  296.    if (optional)
  297.       return ""
  298.  
  299.    printf( "cf2mak.awk usage error:  Command-line parameter '%s' missing\n",
  300.            parname                                                         ) >co
  301.    exit 1  # Abort
  302. }
  303. #
  304. function split_filename( name,        # In: The full file name
  305.                          shards,      # Out:array which receives ["path"],
  306.                                       #     ["name"] and ["ext"] members
  307.                          fname_chars, # In: Regular expression which matches
  308.                                       #     any single file-name character.
  309.                                       #     (must exclude directory separator)
  310.                          # Local variables:
  311.                          pnsep,       # Path/Name separator (1st char of Name)
  312.                          nesep)       # Name/Extension separator (1st Ext char)
  313.  
  314. # Split a file name into three components: Path, Name, and Extension 
  315. {
  316.    pnsep = match( name, fname_chars"*$")
  317.    shards["path"] = substr( name, 1, pnsep-1)
  318.    nesep = match( name, "\\."fname_chars"*$")
  319.    if (debug>2)
  320.       print "in \"" name "\", name starts @ " pnsep ", ext @ " nesep >co
  321.    if (nesep==0) {
  322.       shards["name"] = substr( name, pnsep)
  323.       shards["ext"] = ""
  324.    }
  325.    else {
  326.       shards["name"] = substr( name, pnsep, nesep-pnsep)
  327.       shards["ext"] = substr( name, nesep)
  328.    }
  329. }
  330.  
  331.