2

I'm looking to create documentation from source code that I have. I've been looking around and something like awk seems like it will work, but I've had no luck so far. The information is split in two files, file1.c and file2.c.

Note: I've set up an automatic build environment for the program. This detects changes in the source and builds it. I would like to generate a text file containing a list of any variables which have been modified since the last successful build. The script I'm looking for would be a post-build step, and would run after compilation

In file1.c I have a list of function calls (all the same function) that have a string name to identify them such as:

newFunction("THIS_IS_THE_STRING_I_WANT", otherVariables, 0, &iAlsoNeedThis);
newFunction("I_WANT_THIS_STRING_TOO", otherVariable, 0, &iAnotherOneINeed);
etc...

The fourth parameter in the function call contains the value of the string name in file2. For example:

iAlsoNeedThis = 25;
iAnotherOneINeed = 42;
etc...

I'm looking to output the list to a txt file in the following format:

THIS_IS_THE_STRING_I_WANT = 25
I_WANT_THIS_STRING_TOO = 42

Is there any way of do this?

Thanks

3 Answers 3

2

Here is a start:

NR==FNR {                     # Only true when we are reading the first file
    split($1,s,"\"")          # Get the string in quotes from the first field
    gsub(/[^a-zA-Z]/,"",$4)   # Remove the none alpha chars from the forth field
    m[$4]=s[2]                # Create array 
    next
}
$1 in m {                     # Match feild four from file1 with field one file2
    sub(/;/,"")               # Get rid of the ;
    print m[$1],$2,$3         # Print output
}

Saving this script.awk and running it with your example produces:

$ awk -f script.awk file1 file2
THIS_IS_THE_STRING_I_WANT = 25
I_WANT_THIS_STRING_TOO = 42

Edit:

The modifications you require affects the first line of the script:

NR==FNR && $3=="0," && /start here/,/end here/ {                    
Sign up to request clarification or add additional context in comments.

4 Comments

You're a gentleman and a scholar. This is just what I needed. Thank you very much!
I may have spoken too soon. The script does print everything thing I need, but also a lot of unnecessary information too. Would there be any way to define the script to: 1) Only do the above when the third field is 0 (and not 1, as it is other places in the source.) 2) To only run your script above between a certain section. e.g. if I had a line "// start here", and "// end here" in the source code. Thanks again.
@Matthew that is why I said Here is a start as it was clear the example would be an over simplification. See the edit, this should hopefully reduce the output.
I understand that now. I was so eager to see something work that I overlooked it initially! I was trying to put the above conditions in before the NR==FRN, and then messing about with if statements that were never going to work! Really though, thank you for your help - very much appreciated.
0

You can do it in the shell like so.

#!/bin/sh

eval $(sed 's/[^a-zA-Z0-9=]//g' file2)

while read -r line; do
  case $line in
    (newFunction*)
      set -- $line
      string=${1#*\"}
      string=${string%%\"*}
      while test $# -gt 1; do shift; done
      x=${1#&}
      x=${x%);}
      eval x=\$$x
      printf '%s = %s\n' $string $x
   esac
done < file1.c

Assumptions: newFunction is at the start of the line. Nothing follows the );. Whitespace exactly as in your samples. Output

THIS_IS_THE_STRING_I_WANT = 25
I_WANT_THIS_STRING_TOO = 42

1 Comment

Thanks for the answer. Unfortunately, I'm limited to the windows shell (using gawk currently). There are also comments after the );, and although the newFunction call is the first on the line, it's indented (not sure if this matters)
0

You can execute file file2.c so variables will be defined in bash. Then, you will just have to print $iAlsoNeedThis to get value from iAlsoNeedThis = 25;

It can be done with . file2.c.

Then, what you can do is:

while read line;
do
    name=$(echo $line | cut -d"\"" -f2);
    value=$(echo $line | cut -d"&" -f2 | cut -d")" -f1);
    echo $name = ${!value};
done < file1.c

to get the THIS_IS_THE_STRING_I_WANT, I_WANT_THIS_STRING_TOO text.

5 Comments

Sorry, I should have been clearer. I would like this script to run without having to actually run the program. It will be used to detect changes in the source variables in time, and will be run when the program is being built, not executed.
So please be clearer and do not downvote, it does not cheer up possible answerers...
I've set up an automatic build environment for the program. This detects changes in the source and builds it. I would like to generate a text file containing a list of any variables which have been modified since the last successful build. The script I'm looking for would be a post-build step, and would run after compilation. @fedorqui It was not me who down-voted you.
Useless use of cat. cut ... < file1.c saves a fork and a few million CPU cycles.
Sure, @Jens! In fact, just cut ... file is enough. I edit my answer, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.