The commandline interface for terp

< terp Legal CLI Reference >

Introduction

terp is invoked much the same way ANT is invoked. In fact, following the old adage that "imitation is the sincerest form of flattery," we "borrowed" the ANT launcher scripts and customized them slightly to account for the different use case. The terp launcher scripts are therefore published under the Apache license rather than Codemesh's terp license.

Platform Dependencies

Most of the examples show a Windows command line invocation. Everything works on Unix/Linux as well, but you might have to modify the examples slightly to account for the different treatment of strings in the commonly used Unix shells. Particularly, you might have to:

  • quote the expressions with single or double quotes. Be careful when the expression contains the same type of quote!
  • Escape dollar symbols with a backslash to prevent the shell from trying to use the dollar symbol in an attempt to expand an environment variable.

Expression Mode

All launcher scripts are in the terp distribution's bin folder. Simply change into that folder and invoke terp:

 C:\terp\bin>terp -e 3+4
 7
 C:\terp\bin>

By the way, on Unix/Linux you will probably have to invoke terp with the ./ prefix as seen below. Also on Unix/Linux, after unpacking the distribution, you might have to change the privileges for the terp script to allow execution. Simply execute chmod 755 terp to grant the terp launcher script execution rights.

 /home/alex/terp/bin$ ./terp -e 3+4
 7
 /home/alex/terp/bin$

Here you see terp being invoked in expression mode (-e switch). This is a great way to learn about terp's features interactively. You can quickly try out an expression to see whether it works or not. Just be careful with spaces and with escpe sequences (you might need to escape string quotes to prevent your shell from stripping them).

Interactive Mode

You can also invoke terp in interactive mode (-i switch). In interactive mode, terp allows you type an expression and hit RETURN. It then shows you the result value of the evaluation and awaits your next expression until you type exit and hit RETURN. This mode is great for experimentation. Here's what an example session might look like:

 C:\terp\bin>terp -i
 terp>3+4
 7
 terp>{1,2}[join(eol)]
 1
 2
 terp>x=4
 4
 terp>x+1
 5
 terp>exit
 C:\terp\bin>
    

Expansion Mode

You can also invoke the terp engine in text mode (-t switch):

 C:\terp\bin>terp -t "3+4=${3+4}.${eol}"
 3+4=7.
 C:\terp\bin>

Here you can see the mix of static text and embedded expressions. ${eol} is one of the built-in variables and stands for the host environment's native end-of-line marker, which can differ between operating systems.

Again, on Unix/Linux you might have to work a little harder to use expansion mode because the $ symbol has a meaning in Unix shells. The above Windows example looks like this on my Linux system:

 /home/alex/terp/bin$ ./terp -t '3+4=\${3+4}.\${eol}'
 3+4=7.
 /home/alex/terp/bin$
    

We had to use single quotes and an escaped dollar symbol to prevent the shell from trying to interpret our embedded text as environment variable expansions. Please note that this has nothing to do with terp per se, this is simply a function of the shell trying to do too much with the string that we're trying to pass to terp.

Script Mode

You can also invoke the terp engine in script mode (-s switch). Script mode is essentially expression mode with a file rather than a commandline expression. If you have a file test.scr containing the text 3+4 you can get the evaluated result by running:

 C:\terp\bin>terp -s test.scr
 7
 C:\terp\bin>

You can also evaluate an additional expression using the -cmd option. This is useful if the script file leaves an object on the execution stack and you want to manipulate that object. Take the following example using the same input file as above:

 C:\terp\bin>terp -cmd "tos*4" -s test.scr
 28
 C:\terp\bin>

The built-in variable tos stands for top of stack and in this example resolves to the integer 7. Script mode with a -cmd switch is very useful when a terp script is used to persist an object model and the command is a model transformation that can be performed.

File Mode

There is also a -f option that allows you to specify a template file that you wish to expand. This option always implies text mode and is probably the most commonly useful one for you. Usually, when you expand a file, you wish to save the expanded template to another file. As you can see, terp writes all its output to the console. Simply redirect standard output to create any file you want:

 C:\terp\bin>terp -f source.tpl > output.html 
 C:\terp\bin>

You can of course use output redirection with the other modes as well.

The examples above tell you most of what you need to know, but there are of course many options in addition to -e, -t, and -f.

"Dumb" Properties

Very frequently, you will need to deal with variables. terp comes with a host of built-in variables, but you probably will need to define your own as well. In ANT, you can define variables via a -D option or read in a configuration file via the -propertyfile option. Those options are available in terp as well, but in addition to them, there are also -E and -epropertyfile options. To understand their purpose and the differences between them, let's revisit the expression mode example with a variable.

 C:\terp\bin>terp -Dx=3 -e x+4
 34
 C:\terp\bin>

This might not be exactly what you expected. The reason is that the -D option works as a "dumb" definition, just as in ANT. It simply binds the text string "3" to the variable x. When the expression is evaluated, the evaluation engine sees a sum of a text string and an integer and consequently interprets the plus symbol as a string concatenation operation.

"Smart" Properties

