Endless recursion in gawk-script

160 views Asked by At

Please pardon me in advance for posting such a big part of my problem, but I just can't put my finger on the part that fails...

I got input-files like this (abas-FO if you care to know):

.fo U|xiininputfile = whatever
.type text U|xigibsgarnich
.assign U|xigibsgarnich
..
..Comment
.copy U|xigibswohl = Spaß
.ein "ow1/UWEDEFTEST.FOP"
.in "ow1/UWEINPUT2"
.continue BOTTOM
.read "SOemthing" U|xttmp
!BOTTOM
..
..

Now I want to recursivly follow each .in[put]/.ein[gabe]-statement, parse the mentioned file and if I don't know it yet, add it to an array. My code looks like this:

#!/bin/awk -f

function getFopMap(inputregex, infile, mandantdir, infiles){
    while(getline f < infile){
        #printf "*"
        #don't match if there is a '
        if(f ~ inputregex "[^']"){
            #remove .input-part
            sub(inputregex, "", f)
            #trim right
            sub(/[[:blank:]]+$/, "", f)
            #remove leading and trailing "
            gsub(/(^\"|\"$)/,"" ,f)

            if(!(f in infiles)){
                infiles[f] = "found"
            }
        }
    }
    close(infile)

    for (i in infiles){
        if(infiles[i] == "found"){
            infiles[i] = "parsed"
            cmd = "test -f \"" i "\""
            if(system(cmd) == 0){
                close(cmd)
                getFopMap(inputregex, f, mandantdir, infiles)
            }
        }
    }
}

BEGIN{
    #Matches something like [.input myfile] or [.ein    "ow1/myfile"]
    inputregex = "^\\.(in|ein)[^[:blank:]]*[[:blank:]]+"

    #Get absolute path of infile
    cmd = "python -c 'import os;print os.path.abspath(\"" ARGV[1] "\")'"
    cmd | getline rootfile
    close(cmd)

    infiles[rootfile] = "parsed"
    getFopMap(inputregex, rootfile, mandantdir, infiles)

    #output result
    for(infile in infiles) print infile
    exit
}

I call the script (in the same directory the paths are relative to) like this:

./script ow1/UWEDEFTEST.FOP

I get no output. It just hangs up. If I remove the comment before the printf "*" command, I'm seeing stars, without end.

I appreciate every help and hints how to do it better.

My awk: gawk Version 3.1.7

1

There are 1 answers

2
Ed Morton On BEST ANSWER

idk it it's your only problem but you're calling getline incorrectly and consequently will go into an infinite loop in some scenarios. Make sure you fully understand all of the caveats at http://awk.info/?tip/getline and you might want to use the recursion example there as the starting point for your code.

The most important item initially for your code is that when getline fails it can return a negative value so then while(getline f < infile) will create an infinite loop since the failing getline will always be returning non-zero and will so continue to be called and continue to fail. You need to use while ( (getline f < infile) > 0) instead.