JZtxtcmd

# JZtxtcmd

Inhalt

Topic:.JZtxtcmd.

Topic:.JZtxtcmd.

## 1 Substantiation

Topic:.JZtxtcmd.subst.

Last changed: 2017-0729

JZtxtcmd is a script language with its interpreter. A JZtxtcmd script has capabilities adequate a shell script or batch file but with a well affinity to Java routines and special capability for text generation. A JZtxtcmd script will be interpreted using Java. Only a standard Java Virtual Machine (currently version 8) is necessary to run, like it is usual given on most systems. The ZBNF.jar file contains all byte code of that. Therefore it runs under Windows as well as under Linux, Macintosh and special operation systems which are supported by Java.

Note: Till 2017-03 JZtxtcmd was firmed as JZcmd. It is renamed because it can be used both as Text generator (T) and as command executer (c). The importance as text generator was not shown in the name JZcmd.

In a JZtxtcmd script you can invoke command line statements from your system. You can have local variables which can be filled by results of command line invocations or some more routines. You can have if()...elsif()...else... constructs as well as for(containerelement)... and calling of subroutines which are defined inside the own script or in included scripts.

cmd line ---------------->|<-----Invoke inside a Java application
|          |
Another JZtxtcmd script ->|          |  use Java data
|          +==>+
JZtxtcmd =========+===>cmd line
^              +===>generate text output
Users.JZtxtcmd    +===>write files, especially text generation
script            +===>invoke Java routines,
prepare data.


JZtxtcmd has well capabilities to access Java data. You can work with complex container (arrays, lists, trees) as well as access simple fields or invoke methods. A Java application can prepare data in a special and complex kind, and then invoke srcJava_Zbnf/org/vishia/jztxtcmd/JZtxtcmd with a given user script.jztc to generate an output text or execute somewhat with the data.

The output text from JZtxtcmd may be a XML format, a programming language's sources code, csv-Format for MS-Excel table calculation or any other. For XML the approach is similar like Wikipedia:_XSLT. But XSLT deals with XML input data only.

Topic:.JZtxtcmd.copyleft.

Last changed: 2017-0729

This description and the software, which is described was created from Hartmut Schorrig, Pinzberg, Germany (hartmut.schorrig@vishia.de). Hartmut Schorrig holds the moral rights of this description and the software.

Any citation of this text needs the declaration of the owner of the moral right and the source in the internet www.vishia.org/docuZBNF/JZtxtcmd.html.

## 3 Availability, test and examples

Topic:.JZtxtcmd.testExamp.

Last changed: 2017-0729

To execute a JZtxtcmd-script you need only the Java archive ZBNF-Dowload/.../zbnf.jar and a Java virtual machine currently any version 8.

Some tests and examples are contained in the ZBNF-Download/.../ZBNF.zip This is the whole archive of ZBNF available on http://sf.net/projects/zbnf too.

The capability is tested with the following script contained in ZBNF.zip:

## 4 Capability and general Syntax of a JZtxtcmd script

Topic:.JZtxtcmd.genScript.

The syntax regards of 2 strategies:

• Invocation of commands, program flow control,

• Preparation of texts.

The script has a

main(){
...statements
}


The main()-Routine can be contained in an included file too. That is proper if a special script contains a special part of the program whereby the main is given as standard in the users orbit.

For text preparation a writing style with

 <:>text<&placeholder><.>


is used. The script doesn't use the "quotation marks" for texts. Instead a text is written in the script directly inclusive all white spaces, line feed etc. See 13 Text output and text generation.

The complete syntax is shown and explained in 16 Syntax of a JZtxtcmd script.

What offers JZtxtcmd:

• A simple script well readable.

• Whitespace-strategy. You can wrap lines like your intension. You can use indents to structure like you want to do. For example a long command line can be separated in some lines, one per argument.

Command line invocation:

• Invocation of commands of operation system like in batch files or shell scripts, starting or waiting for completion. See 7.2 start, cmd: Invocation of operation system commands

• Processing error feedbacks of command line invocations with errorlevel, using of input and output/error pipes. The output can be written both to standard output and in internal variable for post-processing.

Program structure, control flow, variable:

Java usage:

• If the JZtxtcmd script is called from a Java context, it can have data associations to any Java instance.

• Access to data, possible to private too (with calling argument flag, for debugging).

• Invocation of methods from given instances with textual, file or numerical parameter or data associations.

• Creation of Java instances.

• Invocation of static Java methods.

• Exception handling support.

Text generating capabilities:

• One text output file, given as argument of JZtxtcmd. The JZtxtcmd can be used as text generator: <+text>... The output file may be a shell script or batch file, a make file or something else.

• Plain text in the script.

• Access to data as part of texts: <&data.method().data>

• Text generation for example for content of variable or calling arguments, simple concatenation writing rules: <:>text<&withData><.>

Zmake approach:

• Zmake offers a strategy to use simple make scripts (more simple than a GNU maker, more simple than ANT) for complex make requirements. The trick is: The first level of Zmake names files and make targets. It is a well user-friendly JZtxtcmd script. A second level, that may be an included JZtxtcmd script, contains the rules how to make with check of dependencies etc.

• A Dependency check especially for C/C++ files is provided as a Java routine able to call in a JZtxtcmd subroutine which organizes the make.

The combination with Java programs offers the following strategy:

• More complex programs are implemented in Java. They can/should be written in a common approach, without the actual using intensions.

• The organisation of calling the Java methods, with its concret arguments are written with JZtxtcmd.

• All Java classes from libraries all over the world are ready to use in a JZtxtcmd script.

JZtxtcmd is structured but not object-oriented by itself. With usage of Java-objects it is object-oriented.

A JZtxtcmd script is parsed and translated from its textual presentation to an internal tree of execution statements while starting. In the running phase the textual script is not used. The interpreter works with its internal data. Independent of this principle a changing of the source text and re-translate to support debug facilities is planned but not implemented yet.

## 5 Invocation of a JZtxtcmd script

Topic:.JZtxtcmd.invoke.

A JZtxtcmd script can be started from a command line environment similar to a batch file or shell script, or it can be started from any Java application inside.

### 5.1 Command line invocation

Topic:.JZtxtcmd.invoke.cmd.

One needs only a standard java upto version 6 and the zbnf.jar file. The last one can be downloaded from ZBNF_on_Sourceforge or from the vishia_Downloadpage.

java -cp path/to/zbnf.jar org.vishia.zcmd.JZtxtcmd scriptfile


To shorten the invocation of JZtxtcmd and to simpify some inclusions, a batch file should be used. That batch file should be invoke-able in the operation system's PATH. Then the invocation of JZtxtcmd will be written only with

jztxtcmd scriptfile


See the template for a batch file for windows: zbnfjax/batch_template/jztxtcmd.bat and linux: zbnfjax/linux_startscript_template/jztxtcmd. This file contains the setting of some environment variable which can be used in JZtxtcmd scripts. It refers paths where other tools are found.

help and JZtxtcmd syntax:

Some more arguments can be given, especially a file path to the standard text output, some arguments for debug, and user arguments. To see a complete argument description, invoke

jztxtcmd --help


The help text is send to the stdout and contain a syntax description in ZBNF format, which is used for parsing.

Text output:

To generate a text output, you can invoke

jztxtcmd JZtxtcmdScript -t:pathTo/file.txt


That file will be written with <+> This text will be generated <.+> inside the script. You can generate for example make files, batch files, xml files etc. etc. controlled by the JZtxtcmdScript.

Another possibilities to control which text files are <+:create>filepath..., FileOpen file =filepath;.

User arguments can be given with the option

-u:anyUserArg




The path to another script is written as simple character String till a whitespace, or in "". That path starts relative from the current script. If the path starts with an environment variable VAR especially the environment variable should contain an absolute path, where the included script can be found. main()-Routine in an included script: If the top level script (which includes) contains a main()-Routine, it is used. If the top level does not contain a main() the first found main() in included scripts is used. One can use a script only with special sub routines which includes the script with the main(). Therewith a special behavior can be variegated with a short special script. ### 6.3 The main routine Topic:.JZtxtcmd.script.main. The main routine is started if another routine is not specified. ### 6.4 Classes Topic:.JZtxtcmd.script.class. The script can be divided in classes. Each class can have sub classes. Yet the routines of classes can be seen as only static routines in comparison with Java classes. Syntax see 16.4 Classes To invoke a sub routine in a class one should write classname.subroutine(...);  For future development: It is an object oriented concept which may usefull to organize the workflow with sub scripts. Each class should have class variables. ### 6.5 Subroutines and subtext Topic:.JZtxtcmd.script.sub. Syntax see 16.5 subroutine. Calling a subroutine see 7.5 call: Invocation of sub routines. Calling a subtext see 13.12 Insert text form a subroutine: <:subtext:...>. Statements in a variable see 9.1.9 Subtextvar, Subroutinevar - statements to execute It is recommended to divide the execution of a task in more as one sub routines. Any routine should be short and easy. Long shell scripts or batch files with some goto are terrible. A routine should be manageable with about one screen size, 40..50 lines. sub mySubroutine(String arg1="example", Obj arg2 = scriptVar){ <+out><&arg1>, <&arg2><.+n> }  arguments and local variables: A subroutine can have an argument list which builds local variable for the routine. For calling a subroutine with building actual arguments see 7.5 call: Invocation of sub routines. If (use-locals) is not set then a subroutine gets a copy of all script variables if they are writeable and gets the reference to readonly script variables. If that variables are changed the value of the script variables are not influenced. A subroutine can define its own variables. All that variables are existent as long as the routine runs. It is possible to call a subroutine which uses the same local variables as the calling level. Then that subroutine is not independent of the calling environment. It should only be called in one environment or in adequate environments. Elsewhere errors are possible if used variable are not found. Such an behaviour is only possible for script languages. It makes easy to dispers the source code without effort for definition of a lot of variables: sub myRoutine(use-locals) { ... } subtext myText(use-locals) <:>...<.>  Such a subroutine or subtext cannot have additional arguments. It should not define a return variable except the return variable should be used in the calling level as return. It is possible to add all local variables of the calling level to the local variables of the subroutine. In that case the subroutine is independent but it knows all variables of the calling level. Changing a variable in the subroutine does not affect the variables of the calling level. The application of that feature may be similar to use-locals: sub myRoutine(add-locals, String moreParameter) { ... } subtext myText(add-locals, String moreParameter) <:>...<.>  returned values: A subroutine can return some values stored in a variable tree. This variable tree is named return inside the subroutine: sub mySub(String arguments){ String return.textret = "any text"; Obj return.objret = anyObjExpression... } outside: Map result; result = call mySub(); <+out>result.textret=<&result.textret><.+n>  ### 6.6 Statement blocks Topic:.JZtxtcmd.script.stm. The main routine, a sub routine or some parts of the routine consists of a statement block. { statements }  Statement blocks can be nested. Especially they are used in control structures: if(condition){ statements} else { statements}  For statements see 7 Statements ### 6.7 Text blocks Topic:.JZtxtcmd.script.. Syntax see Chapter: 16.14 TextExpression. A text argument or a comprehensive part of a subroutine can be a text block. The text block is clamped either with  <:>text block<.>  if the text block is expected as argument, or it is organized as output to any Appendable, simple <+>text block<.+>  for output to the main output text file, given by a calling parameter, usual -t=text.file, or <+openfile>text block<.+>  to output to any javadoc-oracle/java/lang/Appendable especially (see 9.1.12 Openfile). To output with a newline on end written in one line you can write <+>An output line<.+n>  The generated text contains the same characters like written in the source, except line feeds and indentation. The linefeed can be controlled by a parameter, the indentation can be controlled in the following forms.  <+> This is an line left aligned This line starts 2 spaces after ,,<+,,-column, therefore it has 2 spaces as indentation. <:@indent*2>This line starts at the column ,,indent*2,, ::: This line starts with 2 spaces, because 2 spaces after ,,:::,, :::::::::::::This line is left aligned because it starts after ,,:::::,, which starts before the ,,<+,,-line <.+>  One can write to the stdout using <+out>...<.+> and to the stderr using <+err>...<.+>. The environment of the JZtxtcmd invocation can show this texts in a console, redirect to files or redirect for example to a message system in Java using srcJava_vishiaBase/org/vishia/msgDispatch/MsgRedirectConsole: <+out>stdout output like java.lang.System.out.println(...)<.+n> <+err>stderr output like java.lang.System.err.println(...)<.+n>  ### 6.8 Comments in the script Topic:.JZtxtcmd.script.rem. Syntax seechapter.

The script is parsing with comment specifications which are regarded from the parser. That is:

##line comment to end of line
(? block comment
over some more lines ?)


Additional the // and the /* ... */ can be used for comments like in Java or C. That comments are formally parsed, they are visible in the parsers result xml file with option -debug:file, but they are ignored for execution.

Note that a

//comment  <+>text...


does not ignore a start of a text output on the same line. This capability is proper for writing text output in a right column whereby statements are written left. To ignore lines which contain text output use:

##comment <+>inclusively ignore the text output<.+>


Inside text expressions the // does not act as comment. Instead it is a part of the generated text.

<+>text  ##comment to end of line
function(arg);  //A C file may be generated with comments!
..<.+>


In Text expressions it is possible to comment some parts without disturbing the structure, for tests:

<:> <&-datapath.is.comment>
<:---> comment till <--->
<:-if> it is commment till <.-if>
<:-for> it is commment till <.-for>
<!--- It is not comment, but it is comment in an XML file --->
<.>


See syntax 16.14 TextExpression

## 7 Statements

Topic:.JZtxtcmd.statements.

Any independent line in a statement block is a statement. Some statements are designated by a keyword. Statements without a keyword are assignments and / or expressions which can invoke to Java methods.

The statements can be divide to

• Definition of variables

• Stringjar, String, List, Map, Obj, Num, Bool, Class, Classpath: variable declaration, see 9.1 Types of variables and their assignment

• Openfile opens a file, declaration of a Writer variable.

• Fileset, Filepath; Set of files or one file with access to its base path etc. See 9.1.13 Filepath, Fileset

• Set, set: set a environment variable

• Invocation of cmd and sub routines

• Some file handling

• cd change directory

• move file move

• copy file copy

• delete

• if(File:"path/to/file".exists())

• control statements

• for, if, while, program flow control

• break break in a onerror handling

• return end of a subroutine

• exit end of the script.

• onerror exception and error handling.

• Thread Thread execution with Thread variable.

• thread Thread execution independent.

• debug support

• debug debugging support.

• Text expressions

• <+... text expression.

• All other keywords are Statements without a keyword are build with assignments and / or invocations to Java methods. See 10 Expressions.

• variable  =  expression

• expression;

Statements are terminated by a colon ; character. The line structure (spaces, line feed) have not any influence.

The full syntax is described in 16.6 statements.

### 7.1 Definition of variables

Topic:.JZtxtcmd.statements.data.

Variables have to be definined before using. The definition can be come together with an initial or final assignment, which invokes an expression maybe with side effects. There are some but rare types.

• Num: a numeric value build with 10.6 Numeric Expression. It is wrapped with srcJava_vishiaBase/org/vishia/util/CalculatorExpr.Value.

• Bool: a conditionbuild with 10.5 Boolean expression, Conditions. It is wrappend with javadoc-oracle/java/lang/Boolean.

• String: refers a constant text build with textDatapath. It is a javadoc-oracle/java/lang/String.

• Stringjar: It is an container for Strings. One can append, delete or set newly. It is possible to search, check, scan somewhat etc. In Java it is a srcJava_vishiaBase/org/vishia/util/StringPartAppend which is an javadoc-oracle/java/lang/Appendable. It refers to a javadoc-oracle/java/lang/StringBuilder. Syntax see 16.21 Assignment to variables.

• Pipe: It is a java.lang.StringBuilder, a buffer of characters. Some operations appends on the end of the buffer, some operations read from begin of the buffer and shifts the content to left. It is used for command pipes. A pipe is a queue which contains text.

• List: A list container. Any 16.21 Assignment to variables adds a new Object-type element. It can be used in for(variable:list). It is a javadoc-oracle/java/util/List instantiated with a javadoc-oracle/java/util/LinkedList

• Map: A container with a String key. It is used as container for sub variables usually. It is a javadoc-oracle/java/util/Map instantiated with a srcJava_vishiaBase/org/vishia/util/IndexMultiTable. A javadoc-oracle/java/util/TreeMap is not used because the IndexMultiTable is better to debug. The values of a short list (20 elements) can be seen immediately.

• Obj: It is any javadoc-oracle/java/lang/Object. One can create an Object or return it from a  java path.staticmethod()-invocation.

• Class: It is a javadoc-oracle/java/lang/Class. It is used especially to call a  classvar.staticmethod() with it.

• Classpath: It is a javadoc-oracle/java/lang/ClassLoader. It is used when another class Library should be used. Because from the context of the script, the variable names class paths (path to jar-files, path to a directory which contains class-Files), therefore it is named Classpath and not ClassLoader. From the context of running the script it refers an instance to help loading classes. See 9.1.11 Classpath

• Openfile: If this variable is created, the named file is opened for write, maybe append. The variable is an javadoc-oracle/java/lang/Appendable respectively an javadoc-oracle/java/io/Writer. Any assignment to an Openfile will be written in the file. A close() on this variable closes the file. Don't forget close(). A flush() is possible to write out internal buffered content to be visible on file system. See 9.1.12 Openfile and 13 Text output and text generation.

