Skip to content
Advertisement

How to find encapsulating function name from line number

I am looking at a log file which just tells me the filename and the line number inside that file that has the Error. What I am interested is knowing the encapsulating function. For example, here are the contents of the log file

    Error: foo.file on line wxy
    Error: foo.file on line xyz
    .
    .
    .

and here are the contents of the file foo.file

function abc_1234 (...)
    .
    .
    .


    endfunction

    function def_442 ()
    .
    .
    .
   //Following line number is  WXY
    assign Z ==== X;

    endfunction


    function ghi(...)
    .
    .
    .


  //Following line number is  XYZ
    assign X = X;
    endfunction

   .
   .
   .

Based on the above log file, I want to get function names def and ghi returned. I have tried the partial solution provided by @larsks and added [[::blank::]]

# look for function definitions and record the function name
# in the func_name variable
/function [[:alpha:]][[:alnum:]]*[[:blank:]]*([^)]*)/ {
  func_name = substr($2, 1, index($2, "(")-1);
}

# when we reach the target line number, print out the current
# value of func_name
NR == target {
  print func_name
}

It is failing on abc_1234 (...) and def_442 (...) as there is a space before (. I can’t get the above to work

Advertisement

Answer

In order to map a line number to a function definition, you’ll will need to iterate through your source file looking for function definitions, and then print out the current one when you encounter a target line number. For example, something like this:

# look for function definitions and record the function name
# in the func_name variable. This looks for lines matching the pattern
# function <space> <identifier>(<anything>), and records the
# <identifier> part in func_name.
/function [[:alpha:]][[:alnum:]]* *([^)]*)/ {
        func_name = $0
        func_name = gensub("function *", "", 1, func_name)
        func_name = gensub(" *\(.*", "", 1, func_name)
}


# when we reach the target line number, print out the current
# value of func_name.  In awk, the variable NR represents the
# current line number, and target is a variable we expect to be
# passed in on the command line.
NR == target {
  print func_name
}

If you put this in a file called findline.awk and call it like this:

awk -f findline.awk -vtarget=26 mysourcefile.src

Then it will print the name of the function that contains line 26. This script as written isn’t terribly robust, but it hopefully gives you some ideas on how to proceed.

See the awk documentation for details about the gensub function.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement