C ALGORITHM 803, COLLECTED ALGORITHMS FROM ACM. C THIS WORK PUBLISHED IN TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOL. 26,NO. 2, June, 2000, P. 310--319. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # Awk/ # Awk/Sp/ # Awk/Sp/Drivers/ # Awk/Sp/Drivers/a.awk # Awk/Sp/Drivers/testdata.awk # Awk/Sp/Drivers/testdata.m5 # Awk/Sp/Drivers/testdata.out # Awk/Sp/Drivers/testincl.m5 # Awk/Sp/Src/ # Awk/Sp/Src/m5 # Awk/Sp/Src/m5.awk # Doc/ # Doc/README # Doc/m5.1 # Doc/manpage.ps # Doc/manpage.txt # This archive created: Mon Dec 4 12:31:28 2000 export PATH; PATH=/bin:$PATH if test ! -d 'Awk' then mkdir 'Awk' fi cd 'Awk' if test ! -d 'Sp' then mkdir 'Sp' fi cd 'Sp' if test ! -d 'Drivers' then mkdir 'Drivers' fi cd 'Drivers' if test -f 'a.awk' then echo shar: will not over-write existing file "'a.awk'" else cat << "SHAR_EOF" > 'a.awk' function main() { print print " Example 1: Simple Substitution" print " ------------------------------" br = "brown" print " The quick " br " fox." print print " Example 2: Substitution inside a String" print " ---------------------------------------" r = "row" print " The quick b" r "n fox." print print " Example 3: Expression Substitution" print " ----------------------------------" a = 4 b = 3 print " The quick " 2*a + b " foxes." print print " Example 4: Macros References inside a Macro" print " -------------------------------------------" M["fox"] = "$[q] $[b] $[f]" M["q"] = "quick" M["b"] = "brown" M["f"] = "fox" print " The " eval(M["fox"]) "." print print " Example 5: Array Reference Substitution" print " ---------------------------------------" x[7] = "brown" b = 3 print " The quick " x[2*b+1] " fox." print print " Example 6: Function Reference Substitution" print " ------------------------------------------" print " The quick " color(1,2) " fox." print print " Example 7: Substitution of Special Characters" print " ---------------------------------------------" print "\# The \$ quick \\ brown $# fox. $$" } function color(i,j) { print " The lazy dog." if (i == j) return "blue" else return "brown" } function eval(inp ,isplb,irb,out,name) { splb = SP "[" out = "" while( isplb = index(inp, splb) ) { irb = index(inp, "]") if ( irb == 0 ) { out = out substr(inp,1,isplb+1) inp = substr( inp, isplb+2 ) } else { name = substr( inp, isplb+2, irb-isplb-2 ) sub( /^ +/, "", name ) sub( / +$/, "", name ) out = out substr(inp,1,isplb-1) eval(M[name]) inp = substr( inp, irb+1 ) } } out = out inp return out } BEGIN { SP = "$" main() exit } SHAR_EOF fi # end of overwriting check if test -f 'testdata.awk' then echo shar: will not over-write existing file "'testdata.awk'" else cat << "SHAR_EOF" > 'testdata.awk' function main() { print print " Example 1: Simple Substitution" print " ------------------------------" br = "brown" print " The quick " br " fox." print print " Example 2: Substitution inside a String" print " ---------------------------------------" r = "row" print " The quick b" r "n fox." print print " Example 3: Expression Substitution" print " ----------------------------------" a = 4 b = 3 print " The quick " 2*a + b " foxes." print print " Example 4: Macros References inside a Macro" print " -------------------------------------------" M["fox"] = "$[q] $[b] $[f]" M["q"] = "quick" M["b"] = "brown" M["f"] = "fox" print " The " eval(M["fox"]) "." print print " Example 5: Array Reference Substitution" print " ---------------------------------------" x[7] = "brown" b = 3 print " The quick " x[2*b+1] " fox." print print " Example 6: Function Reference Substitution" print " ------------------------------------------" print " The quick " color(1,2) " fox." print print " Example 7: Substitution of Special Characters" print " ---------------------------------------------" print "\# The \$ quick \\ brown $# fox. $$" } function color(i,j) { print " The lazy dog." if (i == j) return "blue" else return "brown" } function eval(inp ,isplb,irb,out,name) { splb = SP "[" out = "" while( isplb = index(inp, splb) ) { irb = index(inp, "]") if ( irb == 0 ) { out = out substr(inp,1,isplb+1) inp = substr( inp, isplb+2 ) } else { name = substr( inp, isplb+2, irb-isplb-2 ) sub( /^ +/, "", name ) sub( / +$/, "", name ) out = out substr(inp,1,isplb-1) eval(M[name]) inp = substr( inp, irb+1 ) } } out = out inp return out } BEGIN { SP = "$" main() exit } SHAR_EOF fi # end of overwriting check if test -f 'testdata.m5' then echo shar: will not over-write existing file "'testdata.m5'" else cat << "SHAR_EOF" > 'testdata.m5' #function main() { Example 1: Simple Substitution ------------------------------ # br = "brown" The quick $br fox. Example 2: Substitution inside a String --------------------------------------- # r = "row" The quick b$(r)n fox. Example 3: Expression Substitution ---------------------------------- # a = 4 # b = 3 The quick $(2*a + b) foxes. Example 4: Macros References inside a Macro ------------------------------------------- # $[fox] = "\$[q] \$[b] \$[f]" # $[q] = "quick" # $[b] = "brown" # $[f] = "fox" The $[fox]. Example 5: Array Reference Substitution --------------------------------------- # x[7] = "brown" # b = 3 The quick $x[2*b+1] fox. Example 6: Function Reference Substitution ------------------------------------------ The quick $color(1,2) fox. Example 7: Substitution of Special Characters --------------------------------------------- \# The \$ quick \\ brown $# fox. $$ #} #include(testincl.m5) SHAR_EOF fi # end of overwriting check if test -f 'testdata.out' then echo shar: will not over-write existing file "'testdata.out'" else cat << "SHAR_EOF" > 'testdata.out' Example 1: Simple Substitution ------------------------------ The quick brown fox. Example 2: Substitution inside a String --------------------------------------- The quick brown fox. Example 3: Expression Substitution ---------------------------------- The quick 11 foxes. Example 4: Macros References inside a Macro ------------------------------------------- The quick brown fox. Example 5: Array Reference Substitution --------------------------------------- The quick brown fox. Example 6: Function Reference Substitution ------------------------------------------ The lazy dog. The quick brown fox. Example 7: Substitution of Special Characters --------------------------------------------- # The $ quick \ brown $# fox. $$ SHAR_EOF fi # end of overwriting check if test -f 'testincl.m5' then echo shar: will not over-write existing file "'testincl.m5'" else cat << "SHAR_EOF" > 'testincl.m5' #function color(i,j) { The lazy dog. # if (i == j) # return "blue" # else # return "brown" #} SHAR_EOF fi # end of overwriting check cd .. if test ! -d 'Src' then mkdir 'Src' fi cd 'Src' if test -f 'm5' then echo shar: will not over-write existing file "'m5'" else cat << "SHAR_EOF" > 'm5' #! /bin/sh #------------------------------------------------------------------------------- # # NAME # m5, m5.awk - macro processor # # SYNOPSIS # m5 [ -Dname ] [ -Dname=def ] [-c] [ -dp char ] [ -o file ] [ # -sp char ] [ file ... ] # # [g|n]awk -f m5.awk X [ -Dname ] [ -Dname=def ] [-c] [ -dp # char ] [ -o file ] [ -sp char ] [ file ... ] # # DESCRIPTION # m5 is a Bourne shell script for invoking m5.awk. m5.awk is # the m5 macro processor translator. Its input may be either # standard input or one or more files listed on the command # line after the optional arguments. An input line with the # directive prefix character (# by default) in column 1 is # termed a directive line (or just a directive); such a line # is treated as a statement in the macro processor language # (awk). Any other input line is termed a text line. Macros # are defined using awk assignment statements and their values # substituted using the substitution prefix character ($ by # default). The backslash (\) is the escape character; its # presence forces the next character to literally appear in # the output. This is most useful when forcing the appearance # of the directive prefix character, the substitution prefix # character, and the escape character itself. # # As noted in the synopsis above, its invocation may require # specification of awk, gawk, or nawk, depending on the ver- # sion of awk available on your system. This choice is # further complicated on some systems, e.g. Sun, which have # both awk (original awk) and nawk (new awk). Other systems # appear to have new awk, but have named it just awk. New awk # should be used, regardless of what it has been named. The # macro processor translator will not work using original awk # because the former, for example, uses the built-in function # match(). # # OPTIONS # The following options are supported: # # -Dname Following the cpp convention, define name as 1 # (one). This is the same as if a -Dname=1 # appeared as an option or #name=1 appeared as # an input line. Names specified using -D are # awk variables defined just before main is # invoked. # # -Dname=def Define name as "def". This is the same as if # #name="def" appeared as an input line. Names # specified using -D are awk variables defined # just before main is invoked. # # X Yes, that really is a capital "X". The ver- # sion of nawk on Sun Solaris 2.5.1 apparently # does its own argument processing before pass- # ing the arguments on to the awk program. In # this case, X (and all succeeding options) are # believed by nawk to be file names and are # passed on to the macro processor translator # (m5.awk) for its own argument processing). # Without the X, Sun nawk attempts to process # succeeding options (e.g., -Dname) as valid # nawk arguments or files, thus causing an # error. This may not be a problem for all # awks. # # -c Compile only. The output program is still # produced, but the final output is not. # # -dp char The directive prefix character (default is #). # # -o file The output program file (default is a.awk). # # -sp char The substitution prefix character (default is # $). # # USAGE # Macro Substitution # All input lines are scanned for macro references which are # indicated by the substitution prefix character ($ by # default). Assuming this default, macro references may be of # the form $var, $(var), $(expr), $[str], $var[expr], or # $func(args). These are replaced by an awk variable, awk # variable, awk expression, awk array reference to the special # array M[], regular awk array reference, or awk function # call, respectively. These are, in effect, macros. The # macro processor translator checks for proper nesting of # parentheses and double quotes when translating $(expr) and # $func(args) macros, and checks for proper nesting of square # brackets and double quotes when translating $[expr] and # $var[expr] macros. The substitution prefix character indi- # cates a a macro reference unless it is (1) escaped (e.g., # \$abc), (2) followed by a character other than A-Z, a-z, (, # or [ (e.g., $@), or (3) inside a macro reference (e.g., # $($abc); probably an error). Consequently, macro references # are significant even inside single or double quoted strings. # Some examples of macro substitution are given below. # # Macros Containing Macros # As already noted, a macro reference inside another macro # reference will not result in substitution and will probably # cause an awk execution-time error. Furthermore, a substitu- # tion prefix character in the substituted string is also gen- # erally not significant because the substitution prefix char- # acter is detected at translation time, and macro values are # assigned at run time. However, macro references of the form # $[expr] provide a simple nested referencing capability. For # example, if $[abc] is in a text line, or in a directive line # and not on the left hand side of an assignment statement, it # is replaced by eval(M["abc"]). When the output output pro- # gram is executed, the m5 runtime routine eval() substitutes # the string M["abc"] examining it for further macro refer- # ences of the form $[str] (where "str" denotes an arbitrary # string). If one is found, substitution and scanning proceed # recursively. Also note that function type macro references # may contain references to other functions, thus also provid- # ing a type of nested referencing. # # Directive Lines # Except for the include directive, when a directive line is # detected, the directive prefix is removed, the line is # scanned for macros, and then the line is copied to the out- # put program (as distinct from the final output). Any valid # awk construct, including the function statement, is allowed # in a directive line. # # Include Directive # A single non-awk directive has been provided: the include # directive. Assuming that "#" is the directive prefix, # #include(filename) directs the macro processor translator to # immediately read from the indicated file, processing lines # from it in the normal manner. Nested includes are allowed. # Include directives must appear on a line by themselves. # More elaborate types of file processing may be directly pro- # grammed using the macro processor language. # # Main Program and Functions # The macro processor translator builds the resulting awk pro- # gram in one of two ways, depending on the form of the first # input line. If that line begins with "function", it is # assumed that the user is providing one or more functions, # including the function "main" required by m5. If the first # line does not begin with "function", then the entire input # file is translated into awk statements which are placed # inside function main. If some input lines are inside func- # tions, and others are not, awk will will detect this and # complain. Generally, the macro processor by design has lit- # tle awareness of the syntax of directive lines (awk state- # ments). As a consequence, syntax errors in directive lines # are not detected until the output program is executed. # # Text Lines # When a text line is encountered, it is scanned for macros, # embedded in awk print statements, and copied to the output # program. For example, the input line # # The quick brown $fox jumped over the lazy $dog. # # is transformed into # # print "The quick brown " fox " jumped over the lazy " dog # "." # # Obviously the use of this technique relies completely on the # presence of the awk concatenation operator (1 or more # blanks). # # Output # Finally, unless the -c (compile only) option is specified, # the output program is executed to produce the final output # (directed by default to standard output). The version of # awk specified in ARGV[0] (the command name) is used to exe- # cute the program. If ARGV[0] is null, awk is used. # # EXAMPLE # Understanding this example requires recognition that macro # substitution is a two-step process: (i) the input text is # translated into an output awk program, and (ii) the awk pro- # gram is executed to produce the final output with the macro # substitutions actually accomplished. The examples below # illustrate this process. # and $ are assumed to be the # directive and substitution prefix characters. # # Input Text # #function main() { # # Example 1: Simple Substitution # ------------------------------ # # br = "brown" # The quick $br fox. # # Example 2: Substitution inside a String # --------------------------------------- # # r = "row" # The quick b$(r)n fox. # # Example 3: Expression Substitution # ---------------------------------- # # a = 4 # # b = 3 # The quick $(2*a + b) foxes. # # Example 4: Macros References inside a Macro # ------------------------------------------- # # $[fox] = "\$[q] \$[b] \$[f]" # # $[q] = "quick" # # $[b] = "brown" # # $[f] = "fox" # The $[fox]. # # Example 5: Array Reference Substitution # --------------------------------------- # # x[7] = "brown" # # b = 3 # The quick $x[2*b+1] fox. # # Example 6: Function Reference Substitution # ------------------------------------------ # The quick $color(1,2) fox. # # Example 7: Substitution of Special Characters # --------------------------------------------- # \# The \$ quick \\ brown $# fox. $$ # #} # #include(testincl.m5) # # Included File testincl.m5 # #function color(i,j) { # The lazy dog. # # if (i == j) # # return "blue" # # else # # return "brown" # #} # # Output Program # function main() { # print # print " Example 1: Simple Substitution" # print " ------------------------------" # br = "brown" # print " The quick " br " fox." # print # print " Example 2: Substitution inside a String" # print " ---------------------------------------" # r = "row" # print " The quick b" r "n fox." # print # print " Example 3: Expression Substitution" # print " ----------------------------------" # a = 4 # b = 3 # print " The quick " 2*a + b " foxes." # print # print " Example 4: Macros References inside a Macro" # print " -------------------------------------------" # M["fox"] = "$[q] $[b] $[f]" # M["q"] = "quick" # M["b"] = "brown" # M["f"] = "fox" # print " The " eval(M["fox"]) "." # print # print " Example 5: Array Reference Substitution" # print " ---------------------------------------" # x[7] = "brown" # b = 3 # print " The quick " x[2*b+1] " fox." # print # print " Example 6: Function Reference Substitution" # print " ------------------------------------------" # print " The quick " color(1,2) " fox." # print # print " Example 7: Substitution of Special Characters" # print " ---------------------------------------------" # print "\# The \$ quick \\ brown $# fox. $$" # } # function color(i,j) { # print " The lazy dog." # if (i == j) # return "blue" # else # return "brown" # } # # function eval(inp ,isplb,irb,out,name) { # # splb = SP "[" # out = "" # # while( isplb = index(inp, splb) ) { # irb = index(inp, "]") # if ( irb == 0 ) { # out = out substr(inp,1,isplb+1) # inp = substr( inp, isplb+2 ) # } else { # name = substr( inp, isplb+2, irb-isplb-2 ) # sub( /^ +/, "", name ) # sub( / +$/, "", name ) # out = out substr(inp,1,isplb-1) eval(M[name]) # inp = substr( inp, irb+1 ) # } # } # # out = out inp # # return out # } # BEGIN { # SP = "$" # main() # exit # } # # Final Output # # Example 1: Simple Substitution # ------------------------------ # The quick brown fox. # # Example 2: Substitution inside a String # --------------------------------------- # The quick brown fox. # # Example 3: Expression Substitution # ---------------------------------- # The quick 11 foxes. # # Example 4: Macros References inside a Macro # ------------------------------------------- # The quick brown fox. # # Example 5: Array Reference Substitution # --------------------------------------- # The quick brown fox. # # Example 6: Function Reference Substitution # ------------------------------------------ # The lazy dog. # The quick brown fox. # # Example 7: Substitution of Special Characters # --------------------------------------------- # # The $ quick \ brown $# fox. $$ # # FILE # a.awk default output program file # # SEE ALSO # awk(1), cpp(1), gawk(1), m4(1), nawk(1). vi(1) # # AUTHOR # William A. Ward, Jr., School of Computer and Information # Sciences, University of South Alabama, Mobile, Alabama, July # 23, 1999. # #------------------------------------------------------------------------------- #AWK=awk #AWK=gawk AWK=nawk $AWK -f $0.awk X $* SHAR_EOF fi # end of overwriting check if test -f 'm5.awk' then echo shar: will not over-write existing file "'m5.awk'" else cat << "SHAR_EOF" > 'm5.awk' #-------------------------------------------------------------------------------# # NAME # m5, m5.awk - macro processor # # SYNOPSIS # m5 [ -Dname ] [ -Dname=def ] [-c] [ -dp char ] [ -o file ] [ # -sp char ] [ file ... ] # # [g|n]awk -f m5.awk X [ -Dname ] [ -Dname=def ] [-c] [ -dp # char ] [ -o file ] [ -sp char ] [ file ... ] # # DESCRIPTION # m5 is a Bourne shell script for invoking m5.awk, which actu- # ally performs the macro processing. m5, unlike many # macroprocessors, does not directly interpret its input. # Instead it uses a two-pass approach in which the first pass # translates the input to an awk program, and the second pass # executes the awk program to produce the final output. # Details of usage are provided below. # # As noted in the synopsis above, its invocation may require # specification of awk, gawk, or nawk, depending on the ver- # sion of awk available on your system. This choice is # further complicated on some systems, e.g. Sun, which have # both awk (original awk) and nawk (new awk). Other systems # appear to have new awk, but have named it just awk. New awk # should be used, regardless of what it has been named. The # macro processor translator will not work using original awk # because the former, for example, uses the built-in function # match(). # # OPTIONS # The following options are supported: # # -Dname Following the cpp convention, define name as 1 # (one). This is the same as if a -Dname=1 # appeared as an option or #name=1 appeared as # an input line. Names specified using -D are # awk variables defined just before main is # invoked. # # -Dname=def Define name as "def". This is the same as if # #name="def" appeared as an input line. Names # specified using -D are awk variables defined # just before main is invoked. # # X Yes, that really is a capital "X". The ver- # sion of nawk on Sun Solaris 2.5.1 apparently # does its own argument processing before pass- # ing the arguments on to the awk program. In # this case, X (and all succeeding options) are # believed by nawk to be file names and are # passed on to the macro processor translator # (m5.awk) for its own argument processing). # Without the X, Sun nawk attempts to process # succeeding options (e.g., -Dname) as valid # nawk arguments or files, thus causing an # error. This may not be a problem for all # awks. # # -c Compile only. The output program is still # produced, but the final output is not. # # -dp char The directive prefix character (default is #). # # -o file The output program file (default is a.awk). # # -sp char The substitution prefix character (default is # $). # # USAGE # Overview # The program that performs the first pass noted above is # called the m5 translator and is named m5.awk. The input to # the translator may be either standard input or one or more # files listed on the command line. An input line with the # directive prefix character (# by default) in column 1 is # treated as a directive statement in the MP directive # language (awk). All other input lines are processed as text # lines. Simple macros are created using awk assignment # statements and their values referenced using the substitu- # tion prefix character ($ by default). The backslash (\) is # the escape character; its presence forces the next character # to literally appear in the output. This is most useful when # forcing the appearance of the directive prefix character, # the substitution prefix character, and the escape character # itself. # # Macro Substitution # All input lines are scanned for macro references that are # indicated by the substitution prefix character. Assuming # the default value of that character, macro references may be # of the form $var, $(var), $(expr), $[str], $var[expr], or # $func(args). These are replaced by an awk variable, awk # variable, awk expression, awk array reference to the special # array M[], regular awk array reference, or awk function # call, respectively. These are, in effect, macros. The MP # translator checks for proper nesting of parentheses and dou- # ble quotes when translating $(expr) and $func(args) macros, # and checks for proper nesting of square brackets and double # quotes when translating $[expr] and $var[expr] macros. The # substitution prefix character indicates a a macro reference # unless it is (i) escaped (e.g., \$abc), (ii) followed by a # character other than A-Z, a-z, (, or [ (e.g., $@), or (iii) # inside a macro reference (e.g., $($abc); probably an error). # # An understanding of the implementation of macro substitution # will help in its proper usage. When a text line is encoun- # tered, it is scanned for macros, embedded in an awk print # statement, and copied to the output program. For example, # the input line # # The quick $fox jumped over the lazy $dog. # # is transformed into # # print "The quick " fox " jumped over the lazy " dog "." # # Obviously the use of this transformation technique relies completely # on the presence of the awk concatenation operator (one or more blanks). # # Macros Containing Macros # As already noted, a macro reference inside another macro # reference will not result in substitution and will probably # cause an awk execution-time error. Furthermore, a # substitution prefix character in the substituted string is # also generally not significant because the substitution pre- # fix character is detected at translation time, and macro # values are assigned at execution time. However, macro # references of the form $[expr] provide a simple nested # referencing capability. For example, if $[abc] is in a text # line, or in a directive line and not on the left hand side # of an assignment statement, it is replaced by # eval(M["abc"])/. When the output program is executed, the # m5 runtime routine eval()/ substitutes the value of M["abc"] # examining it for further macro references of the form $[str] # (where "str" denotes an arbitrary string). If one is found, # substitution and scanning proceed recursively. Function # type macro references may result in references to other mac- # ros, thus providing an additional form of nested referenc- # ing. # # Directive Lines # Except for the include directive, when a directive line is # detected, the directive prefix is removed, the line is # scanned for macros, and then the line is copied to the out- # put program (as distinct from the final output). Any valid # awk construct, including the function statement, is allowed # in a directive line. Further information on writing awk # programs may be found in Aho, Kernighan, and Weinberger, # Dougherty and Robbins, and Robbins. # # Include Directive # A single non-awk directive has been provided: the include # directive. Assuming that # is the directive prefix, # #include(filename) directs the MP translator to immediately # read from the indicated file, processing lines from it in # the normal manner. This processing mode makes the include # directive the only type of directive to take effect at # translation time. Nested includes are allowed. Include # directives must appear on a line by themselves. More ela- # borate types of file processing may be directly programmed # using appropriate awk statements in the input file. # # Main Program and Functions # The MP translator builds the resulting awk program in one of # two ways, depending on the form of the first input line. If # that line begins with "function", it is assumed that the # user is providing one or more functions, including the func- # tion "main" required by m5. If the first line does not # begin with "function", then the entire input file is # translated into awk statements that are placed inside # "main". If some input lines are inside functions, and oth- # ers are not, awk will will detect this and complain. The MP # by design has little awareness of the syntax of directive # lines (awk statements), and as a consequence syntax errors # in directive lines are not detected until the output program # is executed. # # Output # Finally, unless the -c (compile only) option is specified on # the command line, the output program is executed to produce # the final output (directed by default to standard output). # The version of awk specified in ARGV[0] (a built-in awk # variable containing the command name) is used to execute the # program. If ARGV[0] is null, awk is used. # # EXAMPLE # Understanding this example requires recognition that macro # substitution is a two-step process: (i) the input text is # translated into an output awk program, and (ii) the awk # program is executed to produce the final output with the # macro substitutions actually accomplished. The examples # below illustrate this process. # and $ are assumed to be # the directive and substitution prefix characters. This # example was successfully executed using awk on a Cray C90 # running UNICOS 10.0.0.3, gawk on a Gateway E-3200 runing # SuSE Linux Version 6.0, and nawk on a Sun Ultra 2 Model 2200 # running Solaris 2.5.1. # # Input Text # #function main() { # # Example 1: Simple Substitution # ------------------------------ # # br = "brown" # The quick $br fox. # # Example 2: Substitution inside a String # --------------------------------------- # # r = "row" # The quick b$(r)n fox. # # Example 3: Expression Substitution # ---------------------------------- # # a = 4 # # b = 3 # The quick $(2*a + b) foxes. # # Example 4: Macros References inside a Macro # ------------------------------------------- # # $[fox] = "\$[q] \$[b] \$[f]" # # $[q] = "quick" # # $[b] = "brown" # # $[f] = "fox" # The $[fox]. # # Example 5: Array Reference Substitution # --------------------------------------- # # x[7] = "brown" # # b = 3 # The quick $x[2*b+1] fox. # # Example 6: Function Reference Substitution # ------------------------------------------ # The quick $color(1,2) fox. # # Example 7: Substitution of Special Characters # --------------------------------------------- # \# The \$ quick \\ brown $# fox. $$ # #} # #include(testincl.m5) # # Included File testincl.m5 # #function color(i,j) { # The lazy dog. # # if (i == j) # # return "blue" # # else # # return "brown" # #} # # Output Program # function main() { # print # print " Example 1: Simple Substitution" # print " ------------------------------" # br = "brown" # print " The quick " br " fox." # print # print " Example 2: Substitution inside a String" # print " ---------------------------------------" # r = "row" # print " The quick b" r "n fox." # print # print " Example 3: Expression Substitution" # print " ----------------------------------" # a = 4 # b = 3 # print " The quick " 2*a + b " foxes." # print # print " Example 4: Macros References inside a Macro" # print " -------------------------------------------" # M["fox"] = "$[q] $[b] $[f]" # M["q"] = "quick" # M["b"] = "brown" # M["f"] = "fox" # print " The " eval(M["fox"]) "." # print # print " Example 5: Array Reference Substitution" # print " ---------------------------------------" # x[7] = "brown" # b = 3 # print " The quick " x[2*b+1] " fox." # print # print " Example 6: Function Reference Substitution" # print " ------------------------------------------" # print " The quick " color(1,2) " fox." # print # print " Example 7: Substitution of Special Characters" # print " ---------------------------------------------" # print "\# The \$ quick \\ brown $# fox. $$" # } # function color(i,j) { # print " The lazy dog." # if (i == j) # return "blue" # else # return "brown" # } # # function eval(inp ,isplb,irb,out,name) { # # splb = SP "[" # out = "" # # while( isplb = index(inp, splb) ) { # irb = index(inp, "]") # if ( irb == 0 ) { # out = out substr(inp,1,isplb+1) # inp = substr( inp, isplb+2 ) # } else { # name = substr( inp, isplb+2, irb-isplb-2 ) # sub( /^ +/, "", name ) # sub( / +$/, "", name ) # out = out substr(inp,1,isplb-1) eval(M[name]) # inp = substr( inp, irb+1 ) # } # } # # out = out inp # # return out # } # BEGIN { # SP = "$" # main() # exit # } # # Final Output # # Example 1: Simple Substitution # ------------------------------ # The quick brown fox. # # Example 2: Substitution inside a String # --------------------------------------- # The quick brown fox. # # Example 3: Expression Substitution # ---------------------------------- # The quick 11 foxes. # # Example 4: Macros References inside a Macro # ------------------------------------------- # The quick brown fox. # # Example 5: Array Reference Substitution # --------------------------------------- # The quick brown fox. # # Example 6: Function Reference Substitution # ------------------------------------------ # The lazy dog. # The quick brown fox. # # Example 7: Substitution of Special Characters # --------------------------------------------- # # The $ quick \ brown $# fox. $$ # # FILE # a.awk default output program file # # SEE ALSO # awk(1), cpp(1), gawk(1), m4(1), nawk(1). vi(1) # # AUTHOR # William A. Ward, Jr., School of Computer and Information # Sciences, University of South Alabama, Mobile, Alabama, July # 23, 1999. # #------------------------------------------------------------------------------- #-------------------------------------------------------------------------------# # GLOBAL NAMES # # Awk Variable Handling # Awk's approach to handling variables is simple. If a formal parameter # appears in the parameter list of an awk function, then it is a local # variable in that function; it is allocated on entry to the function # and deallocated on exit. It may be used even if (especially if) there # is no corresponding actual argument in the function invocation. All # other awk variables are global. In particular, a variable must be # global for its value to persist across function calls. Furthermore, # there is no such thing as a named constant, only global (persistent) # variables that have their value set and are never changed. # # Naming Convention # The convention adopted here to distinguish between variable types is # to name global variables and constants in all upper case characters # and to name local variables in all lower case characters. This is # consistent with awk's own convention for built-in variables. # # Global Constants (Name, Value, Description) # FALSE 0 Mnemonic for false # FS "\n" Awk field separator is newline (awk builtin) # TRUE 1 Mnemonic for true # # Global Variables # ARGC Number of command line arguments in ARGV[] (awk builtin) # ARGV[] Array containing command line arguments (awk builtin) # C Boolean flag for compile-only # DP Directive prefix character # IMPLICIT_MAIN True if main program is implicit # ND Number of -D type arguments # O Name of executable output file # SP Substitution prefix character # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # # FUNCTION # m5_begin() # # DESCRIPTION # m5_begin performs all initialization that must take place before the # first input line is read. This includes (1) defining global constants, # (2) initializing global variables, and (3) processing command line # arguments in the argument array ARGV. Arguments that begin with the # dash (-) are treated as options while the remaining arguments are # assumed to be file names and are moved to the beginning of the argument # list array ARGV for processing by the program. The valid arguments # are noted at the beginning of this file. # # ARGUMENTS # None. # # LOCAL VARIABLES # argc - Number of original command line arguments. # # i - Argument counter # #------------------------------------------------------------------------------- function m5_begin( argc,i) { # Define global constants FALSE = 0 # Mnemonic for false TRUE = 1 # Mnemonic for true FS = "\n" # awk field separator is newline # Set global variables NEED_EVAL = FALSE # Set default values for global variables which may be reset by arguments DP = "#" # Default directive prefix C = FALSE # Default for compile-only SP = "$" # Default substitution prefix ND = 0 # Default number of -D arguments O = "a.awk" # Default executable output file # Process the arguments in the array ARGV if ( ARGV[0] == "" ) # If command name is undefined ARGV[0] = "awk" # ...Use "awk" argc = ARGC # Save original value of ARGC ARGC = 1 # Reset to count file names for ( i=1; i DP = ARGV[++i] # ...Save dir prefix char else if ( ARGV[i] == "-c" ) # ...Else if arg is -c C = TRUE # ...Set compile-only to true else if ( ARGV[i] == "-sp" ) # ...Else if arg is -sp SP = ARGV[++i] # ...Save sub prefix char else if ( ARGV[i] == "-o" ) # ...Else if arg is -o O = ARGV[++i] # ...Save name of exec file else if ( substr(ARGV[i],1,1) == "-" \ && length(ARGV[i]) > 1 ) # ...Else if invalid option m5_prerr( "m5: Invalid argument " ARGV[i]) else if ( i>1 || ARGV[i] != "X" ) # ...Else found a file name ARGV[ARGC++] = ARGV[i] # ...Put file name back in # argument list } # End function m5_begin #------------------------------------------------------------------------------- # # FUNCTION # m5_dashd(d) # # DESCRIPTION # m5_dashd processes "-D" (dashd) arguments from the command line # previously saved in the global array D. This processing simply # requires writing an assignment statement (one per argument) in # the awk BEGIN section just before the call to main. # # ARGUMENTS # d - A string containing the macro definition, it must be of # the form or =. If only the name is # specified, the value is assumed to be 1 (one). Other # forms are treated as errors. Macro definitions with # embedded blanks are not allowed. # #------------------------------------------------------------------------------- function m5_dashd(d) { if ( ! match(d, /^[A-Za-z][A-Za-z0-9_]*/) ) # If invalid name m5_prerr("m5: Invalid argument -D " d) # ...Display error message else if ( length(d) == RLENGTH ) # Else if -Dname print " " substr(d,1,RLENGTH) \ " = 1" > O # ...Set name = 1 ala cpp else if ( substr(d,RLENGTH+1,1) != "=" ) # Else if next char not equal m5_prerr("m5: Invalid argument -D " d) # ...Display error message else # Else if -Dname=value print " " substr(d,1,RLENGTH) \ " = \"" substr(d,RLENGTH+2) "\"" > O # ...Set name = value } # End function m5_dashd #------------------------------------------------------------------------------- # # FUNCTION # m5_end() # # DESCRIPTION # m5_end performs wrap-up processing after the last input line is read. # First, if the last input line was still inside the function main, it # closes main with a "}". Next, if the program should be executed, the # run-time system system and the awk BEGIN section are added to the output # program, and the program is executed using the awk processor specified # in ARGV[0] (see m5_begin). # # ARGUMENTS # None. # #------------------------------------------------------------------------------- function m5_end() { # If still inside main, close main with "}" m5_output(TRUE) # If the program should be executed (not compile-only), add the run-time # system and the awk BEGIN section to the output program, and then execute # the program. if ( ! C ) { # If not compile-only if ( NEED_EVAL ) m5_preval() # ...Print run-time function print "BEGIN {" > O # ...Print start of BEGIN sect print " SP = \"" SP "\"" > O # ...Print def of SP for ( i=1; i<=ND; i++) # ...For each cmd line def m5_dashd(D[i]) # ...Print cmd line def print " main()" > O # ...Print call to main print " exit" > O # ...Print exit print "}" > O # ...Print end of BEGIN sect system( ARGV[0] " -f " O ) # ...Execute the awk program } # End if not compile-only } # End function m5_end #------------------------------------------------------------------------------- # # FUNCTION # m5_findparen(s,rparen) # # DESCRIPTION # m5_findparen finds the end of a substring in argument "s" containing # balanced parentheses and returns the position relative to the start of # the string s where this is the case. The left and right parenthesis # characters are selectable (see below). Parentheses inside quoted strings # ("...") are ignored for the purpose of determining balance. Escaped # quotes inside quoted strings are allowed. Macro references which span # lines are not allowed. # # ARGUMENTS # s - A string containing the parenthesized portion of a macro # invocation; if the $(ABC + DEF) is the invocation, then s # contains (ABC + DEF). This function should only be invoked # when s begins with the left (open) parenthesis character as # specified by argument lparen. # # rparen - The right parenthesis character. # # LOCAL VARIABLES # ccur - The current character extracted from s. # # i - Position of the current character in s. # # escaped - True if the previous character was the escape character. # # lparen - The left parenthesis character. # # nest - The current nest depth. # # quote - True if inside a quoted string, false otherwise. # #------------------------------------------------------------------------------- function m5_findparen(s,rparen ,ccur,escaped,i,lparen,nest,quoted) { # Initialize variables for processing the parenthesized string escaped = FALSE # Turn escape flag off i = 1 # Init char position in string lparen = substr(s,1,1) # Fetch left paren from string nest = 1 # Init paren nest depth quoted = FALSE # Init quoted flag to off # Examine successive characters in sting s until the parenthesized nest # depth becomes zero (normal termination) or end-of-string is encountered # (an error condition) do { # Do i = i + 1 # ...Move to next char position ccur = substr(s,i,1) # ...Get next character if ( escaped ) # ...If escape flag is on escaped = FALSE # ...Skip this char else if ( ccur == "\\" ) # ...Else if char is escape escaped = TRUE # ...Turn escape flag on else if ( ccur == "\"" ) # ...Else if quote quoted = ! quoted # ...Flip quote indicator else if ( ccur == lparen ) # ...Else if a left paren. nest = nest + (! quoted) # ... increment nest depth else if ( ccur == rparen ) # ...Else if a right paren, nest = nest - (! quoted) # ... decrement nest depth } while( (ccur != "") && (nest > 0) ) # While not end & still nested # Check for error conditions if ( quoted ) # If quotes not closed m5_prerr("m5: Double quotes not closed in macro call $" s) else if ( nest > 0 ) # Else if still nested m5_prerr("m5: Unbalanced " lparen rparen "in macro call " SP s) return i # Return position of right paren } # End function m5_findparen #------------------------------------------------------------------------------- # # FUNCTION # m5_include(inp) # # DESCRIPTION # m5_include is called by m5_main to check for the presence of an # include directive. If one is found, it is processed by extracting # the file name from the directive and then reading further input lines # from that file. After each line is read, m5_main is recursively # called to process the line. # # ARGUMENTS # inp - The current input line. # # LOCAL VARIABLES # file - The name of the file to be included. # # include - True if the input is an include directive, false otherwise. # #------------------------------------------------------------------------------- function m5_include(inp ,file,include) { # Try to match input to " include ( " include = match( inp, /^[ \t]*include[ \t]*\([ \t]*/ ) # If this is an include, process it by recursively calling m5_main if ( include ) { # If this is an include, inp = substr( inp, RLENGTH+1 ) # ...Strip off "include ( " match( inp, /^[^) \t]+/ ) # ...Locate right paren if ( RSTART = 0 ) # ...If no right paren, error m5_prerr("m5: Badly formed include statement") file = substr( inp, 1, RLENGTH ) # ...Extract file name while( (getline < file) > 0 ) # ...While not eof on file, m5_main($0) # ...Recursively process } # End if include return include # Return include flag } # End function m5_include #------------------------------------------------------------------------------- # # FUNCTION # m5_macro(isdir) # # DESCRIPTION # m5_macro processes a macro in the current input line. The remaining # trailing portion of the input line Ris in the global variable INP. # The substitution prefix character has already been removed, so the # start of the macro reference text is the first character in INP. # The text to be copied to the output buffer is the returned value # of the function. # # ARGUMENTS # isdir - True (1) if this is a directive line, false (0) otherwise. # # LOCAL VARIABLES # c - Current input char. # # iend - Character position of the end of the macro reference. # # macro - Contains the current macro reference with the substitution # prefix character removed. # #------------------------------------------------------------------------------- function m5_macro(isdir ,c,iend,macro) { # Get first character c = substr( INP, 1, 1 ) # Get first character # Is this $(...) ? if ( c == "(" ) { # If mac ref is $(...) iend = m5_findparen(INP,")") # ...Find closing ) macro = substr( INP, 2, iend-2 ) # ...Extract macro # Is this $[...] ? } else if ( c == "[" ) { # Else if mac ref is $[...] iend = m5_findparen(INP,"]") # ...Find closing ] macro = substr( INP, 2, iend-2 ) # ...Extract macro sub( /^ +/, "", macro ) # ...Remove leading white space sub( / +$/, "", macro ) # ...Remove trailing white space if ( isdir && match( substr(INP,iend+1), \ /[ \t]*=[^=]/ ) ) # ...If lhs of assignment stmt macro = "M[\"" macro "\"]" # ...Put M[macro] else { # ...Else macro = "eval(M[\"" macro "\"])" # ...Put eval(M[macro]) NEED_EVAL = TRUE # ...Will need runtime eval } # ...End if # Is this $name, $name(...), or $name[...] ? } else if ( c ~ /^[A-Za-z]/ ) { # Else if mac ref is $name... match( INP, /^[A-Za-z0-9_]+/ ) # ...Find end of name c = substr( INP, RLENGTH+1, 1 ) # ...Get 1st char after name if ( c == "(" ) # ...If function reference iend = RLENGTH + m5_findparen( \ substr(INP,RLENGTH+1),")") # ...Find closing ) else if ( c == "[" ) # ...If array reference iend = RLENGTH + m5_findparen( \ substr(INP,RLENGTH+1),"]") # ...Find closing ] else # ...Else iend = RLENGTH # ...Simple name macro = substr( INP, 1, iend ) # ...Extract macro # This is not a macro reference. } else { # Else this is not a mac ref iend = 0 # ...So not to advance INP macro = "" # ...Macro is null } # End if # Adjust input string and return macro string INP = substr( INP, iend+1 ) # Advance input past mac ref return macro # Return macro to put in output } # End function m5_macro #------------------------------------------------------------------------------- # # FUNCTION # m5_main(inp) # # DESCRIPTION # To be supplied. # # ARGUMENTS # inp - On entry, the current input line. inp is scanned for # macros, and the macro-free prefix is appended to "out" # (see below). When inp becomes null, scanning is terminated # and out is printed to the output program. # # LOCAL VARIABLES # buf - Macro-free text from inp accumulates in buf. When a # macro is encountered, buf is copied to out, and buf # set to null. # # c - Current input char. # # e - If a text line, then the escape char, else null. # # isdir - True (1) if this is a directive line, false (0) otherwise. # # out - Text and macro references are copied to out from inp # as inp is scanned; out is the final printed output. # For text lines, out begins with " print". # # macro - Contains the current macro reference with the substitution # prefix character removed. # # q - If a text line, then the double quote char, else null. # # s - If a text line, then the space char, else null. # #------------------------------------------------------------------------------- function m5_main(inp ,buf,c,e,isdir,macro,out,q,s) { # Determine input line type (directive or text) and initialization INP = inp # Move inp to INP (global) isdir = ( substr(INP,1,1) == DP ) # Get input line type escaped = FALSE # No escape prior to loop quoted = FALSE # No escape prior to loop # If this is a directive line if ( isdir ) { # If this is a directive line INP = substr( INP, 2 ) # ...Remove directive prefix if ( m5_include(INP) ) # ...If an include, process & return # ...Return if ( substr(INP,2,1) == " " ) # ...If 2nd char is space, buf = " " # ...Indent else # ...Else buf = "" # ...No indent out = "" # ...Awk command from input e = "" # ...Escape char not needed q = "" # ...Quote char not needed s = "" # ...Space char not needed # Else this is a text line } else { # Else this is a text line. buf = "" # ...Empty buffer out = " print" # ...Awk command is "print" e = "\\" # ...Escape char is needed q = "\"" # ...Quote char is needed s = " " # ...Space char is needed } # End if # Loop to scan input line and process macro references. while ( (c = substr(INP,1,1)) != "" ) { # While not end-of-string INP = substr( INP, 2 ) # ...Remove 1st char if ( escaped ) { # ...If this char is escaped escaped = FALSE # ...Escape only one char buf = buf c # ...Copy current char } else if ( c == "\\" ) { # ...Else if escape char escaped = TRUE # ...Turn on escape mode buf = buf e # ...Copy escape char } else if ( c == "\"" ) { # ...Else if quote char quoted = ! quoted # ...Flip quote mode buf = buf e c # ...Copy escaped quote } else if ( c != SP ) { # ...Else if not sub prefix buf = buf c # ...Copy current char } else { # ...Else this is a macro ref macro = m5_macro(isdir) # ...Translate mac ref if ( macro == "" ) # ...If not really a macro buf = buf c # ...Copy sub prefix else { # ...Else if ( buf != "" ) { # ...Buffer not empty? out = out s q buf q # ...Copy buf to out buf = "" # ...Reset buf } # ...End if if ( isdir && quoted ) # ...Mac in quote in dir? out = out "\" " macro " \"" # ...Mac not quoted else # ...Else out = out s macro # ...Copy mac to out } # ...End if } # ...End if } # End while # Wrap-up processing if ( buf != "" ) # If buffer not empty out = out s q buf q # ...Copy buffer to output m5_output(FALSE,out) # Print output } # End function m5_main #------------------------------------------------------------------------------- # # FUNCTION # m5_output() # # DESCRIPTION # m5_output performs all output except error messages. It also # distinguishes between the situation where function main is or is not # user-provided. A very simple test is used to do this: if the first word # on the line is "function", then it is assumed that the user has written # their own function main, and no special action is taken. Otherwise, the # main function header and trailer are automatically inserted. # # ARGUMENTS # eof - True if this is end of file. # # line - The line to be printed. # #------------------------------------------------------------------------------- function m5_output(eof,line) { NRO = NRO + 1 # Number of output records if ( NRO == 1 ) { # If first line IMPLICIT_MAIN = \ ! match(line, /^[ \t]*function[ \t]/) # ...True if 1st word not func if ( IMPLICIT_MAIN ) # ...If main is implied print "function main() {" > O # ...Main function header } # End if if ( eof && IMPLICIT_MAIN) # If eof and main is implied print "}" > O # ...Main function trailer else # Else print line > O # ...Print normal output line } # End function m5_output #------------------------------------------------------------------------------- # # FUNCTION # m5_prerr(message) # # DESCRIPTION # Handle fatal errors by printing the argument string "message" on # standard error and exiting with error code 1. # # ARGUMENTS # message - Error message. # #------------------------------------------------------------------------------- function m5_prerr(message) { print message | "cat >&2" # Error message to std error. error = 1 # Set error condition. exit # Terminate execution. } # End function m5_prerr #------------------------------------------------------------------------------- # # FUNCTION NAME # m5_preval() # # DESCRIPTION # m5_preval adds the m5 runtime system to the output file. Currently # this consists of a single function "eval" which is used to dynamically # evaluate macros of the form $[name] (where "$" is the substitution # prefix character). eval is basically a scaled down version of m5_main. # Whereas m5_main replaces macro references with awk variable names at # translation time, eval performs true dynamic macro substitution at # execution time. # # Why not make this a separate file? Well, having the entire macro # processor in a single file has its advantages. If the runtime system # were in a separate file, this program would have to be aware of the # file name of the separate file, and this could adversely affect the # portability and ease of installation of m5. # # ARGUMENTS # None. # #------------------------------------------------------------------------------- function m5_preval() { print "function eval(inp ,isplb,irb,out,name) {" > O print "" > O print " splb = SP \"[\"" > O print " out = \"\"" > O print "" > O print " while( isplb = index(inp, splb) ) {" > O print " irb = index(inp, \"]\")" > O print " if ( irb == 0 ) {" > O print " out = out substr(inp,1,isplb+1)" > O print " inp = substr( inp, isplb+2 )" > O print " } else {" > O print " name = substr( inp, isplb+2, irb-isplb-2 )" > O print " sub( /^ +/, \"\", name )" > O print " sub( / +$/, \"\", name )" > O print " out = out substr(inp,1,isplb-1) eval(M[name])" > O print " inp = substr( inp, irb+1 )" > O print " }" > O print " }" > O print "" > O print " out = out inp" > O print "" > O print " return out" > O print "}" > O } # End function m5_preval #------------------------------------------------------------------------------- # # FUNCTION # BEGIN, awk main, and END # # DESCRIPTION # Top level procedure invocations. # # ARGUMENTS # None. # #------------------------------------------------------------------------------- BEGIN { # Initialization... m5_begin() # ...prior to reading any input } # End BEGIN { # Process each line... m5_main($0) # ...to create output program } # End awk main loop END { # Wrap-up processing... m5_end() # ...after all lines read } # End END SHAR_EOF fi # end of overwriting check cd .. cd .. cd .. if test ! -d 'Doc' then mkdir 'Doc' fi cd 'Doc' if test -f 'README' then echo shar: will not over-write existing file "'README'" else cat << "SHAR_EOF" > 'README' INSTALLATION NOTES FOR m5, A MACRO PROCESSOR CONTENTS OF DISTRIBUTION a. README (this file) b. m5, a Bourne shell script wrapper for conveniently executing m5.awk. c. m5.1, a man page for m5 in standard input format. d. m5.awk, the awk source program for the macro processor translator. e. manpage.ps, a PostScript version of m5.1 (processed by troff). f. manpage.txt, a text version of m5.1 (processed by nroff). g. testdata.m5, a file of test data for the program. h. testincl.m5, a second data file included by testdata.m5. i. testdata.awk, the awk program produced by m5 when run on testdata.m5. j. testdata.out, the output produced by m5 when run on testdata.m5. INSTALLATION To install m5, do the following (examples use csh). NOTE: If you want to install into a system directory you will need to login as "root" or get your system administrator to do this. a. Copy m5 into the appropriate system bin directory; e.g., % cp m5 m5.awk /usr/local/bin or into your local bin directory; e.g., % cp m5 m5.awk /home/smith/bin b. Make sure this bin directory is on your executable path; e.g., % echo $PATH c. Make sure m5 is executable; e.g., % chmod a+x m5 d. Determine what new awk is called on your system (awk, gawk, nawk,...); you may need help from your system administrator on this, or you may be able to type the awk command and see if you get a positive response; e.g., % nawk e. Edit the file m5 so that the shell variable AWK is assigned the name you determined in part d.; e.g., % vi m5 f. If all is well, you should be able to try any of the following % m5 testdata.m5 > out % m5 < testdata.m5 > out % cat testdata.m5 | m5 > out g. After executing (one of) the above, files testdata.awk and a.awk should be the same, and files testdata.out and out should be the same. % diff testdata.awk a.awk % diff testdata.out out PLATFORMS TESTED a. Hardware: Cray C90 Model C94AXX, dual 240 MHz Cray CPUs OS: UNICOS 10.0.0.3 Awk: awk and nawk (they appear to be identical) b. Hardware: Gateway E-3200, single 350 MHz Intel Pentium CPU OS: SuSE Linux Version 6.0 Awk: gawk c. Hardware: Sun Ultra 2 Model 2200, dual 200 MHz Sun UltraSPARC CPUs OS: SunOS 4.4.1 (Solaris 2.5.1) Awk: nawk SHAR_EOF fi # end of overwriting check if test -f 'm5.1' then echo shar: will not over-write existing file "'m5.1'" else cat << "SHAR_EOF" > 'm5.1' .de [ .ig ] .. .if n .rm }F }H .TH m5 1 "01 Aug 1999" .SH NAME m5, m5.awk \- macro processor .SH SYNOPSIS .B m5 [ .BI \-D name ] [ .BI \-D name = def ] .RB [ \-c ] [ .BI \-dp " char" ] [ .BI \-o " file" ] [ .BI \-sp " char" ] [ .I file ".\|.\|." ] .LP [\c .B g|n\c ]\c .B awk .B \-f .B m5.awk .B X [ .BI \-D name ] [ .BI \-D name = def ] .RB [ \-c ] [ .BI \-dp " char" ] [ .BI \-o " file" ] [ .BI \-sp " char" ] [ .I file ".\|.\|." ] .SH DESCRIPTION .IX "m5" "" "\fLm5\fP \(em macro processor" .IX "macro processor" "m5 command" "" "\(em \fLm5\fP" .LP \f3m5\fP is a Bourne shell script for invoking \f3m5.awk\fP, which actually performs the macro processing. \f3m5\fP, unlike many macroprocessors, does not directly interpret its input. Instead it uses a two-pass approach in which the first pass translates the input to an awk program, and the second pass executes the awk program to produce the final output. Details of usage are provided below. .LP As noted in the synopsis above, its invocation may require specification of \f3awk\fP, \f3gawk\fP, or \f3nawk\fP, depending on the version of \f3awk\fP available on your system. This choice is further complicated on some systems, e.g. Sun, which have both \f3awk\fP (original awk) and \f3nawk\fP (new awk). Other systems appear to have new awk, but have named it just \f3awk\fP. New awk should be used, regardless of what it has been named. The macro processor translator will not work using original awk because the former, for example, uses the built-in function match(). .SH OPTIONS The following options are supported: .TP 14 \f3-D\f2name\fP Following the \f3cpp\fP convention, define name as 1 (one). This is the same as if a -Dname=1 appeared as an option or #name=1 appeared as an input line. Names specified using -D are awk variables defined just before main is invoked. .TP \f3-D\f2name=def\fP Define name as "def". This is the same as if #name="def" appeared as an input line. Names specified using -D are awk variables defined just before main is invoked. .TP \f3X\fP Yes, that really is a capital "X". The version of \f3nawk\fP on Sun Solaris 2.5.1 apparently does its own argument processing before passing the arguments on to the awk program. In this case, X (and all succeeding options) are believed by \f3nawk\fP to be file names and are passed on to the macro processor translator (\f3m5.awk\fP) for its own argument processing). Without the X, Sun \f3nawk\fP attempts to process succeeding options (e.g., -Dname) as valid \f3nawk\fP arguments or files, thus causing an error. This may not be a problem for all \f3awk\fPs. .TP \f3-c\fP Compile only. The output program is still produced, but the final output is not. .TP \f3-dp\f2 char\fP The directive prefix character (default is #). .TP \f3-o\f2 file\fP The output program file (default is a.awk). .TP \f3-sp\f2 char\fP The substitution prefix character (default is $). .so 77_usage.t .so 77_example.t .SH FILE .PD 0 .TP 14 .B a.awk default output program file .PD .SH SEE ALSO .BR awk (1), .BR cpp (1), .BR gawk (1), .BR m4 (1), .BR nawk (1). .BR vi (1) .SH AUTHOR William A. Ward, Jr., School of Computer and Information Sciences, University of South Alabama, Mobile, Alabama, July 23, 1999. SHAR_EOF fi # end of overwriting check if test -f 'manpage.ps' then echo shar: will not over-write existing file "'manpage.ps'" else cat << "SHAR_EOF" > 'manpage.ps' %! %%BoundingBox: 0.0 0.0 612.0 792.0 %%DocumentFonts: (atend) %%Creator: ward@atlantic.cis.us with Eroff/eps release 3.0.0A %%CreationDate: Fri Jul 30 11:47:02 1999 %%Pages: (atend) %%EndComments /DocState558 save def /pid 558 def 0.2400 dup scale /inch { 300.0000 mul } bind def /pgtop 10.875 inch def /stm usertime def /pgc statusdict begin pagecount end def /ps { print flush } bind def 1.0 setlinewidth /page { showpage restore save home } bind def /home { newpath 0 pgtop moveto } bind def /mf { statusdict /manualfeed true put } bind def /af { statusdict /manualfeed false put } bind def af /xform { transform round exch round exch itransform } bind def 0 0 xform moveto 0 setlinecap /y { neg 0 exch xform rmoveto } bind def /X { currentpoint exch pop xform moveto } bind def /Y { pgtop exch sub currentpoint pop exch xform moveto } bind def /s { show } bind def /S { exch currentpoint exch pop xform moveto show } bind def /l { neg rlineto currentpoint stroke moveto } bind def /bnf { /dy exch def /dx exch def currentpoint /cury exch def /curx exch def newpath curx cury moveto 0 dy rlineto dx 0 rlineto 0 dy neg rlineto closepath stroke curx dx add cury moveto } bind def /b { /dy exch def /dx exch def currentpoint /cury exch def /curx exch def newpath curx cury moveto 0 dy rlineto dx 0 rlineto 0 dy neg rlineto closepath gsave fill grestore gsave 0 setgray stroke grestore newpath curx dx add cury moveto } bind def /B { /dy exch def /dx exch def currentpoint /cury exch def /curx exch def newpath curx cury moveto 0 dy rlineto dx 0 rlineto 0 dy neg rlineto closepath fill 0 curx dx add cury moveto } bind def /polystart { currentpoint newpath moveto } bind def /polynext { rlineto } bind def /polyclose { closepath } bind def /polyfill { gsave closepath setgray fill grestore currentpoint stroke moveto } bind def /polydraw { currentpoint stroke moveto } bind def /c { 2 div /rad exch def currentpoint /y0 exch def /x0 exch def newpath x0 rad add y0 xform rad 0 360 arc closepath stroke x0 rad add rad add y0 xform moveto } bind def /cf { 2 div /rad exch def currentpoint /y0 exch def /x0 exch def newpath x0 rad add y0 xform rad 0 360 arc closepath gsave setgray fill grestore stroke x0 rad add rad add y0 xform moveto } bind def /a { /y2 exch neg def /x2 exch def /y1 exch neg def /x1 exch def x1 y1 xform rmoveto currentpoint currentpoint x2 x2 mul y2 y2 mul add sqrt y1 neg x1 neg atan y2 x2 atan newpath arc stroke moveto x2 y2 rmoveto } bind def /e { currentlinewidth /elw exch def gsave 2 div /yrad exch def 2 div /xrad exch def currentpoint /y0 exch def /x0 exch def x0 xrad add y0 translate xrad yrad scale newpath 0 0 xform 1 0 360 arc closepath elw xrad div setlinewidth stroke grestore elw setlinewidth x0 xrad add xrad add y0 xform moveto } bind def /ef { currentlinewidth /elw exch def gsave 2 div /yrad exch def 2 div /xrad exch def currentpoint /y0 exch def /x0 exch def x0 xrad add y0 translate xrad yrad scale newpath 0 0 xform 1 0 360 arc closepath elw xrad div setlinewidth gsave setgray fill grestore stroke grestore elw setlinewidth x0 xrad add xrad add y0 xform moveto } bind def /spln { rcurveto currentpoint stroke moveto } bind def /ft { /fonttype exch def /xsiz exch def /ysiz exch def /sl exch def fonttype [ xsiz pt 0 sl sin sl cos div ysiz pt mul ysiz pt 0 0 ] makefont setfont } bind def /doImage {{currentfile rasterString readhexstring pop} image} bind def /pt { 4.166667 mul } bind def 0.375 0.000000 add inch 0.25 inch translate /savematrix matrix currentmatrix def /roman-8-dict 20 dict def % Local storage /roman-8-mappings [ 8#260 /Adieresis 8#265 /Aring 8#276 /Aacute 8#300 /Agrave 8#311 /Acircumflex 8#314 /Atilde 8#321 /Ccedilla 8#322 /Edieresis 8#323 /Eacute 8#324 /Egrave 8#325 /Ecircumflex 8#326 /Idieresis 8#327 /Iacute 8#330 /Igrave 8#331 /Icircumflex 8#332 /Ntilde 8#333 /Odieresis 8#334 /Oacute 8#335 /Ograve 8#336 /Ocircumflex 8#337 /Otilde 8#340 /Scaron 8#342 /Udieresis 8#344 /Uacute 8#345 /Ugrave 8#346 /Ydieresis 8#347 /adieresis 8#354 /aring 8#355 /aacute 8#356 /agrave 8#357 /acircumflex 8#360 /atilde 8#362 /ccedilla 8#363 /edieresis 8#364 /eacute 8#366 /egrave 8#367 /ecircumflex 8#374 /idieresis 8#375 /iacute 8#376 /igrave 8#220 /icircumflex 8#221 /ntilde 8#222 /odieresis 8#223 /oacute 8#224 /ograve 8#225 /ocircumflex 8#226 /otilde 8#227 /scaron 8#230 /udieresis 8#231 /uacute 8#232 /ugrave 8#233 /ucircumflex 8#234 /ydieresis 8#235 /Ucircumflex ] def /AddRoman-8 { roman-8-dict begin /roman-8-mappings exch def /newName exch def /oldName exch def /oldDict oldName findfont def /newDict oldDict maxlength dict def oldDict { exch dup /FID ne { dup /Encoding eq { exch dup length array copy newDict 3 1 roll put } { exch newDict 3 1 roll put } ifelse } { pop pop } ifelse } forall newDict /FontName newName put 0 2 roman-8-mappings length 1 sub { dup roman-8-mappings exch get exch 1 add roman-8-mappings exch get newDict /Encoding get 3 1 roll put } for newName newDict definefont pop end } bind def /BracketFontDict 9 dict def /$workingdict 10 dict def BracketFontDict begin /FontType 3 def /FontName (Bracket) cvn def /FontMatrix [ 0.001 0 0 0.001 0 0] def /FontBBox [ -50 -250 1000 1000 ] def /Encoding 256 array def 0 1 255 { Encoding exch /.notdef put } for Encoding dup 65 /Cbv put dup 66 /Clt put dup 67 /Clk put dup 68 /Clb put dup 69 /Crt put dup 70 /Crk put dup 71 /Crb put dup 72 /Clc put dup 73 /Clf put dup 74 /Crc put dup 75 /Crf put dup 76 /Cbr put dup 77 /Crn put dup 78 /Cci put dup 79 /C|| put dup 80 /C^^ put dup 81 /Cr1 put dup 82 /Cr2 put pop /CharProcs 24 dict dup begin /setC { 0 -50 -250 500 1000 setcachedevice} bind def /C.bv {220 -250 moveto 0 1000 rlineto 60 0 rlineto 0 -1000 rlineto fill } bind def /C.cbar { 750 moveto 180 0 rlineto 0 -60 rlineto -180 0 rlineto fill } bind def /C.fbar { -250 moveto 180 0 rlineto 0 60 rlineto -180 0 rlineto fill } bind def /C.brk.end { 1 setlinewidth moveto rlineto rcurveto reversepath 60 0 rlineto rlineto rcurveto fill } bind def /C.setl {dup dtransform exch round exch idtransform pop setlinewidth } bind def /Cbv { 208 setC C.bv } bind def /Clt { 208 setC 0 150 50 210 140 250 0 730 0 150 50 250 200 250 0 750 220 -250 C.brk.end } bind def /Clk { 208 setC 1 setlinewidth 220 -250 moveto 0 400 rlineto 0 50 -50 100 -100 100 rcurveto 50 0 100 50 100 100 rcurveto 0 400 rlineto 60 0 rlineto 0 -400 rlineto 0 -50 -50 -100 -100 -100 rcurveto 50 0 100 -50 100 -100 rcurveto 0 -400 rlineto closepath fill } bind def /Clb { 208 setC 0 -150 50 -210 140 -250 0 -730 0 -150 50 -250 200 -250 0 -750 220 750 C.brk.end } bind def /Crt { 208 setC 0 150 -50 250 -200 250 0 750 0 150 -50 210 -140 250 0 730 220 -250 C.brk.end } bind def /Crk { 208 setC 1 setlinewidth 220 -250 moveto 0 400 rlineto 0 50 50 100 100 100 rcurveto -50 0 -100 50 -100 100 rcurveto 0 400 rlineto 60 0 rlineto 0 -400 rlineto 0 -50 50 -100 100 -100 rcurveto -50 0 -100 -50 -100 -100 rcurveto 0 -400 rlineto fill } bind def /Crb { 208 setC 0 -150 -50 -250 -200 -250 0 -750 0 -150 -50 -210 -140 -250 0 -730 220 750 C.brk.end } bind def /Clc { 208 setC C.bv 280 C.cbar } bind def /Clf { 208 setC C.bv 280 C.fbar } bind def /Crc { 208 setC C.bv 40 C.cbar } bind def /Crf { 208 setC C.bv 40 C.fbar } bind def /Cbr { 0 0 -50 -250 0 1000 setcachedevice 40 C.setl 0 -250 moveto 0 1000 rlineto stroke } bind def /Crn { 208 setC 40 C.setl 0 770 moveto 500 0 rlineto stroke } bind def /Cci { 937 0 -50 -250 937 1000 setcachedevice 40 C.setl 500 250 400 0 360 arc stroke } bind def /C|| { 70 0 -50 -250 70 1000 setcachedevice } bind def /C^^ { 33 0 -50 -250 33 1000 setcachedevice } bind def /Cr1 { 333 0 -50 -250 333 1000 setcachedevice 40 C.setl 0 setlinejoin 700 180 moveto -650 currentlinewidth add 0 rlineto 200 -200 rlineto 50 360 moveto 650 currentlinewidth sub 0 rlineto -200 200 rlineto stroke } bind def /Cr2 { 333 0 -50 -250 333 1000 setcachedevice 40 C.setl 2 setlinejoin 217 18 moveto -150 150 rlineto 150 150 rlineto -150 -150 rlineto 633 0 rlineto 50 360 moveto 633 0 rlineto -150 150 rlineto 150 -150 rlineto -150 -150 rlineto stroke } bind def end def /BuildChar { $workingdict begin /charcode exch def /fontdict exch def fontdict /CharProcs get begin fontdict /Encoding get charcode get load gsave 0 setlinecap 0 setgray newpath exec grestore end end } bind def end /BracketFont BracketFontDict definefont pop %%EndProlog %%Page: label 1 %%PageFonts: (atend) /PageState558 save def home 0 Y 192 X 200 Y %%IncludeFont: Times-Roman /Times-Roman /Times-Roman-8 roman-8-mappings AddRoman-8 /f.R /Times-Roman-8 findfont def 0.0 10 10 f.R ft(m)s 224(5)S 252(\()S 273(1)S 301(\))S 1027 X(User Commands)s 2019 X(m)s 2051(5)S 2079(\()S 2100(1)S 2128(\))S 192 X 400 Y %%IncludeFont: Times-Bold /Times-Bold /Times-Bold-8 roman-8-mappings AddRoman-8 /f.B /Times-Bold-8 findfont def 0.0 9 9 f.B ft(NAME)s 192 X 450 Y 342 X 0.0 10 10 f.R ft(m5,)s 415(m5.awk)S 558 X(-)s 582(macro)S 697(p)S 718(r)S 732(o)S 753(c)S 772(e)S 791(s)S 807(s)S 823(o)S 844(r)S 192 X 520 Y 0.0 9 9 f.B ft(SYNOPSIS)s 192 X 570 Y 342 X 0.0 10 10 f.B ft(m5)s 0.0 10 10 f.R ft 408([)S 432 X 0.0 10 10 f.B ft(-)s 446(D)S %%IncludeFont: Times-Italic /Times-Italic /Times-Italic-8 roman-8-mappings AddRoman-8 /f.I /Times-Italic-8 findfont def 0.0 10 10 f.I ft 476(name)S 0.0 10 10 f.R ft 577(])S 601([)S 625 X 0.0 10 10 f.B ft(-)s 639(D)S 0.0 10 10 f.I ft 669(name)S 0.0 10 10 f.B ft 763(=)S 0.0 10 10 f.I ft 787(def)S 0.0 10 10 f.R ft 849(])S 873([)S 887 X 0.0 10 10 f.B ft(-)s 901(c)S 0.0 10 10 f.R ft 920(])S 944([)S 968 X 0.0 10 10 f.B ft(-)s 982(dp)S 0.0 10 10 f.I ft 1038(char)S 0.0 10 10 f.R ft 1125(])S 1149([)S 1173 X 0.0 10 10 f.B ft(-)s 1187(o)S 1218 X 0.0 10 10 f.I ft(\256)s 1239(le)S 0.0 10 10 f.R ft 1280(])S 1304([)S 1328 X 0.0 10 10 f.B ft(-)s 1342(sp)S 0.0 10 10 f.I ft 1391(char)S 0.0 10 10 f.R ft 1478(])S 1502([)S 1526 X 0.0 10 10 f.I ft(\256)s 1547(le)S 1588(.)S 1605(.)S 1622(.)S 0.0 10 10 f.R ft 1642(])S 192 X 640 Y 342 X([)s 0.0 10 10 f.B ft 356(g|n)S 0.0 10 10 f.R ft 409(])S 0.0 10 10 f.B ft 423(awk)S 507 X(-)s 521(f)S 545(m5.awk)S 695(X)S 0.0 10 10 f.R ft 735([)S 759 X 0.0 10 10 f.B ft(-)s 773(D)S 0.0 10 10 f.I ft 803(name)S 0.0 10 10 f.R ft 904(])S 928([)S 952 X 0.0 10 10 f.B ft(-)s 966(D)S 0.0 10 10 f.I ft 996(name)S 0.0 10 10 f.B ft 1090(=)S 0.0 10 10 f.I ft 1114(def)S 0.0 10 10 f.R ft 1176(])S 1200([)S 1214 X 0.0 10 10 f.B ft(-)s 1228(c)S 0.0 10 10 f.R ft 1247(])S 1271([)S 1295 X 0.0 10 10 f.B ft(-)s 1309(dp)S 0.0 10 10 f.I ft 1365(char)S 0.0 10 10 f.R ft 1452(])S 1476([)S 1500 X 0.0 10 10 f.B ft(-)s 1514(o)S 1545 X 0.0 10 10 f.I ft(\256)s 1566(le)S 0.0 10 10 f.R ft 1607(])S 1631([)S 1655 X 0.0 10 10 f.B ft(-)s 1669(sp)S 0.0 10 10 f.I ft 1718(char)S 0.0 10 10 f.R ft 1805(])S 1829([)S 1853 X 0.0 10 10 f.I ft(\256)s 1874(le)S 1915(.)S 1932(.)S 1949(.)S 0.0 10 10 f.R ft 1969(])S 192 X 710 Y 0.0 9 9 f.B ft(DESCRIPTION)s 192 X 760 Y 342 X 0.0 10 10 f.B ft(m5)s 0.0 10 10 f.R ft 413(is)S 456(a)S 491(Bourne)S 631(shell)S 727(script)S 837(for)S 902(invoking)S 0.0 10 10 f.B ft 1068(m5.awk)S 0.0 10 10 f.R ft 1208(,)S 1234(which)S 1353(actually)S 1504(performs)S 1671(the)S 1739(macro)S 1860(processing.)S 0.0 10 10 f.B ft 2076(m5)S 0.0 10 10 f.R ft 2132(,)S 192 X 810 Y 342 X(unlike)s 461(many)S 567(m)S 599(a)S 618(c)S 637(r)S 651(o)S 672(p)S 693(r)S 707(o)S 728(c)S 747(e)S 766(s)S 782(s)S 798(o)S 819(r)S 833(s)S 849(,)S 872(does)S 961(not)S 1027(directly)S 1169(interpret)S 1325(its)S 1377(input.)S 1496(Instead)S 1630(it)S 1666(uses)S 1750(a)S 1781(two-pass)S 1942(approach)S 2109(in)S 192 X 860 Y 342 X(which)s 456(the)S 519 X(\256)s 542(rst)S 595(pass)S 678(translates)S 849(the)S 912(input)S 1010(to)S 1054(an)S 1105(awk)S 1186(program,)S 1349(and)S 1421(the)S 1484(second)S 1612(pass)S 1696(executes)S 1854(the)S 1918(awk)S 2000(p)S 2021(r)S 2035(o)S 2056(g)S 2077(r)S 2091(a)S 2110(m)S 192 X 910 Y 342 X(to)s 385(produce)S 531(the)S 593 X(\256)s 616(nal)S 678(output.)S 816(Details)S 946(of)S 991(usage)S 1097(are)S 1159(provided)S 1319(b)S 1340(e)S 1359(l)S 1371(o)S 1392(w)S 1422(.)S 192 X 980 Y 342 X(As)s 400(noted)S 506(in)S 551(the)S 615(synopsis)S 771(above,)S 894(its)S 946(invocation)S 1137(may)S 1221(require)S 1353(speci)S 1440 X(\256)s 1463(cation)S 1579(of)S 0.0 10 10 f.B ft 1626(awk)S 0.0 10 10 f.R ft 1700(,)S 0.0 10 10 f.B ft 1722(gawk)S 0.0 10 10 f.R ft 1817(,)S 1839(or)S 0.0 10 10 f.B ft 1886(nawk)S 0.0 10 10 f.R ft 1983(,)S 2006(depend)S 2128 X(-)s 192 X 1030 Y 342 X(ing)s 408(on)S 462(the)S 526(version)S 662(of)S 0.0 10 10 f.B ft 709(awk)S 0.0 10 10 f.R ft 795(available)S 961(on)S 1015(your)S 1104(system.)S 1252(This)S 1338(choice)S 1461(is)S 1501(further)S 1628(complicated)S 1847(on)S 1901(some)S 2000(s)S 2016(y)S 2037(s)S 2053(t)S 2065(e)S 2084(m)S 2116(s)S 2132(,)S 192 X 1080 Y 342 X(e.g.)s 415(Sun,)S 503(which)S 619(have)S 712(both)S 0.0 10 10 f.B ft 800(awk)S 0.0 10 10 f.R ft 888(\(original)S 1048(awk\))S 1146(and)S 0.0 10 10 f.B ft 1221(nawk)S 0.0 10 10 f.R ft 1332(\(new)S 1430(awk\).)S 1548(Other)S 1658(systems)S 1804(appear)S 1931(to)S 1978(have)S 2072(new)S 192 X 1130 Y 342 X(awk,)s 436(but)S 504(have)S 598(named)S 724(it)S 762(just)S 0.0 10 10 f.B ft 837(awk)S 0.0 10 10 f.R ft 911(.)S 945(New)S 1038(awk)S 1122(should)S 1248(be)S 1302(used,)S 1403(regardless)S 1588(of)S 1637(what)S 1733(it)S 1770(has)S 1839(been)S 1932(named.)S 2077(The)S 192 X 1180 Y 342 X(macro)s 462(processor)S 639(translator)S 815(will)S 897(not)S 967(work)S 1069(using)S 1176(original)S 1324(awk)S 1410(because)S 1560(the)S 1628(former,)S 1768(for)S 1833(example,)S 2002(uses)S 2090(the)S 192 X 1230 Y 342 X(built-in)s 477(function)S 628(m)S 660(a)S 679(t)S 691(c)S 710(h)S 731(\()S 745(\))S 759(.)S 192 X 1300 Y 0.0 9 9 f.B ft(OPTIONS)s 192 X 1350 Y 342 X 0.0 10 10 f.R ft(The)s 417(following)S 591(options)S 725(are)S 787(s)S 803(u)S 824(p)S 845(p)S 866(o)S 887(r)S 901(t)S 913(e)S 932(d)S 953(:)S 192 X 1420 Y 342 X 0.0 10 10 f.B ft(-D)s 0.0 10 10 f.I ft 386(name)S 636 X 0.0 10 10 f.R ft(F)s 658(o)S 679(l)S 691(l)S 703(o)S 724(w)S 754(i)S 766(n)S 787(g)S 818(the)S 0.0 10 10 f.B ft 880(cpp)S 0.0 10 10 f.R ft 955(convention,)S 1163(de)S 1203 X(\256)s 1226(ne)S 1276(name)S 1377(as)S 1422(1)S 1453(\(one\).)S 1572(This)S 1656(is)S 1694(the)S 1756(same)S 1852(as)S 1897(if)S 1933(a)S 1962(-)S 1976(D)S 2006(n)S 2027(a)S 2046(m)S 2078(e)S 2097(=)S 2121(1)S 192 X 1470 Y 636 X(appeared)s 802(as)S 850(an)S 903(option)S 1024(or)S 1072(#name=1)S 1242(appeared)S 1408(as)S 1456(an)S 1509(input)S 1609(line.)S 1705(Names)S 1833(speci)S 1920 X(\256)s 1943(ed)S 1995(using)S 2098(-D)S 192 X 1520 Y 636 X(are)s 698(awk)S 778(variables)S 941(de)S 981 X(\256)s 1004(ned)S 1075(just)S 1146(before)S 1264(main)S 1358(is)S 1396(i)S 1408(n)S 1429(v)S 1450(o)S 1471(k)S 1492(e)S 1511(d)S 1532(.)S 192 X 1590 Y 342 X 0.0 10 10 f.B ft(-D)s 0.0 10 10 f.I ft 386(name=def)S 0.0 10 10 f.R ft 636(De)S 685 X(\256)s 708(ne)S 764(name)S 871(as)S 923(")S 938(d)S 959(e)S 978(f)S 992(")S 1006(.)S 1043(This)S 1134(is)S 1179(the)S 1248(same)S 1351(as)S 1403(if)S 1446(#)S 1467(n)S 1488(a)S 1507(m)S 1539(e)S 1558(=)S 1582(")S 1597(d)S 1618(e)S 1637(f)S 1651(")S 1685(appeared)S 1855(as)S 1907(an)S 1964(input)S 2068(line.)S 192 X 1640 Y 636 X(Names)s 762(speci)S 849 X(\256)s 872(ed)S 922(using)S 1023(-D)S 1077(are)S 1139(awk)S 1219(variables)S 1382(de)S 1422 X(\256)s 1445(ned)S 1516(just)S 1587(before)S 1705(main)S 1799(is)S 1837(i)S 1849(n)S 1870(v)S 1891(o)S 1912(k)S 1933(e)S 1952(d)S 1973(.)S 192 X 1710 Y 342 X 0.0 10 10 f.B ft(X)s 636 X 0.0 10 10 f.R ft(Y)s 663(e)S 682(s)S 698(,)S 722(that)S 801(really)S 913(is)S 956(a)S 990(capital)S 1119(")S 1136(X)S 1166(")S 1180(.)S 1215(The)S 1295(version)S 1434(of)S 0.0 10 10 f.B ft 1484(nawk)S 0.0 10 10 f.R ft 1596(on)S 1653(Sun)S 1733(Solaris)S 1865(2.5.1)S 1963(a)S 1982(p)S 2003(p)S 2024(a)S 2043(r)S 2057(e)S 2076(n)S 2097(t)S 2109(l)S 2121(y)S 192 X 1760 Y 636 X(does)s 726(its)S 779(own)S 864(argument)S 1036(processing)S 1229(before)S 1350(passing)S 1489(the)S 1554(arguments)S 1742(on)S 1797(to)S 1843(the)S 1908(awk)S 1990(p)S 2011(r)S 2025(o)S 2046(g)S 2067(r)S 2081(a)S 2100(m)S 2132(.)S 192 X 1810 Y 636 X(In)s 681(this)S 752(case,)S 845(X)S 885(\(and)S 970(all)S 1023(succeeding)S 1221(options\))S 1369(are)S 1431(believed)S 1585(by)S 0.0 10 10 f.B ft 1637(nawk)S 0.0 10 10 f.R ft 1744(to)S 1787(be)S 1837 X(\256)s 1860(le)S 1901(names)S 2018(and)S 2090(are)S 192 X 1860 Y 636 X(passed)s 761(on)S 816(to)S 862(the)S 927(macro)S 1045(processor)S 1218(translator)S 1390(\()S 0.0 10 10 f.B ft 1404(m5.awk)S 0.0 10 10 f.R ft 1544(\))S 1570(for)S 1631(its)S 1683(own)S 1767(argument)S 1938(p)S 1959(r)S 1973(o)S 1994(c)S 2013(e)S 2032(s)S 2048(s)S 2064(i)S 2076(n)S 2097(g)S 2118(\))S 2132(.)S 192 X 1910 Y 636 X(Without)s 785(the)S 848(X,)S 899(Sun)S 0.0 10 10 f.B ft 975(nawk)S 0.0 10 10 f.R ft 1083(attempts)S 1237(to)S 1281(process)S 1418(succeeding)S 1617(options)S 1753(\(e.g.,)S 1849(-Dname\))S 2010(as)S 2057(valid)S 192 X 1960 Y 636 X 0.0 10 10 f.B ft(nawk)s 0.0 10 10 f.R ft 743(arguments)S 928(or)S 973 X(\256)s 996(les,)S 1063(thus)S 1143(causing)S 1282(an)S 1332(error.)S 1444(This)S 1528(may)S 1610(not)S 1674(be)S 1724(a)S 1753(problem)S 1903(for)S 1962(all)S 0.0 10 10 f.B ft 2015(awk)S 0.0 10 10 f.R ft 2089(s.)S 192 X 2030 Y 342 X 0.0 10 10 f.B ft(-c)s 636 X 0.0 10 10 f.R ft(Compile)s 791(only.)S 896(The)S 971(output)S 1089(program)S 1241(is)S 1279(still)S 1353(produced,)S 1530(but)S 1594(the)S 1656 X(\256)s 1679(nal)S 1741(output)S 1859(is)S 1897(not.)S 192 X 2100 Y 342 X 0.0 10 10 f.B ft(-dp)s 0.0 10 10 f.I ft 412(char)S 636 X 0.0 10 10 f.R ft(The)s 711(directive)S 870(pre)S 924 X(\256)s 947(x)S 978(character)S 1144(\(default)S 1286(is)S 1324(#\).)S 192 X 2170 Y 342 X 0.0 10 10 f.B ft(-o)s 387 X 0.0 10 10 f.I ft(\256)s 408(le)S 636 X 0.0 10 10 f.R ft(The)s 711(output)S 829(program)S 981 X(\256)s 1004(le)S 1045(\(default)S 1187(is)S 1225(a)S 1244(.)S 1254(a)S 1273(w)S 1303(k)S 1324(\))S 1338(.)S 192 X 2240 Y 342 X 0.0 10 10 f.B ft(-sp)s 0.0 10 10 f.I ft 405(char)S 636 X 0.0 10 10 f.R ft(The)s 711(substitution)S 918(pre)S 972 X(\256)s 995(x)S 1026(character)S 1192(\(default)S 1334(is)S 1372($\).)S 192 X 2310 Y 0.0 9 9 f.B ft(USAGE)s 192 X 2360 Y 267(Overview)S 192 X 2410 Y 342 X 0.0 10 10 f.R ft(The)s 421(program)S 577(that)S 655(performs)S 820(the)S 886 X(\256)s 909(rst)S 965(pass)S 1051(noted)S 1159(above)S 1274(is)S 1316(called)S 1432(the)S 0.0 10 10 f.I ft 1498(m5)S 1563(translator)S 0.0 10 10 f.R ft 1746(and)S 1822(is)S 1865(named)S 0.0 10 10 f.B ft 1992(m5.awk)S 0.0 10 10 f.R ft 2132(.)S 192 X 2460 Y 342 X(The)s 421(input)S 522(to)S 569(the)S 635(translator)S 809(may)S 894(be)S 947(either)S 1057(standard)S 1213(input)S 1313(or)S 1361(one)S 1435(or)S 1483(more)S 1582 X(\256)s 1605(les)S 1665(listed)S 1770(on)S 1825(the)S 1890(command)S 2068(line.)S 192 X 2510 Y 342 X(An)s 405(input)S 504(line)S 580(with)S 667(the)S 731(directive)S 892(pre)S 946 X(\256)s 969(x)S 1002(character)S 1171(\(#)S 1219(by)S 1274(default\))S 1419(in)S 1465(column)S 1604(1)S 1638(is)S 1679(treated)S 1808(as)S 1856(a)S 1888(directive)S 2050(state)S 2128 X(-)s 192 X 2560 Y 342 X(ment)s 437(in)S 481(the)S 544(MP)S 615(directive)S 775(language)S 939(\(awk\).)S 1068(All)S 1133(other)S 1231(input)S 1329(lines)S 1420(are)S 1483(processed)S 1660(as)S 1706(text)S 1781(lines.)S 1892(Simple)S 2021(m)S 2053(a)S 2072(c)S 2091(r)S 2105(o)S 2126(s)S 192 X 2610 Y 342 X(are)s 404(created)S 537(using)S 638(awk)S 718(assignment)S 917(statements)S 1105(and)S 1176(their)S 1264(values)S 1383(referenced)S 1573(using)S 1675(the)S 1738(substitution)S 1946(pre)S 2000 X(\256)s 2023(x)S 2055(char)S 2128 X(-)s 192 X 2660 Y 342 X(acter)s 440(\($)S 490(by)S 547(default\).)S 714(The)S 794(backslash)S 973(\(\\\))S 1028(is)S 1071(the)S 1138(escape)S 1266(character;)S 1449(its)S 1504(presence)S 1667(forces)S 1785(the)S 1852(next)S 1939(character)S 2109(to)S 192 X 2710 Y 342 X(literally)s 485(appear)S 608(in)S 651(the)S 713(output.)S 851(This)S 935(is)S 973(most)S 1064(useful)S 1177(when)S 1279(forcing)S 1412(the)S 1475(appearance)S 1677(of)S 1723(the)S 1786(directive)S 1946(pre)S 2000 X(\256)s 2023(x)S 2055(char)S 2128 X(-)s 192 X 2760 Y 342 X(acter,)s 445(the)S 507(substitution)S 714(pre)S 768 X(\256)s 791(x)S 822(character,)S 998(and)S 1069(the)S 1131(escape)S 1254(character)S 1420(i)S 1432(t)S 1444(s)S 1460(e)S 1479(l)S 1491(f)S 1505(.)S 192 X 2830 Y 0.0 9 9 f.B ft 267(Macro)S 389(Substitution)S 192 X 2880 Y 342 X 0.0 10 10 f.R ft(All)s 411(input)S 513(lines)S 608(are)S 675(scanned)S 827(for)S 892(macro)S 1013(references)S 1203(that)S 1283(are)S 1351(indicated)S 1523(by)S 1581(the)S 1649(substitution)S 1862(pre)S 1916 X(\256)s 1939(x)S 1976(c)S 1995(h)S 2016(a)S 2035(r)S 2049(a)S 2068(c)S 2087(t)S 2099(e)S 2118(r)S 2132(.)S 192 X 2930 Y 342 X(Assuming)s 525(the)S 591(default)S 723(value)S 829(of)S 878(that)S 955(character,)S 1134(macro)S 1252(references)S 1439(may)S 1524(be)S 1577(of)S 1625(the)S 1690(form)S 1784($var,)S 1882($\(var\),)S 2008($)S 2029(\()S 2043(e)S 2062(x)S 2083(p)S 2104(r)S 2118(\))S 2132(,)S 192 X 2980 Y 342 X($[str],)s 456($var[expr],)S 657(or)S 705($func\(args\).)S 932(These)S 1045(are)S 1110(replaced)S 1268(by)S 1324(an)S 1378(awk)S 1462(variable,)S 1623(awk)S 1707(variable,)S 1868(awk)S 1952(e)S 1971(x)S 1992(p)S 2013(r)S 2027(e)S 2046(s)S 2062(s)S 2078(i)S 2090(o)S 2111(n)S 2132(,)S 192 X 3030 Y 342 X(awk)s 435(array)S 545(reference)S 725(to)S 780(the)S 854(special)S 994(array)S %%IncludeFont: Courier /Courier /Courier-8 roman-8-mappings AddRoman-8 /f.CW /Courier-8 findfont def 0.0 10 10 f.CW ft 1118(M[])S 0.0 10 10 f.R ft 1193(,)S 1225(regular)S 1367(awk)S 1459(array)S 1568(reference,)S 1758(or)S 1815(awk)S 1907(function)S 2070(call,)S 192 X 3230 Y(SunOS 5.5.1)s 946 X(L)s 971(a)S 990(s)S 1006(t)S 1018( )S 1028(c)S 1047(h)S 1068(a)S 1087(n)S 1108(g)S 1129(e)S 1148(:)S 1160( )S 1170(0)S 1191(1)S 1212( )S 1222(A)S 1252(u)S 1273(g)S 1294( )S 1304(1)S 1325(9)S 1346(9)S 1367(9)S 2121 X(1)s 3300 Y showpage PageState558 restore %%PageFonts: Times-Roman Times-Bold Times-Italic Courier %%Page: label 2 %%PageFonts: (atend) /PageState558 save def home %%IncludeFont: Times-Roman /Times-Roman /Times-Roman-8 roman-8-mappings AddRoman-8 /f.R /Times-Roman-8 findfont def 0.0 10 10 f.R ft 1.0000 setlinewidth 192 X 200 Y(m)s 224(5)S 252(\()S 273(1)S 301(\))S 1027 X(User Commands)s 2019 X(m)s 2051(5)S 2079(\()S 2100(1)S 2128(\))S 192 X 400 Y 342 X(respectively.)s 577(These)S 687(are,)S 759(in)S 802(e)S 821 X /Cff{ (f) show xsiz pt 20 div neg 0 rmoveto (f) s }bind def Cff 847(ect,)S 917(macros.)S 1069(The)S 1145(MP)S 1216(translator)S 1387(checks)S 1513(for)S 1573(proper)S 1694(nesting)S 1827(of)S 1873(parentheses)S 2081(and)S 192 X 450 Y 342 X(double)s 471(quotes)S 595(when)S 700(translating)S 893($\(expr\))S 1031(and)S 1106($func\(args\))S 1314(macros,)S 1459(and)S 1534(checks)S 1663(for)S 1726(proper)S 1849(nesting)S 1984(of)S 2032(s)S 2048(q)S 2069(u)S 2090(a)S 2109(r)S 2123(e)S 192 X 500 Y 342 X(brackets)s 494(and)S 566(double)S 692(quotes)S 813(when)S 916(translating)S 1107($[expr])S 1243(and)S 1316($var[expr])S 1506(macros.)S 1659(The)S 1736(substitution)S 1945(pre)S 1999 X(\256)s 2022(x)S 2055(char)S 2128 X(-)s 192 X 550 Y 342 X(acter)s 435(indicates)S 596(a)S 625(a)S 654(macro)S 769(reference)S 937(unless)S 1052(it)S 1086(is)S 1124(\(i\))S 1174(escaped)S 1318(\(e.g.,)S %%IncludeFont: Courier /Courier /Courier-8 roman-8-mappings AddRoman-8 /f.CW /Courier-8 findfont def 0.0 10 10 f.CW ft 1427(\\$abc)S 0.0 10 10 f.R ft 1552(\),)S 1586(\(ii\))S 1648(followed)S 1808(by)S 1860(a)S 1889(character)S 2055(other)S 192 X 600 Y 342 X(than)s 425(A-Z,)S 514(a-z,)S 586(\(,)S 620(or)S 665([)S 689(\(e.g.,)S 0.0 10 10 f.CW ft 798($@)S 0.0 10 10 f.R ft 848(\),)S 882(or)S 927(\(iii\))S 1001(inside)S 1112(a)S 1141(macro)S 1256(reference)S 1424(\(e.g.,)S 0.0 10 10 f.CW ft 1533($\($abc\))S 0.0 10 10 f.R ft 1708(;)S 1730(probably)S 1890(an)S 1940(e)S 1959(r)S 1973(r)S 1987(o)S 2008(r)S 2022(\))S 2036(.)S 192 X 670 Y 342 X(An)s 406(u)S 427(n)S 448(d)S 469(e)S 488(r)S 502(s)S 518(t)S 530(a)S 549(n)S 570(d)S 591(i)S 603(n)S 624(g)S 658(of)S 706(the)S 771(i)S 783(m)S 815(p)S 836(l)S 848(e)S 867(m)S 899(e)S 918(n)S 939(t)S 951(a)S 970(t)S 982(i)S 994(o)S 1015(n)S 1049(of)S 1097(macro)S 1215(substitution)S 1425(will)S 1504(help)S 1590(in)S 1636(its)S 1689(proper)S 1812(usage.)S 1931(When)S 2045(a)S 2078(text)S 192 X 720 Y 342 X(line)s 417(is)S 456(encountered,)S 684(it)S 719(is)S 758(scanned)S 905(for)S 965(macros,)S 1107(embedded)S 1290(in)S 1333(an)S 1383(awk)S 1463(print)S 1553(statement,)S 1735(and)S 1806(copied)S 1929(to)S 1972(the)S 2034(o)S 2055(u)S 2076(t)S 2088(p)S 2109(u)S 2130(t)S 192 X 770 Y 342 X(program.)s 514(F)S 536(o)S 557(r)S 581(example,)S 744(the)S 806(input)S 903(line)S 192 X 840 Y 342 X 0.0 9 9 f.CW ft(The)s 434(quick)S 572($fox)S 687(jumped)S 848(over)S 963(the)S 1055(lazy)S 1170($dog.)S 192 X 910 Y 342 X 0.0 10 10 f.R ft(is)s 380(transformed)S 593(into)S 192 X 980 Y 342 X 0.0 9 9 f.CW ft(print)s 480("The)S 595(quick)S 733(")S 779(fox)S 871(")S 917(jumped)S 1078(over)S 1193(the)S 1285(lazy)S 1400(")S 1446(dog)S 1538(".")S 192 X 1050 Y 342 X 0.0 10 10 f.R ft(Obviously)s 527(the)S 589(use)S 655(of)S 700(this)S 771(t)S 783(r)S 797(a)S 816(n)S 837(s)S 853(f)S 867(o)S 888(r)S 902(m)S 934(a)S 953(t)S 965(i)S 977(o)S 998(n)S 1029(technique)S 1204(relies)S 1306(c)S 1325(o)S 1346(m)S 1378(p)S 1399(l)S 1411(e)S 1430(t)S 1442(e)S 1461(l)S 1473(y)S 192 X 1100 Y 342 X(on)s 394(the)S 456(presence)S 614(of)S 659(the)S 721(awk)S 801(c)S 820(o)S 841(n)S 862(c)S 881(a)S 900(t)S 912(e)S 931(n)S 952(a)S 971(t)S 983(i)S 995(o)S 1016(n)S 1047(operator)S 1198(\(one)S 1283(or)S 1328(more)S 1424(b)S 1445(l)S 1457(a)S 1476(n)S 1497(k)S 1518(s)S 1534(\))S 1548(.)S 192 X 1170 Y %%IncludeFont: Times-Bold /Times-Bold /Times-Bold-8 roman-8-mappings AddRoman-8 /f.B /Times-Bold-8 findfont def 0.0 9 9 f.B ft 267(Macros)S 403(Containing)S 600(Macros)S 192 X 1220 Y 342 X 0.0 10 10 f.R ft(As)s 399(already)S 535(noted,)S 650(a)S 680(macro)S 796(reference)S 965(inside)S 1077(another)S 1215(macro)S 1331(reference)S 1500(will)S 1577(not)S 1643(result)S 1749(in)S 1794(substitution)S 2003(and)S 2076(will)S 192 X 1270 Y 342 X(probably)s 503(cause)S 608(an)S 659(awk)S 739(e)S 758(x)S 779(e)S 798(c)S 817(u)S 838(t)S 850(i)S 862(o)S 883(n)S 904(-)S 918(t)S 930(i)S 942(m)S 974(e)S 1003(error.)S 1115(F)S 1137(u)S 1158(r)S 1172(t)S 1184(h)S 1205(e)S 1224(r)S 1238(m)S 1270(o)S 1291(r)S 1305(e)S 1324(,)S 1344(a)S 1373(substitution)S 1580(pre)S 1634 X(\256)s 1657(x)S 1688(character)S 1854(in)S 1897(the)S 1959(s)S 1975(u)S 1996(b)S 2017(s)S 2033(t)S 2045(i)S 2057(t)S 2069(u)S 2090(t)S 2102(e)S 2121(d)S 192 X 1320 Y 342 X(string)s 452(is)S 494(also)S 576(generally)S 748(not)S 816(signi)S 898 X(\256)s 921(cant)S 1006(because)S 1154(the)S 1221(substitution)S 1433(pre)S 1487 X(\256)s 1510(x)S 1546(character)S 1717(is)S 1760(detected)S 1917(at)S 1963(t)S 1975(r)S 1989(a)S 2008(n)S 2029(s)S 2045(l)S 2057(a)S 2076(t)S 2088(i)S 2100(o)S 2121(n)S 192 X 1370 Y 342 X(time,)s 442(and)S 518(macro)S 638(values)S 761(are)S 828(assigned)S 988(at)S 1034(execution)S 1214(time.)S 1323(However,)S 1501(macro)S 1620(references)S 1808(of)S 1857(the)S 1923(form)S 2018($)S 2039([)S 2053(e)S 2072(x)S 2093(p)S 2114(r)S 2128(])S 192 X 1420 Y 342 X(provide)s 481(a)S 510(simple)S 633(nested)S 752(referencing)S 956(capability.)S 1155(F)S 1177(o)S 1198(r)S 1223(example,)S 1387(if)S 0.0 10 10 f.CW ft 1439($[abc])S 0.0 10 10 f.R ft 1600(is)S 1639(in)S 1683(a)S 1713(text)S 1788(line,)S 1873(or)S 1919(in)S 1963(a)S 1993(d)S 2014(i)S 2026(r)S 2040(e)S 2059(c)S 2078(t)S 2090(i)S 2102(v)S 2123(e)S 192 X 1470 Y 342 X(line)s 423(and)S 501(not)S 572(on)S 631(the)S 699(left)S 772(hand)S 870(side)S 954(of)S 1005(an)S 1061(assignment)S 1266(statement,)S 1454(it)S 1494(is)S 1538(replaced)S 1698(by)S 0.0 10 10 f.CW ft 1771(e)S 1796(v)S 1821(a)S 1846(l)S 1871(\()S 1896(M)S 1921([)S 1946(")S 1971(a)S 1996(b)S 2021(c)S 2046(")S 2071(])S 2096(\))S 0.0 10 10 f.R ft 2121(/)S 2132(.)S 192 X 1520 Y 342 X(When)s 453(the)S 516(output)S 635(program)S 788(is)S 827(executed,)S 999(the)S 0.0 10 10 f.B ft 1062(m5)S 0.0 10 10 f.R ft 1129(runtime)S 1271(routine)S 0.0 10 10 f.B ft 1402(eval\(\))S 0.0 10 10 f.R ft 1503(/)S 1526(substitutes)S 1715(the)S 1778(value)S 1881(of)S 0.0 10 10 f.CW ft 1942(M)S 1967([)S 1992(")S 2017(a)S 2042(b)S 2067(c)S 2092(")S 2117(])S 192 X 1570 Y 342 X 0.0 10 10 f.R ft(examining)s 531(it)S 566(for)S 625(further)S 750(macro)S 865(references)S 1049(of)S 1094(the)S 1156(form)S 1247($[str])S 1348(\(where)S 1475(")S 1490(s)S 1506(t)S 1518(r)S 1531(")S 1558(denotes)S 1697(an)S 1747(arbitrary)S 1903(string\).)S 2043(If)S 2081(one)S 192 X 1620 Y 342 X(is)s 386(found,)S 510(substitution)S 723(and)S 800(scanning)S 966(proceed)S 1116(recursively.)S 1340(F)S 1362(u)S 1383(n)S 1404(c)S 1423(t)S 1435(i)S 1447(o)S 1468(n)S 1506(type)S 1596(macro)S 1718(references)S 1909(may)S 1998(result)S 2109(in)S 192 X 1670 Y 342 X(references)s 526(to)S 569(other)S 666(macros,)S 807(thus)S 887(providing)S 1061(an)S 1111(additional)S 1291(form)S 1382(of)S 1427(nested)S 1545(r)S 1559(e)S 1578(f)S 1592(e)S 1611(r)S 1625(e)S 1644(n)S 1665(c)S 1684(i)S 1696(n)S 1717(g)S 1738(.)S 192 X 1740 Y 0.0 9 9 f.B ft 267(Directive)S 431(Lines)S 192 X 1790 Y 342 X 0.0 10 10 f.R ft(Except)s 470(for)S 530(the)S 593(include)S 729(directive,)S 899(when)S 1001(a)S 1031(directive)S 1191(line)S 1266(is)S 1306(detected,)S 1470(the)S 1534(directive)S 1695(pre)S 1749 X(\256)s 1772(x)S 1805(is)S 1845(removed,)S 2014(the)S 2078(line)S 192 X 1840 Y 342 X(is)s 382(scanned)S 530(for)S 591(macros,)S 734(and)S 807(then)S 892(the)S 956(line)S 1031(is)S 1070(copied)S 1194(to)S 1238(the)S 1301(output)S 1420(program)S 1573(\(as)S 1633(distinct)S 1769(from)S 1861(the)S 1924 X(\256)s 1947(nal)S 2010(o)S 2031(u)S 2052(t)S 2064(p)S 2085(u)S 2106(t)S 2118(\))S 2132(.)S 192 X 1890 Y 342 X(Any)s 425(valid)S 521(awk)S 602(construct,)S 778(including)S 949(the)S 1012(function)S 1164(statement,)S 1347(is)S 1386(allowed)S 1531(in)S 1575(a)S 1605(directive)S 1765(line.)S 1860(F)S 1882(u)S 1903(r)S 1917(t)S 1929(h)S 1950(e)S 1969(r)S 1995(informa)S 2128 X(-)s 192 X 1940 Y 342 X(tion)s 420(on)S 474(writing)S 608(awk)S 690(programs)S 860(may)S 943(be)S 994(found)S 1103(in)S 1147(Aho,)S 1240(Kernighan,)S 1439(and)S 1511(W)S 1548(e)S 1567(i)S 1579(n)S 1600(b)S 1621(e)S 1640(r)S 1654(g)S 1675(e)S 1694(r)S 1708(,)S 1729(Dougherty)S 1920(and)S 1992(R)S 2020(o)S 2041(b)S 2062(b)S 2083(i)S 2095(n)S 2116(s)S 2132(,)S 192 X 1990 Y 342 X(and)s 413(R)S 441(o)S 462(b)S 483(b)S 504(i)S 516(n)S 537(s)S 553(.)S 192 X 2060 Y 0.0 9 9 f.B ft 267(Include)S 404(Directive)S 192 X 2110 Y 342 X 0.0 10 10 f.R ft(A)s 388(single)S 505(non-awk)S 668(directive)S 833(has)S 905(been)S 1001(provided:)S 1179(the)S 1247(include)S 1388(directive.)S 1574(Assuming)S 1760(that)S 1841(#)S 1879(is)S 1924(the)S 1993(d)S 2014(i)S 2026(r)S 2040(e)S 2059(c)S 2078(t)S 2090(i)S 2102(v)S 2123(e)S 192 X 2160 Y 342 X(pre)s 396 X(\256)s 419(x,)S 461(#include\()S 621 X(\256)s 644(lename\))S 791(directs)S 915(the)S 978(MP)S 1049(translator)S 1220(to)S 1264(immediately)S 1486(read)S 1569(from)S 1660(the)S 1722(indicated)S 1888 X(\256)s 1911(le,)S 1962(p)S 1983(r)S 1997(o)S 2018(c)S 2037(e)S 2056(s)S 2072(s)S 2088(i)S 2100(n)S 2121(g)S 192 X 2210 Y 342 X(lines)s 436(from)S 531(it)S 569(in)S 616(the)S 682(normal)S 816(manner.)S 977(This)S 1066(processing)S 1261(mode)S 1369(makes)S 1491(the)S 1558(include)S 1698(directive)S 1862(the)S 1929(only)S 2019(type)S 2107(of)S 192 X 2260 Y 342 X(directive)s 502(to)S 546(take)S 628(e)S 647 X Cff 673(ect)S 734(at)S 776(translation)S 965(time.)S 1070(Nested)S 1197(includes)S 1348(are)S 1410(allowed.)S 1574(Include)S 1711(directives)S 1886(must)S 1977(appear)S 2100(on)S 192 X 2310 Y 342 X(a)s 371(line)S 445(by)S 497(themselves.)S 714(More)S 815(elaborate)S 981(types)S 1081(of)S 1127 X(\256)s 1150(le)S 1192(processing)S 1383(may)S 1466(be)S 1517(directly)S 1658(programmed)S 1883(using)S 1985(appropri)S 2128 X(-)s 192 X 2360 Y 342 X(ate)s 402(awk)S 482(statements)S 670(in)S 713(the)S 775(input)S 872 X(\256)s 895(le.)S 192 X 2430 Y 0.0 9 9 f.B ft 267(Main)S 368(P)S 390(r)S 407(o)S 426(g)S 445(r)S 462(a)S 481(m)S 528(and)S 604(F)S 626(u)S 647(n)S 668(c)S 685(t)S 698(i)S 709(o)S 728(n)S 749(s)S 192 X 2480 Y 342 X 0.0 10 10 f.R ft(The)s 418(MP)S 489(translator)S 660(builds)S 774(the)S 837(resulting)S 996(awk)S 1077(program)S 1230(in)S 1274(one)S 1346(of)S 1392(two)S 1466(ways,)S 1573(depending)S 1760(on)S 1813(the)S 1876(form)S 1968(of)S 2014(the)S 2077 X(\256)s 2100(rst)S 192 X 2530 Y 342 X(input)s 443(line.)S 541(If)S 583(that)S 661(line)S 739(begins)S 863(with)S 952(")S 969(f)S 983(u)S 1004(n)S 1025(c)S 1044(t)S 1056(i)S 1068(o)S 1089(n)S 1108(")S 1122(,)S 1146(it)S 1184(is)S 1226(assumed)S 1384(that)S 1462(the)S 1528(user)S 1612(is)S 1654(providing)S 1832(one)S 1906(or)S 1954(more)S 2053(func)S 2128 X(-)s 192 X 2580 Y 342 X(tions,)s 446(including)S 619(the)S 684(function)S 838(")S 853(m)S 885(a)S 904(i)S 916(n)S 935(")S 965(required)S 1119(by)S 0.0 10 10 f.B ft 1174(m5)S 0.0 10 10 f.R ft 1230(.)S 1263(If)S 1304(the)S 1369 X(\256)s 1392(rst)S 1447(line)S 1524(does)S 1614(not)S 1681(begin)S 1788(with)S 1876(")S 1893(f)S 1907(u)S 1928(n)S 1949(c)S 1968(t)S 1980(i)S 1992(o)S 2013(n)S 2032(")S 2046(,)S 2069(then)S 192 X 2630 Y 342 X(the)s 406(entire)S 515(input)S 614 X(\256)s 637(le)S 680(is)S 720(translated)S 897(into)S 975(awk)S 1057(statements)S 1247(that)S 1323(are)S 1387(placed)S 1509(inside)S 1621(")S 1636(m)S 1668(a)S 1687(i)S 1699(n)S 1718(")S 1732(.)S 1763(If)S 1802(some)S 1901(input)S 1999(lines)S 2090(are)S 192 X 2680 Y 342 X(inside)s 456(functions,)S 636(and)S 710(others)S 826(are)S 891(not,)S 968(awk)S 1051(will)S 1130(will)S 1209(detect)S 1324(this)S 1398(and)S 1472(complain.)S 1662(The)S 1740(MP)S 1813(by)S 1869(design)S 1993(has)S 2063(l)S 2075(i)S 2087(t)S 2099(t)S 2111(l)S 2123(e)S 192 X 2730 Y 342 X(awareness)s 529(of)S 577(the)S 642(syntax)S 765(of)S 813(directive)S 975(lines)S 1068(\(awk)S 1165(statements\),)S 1380(and)S 1454(as)S 1502(a)S 1534(consequence)S 1763(syntax)S 1886(errors)S 1997(in)S 2043(direc)S 2128 X(-)s 192 X 2780 Y 342 X(tive)s 416(lines)S 506(are)S 568(not)S 632(detected)S 784(until)S 872(the)S 934(output)S 1052(program)S 1204(is)S 1242(e)S 1261(x)S 1282(e)S 1301(c)S 1320(u)S 1341(t)S 1353(e)S 1372(d)S 1393(.)S 192 X 2850 Y 0.0 9 9 f.B ft 267(Output)S 192 X 2900 Y 342 X 0.0 10 10 f.R ft(Finally,)s 484(unless)S 601(the)S 666(-c)S 712(\(compile)S 875(only\))S 977(option)S 1098(is)S 1139(speci)S 1226 X(\256)s 1249(ed)S 1302(on)S 1357(the)S 1422(command)S 1600(line,)S 1687(the)S 1752(output)S 1873(program)S 2028(is)S 2069(exe)S 2128 X(-)s 192 X 2950 Y 342 X(cuted)s 446(to)S 491(produce)S 639(the)S 703 X(\256)s 726(nal)S 790(output)S 910(\(directed)S 1073(by)S 1126(default)S 1255(to)S 1299(standard)S 1453(output\).)S 1606(The)S 1682(version)S 1817(of)S 0.0 10 10 f.B ft 1863(awk)S 0.0 10 10 f.R ft 1948(speci)S 2035 X(\256)s 2058(ed)S 2109(in)S 192 X 3000 Y 342 X(ARGV[0])s 526(\(a)S 576(built-in)S 718(awk)S 805(variable)S 959(containing)S 1155(the)S 1224(command)S 1406(name\))S 1528(is)S 1573(used)S 1667(to)S 1717(execute)S 1864(the)S 1934(program.)S 2114(If)S 192 X 3200 Y(SunOS 5.5.1)s 946 X(L)s 971(a)S 990(s)S 1006(t)S 1018( )S 1028(c)S 1047(h)S 1068(a)S 1087(n)S 1108(g)S 1129(e)S 1148(:)S 1160( )S 1170(0)S 1191(1)S 1212( )S 1222(A)S 1252(u)S 1273(g)S 1294( )S 1304(1)S 1325(9)S 1346(9)S 1367(9)S 2121 X(2)s 3300 Y showpage PageState558 restore %%PageFonts: Times-Roman Courier Times-Bold %%Page: label 3 %%PageFonts: (atend) /PageState558 save def home %%IncludeFont: Times-Roman /Times-Roman /Times-Roman-8 roman-8-mappings AddRoman-8 /f.R /Times-Roman-8 findfont def 0.0 10 10 f.R ft 1.0000 setlinewidth 192 X 200 Y(m)s 224(5)S 252(\()S 273(1)S 301(\))S 1027 X(User Commands)s 2019 X(m)s 2051(5)S 2079(\()S 2100(1)S 2128(\))S 192 X 400 Y 342 X(ARGV[0])s 519(is)S 557(null,)S %%IncludeFont: Times-Bold /Times-Bold /Times-Bold-8 roman-8-mappings AddRoman-8 /f.B /Times-Bold-8 findfont def 0.0 10 10 f.B ft 643(awk)S 0.0 10 10 f.R ft 727(is)S 765(used.)S 192 X 470 Y 0.0 9 9 f.B ft(EXAMPLE)s 192 X 520 Y 342 X 0.0 10 10 f.R ft(Understanding)s 607(this)S 685(example)S 845(requires)S 998(recognition)S 1208(that)S 1289(macro)S 1411(substitution)S 1625(is)S 1670(a)S 1706(two-step)S 1868(process:)S 2033(\(i\))S 2090(the)S 192 X 570 Y 342 X(input)s 443(text)S 521(is)S 563(translated)S 742(into)S 822(an)S 876(output)S 998(awk)S 1082(program,)S 1248(and)S 1322(\(ii\))S 1387(the)S 1452(awk)S 1535(program)S 1690(is)S 1731(executed)S 1895(to)S 1941(produce)S 2090(the)S 192 X 620 Y 342 X(\256)s 365(nal)S 430(output)S 551(with)S 639(the)S 704(macro)S 823(s)S 839(u)S 860(b)S 881(s)S 897(t)S 909(i)S 921(t)S 933(u)S 954(t)S 966(i)S 978(o)S 999(n)S 1020(s)S 1050(actually)S 1199(a)S 1218(c)S 1237(c)S 1256(o)S 1277(m)S 1309(p)S 1330(l)S 1342(i)S 1354(s)S 1370(h)S 1391(e)S 1410(d)S 1431(.)S 1465(The)S 1544(examples)S 1717(below)S 1834(illustrate)S 1997(this)S 2072(pro)S 2128 X(-)s 192 X 670 Y 342 X(cess.)s 446(#)S 481(and)S 556($)S 591(are)S 657(assumed)S 815(to)S 862(be)S 916(the)S 982(directive)S 1145(and)S 1220(substitution)S 1431(pre)S 1485 X(\256)s 1508(x)S 1543(characters.)S 1749(This)S 1837(example)S 1994(was)S 2072(suc)S 2128 X(-)s 192 X 720 Y 342 X(cessfully)s 503(executed)S 666(using)S 0.0 10 10 f.B ft 769(awk)S 0.0 10 10 f.R ft 855(on)S 909(a)S 940(Cray)S 1034(C90)S 1116(running)S 1259(UNICOS)S 1426(10.0.0.3,)S 0.0 10 10 f.B ft 1583(gawk)S 0.0 10 10 f.R ft 1690(on)S 1744(a)S 1775(Gateway)S 1937(E-3200)S 2072(run)S 2128 X(-)s 192 X 770 Y 342 X(ing)s 406(SuSE)S 508(Linux)S 618(V)S 645(e)S 664(r)S 678(s)S 694(i)S 706(o)S 727(n)S 758(6.0,)S 830(and)S 0.0 10 10 f.B ft 901(nawk)S 0.0 10 10 f.R ft 1008(on)S 1060(a)S 1089(Sun)S 1164(Ultra)S 1261(2)S 1292(Model)S 1412(2200)S 1506(running)S 1647(Solaris)S 1774(2)S 1795(.)S 1805(5)S 1826(.)S 1836(1)S 1857(.)S 192 X 840 Y 0.0 9 9 f.B ft 267(Input)S 372(T)S 394(e)S 411(x)S 430(t)S 192 X 890 Y 342 X %%IncludeFont: Courier /Courier /Courier-8 roman-8-mappings AddRoman-8 /f.CW /Courier-8 findfont def 0.0 9 9 f.CW ft(#function)s 572(main\(\))S 733({)S 192 X 990 Y 411 X(Example)s 595(1:)S 664(Simple)S 825(S)S 848(u)S 871(b)S 894(s)S 917(t)S 940(i)S 963(t)S 986(u)S 1009(t)S 1032(i)S 1055(o)S 1078(n)S 192 X 1040 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 192 X 1090 Y 342 X(#)s 411(br)S 480(=)S 526(")S 549(b)S 572(r)S 595(o)S 618(w)S 641(n)S 664(")S 192 X 1140 Y 411 X(The)s 503(quick)S 641($br)S 733(fox.)S 192 X 1240 Y 411 X(Example)s 595(2:)S 664(Substitution)S 963(inside)S 1124(a)S 1170(S)S 1193(t)S 1216(r)S 1239(i)S 1262(n)S 1285(g)S 192 X 1290 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 192 X 1340 Y 342 X(#)s 411(r)S 457(=)S 503("row")S 192 X 1390 Y 411 X(The)s 503(quick)S 641(b$\(r\)n)S 802(fox.)S 192 X 1490 Y 411 X(Example)s 595(3:)S 664(Expression)S 917(S)S 940(u)S 963(b)S 986(s)S 1009(t)S 1032(i)S 1055(t)S 1078(u)S 1101(t)S 1124(i)S 1147(o)S 1170(n)S 192 X 1540 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 192 X 1590 Y 342 X(#)s 411(a)S 457(=)S 503(4)S 192 X 1640 Y 342 X(#)s 411(b)S 457(=)S 503(3)S 192 X 1690 Y 411 X(The)s 503(quick)S 641($\(2)S 710 X %%IncludeFont: Symbol /f.S /Symbol findfont def 0.0 9 9 f.S ft(*)s 0.0 9 9 f.CW ft 729(a)S 775(+)S 821(b\))S 890(f)S 913(o)S 936(x)S 959(e)S 982(s)S 1005(.)S 192 X 1790 Y 411 X(Example)s 595(4:)S 664(Macros)S 825(References)S 1078(inside)S 1239(a)S 1285(Macro)S 192 X 1840 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 1377(-)S 192 X 1890 Y 342 X(#)s 411($[fox])S 572(=)S 618("\\$[q])S 779(\\$[b])S 917(\\)S 940($)S 963([)S 986(f)S 1009(])S 1032(")S 192 X 1940 Y 342 X(#)s 411($[q])S 526(=)S 572(")S 595(q)S 618(u)S 641(i)S 664(c)S 687(k)S 710(")S 192 X 1990 Y 342 X(#)s 411($[b])S 526(=)S 572(")S 595(b)S 618(r)S 641(o)S 664(w)S 687(n)S 710(")S 192 X 2040 Y 342 X(#)s 411($[f])S 526(=)S 572("fox")S 192 X 2090 Y 411 X(The)s 503($)S 526([)S 549(f)S 572(o)S 595(x)S 618(])S 641(.)S 192 X 2190 Y 411 X(Example)s 595(5:)S 664(Array)S 802(Reference)S 1032(S)S 1055(u)S 1078(b)S 1101(s)S 1124(t)S 1147(i)S 1170(t)S 1193(u)S 1216(t)S 1239(i)S 1262(o)S 1285(n)S 192 X 2240 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 192 X 2290 Y 342 X(#)s 411(x[7])S 526(=)S 572(")S 595(b)S 618(r)S 641(o)S 664(w)S 687(n)S 710(")S 192 X 2340 Y 342 X(#)s 411(b)S 457(=)S 503(3)S 192 X 2390 Y 411 X(The)s 503(quick)S 641($x[2)S 733 X 0.0 9 9 f.S ft(*)s 0.0 9 9 f.CW ft 752(b+1])S 867(fox.)S 192 X 2490 Y 411 X(Example)s 595(6:)S 664(Function)S 871(Reference)S 1101(S)S 1124(u)S 1147(b)S 1170(s)S 1193(t)S 1216(i)S 1239(t)S 1262(u)S 1285(t)S 1308(i)S 1331(o)S 1354(n)S 192 X 2540 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 192 X 2590 Y 411 X(The)s 503(quick)S 641($color\(1,2\))S 917(fox.)S 192 X 2690 Y 411 X(Example)s 595(7:)S 664(Substitution)S 963(of)S 1032(Special)S 1216(C)S 1239(h)S 1262(a)S 1285(r)S 1308(a)S 1331(c)S 1354(t)S 1377(e)S 1400(r)S 1423(s)S 192 X 2740 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 1377(-)S 1400(-)S 1423(-)S 192 X 2790 Y 342 X(\\#)s 434(The)S 526(\\$)S 595(quick)S 733(\\\\)S 802(brown)S 940($#)S 1009(fox.)S 1124($$)S 192 X 2840 Y 342 X(#})s 192 X 2890 Y 342 X(#)s 365(i)S 388(n)S 411(c)S 434(l)S 457(u)S 480(d)S 503(e)S 526(\()S 549(t)S 572(e)S 595(s)S 618(t)S 641(i)S 664(n)S 687(c)S 710(l)S 733(.)S 756(m)S 779(5)S 802(\))S 192 X 3200 Y 0.0 10 10 f.R ft(SunOS 5.5.1)s 946 X(L)s 971(a)S 990(s)S 1006(t)S 1018( )S 1028(c)S 1047(h)S 1068(a)S 1087(n)S 1108(g)S 1129(e)S 1148(:)S 1160( )S 1170(0)S 1191(1)S 1212( )S 1222(A)S 1252(u)S 1273(g)S 1294( )S 1304(1)S 1325(9)S 1346(9)S 1367(9)S 2121 X(3)s 3300 Y showpage PageState558 restore %%PageFonts: Times-Roman Times-Bold Courier Symbol %%Page: label 4 %%PageFonts: (atend) /PageState558 save def home %%IncludeFont: Times-Roman /Times-Roman /Times-Roman-8 roman-8-mappings AddRoman-8 /f.R /Times-Roman-8 findfont def 0.0 10 10 f.R ft 1.0000 setlinewidth 192 X 200 Y(m)s 224(5)S 252(\()S 273(1)S 301(\))S 1027 X(User Commands)s 2019 X(m)s 2051(5)S 2079(\()S 2100(1)S 2128(\))S 192 X 400 Y %%IncludeFont: Times-Bold /Times-Bold /Times-Bold-8 roman-8-mappings AddRoman-8 /f.B /Times-Bold-8 findfont def 0.0 9 9 f.B ft 267(Included)S 425(File)S 502(testincl.m5)S 192 X 450 Y 342 X %%IncludeFont: Courier /Courier /Courier-8 roman-8-mappings AddRoman-8 /f.CW /Courier-8 findfont def 0.0 9 9 f.CW ft(#function)s 572(color\(i,j\))S 825({)S 192 X 500 Y 411 X(The)s 503(lazy)S 618(dog.)S 192 X 550 Y 342 X(#)s 411(if)S 480(\(i)S 549(==)S 618(j\))S 192 X 600 Y 342 X(#)s 480 X(return)s 641(")S 664(b)S 687(l)S 710(u)S 733(e)S 756(")S 192 X 650 Y 342 X(#)s 411(else)S 192 X 700 Y 342 X(#)s 480 X(return)s 641(")S 664(b)S 687(r)S 710(o)S 733(w)S 756(n)S 779(")S 192 X 750 Y 342 X(#})s 192 X 820 Y 0.0 9 9 f.B ft 267(Output)S 400(P)S 422(r)S 439(o)S 458(g)S 477(r)S 494(a)S 513(m)S 192 X 870 Y 342 X 0.0 9 9 f.CW ft(function)s 549(main\(\))S 710({)S 192 X 920 Y 411 X(print)s 192 X 970 Y 411 X(print)s 549(")S 641(Example)S 825(1:)S 894(Simple)S 1055(S)S 1078(u)S 1101(b)S 1124(s)S 1147(t)S 1170(i)S 1193(t)S 1216(u)S 1239(t)S 1262(i)S 1285(o)S 1308(n)S 1331(")S 192 X 1020 Y 411 X(print)s 549(")S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(")S 192 X 1070 Y 411 X(br)s 480(=)S 526(")S 549(b)S 572(r)S 595(o)S 618(w)S 641(n)S 664(")S 192 X 1120 Y 411 X(print)s 549(")S 641(The)S 733(quick)S 871(")S 917(br)S 986(")S 1032(fox.")S 192 X 1170 Y 411 X(print)s 192 X 1220 Y 411 X(print)s 549(")S 641(Example)S 825(2:)S 894(Substitution)S 1193(inside)S 1354(a)S 1400(S)S 1423(t)S 1446(r)S 1469(i)S 1492(n)S 1515(g)S 1538(")S 192 X 1270 Y 411 X(print)s 549(")S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 1377(-)S 1400(-)S 1423(-)S 1446(-)S 1469(-)S 1492(-)S 1515(-)S 1538(")S 192 X 1320 Y 411 X(r)s 457(=)S 503("row")S 192 X 1370 Y 411 X(print)s 549(")S 641(The)S 733(quick)S 871(b")S 940(r)S 986("n)S 1055(fox.")S 192 X 1420 Y 411 X(print)s 192 X 1470 Y 411 X(print)s 549(")S 641(Example)S 825(3:)S 894(Expression)S 1147(S)S 1170(u)S 1193(b)S 1216(s)S 1239(t)S 1262(i)S 1285(t)S 1308(u)S 1331(t)S 1354(i)S 1377(o)S 1400(n)S 1423(")S 192 X 1520 Y 411 X(print)s 549(")S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 1377(-)S 1400(-)S 1423(")S 192 X 1570 Y 411 X(a)s 457(=)S 503(4)S 192 X 1620 Y 411 X(b)s 457(=)S 503(3)S 192 X 1670 Y 411 X(print)s 549(")S 641(The)S 733(quick)S 871(")S 917(2)S 940 X %%IncludeFont: Symbol /f.S /Symbol findfont def 0.0 9 9 f.S ft(*)s 0.0 9 9 f.CW ft 959(a)S 1005(+)S 1051(b)S 1097(")S 1143(f)S 1166(o)S 1189(x)S 1212(e)S 1235(s)S 1258(.)S 1281(")S 192 X 1720 Y 411 X(print)s 192 X 1770 Y 411 X(print)s 549(")S 641(Example)S 825(4:)S 894(Macros)S 1055(References)S 1308(inside)S 1469(a)S 1515(M)S 1538(a)S 1561(c)S 1584(r)S 1607(o)S 1630(")S 192 X 1820 Y 411 X(print)s 549(")S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 1377(-)S 1400(-)S 1423(-)S 1446(-)S 1469(-)S 1492(-)S 1515(-)S 1538(-)S 1561(-)S 1584(-)S 1607(-)S 1630(")S 192 X 1870 Y 411 X(M["fox"])s 618(=)S 664("$[q])S 802($[b])S 917($[f]")S 192 X 1920 Y 411 X(M["q"])s 572(=)S 618(")S 641(q)S 664(u)S 687(i)S 710(c)S 733(k)S 756(")S 192 X 1970 Y 411 X(M["b"])s 572(=)S 618(")S 641(b)S 664(r)S 687(o)S 710(w)S 733(n)S 756(")S 192 X 2020 Y 411 X(M["f"])s 572(=)S 618("fox")S 192 X 2070 Y 411 X(print)s 549(")S 641(The)S 733(")S 779(e)S 802(v)S 825(a)S 848(l)S 871(\()S 894(M)S 917([)S 940(")S 963(f)S 986(o)S 1009(x)S 1032(")S 1055(])S 1078(\))S 1124(".")S 192 X 2120 Y 411 X(print)s 192 X 2170 Y 411 X(print)s 549(")S 641(Example)S 825(5:)S 894(Array)S 1032(Reference)S 1262(S)S 1285(u)S 1308(b)S 1331(s)S 1354(t)S 1377(i)S 1400(t)S 1423(u)S 1446(t)S 1469(i)S 1492(o)S 1515(n)S 1538(")S 192 X 2220 Y 411 X(print)s 549(")S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 1377(-)S 1400(-)S 1423(-)S 1446(-)S 1469(-)S 1492(-)S 1515(-)S 1538(")S 192 X 2270 Y 411 X(x[7])s 526(=)S 572(")S 595(b)S 618(r)S 641(o)S 664(w)S 687(n)S 710(")S 192 X 2320 Y 411 X(b)s 457(=)S 503(3)S 192 X 2370 Y 411 X(print)s 549(")S 641(The)S 733(quick)S 871(")S 917(x[2)S 986 X 0.0 9 9 f.S ft(*)s 0.0 9 9 f.CW ft 1005(b+1])S 1120(")S 1166(fox.")S 192 X 2420 Y 411 X(print)s 192 X 2470 Y 411 X(print)s 549(")S 641(Example)S 825(6:)S 894(Function)S 1101(Reference)S 1331(S)S 1354(u)S 1377(b)S 1400(s)S 1423(t)S 1446(i)S 1469(t)S 1492(u)S 1515(t)S 1538(i)S 1561(o)S 1584(n)S 1607(")S 192 X 2520 Y 411 X(print)s 549(")S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 1377(-)S 1400(-)S 1423(-)S 1446(-)S 1469(-)S 1492(-)S 1515(-)S 1538(-)S 1561(-)S 1584(-)S 1607(")S 192 X 2570 Y 411 X(print)s 549(")S 641(The)S 733(quick)S 871(")S 917(color\(1,2\))S 1170(")S 1216(fox.")S 192 X 2620 Y 411 X(print)s 192 X 2670 Y 411 X(print)s 549(")S 641(Example)S 825(7:)S 894(Substitution)S 1193(of)S 1262(Special)S 1446(C)S 1469(h)S 1492(a)S 1515(r)S 1538(a)S 1561(c)S 1584(t)S 1607(e)S 1630(r)S 1653(s)S 1676(")S 192 X 2720 Y 411 X(print)s 549(")S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 1377(-)S 1400(-)S 1423(-)S 1446(-)S 1469(-)S 1492(-)S 1515(-)S 1538(-)S 1561(-)S 1584(-)S 1607(-)S 1630(-)S 1653(-)S 1676(")S 192 X 2770 Y 411 X(print)s 549("\\#)S 664(The)S 756(\\$)S 825(quick)S 963(\\\\)S 1032(brown)S 1170($#)S 1239(fox.)S 1354($$")S 192 X 2820 Y 342 X(})s 192 X 2870 Y 342 X(function)s 549(color\(i,j\))S 802({)S 192 X 2920 Y 411 X(print)s 549(")S 641(The)S 733(lazy)S 848(dog.")S 192 X 2970 Y 411 X(if)s 480(\(i)S 549(==)S 618(j\))S 192 X 3020 Y 480 X(return)s 641(")S 664(b)S 687(l)S 710(u)S 733(e)S 756(")S 192 X 3220 Y 0.0 10 10 f.R ft(SunOS 5.5.1)s 946 X(L)s 971(a)S 990(s)S 1006(t)S 1018( )S 1028(c)S 1047(h)S 1068(a)S 1087(n)S 1108(g)S 1129(e)S 1148(:)S 1160( )S 1170(0)S 1191(1)S 1212( )S 1222(A)S 1252(u)S 1273(g)S 1294( )S 1304(1)S 1325(9)S 1346(9)S 1367(9)S 2121 X(4)s 3300 Y showpage PageState558 restore %%PageFonts: Times-Roman Times-Bold Courier Symbol %%Page: label 5 %%PageFonts: (atend) /PageState558 save def home %%IncludeFont: Times-Roman /Times-Roman /Times-Roman-8 roman-8-mappings AddRoman-8 /f.R /Times-Roman-8 findfont def 0.0 10 10 f.R ft 1.0000 setlinewidth 192 X 200 Y(m)s 224(5)S 252(\()S 273(1)S 301(\))S 1027 X(User Commands)s 2019 X(m)s 2051(5)S 2079(\()S 2100(1)S 2128(\))S 192 X 400 Y 411 X %%IncludeFont: Courier /Courier /Courier-8 roman-8-mappings AddRoman-8 /f.CW /Courier-8 findfont def 0.0 9 9 f.CW ft(else)s 192 X 450 Y 480 X(return)s 641(")S 664(b)S 687(r)S 710(o)S 733(w)S 756(n)S 779(")S 192 X 500 Y 342 X(})s 192 X 600 Y 342 X(function)s 549(e)S 572(v)S 595(a)S 618(l)S 641(\()S 664(i)S 687(n)S 710(p)S 792(,)S 815(i)S 838(s)S 861(p)S 884(l)S 907(b)S 930(,)S 953(i)S 976(r)S 999(b)S 1022(,)S 1045(o)S 1068(u)S 1091(t)S 1114(,)S 1137(n)S 1160(a)S 1183(m)S 1206(e)S 1229(\))S 1275({)S 192 X 700 Y 411 X(splb)s 526(=)S 572(SP)S 641("[")S 192 X 750 Y 411 X(out)s 503(=)S 549("")S 192 X 850 Y 411 X(while\()s 572(isplb)S 710(=)S 756(index\(inp,)S 1009(splb\))S 1147(\))S 1193({)S 192 X 900 Y 480 X(irb)s 572(=)S 618(index\(inp,)S 871("]"\))S 192 X 950 Y 480 X(if)s 549(\()S 595(irb)S 687(==)S 756(0)S 802(\))S 848({)S 192 X 1000 Y 549 X(out)s 641(=)S 687(out)S 779(s)S 802(u)S 825(b)S 848(s)S 871(t)S 894(r)S 917(\()S 940(i)S 963(n)S 986(p)S 1009(,)S 1032(1)S 1055(,)S 1078(i)S 1101(s)S 1124(p)S 1147(l)S 1170(b)S 1193(+)S 1216(1)S 1239(\))S 192 X 1050 Y 549 X(inp)s 641(=)S 687(substr\()S 871(inp,)S 986(isplb+2)S 1170(\))S 192 X 1100 Y 480 X(})s 526(else)S 641({)S 192 X 1150 Y 549 X(name)s 664(=)S 710(substr\()S 894(inp,)S 1009(isplb+2,)S 1216(irb-isplb-2)S 1492(\))S 192 X 1200 Y 549 X(sub\()s 664(/\303)S 733(+/,)S 825("",)S 917(name)S 1032(\))S 192 X 1250 Y 549 X(sub\()s 664(/)S 710(+$/,)S 825("",)S 917(name)S 1032(\))S 192 X 1300 Y 549 X(out)s 641(=)S 687(out)S 779(s)S 802(u)S 825(b)S 848(s)S 871(t)S 894(r)S 917(\()S 940(i)S 963(n)S 986(p)S 1009(,)S 1032(1)S 1055(,)S 1078(i)S 1101(s)S 1124(p)S 1147(l)S 1170(b)S 1193(-)S 1216(1)S 1239(\))S 1285(e)S 1308(v)S 1331(a)S 1354(l)S 1377(\()S 1400(M)S 1423([)S 1446(n)S 1469(a)S 1492(m)S 1515(e)S 1538(])S 1561(\))S 192 X 1350 Y 549 X(inp)s 641(=)S 687(substr\()S 871(inp,)S 986(irb+1)S 1124(\))S 192 X 1400 Y 480 X(})s 192 X 1450 Y 411 X(})s 192 X 1550 Y 411 X(out)s 503(=)S 549(out)S 641(inp)S 192 X 1650 Y 411 X(return)s 572(out)S 192 X 1700 Y 342 X(})s 192 X 1750 Y 342 X(BEGIN)s 480({)S 192 X 1800 Y 411 X(SP)s 480(=)S 526("$")S 192 X 1850 Y 411 X(main\(\))s 192 X 1900 Y 411 X(exit)s 192 X 1950 Y 342 X(})s 192 X 2020 Y %%IncludeFont: Times-Bold /Times-Bold /Times-Bold-8 roman-8-mappings AddRoman-8 /f.B /Times-Bold-8 findfont def 0.0 9 9 f.B ft 267(Final)S 367(Output)S 192 X 192 X 2120 Y 411 X 0.0 9 9 f.CW ft(Example)s 595(1:)S 664(Simple)S 825(S)S 848(u)S 871(b)S 894(s)S 917(t)S 940(i)S 963(t)S 986(u)S 1009(t)S 1032(i)S 1055(o)S 1078(n)S 192 X 2170 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 192 X 2220 Y 411 X(The)s 503(quick)S 641(brown)S 779(fox.)S 192 X 2320 Y 411 X(Example)s 595(2:)S 664(Substitution)S 963(inside)S 1124(a)S 1170(S)S 1193(t)S 1216(r)S 1239(i)S 1262(n)S 1285(g)S 192 X 2370 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 192 X 2420 Y 411 X(The)s 503(quick)S 641(brown)S 779(fox.)S 192 X 2520 Y 411 X(Example)s 595(3:)S 664(Expression)S 917(S)S 940(u)S 963(b)S 986(s)S 1009(t)S 1032(i)S 1055(t)S 1078(u)S 1101(t)S 1124(i)S 1147(o)S 1170(n)S 192 X 2570 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 192 X 2620 Y 411 X(The)s 503(quick)S 641(11)S 710(f)S 733(o)S 756(x)S 779(e)S 802(s)S 825(.)S 192 X 2720 Y 411 X(Example)s 595(4:)S 664(Macros)S 825(References)S 1078(inside)S 1239(a)S 1285(Macro)S 192 X 2770 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 1377(-)S 192 X 2820 Y 411 X(The)s 503(quick)S 641(brown)S 779(fox.)S 192 X 2920 Y 411 X(Example)s 595(5:)S 664(Array)S 802(Reference)S 1032(S)S 1055(u)S 1078(b)S 1101(s)S 1124(t)S 1147(i)S 1170(t)S 1193(u)S 1216(t)S 1239(i)S 1262(o)S 1285(n)S 192 X 2970 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 192 X 3020 Y 411 X(The)s 503(quick)S 641(brown)S 779(fox.)S 192 X 3220 Y 0.0 10 10 f.R ft(SunOS 5.5.1)s 946 X(L)s 971(a)S 990(s)S 1006(t)S 1018( )S 1028(c)S 1047(h)S 1068(a)S 1087(n)S 1108(g)S 1129(e)S 1148(:)S 1160( )S 1170(0)S 1191(1)S 1212( )S 1222(A)S 1252(u)S 1273(g)S 1294( )S 1304(1)S 1325(9)S 1346(9)S 1367(9)S 2121 X(5)s 3300 Y showpage PageState558 restore %%PageFonts: Times-Roman Courier Times-Bold %%Page: label 6 %%PageFonts: (atend) /PageState558 save def home %%IncludeFont: Times-Roman /Times-Roman /Times-Roman-8 roman-8-mappings AddRoman-8 /f.R /Times-Roman-8 findfont def 0.0 10 10 f.R ft 1.0000 setlinewidth 192 X 200 Y(m)s 224(5)S 252(\()S 273(1)S 301(\))S 1027 X(User Commands)s 2019 X(m)s 2051(5)S 2079(\()S 2100(1)S 2128(\))S 192 X 400 Y 411 X %%IncludeFont: Courier /Courier /Courier-8 roman-8-mappings AddRoman-8 /f.CW /Courier-8 findfont def 0.0 9 9 f.CW ft(Example)s 595(6:)S 664(Function)S 871(Reference)S 1101(S)S 1124(u)S 1147(b)S 1170(s)S 1193(t)S 1216(i)S 1239(t)S 1262(u)S 1285(t)S 1308(i)S 1331(o)S 1354(n)S 192 X 450 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 192 X 500 Y 411 X(The)s 503(lazy)S 618(dog.)S 192 X 550 Y 411 X(The)s 503(quick)S 641(brown)S 779(fox.)S 192 X 650 Y 411 X(Example)s 595(7:)S 664(Substitution)S 963(of)S 1032(Special)S 1216(C)S 1239(h)S 1262(a)S 1285(r)S 1308(a)S 1331(c)S 1354(t)S 1377(e)S 1400(r)S 1423(s)S 192 X 700 Y 411 X(-)s 434(-)S 457(-)S 480(-)S 503(-)S 526(-)S 549(-)S 572(-)S 595(-)S 618(-)S 641(-)S 664(-)S 687(-)S 710(-)S 733(-)S 756(-)S 779(-)S 802(-)S 825(-)S 848(-)S 871(-)S 894(-)S 917(-)S 940(-)S 963(-)S 986(-)S 1009(-)S 1032(-)S 1055(-)S 1078(-)S 1101(-)S 1124(-)S 1147(-)S 1170(-)S 1193(-)S 1216(-)S 1239(-)S 1262(-)S 1285(-)S 1308(-)S 1331(-)S 1354(-)S 1377(-)S 1400(-)S 1423(-)S 192 X 750 Y 342 X(#)s 411(The)S 503($)S 549(quick)S 687(\\)S 733(brown)S 871($#)S 940(fox.)S 1055($$)S 192 X 820 Y %%IncludeFont: Times-Bold /Times-Bold /Times-Bold-8 roman-8-mappings AddRoman-8 /f.B /Times-Bold-8 findfont def 0.0 9 9 f.B ft(FILE)s 192 X 870 Y 342 X 0.0 10 10 f.B ft(a.awk)s 636 X 0.0 10 10 f.R ft(default)s 764(output)S 882(program)S 1034 X(\256)s 1057(le)S 192 X 940 Y 0.0 9 9 f.B ft(SEE)s 278(ALSO)S 192 X 990 Y 342 X 0.0 10 10 f.B ft(awk)s 0.0 10 10 f.R ft 416(\(1\),)S 0.0 10 10 f.B ft 485(cpp)S 0.0 10 10 f.R ft 550(\(1\),)S 0.0 10 10 f.B ft 619(gawk)S 0.0 10 10 f.R ft 714(\(1\),)S 0.0 10 10 f.B ft 783(m4)S 0.0 10 10 f.R ft 839(\(1\),)S 0.0 10 10 f.B ft 908(nawk)S 0.0 10 10 f.R ft 1005(\(1\).)S 0.0 10 10 f.B ft 1084(vi)S 0.0 10 10 f.R ft 1117(\(1\))S 192 X 1060 Y 0.0 9 9 f.B ft(AUTHOR)s 192 X 1110 Y 342 X 0.0 10 10 f.R ft(William)s 499(A.)S 558(W)S 595(a)S 614(r)S 628(d)S 649(,)S 679(Jr.,)S 749(School)S 886(of)S 941(Computer)S 1129(and)S 1210(Information)S 1431(Sciences,)S 1609(University)S 1807(of)S 1862(South)S 1980(A)S 2010(l)S 2022(a)S 2041(b)S 2062(a)S 2081(m)S 2113(a)S 2132(,)S 192 X 1160 Y 342 X(Mobile,)s 484(Alabama,)S 656(July)S 736(23,)S 798(1999.)S 192 X 3200 Y(SunOS 5.5.1)s 946 X(L)s 971(a)S 990(s)S 1006(t)S 1018( )S 1028(c)S 1047(h)S 1068(a)S 1087(n)S 1108(g)S 1129(e)S 1148(:)S 1160( )S 1170(0)S 1191(1)S 1212( )S 1222(A)S 1252(u)S 1273(g)S 1294( )S 1304(1)S 1325(9)S 1346(9)S 1367(9)S 2121 X(6)s 3300 Y showpage PageState558 restore %%PageFonts: Times-Roman Courier Times-Bold %%Page: label 7 %%PageFonts: (atend) /PageState558 save def home %%IncludeFont: Times-Roman /Times-Roman /Times-Roman-8 roman-8-mappings AddRoman-8 /f.R /Times-Roman-8 findfont def 0.0 10 10 f.R ft 1.0000 setlinewidth PageState558 restore %%Trailer %%DocumentFonts: Times-Roman Times-Bold Times-Italic Courier Symbol %%Pages: 6 DocState558 restore %%EOF SHAR_EOF fi # end of overwriting check if test -f 'manpage.txt' then echo shar: will not over-write existing file "'manpage.txt'" else cat << "SHAR_EOF" > 'manpage.txt' NAME m5, m5.awk - macro processor SYNOPSIS m5 [ -Dname ] [ -Dname=def ] [-c] [ -dp char ] [ -o file ] [ -sp char ] [ file ... ] [g|n]awk -f m5.awk X [ -Dname ] [ -Dname=def ] [-c] [ -dp char ] [ -o file ] [ -sp char ] [ file ... ] DESCRIPTION m5 is a Bourne shell script for invoking m5.awk, which actu- ally performs the macro processing. m5, unlike many macroprocessors, does not directly interpret its input. Instead it uses a two-pass approach in which the first pass translates the input to an awk program, and the second pass executes the awk program to produce the final output. Details of usage are provided below. As noted in the synopsis above, its invocation may require specification of awk, gawk, or nawk, depending on the ver- sion of awk available on your system. This choice is further complicated on some systems, e.g. Sun, which have both awk (original awk) and nawk (new awk). Other systems appear to have new awk, but have named it just awk. New awk should be used, regardless of what it has been named. The macro processor translator will not work using original awk because the former, for example, uses the built-in function match(). OPTIONS The following options are supported: -Dname Following the cpp convention, define name as 1 (one). This is the same as if a -Dname=1 appeared as an option or #name=1 appeared as an input line. Names specified using -D are awk variables defined just before main is invoked. -Dname=def Define name as "def". This is the same as if #name="def" appeared as an input line. Names specified using -D are awk variables defined just before main is invoked. X Yes, that really is a capital "X". The ver- sion of nawk on Sun Solaris 2.5.1 apparently does its own argument processing before pass- ing the arguments on to the awk program. In this case, X (and all succeeding options) are believed by nawk to be file names and are passed on to the macro processor translator (m5.awk) for its own argument processing). Without the X, Sun nawk attempts to process succeeding options (e.g., -Dname) as valid nawk arguments or files, thus causing an error. This may not be a problem for all awks. -c Compile only. The output program is still produced, but the final output is not. -dp char The directive prefix character (default is #). -o file The output program file (default is a.awk). -sp char The substitution prefix character (default is $). USAGE Overview The program that performs the first pass noted above is called the m5 translator and is named m5.awk. The input to the translator may be either standard input or one or more files listed on the command line. An input line with the directive prefix character (# by default) in column 1 is treated as a directive statement in the MP directive language (awk). All other input lines are processed as text lines. Simple macros are created using awk assignment statements and their values referenced using the substitu- tion prefix character ($ by default). The backslash (\) is the escape character; its presence forces the next character to literally appear in the output. This is most useful when forcing the appearance of the directive prefix character, the substitution prefix character, and the escape character itself. Macro Substitution All input lines are scanned for macro references that are indicated by the substitution prefix character. Assuming the default value of that character, macro references may be of the form $var, $(var), $(expr), $[str], $var[expr], or $func(args). These are replaced by an awk variable, awk variable, awk expression, awk array reference to the special array M[], regular awk array reference, or awk function call, respectively. These are, in effect, macros. The MP translator checks for proper nesting of parentheses and dou- ble quotes when translating $(expr) and $func(args) macros, and checks for proper nesting of square brackets and double quotes when translating $[expr] and $var[expr] macros. The substitution prefix character indicates a a macro reference unless it is (i) escaped (e.g., \$abc), (ii) followed by a character other than A-Z, a-z, (, or [ (e.g., $@), or (iii) inside a macro reference (e.g., $($abc); probably an error). An understanding of the implementation of macro substitution will help in its proper usage. When a text line is encoun- tered, it is scanned for macros, embedded in an awk print statement, and copied to the output program. For example, the input line The quick $fox jumped over the lazy $dog. is transformed into print "The quick " fox " jumped over the lazy " dog "." Obviously the use of this transformation technique relies completely on the presence of the awk concatenation operator (one or more blanks). Macros Containing Macros As already noted, a macro reference inside another macro reference will not result in substitution and will probably cause an awk execution-time error. Furthermore, a substitution prefix character in the substituted string is also generally not significant because the substitution pre- fix character is detected at translation time, and macro values are assigned at execution time. However, macro references of the form $[expr] provide a simple nested referencing capability. For example, if $[abc] is in a text line, or in a directive line and not on the left hand side of an assignment statement, it is replaced by eval(M["abc"])/. When the output program is executed, the m5 runtime routine eval()/ substitutes the value of M["abc"] examining it for further macro references of the form $[str] (where "str" denotes an arbitrary string). If one is found, substitution and scanning proceed recursively. Function type macro references may result in references to other mac- ros, thus providing an additional form of nested referenc- ing. Directive Lines Except for the include directive, when a directive line is detected, the directive prefix is removed, the line is scanned for macros, and then the line is copied to the out- put program (as distinct from the final output). Any valid awk construct, including the function statement, is allowed in a directive line. Further information on writing awk programs may be found in Aho, Kernighan, and Weinberger, Dougherty and Robbins, and Robbins. Include Directive A single non-awk directive has been provided: the include directive. Assuming that # is the directive prefix, #include(filename) directs the MP translator to immediately read from the indicated file, processing lines from it in the normal manner. This processing mode makes the include directive the only type of directive to take effect at translation time. Nested includes are allowed. Include directives must appear on a line by themselves. More ela- borate types of file processing may be directly programmed using appropriate awk statements in the input file. Main Program and Functions The MP translator builds the resulting awk program in one of two ways, depending on the form of the first input line. If that line begins with "function", it is assumed that the user is providing one or more functions, including the func- tion "main" required by m5. If the first line does not begin with "function", then the entire input file is translated into awk statements that are placed inside "main". If some input lines are inside functions, and oth- ers are not, awk will will detect this and complain. The MP by design has little awareness of the syntax of directive lines (awk statements), and as a consequence syntax errors in directive lines are not detected until the output program is executed. Output Finally, unless the -c (compile only) option is specified on the command line, the output program is executed to produce the final output (directed by default to standard output). The version of awk specified in ARGV[0] (a built-in awk variable containing the command name) is used to execute the program. If ARGV[0] is null, awk is used. EXAMPLE Understanding this example requires recognition that macro substitution is a two-step process: (i) the input text is translated into an output awk program, and (ii) the awk program is executed to produce the final output with the macro substitutions actually accomplished. The examples below illustrate this process. # and $ are assumed to be the directive and substitution prefix characters. This example was successfully executed using awk on a Cray C90 running UNICOS 10.0.0.3, gawk on a Gateway E-3200 runing SuSE Linux Version 6.0, and nawk on a Sun Ultra 2 Model 2200 running Solaris 2.5.1. Input Text #function main() { Example 1: Simple Substitution ------------------------------ # br = "brown" The quick $br fox. Example 2: Substitution inside a String --------------------------------------- # r = "row" The quick b$(r)n fox. Example 3: Expression Substitution ---------------------------------- # a = 4 # b = 3 The quick $(2*a + b) foxes. Example 4: Macros References inside a Macro ------------------------------------------- # $[fox] = "\$[q] \$[b] \$[f]" # $[q] = "quick" # $[b] = "brown" # $[f] = "fox" The $[fox]. Example 5: Array Reference Substitution --------------------------------------- # x[7] = "brown" # b = 3 The quick $x[2*b+1] fox. Example 6: Function Reference Substitution ------------------------------------------ The quick $color(1,2) fox. Example 7: Substitution of Special Characters --------------------------------------------- \# The \$ quick \\ brown $# fox. $$ #} #include(testincl.m5) Included File testincl.m5 #function color(i,j) { The lazy dog. # if (i == j) # return "blue" # else # return "brown" #} Output Program function main() { print print " Example 1: Simple Substitution" print " ------------------------------" br = "brown" print " The quick " br " fox." print print " Example 2: Substitution inside a String" print " ---------------------------------------" r = "row" print " The quick b" r "n fox." print print " Example 3: Expression Substitution" print " ----------------------------------" a = 4 b = 3 print " The quick " 2*a + b " foxes." print print " Example 4: Macros References inside a Macro" print " -------------------------------------------" M["fox"] = "$[q] $[b] $[f]" M["q"] = "quick" M["b"] = "brown" M["f"] = "fox" print " The " eval(M["fox"]) "." print print " Example 5: Array Reference Substitution" print " ---------------------------------------" x[7] = "brown" b = 3 print " The quick " x[2*b+1] " fox." print print " Example 6: Function Reference Substitution" print " ------------------------------------------" print " The quick " color(1,2) " fox." print print " Example 7: Substitution of Special Characters" print " ---------------------------------------------" print "\# The \$ quick \\ brown $# fox. $$" } function color(i,j) { print " The lazy dog." if (i == j) return "blue" else return "brown" } function eval(inp ,isplb,irb,out,name) { splb = SP "[" out = "" while( isplb = index(inp, splb) ) { irb = index(inp, "]") if ( irb == 0 ) { out = out substr(inp,1,isplb+1) inp = substr( inp, isplb+2 ) } else { name = substr( inp, isplb+2, irb-isplb-2 ) sub( /^ +/, "", name ) sub( / +$/, "", name ) out = out substr(inp,1,isplb-1) eval(M[name]) inp = substr( inp, irb+1 ) } } out = out inp return out } BEGIN { SP = "$" main() exit } Final Output Example 1: Simple Substitution ------------------------------ The quick brown fox. Example 2: Substitution inside a String --------------------------------------- The quick brown fox. Example 3: Expression Substitution ---------------------------------- The quick 11 foxes. Example 4: Macros References inside a Macro ------------------------------------------- The quick brown fox. Example 5: Array Reference Substitution --------------------------------------- The quick brown fox. Example 6: Function Reference Substitution ------------------------------------------ The lazy dog. The quick brown fox. Example 7: Substitution of Special Characters --------------------------------------------- # The $ quick \ brown $# fox. $$ FILE a.awk default output program file SEE ALSO awk(1), cpp(1), gawk(1), m4(1), nawk(1). vi(1) AUTHOR William A. Ward, Jr., School of Computer and Information Sciences, University of South Alabama, Mobile, Alabama, July 23, 1999. SHAR_EOF fi # end of overwriting check cd .. # End of shell archive exit 0