cmd execute.exe;     //adds $myEnv as myEnv set Env2="text2"; //adds Env2 as %myEnv in variables and to the cmdExecuter. } //end of subroutine removes the instance of cmdExecuter.  #### 7.2.4 pipeline handling Topic:.JZtxtcmd.statements.cmd.pipe. The standard output of a cmd invocation can be gathered with an append assignment:  textBuffer += cmd myCommand;  whereby the textBuffer of this example can be a Stringjar, a Openfile, a Pipe or any other Appendable in the Java data. It is possible to have more as one Appendable which gather the standard output. Especially out can be used to forwarding the stdout of the process to the stdout of the JZtxtcmd execution: textBuffer += out += cmd myCommand;  In this case the stdout is forwarding to the JZtxtcmd console output and gathered in the textBuffer too. The output is handled simultaneous while the command line execution process runs. If a execution needs some time, for example a search and report process from many files, the user can visit the output of the command line execution straight. This is a capability of the java virtual machine command line process handling with its application interface class javadoc-oracle/java/lang/Process and the class srcJava_vishiaBase/org/vishia/cmd/CmdExecuter The other possiblity for gathering the stdout of the process and the only one possibility for a separated stderr and stdin is: cmd myCommand <:stdout:textBuffer> <:stdout:out> <:stderr:out> <:stdin:myPipe>;  Both variants can be combined. stdout and stderr can be written in any number of destinations. The stdin can be given only one time. #### 7.2.5 Exit code of cmds, errorlevel Topic:.JZtxtcmd.statements.cmd.errorlevel. A cmd invocation has an exit code. It is a principle both in UNIX-like operation systems and in MS-Windows. Usual a higher value of an exit code means a more fatal error. 1 may be a warning, 0 is successfully. The exit code is designated as errorlevel usual in MS-Windows batch files. After a cmd invocation one can output the exitcode for example as hexadecimal value writing cmd myCmd ... <+out>exit error level = <&jztcsub.cmdErrorlevel:"%8X"><.+n>  There are two startegies to handle the exit code: if errorlevel 1 { ...statements...}  That statements are executed additionally if the last cmd sets the requested or a higher errorlevel. For example a warning can be logged. throw on errorlevel 2;  If that statement is executed, an exception is thrown if the exit code (errorlevel) of the last cmd invocation is equal or higher to the requested value. It means, the following statements are skipped till a onerror {...} or onerror cmd {...} statement is found or the block is left with that exception. Both strategies can be combined: cmd myExecutable.exe arguments throw on errorlevel 5 if errorlevel 1 { ...} ... ...further statements ... onerror cmd { ... alternatively statements on fail } ...continue processing  If the command generates an exit code equal or greater 5, the further statments are skipped. They should not be executed, because the permissions are not given. If the errorlevel is 1..4, the further statements are executed. The onerror cmd block is executed only if the exit code is 5 or higher. There may be executed any alternatively things. Last not least the processing continues after the onerror-block. See examples_JZtxtcmd:TestAll/readme.txt: sub testErrorlevel() #### 7.2.6 Execution time for operation system commands Topic:.JZtxtcmd.statements.cmd.calctime. The invocation of a operation system command call creates a new process in the operation system. That needs a few milliseconds. A value of about 50 ms was measured with an Notebook with MS-Windows XP, Intel dual core about 1.2 GHz. That time is not large if a complex command line process is started. But if some command lines are executed one after another, each of them with a small task, then this 50 ms are multiplied by the number of cmd invocations. For example a compilation or any other translation was started. If a Windows-batch-file or a UNIX shell script runs, the cmd.exe or shell script interpreter optimizes the invocation of commands. There is not an extra process for each command. Therefore it may be recommended for a block of commands to generate such an script and executed the whole script. Of course the advantage of an operation-system-independent syntax for JZtxtcmd is not able to use if either a MS-Windows batch file should be executed or on the other hand an UNIX/LINUX shell script. But usual such JZtxtcmd user scripts are proposed for a special operation system. For example to invoke some commands as batch in windows one can write: Openfile bat = "myBatch.bat"; ##opens in current directory <+bat> echo off dir >out.txt call otherbatch.bat <.+close> cmd cmd.exe /C myBatch.bat;  The batch is contained as text lines in a JZtxtcmd script. That text lines are written to a file. That file is executed with cmd.exe, the MS-Windows batch file executer. The produced text in out.txt can be read in the JZtxtcmd script then and it can be evaluated: Stringjar sdir = FileSystem.readFile("out.txt"); ##reads the file. if(sdir.seek("myBatch").line().found()){ String line = sdir.getCurrentPart(); <+out><&line><.+n> }  See examples_JZtxtcmd:TestAll/readme.txt: sub testBatch() ### 7.3 currdir, cd statement Topic:.JZtxtcmd.statements.currdir. Inside a JZtxtcmd script a current directory can be set. It is used especially for 7.2 start, cmd: Invocation of operation system commands and for file operations with relative paths: cmd execute anything; ## uses the currdir for command process Openfile myfile = relative/path.ext ## uses the currdir to build the file path datapath.method(File:"relative/path") ## creates an absolute File object with currdir  • On start of a JZtxtcmd script the currdir on scriptlevel can be set with start parameter. Per default it is the current dir of the operation systems. • The currdir = path; - statement on start on a JZtxtcmd script can determine either an abbreviating directory with relative path or another current directory for the JZtxtcmd script in opposite to the operation system's one. • Especially with currdir = scriptdir;  on start of JZtxtcmd the directory where the JZtxtcmd script is located can be set as current directory. Often some other files are located in the same directory or with relative paths to them. • A sub routine gets its local current directory from the calling level. In a sub routine the current directory can be changed with cd-statement. It is valid only for the subroutine level and its called nested level. This behavior is adequate to the cd-statement in other scripts and adequate to the set of environment variables. • The script level's current directory can be changed in a sub routine: Access to • The jztcsub.currdir() returns the current directory of the sub level as text. It uses the / as path separator. • The current directory of any execution level is hold in the variable jztcsub.currdir in the srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExecuteLevel instance. It is a java.io.File object with an absolute normalized path. Practice of absolute and relative paths: It is not recommended to define an absolute path if the script should be used on several computers may be with different locations in the file system. On the other hand the usage of absolute paths for files is at runtime proper. For example if a file should be opened but it fails, an error message which names the absolute path of the file is more helpfull. If the message contains the relative path only, the question remains on which path starts the relative one. The following rule should be valid: • Use relative paths in all scripts and sources. Therewith the location in the file system is variable. • On execution time the relative paths should be translated to absolute ones. #### 7.3.1 Determine the currdir on start on JZtxtcmd Topic:.JZtxtcmd.statements.currdir.start. A path for the current directory can be given: #### 7.3.2 cd versus currdir = path Topic:.JZtxtcmd.statements.currdir.cd. The statement cd or CD is known from both Unix shell scripts and MS-Windows batch files. The JZtxtcmd supports it too: cd newDir  changes the content of the currdir of any subroutine level. Relative paths can be used, especially ... This changes are done in the local copy of the subroutine, not for the script variable currdir. If the newDir is faulty, non existing or any faulty path, an IllegalArgumentException is thrown. The user can catch such an exception with cd requestedPath/maybe/faulty ... do something with it onerror{ ...errorHandling }  Instead cd the form currdir = "newDir";  can be used. The difference between both is less. cd mydir; currdir = "mydir";  • cd uses a <textValue>, see 10.2 textValue or textDatapath, whereby currdir = uses a <textDatapath>. The cd statement is similar the known operation system's one. • The currdir = ... is like an JZtxtcmd assignment. Both operations are adequate in respect to working with relativ paths. If a relative path is given, it is regarded to the actual value of the currdir. Especially on start of a JZtxtcmd script or in a sub routine the following statement can be used: currdir = scriptdir; currdir = <:><&scriptdir>/../relative<.>;  Often it is usefull if the script is contained in a working area in an sub directory, and the working area should be used as current directory without any other effort. Especially some environement variable of the operation system can be used to set a special, usual absolute currdir: currdir =$CD;  ##set it to the operation system's current dir
currdir = $PWD; ##adequate for Unix currdir =$HOME;
currdir = <:><&$HOME>/myDir<.>; ##inside the HOME directory  Note that the environment variables are case sensitive in the JZtxtcmd script like in UNIX/Linux in opposite to the non case-sensitive ones in MS-Windows. #### 7.3.3 Access to the currdir as variable Topic:.JZtxtcmd.statements.currdir.varaccess. The currdir is a variable of JZtxtcmd. But the assignment currdir = ... is a special statement. If the value of the currdir is need as text value for example to output it for check one can write: <+out><&jztc.scriptLevel.currdir><.+n> <+out><&jztc.scriptLevel.currdir()><.+n> <+out><&jtcmdsub.currdir><.+n> <+out><&jztcsub.currdir()><.+n> <+out><&currdir><.+n>  The method currdir() on sub level or for the whole JZtxtcmd script returns a string which uses / as separator for directories in the path, like it is recommended for internal use. The field currdir in the instance jztcsub or jztc.scriptLevel is a reference to a java.io.File. Therefore it's conversion to a String returns the path in the operation system's kind. It is a property of the Java Virtual Machine. Therefore the backslash \ is written as path separator. #### 7.3.4 The currdir of JZtxtcmd does not affect the operation system's current directory Topic:.JZtxtcmd.statements.currdir.noOs. If you invoke any Java method, and that Java method tries to open a file for example with Writer openit = new FileWriter("relative/path");  then the Java Virtual Machine delegates the resolving of the relative path to an absolute one to the operation system. Of course the operation system does not know a currdir variable of the JZtxtcmd level. Therefore it may be failed. If you use a File object instead: Writer openit = new FileWriter(File:"relative/path");  then the File will be build with an absolute path which uses the JZtxtcmd-internal currdir instead. If any Java module can be influenced with a special setting of the current directory you can do so. For example and especially the class srcJava_vishiaBase/org/vishia/mainCmd/MainCmd knows an command line argument "--currdir:value" which can be set from Java internally too. You can write java path.to.Main.main(<:>--currdir:<&currdir><.>, "further arguments...");  If you're attempt to invoke a Java program which uses MainCmd from the JZtxtcmd script. ### 7.4 File commands Topic:.JZtxtcmd.statements.copy. There are some commands to offer operation systems capability: mkdir path/to/dir;  Syntax see 16.6 statements. It makes all necessary directories starting from the current directory or with the given absolute path. If the directory exists already, it is ok, no error. The path can be given as immediate text without spaces, or in "" or as <:>textexpression<.>. If the path ends with a ' (Apostroph, Hexa 0x27) then it means, the path ends with a file name. The file part is removed then, only the directory is created: mkdir <:><&path_to_file_variable>'<.>;  creates the directories to the file, not the file itself (since 2018-01). Copying a file. The copy command knows 3 options: • -n: Saves the copied file with a new time stamp, the current date. This is like usual in Unix. It is necessary if a standard maker is used and the copied files are sources. Without this option the destination file preservs the time stamp from the source. That is the standard behavior in MS-Windows for a copy. • -w: Overwrites files if they are exists. If this option is not set and the destination file exists, the copy will be aborted with an IllegalArgumentException. • -r: Overwrites files though they are read only. This is a behavior which may subvert the safety because files are set read only to prevent overwrite. On the other hand the user knows which files should be overwritten. The option -r includes -w. copy -n-w-r path/to/source.ext dst/path/name.ext  The arguments for copy are textvalues Use "path/with special;chars", you can build a path with a <:>textexpression with <&values><.>. The copy command does only copy files. For copying directory trees use copydir ...TODO  The move command is a rename if the move source/File dstdir  The source/File can be a directory which is moved into the dstdir. Both arguments are paths as textValue. Therefore you can write for example: copy <:>myPath/<&fileNameInVariable>.ext<.> <:><&dstPath>/<&fileNameInVariable>.ext<.>  using variables. The copy operation copied directory trees if it is given. Check of file properties To check file properties the capability of the class javadoc-oracle/java.io.File can be used. A file object can be build with: Obj myFile = File:name.ext;  whereby name.ext is a textValue. It builds the File with the given path inside the currdir of the JZtxtcmd environment. It is possible or proper to build the File object only temporary, in conclusion with the check operation: if(File:"path/to/file.ext".exists()) { ... }  In this case the name of the file is written in "" because the following .exists() method should be separated from the name. Of course it is a syntax error if you write if(File:path/to/file.ext.exists()) ... because .exists is recogized as part of the file name (extension) and the following () are unexpected. Like usual for a textValue the file can be build with: File:&variableContainsPath File:&dataAccess.to.javadata File:<:><&basepath>/to/<&name>.ext<.>  ### 7.5 call: Invocation of sub routines Topic:.JZtxtcmd.statements.call. Sub routines are parts of a JZtxtcmd script, see 6.5 Subroutines and subtext. Syntax see 16.18 callSubroutine, callSubtext. calls a subroutine  call mySubroutine(argname=argvalue);  Writing rules, name of the sub routine: The Name of the sub routine can be either a constant string value or a value from any location. In the last case the routine is determined by the user's data. call &theName();  Actual arguments for the subroutine: The order of the formal arguments and the order of the actual values does not need the same one. The arguments are named both in formal and actual lists (other than in C, Java). It is checked whether corrent names for actual arguments are used and whether all necessary actual arguments are given. Formal arguments can have default values for missing actual arguments. Be aware that the calculation of actual values may have side effects, depending on their calculation routines. The default value will be calculated • only if it is necessary because the actual arguments are missing, • at the time on calling the sub routine with actual data. • The data environment for calculation of default arguments is the script or the class, not the calling environment. Because JZtxtcmd is a interpreted execution, it may be possible that the calling environment is used to calculate the actual values. But from static view the calling environment is unknown from the subroutine's head line. Therefore the calling environment is displaced for that operation. Example: sub mySubroutine(String arg1="example", Obj arg2 = scriptVar){ <+out><&arg1>, <&arg2><.+n> } ... { //any calling enviroment: Obj scriptVar = xyz; call mySubroutine(arg1="myOtherExample"); }  It is called without actual argument arg2. Therefore the value for arg2 is calculated on calling time. But the local scriptVar is not used, instead the script variable with that same name is used. Type of arguments: Usual an argument of a sub routine is either a constant or an expression, see 16.10 Object value: objExpr. It may be a simple access to a variable. An object expression allows some type conversions: If a java.io.File object is expected but only the path is given, use call subroutine(fileArg = File: "path/to/file");  If the filepath is relative then the 7.3 currdir, cd statement is used. It is the same like arguments for invocation of Java methods, see 9.9 Access to Java internal data. If a Filepath variable should be build only for the subroutine's argument then the definition can be write directly in the actual argument list: call subroutine(pathArg = Filepath: "path:local/file.ext");  It builds a srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdFilepath object on demand as actual argument. The subroutine gets the reference to it. Hint: The filepath does not need to write in "" if it does not contain spaces and special characters. Adequate the access to a fileset with a filepath can be written with: call subroutine(pathArg = Fileset: path:&filesetVariable);  That construct builds a srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdAccessFileset Hint: On missing variables etc. a runtime error occurs. Because JZtxtcmd is interpretative, it is not possible to check all variables on compile respectively start time. Use 12 onerror - Exceptionhandling to handle such situations. Return values: To transport results from the subroutine to outside there are 2 ways: • Use a return object. The return object is map of one or more variables. That is a approach of functional programming. • Add an additional element to a given map of an actual argument. Both ways can be combined. For the first way the call-statement is an assignment: sub testResultRet(String someArgs){ //creates a String variable inside the return Map: String return.text = <:>testResult-return from <&someArgs><.>; String return.anotherOne = "other return value"; } Map result; result = call testResultRet(someArgs = "someArgs");  The return value in this example assigned to result is a Map which contains all returned variables from the sub routines. It is similar a returned instance of a comprehensive class type in Java. To replenish any argument variable one can use the following pattern: sub testResultSub(Map arg){ String arg.ret = "testResult-replenish"; }  The arg is a Map of variables, maybe created by Map map;  or maybe the local variables of the calling level: call testResultSub(arg=jztcsub.localVariables);  This method is not functionally, not object oriented, but it may be convenient for practice. It is typical for interpretatively execution: The local variables can be replenished by some more stuff. ### 7.6 Invocation of Java methods Topic:.JZtxtcmd.statements.. You can invoke static java methods with arguments: java org.vishia.util.FileList.list("anyDirectory/path", "*", ".filelist.list");  This example invokes the static method list of the class org.vishia.util.FileList with the given textual arguments. The arguments can be build as text expression with <:>expression <&value><.>, with numeric expressions are with JZtxtcmd variable which are instances of Java data, see 9 Data and variables. You can create java instances and invoke their non-static methods. Example: Obj checkDeps = new org.vishia.checkDeps_C.CheckDependencyFile(console, 1); .... test = checkDeps.readDependencies(<:><&objDir>/ccs_dsp_obj<&$PARAM>.deps.txt<.>);


An instance of org.vishia.checkDeps_C.CheckDependencyFile will be created. After them the method readDependencies(...) is called.

See

### 7.7 Zmake

Topic:.JZtxtcmd.statements.zmake.

A Zmake statement is written in form:

zmake output := subroutine(input&fileset, input, parameter=value);


See Syntax: 16.19 Zmake. The subroutine is the translator between some inputs and the output. The output is a file or a directory and extension, where some files should be stored.

For example some files can be zipped. The output is the location of the zip file. The inputs are the files to zip. Another example is: C/C++ compilation (outputs: object files) and linking (output: The executable, maybe some more files in the output directory).

The subroutine contains the statements how to make. It is possible to invoke that commands, which executes the make process. It is possible too to produce a text output which contains the make controlling. The text output file can be a classic make file, an ANT make file, any batch or shell script or any other. The subroutine or some variables can contain some parameter to control the make. For details see Zmake.

The Zmake works with file entities and file sets. See 9.1.13 Filepath, Fileset

The subroutine is a normal JZtxtcmd sub routine. The output and input are assembled in an instance of srcJava_vishiaBase/org/vishia/cmd/ZmakeTarget which is given as first parameter:

sub subroutine( Obj target :org.vishia.cmd.ZmakeTarget, .....) {
...make target statements
}


Example make for one file only whereby the file path is given as absolute path in a environment variable:

zmake <:><&$2>.crefl<.> := genReflection(&$1);


The output file will be build with the input file plus the special extension. The input argument is only the given file path.

Example using a fileset:

Fileset srcSet =
( fileA.c
, local/path/fileB.c
, otherPath/*.c       ##all files of that directory
);
zmake "output/path/*.obj" := ccCompile("access/path": &srcSet, argument="arg_value");
zmake "output/path/*.obj" := ccCompile(access/path:&srcSet, argument="arg_value");


The zmake routine can decide which parts from the output is used for any file. For example the output files can be build with the directory of output and the extension, and the names or local pathes without extension from the input files. The & is the separator between a access path and the name of the set. The access path can be empty, an text expression or a dataAccess.

The : on end of access path marks, that the access path acts as base path for the files of the set. If the accessPath contains a : than the localPath starts there if the paths in the Fileset don't contain an localPath part. Especially .:&fileset means, the accessPath starts from the current directory and the paths of the Fileset are the local ones. Note: . is the current directory. Another example: ../../access/path:&fileset. It is a good style if the Fileset does name the local paths only. Too see variants with the localPath in Fileset and usage of parts of the filePath see the example in the zbnf.zip download

The zmake routine takes arguments in the same way like any other subroutine, see 7.5 call: Invocation of sub routines. The no named argument is a target input. It consists of two parts: The accessPath and the access to the Fileset. The access to Fileset is written right after a &. The accessPath can be omitted or given as "string", as & <dataAccess> or as chars till & without quotes. If the accessPath is given as & <dataAccess>, the distinction between a singulary access path as data Access and the & <dataAccess?zmakeFilesetVariable> is done with test of the accessed instance. It is checked whether it is a Fileset or not.

The given accessPath is converted to a String if it is accessed via & <dataAccess>. The String-given accessPath is converted to a srcJava_vishiaBase/org/vishia/util/FilePath. In that constructor the String is divided especially into the local path and the base path, separated by the character ':'.

ZBNF/examples_JZtxtcmd/TestAll/testFileset.JZtxt.bat


### 7.8 Assignments, Expressions and Text expressions

Topic:.JZtxtcmd.statements.expr.

An Expression maybe a simple access to data, but it is an execution of methods/routines often. The execution may be seen as side effect of the assignment, but it may be the originally approach and the assignment may be the secondary one. It is like in normal programming languages.

Assignments see 9.1 Types of variables and their assignment, its syntax: 16.21 Assignment to variables

Expressions see Chapter: 10 Expressions, its syntax: 16.10 Object value: objExpr

Text expressions see 13 Text output and text generation, its syntax: 16.9 Text value: textDatapath, textValue

## 8 Program flow control

Topic:.JZtxtcmd.if.

Syntax see 16.16 Control statements.

### 8.1 if()...elsif()...else...

Topic:.JZtxtcmd.if.if.

One can write

if(condition){
statements;
}
elseif(otherCondition){
statements;
}
else {
statements;
}


All program flow control statements can be nested, of course. The { } are necessary, other than in C, Java.

The elsif is the same like  else if which is possible in Java, C etc. also. It is a chain of if. elsif and else are optional.

The condition is a 10.5 Boolean expression, Conditions. If the condition is a datapath only, it is false if the path is faulty.

### 8.2 while()...

Topic:.JZtxtcmd.if.while.

One can write

while(condition) {
statements;
}


to execute statemens so long as the condition is true.

do {
statements;
} while(condition);


checks after the loop body.

### 8.3 for(container)...

Topic:.JZtxtcmd.if.for.

The JZtxtcmd does support the iteration over a container and execute statements with the current element. The old-style for loop known from other programming languages is not supported. If such one is necessary, it is able to execute it with while(...) instead. The old style for loop is imagined for indexed access to arrays usually. The for-container iteration is also known in other modern programming languages. One can write

for(element: datapath.container){
statements ...;
}


The statements were executed for each element in the container. The element on each loop referred by the variable, can (should) be used inside the statements.

Condition in for:

Additionally there is a possibility to leave the for-loop. One should write:

for(element:container && condition){
....
}


If the condition is false the for-loop is left. For example an element can be searched in the container. Write:

Obj found;
if(element.attribute == expected){
found = element;
}
}


Iteration variable can be used after a broken loop:

Since 2016-02: The iteration variable (element of the container) is created with this for loop. It is existing in the following statements after the for furthermore (rather than in Java, there it is a local variable of the for loop only). But if the for-loop is executed till its end, the iteration variable is null. Only if the for-loop was broken either by a condition or by a break statement, the iteration variable remains the last used container value. This can be used especially for searching an element in a container. The iteration variable is set before the condition is checked. Therefore it is possible to use the iteration variable in the condition too. To search an element is is shorter to write:

for(element:container && element.attribute != expected);
//use element in further statements
//it contains that value where the condition was false,
//in this case: ,,element.attribute == expected,,.
if(element) {
... //The element where the for loop was broken.
}


check if the container has a next element <:hasNext>:

Especially for text generation there is a possibility to quest whether a next element exists after the current one. Often things should be separated by a colon etc, but the colon should not be written after the last element. Write:

for(element: container) {
<+textOutput><&element.value><:hasNext>, <.hasNext><.+>
}


then the elements are separated with , but after the last element there is no ,.

The same operation in a text:

<+textOutput><:for:element:container><&element.value><:hasNext>, <.hasNext><.for><.+>


Implementation in Java, container types are Iterable, Map or an array:

The container is any javadoc-oracle/java/lang/Iterable, a javadoc-oracle/java/util/Map or any array in Java. A Map is iterated by its entrySet(), the elements are the value of the entries.

### 8.4 break, return, exit

Topic:.JZtxtcmd.if.break.

• break is admissible only in a statement block of a loop (for, while) and in an onerror block.

• If a break is contained in a loop's statement block, the statement block and the loop is broken. It is like other programming languages Java, C etc.

• If a break is written inside an onerror block, the enclosing block will be broken. It is a feature of 12 onerror - Exceptionhandling.

• return aborts the current subroutine. Don't confuse it with a return variable, see Chapter: 6.5 Subroutines and subtext

• exit aborts the whole script.

• throw aborts all blocks till a proper onerror is found.

Don't use return except in an onerror block:

A subroutine ends on its last statement. The only exception of this rule should be: An exception has occurred inside the subroutine. A conditional return inside a subroutine is not recommended, it is a bad style. The reason for that is: A return inside a lot of statements can lose sight. The algorithm inside a sub routine should be strongly structured. Note the following example:

With return inside (for example in Java);

void mySub(){
ObjType foundObj;
anyContainer.anyOpenAction();
while(anyContainer.hasNext()){
ObjType obj = container.next();
if(obj.hasExpectedProperties){
anyContainer.anyCloseAction();
do something...
return;
}
}
anyContainer.anyCloseAction();
}


Something is searched in a while loop. If it is found, the evaluation is done in a if-branch inside the while, with return inside.

Without return, code of JZtxtcmd:

• The while loop has the task to search only. It is finished if foundObj is set. That is visible in the while condition.

• The condition whether something was found or not is done after the searching process, obvious visible in the straight forward thread of the subroutine.

• Any neccessary close or finishing operation for the container handling is only programmed one time, after the container-handling while loop.

• The decision between found or not found - thats the question here - is clearly visible in the if - else statement.

sub mySub(){
Obj foundObj;
anyContainer.anyOpenAction();
while(foundObj ==null && anyContainer.hasNext()){
Obj obj = container.next();
if(obj.hasExpectedProperties){
foundObj = obj;
}
}
anyContainer.anyCloseAction();
if(foundObj){
do something...
} else {
}
}


Of course, the algorithm without return inside needs the second if-condition. It may be more expensive for calculation time. But that is minimal. In fast algorithm with slow processors (C programming for embedded) a return inside may be proper, because calculation time. But for complex algorithm in fast execution environments the return inside is not necessary, and a less proper style for programming.

Don't use break in loops:

A conditional break in a loop is not recommended. It is a bad style. The reason for that is: A break inside the loop's statements can lose sight. The condition to whether continue a loop should be able to seen only in the loop's head statement. Note the following example:

 Obj found;
Obj myIterator = myList.iterator();
while(!found && myIterator.hasNext()){
Obj element = myIterator.next();
<+out><&element><.+n>
if(element.equals("test2")){
found = element;
}
}


One of the condition to continue the loop is !found, the other one is myIterator.hasNext() - some more elements exists. That both conditions are able to see in the while(...)-line. Thats all. If the algorithm has a break:

 Obj found;
Obj myIterator = myList.iterator();
while(myIterator.hasNext()){
Obj element = myIterator.next();
<+out><&element><.+n>
if(element.equals("test2")){
found = element;
break;
}
}


- the break is not seen if the while(...) is checked.

The possibility for break in loops and return in subroutines in JZtxtcmd is a concession for widely used styles only. But the break inside an ..onerror block is necessary to abort further execution after the onerror-block.

## 9 Data and variables

Topic:.JZtxtcmd.data.

A JZtxtcmd script can have script variables and local variables in sub routines. (future extension: class variables). Another possibility is getting and storing values from/to any Java instances.

### 9.1 Types of variables and their assignment

Topic:.JZtxtcmd.data.type.

A JZtxtcmd variable is a reference to the data. There are a few types:

#### 9.1.1 Num

Topic:.JZtxtcmd.data.type.Num.

A numerical variable is presented by a integer or float (double) value. It is calculated using 10.6 Numeric Expression and presented by an Object of type srcJava_vishiaBase/org/vishia/util/CalculatorExpr.Value.

#### 9.1.2 Bool

Topic:.JZtxtcmd.data.type..

It is a boolean value or a condition, set to true or false. It is presented by an Object of type javadoc-oracle/java/lang/Boolean. Note that on definition of a Bool variable one can write

Bool myBool = a > 5;


whereby on assignment one should write:

myBool = bool(a > 5);


The reason for that difference is: The translator of the script (parser) does not recognize the type of a variable on assignment. To accept a boolean expression the bool(...) is necessary. It may be a good style because the reader of the script sees that it is a boolean assignment.

Note that the test of existence of a variable path can be written with a simple boolean assignment:

Bool myPathexists = path/to/variable;  //false if path is faulty.
myPathExists = bool(path/to/variable);
myPathExists = path/to/variable;


In this case both variants to write are accepted, with or without bool(...) because syntactical it is not necessary, The execution evaluates an boolean expression anytime with the feature of false on a non existing path instead of an exception.

#### 9.1.3 String

Topic:.JZtxtcmd.data.type.String.

A String: refers a constant text.

The text can be built with any text expression. A String variable can change its content. But the string gotten from a String variable before changing will be never changed. It is the same like a String in Java.

String myString = "text";
String mySecond = myString; //refers text
myString = "other text";    //mySecond remain unchanged!


For text expressions see the syntax in 16.9 Text value: textDatapath, textValue

#### 9.1.4 Stringjar - adding Strings, search in Strings

Topic:.JZtxtcmd.data.type.Stringjar.

A Stringjar references a srcJava_vishiaBase/org/vishia/util/StringPartAppend. It contains a javadoc-oracle/java/lang/StringBuilder which is used as Appendable. This class has all features of srcJava_vishiaBase/org/vishia/util/StringPartScan and srcJava_vishiaBase/org/vishia/util/StringPart. With that it is possible to Append or store any text and analyze it after them or while appending. Additional a remove method is included to remove parts of texts which are not need furthermore.

One can append using

Stringjar myBuffer;                //a new empty buffer
Stringjar myBuffer = "start text"; //a new buffer with intial text
myBuffer += " appended text";         //append


The += operation symbol for the assignment is the append symbol. A = assigns a new start text.

One can search any text in the Stringjar. The access to a Stringjar reads the current visible part. Additionally one can use the javadoc-oracle/java/lang/StringBuilder-methods with the stringBuilder()-method. For example:

myBuffer.stringBuilder().insert(myPosition, "a inserted text").


The instruction

myBuffer = "new Text"


does not create a new Stringjar Object (not like in Java) but initialize the given object with this new value. If a reference

Obj myBuffer2 = myBuffer;


was build before, the value of myBuffer2 is changed too because it is the same reference. But if is defined

Stringjar myBuffer2 = myBuffer;


then a new Instance of a Stringjar is created with initial value of the content of myBuffer.

Note that the javadoc-oracle/java/lang/StringBuilder is not threadsafe. A StringBuffer is threadsafe but slower. Since the Java version 5 the StringBuffer can be replaced by using the java-StringBuilder with exact the same capabilities, but without synchronized-Mechanism. It is more fast. The major of applications don't need the thread-safe property because the StringBuffer will be filled and changed usual in one thread. If it is necessary to handle a StringBuilder in more as one threads, in Java synchronized mechanism can be used. A JZtxtcmd script should not encouraged to handle with data in threads complexly. Fill in one thread, evaluate after them in another thread. Therefore the usage of StringBuilder is proper.

#### 9.1.5 Obj - any Object

Topic:.JZtxtcmd.data.type.Obj.

• Obj is any Object, any Java instance.

It is possible to create a Java instance or get any instance from a Java context:

Obj myObj = new org.myPackage.MyClass(args);
myObj = otherInstance.method_whichReturnsAnObject(args);
myObj = java org.myPackage.MyClass.myStaticMethod(args);


With this java instance any action can be done:

myObj.method();


Or the object can be added to a container to use it in a for loop.

myList.add(myObj);


The reference to the Java instance should be removed if the instance is not used any more. The garbage collector of the Java Runtime Environment will removed it:

myObj = null;


#### 9.1.6 Pipe

Topic:.JZtxtcmd.data.type.Pipe.

One can append to the pipe with


Pipe myPipe += "appended text";


or invoke any method of this class. The pipe can read out usual in another thread with the getLine or get method.

#### 9.1.7 List - a List of values

Topic:.JZtxtcmd.data.type.List.

• List is an instance which implements the javadoc-oracle/java/util/List interface.

It is able to use as container in a for-statement. A

List myList;
myList += anyObjectExpression


creates an empty list and adds an Object.

myList += anotherList;


If the added object is a java/util/List-container too, its elements are added.

myList.clear();


clears the list. One can use all methods of the List interface.

Building of container with List:

A List (an instance which implements the javadoc-oracle/java/util/List interface) is a container, able to use in a JZtxtcmd-for loop, see 8.3 for(container)....

The List can be built and used in the following way:

• Any List from Java data can be assigned and evaluated in the JZtxtcmd script.

• A List can be used with += to append data, it builds a new content of the container.

• A List can be defined as const container.

The last one possibility is proper to set some data, then evaluate something with this settings.

A list can be defined with constant texts:

List myList = [ "ab", "cd", "xyz" ];


The [...] are the brackets for the container. The items of the container are separated with comma.

Another form of such a container is a Container which contains variables:

List list2 =
[ String var1 = "ab";
String var2 = "cd";
];


An advantage in opposite to the simple Strings is: The Strings have names. It is possible to evaluate:

 for(var: list2) {
<+><&var.name>, <.+>
}
<+><.+n>
for(var: list2) {
<+><&var.value>, <.+>
}


This outputs the names in the first line and the values in the second line.

A List can be build by a Subtext variable:

List listSubtext =
[ Subtext item1 = <:>Use the content of <&otherVariable><.>;
Subtext item2 = "constant text";
];


For evaluating that container it can be written:

 String otherVariable = "content";
for(var: listSubtext) {
<+><&var.name>, <.+>
}
<+><.+n>
for(var: listSubtext) {
<+><&var>, <.+>
}


In this case the <&var> contains a Subtext, therefore the content is evaluated now in the given context. It means the variable with name otherVariable is found in the Subtext and its content is used in the for loop.

Another form of a List container can be built like:

 List variationParameter =
[ { name="hi",  Rfault="10.0", Lfault = "0.1", descr="High impedance fault"  }
, { name="mid", Rfault="0.2", Lfault = "0.1", descr="Middle impedance fault" }
, { name="low", Rfault="0.1", Lfault = "0.1", descr="Low impedance fault"    }
];


This list contains a Map of String variables. Now the combination is interesting. A loop of all variations is build, the loop uses the listSubtext:

List cellcontent =
[ Subtext cell1 = <:>Rfault = <&parameter.Rfault><.>;
[ Subtext cell2 = <:>Lfault = <&parameter.Lfault><.>;
String  cell3 = "constant text";
];

##Builds a line with the names:
##
for(var: listSubtext) {
<+><&var.name>, <.+>
}
<+><.+n>
##Builds some lines with values:
##
for(parameter: variationParameter) {
for(cell: cellContent) {
<+outs><&cell>, <.+>
}
<+outs><.+n>
}


This builds a file with 4 lines for the names and the 3 variations with a content which is defined on the Subtext cell1 etc.

#### 9.1.8 Map - a Set of variables

Topic:.JZtxtcmd.data.type.Map.

A Map is an instance which implements the javadoc-oracle/java/util/Map interface.

It is able to use as container in a for-statement.

A map is able to use especially to store variables:

Map myContainer;
String myContainer.anyVariable = "text";  //defines a String variable inside that Map


The variable is stored in the map and can be gotten by myContainer.anyVariable. This can be used to provide the variable container for sub routines too:

sub mysubroutine(Map data) {
String data.myNewVariable = "value";
}
.....
call mysubroutine(data=myContainer);
<+out><&myContainer.myNewVariable><.+n>;


A Map is build if a dataStruct is created writing (see also Chapter: 10.4 Object expression):

Map dataStruct = { String text = "value"; List anyOther = something; };


or if such an construct is used in an argument list:

myData.myJavaMethod({ String cmd1 = "cmd"; String data = anydata; }, furtherArg);


In this case the method gets an argument of type Map which contains that two elements.

One can use all methods of the java.lang.Map interface especially

myMap.clear();
myMap.put("name", value);


The value can be accessed though it is not a Variable with

Obj value = myMap.name
Obj value = myMap.get("name");


#### 9.1.9 Subtextvar, Subroutinevar - statements to execute

Topic:.JZtxtcmd.data.type.Subtextvar.

A Subtext is a variable which contains a srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdScript.Subroutine to build a text. It is a subroutine stored in a variable, similar like a function pointer in C-programming.

Subtextvar myStatements = <.>constant text and <&variable><.>;
Subtextvar myParametrizedStatements(String textArg) = <:>uses only <&textArg><.>;


A static subtext as script part is slightly different:

subtext mySubtext(String textArg) = <:>uses only <&textArg><.>;


Syntactically only the keyword subtext against Subtextvar is different. But a Subtextvar is a variable which can be a part of a List or Map, can be used as argument or stored in another Obj variable. mySubtext is not a variable but the name of a static subtext. The name can be stored as String: String theSubtext = "mySubtext";; this String can be used as argument to invoke different subtexts writing <:subtext:&theSubtext:args>. Dealing with that subtext names it is possible too to dynamic the invocation of subtexts - but using a Subtextvar may be more simple in some cases.

The statements of a Subtextvar are executed either if the value of the variable is used in an access to &myStatements, or with a <:subtext:...> in a text expression:

String myValue = <&myStatements>;
<+>textExpression invokes <:subtext:&myParametrizedStatements:textArg="my textArg">
but it can invoke <:subtext:&myStatements> without arguments too...<.+>


It is for a simple application without arguments in the current execution environment, and for a exactly application like any other subroutine respectively subtext with its own execution environment and arguments. The argumentless variant is adequate

Subtextvar myStatemens(use-local) = <.>...<:>


see &chapter, arguments and local variables. For this variant the execution environment is the current context. For example:

String variable = "Example";
<:>Any text uses <&myStatements>. <.>


The execution of the text expression finds the variable myStatements, detects that it contains statements, and exucutes it with the given context where the variable is known. Therewith the following text is produced:

Any text uses constant text and Example.


See 9.1.7 List - a List of values to see how some Subtext in a List container are used.

A Subtext variable can be used as actual and formal argument for a subroutine, maybe stored, used for a callback-mechanism. It can be used in a call statement too.

If some Subtext are contained in a map and get from there, you should store it in an Obj variable temporary because the map.get(key)-statement can only return an Obj. See 9.1.8 Map - a Set of variables. For example:

Map accesses = {
Subtextvar int(String name) = <:>super.getInt32(k_<&name>)<.>;
Subtextvar char(String name) = <:>super.getChar(k_<&name>)<.>;
Subtextvar int16(String name) = <:>super.getInt16(k_<&name>)<.>;
Subtextvar float(String name) = <:>super.getFloat(k_<&name>)<.>;
Subtextvar double(String name) = <:>super.getDouble(k_<&name>)<.>;
};


This is from Cheader2JavaByteDataAccess.jztc. The map was build to find a type from C-programming, int16 etc. To find the proper Subtextvar with a given C-type, it is programmed:

Obj accessRtn = accesses.get(attrib.type.name);


The Obj contains the gotten access routine after the access. To execute it:

<+javaSrc>
return <:subtext:&accessRtn:name=&attrib.name><.+>


The Obj which is typeof org.vishia.JZtxtcmdScript.Subroutine is taken as subtext argument and executed therewith with the given further arguments.

#### 9.1.10 Class - ?instanceof check, class loader, static method invocation

Topic:.JZtxtcmd.data.type.Class.

A Class variable is created with

Class myClass = path.to.MyClass;
Class myInnerClass = path.to.MyClass$InnerClass;  Whereby path.to.MyClass is a java package path. The named javadoc-oracle/java/lang/Class object will be stored in the myClass variable. A Class can be defined in a specific jar-file or any file location which needs a specific javadoc-oracle/java/lang/ClassLoader-instance. Such can be stored in a Classpath-variable or it can be accessed via any data.path. Using that one can write: Classpath classLoader = "D:/The/specific/jarfile.jar"; Class myClass = : classLoader : path.to.MyClass;  A Class variable can be used to access static fields and call of methods or to create an instance of the class: myClass.aStaticMethod(args); ##calls it. <:>A text <&myClass.staticMethodText(args)> ...<.> Obj aObj = java new &myClass:(args); ## creates an Object  Using a Class variable is a short form to invoke: java path.to.MyClass.aStaticMethod(args); ## without Class variable  A benefit using a Class variable in opposite to the last example is: If the path is wrong, an exception is thrown on definition of the Class variable already. To check whether any Object is instanceof the expected type, write if(myObj ?instanceof myClass) { ....  The check returns true if the object is derived from the myClass or implements the given myClass-interface of course. See 10.5 Boolean expression, Conditions #### 9.1.11 Classpath Topic:.JZtxtcmd.data.type.Classpath. A Classpath-variable holds a ClassLoader-instance. The javadoc-oracle/java/lang/ClassLoader in a Java environment is responsible to load classes from any jar-file or other location and translating it into internal machince code. If the JZtxtcmd script application needs other classes than given in the classpath of the java invocation, the Classpath should be used: Command line to invoke JZtxtcmd. Only the Zbnf.jar is given usual: java -cp path/to/Zbnf.jar myScript.jztc  Inside the script, an additonal jar file should be used: Classpath loader = path/to/additonal.jar; java :loader: package.path.Userclass.main();  The example shows the invocation of the main-routine of any class, which is located in the additonal.jar. A javadoc-oracle/java/lang/ClassLoader can know more as one jar files (and other sources of class code). It is possible to build a: Fileset jarfiles = ( path/jar1.jar , path2/jar2.jar ); Classpath loader = path/to&jarfiles, D:/any/other/file.jar;  This example shows a Fileset, describing some jar files which are located in the same pool. The path/to is the common path of both. Additinal D:/any/other/file.jar is addressed. All three jar files are given with this ClassLoader instance. One can give absolute paths to the files or relative ones. Relative paths are regarded to the current currdir directory. Usual it is set relative to the scriptdir where the main script is located: currdir = scriptdir; Classpath loader = relative/to/currdir/myjar.jar;  The other possibility is, relativ to the maybe included script: Classpath loader = <:><:scriptdir>/path/myjar.jar<.>;  A Classpath variable can be used especially to create a Class-Variable. #### 9.1.12 Openfile Topic:.JZtxtcmd.data.type.Openfile. It opens a file for writing on creation. It is a javadoc-oracle/java/io/Writer and an Appendable. Openfile myFile = "filename"; myFile += "any text"; myFile.flush(); myFile.close();  The filename can be built as text expression, of course. It have to be supplied on the definition statement. String name = ...from any procedure; Openfile myFile = <:><&name>.txt<.>;  It is recommended to close the file. Elsewhere the file remain open till the process, which executes the JZtxtcmd interpreter is finished on the operation system. If it is a long-running process, the file will remain open. #### 9.1.13 Filepath, Fileset Topic:.JZtxtcmd.data.type.fileset. See examples_Fileset. Syntax see 16.8 Fileset, Filepath. A Filepath is a String-given path which describes a file or maybe some files with wildcards. The parts of a Filepath are divide to drive, directory path. local path, name, extension and some designations for wildcards usage. From a Filepath several Strings can be build. See srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdFilepath: Instance which is used in JZtxtcmd for Filepath See srcJava_vishiaBase/org/vishia/util/FilePath: Core instance which implements the Filepath with its access methods. • name() namext() ext(): The file name, the extension or name.ext • basepath(): The path before a :, before the localfile() • absfile() absdir() absname() absbasepath(): builds an normalized absolute path with the current directory of the context. • localfile() localdir() localname(): local path parts. • fileW() etc: All methods which returns paths are existing with suffix 'W'. That methods return a backslash as separator (W=Windows) where the methods without W returns a slash as separator. Note that all path which are used in a Java context can be written both with slash or backslash in a MS-Windows-context. The usage of slash is recommended, it is the compatible form. Only if a text should be generated for windows processing, especially a bat-file, one should use the 'W'-variant. localfile(): As a special feature a : can be used as separation between the path and a local part of the path: Filepath myPath = "D:/the/path:local/path/file.ext";  A Filepath can be written relative or absolute. A relative path can be associated to different base directory locations in its usage in the script. There are methods to build the file String using an access path or a common-path: myPath.file(Appendable, commonpath, accesspath)  adds the filepath to the appendable regarding a commonpath and a accesspath. For example: Filepath commonpath = mydocs; Filepath accesspath = D:/data; Filepath thefile = docA/fileX.doc; Stringjar buffer; thefile.fileW(buffer,commonpath, accesspath);  fills the buffer with D:\data\mydocs\docA\fileX.doc. The commonpath and the accesspath can be parameters of a subroutine and can be set for example in an included script. The file which should be handled is docA/fileX.doc. The other Filepath variables determines where this file will be located. The commonpath is an additional feature for common base paths. Usual only the accesspath is a point of interest: Wildcards in a Filepath: One can write a single * one time in any name of a path, maybe in a directory part too. Then all matching directories respectively files are used. One can write a /**/ as directory in the path. That means all sub directories in any tree depth are matching: mydir/**/*.obj  addresses all object files in any sub directory level from mydir. my*dirs/test*/*  addresses all files in directories which starts with my end ends with dirs, then in all directories which starts with test and there all files. The method myFilepath.expandFiles(listToAdd, commonPath, accessPath, currdir)  builds Filepath instances for all found files and adds it to the given list. Variable in a Filepath: A Filepath can start with any JZtxtcmd variable. In the Filepath the variable is designated with an &. Then the Filepath starts with &. On evaluation the path the content of the variable is used. Usual the variable is a filepath too, which contains the start directory of files. This feature increases the flexibility while using FilePaths: Filepath whichDocu = docA; Fileset docuFiles = ( &whichDocu/fileX.doc, &whichDocu/fileY.doc);  This two statements can be written in different files, one may be included. Usage of &$ gets an environment variable:

Filepath tmpfile = &$TMP/tmpfile.txt;  Build Strings from file entities: The following table presents all methods to build Strings from a file entity: Path designation: • abs...: Absolute path • local...: Local path • Elsewhere the path like written in the fileset and its access: Either the given absolute path, or the given path with the access path. Part designation: • basepath: The base path if exists, or an "." respectively the root directory if it is not defined. • dir: The directory, absolute, local or like given • pathname: The file with path but without the extension, absolute, local or like given • file: The file with path and extension, absolute, local or like given • name The name only. • ext The extension only. windows or slash designation: • All methods except name() and ext() are available with an ending W. This produces backslashs in the path. Elsewhere slashes are produced. With that the following combinations exists as methods:  absolute base_local like given only local abs-backslash like given local absbasepath() basepath() absbasepathW() basepathW() absdir() base_localdir() dir() localdir() absdirW() dirW() localdirW() absname() pathname() localname() absnameW() pathnameW() localnameW() absfile() base_localfile() file() localfile() absfileW() fileW() localfileW() name() namext() ext() • absolute builds an absolute path maybe with the given$chapter if the path is given relative.

• base_local returns the basepath and the localpath separated by the colon.

• like given returns either an absolute path if it is given in this form or a relative path.

• only local returns the local part.

Examples using several configurations of Filepath and Fileset are contained in the Zbnf-Download examples_JZtxtcmd/HandleSomeFiles.

Fileset:

A Fileset contains one or more Filepath, it names files:

Fileset myset = ( file1.ext, path/file2.ext, "base path:local/**/file 3.*");


The ** means any directory tree depth. Wildcards can be used in directory names too. One can use slash or backslash as directory separator. The slash is recommended.

One can build a list of Filepath with the method

List files = myset.listFiles();


Then all files from the set are presented in that list. If you invoke:

List files = myset.listFilesExpanded();


then all files with wildcards are expanded to the real existing files of the moment of execution. This method accesses the file system.

Since 2017-09: A Fileset can include another Fileset:

FileSet set2 = ( &myset, file2.ext, .....);


On listFiles() or listFilesExpanded() this sub Fileset is recognized, unpacked and included.

Using of Fileset in zmake:

zmake supports file sets because most of operation of zmake deals with files. One can write:

zmake myOutput/file.ext := makeroutine(path/sub & fileset);


whereby fileset is a name of a Fileset. path/sub is the access path to the Fileset.

Usual the access path should be a base path and the files of the Fileset describe a local path. Then one should write:

zmake myOutput/file.ext := makeroutine(path/sub: & fileset);


The colon as last character of the Filepath of the access path defines path/sub as base path.

The access path can be a variable, because a Filepath can be build with a variable:

zmake myOutput/file.ext := makeroutine(&filepath:&fileset);


In this case the filepath.file() builds the access path as base path.

Relation between base path and local path:

Especially if a Fileset is used with an access path, then the following rules are valid:

• If the Filepath of the access path contains a local path, then it is used as local one. The base part is the base part of the access path.

• If the Filepath of the access path does not contain a local path, then the whole access path is the base path.

View the following examples:

Fileset fileset = (localpath/myFile, otherpath/file2.ext);

zmake output1 := routine1(base:local&fileset);
zmake output2 := routine2(path&fileset);


base:local respectively path is the access Filepath for the Fileset.

routine2 uses path as base path, routine1 use local/ from the access variable as part of the local path.

If a Filepath contains a scriptVariable, the scriptVariable will be handled in an adequate way:

Filepath path1 = base:local;
Filepath path2 = path2;
Filepath path1a = &path1/file.ext;
Filepath path2a = &path2/file.ext;
Filepath path1b = &path1:file.ext;
Filepath path2b = &path2:file.ext;


The resulting is

path1a = base:local/file.ext;
path2a = path2/file.ext;
path1b = base/local:file.ext;
path2b = path2:file.ext;


See examples_Fileset.

#### 9.1.14 Set

Topic:.JZtxtcmd.data.type.set.

It sets environment variables for the next 7.2 start, cmd: Invocation of operation system commands.

set name = value


The environment variable is stored in the variable context with $ as prefix for its identifier. One cannot change the value of an environment variable, but the variable is possible to set newly: Set env = "value"; cmd anyCmd; Set env = <:>other value<.>; cmd otherCmd;  • set and SET does the same like Set. ### 9.2 The data path Topic:.JZtxtcmd.data.path. A variable of the script or subroutine level may contain a simple value or text. On the other hand • a variable can refer any Java instance, which has internal data and methods. • a variable can refer a Map<String, Object>. In the first case a JZtxtcmd variable can contain a reference to any Java instance. The attributes, references and methods of that instance can be accessed. In the second case the Map refers other data by its name. It builds a tree of data. In JZtxtcmd it is possible to build a datapath to address data. The syntax is described in 16.11 DataPath, Data access. jztc.startmilli  is the path from the predefined variable jztc which refers the instance of JZtxtcmdExecuter to the data field srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.JZtxtcmd#startmilli. In a Datapath methods can be invoked. For example the current directory as String with Slash (unified) can be gotten with jztcsub.currdir()  A method can be called with actual arguments. The next example creates a user specific object and invokes a method from it. That is inclusion of Java classes pure: Obj myObj = new mypackage.MyClass(); myObj.myMethod(5, "a string", jztcsub.currdir());  The fields and methods from any instance are found and accessed via the reflection mechanism of Java. The translator of the JZtxtcmd-script has not any knowledge of the objects and there elements. It means the translator cannot detect errors, other then a Java compiler. It is a property of script languages in opposite to static languages. Errors in access are detect on runtime via an exception, which can be catched with an onerror statement in the JZtxtcmd script: anyObj.reference.method(parameter); anyOther.datapath = value; onerror { <+out>Access error in script: <&error><.+n> }  A script should be checked by running all branches of software. Therewith all data paths should be checked on runtime. If a branch is not tested the a probably usefully message should be outputted. Access to private fields and methods: The flag jztc.bAccessPrivate = 1;  can be set in the script. Then the datapath can access private and protected elements of a class members just as well public ones. Note that the private and protected encapsulation is forehand a property of the compilation and source dependencies. A debugger can access private members to show there content of course. Therefore it may nice to access them in a JZtxtcmd script too. But a software, including the JZtxtcmd script software should not presume the existence of the private members. Private and protected elements are not public, therefore they can be changed and removed in the software life time cycle without consultation of all assumedly users. Syntax and implementation: The access via datapath is implemented in the class srcJava_vishiaBase/org/vishia/util/DataAccess. For the syntax of a datapath in a JZtxtcmd script see 16.11 DataPath, Data access Predefined script and subroutine variable are described in 9.5 Predefined script variables ### 9.3 Variable definition context, datapool Topic:.JZtxtcmd.data.defcontext. A JZtxtcmd script knows scriptvariable, see 6.1 Script variables. They are defined at script level and contained in the script datapool. The other possibility is the class level (future extension) or the level of the routine with the local datapool. Local variables in subroutines: Variable which are defined inside sub routines are local valid, usual known from all static programming languages. But Variable which are defined in inner statement blocks are defined for the subroutine level, other than in static programming languages. This feature saves calculation time for nested blocks because the variable should not be copied for any inner block. Often inner blocks does not define variables, then this feature does not matter. But respect: sub anySubroutine(String arg) { if(condition) { String s2 = arg; } else { String s2 = "other"; } <+out>result= <&s2><.+> }  It is possible to define a variable conditionally, and evaluate outside of the conditions. If the variable is not defined on evaluating time, an exception is thrown or false is returned: sub anySubroutine() { if(condition) { String s2 = arg; } if(s2) { //only if s2 is existing <+out>result= <&s2><.+> } }  For checking the existence of a datapath see10.5 Boolean expression, Conditions. On comparison with static languages it is: void aC_function(char const* arg) { char const* s2; //defined but not set. if(condition){ s2 = arg; } else { s2 = "other"; } ... }  The C/C++ or Java language needs the declaration of the variable outside the nested statement block but the assignment can be done inside. There may be the adequate effect: an undefined variable. But the Java compiler detects this situation on compiletime (other than C), the JZtxtcmd script execution detects it on run time only. Note that the last value of an element of a for(element: container){ //... } <+out>last element:<&element><-+>  is existing outside of the for loop because that behaviour. Other than in static languages. In case of doubt you should not use that property. Use the policies of static language for a well program structure. But you can use that behaviour if it is gainful for your solution. Tree of variable definition, build structures: It is possible to define a tree of variables. A variable acts at tree root, some variables are defined below that root, that variables can act as tree root too. A treelike structure of variable offers a struct definition of data. It is possible to use the root variable of a tree or any of its boughs as argument of a subroutine. Then the subroutine knows all data of that bough. Note that it is another concept of structuring data than in C with a struct definition. The writing rule for definition a variable inside a tree is: Obj myContainer.insideContainer.newObjvariable;  That defines the myContainer if not existing yet, inside the deeper level insideContainer and then the Object Variable with name newObjVariable. It is possibile to deal with myContainer for example to supply it to a sub routine call. The sub routine gets the content of this container and can define inside more variables: sub mySub(Obj container){ String container.myStringInSub = "anyText"; } ... call mySub(container = myContainer);  This possibility builds data structures in form of variables in a pool. The container is a Map<String, DataAccess.Variable> with the given name of the variable. It is possible too to create a variable in this kind in a existing user level Java instance: Obj myJavaObj = anyOtherAccess.getJavaObject(); //gets the reference in the given context String myJavaObj.container.newString = "xxx"; //creates a String Variable in the users instance.  With them in the Java programming level that data can be used: myJavaObj.doAnything(); //invokes a method of the Java instance.  A simple variable without dot or the start variable will be created in the datapool of the context, either in the script, or at class level or as local variable of the routine. Because a subroutine has its local datapool, the script variables are never destroyed. A defined variable in a sub routine with the same name like a script variable covers the script variable. This is a well used effect if necessarry. The created variable is a instance of type srcJava_vishiaBase/org/vishia/util/DataAccess.Variable. This instance contains the name, the type, the const designation and an Object reference to the value. The datapool is a Map<String, DataAccess.Variable> with the name as key. If a variable is existing already, it will be created newly. Normally a variable should not be declared twice. But it is not checked. In further versions of JZtxtcmd a second definition may be cause an exeception. Don't do so. The next level after a dot is either a 9.9 Access to Java internal data or the level before is a datapool. A new variable will be created always inside its left side datapool. The following rules are valid: • a) A simple variable or the last datapathElement is created always newly as instance of DataAccess.Variable. • b) If the startVariable or any variable of the datapath is not existing, it will be created as instance of DataAccess.Variable. If a further datapathElement followes, its Object value is intialized with an instance of Map<String, DataAccess.Variable>. It means, a variable node left builds a datapool. • c) An existing left-side datapathElement have to be of type Map<String, DataAccess.Variable> if the right-side variable is not existing or if it is the last one and should be created therefore. Otherwise an exception is thrown. • d) If a variable left-side of a further datapathElement exists, it will not be created newly. • e) An existing left-side datapathElement can have any type, if the right-side datapathElement is exisiting and it is not the last one. In this case method calls are admissible too. It is a 9.9 Access to Java internal data. Examples: • myVariable: rule a). It is created newly. • myData.variable: rule a)b). myData is a new datapool, its first element is variable • myData.variable2: rule a)c). myData is yet existing as datapool, variable2 is created inside • data.methodx(param).variable: rule a)c)d)e): Assumed, data is an existing java instance which offers a class method. This methodx(param) returns a Map<String, DataAccess.Variable> which is the container to add variable. For the syntax of variable definition see 16.7 Variables. ### 9.4 Datapath depending on Variables Topic:.JZtxtcmd.data.dataElementVar. Sometimes it may be necessary to access data depending on other conditions. For example access data in a tree which is build from any data base. Instead write if (ctrlVar == "A"){ data = path.to.A.data; } elsif(ctrlVar == "B"){ data = path.to.B.data; }  one can write: data = path.to.&(ctrlVar).data;  The content of ctrlVar replaces that part inside the Datapath. Of course only admissible values can be processed. Elsewhere an exception is thrown which can catched with 12 onerror - Exceptionhandling. An example for that is contained in examples_JZtxtcmd/TestAll/testAll.jz.bat in the sub testVariableDatapath(). ### 9.5 Predefined script variables Topic:.JZtxtcmd.data.prevar. Some variables are defined on start of JZtxtcmd-execution and for any sub level. They are constant, it means not able to change in the users script. Some variable are constant for the whole execution, some variable are set for special situations. They are: • scriptdir The directory where the script from this JZtxtcmd invocation is located. It is an absolute normalized path with Slash as separator. • scriptfile The file name.ext of the script from this JZtxtcmd invocation. • console Reference to an instance of srcJava_vishiaBase/org/vishia/cmd/MainCmd which is often used for some vishia methods. • error The last error message from an exception. • out constant script variable, the standard output, it is an Appendable. • err constant script variable, stderr • text constant script variable, it is the srcJava_vishiaBase/org/vishia/util/StringFormatter respecitvely an java.lang.Appendable where the <+>text output<.+> is written out, given from command line argument -t:outputfile or from the appropriate calling argument. • null constant script variable, a null reference. • nextNr instance of srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.JZtxtcmd.NextNr which increments and returns a number on any access. It is a simple possibility to have a counter. • test constant script variable to the srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdTester for some test methods. • conv constant script variable to the srcJava_vishiaBase/org/vishia/util/Conversion for some conversion methods. • jztc constant script variable, reference to the srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.JZtxtcmd. It is possible to access public methods and fields. The following static classes are provided as 9.1.10 Class - ?instanceof check, class loader, static method invocation script variables for simple access to static methods: Some variables are defined in any subroutine level. That are local variables, which are independent only valid for the subroutine level: #### 9.5.1 jztc Topic:.JZtxtcmd.data.prevar.jztc. It references srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.JZtxtcmd. Able to use for: • jztc.bAccessPrivate = 1;: Enable access to private and protected data in Java class instances. • jztc.scriptVariables().anyVariable = newValue;: change script-variables from any execution level. • jztc.log: Instance of srcJava_vishiaBase/org/vishia/mainCmd/MainCmdLogging_ifc for logging • jztc.startmilli: milliseconds after 1970, start time of the script (begin running phase), use System.currentTimeMillisec() to build differences or set it newly. • jztc.startnano: nanoseconds relative, start time of the script (begin running phase), use System.nanoTime() to build differences or set it newly. See javadoc-oracle/java/lang/System #### 9.5.2 jztcsub Topic:.JZtxtcmd.data.prevar.jztcsub. It references srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExecuteLevel. Able to use for: • jztcsub.currdir(): current directory as String • jztcsub.localVariables: Map<String, DataAccess.Variable> of all local variables able to use for subroutine-argument • jztcsub.cmdErrorlevel: Return value of the last cmd invocation. ### 9.6 Definition and change of script variables Topic:.JZtxtcmd.data.var. Script variables have a global character. They should be only a few variable, able to look over them. Some script variable are pre-defined and not able to change. Some other script variable can be changed but that is restricted. Normally the subroutines get a local copy of the script variables, so a change of it does only change the value of the local copy. In seldom cases a change of a script variable should be required. That can be done by using the script variable jztc. It is the JZtxtcmdExecuter itself, see 9.5 Predefined script variables. One should write jztc.scriptVariables().TEST = "new script value";  to copy the local value of - for example TEST to the script variable. That should only be done if the variable for the whole script need to be changed really. It should not used because it is more simple to deal with that value between two sub invocations. //Negative pattern: call mySub1(...); //changes the TEST globally. call mySub2(...); //Uses the changed value of the global variable.  That is an simple old programming style. It disadvantage: A subroutine can not assert that the value of a script variable is set with the known value of the script, any other program part may have change it for its stuff. If it is necessary to have a changed value of a script variable, you can change it locally: TEST = "new value"; //changes the local copy  If subroutines of a deeper level should use this changed current directory, it is possible to give it as a parameter: sub mySub(TEST=TEST,...){...}  That subroutine defines a calling argument TEST, it is initialized per default with the current value of TEST of the script, not of the caller. If that subroutine should override the script variable of TEST one should write: call changeCD(TEST=TEST);  ### 9.7 Access to environment variables Topic:.JZtxtcmd.data.env. Environment variables of the systems environment which has called the JZtxtcmd process are available with &$name


Especially the standard operation system variable are stuff to use, such as &$HOME, &$OS Which variable are existing depends on the operation system and the calling environment.

Topic:.JZtxtcmd.data.env.

The first level of a variable is a local variable of the current JZtxtcmd subroutine or a scriptvariable of the current jztc Script. Note the existence of 9.5 Predefined script variables.

A JZtxtcmd variable can be stored in a tree structure. A node is a 9.1.8 Map - a Set of variables, the last element is the specified JZtxtcmd variable. To access such a treed variable write

localVar.subvar.subsubvar


Note that such a structure can be defined with

Map localVar;
Map localVar.subvar;
String localVar.subvar.subsubvar;


It is possible too to transport a reference to a node to any subroutine:

call mySub(localVar.subvar);
sub mySub(Map map){
<+out><&map.subsubvar><.+n>
}


In a context where a normal text is parsed as text literal a * have to be written before the variable. For example:

call mySub();  //mySub is the direct name
call *mySub(); //mySub is a variable which contains the name.
cmd execute.exe argument;   //"argument" is the direct argument.
cmd execute.exe *argument;  //argument contains the argument string.


The same rule is valid for environment variables: &$envvar in that adequate context. Variable can start with $ in its identifier. That are conventionell JZtxtcmd variable. But they are used as environment variable for 7.2 start, cmd: Invocation of operation system commands.

Topic:.JZtxtcmd.data.jdata.

The first tag to access to Java internal data is a JZtxtcmd variable. It can contain any Reference to a Java object. For example a new Object can be created:

Obj myBuffer = new java.lang.StringBuilder("initial text");


If a JZtxtcmd script is embedded in a Java environment some JZtxtcmd script variables can be predefined with references to Java objects. For example refer Zmake. A Zmake generation script is a JZtxtcmd script. It knows via zmake all necessary stuff from the zmake input file.

myBuffer.insert(8, "any other ");


in this example insert(...) is a method from the referenced class javadoc-oracle/java/lang/StringBuilder.

The path starting from the JZtxtcmd variable is written in normal Java language style. It is executed using the Reflection mechanism of the Java language.

The actual arguments of methods are 10 Expressions, see also the syntax in Chapter: 16.10 Object value: objExpr. If a method expects a java.io.File as argument, one can write

•  anymethod(..., File: text_expression,...)

to get a file object with the textual given path. Note that return values from 9.1.13 Filepath, Fileset is a CharSequence. to convert it to an expected File instance write

java pkg.path.javaMethod(..., File: &myFilepath.absfile(), ...);


References to other instances can be given with datapaths too:

Obj myStringPart = new org.vishia.util.StringPart(myBuffer);
java pkg.path.javaMethod(..., myStringPart, ...);


The constructor of StringPart expects a Reference to an java.lang,CharSequence which is given with the myBuffer. The mechanism of overloaded (argument dependent) methods works properly.

The access is restricted normally, only public members can be accessed. But it can be unlocked. The cmd line Argument

-accessPrivate


respectively calling arguments accessPrivate

can be set on invocation of JZtxtcmd. Then the access to private members are unlocked. Private members may be necessary to access for example for debugging.

The access to Java data can be a long term, started on any given variable in the JZtxtcmd context:

 myVariable.field.method().fieldB


In this example the method() may return an instance which's fieldB is accessed.

If an instance is a java.util.Map the next element is taken is key for the map to select the member:

myVariable.myMap.key


It is the same to write

myVariable.myMap.get(key)


A special feature is, to hold the name inside a variable:

myVariable.myMap.&(variableContainsKey)


The length of an array or the size of a java.util.Container or java.util.Map can be requested by

myVariable.myMap.[]


The [] should be associated with the length of the whole container.

To Access array elements you can use the known

myData[index]


but yet only with one index as constant value. (2016-01-17). It is proper to read out data from a pre-prepared array.

### 9.10 Access to static Java data and Invocation of static Java methods

Topic:.JZtxtcmd.data.jstatic.

The keyword java or a simple % on start of a datapath declares the path as a package.class path to a Java class or method.

Obj myObj = java org.myPackage.MyClass.getData(args);
java org.myPackage.MyClass.doAnything();
%org.myPackage.MyClass.doAnything();


Alternatively a Class variable can be used to invoke a static method:

Class MyClass = java org.myPackage.MyClass;
...
MyClass.doAnything();


The package path should be complete and the classes should be able to find by the running JVM. It means self-written Java classes should be the part of the class path of the invocation of JZtxtcmd. Alternatively the capabilities of the java.lang.ClassLoader can be used.

Some classes are able to address by the name without the package path. It is more easy to write. That are classes which provides often used static methods. The following identifier are pre-defined as Class-Variable:

### 9.11 Creation of new instances of Java classes

Topic:.JZtxtcmd.data.jnew.

The keyword new or java new on start of a datapath declares the path as a package.class path to a Java class for creation a new instance.

Obj myObj = java new org.myPackage.MyClass(args);


The package path should be complete and the classes should be able to find by the running JVM. It means self-written Java classes should be the part of the class path of the invocation of JZtxtcmd. Alternatively the capabilities of the java.lang.ClassLoader can be used.

### 9.12 Invocation of Java methods, arguments

Topic:.JZtxtcmd.data.method.

A method invocation is part of a Chapter: 9.2 The data path.

Static java methods can be invoked with 9.10 Access to static Java data and Invocation of static Java methods. The following examples shows the invocation of the static method atan2 (arcus tangens) with 2 numeric values:

Num value = java java.lang.Math.atan2(1.5, 2.2);


An interesting case is the invocation of a

public static final void main(String[] args){ ... }


which is the main routine of all Java classes which can be ivoked by a command line. In a JZtxtcmd script you can write:

java myPackage.Path.Class.main();
java myPackage.Path.OtherClass.main("argument", <:>argument <&variabe><.>, "third argument");


If a method expects exactly one argument of type String[] and all given arguments are CharSequence, then the proper String[] will be build with all given CharSequences. If no argument is given, that routine gets a String[0].

Non-static Java methods can be invoked either on a reference to a 9.11 Creation of new instances of Java classes or on a Java instance referred with a 9.5 Predefined script variables. The following example creates an instance and invokes a method from them with numeric values:

 Obj obj = new org.vishia.zcmd.JZtxtcmdUserExample();
obj.methodTest(5,8);


The arguments are an ObjExpr, see 10.4 Object expression and syntax: 16.10 Object value: objExpr. The expression will be translated to the internal presentation in JZtxtcmd and it will be calculated on Runtime before the method is searched.

Methods in Java are argument-sensitive (adequate in C++ also). It means, methods with the same name but with different argument numbers or types are different methods. Therefore the argument should be checked. Additionally the arguments should be converted. It is done as capability of srcJava_vishiaBase/org/vishia/util/DataAccess.

• An argument is matching if the method expected a super type of the given argument value. For example a CharSequence can be given by a String or a StringBuilder.

• An argument is matching if it can be converted automatically, especially for numeric arguments. If a float is expected, but an integer is given, it is okay. The reflection mechanism expects an Float instance. It is converted from an int to Float.

A numeric value will be calculated and the result will be converted if possible. For example

 Obj obj = new org.vishia.zcmd.JZtxtcmdUserExample();
obj.methodTest(5*Math.PI, 8+5);


In this case the first argument uses the JZtxtcmd variable Math which is the class javadoc-oracle/java/lang/Math to get the value of pi. The double density value of 5*pi is converted to the requested float. The second argument is 13.

An integer value can be converted to a char. A String with exactly 1 character can be converted to a char argument:

 obj.methodTest('a');
obj.methodTest('b'-1);
obj.methodTest(65+32);
obj.methodTest(0x61);
obj.methodTest("a");


All this examples invokes the method methodTest(char cc) in that class with the character 'a'.

Any CharSequence can be converted to a String:

 ## invokes methodTest(String)
obj.methodTest(<:>content of <&obj><.>);


The expression is calculated in a StringBuilder-Buffer. It is converted to a String because the methodTest(String) exists.

If a method requests a javadoc-oracle/java/io/File it can be written:

obj.methodTest(File: "myFile");
obj.methodTest(File: path/theFile.ext);


The File: causes to convert the following text expression to a file path and name with the currdir how it is set in the JZtxtcmd context.

Note that comlex numeric calculations are much slower than in a Java execution environment because the JVM translates operations from its bytecode in machine code before execution. Therefore a Java Bytecode execution is aproximately equal fast like programming in a direct compiled language such as C or C++. But the JZtxtcmd execution is really an interpreter and therefore slower. Complex numeric calculations should be programmed in Java. But the numeric calculations are not slower as in other script languages.

## 10 Expressions

Topic:.JZtxtcmd.expr.

An expression can be used to combine something to assign its result to a variable or for a actual argument only. The basic idea of Functional Programming is, expressions to calculate something ('functions') should not have side effects.

An expression can have side effects, it changes other data. The so named 'side effect of an expression' can be the goal to invoke an expression. Calling a procedure.

It is the same like in all other programming languages.

The result of an expression can associated to the categories:

• text (String)

• numeric (float, double, integer)

• boolean (true or false for conditions)

• any object of a dedicated type.

To concatenate strings see 13 Text output and text generation.

A numeric or boolean value is stored in the wrapped form as Object.

### 10.1 Operands of the expression, constants, Java DataAccess

Topic:.JZtxtcmd.expr.DataAcess.

Operands are either

• constant: 5.0, 387, "constant text"

• Values in a JZtxtcmd Variable

• Values from any Java location.

### 10.2 textValue or textDatapath

Topic:.JZtxtcmd.expr.textDatapath.

See its syntax in 16.9 Text value: textDatapath, textValue.

textValue

If a text is expected in the syntactical context the constant text can be written as usual. For example in 7.2 start, cmd: Invocation of operation system commands a command can be written simple as:

cmd notepad.exe myfile;


It is like a command line in a batch file or shell script. The spaces are the separator between arguments. Any argument is a textValue. Note that a textValue written as simple text cannot start with an ampersand & and ends on a whitespace or one of the character ;,)(.

If a constant text should not be used rather the content of a variable one can write:

cmd &myCommand &myArg;


If the textValue starts with an ampersand, a 16.11 DataPath, Data access follows. In the simple kind it is the name of a variable which's content is used.

Alternatively a textvalue can be written with quotation mark like known:

cmd notepad.exe "my file with spaces in the name.txt"


The forth form is use an 10.3 Text expression for a textValue. It offers the possibility to assemble the text with variable content in any desired form. One can write for example:

cmd notepad.exe <:><&topic>.<&extension><.>;


In this case the file name for the notepad is built with the content of a variable topic and a special extension stored in the variable extension.

textDatapath

If a text is expected but usually not an immediately text a textDatapath is used syntactically. To get a constant text one should be used quotation marks. It initializes with a constant text. Writing of quotation marks are usual in that kinds:

String myVariable = "any text";


A datapath can be written immediately. A simple String is recognized as identifier. For example, the new defined String myVariable is filled with the content of otherVariable:

String myVariable = otherVariable;


For compatibility you can write also, the & is optional. Then the textDatapath and the textValue are written with the same syntax:

String myVariable = &otherVariable;


Note that a datapath can be a variable path. In the following example the datapath is contained in the variable a_datapath, see 9.4 Datapath depending on Variables:

String myVariable = &(a_datapath);


The same in a textValue but compatible in a textDatapath can be written as:

String myVariable = &&(a_datapath);


A textDatapath can be build with an Chapter: 10.3 Text expression too, it is the same like in textValue:

<:>a textDatapath with <&value><.>


### 10.3 Text expression

Topic:.JZtxtcmd.expr.textExpr.

Syntax see Chapter: 16.14 TextExpression

A textExpression is written between

<:>the text expression<.>


if it is used as an argument String or for assignment to a String or Stringjar or Obj-Variable.

Text expressions are used for 13 Text output and text generation respectively write into files and output texts to console. The the expression is written between

<+channel>the text expression<.+n+flush>


A text expression can contain:

A text expression can be spreaded over some lines, whereby indentation is regarded, see 13.3 Lines and indentation in the script

Simple example: build a path relative to the script directory:

<:><:scriptdir>/my/file.ext<.>


For example a String argument should be given for a subroutine or Java method invocation. The argument list may contain:

myObj.method(<:>The String with <&variable> has called <&otherObj.method(<:>with <&variable><.>)><.>);


In this example two text expressions are nested.

### 10.4 Object expression

Topic:.JZtxtcmd.expr.objExpr.

Syntax see Chapter: 16.10 Object value: objExpr.

Any free instance is an java.lang.Object and it can be stored as an Obj:

Obj data = myDatapool.method(args);


The args are an Object expression too. The gotten instance has its specified type of course. Therefore any method of this type can be used:

data.specialMethod(args);


Because the JZtxtcmd is an dynamic language, not only the few methods of java.lang.Object can be invoked.

An Object expression can be build as Map of some named Objects:

Obj myDatastruct = { String val1 = "anything"; Obj data = theData; };


That is usefull if the Object with more as one data should be stored and transfered in an container.

### 10.5 Boolean expression, Conditions

Topic:.JZtxtcmd.expr.bool.

Syntax see Chapter: 16.12 Condition expression.

To get boolean values with boolean operators especially for method arguments one have to be used the JZtxtcmd

bool( boolExpr )


method. To check conditions in 8 Program flow control one should write

if( boolExpr ) { ... }


A boolExpr can contain && and || and the ! like known for Java, C. Instead ! not can be written. It may be better visible in a JZtxtcmd script. The bool(...) syntax is not necessary if only boolean is expected, especially in 8 Program flow control.

The operands for boolean logic are either compare results or simple values.

A boolExpr which contains only a 16.11 DataPath, Data access is false if the data path is faulty. A NoSuchFieldException or a NoSuchMethodException are catched and forces the false value. In this kind the user can write

Obj exist = bool( data.path);


then exists is set to false or true depending of the corretness of the path.

if(data.path){...}


is not executed if the path is faulty or the variable is null or 0, whereby

if(not data.path ==null){...}


causes an exception if the data.path is faulty, because the path is used to compare.

Comparison:

Two numeric expression results can be compared using

==  !=  >   >=  <   <=


like it is known in Java, C. Alternatively it can be used

?eq ?ne ?gt ?ge ?lt ?le


especially in text generation parts because > has an abbreviating meaning <&textpart> etc, see 13 Text output and text generation.

Note that comparison are parts of a boolean expression. bool(a > b) should be written to build a boolean value of the comparison.

Comparison of Strings:

If you write

myVariable == "reqested text"


and the variable is a CharSequence, the content is be checked on equality. != can be checked too. The operation

myVariable >= "starttext"
myVariable ?ge "starttext"


returns true, if the variable startsWith the comparison text. The >= means it may be longer or equal. It is not a comparison of alphabetic order. The >= it usefull in some operations. Another proper special operator is

myVariable > "containstext"
myVariable ?gr "containstext"


It returns true if the variable contains the text.

That comparison are done if both operands left and right of the compare operator are a CharSequence such as a javadoc-oracle/java/lang/String, a javadoc-oracle/java/lang/StringBuilder or a Stringjar: srcJava_vishiaBase/org/vishia/util/StringPartAppend.

Check of a reference whether it is null:

In difference to Java language it is possible to write simple

if(myObject) { ...


If the myObject is null that expression is false. myObject can be any reference in any data.

instanceof - Check of a reference whether it is an expected type:

Similar to Java language an Object can be checked whether it is an instance of an expected type. Write

Class myExpectedType = org.myPackage.MyType;   ##used for instanceof check

Obj anyObj = ...
Class
...
if(anyObj ?instanceof myExpectedType) { ...


The ?instanceof operator needs on left side any Object and on right side a Class object. It is true if the class is type of the given type, maybe in an super class too.

Automatic conversion to boolean:

Inside a bool(...) respectively in a boolean expression of a control statement an automatic boolean conversion is done:

• References which provides a null are converted to false, existing references are true

• But references which refers to a Boolean instance returns false both on null-reference as if the boolean value is false.

• Numeric values are not converted automatically (since 2016-06). That is because firstly it should be able to check whether the value is found. The null-test is prior. Look for the example:

Map myMap = .... //contains some variables
Obj value = myMap.name;  //searches the instance with key "name" in the map.
if(value) {
//it should check whether the Obj is found. It can be a numeric type.
if(value !=0) {
//That is true if the value is numeric and not 0.
//If the value is not found (,,null,,) or not a numeric, the boolean expression is false.
....
} }


### 10.6 Numeric Expression

Topic:.JZtxtcmd.expr.num.

Syntax see Chapter: 16.13 Numeric Expression

A numeric expression can be build with the ordinary numeric operators + - * / and ( ) with numeric values. Functions can be called with the javadoc-oracle/java/lang/Math methods.



Class Math = java.lang.Math;  ##defines Math in a variable

Num y = Math.sin(0.1);               //calculates
Num y2 = %java.lang.Math.sin(0.1);   //long form for static methods
<+out>y = <&y:%1.5f> <.+n>           //outputs it with given format.


Usual numeric expressions may be used only for building of arguments for some methods. Complex numeric calculations should be programmed in Java routines. arrays are supported yet only with access to 1 index as constant (2016-01).

Multithreading is an important capability, which is missing in some other script languages. For example an executable can be started via 7.2 start, cmd: Invocation of operation system commands which needs some time to execute. Simultan another executable can be started. It needs its own thread because the thread should wait of finish the cmd line process when its result is needed. Java methods can be started too in the other thread. Then it works in the same process space with possibility of data exchange.

A thread is able to define in two ways:

{ ... any statement block;
... statements;
}
...more statements,
}


The thread starts if the execution in the parent statements arrives the thread statement. The thread is executed concurrently to the parent statements with the Java's VM thread capability. It is similar as a _Fork_(system_call)_(Wikipedia) in UNIX systems, but with a second thread in the same process of operation system. In opposite fork creates an new process on operation system level.

If the last statement of the thread is finished, the thread will be removed.

If the parent statement block reaches its end, the thread is not influenced. The thread block is independently. But the thread block uses the same local variable as the parent statement block. It means, that variables are not removed so long as the thread runs.

{ parent block;
}
...
}


The statements of a thread can produce text with <+>text<.+> which is merged in the output text consistently. The text generation is not interrupted between <+> and its closing <.+> by another thread, it is synchronized.

### 11.1 Commands and messages to and from a thread

The class JZtxtcmdThread contains 2 queues one for commands, one for messages. A thread can await a command writte with:

 Obj cmd1 = myThread.awaitcmd(100000);  ##NOTE: cmd is a keyword, use variable name 'cmd1'


For that time the thread is dormant. The command is type of docuSrcJava_vishiaBase/org/vishia/cmd/JZtxtcmdThread.MsgItem. Any other thread can send a command to the JZtxtcmdThread instance with

myThread.sendcmd("command", anydata);


The Thread can send a message with

myThread.sendmsg("identifier", data);


which is awaiting by another thread:

myThread.awaitmsg(10000);


The argument is the timeout time. Because JZtxtcmd is not used for interactive operations but for batch processing the waiting time need only for execution time of some other operations. The timeout is proper if any thing hangs.

One thread can wait till the other thread is finished with its work:

if(myThread.join(10000)) { .... }


The join method returns with false if the timeout expires. This capability is important if a common task is splitted and should be continued if both parts are finished. Join with more than two threads is possible with some join invocations one after another.

Because multi-core processing is usual the fork and join can save time. The Java Virtual Machine respectively the operation system will divide several threads to extra cores if there are enough CPU time for that. Then the execution works really simultaneously.

## 12 onerror - Exceptionhandling

Topic:.JZtxtcmd.onerror.

Syntax see 16.17 Exception handling.

The Wikipedia:_Exception_handling is a core concept of a modern programming style. Older programming strategies works with an error variable for example the errorlevel of MS-Windows commands and batches or the errno variable in C language (Wikipedia:_Errno.h). In that older style an error have to be checked. If the error was not recognized, the algorithm is continued with erroneous data.

The basic idea of the modern exception handling is: The causer of an error may not correct the problem - it can be propagate the situation only.

If an error occurs then the normal operation order is aborted without additional programming effort. The program flow is continued on an proper catch block. That block can be located in the own procedure or in any superior calling level. In the catch block either the whole program may be aborted with a proper output, it is the simple variant, or erroneous or missing data are replaced and the session can be go on.

On the other hand errors such as missing variables should not cause an aborting of the algorithm, instead it should only reported and the algorithm should be continued. Especially on text generation the generated text can contain such error reports instead of the expected text parts. The generated text can be checked wether it contains such error reports. They should be fixed in the JZtxtcmd script language or in the called Java routines, - and then generate ones more! This strategy is substantially the same like the throw-catch. The catch routine generates the error report into the output text.

There are two types of exception thinking:

• a) The exception is not expected usual. The exception handling should help to find out the mistake