What you probably hoped for was a result of 7. You can get this result by using the following invocation:

 C:\terp\bin>terp -Ex=3 -e x+4
 7
 C:\terp\bin>

In this example, the terp engine evaluates x=3 as a terp expression, in this case a variable assignment, and 3 is recognized as an integer. Consequently, the evaluation engine encounters a sum of two integers and calculates the correct numeric result.

The -propertyfile option allows you to specify a file which is expected to contain one "dumb" variable assignment per line. The -epropertyfile option correspondingly is expected to contain one terp assignment expression per line.

Please see a complete list of options in the CLI Reference.

Encoding

If you are working on non-US systems, you might need to adjust the encoding that is used for console output to prevent the display of gibberish characters. The issue stems from the fact that Java internally uses Unicode to represent text but that Unicode text has to be mapped to limited size code pages for display in your console. This is a known internationaliztion problem on Windows and probably other platforms too (although they are less commonly used as client platforms).

You can work around this issue by specifying the optional -encoding option or by changing the default file.encoding used by the Java runtime. The following example demonstrates the problem on my US system. I attempt to display an accented e character by using its unicode value in a character literal. Without a code page override, the symbol that is displayed is a mathematical symbol rather than the accented e character.

 C:\terp\bin>terp -e "'\u00e9'"
 ?
 C:\terp\bin>terp -enc Cp850 -e "'\u00e9'"
 é
 C:\terp\bin>set "TERP_OPTS=-Dfile.encoding=Cp850"
 C:\terp\bin>terp -e "'\u00e9'"
 é
    

Context Help Function

Particularly at first, when you are familiarizing yourself with terp, you will have problems remembering names of variables or properties. Just remember that you can use the help property at any point. It might not give you all the information you were hoping for, but it can provide you with some basic type information and API descriptions. Take the following example where help is called at the global scope:

 C:\terp\bin>terp -e help
 Global Variables
 
          aix:  A predefined operating system family name representing IBM's AIX.
                The string's value is 'aix'.
        alpha:  A predefined processor architecture family name representing HP's
                Alpha chip.  The string's value is 'alpha'.
        amd64:  A predefined processor architecture family name representing
                AMD's amd64 or Intel's x64 family of CPUs.  The string's value is
                'amd64'.
          ant:  The object is of type 'com.codemesh.terp.eval.TerpContextImpl$1'.
                
          arm:  A predefined processor architecture family name representing the
                ARM family of CPUs.  The string's value is 'arm'.
        armbe:  A predefined processor architecture family name representing the
                big-endian ARM family of CPUs.  The string's value is 'armbe'.
        armle:  A predefined processor architecture family name representing the
                little-endian ARM family of CPUs.  The string's value is 'armle'.
                
       center:  Allows the use of unquoted 'center' in metadata. The object is of
                type 'com.codemesh.terp.api.Justify'.
            e:  The number 'e' with a value of 2.718281828459045. Use formatters
                such as e['%4.2f'] to change the textual representation. The
                object is of type 'Double'.
      freebsd:  A predefined operating system family name representing FreeBSD. 
                The string's value is 'freebsd'.
         help:  Displays this help message. The object is of type 'com.codemesh.
                terp.eval.TerpContextImpl$2'.
        hosts:  Map containing all hosts known to terp. Keyed by case-insensitive
                hostname. The object is of type 'com.codemesh.terp.util.
                CaseInsensitiveTreeMap'.
         hpux:  A predefined operating system family name representing HP's HP-UX.
                The string's value is 'hpux'.
         ia64:  A predefined processor architecture family name representing
                Intel's Itanium CPU.  The string's value is 'ia64'.
         irix:  A predefined operating system family name representing SGI's IRIX.
                The string's value is 'irix'.
         left:  The string 'left'. Allows the use of unquoted 'left' in metadata.
                The object is of type 'com.codemesh.terp.api.Justify'.
        linux:  A predefined operating system family name representing generic
                Linux of all types.  The string's value is 'linux'.
    localhost:  Reference to the local host. Synonymous with hosts['localhost'].
                The object is of type 'com.codemesh.terp.api.Rvalue$ForMap'.
       macosx:  A predefined operating system family name representing Apple's
                MacOS X.  The string's value is 'macosx'.
         mips:  A predefined processor architecture family name representing the
                MIPS family of CPUs.  The string's value is 'mips'.
       mipsbe:  A predefined processor architecture family name representing the
                MIPS big-endian family of CPUs.  The string's value is 'mipsbe'.
       mipsle:  A predefined processor architecture family name representing the
                MIPS little-endian family of CPUs.  The string's value is
                'mipsle'.
          now:  The current time. Use formatters such as now['%tY'] to change the
                textual representation. The object is of type 'com.codemesh.terp.
                eval.TerpContextImpl$3'.
      openvms:  The string's value is 'openvms'.
           os:  The local host's operating system. Synonymous with localhost.os.
                The object is of type 'com.codemesh.terp.eval.TerpContextImpl$4'.
                
        os390:  The string's value is 'os390'.
         osf1:  The string's value is 'osf1'.
       parisc:  A predefined processor architecture family name representing HP's
                PA-RISC (32-bit) family of CPUs.  The string's value is 'parisc'.
                
     pariscv2:  A predefined processor architecture family name representing HP's
                PA-RISC (64-bit) family of CPUs.  The string's value is
                'pariscv2'.
           pi:  The number 'pi' with a value of 3.141592653589793. Use formatters
                such as pi['%4.2f'] to change the textual representation. The
                object is of type 'Double'.
          ppc:  A predefined processor architecture family name representing the
                PowerPC (32-bit) family of CPUs.  The string's value is 'ppc'.
        ppc64:  A predefined processor architecture family name representing the
                PowerPC (64-bit) family of CPUs.  The string's value is 'ppc64'.
        ppcbe:  A predefined processor architecture family name representing the
                PowerPC big-endian family of CPUs.  The string's value is 'ppcbe'.
                
        ppcle:  A predefined processor architecture family name representing the
                PowerPC little-endian family of CPUs.  The string's value is
                'ppcle'.
    procarchs:  The local host's processor architectures. Synonymous with
                localhost.procarchs. The object is of type 'com.codemesh.terp.
                eval.TerpContextImpl$5'.
          qnx:  The string's value is 'qnx'.
        right:  The string 'right'. Allows the use of unquoted 'right' in
                metadata. The object is of type 'com.codemesh.terp.api.Justify'.
         s390:  The string's value is 's390'.
        s390x:  The string's value is 's390x'.
           sh:  A predefined processor architecture family name representing the
                SuperH family of CPUs.  The string's value is 'sh'.
         shbe:  A predefined processor architecture family name representing the
                SuperH big-endian family of CPUs.  The string's value is 'shbe'.
        shell:  The local host's shell according to terp's preference. Synonymous
                with localhost.shell. The object is of type 'com.codemesh.terp.
                eval.TerpContextImpl$8'.
         shle:  A predefined processor architecture family name representing the
                SuperH little-endian family of CPUs.  The string's value is
                'shle'.
        sparc:  A predefined processor architecture family name representing
                SUN's SPARC (32-bit) family of CPUs.  The string's value is
                'sparc'.
      sparcv9:  A predefined processor architecture family name representing
                SUN's SPARCv9 (64-bit) family of CPUs.  The string's value is
                'sparcv9'.
        sunos:  A predefined operating system family name representing SUN's
                Solaris.  The string's value is 'sunos'.
       superh:  A predefined processor architecture family name representing the
                SuperH family of CPUs.  The string's value is 'superh'.
     superhbe:  A predefined processor architecture family name representing the
                SuperH big-endian family of CPUs.  The string's value is
                'superhbe'.
     superhle:  A predefined processor architecture family name representing the
                SuperH little-endian family of CPUs.  The string's value is
                'superhle'.
 terp.version:  The object is of type 'com.codemesh.terp.eval.TerpContextImpl$9'.
                
    universal:  A pseudo processor architecture family name representing the
                superset of MacOS X CPUs (ppc,ppc64,x86,amd64).  The string's
                value is 'universal'.
  universal32:  A predefined processor architecture family name representing the
                32-bit superset of MacOS X CPUs (ppc, x86).  The string's value
                is 'universal32'.
  universal64:  A predefined processor architecture family name representing the
                64-bit superset of MacOS X CPUs (ppc64, amd64).  The string's
                value is 'universal64'.
      windows:  A predefined operating system family name representing Microsoft
                Windows.  The string's value is 'windows'.
          x86:  A predefined processor architecture family name representing
                Intel's 32-bit X86 family of CPUs.  The string's value is 'x86'.
 

