JZcmd

# JZcmd

Inhalt

Topic:.JZcmd.

.

Topic:.JZcmd.

.

## 1 Substantiation

Topic:.JZcmd.subst.

JZcmd is a script language with its interpreter. A JZcmd 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 JZcmd script will be interpreted using Java. Only a standard Java Virtual Machine (upto version 6) 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.

In a JZcmd 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 JZcmd script--->|           |  use Java data
|           +==>+
JZcmd ===========+===>cmd line
^               +===>generate text output
Users JZcmd      +===>write files, especially text generation
script           +===>invoke Java routines,
prepare data.


As a special capability you can have access to Java data. In this kind you can work with complex container (arrays, lists, trees). A Java class can prepare data in a special and complex kind, and the JZcmd organizes the calling of that class methods with given parameters. You can prepare Java data inside a JZcmd script accessing some user specific Java classes and calling their methods. You can invoke JZcmd from a Java application too.

JZcmd has well capabilities to generate text output from any given Java data. The output text may be a XML format, a programming language's sources code, csv-Format for MS-Excel table calculation, a make script (see Zmake) or any other. The structure of the text is described with the JZcmd script. The data determine the value of place holders, conditionals and repetition sequences. The approach is similar like Wikipedia:_XSLT. But XSLT deals with XML input data only.

JZcmd is used inside

It is possible to write a .bat batch execution script for windows or a shell script for linux, which contains only the start of java JZcmd in a single line, then contains the JZcmd script text. Such a file is named usual with the extension

mybatchscript.jz.bat


If a JZcmd script is used for text generation then it is invoked from a special Java program, or especially from one of the ZBNF tool suite Zbnf2Text, Zmake, ZState. Then the script contains the rules how to generate the text. Such a generation script file is designated usual with

myTextgenerationScript.jzgen


Topic:.JZcmd.copyleft.

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/ZBNF/sf/docu/JZcmd.html.

## 3 Availability, test and examples

Topic:.JZcmd.testExamp.

The capability is tested with the following script:

This test script can be invoked immediately with a command line. Copy it simply from the browsers output as text.

It has produced the following text on the last documented test, use it to compare:

To get the JZcmd script machine, you need only the zbnfjax.jar java class archive, which is contained in the

The content of zbnfjax.zip is contained in the ZBNF project: http://www.vishia.org/ZBNF/download/last/ZBNF.zip or from http://sf.net/projects/zbnf.

## 4 Capability and general Syntax of a JZcmd script

Topic:.JZcmd.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 JZcmd script.

What offers JZcmd:

• 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 JZcmd 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 JZcmd. The JZcmd 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 JZcmd script. A second level, that may be an included JZcmd 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 JZcmd 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 JZcmd.

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

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

A JZcmd 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 JZcmd script

Topic:.JZcmd.invoke.

A JZcmd 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:.JZcmd.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.JZcmd scriptfile


To shorten the invocation of JZcmd 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 JZcmd will be written only with

jzcmd scriptfile


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

help and JZcmd 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

jzcmd --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

jzcmd JZcmdScript -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 JZcmdScript.

User arguments can be given with the option

-u:anyUserArg