• b) The exception may be expected. It should be accepted and an alternative handling should be done.

Not at any time a programmer should think: There is never a reason for a mistake, it doesn't be need to handle. Think: The unknown reason cannot be known! It is adequate Murphy's Law. Therefore a) is present anytime.

### 12.1 errortoOutput

Topic:.JZtxtcmd.onerror.errortoOutput.

With the statement

errortoOutput;


all errors of execution are written in the current output text in the form

<??? error-report ???>


That flag is valid for the sub routine and all called levels till the statement

errortoOutput off;


but not for superior (calling) levels. It has not a script-global effect. If it is given:

errortoOutput;  //set on script level


it is valid for the script. In a sub routine

errorToOutput off;
statements ...;
on error{
exception handling statements;
}


can be set though the scriptlevel sets errorToOutput.

### 12.2 onerror statement block

Topic:.JZtxtcmd.onerror.onerror.

The statement

onerror {
statementblock
}


can be inserted after some statements inclusively calling of sub routines, which may throw an exception. On exception the JZtxtcmd execution is continued on the next found onerror statement with the proper type. This block is executed.

If an onerror block is found in the normal statements order, it is skipped.

The onerror block is the catch block in comparison to Java, C++ and other adequate programming languages. A try is not necessary in JZtxtcmd. All of the program code is tried.

