_AWK AS A C CODE GENERATOR_ by Wahhab Baldwin [LISTING ONE] # This program reads a C structure and produces C code # to write the record to a C-ISAM work area. # There are limitations on the input format: see sample BEGIN { FS = "[ \t[]+" # Override default } # field separators $1 == "struct" && $3 == "{" { # Opening record struct rec = $2 print "/* " $2 " */" offset = 0 } $2 == "struct" && $3 == "{" { # Struct within record type = "struct" j = 0 } $2 == "long" { f(type == "struct", "stlong", $3, 4)} $2 == "int" { f(type == "struct", "stint", $3, 2)} $2 == "float" { f(type == "struct", "stfloat", $3, 4)} $2 == "double" { f(type == "struct", "stdbl", $3, 8)} $2 == "char" && NF > 3 { # String f(type == "struct", "stchar", $3, $4 - 1)} $2 == "char" && NF == 3 { # Single character f(type == "struct", "stchar", $3, 1)} $2 == "}" && NF > 3 { # Array of structs type = "" print "\tfor (i = 0; i < " $4 + 0 "; i++) {" for (k = 0; k < j; k++) { gsub(";", "", name[k]) temp = $3 "[i]." name[k] emit2("\t" stype[k], temp, flen[k]) } print "\t}" offset += ($4 - 1) * slen slen = 0 } $2 == "}" && NF == 3 { # Named struct type = "" for (k = 0; k < j; k++) emit(stype[k], $3 "." name[k], flen[k]) slen = 0 } function f(bool, str, x, y) { if (bool) setup(str, x, y) else emit(str, x, y) } function setup(type, varname, l) { # Save field data in array name[j] = varname stype[j] = type flen[j++] = l slen += l } function emit(type, varname, l) { # Print C code for field gsub(";", "", varname) print "\t" type "(p." rec "->" varname, ", inf_rec + " offset \ (type == "ststring" ? ", " l ");" : ");") offset += l } function emit2(type, varname, l) { # Print C code for field in struct gsub(";", "", varname) print "\t" type "(p." rec "->" varname, ", inf_rec + i * " slen, "+", offset (type ~ /string/ ? ", " l ");": ");") offset += l } [Example 1: Simple AWK program to total a series of numbers] {total += $1} END {print total} # Total for all input [Example 2: Built-in AWK function for global substitution] {gsub(/aluminium/, "aluminum")} {gsub(/colour/, "color")} [Example 3: Using strings rather than integers as array subscripts] # Program to count word usage in input. # eliminate all non-letters except space { gsub(/[^A-Za-z ]/, "") } # add words to associative array { for (i = 1; i <= NF; i++) ++word[$i] } # print each array entry END { for (j in word) print j, word[j] } [Example 4: Alternative to using the ? operator] if (type ~ /string/) last_part = ", " l ");" else last_part = ");" print "\t" type "(p." rec "->" varname ", inf_rec + " offset last_part