|
Packit Service |
f629e6 |
# xref.awk - cross reference an awk program
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# 12/2010: Modified for gawk test suite to use a variable
|
|
Packit Service |
f629e6 |
# for the sort command and to use `sort -k1' instead of `sort +1'
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
BEGIN {
|
|
Packit Service |
f629e6 |
if (sortcmd == "") sortcmd = "sort" # "sort -k1"
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# create array of keywords to be ignored by lexer
|
|
Packit Service |
f629e6 |
asplit("BEGIN:END:atan2:break:close:continue:cos:delete:" \
|
|
Packit Service |
f629e6 |
"do:else:exit:exp:for:getline:gsub:if:in:index:int:" \
|
|
Packit Service |
f629e6 |
"length:log:match:next:print:printf:rand:return:sin:" \
|
|
Packit Service |
f629e6 |
"split:sprintf:sqrt:srand:sub:substr:system:while",
|
|
Packit Service |
f629e6 |
keywords,":")
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# build the symbol-state table
|
|
Packit Service |
f629e6 |
split("00:00:00:00:00:00:00:00:00:00:" \
|
|
Packit Service |
f629e6 |
"20:10:10:12:12:11:07:00:00:00:" \
|
|
Packit Service |
f629e6 |
"08:08:08:08:08:33:08:00:00:00:" \
|
|
Packit Service |
f629e6 |
"08:44:08:36:08:08:08:00:00:00:" \
|
|
Packit Service |
f629e6 |
"08:44:45:42:42:41:08",machine,":")
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# parse the input and store an intermediate representation
|
|
Packit Service |
f629e6 |
# of the cross-reference information
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# set up the machine
|
|
Packit Service |
f629e6 |
state = 1
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# run the machine
|
|
Packit Service |
f629e6 |
for (;;) {
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# get next symbol
|
|
Packit Service |
f629e6 |
symb = lex()
|
|
Packit Service |
f629e6 |
nextstate = substr(machine[state symb],1,1)
|
|
Packit Service |
f629e6 |
act = substr(machine[state symb],2,1)
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# perform required action
|
|
Packit Service |
f629e6 |
if ( act == "0" )
|
|
Packit Service |
f629e6 |
; # do nothing
|
|
Packit Service |
f629e6 |
else if ( act == "1" ) {
|
|
Packit Service |
f629e6 |
if ( ! inarray(tok,names) )
|
|
Packit Service |
f629e6 |
names[++nnames] = tok
|
|
Packit Service |
f629e6 |
lines[tok,++xnames[tok]] = NR }
|
|
Packit Service |
f629e6 |
else if ( act == "2" ) {
|
|
Packit Service |
f629e6 |
if ( tok in local ) {
|
|
Packit Service |
f629e6 |
tok = tok "(" funcname ")"
|
|
Packit Service |
f629e6 |
if ( ! inarray(tok,names) )
|
|
Packit Service |
f629e6 |
names[++nnames] = tok
|
|
Packit Service |
f629e6 |
lines[tok,++xnames[tok]] = NR }
|
|
Packit Service |
f629e6 |
else {
|
|
Packit Service |
f629e6 |
tok = tok "()"
|
|
Packit Service |
f629e6 |
if ( ! inarray(tok,names) )
|
|
Packit Service |
f629e6 |
names[++nnames] = tok
|
|
Packit Service |
f629e6 |
lines[tok,++xnames[tok]] = NR } }
|
|
Packit Service |
f629e6 |
else if ( act == "3" ) {
|
|
Packit Service |
f629e6 |
funcname = tok
|
|
Packit Service |
f629e6 |
flines[tok] = NR }
|
|
Packit Service |
f629e6 |
else if ( act == "4" )
|
|
Packit Service |
f629e6 |
braces++
|
|
Packit Service |
f629e6 |
else if ( act == "5" ) {
|
|
Packit Service |
f629e6 |
braces--
|
|
Packit Service |
f629e6 |
if ( braces == 0 ) {
|
|
Packit Service |
f629e6 |
for ( temp in local )
|
|
Packit Service |
f629e6 |
delete local[temp]
|
|
Packit Service |
f629e6 |
funcname = ""
|
|
Packit Service |
f629e6 |
nextstate = 1 } }
|
|
Packit Service |
f629e6 |
else if ( act == "6" ) {
|
|
Packit Service |
f629e6 |
local[tok] = 1 }
|
|
Packit Service |
f629e6 |
else if ( act == "7" )
|
|
Packit Service |
f629e6 |
break
|
|
Packit Service |
f629e6 |
else if ( act == "8" ) {
|
|
Packit Service |
f629e6 |
print "error: xref.awk: line " NR ": aborting" \
|
|
Packit Service |
f629e6 |
> "/dev/con"
|
|
Packit Service |
f629e6 |
exit 1 }
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# finished with current token
|
|
Packit Service |
f629e6 |
state = nextstate }
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# finished parsing, now ready to print output
|
|
Packit Service |
f629e6 |
for ( i = 1; i <= nnames; i++ ) {
|
|
Packit Service |
f629e6 |
printf "%d ", xnames[names[i]] | sortcmd
|
|
Packit Service |
f629e6 |
if ( index(names[i],"(") == 0 )
|
|
Packit Service |
f629e6 |
printf "%s(%d)", names[i], flines[names[i]] | sortcmd
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
printf "%s", names[i] | sortcmd
|
|
Packit Service |
f629e6 |
for ( j = 1; j <= xnames[names[i]]; j++ )
|
|
Packit Service |
f629e6 |
if ( lines[names[i],j] != lines[names[i],j-1] )
|
|
Packit Service |
f629e6 |
printf " %d", lines[names[i],j] | sortcmd
|
|
Packit Service |
f629e6 |
printf "\n" | sortcmd }
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
close(sortcmd)
|
|
Packit Service |
f629e6 |
} # END OF PROGRAM
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
function asplit(str,arr,fs, n) { n = split(str,temp_asplit,fs)
|
|
Packit Service |
f629e6 |
for ( i = 1; i <= n; i++ ) arr[temp_asplit[i]]++ }
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
function inarray(val,arr, j, tmp) {
|
|
Packit Service |
f629e6 |
for ( j in arr )
|
|
Packit Service |
f629e6 |
tmp[arr[j]]++
|
|
Packit Service |
f629e6 |
return (val in tmp) }
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
function lex() {
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
for (;;) {
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ( tok == "(eof)" ) return 7
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
while ( length(line) == 0 )
|
|
Packit Service |
f629e6 |
if ( getline line == 0 ) {
|
|
Packit Service |
f629e6 |
tok = "(eof)"; return 7 }
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
sub(/^[ \t]+/,"",line) # remove white space,
|
|
Packit Service |
f629e6 |
sub(/^"([^"]|\\")*"/,"",line) # quoted strings,
|
|
Packit Service |
f629e6 |
sub(/^\/([^\/]|\\\/)+\//,"",line) # regular expressions,
|
|
Packit Service |
f629e6 |
sub(/^#.*/,"",line) # and comments
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ( line ~ /^function/ ) {
|
|
Packit Service |
f629e6 |
tok = "function"; line = substr(line,9); return 1 }
|
|
Packit Service |
f629e6 |
else if ( line ~ /^{/ ) {
|
|
Packit Service |
f629e6 |
tok = "{"; line = substr(line,2); return 2 }
|
|
Packit Service |
f629e6 |
else if ( line ~ /^}/ ) {
|
|
Packit Service |
f629e6 |
tok = "}"; line = substr(line,2); return 3 }
|
|
Packit Service |
f629e6 |
# change regexes to use posix character classes
|
|
Packit Service |
f629e6 |
else if ( match(line,/^[[:alpha:]_][[:alnum:]]*\[/) ) {
|
|
Packit Service |
f629e6 |
tok = substr(line,1,RLENGTH-1)
|
|
Packit Service |
f629e6 |
line = substr(line,RLENGTH+1)
|
|
Packit Service |
f629e6 |
return 5 }
|
|
Packit Service |
f629e6 |
else if ( match(line,/^[[:alpha:]_][[:alnum:]]*\(/) ) {
|
|
Packit Service |
f629e6 |
tok = substr(line,1,RLENGTH-1)
|
|
Packit Service |
f629e6 |
line = substr(line,RLENGTH+1)
|
|
Packit Service |
f629e6 |
if ( ! ( tok in keywords ) ) return 6 }
|
|
Packit Service |
f629e6 |
else if ( match(line,/^[[:alpha:]_][[:alnum:]]*/) ) {
|
|
Packit Service |
f629e6 |
tok = substr(line,1,RLENGTH)
|
|
Packit Service |
f629e6 |
line = substr(line,RLENGTH+1)
|
|
Packit Service |
f629e6 |
if ( ! ( tok in keywords ) ) return 4 }
|
|
Packit Service |
f629e6 |
else {
|
|
Packit Service |
f629e6 |
match(line,/^[^[:alpha:]_{}]/)
|
|
Packit Service |
f629e6 |
tok = substr(line,1,RLENGTH)
|
|
Packit Service |
f629e6 |
line = substr(line,RLENGTH+1) } } }
|