That mechanism works both for internal thrown Exceptions in Java codes and the throw statement in JZtxtcmd.

There are a few types of onerror:

onerror notfound { ... }


It is executed especially if a variable is used in a JZtxtcmd script which is not existing. JZtxtcmd is a dynamic languages, which does not check the existence of variables on compile time. Furthermore that type is used if a field or method is not found in any Java classes using reflection. Commonly one can say if a datapath is faulty. See 9 Data and variables, especially 9.8 Access to JZtxtcmd local or script variables and 9.9 Access to Java internal data. That onerror block may be usefull if a script is written newly. The associated exception types are javadoc-oracle/java/lang/NoSuchFieldException and javadoc-oracle/java/lang/NoSuchMethodException

onerror file { ... }


Files are a known causer of errors. A file can be deleted thought its existence is expected. It can be write protected, locked, corrupted, or the media is not present. All that errors are subclasses of javadoc-oracle/java/io/IOException whereby the javadoc-oracle/java/io/FileNotFoundException is a known candidat of this group.

onerror exit { ... }


This exception is thrown by an exit statement of a JZtxtcmd script. Any subroutine can invoke exit. But whether the whole program is exited or not can be catched with this onerror handling. Normally exit should be done. But if a sub routine is called and the caller has a replacement strategy, the exit can be prohibited. The error type which is thrown is srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExitException.

onerror cmd { ... }


This onerror handling is especially for the throw on errorlevel statement after cmd line invocations, see 7.2 start, cmd: Invocation of operation system commands.

onerror internal { ... }


This onerror block is used for all other Exceptions especially any of the javadoc-oracle/java/lang/RuntimeException.

onerror { ... }


If an error type is not given, all Exceptions where catched here.

In the statements of an onerror-Block should offer alternatively handlings and set data with proper values. To control the program after such an block, all further necessary data should be set with proper information.

For example a file cannot be read. Some Information are not present. But all others of the following algorithm should be done nevertheless. Write

data = anyReadAlgorithmFromFile();
onerror file {
data = "default-value";
}


The following algorithm does not need to know about the file read problem, it looks only to data.

### 12.3 Exception handling for cmd line invocation

Topic:.JZtxtcmd.onerror.throwCmd.

The cmd line invocation ends with an errorlevel which is stored in the variable jztcsub.cmdErrorlevel. An exception is not thrown. That is the old style of error handling. But with the statement

throw on errorlevel 99


an exception is thrown if the errorlevel is greater or equal the given number (99 in example). It means the next statements are skipped till the next onerror block or the subroutine if left if there is not an onerror block and the next expressions in the superior routine are skipped etc.

### 12.4 conditional throw statement

Topic:.JZtxtcmd.onerror.throw.

In a JZtxtcmd an exception can be thrown usual conditionally:

if(condition){ throw "any text"; }


