Modifiers in Makefile rule's dependency list - macros

The problem is fairly simple. I am trying to write a rule, that given the name of the required file will be able to tailor its dependencies.
Let's say I have two programs: calc_foo and calc_bar and they generate a file with output dependent on the parameter. My target would have a name 'target_*_*'; for example, 'target_foo_1' would be generated by running './calc_foo 1'.
The question is, how to write a makefile that would generate outputs of the two programs for a range of parameters?

If there are just a few programs, you can have a rule for each one:
target_foo_%:
./calc_foo $*
If you want to run a program with a list of parameters:
foo_parameter_list = 1 2 green Thursday 23 bismuth
foo_targets = $(addprefix target_foo_,$(foo_parameter_list))
all: $(foo_targets)
If you want a different set of parameters for each program, but with some in common, you can separate the common ones:
common_parameter_list = 1 2 green Thursday
foo_parameter_list = $(common_parameters) 23 bismuth
bar_parameter_list = $(common_parameters) 46 111
If it turns out you have more programs than you thought, but still want to use this method, you just want to automate it:
# add programs here
PROGRAMS = foo bar baz
# You still have to tailor the parameter lists by hand
foo_parameter_list = 1 2 green Thursday 23 bismuth
# everything from here on can be left alone
define PROGRAM_template
$(1)_targets = $(addprefix target_$(1)_,$($(1)_parameter_list))
target_$(1)_%:
./calc_$(1) $$*
all: $(1)_targets
endef
$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))

