String expression artefact

General Macro Scheduler discussion

Moderators: JRL, Dorian (MJT support)

Post Reply
observer
Junior Coder
Posts: 44
Joined: Tue Aug 18, 2009 7:55 pm

String expression artefact

Post by observer » Sun Oct 18, 2009 9:59 am

Hi,
Just run the code below.

Code: Select all

Let>a=Hello everybody
Let>b={"a"}
MDL>%b%
MDL> %b%
This artefact makes difficulties when RegistryWriteKey command is used.

gdyvig
Automation Wizard
Posts: 447
Joined: Fri Jun 27, 2008 7:57 pm
Location: Seattle, WA

Workaround

Post by gdyvig » Sun Oct 18, 2009 1:21 pm

Hi observer,

When I originally replied, I thought it looked like something needed fixing. But I now believe it is working as designed.

These 2 statements are equivalent:
Let>b={"a"}
Let>b=a

The system variable VAREXPLICIT tells Macro Scheduler whether to interpret a string as data or as a variable. If VAREXPLICIT is 0, Macro Scheduler attempts to interpret the string as a variable. If the variable has not already been defined it treats the string as data. The default value for VAREXPLICIT is 0, therefore the behavior you are seeing.

One of the reasons for VAREXPLICIT 0 is to help out newbies by not requiring the use of percent (%) around variables. Makes the script look simpler and cleaner. Another more powerful reason is to be able to read variable names from files and convert them to their values.

Complex expressions and some commands (like MDL) default to VAREXPLICIT 1.


This workaround should help:

Code: Select all

//VAREXPLICIT 0 implied
Let>a=Hello everybody
Let>b={"a"}
MDL>%b%
MDL> %b%
MDL>b:%b%
Let>VAREXPLICIT=1
MDL>%b%
MDL> %b%
MDL>b:%b%


Gale

observer
Junior Coder
Posts: 44
Joined: Tue Aug 18, 2009 7:55 pm

Post by observer » Sun Oct 18, 2009 9:59 pm

