Hello,
I have some code that works more or less. This is called by a make file to adjust some hard-coded definitions in the src code. The script generated some values by looking at some of the src files and then writes those values to specific locations in other files. The awk code is used to find the line in the src file that needs to be replaced and then print the modified file.
This example sets the size of a block of shared memory
# replace multiplier of SHMEMSIZE in sizedefs.h with $num_pages*pagesize
# generated value to substitute for current line
numpages_replacement_line="#define SHMEMSIZE (4096 * $num_pages)"
# value of comment character for current src file, C code in this case
comment_ch='//'
path to file we are working on
filename='./src/sizedefs.h'
# process file to switch out line to replace
awk -v replace="$numpages_replacement_line" \
-v comment="$comment_ch" ' { if( substr($0,1,2) == comment )
print $0;
else if($0 ~ /\#define SHMEMSIZE \(4096 /)
print replace;
else
print $0;
} ' $filename > tmp
# overwrite original file
mv tmp $filename
There are commented out lines in the src that could match the regex, /\#define SHMEMSIZE \(4096 /, so the first step compares the first two characters of $0 to see if the line is commented out. If so, the line is ignored (printed). If the line is not commented out, there is a check to see if the line contains the regex (the text in red above). Lines that do not match the regex are printed. When the regex is found, the substitute line is printed. Finally, the original file is overwritten by the modified temp file.
This works, but there are some issues.
The first issue is that I believe this will only work if the comment is the first two characters on the line. This doesn't look like it will work if the comment is indented, which is common in c and c++. This was originally written for old FORTRAN code where the comment was always a "C" in the first column of the punch card. Is there a way to ignore leading whitespace and check if "//" is the first two non-whitespace characters?
Second, I was not able to pass in the regex line, meaning the line I was looking for. When I tried something like,
numpages_find_line="\#define SHMEMSIZE \(4096"
-v find="$numpages_find_line"
$0 ~ find
I got an error for unmatched parenthesis and I wasn't able to figure out how to escape it. This means that the awk code has to be hard coded for each find and replace and can't be used as a function, etc.
This also doesn't account for multi-line comments. That isn't an issue in this case, but it would be nice to know how to address that. I guess I would look for the start /* and save lines in an array until the */ and then print the array.
Suggestions would be appreciated,
LMHmedchem