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
|
||
|
||
|
||
|
||
|