Inhalt
Topic:.JZtxtcmd.
Topic:.JZtxtcmd.
Topic:.JZtxtcmd.subst.
Last changed: 2017-0729
JZtxtcmd is a script language with its interpreter. A JZtxtcmd script has capabilities adequate a shell script or batch file but with a well affinity to Java routines and special capability for text generation. A JZtxtcmd script will be interpreted using Java. Only a standard Java Virtual Machine (currently version 8) is necessary to run, like it is usual given on most systems. The ZBNF.jar file contains all byte code of that. Therefore it runs under Windows as well as under Linux, Macintosh and special operation systems which are supported by Java.
Note: Till 2017-03 JZtxtcmd was firmed as JZcmd. It is renamed because it can be used both as Text generator (T) and as command executer (c). The importance as text generator was not shown in the name JZcmd.
In a JZtxtcmd script you can invoke command line statements from your system. You can have local variables which can be filled by results of command line invocations or some more routines. You can have if()...elsif()...else...
constructs as well as for(containerelement)...
and calling of subroutines which are defined inside the own script or in included scripts.
cmd line ---------------->|<-----Invoke inside a Java application | | Another JZtxtcmd script ->| | use Java data | +==>+ JZtxtcmd =========+===>cmd line ^ +===>generate text output | +<== read files Users.JZtxtcmd +===>write files, especially text generation script +===>invoke Java routines, prepare data.
JZtxtcmd has well capabilities to access Java data. You can work with complex container (arrays, lists, trees) as well as access simple fields or invoke methods. A Java application can prepare data in a special and complex kind, and then invoke srcJava_Zbnf/org/vishia/jztxtcmd/JZtxtcmd with a given user script.jztc to generate an output text or execute somewhat with the data.
The output text from JZtxtcmd may be a XML format, a programming language's sources code, csv-Format for MS-Excel table calculation or any other. For XML the approach is similar like Wikipedia:_XSLT. But XSLT deals with XML input data only.
Topic:.JZtxtcmd.copyleft.
Last changed: 2017-0729
This description and the software, which is described was created from Hartmut Schorrig, Pinzberg, Germany (hartmut.schorrig@vishia.de). Hartmut Schorrig holds the moral rights of this description and the software.
The software can be used with the LPGL license (Lesser General Public License, published by the Free Software Foundation).
Any citation of this text needs the declaration of the owner of the moral right and the source in the internet www.vishia.org/docuZBNF/JZtxtcmd.html
.
Topic:.JZtxtcmd.testExamp.
Last changed: 2017-0729
To execute a JZtxtcmd-script you need only the Java archive ZBNF-Dowload/.../zbnf.jar and a Java virtual machine currently any version 8.
Some tests and examples are contained in the ZBNF-Download/.../ZBNF.zip This is the whole archive of ZBNF available on http://sf.net/projects/zbnf too.
The capability is tested with the following script contained in ZBNF.zip:
Topic:.JZtxtcmd.genScript.
The syntax regards of 2 strategies:
Invocation of commands, program flow control,
Preparation of texts.
The script has a
main(){ ...statements }
The main()
-Routine can be contained in an included file too. That is proper if a special script contains a special part of the program
whereby the main is given as standard in the users orbit.
For text preparation a writing style with
<:>text<&placeholder><.>
is used. The script doesn't use the "quotation marks"
for texts. Instead a text is written in the script directly inclusive all white spaces, line feed etc. See 13 Text output and text generation.
The complete syntax is shown and explained in 16 Syntax of a JZtxtcmd script.
What offers JZtxtcmd:
A simple script well readable.
Whitespace-strategy. You can wrap lines like your intension. You can use indents to structure like you want to do. For example a long command line can be separated in some lines, one per argument.
Command line invocation:
Invocation of commands of operation system like in batch files or shell scripts, starting or waiting for completion. See 7.2 start, cmd: Invocation of operation system commands
Processing error feedbacks of command line invocations with errorlevel, using of input and output/error pipes. The output can be written both to standard output and in internal variable for post-processing.
Program structure, control flow, variable:
program flow control with if ... elsif ... else
, while(cond)
for(element : container)
. See 8 Program flow control
nested statement blocks {....}
including of sub-scripts, which can contain sub-routines or the main routine. See 6.5 Subroutines and subtext and 7.5 call: Invocation of sub routines
exception handling. See 12 onerror - Exceptionhandling
Scriptvariable and sub-routine variable. See 9 Data and variables
Usage of environment-variable, building of environment variable for the following command invocations.
multithreading: Build of statement blocks which runs in another thread. See 11 Multithreading
Java usage:
If the JZtxtcmd script is called from a Java context, it can have data associations to any Java instance.
Access to data, possible to private too (with calling argument flag, for debugging).
Invocation of methods from given instances with textual, file or numerical parameter or data associations.
Creation of Java instances.
Invocation of static Java methods.
Exception handling support.
Text generating capabilities:
One text output file, given as argument of JZtxtcmd. The JZtxtcmd can be used as text generator: <+text>...
The output file may be a shell script or batch file, a make file or something else.
Plain text in the script.
Access to data as part of texts: <&data.method().data>
Text generation for example for content of variable or calling arguments, simple concatenation writing rules: <:>text<&withData><.>
Zmake approach:
Zmake offers a strategy to use simple make scripts (more simple than a GNU maker, more simple than ANT) for complex make requirements. The trick is: The first level of Zmake names files and make targets. It is a well user-friendly JZtxtcmd script. A second level, that may be an included JZtxtcmd script, contains the rules how to make with check of dependencies etc.
A Dependency check especially for C/C++ files is provided as a Java routine able to call in a JZtxtcmd subroutine which organizes the make.
The combination with Java programs offers the following strategy:
More complex programs are implemented in Java. They can/should be written in a common approach, without the actual using intensions.
The organisation of calling the Java methods, with its concret arguments are written with JZtxtcmd.
All Java classes from libraries all over the world are ready to use in a JZtxtcmd script.
JZtxtcmd is structured but not object-oriented by itself. With usage of Java-objects it is object-oriented.
A JZtxtcmd script is parsed and translated from its textual presentation to an internal tree of execution statements while starting. In the running phase the textual script is not used. The interpreter works with its internal data. Independent of this principle a changing of the source text and re-translate to support debug facilities is planned but not implemented yet.
Topic:.JZtxtcmd.invoke.
A JZtxtcmd script can be started from a command line environment similar to a batch file or shell script, or it can be started from any Java application inside.
Topic:.JZtxtcmd.invoke.cmd.
One needs only a standard java upto version 6 and the zbnf.jar
file. The last one can be downloaded from ZBNF_on_Sourceforge or from the vishia_Downloadpage.
java -cp path/to/zbnf.jar org.vishia.zcmd.JZtxtcmd scriptfile
To shorten the invocation of JZtxtcmd and to simpify some inclusions, a batch file should be used. That batch file should be invoke-able in the operation system's PATH. Then the invocation of JZtxtcmd will be written only with
jztxtcmd scriptfile
See the template for a batch file for windows: zbnfjax/batch_template/jztxtcmd.bat and linux: zbnfjax/linux_startscript_template/jztxtcmd. This file contains the setting of some environment variable which can be used in JZtxtcmd scripts. It refers paths where other tools are found.
help and JZtxtcmd syntax:
Some more arguments can be given, especially a file path to the standard text output, some arguments for debug, and user arguments. To see a complete argument description, invoke
jztxtcmd --help
The help text is send to the stdout and contain a syntax description in ZBNF format, which is used for parsing.
Text output:
To generate a text output, you can invoke
jztxtcmd JZtxtcmdScript -t:pathTo/file.txt
That file will be written with <+> This text will be generated <.+>
inside the script. You can generate for example make files, batch files, xml files etc. etc. controlled by the JZtxtcmdScript
.
Another possibilities to control which text files are <+:create>filepath...
, FileOpen file =filepath;
.
User arguments can be given with the option
-u:anyUserArg
The textual value is stored in script-variables named $1
, $2
... $10
etc. which can be used in the script.
Debug facilities:
With the option
jztxtcmd 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.
Last but not least you can start the JZtxtcmd for example in a Eclipse environment for debugging. You can set a breakpoint
in the Java source lines and activate it with a debug
statement, see 15 Debugging possibilities. Then one can see how does it works in Java.
Topic:.JZtxtcmd.invoke.jztxtcmd.bat.
It is recommended to store a batch file in the operation system's PATH to invoke JZtxtcmd simple. Such a file jztxtcmd.bat
should have the following content, this file is contained in the ZBNF download in zbnfjax/batch_templat/jztxtcmd.bat
:
@echo off REM This is the start batch for JZtxtcmd 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 JZtxtcmd is referenced here. REM adapt the path to the zbnfjax folder of vishia-ZBNF tools. REM It contains the jar archive for execution of JZtxtcmd and some JZtxtcmd scripts which may be included. set ZBNFJAX_HOME=D:/vishia/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 JZtxtcmd scripts. REM Comment it if not used. set XML_TOOLS=D:\Programme\XML_Tools REM This is the invocation of JZtxtcmd, with up to 9 arguments. java -cp %ZBNFJAX_HOME%/zbnf.jar org.vishia.zcmd.JZtxtcmd %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:
jztxtcmd path\to\script.jztxtcmd jztxtcmd %0
The second form uses the same script, see meaning of %0 in batch programming in MS-Windows.
The installation conditions for some tools are contained in the jztxtcmd.bat
script.
The same startegy can be used for UNIX/LINUX using a shell script.
Topic:.JZtxtcmd.invoke.bat.
It is possible to write a JZtxtcmd 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 jztxtcmd.bat %0 pause exit /B ==JZtxtcmd== currdir = <:><&scriptdir>/../..<.>; Filepath input = path/to/myFile.csv; main(){ execute(input); }
The batchfile contains the start of jztxtcmd, here calling of a sub-batch which knows the calling conditions, see 5.1 Command line invocation. %0
ist the path to the batch file itself. The batch file is ended on the exit /B
statement. All text after them won't be processed from the Windows command interpreter. The JZtxtcmd script starts after
the label ==JZtxtcmd==
.
Writing inside a java source file:
Another possibility is, writing a JZtxtcmd script on start of a Java source file. Follow the pattern:
//D:/vishia/Java/srcJava_vishiaBase/org/vishia/util/test/TestCalculatorExpr.java //==JZtxtcmd== //JZtxtcmd Obj a = java org.vishia.util.test.TestCalculatorExpr.testSimpleExpression(); //==endJZtxtcmd== 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 //JZtxtcmd
. It is a comment in the Java source file. But if this file is used as JZtxtcmd 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 JZtxtcmd
with the main class org.vishia.zcmd.JZtxtcmd
. 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 JZtxtcmd script ends with the label //endJZtxtcmd
. The text after them is not used for JZtxtcmd.
Topic:.JZtxtcmd.invoke.java.
See srcJava_Zbnf/org/vishia/jztxtcmd/JZtxtcmd
A parsed script can be executed invoking execute(...) in srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter. 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.
Topic:.JZtxtcmd.script.
A JZtxtcmd script is a textual script. It is parsed and converted to an internal representation of data and statements while starting JZtxtcmd. 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 JZtxtcmd execution.
The syntax of a JZtxtcmd script is defined in ZBNF syntax language internally in the JZtxtcmd script translator engine. That syntax can be presented in the help output, see 16 Syntax of a JZtxtcmd 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 JZtxtcmdScript 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:
==JZtxtcmd==
The script should contain a main(...)
-routine.
Topic:.JZtxtcmd.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.7 Variables.
Topic:.JZtxtcmd.script.incl.
Syntax: 16.3 The include statement
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 it can contain some subroutines and a main().
include path/to/otherScript.jzTc include $ENV_TO/"path/global Script.jzTc"
The path to another script is written as simple character String till a whitespace, or in ""
. That path starts relative from the current script. If the path starts with an environment variable $VAR
especially the environment variable should contain an absolute path, where the included script can be found.
main()-Routine in an included script:
If the top level script (which includes) contains a main()
-Routine, it is used. If the top level does not contain a main()
the first found main()
in included scripts is used. One can use a script only with special sub routines which includes the script with the main()
. Therewith a special behavior can be variegated with a short special script.
Topic:.JZtxtcmd.script.main.
A script or a included script should contain a main routine. This is used to execute the script. (The main routine is started if another routine is not specified. TODO how?)
main() { ##statements }
Topic:.JZtxtcmd.script.class.
The script can be divided in classes. Each class can have sub classes. Yet the routines of classes can be seen as only static routines in comparison with Java classes.
Syntax see 16.4 Classes
To invoke a sub routine in a class one should write
classname.subroutine(...);
For future development: It is an object oriented concept which may usefull to organize the workflow with sub scripts. Each class should have class variables.
Topic:.JZtxtcmd.script.sub.
Syntax see 16.5 subroutine.
Calling a subroutine see 7.5 call: Invocation of sub routines.
Calling a subtext see 13.12 Insert text form a subroutine: <:subtext:...>.
Statements in a variable see 9.1.9 Subtextvar, Subroutinevar - statements to execute
It is recommended to divide the execution of a task in more as one sub routines. Any routine should be short and easy. Long shell scripts or batch files with some goto are terrible. A routine should be manageable with about one screen size, 40..50 lines.
sub mySubroutine(String arg1="example", Obj arg2 = scriptVar){ <+out><&arg1>, <&arg2><.+n> }
arguments and local variables:
A subroutine can have an argument list which builds local variable for the routine. For calling a subroutine with building actual arguments see 7.5 call: Invocation of sub routines.
If (use-locals)
is not set then a subroutine gets a copy of all script variables if they are writeable and gets the reference to readonly
script variables. If that variables are changed the value of the script variables are not influenced. A subroutine can define
its own variables. All that variables are existent as long as the routine runs.
It is possible to call a subroutine which uses the same local variables as the calling level. Then that subroutine is not independent of the calling environment. It should only be called in one environment or in adequate environments. Elsewhere errors are possible if used variable are not found. Such an behaviour is only possible for script languages. It makes easy to dispers the source code without effort for definition of a lot of variables:
sub myRoutine(use-locals) { ... } subtext myText(use-locals) <:>...<.>
Such a subroutine or subtext cannot have additional arguments. It should not define a return variable except the return variable should be used in the calling level as return.
It is possible to add all local variables of the calling level to the local variables of the subroutine. In that case the
subroutine is independent but it knows all variables of the calling level. Changing a variable in the subroutine does not
affect the variables of the calling level. The application of that feature may be similar to use-locals
:
sub myRoutine(add-locals, String moreParameter) { ... } subtext myText(add-locals, String moreParameter) <:>...<.>
returned values:
A subroutine can return some values stored in a variable tree. This variable tree is named return inside the subroutine:
sub mySub(String arguments){ String return.textret = "any text"; Obj return.objret = anyObjExpression... } outside: Map result; result = call mySub(); <+out>result.textret=<&result.textret><.+n>
Topic:.JZtxtcmd.script.stm.
The main routine, a sub routine or some parts of the routine consists of a statement block.
{ statements }
Statement blocks can be nested. Especially they are used in control structures:
if(condition){ statements} else { statements}
For statements see 7 Statements
Topic:.JZtxtcmd.script..
See 13 Text output and text generation and 10.3 Text expression.
Syntax see Chapter: 16.14 TextExpression.
A text argument or a comprehensive part of a subroutine can be a text block. The text block is clamped either with
<:>text block<.>
if the text block is expected as argument, or it is organized as output to any Appendable, simple
<+>text block<.+>
for output to the main output text file, given by a calling parameter, usual -t=text.file
, or
<+openfile>text block<.+>
to output to any javadoc-oracle/java/lang/Appendable especially (see 9.1.12 Openfile).
To output with a newline on end written in one line you can write
<+>An output line<.+n>
The generated text contains the same characters like written in the source, except line feeds and indentation. The linefeed can be controlled by a parameter, the indentation can be controlled in the following forms.
<+> This is an line left aligned This line starts 2 spaces after ,,<+,,-column, therefore it has 2 spaces as indentation. <:@indent*2>This line starts at the column ,,indent*2,, ::: This line starts with 2 spaces, because 2 spaces after ,,:::,, :::::::::::::This line is left aligned because it starts after ,,:::::,, which starts before the ,,<+,,-line <.+>
See 13.3 Lines and indentation in the script.
One can write to the stdout using <+out>...<.+>
and to the stderr using <+err>...<.+>
. The environment of the JZtxtcmd invocation can show this texts in a console, redirect to files or redirect for example to
a message system in Java using srcJava_vishiaBase/org/vishia/msgDispatch/MsgRedirectConsole:
<+out>stdout output like java.lang.System.out.println(...)<.+n> <+err>stderr output like java.lang.System.err.println(...)<.+n>
Topic:.JZtxtcmd.script.rem.
Syntax see $chapter.
The script is parsing with comment specifications which are regarded from the parser. That is:
##line comment to end of line (? block comment over some more lines ?)
Additional the //
and the /* ... */
can be used for comments like in Java or C. That comments are formally parsed, they are visible in the parsers result xml
file with option -debug:file
, but they are ignored for execution.
Note that a
//comment <+>text...
does not ignore a start of a text output on the same line. This capability is proper for writing text output in a right column whereby statements are written left. To ignore lines which contain text output use:
##comment <+>inclusively ignore the text output<.+>
Inside text expressions the //
does not act as comment. Instead it is a part of the generated text.
<+>text ##comment to end of line function(arg); //A C file may be generated with comments! ..<.+>
In Text expressions it is possible to comment some parts without disturbing the structure, for tests:
<:> <&-datapath.is.comment> <:---> comment till <---> <:-if> it is commment till <.-if> <:-for> it is commment till <.-for> <!--- It is not comment, but it is comment in an XML file ---> <.>
See syntax 16.14 TextExpression
Topic:.JZtxtcmd.statements.
Any independent line in a statement block is a statement. Some statements are designated by a keyword. Statements without a keyword are assignments and / or expressions which can invoke to Java methods.
The statements can be divide to
Definition of variables
Stringjar
, String
, List
, Map
, Obj
, Num
, Bool
, Class
, Classpath
: variable declaration, see 9.1 Types of variables and their assignment
Openfile
opens a file, declaration of a Writer variable.
Fileset
, Filepath
; Set of files or one file with access to its base path etc. See 9.1.13 Filepath, Fileset
Set
, set
: set a environment variable
Invocation of cmd and sub routines
call
call of subroutines of the JZtxtcmd script
start
start of a independent command process
cmd
execution of a command process with stdout, stderr and errlevel feedback: Chapter: 7.2 start, cmd: Invocation of operation system commands
zmake
A Zmake target. See @7.7 Zmake
Some file handling
cd
change directory
move
file move
copy
file copy
delete
if(File:"path/to/file".exists())
control statements
for
, if
, while
, program flow control
break
break in a onerror handling
return
end of a subroutine
exit
end of the script.
onerror
exception and error handling.
Thread
Thread execution with Thread variable.
thread
Thread execution independent.
debug support
debug
debugging support.
Text expressions
<+...
text expression.
All other keywords are Statements without a keyword are build with assignments and / or invocations to Java methods. See 10 Expressions.
variable =
expression
expression;
Statements are terminated by a colon ;
character. The line structure (spaces, line feed) have not any influence.
The full syntax is described in 16.6 statements.
Topic:.JZtxtcmd.statements.data.
Variables have to be definined before using. The definition can be come together with an initial or final assignment, which invokes an expression maybe with side effects. There are some but rare types.
Num
: a numeric value build with 10.6 Numeric Expression. It is wrapped with srcJava_vishiaBase/org/vishia/util/CalculatorExpr.Value.
Bool
: a conditionbuild with 10.5 Boolean expression, Conditions. It is wrappend with javadoc-oracle/java/lang/Boolean.
String
: refers a constant text build with textDatapath. It is a javadoc-oracle/java/lang/String.
Stringjar
: It is an container for Strings. One can append, delete or set newly. It is possible to search, check, scan somewhat etc.
In Java it is a srcJava_vishiaBase/org/vishia/util/StringPartAppend which is an javadoc-oracle/java/lang/Appendable. It refers to a javadoc-oracle/java/lang/StringBuilder. Syntax see 16.21 Assignment to variables.
Pipe
: It is a java.lang.StringBuilder
, a buffer of characters. Some operations appends on the end of the buffer, some operations read from begin of the buffer
and shifts the content to left. It is used for command pipes. A pipe is a queue which contains text.
List
: A list container. Any 16.21 Assignment to variables adds a new Object-type element. It can be used in for(variable:list)
. It is a javadoc-oracle/java/util/List instantiated with a javadoc-oracle/java/util/LinkedList
Map
: A container with a String key. It is used as container for sub variables usually. It is a javadoc-oracle/java/util/Map instantiated with a srcJava_vishiaBase/org/vishia/util/IndexMultiTable. A javadoc-oracle/java/util/TreeMap is not used because the IndexMultiTable
is better to debug. The values of a short list (20 elements) can be seen immediately.
Obj
: It is any javadoc-oracle/java/lang/Object. One can create an Object or return it from a java path.staticmethod()
-invocation.
Class
: It is a javadoc-oracle/java/lang/Class. It is used especially to call a classvar.staticmethod()
with it.
Classpath
: It is a javadoc-oracle/java/lang/ClassLoader. It is used when another class Library should be used. Because from the context of the script, the variable names class paths
(path to jar-files, path to a directory which contains class-Files), therefore it is named Classpath
and not ClassLoader
. From the context of running the script it refers an instance to help loading classes. See 9.1.11 Classpath
Openfile
: If this variable is created, the named file is opened for write, maybe append. The variable is an javadoc-oracle/java/lang/Appendable respectively an javadoc-oracle/java/io/Writer. Any assignment to an Openfile
will be written in the file. A close()
on this variable closes the file. Don't forget close(). A flush()
is possible to write out internal buffered content to be visible on file system. See 9.1.12 Openfile and 13 Text output and text generation.
Set
and set
defines or changes internal environment variables which can be accessed with $name
in the script and which are present on cmd
line invocation. See 9.1.14 Set
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.7 Variables
Topic:.JZtxtcmd.statements.cmd.
If the JZtxtcmdExecuter 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.9 Text value: textDatapath, textValue for the first argument.
If you write
cmd notepad.exe &file;
then the JZtxtcmd waits till notepad is finished. That is the difference between the both JZtxtcmd 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 JZtxtcmd 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 JZtxtcmd/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.
Topic:.JZtxtcmd.statements.cmd.args.
There are four possibilities to give arguments. For the full syntax see 16.20 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"; 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.9 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"; cmd notepad.exe <:args:myArgs>;
Topic:.JZtxtcmd.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:.JZtxtcmd.statements.cmd.env.
The command line invocation gets all variables from the calling environment of the JZtxtcmd 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 jztcsub.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.
Topic:.JZtxtcmd.statements.cmd.pipe.
The standard output of a cmd invocation can be gathered with an append assignment:
textBuffer += cmd myCommand;
whereby the textBuffer
of this example can be a Stringjar
, a Openfile
, a Pipe
or any other Appendable
in the Java data. It is possible to have more as one Appendable which gather the standard output. Especially out
can be used to forwarding the stdout of the process to the stdout of the JZtxtcmd execution:
textBuffer += out += cmd myCommand;
In this case the stdout is forwarding to the JZtxtcmd console output and gathered in the textBuffer too. The output is handled simultaneous while the command line execution process runs. If a execution needs some time, for example a search and report process from many files, the user can visit the output of the command line execution straight. This is a capability of the java virtual machine command line process handling with its application interface class javadoc-oracle/java/lang/Process and the class srcJava_vishiaBase/org/vishia/cmd/CmdExecuter
The other possiblity for gathering the stdout of the process and the only one possibility for a separated stderr and stdin is:
cmd myCommand <:stdout:textBuffer> <:stdout:out> <:stderr:out> <:stdin:myPipe>;
Both variants can be combined. stdout
and stderr
can be written in any number of destinations. The stdin
can be given only one time.
Topic:.JZtxtcmd.statements.cmd.errorlevel.
A cmd invocation has an exit code. It is a principle both in UNIX-like operation systems and in MS-Windows. Usual a higher
value of an exit code means a more fatal error. 1 may be a warning, 0 is successfully. The exit code is designated as errorlevel
usual in MS-Windows batch files.
After a cmd invocation one can output the exitcode for example as hexadecimal value writing
cmd myCmd ... <+out>exit error level = <&jztcsub.cmdErrorlevel:"%8X"><.+n>
There are two startegies to handle the exit code:
if errorlevel 1 { ...statements...}
That statements are executed additionally if the last cmd sets the requested or a higher errorlevel. For example a warning can be logged.
throw on errorlevel 2;
If that statement is executed, an exception is thrown if the exit code (errorlevel) of the last cmd invocation is equal or
higher to the requested value. It means, the following statements are skipped till a onerror {...}
or onerror cmd {...}
statement is found or the block is left with that exception.
Both strategies can be combined:
cmd myExecutable.exe arguments throw on errorlevel 5 if errorlevel 1 { ...} ... ...further statements ... onerror cmd { ... alternatively statements on fail } ...continue processing
If the command generates an exit code equal or greater 5, the further statments
are skipped. They should not be executed, because the permissions are not given. If the errorlevel is 1..4, the further statements
are executed. The onerror cmd
block is executed only if the exit code is 5 or higher. There may be executed any alternatively things. Last not least the
processing continues after the onerror
-block.
See examples_JZtxtcmd:TestAll/readme.txt: sub testErrorlevel()
Topic:.JZtxtcmd.statements.cmd.calctime.
The invocation of a operation system command call creates a new process in the operation system. That needs a few milliseconds. A value of about 50 ms was measured with an Notebook with MS-Windows XP, Intel dual core about 1.2 GHz.
That time is not large if a complex command line process is started. But if some command lines are executed one after another, each of them with a small task, then this 50 ms are multiplied by the number of cmd invocations. For example a compilation or any other translation was started.
If a Windows-batch-file or a UNIX shell script runs, the cmd.exe
or shell script interpreter optimizes the invocation of commands. There is not an extra process for each command. Therefore
it may be recommended for a block of commands to generate such an script and executed the whole script. Of course the advantage
of an operation-system-independent syntax for JZtxtcmd is not able to use if either a MS-Windows batch file should be executed
or on the other hand an UNIX/LINUX shell script. But usual such JZtxtcmd user scripts are proposed for a special operation
system.
For example to invoke some commands as batch in windows one can write:
Openfile bat = "myBatch.bat"; ##opens in current directory <+bat> echo off dir >out.txt call otherbatch.bat <.+close> cmd cmd.exe /C myBatch.bat;
The batch is contained as text lines in a JZtxtcmd script. That text lines are written to a file. That file is executed with
cmd.exe
, the MS-Windows batch file executer.
The produced text in out.txt
can be read in the JZtxtcmd script then and it can be evaluated:
Stringjar sdir = FileSystem.readFile("out.txt"); ##reads the file. if(sdir.seek("myBatch").line().found()){ String line = sdir.getCurrentPart(); <+out><&line><.+n> }
See examples_JZtxtcmd:TestAll/readme.txt: sub testBatch()
Topic:.JZtxtcmd.statements.currdir.
Inside a JZtxtcmd script a current directory can be set. It is used especially for 7.2 start, cmd: Invocation of operation system commands and for file operations with relative paths:
cmd execute anything; ## uses the currdir for command process Openfile myfile = relative/path.ext ## uses the currdir to build the file path datapath.method(File:"relative/path") ## creates an absolute File object with currdir
On start of a JZtxtcmd script the currdir on scriptlevel can be set with start parameter. Per default it is the current dir of the operation systems.
The currdir = path;
- statement on start on a JZtxtcmd script can determine either an abbreviating directory with relative path or another current
directory for the JZtxtcmd script in opposite to the operation system's one.
Especially with currdir = scriptdir;
on start of JZtxtcmd the directory where the JZtxtcmd script is located can be set as current directory. Often some other
files are located in the same directory or with relative paths to them.
A sub routine gets its local current directory from the calling level. In a sub routine the current directory can be changed
with cd
-statement. It is valid only for the subroutine level and its called nested level. This behavior is adequate to the cd
-statement in other scripts and adequate to the set of environment variables.
The script level's current directory can be changed in a sub routine: Access to
The jztcsub.currdir()
returns the current directory of the sub level as text. It uses the /
as path separator.
The current directory of any execution level is hold in the variable jztcsub.currdir
in the srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExecuteLevel instance. It is a java.io.File
object with an absolute normalized path.
Practice of absolute and relative paths:
It is not recommended to define an absolute path if the script should be used on several computers may be with different locations in the file system.
On the other hand the usage of absolute paths for files is at runtime proper. For example if a file should be opened but it fails, an error message which names the absolute path of the file is more helpfull. If the message contains the relative path only, the question remains on which path starts the relative one.
The following rule should be valid:
Use relative paths in all scripts and sources. Therewith the location in the file system is variable.
On execution time the relative paths should be translated to absolute ones.
Topic:.JZtxtcmd.statements.currdir.start.
A path for the current directory can be given:
If the JZtxtcmd was invoked from command line via srcJava_Zbnf/org/vishia/jztxtcmd/JZtxtcmd#main(java.lang.String[]) a current dir can be given as absolute or relative path with the command line argument -currdir=PATH. A relative path is translated to an absolute one regarding the current directory of the command line invocation.
If the JZtxtcmd was invoked from any Java execution, the currdir may be given with a calling argument. It is set at the discretion of the caller. See srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter#execSub(org.vishia.cmd.JZtxtcmdScript.Subroutine, java.util.Map, boolean, java.lang.Appendable, java.io.File)
On start of the script an statement
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.
Topic:.JZtxtcmd.statements.currdir.cd.
The statement cd
or CD
is known from both Unix shell scripts and MS-Windows batch files. The JZtxtcmd supports it too:
cd newDir
changes the content of the currdir
of any subroutine level. Relative paths can be used, especially ..
. This changes are done in the local copy of the subroutine, not for the script variable currdir
. If the newDir is faulty, non existing or any faulty path, an IllegalArgumentException is thrown. The user can catch such
an exception with
cd requestedPath/maybe/faulty ... do something with it onerror{ ...errorHandling }
See 12 onerror - Exceptionhandling
Instead cd
the form
currdir = "newDir";
can be used. The difference between both is less.
cd mydir; currdir = "mydir";
cd
uses a <textValue>
, see 10.2 textValue or textDatapath, whereby currdir =
uses a <textDatapath>
. The cd
statement is similar the known operation system's one.
The currdir = ...
is like an JZtxtcmd assignment. Both operations are adequate in respect to working with relativ paths. If a relative path
is given, it is regarded to the actual value of the currdir
.
Especially on start of a JZtxtcmd script or in a sub routine the following statement can be used:
currdir = scriptdir; currdir = <:><&scriptdir>/../relative<.>;
Often it is usefull if the script is contained in a working area in an sub directory, and the working area should be used as current directory without any other effort.
Especially some environement variable of the operation system can be used to set a special, usual absolute currdir:
currdir = $CD; ##set it to the operation system's current dir currdir = $PWD; ##adequate for Unix currdir = $HOME; currdir = <:><&$HOME>/myDir<.>; ##inside the HOME directory
Note that the environment variables are case sensitive in the JZtxtcmd script like in UNIX/Linux in opposite to the non case-sensitive ones in MS-Windows.
Topic:.JZtxtcmd.statements.currdir.varaccess.
The currdir
is a variable of JZtxtcmd. But the assignment currdir = ...
is a special statement. If the value of the currdir is need as text value for example to output it for check one can write:
<+out><&jztc.scriptLevel.currdir><.+n> <+out><&jztc.scriptLevel.currdir()><.+n> <+out><&jtcmdsub.currdir><.+n> <+out><&jztcsub.currdir()><.+n> <+out><&currdir><.+n>
The method currdir()
on sub level or for the whole JZtxtcmd script returns a string which uses /
as separator for directories in the path, like it is recommended for internal use.
The field currdir
in the instance jztcsub
or jztc.scriptLevel
is a reference to a java.io.File
. Therefore it's conversion to a String returns the path in the operation system's kind. It is a property of the Java Virtual
Machine. Therefore the backslash \ is written as path separator.
Topic:.JZtxtcmd.statements.currdir.noOs.
If you invoke any Java method, and that Java method tries to open a file for example with
Writer openit = new FileWriter("relative/path");
then the Java Virtual Machine delegates the resolving of the relative path to an absolute one to the operation system. Of course the operation system does not know a currdir variable of the JZtxtcmd level. Therefore it may be failed.
If you use a File object instead:
Writer openit = new FileWriter(File:"relative/path");
then the File will be build with an absolute path which uses the JZtxtcmd-internal currdir instead.
If any Java module can be influenced with a special setting of the current directory you can do so. For example and especially
the class srcJava_vishiaBase/org/vishia/mainCmd/MainCmd knows an command line argument "--currdir:value"
which can be set from Java internally too. You can write
java path.to.Main.main(<:>--currdir:<&currdir><.>, "further arguments...");
If you're attempt to invoke a Java program which uses MainCmd
from the JZtxtcmd script.
Topic:.JZtxtcmd.statements.copy.
There are some commands to offer operation systems capability:
mkdir path/to/dir;
Syntax see 16.6 statements. It makes all necessary directories starting from the current directory or with the given absolute path. If the directory
exists already, it is ok, no error. The path can be given as immediate text without spaces, or in "" or as <:>textexpression<.>
. If the path ends with a '
(Apostroph, Hexa 0x27) then it means, the path ends with a file name. The file part is removed then, only the directory is
created:
mkdir <:><&path_to_file_variable>'<.>;
creates the directories to the file, not the file itself (since 2018-01).
Copying a file. The copy command knows 3 options:
-n
: Saves the copied file with a new time stamp, the current date. This is like usual in Unix. It is necessary if a standard
maker is used and the copied files are sources. Without this option the destination file preservs the time stamp from the
source. That is the standard behavior in MS-Windows for a copy.
-w
: Overwrites files if they are exists. If this option is not set and the destination file exists, the copy will be aborted
with an IllegalArgumentException.
-r
: Overwrites files though they are read only. This is a behavior which may subvert the safety because files are set read only
to prevent overwrite. On the other hand the user knows which files should be overwritten. The option -r
includes -w
.
copy -n-w-r path/to/source.ext dst/path/name.ext
The arguments for copy are textvalues
Use "path/with special;chars"
, you can build a path with a <:>textexpression with <&values><.>
.
The copy command does only copy files. For copying directory trees use
copydir ...TODO
The move command is a rename if the
move source/File dstdir
The source/File
can be a directory which is moved into the dstdir
. Both arguments are paths as textValue
. Therefore you can write for example:
copy <:>myPath/<&fileNameInVariable>.ext<.> <:><&dstPath>/<&fileNameInVariable>.ext<.>
using variables. The copy operation copied directory trees if it is given.
Check of file properties
To check file properties the capability of the class javadoc-oracle/java.io.File can be used. A file object can be build with:
Obj myFile = File:name.ext;
whereby name.ext
is a textValue. It builds the File with the given path inside the currdir
of the JZtxtcmd environment.
It is possible or proper to build the File object only temporary, in conclusion with the check operation:
if(File:"path/to/file.ext".exists()) { ... }
In this case the name of the file is written in ""
because the following .exists()
method should be separated from the name. Of course it is a syntax error if you write if(File:path/to/file.ext.exists()) ...
because .exists
is recogized as part of the file name (extension) and the following ()
are unexpected.
Like usual for a textValue
the file can be build with:
File:&variableContainsPath File:&dataAccess.to.javadata File:<:><&basepath>/to/<&name>.ext<.>
Topic:.JZtxtcmd.statements.call.
Sub routines are parts of a JZtxtcmd script, see 6.5 Subroutines and subtext.
Syntax see 16.18 callSubroutine, callSubtext.
calls a subroutine
call mySubroutine(argname=argvalue);
Writing rules, name of the sub routine:
The Name of the sub routine can be either a constant string value or a value from any location. In the last case the routine is determined by the user's data.
call &theName();
Actual arguments for the subroutine:
The order of the formal arguments and the order of the actual values does not need the same one. The arguments are named both in formal and actual lists (other than in C, Java). It is checked whether corrent names for actual arguments are used and whether all necessary actual arguments are given. Formal arguments can have default values for missing actual arguments.
Be aware that the calculation of actual values may have side effects, depending on their calculation routines. The default value will be calculated
only if it is necessary because the actual arguments are missing,
at the time on calling the sub routine with actual data.
The data environment for calculation of default arguments is the script or the class, not the calling environment.
Because JZtxtcmd is a interpreted execution, it may be possible that the calling environment is used to calculate the actual values. But from static view the calling environment is unknown from the subroutine's head line. Therefore the calling environment is displaced for that operation.
Example:
sub mySubroutine(String arg1="example", Obj arg2 = scriptVar){ <+out><&arg1>, <&arg2><.+n> } ... { //any calling enviroment: Obj scriptVar = xyz; call mySubroutine(arg1="myOtherExample"); }
It is called without actual argument arg2
. Therefore the value for arg2
is calculated on calling time. But the local scriptVar
is not used, instead the script variable with that same name is used.
Type of arguments:
Usual an argument of a sub routine is either a constant or an expression, see 16.10 Object value: objExpr. It may be a simple access to a variable.
An object expression allows some type conversions:
If a java.io.File
object is expected but only the path is given, use
call subroutine(fileArg = File: "path/to/file");
If the filepath is relative then the 7.3 currdir, cd statement is used. It is the same like arguments for invocation of Java methods, see 9.9 Access to Java internal data.
If a Filepath
variable should be build only for the subroutine's argument then the definition can be write directly in the actual argument
list:
call subroutine(pathArg = Filepath: "path:local/file.ext");
It builds a srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdFilepath object on demand as actual argument. The subroutine gets the reference to it. Hint: The filepath does not need to write in
""
if it does not contain spaces and special characters.
Adequate the access to a fileset with a filepath can be written with:
call subroutine(pathArg = Fileset: path:&filesetVariable);
That construct builds a srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdAccessFileset
Hint: On missing variables etc. a runtime error occurs. Because JZtxtcmd is interpretative, it is not possible to check all variables on compile respectively start time. Use 12 onerror - Exceptionhandling to handle such situations.
Return values:
To transport results from the subroutine to outside there are 2 ways:
Use a return object. The return object is map of one or more variables. That is a approach of functional programming.
Add an additional element to a given map of an actual argument.
Both ways can be combined. For the first way the call
-statement is an assignment:
sub testResultRet(String someArgs){ //creates a String variable inside the return Map: String return.text = <:>testResult-return from <&someArgs><.>; String return.anotherOne = "other return value"; } Map result; result = call testResultRet(someArgs = "someArgs");
The return value in this example assigned to result
is a Map which contains all returned variables from the sub routines. It is similar a returned instance of a comprehensive
class type in Java.
To replenish any argument variable one can use the following pattern:
sub testResultSub(Map arg){ String arg.ret = "testResult-replenish"; }
The arg
is a Map of variables, maybe created by
Map map;
or maybe the local variables of the calling level:
call testResultSub(arg=jztcsub.localVariables);
This method is not functionally, not object oriented, but it may be convenient for practice. It is typical for interpretatively execution: The local variables can be replenished by some more stuff.
Topic:.JZtxtcmd.statements..
You can invoke static java methods with arguments:
java org.vishia.util.FileList.list("anyDirectory/path", "*", ".filelist.list");
This example invokes the static method list
of the class org.vishia.util.FileList
with the given textual arguments. The arguments can be build as text expression with <:>expression <&value><.>
, with numeric expressions are with JZtxtcmd variable which are instances of Java data, see 9 Data and variables.
You can create java instances and invoke their non-static methods. Example:
Obj checkDeps = new org.vishia.checkDeps_C.CheckDependencyFile(console, 1); .... test = checkDeps.readDependencies(<:><&objDir>/ccs_dsp_obj<&$PARAM>.deps.txt<.>);
An instance of org.vishia.checkDeps_C.CheckDependencyFile
will be created. After them the method readDependencies(...)
is called.
See
Topic:.JZtxtcmd.statements.zmake.
A Zmake statement is written in form:
zmake output := subroutine(input&fileset, input, parameter=value);
See Syntax: 16.19 Zmake. The subroutine is the translator between some inputs and the output. The output is a file or a directory and extension, where some files should be stored.
For example some files can be zipped. The output is the location of the zip file. The inputs are the files to zip. Another example is: C/C++ compilation (outputs: object files) and linking (output: The executable, maybe some more files in the output directory).
The subroutine contains the statements how to make. It is possible to invoke that commands, which executes the make process. It is possible too to produce a text output which contains the make controlling. The text output file can be a classic make file, an ANT make file, any batch or shell script or any other. The subroutine or some variables can contain some parameter to control the make. For details see Zmake.
The Zmake works with file entities and file sets. See 9.1.13 Filepath, Fileset
The subroutine
is a normal JZtxtcmd sub
routine. The output
and input
are assembled in an instance of srcJava_vishiaBase/org/vishia/cmd/ZmakeTarget which is given as first parameter:
sub subroutine( Obj target :org.vishia.cmd.ZmakeTarget, .....) { ...make target statements }
Example make for one file only whereby the file path is given as absolute path in a environment variable:
zmake <:><&$2>.crefl<.> := genReflection(&$1);
The output file will be build with the input file plus the special extension. The input argument is only the given file path.
Example using a fileset:
Fileset srcSet = ( fileA.c , local/path/fileB.c , otherPath/*.c ##all files of that directory ); zmake "output/path/*.obj" := ccCompile("access/path": &srcSet, argument="arg_value"); zmake "output/path/*.obj" := ccCompile(access/path:&srcSet, argument="arg_value");
The zmake routine can decide which parts from the output is used for any file. For example the output files can be build with
the directory of output and the extension, and the names or local pathes without extension from the input files. The &
is the separator between a access path and the name of the set. The access path can be empty, an text expression or a dataAccess.
The :
on end of access path marks, that the access path acts as base path for the files of the set. If the accessPath contains
a :
than the localPath starts there if the paths in the Fileset don't contain an localPath part. Especially .:&fileset
means, the accessPath starts from the current directory and the paths of the Fileset are the local ones. Note: .
is the current directory. Another example: ../../access/path:&fileset
. It is a good style if the Fileset does name the local paths only. Too see variants with the localPath in Fileset and usage
of parts of the filePath see the example in the zbnf.zip download
The zmake routine takes arguments in the same way like any other subroutine, see 7.5 call: Invocation of sub routines. The no named argument is a target input. It consists of two parts: The accessPath and the access to the Fileset. The access
to Fileset is written right after a &
. The accessPath can be omitted or given as "string"
, as & <dataAccess>
or as chars till &
without quotes. If the accessPath is given as & <dataAccess>
, the distinction between a singulary access path as data Access and the & <dataAccess?zmakeFilesetVariable>
is done with test of the accessed instance. It is checked whether it is a Fileset or not.
The given accessPath is converted to a String if it is accessed via & <dataAccess>
. The String-given accessPath is converted to a srcJava_vishiaBase/org/vishia/util/FilePath. In that constructor the String is divided especially into the local path and the base path, separated by the character ':'.
ZBNF/examples_JZtxtcmd/TestAll/testFileset.JZtxt.bat
Topic:.JZtxtcmd.statements.expr.
An Expression maybe a simple access to data, but it is an execution of methods/routines often. The execution may be seen as side effect of the assignment, but it may be the originally approach and the assignment may be the secondary one. It is like in normal programming languages.
Assignments see 9.1 Types of variables and their assignment, its syntax: 16.21 Assignment to variables
Expressions see Chapter: 10 Expressions, its syntax: 16.10 Object value: objExpr
Text expressions see 13 Text output and text generation, its syntax: 16.9 Text value: textDatapath, textValue
Topic:.JZtxtcmd.if.
Syntax see 16.16 Control statements.
Topic:.JZtxtcmd.if.if.
One can write
if(condition){ statements; } elseif(otherCondition){ statements; } else { statements; }
All program flow control statements can be nested, of course. The { }
are necessary, other than in C, Java.
The elsif
is the same like else if
which is possible in Java, C etc. also. It is a chain of if. elsif
and else
are optional.
The condition is a 10.5 Boolean expression, Conditions. If the condition is a datapath only, it is false if the path is faulty.
Topic:.JZtxtcmd.if.while.
One can write
while(condition) { statements; }
to execute statemens so long as the condition is true.
do { statements; } while(condition);
checks after the loop body.
Topic:.JZtxtcmd.if.for.
The JZtxtcmd does support the iteration over a container and execute statements with the current element. The old-style for loop known from other programming languages is not supported. If such one is necessary, it is able to execute it with while(...)
instead. The old style for loop is imagined for indexed access to arrays usually. The for-container iteration is also known
in other modern programming languages. One can write
for(element: datapath.container){ statements ...; }
The statements were executed for each element in the container. The element on each loop referred by the variable
, can (should) be used inside the statements.
Condition in for:
Additionally there is a possibility to leave the for-loop. One should write:
for(element:container && condition){ .... }
If the condition is false the for-loop is left. For example an element can be searched in the container. Write:
Obj found; for(element:container && not found){ if(element.attribute == expected){ found = element; } }
Iteration variable can be used after a broken loop:
Since 2016-02: The iteration variable (element of the container) is created with this for loop. It is existing in the following
statements after the for furthermore (rather than in Java, there it is a local variable of the for loop only). But if the
for-loop is executed till its end, the iteration variable is null
. Only if the for-loop was broken either by a condition or by a break statement, the iteration variable remains the last used
container value. This can be used especially for searching an element in a container. The iteration variable is set before
the condition is checked. Therefore it is possible to use the iteration variable in the condition too. To search an element
is is shorter to write:
for(element:container && element.attribute != expected); //use element in further statements //it contains that value where the condition was false, //in this case: ,,element.attribute == expected,,. if(element) { ... //The element where the for loop was broken. }
check if the container has a next element <:hasNext>:
Especially for text generation there is a possibility to quest whether a next element exists after the current one. Often things should be separated by a colon etc, but the colon should not be written after the last element. Write:
for(element: container) { <+textOutput><&element.value><:hasNext>, <.hasNext><.+> }
then the elements are separated with , but after the last element there is no ,.
The same operation in a text:
<+textOutput><:for:element:container><&element.value><:hasNext>, <.hasNext><.for><.+>
Implementation in Java, container types are Iterable, Map or an array:
The container is any javadoc-oracle/java/lang/Iterable, a javadoc-oracle/java/util/Map or any array in Java. A Map
is iterated by its entrySet()
, the elements are the value of the entries.
Topic:.JZtxtcmd.if.break.
break
is admissible only in a statement block of a loop (for
, while
) and in an onerror
block.
If a break
is contained in a loop's statement block, the statement block and the loop is broken. It is like other programming languages
Java, C etc.
If a break
is written inside an onerror
block, the enclosing block will be broken. It is a feature of 12 onerror - Exceptionhandling.
return
aborts the current subroutine. Don't confuse it with a return
variable, see Chapter: 6.5 Subroutines and subtext
exit
aborts the whole script.
throw
aborts all blocks till a proper onerror
is found.
Don't use return except in an onerror
block:
A subroutine ends on its last statement. The only exception of this rule should be: An exception has occurred inside the subroutine.
A conditional return
inside a subroutine is not recommended, it is a bad style. The reason for that is: A return inside a lot of statements can
lose sight. The algorithm inside a sub routine should be strongly structured. Note the following example:
With return inside (for example in Java);
void mySub(){ ObjType foundObj; anyContainer.anyOpenAction(); while(anyContainer.hasNext()){ ObjType obj = container.next(); if(obj.hasExpectedProperties){ anyContainer.anyCloseAction(); do something... return; } } anyContainer.anyCloseAction(); <+out>not found.<.+n>; }
Something is searched in a while loop. If it is found, the evaluation is done in a if-branch inside the while, with return inside.
Without return, code of JZtxtcmd:
The while loop has the task to search only. It is finished if foundObj is set. That is visible in the while condition.
The condition whether something was found or not is done after the searching process, obvious visible in the straight forward thread of the subroutine.
Any neccessary close or finishing operation for the container handling is only programmed one time, after the container-handling while loop.
The decision between found or not found - thats the question here - is clearly visible in the if - else statement.
sub mySub(){ Obj foundObj; anyContainer.anyOpenAction(); while(foundObj ==null && anyContainer.hasNext()){ Obj obj = container.next(); if(obj.hasExpectedProperties){ foundObj = obj; } } anyContainer.anyCloseAction(); if(foundObj){ do something... } else { <+out>not found.<.+n>; } }
Of course, the algorithm without return inside needs the second if-condition. It may be more expensive for calculation time. But that is minimal. In fast algorithm with slow processors (C programming for embedded) a return inside may be proper, because calculation time. But for complex algorithm in fast execution environments the return inside is not necessary, and a less proper style for programming.
Don't use break in loops:
A conditional break
in a loop is not recommended. It is a bad style. The reason for that is: A break
inside the loop's statements can lose sight. The condition to whether continue a loop should be able to seen only in the
loop's head statement. Note the following example:
Obj found; Obj myIterator = myList.iterator(); while(!found && myIterator.hasNext()){ Obj element = myIterator.next(); <+out><&element><.+n> if(element.equals("test2")){ found = element; } }
One of the condition to continue the loop is !found
, the other one is myIterator.hasNext()
- some more elements exists. That both conditions are able to see in the while(...)
-line. Thats all. If the algorithm has a break
:
Obj found; Obj myIterator = myList.iterator(); while(myIterator.hasNext()){ Obj element = myIterator.next(); <+out><&element><.+n> if(element.equals("test2")){ found = element; break; } }
- the break is not seen if the while(...)
is checked.
The possibility for break
in loops and return
in subroutines in JZtxtcmd is a concession for widely used styles only. But the break inside an ..onerror block is necessary to abort further execution after the
onerror-block.
Topic:.JZtxtcmd.data.
A JZtxtcmd script can have script variables and local variables in sub routines. (future extension: class variables). Another possibility is getting and storing values from/to any Java instances.
Topic:.JZtxtcmd.data.type.
A JZtxtcmd variable is a reference to the data. There are a few types:
Topic:.JZtxtcmd.data.type.Num.
A numerical variable is presented by a integer or float (double) value. It is calculated using 10.6 Numeric Expression and presented by an Object of type srcJava_vishiaBase/org/vishia/util/CalculatorExpr.Value.
Num value = 5.0; ##initialize a double value Num val1 = 0x124; ##initialize a int value from hex form. Num val2 = stringValue;
A stringValue will be converted to a numeric equivalent. Depending on the string value it will be stored as long, integer, float or double. (since 2018-09)
Topic:.JZtxtcmd.data.type..
It is a boolean value or a condition, set to true
or false
. It is presented by an Object of type javadoc-oracle/java/lang/Boolean. Note that on definition of a Bool variable one can write
Bool myBool = a > 5;
whereby on assignment one should write:
myBool = bool(a > 5);
The reason for that difference is: The translator of the script (parser) does not recognize the type of a variable on assignment.
To accept a boolean expression the bool(...)
is necessary. It may be a good style because the reader of the script sees that it is a boolean assignment.
Note that the test of existence of a variable path can be written with a simple boolean assignment:
Bool myPathexists = path/to/variable; //false if path is faulty. myPathExists = bool(path/to/variable); myPathExists = path/to/variable;
In this case both variants to write are accepted, with or without bool(...)
because syntactical it is not necessary, The execution evaluates an boolean expression anytime with the feature of false
on a non existing path instead of an exception.
Topic:.JZtxtcmd.data.type.String.
A String
: refers a constant text.
The text can be built with any text expression. A String variable can change its content. But the string gotten from a String variable before changing will be never changed. It is the same like a String in Java.
String myString = "text"; String mySecond = myString; //refers text myString = "other text"; //mySecond remain unchanged!
For text expressions see the syntax in 16.9 Text value: textDatapath, textValue
Topic:.JZtxtcmd.data.type.Stringjar.
A Stringjar
references a srcJava_vishiaBase/org/vishia/util/StringPartAppend. It contains a javadoc-oracle/java/lang/StringBuilder which is used as Appendable. This class has all features of srcJava_vishiaBase/org/vishia/util/StringPartScan and srcJava_vishiaBase/org/vishia/util/StringPart. With that it is possible to Append or store any text and analyze it after them or while appending. Additional a remove method
is included to remove parts of texts which are not need furthermore.
One can append using
Stringjar myBuffer; //a new empty buffer Stringjar myBuffer = "start text"; //a new buffer with intial text myBuffer += " appended text"; //append
The +=
operation symbol for the assignment is the append symbol. A =
assigns a new start text.
One can search any text in the Stringjar. The access to a Stringjar reads the current visible part. Additionally one can use the javadoc-oracle/java/lang/StringBuilder-methods with the stringBuilder()-method. For example:
myBuffer.stringBuilder().insert(myPosition, "a inserted text").
The instruction
myBuffer = "new Text"
does not create a new Stringjar Object (not like in Java) but initialize the given object with this new value. If a reference
Obj myBuffer2 = myBuffer;
was build before, the value of myBuffer2 is changed too because it is the same reference. But if is defined
Stringjar myBuffer2 = myBuffer;
then a new Instance of a Stringjar is created with initial value of the content of myBuffer
.
Note that the javadoc-oracle/java/lang/StringBuilder is not threadsafe. A StringBuffer
is threadsafe but slower. Since the Java version 5 the StringBuffer can be replaced by using the java-StringBuilder
with exact the same capabilities, but without synchronized-Mechanism. It is more fast. The major of applications don't need
the thread-safe property because the StringBuffer will be filled and changed usual in one thread. If it is necessary to handle
a StringBuilder in more as one threads, in Java synchronized
mechanism can be used. A JZtxtcmd script should not encouraged to handle with data in threads complexly. Fill in one thread,
evaluate after them in another thread. Therefore the usage of StringBuilder is proper.
Topic:.JZtxtcmd.data.type.Obj.
Obj
is any Object, any Java instance.
It is possible to create a Java instance or get any instance from a Java context:
Obj myObj = new org.myPackage.MyClass(args); myObj = otherInstance.method_whichReturnsAnObject(args); myObj = java org.myPackage.MyClass.myStaticMethod(args);
With this java instance any action can be done:
myObj.method();
Or the object can be added to a container to use it in a for loop.
myList.add(myObj);
The reference to the Java instance should be removed if the instance is not used any more. The garbage collector of the Java Runtime Environment will removed it:
myObj = null;
Topic:.JZtxtcmd.data.type.Pipe.
Pipe
: reference to a srcJava_vishiaBase/org/vishia/util/PipeRingBuffer, an Appendable.
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.
Topic:.JZtxtcmd.data.type.List.
List
is an instance which implements the javadoc-oracle/java/util/List interface.
It is able to use as container in a for-statement. A
List myList; myList += anyObjectExpression
creates an empty list and adds an Object.
myList += anotherList;
If the added object is a java/util/List
-container too, its elements are added.
myList.clear();
clears the list. One can use all methods of the List interface.
Building of container with List:
A List (an instance which implements the javadoc-oracle/java/util/List interface) is a container, able to use in a JZtxtcmd-for loop, see 8.3 for(container)....
The List can be built and used in the following way:
Any List from Java data can be assigned and evaluated in the JZtxtcmd script.
A List can be used with +=
to append data, it builds a new content of the container.
A List can be defined as const container.
The last one possibility is proper to set some data, then evaluate something with this settings.
A list can be defined with constant texts:
List myList = [ "ab", "cd", "xyz" ];
The [...]
are the brackets for the container. The items of the container are separated with comma.
Another form of such a container is a Container which contains variables:
List list2 = [ String var1 = "ab"; String var2 = "cd"; ];
An advantage in opposite to the simple Strings is: The Strings have names. It is possible to evaluate:
for(var: list2) { <+><&var.name>, <.+> } <+><.+n> for(var: list2) { <+><&var.value>, <.+> }
This outputs the names in the first line and the values in the second line.
A List can be build by a Subtext
variable:
List listSubtext = [ Subtext item1 = <:>Use the content of <&otherVariable><.>; Subtext item2 = "constant text"; ];
For evaluating that container it can be written:
String otherVariable = "content"; for(var: listSubtext) { <+><&var.name>, <.+> } <+><.+n> for(var: listSubtext) { <+><&var>, <.+> }
In this case the <&var>
contains a Subtext
, therefore the content is evaluated now in the given context. It means the variable with name otherVariable
is found in the Subtext
and its content is used in the for loop.
Another form of a List container can be built like:
List variationParameter = [ { name="hi", Rfault="10.0", Lfault = "0.1", descr="High impedance fault" } , { name="mid", Rfault="0.2", Lfault = "0.1", descr="Middle impedance fault" } , { name="low", Rfault="0.1", Lfault = "0.1", descr="Low impedance fault" } ];
This list contains a Map
of String variables. Now the combination is interesting. A loop of all variations is build, the loop uses the listSubtext
:
List cellcontent = [ Subtext cell1 = <:>Rfault = <¶meter.Rfault><.>; [ Subtext cell2 = <:>Lfault = <¶meter.Lfault><.>; String cell3 = "constant text"; ]; ##Builds a line with the names: ## for(var: listSubtext) { <+><&var.name>, <.+> } <+><.+n> ##Builds some lines with values: ## for(parameter: variationParameter) { for(cell: cellContent) { <+outs><&cell>, <.+> } <+outs><.+n> }
This builds a file with 4 lines for the names and the 3 variations with a content which is defined on the Subtext cell1
etc.
Topic:.JZtxtcmd.data.type.Map.
A Map
is an instance which implements the javadoc-oracle/java/util/Map interface.
It is able to use as container in a for-statement.
A map is able to use especially to store variables:
Map myContainer; String myContainer.anyVariable = "text"; //defines a String variable inside that Map
The variable is stored in the map and can be gotten by myContainer.anyVariable
. This can be used to provide the variable container for sub routines too:
sub mysubroutine(Map data) { String data.myNewVariable = "value"; } ..... call mysubroutine(data=myContainer); <+out><&myContainer.myNewVariable><.+n>;
A Map is build if a dataStruct is created writing (see also Chapter: 10.4 Object expression):
Map dataStruct = { String text = "value"; List anyOther = something; };
or if such an construct is used in an argument list:
myData.myJavaMethod({ String cmd1 = "cmd"; String data = anydata; }, furtherArg);
In this case the method gets an argument of type Map which contains that two elements.
One can use all methods of the java.lang.Map interface especially
myMap.clear(); myMap.put("name", value);
The value can be accessed though it is not a Variable with
Obj value = myMap.name Obj value = myMap.get("name");
Topic:.JZtxtcmd.data.type.Subtextvar.
A Subtext
is a variable which contains a srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdScript.Subroutine to build a text. It is a subroutine stored in a variable, similar like a function pointer in C-programming.
Subtextvar myStatements = <.>constant text and <&variable><.>; Subtextvar myParametrizedStatements(String textArg) = <:>uses only <&textArg><.>;
A static subtext as script part is slightly different:
subtext mySubtext(String textArg) = <:>uses only <&textArg><.>;
Syntactically only the keyword subtext
against Subtextvar
is different. But a Subtextvar
is a variable which can be a part of a List
or Map
, can be used as argument or stored in another Obj
variable. mySubtext
is not a variable but the name of a static subtext. The name can be stored as String: String theSubtext = "mySubtext";
; this String can be used as argument to invoke different subtext
s writing <:subtext:&theSubtext:args>
. Dealing with that subtext names it is possible too to dynamic the invocation of subtexts - but using a Subtextvar
may be more simple in some cases.
The statements of a Subtextvar are executed either if the value of the variable is used in an access to &myStatements
, or with a <:subtext:...>
in a text expression:
String myValue = <&myStatements>; <+>textExpression invokes <:subtext:&myParametrizedStatements:textArg="my textArg"> but it can invoke <:subtext:&myStatements> without arguments too...<.+>
It is for a simple application without arguments in the current execution environment, and for a exactly application like any other subroutine respectively subtext with its own execution environment and arguments. The argumentless variant is adequate
Subtextvar myStatemens(use-local) = <.>...<:>
see &chapter, arguments and local variables. For this variant the execution environment is the current context. For example:
String variable = "Example"; <:>Any text uses <&myStatements>. <.>
The execution of the text expression finds the variable myStatements
, detects that it contains statements, and exucutes it with the given context where the variable
is known. Therewith the following text is produced:
Any text uses constant text and Example.
See 9.1.7 List - a List of values to see how some Subtext in a List container are used.
A Subtext variable can be used as actual and formal argument for a subroutine, maybe stored, used for a callback-mechanism. It can be used in a call statement too.
If some Subtext
are contained in a map and get from there, you should store it in an Obj
variable temporary because the map.get(key)
-statement can only return an Obj
. See 9.1.8 Map - a Set of variables. For example:
Map accesses = { Subtextvar int(String name) = <:>super.getInt32(k_<&name>)<.>; Subtextvar char(String name) = <:>super.getChar(k_<&name>)<.>; Subtextvar int16(String name) = <:>super.getInt16(k_<&name>)<.>; Subtextvar float(String name) = <:>super.getFloat(k_<&name>)<.>; Subtextvar double(String name) = <:>super.getDouble(k_<&name>)<.>; };
This is from Cheader2JavaByteDataAccess.jztc
. The map was build to find a type from C-programming, int16
etc. To find the proper Subtextvar
with a given C-type, it is programmed:
Obj accessRtn = accesses.get(attrib.type.name);
The Obj
contains the gotten access routine after the access. To execute it:
<+javaSrc> return <:subtext:&accessRtn:name=&attrib.name><.+>
The Obj which is typeof org.vishia.JZtxtcmdScript.Subroutine
is taken as subtext argument and executed therewith with the given further arguments.
Topic:.JZtxtcmd.data.type.Class.
A Class variable is created with
Class myClass = path.to.MyClass; Class myInnerClass = path.to.MyClass$InnerClass;
Whereby path.to.MyClass
is a java package path. The named javadoc-oracle/java/lang/Class object will be stored in the myClass
variable.
A Class can be defined in a specific jar-file or any file location which needs a specific javadoc-oracle/java/lang/ClassLoader-instance. Such can be stored in a Classpath-variable or it can be accessed via any data.path. Using that one can write:
Classpath classLoader = "D:/The/specific/jarfile.jar"; Class myClass = : classLoader : path.to.MyClass;
A Class variable can be used to access static fields and call of methods or to create an instance of the class:
myClass.aStaticMethod(args); ##calls it. <:>A text <&myClass.staticMethodText(args)> ...<.> Obj aObj = java new &myClass:(args); ## creates an Object
Using a Class
variable is a short form to invoke:
java path.to.MyClass.aStaticMethod(args); ## without Class variable
A benefit using a Class
variable in opposite to the last example is: If the path is wrong, an exception is thrown on definition of the Class
variable already.
To check whether any Object is instanceof the expected type, write
if(myObj ?instanceof myClass) { ....
The check returns true if the object is derived from the myClass
or implements the given myClass
-interface of course. See 10.5 Boolean expression, Conditions
Topic:.JZtxtcmd.data.type.Classpath.
A Classpath
-variable holds a ClassLoader-instance. The javadoc-oracle/java/lang/ClassLoader in a Java environment is responsible to load classes from any jar-file or other location and translating it into internal
machince code. If the JZtxtcmd script application needs other classes than given in the classpath of the java invocation,
the Classpath should be used:
Command line to invoke JZtxtcmd. Only the Zbnf.jar is given usual:
java -cp path/to/Zbnf.jar myScript.jztc
Inside the script, an additonal jar file should be used:
Classpath loader = path/to/additonal.jar; java :loader: package.path.Userclass.main();
The example shows the invocation of the main-routine of any class, which is located in the additonal.jar
.
A javadoc-oracle/java/lang/ClassLoader can know more as one jar files (and other sources of class code). It is possible to build a:
Fileset jarfiles = ( path/jar1.jar , path2/jar2.jar ); Classpath loader = path/to&jarfiles, D:/any/other/file.jar;
This example shows a Fileset
, describing some jar files which are located in the same pool. The path/to
is the common path of both. Additinal D:/any/other/file.jar
is addressed. All three jar files are given with this ClassLoader instance.
One can give absolute paths to the files or relative ones. Relative paths are regarded to the current currdir
directory. Usual it is set relative to the scriptdir
where the main script is located:
currdir = scriptdir; Classpath loader = relative/to/currdir/myjar.jar;
The other possibility is, relativ to the maybe included script:
Classpath loader = <:><:scriptdir>/path/myjar.jar<.>;
A Classpath
variable can be used especially to create a Class-Variable.
Topic:.JZtxtcmd.data.type.Openfile.
It opens a file for writing on creation. It is a javadoc-oracle/java/io/Writer and an Appendable.
Openfile myFile = "filename"; myFile += "any text"; myFile.flush(); myFile.close();
The filename can be built as text expression, of course. It have to be supplied on the definition statement.
String name = ...from any procedure; Openfile myFile = <:><&name>.txt<.>;
It is recommended to close the file. Elsewhere the file remain open till the process, which executes the JZtxtcmd interpreter is finished on the operation system. If it is a long-running process, the file will remain open.
To provide an Openfile
to another subroutine, an Obj
should be used. The Openfile
keyword can only be used for create and opening a Writer
instance. It is an Obj
:
call mySub( myFile = myFile); ... sub mySub(Obj myFile) { <+myFile>output anything<.+n>
The <+append>
accepts formally any Obj but expects that it is an Appendable.
Topic:.JZtxtcmd.data.type.fileset.
See examples_Fileset.
Syntax see 16.8 Fileset, Filepath.
A Filepath
is a String-given path which describes a file or maybe some files with wildcards. The parts of a Filepath are divide to drive,
directory path. local path, name, extension and some designations for wildcards usage. From a Filepath several Strings can
be build.
See srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdFilepath: Instance which is used in JZtxtcmd for Filepath
See srcJava_vishiaBase/org/vishia/util/FilePath: Core instance which implements the Filepath
with its access methods.
name() namext() ext()
: The file name, the extension or name.ext
basepath()
: The path before a :
, before the localfile()
absfile() absdir() absname() absbasepath()
: builds an normalized absolute path with the current directory of the context.
localfile() localdir() localname()
: local path parts.
fileW()
etc: All methods which returns paths are existing with suffix 'W'. That methods return a backslash as separator (W=Windows)
where the methods without W returns a slash as separator. Note that all path which are used in a Java context can be written
both with slash or backslash in a MS-Windows-context. The usage of slash is recommended, it is the compatible form. Only if
a text should be generated for windows processing, especially a bat-file, one should use the 'W'-variant.
localfile():
As a special feature a :
can be used as separation between the path and a local part of the path:
Filepath myPath = "D:/the/path:local/path/file.ext";
A Filepath can be written relative or absolute. A relative path can be associated to different base directory locations in its usage in the script. There are methods to build the file String using an access path or a common-path:
myPath.file(Appendable, commonpath, accesspath)
adds the filepath to the appendable regarding a commonpath and a accesspath. For example:
Filepath commonpath = mydocs; Filepath accesspath = D:/data; Filepath thefile = docA/fileX.doc; Stringjar buffer; thefile.fileW(buffer,commonpath, accesspath);
fills the buffer with D:\data\mydocs\docA\fileX.doc
. The commonpath and the accesspath can be parameters of a subroutine and can be set for example in an included script. The
file which should be handled is docA/fileX.doc
. The other Filepath variables determines where this file will be located. The commonpath
is an additional feature for common base paths. Usual only the accesspath
is a point of interest:
Wildcards in a Filepath:
One can write a single *
one time in any name of a path, maybe in a directory part too. Then all matching directories respectively files are used.
One can write a /**/
as directory in the path. That means all sub directories in any tree depth are matching:
mydir/**/*.obj
addresses all object files in any sub directory level from mydir
.
my*dirs/test*/*
addresses all files in directories which starts with my
end ends with dirs
, then in all directories which starts with test
and there all files.
The method
myFilepath.expandFiles(listToAdd, commonPath, accessPath, currdir)
builds Filepath instances for all found files and adds it to the given list.
Variable in a Filepath:
A Filepath can start with any JZtxtcmd variable. In the Filepath the variable is designated with an &
. Then the Filepath starts with &
. On evaluation the path the content of the variable is used. Usual the variable is a filepath too, which contains the start
directory of files. This feature increases the flexibility while using FilePaths:
Filepath whichDocu = docA; Fileset docuFiles = ( &whichDocu/fileX.doc, &whichDocu/fileY.doc);
This two statements can be written in different files, one may be included.
Usage of &$
gets an environment variable:
Filepath tmpfile = &$TMP/tmpfile.txt;
Build Strings from file entities:
The following table presents all methods to build Strings from a file entity:
Path designation:
abs...
: Absolute path
local...
: Local path
Elsewhere the path like written in the fileset and its access: Either the given absolute path, or the given path with the access path.
Part designation:
basepath
: The base path if exists, or an ".
" respectively the root directory if it is not defined.
dir
: The directory, absolute, local or like given
pathname
: The file with path but without the extension, absolute, local or like given
file
: The file with path and extension, absolute, local or like given
name
The name only.
ext
The extension only.
windows or slash designation:
All methods except name()
and ext()
are available with an ending W
. This produces backslashs in the path. Elsewhere slashes are produced.
With that the following combinations exists as methods:
absolute |
base_local |
like given |
only local |
abs-backslash |
like given |
local |
absbasepath() |
basepath() |
absbasepathW() |
basepathW() |
|||
absdir() |
base_localdir() |
dir() |
localdir() |
absdirW() |
dirW() |
localdirW() |
absname() |
pathname() |
localname() |
absnameW() |
pathnameW() |
localnameW() |
|
absfile() |
base_localfile() |
file() |
localfile() |
absfileW() |
fileW() |
localfileW() |
name() |
||||||
namext() |
||||||
ext() |
absolute builds an absolute path maybe with the given $chapter if the path is given relative.
base_local returns the basepath and the localpath separated by the colon.
like given returns either an absolute path if it is given in this form or a relative path.
only local returns the local part.
Examples using several configurations of Filepath and Fileset are contained in the Zbnf-Download examples_JZtxtcmd/HandleSomeFiles
.
Fileset:
A Fileset
contains one or more Filepath, it names files:
Fileset myset = ( file1.ext, path/file2.ext, "base path:local/**/file 3.*");
The **
means any directory tree depth. Wildcards can be used in directory names too. One can use slash or backslash as directory
separator. The slash is recommended.
See srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdFileset.
One can build a list of Filepath
with the method
List files = myset.listFiles();
Then all files from the set are presented in that list. If you invoke:
List files = myset.listFilesExpanded();
then all files with wildcards are expanded to the real existing files of the moment of execution. This method accesses the file system.
Since 2017-09: A Fileset can include another Fileset:
FileSet set2 = ( &myset, file2.ext, .....);
On listFiles()
or listFilesExpanded()
this sub Fileset is recognized, unpacked and included.
Using of Fileset in zmake:
zmake supports file sets because most of operation of zmake deals with files. One can write:
zmake myOutput/file.ext := makeroutine(path/sub & fileset);
whereby fileset
is a name of a Fileset
. path/sub
is the access path to the Fileset.
Usual the access path should be a base path and the files of the Fileset describe a local path. Then one should write:
zmake myOutput/file.ext := makeroutine(path/sub: & fileset);
The colon as last character of the Filepath of the access path defines path/sub
as base path.
The access path can be a variable, because a Filepath
can be build with a variable:
zmake myOutput/file.ext := makeroutine(&filepath:&fileset);
In this case the filepath.file()
builds the access path as base path.
Relation between base path and local path:
Especially if a Fileset
is used with an access path, then the following rules are valid:
If the Filepath
of the access path contains a local path, then it is used as local one. The base part is the base part of the access path.
If the Filepath
of the access path does not contain a local path, then the whole access path is the base path.
View the following examples:
Fileset fileset = (localpath/myFile, otherpath/file2.ext); zmake output1 := routine1(base:local&fileset); zmake output2 := routine2(path&fileset);
base:local
respectively path
is the access Filepath for the Fileset.
routine2
uses path
as base path, routine1
use local/
from the access variable as part of the local path.
If a Filepath contains a scriptVariable, the scriptVariable will be handled in an adequate way:
Filepath path1 = base:local; Filepath path2 = path2; Filepath path1a = &path1/file.ext; Filepath path2a = &path2/file.ext; Filepath path1b = &path1:file.ext; Filepath path2b = &path2:file.ext;
The resulting is
path1a = base:local/file.ext; path2a = path2/file.ext; path1b = base/local:file.ext; path2b = path2:file.ext;
See examples_Fileset.
Topic:.JZtxtcmd.data.type.set.
It sets environment variables for the next 7.2 start, cmd: Invocation of operation system commands.
set name = value
The environment variable is stored in the variable context with $
as prefix for its identifier. One cannot change the value of an environment variable, but the variable is possible to set
newly:
Set env = "value"; cmd anyCmd; Set env = <:>other value<.>; cmd otherCmd;
set
and SET
does the same like Set
.
Topic:.JZtxtcmd.data.path.
A variable of the script or subroutine level may contain a simple value or text. On the other hand
a variable can refer any Java instance, which has internal data and methods.
a variable can refer a Map<String, Object>.
In the first case a JZtxtcmd variable can contain a reference to any Java instance. The attributes, references and methods of that instance can be accessed.
In the second case the Map refers other data by its name. It builds a tree of data.
In JZtxtcmd it is possible to build a datapath to address data. The syntax is described in 16.11 DataPath, Data access.
jztc.startmilli
is the path from the predefined variable jztc
which refers the instance of JZtxtcmdExecuter to the data field srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.JZtxtcmd#startmilli.
In a Datapath methods can be invoked. For example the current directory as String with Slash (unified) can be gotten with
jztcsub.currdir()
A method can be called with actual arguments. The next example creates a user specific object and invokes a method from it. That is inclusion of Java classes pure:
Obj myObj = new mypackage.MyClass(); myObj.myMethod(5, "a string", jztcsub.currdir());
The fields and methods from any instance are found and accessed via the reflection mechanism of Java. The translator of the
JZtxtcmd-script has not any knowledge of the objects and there elements. It means the translator cannot detect errors, other
then a Java compiler. It is a property of script languages in opposite to static languages. Errors in access are detect on
runtime via an exception, which can be catched with an onerror
statement in the JZtxtcmd script:
anyObj.reference.method(parameter); anyOther.datapath = value; onerror { <+out>Access error in script: <&error><.+n> }
A script should be checked by running all branches of software. Therewith all data paths should be checked on runtime. If a branch is not tested the a probably usefully message should be outputted.
Access to private fields and methods:
The flag
jztc.bAccessPrivate = 1;
can be set in the script. Then the datapath can access private and protected elements of a class members just as well public ones. Note that the private and protected encapsulation is forehand a property of the compilation and source dependencies. A debugger can access private members to show there content of course. Therefore it may nice to access them in a JZtxtcmd script too. But a software, including the JZtxtcmd script software should not presume the existence of the private members. Private and protected elements are not public, therefore they can be changed and removed in the software life time cycle without consultation of all assumedly users.
Syntax and implementation:
The access via datapath is implemented in the class srcJava_vishiaBase/org/vishia/util/DataAccess.
For the syntax of a datapath in a JZtxtcmd script see 16.11 DataPath, Data access
Predefined script and subroutine variable are described in 9.5 Predefined script variables
Topic:.JZtxtcmd.data.defcontext.
A JZtxtcmd script knows scriptvariable, see 6.1 Script variables. They are defined at script level and contained in the script datapool. The other possibility is the class level (future extension) or the level of the routine with the local datapool.
Local variables in subroutines:
Variable which are defined inside sub routines are local valid, usual known from all static programming languages. But Variable which are defined in inner statement blocks are defined for the subroutine level, other than in static programming languages. This feature saves calculation time for nested blocks because the variable should not be copied for any inner block. Often inner blocks does not define variables, then this feature does not matter. But respect:
sub anySubroutine(String arg) { if(condition) { String s2 = arg; } else { String s2 = "other"; } <+out>result= <&s2><.+> }
It is possible to define a variable conditionally, and evaluate outside of the conditions. If the variable is not defined
on evaluating time, an exception is thrown or false
is returned:
sub anySubroutine() { if(condition) { String s2 = arg; } if(s2) { //only if s2 is existing <+out>result= <&s2><.+> } }
For checking the existence of a datapath see10.5 Boolean expression, Conditions.
On comparison with static languages it is:
void aC_function(char const* arg) { char const* s2; //defined but not set. if(condition){ s2 = arg; } else { s2 = "other"; } ... }
The C/C++ or Java language needs the declaration of the variable outside the nested statement block but the assignment can be done inside. There may be the adequate effect: an undefined variable. But the Java compiler detects this situation on compiletime (other than C), the JZtxtcmd script execution detects it on run time only.
Note that the last value of an element of a
for(element: container){ //... } <+out>last element:<&element><-+>
is existing outside of the for loop because that behaviour. Other than in static languages. In case of doubt you should not use that property. Use the policies of static language for a well program structure. But you can use that behaviour if it is gainful for your solution.
Tree of variable definition, build structures:
It is possible to define a tree of variables. A variable acts at tree root, some variables are defined below that root, that
variables can act as tree root too. A treelike structure of variable offers a struct definition of data. It is possible to
use the root variable of a tree or any of its boughs as argument of a subroutine. Then the subroutine knows all data of that
bough. Note that it is another concept of structuring data than in C with a struct
definition.
The writing rule for definition a variable inside a tree is:
Obj myContainer.insideContainer.newObjvariable;
That defines the myContainer
if not existing yet, inside the deeper level insideContainer
and then the Object Variable with name newObjVariable
.
It is possibile to deal with myContainer
for example to supply it to a sub routine call. The sub routine gets the content of this container and can define inside
more variables:
sub mySub(Obj container){ String container.myStringInSub = "anyText"; } ... call mySub(container = myContainer);
This possibility builds data structures in form of variables in a pool. The container is a Map<String, DataAccess.Variable>
with the given name of the variable.
It is possible too to create a variable in this kind in a existing user level Java instance:
Obj myJavaObj = anyOtherAccess.getJavaObject(); //gets the reference in the given context String myJavaObj.container.newString = "xxx"; //creates a String Variable in the users instance.
With them in the Java programming level that data can be used:
myJavaObj.doAnything(); //invokes a method of the Java instance.
A simple variable without dot or the start variable will be created in the datapool of the context, either in the script,
or at class level or as local variable of the routine. Because a subroutine has its local datapool, the script variables are
never destroyed. A defined variable in a sub routine with the same name like a script variable covers the script variable.
This is a well used effect if necessarry. The created variable is a instance of type srcJava_vishiaBase/org/vishia/util/DataAccess.Variable. This instance contains the name, the type, the const designation and an Object reference to the value. The datapool is a
Map<String, DataAccess.Variable>
with the name as key.
If a variable is existing already, it will be created newly. Normally a variable should not be declared twice. But it is not checked. In further versions of JZtxtcmd a second definition may be cause an exeception. Don't do so.
The next level after a dot is either a 9.9 Access to Java internal data or the level before is a datapool. A new variable will be created always inside its left side datapool. The following rules are valid:
a) A simple variable or the last datapathElement
is created always newly as instance of DataAccess.Variable
.
b) If the startVariable
or any variable of the datapath is not existing, it will be created as instance of DataAccess.Variable
. If a further datapathElement
followes, its Object value
is intialized with an instance of Map<String, DataAccess.Variable>
. It means, a variable node left builds a datapool.
c) An existing left-side datapathElement
have to be of type Map<String, DataAccess.Variable>
if the right-side variable is not existing or if it is the last one and should be created therefore. Otherwise an exception
is thrown.
d) If a variable left-side of a further datapathElement
exists, it will not be created newly.
e) An existing left-side datapathElement
can have any type, if the right-side datapathElement
is exisiting and it is not the last one. In this case method calls are admissible too. It is a 9.9 Access to Java internal data.
Examples:
myVariable
: rule a). It is created newly.
myData.variable
: rule a)b). myData
is a new datapool, its first element is variable
myData.variable2
: rule a)c). myData
is yet existing as datapool, variable2
is created inside
data.methodx(param).variable
: rule a)c)d)e): Assumed, data
is an existing java instance which offers a class method. This methodx(param)
returns a Map<String, DataAccess.Variable>
which is the container to add variable
.
For the syntax of variable definition see 16.7 Variables.
Topic:.JZtxtcmd.data.dataElementVar.
Sometimes it may be necessary to access data depending on other conditions. For example access data in a tree which is build from any data base. Instead write
if (ctrlVar == "A"){ data = path.to.A.data; } elsif(ctrlVar == "B"){ data = path.to.B.data; }
one can write:
data = path.to.&(ctrlVar).data;
The content of ctrlVar
replaces that part inside the Datapath. Of course only admissible values can be processed. Elsewhere an exception is thrown
which can catched with 12 onerror - Exceptionhandling.
An example for that is contained in examples_JZtxtcmd/TestAll/testAll.jz.bat in the sub testVariableDatapath()
.
Topic:.JZtxtcmd.data.prevar.
Some variables are defined on start of JZtxtcmd-execution and for any sub level. They are constant, it means not able to change in the users script. Some variable are constant for the whole execution, some variable are set for special situations. They are:
scriptdir
The directory where the script from this JZtxtcmd invocation is located. It is an absolute normalized path with Slash as
separator.
scriptfile
The file name.ext of the script from this JZtxtcmd invocation.
console
Reference to an instance of srcJava_vishiaBase/org/vishia/cmd/MainCmd which is often used for some vishia methods.
error
The last error message from an exception.
out
constant script variable, the standard output, it is an Appendable.
err
constant script variable, stderr
text
constant script variable, it is the srcJava_vishiaBase/org/vishia/util/StringFormatter respecitvely an java.lang.Appendable
where the <+>text output<.+>
is written out, given from command line argument -t:outputfile
or from the appropriate calling argument.
null
constant script variable, a null reference.
nextNr
instance of srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.JZtxtcmd.NextNr which increments and returns a number on any access. It is a simple possibility to have a counter.
test
constant script variable to the srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdTester for some test methods.
conv
constant script variable to the srcJava_vishiaBase/org/vishia/util/Conversion for some conversion methods.
jztc
constant script variable, reference to the srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.JZtxtcmd. It is possible to access public methods and fields.
The following static classes are provided as 9.1.10 Class - ?instanceof check, class loader, static method invocation script variables for simple access to static methods:
System
: javadoc-oracle/java/lang/System
Math
: javadoc-oracle/java/lang/Math for all math operations
FileSystem
: srcJava_vishiaBase/org/vishia/util/FileSystem: Some helpfull file operations
StringFunctions
: srcJava_vishiaBase/org/vishia/util/StringFunctions: Some helpfull String operations especially with CharSequence
instances.
Some variables are defined in any subroutine level. That are local variables, which are independent only valid for the subroutine level:
jztcsub
constant variable of any execution level, reference to the srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExecuteLevel
return
constant Map defined for the current subroutine for returned data from a subroutine. This variable is created on demand only
if any return-Variable is created. A subroutine returns this Map or null
if no return definition is inside. See 7.5 call: Invocation of sub routines.
Topic:.JZtxtcmd.data.prevar.jztc.
It references srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.JZtxtcmd. Able to use for:
jztc.bAccessPrivate = 1;
: Enable access to private and protected data in Java class instances.
jztc.scriptVariables().anyVariable = newValue;
: change script-variables from any execution level.
jztc.log
: Instance of srcJava_vishiaBase/org/vishia/mainCmd/MainCmdLogging_ifc for logging
jztc.startmilli
: milliseconds after 1970, start time of the script (begin running phase), use System.currentTimeMillisec()
to build differences or set it newly.
jztc.startnano
: nanoseconds relative, start time of the script (begin running phase), use System.nanoTime()
to build differences or set it newly. See javadoc-oracle/java/lang/System
Topic:.JZtxtcmd.data.prevar.jztcsub.
It references srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExecuteLevel. Able to use for:
jztcsub.currdir()
: current directory as String
jztcsub.localVariables
: Map<String, DataAccess.Variable> of all local variables able to use for subroutine-argument
jztcsub.cmdErrorlevel
: Return value of the last cmd
invocation.
Topic:.JZtxtcmd.data.var.
Script variables have a global character. They should be only a few variable, able to look over them. Some script variable
are pre-defined and not able to change. Some other script variable can be changed but that is restricted. Normally the subroutines
get a local copy of the script variables, so a change of it does only change the value of the local copy. In seldom cases
a change of a script variable should be required. That can be done by using the script variable jztc
. It is the JZtxtcmdExecuter itself, see 9.5 Predefined script variables. One should write
jztc.scriptVariables().TEST = "new script value";
to copy the local value of - for example TEST
to the script variable. That should only be done if the variable for the whole script need to be changed really. It should
not used because it is more simple to deal with that value between two sub invocations.
//Negative pattern: call mySub1(...); //changes the TEST globally. call mySub2(...); //Uses the changed value of the global variable.
That is an simple old programming style. It disadvantage: A subroutine can not assert that the value of a script variable is set with the known value of the script, any other program part may have change it for its stuff.
If it is necessary to have a changed value of a script variable, you can change it locally:
TEST = "new value"; //changes the local copy
If subroutines of a deeper level should use this changed current directory, it is possible to give it as a parameter:
sub mySub(TEST=TEST,...){...}
That subroutine defines a calling argument TEST
, it is initialized per default with the current value of TEST
of the script, not of the caller.
If that subroutine should override the script variable of TEST
one should write:
call changeCD(TEST=TEST);
Topic:.JZtxtcmd.data.env.
Environment variables of the systems environment which has called the JZtxtcmd process are available with
&$name
Especially the standard operation system variable are stuff to use, such as &$HOME
, &$OS
Which variable are existing depends on the operation system and the calling environment.
Topic:.JZtxtcmd.data.env.
The first level of a variable is a local variable of the current JZtxtcmd subroutine or a scriptvariable of the current jztc Script. Note the existence of 9.5 Predefined script variables.
A JZtxtcmd variable can be stored in a tree structure. A node is a 9.1.8 Map - a Set of variables, the last element is the specified JZtxtcmd variable. To access such a treed variable write
localVar.subvar.subsubvar
Note that such a structure can be defined with
Map localVar; Map localVar.subvar; String localVar.subvar.subsubvar;
It is possible too to transport a reference to a node to any subroutine:
call mySub(localVar.subvar); sub mySub(Map map){ <+out><&map.subsubvar><.+n> }
In a context where a normal text is parsed as text literal a *
have to be written before the variable. For example:
call mySub(); //mySub is the direct name call *mySub(); //mySub is a variable which contains the name. cmd execute.exe argument; //"argument" is the direct argument. cmd execute.exe *argument; //argument contains the argument string.
The same rule is valid for environment variables: &$envvar
in that adequate context.
Variable can start with $
in its identifier. That are conventionell JZtxtcmd variable. But they are used as environment variable for 7.2 start, cmd: Invocation of operation system commands.
Topic:.JZtxtcmd.data.jdata.
The first tag to access to Java internal data is a JZtxtcmd variable. It can contain any Reference to a Java object. For example a new Object can be created:
Obj myBuffer = new java.lang.StringBuilder("initial text");
If a JZtxtcmd script is embedded in a Java environment some JZtxtcmd script variables can be predefined with references to
Java objects. For example refer Zmake. A Zmake generation script is a JZtxtcmd script. It knows via zmake
all necessary stuff from the zmake input file.
To access to java elements one can write
myBuffer.insert(8, "any other ");
in this example insert(...)
is a method from the referenced class javadoc-oracle/java/lang/StringBuilder.
The path starting from the JZtxtcmd variable is written in normal Java language style. It is executed using the Reflection mechanism of the Java language.
The actual arguments of methods are 10 Expressions, see also the syntax in Chapter: 16.10 Object value: objExpr. If a method expects a java.io.File
as argument, one can write
anymethod(..., File: text_expression
,...)
to get a file object with the textual given path. Note that return values from 9.1.13 Filepath, Fileset is a CharSequence. to convert it to an expected File instance write
java pkg.path.javaMethod(..., File: &myFilepath.absfile(), ...);
References to other instances can be given with datapaths too:
Obj myStringPart = new org.vishia.util.StringPart(myBuffer); java pkg.path.javaMethod(..., myStringPart, ...);
The constructor of StringPart
expects a Reference to an java.lang,CharSequence
which is given with the myBuffer
. The mechanism of overloaded (argument dependent) methods works properly.
Access to protected and private elements:
The access is restricted normally, only public members can be accessed. But it can be unlocked. The cmd line Argument
-accessPrivate
of srcJava_Zbnf/org/vishia/jztxtcmd/JZtxtcmd
respectively calling arguments accessPrivate
can be set on invocation of JZtxtcmd. Then the access to private members are unlocked. Private members may be necessary to access for example for debugging.
The access to Java data can be a long term, started on any given variable in the JZtxtcmd context:
myVariable.field.method().fieldB
In this example the method()
may return an instance which's fieldB
is accessed.
If an instance is a java.util.Map
the next element is taken is key for the map to select the member:
myVariable.myMap.key
It is the same to write
myVariable.myMap.get(key)
A special feature is, to hold the name inside a variable:
myVariable.myMap.&(variableContainsKey)
The length of an array or the size of a java.util.Container
or java.util.Map
can be requested by
myVariable.myMap.[]
The []
should be associated with the length of the whole container.
To Access array elements you can use the known
myData[index]
but yet only with one index as constant value. (2016-01-17). It is proper to read out data from a pre-prepared array.
Topic:.JZtxtcmd.data.jstatic.
The keyword java
or a simple %
on start of a datapath declares the path as a package.class path to a Java class or method.
Obj myObj = java org.myPackage.MyClass.getData(args); java org.myPackage.MyClass.doAnything(); %org.myPackage.MyClass.doAnything();
Alternatively a Class
variable can be used to invoke a static method:
Class MyClass = java org.myPackage.MyClass; ... MyClass.doAnything();
The package path should be complete and the classes should be able to find by the running JVM. It means self-written Java classes should be the part of the class path of the invocation of JZtxtcmd. Alternatively the capabilities of the java.lang.ClassLoader can be used.
Some classes are able to address by the name without the package path. It is more easy to write. That are classes which provides often used static methods. The following identifier are pre-defined as Class-Variable:
Math
for javadoc-oracle/java/lang/Math with all static mathematic functions and constants.
System
for javadoc-oracle/java/lang/System with some special methods.
FileSystem
for srcJava_vishiaBase/org/vishia/util/FileSystem for File access functionality.
StringFunctions
for srcJava_vishiaBase/org/vishia/util/StringFunctions for String processing capability.
Topic:.JZtxtcmd.data.jnew.
The keyword new
or java new
on start of a datapath declares the path as a package.class path to a Java class for creation a new instance.
Obj myObj = java new org.myPackage.MyClass(args);
The package path should be complete and the classes should be able to find by the running JVM. It means self-written Java classes should be the part of the class path of the invocation of JZtxtcmd. Alternatively the capabilities of the java.lang.ClassLoader can be used.
Topic:.JZtxtcmd.data.method.
A method invocation is part of a Chapter: 9.2 The data path.
Static java methods can be invoked with 9.10 Access to static Java data and Invocation of static Java methods. The following examples shows the invocation of the static method atan2 (arcus tangens) with 2 numeric values:
Num value = java java.lang.Math.atan2(1.5, 2.2);
An interesting case is the invocation of a
public static final void main(String[] args){ ... }
which is the main routine of all Java classes which can be ivoked by a command line. In a JZtxtcmd script you can write:
java myPackage.Path.Class.main(); java myPackage.Path.OtherClass.main("argument", <:>argument <&variabe><.>, "third argument");
If a method expects exactly one argument of type String[] and all given arguments are CharSequence
, then the proper String[] will be build with all given CharSequences. If no argument is given, that routine gets a String[0]
.
Non-static Java methods can be invoked either on a reference to a 9.11 Creation of new instances of Java classes or on a Java instance referred with a 9.5 Predefined script variables. The following example creates an instance and invokes a method from them with numeric values:
Obj obj = new org.vishia.zcmd.JZtxtcmdUserExample(); obj.methodTest(5,8);
The arguments are an ObjExpr
, see 10.4 Object expression and syntax: 16.10 Object value: objExpr. The expression will be translated to the internal presentation in JZtxtcmd and it will be calculated on Runtime before the
method is searched.
Methods in Java are argument-sensitive (adequate in C++ also). It means, methods with the same name but with different argument numbers or types are different methods. Therefore the argument should be checked. Additionally the arguments should be converted. It is done as capability of srcJava_vishiaBase/org/vishia/util/DataAccess.
An argument is matching if the method expected a super type of the given argument value. For example a CharSequence
can be given by a String
or a StringBuilder
.
An argument is matching if it can be converted automatically, especially for numeric arguments. If a float is expected, but
an integer is given, it is okay. The reflection mechanism expects an Float
instance. It is converted from an int
to Float
.
A numeric value will be calculated and the result will be converted if possible. For example
Obj obj = new org.vishia.zcmd.JZtxtcmdUserExample(); obj.methodTest(5*Math.PI, 8+5);
In this case the first argument uses the JZtxtcmd variable Math
which is the class javadoc-oracle/java/lang/Math to get the value of pi. The double density value of 5*pi
is converted to the requested float. The second argument is 13
.
An integer value can be converted to a char
. A String with exactly 1 character can be converted to a char
argument:
obj.methodTest('a'); obj.methodTest('b'-1); obj.methodTest(65+32); obj.methodTest(0x61); obj.methodTest("a");
All this examples invokes the method methodTest(char cc)
in that class with the character 'a'.
Any CharSequence can be converted to a String:
## invokes methodTest(String) obj.methodTest(<:>content of <&obj><.>);
The expression is calculated in a StringBuilder
-Buffer. It is converted to a String because the methodTest(String)
exists.
A boolean
argument can be given with an integer value:
void myMethod(int a, boolean b) ...//Java obj.myMethod(23, 1); //JzTxtCmd, give ,,true,, for ,,b,,. Num value = 34; Num condition = 1; obj.myMethod(value, condition); //JzTxtCmd, from variable.
A Bool condition = 1
does not work unfortunately till version 2018-08.
Bool condition = a > b; //can be used from version 2018-09
The possible conversions are programmed in srcJava_vishiaBase/org/vishia/util/DataAccess in private initConversion()
.
If a method requests a javadoc-oracle/java/io/File it can be written:
obj.methodTest(File: "myFile"); obj.methodTest(File: path/theFile.ext);
The File:
causes to convert the following text expression to a file path and name with the currdir how it is set in the JZtxtcmd context.
Note that comlex numeric calculations are much slower than in a Java execution environment because the JVM translates operations from its bytecode in machine code before execution. Therefore a Java Bytecode execution is aproximately equal fast like programming in a direct compiled language such as C or C++. But the JZtxtcmd execution is really an interpreter and therefore slower. Complex numeric calculations should be programmed in Java. But the numeric calculations are not slower as in other script languages.
Topic:.JZtxtcmd.expr.
An expression can be used to combine something to assign its result to a variable or for a actual argument only. The basic idea of Functional Programming is, expressions to calculate something ('functions') should not have side effects.
An expression can have side effects, it changes other data. The so named 'side effect of an expression' can be the goal to invoke an expression. Calling a procedure.
It is the same like in all other programming languages.
The result of an expression can associated to the categories:
text (String)
numeric (float, double, integer)
boolean (true or false for conditions)
any object of a dedicated type.
To concatenate strings see 13 Text output and text generation.
A numeric or boolean value is stored in the wrapped form as Object.
Topic:.JZtxtcmd.expr.DataAcess.
Operands are either
constant: 5.0
, 387
, "constant text"
Values in a JZtxtcmd Variable
Values from any Java location.
See, 9.8 Access to JZtxtcmd local or script variables or 9.9 Access to Java internal data.
Topic:.JZtxtcmd.expr.textDatapath.
See its syntax in 16.9 Text value: textDatapath, textValue.
textValue
If a text is expected in the syntactical context the constant text can be written as usual. For example in 7.2 start, cmd: Invocation of operation system commands a command can be written simple as:
cmd notepad.exe myfile;
It is like a command line in a batch file or shell script. The spaces are the separator between arguments. Any argument is
a textValue
. Note that a textValue
written as simple text cannot start with an ampersand &
and ends on a whitespace or one of the character ;,)(
.
If a constant text should not be used rather the content of a variable one can write:
cmd &myCommand &myArg;
If the textValue
starts with an ampersand, a 16.11 DataPath, Data access follows. In the simple kind it is the name of a variable which's content is used.
Alternatively a textvalue
can be written with quotation mark like known:
cmd notepad.exe "my file with spaces in the name.txt"
The forth form is use an 10.3 Text expression for a textValue
. It offers the possibility to assemble the text with variable content in any desired form. One can write for example:
cmd notepad.exe <:><&topic>.<&extension><.>;
In this case the file name for the notepad is built with the content of a variable topic
and a special extension stored in the variable extension
.
textDatapath
If a text is expected but usually not an immediately text a textDatapath
is used syntactically. To get a constant text one should be used quotation marks. It initializes with a constant text. Writing
of quotation marks are usual in that kinds:
String myVariable = "any text";
A datapath can be written immediately. A simple String is recognized as identifier. For example, the new defined String myVariable
is filled with the content of otherVariable
:
String myVariable = otherVariable;
For compatibility you can write also, the &
is optional. Then the textDatapath and the textValue are written with the same syntax:
String myVariable = &otherVariable;
Note that a datapath can be a variable path. In the following example the datapath is contained in the variable a_datapath
, see 9.4 Datapath depending on Variables:
String myVariable = &(a_datapath);
The same in a textValue but compatible in a textDatapath can be written as:
String myVariable = &&(a_datapath);
A textDatapath can be build with an Chapter: 10.3 Text expression too, it is the same like in textValue:
<:>a textDatapath with <&value><.>
Topic:.JZtxtcmd.expr.textExpr.
See also Chapter: 13 Text output and text generation
Syntax see Chapter: 16.14 TextExpression
A textExpression is written between
<:>the text expression<.>
if it is used as an argument String or for assignment to a String
or Stringjar
or Obj
-Variable.
Text expressions are used for 13 Text output and text generation respectively write into files and output texts to console. The the expression is written between
<+channel>the text expression<.+n+flush>
A text expression can contain:
13.8 Place holder and values <&dataText>: <&datapath>
:
13.11 Program control in text expressions: conditinals, <:if:condition>...<:elsif:condition>...<:else>...<.if>
,
loops <:for:variable:container>...<.for>
TODO calling of sub routines <&subtext:name:args>
A text expression can be spreaded over some lines, whereby indentation is regarded, see 13.3 Lines and indentation in the script
Simple example: build a path relative to the script directory:
<:><:scriptdir>/my/file.ext<.>
For example a String argument should be given for a subroutine or Java method invocation. The argument list may contain:
myObj.method(<:>The String with <&variable> has called <&otherObj.method(<:>with <&variable><.>)><.>);
In this example two text expressions are nested.
Topic:.JZtxtcmd.expr.objExpr.
Syntax see Chapter: 16.10 Object value: objExpr.
Any free instance is an java.lang.Object
and it can be stored as an Obj
:
Obj data = myDatapool.method(args);
The args are an Object expression too. The gotten instance has its specified type of course. Therefore any method of this type can be used:
data.specialMethod(args);
Because the JZtxtcmd is an dynamic language, not only the few methods of java.lang.Object
can be invoked.
An Object expression can be build as Map of some named Objects:
Obj myDatastruct = { String val1 = "anything"; Obj data = theData; };
That is usefull if the Object with more as one data should be stored and transfered in an container.
Topic:.JZtxtcmd.expr.bool.
Syntax see Chapter: 16.12 Condition expression.
To get boolean values with boolean operators especially for method arguments one have to be used the JZtxtcmd
bool( boolExpr )
method. To check conditions in 8 Program flow control one should write
if( boolExpr ) { ... }
A boolExpr
can contain &&
and ||
and the !
like known for Java, C. Instead !
not
can be written. It may be better visible in a JZtxtcmd script. The bool(...)
syntax is not necessary if only boolean is expected, especially in 8 Program flow control.
The operands for boolean logic are either compare results or simple values.
Not found variable:
A boolExpr
which contains only a 16.11 DataPath, Data access is false
if the data path is faulty. A NoSuchFieldException
or a NoSuchMethodException
are catched and forces the false
value. In this kind the user can write
Obj exist = bool( data.path);
then exists
is set to false or true depending of the corretness of the path.
if(data.path){...}
is not executed if the path is faulty or the variable is null or 0, whereby
if(not data.path ==null){...}
causes an exception if the data.path
is faulty, because the path is used to compare.
Comparison:
Two numeric expression results can be compared using
== != > >= < <=
like it is known in Java, C. Alternatively it can be used
?eq ?ne ?gt ?ge ?lt ?le
especially in text generation parts because >
has an abbreviating meaning <&textpart>
etc, see 13 Text output and text generation.
Note that comparison are parts of a boolean expression. bool(a > b)
should be written to build a boolean value of the comparison.
Comparison of Strings:
If you write
myVariable == "reqested text"
and the variable is a CharSequence
, the content is be checked on equality. !=
can be checked too. The operation
myVariable >= "starttext" myVariable ?ge "starttext"
returns true, if the variable startsWith the comparison text. The >=
means it may be longer or equal. It is not a comparison of alphabetic order. The >=
it usefull in some operations. Another proper special operator is
myVariable > "containstext" myVariable ?gr "containstext"
It returns true if the variable contains the text.
That comparison are done if both operands left and right of the compare operator are a CharSequence
such as a javadoc-oracle/java/lang/String, a javadoc-oracle/java/lang/StringBuilder or a Stringjar
: srcJava_vishiaBase/org/vishia/util/StringPartAppend.
Check of a reference whether it is null:
In difference to Java language it is possible to write simple
if(myObject) { ...
If the myObject
is null that expression is false. myObject
can be any reference in any data.
instanceof - Check of a reference whether it is an expected type:
Similar to Java language an Object can be checked whether it is an instance of an expected type. Write
Class myExpectedType = org.myPackage.MyType; ##used for instanceof check Obj anyObj = ... Class ... if(anyObj ?instanceof myExpectedType) { ...
The ?instanceof
operator needs on left side any Object and on right side a Class object. It is true if the class is type of the given type,
maybe in an super class too.
Automatic conversion to boolean:
Inside a bool(...)
respectively in a boolean expression of a control statement an automatic boolean conversion is done:
References which provides a null
are converted to false
, existing references are true
But references which refers to a Boolean instance returns false
both on null-reference as if the boolean value is false.
Numeric values are not converted automatically (since 2016-06). That is because firstly it should be able to check whether the value is found. The null-test is prior. Look for the example:
Map myMap = .... //contains some variables Obj value = myMap.name; //searches the instance with key "name" in the map. if(value) { //it should check whether the Obj is found. It can be a numeric type. if(value !=0) { //That is true if the value is numeric and not 0. //If the value is not found (,,null,,) or not a numeric, the boolean expression is false. .... } }
Topic:.JZtxtcmd.expr.num.
Syntax see Chapter: 16.13 Numeric Expression
A numeric expression can be build with the ordinary numeric operators + - * /
and ( )
with numeric values. Functions can be called with the javadoc-oracle/java/lang/Math methods.
Class Math = java.lang.Math; ##defines Math in a variable Num y = Math.sin(0.1); //calculates Num y2 = %java.lang.Math.sin(0.1); //long form for static methods <+out>y = <&y:%1.5f> <.+n> //outputs it with given format.
Usual numeric expressions may be used only for building of arguments for some methods. Complex numeric calculations should be programmed in Java routines. arrays are supported yet only with access to 1 index as constant (2016-01).
Topic:.JZtxtcmd.thread.
Multithreading is an important capability, which is missing in some other script languages. For example an executable can be started via 7.2 start, cmd: Invocation of operation system commands which needs some time to execute. Simultan another executable can be started. It needs its own thread because the thread should wait of finish the cmd line process when its result is needed. Java methods can be started too in the other thread. Then it works in the same process space with possibility of data exchange.
A thread is able to define in two ways:
{ ... any statement block; thread { ... statements; } ...more statements, }
The thread starts if the execution in the parent statements arrives the thread
statement. The thread is executed concurrently to the parent statements with the Java's VM thread capability. It is similar
as a _Fork_(system_call)_(Wikipedia) in UNIX systems, but with a second thread in the same process of operation system. In opposite fork creates an new process on operation system level.
If the last statement of the thread is finished, the thread will be removed.
If the parent statement block reaches its end, the thread is not influenced. The thread block is independently. But the thread block uses the same local variable as the parent statement block. It means, that variables are not removed so long as the thread runs.
{ parent block; Thread myThread = { ...threadblock; } ... }
The second form uses a dedicated thread variable. But it is the same principle and an adequate syntax. The thread variable is type of srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdThread. The state of the thread can be gotten by reading the variable srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdThread#state. Last not least the method srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdThread#join(int) can be called in any other thread (usual the main thread) to await the finishing of that thread. This is a join operation.
The statements of a thread can produce text with <+>text<.+>
which is merged in the output text consistently. The text generation is not interrupted between <+>
and its closing <.+>
by another thread, it is synchronized.
Topic:.JZtxtcmd.thread.msg.
The class JZtxtcmdThread contains 2 queues one for commands, one for messages. A thread can await a command writte with:
Obj cmd1 = myThread.awaitcmd(100000); ##NOTE: cmd is a keyword, use variable name 'cmd1'
For that time the thread is dormant. The command is type of docuSrcJava_vishiaBase/org/vishia/cmd/JZtxtcmdThread.MsgItem. Any other thread can send a command to the JZtxtcmdThread instance with
myThread.sendcmd("command", anydata);
The Thread can send a message with
myThread.sendmsg("identifier", data);
which is awaiting by another thread:
myThread.awaitmsg(10000);
The argument is the timeout time. Because JZtxtcmd is not used for interactive operations but for batch processing the waiting time need only for execution time of some other operations. The timeout is proper if any thing hangs.
Topic:.JZtxtcmd.thread.join.
One thread can wait till the other thread is finished with its work:
if(myThread.join(10000)) { .... }
The join method returns with false if the timeout expires. This capability is important if a common task is splitted and should be continued if both parts are finished. Join with more than two threads is possible with some join invocations one after another.
Because multi-core processing is usual the fork and join can save time. The Java Virtual Machine respectively the operation system will divide several threads to extra cores if there are enough CPU time for that. Then the execution works really simultaneously.
Topic:.JZtxtcmd.onerror.
Syntax see 16.17 Exception handling.
The Wikipedia:_Exception_handling is a core concept of a modern programming style. Older programming strategies works with an error variable for example the errorlevel
of MS-Windows commands and batches or the errno
variable in C language (Wikipedia:_Errno.h). In that older style an error have to be checked. If the error was not recognized, the algorithm is continued with erroneous data.
The basic idea of the modern exception handling is: The causer of an error may not correct the problem - it can be propagate the situation only.
If an error occurs then the normal operation order is aborted without additional programming effort. The program flow is continued on an proper catch block. That block can be located in the own procedure or in any superior calling level. In the catch block either the whole program may be aborted with a proper output, it is the simple variant, or erroneous or missing data are replaced and the session can be go on.
On the other hand errors such as missing variables should not cause an aborting of the algorithm, instead it should only reported and the algorithm should be continued. Especially on text generation the generated text can contain such error reports instead of the expected text parts. The generated text can be checked wether it contains such error reports. They should be fixed in the JZtxtcmd script language or in the called Java routines, - and then generate ones more! This strategy is substantially the same like the throw-catch. The catch routine generates the error report into the output text.
There are two types of exception thinking:
a) The exception is not expected usual. The exception handling should help to find out the mistake
b) The exception may be expected. It should be accepted and an alternative handling should be done.
Not at any time a programmer should think: There is never a reason for a mistake, it doesn't be need to handle. Think: The unknown reason cannot be known! It is adequate Murphy's Law. Therefore a) is present anytime.
Topic:.JZtxtcmd.onerror.errortoOutput.
With the statement
errortoOutput;
all errors of execution are written in the current output text in the form
<??? error-report ???>
That flag is valid for the sub routine and all called levels till the statement
errortoOutput off;
but not for superior (calling) levels. It has not a script-global effect. If it is given:
errortoOutput; //set on script level
it is valid for the script. In a sub routine
errorToOutput off; statements ...; on error{ exception handling statements; }
can be set though the scriptlevel sets errorToOutput
.
Topic:.JZtxtcmd.onerror.onerror.
The statement
onerror { statementblock }
can be inserted after some statements inclusively calling of sub routines, which may throw an exception. On exception the
JZtxtcmd execution is continued on the next found onerror
statement with the proper type. This block is executed.
If an onerror
block is found in the normal statements order, it is skipped.
The onerror
block is the catch
block in comparison to Java, C++ and other adequate programming languages. A try
is not necessary in JZtxtcmd. All of the program code is tried.
That mechanism works both for internal thrown Exceptions in Java codes and the throw
statement in JZtxtcmd.
There are a few types of onerror
:
onerror notfound { ... }
It is executed especially if a variable is used in a JZtxtcmd script which is not existing. JZtxtcmd is a dynamic languages,
which does not check the existence of variables on compile time. Furthermore that type is used if a field or method is not
found in any Java classes using reflection. Commonly one can say if a datapath is faulty. See 9 Data and variables, especially 9.8 Access to JZtxtcmd local or script variables and 9.9 Access to Java internal data. That onerror
block may be usefull if a script is written newly. The associated exception types are javadoc-oracle/java/lang/NoSuchFieldException and javadoc-oracle/java/lang/NoSuchMethodException
onerror file { ... }
Files are a known causer of errors. A file can be deleted thought its existence is expected. It can be write protected, locked, corrupted, or the media is not present. All that errors are subclasses of javadoc-oracle/java/io/IOException whereby the javadoc-oracle/java/io/FileNotFoundException is a known candidat of this group.
onerror exit { ... }
This exception is thrown by an exit
statement of a JZtxtcmd script. Any subroutine can invoke exit
. But whether the whole program is exited or not can be catched with this onerror
handling. Normally exit should be done. But if a sub routine is called and the caller has a replacement strategy, the exit
can be prohibited. The error type which is thrown is srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExitException.
onerror cmd { ... }
This onerror handling is especially for the throw on errorlevel
statement after cmd line invocations, see 7.2 start, cmd: Invocation of operation system commands.
onerror internal { ... }
This onerror block is used for all other Exceptions especially any of the javadoc-oracle/java/lang/RuntimeException.
onerror { ... }
If an error type is not given, all Exceptions where catched here.
In the statements of an onerror-Block should offer alternatively handlings and set data with proper values. To control the program after such an block, all further necessary data should be set with proper information.
For example a file cannot be read. Some Information are not present. But all others of the following algorithm should be done nevertheless. Write
data = anyReadAlgorithmFromFile(); onerror file { data = "default-value"; }
The following algorithm does not need to know about the file read problem, it looks only to data.
Topic:.JZtxtcmd.onerror.throwCmd.
See Topic:.JZtxtcmd.statements.cmd.errorlevel.@$chapter
The cmd line invocation ends with an errorlevel which is stored in the variable jztcsub.cmdErrorlevel
. An exception is not thrown. That is the old style of error handling. But with the statement
throw on errorlevel 99
an exception is thrown if the errorlevel is greater or equal the given number (99 in example). It means the next statements
are skipped till the next onerror
block or the subroutine if left if there is not an onerror block and the next expressions in the superior routine are skipped
etc.
Topic:.JZtxtcmd.onerror.throw.
In a JZtxtcmd an exception can be thrown usual conditionally:
if(condition){ throw "any text"; }
It throw an org.vishia.cmd.JZtxtcmdExecuter$JZtxtcmdThrow
exception. The execution is continued on the next onerror block.
Topic:.JZtxtcmd.onerror.info.
The following data access paths can be used:
error excStacktraceinfo() jztcsub.threadData.exception
The text of an exception is stored in the error
variable. That variable can be used especially to log the exception.
<+log>Exception <&error><.+>
The Exception object itself (derived type of javadoc-oracle/java/lang/Throwable is stored in the jztcsub.threadData.exception
field. See 9.5.2 jztcsub.
A Stacktrace can be reported by using
String stacktrace = jztcsub.excStacktraceinfo();
This method returns in one line the information about the exception (Type, message) and the stacktrace for up to 20 levels in a one-line-presentation. The one-line is an advantage if this information should be merged in an outputted text: It does not disturb the line structure.
An example for sucn an line with wrapped lines for better readybility, it is one line:
JZtxtcmd.execute - exception at; @D:\vishia\ZBNF\sf\ZBNF\examples_JZtxtcmd\T estAll\testAll.jz.cmd:142,28; e <*);; java.lang.NoSuchFieldException: DataAccess.getData - not found in datapool; unknown; datapool contain s; :$TEST, FileSystem, StringFunctions, System, console, conv, err, er ror, error, file, jztc, jztcsub, nextNr, nextnr, null, out, scriptOb j, scriptStringEmpty, scriptStringSet, scriptStringSet2, scriptdir, sc riptfile, test, text, ; org.vishia.util.DataAccess.access(DataAccess.j ava:670); org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.dataAccess(JZtxtcmdEx ecuter.java:1964); org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.executeDa tatext(JZtxtcmdExecuter.java:1590); org.vishia.cmd.JZtxtcmdExecuter$ExecuteL evel.execute(JZtxtcmdExecuter.java:752); org.vishia.cmd.JZtxtcmdExecuter$Exe cuteLevel.execute(JZtxtcmdExecuter.java:662); org.vishia.cmd.JZtxtcmdExecute r$ExecuteLevel.textAppendToVarOrOut(JZtxtcmdExecuter.java:1169); org.vish ia.cmd.JZtxtcmdExecuter$ExecuteLevel.execute(JZtxtcmdExecuter.java:714); org .vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.execute(JZtxtcmdExecuter.java:662) ; org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.execSubroutine(JZtxtcmdExecut er.java:1321); org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.execCall(JZcm dExecuter.java:1211); org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.execut e(JZtxtcmdExecuter.java:753); org.vishia.cmd.JZtxtcmdExecuter$ExecuteLevel.e xecute(JZtxtcmdExecuter.java:662); org.vishia.cmd.JZtxtcmdExecuter.execute(J ZcmdExecuter.java:431); org.vishia.zcmd.JZtxtcmd.execute(JZtxtcmd.java:398); org.vishia.zcmd.JZtxtcmd.execute(JZtxtcmd.java:354); org.vishia.zcmd.JZtxtcmd.s main(JZtxtcmd.java:190); org.vishia.zcmd.JZtxtcmd.main(JZtxtcmd.java:142);
One stacktrace level is presented with (last line of the example):
org.vishia.zcmd.JZtxtcmd.main(JZtxtcmd.java:142);
In an Eclipse console window that format is shown with links to the source code, like usual with an eclipse-generated stack trace. The method and the file and line is shown.
Topic:.JZtxtcmd.onerror..
The exception information contains the original exception type and text from its Java internal context inclusively the stacktrace
in the Java context. Additionally the file and line-number and a short presentation of the JZtxtcmd statement is shown, where
the exception was caused. If the onerror {...}
-block is found in a superior subroutine level, the calling order to the subroutine is not shown (no stacktrace at JZtxtcmd
level). Usual the calling order is less complex as in Java method nesting. See the example:
sub routine(){ line = causes.exception; } sub callingRoutine(){ call routine(); other statements; onerror{ <+out>error: <&error> <.+n> }
The error
variable contains the line where the exception was caused. Though the onerror
-catch block is in the other subroutine it is evident that the call routine()
was executed lastly before onerror
. If that routine contains:
sub callingRoutine(){ call routine(); ## first other statements; call routine(); ## second onerror{ <+out>error: <&error> <.+n> }
it is not clear whether the first or the second call is done lastly. But usual this fact may not important. Therefore the effort of a stack trace on JZtxtcmd execution is omitted. The Java stacktrace shows indeed the fact of calling a subroutine, but it also does not contain the fact which line causes the call. A stacktrace in Java does not contain data unfortunately.
If a debugger is used, for example with an Eclipse environment, a break can be set in the catch
block of the method srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExecuteLevel#execute(...) to view details.
Topic:.JZtxtcmd.text.
The capability of text generation is used either to build arguments or textual values for Strings or to produce output text.
Topic:.JZtxtcmd.text.out.
For building a text expression the text should be surrounded with
<:>That is the text with <&variable>-content or <&obj.operation()><.>
If the text is written in more as one line, either a line break can be suppressed using
<:>Text in one line <: > but written in the script in more lines<.>
The all white spaces after <: >
are skipped. Or: The text can be marked with
.....some script statements maybe indented <:> ==== The indented text, but with 4 spaces only ==== } //end of block for example in a generated source <.>
The ==
till the position of <:>
in the line above are skipped. That helps to designate text part in a script.
Inside a text expression subtexts, if and for-container can be used, special characters can be used:
<:>Text <:if:condition>with conditional parts><.if> continue though line break in script: ==<:for:item:containerVariable>repeated <&item.text> <.for> <: > <:call:subtext:argument,argument> ==<:n><.>
The subtext
is the name of the sub subtext
routine, see Chapter: 6.5 Subroutines and subtext, or the name of the subtext routine can be gotten from a String
variable writing <call:&subtextvariable:...>
. That enables more complex controlled sub texts.
A text expression used especially for assignment and argument string is written like
String var = <:>this text is assigned to the var<.> call subroutine(<:>text used as argument<.>);
A text expression is outputted to the JZtxtcmd output file 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<.>
The JZtxtcmd output file can be determined by -o=file
option on invocation or with setting the script variable
text = "path/to/file.txt";
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.
Topic:.JZtxtcmd.text.text.
The text output file may be given with the command line argument -t:path/to/textOutput.ext
or for Java-internal invocation as argument of invocation of docuSrcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter#execute(org.vishia.cmd.JZtxtcmdScript, boolean, boolean, java.lang.Appendable,
java.lang.String) and docuSrcJava_vishiaBase/org/vishia/cmd/JZtxtcmdExecuter#execSub(org.vishia.cmd.JZtxtcmdScript.Subroutine, java.util.Map, boolean,
java.lang.Appendable, java.io.File). In this cases the output is determined outside of the JZtxtcmd script.
The text output file can be set or changed within the JZtxtcmd script with the statement
<+:create>path/to/textOutputFile.ext<.+> <+:append>path/to/textOutputFile.ext<.+>
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.
The output can be determined for the whole script via setting the script variable (fixed in 2018-09):
text = "path/to/textOutputFile.ext";
Another approach is: assign an existing appendable. It can be especially a TextBox in a GUI:
text = window.getWidget("outTexts");
Topic:.JZtxtcmd.text.indent.
To produce a newline after the output line one can write
<+>My line<.+n>
The Text in a JZtxtcmd script for text output is written as plain text after a text output statement. It can be written over some lines.
Because the script usually works with indentation for the statements, the text in the script should be indented too. If the indentation of the text in the script is the same as the statement which introduces the text output, it is not indented in the output:
sub myRoutine(...) { for(variable: container) { <+><: > Create this text in the output without indentation with several lines, maybe with <&variable.value> <.+> if(condition) { <+>A text line next Line of this text <.+> } ...
There are some more possibilities especially to mark and separate ranges of text with ranges of statements. The rule for that
is: One of the character =
, :
or +
can be used as marker left of the indentation column of the plain text. You can write in the same example:
sub myRoutine(...) { for(variable: container) { <+><: > ====Create this text in the output without indentation ====with several lines, maybe with <&variable.value> ====<.+> if(condition) { =========<+>A text line =========next Line of this text =========<.+> } ...
The ===
or :::
with at least 3 character length is possible overall in the script, it is ignored by the parser. It should be used only before
the <:>
to mark that area as text output.
It may be better obvious that there are text lines. Instead ======
there can be used ::::
or ++++++
too, but not in combination in one line.
<+><:s> ==testText()== 1. line without indentation. It starts before indentation column in the script. 2. line without indentation. It starts exactly on indentation column. 3. line has 2 spaces indentation. It starts after the indentation column. ::::4. line without indentation with :::: in script. ::::::::5. line without indentation with more :::::: in script. ++ 6. line with 2 spaces indentation because it starts after indentation chars. :::::::: 7. line with 2 spaces indentation. It starts after the indentation chars though there are longer as indentation point in the script. ++++: 8. line starts with a colon as first char after ++++ indentation. =====9. line without indentation ==+10. line starts with a '+' because first char after another indentation char though before indentation point. <.+>
The text can be written with an indentation in the script. It is generated without indentation if the text starts after the
column where the <+
ends. The indentation till this start column should be done with spaces or with colon :::
in the script. In this example all lines except the fifth
are written in output without indentation. A line which starts left of the script indentation column is written correctly.
Because the fifth indented line
starts one character after the script indentation column, it is written with one space in the output.
The <:s>
skips over all white spaces inclusively that text marker before indentation. It is processed while preparing the source for
an jztxtcmd script (translating phase), not at runtime. A <: >
skips over all white spaces while parsing the source. Therefore it does not skip the text marker before indentation. A <: >
can be used instead <:s>
in special cases.
A :::
may clearly mark a text line. That marker can be written starting before the indentation line. Then the line starts exactly
after the :::::
. The number of colons is no matter how:
<+> :::::::::line without indentation ::::::::: line with one space left :: line with one space left. ::::line starts with the ::::<.+>
One should not use tabulators for indentation. The JZtxtcmd executer does not know a tabulator width of the used editor. Only if all text lines should be left aligned in output the user can use tabs in the script. The JZtxtcmdExecuter counts only spaces and tabs from the start of a JZtxtcmd source text to skip over the source indentation characters independent of spaces or tabulators.
Pattern for well readable JZtxtcmd script code and generated text:
To separate statements and text the following pattern can be used. Separation of text and statements is nice to have especially if C-code or similar should be produced. The JZtxtcmd source is better able to read, no confusion because the syntax is similar. Write:
if(JZtxtcmdexpression) { <+> :::::::::::: if(C_expression) { //similar syntax like JZtxtcmd :::::::::::: doSomethind() :::::::::::: }<.+> }
The JZtxtcmd statements are written left.
The output text is written rigth.
The <+>
defines the column where indentation starts, right side.
The ::::::::
marks clearly output text lines.
The output text starts with a newline usually and ends without a newline. This is a well convention for text generation because the start of line is known often whereby the continuation or end of line may be known only in the further context.
Often an variable indentation is necessary in the generated text. See the example:
sub generateWhile(int recurs, ...) { <+> ::::::::<:@2*recurs>while(C_condition) {<.+> call generateInnerCode(recurs = recurs+1); ::::::::<+> ::::::::<:@2*recurs>} //while <.+> }
See 13.7 Column tabulator. The column tabulator produces the necessary indentation with the recurs
variable. If there are nested while(...)
etc it is written in the correct indentation form. The while(C_condition)
-line in the example starts on the column 2 * recurs
so far as the } //while
because the line starts immediately after the colons ::::::
but set its output column to the calulated value.
On the other hand if a generated text contains less and simple JZtxtcmd statements one can write it inside the text like:
sub switchStates(Obj stateComposite, Num recurs) { <+> :::<:@2*recurs> switch(<&stm.zsrcFile.variables.StateInstance>.state<&stateComposite.stateId>) { :::<:@2*recurs> case 0: entry_<&stateComposite.stateDefault><&stateMethodSuffix>(thiz); break;<.+> call switchCaseState(stateComposite = stateComposite, recurs = recurs+1); <+> :::<:@2*recurs> } //switch <&stateComposite.stateId> <.+> }
In this example the case
-Statements are generated from a JZtxtcmd-subroutine. It is well able to read to write the subroutine call inside the text.
The formal syntactical separation between both is done with the
text<.+> JZtxtcmd statements <+> text
The well able to read separation is done with the :::::
.
To write a text without newline on start one can write:
JZtxtcmdExpression() <+>output text <.+> ::::::::::<+>further text<.+>
The <+> is written at right side, like above.
Text after <+> immediately - no line feed.
One can use :::
inside JZtxtcmd statement to mark a line which contains output text, it is better seen.
Note that
:::::::::::::<+>output text<.+n>
produces an output text with a line feed on end.
Line feed on start or end of an output:
Writing
<+output:n>Line starts with newline<+> <+output> appends on this line<+> <+output>and ends with newline <.+n>
produces a newline on start or on end of the text with a lightweigth code in the script.
<+:n>One line in the -t:text-output<.+> <+> appends on this line<.+> <+> and ends the line <.+n>
Prevent line feed and spaces with more as one script lines:
It is possible to write a text in the script in several lines, which should be outputted in one line. For example this is able to use to produce batch or shell script files with long lines because long command line arguments are necessary. Write
<+>cmd <: > arg1 <: > arg2 <: > ##comments are possible <.+> if(condition){ <+>arg3<.+> } <+> <.+>
This produces in the output:
cmd arg1 arg2 arg3
With conditional arg3
and a newline on end. The syntax <: >
(one space after :
) skips over all following white spaces, especially over the line feed in this example.
Topic:.JZtxtcmd.text.transcript.
All characters in the line are transformed to the output without changing. One can use tabulator characters in the text to produce tabulators in the output text.
The newline character(s) in the produces text is given with the argument -nl=[n|rn|r]
of the invocation of JZtxtcmd. It is not the newline character(s) of the JZtxtcmd script. For example the script can be written
with only a \n
-Character (0x0a) and the produced text can be written with \r\n
like standard in Windows.
One can output some characters writing:
a <:lf>
produces a newline, line feed with the given newline setting.
a <:n>
produces a newline character in the text (0x0a).
a <:r>
produces a return character in the text (0x0d).
a <:t>
produces a tabulator character in the text (0x09).
a <:<CHARS>
produces a <
character with the following CHARS
in the text. With them a text can output the character combination <:
, <+
and <&
using <:<:>
, <:<+>
and <:<&>
. It is possible to write for example <:<&myVar>>
to produce the text <&myVar>
. Note that the first of the >>
is the end of CHARS
syntactically. The second of the >>
produces the >
in the text. But it is proper to read <:<&myVar>>
.
a <:#CHARS>
produces a #
with the following CHARS
. With them a text can output a ##
using <:##>
a <:scriptdir>
writes the directory as absolute path, where this script source is located. It helps if a script should use files with relative
path to it.
Example:
<+>Text<:lf>next line<.+> <+><:t>after tab <:<:special>> <:r>after 0x0d
produces
Text next line after tab <:special> after 0x0d
Topic:.JZtxtcmd.text.dataElementVar.
Sometimes it may be necessary to access data depending on other data. The name in a datapath is given in any other variable,
not as constant name. It is an indirection. If the ctrlVar
contains a part of the name in another datapath you may write:
if (ctrlVar == "A"){ data = path.to.A.data; } elsif(ctrlVar == "B"){ data = path.to.B.data; }
Because the content in the ctrlVar
is exact the name in the datapath, it is more simple to write:
data = path.to.&(ctrlVar).data;
or inside a text expression:
<:>... <&path.to.&(ctrlVar).data> ...<.>
The content of ctrlVar
replaces that part inside the Datapath. Of course only admissible values can be processed. Elsewhere an exception is thrown
which can catched with 12 onerror - Exceptionhandling.
A maybe typical construct is
<:>... <&&(path)> ...<.>
if the path contains the whole data path.
An example for that is contained in examples_JZtxtcmd/TestAll/testAll.jz.bat in the sub testVariableDatapath()
.
Topic:.JZtxtcmd.text..
It is possible to hold an
Topic:.JZtxtcmd.text.col.
One can set the next column position in a line writing
<:@100>
Then the position in the line is set exactly in this example to 100. If the line is shorter, spaces are appended before. If the line is longer then the content at this position will be overwrite. Use
<:@100 : 2>
to prevent over-writing of content. If a :
is written, the column position is set after the current end, with at least the given number of spaces, 2
in this example. Both forms may be proper:
The example produces a list where the information
is over-written, the column is correct:
<+out><&information><:@20> <&furtherOne><.+n> information further one next line with a inf furtherOneContent third line is shorte thefurtherOne
The information in the left column will be clipped because of the <:@20>
. The spaces after <:@20>
ensure a proper readability.
<+out>#define <&name><:@20:1> <&value><.+n> #define myName value #define aLongLongExplicitelyName value #define otherName otherValue
The information will never be clipped. This is an example of a generated C file. The value may be better able to read in a column orientation, but the correct syntax is prior.
Instead a constant value an expression can be used to calulated the column. Usually that is a given numeric value in a variable:
<+><:@ indent : 2> text<.+>
This text has an indentation which is given in the variable indent
.
<+><:@2*recursion> +--<&treecontent><.+>
It shows a tree with indentation depending on tree depth given in a variable recursion
.
Topic:.JZtxtcmd.text.data.
The text can contain variable values of course. One should use
<&any.datapath>
to get data from any location. The any.datapath
is the same like in assignments to String
variables, see the whole chapter 9 Data and variables, the syntax of datapath
in 16.9 Text value: textDatapath, textValue and syntax: 16.11 DataPath, Data access. All non-textual Objects are converted to its text presentation using the toString()
method of javadoc-oracle/java/lang/Object#toString(). Numeric values are converting using its Standard conversion of the Wrapper types javadoc-oracle/java/lang/Float etc.
Topic:.JZtxtcmd.text..
Since 2016-02:
If a datapath is faulty, an replacement text can be used instead to see the mistake in the output text. Then an 12 onerror - Exceptionhandling] is not necessary. Write
<&my.datapath:?replacement-text>
to output replacement-text
if an error is occurred. Usual one can write:
<&my.datapath:? ?error? > <&datapath?" <--->error<---> ">
to see ?error?
or <--->error<--->
in the output text. Such a label can be searched. The error text can be written in ""..."
if it contains a :
or >
.
Topic:.JZtxtcmd.text..
Numeric types can be converted with a special format. Write
<&datapath:formatString>
with a valid format string of the Java's formatter class javadoc-oracle/java/util/Formatter. Example:
Obj numeric = myData.intvalue; //accesses to any int variable. <+>Value = <&numeric> = 0x<&numeric:%08x><.+>
The JZtxtcmd variable numeric
stores a numeric value, with its Wrapper class javadoc-oracle/java/lang/Integer. Then a text is produces containing the value in decimal (standard) and with the given format String as hexadecimal value.
In this example the replacement on text error is used too with String "?error?". This should be written before the format string. See 16.14 TextExpression
Topic:.JZtxtcmd.text.if.
In a text expression some control statements can be used, see the syntax in 16.9 Text value: textDatapath, textValue.
One can write conditional text using
<:if:condition>conditional text<:elsif:othercondition>the text<:else>else text<.if>
<:if:condition>conditional text<:else>else text<.if>
<:if:condition>conditional text<.if>
Syntactical the conditions are conditionInText
, see 16.12 Condition expression. A condition can be a simple quest whether a variable exists or a data path is valid:
<:if:datapath>
If the datapath is invalid (the destination does not exist), then it is false.
If one write
<:if:datapath !=null>
then an exception is thrown if the datapath is invalid. Because, it is tested explicitely. If a datapath returns a String value, one can use all javadoc-oracle/java/lang/String test capabilties such as
<:if:datapath.to.any.string.contains("check it")>
The
<:if:datapath.to.any.string == "my text">
checks with String.equals("my text")
. !=
is !string.equals()
.
<:if:datapath.to.any.string ?ge "my text">
means is equal or longer which is String.startsWith("my text")
in Java-language.
All other compare operators executes a comparison in alphabetic order.
Numeric values can be calculated and compared, for example
<:if:datapath.to.any.numValue ?ge 345.56>
Note that the operator >
and >=
cannot be used because syntactical conflicts. Use ?gt
and ?ge
instead. <
and <=
can be used because it is not a syntactical conflict. But because better read ability one should use ?lt
and ?le
.
One can use a
<:while:condition>repeated text<.while>
and a container-iteration.
<:for:variable:container>do for all <&variable> elements<.for>
An assignment is possibile writing
<=variable:datapath.toany.value>
<=variable>any text value<.variable>
That assignments may be important in a <:while...>
.
Topic:.JZtxtcmd.text.subtext.
Syntax see 16.18 callSubroutine, callSubtext. and Chapter: 16.5 subroutine.
You can define a subtext or sub routine to produce text inside a given text. A subtext can be defined in two forms:
subtext mySubtext(String arguments) <:>this is the text with <&arguments><.> sub mySubtext(String arguments) { <:>this is the text with <&arguments><.> }
Both forms of definition seems to be similar. The difference is: A subtext can only define one text expression, whereby a
subroutine can be used to do some other text output additionally. Use a subtext
for short texts.
Such a subtext
can be called, the text will be inserted inside any text expression:
<:>...<:call: name: data = anyData, arg2=value> ...<.> <:>...<:subtext: name: data = anyData, arg2=value> ...<.> <:>...<:subtext: "name" :data = anyData, arg2=value> ...<.>
Usage of <call:...
or <:subtext...
is adequate. The name of the subroutine is a textValue, see 16.9 Text value: textDatapath, textValue. Therefore it can be gotten from a variable too writing an &
before the variable name:
<:>...<:call:&nameFromDatapath :data = ...> ...<.>
That is a possibility to invoke several sub texts controlled by data content.
A subtext can be held inside a variable too, see 9.1.9 Subtextvar, Subroutinevar - statements to execute.
Topic:.JZtxtcmd.text..
<:=variablePathString>any text <&content><.=>
<:=variablePathOther = 234> <:=variableAppend += 234>
The first form fills a String variable with a String expression.
The second form defines any expression to set the variable after the =
The third form appends to the variable equivalent to the +=
9.1 Types of variables and their assignment
That assignments do not produce text in the current output.
Topic:.JZtxtcmd.text.file.
The JZtxtcmd knows one main output text file. It is possible that this output file is the approach of the script invocation, the user will get a generated output file from some inputs. Another approach may be, the main output file is the log output of the script running process.
The main output file is given by parameter of the script invocation. This output file is deleted if it is existing and reopened newly. If the output file is locked from another process (opened), the script invocation is aborted with an error. The output file is remaining opened but flushed frequently, so the output can be monitored by the user while reading this file in another process. It is necessary if the main output is used as log.
Nevertheless the script process can have a second log file which is written from some Java methods which uses the log capability
of the message dispatcher. That log can't be controlled by the user, it is a really log of Java processing. That log is given
with the --report:FILE
parameter.
Writing in the main output file is done by writing
<+>text<.+>
wherby text
is a 16.14 TextExpression.
To flush the output one should use a flush operator inside the text:
<+>text<:flush><.+>
or more simple flush with the and tag:
<+>text<.+flush>
or flush in conclusion with a newline:
<+>text<.+n+flush>
like any other text output with <+channel>....<.+n+flush>.
Topic:.JZtxtcmd.gui.
One of the JZtxtcmd script approach is using as batch script only. But on the other hand a graphical user interface can be initialized and used by using proper Java classes. The org.vishia.gral is proper to use for that. Especially building a GUI can be described via a script, which can be a part of the JZtxtcmd script, as text in a String. Subroutines of JZtxtcmd can be used inside a Graphical User Interface as action code. for fields, buttons etc.
String guicfg = <:> @primaryWindow, 3-2++,0+5: Text("Mini-GUI"); @5-2,0+10: Text("script controlled via <&scriptfile>"); @10-4,0+45: InputTextline(%t:"Tracefile (d&drop)", name=inputfile, dropFiles="dropFile"); @14-3,33+12: Button(TestButton, "read & check", action=readCheck); @18-4,0+45: InputTextline(%t:"Out dir (d&drop)", name=outDir, dropFiles="dropFile"); @22-4,0+4: InputTextline(%t:"Nr trace 1..4", name=nrTrace); @22-3,33+12: Button(TestButton, "convert", action=convertCsv); @24+20,0+45: OutputBox(name=outTexts); <.>; Obj gralActions = java new org.vishia.gral.ifc.GralActionJztc(jztc, out); gralActions.add(jztc.sub("readCheck")); gralActions.add(jztc.sub("convertCsv")); gralActions.add(jztc.sub("dropFile")); Obj window=java org.vishia.gral.cfg.GralCfgWindow.createWindow("MLtraceGui", "Trace GUI ML", "C", guicfg, null, console); text = window.getWidget("outTexts"); main(){ while(!window.isGraphicDisposed()) { jztc.sleep(1000); } } sub readCheck(){ String sfile = window.getTextFrom("inputfile"); <+out>read and prepare <&sfile><.+n> Filepath file = &sfile; ....
This example creates a Window with content given as script in guicfg
. The sub routines as action should be registered in the shown form. The Subroutines are executed as callback from the buttons
etc. in an extra thread created in the class srcJava_vishiaGui/org/vishia/gral/ifc/GralActionJztc which creates a thread in srcJava_Zbnf/org/vishia/cmd/JZtxtcmdThreadQueue. For this reason the actions are not executed in the graphical thread, but one after another. If you press several buttons
fastly one after another, the sub routines will be executed in a few milliseconds usually, but the graphic does not hang in
any case, also if the execution needs some more time for example for converting routines.
Topic:.JZtxtcmd.debug.
A JZtxtcmd script should be simple and short. Usual a well running script is modified and tested. Any small-step modification should be tested. Errors can be seen in comparison of the last well running version to the changes. It is the recent strategy of scripting.
If special java routines should be used, the associated javadoc should be read well. Then test...
Topic:.JZtxtcmd.debug.syntax.
While invocation JZtxtcmd the given script is translated complete firstly. If any syntactical error is found, an error message like
JZtxtcmd - Error parsing genscript; Parse ERROR at input:2202(0x89a) >>>>call TestResult.replenish(arg=map);| <+out>testResult() - replenish; <&map.re expected: ---------------------------------------------- "." in topLevelSyntax.subClass.subroutine.statementBlock.statement.DefVariable.DefMapVar.variable. ";" in topLevelSyntax.subClass.subroutine.statementBlock.statement. founded before: ---------------------------------------------- [184..187]<...?datapath> syntax=? input=0..0(78, 51) read: "result.anotherOne" xmlNode=<datapath>...</> [185]<...?startVariable> identifier:result syntax=$ input=0..0(0, 0) xmlNode=result
One can report the syntax with invocation
java -cp $CLASSPATH org.vishia.zcmd.JZtxtcmd --help
or check the syntax in this documentation. The syntax error shows that position in the text where the parser has failed. Often
the mistake is on position before that. The expected:
names the nesting of syntax component and the characters which where expected there.
In that example a ;
is missing only on the last statement. The parser cannot know that you have forgotten a semicolon. The parser thinks the
last statement should be continued. The second expected:
proposal names the error in fact, the missing semicolon on statement end. But the parser expects that the last written text
may be a variable path which is incomplete. Which of that expected:
things are correct, one can desired on viewing the text before.
Additional the parser reports what is accepted before. In this case it is a datapath. View the syntax of datapath
. After a startvariable
some more path elements separated with a dot may be expected.
The output of the syntax error is the standard behavior of a ZBNF-parser.
Topic:.JZtxtcmd.debug.xmlSrc.
Sometimes there may be differences in interpretation of the source code of a JZscript. The JZscript will be parsed with a ZBNF parser. That parse result can be shown in XML format to check only the parser. Write on the first line:
!checkXml = "path/to/checkfile.xml";
Then the parser's result will be written in that file in XML format.
You can use
!checkXml= <:><:scriptdir>/test.xml<.>;
instead to write it in the directory of the script.
Note that included scripts are not regarded.
On the other hand you can write:
!checkJZtxtcmd = "path/to/checJzcmd.txt";
That writes a text file which contains the 'toString()'-result of all statements in the script, included scripts regarding. This second form representates that data, which are converted from the parser's result (able to show with XML) into the internal presentation.
Topic:.JZtxtcmd.debug.onerror.
A static language tests as soon as possible mistakes on compile time. But a dynamic language accepts some constructs which's
mistakes are obvious on run time only. For example a static language tests types of arguments of a subroutine. The JZtxtcmd
dynamic language does not distinguish types, like other dynamic languages. An Obj
type can contain any Object. Whether it is matching to a called Java subroutine, it can be checked on runtime only.
If any dissonant constellation are ascertain on run time, an exception is thrown by the Java execution process. One can use
an onerror
construct in the JZtxtcmd script:
doAnything in the script; do next; onerror { <+out>Error on xyz; <&error><.+n> }
If an exception is thrown, the next following onerror
block is executed. The error
variable should contain a significant text about the mistake. It is outputted on console in this example. The console may
be redirect in a message system. With that stuff the error may be able to interprete by the user.
If the error is not catched in that level, it may be catched in the calling level. Last not least the JZtxtcmd class aborts and reports.
The error variable contains the Java-Exception class name, the exception message text, the file and source line and column and a short notification of the JZtxtcmd statement where the error occurs. For example in a subroutine a faulty variable is used. The error is catched in the level above.
The following text is outputted:
Topic:.JZtxtcmd.debug.JZtxtcmdTester.
The JZtxtcmd knows a variable test
which refers an instance of srcJava_vishiaBase/org/vishia/cmd/JZtxtcmdTester. This class has some capabilities for output data for test.
The following statement writes a line which contains the information about the type and the toString()
-value of data:
out += test.infoln("my info", data); //appends a line with info <+out>it is the same: my info<&test.info(data)>, maybe some more in the line <.+n>
The following statement writes the internal data of an instance which is able to address with a datapath:
test.dataTree(data, out, 1); <+> <&test.dataTree(path/to/data, out, 1)> <.+>
The third argument 1
is the deepness of data, used if references are used in the instance. It can be set to any number of deepness. Then referenced
data and the references their etc. are shown too.
The out
is the standard output. You can use any Appendable
object, especially to get the information in a file:
Openfile outfile = "path/to/myFile.txt"; test.dataTree(data, outfile, 3); outfile.close(); //don't forget to close!
It is possible to write that information with a html format:
Filepath htmldata = "path/to/myFile.html"; test.dataHtml(data, htmldata);
This is the most complex but recommended form to output the data which can be used in a script. Usual the root data in a special script may be outputted. The html file contains the data of the given instance and all referenced instances. The references instances are written independent, not in form of a tree. The references are presented in html as hyperlinks inside that html document. With the known usability of following links and switch back of a browser the referenced data can be evalated. That can help to write a JZtxtcmd script:
Topic:.JZtxtcmd.debug.eclipse.
The JZtxtcmd can be executed in an Eclipse or another integrated development environment. You don't need to understand the whole source code of the translator javadocPriv-Zbnf/org/vishia/zcmd/JZtxtcmd and interpreter javadocPriv-vishiaBase/org/vishia/cmd/JZtxtcmdExecuter. It is sufficient to view to some details, set a breakpoint, view data etc.
Especially if Java routines of the user are invoked inside the user's JZtxtcmd script, the user can set a breakpoint and debug its own routines. On return of this routines it returns to the JZtxtcmdExecuter loop, see the stacktrace of debugging.
Set a breakpoint on start of your method in class.
Check whether this method is called really.
Check the arguments
Check the details.
break on access to any data:
If any variable or a method is not is not found, you can set the following instruction line before that access:
java org.vishia.util.DataAccess.debugIdent("myData"); myData.myMethod(args);
The first instruction sets a (non-threadsafe) debug comparison String in the class DataAccess. If that indentifier is used then it forces the execution of srcJava_vishiaBase/org/vishia/util/DataAccess#debug() where a breakpoint can be set. There you can visit given variables, methods etc. with the debugger variable context maybe especially in the given localVariables.
You can set a break for a found method but with argument problems by setting:
java org.vishia.util.DataAccess.debugMethod("myMethod"); myData.myMethod(args);
The next instructions in DataAccess
checks the actual arguments, which may be faulty.
break in the execution loop of JZtxtcmd:
If any of the execution of the JZtxtcmd script seems to be obscure, you can insert a debug
statement bevor the obscure statement:
...jztxtcmd statements debug "my text"; debug <:>any <&variable>-expression<.>; debug; obscure statements; ... <+out> any text <:debug:"my text"> <&obscureData><.+> <+out> any text <:debug> <&obscureData><.+>
On a debug statement the method javadocPriv-vishiaBase/org/vishia/cmd/JZtxtcmdExecuter.ExecuteLevel#debug(org.vishia.cmd.JZtxtcmdScript.JZtxtcmditem)
int debug(JZtxtcmdScript.JZtxtcmditem statement) //throws Exception { try{ CharSequence text = evalString(statement); } catch(Exception exc){ //unexpected } Assert.stop(); return 1; }
is executed. You can set a breakpoint to the stop()
line. The text
should be set with your "my text"
of the debug-statement. If this statement returns, it continues in the interpreter loop of the JZtxtcmd script. The next
statement will be the 'obscure' one. You can study whats happen.
Topic:.JZtxtcmd.syntax.
This chapter describes the exact formal syntax which is used to parse the script. The syntax is shown both in ZBNF and in a more readable explaination format. The internal used ZBNF-Syntax-Script is contained in the Java-class javadoc-Zbnf/org/vishia/zcmd/JZcmdSyntax. You can invoke JZtxtcmd from command line to output the syntax with the help text:
java -cp path/to/zbnf.jar org.vishia.zcmd.JZtxtcmd --help:helpoutput.txt
Details of the syntax may be changed in further development. Therefore see and compare that help output.
Topic:.JZtxtcmd.syntax.script.
The syntax starts with some common settings and the definition of the top-level component, the frame of a script.
$comment=(?...?). $endlineComment=\#\#. ##The ## is the start chars for an endline-comment or commented line in the generator script. $keywords= new | cmd | cmd_check | start | debug | java | stdout | stdin | stderr | subtext | sub | main | call | cd | CD | REM | Rem | rem | Pipe | StringBuffer | Stringjar | String | List | Openfile | Fileset | Obj | Set | set | include | zbatch | break | XXXreturn | exit | onerror | instanceof | for | while | do | if | elsif | else | throw .
The syntax of the whole script is given with:
JZtxtcmd::= [<*|==JZtxtcmd==?>==JZtxtcmd== ] [<*|==JZcmd==?>==JZcmd== ] [{ ! checkjzTc = <textValue?checkJZcmdFile> ; | ! checkJZcmd = <textValue?checkJZcmdFile> ; | ! checkXml = <textValue?checkXmlFile> ; }] [{ [REM|Rem|rem] <*\n\r?> ##Remark like in batch files | include <include> ; | currdir = <textDatapath?cd> ; }] .....
It contains:
==JZtxtcmd==
: Start marker: A JZtxtcmd script can contain some other text, especially a start sequence of a batch file or a shell script.
One can write for example a windows batch file which invokes java ... JZtxtcmd thisScript
and exit
then. After them the ==JZtxtcmd==
label is written. The parser skips over the whole text before the first ==JZtxtcmd==
is found. The syntax means, all text will be skipped if the marker ==JZtxtcmd==
will be found. If that marker is not found, nothing is skipped. Note: Don't write that marker inside a JZtxtcmd source.
checkJZcmd = ...
: Test outputs: On start of script it is possible to define output files for test.
include
: included Scripts, see 16.3 The include statement and 6.2 Included scripts
currdir..: See Chapter: 7.3 currdir, cd statement
Topic:.JZtxtcmd.syntax..
The syntax of the JZtxtcmd::=....
continues with
..... { [//] ==endJZcmd==<*\e?> | [REM|Rem|rem] <*\n\r?> ##Remark like in batch files | //JZtxtcmd ##ignore //JZtxtcmd, it may be a comment for another language | //JZcmd ##ignore //JZcmd, it may be a comment for another language | //<*\n\r?> ##line comment in C style | /*<*|*/?>*/ ##block commment in C style | <DefVariable?> ; | <statement?> | subtext <subtext?subroutine> | sub <subroutine> | class <subClass> | main ( ) \{ <statementBlock?mainRoutine> \} } \e.
Topic:.JZtxtcmd.syntax...
It is possible to set an end marker in the text. It is is detect, all content till the end of the file will be skipped. <*\e?>
means, skip all till the end of file, without semantic meaning.
{ [//] ==endJZcmd==<*\e?>
Topic:.JZtxtcmd.syntax..comment.
Comments can be given with starting from ##
to the line end or between (? comment ?)
. That comments are ignored in the parsing process.
Additional the //
and the /* ... */
can be used for comments like in Java or C. That comments are formally parsed, they are visible in the parsers result xml
file with option -debug:file
, but they are ignored for execution.
| [REM|Rem|rem] <*\n\r?> ##Remark like in batch files | //JZtxtcmd ##ignore //JZtxtcmd, it may be a comment for another language | //<*\n\r?> ##line comment in C style | /*<*|*/?>*/ ##block commment in C style
Topic:.JZtxtcmd.syntax..var.
The <DefVariables?>
enables the declaration of variables on script level. The variables can be declared between routines and classes. But they
are visible and created all on start of execution.
| <DefVariable?> ; | <statement?>
Topic:.JZtxtcmd.syntax..main.
The script consist of definition of sub
, subroutines and classes and the main routine. All of it can be contained more as one time in any order.
| subtext <subtext?subroutine> | sub <subroutine> | class <subClass> | main ( ) \{ <statementBlock?mainRoutine> \} } \e.
Topic:.JZtxtcmd.syntax.include.
The path can be given starting with an optional environment variable, optional continued with a path.
include::= [$<$?envVar>[/|\\]][ <""?path> | <*;\ ?path>].
Topic:.JZtxtcmd.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.
Topic:.JZtxtcmd.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.14 TextExpression, it contains a <textExpr>
itself. The procedures for calling are the same.
Topic:.JZtxtcmd.syntax.stm.
Syntax:
statementBlock::= { <statement?> }. statement::= \{ [<statementBlock>] \} | REM <*\n\r?> ##Remark like in batch files | ::{:} ##Skip over ::: | =={=} ##Skip over ::: | //JZtxtcmd ##ignore //JZtxtcmd, it may be a comment for another language | //JZcmd ##ignore //JZcmd, it may be a comment for another language | //<*|\n|\r|\<+?> ##line commment in C style but only till <+ | /*<*|*/?>*/ ##block commment in C style | text = <textValue?createTextOut> ; ##set text output | currdir = <textDatapath?cd> ; ##set current directory | [cd|CD] [<textValue?cd> | <*\ ;?cd> ; ] ##change current directory | mkdir <textValue?mkdir> ; ##create any directory if not exists | <DefVariable?> ; | for <forCtrl> | if <ifCtrl> | while <whileCtrl> | do <dowhileCtrl> | start <cmdLine?cmdStart> | zmake <zmake> | move <srcdst?move> ; | copy <srcdst?copy> ; | [rm|del] <oneArg?del> ; | break <?breakBlock> ; | return <?return> ; | exit <#?exitScript> ; | throw on errorlevel <#?throwonerror> | throw <textDatapath?throw> | onerror <onerror> | errortoOutput off <?errorToOutput=0> | errortoOutput <?errorToOutput=1> | if errorlevel <iferrorlevel> | debug [<textValue?debug>| <?debug>] ; | debugOp <textValue?debugOp> ; | <callSubroutine?call> | <threadBlock> | \<+:create\><textExpr?createTextOut>\<\.+\> | \<+:append\><textExpr?appendTextOut>\<\.+\> | \<+ <textOut> | \<:\><textExpr?.indent=-3>\<\.\> [;] | <cmdLineWait?cmdWait> | <assignExpr> | ; . srcdst::= [{ -n<?newTimestamp>| -w<?overwr> | -r<overwro>}] [ src=] <textValue?src> [ dst=] <textValue?dst> . oneArg::= <textValue?src> .
Topic:.JZtxtcmd.syntax.var.
See
DefVariable::= String\ <DefStringVar?textVariable> | Stringjar\ <DefSpecVar?Stringjar> | Num\ <DefNumVar> | Bool\ <DefBoolVar> | Pipe\ <DefSpecVar?Pipe> | List\ <DefSpecVar?List> | Map\ <DefMapVar> | Obj\ <DefObjVar> | Class\ <DefClassVar> | Classpath\ <DefClasspath> | Openfile\ <Openfile> | Fileset\ <DefFileset> | Filepath\ <DefFilepath> | Set\ <DefStringVar?setEnvVar> | set\ <DefStringVar?setEnvVar> | SET\ <DefStringVar?setEnvVar> .
The syntax component <DefVariable?>
is used both in the script outside of routines for script variables, 16.1 The head of a script in classes and in the body of routines, see $chapter. The first one builds script variables, the second and third one builds variables valid in its class or routine context non
stored outside of the class or subroutine execution time.
See 16.11 DataPath, Data access how access variables.
DefNumVar::= [const <?const>] <definePath?defVariable> [ = <numExpr>]. DefBoolVar::= [const <?const>] <definePath?defVariable> [ = <boolExpr>]. DefList::= [const <?const>] <definePath?defVariable>
[ = [ {<?element> { <dataStruct?dataSet> } ? , } ] ##some { dataSet, ...}
= [ <dataStruct?> ] ##some String or variable (const) definitions in the container.
= <objExpr?> [!;]
= [ { <objExpr?objElement> ? , } ]
].
DefSpecVar::= [const <?const>] <definePath?defVariable> [ = <objExpr?>]. DefObjVar::= [const <?const>] <definePath?defVariable> [ : <$\.?type>] [ = <objExpr?>]. DefClassVar::= [const] <definePath?defVariable> = [: <dataAccess?loader> : ] ## a datapath to a ClassLoader instance, a Classpath variable. <textValue?>. ## The package path maybe contained in any expression DefClasspath::= [const] <definePath?defVariable> = [ : <$?parentClasspath> : ] { <filesetAccess> ? , }. DefStringVar::= [const <?const>] <definePath?defVariable> [ = <textDatapath?>]. DefMapVar::= [const <?const>] <definePath?defVariable> [ = \{ <dataStruct> \} ]. Openfile::= [const <?const>] <definePath?defVariable> = <textDatapath?> .
The variable is defined like a datapath, though it is not an access path but an path which defines a variable.
definePath::= <$-?startVariable>[ [?\. \>] \.{ <defineSubelement?datapathElement> ? [?\. \>] \.}]. defineSubelement::= <$-?ident> [( [{ <objExpr?argument> ? ,}])<?whatisit=(>].
A definePath
for a variable starts with an identifier. An identifier is written like in Java, C or the most other programming languages.
The character -
is admissible too inside the identifier. An identifier can be written for example my-variable
. It does not contain any $
. The so named start variable is member of the datapool of a JZtxtcmd execution environment. A new defined variable will be
added to this pool, but only valid for the execution level, in the current subroutine.
A variable
can be continued with defineSubelement
which can be either a variable identifier or a method call. But the last member of that should be a simple variable ident
. It is not shown in syntax, only checked on run time.
In this kind it is possible to create a tree of variables. If a subroutine needs some variables, one does not need to offer all variables as parameter singly by singly. One can build a proper local datapool and offer this pool as variable to the subroutine. See 16.18 callSubroutine, callSubtext. Another possibility is adding a variable in a Map-container inside any user-Java-class.
A variable in an container is always an instance of javadoc-vishiaBase/org/vishia/util/DataAccess.Variable. A defineSubelement
can describe a field or method inside any (user-) Java class, see javadoc-vishiaBase/org/vishia/util/DataAccess.access(...).
The value after the =
is the initial value of the variable. It is necessary, if the variable is const
, elsewhere it is optional. See next chapter. On Openfile
it is necessary, it's the file name.
Topic:.JZtxtcmd.syntax.filepath.
DefFileset::= <definePath?defVariable> [ = ( [ commonpath = [<""?commonPath>|<*;,)(\ \r\n?commonPath>] , ] { [{ //JZtxtcmd | //<*\n\r?>}] [<""?filePath>|<*;,)(\ \r\n?filePath>] [{ //JZtxtcmd | //<*\n\r?>}] ? , } ) ] .
A Fileset is a variable with the same definition context possibilities like any other variable. It is constant initialized
by a list of <Filepath>
and maybe a commonpath
which is used as base path for all files.
DefFilepath::= <definePath?defVariable> [ = <textValue?> ].
A Filepath is a variable with the same definition context possibilities like any other variable. It is constant initialized
by a <Filepath>
. A Filepath
is written either in ""
or as character string till a whitespace or till a ;
. The prepFilePath
-syntax is applicated to that parse result:
prepFilePath::=<$NoWhiteSpaces><! *?> [ &$<$?@envVariable> [\\|/|] ##path can start with a environment variable's content | &<$?@scriptVariable> [\\|/|] ##path can start with a scriptvariable's content | [<!.?@drive>:] ## only 1 char with followed : is the drive letter [ [/|\\]<?@absPath>] ## starting with / maybe after d: is absolute path |] [ <*:?@pathbase>[?:=]:] ## all until : is pathbase, but not till a := [ <toLastChar:/\\?@path>[\\|/|]] ## all until last \ or / is path [ <toLastChar:.?@name> ## all until exclusive dot is the name <*\e?@ext> ## from dot to end is the extension | <*\e?@name> ## No dot is found, all is the name. ] .
The String definition of a Filepath is divided in the parts like shown. Note that a Filepath can contain either the identifier of an environment variable or of a JZtxtcmd-Scriptvariable as start of the path. The content of the variable is evaluated on access to the Filepath. See javadoc-vishiaBase/org/vishia/util/FilePath.
The Filepath is tokenized in its part from the Constructor javadoc-vishiaBase/org/vishia/util/FilePath#FilePath(java.lang.String) in the same way like shown here with an Java core algorithm.
Topic:.JZtxtcmd.syntax.textDatapath.
A text expression presents a String:
textDatapath::= <""?text> | \<:\><textExpr>\<\.\> | [& [?(] ] <dataAccess> . textValue::= <""?text> | \<:\><textExpr>\<\.\> | & <dataAccess> | <*;,)(\ \r\n\>?text> . textValueTextExpr::= <""?text> | \<:\><textExpr>\<\.\> | & <dataAccess> | <*:;,)(\ \r\n\>?text> .
There are two forms. The textDatapath
is used in a normal programming environment. The textValue
is used in that syntactical contexts where a simple text value is expectable. Without quotion marks, a text value is supplied: cmd myCmd.exe
Such an constant text ends respectively cannot contain the characters *;(
and spaces because that are following syntactical characters. A textValue
allows to write more simple in the script.
For textExpr
see 16.14 TextExpression
The datapath
can access either to a location which contains text, or to a location which does not contain text. If a text is expected
in the running context, a non-text will be converted to text calling the toString()
operation of the gotten instance.
Topic:.JZtxtcmd.syntax.objExpr.
An objExpr
which presents any Object to assign to a variable or used for a calling argument is defined as
objExpr::= | Filepath : <textValue?Filepath> ## A textValue which builds a Filepath in the currdir | Fileset: <filesetAccess> | \{ <dataStruct> \} ## It is a Map of Variables. | <""?text> ## It is a constant text. | \<:\><textExpr>\<\.\> ## It is a text assembled in runtime. | <numExpr>. ## special detection of a simple dataAccess. dataStruct::= { <DefVariable?> ; } | { <DefStringVar?textVariable> ? , }.
It is either a text, an concatenation of texts, an access to data or a complex boolean or numeric expression. If the numExpr
only contains a DataPath it is stored as simple dataAccess.
The dataStruct
is a special form which can be used to build a Map of Objects to store as one Object.
If the type File:
is given a textual expression is converted to a java.io.File-instance on runtime.
If one of the types Filepath
or Fileset
are given a texual expression or the special syntax of an filesetAccess
is converted to the types javadoc-vishiaBase/org/vishia/cmd/JZcmdFilepath respectively javadoc-vishiaBase/org/vishia/cmd/JZcmdAccessFileset.
Topic:.JZtxtcmd.syntax.DataAccess.
See
9.9 Access to Java internal data
dataAccess::= [ $<$?envVariable> | [<?startVariable> $<#?>| $<$?>] ## $1 .. $999 are the arguments of JZtxtcmd, $name for environment | [java\ ] new\ <staticJavaAccess?newJavaClass> | [%|java\ ] <staticJavaAccess?staticJavaMethod> | <dataPath?> ].
For variable
see 16.7 Variables. The same syntax is used to describe an access to a variable and describe the path to create a variable. The difference in
runtime is: The last element of an access can be a method invocation. The elements should be existing.
Inside a data path a new Java instance can be created, see 9.11 Creation of new instances of Java classes or a static method can be accessed either with the keyword java
or a simple %
on start of the path to the Java class. See 9.10 Access to static Java data and Invocation of static Java methods. Both expressions need a package-path to the Java class and the constructor- or the method-name.
A Class
-variable can be used instead a direct given package path. Note that a few Classes are given by 9.5 Predefined script variables. The Class
-variable can be located anywhere in the JZtxtcmd script or in any Java data context. Therefore it is written as & <dataAccess?classVar> :
itself.
The package path can be located in another jar file which is defined with a Classpath
-Variable.
Therefore an access to static elements of a Java class can be written with the syntax:
## Access to a Java class constructor or static method or field staticJavaAccess::= [ & <dataAccess?Class_Var> : [<$\.$?javapath>] ## access via Class variable .element | [: <dataAccess?Classpath_Var> : ] <$\.$?javapath> ## [Classpath] package.path.Class.element ] [( [ { <objExpr?argument> ? , } ])]. ## arguments
A dataPath
is used to address any field or method in a Java class or any member of a Map in a path.
dataPath::= [ File : <textValue?File> ##creates a file object with given path | <startDatapath> ] [ [?\. \>] \.{ <datapathElement> ? [?\. \>] \.}]. ## A datapath cannot start with an JZtxtcmd keyword! startDatapath::= <?whatisit=@> [ & ( <dataPath> ) ##takes the result of <dataPath> as name of an element or method. | <$-?ident> ][ ( [{ <objExpr?argument> ? ,}]) <?whatisit=(> ##a method | \[ <#?index> \] <?whatisit=\[> ##an indexed array access |]. datapathElement::= [ & ( <dataPath> ) ##takes the result of <dataPath> as name of an element or method. | ##Field or method identifier, use regex for the second datapath element, it can be a JZtxtcmd keyword too! [<?ident> [@] [\[\] ##[] instead name for length operation. | <![\\w-]+?>] ##name as regex or [] for length of array or size() of container ] ][ ( [{ <objExpr?argument> ? ,}]) <?whatisit=(> ##a method | \[ <#?index> \] <?whatisit=\[> ##an indexed array access |].
An indentifier of a datapath element can start with @
especially to access to a XML tree, to the attributes.
Topic:.JZtxtcmd.syntax.condition.
A condition is a boolean expression:
condition::=<andExpr?> [{\|\| <?boolCheckOrOperation> <andExpr?boolOrOperation>}]. andExpr::= <boolExpr?> [{ && <?boolCheckAndOperation> <boolExpr?boolAndOperation>}]. boolExpr::= [<?boolNot> ! | not| NOT|] [ ( <condition?parenthesisCondition> ) | <numExpr?> [<cmpOperation>] ]. cmpOperation::=[ \?[<?cmpOperator>gt|ge|lt|le|eq|ne|instanceof] | [<?cmpOperator> != | == | \>= | \> | \<= | \< ]] <numExpr?>. instanceof::=<objExpr> instanceof <staticJavaAccess>.
Because the cascade of or operations with andExpr
which can contain and operations, that contains an boolExpr
with comparison, the rule of higher priority of
cmp
and
or
is met. The boolExpr
can contain the unary not able to write with !
like in C, Java or with the keyword not
which may be better able to read. (...)
-parenthesis conditions are possible too.
The compareOperation
defines additional to the known compare operators from Java, C and the most other programming languages the operators written
with:
?gt
greater then, >
?ge
greater or equal, >=
?lt
less then, <
?le
less or equal, <=
?eq
equal, ==
?ne
not equal, !=
This writing possibility should be used especially in text expressions, where the >
may have another meaning (closing of a tag).
For text expressions the adequat syntax components are given. The only one difference is the absence of the >
etc. comparison operators.
conditionInText::=<andExprInText?> [{\|\| <?boolCheckOrOperation> <andExprInText?boolOrOperation>}]. andExprInText::= <boolExprInText?> [{ && <?boolCheckAndOperation> <boolExprInText?boolAndOperation>}]. boolExprInText::= [<?boolNot> ! | not|] [ ( <conditionInText?parenthesisCondition> ) | <numExpr?> [<cmpOperationInText?cmpOperation>] ]. cmpOperationInText::=[ \?[<?cmpOperator>gt|ge|lt|le|eq|ne] | [<?cmpOperator> != | == ]] <numExpr?>.
Topic:.JZtxtcmd.syntax.numExpr.
numExpr::= bool ( <boolExpr?> ) | <multExpr?> [{ + <multExpr?addOperation> | - <multExpr?subOperation>}]. multExpr::= <value?> [{ * <value?multOperation> | / <value?divOperation> }]. value::= 0x<#x?intValue> | <#?intValue>[?\.] | <#f?doubleValue> | ##unary - associated to value. [{[<?unaryOperator> ! | ~ | - | + ]}] ##additional unary operators. [ 0x<#x?intValue> | <#?intValue> ##ones of kind of value: | '<!.?charValue>' | <""?textValue> | ( <numExpr?parenthesisExpr> ) | [& [?(] ] <dataAccess> ## & is optional, don't confuse with &(variable) ].
Because the cascade of + - operations with multExpr
which can contain * / operations, that contains an value
, the rule of higher priority of
parenthesis, functions, any values
* /
+ -
is met. The value
can contain the unary ! ~ - + operators and (...)
-parenthesis like in C, Java.
A non const value comes from a datapath
, see 16.11 DataPath, Data access and $chapter, 9.9 Access to Java internal data. If that results are used for numeric expressions, they should be of an numeric type or they should be a String which is
able to translate in a numeric type. That translation rules are processed in the javadoc-vishiaBase/org/vishia/util/CalculatorExp. In a JZtxtcmd variable a numeric wrapper type such as javadoc-oracle/java/lang/Float can be stored.
All numeric methods of the Java standard class javadoc-oracle/java/lang/Math can be used.
Topic:.JZtxtcmd.syntax.textExpr.
See 13 Text output and text generation
textExpr::=<$NoWhiteSpaces> { [?\<\.] ##abort on <. [ \<&-<*\>?>\> ##<&- it is comment> | \<:---\><*|---\>?>\<---\> ##<:---> comment <---> not confused with XML <--- will be produced as output ---> | \<:-<*\>?>\><textExpr?>\<\.-<*\>?>\> ##<:-comment> comment <.- > | \#\#<*\r\n?> ##comment to eol in a text Expression | \<:\{ <statementBlock?> <!\\s*> \}\> ##one or more statements inside a text expression, do not produce an output text. | \<:for:<forInText?forCtrl> | \<:if: <ifInText?ifCtrl> | \<:hasNext\> <textExpr?hasNext> \<\.hasNext\> | \<:subtext : <callSubtext?call> | \<:call : <callSubtext?call> | \<:scriptdir<?scriptdir>\> | \<:debug[:<textDatapath?debug>| <?debug>]\> | \<&<dataText> | \<: [<?transliteration>n|r|t|b|[\<|#|\"]<*\>?>] \> | \<:[<#?utf16code>|x<#x?utf16code>]\> | \<:lf\><?newline> | \<:\ \><!\\s*?> [ \#\#<*\r\n?> <!\\s*?> ] | \<:s\><?skipWhiteSpaces> | \<:@<setColumn>\> | \<:<DefVariable?>\> | \<:\><textExpr?>\<\.\> | <*|\<:|\<&|\#\#|\<\.?plainText> ] }.
Text expressions are used either to output text in 16.6 statements <+textout>
or for textual arguments and values. Generally all white spaces in the text are used. The tag <$NoWhiteSpace>
in the syntax means, that whitespaces in the syntax have not the meaning to skip over the whitespaces in the parsed text.
Therefore all white spaces of the parsed text are read. The text can contain the named control elements and the possibility
of values with format dataText
:
dataText::=<dataAccess>[ \:\?[<""?errorText>|<*\>:?errorText>]][ \: [<""?formatText>|<*\>?formatText>]] \>.
A <:n>
produces a new line with the requested coding like given as calling argument of JZtxtcmd (0x0d, 0x0a, only 0x0a, only 0x0d).
The transcription
of some special characters is possible:
<:n>
produces a newline character in the text (0x0a).
<:r>
produces a return character in the text (0x0d).
<:t>
produces a tabulator character in the text (0x09).
<:<>
produces a <
character in the text. With them a text can output the character combination <:
and <*
using <:<>:
and <:<>*
.
<:#>
produces a #
. With them a text can output a ##
The <: >
overrides all whitespaces. It is the possibility to wrap text where the generated text should not wrapped.
The ##
comment is recognized especially, because the comment functionality of the parser is switched off too in the <$NoWhiteSpace>
-mode. Note that the syntax should contain \#\#
instead a simple ##
because elsewhere it is a comment in the syntax.
Note that a
//comment <+>text...
does not ignore a start of a text output on the same line. This capability is proper for writing text output in a right column whereby statements are written left. To ignore lines which contain text output use:
##comment <+>inclusively ignore the text output<.+>
Topic:.JZtxtcmd.syntax.textOut.
See 13 Text output and text generation.
textOut::= [<dataPath?assign>] [:n<?newline>] \> [<textExpr>] [ \<\.+\> ## end text variants: | \<\.n+\><?newline> | \<\.+n\><?newline> | \<\.+n+flush\><?newline><?flush> | \<\.+flush\><?flush> | \<\.+n+close\><?close> | \<\.+close\><?close> ]. setColumn::=<numExpr> [ : <numExpr?minSpaces>] | : <numExpr?minSpaces>.
Note: in
statement::= | \<+ <textOut>
The textOut
appends the text between <+variable>...TEXT...<.+> to the variable. The variable should be an Appendable type. See 16.7 Variables. It is either an
Openfile, a
Stringjar, a
Pipe or any other
Obj which is of type javadoc-Oracle/java/lang/Appendable. That is checked on Runtime.
The Indentation of the plainText
is realized with storing the column position where the syntax component <textOut>
starts. It is after the <+
because the white space is parsed inside the syntax component.
Topic:.JZtxtcmd.syntax.ctrl.
Program flow control is used both in statements of the script and it is possible inside a text expression.
See 16.6 statements
See $chapter
forCtrl::= ( <$?forVariable> : <dataAccess?forContainer> [ && <condition> ]) \{ <statementBlock> \} . forInText::= <$?forVariable> : <dataAccess?forContainer> [ && <condition> ] \> <textExpr> \<\.for[ : <$?@checkForVariable> ]\>. ##name is the name of the container element data reference
That control statements iterates over any container, which is gotten from any Java data context. For example and especially
it is a result of a parsing process. The datapath
should describe a path to either a javadoc-oracle/java/util/Iterable, a javadoc-oracle/java/util/Map or to any array type. The Map
will be iterated over its ValueSet
whereby the forVariable
gets the values. The key of the Map element is not used. Usual the key information may be found in the value too. The forVariable
gets the reference to one element of the container for any repetition.
Additionally a for
can be terminated if the optional condition
is false. Therewith it is possible to iterate over an container but abort that iteration if anything was found there.
ifCtrl::= <ifBlock> [{ elsif <ifBlock> }][ else \{ [<statementBlock?elseBlock>] \} ]. ifBlock::= ( <condition> ) \{ <statementBlock> \} . ifInText::= <ifBlockInText?ifBlock> [{ \<:elsif : <ifBlockInText?ifBlock> }][ \<:else\> <textExpr?elseBlock> ] \<\.if\>. ifBlockInText::= <conditionInText?condition> \> <textExpr>.
To support a chain of if blocks any number of elsif
can be used. It is the same like else if(condition){...}
in Java or C/C++.
whileCtrl::= ( <condition> ) \{ [<statementBlock>] \} . dowhileCtrl::= \{ [<statementBlock>] \} while ( <condition> ) ; .
Both while forms are known in other programming languages.
The JZtxtcmd does not support a switch-case
. Adequate the if..elsif
may be used. Secondary a simple for(int var...)
with an numeric index is not supported. Use while(...)
instead, it does the same.
Topic:.JZtxtcmd.syntax.onerror.
See 12 onerror - Exceptionhandling
onerror::= [ <#?errorLevel> | [<?errortype> notfound | cmd | file | internal | exit ] |] \{ [<statementBlock>] \}.
Topic:.JZtxtcmd.syntax.call.
See
callSubroutine::= [{ <dataPath?assign> [ = | += <?append>] }] call <textValue?callName> ( [{ <namedArgument?actualArgument> ? , }] ) ; . callSubtext::=<textValue?callName> [ : { <namedArgument?actualArgument> ? , }] \>. namedArgument::= <$?name> = <objExpr?>.
A namedArgument
is any expression. If a namedArgument
is designated as Filepath
or Fileset
it has the special syntax of this elements able to use to build such values on the fly on a subroutine call with the Filepath-Syntax for the actual value.
Topic:.JZtxtcmd.syntax.zmake.
See 7.7 Zmake.
zmake::= [ : <$-?name> :[?=] ] ##optional : name : of the zmake target, not ends with := <textValue?zmakeOutput> := <textValue?callName> ( { <namedArgument?actualArgument> | <filesetAccess> ? ,} ). ## An accessPath is a Filepath, see prepFilepath::=, but analyzed on Java level. filesetAccess::= [ <""?accessPath> | \<:\><textExpr>\<\.\> | & <dataAccess> | <*\ \r\n,)&?accessPath> ##will be converted to Filepath maybe with ':' |] [ & <dataAccess?zmakeFilesetVariable>] .
The accessPath can be given as & <dataAccess>
. The distinction between a singulary access path as data Access and the & <dataAccess?zmakeFilesetVariable>
is done with test of the accessed instance. It is checked whether it is a Fileset or not.
The accessPath is converted to a String if it is accessed via & <dataAccess>
. The String-given accessPath is converted to a srcJava_vishiaBase/org/vishia/util/FilePath. In that constructor the String is divided especially into the local path and the base path, separated by the character ':'.
Topic:.JZtxtcmd.syntax.cmd.
See 7.2 start, cmd: Invocation of operation system commands
cmdLineWait::=[{ <dataPath?assign> += }] cmd\ <cmdLine?>. cmdLine::= [\!argsCheck!<?argsCheck>] <textValue?> [{[?;[\ |\n|\r]] [ \<\:arg\><textExpr?actualArgument>\<\.arg\> | \<\:args:<dataAccess?argList>\> |<textValue?actualArgument>] }] [ \<:stdout:[ pipe<?pipe>| [$]<$?stdoutVariable>] \>] ;. iferrorlevel::= <#?errorLevel> \{ [<statementBlock>] \}.
A cmdLineWait
assigns its stdout to the variable(s), see 16.20 Command line invocation
Topic:.JZtxtcmd.syntax.assign.
Syntax:
assignExpr::= [{ <dataPath?assign> [ = | += <?append>] }] <objExpr?> ;.
The assignExpr
is an either an expression without any assign, a procedure call in Pascal-programming language slang. Or it is a function call (Pascal) with or without side effects respectively a simple access to variables (get) or const which value or result may
be assigned to any variables. For the objExpr
see the syntax of 16.10 Object value: objExpr. An assignment can be done for more as one variable, or the objExpr
can be executed without assignment.
The assignment can be an append, especially to a Appendable, Stringjar or Pipe variable. Then the +=
should be written. A Stringjar can be set newly by using a "=". An Appendable or Pipe can't be assigned, only append. If
a =
is used, an IllegalArgumentException is thrown in runtime. See 16.7 Variables and their types.
In opposite to the definition of variables the variable have to be existing. A variable is never created on demand. It is a important property of program safety: In some other dynamic languages a variable is created whenever it is used without explicit declaration. If the programmer writes a false identifier, this error is not detected whether on compile- nor on run-time. The actually meant variable will be unchanged, and a new not used variable will be created. The failure is non-obvious.
The rules for variable in 16.7 Variables are not valid for assignments, because there are not newly created variables. Instead the following rules are valid to recognize the type of a variable:
a) If the found variable is of type srcJava_vishiaBase:_org/vishia/util/DataAccess.Variable, its type is checked, the Object value
should be matched.
b) If the found instance is of type java.lang.Appendable
, the right side String representation is appended to it. If it is an Writer
or such, it is a file writing.
c) If the found reference type matches to the right side instance type, the reference is replaced. In this kind a String reference is replaces by a right side String.
Topic:.JZtxtcmd.syntax..
threadBlock::= Thread <dataPath?defThreadVar> = [thread] \{ <statementBlock> \} | thread \{ <statementBlock> \}.
A thread can be defined eiher with a thread variable or without it. If a thread variable is not given, it will be created internally but not referenced by the users JZtxtcmd data.