It throw an org.vishia.cmd.JZtxtcmdExecuter$JZtxtcmdThrow exception. The execution is continued on the next onerror block. ### 12.5 Show exception information Topic:.JZtxtcmd.onerror.info. The following data access paths can be used: error excStacktraceinfo() jztcsub.threadData.exception  The text of an exception is stored in the error variable. That variable can be used especially to log the exception. <+log>Exception <&error><.+>  The Exception object itself (derived type of javadoc-oracle/java/lang/Throwable is stored in the jztcsub.threadData.exception field. See 9.5.2 jztcsub. A Stacktrace can be reported by using String stacktrace = jztcsub.excStacktraceinfo();  This method returns in one line the information about the exception (Type, message) and the stacktrace for up to 20 levels in a one-line-presentation. The one-line is an advantage if this information should be merged in an outputted text: It does not disturb the line structure. An example for sucn an line with wrapped lines for better readybility, it is one line: JZtxtcmd.execute - exception at; @D:\vishia\ZBNF\sf\ZBNF\examples_JZtxtcmd\T estAll\testAll.jz.cmd:142,28; e <*);; java.lang.NoSuchFieldException: DataAccess.getData - not found in datapool; unknown; datapool contain s; :$TEST, FileSystem, StringFunctions, System, console, conv, err, er
ror, error, file, jztc, jztcsub, nextNr, nextnr, null, out, scriptOb
j, scriptStringEmpty, scriptStringSet, scriptStringSet2, scriptdir, sc
riptfile, test, text, ; org.vishia.util.DataAccess.access(DataAccess.j
ava:670); org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.dataAccess(JZtxtcmdEx ecuter.java:1964); org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.executeDa
tatext(JZtxtcmdExecuter.java:1590); org.vishia.cmd.JZtxtcmdExecuter$ExecuteL evel.execute(JZtxtcmdExecuter.java:752); org.vishia.cmd.JZtxtcmdExecuter$Exe
cuteLevel.execute(JZtxtcmdExecuter.java:662); org.vishia.cmd.JZtxtcmdExecute
r$ExecuteLevel.textAppendToVarOrOut(JZtxtcmdExecuter.java:1169); org.vish ia.cmd.JZtxtcmdExecuter$ExecuteLevel.execute(JZtxtcmdExecuter.java:714); org
.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.execute(JZtxtcmdExecuter.java:662) ; org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.execSubroutine(JZtxtcmdExecut
er.java:1321); org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.execCall(JZcm dExecuter.java:1211); org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.execut
e(JZtxtcmdExecuter.java:753); org.vishia.cmd.JZtxtcmdExecuterExecuteLevel.e xecute(JZtxtcmdExecuter.java:662); org.vishia.cmd.JZtxtcmdExecuter.execute(J ZcmdExecuter.java:431); org.vishia.zcmd.JZtxtcmd.execute(JZtxtcmd.java:398); org.vishia.zcmd.JZtxtcmd.execute(JZtxtcmd.java:354); org.vishia.zcmd.JZtxtcmd.s main(JZtxtcmd.java:190); org.vishia.zcmd.JZtxtcmd.main(JZtxtcmd.java:142);  One stacktrace level is presented with (last line of the example):  org.vishia.zcmd.JZtxtcmd.main(JZtxtcmd.java:142);  In an Eclipse console window that format is shown with links to the source code, like usual with an eclipse-generated stack trace. The method and the file and line is shown. ### 12.6 Omitted stacktrace for JZtxtcmd call levels Topic:.JZtxtcmd.onerror.. The exception information contains the original exception type and text from its Java internal context inclusively the stacktrace in the Java context. Additionally the file and line-number and a short presentation of the JZtxtcmd statement is shown, where the exception was caused. If the onerror {...}-block is found in a superior subroutine level, the calling order to the subroutine is not shown (no stacktrace at JZtxtcmd level). Usual the calling order is less complex as in Java method nesting. See the example: sub routine(){ line = causes.exception; } sub callingRoutine(){ call routine(); other statements; onerror{ <+out>error: <&error> <.+n> }  The error variable contains the line where the exception was caused. Though the onerror-catch block is in the other subroutine it is evident that the call routine() was executed lastly before onerror. If that routine contains: sub callingRoutine(){ call routine(); ## first other statements; call routine(); ## second onerror{ <+out>error: <&error> <.+n> }  it is not clear whether the first or the second call is done lastly. But usual this fact may not important. Therefore the effort of a stack trace on JZtxtcmd execution is omitted. The Java stacktrace shows indeed the fact of calling a subroutine, but it also does not contain the fact which line causes the call. A stacktrace in Java does not contain data unfortunately. If a debugger is used, for example with an Eclipse environment, a break can be set in the catch block of the method srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExecuteLevel#execute(...) to view details. ## 13 Text output and text generation Topic:.JZtxtcmd.text. The capability of text generation is used either to build arguments or textual values for Strings or to produce output text. ### 13.1 Text output Topic:.JZtxtcmd.text.out. For building a textual argument the text should be surrounded with <:>That is the text<.>  To output to the JZtxtcmd output file one should write <+>Text to the text generation output<.>  A text expression used especially for assignment and argument string is written like <:>text as text expression for assignmant or as argument<.>  A text expression is outputted like <+>text<.> if it is not a part of an assignment or argument: <:>this text is written to the text generation output<.> <+>it is the same output<.> String var = <:>this text is assigned to the var<.> call subroutine(<:>text used as argument<.>);  If a subtext is called inside the sub mySubtext(args) <:>This text is the output of the sub text - the core funtionality of the subroutine <.> <+>But this text is written to the text generation output immediately<.> <+out>Of course the standard output can be used<.<  A text can be send to the <+out>Text to standard out, it uses System.out from Java<.> <+err>Text to standard err, it uses System.err from Java<.>  It depends on the settings in the Java environment whether this text is written to console output or it is redirected anywhere other, using System.redirectOut(PrintStream). To write text into a file one can write: Openfile myfile = "path/to/file.txt"; <+myfile>Write text<.+n> ... <+myfile>more text<.+n> myfile.close(); //the file should be closed! <+myfile>The last line<.+n.+close> //alternative close  To flush or close the text output, one can write: <+>a line seen in the output file<.+flush> <+>another line with newline on end<.+n+flush> <+>The last line<.+n+close>  After <.+close> or <.+n+close> the next <+myfile>text...<.> causes an NullPointerException because the output is closed. Therefore <.+close> or <.+n+close> should be written on the last text output statement. Note: Don't forget close. In a short running script a close is done by the operation system because the process is finished and terminated. But a longer running application locks the file if it is not closed. The text between <+...>TEXT<.+>.. is a 10.3 Text expression which can contain values from any data (datapath), conditionals. for-loops etc. ### 13.2 Set and change the JZtxtcmd text output file Topic:.JZtxtcmd.text.text. The text output file may be given with the command line argument -t:path/to/textOutput.ext or for Java-internal invocation as argument of invocation of docuSrcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter#execute(org.vishia.cmd.JZtxtcmdScript, boolean, boolean, java.lang.Appendable, java.lang.String) and docuSrcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter#execSub(org.vishia.cmd.JZtxtcmdScript.Subroutine, java.util.Map, boolean, java.lang.Appendable, java.io.File). In this cases the output is determined outside of the JZtxtcmd script. The text output file can be set or changed within the JZtxtcmd script with the statement <+:create>path/to/textOutputFile.ext<.+> <+:append>path/to/textOutputFile.ext<.+> text = path/to/textOutputFile.ext; //now deprecated, use above  Both statements closes a current existing text output and opens the new one. If that action fails, an Exception is thrown which can catched by a Chapter: 12 onerror - Exceptionhandling. The text expression till <.+> is used as file path. The <+:append> opens for append, the <+:create> clears an existing file. Both creates a new one if not existing. The path can be build as text expression: <+:create><&argdir>/out.txt<.+>;  for example if a directory is given as argument. ### 13.3 Lines and indentation in the script Topic:.JZtxtcmd.text.indent. To produce a newline after the output line one can write <+>My line<.+n>  The Text in a JZtxtcmd script for text output is written as plain text after a text output statement. It can be written over some lines. Because the script usually works with indentation for the statements, the text in the script should be indented too. If the indentation of the text in the script is the same as the statement which introduces the text output, it is not indented in the output: sub myRoutine(...) { for(variable: container) { <+><: > Create this text in the output without indentation with several lines, maybe with <&variable.value> <.+> if(condition) { <+>A text line next Line of this text <.+> } ...  There are some more possibilities especially to mark and separate ranges of text with ranges of statements. The rule for that is: One of the character =, : or + can be used as marker left of the indentation column of the plain text. You can write in the same example: sub myRoutine(...) { for(variable: container) { <+><: > ====Create this text in the output without indentation ====with several lines, maybe with <&variable.value> ====<.+> if(condition) { =========<+>A text line =========next Line of this text =========<.+> } ...  The === or ::: with at least 3 character length is possible overall in the script, it is ignored by the parser. It should be used only before the <:> to mark that area as text output. It may be better obvious that there are text lines. Instead ====== there can be used :::: or ++++++ too, but not in combination in one line.  <+><:s> ==testText()== 1. line without indentation. It starts before indentation column in the script. 2. line without indentation. It starts exactly on indentation column. 3. line has 2 spaces indentation. It starts after the indentation column. ::::4. line without indentation with :::: in script. ::::::::5. line without indentation with more :::::: in script. ++ 6. line with 2 spaces indentation because it starts after indentation chars. :::::::: 7. line with 2 spaces indentation. It starts after the indentation chars though there are longer as indentation point in the script. ++++: 8. line starts with a colon as first char after ++++ indentation. =====9. line without indentation ==+10. line starts with a '+' because first char after another indentation char though before indentation point. <.+>  The text can be written with an indentation in the script. It is generated without indentation if the text starts after the column where the <+ ends. The indentation till this start column should be done with spaces or with colon ::: in the script. In this example all lines except the fifth are written in output without indentation. A line which starts left of the script indentation column is written correctly. Because the fifth indented line starts one character after the script indentation column, it is written with one space in the output. The <:s> skips over all white spaces inclusively that text marker before indentation. It is processed while preparing the source for an jztxtcmd script (translating phase), not at runtime. A <: > skips over all white spaces while parsing the source. Therefore it does not skip the text marker before indentation. A <: > can be used instead <:s> in special cases. A ::: may clearly mark a text line. That marker can be written starting before the indentation line. Then the line starts exactly after the :::::. The number of colons is no matter how:  <+> :::::::::line without indentation ::::::::: line with one space left :: line with one space left. ::::line starts with the ::::<.+>  One should not use tabulators for indentation. The JZtxtcmd executer does not know a tabulator width of the used editor. Only if all text lines should be left aligned in output the user can use tabs in the script. The JZtxtcmdExecuter counts only spaces and tabs from the start of a JZtxtcmd source text to skip over the source indentation characters independent of spaces or tabulators. Pattern for well readable JZtxtcmd script code and generated text: To separate statements and text the following pattern can be used. Separation of text and statements is nice to have especially if C-code or similar should be produced. The JZtxtcmd source is better able to read, no confusion because the syntax is similar. Write: if(JZtxtcmdexpression) { <+> :::::::::::: if(C_expression) { //similar syntax like JZtxtcmd :::::::::::: doSomethind() :::::::::::: }<.+> }  • The JZtxtcmd statements are written left. • The output text is written rigth. • The <+> defines the column where indentation starts, right side. • The :::::::: marks clearly output text lines. • The output text starts with a newline usually and ends without a newline. This is a well convention for text generation because the start of line is known often whereby the continuation or end of line may be known only in the further context. Often an variable indentation is necessary in the generated text. See the example: sub generateWhile(int recurs, ...) { <+> ::::::::<:@2*recurs>while(C_condition) {<.+> call generateInnerCode(recurs = recurs+1); ::::::::<+> ::::::::<:@2*recurs>} //while <.+> }  See 13.7 Column tabulator. The column tabulator produces the necessary indentation with the recurs variable. If there are nested while(...) etc it is written in the correct indentation form. The while(C_condition)-line in the example starts on the column 2 * recurs so far as the } //while because the line starts immediately after the colons :::::: but set its output column to the calulated value. On the other hand if a generated text contains less and simple JZtxtcmd statements one can write it inside the text like: sub switchStates(Obj stateComposite, Num recurs) { <+> :::<:@2*recurs> switch(<&stm.zsrcFile.variables.StateInstance>.state<&stateComposite.stateId>) { :::<:@2*recurs> case 0: entry_<&stateComposite.stateDefault><&stateMethodSuffix>(thiz); break;<.+> call switchCaseState(stateComposite = stateComposite, recurs = recurs+1); <+> :::<:@2*recurs> } //switch <&stateComposite.stateId> <.+> }  In this example the case-Statements are generated from a JZtxtcmd-subroutine. It is well able to read to write the subroutine call inside the text. The formal syntactical separation between both is done with the text<.+> JZtxtcmd statements <+> text  The well able to read separation is done with the :::::. To write a text without newline on start one can write: JZtxtcmdExpression() <+>output text <.+> ::::::::::<+>further text<.+>  • The <+> is written at right side, like above. • Text after <+> immediately - no line feed. • One can use ::: inside JZtxtcmd statement to mark a line which contains output text, it is better seen. Note that  :::::::::::::<+>output text<.+n>  produces an output text with a line feed on end. Line feed on start or end of an output: Writing <+output:n>Line starts with newline<+> <+output> appends on this line<+> <+output>and ends with newline <.+n>  produces a newline on start or on end of the text with a lightweigth code in the script. <+:n>One line in the -t:text-output<.+> <+> appends on this line<.+> <+> and ends the line <.+n>  Prevent line feed and spaces with more as one script lines: It is possible to write a text in the script in several lines, which should be outputted in one line. For example this is able to use to produce batch or shell script files with long lines because long command line arguments are necessary. Write <+>cmd <: > arg1 <: > arg2 <: > ##comments are possible <.+> if(condition){ <+>arg3<.+> } <+> <.+>  This produces in the output: cmd arg1 arg2 arg3  With conditional arg3 and a newline on end. The syntax <: > (one space after : ) skips over all following white spaces, especially over the line feed in this example. ### 13.4 Special characters and text parts in the text Topic:.JZtxtcmd.text.transcript. All characters in the line are transformed to the output without changing. One can use tabulator characters in the text to produce tabulators in the output text. The newline character(s) in the produces text is given with the argument -nl=[n|rn|r] of the invocation of JZtxtcmd. It is not the newline character(s) of the JZtxtcmd script. For example the script can be written with only a \n-Character (0x0a) and the produced text can be written with \r\n like standard in Windows. One can output some characters writing: • a <:lf> produces a newline, line feed with the given newline setting. • a <:n> produces a newline character in the text (0x0a). • a <:r> produces a return character in the text (0x0d). • a <:t> produces a tabulator character in the text (0x09). • a <:<CHARS> produces a < character with the following CHARS in the text. With them a text can output the character combination <:, <+ and <& using <:<:>, <:<+> and <:<&>. It is possible to write for example <:<&myVar>> to produce the text <&myVar>. Note that the first of the >> is the end of CHARS syntactically. The second of the >> produces the > in the text. But it is proper to read <:<&myVar>>. • a <:#CHARS> produces a # with the following CHARS. With them a text can output a ## using <:##> • a <:scriptdir> writes the directory as absolute path, where this script source is located. It helps if a script should use files with relative path to it. Example: <+>Text<:lf>next line<.+> <+><:t>after tab <:<:special>> <:r>after 0x0d  produces Text next line after tab <:special> after 0x0d  ### 13.5 Datapath depending on Variables Topic:.JZtxtcmd.text.dataElementVar. Sometimes it may be necessary to access data depending on other data. The name in a datapath is given in any other variable, not as constant name. It is an indirection. If the ctrlVar contains a part of the name in another datapath you may write: if (ctrlVar == "A"){ data = path.to.A.data; } elsif(ctrlVar == "B"){ data = path.to.B.data; }  Because the content in the ctrlVar is exact the name in the datapath, it is more simple to write: data = path.to.&(ctrlVar).data;  or inside a text expression: <:>... <&path.to.&(ctrlVar).data> ...<.>  The content of ctrlVar replaces that part inside the Datapath. Of course only admissible values can be processed. Elsewhere an exception is thrown which can catched with 12 onerror - Exceptionhandling. A maybe typical construct is <:>... <&&(path)> ...<.>  if the path contains the whole data path. An example for that is contained in examples_JZtxtcmd/TestAll/testAll.jz.bat in the sub testVariableDatapath(). ### 13.6 Expression in the expression Topic:.JZtxtcmd.text.. It is possible to hold an ### 13.7 Column tabulator Topic:.JZtxtcmd.text.col. One can set the next column position in a line writing <:@100>  Then the position in the line is set exactly in this example to 100. If the line is shorter, spaces are appended before. If the line is longer then the content at this position will be overwrite. Use <:@100 : 2>  to prevent over-writing of content. If a : is written, the column position is set after the current end, with at least the given number of spaces, 2 in this example. Both forms may be proper: The example produces a list where the information is over-written, the column is correct: <+out><&information><:@20> <&furtherOne><.+n> information further one next line with a inf furtherOneContent third line is shorte thefurtherOne  The information in the left column will be clipped because of the <:@20>. The spaces after <:@20>  ensure a proper readability. <+out>#define <&name><:@20:1> <&value><.+n> #define myName value #define aLongLongExplicitelyName value #define otherName otherValue  The information will never be clipped. This is an example of a generated C file. The value may be better able to read in a column orientation, but the correct syntax is prior. Instead a constant value an expression can be used to calulated the column. Usually that is a given numeric value in a variable: <+><:@ indent : 2> text<.+>  This text has an indentation which is given in the variable indent. <+><:@2*recursion> +--<&treecontent><.+>  It shows a tree with indentation depending on tree depth given in a variable recursion. ### 13.8 Place holder and values <&dataText> Topic:.JZtxtcmd.text.data. The text can contain variable values of course. One should use <&any.datapath>  to get data from any location. The any.datapath is the same like in assignments to String variables, see the whole chapter 9 Data and variables, the syntax of datapath in 16.9 Text value: textDatapath, textValue and syntax: 16.11 DataPath, Data access. All non-textual Objects are converted to its text presentation using the toString() method of javadoc-oracle/java/lang/Object#toString(). Numeric values are converting using its Standard conversion of the Wrapper types javadoc-oracle/java/lang/Float etc. ### 13.9 Replacement text on error Topic:.JZtxtcmd.text.. Since 2016-02: If a datapath is faulty, an replacement text can be used instead to see the mistake in the output text. Then an 12 onerror - Exceptionhandling] is not necessary. Write <&my.datapath:?replacement-text>  to output replacement-text if an error is occurred. Usual one can write: <&my.datapath:? ?error? > <&datapath?" <--->error<---> ">  to see  ?error?  or  <--->error<--->  in the output text. Such a label can be searched. The error text can be written in ""..." if it contains a : or >. ### 13.10 Numeric formatting Topic:.JZtxtcmd.text.. Numeric types can be converted with a special format. Write <&datapath:formatString>  with a valid format string of the Java's formatter class javadoc-oracle/java/util/Formatter. Example: Obj numeric = myData.intvalue; //accesses to any int variable. <+>Value = <&numeric> = 0x<&numeric:%08x><.+>  The JZtxtcmd variable numeric stores a numeric value, with its Wrapper class javadoc-oracle/java/lang/Integer. Then a text is produces containing the value in decimal (standard) and with the given format String as hexadecimal value. In this example the replacement on text error is used too with String "?error?". This should be written before the format string. See 16.14 TextExpression ### 13.11 Program control in text expressions Topic:.JZtxtcmd.text.if. In a text expression some control statements can be used, see the syntax in 16.9 Text value: textDatapath, textValue. One can write conditional text using • <:if:condition>conditional text<:elsif:othercondition>the text<:else>else text<.if> • <:if:condition>conditional text<:else>else text<.if> • <:if:condition>conditional text<.if> Syntactical the conditions are conditionInText, see 16.12 Condition expression. A condition can be a simple quest whether a variable exists or a data path is valid: <:if:datapath>  If the datapath is invalid (the destination does not exist), then it is false. If one write <:if:datapath !=null>  then an exception is thrown if the datapath is invalid. Because, it is tested explicitely. If a datapath returns a String value, one can use all javadoc-oracle/java/lang/String test capabilties such as <:if:datapath.to.any.string.contains("check it")>  The <:if:datapath.to.any.string == "my text">  checks with String.equals("my text"). != is !string.equals(). <:if:datapath.to.any.string ?ge "my text">  means is equal or longer which is String.startsWith("my text") in Java-language. All other compare operators executes a comparison in alphabetic order. Numeric values can be calculated and compared, for example <:if:datapath.to.any.numValue ?ge 345.56>  Note that the operator > and >= cannot be used because syntactical conflicts. Use ?gt and ?ge instead. < and <= can be used because it is not a syntactical conflict. But because better read ability one should use ?lt and ?le. One can use a • <:while:condition>repeated text<.while> and a container-iteration. • <:for:variable:container>do for all <&variable> elements<.for> An assignment is possibile writing • <=variable:datapath.toany.value> • <=variable>any text value<.variable> That assignments may be important in a <:while...>. ### 13.12 Insert text form a subroutine: <:subtext:...> Topic:.JZtxtcmd.text.subtext. Syntax see 16.18 callSubroutine, callSubtext. and Chapter: 16.5 subroutine. You can define a subtext or sub routine to produce text inside a given text. A subtext can be defined in two forms: subtext mySubtext(String arguments) <:>this is the text with <&arguments><.> sub mySubtext(String arguments) { <:>this is the text with <&arguments><.> }  Both forms of definition seems to be similar. The difference is: A subtext can only define one text expression, whereby a subroutine can be used to do some other text output additionally. Use a subtext for short texts. Such a subtext can be called, the text will be inserted inside any text expression: <:>...<:call: name: data = anyData, arg2=value> ...<.> <:>...<:subtext: name: data = anyData, arg2=value> ...<.> <:>...<:subtext: "name" :data = anyData, arg2=value> ...<.>  Usage of <call:... or <:subtext... is adequate. The name of the subroutine is a textValue, see 16.9 Text value: textDatapath, textValue. Therefore it can be gotten from a variable too writing an & before the variable name: <:>...<:call:&nameFromDatapath :data = ...> ...<.>  That is a possibility to invoke several sub texts controlled by data content. A subtext can be held inside a variable too, see 9.1.9 Subtextvar, Subroutinevar - statements to execute. ### 13.13 Setting variables in the text expression Topic:.JZtxtcmd.text.. <:=variablePathString>any text <&content><.=> <:=variablePathOther = 234> <:=variableAppend += 234>  The first form fills a String variable with a String expression. The second form defines any expression to set the variable after the = The third form appends to the variable equivalent to the += 9.1 Types of variables and their assignment That assignments do not produce text in the current output. ### 13.14 Writing to the main output file Topic:.JZtxtcmd.text.file. The JZtxtcmd knows one main output text file. It is possible that this output file is the approach of the script invocation, the user will get a generated output file from some inputs. Another approach may be, the main output file is the log output of the script running process. The main output file is given by parameter of the script invocation. This output file is deleted if it is existing and reopened newly. If the output file is locked from another process (opened), the script invocation is aborted with an error. The output file is remaining opened but flushed frequently, so the output can be monitored by the user while reading this file in another process. It is necessary if the main output is used as log. Nevertheless the script process can have a second log file which is written from some Java methods which uses the log capability of the message dispatcher. That log can't be controlled by the user, it is a really log of Java processing. That log is given with the --report:FILE parameter. Writing in the main output file is done by writing <+>text<.+>  wherby text is a 16.14 TextExpression. To flush the output one should use a flush operator inside the text: <+>text<:flush><.+>  or more simple flush with the and tag: <+>text<.+flush>  or flush in conclusion with a newline: <+>text<.+n+flush>  like any other text output with <+channel>....<.+n+flush>. ## 14 Interaction Topic:.JZtxtcmd.interact. A JZtxtcmd script is intended as batch script firstly. For example its subroutines can be used inside a Graphical User Interface as action code. Though a minimal interaction is designated which may be important for simple user quests for a batch. Besides it is possible to open a graphical application within a JZtxtcmd script. ## 15 Debugging possibilities Topic:.JZtxtcmd.debug. A JZtxtcmd script should be simple and short. Usual a well running script is modified and tested. Any small-step modification should be tested. Errors can be seen in comparison of the last well running version to the changes. It is the recent strategy of scripting. If special java routines should be used, the associated javadoc should be read well. Then test... ### 15.1 Handling syntax errors Topic:.JZtxtcmd.debug.syntax. While invocation JZtxtcmd the given script is translated complete firstly. If any syntactical error is found, an error message like JZtxtcmd - Error parsing genscript; Parse ERROR at input:2202(0x89a) >>>>call TestResult.replenish(arg=map);| <+out>testResult() - replenish; <&map.re expected: ---------------------------------------------- "." in topLevelSyntax.subClass.subroutine.statementBlock.statement.DefVariable.DefMapVar.variable. ";" in topLevelSyntax.subClass.subroutine.statementBlock.statement. founded before: ---------------------------------------------- [184..187]<...?datapath> syntax=? input=0..0(78, 51) read: "result.anotherOne" xmlNode=<datapath>...</> [185]<...?startVariable> identifier:result syntax= input=0..0(0, 0) xmlNode=result