The textual value is stored in script-variables named $1, $2 ... $10 etc. which can be used in the script. Debug facilities: With the option jzcmd scriptfile -debug:pathTo/debug.xml  the result of parsing of the script is written in XML format. With them it can be checked how the input was understood from the parser. It may help in complex syntactical situations. The option --loglevel:334 --log:pathTo/parserLog.txt  switches on a parser logging. It is only used for the ZBNF parser while parsing the script. Normally it is not necessary. But if sophisticated syntactical errors are given, it may be usefull. ### 5.2 Start batch file in a MS-Windows and UNIX Topic:.JZcmd.invoke.jzcmd.bat. It is recommended to store a batch file in the operation system's PATH to invoke JZcmd simple. Such a file jzcmd.bat should have the following content, this file is contained in the ZBNF download in zbnfjax/batch_templat/jzcmd.bat: @echo off REM This is the start batch for JZcmd execution for MS-Windows. REM It should be copied in a directory which is referenced by the Operation system's PATH REM and adapt with the paths to Java and the other tools. REM All what is need to run JZcmd is referenced here. REM adapt the path to the zbnfjax folder of vishia-ZBNF tools. REM It contains the jar archive for execution of JZcmd and some JZcmd scripts which may be included. set ZBNFJAX_HOME=D:/vishia/ZBNF/sf/ZBNF/zbnfjax REM If necessary adapt the PATH for a special java version. Comment it if the standard Java installation should be used. REM Note Java does not need an installation. It runs well if it is only present in the file system. set JAVA_HOME=D:\Programme\JAVA\jre7 set PATH=%JAVA_HOME%\bin;%PATH% REM adapt the path to the Java-JDK directory. That should contain bin/javac.exe. REM The JDK is necessary for compilation of java sources. Comment it if not used. set JAVA_JDK=D:\Programme\JAVA\jdk1.7.0_51 REM adapt the path to the Xml-Tools. See zbnfjax-readme. REM The XML tools are necessary for some XML operations. This environment variable may be used in some JZcmd scripts. REM Comment it if not used. set XML_TOOLS=D:\Programme\XML_Tools REM This is the invocation of JZcmd, with up to 9 arguments. java -cp %ZBNFJAX_HOME%/zbnf.jar org.vishia.zcmd.JZcmd %1 %2 %3 %4 %5 %6 %7 %8 %9 if errorlevel 1 pause  Up to 9 arguments are given by forwarding from calling level. Usual only 1 or 2 are necessary. A script can be invoked from command line or inside another script by simple writing: jzcmd path\to\script.jzcmd  The installation conditions for some tools are contained in the jzcmd.bat script. The same startegy can be used for UNIX/LINUX using a shell script. ### 5.3 Invocation from a Java application Topic:.JZcmd.invoke.java. A parsed script can be executed invoking execute(...) in javadoc-vishiaBase/org/vishia/cmd/JZcmdExecuter. It is possible to parse a capacious script on start of an application and then invoke special routines from that for example in a graphical application. ## 6 Structure of a JZcmd script Topic:.JZcmd.script. A JZcmd script is a textual script. It is parsed and converted to an internal representation of data and statements while starting JZcmd. The user can change the scripts text before it is started. Changing while running the script has no effect. There is no representation of parsed internal data outside of the JZcmd execution. The syntax of a JZcmd script is defined in ZBNF syntax language internally in the JZcmd script translator engine. That syntax can be presented in the help output, see 16 Syntax of a JZcmd script. If the syntax should be shown in the following text, it is written in form: • terminal symbol [ ] < > = : Terminal symbols are written in a mono-space font. •  monospacedItalic: On that position any identifier should be written. • italic: It is a ZBNF component, any part with a specific syntax. The text is a hint of the semantic. The syntax is explained verbal in the following text. • ... At some positions ... are written as wild-card for a partial syntax, which isn't significant in the given context. • [ option ] { repetition }. : The syntax control symbols are written in the standard italic paragraph font. Some examples in mono-space font without special character fonts are given additionally. The JZcmdScript can contain any other lines before, especially a command line invocation, which ends with exit. The script starts after the marker if other lines are need on start of that file: ==JZcmd==  The script should contain a main(...)-routine. ### 6.1 Script variables Topic:.JZcmd.script.scriptvar. All types of variables can be noted in a script outside of subroutines and outside of the main routine. The variables will be created on start time of the execution in their order in the script, independently of their position on top or between routines. One should write script variables on beginning of the script, but one can write script variables in the context of a sub routine, if they are need their especially. Script variables are existing outside of the running time of a routine, where the variable of a routine does exist only while the routine runs. Script variables can be changed in routines. See 9 Data and variables and syntax: 16.5 Variables. ### 6.2 Included scripts Topic:.JZcmd.script.incl. One can include another script in the given script. All included scripts are parsed independently and after the given script. An included script part acts like it continues the current script on end. It can define more script variables, can include another script, especially can contain some subroutines and a main(). The first found main() wins. Because the first script is parsed at first, its main routine wins. But the main routine can be defined in a included script too. One can use a script whith special sub routines but does not contain a main routine. With them, a special behavior can be variegated with a short special script. The included scripts are not textual included like an #include statement in C++ or like the ZBNF-parsers $import in syntax scripts.

Syntay see 16.1.8 The include statement.

### 6.3 The main routine

Topic:.JZcmd.script.main.

The main routine is started if another routine is not specified.

### 6.4 Classes

Topic:.JZcmd.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.2 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:.JZcmd.script.sub.

Syntax see 16.3 subroutine.

Calling a subroutine see 7.5 call: Invocation of sub routines.

Calling a subtext see 13.9 Insert text form a subroutine: <:subtext:...>.

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) { ... }


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 = call mySub();
<+out>result.textret=<&result.textret><.+n>


subtext:

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 things additionally. An text output written with <:>textexpression <.> inside a sub routine is written in the current text if the subroutine was called inside a text expression with <:subtext:"mySubtext":arguments>.

### 6.6 Statement blocks

Topic:.JZcmd.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:.JZcmd.script..

Syntax see Chapter: 16.12 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.11 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 JZcmd invocation can show this texts in a console, redirect to files or redirect for example to a message system in Java using javadoc-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:.JZcmd.script.rem.

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!
..<.+>


### 6.9 Script as part of another file

Topic:.JZcmd.script.bat.

It is possible to write a JZcmd script in a MS-Windows batchfile. The advantage: There is only one file which contains the start of the script and the script itself. Write for example:

call jzcmd.bat thisFile.jz.bat
pause
exit /B

==JZcmd==
currdir = <:><&scriptdir>/../..<.>;

Filepath input = path/to/myFile.csv;

main(){
execute(input);
}


The batchfile contains the start of jzcmd, here calling of a sub-batch which knows the calling conditions, see 5.1 Command line invocation. The batch file is ended on the exit /B statement. All text after them won't be processed from the Windows command interpreter. The JZcmd script starts after the label ==JZcmd==.

Writing inside a java source file:

Another possibility is, writing a JZcmd script on start of a Java source file. Follow the pattern:

//D:/vishia/Java/srcJava_vishiaBase/org/vishia/util/test/TestCalculatorExpr.java
//==JZcmd==
//JZcmd Obj a = java org.vishia.util.test.TestCalculatorExpr.testSimpleExpression();
//==endJZcmd==
package org.vishia.util.test;

import org.vishia.util.Assert;
import org.vishia.util.CalculatorExpr;

public class TestCalculatorExpr
{ //any class
}


The first line is a comment line with the filename. It helps to organize the invocation.

The second line starts with //JZcmd. It is a comment in the Java source file. But if this file is used as JZcmd script, the following line is used as script source. In this case a script variable is initialized with a static Java method. This line causes the invocation of that static method in exactly this source, to test somewhat. To use that, in an Eclipse-IDE there is only one Debug entry named JZcmd with the main class org.vishia.zcmd.JZcmd. The line with the filename is sufficient as calling argument. Then this file as script is started. It is possible to set a breakpoint on start of the called Java method - to test it.

