• Support
  • Articles
  • Resources
  • Products

TeraTerm Macro language for dummies (or something like that)

Moderator: boris

6 postsPage 1 of 1

rgaiken
Beginner

Posts:
42
Joined: Mon Apr 02, 2012 2:53 pm
by rgaiken » Mon Oct 22, 2012 2:45 am
So I'm attempting to consolidate what I know of the TeraTerm language into a single mega-post. If you have any knowledge that you think would be a valuable addition to this post, feel free to let me know.

Note that this is pretty much just an abridged form of the language reference tied into a somewhat cohesive format. Just because something isn't mentioned here doesn't mean it doesn't exist; check out the official language reference and search the forums to get a handle on some of TeraTerm's more advanced features. This is really not a full-fledged tutorial to take you from the very basics of computer literacy; if you have no prior programming experience this may be challenging to follow.

As a little precursor, if you happen to use Programmer's Notepad as your editor of choice, the NSIS Installer highlighting scheme matches fairly well with this scripting language. Vim users might be able to make use of this highlighting scheme (somewhat outdated, won't have latest keywords).

TeraTerm basics

So to start things off, let's deal with variables.

There are two types of variables: Strings (limited to 255 characters) , and Integers (Limited to ~ +/-2 billion) (want to go bigger?). The type is determined implicitly when the variable is created and cannot be altered afterwards.

Also, since TeraTerm 4.72, there are now arrays of both of these types (limited to 65536 indices per array)

Code: Select all

  1. integerVariable=10 ; An Integer variable
  2. strVariable='asdf' ; A string variable
  3. strVariable2='0' ; Still a string variable
  4. integerVariable='asdf' ; ERROR!!!!!!
  5. integerVariable=2
  6. ; A little fun with arrays:
  7. intdim integerArray 10 ; Create an integer array of size 10
  8. integerArray[0]=10 ; Assigns the first element of the array to 0
  9. integerArray[10]=10 ; ERROR!!!!!
  10. ; It's almost exactly the same for strings, just using strdim instead:
  11. strdim strArray integerVariable ; Creates a string array that has the size given in integerVariable
  12. ; Also, by the way, the semicolon (;) is the character that denotes a comment; anything after it in a line has no effect on the running of your script (notice how I used the semicolon in a grammatically correct way in a sentence about semicolons ;-)


But variables by themselves are boring. The real basis of any programming language is the if statement. However an if statement by itself is somewhat boring, so let's go a little further and also show you a wait statement:

Code: Select all

  1. wait 'value = 0' 'ERROR'
  2. if result=1 then
  3. ; value = 0 was received on the terminal
  4. elseif result=2
  5. ; ERROR was received on the terminal
  6. endif


The wait statement is one of the more or less unique features of TeraTerm. Essentially, it reads through all of the serial output that hasn't been parsed yet, and when one of the strings in its sensitivity list is found, it sets result to the index of that string and moves on. The documentation for the setsync command has a partial general overview for how TeraTerm internally works.

Note that you can also set a timeout for wait, and it will then only hold up the execution of the script for at most timeout.mtimeout seconds:

Code: Select all

  1. timeout=1
  2. mtimeout=500 ; Set the timeout for 1.5 seconds
  3. wait 'Good' 'Bad'
  4. if result=0 then
  5. ; Neither good nor bad appeared in the terminal output during the 1.5 seconds
  6. endif


A nice counterpoint to the 'wait' command is the 'sendln' and 'send' commands. These guys do pretty much what their names suggest: they write stuff back out to the terminal (with sendln adding a newline at the end of its string).
A common use that I have for the wait/sendln pair is to send a series of commands to a machine.
For example, when sending a series of commands to a Linux box, it might look something like the following:

Code: Select all

  1. wait 'root@localhost#'
  2. sendln 'command'
  3. wait 'root@localhost#'
  4. sendln 'command'
  5. wait 'root@localhost#'
  6. sendln 'command'

This ensures that the prior command has finished before you send the next command. The sendkcode command is also occasionally useful in some cases.

Note that the above code is somewhat ugly. If the prompt were to change (say from root@localhost to root@servername), I'd have to manually replace a bunch of lines. Since I'm lazy, the following format is much nicer:

Code: Select all

  1. cmdPrompt='root@localhost'
  2. wait cmdPrompt
  3. sendln 'command'
  4. wait cmdPrompt
  5. sendln 'command'
  6. wait cmdPrompt
  7. sendln 'command'

