Nested conditionals in makefiles - if-statement

A makefile here has nested if statements to assign variable values and targets to be built.
The current nested structure isn't really a nest - it is a series of if statements:
There isn't any use of else.
Is this because makefiles don't have an equivalent of elseIf?
Current structure (indentations added for readability in this post)
If condition x
if condition x.x
blah
endif
if condition x.y
blah blah
endif
endif
if condition y
if condition y.x
blah
endif
if condition y.y
blah blah
endif
endif
Pseudocod-ish version of desired structure:
If condition x
if condition x.x
blah
else
if condition x.y
blah blah
endif
else
if condition y
if condition y.x
blah
else
if condition y.y
blah blah
endif
endif

Does this answer your question?
ifeq ($(VAR1),x)
ifeq ($(VAR2),x)
$(info x.x)
else ifeq ($(VAR2),y)
$(info x.y)
endif
else ifeq ($(VAR1),y)
ifeq ($(VAR2),x)
$(info y.x)
else ifeq ($(VAR2),y)
$(info y.y)
endif
endif
all:;
Demo:
$ make VAR1=x VAR2=y
x.y
make: 'all' is up to date.
But you can also:
ifeq ($(VAR1).$(VAR2),x.x)
$(info x.x)
else ifeq ($(VAR1).$(VAR2),x.y)
$(info x.y)
else ifeq ($(VAR1).$(VAR2),y.x)
$(info y.x)
else ifeq ($(VAR1).$(VAR2),y.y)
$(info y.y)
endif
all:;
Demo:
$ make VAR1=y VAR2=x
y.x
make: 'all' is up to date.
For more information the best source is the GNU make manual, section Syntax of Conditionals.

Related

HMI macro of if-else statement

I want to use buttons in HMI screen to control the plc. The result should be when I turn on one of the button and another one will be turned off. What should I type in the screen cycle macro in order to make the function work?
Buttons in HMI and screen for macro
Because you didn't specify the model or brand of the HMI, and I couldn't identify it from the image and the code doesn't seem to be standardized as ST from IEC-61131, I'll put it as a "pseudo-code", so you'll have to adjust it according to the correct syntax.
//Declare as global or equivalent, or use a PLC memory
Bool oldM3
Bool oldM4
//------- Run cycllic --------
//Get the transition of M3
IF NOT oldM3 AND M3 THEN
oldM3 = true
M4 = false
ENDIF
IF NOT M3 THEN
oldM3 = false
ENDIF
//Get the transition of M4
IF NOT oldM4 AND M4 THEN
oldM4 = true
M3 = false
ENDIF
IF NOT M4 THEN
oldM4 = false
ENDIF

Wrapping long text sections in Jinja2

I have the definition of a variable, it's name and an associated comment in a YAML file and am trying to use Jinja2 to create an appropriate target file; in this case a proprietary config file
...
- comment: >
This is a comment which will almost certainly end up longer than standard eighty characters or at least on the occasion on which it does.
name: my_useful_variable
value: /a/long/example/path/to/my/file.txt
I would like this text to be rendered as follows:
# This is a comment which will almost certainly end up
# longer than standard eighty characters or at least on
# the occasion on which it does.
my_useful_variable = "/a/long/example/path/to/my/file.txt"
Does Jinja2 have any way of wrapping text so that the long comment line is limited in length and split over however many lines is necessary?
So far I have:
# {{item.comment}}
{{item.name}} = "{{item.value}}"
But this of course does not deal with the length of the comment.
Solution
Following on from the answer provided by #blhsing below, I came up with the following macro, which works fine for basic variables and simple lists (i.e. not dictionaries or more complex hierarchical data structures:
{% macro set_params(param_list, ind=4, wid=80) -%}
{% for item in param_list %}
{% if item.comment is defined %}{{item.comment|wordwrap(wid - ind - 2)|replace('', ' ' * ind +'# ', 1)|replace('\n', '\n' + ' ' * ind + '# ')}}
{% endif %}
{% if item.value is iterable and item.value is not string %}{{item.name|indent(ind, True)}} = [ {% for item_2 in item.value %}{{item_2}}{{ ", " if not loop.last else " " }}{% endfor %}{% else %}{{item.name|indent(ind, True)}} = {{item.value}}{% endif %}
{% endfor %}
{%- endmacro %}
To use this, simply pass a list of items similar to the spec given at the top together with the indentation and the page width.
A bit of explanation:
Line 3, If comment is defined then it is word wrapped to the correct length bearing in mind the width and the indent. The first replace deals with indenting the first line and the second indents subsequent lines. All prefixed with '# '
Line 5, depending on whether the variable is simple or iterable, it is rendered in the form name = value or name = [ value1, value2, value3 ]
Of course, it is not fool-proof but it meets my basic requirements.
You can prepend the given string with a newline character, then use the wordwrap filter to wrap the text into multiple lines first, and use the replace filter to replace newline characters with newline plus '# ':
{{ ('\n' ~ item.comment) | wordwrap(78) | replace('\n', '\n# ') }}
The above assumes you want each line to be no more than 80 characters. Change 78 to your desired line width minus 2 to leave room for '# '.
If you're doing this in Ansible, another option is to use the Ansible comment filter:
{{ item.comment | wordwrap(78) | comment }}
or, for more detailed control
{{ item.comment | wordwrap(78) | comment(decoration="# ", prefix="", postfix="") }}
Docs: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#adding-comments-to-files

AHK help regarding RegExReplace

I need assistance with RegExReplace in AHK.
I want my script to search text and keep only numbers after $ sign.
Right now I have:
F1::
Clipboard =
SendInput, ^c
ClipWait
Variable := Clipboard
NewVar := RegExReplace(Variable,"[^.0-9]+", "{+}")
send % NewVar
return
For example if text is "unit $400 unit 500 $400" I get 400+500+400+
What I would like to get is "400+400+"
I havent been able to figure out how to exclude numbers that dont have $ and I am not sure RegEx is the best thing to use here.
Any help would be great!
This is the final version, that does what I need. Thank you all for advise!!!
F1::
Clipboard =
SendInput, ^c
ClipWait
Pos := 1
While Pos {
Pos:=RegExMatch( Clipboard, "\$(\d+(?:\.\d+)?)", M, Pos+StrLen(M1) )
Match%A_Index% := M1
M2 := M2 Match%A_Index% "{+}"
}
Send % "=sum(" M2
Send {BS}{BS}){enter}
M2 :=
return
NewVar := RegExReplace(Variable, "^.*?\s\$")
NewVar := RegExReplace(NewVar, "\s.*?\$", "+")
I don't know how to do this with RegExReplace, but I can suggest an example using the RegExMatch function.
Unfortunately, AutoHotkey doesn't support the /g/ flag for the global searching, so you have to use a loop to search all values you need.
#NoEnv
SendMode Input
F1::
Clipboard =
SendInput, ^c
ClipWait
i := 1
while pos := RegExMatch(Clipboard, "\$(\d+)", match, i)
{
i += pos
sendinput % match1 "{+}"
}
; sendinput {backspace} ; uncomment this line if you want the last PLUS character to be removed
return

doxygen equations not appearing correctly

I am having some issues with doxygen. I am trying to include an inline formula:
blah blah \f$ x \in [0,1] \f$ blah blah
but the html looks like
blah blah \( x \in [0,1] \) blah blah
Does anyone know why? If it helps:
EXTRA_PACKAGES = mathtools amsmath
USE_MATHJAX = YES
Make sure you have latex installed and verify whether you have these configurations on your Doxygen file:
GENERATE_LATEX = YES
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex #latex command name to be called from terminal

How can I convert a list of .png to a list of pdf in makefile?

I want to loop over a list of .png files and convert them to a corresponding pdf file:
PICLIST = $(sort $(wildcard pic??.png))
all:
for i in $(PICLIST) ; do \
convert -resize 80% $$i $(wildcard pic??.pdf) ; \
done
but i got some errors as follow:
for i in pic01.png pic02.png pic03.png ; do \
convert -resize 80% $i ; \
done
convert: no images defined `pic01.png' # error/convert.c/ConvertImageCommand/3145.
The problem is you're trying to use $(wildcard ...) inside the recipe. Make will always expand all variables inside the recipe before it starts the shell that will run the recipe, and before the for-loop starts there are no .pdf files, so the wildcard function expands to nothing. This gives you an illegal command line for convert.
Also I don't see how you can have 1000 pictures if they're numbered 00 to 99 (your wildcard only matches two characters--maybe they use letters as well?)
However, why are you even using a makefile here? You just have one target, that runs one command (a for loop). Why don't you just write a shell script instead of a makefile?
If you want to do it the "make way" where each time a .png file is modified that, and only that, image is converted to a .pdf, then you have to do something like this:
CONVERTFLAGS := -resize 80%
PICLIST := $(wildcard pic??.png)
PDFLIST := $(PICLIST:%.png=%.pdf)
all: $(PDFLIST)
%.pdf : %.png
convert $(CONVERTFLAGS) $< $#