The JZcmd script ends with the label //endJZcmd. The text after them is not used for JZcmd.

## 7 Statements

Topic:.JZcmd.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.12 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.4 statements.

### 7.1 Definition of variables

Topic:.JZcmd.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.

A variable except Openfile can be defined and initialized or only defined. Openfile is initialized in any case, it opens the designated file for text write operations. The textDatapath is the file name.

See 9 Data and variables and syntax: 16.5 Variables

### 7.2 start, cmd: Invocation of operation system commands

Topic:.JZcmd.statements.cmd.

If the JZcmdExecuter is used as a script executer, it may be substantial to invoke operation system commands. Their result can be used for further evaluation.

To invoke a simple executable one should write

start notepad.exe &file;


to execute for example the notepad program in windows. &file is a 16.7 Text value: textDatapath, textValue for the first argument.

If you write

cmd notepad.exe &file;


then the JZcmd waits till notepad is finished. That is the difference between the both JZcmd statements start and cmd

Note that the invocation of a batch script in windows, a shell script in linux or a so named 'internal' command in windows can't be invoked direct. It needs the invocation of cmd.exe in windows or a shell for example konsole in Linux. To invoke a batch file in windows and wait for its finishing one should write

cmd cmd.exe /C thebatch.bat "maybe param" &nextParam ;


The cmd.exe, Window's command interpreter, is invoked with the calling of the batch as command argument. The invoked executable, cmd.exe in this example is executed in an own process of the operation system, but without any console window. The standard in, out and err are provided and gathered by the execution enviroment of the JZcmd respectively from the Java's process execution facility.

If the execution of the batch should be shown in a console window ('DOS-box'), one should invoke:

cmd cmd.exe /C start cmd.exe /C thebatch.bat


It seems to be obfuscated but it is straight forward:

• cmd.exe is started, it is the command line interpreter program of windows running as process started from Java.

• /C start starts the internal command 'start' of the command line interpreter to start any programm without waiting.

• cmd.exe What is started? We need a command line window, that is cmd.exe

• /C thebatch.bat What should be executed: The batch. The option /C is an option of cmd.exe for the first command.

Only the first cmd.exe may be intuitively unexpected. But this cmd.exe is the programm which is called from the JZcmd/Java process invocation, instead for example notepad.exe or windword.exe etc. It does not creates a console window by itself just as cmd.exe written in a console window does not create a second window.

#### 7.2.1 Arguments for the command

Topic:.JZcmd.statements.cmd.args.

There are four possibilities to give arguments. For the full syntax see 16.18 Command line invocation.

Firtly and simple the arguments can be given as a constant text. The " are necessary if spaces, a ; or a ( are contained in the text:

cmd notepad.exe "myfile.txt";


An argument can be contained in a variable. It is given as access path to either a variable, Java data etc. which contains the value for the argument:

cmd notepad.exe &file;


The argument can be built with a text expression, see syntax: 16.7 Text value: textDatapath, textValue:

cmd notepad.exe <:>path/<&file><.>;


Last but not least arguments can be prepared in a List of Strings or any other Objects. the <:args:LIST> expands the list in maybe more as one argument:

List myArgs;
myArgs += "myfile.txt";


#### 7.2.2 Check of command arguments

Topic:.JZcmd.statements.cmd.argsCheck.

The command arguments can be complexely. For example to execute a command like

result += cmd !argsCheck! cmd.exe /C netsh interface ip set address <:>name="<&nameNetAdapter>"<.> static <:><&ipOwn><.> 255.255.255.0 192.168.1.1 1;


the arguments are build in the line with some variables. Any of the variables may be set with a faulty content. The command have a syntax check, sends a error text and sets an error level if any of its arguments are faulty. But like usual the error text of the command is not so pithy like necessary. To view what exactly is gotten by the command executer the !argsCheck! label can be used. Then the arguments which are sent to the command line are stored as String[]-array in the local variable argsCheck. This variable can be written out for checks. For example:

<+out><:for:arg:argsCheck><:n>--><&arg><--<.for><.+n>


presents the command arguments in one line per argument

-->arg1<--
-->arg2 may contain spaces <--


Topic:.JZcmd.statements.cmd.env.

The command line invocation gets all variables from the calling environment of the JZcmd script, especially that are the operation system variables. Additionally all local variables which are defined with set starts with $ are transfered without $ in its name as environment variable for the cmd execution.

If some environment variables will be defined in one subroutine level, all of them are added to the jzcmdsub.cmdExecuter instance. The cmdExecuter in another subroutine level does not know this environment variables:

sub mySub(){
set myEnv = "text";  //added as $myEnv in variables 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:.JZcmd.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 JZcmd execution:

textBuffer += out += cmd myCommand;


In this case the stdout is forwarding to the JZcmd 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:.JZcmd.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 = <&jzcmdsub.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.

#### 7.2.6 Execution time for operation system commands

Topic:.JZcmd.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 JZcmd 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 JZcmd 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 JZcmd 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 JZcmd 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>
}


### 7.3 currdir, cd statement

Topic:.JZcmd.statements.currdir.

Inside a JZcmd 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 JZcmd 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 JZcmd script can determine either an abbreviating directory with relative path or another current directory for the JZcmd script in opposite to the operation system's one.

• Especially with currdir = scriptdir;  on start of JZcmd the directory where the JZcmd 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 jzcmdsub.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 jzcmdsub.currdir in the javadoc-vishiaBase/org/vishia/cmd/JZcmdExecuter.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 JZcmd