The global variables give you a good starting point for some of the built-in data types representing operating system, processor architecture, and host. But what can you do with each of these custom types? Let's ask help what can be done with the object representing the local host's operating system:

 C:\terp\bin>terp -e os.help
 Type   :  com.codemesh.terp.data.OS
 Help   :  An operating system abstraction. You will not usually create instances
           of this type but rather use the instance that is already available via
           the global 'os' variable.
 
 Method : String getName()
          Returns the operating system's name.
 
 Method : com.codemesh.terp.data.Version getVersion()
          Returns the operating system's version number as reported by Java.
 
 Method : com.codemesh.terp.util.CaseInsensitiveTreeMap getTraits()
          Returns the operating system's named traits.
 
 Method : String getFamily()
          Returns the operating system's family name. Legal values include 'aix',
          'hpux', 'linux', 'macosx', sunos', and 'windows'.
 
 Method : java.util.Collection getProcArchs()
          Returns the processor architectures this operating system supports.
          This is not necessarily the same collection of processor architectures
          that the host supports. You could for example run 32-bit Windows on a
          64-bit Intel machine.
 
 Method : String getCode()
          Returns the operating system's code.
 
 Method : String getFlavor()
          Returns the operating system's flavor. A flavor could for example be
          'RHEL' or 'SUSE' for different Linux distributions.
 
 

The synthetic help property always gives you information about the current object. The help might not include the most complete description, but you will always learn the object's type and some things you can do with it.


Copyright 2006-2016 by Codemesh, Inc., ALL RIGHTS RESERVED

:
terp command line interface
codemesh.com home expressions templates ant about us contact us download   

Commandline