One can report the syntax with invocation

java -cp $CLASSPATH org.vishia.zcmd.JZtxtcmd --help  or check the syntax in this documentation. The syntax error shows that position in the text where the parser has failed. Often the mistake is on position before that. The expected: names the nesting of syntax component and the characters which where expected there. In that example a ; is missing only on the last statement. The parser cannot know that you have forgotten a semicolon. The parser thinks the last statement should be continued. The second expected: proposal names the error in fact, the missing semicolon on statement end. But the parser expects that the last written text may be a variable path which is incomplete. Which of that expected: things are correct, one can desired on viewing the text before. Additional the parser reports what is accepted before. In this case it is a datapath. View the syntax of datapath. After a startvariable some more path elements separated with a dot may be expected. The output of the syntax error is the standard behavior of a ZBNF-parser. ### 15.2 Check the content of the script Topic:.JZtxtcmd.debug.xmlSrc. Sometimes there may be differences in interpretation of the source code of a JZscript. The JZscript will be parsed with a ZBNF parser. That parse result can be shown in XML format to check only the parser. Write on the first line: !checkXml = "path/to/checkfile.xml";  Then the parser's result will be written in that file in XML format. You can use !checkXml= <:><:scriptdir>/test.xml<.>;  instead to write it in the directory of the script. Note that included scripts are not regarded. On the other hand you can write: !checkJZtxtcmd = "path/to/checJzcmd.txt";  That writes a text file which contains the 'toString()'-result of all statements in the script, included scripts regarding. This second form representates that data, which are converted from the parser's result (able to show with XML) into the internal presentation. ### 15.3 onerror facility Topic:.JZtxtcmd.debug.onerror. A static language tests as soon as possible mistakes on compile time. But a dynamic language accepts some constructs which's mistakes are obvious on run time only. For example a static language tests types of arguments of a subroutine. The JZtxtcmd dynamic language does not distinguish types, like other dynamic languages. An Obj type can contain any Object. Whether it is matching to a called Java subroutine, it can be checked on runtime only. If any dissonant constellation are ascertain on run time, an exception is thrown by the Java execution process. One can use an onerror construct in the JZtxtcmd script: doAnything in the script; do next; onerror { <+out>Error on xyz; <&error><.+n> }  If an exception is thrown, the next following onerror block is executed. The error variable should contain a significant text about the mistake. It is outputted on console in this example. The console may be redirect in a message system. With that stuff the error may be able to interprete by the user. If the error is not catched in that level, it may be catched in the calling level. Last not least the JZtxtcmd class aborts and reports. The error variable contains the Java-Exception class name, the exception message text, the file and source line and column and a short notification of the JZtxtcmd statement where the error occurs. For example in a subroutine a faulty variable is used. The error is catched in the level above. The following text is outputted: ### 15.4 Check data on runtime Topic:.JZtxtcmd.debug.JZtxtcmdTester. The JZtxtcmd knows a variable test which refers an instance of srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdTester. This class has some capabilities for output data for test. The following statement writes a line which contains the information about the type and the toString()-value of data: out += test.infoln("my info", data); //appends a line with info <+out>it is the same: my info<&test.info(data)>, maybe some more in the line <.+n>  The following statement writes the internal data of an instance which is able to address with a datapath:  test.dataTree(data, out, 1); <+> <&test.dataTree(path/to/data, out, 1)> <.+>  The third argument 1 is the deepness of data, used if references are used in the instance. It can be set to any number of deepness. Then referenced data and the references their etc. are shown too. The out is the standard output. You can use any Appendable object, especially to get the information in a file: Openfile outfile = "path/to/myFile.txt"; test.dataTree(data, outfile, 3); outfile.close(); //don't forget to close!  It is possible to write that information with a html format: Filepath htmldata = "path/to/myFile.html"; test.dataHtml(data, htmldata);  This is the most complex but recommended form to output the data which can be used in a script. Usual the root data in a special script may be outputted. The html file contains the data of the given instance and all referenced instances. The references instances are written independent, not in form of a tree. The references are presented in html as hyperlinks inside that html document. With the known usability of following links and switch back of a browser the referenced data can be evalated. That can help to write a JZtxtcmd script: ### 15.5 Debugging in an Integrated Development Environment, for example Eclipse Topic:.JZtxtcmd.debug.eclipse. The JZtxtcmd can be executed in an Eclipse or another integrated development environment. You don't need to understand the whole source code of the translator javadocPriv-Zbnf/org/vishia/zcmd/JZtxtcmd and interpreter javadocPriv-vishiaBase/org/vishia/cmd/JZtxtcmdExecuter. It is sufficient to view to some details, set a breakpoint, view data etc. Especially if Java routines of the user are invoked inside the user's JZtxtcmd script, the user can set a breakpoint and debug its own routines. On return of this routines it returns to the JZtxtcmdExecuter loop, see the stacktrace of debugging. • Set a breakpoint on start of your method in class. • Check whether this method is called really. • Check the arguments • Check the details. break on access to any data: If any variable or a method is not is not found, you can set the following instruction line before that access: java org.vishia.util.DataAccess.debugIdent("myData"); myData.myMethod(args);  The first instruction sets a (non-threadsafe) debug comparison String in the class DataAccess. If that indentifier is used then it forces the execution of srcJava_vishiaBase/org/vishia/util/DataAccess#debug() where a breakpoint can be set. There you can visit given variables, methods etc. with the debugger variable context maybe especially in the given localVariables. You can set a break for a found method but with argument problems by setting: java org.vishia.util.DataAccess.debugMethod("myMethod"); myData.myMethod(args);  The next instructions in DataAccess checks the actual arguments, which may be faulty. break in the execution loop of JZtxtcmd: If any of the execution of the JZtxtcmd script seems to be obscure, you can insert a debug statement bevor the obscure statement: ...jztxtcmd statements debug "my text"; debug <:>any <&variable>-expression<.>; debug; obscure statements; ... <+out> any text <:debug:"my text"> <&obscureData><.+> <+out> any text <:debug> <&obscureData><.+>  On a debug statement the method javadocPriv-vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExecuteLevel#debug(org.vishia.cmd.JZtxtcmdScript.JZtxtcmditem)  int debug(JZtxtcmdScript.JZtxtcmditem statement) //throws Exception { try{ CharSequence text = evalString(statement); } catch(Exception exc){ //unexpected } Assert.stop(); return 1; }  is executed. You can set a breakpoint to the stop() line. The text should be set with your "my text" of the debug-statement. If this statement returns, it continues in the interpreter loop of the JZtxtcmd script. The next statement will be the 'obscure' one. You can study whats happen. ## 16 Syntax of a JZtxtcmd script Topic:.JZtxtcmd.syntax. This chapter describes the exact formal syntax which is used to parse the script. The syntax is shown both in ZBNF and in a more readable explaination format. The internal used ZBNF-Syntax-Script is contained in the Java-class javadoc-Zbnf/org/vishia/zcmd/JZcmdSyntax. You can invoke JZtxtcmd from command line to output the syntax with the help text:  java -cp path/to/zbnf.jar org.vishia.zcmd.JZtxtcmd --help:helpoutput.txt  Details of the syntax may be changed in further development. Therefore see and compare that help output. ### 16.1 The head of a script Topic:.JZtxtcmd.syntax.script. The syntax starts with some common settings and the definition of the top-level component, the frame of a script. $comment=(?...?).
$endlineComment=\#\#. ##The ## is the start chars for an endline-comment or commented line in the generator script.$keywords= new | cmd | cmd_check | start
| debug | java
| stdout | stdin | stderr
| subtext | sub | main | call | cd | CD | REM | Rem | rem
| Pipe | StringBuffer | Stringjar | String | List | Openfile | Fileset | Obj | Set | set | include | zbatch
| break | XXXreturn | exit | onerror | instanceof | for | while | do | if | elsif | else | throw .


The syntax of the whole script is given with:

JZtxtcmd::=
[<*|==JZtxtcmd==?>==JZtxtcmd== ]
[<*|==JZcmd==?>==JZcmd== ]
[{ ! checkjzTc = <textValue?checkJZcmdFile> ;
| ! checkJZcmd = <textValue?checkJZcmdFile> ;
| ! checkXml = <textValue?checkXmlFile> ;
}]
[{ [REM|Rem|rem] <*\n\r?> ##Remark like in batch files
| include <include> ;
| currdir = <textDatapath?cd> ;
}]
.....


It contains:

• ==JZtxtcmd==: Start marker: A JZtxtcmd script can contain some other text, especially a start sequence of a batch file or a shell script. One can write for example a windows batch file which invokes java ... JZtxtcmd thisScript and exit then. After them the ==JZtxtcmd== label is written. The parser skips over the whole text before the first ==JZtxtcmd== is found. The syntax means, all text will be skipped if the marker ==JZtxtcmd== will be found. If that marker is not found, nothing is skipped. Note: Don't write that marker inside a JZtxtcmd source.

• checkJZcmd = ...: Test outputs: On start of script it is possible to define output files for test.

• include: included Scripts, see 16.3 The include statement and 6.2 Included scripts

• currdir..: See Chapter: 7.3 currdir, cd statement

### 16.2 The content of a script

Topic:.JZtxtcmd.syntax..

The syntax of the JZtxtcmd::=.... continues with