That looks much nicer.

Looping

Branching is all well and good, but eventually you will want to do something that has some repetition in it. Teraterm has several more or less standard looping constructs

Code: Select all

  1. do while i>0
  2.     i = i - 1
  3. loop
  4. do
  5.     i=i-1
  6. loop while i>0
  7. for j 1 10
  8.     i=j+i
  9. next
  10. until i > 10
  11.   i = i + 1
  12. enduntil
  13. while i>0
  14.   i = i - 1
  15. endwhile


I won't go into too much detail about all of these; TeraTerm probably has more looping constructs than is really healthy, but definitely keep in mind the 'for' loop, and the fact that the 'do while' loop can be done as a pre-test loop or a post-test loop. The 'break' command can also be used to escape from a loop before its condition triggers

Lastly for the basics is TeraTerm's goto command. Some people (especially those experienced with C and who have experienced the nightmares of spaghetti code) view gotos as positively evil and wish they could be nuked from every language in existence. Gotos can do just about anything, but typically not as nicely as one of the above looping structures. About the only place that gotos should really go is in error handling:

Code: Select all

  1. wait 'Good' 'Bad'
  2. if result=2 goto ERROR
  3. ; Presumably, a bunch of non-related code goes here
  4. exit ; Typically, you don't want to execute the error code upon successful completion of the normal code, so this exits before doing that
  5. :ERROR
  6. ; Error-handling/messaging code goes here
  7. exit


TeraTerm and regular expressions

Regular expressions are an interesting creature in and of themselves. An old and relatively well-known quote about regular expressions (regexes) goes something like this:
Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems.

Regexes are a double-edged sword that allow you to do stuff with strings that would normally not be possible. Since I don't really want to go into all the nitty gritty, here's a link to wikipedia, as well as afairly-well-laid-out regex tutorial site. Note that TeraTerm has also posted a reference for the regex engine that they use, but that isn't really laid out for learning...

TeraTerm has several commands which use the power of regular expressions (let me know which one's I'm forgetting...):

Code: Select all

  1. waitregex <string1 with regular expression> [<string2 with regular expression> ...]
  2. strmatch <target string> <string with regular expression>
  3. strreplace <strvar> <index> <regex> <newstr>


strmatch and strreplace are both relatively normal. You put your regular expression in, and TeraTerm works its magic.

waitregex is a beast that I've seen misused in these forums time and again. In many ways, it is identical to the wait command, just with regular expression support. The large difference is with regular expression matching. Regular expression matching is what happens when a regular expression with parenthesis triggers on a string. The result inside the string is then returned (in normal regular expressions, it is returned as \1, \2, \3, etc, while with TeraTerm, they are stored in the groupmatchstr1, groupmatchstr2,...,groupmatchstr9 variables).

An example is as follows:

Code: Select all

  1. waitregex 'value = ([0-9]+)' 'ERROR'
  2. if result=1 then
  3.     str2int returnValue groupmatchstr1
  4. endif


Let's pick the above code fragment apart bit by bit.
First we have '[0-9]+' This regex essentially grabs the largest amount of consecutive characters that fall between 0 and 9. The parenthesis '(...)' are what initiate the grouping. With the parenthesis, the string that was caught by '[0-9]+' gets stored into groupmatchstr1. If the regular expression as a whole was triggered, the result will be one and the if statement will let the str2int command work its magic. The str2int command (and its counterpart, the int2str command) do exactly what their names suggest: convert between string and integer variables.

Thus, if the 'value = 5643' was received on the terminal, this code would set returnValue to 5643

Note that waitregex only works on the first 255 characters of a line, so anything further than that and you're going to have to find another way.

File input and output
My file I/O skills are minimal at best. Anything that you'd care to offer is gladly accepted
Also, don't forget about the ability to use logging commands in some cases (check out loginfo, logopen, logclose, logstart, logpause, and logwrite)

User input and output
Most of the commands used here are described in the Miscellaneous Commands section of the TTL Command Reference.

Code: Select all

  1. messagebox <message> <title>

This is one of the most commonly-used UI-type commands of the macro language. It pops up a window with the title equal to <title>, and the content equal to <message>, with an Ok button at the bottom. Note that code beneath this command won't execute until Ok is clicked.


Code: Select all

  1. yesnobox <message> <title>

This is almost identical to the messagebox, however rather than an Ok button, there's a Yes and a No button. If Yes is clicked, result=1, otherwise result=0


