Blame test/xref.awk

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