Notifications
Clear all

[Closed] canExecute??

 PEN

OK I need a way to know if I can execute a string without getting an error.

If I execute:

execute "test"

it will return undefined.

if I execute:

execute "test this"

I get an error.

if I execute:

execute "testthis"

it returns undefined again. So it looks as though the space causes the problem…how ever…

if I execute:

execute "2 + 2"

I get the value 4. So the spaces are not the issue.

I need a way to know that I can execute a string. I would prefer not to use a try()catch()

Any ideas?

11 Replies

I don’t think there’s any way to check if any given string contains a valid expression. You could, however, validate the string against a fixed list of valid expressions (very much like how the old text adventures work), by splitting the input string using spaces, and validating each word in the array by a custom parser function.

For example if an expression contains two words, and the first word is go, the second word can only be north, east, south or west.

I can’t really think of another way to tackle this. Aside from using try/catch ofcourse. There are simple too many possibilities.

Hope this helps,
Martijn

If it’s just simple stuff, perhaps you could filterString the string into it’s component parts, filter out operators, then test for defined strings, or numbers. But it would probably fail on anything other than quite simple expressions, e.g.

“2 + 7” – OK: 2 and 7 are defined
“print $sphere01” – OK: “print” and “$sphere01” are defined
“s = sphere pos:[10,10,10]” – FAIL: “pos” would be undefined.

What’s the reasoning behind the question? Perhaps there’s a compromise?

 PEN

Thanks guys.

What I’m writting is a very general data file reader. It is using something similar to XML, really it is XML but I want to be able to store any data I may need in the future with it in a hierarchy based format.

When the file is read in I’m reading the tags and any parameters in the tags. I’m then creating a struct from that data and storing it in a hierarchy. This can then be recursed and the data used. If a parameter is a value I want to convert it to a value like 100 instead of “100”, or true instead of “true”. How ever is the value of one of the parameters is a string then I can’t execute it.

I could just store all the parameters as strings and leave it up to the final script. That way I would know what parameters should be executed and which shouldn’t. If I did it this way I wouldn’t end up with the problem of wanting “true” to remain as a string and not a boolean value.

The later is safer but it takes more work when using it. What do you think, leave it all as strings or execute the values using a try()catch()?

1 Reply
(@johnswafford)
Joined: 1 year ago

Posts: 0

I’m not sure if this is useful to you, but the code below is a partial example of an approach my script uses to safeguard against invalid setting strings being retrieved from an INI file.

LoadSettingsFromINI =
(
local Str, AsBol, AsInt, AsFlt
Settings[1] =
(
Str = (LoadSettFromINI “MyRollout” “MaxR3Clone”)
if ((AsBol = (Str==“true”))OR(Str==“false”)) then AsBol else false
–“as booleanClass” String-to-Boolean Coercion was added in
–max 7, so this conversion could be done in a different way
)
Settings[2] =
(
Str = (LoadSettFromINI “MyRollout” “CloneType”)
if ((Str.count!=0)AND
((classOf (AsInt = (try (Str as integer) catch (undefined))))==Integer)AND
(AsInt>0)AND
(AsInt<4)) then AsInt else 3
)
Settings[3] =
(
Str = (LoadSettFromINI “MyRollout” “StandoffDist”)
if ((Str.count!=0)AND
((classOf (AsFlt = (try (Str as float) catch (undefined))))==Float)AND
(AsFlt>=1.1)AND
(AsFlt<=10000)) then AsFlt else 1.5
)
)

If the strings are not valid boolean/integer/float strings, then default values are used instead. This approach might allow you to convert from strings safely…

Paul,

Execute() is similar to FileIn(), it only operates on a string instead of a filestream.
So anything that is a valid MAXScript expression can be executed. If “test” happens to be defined as a global variable, you woudn’t get undefined but the value stored in the variable.
Since “test this” is not a valid expression, it would fail. However, “test = this” would work as it would assign the value from one undefined variable to another.

If you really have to use execute(), use try()catch().

 PEN

Thanks bobo. I think that I’m going for the latter. Now I’m just trying to get my hierarchy right and my head just isn’t into it.

For simplicity’s sake, you could go with try/catch, however if you’re writing the data in the first place as XML I would just include a “type” attribute on the exported node, and cast the variable on the import.

<data>
  	<value type="boolean">true</value>
   	<value type="number">10</value>
   </data>

or

<data>
  	<boolean>true</boolean>
   	<number>10</number>
   </data>

That way you’re not only flexible, but in control.

 PEN

I thought about going with the type param, I guess I could then assume it is a string if it hasn’t been added.

 eek

Why dont you filter the string into an array? if the space is the key to determining whether its a string or not:

stringCheck =#(“a”,“b”,“c”,“d”,“e”,“f”,“g”,“h”,“i”,“j”,“k”,“l”,“m”,“n”,“o”,“p”,“q”,“r”,“s”,“t”,“u”,“v”,“w”,“x”,“y”,“z”)

string = “this test”
executeState = true

for i = 1 to string.count do
(
for n = 1 to stringCheck.count do
(
if string[i] != stringCheck[n] do
executeState = false
exit
)
)

if (executeState == true) do
(
execute string
)

you could also do a filterstring to determine what the string is made of:

filteredString = (filterString “this test” ” “)

then go through each letter and check if its a letter or not = string. You’d have to set a ton of rules though.

The spaces are really the dealbreaker though for the filterstring approach because this would execute fine:

 
bob = 24 
mike = 4
jones = 24 + Bob --(Jones = 48)
Jill = bob + mike --(Jill = 28)

So would:


jones = quat 10 34 2 100

otherwise you could check to see if there are spaces and no *-+/ math values.

Another problem would be checking strings…


jones = "captain picard rocks your socks"

…would execute but…


jones = "captain picard rocks your socks

…would error out. I must admit though… why do you have so little control over what you execute? Couldn’t you control this easier on the data file creation end? Garbage in Garbage out and all that. Just what all might try to get executed that you don’t know about?

Page 1 / 2