This seems to do more or less what you are requesting - assuming you are using GNU Make.
Makefile
BAR_out = target_bar_
BAR_list = 1 2 3 4 5 6 7 8 9
BAR_targets = $(addprefix ${BAR_out},${BAR_list})
FOO_out = target_foo_
FOO_list = 11 12 13 14 15 16 17 18 19
FOO_targets = $(addprefix ${FOO_out},${FOO_list})
all: ${BAR_targets} ${FOO_targets}
${BAR_targets}:
calc_bar $(subst ${BAR_out},,$#)
${FOO_targets}:
calc_foo $(subst ${FOO_out},,$#)
It can probably be cleaned up, but I tested it with the commands:
calc_bar
echo "BAR $#" | tee target_bar_$#
sleep $#
calc_foo
echo "FOO $#" | tee target_foo_$#
sleep $#
Clearly, if you want a different list, you can specify that on the command line:
make -j4 FOO_LIST="1 2 3 4 5 6 33"

Related

How to use if condition in selenium IDE

3 login based questions in the website to be automated
I need correct code to automate these.
enter image description here
When using "if ..." Commands in test steps in Selenium IDE for Chrome, you need to remember the following:
Use "if ... end" to form a single branch of test steps.
Use "if ... else ... end" to form two branches of test steps.
Use "if ... else if ... else ... end" to form multiple branches of test steps.
Use JavaScript Boolean expression syntax to specify conditions to "if" and "else if" commands.
${variable} is allowed in condition expressions.
Here is a sample test called "Condition" on how to use variables:
1 execute script | return (new Date()).getDay(); | day
2 echo | ${day}
3 if | ${day} < 1
4 echo | Sunday
5 else if | ${day} > 5
6 echo | Saturday
7 else
8 echo Weekday
9 end
Here is the log output when you execute the above test.
1. executeScript on return (new Date()).getDay(); with value day OK
echo: 0
3. if on ${day} < 1 OK
echo: Sunday
5. elseIf on ${day} > 5 OK
7. else OK
9. end OK

CLLE SNDRCVF command not allowed

I am trying to compile this piece of CL code using Rational Series but keep getting error.
This is my CL code:
PGM
DCLF FILE(LAB4DF)
SNDRCVF RCDFMT(RECORD1) /* send, recieve file */
DOWHILE (&IN03 = '0')
SELECT
WHEN (&USERINPUT = '1' *OR &USERINPUT = '01') CALLSUBR OPTION1
OTHERWISE DO
*IN03 = '1'
ENDDO
ENDSELECT
ENDDO
SUBR OPTION1
DSPLIBL
ENDSUBR
ENDPGM
And this is my DSPF code
A R RECORD1
A 1 38'LAB 4'
A 3 3'Please select one of the following-
A options:'
A 6 11'3. Maximum Invalid Signon Attempt-
A s allowed'
A 8 11'5. Run Instructor''s Insurance Pr-
A ogram'
A 5 11'2. Signed on User''s Message Queu-
A e'
A 1 3'Yathavan Parameshwaran'
A 7 11'4. Initial number of active jobs -
A for storage allocation'
A 4 11'1. Previous sign on by signed on -
A user'
A 14 11'F3 = Exit'
A 14 31'F21 = Command Line'
A 2 70TIME
A 1 72DATE
A 9 11'Option: '
A USERINPUT 2 B 9 19
A 91 DSPATR(RI)
A 92 DSPATR(PC)
A MSGTXT1 70 O 11 11
A MSGTXT2 70 O 12 11
Is there a problem with my CL code or DSPF code?
You forgot to say what error you were getting. It's always important to put all the information about error messages into your questions.
There are two errors.
&IN03 is not defined
Your assignment to *IN03 should be to &IN03, but that's not how you do an assignment in CLP
If you want to be able to press F3, you have to code something like CA03(03) in the "Functions" for the record format.
To assign a variable in CL, code
CHGVAR name value
Looking at the documentation here, I suspect you need to add RCDFMT to your DCLF spec like so:
DCLF FILE(LAB4DF) RCDFMT(RECORD1)
SNDRCVF RCDFMT(RECORD1) /* send, recieve file */
If you really do only have 1 record format in your display file, then you can also omit the RCDFMT from both commands like so:
DCLF FILE(LAB4DF)
SNDRCVF /* send, recieve file */

Why does an argument $args after = sign not get expanded? ($args as parameter to jvm typical -D switch)

I have the following definition in my *profile.ps1 file:
if(Test-Path $env:M2_HOME){
function mvn{
$cmd = "$env:M2_HOME\bin\mvn.bat"
& $cmd $args
}
}
When I define a function using this function in powershell like:
function d { mvn help:describe $args }
using like:
d -Dplugin=jar
everything is fine as opposed to defining the latter as:
function d { mvn help:describe -Dplugin=$args }
using like:
d jar
Is there some builtin to handle this corner case?
It looks like you just need to make sure you're passing the arguments as strings and ensure they're evaluated first:
function mvn{
$cmd = "$env:M2_HOME\bin\mvn.bat"
& $cmd $args
}
function d { mvn "help:describe" "-Dplugin=$($args)" }
for get argument through call function you should use like this
function test {
write-host $args[0]
write-host $args[1]
}
test stackoverflow powershell
output
stackoverflow
powershell
stackoverflow is first argument passed to function and powershell is second argument passed to function
for every argument passed to function
function test {
foreach ($a in $args){
write-host "output:$args"
}
}
test 1 2 3 4 5 6 7 8
output:
test 1 2 3 4 5 6 7 8
output:1 2 3 4 5 6 7 8
output:1 2 3 4 5 6 7 8
output:1 2 3 4 5 6 7 8
output:1 2 3 4 5 6 7 8
output:1 2 3 4 5 6 7 8
output:1 2 3 4 5 6 7 8
output:1 2 3 4 5 6 7 8
output:1 2 3 4 5 6 7 8
for your function
if(Test-Path $env:M2_HOME){
function mvn{
$cmd = "$env:M2_HOME\bin\mvn.bat"
foreach ($arg in $args) {
& $cmd $args}
}
}
Someone seems to have made a similar observation:
The reason seems -D being a special character in powershell more or less marking where exactly each particluar special option string determined by -D ends, at least this modification to my calling function then works for me:
function x {mvn help:describe `-Dplugin=$args}
Sure it would be nice to handle such occasions in the hosting function somehow (mvn definition in my *profile.ps1), but that solutions rather seems out of scope of my question.

I dont understand this little perl code (if ...)

Can someone explain me this short pearl code?
$batstr2 = "empty" if( $status2 & 4 );
What say the if statement ?
Already answered many times, for the case if you don't know what is the Bitwise And, here is a small example:
perl -e 'print "dec\t bin\t&4\n";printf "%d\t%8b\t%-8b\n", $_, $_, ($_ & 4) for (0..8);'
prints:
dec bin &4
0 0 0
1 1 0
2 10 0
3 11 0
4 100 100
5 101 100
6 110 100
7 111 100
8 1000 0
as you can see, when the 3rb bit from right is 1 - the $num & 4 is true.
That's using the if as a statement modifier. It's roughly the same as
if ($status & 4) {
$batstr2 = "empty";
}
and exactly the same as
($status & 4) and ($batstr2 = "empty");
a variety of constructs can be used as statement modifiers, including: if, unless, while, until, for, when. These modifiers can't be stacked (foo() if $bar for #baz won't work), you are limited for one modifer per simple statement.
That's a bitwise and - http://perldoc.perl.org/perlop.html#Bitwise-And . $status2 is being used as a bit mask and it sets $batstr2 to 'empty' if the bit is set.
It sets $batstr2 to "empty" if the 3rd least significant bit of $status2 is set - it is a logical AND mask.

sed remove line containing a string and nothing but; automation using for loop

Q1: Sed specify the whole line and if the line is nothing but the string then delete
I have a file that contains several of the following numbers:
1 1
3 1
12 1
1 12
25 24
23 24
I want to delete numbers that are the same in each line. For that I have either been using:
sed '/1 1/d' < old.file > new.file
OR
sed -n '/1 1/!p' < old.file > new.file
Here is the main problem. If I search for pattern '1 1' that means I get rid of '1 12' as well. So for I want the pattern to specify the whole line and if it does, to delete it.
Q2: Automation of question 1
I am also trying to automate this problem. The range of numbers in the first column and the second column could be from 1 to 25.
So far this is what I got:
for ((i=1;i<26;i++)); do
sed "/'$i' '$i'/d" < oldfile > newfile; mv newfile oldfile;
done
This does nothing to the oldfile in the end. :(
This would be more readable with awk:
awk '$1 == $2 {next} {print}' oldfile > newfile
Update based on comment:
If the requirement is to remove lines where the two values are within 1 of each other:
awk '{d = $1-$2; if (-1 <= d && d <= 1) next; else print}' oldfile
Unfortunately, awk does not have abs() (at least nawk and gawk don't)
Just put the first number in a group (\([0-9]*\)) and then look for it with a backreference (\1). Since the line to delete should contain only the group, repeated, use the ^ to mark the beginning of line and the $ to mark the end of line. For example, for the following file:
$ cat input
1 1
3 1
12 1
1 12
12 12
12 13
13 13
25 24
23 24
...the result is:
$ sed '/^\([0-9]*\) \1$/d' input
3 1
12 1
1 12
12 13
25 24
23 24
You can also do it with grep:
grep -E -v "([0-9])*\s\1" testfile
Look for multiple digits in a row and remember them, followed by a single whitespace, followed by whatever digits you remembered.