sed/awk - generating Makefiles (Re: awk processing of Makefile macros)

sed/awk - generating Makefiles (Re: awk processing of Makefile macros)

Post by Greg Ear » Sat, 24 Apr 1993 11:39:28



The thread in the References: talks about using "awk" on Makefiles.

I have a similar question, but it's about generating contents of Makefiles:

A user I'm helping has a program on VMS that generates lines in the following
format:

$(VARIABLE)/FILENAME.EXT: FILENAME.EXT.ext%%sometext(FILENAME.EXT[,VARIABLE])

Where it says ".EXT.ext", I mean the 3 letter extension is followed by the
same 3 letters, in lower case (hey, I didn't write the thing that generates
this output (-: ).  Where it says "[,VARIABLE]" I mean that this part is
optional; i.e., a line could end " ... %%makeapp_r2(CFORM.COM)" whereas
another line could end with " ... %%makeapp(BADLABELS.COM,R2LIB)".

We want to convert the above input format into

$(VARIABLE)/filename: filename.ext
        sometext(filename[,VARIABLE])

A real example:

$(R2LIB)/CFORM.COM: CFORM.COM.com%%makeapp_r2(CFORM.COM)

becomes

$(R2LIB)/cform: cform.com
        makeapp_r2(cform)

and

$(R2LIB)/BADLABELS.COM: BADLABELS.COM.com%%makeapp(BADLABELS.COM,R2LIB)

becomes

$(R2LIB)/badlabels: badlabels.com
        makeapp(badlabels,R2LIB)

It's an interesting problem due to the use of both string manipulations and
things like lowercasing of whole string tokens, etc.

Currently, the user is using a horrendously ugly sed script to do this, with
horrible things like lower-casing everything first, making copies of the
pattern space, then deleting things selectively, etc.  The current script:

------------------------------------------------------------------------------
# This script takes a file containing dependencies generated by VAX CMS
# and massages it to look good for make.  The file is assumed to
# consist of lines of the form:
#
# $(VICCPU)/FILE.C.o: FILE.C.c%%macro(FILE.C)
# or
# $(R2LIB)/FILE.COM: FILE.COM.com%%macro(FILE.COM,R2LIB)
#
# where 'FILE' is a filename and 'macro' is the name of an Imake macro used
# to compile that file.  Capitalization is important, as every capital '.C'
# or '.COM' is stripped, but lowercase '.c's or '.com's are kept.  The
# filename is converted to lower case, and the '%%" is converted to a
# newline-tab combination.  The value in the "$()" at the beginning is
# kept in upper case, as is the value after the comma in the macro.
# The output will look like (without the '#' of course):
#
# $(VICCPU)/file.o: file.c
#       macro(file)
# or
# $(R2LIB)/file: file.com
#       macro(file,R2LIB)
#

# Delete any capital '.COM's
s/\.COM//g
# Delete any capital '.C's
s/\.C//g
# For lines beginning with $(STUFF) make everything else lowercase
/^\$([^)]*)/{
h;
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;
H;
x;
s/^\$(\([^)]*\))[^\n]*\n\$([^)]*)/\$(\1)/

Quote:}

# For lines not beginning with $(STUFF), make everything lowercase
/^\$([^)]*)/!y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
# For lines ending in ,stuff) make STUFF uppercase again
/,[^)]*)$/{
h;
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
H;
x;
s/,[^)]*)\n.*,\([^)]*\))$/,\1)/
Quote:}

# Replace '%%' with newline and tab
s/%%/\
        /
------------------------------------------------------------------------------

Yuck!  (-:

I said "This looks like a job for Perl" but he said - "Sorry, this is part of
a deliverable and we can't assume our customers have Perl".  I said, "OK, then
maybe awk + sed would work".  He said "Go for it" but I immediately got tripped
up by the case-changing parts (HP-UX "awk" has "toupper()" and "tolower()", but
SunOS "nawk" does not.  *sigh*).  We can't use special features of a particular
vendor's awk or sed, like the aforementioned HP-UX "awk" functions.

Any suggestions for doing this with "awk" + "sed" (and/or other standard UNIX
tools) in a better way than the above would be greatly appreciated!  (The
sed script invocation is being used as part of an Imake template.)

--
        - Greg Earle
          Phone: (818) 353-8695         FAX: (818) 353-1877


 
 
 

sed/awk - generating Makefiles (Re: awk processing of Makefile macros)

Post by Jim Dav » Mon, 26 Apr 1993 08:49:15



>A user I'm helping has a program on VMS that generates lines in the following
>format:

>$(VARIABLE)/FILENAME.EXT: FILENAME.EXT.ext%%sometext(FILENAME.EXT[,VARIABLE])

>We want to convert the above input format into

>$(VARIABLE)/filename: filename.ext
>    sometext(filename[,VARIABLE])

Here's an approach, using nawk under SunOS 4.1.1:

wolf; cat awk.script
#!/bin/nawk -f

BEGIN   { FS="%%"
          Upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
          Lower = "abcdefghijklmnopqrstuvwxyz" }

        { gsub(/\.COM/, "")
          gsub(/\.C/, "")
          match($1, "/.*$")
          $1 = substr($1, 1, RSTART) lower(substr($1, RSTART+1, RLENGTH-1))
          if (m = index($2, ","))
                $2 = lower(substr($2, 1, m-1)) substr($2, m)
          else
                $2 = lower($2)
          printf("%s\n\t%s\n", $1, $2)
        }

        function lower(s) {
                t = ""
                len = length(s)
                for (i = 1; i <= len; i++) {
                        c = substr(s, i, 1)
                        if ( p = index(Upper, c))
                                c = substr(Lower, p, 1)
                        t = t c
                }
                return t
        }

wolf; cat testdata
$(R2LIB)/CFORM.COM: CFORM.COM.com%%makeapp_r2(CFORM.COM)
$(R2LIB)/BADLABELS.COM: BADLABELS.COM.com%%makeapp(BADLABELS.COM,R2LIB)
$(VICCPU)/FILE.C.o: FILE.C.c%%macro(FILE.C)
$(R2LIB)/FILE.COM: FILE.COM.com%%macro(FILE.COM,R2LIB)

wolf; ./awk.script < testdata
$(R2LIB)/cform: cform.com
        makeapp_r2(cform)
$(R2LIB)/badlabels: badlabels.com
        makeapp(badlabels,R2LIB)
$(VICCPU)/file.o: file.c
        macro(file)
$(R2LIB)/file: file.com
        macro(file,R2LIB)
--
Jim Davis               | "I'll have access to firearms before you will."