Topic:.JZcmd.statements.currdir.start.

A path for the current directory can be given:

 currdir = "path/to/mycurrentdir"
currdir = scriptdir;
currdir = <:><&scriptdir>/../relative<.>

• can be used to define a proper current directory for the whole script (set it for script level).

• If a current directory is not given on start level, the operation system's current dir setting is used.

#### 7.3.2 cd or currdir = path

Topic:.JZcmd.statements.currdir.cd.

The statement cd or CD is known from both Unix shell scripts and MS-Windows batch files. The JZcmd 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 JZcmd 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 JZcmd 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 JZcmd script like in UNIX/Linux in opposite to the non case-sensitive ones in MS-Windows.

Topic:.JZcmd.statements.currdir.varaccess.

The currdir is a variable of JZcmd. 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><&jzcmd.scriptLevel.currdir><.+n>
<+out><&jzcmd.scriptLevel.currdir()><.+n>
<+out><&jzcmdsub.currdir><.+n>
<+out><&jzcmdsub.currdir()><.+n>
<+out><&currdir><.+n>


The method currdir() on sub level or for the whole JZcmd 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 jzcmdsub or jzcmd.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 JZcmd does not affect the operation system's current directory

Topic:.JZcmd.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 JZcmd 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 the JZcmd-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 javadoc-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 JZcmd script.

### 7.4 File commands

Topic:.JZcmd.statements.copy.

There are some commands to offer operation systems capability:

mkdir path/to/dir


It makes the directory starting from the current directory or with the given absolute path. If the directory exists already, it is ok, no error.

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 JZcmd 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:<:><&basepath>/to/<&name>.ext<.>


### 7.5 call: Invocation of sub routines

Topic:.JZcmd.statements.call.

Sub routines are parts of a JZcmd script, see 6.5 Subroutines and subtext.

Syntax see 16.16 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 JZcmd 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.8 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/JZcmdFilepath 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.

call subroutine(pathArg = Fileset: path:&filesetVariable);


That construct builds a srcJava_vishiaBase:_org/vishia/cmd/JZcmdAccessFileset

Hint: On missing variables etc. a runtime error occurs. Because JZcmd 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=jzcmdsub.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 Zmake

Topic:.JZcmd.statements.zmake.

A Zmake statement is written in form:

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


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 examples see Zmake.

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

### 7.7 Assignments, Expressions and Text expressions

Topic:.JZcmd.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.19 Assignment to variables

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

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

## 8 Program flow control

Topic:.JZcmd.if.

Syntax see 16.14 Control statements.

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

Topic:.JZcmd.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:.JZcmd.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:.JZcmd.if.for.

The JZcmd 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(variable: datapath.container){
statements(variable);
}


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.

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

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


The condition is checked before any iteration. If it 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;
}
}


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.

Condition if the container has a next element:

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 ,.

### 8.4 break, return, exit

Topic:.JZcmd.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.

• 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 JZcmd:

• 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 JZcmd 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:.JZcmd.data.

A JZcmd 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:.JZcmd.data.type.

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

#### 9.1.1 Num

Topic:.JZcmd.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 javadoc-vishiaBase/org/vishia/util/CalculatorExpr.Value.

#### 9.1.2 Bool

Topic:.JZcmd.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:.JZcmd.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.7 Text value: textDatapath, textValue

#### 9.1.4 Stringjar

Topic:.JZcmd.data.type.Stringjar.

A Stringjar references a javadoc-vishiaBase/org/vishia/util/StringPartAppend. It contains a javadoc-oracle/java/lang/StringBuilder which is used as Appendable. This class has all features of javadoc-vishiaBase/org/vishia/util/StringPartScan and javadoc-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 JZcmd 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 Pipe

Topic:.JZcmd.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.6 List

Topic:.JZcmd.data.type.List.

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.

#### 9.1.7 Map

Topic:.JZcmd.data.type.Map.

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";


The variable is stored in the map and can be gotten by myContainer.anyVariable.

A Map is build especially on an Chapter: 10.4 Object expression if a dataStruct is created writing:

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


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

myData.method({ String cmd1 = "cmd"; String data = anydata; }, nextArg);


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

One can use all methods of the Map interface especially

myMap.clear();


#### 9.1.8 Obj

Topic:.JZcmd.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.9 Class

Topic:.JZcmd.data.type.Class.

A Class variable is created with

Class MyClass = path.to.Class;


Whereby path.to.Class 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.Class;


A Class variable can be used to access static fields and methods or to create an instance of the class:

MyClass.itsStaticMethod(args);
<:>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.Class.itsStaticMethod(args);  ## without Class variable


A second benefit using a Class variable is: If the path is wrong, an exception is thrown on definition of the Class variable, before the access is executed.

#### 9.1.10 Classpath

Topic:.JZcmd.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 JZcmd script application needs other classes than given in the classpath of the java invocation, the Classpath should be used:

Command line to invoke JZcmd. Only the Zbnf.jar is given usual:

java -cp path/to/Zbnf.jar myScript.jzcmd


Inside the script, an additonal jar file should be used:

Classpath loader = path/to/additonal.jar;


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
);


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;


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.11 Openfile

Topic:.JZcmd.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 JZcmd interpreter is finished on the operation system. If it is a long-running process, the file will remain open.

#### 9.1.12 Filepath, Fileset

Topic:.JZcmd.data.type.fileset.

See examples_Fileset.

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 javadoc-vishiaBase/org/vishia/cmd/JZcmdFilepath: Instance which is used in JZcmd for Filepath

See javadoc-vishiaBase/org/vishia/util/FilePath: Core instance which implements the Filepath with its access methods.