.....
{ [//] ==endJZcmd==<*\e?>
| [REM|Rem|rem] <*\n\r?> ##Remark like in batch files
| //JZtxtcmd       ##ignore //JZtxtcmd, it may be a comment for another language
| //JZcmd      ##ignore //JZcmd, it may be a comment for another language
| //<*\n\r?> ##line comment in C style
| /*<*|*/?>*/ ##block commment in C style
| <DefVariable?> ;
| <statement?>
| subtext  <subtext?subroutine>
| sub <subroutine>
| class <subClass>
| main ( ) \{ <statementBlock?mainRoutine> \}
} \e.


#### 16.2.1 End marker

Topic:.JZtxtcmd.syntax...

It is possible to set an end marker in the text. It is is detect, all content till the end of the file will be skipped. <*\e?> means, skip all till the end of file, without semantic meaning.

{ [//] ==endJZcmd==<*\e?>


Topic:.JZtxtcmd.syntax..comment.

Comments can be given with starting from ## to the line end or between (? comment ?). That comments are ignored in the parsing process.

Additional the // and the /* ... */ can be used for comments like in Java or C. That comments are formally parsed, they are visible in the parsers result xml file with option -debug:file, but they are ignored for execution.

| [REM|Rem|rem] <*\n\r?> ##Remark like in batch files
| //JZtxtcmd      ##ignore //JZtxtcmd, it may be a comment for another language
| //<*\n\r?>   ##line comment in C style
| /*<*|*/?>*/  ##block commment in C style


#### 16.2.3 ScriptVariable and Script-Statements

Topic:.JZtxtcmd.syntax..var.

The <DefVariables?> enables the declaration of variables on script level. The variables can be declared between routines and classes. But they are visible and created all on start of execution.

| <DefVariable?> ;
| <statement?>


#### 16.2.4 The main syntax of the rest of the script

Topic:.JZtxtcmd.syntax..main.

The script consist of definition of sub, subroutines and classes and the main routine. All of it can be contained more as one time in any order.

| subtext  <subtext?subroutine>
| sub <subroutine>
| class <subClass>
| main ( ) \{ <statementBlock?mainRoutine> \}
} \e.


### 16.3 The include statement

Topic:.JZtxtcmd.syntax.include.

The path can be given starting with an optional environment variable, optional continued with a path.

include::= [$<$?envVar>[/|\\]][ <""?path> | <*;\ ?path>].


### 16.4 Classes

Topic:.JZtxtcmd.syntax.class.

Syntax:


subtext::= <$?name> ( [ use-locals<?useLocals> | { add-locals<?addLocals> | <DefVariable?formalArgument> ? , }|] ) \<:\><textExpr>\<\.\>.  The difference between a subroutine and a subtext is: A subtext can be invoked inside a 16.14 TextExpression, it contains a <textExpr> itself. The procedures for calling are the same. ### 16.6 statements Topic:.JZtxtcmd.syntax.stm. Syntax: statementBlock::= { <statement?> }. statement::= \{ [<statementBlock>] \} | REM <*\n\r?> ##Remark like in batch files | ::{:} ##Skip over ::: | =={=} ##Skip over ::: | //JZtxtcmd ##ignore //JZtxtcmd, it may be a comment for another language | //JZcmd ##ignore //JZcmd, it may be a comment for another language | //<*|\n|\r|\<+?> ##line commment in C style but only till <+ | /*<*|*/?>*/ ##block commment in C style | text = <textValue?createTextOut> ; ##set text output | currdir = <textDatapath?cd> ; ##set current directory | [cd|CD] [<textValue?cd> | <*\ ;?cd> ; ] ##change current directory | mkdir <textValue?mkdir> ; ##create any directory if not exists | <DefVariable?> ; | for <forCtrl> | if <ifCtrl> | while <whileCtrl> | do <dowhileCtrl> | start <cmdLine?cmdStart> | zmake <zmake> | move <srcdst?move> ; | copy <srcdst?copy> ; | [rm|del] <oneArg?del> ; | break <?breakBlock> ; | return <?return> ; | exit <#?exitScript> ; | throw on errorlevel <#?throwonerror> | throw <textDatapath?throw> | onerror <onerror> | errortoOutput off <?errorToOutput=0> | errortoOutput <?errorToOutput=1> | if errorlevel <iferrorlevel> | debug [<textValue?debug>| <?debug>] ; | debugOp <textValue?debugOp> ; | <callSubroutine?call> | <threadBlock> | \<+:create\><textExpr?createTextOut>\<\.+\> | \<+:append\><textExpr?appendTextOut>\<\.+\> | \<+ <textOut> | \<:\><textExpr?.indent=-3>\<\.\> [;] | <cmdLineWait?cmdWait> | <assignExpr> | ; . srcdst::= [{ -n<?newTimestamp>| -w<?overwr> | -r<overwro>}] [ src=] <textValue?src> [ dst=] <textValue?dst> . oneArg::= <textValue?src> .  ### 16.7 Variables Topic:.JZtxtcmd.syntax.var. See • DefVariable::= String\ <DefStringVar?textVariable> | Stringjar\ <DefSpecVar?Stringjar> | Num\ <DefNumVar> | Bool\ <DefBoolVar> | Pipe\ <DefSpecVar?Pipe> | List\ <DefSpecVar?List> | Map\ <DefMapVar> | Obj\ <DefObjVar> | Class\ <DefClassVar> | Classpath\ <DefClasspath> | Openfile\ <Openfile> | Fileset\ <DefFileset> | Filepath\ <DefFilepath> | Set\ <DefStringVar?setEnvVar> | set\ <DefStringVar?setEnvVar> | SET\ <DefStringVar?setEnvVar> .  The syntax component <DefVariable?> is used both in the script outside of routines for script variables, 16.1 The head of a script in classes and in the body of routines, see$chapter. The first one builds script variables, the second and third one builds variables valid in its class or routine context non stored outside of the class or subroutine execution time.

See 16.11 DataPath, Data access how access variables.

DefNumVar::= [const <?const>] <definePath?defVariable>  [ = <numExpr>].
DefBoolVar::= [const <?const>] <definePath?defVariable>  [ = <boolExpr>].
DefList::= [const <?const>] <definePath?defVariable>


[ = [ {<?element> { <dataStruct?dataSet> } ? , } ] ##some { dataSet, ...}

= [ <dataStruct?> ] ##some String or variable (const) definitions in the container.

= <objExpr?> [!;]

= [ { <objExpr?objElement> ? , } ]

].

DefSpecVar::= [const <?const>] <definePath?defVariable>  [ = <objExpr?>].
DefObjVar::= [const <?const>] <definePath?defVariable> [ : <$\.?type>] [ = <objExpr?>]. DefClassVar::= [const] <definePath?defVariable> = [: <dataAccess?loader> : ] ## a datapath to a ClassLoader instance, a Classpath variable. <textValue?>. ## The package path maybe contained in any expression DefClasspath::= [const] <definePath?defVariable> = [ : <$?parentClasspath> : ] { <filesetAccess> ? , }.
DefStringVar::= [const <?const>] <definePath?defVariable> [ = <textDatapath?>].
DefMapVar::= [const <?const>] <definePath?defVariable> [ = \{ <dataStruct> \}  ].
Openfile::= [const <?const>] <definePath?defVariable> = <textDatapath?> .


The variable is defined like a datapath, though it is not an access path but an path which defines a variable.

definePath::= <$-?startVariable>[ [?\. \>] \.{ <defineSubelement?datapathElement> ? [?\. \>] \.}]. defineSubelement::= <$-?ident> [( [{ <objExpr?argument> ? ,}])<?whatisit=(>].


A definePath for a variable starts with an identifier. An identifier is written like in Java, C or the most other programming languages. The character - is admissible too inside the identifier. An identifier can be written for example my-variable. It does not contain any $. The so named start variable is member of the datapool of a JZtxtcmd execution environment. A new defined variable will be added to this pool, but only valid for the execution level, in the current subroutine. A variable can be continued with defineSubelement which can be either a variable identifier or a method call. But the last member of that should be a simple variable ident. It is not shown in syntax, only checked on run time. In this kind it is possible to create a tree of variables. If a subroutine needs some variables, one does not need to offer all variables as parameter singly by singly. One can build a proper local datapool and offer this pool as variable to the subroutine. See 16.18 callSubroutine, callSubtext. Another possibility is adding a variable in a Map-container inside any user-Java-class. A variable in an container is always an instance of javadoc-vishiaBase/org/vishia/util/DataAccess.Variable. A defineSubelement can describe a field or method inside any (user-) Java class, see javadoc-vishiaBase/org/vishia/util/DataAccess.access(...). The value after the = is the initial value of the variable. It is necessary, if the variable is const, elsewhere it is optional. See next chapter. On Openfile it is necessary, it's the file name. ### 16.8 Fileset, Filepath Topic:.JZtxtcmd.syntax.filepath. DefFileset::= <definePath?defVariable> [ = ( [ commonpath = [<""?commonPath>|<*;,)(\ \r\n?commonPath>] , ] { [{ //JZtxtcmd | //<*\n\r?>}] [<""?filePath>|<*;,)(\ \r\n?filePath>] [{ //JZtxtcmd | //<*\n\r?>}] ? , } ) ] .  A Fileset is a variable with the same definition context possibilities like any other variable. It is constant initialized by a list of <Filepath> and maybe a commonpath which is used as base path for all files. DefFilepath::= <definePath?defVariable> [ = <textValue?> ].  A Filepath is a variable with the same definition context possibilities like any other variable. It is constant initialized by a <Filepath>. A Filepath is written either in "" or as character string till a whitespace or till a ;. The prepFilePath-syntax is applicated to that parse result: prepFilePath::=<$NoWhiteSpaces><! *?>
[ &$<$?@envVariable> [\\|/|]      ##path can start with a environment variable's content
| &<$?@scriptVariable> [\\|/|] ##path can start with a scriptvariable's content | [<!.?@drive>:] ## only 1 char with followed : is the drive letter [ [/|\\]<?@absPath>] ## starting with / maybe after d: is absolute path |] [ <*:?@pathbase>[?:=]:] ## all until : is pathbase, but not till a := [ <toLastChar:/\\?@path>[\\|/|]] ## all until last \ or / is path [ <toLastChar:.?@name> ## all until exclusive dot is the name <*\e?@ext> ## from dot to end is the extension | <*\e?@name> ## No dot is found, all is the name. ] .  The String definition of a Filepath is divided in the parts like shown. Note that a Filepath can contain either the identifier of an environment variable or of a JZtxtcmd-Scriptvariable as start of the path. The content of the variable is evaluated on access to the Filepath. See javadoc-vishiaBase/org/vishia/util/FilePath. The Filepath is tokenized in its part from the Constructor javadoc-vishiaBase/org/vishia/util/FilePath#FilePath(java.lang.String) in the same way like shown here with an Java core algorithm. ### 16.9 Text value: textDatapath, textValue Topic:.JZtxtcmd.syntax.textDatapath. A text expression presents a String: textDatapath::= <""?text> | \<:\><textExpr>\<\.\> | [& [?(] ] <dataAccess> . textValue::= <""?text> | \<:\><textExpr>\<\.\> | & <dataAccess> | <*;,)(\ \r\n\>?text> . textValueTextExpr::= <""?text> | \<:\><textExpr>\<\.\> | & <dataAccess> | <*:;,)(\ \r\n\>?text> .  There are two forms. The textDatapath is used in a normal programming environment. The textValue is used in that syntactical contexts where a simple text value is expectable. Without quotion marks, a text value is supplied: cmd myCmd.exe Such an constant text ends respectively cannot contain the characters *;( and spaces because that are following syntactical characters. A textValue allows to write more simple in the script. For textExpr see 16.14 TextExpression The datapath can access either to a location which contains text, or to a location which does not contain text. If a text is expected in the running context, a non-text will be converted to text calling the toString() operation of the gotten instance. ### 16.10 Object value: objExpr Topic:.JZtxtcmd.syntax.objExpr. An objExpr which presents any Object to assign to a variable or used for a calling argument is defined as objExpr::= | Filepath : <textValue?Filepath> ## A textValue which builds a Filepath in the currdir | Fileset: <filesetAccess> | \{ <dataStruct> \} ## It is a Map of Variables. | <""?text> ## It is a constant text. | \<:\><textExpr>\<\.\> ## It is a text assembled in runtime. | <numExpr>. ## special detection of a simple dataAccess. dataStruct::= { <DefVariable?> ; } | { <DefStringVar?textVariable> ? , }.  It is either a text, an concatenation of texts, an access to data or a complex boolean or numeric expression. If the numExpr only contains a DataPath it is stored as simple dataAccess. The dataStruct is a special form which can be used to build a Map of Objects to store as one Object. If the type File: is given a textual expression is converted to a java.io.File-instance on runtime. If one of the types Filepath or Fileset are given a texual expression or the special syntax of an filesetAccess is converted to the types javadoc-vishiaBase/org/vishia/cmd/JZcmdFilepath respectively javadoc-vishiaBase/org/vishia/cmd/JZcmdAccessFileset. ### 16.11 DataPath, Data access Topic:.JZtxtcmd.syntax.DataAccess. See • dataAccess::= [$<$?envVariable> | [<?startVariable>$<#?>| $<$?>]    ## $1 ..$999 are the arguments of JZtxtcmd, $name for environment | [java\ ] new\ <staticJavaAccess?newJavaClass> | [%|java\ ] <staticJavaAccess?staticJavaMethod> | <dataPath?> ].  For variable see 16.7 Variables. The same syntax is used to describe an access to a variable and describe the path to create a variable. The difference in runtime is: The last element of an access can be a method invocation. The elements should be existing. Inside a data path a new Java instance can be created, see 9.11 Creation of new instances of Java classes or a static method can be accessed either with the keyword java or a simple % on start of the path to the Java class. See 9.10 Access to static Java data and Invocation of static Java methods. Both expressions need a package-path to the Java class and the constructor- or the method-name. A Class-variable can be used instead a direct given package path. Note that a few Classes are given by 9.5 Predefined script variables. The Class-variable can be located anywhere in the JZtxtcmd script or in any Java data context. Therefore it is written as & <dataAccess?classVar> : itself. The package path can be located in another jar file which is defined with a Classpath-Variable. Therefore an access to static elements of a Java class can be written with the syntax: ## Access to a Java class constructor or static method or field staticJavaAccess::= [ & <dataAccess?Class_Var> : [<$\.$?javapath>] ## access via Class variable .element | [: <dataAccess?Classpath_Var> : ] <$\.$?javapath> ## [Classpath] package.path.Class.element ] [( [ { <objExpr?argument> ? , } ])]. ## arguments  A dataPath is used to address any field or method in a Java class or any member of a Map in a path. dataPath::= [ File : <textValue?File> ##creates a file object with given path | <startDatapath> ] [ [?\. \>] \.{ <datapathElement> ? [?\. \>] \.}]. ## A datapath cannot start with an JZtxtcmd keyword! startDatapath::= <?whatisit=@> [ & ( <dataPath> ) ##takes the result of <dataPath> as name of an element or method. | <$-?ident>
][
( [{ <objExpr?argument> ? ,}]) <?whatisit=(>   ##a method
| $<#?index>$ <?whatisit=$> ##an indexed array access |]. datapathElement::= [ & ( <dataPath> ) ##takes the result of <dataPath> as name of an element or method. | ##Field or method identifier, use regex for the second datapath element, it can be a JZtxtcmd keyword too! [<?ident> [@] [\[$   ##[] instead name for length operation.
| <![\\w-]+?>]        ##name as regex or [] for length of array or size() of container
]
][
( [{ <objExpr?argument> ? ,}]) <?whatisit=(>   ##a method
| $<#?index>$ <?whatisit=\[>   ##an indexed array access
|].


An indentifier of a datapath element can start with @ especially to access to a XML tree, to the attributes.

### 16.12 Condition expression

Topic:.JZtxtcmd.syntax.condition.

A condition is a boolean expression:

condition::=<andExpr?> [{\|\| <?boolCheckOrOperation> <andExpr?boolOrOperation>}].
andExpr::= <boolExpr?> [{ && <?boolCheckAndOperation> <boolExpr?boolAndOperation>}].
boolExpr::= [<?boolNot> ! | not| NOT|]
[ ( <condition?parenthesisCondition> )
| <numExpr?> [<cmpOperation>]
].
cmpOperation::=[ \?[<?cmpOperator>gt|ge|lt|le|eq|ne|instanceof] |  [<?cmpOperator> != | == | \>= | \> | \<= | \< ]] <numExpr?>.
instanceof::=<objExpr> instanceof <staticJavaAccess>.


Because the cascade of or operations with andExpr which can contain and operations, that contains an boolExpr with comparison, the rule of higher priority of

• cmp

• and

• or

is met. The boolExpr can contain the unary not able to write with ! like in C, Java or with the keyword not which may be better able to read. (...)-parenthesis conditions are possible too.

The compareOperation defines additional to the known compare operators from Java, C and the most other programming languages the operators written with:

• ?gt greater then, >

• ?ge greater or equal, >=

• ?lt less then, <

• ?le less or equal, <=

• ?eq equal, ==

• ?ne not equal, !=

This writing possibility should be used especially in text expressions, where the > may have another meaning (closing of a tag).

For text expressions the adequat syntax components are given. The only one difference is the absence of the > etc. comparison operators.

conditionInText::=<andExprInText?> [{\|\| <?boolCheckOrOperation> <andExprInText?boolOrOperation>}].
andExprInText::= <boolExprInText?> [{ && <?boolCheckAndOperation> <boolExprInText?boolAndOperation>}].
boolExprInText::= [<?boolNot> ! | not|]
[ ( <conditionInText?parenthesisCondition> )
| <numExpr?> [<cmpOperationInText?cmpOperation>]
].
cmpOperationInText::=[ \?[<?cmpOperator>gt|ge|lt|le|eq|ne] |  [<?cmpOperator> != | == ]] <numExpr?>.


### 16.13 Numeric Expression

Topic:.JZtxtcmd.syntax.numExpr.

numExpr::=  bool ( <boolExpr?> )
| <multExpr?> [{ + <multExpr?addOperation> | - <multExpr?subOperation>}].
multExpr::= <value?> [{ * <value?multOperation> | / <value?divOperation> }].
value::= 0x<#x?intValue> | <#?intValue>[?\.] | <#f?doubleValue> |    ##unary - associated to value.
[{[<?unaryOperator> ! | ~ | - | + ]}]        ##additional unary operators.
[ 0x<#x?intValue> | <#?intValue>  ##ones of kind of value:
| '<!.?charValue>' | <""?textValue>
| ( <numExpr?parenthesisExpr> )
| [& [?(] ] <dataAccess>   ## & is optional, don't confuse with &(variable)
].


Because the cascade of + - operations with multExpr which can contain * / operations, that contains an value, the rule of higher priority of

• parenthesis, functions, any values

• * /

• + -

is met. The value can contain the unary ! ~ - + operators and (...)-parenthesis like in C, Java.

A non const value comes from a datapath, see 16.11 DataPath, Data access and $chapter, 9.9 Access to Java internal data. If that results are used for numeric expressions, they should be of an numeric type or they should be a String which is able to translate in a numeric type. That translation rules are processed in the javadoc-vishiaBase/org/vishia/util/CalculatorExp. In a JZtxtcmd variable a numeric wrapper type such as javadoc-oracle/java/lang/Float can be stored. All numeric methods of the Java standard class javadoc-oracle/java/lang/Math can be used. ### 16.14 TextExpression Topic:.JZtxtcmd.syntax.textExpr. textExpr::=<$NoWhiteSpaces>
{ [?\<\.]                             ##abort on <.
[ \<&-<*\>?>\>                          ##<&- it is comment>
| \<:---\><*|---\>?>\<---\> ##<:---> comment <---> not confused with XML <--- will be produced as output --->
| \<:-<*\>?>\><textExpr?>\<\.-<*\>?>\> ##<:-comment> comment <.- >
| \#\#<*\r\n?>   ##comment to eol in a text Expression
| \<:\{  <statementBlock?>  <!\\s*>  \}\>  ##one or more statements inside a text expression, do not produce an output text.
| \<:for:<forInText?forCtrl>
| \<:if: <ifInText?ifCtrl>
| \<:hasNext\> <textExpr?hasNext> \<\.hasNext\>
| \<:subtext : <callSubtext?call>
| \<:call : <callSubtext?call>
| \<:scriptdir<?scriptdir>\>
| \<:debug[:<textDatapath?debug>| <?debug>]\>
| \<&<dataText>
| \<: [<?transliteration>n|r|t|b|[\<|#|\"]<*\>?>] \>
| \<:[<#?utf16code>|x<#x?utf16code>]\>
| \<:lf\><?newline>
| \<:\ \><!\\s*?> [ \#\#<*\r\n?> <!\\s*?> ]
| \<:s\><?skipWhiteSpaces>
| \<:@<setColumn>\>
| \<:<DefVariable?>\>
| \<:\><textExpr?>\<\.\>
| <*|\<:|\<&|\#\#|\<\.?plainText>
]
}.


Text expressions are used either to output text in 16.6 statements <+textout> or for textual arguments and values. Generally all white spaces in the text are used. The tag <$NoWhiteSpace> in the syntax means, that whitespaces in the syntax have not the meaning to skip over the whitespaces in the parsed text. Therefore all white spaces of the parsed text are read. The text can contain the named control elements and the possibility of values with format dataText: dataText::=<dataAccess>[ \:\?[<""?errorText>|<*\>:?errorText>]][ \: [<""?formatText>|<*\>?formatText>]] \>.  A <:n> produces a new line with the requested coding like given as calling argument of JZtxtcmd (0x0d, 0x0a, only 0x0a, only 0x0d). The transcription of some special characters is possible: • <:n> produces a newline character in the text (0x0a). • <:r> produces a return character in the text (0x0d). • <:t> produces a tabulator character in the text (0x09). • <:<> produces a < character in the text. With them a text can output the character combination <: and <* using <:<>: and <:<>*. • <:#> produces a #. With them a text can output a ## The <: > overrides all whitespaces. It is the possibility to wrap text where the generated text should not wrapped. The ## comment is recognized especially, because the comment functionality of the parser is switched off too in the <$NoWhiteSpace>-mode. Note that the syntax should contain \#\# instead a simple ## because elsewhere it is a comment in the syntax.

Note that a

//comment  <+>text...


does not ignore a start of a text output on the same line. This capability is proper for writing text output in a right column whereby statements are written left. To ignore lines which contain text output use:

##comment <+>inclusively ignore the text output<.+>


### 16.15 Assign an output text

Topic:.JZtxtcmd.syntax.textOut.

textOut::= [<dataPath?assign>] [:n<?newline>] \>
[<textExpr>]
[ \<\.+\>                     ## end text variants:
| \<\.n+\><?newline>
| \<\.+n\><?newline>
| \<\.+n+flush\><?newline><?flush>
| \<\.+flush\><?flush>
| \<\.+n+close\><?close>
| \<\.+close\><?close>
].
setColumn::=<numExpr> [ : <numExpr?minSpaces>] | : <numExpr?minSpaces>.


Note: in

statement::=
| \<+ <textOut>


The textOut appends the text between <+variable>...TEXT...<.+> to the variable. The variable should be an Appendable type. See 16.7 Variables. It is either an Openfile, a Stringjar, a Pipe or any other Obj which is of type javadoc-Oracle/java/lang/Appendable. That is checked on Runtime.

The Indentation of the plainText is realized with storing the column position where the syntax component <textOut> starts. It is after the <+ because the white space is parsed inside the syntax component.

### 16.16 Control statements

Topic:.JZtxtcmd.syntax.ctrl.

Program flow control is used both in statements of the script and it is possible inside a text expression.

• See $chapter forCtrl::= ( <$?forVariable> : <dataAccess?forContainer> [ && <condition> ])  \{ <statementBlock> \} .
forInText::= <$?forVariable> : <dataAccess?forContainer> [ && <condition> ] \> <textExpr> \<\.for[ : <$?@checkForVariable> ]\>.
##name is the name of the container element data reference


That control statements iterates over any container, which is gotten from any Java data context. For example and especially it is a result of a parsing process. The datapath should describe a path to either a javadoc-oracle/java/util/Iterable, a javadoc-oracle/java/util/Map or to any array type. The Map will be iterated over its ValueSet whereby the forVariable gets the values. The key of the Map element is not used. Usual the key information may be found in the value too. The forVariable gets the reference to one element of the container for any repetition.

Additionally a for can be terminated if the optional condition is false. Therewith it is possible to iterate over an container but abort that iteration if anything was found there.

ifCtrl::= <ifBlock> [{ elsif <ifBlock>  }][ else \{ [<statementBlock?elseBlock>] \} ].
ifBlock::= ( <condition> ) \{ <statementBlock> \} .
ifInText::= <ifBlockInText?ifBlock> [{ \<:elsif : <ifBlockInText?ifBlock>  }][ \<:else\> <textExpr?elseBlock> ] \<\.if\>.
ifBlockInText::= <conditionInText?condition> \> <textExpr>.


To support a chain of if blocks any number of elsif can be used. It is the same like  else if(condition){...} in Java or C/C++.

whileCtrl::= ( <condition> ) \{ [<statementBlock>] \} .
dowhileCtrl::=  \{ [<statementBlock>] \} while ( <condition> ) ; .


Both while forms are known in other programming languages.

The JZtxtcmd does not support a switch-case. Adequate the if..elsif may be used. Secondary a simple for(int var...) with an numeric index is not supported. Use while(...) instead, it does the same.

### 16.17 Exception handling

Topic:.JZtxtcmd.syntax.onerror.

onerror::= [ <#?errorLevel>
| [<?errortype> notfound | cmd | file | internal | exit ]
|]
\{ [<statementBlock>] \}.


### 16.18 callSubroutine, callSubtext

Topic:.JZtxtcmd.syntax.call.

See

callSubroutine::= [{ <dataPath?assign> [ = | += <?append>] }] call <textValue?callName> ( [{ <namedArgument?actualArgument> ? , }] ) ; .
callSubtext::=<textValue?callName> [ : { <namedArgument?actualArgument> ? , }] \>.
namedArgument::= <$?name> = <objExpr?>.  A namedArgument is any expression. If a namedArgument is designated as Filepath or Fileset it has the special syntax of this elements able to use to build such values on the fly on a subroutine call with the Filepath-Syntax for the actual value. ### 16.19 Zmake Topic:.JZtxtcmd.syntax.zmake. See 7.7 Zmake. zmake::= [ : <$-?name> :[?=] ]  ##optional : name : of the zmake target, not ends with :=
<textValue?zmakeOutput> := <textValue?callName>
( { <namedArgument?actualArgument> | <filesetAccess> ? ,} ).
## An accessPath is a Filepath, see prepFilepath::=, but analyzed on Java level.
filesetAccess::= [ <""?accessPath> | \<:\><textExpr>\<\.\>
| & <dataAccess>
| <*\ \r\n,)&?accessPath> ##will be converted to Filepath maybe with ':'
|] [ & <dataAccess?zmakeFilesetVariable>] .


The accessPath can be given as & <dataAccess>. The distinction between a singulary access path as data Access and the & <dataAccess?zmakeFilesetVariable> is done with test of the accessed instance. It is checked whether it is a Fileset or not.

The accessPath is converted to a String if it is accessed via & <dataAccess>. The String-given accessPath is converted to a srcJava_vishiaBase/org/vishia/util/FilePath. In that constructor the String is divided especially into the local path and the base path, separated by the character ':'.

### 16.20 Command line invocation

Topic:.JZtxtcmd.syntax.cmd.

cmdLineWait::=[{ <dataPath?assign> += }] cmd\  <cmdLine?>.
cmdLine::= [\!argsCheck!<?argsCheck>] <textValue?> [{[?;[\ |\n|\r]] [ \<\:arg\><textExpr?actualArgument>\<\.arg\> | \<\:args:<dataAccess?argList>\> |<textValue?actualArgument>] }]
[ \<:stdout:[ pipe<?pipe>| [$]<$?stdoutVariable>] \>] ;.
iferrorlevel::= <#?errorLevel> \{ [<statementBlock>] \}.


A cmdLineWait assigns its stdout to the variable(s), see 16.20 Command line invocation

### 16.21 Assignment to variables

Topic:.JZtxtcmd.syntax.assign.

Syntax:

assignExpr::= [{ <dataPath?assign> [ = | += <?append>] }] <objExpr?> ;.


The assignExpr is an either an expression without any assign, a procedure call in Pascal-programming language slang. Or it is a function call (Pascal) with or without side effects respectively a simple access to variables (get) or const which value or result may be assigned to any variables. For the objExpr see the syntax of 16.10 Object value: objExpr. An assignment can be done for more as one variable, or the objExpr can be executed without assignment.

The assignment can be an append, especially to a Appendable, Stringjar or Pipe variable. Then the += should be written. A Stringjar can be set newly by using a "=". An Appendable or Pipe can't be assigned, only append. If a = is used, an IllegalArgumentException is thrown in runtime. See 16.7 Variables and their types.

In opposite to the definition of variables the variable have to be existing. A variable is never created on demand. It is a important property of program safety: In some other dynamic languages a variable is created whenever it is used without explicit declaration. If the programmer writes a false identifier, this error is not detected whether on compile- nor on run-time. The actually meant variable will be unchanged, and a new not used variable will be created. The failure is non-obvious.

The rules for variable in 16.7 Variables are not valid for assignments, because there are not newly created variables. Instead the following rules are valid to recognize the type of a variable:

• a) If the found variable is of type srcJava_vishiaBase:_org/vishia/util/DataAccess.Variable, its type is checked, the Object value should be matched.

• b) If the found instance is of type java.lang.Appendable, the right side String representation is appended to it. If it is an Writer or such, it is a file writing.

• c) If the found reference type matches to the right side instance type, the reference is replaced. In this kind a String reference is replaces by a right side String.

Topic:.JZtxtcmd.syntax..

threadBlock::= Thread <dataPath?defThreadVar> = [thread] \{ <statementBlock> \}