Code: Select all

  1. inputbox <message> <title> [<default>]

The third of the *box commands that I use on a normal basis, this is like the messagebox command, but with an area that the user can type stuff in. That area is populated with <default> when the window first appears, and after the user clicks Ok, the variable 'inputstr' contains the value of that area.

Strings!!!
Fill this section with stuff for commands like sprintf2

Connecting to things other than serial ports and whatnot
I'm really not at all good with TeraTerm in this department. If someone else here has some wisdom to offer, feel free to drop it off here...

Any feedback is appreciated, both for my sake, and for all of the newbies out there. The main goal of this post is to be a one-stop learning reference for people who are just learning the language, as well as to facilitate the general usability of it through simple examples.

Good luck, bon apetit, hasta la vista, whatever. Just go out and make/break something...
:cool: :cool:


Changelog:
10/24/2012 - Added a brief (unverified) description of arrays (I use a slightly older version of TT at work, and primarily use Linux at home currently, so I haven't had a chance to play around with these)
10/31/2012 - Added more formatting/hyperlinks and clarified a few points

Let's keep the suggestions coming!
Last edited by rgaiken on Wed Oct 31, 2012 9:53 pm, edited 3 times in total.
If one of my posts helped you out, do me a favor:
Next time anyone asks you for help, go out of your way to help them.

Thanks!
boris
Moderator, LogMeTT and TTLEditor developer

Posts:
1596
Joined: Sat Jan 08, 2005 2:52 pm
by boris » Wed Oct 24, 2012 1:59 pm
Thanks for putting this together. This is really need and should be kept updated. So far just one request - please add array variable type.

I also encourage everyone to participate in expanding this topic, but try to keep it simple to follow the subject "TeraTerm Macro language for dummies".
Thanks.
Best regards,
Boris
rgaiken
Beginner

Posts:
42
Joined: Mon Apr 02, 2012 2:53 pm
by rgaiken » Thu Oct 25, 2012 2:37 am
I added a small section on arrays (based off of what I read in the documentation; I don't have a new enough TT install to use those).

Also, I'll try to stay at least reasonably active, but there may be weeks/months where I don't touch these forums, so if you see someone leaving a suggestion for an edit and I don't jump on it in relatively short order, feel free to push your own edit (if you can, not sure how much mod powers you have)

-Ross
If one of my posts helped you out, do me a favor:
Next time anyone asks you for help, go out of your way to help them.

Thanks!
gradytrain
Newbie

Posts:
5
Joined: Tue Apr 02, 2013 7:49 pm
by gradytrain » Tue Apr 02, 2013 7:57 pm
This is kind of newb question (this is the "...for dummies" thread)

But with inputboxs if I wanted the box to take a integer and store to variable n and use n in a while loop, how is that done?

Thank.
rgaiken
Beginner

Posts:
42
Joined: Mon Apr 02, 2012 2:53 pm
by rgaiken » Thu Apr 04, 2013 2:31 am
gradytrain wrote:This is kind of newb question (this is the "...for dummies" thread)

But with inputboxs if I wanted the box to take a integer and store to variable n and use n in a while loop, how is that done?

Thank.

inputbox stores the result as a string in 'inputstr'

so to use that as an integer, you'd need to convert it to an int using str2int
(e.g. str2int intVal inputstr)

From there, you can just use the integer in the while loop
If one of my posts helped you out, do me a favor:
Next time anyone asks you for help, go out of your way to help them.

Thanks!
gradytrain
Newbie

Posts:
5
Joined: Tue Apr 02, 2013 7:49 pm
by gradytrain » Thu Apr 04, 2013 12:48 pm
rgaiken wrote:
gradytrain wrote:This is kind of newb question (this is the "...for dummies" thread)

But with inputboxs if I wanted the box to take a integer and store to variable n and use n in a while loop, how is that done?

Thank.

inputbox stores the result as a string in 'inputstr'

so to use that as an integer, you'd need to convert it to an int using str2int
(e.g. str2int intVal inputstr)

From there, you can just use the integer in the while loop


I had actually figured out, I didn't read the part about inputstr until after I had originally submitted the post.

Thanks for showing the str2int example, it answers another question I had...

If I can submit suggestion I wouldn't mind seeing some dummy variable examples or screenshots of some sort.
Display posts from previous:
Sort by:

6 postsPage 1 of 1

Users browsing this forum: No registered users
cron