• name() nameext() 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 JZcmd 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() nameext() 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_JZcmd/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. 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.13 Set Topic:.JZcmd.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:.JZcmd.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 JZcmd 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 JZcmd it is possible to build a datapath to address data. The syntax is described in 16.9 DataPath, Data access.

jzcmd.startmilli


is the path from the predefined variable jzcmd which refers the instance of JZcmdExecuter to the data field javadoc-vishiaBase/org/vishia/cmd/JZcmdExecuter.JZcmd#startmilli.

In a Datapath methods can be invoked. For example the current directory as String with Slash (unified) can be gotten with

jzcmdsub.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", jzcmdsub.currdir());


The fields and methods from any instance are found and accessed via the reflection mechanism of Java. The translator of the JZcmd-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 JZcmd 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.

The flag

jzcmd.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 JZcmd script too. But a software, including the JZcmd 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 javadoc-vishiaBase/org/vishia/util/DataAccess.

For the syntax of a datapath in a JZcmd script see 16.9 DataPath, Data access

Predefined script and subroutine variable are described in 9.5 Predefined script variables

### 9.3 Variable definition context, datapool

Topic:.JZcmd.data.defcontext.

A JZcmd 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 JZcmd 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 JZcmd 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.5 Variables.

### 9.4 Datapath depending on Variables

Topic:.JZcmd.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.A.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_JZcmd/TestAll/testAll.jz.bat in the sub testVariableDatapath().

### 9.5 Predefined script variables

Topic:.JZcmd.data.prevar.

Some variables are defined on start of JZcmd-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 JZcmd invocation is located. It is an absolute normalized path with Slash as separator.

• scriptfile The file name.ext of the script from this JZcmd invocation.

• console Reference to an instance of javadoc-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 javadoc-vishiaBase/org/vishia/cmd/JZcmdExecuter.JZcmd.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 javadoc-vishiaBase/org/vishia/cmd/JZcmdTester for some test methods.

• conv constant script variable to the javadoc-vishiaBase/org/vishia/util/Conversion for some conversion methods.

• jzcmd constant script variable, reference to the javadoc-vishiaBase/org/vishia/cmd/JZcmdExecuter.JZcmd. It is possible to access public methods and fields.

The following static classes are provided as 9.1.9 Class 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 jzcmd

Topic:.JZcmd.data.prevar.jzcmd.

It references javadoc-vishiaBase/org/vishia/cmd/JZcmdExecuter.JZcmd. Able to use for:

• jzcmd.bAccessPrivate = 1;: Enable access to private and protected data in Java class instances.

• jzcmd.scriptVariables().anyVariable = newValue;: change script-variables from any execution level.

• jzcmd.log: Instance of javadoc-vishiaBase/org/vishia/mainCmd/MainCmdLogging_ifc for logging

• jzcmd.startmilli: milliseconds after 1970, start time of the script (begin running phase), use System.currentTimeMillisec() to build differences or set it newly.

• jzcmd.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 jzcmdsub

Topic:.JZcmd.data.prevar.jzcmdsub.

It references javadoc-vishiaBase/org/vishia/cmd/JZcmdExecuter.ExecuteLevel. Able to use for:

• jzcmdsub.currdir(): current directory as String

• jzcmdsub.localVariables: Map<String, DataAccess.Variable> of all local variables able to use for subroutine-argument

• jzcmdsub.cmdErrorlevel: Return value of the last cmd invocation.

### 9.6 Definition and change of script variables

Topic:.JZcmd.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 jzcmd. It is the JZcmdExecuter itself, see 9.5 Predefined script variables. One should write

jzcmd.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);


Topic:.JZcmd.data.env.

Environment variables of the systems environment which has called the JZcmd process are available with

### 12.5 Show exception information

Topic:.JZcmd.onerror.info.

The following data access paths can be used:

error
excStacktraceinfo()


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 jzcmdsub.threadData.exception field. See 9.5.2 jzcmdsub.

A Stacktrace can be reported by using

String stacktrace = jzcmdsub.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:

JZcmd.execute - exception at; @D:\vishia\ZBNF\sf\ZBNF\examples_JZcmd\T
estAll\testAll.jz.cmd:142,28; e <*);; java.lang.NoSuchFieldException:
s; :$TEST, FileSystem, StringFunctions, System, console, conv, err, er ror, error, file, jzcmd, jzcmdsub, 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.JZcmdExecuter$ExecuteLevel.dataAccess(JZcmdEx
ecuter.java:1964); org.vishia.cmd.JZcmdExecuter$ExecuteLevel.executeDa tatext(JZcmdExecuter.java:1590); org.vishia.cmd.JZcmdExecuter$ExecuteL
evel.execute(JZcmdExecuter.java:752); org.vishia.cmd.JZcmdExecuter$Exe cuteLevel.execute(JZcmdExecuter.java:662); org.vishia.cmd.JZcmdExecute r$ExecuteLevel.textAppendToVarOrOut(JZcmdExecuter.java:1169); org.vish
ia.cmd.JZcmdExecuter$ExecuteLevel.execute(JZcmdExecuter.java:714); org .vishia.cmd.JZcmdExecuter$ExecuteLevel.execute(JZcmdExecuter.java:662)
; org.vishia.cmd.JZcmdExecuter$ExecuteLevel.execSubroutine(JZcmdExecut er.java:1321); org.vishia.cmd.JZcmdExecuter$ExecuteLevel.execCall(JZcm
dExecuter.java:1211); org.vishia.cmd.JZcmdExecuter$ExecuteLevel.execut e(JZcmdExecuter.java:753); org.vishia.cmd.JZcmdExecuter$ExecuteLevel.e
xecute(JZcmdExecuter.java:662); org.vishia.cmd.JZcmdExecuter.execute(J
ZcmdExecuter.java:431); org.vishia.zcmd.JZcmd.execute(JZcmd.java:398);
org.vishia.zcmd.JZcmd.execute(JZcmd.java:354); org.vishia.zcmd.JZcmd.s
main(JZcmd.java:190); org.vishia.zcmd.JZcmd.main(JZcmd.java:142);