Hi Gale,
1. Why does the command interpreter change the behaviour when an extra space is used?
If I utilize %% symbols I expect to get the same result in both cases (%b% and %SPACE%%b%). How does interpreter distinguish the "final" variable value (Hello everybody) from "intermediate" value (a)
2. Suppose I have the result of third party app password crypting. Something like this:
{~@%$#*!?} (this is random string! not the expression)
I need to write this string to Windows registry.
So, I make the code...
///
Let>MyPass={~@%$#*!?}
Let>REG_INTASSTR=1
RegistryWriteKey>HKEY_CURRENT_USER,TestMacro,UserPass,MyPass
///
... then I run it ... and I get syntax error.

Further, I run this one...
///
Let>MyPass={~@%$#*!?}
Let>REG_INTASSTR=1
RegistryWriteKey>HKEY_CURRENT_USER,TestMacro,UserPass,%MyPass%
///
... and I get syntax error

Next try...
///
Let>MyPass={"{~@%$#*!?}"}
Let>REG_INTASSTR=1
RegistryWriteKey>HKEY_CURRENT_USER,TestMacro,UserPass,%MyPass%
///
... fail again!

Finally, this one...
///
Let>MyPass={"{~@%$#*!?}"}
Let>REG_INTASSTR=1
RegistryWriteKey>HKEY_CURRENT_USER,TestMacro,UserPass,MyPass
///
... and (WOW!) I meet with success!
I am just wondering what logic is used by the command interpreter?

gdyvig
Automation Wizard
Posts: 447
Joined: Fri Jun 27, 2008 7:57 pm
Location: Seattle, WA

Post by gdyvig » Sun Oct 18, 2009 10:40 pm

Hi Observer,
1. Why does the command interpreter change the behaviour when an extra space is used?
I did get the same behavior for these two cases:
MDL>%b%
MDL> %b%

But you will get different behavior for these three cases:
Let>b=Hello Venus
Let> b=Hello Mars
Let> b =Hello Jupiter

The reason:
Leading, embedded, and trailing spaces can be part of a variable name. If you do not want this behavior, set the system variable IGNORESPACES to 1.
How does interpreter distinguish the "final" variable value (Hello everybody) from "intermediate" value (a)



If VAREXPLICIT=0:

Let>a=Hello everybody
//a is a variable
Let>b=a
//interpretter asks is "a" a variable?
//It is, so it says Let>b=%a%
//which expands to "Hello everybody"

For unambiguous handling of variables you should use VAREXPLICIT 1 for most of your script and use VAREXPLICIT 0 only when you need its special capabilities.


Will check the remaining questions later.

Recommend you use VAREXPLICIT 1.
2. Suppose I have the result of third party app password crypting. Something like this:
{~@%$#*!?} (this is random string! not the expression)
I need to write this string to Windows registry.
So, I make the code...
///
Let>MyPass={~@%$#*!?}
Let>REG_INTASSTR=1
RegistryWriteKey>HKEY_CURRENT_USER,TestMacro,UserPass,MyPass
///
... then I run it ... and I get syntax error.
You indicate the braces are part of the password.

So this is incorrect because braces indicate a complex expression:
Let>MyPass={~@%$#*!?}

And this is correct:
Let>MyPass={"{~@%$#*!?}"}

With that value for MyPass and VAREXPLICIT 0 I would have expected the last 2 of your statements to work, not just the last one.


RegistryWriteKey>HKEY_CURRENT_USER,TestMacro,UserPass,MyPass
and
RegistryWriteKey>HKEY_CURRENT_USER,TestMacro,UserPass,%MyPass%
should provide the same result
Are you sure you removed trailing spaces on all statements?


Gale

observer
Junior Coder
Posts: 44
Joined: Tue Aug 18, 2009 7:55 pm

Post by observer » Mon Oct 19, 2009 8:42 am

Hi Gale,
Are you sure you removed trailing spaces on all statements?
Just run this code

Code: Select all

Let>MyPass={"{~@%$#*!?}"}
MDL>%MyPass%

User avatar
Marcus Tettmar
Site Admin
Posts: 7395
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Post by Marcus Tettmar » Mon Oct 19, 2009 10:39 am

Do this:

Code: Select all

Let>MyPass={"{~@%$#*!?}"}
MDL>MyPass
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

observer
Junior Coder
Posts: 44
Joined: Tue Aug 18, 2009 7:55 pm

Post by observer » Mon Oct 19, 2009 11:25 am

Hi Marcus,
Do this:
Let>MyPass={"{~@%$#*!?}"}
MDL>MyPass
What's wrong with my example? If it is correct why the error occured?

So, try to find any workaround to resolve this issue:

Code: Select all

PutClipBoard>{~@%$#*!?}
GetClipBoard>RandomPass
Let>MyPass={"RandomPass"}
MDL>Generated(crypted) password is  %MyPass%
MDL>Generated(crypted) password is  MyPass

User avatar
Marcus Tettmar
Site Admin
Posts: 7395
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Post by Marcus Tettmar » Mon Oct 19, 2009 2:36 pm

When you use @ symbols the interpreter recursively tries to resolve the variable character by character and will treat { } as complex expressions.

Code: Select all

PutClipBoard>{"{~@%$#*!?}"}
GetClipBoard>RandomPass
Let>MyPass=RandomPass
MDL>Generated(crypted) password is  %MyPass%
MDL>Generated(crypted) password is  MyPass
As Gdyvig said eaerlier, since your string starts and ends with { and } you will need to tell Macro Scheduler it's a string not a complex expression. So the issue is how you set the value onto the clipboard. The above solves the issue.

Your last line sees MyPass as a string because it is not in % symbols.

You don't need the Let>MyPass=RandomPass bit you could just do:

Code: Select all

PutClipBoard>{"{~@%$#*!?}"}
GetClipBoard>RandomPass
MDL>Generated(crypted) password is  %RandomPass%
Different version with the user being asked for the value instead:

Code: Select all

Input>inp_pass,Enter a password beginning with { and ending in }
PutClipBoard>inp_pass
GetClipBoard>RandomPass
MDL>Generated(crypted) password is  %RandomPass%
All the above work fine.

The issue you had was that you needed to force the {...} to be a string not an expression and the way to do that is to put it inside quotes.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

observer
Junior Coder
Posts: 44
Joined: Tue Aug 18, 2009 7:55 pm

Post by observer » Mon Oct 19, 2009 4:09 pm

Hi Marcus,
Content of target string is unpredictable and I get it from other application. I had used PutClipBoard and GetClipBoard commands to demonstrate the string content is predefined. So, there is no way to use correct format of PutClipBoard command, because of GetClipBoard/ReadLn/RegistryReadKey commands are utilized only.
Suppose I get the content of the string from Clipboard. So, I need to save this string in text file with some comments. Something like this:

Code: Select all

// I get unpredictable string content from clipboard
GetClipBoard>RandomPass

// I set MyPass variable to be sure this data will be interpret as a string
Let>MyPass={"RandomPass"}

// Then I save this variable in text file
WriteLn>C:\SavedPass.txt,nWLNRes,Generated password is %MyPass%
This method don't let me to save the real password. And this is the issue.

Actually, this is not a great problem if you don't need any comments. So, in that case the last command will be
WriteLn>C:\SavedPass.txt,nWLNRes,%MyPass%
... and it works fine.

gdyvig
Automation Wizard
Posts: 447
Joined: Fri Jun 27, 2008 7:57 pm
Location: Seattle, WA

Post by gdyvig » Mon Oct 19, 2009 7:45 pm

Hi observer,

Try this:

Code: Select all

// I get unpredictable string content from clipboard
GetClipBoard>RandomPass

// I set MyPass variable to be sure this data will be interpret as a string
Let>MyPass={%RandomPass%}

// Then I save this variable in text file
WriteLn>C:\SavedPass.txt,nWLNRes,Generated password is %MyPass%
Because RandomPass is meant to be a variable name it should be enclosed in percents rather than quotes.

While WriteLn has no problems with %MyPass%, MDL does depending on what special characters it contains. So for MDL you take the percents off.

Gale

observer
Junior Coder
Posts: 44
Joined: Tue Aug 18, 2009 7:55 pm

Post by observer » Tue Oct 20, 2009 7:44 am

Hi Gale,
Because RandomPass is meant to be a variable name it should be enclosed in percents rather than quotes.
So, there is no need to use MyPass variable at all. The code below works fine.

Code: Select all

// I get unpredictable string content from clipboard
GetClipBoard>RandomPass

// Then I save this variable in text file
WriteLn>C:\SavedPass.txt,nWLNRes,Generated password is %RandomPass%
Actually, I am just trying to attract your attention to inconsequent behaviour of command interpreter.

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts