Windows command line: setting global variables to each other - command-line

scenario further updated
Hi all:
I'm trying to set a global variable to another in windows command line batch language. The syntax I've tried is as below:
:: these are global vars
SET varThree=%varOne%\something
SET varOne=
SET varTwo=2
:Section
SET varOne=%varTwo%
::more setting of varOne to other global variables
GOTO Section2
:Section2
echo %varThree%
GOTO cleanup
:cleanup
SET varThree=
SET varTwo=
SET varOne=
The value of varOne seems to be lost when it comes to echoing %varThree%.
I was wondering how can I set the above variable properly?
TIA.
EDIT:
The cleanup section was there as a way to ensure the variables are being cleaned up upon exiting of the program. When I removed it, it took the 2nd run in order for varOne to lose its state. Likewise when I re-introduced it, it took the 2nd run for the state of varOne to come back. Any ideas why is this happening?

You don't use the percent signs on the left side.
Also, you might want to read about delay-expanded variables (like !varTwo! instead of %varTwo%), since you might run into problems with incorrect expansions.
See this link about delayed expansions: Cmd.exe Documentation
Edit: You're also missing a "Set" on the left, so this:
:Section
%varOne%=%varTwo%
Should really be:
:Section
Set varOne=%varTwo%

Try:
varOne=%varTwo%

You are wrong in looking for a "post-compiling" syntax.
In your scenario
SET varThree=%varOne%\something
cause varThree set with "\something", because varOne is not defined yet.
Speaking about your scenario, you have to use
echo %varOne%%varThree%
in ":section2".

Related

Cimplicity Screen - one object/button that is dependent on hundreds of points

So I have created a huge screen that essentially just shows the robot status for every robot in this factory (individually)… At the very end of the project, they decided they want one object on the screen that blinks if any of the 300 robots fault. I am trying to think of a way to make this work. Maybe a global script of some kind? Problem is, I do not do much scripting in Cimplicity, so any help is appreciated.
All the points that are currently used on this screen (to indicate a fault) have very similar names… as in, the beginning is the same… so I was thinking of a script that could maybe recognize if a bit is high based on PART of it's string name characteristic. The end will change a little each time, but I am sure there is a way to only look for part of a string and negate the rest. If the end has to be hard coded, that's fine.
You can use a Python script in Cimplicity.
I will not go into detail on the use of python in Cimplicity, which is well described in the documentation indicated above.
Here's an example of what can be done... note that I don't have a way to test it and, of course, this will work if the name of your robots in the declaration follows the format Robot_1, Robot_2, Robot_3 ... Robot_10 ... Robot_300 and it also depends on the Name and the Type of the fault variable... as you didn't define it, I imagine it can be an integer, with ZERO indicating no error. But if you use something other than that, you can easily change it.
import cimplicity
(...)
OneRobotWithFault = False
# Here you get the values and check for fault
for i in range(0, 300):
pointName = f'MyFactory.Robot_{i}.FaultCode'
robotFaultCode = cimplicity.point_get(pointName)
if robotFaultCode > 0:
OneRobotWithFault = True
break
# Set the status to the variable "WeHaveRobotWithFault"
cimplicity.point_set("WeHaveRobotWithFault", OneRobotWithFault)

Why doesn't the MoneyFormat script variable work?

The script variable MoneyFormat is supposed to control the default format used for the Money function. It doesn't seem to work.  Why is that?
Set MoneyFormat = '$#,##0.00;-$#,##0.00';
...
LOAD
Money(Revenue, '$#,##0.00;-$#,##0.00') AS Revenue1, // OK: $123,456.78
Money(Revenue, '$(MoneyFormat)') AS Revenue2, // OK: $123,456.78
Money(Revenue) AS Revenue3, // Wrong: $123456.78
...
Edit:
I don't know how much of this is relevant, but to be clear, here are all of my settings instead of just MoneyFormat:
SET ThousandSep=',';
SET DecimalSep='.';
SET MoneyThousandSep=',';
SET MoneyDecimalSep='.';
SET MoneyFormat='$#,##0.00;-$#,##0.00';
SET TimeFormat='h:mm:ss TT';
SET DateFormat='M/D/YYYY';
SET TimestampFormat='M/D/YYYY h:mm:ss[.fff] TT';
SET FirstWeekDay=6;
SET BrokenWeeks=1;
SET ReferenceDay=0;
SET FirstMonthOfYear=1;
SET CollationLocale='en-US';
SET CreateSearchIndexOnReload=1;
SET MonthNames='Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec';
SET LongMonthNames='January;February;March;April;May;June;July;August;September;October;November;December';
SET DayNames='Mon;Tue;Wed;Thu;Fri;Sat;Sun';
SET LongDayNames='Monday;Tuesday;Wednesday;Thursday;Friday;Saturday;Sunday';
EDIT: Doesn't work after all.... See comments
This looked like a simple problem, but it took me quite a while to actually solve it since the documentation doesn't really help at all.
The solution should be:
Replace this:
Set MoneyFormat = '$#,##0.00;-$#,##0.00';
with this:
Set MoneyDecimalSep='.';
Set MoneyThousandSep=',';
Set MoneyFormat='$ #,##0.00;$ -#,##0.00';
So in the end it's quite simple. I solved it by looking at the variable MoneyFormat and after a while I noticed the important difference between $ and € numbers and this took me to the missing variables.

SQL variables and the IF statement

I am using T-SQL in SQLCMD mode in SSMS to run various subfile from one file, and the principle file (princ.sql) is where I need to declared and set a variable #MyInteger and run a subfile:
DECLARE #MyInteger INT
SET #MyInteger = 20
:setvar path "your absolute file path here"
:r $(path)\"query.sql"
:r $(path)\"uses Myingteger too.sql"
This works fine; as a minimal example, consider query.sql and 'uses MyInteger too.sql' to have the same one line
SELECT #MyInteger
and i do get back two instances of 20.
My trouble is that I would like to be able to run query.sql on its own using a locally defined variable #SubMyInteger.
My ideal situation for query.sql is
IF #MyInteger is declared
SET #SubMyInteger = #MyInteger
ELSE
SET #SubMyInteger = 90
SELECT #SubMyInteger
Then when I run query.sql, #MyInteger would not have been declared, so #SubMyInteger would be assigned 90, and 90 would be returned. I would also get back two 20s as before if i ran princ.sql
For the IF statement, I have so far tried two things:
IF OBJECT_ID('#MyInteger') IS NOT NULL
and
IF #MyInteger IS NOT NULL
I get the error
Must declare scalar variable "#MyInteger".
If I try declaring #MyInteger and then run princ.sql, I get the error
The variable '#MyInteger' has already been declared.
even if the declare statement is conditioned with an IF.
Is there a way to achieve what I want here?
Thanks

Macro name expanded from another macro in makefile

I have a makefile with the following format. First I define what my outputs are;
EXEFILES = myexe1.exe myexe2.exe
Then I define what the dependencies are for those outputs;
myexe1.exe : myobj1.obj
myexe2.exe : myobj2.obj
Then I have some macros that define extra dependencies for linking;
DEP_myexe1 = lib1.lib lib2.lib
DEP_myexe2 = lib3.lib lib4.lib
Then I have the target for transforming .obj to .exe;
$(EXEFILES):
$(LINK) -OUT:"Exe\$#" -ADDOBJ:"Obj\$<" -IMPLIB:$($($(DEP_$*)):%=Lib\\%)
What I want to happen is (example for myexe1.exe)
DEP_$* -> DEP_myexe1
$(DEP_myexe1) -> lib1.lib lib2.lib
$(lib1.lib lib2.lib:%=Lib\\%) -> Lib\lib1.lib Lib\lib2.lib
Unfortunately this is not working. When I run make --just-print, the -IMPLIB: arguments are empty. However, if I run $(warning DEP_$*) I get
DEP_myexe1
And when I run $(warning $(DEP_myexe1)) I get
lib1.lib lib2.lib
So for some reason, make does not like the combination of $(DEP_$*). Perhaps it cannot resolve macro names dynamically like this. What can I do to get this to work? Is there an alternative?
Where does $(warning DEP_$*) give you DEP_myexe1 as output exactly? Because given your makefile above it shouldn't.
$* is the stem of the target pattern that matched. In your case, because you have explicit target names, you have no patten match and so no stem and so $* is always empty.
Additionally, you are attempting a few too many expansions. You are expanding $* to get myexe1 directly (assuming for the moment that variable works the way you intended). You then prefix that with DEP_ and used $(DEP_$*) to get the lib1.lib lib2.lib. You then expand that result $($(DEP_$*)) and then expand that (empty) result again (to do your substitution) $($($(DEP_$*)):%=Lib\\%).
You want to either use $(#:.exe=) instead of $* in your rule body or use %.exe as your target and then use $* to get myexe1/myexe2.
You then want to drop two levels of expansion from $($($(DEP_$*)):%=Lib\\%) and use $(DEP_$*:%=Lib\\%) instead.
So (assuming you use the pattern rule) you end up with:
%.exe:
$(LINK) -OUT:"Exe\$#" -ADDOBJ:"Obj\$<" -IMPLIB:$(DEP_$*:%=Lib\\%)
I managed to get it working without needing to resolve macros in the way described above. I modified the linking dependencies like this;
myexe1.exe : myobj1.obj lib1.lib lib2.lib
myexe2.exe : myobj2.obj lib3.lib lib4.lib
Then I need to filter these files by extension in the target recipe;
$(EXEFILES):
$(LINK) -OUT:"$(EXE_PATH)\$#" -ADDOBJ:$(patsubst %, Obj\\%, $(filter %.obj, $^)) -IMPLIB:$(patsubst %, Lib\\%, $(filter %.lib, $^))
The $(pathsubst ...) is used to prepend the path that the relevant files are in.
In the case of myexe1.exe, the link command expands to;
slink -OUT:"Exe\myexe1.exe" -ADDOBJ: Obj\myexe1.obj -IMPLIB: Lib\lib1.lib Lib\lib2.lib
Out of interest's sake, I would still like to know if it is possible to resolve macro names like in the question.

Can a list of strings be supplied to Capistrano tasks?

I have a task whose command in 'run' is the same except for a single value. This value would out of a list of potential values. What I would like to do is create a task which would use this list of values to define the task and then use that same value in the command defined in 'run'. The point is that it would be great to define the task in such a way where I don't have to repeat nearly identical task definitions for each value.
For example: I want a task that will get the status of a single program from a list of programs that I have defined in an array. I would like to define task to be something like this:
set programs = %w["postfix", "nginx", "pgpool"]
programs.each do |program|
desc "#{program} status"
task :#{program} do
run "/etc/init.d/#{program} status"
end
end
This obviously doesn't work, but hopefully it shows what I am attempting here.
Thoughts?
Well, I answered my own question... with a little trial and error. I also did the same thing with namespace so the control of services is nice and elegant. It works quite nicely!
set :programs, %w[postfix nginx pgpool]
set :init_commands, %w[status start stop]
# init.d service control
init_commands.each do |init_command|
namespace :"#{init_command}" do
programs.each do |program|
desc "#{program} #{init_command}"
task :"#{program}" do
run "/etc/init.d/#{program} #{init_command}"
end
end
end
end