116 lines
3.6 KiB
Plaintext
116 lines
3.6 KiB
Plaintext
_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
|
|
|
|
|
|
|
|
|