One stacktrace level is presented with (last line of the example):

 org.vishia.zcmd.JZcmd.main(JZcmd.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 JZcmd call levels

Topic:.JZcmd.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 JZcmd 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 JZcmd 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 JZcmd 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 javadoc-vishiaBase/org/vishia/cmd/JZcmdExecuter.ExecuteLevel#execute(...) to view details.

## 13 Text output and text generation

Topic:.JZcmd.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:.JZcmd.text.out.

For building a textual argument the text should be surrounded with

<:>That is the text<.>


To output to the JZcmd 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 JZcmd text output file

Topic:.JZcmd.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/JZcmdExecuter#execute(org.vishia.cmd.JZcmdScript, boolean, boolean, java.lang.Appendable, java.lang.String) and docuSrcJava_vishiaBase/org/vishia/cmd/JZcmdExecuter#execSub(org.vishia.cmd.JZcmdScript.Subroutine, java.util.Map, boolean, java.lang.Appendable, java.io.File). In this cases the output is determined outside of the JZcmd script.

The text output file can be set or changed within the JZcmd 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:.JZcmd.text.indent.

To produce a newline after the output line one can write

<+>My line<.+n>


The Text is a plain text. It can be written over some lines. Usual it is indented if the surround algorithm is indented:

sub myRoutine(...)
{ for(variable: container) {
<+><: >
Create this text for it
with several lines <&variable.value>
<.+>
} ...


The text is indented of course. But in the output file the text has not an indent, of course. That is because the text starts in the column where the <+> is notated which is the indentation column. Note that in this example the first line does not start with a newline because the <: >.

There are some more possibilities especially to mark and separate ranges of text with ranges of statements:

sub myRoutine(...)
{ for(variable: container) {
<+><: >
====Create this text for it
====with several lines <&variable.value>
<.+>
if(condition) {   =========<+>A text line
=========next Line of this text
=========<.+>
}  ...


Therewith it is better obvious that there are text lines. Instead ====== there can be used :::: or ++++++ too, but not in combination in one line. Syntactically the ==== is written outside of the text before <+>A textline and inside the text in the next lines. Both is admissable. The first one is skipped by the parser of the JZcmd script. A === starting before the indentation column. See the next example which shows possibilities which may be proper or not:

     <+><: >
==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.

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 JZcmd 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 JZcmdExecuter counts only spaces and tabs from the start of a JZcmd source text to skip over the source indentation characters independent of spaces or tabulators.

Pattern for well readable JZcmd 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 JZcmd source is better able to read, no confusion because the syntax is similar. Write:

if(JZcmdexpression) {              <+>
::::::::::::  if(C_expression) { //similar syntax like JZcmd
::::::::::::    doSomethind()
::::::::::::  }<.+>
}

• The JZcmd 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.5 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 JZcmd 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 JZcmd-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<.+>
JZcmd statements <+>
text


The well able to read separation is done with the :::::.

To write a text without newline on start one can write:

JZcmdExpression()                  <+>output text <.+>
::::::::::<+>further text<.+>

• The <+> is written at right side, like above.

• Text after <+> immediately - no line feed.

• One can use ::: inside JZcmd 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:.JZcmd.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 JZcmd. It is not the newline character(s) of the JZcmd 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:

• <:lf> produces a newline, line feed with the given newline setting.

• <: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).

• <:<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>>.

• <:#CHARS> produces a # with the following CHARS. With them a text can output a ## using <:##>

• <: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 Column tabulator

Topic:.JZcmd.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.6 Place holder and values

Topic:.JZcmd.text.data.

The text can contain variable values of course. One should use

<&datapath>


to get data from any location. The datapath is the same like in assignments to String variables, see the whole chapter 9 Data and variables, the syntax of datapath in 16.7 Text value: textDatapath, textValue and syntax: 16.9 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.7 Numeric formatting

Topic:.JZcmd.text..

Numeric types can be converted with a special format. Write

<&datapath:''formatString''>


with a valie 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 JZcmd 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.

### 13.8 Program control in text expressions

Topic:.JZcmd.text.if.

In a text expression some control statements can be used, see the syntax in 16.7 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.10 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.9 Insert text form a subroutine: <:subtext:...>

Topic:.JZcmd.text.subtext.

Syntax see 16.16 callSubroutine, callSubtext. Inside a text expression one can write

...<:subtext:name:arg = value, arg2=value> ...


Then the subroutine name is called and executed.

sub name(Obj arg, String arg2="default"){
...some statements


Its output

<:>text in subroutine<.>


is written to the currently text where the <:subtext...> is called.

With that feature a text expression can be more simple to read because some complex generation conditions of a part of a text can be externalized.

In a subroutine any other text output can be done too of course with

<+channel>...text<.+>


If the channel is the same, especially if

<+>text<:subtext:subroutine>...

sub subroutine{ <+>text...<.+>...


was written, it has the same effect. The difference is a semantic one:

• Use <:>text... to merge into the current text, independent of the fact whether it is the main text or not.

• Use <+>text... to output to the main text

### 13.10 Writing to the main output file

Topic:.JZcmd.text.file.

The JZcmd 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.12 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:.JZcmd.interact.

A JZcmd 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 JZcmd script.

## 15 Debugging possibilities

Topic:.JZcmd.debug.

A JZcmd 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:.JZcmd.debug.syntax.

While invocation JZcmd the given script is translated complete firstly. If any syntactical error is found, an error message like

JZcmd - 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.JZcmd --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:.JZcmd.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:

!checkJZcmd = "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:.JZcmd.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 JZcmd 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 JZcmd 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 JZcmd 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 JZcmd 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:.JZcmd.debug.JZcmdTester.

The JZcmd knows a variable test which refers an instance of javadoc-vishiaBase/org/vishia/cmd/JZcmdTester. 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 JZcmd script:

### 15.5 Debugging in an Integrated Development Environment, for example Eclipse

Topic:.JZcmd.debug.eclipse.

The JZcmd 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/JZcmd and interpreter javadocPriv-vishiaBase/org/vishia/cmd/JZcmdExecuter. 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 JZcmd script, the user can set a breakpoint and debug its own routines. On return of this routines it returns to the JZcmdExecuter 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.

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 javadoc-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 JZcmd:

If any of the execution of the JZcmd script seems to be obscure, you can insert a debug statement bevor the obscure statement:

...jzcmd 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/JZcmdExecuter.ExecuteLevel#debug(org.vishia.cmd.JZcmdScript.JZcmditem)

 void debug(JZcmdScript.JZcmditem statement) throws Exception{
CharSequence text = evalString(statement);
Debugutil.stop();
}


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 JZcmd script. The next statement will be the 'obscure' one. You can study whats happen.

## 16 Syntax of a JZcmd script

Topic:.JZcmd.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 JZcmd from command line to output the syntax with the help text:

 java -cp path/to/zbnf.jar org.vishia.zcmd.JZcmd --help:helpoutput.txt


Details of the syntax may be changed in further development. Therefore see and compare that help output.

### 16.1 The script

Topic:.JZcmd.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 . JZcmd::= .....  #### 16.1.1 JZcmd marker Topic:.JZcmd.syntax.script.ZGenMarker. A JZcmd 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 ... JZcmd thisScript and exit then. After them the ==JZcmd== label is written. The parser skips over the whole text before the first ==JZcmd== is found. [<*|==ZGen==?>==ZGen== ] [<*|==JZcmd==?>==JZcmd== ]  The syntax means, all text will be skipped if the marker ==JZcmd== will be found. If that marker is not found, nothing is skipped. Note: Don't write that marker inside a JZcmd source. #### 16.1.2 Test outputs Topic:.JZcmd.syntax.script.test. On start of script it is possible to define output files for test: [{ ! checkJZcmd = <textValue?checkJZcmdFile> ; | ! checkXml = <textValue?checkXmlFile> ; }]  #### 16.1.3 include Topic:.JZcmd.syntax.script.include. The { include [<""?include> | <* ?include>] ; } enables the designation of included files. The file path can be given with or without quotion marks. A relative given file path starts from this file, which includes. The include statements should be given on start of the script. [{ [REM|Rem|rem] <*\n\r?> ##Remark like in batch files | include <include> ; | currdir = <textDatapath?cd> ; }]  #### 16.1.4 End marker Topic:.JZcmd.syntax.script.. 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?>  #### 16.1.5 comments Topic:.JZcmd.syntax.script.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. | //JZcmd ##ignore //JZcmd, it may be a comment for another language | //<*\n\r?> ##line comment in C style | /*<*|*/?>*/ ##block commment in C style | [REM|Rem|rem] <*\n\r?> ##Remark like in batch files  #### 16.1.6 ScriptVariable Topic:.JZcmd.syntax.script.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?> ;  #### 16.1.7 The main syntax of the rest of the script Topic:.JZcmd.syntax.script.main. The script consist of definition of subtext, 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.1.8 The include statement Topic:.JZcmd.syntax.script.include. The path can be given starting with an optional environment variable, optional continued with a path. include::= [$<$?envVar>[/|\\]][ <""?path> | <*;\ ?path>].  ### 16.2 Classes Topic:.JZcmd.syntax.class. Syntax: subClass::= <$?name> \{
{ subtext  <subtext?subroutine>
| sub <subroutine>
| class <subClass>
} \}.


A subclass starts with class <subClass>  either on script level or inside a class. It can contain sub routines with statements or sub routines to build text.

A class is yet only a division of the script. The subRoutine have static character.

### 16.3 subroutine

Topic:.JZcmd.syntax.sub.

Syntax:

subroutine::= <$?name> ( [ use-locals<?useLocals> | { add-locals<?addLocals> | <DefVariable?formalArgument> ? , }|] ) \{ [<statementBlock>] \}. 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.12 TextExpression, it contains a <textExpr> itself. The procedures for calling are the same.

### 16.4 statements

Topic:.JZcmd.syntax.stm.

Syntax:

statementBlock::= { <statement?> }.

statement::=
\{ [<statementBlock>] \}
| REM <*\n\r?> ##Remark like in batch files
| ::{:}                ##Skip over :::
| //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
| currdir = <textDatapath?cd> ;   ##set current directory
| [cd|CD] [<textValue?cd> | <*\ ;?cd> ; ]  ##change current directory
| <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>] ;
| <callSubroutine?call>
| \<+<textOut>
| \<:\><textExpr>\<\.\> [;]
| <cmdLineWait?cmdWait>
| <assignExpr>
| ;
.

srcdst::= [src=] <textValue?actualArgument> [dst=] <textValue?actualArgument> .
oneArg::= <textValue?actualArgument> .


### 16.5 Variables

Topic:.JZcmd.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 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.9 DataPath, Data access how access variables. DefNumVar::= [const <?const>] <definePath?defVariable> [ = <numExpr>]. DefBoolVar::= [const <?const>] <definePath?defVariable> [ = <boolExpr>]. 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 JZcmd 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.16 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.6 Fileset, Filepath

Topic:.JZcmd.syntax.filepath.

DefFileset::= <definePath?defVariable> [ =  (
[ commonpath = [<""?commonPath>|<*;,)(\ \r\n?commonPath>] , ]
{ [{ //JZcmd | //<*\n\r?>}] [<""?filePath>|<*;,)(\ \r\n?filePath>] [{ //JZcmd | //<*\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>.

DefFilepath::= <definePath?defVariable> [ = <textValue?> ].


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 JZcmd-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.7 Text value: textDatapath, textValue

Topic:.JZcmd.syntax.textDatapath.

A text expression presents a String:

textDatapath::=  <""?text> | \<:\><textExpr>\<\.\> | [& [?(] ] <dataAccess> .

textValue::=  <""?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.12 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.8 Object value: objExpr

Topic:.JZcmd.syntax.objExpr.

An objExpr which presents any Object to assign to a variable or used for a calling argument is defined as

objExpr::=
File : <textValue?File>         ## A textValue which builds a java.lang.File in the currdir
| 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?> ; }.


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.9 DataPath, Data access

Topic:.JZcmd.syntax.DataAccess.

See

dataAccess::=
[ $<$?envVariable>
| [<?startVariable> $<#?>|$<$?>] ##$1 .. $999 are the arguments of JZcmd,$name for environment
| [java\ ] new\  <staticJavaAccess?newJavaClass>
| [%|java\ ] <staticJavaAccess?staticJavaMethod>
| <dataPath?>
].


For variable see 16.5 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 JZcmd 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::= <startDatapath>[ [?\. \>] \.{ <datapathElement> ? [?\. \>] \.}].

startDatapath::= [ & ( <dataPath> ) | <$-?ident> ] <?whatisit=@> [( [{ <objExpr?argument> ? ,}])<?whatisit=+>]. ## Use regex for the second datapath element, it can be a JZcmd keyword too! datapathElement::= [ & ( <dataPath> ) |[<?ident>[@]<![\\w-]+?>]] [( [{ <objExpr?argument> ? ,}])<?whatisit=(>].  An indentifier of a datapath element can start with @ especially to access to a XML tree, to the attributes. ### 16.10 Condition expression Topic:.JZcmd.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.11 Numeric Expression Topic:.JZcmd.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.9 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 JZcmd 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.12 TextExpression

Topic:.JZcmd.syntax.textExpr.

textExpr::=<$NoWhiteSpaces> { [?\<\.\>] ##abort on <.> [ \<&-<*\>?>\> ##<&- it is comment> | \<:-<*\>?>\><textExpr?>\<\.-<*\>?>\> ##<:-comment> comment <.- > | \#\#<*\r\n?> ##comment to eol in a text Expression | \<:for:<forInText?forCtrl> | \<:if: <ifInText?ifCtrl> | \<:hasNext\> <textExpr?hasNext> \<\.hasNext\> | \<:subtext : <callSubtext?call> | \<:scriptdir<?scriptdir>\> | \<:debug[:<textDatapath?debug>| <?debug>]\> | \<&<dataText> | \<: [<?transliteration>n|r|t|[\<|#|\"]<*\>?>] \> | \<:lf\><?newline> | \<:\ \><!\\s*?> [ \#\#<*\r\n?> <!\\s*?> ] | \<:@<setColumn>\> | \<:\><textExpr?>\<\.\> | <*|\<:|\<=|\<&|\#\#|\<\.?plainText> ] }.  Text expressions are used either to output text in 16.4 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.

dataText::=<dataAccess>[ \: [<""?formatText>|<*\>?formatText>]] \>.     ##<*expr: format>


The text can contain the named control elements and the possibility of values with format dataText.

A <:n> produces a new line with the requested coding like given as calling argument of JZcmd (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.13 Assign an output text Topic:.JZcmd.syntax.textOut. textOut::= [<dataPath?assign>] \> <textExpr>[ \<\.+\> | \<\.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.5 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.14 Control statements Topic:.JZcmd.syntax.ctrl. Program flow control is used both in statements of the script and it is possible inside a text expression. 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 JZcmd 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.15 Exception handling

Topic:.JZcmd.syntax.onerror.

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


### 16.16 callSubroutine, callSubtext

Topic:.JZcmd.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.17 Zmake Topic:.JZcmd.syntax.zmake. See 7.6 Zmake. zmake::= [ : <$-?name> :[?=] ] <textValue?zmakeOutput> := <textValue?callName> ( { <namedArgument?actualArgument> | <filesetAccess> ? ,} ).

## An accessPath is a Filepath, see prepFilepath::=, but analyzed on Java level.
filesetAccess::= [
<""?accessPath> | \<:\><textExpr>\<\.\>
| [<?accessPathOrFilesetVariable> [&]<*\ \r\n,)&;?>]
] [ & <$?zmakeFilesetVariable>] .  ### 16.18 Command line invocation Topic:.JZcmd.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.18 Command line invocation

### 16.19 Assignment to variables

Topic:.JZcmd.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.8 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.5 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.5 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:.JZcmd.syntax..

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