 |
The scripting language
|
CodeWorker must be seen as a script interpreter that is intended to parse and
to generate any kind of text or source code. This interpreter admits some options
on the command line. Some of them look like those of a compiler.
CodeWorker doesn't provide any Graphical User Interface, but a console
mode allows interactivity with the user.
1 Command line of the interpreter
The leader script is the name given to the script that is executed first by the interpreter.
It exists six ways to pass this leader script to the interpreter via the command line:
- the script describes all the processing tasks for parsing text, decorating the graph and
generating code ; the option of the command line is -script to execute the script,
- the script describes an extended BNF grammar ; the option of the command line is
-parseBNF for executing the script and parsing the source file,
- the script describes how to generate code ; the option of the command line is
-generate to execute the script and to generate the output file,
- the script describes how to expand a file ; the option of the command line is
-expand to execute the script and to expand the output file into its markups,
- a file contains embedded scripts driving their own expansion ; the option of the command line is
-autoexpand to execute embedded scripts located below each markups, expanding the output file on markups,
- the script describes a source-to-source translation ; the option of the
command line is -translate to execute the script and to translate the source
file to the output file,
To find easier a file to open for reading among some directories, the option -I
specifies a path to explore. It gives more flexibility in sharing input files (both scripts
and user files, excepting generated or expanded files) between directories, and it avoids
relative or absolute paths into scripts.
It is possible to define some properties on the command line, thanks to option -define
(or -D). These properties are intended to be exploited into scripts.
It is recommended to specify a kind of working directory with option -path.
The assigned value is accessible into scripts via the function getWorkingPath(). This
working directory generally indicates the output path for copying or generating
files. The developer of scripts decides how to use it.
CodeWorker interprets scripts efficiently for speed. However, it is more convenient to run
a standalone executable, instead of the interpreter and some script files. Moreover, once
scripts are stable, why not to compile them as an executable to run the project a few times
faster? Option -c++ allows translating the leader script and all its dependencies to
C++ source codes, ready-to-compile.
To facilitate the tracking of errors, an integrated debugger is called thanks to the
option -debug. It runs into the console, and some classical commands allow taking
the control of the execution and exploring the stack and the variables.
Here are presented all switches that are allowed on the command line:
| Switch | Description |
| -args [arg]* |
Pass some arguments to the command line.
The list of arguments stops at the end of the command line or as soon as an option
is encountered. The arguments are stored in a global array variable called _ARGS. |
| -autoexpand file-to-expand |
The file file-to-expand is explored
for expanding code at markups, executing a template-based script inserted
just below each markup.
It is identical to execute the script function autoexpand(file-to-expand, project). |
-c++ generated-project-path
CodeWorker-path? |
To translate the leader script and all its
dependencies in C++ source code, once the execution of the leader script has
achieved (same job as compileToCpp() compileToCpp()). The CodeWorker-path
is optional and gives the path through includes and libraries of the software. However, it is now
recommended to specify CodeWorker-path by the switch -home. |
-c++2target script-file
generated-project-path target-language? |
To translate the leader script and all its dependencies in C++ source code.
Hence, the C++ is translated to a target language, all that once the execution
of the leader script has achieved. Do not forget to give the path through
includes and libraries of CodeWorker, setting the switch -home.
A preprocessor definition called "c++2target-path" is automatically
created. It contains the path of the generated project. Call
getProperty("c++2target-path") to retrieve the path value.
target-language is optional if at least one script of the project
holds the target into its filename, just before the extension. Example:
"myscript.java.cwt" means that the target language of this script is "java".
A property can follow the name of the target language, separated by a '=' symbol.
The property is accessible via getProperty("c++2target-property"), and
its nature depends on the target. For instance, in Java, this property represents
the package the generated classes will belong to. Example: java=org.landscape.mountains. |
| -c++external filename |
To generate C++ source code for implementing
all functions declared as external into scripts. |
| -commentBegin format |
To specify the format of a beginning of comment. |
| -commentEnd format |
To specify the format of a comment's end. |
| -compile scriptFile |
To compile a script file, just
to check whether the syntax is correct. |
| Switch | Description |
| -commands commandFile |
To load all arguments processed ordinary on the command-line.
It must be the only switch or else passed on the command-line. |
| -console |
To open a console session (default mode if no script
to interpret is specified via -script or -compile or
-generate or -expand. |
| -debug [remote]? |
To debug a script in a console while executing it. The optional
argument remote defines parameters for a remote socket control of the debugging session.
remote looks like <hostname>:<port>. If <hostname> is empty, CodeWorker runs as a
socket server.
|
-define VAR=value
or -D ... |
To define some variables, as
when using the C++ preprocessor or when passing properties to the JAVA compiler.
These variables are similar to properties, insofar as they aren't exploited during
the preprocessing of scripts to interpret. This option conforms to the format
-define VAR when no value has to be assigned ; in that case,
"true" is assigned by default to variable VAR. The script
function getProperty("VAR") gives
the value of variable VAR.
|
-expand pattern-script
file-to-expand |
Script
file pattern-script is executed to expand file file-to-expand
into markups.
It is identical to execute script function expand(pattern-script, project, file-to-expand). |
| -fast |
To optimize speed. While processing generation, the output
file is built into memory, instead of into a temporary file.
|
-generate pattern-script
file-to-generate |
Script
file pattern-script is executed to generate file file-to-generate.
It is identical to execute script function generate(pattern-script, project, file-to-generate).
|
| -genheader text |
Adds a header at the beginning of all generated
files, followed by a text (see procedure setGenerationHeader() setGenerationHeader()). |
| -help or ? |
Help about the command line. |
| -home CodeWorker-path |
Specifies the path to the home directory of CodeWorker. |
| -I path |
Specify a path to explore when trying
to find a file while invoking include or parseFree
or parseAsBNF or generate or expand or ... This option may be
repeated to specify more than one path. |
-insert variable_expression
value |
Creates a new node in
the main parse tree project and assigns a constant value to it. It is identical
to execute the statement insert variable_expression = " value " ;.
|
| -nologo |
The interpreter doesn't write the copyright in the shell at the beginning. |
| Switch | Description |
| -nowarn warnings |
Specified warning types are ignored. They are separated by pipe symbols.
Today, the only recognized type is undeclvar, which prevents the developer against the
use of a undeclared variable. |
-parseBNF BNF-parsing-script
source-file |
The script
file BNF-parsing-script parses source-file from an extended BNF grammar.
It is identical to execute the script function parseAsBNF(BNF-parsing-script, project, source-file).
|
| -path path |
Output directory, returned by the script
function getWorkingPath(), and used ordinary to specify where
to generate or copy a file. |
| -quantify [outputFile]? |
To execute scripts into quantify mode that consists of
measuring the coverage and the time consuming. Results are saved to HTML file outputFile or
displayed to the console if not present. |
-report report-file
request-flag |
To generate a report once the execution has achieved.
The report is saved to file report-file and nature of information
depends on the flag request-flag. This flag must be built by computing
a bitwise OR for one or several of the following integer constants:
- 1: provides every output file written by a template-based script (generate(), expand() or translate)
- 2: provides every input file scanned by a BNF parse script (parseAsBNF() or translate())
- 4: provides details of coverage recording for every output file using the #coverage directive
- 8: provides details of coverage recording for every input file using the #matching directive
- 16: provides details of coverage recording for every output file written by a template-based script
- 32: provides details of coverage recording for every input file scanned by a BNF parse script
Notice that flags 16 and 32 may become highly time and memory consuming, depending both on
how many input/output files you have to process and on their size.
|
| -script script-file |
Defines the leader script, which will be
executed first. |
| -stack depth |
To limit the recursive call of functions, for avoiding an
overflow stack memory. By default, the depth is set to 1000. |
| -stdin filename |
To change the standard input for reading from an
existing file. It may be useful for running a scenario. |
| -stdout filename |
To change the standard output for writing it to a file. |
| -time |
To display the execution time expressed in milliseconds, just
before exiting. |
| Switch | Description |
-translate translation-script
source-file file-to-generate |
Script
file translation-script processes a source-to-source translation.
It is identical to execute the script function translate(translation-script, project, source-file, file-to-generate).
|
| -varexist |
To trigger a warning when the value of a variable that doesn't
exist is required into a script. |
| -verbose |
To display internal messages of the interpreter (information). |
| -version version-name |
To force interpreted scripts as written in a
precedent version given by version-name. |
Note that the interpreter proposes a convenient way for running a common script with arguments:
codeworker <script-file> <arg1> ... <argN> [<switch>]*
This writing replaces the more verbose:
codeworker -script <script-file> -args <arg1> ... <argN> [<switch>]*
A console mode is launched when the command line is empty. The console only accepts
scripts written in the common syntax, with common functions and procedures. So, parsing
and generation scripts aren't typed directly on the console.
2 Syntax generalities and statements
A script in CodeWorker consists of a series of statements that are organized into
blocks (also known as compound statements). A statement is an instruction
the interpreter has to execute.
A single statement must close with a semicolon (';'). A compound statement is defined
by enclosing instructions between braces ('{}'). A block can be used
everywhere you can use a single statement and must never end with a semicolon after the
trailing brace.
Comments are indicated either by surrounding the text with '/*' and '*/'
or by preceding the rest of the line to ignore with a double slash ('//').
It exists three families of scripts here. To facilitate their syntax highlighting in editors,
or to indicate briefly the type of the script, we suggest to employ some file extensions,
depending on the nature of the script. The next table exposes the different extensions used
commonly in CodeWorker.
| Extension | Description |
| ".cwt" |
a template-based script, for text generation |
| ".cwp" |
a extended-BNF parse script, for parsing text |
| ".cws" |
a common script, none of the precedent |
The structure of the grammar is so rich that it is a challenge to find an editor, which
offers a syntax highlighting engine powerful enough. JEdit proposes the writing of
production rules to describe it, so it is possible to express the syntax highlighting of
the scripting language.
You'll find a package dedicated to JEdit on the Web site, for the inclusion of these new
highlighting modes. Many thanks to Patrick Brannan for this contribution.
2.1 preprocessor directives
A preprocessor directive always starts with a '#' symbol and is followed by the name
of the directive.
2.1.1 Including a file
The #include filename directive tells the preprocessor to replace
the directive at the point where it appears by the contents of the file specified by the
constant string filename. The preprocessor looks for the file in the current
directory and then searches along the path specified by the -I option on the command
line.
2.1.2 Extending the language via a package
A package is an extension of the scripting language that allows adding new
functions in CodeWorker at runtime. A package is implemented as an executable module,
which exports all new functions the developer wants to make available in the interpreter.
Loading of a package
The preprocessor directive #use tells the interpreter that it must extend itself
with the functions exposed by a package.
The syntax is:
#use package-name
Loading a package more than once has no effect.
The name of the package must prefix the name of the function, when calling it:
package-name::my-function(parameters...)
Example:
#use PGSQL
PGSQL::connect("-U pilot -d emergencyDB");
local sRequest = "SELECT solution FROM average_adjustment WHERE damage = 'broken wing'";
local listOfSolutions;
PGSQL::selectList(sRequest, listOfSolutions);
if listOfSolutions.empty()
traceLine("No solution. Suggestion: parachute jump?");
else {
traceLine("Solutions:");
foreach i in listOfSolutions
traceLine(" -" + i);
}
PGSQL::disconnect(); // if the plane hasn't crashed yet
The PGSQL package serves here for connecting to and querying a PostGreSQL database.
For this example, the package exports three functions: PGSQL::connect,
PGSQL::selectList and PGSQL::disconnect.
The executable module
CodeWorker expects a dynamic library, whose name is deduced from the package name and from
the platform the interpreter is running to.
The short name of the dynamic library concatenates "cw" at the end of the
package name. The extension of the dynamic library must be ".dll" under
Microsoft Windows, and ".so" under Linux.
You must put the dynamic library at a place where CodeWorker will find it at runtime.
Microsoft Windows proceeds in the following order to locate the library:
- The directory where the executable module for the current process is located.
- The current directory.
- The Windows system directory (not recommended - it concerns CodeWorker only).
- The Windows directory (not recommended - same reason).
- The directories listed in the PATH environment variable.
Under Unix, a relative path for the shared object refers to the current directory
(according to the man description of dlopen(3C)).
So, when CodeWorker reads #use PGSQL, it searches a dynamic library
called "PGSQLcw.dll" under Windows or "PGSQLcw.so"
under Linux.
Building a package
This section is intended to those that want to build their own packages, for binding to
a database or to a graphical library ... or just for gluing with their own libraries.
When the interpreter find the preprocessor directive #use package-name
in a script, it loads the executable module and executes the exported C-like function
CW4DL_EXPORT_SYMBOL void package-name_Init(CW4dl::Interpreter*).
The preprocessor definition CW4DL_EXPORT_SYMBOL and the namespace CW4dl are
both declared in the C++ header file "CW4dl.h". This header file is located in
the "include" directory if you downloaded binaries, and at the root of the project
if you downloaded sources.
The C-like function 'package-name_Init()' MUST be present!
C-like means that it is declared extern "C" (done by CW4DL_EXPORT_SYMBOL).
Initializing the module that way is useful for registering new functions in the engine,
via the function createCommand() of the interpreter (see the header file "CW4dl.h"
in the declaration of the class Interpreter for learning more about it).
Every function to export must start its declaration with the preprocessor definition
CW4DL_EXPORT_SYMBOL (means 'extern "C"', but a little more under Windows).
- Up to 4 parameters, the signature of such a function looks like:
CW4DL_EXPORT_SYMBOL const char*
selectList(CW4dl::Interpreter*,
CW4dl::Parameter p1, CW4dl::Parameter p2);
where selectList is a function expecting 2 parameters.
The initializer PGSQL_Init() in our example informs the engine about the existence
of this function selectList in the package:
createCommand("selectList", VALUE_PARAMETER, NODE_PARAMETER);
which means that selectList expects a string followed by a tree.
In the body of the function 'selectList(...)', the C++ binding is obtained easily
by a cast of CW4dl::Parameter:
- (const char*) p1 for the value parameter p1,
- (CW4dl::Tree*) p2 for the node parameter p2,
- if a function contains strictly more than 4 parameter, its signature changes
and requires a variable number of parameters:
CW4DL_EXPORT_SYMBOL const char*
myFunction(CW4dl::Interpreter*,
int nbParams, CW4dl::Parameter* tParams);
where tParams is an array of parameter types, and where 'nbParams' gives
the size.
The initializer PGSQL_Init() informs the engine about the existence
of this function in the package differently too:
createCommand("myFunction", 6, tParams);
which means that myFunction has 6 parameters whose types are provided
in tParams.
Every function returns const char*. The CodeWorker's keyword null designates
an atypical tree node. It doesn't accept navigation and reference, only passing by parameter to a function.
On the C++ side, this null tree node is seen as a null pointer of kind CW4dl::Tree*.
The interpreter CW4dl::Interpreter represents the runtime context of CodeWorker.
It is the unavoidable intermediary between the module you are building and CodeWorker.
Use it for:
- registering new functions into the CodeWorker's engine,
- throwing an error,
- handling parse trees,
The #line directive forces to another number the line counter of the script file
being parsed. The line just after the directive is supposed to be worth the number specified after
#line.
2.1.3 Changing the syntax of the scripting language
The #syntax directive tells the preprocessor not to parse the following
instructions as classical statements of the scripting language, but as conforming to another
syntax. It allows adapting the syntax to what you are programming:
- If you are programming a kind of makefile logic, where you have to check
whether a file has been changed before another or not (using the function
fileLastModification() fileLastModification() for example), it is clear
that you would prefer to implement it in a makefile-like syntax rather than
in the scripting language's syntax,
- If you are programming a kind of shell logic, where you have to copy files
and directories, or re/move them, you would prefer to implement it in a shell-like
syntax rather than in the scripting language's syntax. For instance:
traceLine("Creating directory 'CodeWorker'...");
removeDirectory("CodeWorker");
copyFile("readme.txt", "CodeWorker/readme.txt");
...
might be written in a shell-like syntax, inlayed in the CodeWorker script:
#syntax shell:"TinyShell.cwp"
echo Creating directory 'CodeWorker'...
rmdir CodeWorker
copy readme.txt CodeWorker/readme.txt
...
#end syntax
The directive admits the following writing:
"#syntax" [parsing-mode [':' BNF-script-file]? | BNF-script-file]
How does it work? The piece of source code, which doesn't conform to the syntax of the script
language, is put between the directives #syntax ... and #end syntax. If the
trailing directive isn't found, the remaining of the script is considered as written in a
foreign syntax. Be careful that the trailing directive must start at the beginning of the line
necessary to be recognized and that no spaces are allowed between # and end.
At runtime, the famous piece of source code is parsed and processed via the BNF script file.
Note that it is possible to attach an identifier (called parsing-mode above) to a
script file, and to specify later, in any other script, the parsing mode only;
CodeWorker will find the corresponding BNF script file. It avoids to handle a physical name
of the BNF parsing file, where a logical name of parsing mode is more convenient.
Example:
// the first time, a parsing mode may be attached to the BNF script file
#syntax shell:"TinyShell.cwp"
...
#end syntax
// at the second call, it isn't recommended to use the path of the parsing file
// it is better to use the parsing mode registered previously
#syntax shell
...
#end syntax
// here, I know that I'll call it once only, so I don't care about a parsing mode
#syntax "MakeFile.cwp"
...
#end syntax
where the parsing script "TinyShell.cwp" might be worth:
// file "GettingStarted/TinyShell.cwp":
tinyShell ::=
#ignore(C++)
#continue
[
#readIdentifier:sCommand
#ignore(blanks) #continue
command<sCommand>
]* #empty;
//----------------------------//
// commands of the tiny shell //
//----------------------------//
command<"copy"> ::=
#continue parameter:sSource parameter:sDestination
=> {copyFile(sSource, sDestination);};
command<"rmdir"> ::=
#continue parameter:sDirectory
=> {removeDirectory(sDirectory);};
command<"del"> ::=
#continue parameter:sFile
=> {deleteFile(sFile);};
//--------------------
// Some useful clauses
//--------------------
parameter:value ::=
#readCString:parameter
|
#!ignore #continue [~[' ' | '\t' | '\r' | '\n']]+:parameter;
Of course, the parsing and the processing are implemented in the scripting language, so changing
the syntax will be slower than keeping the default one. However, it allows writing a code
easy to support and to understand.
2.1.4 Managing changes in a multi-language generation
The directives #reference and #attach serve to be notified when a change has
been made into a script for generating in a given language, but not taken back in another
language. For example, you are writing a framework both in C++ and JAVA. You are adding some
new features in C++ or correcting some mistakes. One day, you'll be care not to forget to
update the JAVA generation. In fact, thanks to these directives, a warning will be produced
up to changes will have been put in the other script.
How does it work? Directives must delimit the piece of script you have changed:
"#reference" key
...
"#end" key
The key is an identifier that allows putting more than one reference area into a
script file. A #reference area might cover one or more #reference
directives, without confusing about boundaries. The directive must be put at the beginning of
the line.
Here are the directives delimiting the piece of script that should be updated later in
another file:
"#attach" reference-file ':' reference-key
...
"#end" reference-key
A #attach area might cover one or more #reference or #attach
directives, as a #reference area. The directive must be put at the beginning of the
line.
The first time CodeWorker will encounter the reference script file, it will compute
a number that depends on the content of the area. The first time CodeWorker will encounter an
attached script file, it will get back the magic number of the reference
area, found both by the file name and the key of the reference. And then, at the beginning,
the reference and attached areas are considered as similar. CodeWorker stores
the magic number of the reference just behind the #attach directive:
"#attach" reference-file ':' reference-key ',' reference-number
In fact, a script file that must be updated, so as to store the magic numbers for some attached
areas, takes into account the modifications at the end of the parsing, and only if no error
was encountered. If the writefileHook() function (see writefileHook) is implemented,
it is called and the script file doesn't change if it returns false. If the script file
is read-only, the corresponding readonlyHook() function is called (see readonlyHook).
If it isn't possible to save the script file, an error is thrown.
When a change occurs in the reference area, the next time CodeWorker will encounter
it, the magic number will be recomputed. When an attached piece of script is encountered after
the change, the old magic number of the reference is compared to the new one. If they aren't
the same, a warning is displayed to notify that the attached area hasn't been updated yet.
Once the changes have been taken back into the attached area, the magic number of the reference
must be cut (don't forget the comma too!). And so, the next time this attached area will be
encountered by the interpreter, it will get back the magic number of the reference
area. And then, the reference area and the attached area are considered as
similar once again.
Of course, the use of these directives is quite constraining. However, it is the only way in
CodeWorker to assure that features and corrections have been taken back in all generated
languages.
2.2 Constant literals
CodeWorker handles all basic types as strings, and doesn't distinguish a double from a boolean or a date.
A string literal is a sequence of characters from the source character set enclosed in double quotation marks (" ").
String literals are used to represent a sequence of characters which, taken together, form a null-terminated string.
The interpretation done of the data depends on the context: function increment(index)
expects that its argument index contains a number, but stored as a string.
- Floating-point numbers are represented as they are commonly admitted into programming languages: 3.141592 or 5.5E+6.
- Integers are represented without the dot, 64 for instance.
- A character literal is represented between single quotes as in C or JAVA; it admits
classical escape characters.
- Bytes are represented as a couple of hexadecimal digits. The 4D byte is the
ASCII of the letter N.
- About boolean types, an empty string "" means false, and any kind of sequence of characters means true, such as "1" or "raspberries".
Two constant literals are provided: keyword true is worth
"true" and false is an empty string.
- dates are written according to a format that looks like 24sep2002, where:
- day takes 2 digits
- month is represented as the 3 first letters of the corresponding english word ; aug as august and may as may, for instance
- year takes 4 digits: 2002 but never 02.
- the time representation conforms to the format:
HH:MM:SS.millis
A constant tree describes a tree as a list of constant trees and expressions, intended
to be assigned to a variable. Example:
local aVariable = "a"{["yellow", "red":"or"{.alternative="orange"
], .vehicle="submarine"};}
You'll find more information in the sub section Scope below.
2.3 Variables, declaration and assignment
Variables serve as containers for the data you use into scripts. Data type is a tree that may
be reduced to a leaf node, which contains a value and that's all.
2.3.1 Declaring variables
It isn't necessary to declare a variable before using if for the first time. A variable that
is assigned without being declared is understood as a new sub-node to be added to the current
tree context. The current context is obtained by the read-only variable called this.
It corresponds to the main parse tree whose root name is project when you are into
the leader script, and to the variable passed by parameter when calling a parsing or pattern
script.
The next table exposes all pre-defined variable names (accessible from anywhere) and their meaning:
| Variable Name | Description |
| project |
The main parse tree, always present. |
| this |
It points to the current context variable. |
| _ARGS |
An array of all custom command-line arguments. Custom arguments are following the script file name or the switch -args on the command-line. |
| _REQUEST |
If the interpreter works as a CGI program, it stores all parameters of the request in a association table. The key is the parameter name, which associates the corresponding value. |
A variable that is read without being declared returns an empty string, but doesn't cause the
creation of a sub-node. The danger is that you aren't safe from a spelling mistake. To prevent
it, put the option -varexist on the command line and use the function existVariable()
to check whether a variable exists or not.
2.3.2 Scope
When you declare a local variable, it is valid for use within a specific area of code, called
the scope. When the flow of execution leaves the scope, the content of the variable,
a subtree specially allocated during its declaration, is deleted and disappears forever from
the stack. A scope is delimited by a block.
To declare a variable to the stack, use the following declaration statement:
local-variable-statement ::= "local" local-variable-declaration ';'
local-variable-declaration ::= variable [ '=' assignment-expression ]?
assignment-expression ::= constant-tree | expression
constant-tree ::= [tree-value]? '{' [tree-array-or-attribute [',' tree-array-or-attribute]* ]? '}'
tree-value ::= expression
tree-array-or-attribute ::= tree-array | tree-attribute
tree-attribute ::= '.' attribute-name '=' assignment-expression
tree-array ::= '[' tree-array-item [',' tree-array-item]* ']'
tree-array-item ::= expression ':' assignment-expression | assignment-expression
An extension of the syntax allows the declaration of more than one variable in one shot. A comma separates the
variable declarations:
local-variable-statement ::= "local" local-variable-declaration [ ',' local-variable-declaration ]* ';'
The local variable points to a new empty tree, pushed into the stack.
- If an expression is present after the local declaration, it is evaluated and
the string result is assigned to the new local variable.
- If a constant tree is present after the local declaration, it is assigned to
the new local variable. Example:
local aVariable = {"a", {"yellow", "red"}, "submarine"};
is equivalent to:
local aVariable;
pushItem aVariable = "a";
pushItem aVariable;
pushItem aVariable#back = "yellow";
pushItem aVariable#back = "red";
pushItem aVariable = "submarine";
where pushItem means that a new item has to be added in the array owned
by aVariable, and where #last means accessing to the last item
of the array.
To assign a reference to another variable, instead of either the result of
evaluating an expression or a constant tree, use rather the following declaration statement:
local-ref-statement ::= "localref" local-ref-declaration [ ',' local-ref-declaration ]* ';'
local-ref-declaration ::= variable '=' reference
In the case of a CodeWorker version strictly older than 1.13, local
variables that are declared in the body of a script or in the scope of a function may
be accessed further in the scope of functions during their timelife. So a different behaviour
may occur with a more recent CodeWorker interpreter.
This stack management had historical reasons, but it is now obsolete and often reflects an
implementation's error. To preserve you from this kind of mistake, a warning may be displayed,
so that scripts strictly older than version 1.13 may continue to run. Specify a
version strictly older than 1.13 to the command line (option -version) for
reclaiming that CodeWorker checks and generates a warning.
To correct this kind of mistake in old scripts, the variable should be propagated in an
argument for functions that refer to it.
To declare a global variable, use the global statement. The declaration of a global
variable can be specified anywhere in scripts. The first time the declaration of a global
variable is encountered, the interpreter registers it as accessible from any point into
scripts. The second time the interpreter encounters a global declaration for the variable,
the latter remains global but its content is cleared.
Note that if a local variable or an attribute of the current node (this) is identical
to the name of an existing global variable, the global variable remains hidden while
the flow of control hasn't left the scope that contains the homonym.
the global declaration statement looks like:
global-variable-statement ::= "global" global-variable-declaration [ ',' global-variable-declaration ]* ';'
global-variable-declaration ::= variable [ '=' assignment-expression ]?
2.3.3 Navigating along branches
It is possible to navigate along a branch of the subtree put into the variable. A branch
points to a node of the subtree. The syntax looks generally like:
branch ::= variable ['.' sub-node]*
If the branch isn't known before runtime, it may be build during the execution.
Example: while parsing an XML file, each time an XML attribute is encountered, one creates the
corresponding attribute into the parse tree. But the name of the attribute is discovered
during the parsing. The directive #evaluateVariable(expression) allows doing it.
expression is evaluated at runtime and provides a branch:
#evaluateVariable("a.b.c")
will resolve the path "a.b.c" at runtime and
navigate from a to textit{c}.
A node may contain an array of nodes, which are indexed by a key that is a constant string.
A branch allows navigating through arrays, and the definitive syntax of branches conforms
to:
branch ::= "#evaluateVariable" '(' expression ')'
::= variable ['.' sub-node | array-access]*
array-access ::= '[' expression ']'
::= '#' ["front" | "back" | "parent"] | "root"]
::= '#' '[' integer-expression ']'
We see that there are some ways to access an item node of an array or to change how to
navigate from nodes to nodes:
- sub-node '[' expression ']' means that
we'll access the node item associated to the string key resulting of the
expression's evaluation,
- sub-node '#' "front" means that the first item
node of the array is required. If the array is empty, an error occurs.
- sub-node '#' "back" means that the last item
node of the array is required. If the array is empty, an error occurs.
- sub-node '#' "parent" means that one comes back
up the parent's node of sub-node.
- sub-node '#' "root" means that one comes back
up the root's node of the tree sub-node belongs to.
- sub-node '#' '[' <integer-expression> ']' means
that we'll access the node item located at the position given by the evaluation
of the expression. The position starts counting to 0. An error is raised if the
position is out of bounds.
2.3.4 Assignments
CodeWorker provides some different ways to put a data into a variable or into the node
pointed to by a branch:
- set variable-branch ['=' | '+='] assignment-expression :
the expression is evaluated and the resulting string value is assigned to the
variable, or concatenated if the operator '+=' was required. Keyword
set may be omitted. The node to assign is supposed existing yet. If not,
the assignment is done, but it causes a warning to prevent a spelling mistake on
the variable's name.
- insert variable-branch [['=' | '+='] assignment-expression]? :
it works like the set assignment, except that it is the preferred mode
to add a new node when the variable doesn't exist yet. If the node already exists,
of course it isn't added twice, and the assignment if done as expected. If no
assignment is specified after the variable's name, nothing is assigned to the node.
So, if the node wasn't existing yet, it contains an empty string. Otherwise,
the ancient value isn't changed.
- ref variable '=' existing-variable-or-branch :
the variable to assign will refer to an existing node. Inspecting the variable
will cause inspecting the referenced existing node. If the referenced node doesn't
exist, an error occurs. If you apply the reference to a variable that already
refers a node, this link is broken instead of propagating the reference to the
referred node. This operator is very useful during the decoration of the
parse tree, and leads to transform the tree as a freely-oriented graph.
Be careful not to keep a reference to a local variable once the flow of execution
has left its scope: the local variable is deleted, and so, the reference points
to a corrupted part of the memory.
If you intend to assign a reference to a variable into a function and that the
variable is passed by parameter, don't forget to take the reference parameter
mode:
function badFunction(myVar : node) {
...
// myVar will keep up a reference to aNode
// up to the end of the function:
ref myVar = aNode;
...
// myVar is passed as variable, so the
// reference is cancelled once the function is left!
}
// To keep the reference after leaving the function, change the parameter
// mode to reference:
function goodFunction(myVar : reference) {
...
// myVar will keep up a reference to aNode
// up to the end of the function:
ref myVar = aNode;
...
// myVar is passed as reference, so the
// reference is kept once the function is left!
}
- setall variable-branch '=' existing-variable-or-branch :
value, attributes and array of the variable to assign are purged, and the subtree,
to which the existing variable points, is copied integrally to the node to
assign.
- merge variable-branch '=' existing-variable-or-branch :
the subtree, to which the existing variable points, is copied integrally to the
node to assign, preserving the attributes and the arrays of the assigned node,
which are updated or completed.
- pushItem variable-branch ['=' expression]? :
a new item node is added at the end of the variable's array, whose key is worth
its position, starting at 0. If the expression exists, then after evaluating it,
the result is assigned to the item node as a value. If no array was previously
existing, the item becomes its first component.
2.4 Expressions
2.4.1 Presentation
The BNF representation of an expression looks like:
expression ::= boolean-expr | ternary-expr
boolean-expr ::= comparison-expr [boolean-op comparison-expr]
boolean-op ::= '&' | '&&' | '|' | '||' | '^' | '^^'
ternary-expr ::= comparison-expr '?' expression ':' expression
comparison-expr ::= concatenation-expr [comparison-op concatenation-expr | "in" constant-set]
constant-set ::= '{' constant-string [',' constant-string]* '}'
comparison-op ::= '<' | '<=' | '==' | '=' | '!=' | '<>' | '>' | '>='
concatenation-expr ::= stdliteral-expr ['+' stdliteral-expr]*
stdliteral-expr ::= literal-expr
::= '$' arithmetic-expr '$'
literal-expr ::= constant-string | number
::= "true" | "false"
::= '(' expression ')'
::= '!' literal-expr
::= preprocessor-expr
::= function-call
::= variable-or-branch
arithmetic-expr ::= comparith-expr [boolean-op comparith-expr]*
comparith-expr ::= sum-expr [comparison-op sum-expr]
sum-expr ::= shift-expr [['+' | '-'] shift-expr]*
shift-expr ::= factor-expr [["<<" | ">>"] factor-expr]*
factor-expr ::= literal-expr [['*' | '/' | '%'] literal-expr]*
unary-expr ::= literal-expr ["++" | "--"]
literal-expr ::= string | variable-expr | number | unary-expr
::= '~' literal-expr
preprocessor-expr ::= '#' ["LINE" | "FILE"]
where:
2.4.2 Arithmetic expressions
The classical syntax of the interpreter forces expressions to work on sequences of characters.
So, comparison operators apply the lexicographical order and the '+' operator concatenates
two strings and the '*' operator doesn't exist.
Of course, it exists some functions to handle strings as number and to execute an arithmetic
operation (the 'add()' or 'mult()' functions for instance) or a comparison (the
'isPositive()' or 'inf()' functions for instance).
However, it appears clearly more convenient to write arithmetic operations and comparisons in a
natural way, using operators instead of the corresponding functions. So, CodeWorker provides
an escape mode that draws its inspiration from LaTeX to express mathematical formulas:
the arithmetic expression are delimited by the symbol '$'.
Example:
local a = 11;
local b = 7;
traceLine("Classical mode = '"
+ inf(add(mult(5, a), 3), sub(mult(a, a), mult(b, b))) + "'");
traceLine("Escape mode = '" + $5*a + 3 < a*a - b*b$ + "'");
Output:
Classical mode = 'true'
Escape mode = 'true'
2.5 Common statements
2.5.1 The 'if' statement
The BNF representation of the while statement is:
if-statement ::= "if" expression then-statement
["else" else-statement]?
The if statement evaluates the expression following immediately. The expression
must be of arithmetic, text, variable or condition type. In both forms of the if
syntax, if the expression evaluates to a nonempty string, the statement dependent on the
evaluation is executed; otherwise, it is skipped.
In the if...else syntax, the second statement is executed if the result of evaluating
the expression is an empty string. The else clause of an if...else statement is
associated with the closest previous if statement that does not have a corresponding
else statement.
2.5.2 The 'while'/'do' statements
The BNF representation of the while statement is:
while_statement ::= "while" expression statement
The while statement lets you repeat a statement or compound
statement as long as a specified expression becomes an empty
string. The expression in a while statement is evaluated before
the body of the loop is executed. Therefore, the body of the loop
may be never executed. If expression returns an empty string,
the while statement terminates and control passes to the next
statement in the program. If expression is non-empty, the process
is repeated. The while statement can also terminate when a
break, or return statement is executed within the statement
body. When a continue statement is encountered, the control breaks
the flow and jumps to the evaluation of the expression.
Note that the break and continue statements apply to
the first loop statement (foreach/forfile/select, do/while) they encounter
while leaving instruction blocks.
The BNF representation of the do statement is:
do_statement ::= "do" statement "while" expression ';'
The do-while statement lets you repeat a statement or compound
statement until a specified expression becomes an empty string. The
expression in a do-while statement is evaluated after the body of the
loop is executed. Therefore, the body of the loop is always executed at
least once. If expression returns an empty string, the do-while
statement terminates and control passes to the next statement in the
program. If expression is non-empty, the process is repeated.
The do-while statement can also terminate when a break, or return
statement is executed within the statement body. When a continue
statement is encountered, control is transferred to the evaluation of
the expression.
2.5.3 The 'switch' statement
The BNF representation of this statement is:
switch_statement ::= "switch" '(' expression ')' '{' (label_declaration)* ("default" ':' statement)? '}'
label_declaration ::= ["case" | "start"] constant_string ':' statement
The switch statement allows selection among multiple sections of
code, depending on the value of an expression. The expression enclosed
in parentheses, the controlling expression, must be of string type.
The switch statement causes an unconditional jump to, into, or past
the statement that is the switch body, depending on the value of the
controlling expression, the constant string values of the case or start labels,
and the presence or absence of a default label. The switch body is
normally a compound statement (although this is not a syntactic
requirement). Usually, some of the statements in the switch body are
labeled with case labels or with start labels or with the default
label. The default label can appear only once.
The constant-string in the case label is compared for equality with the controlling
expression. The constant-string in the start label is compared for equality with the
first characters of the controlling expression. In a given switch statement, no two
constant strings in start or case statements can evaluate to the same value.
The switch statement behaviour depends on how the controlling
expression matches with labels. If a case label exactly matches with
the controlling expression, control is transferred to the statement
following that label. If failed, start labels are iterated into the
lexicographical order, and the control is transferred to the statement
following the first label that matches with the beginning of the controlling expression.
If failed, control is transferred to the default statement or, if not present,
an error is thrown.
A switch statement can be nested. In such cases, case or start or
default labels associate with the most deeply nested switch
statements that enclose them.
Control is not impeded by case or start or default labels. To
stop execution at the end of a part of the compound statement, insert a
break statement. This transfers control to the statement after the
switch statement.
2.5.4 The 'foreach' statement
The BNF representation of this statement is:
foreach_statement ::= "foreach" iterator "in" [direction]?
[sorted_declaration]? [cascading_declaration]? list-node body_statement
direction ::= "reverse"
sorted_declaration ::= "sorted" ["no_case"]? ["by_value"]?
cascading_declaration ::= "cascading" ["first" | "last"]?
A foreach statement iterates all items of the list owned by node list-node.
The iterator refers to the current item of the list, and the body statement is executed
on it.
Items are iterated either in the order of entrance, or in alphabetical order if
option sorted is set. The sort operates on keys, except if the option by_value is set.
The order is inverted if option reverse was chosen.
To ignore the case, these options must be followed by no_case.
If not, uppercase letters are considered as smaller than any lowercase letter.
// file "Documentation/ForeachSampleSorted.cws":
local list;
insert list["silverware"] = "tea spoon";
insert list["Mountain"] = "Everest";
insert list["SilverWare"] = "Tea Spoon";
insert list["Boat"] = "Titanic";
insert list["acrobat"] = "Circus";
traceLine("Sorted list in a classical order:");
foreach i in sorted list {
traceLine("\t" + key(i));
}
traceLine("Note that uppercases are listed before lowercases." + endl());
traceLine("Sorted list where the case is ignored:");
foreach i in sorted no_case list {
traceLine("\t" + key(i));
}
traceLine("Reverse sorted list:");
foreach i in reverse sorted list {
traceLine("\t" + key(i));
}
traceLine("Reverse sorted list where the case is ignored:");
foreach i in reverse sorted no_case list {
traceLine("\t" + key(i));
}
Output:
Sorted list in a classical order:
Boat
Mountain
SilverWare
acrobat
silverware
Note that uppercases are listed before lowercases.
Sorted list where the case is ignored:
acrobat
Boat
Mountain
SilverWare
silverware
Reverse sorted list:
silverware
acrobat
SilverWare
Mountain
Boat
Reverse sorted list where the case is ignored:
silverware
SilverWare
Mountain
Boat
acrobat
Control may not be sequential into the body statement. break and return enable
exiting definitely the loop, and continue transfers the control to the head of the
foreach statement for the next iteration.
Option cascading allows propagating foreach on item nodes. The way
it works is illustrated by an example:
foreach i in cascading myObjectModeling.packages ...
At the beginning, i points to myObjectModeling.packages#front and
the body is executed. Before iterating i to the next item, the foreach checks whether
the item node myObjectModeling.packages#front owns attribute packages or not.
If yes, it applies recursively foreach on myObjectModeling.packages#front.packages.
Option cascading avoids writing the following code:
function propagateOnPackages(myPackage : node) {
foreach i in myPackage {
// my code to apply on this package
if existVariable(myPackages.packages)
propagateOnPackages(myPackages.packages);
}
}
propagateOnPackages(myObjectModeling.packages);
Option cascading offers two behaviours:
- first means that the item is cascaded before running the body,
// file "Documentation/ForeachSampleFirst.cws":
local myObjectModeling;
insert myObjectModeling.packages["Massif"] = "...";
local myPackage;
ref myPackage = myObjectModeling.packages["Massif"];
insert myPackage.packages["Alps"] = "...";
insert myPackage.packages["Himalaya"] = "...";
insert myPackage.packages["Rock Mountains"] = "...";
insert myObjectModeling.packages["Silverware"] = "...";
ref myPackage = myObjectModeling.packages["Silverware"];
insert myPackage.packages["Spoon"] = "...";
insert myPackage.packages["Fork"] = "...";
insert myPackage.packages["Knife"] = "...";
foreach i in cascading first myObjectModeling.packages {
traceLine("\t" + key(i));
}
Output:
Alps
Himalaya
Rock Mountains
Massif
Spoon
Fork
Knife
Silverware
- last is the default behaviour, as seen in previous examples, and
// file "Documentation/ForeachSampleLast.cws":
local myObjectModeling;
insert myObjectModeling.packages["Massif"] = "...";
local myPackage;
ref myPackage = myObjectModeling.packages["Massif"];
insert myPackage.packages["Alps"] = "...";
insert myPackage.packages["Himalaya"] = "...";
insert myPackage.packages["Rock Mountains"] = "...";
insert myObjectModeling.packages["Silverware"] = "...";
ref myPackage = myObjectModeling.packages["Silverware"];
insert myPackage.packages["Spoon"] = "...";
insert myPackage.packages["Fork"] = "...";
insert myPackage.packages["Knife"] = "...";
foreach i in cascading last myObjectModeling.packages {
traceLine("\t" + key(i));
}
Output:
Massif
Alps
Himalaya
Rock Mountains
Silverware
Spoon
Fork
Knife
propagates the foreach on the current item after executing the body.
2.5.5 The 'forfile' statement
The BNF representation of this statement is:
forfile_statement ::= "forfile" iterator "in" [sorted_declaration]? [cascading_declaration]? file-pattern body_statement
sorted_declaration ::= "sorted" ["no_case"]?
cascading_declaration ::= "cascading" ["first" | "last"]?
A forfile statement iterates the name of all files that verify the filter file-pattern.
The iterator refers to the current item of the list composed of retained file names, and the body statement is executed
on it. Note that the file pattern may begin with a path, which cannot contain jocker characters ('*' and '?').
Like for the foreach statement, items are iterated either in the order of entrance, or in alphabetical order of keys if
option sorted is set. To ignore the case, the option must be followed by no_case.
If not, uppercase letters are considered as smaller than any lowercase letter.
Control may not be sequential into the body statement. break and return enable
exiting definitely the loop, and continue transfers the control to the head of the
forfile statement for the next iteration.
The option cascading allows propagating forfile on directories recursively.
The way it works is illustrated by an example:
// file "Documentation/ForfileSample.cws":
local iIndex = 0;
forfile i in cascading "*.html" {
if $findString(i, "manual_") < 0$ &&
$findString(i, "Bugs") < 0$ {
traceLine(i);
}
// if too long, stop the iteration
if $iIndex > 15$ break;
increment(iIndex);
}
Output:
cs/DOTNET.html
cs/tests/data/MatchingTest/example.csv.html
Documentation/LastChanges.html
java/JAVAAPI.html
java/data/MatchingTest/example.csv.html
Scripts/Tutorial/GettingStarted/defaultDocumentation.html
WebSite/AllDownloads.html
WebSite/examples/basicInformation.html
WebSite/highlighting/basicInformation.html
WebSite/repository/highlighting.html
WebSite/repository/JEdit/Entity.java.cwt.html
WebSite/serewin/ExempleIllustre.html
WebSite/tutorials/DesignSpecificModeling/tutorial.html
WebSite/tutorials/DesignSpecificModeling/highlighting/demo.cws.html
WebSite/tutorials/overview/tinyDSL_spec.html
WebSite/tutorials/overview/scripts2HTML/CodeWorker_grammar.html
At the beginning, i points to the first HTML file of the current directory and
the body is executed. Before iterating i to the next item, the forfile checks whether
the directory of the current file owns subfolders or not. If yes, it applies recursively
forfile on subfolders.
Option cascading offers two behaviours:
- first means that the subfolders are visited before running the body,
- last is the default behaviour, as seen in previous examples, and
propagates the forfile on the subfolder after executing the body.
2.5.6 The 'select' statement
The BNF representation of this statement is:
select_statement ::= "select" iterator "in" [sorted_declaration]? node-motif body_statement
sorted_declaration ::= "sorted" first-key [, other-key]*
first-key ::= branch
other-key ::= branch
A select statement iterates a list of nodes that match a motif expression.
The iterator refers to the current item of the list composed of retained nodes, and the body statement is executed
on it.
// file "Documentation/SelectSample.cws":
local a;
pushItem a.b;
pushItem a.b#back.c = "01";
pushItem a.b#back.c = "02";
pushItem a.b#back.c = "03";
pushItem a.b;
pushItem a.b#back.c = "11";
pushItem a.b#back.c = "12";
pushItem a.b#back.c = "13";
pushItem a.b;
pushItem a.b#back.c = "21";
pushItem a.b#back.c = "22";
pushItem a.b#back.c = "23";
select i in a.b[].c[] {
traceLine("i = "+ i);
}
Output:
i = 01
i = 02
i = 03
i = 11
i = 12
i = 13
i = 21
i = 22
i = 23
Like for the foreach statement, items are iterated either in the order of entrance, or
according to the sorting result if the option sorted is set.
Control may not be sequential into the body statement. break and return enable
exiting definitely the loop, and continue transfers the control to the head of the
select statement for the next iteration.
2.5.7 The 'try'/'catch' statement
The BNF representation of this statement is:
try-catch-statement ::= "try" try-statement
"catch" '('error_message_variable')'
catch-statement
Error handling is implemented by using the try, catch, and error
keyword. With error handling, your program can communicate unexpected events to a higher
execution context that is better able to recover from such abnormal events.
These errors are handled by code that is outside the normal flow of control.
The compound statement after the try clause is the guarded section of code. An error
is thrown (or raised) when command error(message-text) is called or
when CodeWorker encounters an internal error. The compound statement after the catch
clause is the error handler, and catches (handles) the error thrown. The catch clause
statement indicates the name of the variable that must receive the error message.
2.5.8 The 'exit' statement
The BNF representation of this statement is:
exit_statement ::= "exit" integer-expression ";"
A exit statement leaves the application and returns an error code, given by the integer-expression.
Example:
exit -1;
2.6 User-defined functions
The BNF representation of a user-defined function to implement is:
user-function ::= classical-function-definition | template-function-definition
classical-function-definition ::= classical-function-prototype compound-statement
classical-function-prototype ::= "function" function-name '(' parameters ')'
template-function-definition ::= see the next section, template function, for more information
parameters ::= parameter [',' parameter]*
parameter ::= argument [':' parameter-mode [':' default-value]? ]?
parameter-mode ::= "value" | "node" | "reference" | "index"
default-value ::= "project" | "this" | "null" | "true" | "false" | constant-string
The scripting language allows the user implementing its own functions. Parameters may be passed
to the body of the function. A value may be returned by the function and, if so, the return
type is necessary a sequence of characters. Of course, functions manage their own stack, and
so, accept recursive calls.
An argument may have a default value if the parameter is missing in a call. All following arguments
must then have default values too. A node argument can't have a constant string as a default
argument, but it can be worth a global variable.
2.6.1 Parameters and return value
Arguments passed by parameter must be chosen among the following modes:
- value: if the mode of argument is omitted, this is the default mode ; it
requires a sequence of characters (a value of node, a constant string or the
result of a expression),
- node: a node is passed and it may be changed or inspected in the body.
The scope of a reference assignment is limited to the scope of the function: once
the function is left, the variable receives the value of the referenced node. It
is explained by the fact that the parameter is a new local variable, which refers
to the node passed as argument. So, a reference assignment is applied on the
local variable only.
- iterator: the iterator of a foreach statement is expected, for applying
iterator functions on the argument (first() for instance). Not really
useful and node is now sufficient.
- reference: a node is passed and it may be changed or expected in the body.
On the contrary of variable mode, a reference assignment is propagated
outside the scope of the function.
If you have omitted to return a value from a function, it returns an empty string ; in that
case, you expects to call this function as a procedure and the result isn't exploited. The
special procedure nop takes a function call as parameter and allows executing the
function and ignoring the result. It isn't compulsory to use nop for calling a function
as a procedure. As in C or C++, you can type the function call followed by a semi-colon and
the result is lost.
It exists two possibilities for returning a value:
- to populate an internal local variable whose name is the same as the function name,
- to use the return statement, followed by the expression to evaluate,
If you wish to execute a particular process in any case before leaving a function and:
- it exists more than one controlling sequence to leave,
- some errors may be raised,
2.6.2 The 'finally' statement
the statement finally warrants you that the block of instructions that follows the
keyword will be systematically executed before leaving. This declaration may be placed
anywhere into the body of the function. Its syntax conforms to:
finally-statement ::= "finally" compound-statement
Example:
// file "Documentation/FinallySample.cws":
1 function f(v : value) {
2 traceLine("BEGIN f(v)");
3 finally {
4 traceLine("END f(v)");
5 }
6 // the body of the function, with more than
7 // one way to exit the function, for example:
8 if !v return "empty";
9 if v == "1" return "first";
10 if v == "2" return "second";
11 if v == "3" return "third";
12 return "other";
13 }
14
15 traceLine("...f(1) has been executed and returned '" + f(1) + "'");
line 3: the finally statement is put anywhere in the body,
line 4: this statement will be executed while exiting the function, even if an exception was
raised,
Output:
BEGIN f(v)
END f(v)
...f(1) has been executed and returned 'first'
2.6.3 Unusual function declarations
It may arrive that a function prototype must be declared before being implemented, because of
a cross-reference with another function for instance. The scripting language offers the forward
declaration to answer this need. To do that, the prototype of the function is written,
preceded by the declare keyword:
forward-declaration ::= "declare" function-prototype ';'
If the body of the function must be implemented in another library and into C++ for example,
the prototype of the function is preceded by the external keyword (see section C++ binding):
external-declaration ::= "external" function-prototype ';'
2.6.4 Template functions
CodeWorker proposes a special category of functions called template functions.
Because of CodeWorker doesn't provide a typed scripting language, template hasn't to
be understood as it is commonly exploited in C++ for instance.
A template function represents a set of functions with the
same prototype, except the dispatching constant. The dispatching constant
is a constant string that extends that name of the function. These functions
instantiate the template function for a particular dispatching
constant. Each instantiated function implements its own body.
The BNF representation of a template function to implement is:
template-function-definition ::= instantiated-function-definition | generic-function-definition
instantiated-function-definition ::= instantiated-function-prototype compound-statement
instantiated-function-prototype ::= "function" function-name '<' dispatching-constant '>' '(' parameters ')'
dispatching-constant ::= a constant string between double quotes
generic-function-definition ::= generic-function-prototype [compound-statement | template-based-body]
generic-function-prototype ::= "function" function-name '<' generic-key '>' '(' parameters ')'
generic-key ::= an identifier that matches any dispatching constant with no attached prototype
template-based-body ::= "{{" template-based-script "}}"
template-based-script ::= a piece of template-based script describing the generic implementation
A call to a template function requires to provide a dispatching expression
to determine the dispatching constant. The dispatching expression will be
evaluated during the execution and CodeWorker will resolve what instantiated
function of this template to call: the result of the dispatching expression must
match with the dispatching constant of the instantiated function.
The BNF representation of a call to a template function is:
instantiated-function-call ::= function-name '<' dispatching-expression '>' '(' parameters ')'
parameters ::= expression [',' expression]*
Note that a dispatching constant may be empty and such an instantiated function
can be called as a classical function. In fact, classical functions are considered as
instantiated functions where the dispatching constant is empty.
template functions bring generic programming in the language:
let imagine that we need function getType(myType : node), to decline for every
language we could have to generate (C++, Java, ...).
Normally, you'll write the following lines to recover the type depending on the
language for which you are producing the source code:
if doc_language == "C++" {
sType = getCppType(myParameterType);
} else if doc_language == "JAVA" {
sType = getJAVAType(myParameterType);
} else {
error("unrecognized language '" + doc_language + "'");
}
Thanks to the template functions, you may replace the precedent lines by the next one:
sType = getType<doc_language>(myParameterType);
with:
function getType<"JAVA">(myType : node) {
... // implementation for returning a Java type
}
function getType<"C++">(myType : node) {
... // implementation for returning a C++ type
}
During the execution, the function getType<T>(myType : node) resolves
on what instantiated function it has to dispatch: either getType<"JAVA">(myType : node)
or getType<"C++">(myType : node), depending on what value is assigned to
variable doc_language.
Trying to call an instantiated function that doesn't exist, raises an error at runtime.
However, one might imagine an implementation by default. For instance:
function getType<T>(myType : node) {
... // common implementation for any unrecognized language
}
For those that know generic programming with C++ templates, here is a classical example of
using template functions:
function f<1>() { return 1; }
function f<N>() { return $N*f<$N - 1$>()$; }
local f10 = f<10>();
if $f10 != 3628800$ error("10! should be worth 3628800");
traceLine("10! = " + f10);
Output:
10! = 3628800
To provide more flexibility in the implementation of the template function, depending on
the generic key <T>, the body admits a template-based script to implement
the source code of the function.
The specialization of the function for a given template instantiation key is then resolved at runtime.
Example:
The template function f inserts a new attribute in a tree node. The attribute has the name passed
to the generic key for instantiation, and the value of the instantiation key is assigned to the new attribute.
Then, the function calls itself recursively on the instantiation key without the last character.
For instance, the source code of f<"field"> should be:
function f<"field">(x : node) {
insert x.field = "field";
f<"fiel">(x); // cut the last character
}
Code:
//a synonym of f<"">(x : node), terminal condition for recusive calls
function f(x : node) {/*does nothing*/}
function f<T>(x : node) {{
// '{{' announces a template-based script, which
// will generate the correct implementation during the instantiation
insert x.@T@ = "@T@";
f<"@T.rsubString(1)@">(x);
@
// '}}' announces the end of the template-based script
}}
f<"field">(project);
traceObject(project);
Output:
Tracing variable 'project':
field = "field"
fiel = "fiel"
fie = "fie"
fi = "fi"
f = "f"
End of variable's trace 'project'.
2.6.5 Methods
For more readability, syntactical facilities are offered to call functions on a node as if
this function was a method of the node. For example, it is possible to call function
leftString on the node a like this:
a.leftString(2), instead of the classical functional form:
leftString(a, 2).
The rule is that every function (user-defined included) whose first argument is passed either
by value or by node or by index (but never by reference) can
propose a method call.
In that case, the method call applies on the first argument, which has to be a node.
The BNF representation of a method call is:
method-call ::= variable '.' function-name '(' parameters ')'
parameters ::= expression [',' expression]*
where parameters have missed the first argument of the function called function-name.
It exists some exceptions where the method doesn't apply to the first argument:
- findElement applies on the second argument,
- replaceString applies on the third argument,
The following methods offer a synonym to the function name:
- empty is a synonym as a method of the function isEmpty,
- length is a synonym for the function lengthString,
- size is a synonym for the function getArraySize,
2.6.6 The 'readonly' hook
The BNF representation of this statement is:
readonlyHook-statement ::= "readonlyHook" '(' filename ')'
compound-statement
The token filename is the argument name that the user chooses for passing the name
of the file to the body of the hook.
This special function allows implementing a hook that will be called each time a
read-only file will be encountered while generating the output file through the
generate or expand instruction.
Limitations: only one declaration of this hook is authorized, and it can't be declared inside
a parsing or pattern script.
Example:
Common usage: file to generate has to be checked out from a source code control system
(see system command to run executables).
readonlyHook(sFilename) {
if !getProperty("SSProjectFolder") || !getProperty("SSWorkingFolder") || !getProperty("SSExecutablePath") || !getProperty("SSArchiveDir") {
traceLine("WARNING: properties 'SSProjectFolder' and 'SSWorkingFolder' and 'SSExecutablePath' and 'SSArchiveDir' should be passed to the command line for checking out read-only files from Source Safe");
} else {
if startString(sFilename, getProperty("SSWorkingFolder")) {
local sourceSafe;
insert sourceSafe.fileName = sFilename;
generate("SourceSafe.cwt", sourceSafe, getEnv("TMP") + "/SourceSafe.bat");
if sourceSafe.isOk {
putEnv("SSDIR", getProperty("SSArchiveDir"));
traceLine("checking out '" + sFilename + "' from Source Safe archive '" + getProperty("SSArchiveDir") + "'");
local sFailed = system(getEnv("TMP") + "/SourceSafe.bat");
if sFailed {
traceLine("Check out failed: '" + sFailed + "'");
}
}
} else {
traceLine("Unable to check out '" + sFilename + "': working folder starting with '" + getProperty("SSWorkingFolder") + "' expected");
}
}
}
2.6.7 The 'write file' hook
This special function allows implementing a hook that will be called just before writing a
file, after ending a text generation process such as expanding or generating or translating
text.
It is very important to notice that it returns a boolean value. A true value means that
the generated text must be written into the file. A false boolean value means that the
generated text doesn't have to be written into the file.
CodeWorker always interprets not returning a value explicitly of a function, as
returning an empty string. If you forget to return a value, the generated text will not be
written into the file!
The BNF representation of this statement is:
writefileHook-statement ::= "writefileHook" '(' filename ',' position ',' creation ')' compound-statement
| Argument | Type | Description |
| filename |
string |
The argument name that the user chooses for
passing the file name to the body of the hook.
|
| position |
int |
The argument name that the user chooses for
passing a position where a difference occurs between the new
generated version of the file and the precedent one.
If the files don't have the same size, the position is worth
-1.
|
| creation |
boolean |
The argument name that the user chooses for
passing whether the file is created or updated.
The argument is worth true if the file doesn't exist
yet. |
Limitations: only one declaration of this hook is authorized, and it can't be declared inside
a parsing or pattern script.
Example:
writefileHook(sFilename, iPosition, bCreation) {
if bCreation {
traceLine("Creating file '" + sFilename + "'!");
} else {
traceLine("Updating file '" + sFilename + "', difference at " + iPosition + "!");
}
return true;
}
2.6.8 The 'step into' hook
This special function is automatically called before that the extended BNF engine
resolves the production rule of a BNF non-terminal. Combined with stepoutHook(),
it is very useful for trace and debug tasks.
This hook can be implemented in parse scripts only.
The BNF representation of this statement is:
stepintoHook-statement ::= "stepintoHook" '(' sClauseName ',' localScope ')' compound-statement
| Argument | Type | Description |
| sClauseName |
string |
The name of the non-terminal.
|
| localScope |
tree |
The scope of parameters used into the production rule.
|
2.6.9 The 'step out' hook
This special function is automatically called once the extended BNF engine has finished
the resolution of a BNF non-terminal. Combined with stepintoHook(), it is very
useful for trace and debug tasks.
This hook can be implemented in parse scripts only.
The BNF representation of this statement is:
stepoutHook-statement ::= "stepoutHook" '(' sClauseName ',' localScope ',' bSuccess ')' compound-statement
| Argument | Type | Description |
| sClauseName |
string |
The name of the non-terminal.
|
| localScope |
tree |
The scope of local variables and parameters used into the production rule.
|
| bSuccess |
boolean |
Whether the resolution of the production rule has succeeded or not. |
2.7 Statement's modifiers
A statement's modifier is a directive that stands just before a statement, meaning an instruction
or a compound statement.
This directive operates some actions in the scope of the statement and then restores the
behaviour as being before.
This action may be:
- to measure the time that is consumed by the execution of the statement,
- to redirect into a variable all messages intended to the console during the
execution of the statement,
- to push a new project parse tree,
- to change the output file during the execution of the statement, while generating
text,
- to redirect the output stream into a variable during the execution of the statement,
while generating text,
- to change the output file during the execution of the statement, while generating
text, and to apply an expansion mode on it,
2.7.1 Statement's modifier 'delay'
This keyword stands just before an instruction or a compound statement. It executes the statement and then, it
measures the time it has consumed.
Function getLastDelay (getLastDelay()) gives you the last measured duration.
Example:
local list;
local iIndex = 4;
delay while isPositive(decrement(iIndex)) {
pushItem list = "element " + iIndex;
traceLine("creating node '" + list#back + "'");
}
traceLine("time of execution = " + getLastDelay() + " seconds");
Output:
creating node 'element 3'
creating node 'element 2'
creating node 'element 1'
time of execution = 0.000043301592800202261 seconds
2.7.2 Statement modifier 'quiet'
This keyword stands just before an instruction or a compound statement. It executes the
statement and all messages intended to the console are concatenated into a string, instead of
being displayed. The variable that receives the concatenation of messages is specified after
the quiet keyword.
The BNF representation of the quiet statement modifier looks like:
quiet_modifier ::= "quiet" '(' variable ')' statement
Note that the variable must have been declared before, as a local one or as an attribute of
the parse tree. If this variable doesn't exist while executing the statement, an error is
raised.
2.7.3 Statement modifier 'new project'
This keyword stands just before an instruction or a compound statement. A new project
parse tree is created, which is empty and that replaces temporarily the current one.
The statement is executed and, once the controlling sequence leaves the statement, the
temporary parse tree is removed, and the precedent project comes back as the current
one.
The BNF representation of the new_project statement modifier looks like:
new_project_modifier ::= "new_project" statement
This statement modifier is useful to handle a task that doesn't have to interact with the main parse tree.
2.7.4 Statement modifier 'file as standard input'
This keyword stands just before an instruction or a compound statement. A new standard input
is opened for reading data. Generally, the keyboard is the standard input, but here, it will
be the content of a file that is passed to the argument filename. Once the execution
of the statement has completed, the precedent standard input comes back.
The BNF representation of the file_as_standard_input statement's modifier looks like:
file_as_standard_input_modifier ::= "file_as_standard_input" '(' filename ')' statement
This statement modifier is useful to replay a sequence of commands for the debugger or to drive
the standard input from an external module that puts its instructions into a file for a batch
mode or anything else.
2.7.5 Statement modifier 'string as standard input'
This keyword stands just before an instruction or a compound statement. A new standard input
is opened for reading data. Generally, the keyboard is the standard input, but here, it will
be the content of the string that is passed to argument. Once the execution of the statement
has completed, the precedent standard input comes back.
The BNF representation of the string_as_standard_input statement's modifier looks like:
string_as_standard_input_modifier ::= "string_as_standard_input" '(' expression ')' statement
The standard input is the result of evaluating expression.
This statement modifier is useful to drive the standard input of CodeWorker from an external
module, such as a JNI library or an external C++ application ( see chapter external bindings).
2.7.6 Statement modifier 'parsed file'
This keyword stands just before an instruction or a compound statement that belongs to a
parsing/translation script exclusively. A new input file is opened for source scanning,
and replaces temporarily the precedent during the execution of the statement.The statement is
executed and, once the controlling sequence leaves the statement, the input file is closed
properly and the precedent one comes back.
The BNF representation of the parsed_file statement modifier looks like:
parsed_file_modifier ::= "parsed_file" '(' filename ')' statement
The token filename is an expression that is evaluated to give the name of the input
file.
This statement modifier is useful to handle a task that must redirect the text to parse into
another input file. An example could be to emulate the C++ preprocessing on #include
directives.
2.7.7 Statement modifier 'parsed string'
This keyword stands just before an instruction or a compound statement that belongs to a
parsing/translation script exclusively. The result of an expression is taken as the source to scan,
and replaces temporarily the precedent input during the execution of the statement.The statement is
executed and, once the controlling sequence leaves the statement the precedent input comes back.
The BNF representation of the parsed_string statement modifier looks like:
parsed_string_modifier ::= "parsed_string" '(' expression ')' statement
The token fexpression is an expression that is evaluated to give the text to scan.
This statement modifier is useful to handle a task that must temporary parse a string.
2.7.8 Statement modifier 'generated file'
This keyword stands just before an instruction or a compound statement that belongs to a
pattern script exclusively. A new output file is opened for source code generation, preserving
protected areas as usually, and replaces temporarily the current one during the execution of the
statement. The statement is executed and, once the controlling sequence leaves the statement,
the output file is closed properly and the precedent one takes its place.
The BNF representation of the generated_file statement modifier looks like:
generated_file_modifier ::= "generated_file" '(' filename ')' statement
The token filename is an expression that is evaluated to give the name of the output
file.
This statement modifier is useful to handle a task that must redirect the generated text into
another output file. An example could be to split an HTML text to generate into a few files
for implementing a frame set.
2.7.9 Statement modifier 'generated string'
This keyword stands just before an instruction or a compound statement that belongs to a
pattern script exclusively. The output stream is redirected into a variable that
replaces temporarily the current output stream during the execution of the statement.
The statement is executed and, once the controlling sequence leaves the statement,
the variable is populated with the content of the output produced during this scope and the
precedent output stream takes its place.
The BNF representation of the generated_string statement modifier looks like:
generated_string_modifier ::= "generated_string" '(' variable ')' statement
The variable argument gives the name of the variable that will be populated with the
generated text. This variable must already exist, declared on the stack or referring a node of
the current parse tree.
2.7.10 Statement modifier 'appended file'
This keyword stands just before an instruction or a compound statement that belongs to a
pattern script exclusively. A new output file is opened for appending source code generation
at the end of the file and replaces temporarily the current one during the execution of the
statement. The statement is executed and, once the controlling sequence leaves the statement,
the output file is closed properly and the precedent one takes its place.
The BNF representation of the appended_file statement modifier looks like:
appended_file_modifier ::= "appended_file" '(' filename ')' statement
The token filename is an expression that is evaluated to give the name of the output
file to append.
3 Common functions and procedures
All functions and procedures that are described below may be encountered in any kind of
scripts : parsing, source code generation and file expanding, process driving, included script
files.
| Category interpreter | Function for running a CodeWorker script |
| autoexpand |
Expands a file on markups, following the directives self-contained in the file. |
| executeString |
Executes a script given in a string. |
| executeStringQuiet |
Interprets a string as a script and returns all traces intended to the console. |
| expand |
Expands a file on markups, following the directives of a template-based script. |
| extendExecutedScript |
Extend the current executed script dynamically with the content of the string. |
| generate |
Generates a file, following the directives of a template-based script. |
| generateString |
Generates a string, following the directives of a template-based script. |
| parseAsBNF |
Parses a file with a BNF script. |
| parseFree |
Parses a file with an imperative script. |
| parseFreeQuiet |
Parses a file with an imperative script, reroute all console messages and returns them as a string. |
| parseStringAsBNF |
Parses a string with a BNF script. |
| traceEngine |
Displays the state of the interpreter. |
| translate |
Performs a source-to-source translation or a program transformation. |
| translateString |
Performs a source-to-source translation or a program transformation on strings. |
| Category string | Functions for handling strings |
| charAt |
Returns the characters present at a given position of a string. |
| completeLeftSpaces |
Completes a string with spaces to the left so that it reaches a given size. |
| completeRightSpaces |
Completes a string with spaces to the right so that it reaches a given size. |
| composeAdaLikeString |
Converts a sequence of characters to a Ada-like string without double quote delimiters. |
| composeCLikeString |
Converts a sequence of characters to a C-like string without double quote delimiters. |
| composeHTMLLikeString |
Converts a sequence of characters to an HTML-like text |
| composeSQLLikeString |
Converts a sequence of characters to a SQL-like string without single quote delimiters. |
| coreString |
Extracts the core of a string, leaving the beginning and the end. |
| countStringOccurences |
How many occurences of a string to another. |
| cutString |
Cuts a string at each separator encountered. |
| endString |
Compares the end of the string. |
| endl |
Returns an end-of-line, depending on the operating system. |
| equalsIgnoreCase |
Compares two strings, ignoring the case. |
| executeString |
Executes a script given in a string. |
| executeStringQuiet |
Interprets a string as a script and returns all traces intended to the console. |
| findFirstChar |
Returns the position of the first character amongst a set, encountered into a string. |
| findLastString |
Returns the position of the last occurence of a string to another. |
| findNextString |
Returns the next occurence of a string to another. |
| findString |
Returns the first occurence of a string to another. |
| generateString |
Generates a string, following the directives of a template-based script. |
| joinStrings |
Joins a list of strings, adding a separator between them. |
| leftString |
Returns the beginning of a string. |
| lengthString |
Returns the length of a string. |
| midString |
Returns a substring starting at a point for a given length. |
| parseStringAsBNF |
Parses a string with a BNF script. |
| repeatString |
Returns the concatenation of a string repeated a few times. |
| replaceString |
Replaces a substring with another. |
| replaceTabulations |
Replaces tabulations with spaces. |
| rightString |
Returns the end of a string. |
| rsubString |
Returns the left part of a string, ignoring last characters. |
| startString |
Checks the beginning of a string. |
| subString |
Returns a substring, ignoring the first characters. |
| toLowerString |
Converts a string to lowercase. |
| toUpperString |
Converts a string to uppercase. |
| trim |
Eliminates heading and trailing whitespaces. |
| trimLeft |
Eliminates the leading whitespaces. |
| trimRight |
Eliminates the trailing whitespaces. |
| truncateAfterString |
Special truncation of a string. |
| truncateBeforeString |
Special truncation of a string. |
| Category array | Functions handling arrays |
| findElement |
Checks the existence of an entry key in an array. |
| findFirstSubstringIntoKeys |
Returns the first entry key of an array, containing a given string. |
| findNextSubstringIntoKeys |
Returns the next entry key of an array, containing a given string. |
| getArraySize |
Returns the number of items in an array. |
| insertElementAt |
Inserts a new element to a list, at a given position. |
| invertArray |
Inverts the order of items in an array. |
| isEmpty |
Checks whether a node has items or not. |
| removeAllElements |
Removes all items of the array. |
| removeElement |
Removes an item, given its entry key. |
| removeFirstElement |
Removes the first item of the array. |
| removeLastElement |
Removes the last item of the array. |
| Category node | Functions handling a node |
| clearVariable |
Removes the subtree and assigns an empty value. |
| equalTrees |
Compares two subtrees. |
| existVariable |
Checks the existence of a node. |
| getVariableAttributes |
Extract all attribute names of a tree node. |
| removeRecursive |
Removes a given attribute from the subtree. |
| removeVariable |
Removes a given variable. |
| slideNodeContent |
Moves the subtree elsewhere on a branch. |
| sortArray |
Sort an array, considering the entry keys. |
| Category iterator | Functions handling an iterator |
| createIterator |
Creates an iterator pointing to the beginning of a list. |
| createReverseIterator |
Creates a reverse iterator pointing to the end of a list. |
| duplicateIterator |
Duplicates an iterator. |
| first |
Returns true if the iterator points to the first item. |
| index |
Returns the position of an item in a list. |
| key |
Returns the entry key of the item pointed to by the iterator. |
| last |
Returns true if the iterator points to the last item. |
| next |
Move an iterator to the next item of a list. |
| prec |
Move an iterator to the precedent item of a list. |
| Category file | Functions handling files |
| appendFile |
Writes the content of a string to the end of a file |
| canonizePath |
Builds an absolute path, starting to the current directory. |
| changeFileTime |
Changes the access and modification times of a file. |
| chmod |
Changes the permissions of a file. |
| copyFile |
Copies a file. |
| copyGenerableFile |
Copies a file with protected areas or expandable markups, only if the hand-typed code differs between source and destination. |
| copySmartFile |
Copies a file only if the destination differs. |
| createVirtualFile |
Creates a transient file in memory. |
| createVirtualTemporaryFile |
Creates a transient file in memory, CodeWorker choosing its name. |
| deleteFile |
Deletes a file on the disk. |
| deleteVirtualFile |
Deletes a transient file from memory. |
| existFile |
Checks the existence of a file. |
| existVirtualFile |
Checks the existence of a transient file, created in memory. |
| exploreDirectory |
Browses all files of a directory, recursively or not. |
| fileCreation |
Returns the creation date of a file. |
| fileLastAccess |
Returns the last access date of a file. |
| fileLastModification |
Returns the last modification date of a file. |
| fileLines |
Returns the number of lines in a file. |
| fileMode |
Returns the permissions of a file. |
| fileSize |
Returns the size of a file. |
| getGenerationHeader |
Returns the comment to put into the header of generated files. |
| getShortFilename |
Returns the short name of a file |
| indentFile |
Indents a file, depending on the target language. |
| loadBinaryFile |
Loads a binary file and stores each byte in a hexadecimal representation of 2 digits. |
| loadFile |
Returns the content of a file or raises an error if not found. |
| loadVirtualFile |
Returns the content of a transient file or raises an error if not found. |
| pathFromPackage |
Converts a package path to a directory path. |
| relativePath |
Returns the relative path, which allows going from a path to another. |
| resolveFilePath |
Gives the location of a file with no ambiguity. |
| saveBinaryToFile |
Saves binary data to a file. |
| saveToFile |
Saves the content of a string to a file |
| scanDirectories |
Explores a directory, filtering filenames. |
| scanFiles |
Returns a flat list of all filenames matching with a filter. |
| Category directory | Functions handling directories |
| changeDirectory |
Changes the current directory (chdir() in C). |
| copySmartDirectory |
Copies files of a directory recursively only when destination files differ from source files. |
| createDirectory |
Creates a new directory. |
| existDirectory |
Check the existence of a directory. |
| exploreDirectory |
Browses all files of a directory, recursively or not. |
| getCurrentDirectory |
Returns the current directory (getcwd() in C). |
| removeDirectory |
Removes a directory from the disk. |
| scanDirectories |
Explores a directory, filtering filenames. |
| scanFiles |
Returns a flat list of all filenames matching with a filter. |
| Category URL | Functions working on URL transfers (HTTP,...) |
| decodeURL |
Decodes an HTTP URL. |
| encodeURL |
Encodes an URL to HTTP. |
| getHTTPRequest |
Sends an HTTP's GET request. |
| postHTTPRequest |
Sends an HTTP's POST request. |
| sendHTTPRequest |
Sends an HTTP request. |
| Category datetime | Functions handling date-time |
| addToDate |
Change a date by shifting its internal fields days/months/years or time. |
| compareDate |
Compares two dates. |
| completeDate |
Extends an incomplete date with today characteristics. |
| fileCreation |
Returns the creation date of a file. |
| fileLastAccess |
Returns the last access date of a file. |
| fileLastModification |
Returns the last modification date of a file. |
| formatDate |
Changes the format of a date. |
| getLastDelay |
Returns the time consumed to execute a statement. |
| getNow |
Returns the current date-time. |
| setNow |
Fixes the current date-time. |
| Category numeric | Functions handling numbers |
| add |
Equivalent admitted writing is $a + b$. |
| ceil |
Returns the smallest integer greater that or equal to a number |
| decrement |
Equivalent admitted writing is set a = $a - 1$;. |
| div |
Equivalent admitted writing is $a / b$. |
| equal |
Equivalent admitted writing is $a == b$. |
| exp |
Returns the exponential of a value. |
| floor |
Returns the largest integer less that or equal to a number |
| increment |
Equivalent admitted writing is set a = $a + 1$;. |
| inf |
Equivalent admitted writing is $a < b$. |
| isNegative |
Equivalent admitted writing is $a < 0$. |
| isPositive |
Equivalent admitted writing is $a > 0$. |
| log |
Returns the Neperian logarithm. |
| mod |
Equivalent admitted writing is $a % b$. |
| mult |
Equivalent admitted writing is $a * b$. |
| pow |
Raises a number to the power of another. |
| sqrt |
Calculates the square root. |
| sub |
Equivalent admitted writing is $a - b$. |
| sup |
Equivalent admitted writing is $a > b$. |
| Category standard | Classical functions of any standard library |
| UUID |
Generates an UUID. |
| error |
Raises an error message |
| inputKey |
If any, returns the last key pressed on the standard input. |
| inputLine |
Wait for the standard input to the console. |
| isIdentifier |
Checks whether a string is a C-like identifier or not. |
| isNumeric |
Checks whether a string is a floating-point number or not. |
| randomInteger |
Generates a pseudorandom number. |
| randomSeed |
Changes the seed of the pseudorandom generator. |
| traceLine |
Displays a message to the console, adding a carriage return. |
| traceObject |
Displays the content of a node to the console. |
| traceStack |
Displays the stack to the console. |
| traceText |
Displays a message to the console. |
| Category conversion | Type conversion |
| byteToChar |
Converts a byte (hexadecimal representation of 2 digits) to a character. |
| bytesToLong |
Converts a 4-bytes sequence to an unsigned long integer in its decimal representation. |
| bytesToShort |
Converts a 2-bytes sequence to an unsigned short integer in its decimal representation. |
| charToByte |
Converts a character to a byte (hexadecimal representation of 2 digits). |
| charToInt |
Converts a character to the integer value of the corresponding ASCII. |
| hexaToDecimal |
Converts an hexadecimal representation to an integer. |
| hostToNetworkLong |
Converts a 4-bytes representation of a long integer to the network bytes order. |
| hostToNetworkShort |
Converts a 2-bytes representation of a short integer to the network bytes order. |
| longToBytes |
Converts an unsigned long integer in decimal base to its 4-bytes representation. |
| networkLongToHost |
Converts a 4-bytes representation of a long integer to the host bytes order. |
| networkShortToHost |
Converts a 2-bytes representation of a short integer to the host bytes order. |
| octalToDecimal |
Converts an octal representation to a decimal integer. |
| shortToBytes |
Converts an unsigned short integer in decimal base to its 2-bytes representation. |
| Category system | Functions relative to the operating system |
| computeMD5 |
Computes the MD5 of a string. |
| environTable |
Equivalent of environ() in C |
| existEnv |
Checks the existence of an environment variable. |
| getEnv |
Returns an environment variable, or raises an error if not exist. |
| openLogFile |
Opens a log file for logging every console trace. |
| putEnv |
Puts a value to an environment variable. |
| sleep |
Suspends the execution for millis milliseconds. |
| system |
Equivalent to the C function system(). |
| Category command | Relative to the command line |
| compileToCpp |
Translates a script to C++. |
| getIncludePath |
Returns the include path passed via the option -I. |
| getProperty |
Returns the value of a property passed via the option -D. |
| getVersion |
Returns the version of the interpreter. |
| getWorkingPath |
Returns the output directory passed via option -path. |
| setIncludePath |
Changes the option -I while running. |
| setProperty |
Adds/changes a property (option -D) while running. |
| setVersion |
Gives the version of scripts currently interpreted by CodeWorker. |
| setWorkingPath |
Does the job of the option -path. |
| Category generation | Functions relative to generation |
| addGenerationTagsHandler |
Adds your own CodeWorker's tags handler |
| autoexpand |
Expands a file on markups, following the directives self-contained in the file. |
| expand |
Expands a file on markups, following the directives of a template-based script. |
| extractGenerationHeader |
Gives the generation header of a generated file, if any. |
| generate |
Generates a file, following the directives of a template-based script. |
| generateString |
Generates a string, following the directives of a template-based script. |
| getCommentBegin |
Returns the current format of a comment's beginning. |
| getCommentEnd |
Returns the current format of a comment's end. |
| getGenerationHeader |
Returns the comment to put into the header of generated files. |
| getTextMode |
Returns the text mode amongst "DOS", "UNIX" and "BINARY". |
| getWriteMode |
Returns how text is written during a generation (insert/overwrite). |
| listAllGeneratedFiles |
Gives the list of all generated files. |
| removeGenerationTagsHandler |
Removes a custom generation tags handler |
| selectGenerationTagsHandler |
Selects your own CodeWorker's tags handler for processing generation tasks |
| setCommentBegin |
Changes what a beginning of comment looks like, perhaps before expanding a file. |
| setCommentEnd |
Changes what an end of comment looks like, perhaps before expanding a file. |
| setGenerationHeader |
Specifies a comment to put at the beginning of every generated file. |
| setTextMode |
"DOS", "UNIX" or "BINARY" |
| setWriteMode |
Selects how to write text during a generation (insert/overwrite). |
| translate |
Performs a source-to-source translation or a program transformation. |
| translateString |
Performs a source-to-source translation or a program transformation on strings. |
| Category parsing | Functions relative to scanning/parsing |
| parseAsBNF |
Parses a file with a BNF script. |
| parseFree |
Parses a file with an imperative script. |
| parseFreeQuiet |
Parses a file with an imperative script, reroute all console messages and returns them as a string. |
| parseStringAsBNF |
Parses a string with a BNF script. |
| translate |
Performs a source-to-source translation or a program transformation. |
| translateString |
Performs a source-to-source translation or a program transformation on strings. |
| Category socket | Socket operations |
| acceptSocket |
Listens for a client connection and accepts it. |
| closeSocket |
Closes a socket descriptor. |
| createINETClientSocket |
Creates a stream socket connected to the specified port and IP address. |
| createINETServerSocket |
Creates a server stream socket bound to a specified port. |
| receiveBinaryFromSocket |
Reads binary data from the socket, knowing the size. |
| receiveFromSocket |
Reads text or binary data from a socket. |
| receiveTextFromSocket |
Reads text from a socket, knowing the size. |
| sendBinaryToSocket |
Writes binary data to a socket. |
| sendTextToSocket |
Writes text to a socket. |
| Category unknown | Various types of function |
| loadProject |
Loads a parse tree previously saved thanks to saveProject(). |
| not |
The boolean negation, equivalent to !a. |
| produceHTML |
| saveProject |
Saves a parse tree to XML or to a particular text format. |
| saveProjectTypes |
Factorizes nodes of the projects to distinguish implicit types for node and saves it to XML. |
3.1 acceptSocket
- function acceptSocket(serverSocket : int) : int
| Parameter | Type | Description |
| serverSocket |
int |
a server socket previously created via createINETServerSocket() |
This function blocks until a client connection arrives, and returns the corresponding
socket descriptor.
Once a connection has been established, use directly the send/receive functions
or attachInputToSocket()/attachOutputToSocket for reading/writing
to the socket via a BNF-parsing/template-based script.
See also:
createINETClientSocket createINETClientSocket(), createINETServerSocket createINETServerSocket(), attachInputToSocket attachInputToSocket(), detachInputFromSocket detachInputFromSocket(), attachOutputToSocket attachOutputToSocket(), detachOutputFromSocket detachOutputFromSocket(), receiveBinaryFromSocket receiveBinaryFromSocket(), receiveFromSocket receiveFromSocket(), receiveTextFromSocket receiveTextFromSocket(), sendTextToSocket sendTextToSocket(), sendBinaryToSocket sendBinaryToSocket(), closeSocket closeSocket(), flushOutputToSocket flushOutputToSocket()
3.2 add
- function add(left : double, right : double) : double
| Parameter | Type | Description |
| left |
double |
left arithmetic member |
| right |
double |
right arithmetic member |
Returns the result of arithmetic addition left + right.
Members are converted from strings to numbers, supposed being worth 0 if a parsing error occurs;
then the addition is processed, and the result is converted to a string,
skipping fractional part if all digits after the dot are 0.
Remember that the symbol '+' means the concatenation of text. Using
this operator instead of function add will concatenate digits!
However, it exists an escape mode that allows writing arithmetic expressions
between '$' symbols, as formula under LaTeX. So, $left + right$
is equivalent to add(left, right).
Example:
local a = 3.2;
traceLine(a + " + 4.5 = " + add(a, "4.5"));
traceLine(a + " + 2.8 = " + add(a, 2.8) + " <- integer value");
Output:
3.2 + 4.5 = 7.7
3.2 + 2.8 = 6 <- integer value
See also:
sub sub(), mult mult(), div div(), exp exp(), log log(), mod mod(), pow pow()
3.3 addGenerationTagsHandler
- function addGenerationTagsHandler(key : string, reader : script, writer : script) : bool
| Parameter | Type | Description |
| key |
string |
designates the handler |
| reader |
script<BNF> |
extended-BNF script of the reader |
| writer |
script<pattern> |
template-based script of the writer |
Adds a new generation tags handler, designated by key.
Returns true if key isn't reserved yet for another generation tags handler.
See also:
removeGenerationTagsHandler removeGenerationTagsHandler(), selectGenerationTagsHandler selectGenerationTagsHandler()
3.4 addToDate
- function addToDate(date : string, format : string, shifting : string) : string
| Parameter | Type | Description |
| date |
string |
the date to change |
| format |
string |
the format to apply on the reading of the shifting argument |
| shifting |
string |
the offset values to apply on the date, whose meanings are known by the offset argument |
Change a date by applying offset values on its internal representation.
The internal representation holds the year / month / day and hour / minute / second
and millisecond fields. You choose what fields to shift, giving a date
format as the first argument, and an offset value for each fields seen in the
format as the second argument.
The field types have the same syntax as in the function formatDate, except
that the field values might be negative.
For instance, if the field type is "%m", the month must occupy 2 digits maximum for a
positive offset, and 3 characters for a negative offset, the first one being the sign.
The offsets are applied in the order they are read, from the left-hand side to the right.
The function returns the value of the date after applying the shift.
Example:
traceLine("Substract 2 months and add 20 hours to the current date-time:");
local newDate = addToDate(getNow(), "%m,%H", "-2,20");
traceLine("one manner: " + getNow() + " -> " + newDate);
newDate = addToDate(getNow(), "%m%H", "-0220");
traceLine("another manner: " + getNow() + " -> " + newDate);
Output:
Substract 2 months and add 20 hours to the current date-time:
one manner: 02aug2008 20:42:00.500 -> 03jun2008 16:42:00.500
another manner: 02aug2008 20:42:00.500 -> 03jun2008 16:42:00.500
See also:
formatDate formatDate(), compareDate compareDate(), completeDate completeDate(), getLastDelay getLastDelay(), getNow getNow(), setNow setNow()
3.5 appendFile
- procedure appendFile(filename : string, content : string)
| Parameter | Type | Description |
| filename |
string |
name of the file to append |
| content |
string |
sequence of characters to write at the end of the file |
Writes the text content at the end of the file filename.
If the file doesn't exist, the function creates it.
See also:
copyFile copyFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.6 autoexpand
- procedure autoexpand(outputFileName : string, this : treeref)
| Parameter | Type | Description |
| outputFileName |
string |
the existing file to expand |
| this |
treeref |
the current node that will be accessed with this variable |
Expands an existing file whose name is passed to the argument outputFileName,
executing template-based scripts located at each markup. The file contains
its own scripts for expanding code.
Expanding a file consists of generating code into marked out areas only, the rest
of the file remaining the same. The markup is put into a comment, knowing that the
syntax of the comment must conform to the type of the expanded file outputFileName.
So, an HTML file expects <!- - and - ->, a JAVA file is waiting
for // and "\n", ... The markup is announced by
##markup## followed by a string that represents the markup key.
Don't forget to configure correctly the syntax of comment boundaries with procedures
setCommentBegin() (see setCommentBegin()) and setCommentEnd() (see setCommentEnd()).
When the procedure is called, CodeWorker jumps from a markup to another. To
handle a markup, it checks whether text was already generated, put between tags
##begin##"markup-key" and ##end##"markup-key",
added automatically the first time an expansion is required, to demarquate the
portion of code that doesn't belong to the user. Then, it extracts all protected
areas, if any, and it generates code at the position of the markup, adding
begin/end tags seen before.
The interpreter reclaims the tags ##script## just after the markup.
It extracts the embedded text, considered as a template-based script, eventually
put between comments, and the interpreter executes this embedded script.
Note that some data might be put between tags ##data##, accessible
in the template-based script via the function getMarkupValue() (see getMarkupValue()).
This block of custom data comes after the ##script## tag, if present.
Be careful not to confuse this prodedure with generate() that doesn't care
about markups and that overwrites the output file completely, except protected
areas of course.
See also:
expand expand(), generate generate(), generateString generateString(), translate translate(), parseAsBNF parseAsBNF(), parseFree parseFree(), parseFreeQuiet parseFreeQuiet(), parseStringAsBNF parseStringAsBNF(), translateString translateString()
3.7 bytesToLong
3.8 bytesToShort
3.9 byteToChar
3.10 canonizePath
- function canonizePath(path : string) : string
| Parameter | Type | Description |
| path |
string |
the path to canonize |
Returns the path passed to the argument path after having canonized it.
To canonize a path means that:
- '..' and '.' directories are processed,
- backslashes are changed to forward slashes,
- if the path is relative, it is converted to a full path, starting
at the current directory.
Example:
traceLine("current directory = '" + getCurrentDirectory() + "'");
local sPath = "WebSite/downloads/CodeWorker.zip";
traceLine(" path = '" + sPath + "'");
traceLine(" result = '" + canonizePath(sPath) + "'");
local sCurrentDirectory = getCurrentDirectory();
changeDirectory(sCurrentDirectory + "Documentation");
traceLine("current directory = '" + getCurrentDirectory() + "'");
set sPath = "../Scripts/Tutorial/GettingStarted/tiny.html";
traceLine(" path = '" + sPath + "'");
traceLine(" result = '" + canonizePath(sPath) + "'");
changeDirectory(sCurrentDirectory);
traceLine("current directory = '" + getCurrentDirectory() + "'");
set sPath = ".";
traceLine(" path = '" + sPath + "'");
traceLine(" result = '" + canonizePath(sPath) + "'");
Output:
current directory = 'E:/projects/generator/'
path = 'WebSite/downloads/CodeWorker.zip'
result = 'e:/projects/generator/WebSite/downloads/CodeWorker.zip'
current directory = 'E:/projects/generator/Documentation/'
path = '../Scripts/Tutorial/GettingStarted/tiny.html'
result = 'e:/projects/generator/Scripts/Tutorial/GettingStarted/tiny.html'
current directory = 'E:/projects/generator/'
path = '.'
result = 'e:/projects/generator'
See also:
changeDirectory changeDirectory(), copySmartDirectory copySmartDirectory(), exploreDirectory exploreDirectory(), getCurrentDirectory getCurrentDirectory(), relativePath relativePath(), removeDirectory removeDirectory(), resolveFilePath resolveFilePath(), scanDirectories scanDirectories(), existDirectory existDirectory()
3.11 ceil
3.12 changeDirectory
- function changeDirectory(path : string) : bool
| Parameter | Type | Description |
| path |
string |
path name of the directory |
The function changes the current directory of CodeWorker to the directory
specified by the path argument. The parameter must refer to an existing
directory.
Example:
traceLine("current directory = '" + getCurrentDirectory() + "'");
local sOldDirectory = getCurrentDirectory();
local sNewDirectory = sOldDirectory + "Documentation";
traceLine("call to changeDirectory('" + sNewDirectory + "')");
changeDirectory(sNewDirectory);
traceLine("new current directory = '" + getCurrentDirectory() + "'");
changeDirectory(sOldDirectory);
Output:
current directory = 'E:/projects/generator/'
call to changeDirectory('E:/projects/generator/Documentation')
new current directory = 'E:/projects/generator/Documentation/'
See also:
canonizePath canonizePath(), copySmartDirectory copySmartDirectory(), exploreDirectory exploreDirectory(), getCurrentDirectory getCurrentDirectory(), relativePath relativePath(), removeDirectory removeDirectory(), resolveFilePath resolveFilePath(), scanDirectories scanDirectories(), existDirectory existDirectory()
3.13 changeFileTime
- function changeFileTime(filename : string, accessTime : string, modificationTime : string) : int
| Parameter | Type | Description |
| filename |
string |
name of the file to set |
| accessTime |
string |
date-time of the last access |
| modificationTime |
string |
date-time of the last modification |
The function changes the access and modification times of the file filename.
The user ID of the process must be the owner of the file, or the process must
have appropriate privileges.
In case of failure, the function returns a negative integer:
- -1: unknown error that shouldn't appear,
- -2: permission denied,
- -3: too many files have been opened,
- -4: file not found,
- -5: invalid times argument,
Example:
local oldAccessTime = fileLastAccess("readme.txt");
local oldModifTime = fileLastModification("readme.txt");
traceLine("old modification time of 'readme.txt' = '" + oldModifTime + "'");
if $changeFileTime("readme.txt", getNow(), getNow()) < 0$
error("'changeFileTime()' has failed!");
local newModifTime = fileLastModification("readme.txt");
traceLine("new modification time of 'readme.txt' = '" + newModifTime + "'");
// put the same times as before calling the example:
if $changeFileTime("readme.txt", oldAccessTime, oldModifTime) < 0$
error("'changeFileTime()' has failed!");
Output:
old modification time of 'readme.txt' = '02may2008 04:51:36'
new modification time of 'readme.txt' = '02aug2008 20:42:00'
See also:
copyFile copyFile(), appendFile appendFile(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.14 charAt
- function charAt(text : string, index : int) : string
| Parameter | Type | Description |
| text |
string |
a sequence of characters |
| index |
int |
the index of the character to extract from text |
Returns the character at the specified index. An index ranges from 0 to lengthString(text) - 1. The first character of the sequence is at index 0, the next at index 1, and so on. If the index argument is out of bounds (negative or not less than the length of text), it returns an empty string.
Example:
local sText = "I have but one lamp by which my feet are guided, and that is the lamp of experience. (P. Henry)";
traceLine("charAt('" + sText + "', 2) = '" + charAt(sText, 2) + "' <- index = 2 gives the third character of the string");
Output:
charAt('I have but one lamp by which my feet are guided, and that is the lamp of experience. (P. Henry)', 2) = 'h' <- index = 2 gives the third character of the string
See also:
coreString coreString(), cutString cutString(), joinStrings joinStrings(), leftString leftString(), lengthString lengthString(), midString midString(), rightString rightString(), rsubString rsubString(), subString subString()
3.15 charToByte
3.16 charToInt
3.17 chmod
- function chmod(filename : string, mode : string) : bool
| Parameter | Type | Description |
| filename |
string |
file to which change the permission setting |
| mode |
string |
permission setting as a concatenation of 'R' and/or 'W' and/or 'X' |
The chmod function changes the permission setting of the file specified by filename.
The permission setting controls read and write and execute access to the file.
The argument mode holds the permission setting of the file as a concatenation of chars amongst the following:
- 'R' for reading permitted,
- 'W' for writing permitted,
- 'X' for executing permitted (ignored on Windows platform),
The function fails when the file given by the argument filename is not found, and an error is thrown when the argument mode contains an unexpected character.
Example:
local bSuccess = chmod("Documentation/CodeWorker.tex", "RW");
if !bSuccess error("file 'Documentation/CodeWorker.tex' not found!");
traceLine("R + W permitted on file 'Documentation/CodeWorker.tex'");
Output:
R + W permitted on file 'Documentation/CodeWorker.tex'
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.18 clearVariable
- procedure clearVariable(node : treeref)
| Parameter | Type | Description |
| node |
treeref |
the node to clear |
All attributes of the argument node are deleted, its array of nodes is
cleared and its value becomes an empty string. If the node was referring to
another node, the link is cleared.
Please note that the node isn't removed; see removeVariable() for that.
Example:
local myNode = "the value";
insert myNode.a1 = "attribute 1";
insert myNode.a2 = "attribute 2";
insert myNode.array["1"] = "node 1";
insert myNode.array["2"] = "node 2";
traceObject(myNode);
traceLine("-- the variable 'myNode' is cleared:");
clearVariable(myNode);
traceObject(myNode);
Output:
Tracing variable 'myNode':
"the value"
a1 = "attribute 1"
a2 = "attribute 2"
array
array["1", "2"]
End of variable's trace 'myNode'.
-- the variable 'myNode' is cleared:
Tracing variable 'myNode':
End of variable's trace 'myNode'.
Deprecated form: clearNode has disappeared since version 3.8.7
See also:
existVariable existVariable(), findFirstSubstringIntoKeys findFirstSubstringIntoKeys(), findElement findElement(), findNextSubstringIntoKeys findNextSubstringIntoKeys(), getArraySize getArraySize(), getVariableAttributes getVariableAttributes(), invertArray invertArray(), isEmpty isEmpty(), removeVariable removeVariable()
3.19 closeSocket
- procedure closeSocket(socket : int)
| Parameter | Type | Description |
| socket |
int |
a client/server socket descriptor |
This procedure closes the socket descriptor specified to the argument socket.
See also:
createINETClientSocket createINETClientSocket(), createINETServerSocket createINETServerSocket(), acceptSocket acceptSocket(), attachInputToSocket attachInputToSocket(), detachInputFromSocket detachInputFromSocket(), attachOutputToSocket attachOutputToSocket(), detachOutputFromSocket detachOutputFromSocket(), receiveBinaryFromSocket receiveBinaryFromSocket(), receiveFromSocket receiveFromSocket(), receiveTextFromSocket receiveTextFromSocket(), sendTextToSocket sendTextToSocket(), sendBinaryToSocket sendBinaryToSocket(), flushOutputToSocket flushOutputToSocket()
3.20 compareDate
- function compareDate(date1 : string, date2 : string) : int
| Parameter | Type | Description |
| date1 |
string |
a date that conforms to the following format: "%d%b%Y %H:%M:%S.%L" |
| date2 |
string |
second date to compare to date1 |
The function returns:
- a negative value when date1 < date2,
- zero when date1 is equal to date2,
- a positive value when date1 > date2.
If an argument doesn't conform to the expected syntax for a date
(meaning that it must match with "%d%b%Y %H:%M:%S.%L"),
an error is raised.
Example:
local date1 = "19jan2003 20:12:00.000";
local date2 = "28dec2012 07:30:00.000";
local now = getNow();
traceLine("getNow() = '" + now + "'");
traceLine("compareDate('" + date1 + "', getNow()) = " + compareDate(date1, now));
traceLine("compareDate('" + date2 + "', getNow()) = " + compareDate(date2, now));
Output:
getNow() = '02aug2008 20:42:00.500'
compareDate('19jan2003 20:12:00.000', getNow()) = -1
compareDate('28dec2012 07:30:00.000', getNow()) = 1
See also:
formatDate formatDate(), addToDate addToDate(), completeDate completeDate(), getLastDelay getLastDelay(), getNow getNow(), setNow setNow()
3.21 compileToCpp
- procedure compileToCpp(scriptFileName : string, projectDirectory : string, CodeWorkerDirectory : string)
| Parameter | Type | Description |
| scriptFileName |
string |
the name of a script file to compile to C++ |
| projectDirectory |
string |
the location where to put on the disk the scripts compiled to C++ |
| CodeWorkerDirectory |
string |
the root path of CodeWorker either in development or distributed state |
Compiles the leader script file called scriptFileName and all scripts
that might be reclaimed during the execution. The corresponding C++ files are
stored into projectDirectory with the makefile (a Visual C++'s DSP
file). The path to libraries and the origin of some important include files is
determined thanks to the path to CodeWorker put into CodeWorkerDirectory.
The script file cannot be a pattern script or a parsing script.
If an error occurs, an error message is raised.
Example:
local sScriptFile = "GettingStarted/LeaderScript6.cws";
local sDirectory = getWorkingPath() +
"Scripts/Tutorial/GettingStarted/bin";
removeDirectory(sDirectory);
compileToCpp(sScriptFile, sDirectory, ".");
local theFiles;
if !scanFiles(theFiles, sDirectory, "", true) error("should have worked!");
traceLine("generated files:");
foreach i in sorted theFiles traceLine(" " + i);
Output:
generated files:
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/CGExternalHandling.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/CGRuntime.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/CppObjectBody_cwt.cpp
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/CppObjectBody_cwt.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/CppObjectHeader_cwt.cpp
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/CppObjectHeader_cwt.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/CppParsingTree.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/DynPackage.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/HTML2LaTeX_cwp.cpp
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/HTML2LaTeX_cwp.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/HTMLDocumentation_cwt.cpp
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/HTMLDocumentation_cwt.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/JAVAObject_cwt.cpp
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/JAVAObject_cwt.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/LeaderScript6.dsp
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/LeaderScript6_cws.cpp
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/LeaderScript6_cws.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/Makefile
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/SimpleML-parsing_cwp.cpp
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/SimpleML-parsing_cwp.h
e:\Projects\generator/Scripts/Tutorial/GettingStarted/bin/UtlException.h
3.22 completeDate
- function completeDate(date : string, format : string) : string
| Parameter | Type | Description |
| date |
string |
a date-time representation to complete |
| format |
string |
the format that the date argument conforms to |
Completes the date passed to the argument date, so as it conforms to the
syntax of a date in CodeWorker meaning: "%d%b%Y %H:%M:%S.%L".
Starting from today date with reset time (00:00:00.0), it replaces date-time
characteristics with those of the parameter date and returns the result
of the substitutions.
See formatDate() to reading the description of a date format.
A format type was added for this function: '%|'.
Once the date has been iterated up to the end, if the format wasn't applied on it completely,
an error occurs, except if '%|' stands at the current position in the format.
Example:
traceLine("Today date with reset time = '" + completeDate(getNow(), "%d%b%Y") + "'");
local dDateAsNumber = formatDate(getNow(), "%t");
traceLine("Today date (Excel-like) = '" + dDateAsNumber + "'");
traceLine("Preceding day = '" + completeDate($dDateAsNumber - 1$, "%t") + "'");
traceLine("15th of the current month = '" + completeDate("15", "%d") + "'");
traceLine("august of this year = '" + completeDate("08", "%m") + "'");
traceLine("15/04 = '" + completeDate("15/04", "%d/%m") + "'");
traceLine("december 31, 2003 = '" + completeDate("december 31, 2003", "%B %d, %Y") + "'");
Output:
Today date with reset time = '02aug2008'
Today date (Excel-like) = '39662.862506'
Preceding day = '01aug2008 20:42:00.518'
15th of the current month = '15aug2008'
august of this year = '02aug2008'
15/04 = '15apr2008'
december 31, 2003 = '31dec2003'
See also:
formatDate formatDate(), addToDate addToDate(), compareDate compareDate(), getLastDelay getLastDelay(), getNow getNow(), setNow setNow()
3.23 completeLeftSpaces
- function completeLeftSpaces(text : string, length : int) : string
| Parameter | Type | Description |
| text |
string |
a sequence of characters |
| length |
int |
the length to obtain for text |
Completes the string given by argument text with spaces to the left, so
that the resulting string takes up length characters long. If the
argument text contains more than length characters, it returns
text.
Example:
traceLine("completeLeftSpaces(1, 3) = '" + completeLeftSpaces(1, 3) + "'");
traceLine("completeLeftSpaces(123, 3) = '" + completeLeftSpaces(123, 3) + "'");
traceLine("completeLeftSpaces(1234, 3) = '" + completeLeftSpaces(1234, 3) + "'");
Output:
completeLeftSpaces(1, 3) = ' 1'
completeLeftSpaces(123, 3) = '123'
completeLeftSpaces(1234, 3) = '1234'
See also:
countStringOccurences countStringOccurences(), completeRightSpaces completeRightSpaces(), repeatString repeatString(), replaceString replaceString(), replaceTabulations replaceTabulations(), toLowerString toLowerString(), toUpperString toUpperString(), trimLeft trimLeft(), trimRight trimRight(), trim trim(), truncateAfterString truncateAfterString(), truncateBeforeString truncateBeforeString()
3.24 completeRightSpaces
- function completeRightSpaces(text : string, length : int) : string
| Parameter | Type | Description |
| text |
string |
a sequence of characters |
| length |
int |
the length to obtain for text |
Completes the string given by argument text with spaces to the right, so
that the resulting string takes up length characters long. If the
argument text contains more than length characters, it returns
text.
Example:
traceLine("completeRightSpaces(1, 3) = '" + completeRightSpaces(1, 3) + "'");
traceLine("completeRightSpaces(123, 3) = '" + completeRightSpaces(123, 3) + "'");
traceLine("completeRightSpaces(1234, 3) = '" + completeRightSpaces(1234, 3) + "'");
Output:
completeRightSpaces(1, 3) = '1 '
completeRightSpaces(123, 3) = '123'
completeRightSpaces(1234, 3) = '1234'
See also:
countStringOccurences countStringOccurences(), completeLeftSpaces completeLeftSpaces(), repeatString repeatString(), replaceString replaceString(), replaceTabulations replaceTabulations(), toLowerString toLowerString(), toUpperString toUpperString(), trimLeft trimLeft(), trimRight trimRight(), trim trim(), truncateAfterString truncateAfterString(), truncateBeforeString truncateBeforeString()
3.25 composeAdaLikeString
- function composeAdaLikeString(text : string) : string
| Parameter | Type | Description |
| text |
string |
a sequence of character to convert to a Ada-like string |
Returns the conversion of the sequence of characters given by argument
text to a Ada-like string, without double quote delimiters.
If text contains a double-quote, it is repeated in the sequence.
Example:
local sText = "double-quote \" inlayed in the sequence";
traceLine("composeAdaLikeString('" + sText + "') = '" + composeAdaLikeString(sText) + "'");
Output:
composeAdaLikeString('double-quote " inlayed in the sequence') = 'double-quote "" inlayed in the sequence'
See also:
composeCLikeString composeCLikeString(), composeHTMLLikeString composeHTMLLikeString(), composeSQLLikeString composeSQLLikeString()
3.26 composeCLikeString
- function composeCLikeString(text : string) : string
| Parameter | Type | Description |
| text |
string |
a sequence of character to convert to a C-like string |
Returns the conversion of the sequence of characters given by argument
text to a C-like string, without double quote delimiters. It means that special characters of text
are replaced by their escape sequence, the rest remaining the same.
It recognizes the following escape sequences:
- '\\' as backslash (\), ASCII value 92,
- '\' ' as single quotation mark ('), ASCII value 39,
- '\"' as double quotation mark ("), ASCII value 34,
- '\a' as alert (BEL), ASCII value 7,
- '\b' as backspace (BS), ASCII value 8,
- '\f' as formfeed (FF), ASCII value 12,
- '\n' as newline (LF), ASCII value 10,
- '\r' as carriage return (CR), ASCII value 13,
- '\t' as horizontal tab (HT), ASCII value 9,
- '\v' as vertical tab (VT), ASCII value 11,
Example:
local sText = "\t=tabulation,\n=newline";
traceLine("composeCLikeString('" + sText + "') = '" + composeCLikeString(sText) + "'");
Output:
composeCLikeString(' =tabulation,
=newline') = '\t=tabulation,\n=newline'
See also:
composeAdaLikeString composeAdaLikeString(), composeHTMLLikeString composeHTMLLikeString(), composeSQLLikeString composeSQLLikeString()
3.27 composeHTMLLikeString
- function composeHTMLLikeString(text : string) : string
| Parameter | Type | Description |
| text |
string |
a sequence of character to convert to an HTML-like string |
Returns the conversion of the sequence of characters given by argument
tex to an HTML-like string. It means that special characters of text
are replaced by their HTML escape sequence (&...;), the rest remaining the same.
Example:
local sText = "< & > aren't admitted by HTML";
traceLine("composeHTMLLikeString('" + sText + "') = '" + composeHTMLLikeString(sText) + "'");
Output:
composeHTMLLikeString('< & > aren't admitted by HTML') = '< & > aren't admitted by HTML'
See also:
composeCLikeString composeCLikeString(), composeAdaLikeString composeAdaLikeString(), composeSQLLikeString composeSQLLikeString()
3.28 composeSQLLikeString
- function composeSQLLikeString(text : string) : string
| Parameter | Type | Description |
| text |
string |
a sequence of character to convert to a SQL-like string |
Returns the conversion of the sequence of characters given by argument
text to a SQL-like string, without single quote delimiters. It means that special characters of text
are replaced by their escape sequence, the rest remaining the same.
It recognizes the following escape sequences:
- '\\' as backslash (\), ASCII value 92,
- '\' ' as single quotation mark ('), ASCII value 39,
- '\"' as double quotation mark ("), ASCII value 34,
- '\a' as alert (BEL), ASCII value 7,
- '\b' as backspace (BS), ASCII value 8,
- '\f' as formfeed (FF), ASCII value 12,
- '\n' as newline (LF), ASCII value 10,
- '\r' as carriage return (CR), ASCII value 13,
- '\t' as horizontal tab (HT), ASCII value 9,
- '\v' as vertical tab (VT), ASCII value 11,
The function translates the single quote to an escape sequence "\'", instead of
repeating twice the single quote as in the SQL-standard. It presents the advantage
of being more readable, but if you encounters a drawback in using this translation,
apply replaceString() to change "\'" in "''".
Example:
local sText = "\t=tabulation,\n=newline,'=single quote,\"=double quote";
traceLine("composeSQLLikeString('" + sText + "') = '" + composeSQLLikeString(sText) + "'");
Output:
composeSQLLikeString(' =tabulation,
=newline,'=single quote,"=double quote') = '\t=tabulation,\n=newline,''=single quote,\"=double quote'
See also:
composeCLikeString composeCLikeString(), composeAdaLikeString composeAdaLikeString(), composeHTMLLikeString composeHTMLLikeString()
3.29 computeMD5
- function computeMD5(text : string) : string
| Parameter | Type | Description |
| text |
string |
the string to encrypt in MD5 |
Computes the MD5 of a string.
This optimized MD5 implementation conforms to RFC 1321.
Source: http://www.cr0.net:8040/code/crypto/md5/
Copyright 2001-2004 Christophe Devine
Example:
local sSentence = "Garfield squashed 5 spiders yesterday";
local sCode = computeMD5(sSentence);
if sCode != "B2D989F0C0501E9A9D4A9F1B4D06E2C5" {
error("bad result from 'computeMD5()'!");
}
traceLine("computeMD5('" + sSentence + "') = " + sCode);
Output:
computeMD5('Garfield squashed 5 spiders yesterday') = B2D989F0C0501E9A9D4A9F1B4D06E2C5
3.30 copyFile
- procedure copyFile(sourceFileName : string, destinationFileName : string)
| Parameter | Type | Description |
| sourceFileName |
string |
the name of the file to copy |
| destinationFileName |
string |
the name of the copy |
This procedure copies a file sourceFileName to another location
destinationFileName. It raises an error if something wrong has happened
(either the source file doesn't exist or permissions are insufficient for copy).
Example:
deleteFile("Documentation/readme.txt");
copyFile("readme.txt", "Documentation/readme.txt");
traceLine("file 'readme.txt' has been copied successfully!");
Output:
file 'readme.txt' has been copied successfully!
See also:
appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.31 copyGenerableFile
- procedure copyGenerableFile(sourceFileName : string, destinationFileName : string)
| Parameter | Type | Description |
| sourceFileName |
string |
the name of the file to copy |
| destinationFileName |
string |
the name of the copy |
This procedure copies a generable file sourceFileName to another location
destinationFileName if the files have differences in the hand-typed text.
It raises an error if something wrong has happened (either the source file doesn't
exist or permissions are insufficient for copy).
A generable file is any source file containing protected areas or expandable markups.
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.32 copySmartDirectory
- procedure copySmartDirectory(sourceDirectory : string, destinationPath : string)
| Parameter | Type | Description |
| sourceDirectory |
string |
the name of the directory to copy |
| destinationPath |
string |
the path where to copy the directory |
This procedure copies a directory sourceDirectory to another location
destinationPath recursively, checking for each file if it doesn't exist yet
or it the content has changed. It avoids copying a file whereas it has no impact,
and then modifying the last changing date of the destination file.
It raises an error if something wrong has happened (the source directory
must exist and permissions must be sufficient to copy if required). Note that
empty directories are ignored.
See also:
changeDirectory changeDirectory(), canonizePath canonizePath(), exploreDirectory exploreDirectory(), getCurrentDirectory getCurrentDirectory(), relativePath relativePath(), removeDirectory removeDirectory(), resolveFilePath resolveFilePath(), scanDirectories scanDirectories(), existDirectory existDirectory()
3.33 copySmartFile
- function copySmartFile(sourceFileName : string, destinationFileName : string) : bool
| Parameter | Type | Description |
| sourceFileName |
string |
the name of the file to copy |
| destinationFileName |
string |
the name of the copy |
This function copies a file sourceFileName to another location
destinationFileName only if either file destinationFileName
doesn't exist yet or the content of file destinationFileName is
different of the content of file sourceFileName. It avoids copying
a file when it has no impact, and then modifying the last changing date of
the destination file. It raises an error if something wrong has happened
(either the file doesn't exist or permissions aren't sufficient to copy when required).
If the function copies the file, and only in that case, it return true.
Example:
deleteFile("Documentation/readme.txt");
traceLine("First call to the 'copySmartFile()': the file is copied");
copySmartFile("readme.txt", "Documentation/readme.txt");
traceLine("Second call to the 'copySmartFile()': nothing is done");
copySmartFile("readme.txt", "Documentation/readme.txt");
Output:
First call to the 'copySmartFile()': the file is copied
Second call to the 'copySmartFile()': nothing is done
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.34 coreString
- function coreString(text : string, pos : int, lastRemoved : int) : string
| Parameter | Type | Description |
| text |
string |
the string to work on |
| pos |
int |
the beginning position, inclusive, starting at 0 |
| lastRemoved |
int |
the number of characters to ignore at the end of text |
Returns a substring of argument text.
The substring begins at the position specified by argument pos and ignores the last characters, which number is specifier by argument lastRemoved.
The first character starts at position 0, the next at position 1, and so on.
Example:
local sSentence = "Do you believe in human being?";
traceLine("coreString('" + sSentence + "', 18, 7) = '" + coreString(sSentence, 18, 7) + "'");
Output:
coreString('Do you believe in human being?', 18, 7) = 'human'
See also:
charAt charAt(), cutString cutString(), joinStrings joinStrings(), leftString leftString(), lengthString lengthString(), midString midString(), rightString rightString(), rsubString rsubString(), subString subString()
3.35 countStringOccurences
- function countStringOccurences(string : string, text : string) : int
| Parameter | Type | Description |
| string |
string |
sequence of characters where occurrences of substring text are to be counted |
| text |
string |
substring to count |
Returns the number of times the substring specified by argument text is found into the sequence of characters held by argument string.
Example:
local sSentence = "Do you believe in human being?";
traceLine("countStringOccurences('" + sSentence + "', 'in') = " + countStringOccurences(sSentence, "in"));
Output:
countStringOccurences('Do you believe in human being?', 'in') = 2
See also:
completeLeftSpaces completeLeftSpaces(), completeRightSpaces completeRightSpaces(), repeatString repeatString(), replaceString replaceString(), replaceTabulations replaceTabulations(), toLowerString toLowerString(), toUpperString toUpperString(), trimLeft trimLeft(), trimRight trimRight(), trim trim(), truncateAfterString truncateAfterString(), truncateBeforeString truncateBeforeString()
3.36 createDirectory
- function createDirectory(path : string) : bool
| Parameter | Type | Description |
| path |
string |
the path of directories to create |
This function creates a new directory and returns whether the operation has succeeded or not.
It fails if the complete path already exists, or if it is invalid.
3.37 createINETClientSocket
- function createINETClientSocket(remoteAddress : string, port : int) : int
| Parameter | Type | Description |
| remoteAddress |
string |
a remote IP address (Internet namespace) |
| port |
int |
a remote port number |
This function creates a client socket and connects it to the specified remote port,
at the specified address IP remoteAddress, and returns a new socket
descriptor. The socket is of type stream.
Once the creation has achieved, use directly the send/receive functions
or attachInputToSocket()/attachOutputToSocket for reading/writing
to the socket via a BNF-parsing/template-based script.
See also:
createINETServerSocket createINETServerSocket(), acceptSocket acceptSocket(), attachInputToSocket attachInputToSocket(), detachInputFromSocket detachInputFromSocket(), attachOutputToSocket attachOutputToSocket(), detachOutputFromSocket detachOutputFromSocket(), receiveBinaryFromSocket receiveBinaryFromSocket(), receiveFromSocket receiveFromSocket(), receiveTextFromSocket receiveTextFromSocket(), sendTextToSocket sendTextToSocket(), sendBinaryToSocket sendBinaryToSocket(), closeSocket closeSocket(), flushOutputToSocket flushOutputToSocket()
3.38 createINETServerSocket
- function createINETServerSocket(port : int, backLog : int) : int
| Parameter | Type | Description |
| port |
int |
a local port number |
| backLog |
int |
maximum queue length for incoming connection (1-5) |
This function creates a server socket bound to port and returns a
new socket descriptor. The socket is of type stream.
The argument backLog specifies the size of the queue connection.
A new connection is refused when the queue is full.
Once the creation has achieved, use the function acceptSocket() to wait for
a new client connection (blocking call).
See also:
createINETClientSocket createINETClientSocket(), acceptSocket acceptSocket(), attachInputToSocket attachInputToSocket(), detachInputFromSocket detachInputFromSocket(), attachOutputToSocket attachOutputToSocket(), detachOutputFromSocket detachOutputFromSocket(), receiveBinaryFromSocket receiveBinaryFromSocket(), receiveFromSocket receiveFromSocket(), receiveTextFromSocket receiveTextFromSocket(), sendTextToSocket sendTextToSocket(), sendBinaryToSocket sendBinaryToSocket(), closeSocket closeSocket(), flushOutputToSocket flushOutputToSocket()
3.39 createIterator
- function createIterator(i : iterator, list : treeref) : bool
| Parameter | Type | Description |
| i |
iterator |
iterator to initialize |
| list |
treeref |
the iterator will point to the beginning of this list |
The variable i will become an iterator pointing to the first item of the list.
If the list is empty, there is no iterator created and the function returns false.
i must have been declared before.
Example:
local list = {"parsing", "tool", "and", "code", "generation"};
local it;
if !createIterator(it, list) error("shouldn't be the case!");
do {
traceLine("\t" + it);
} while next(it);
Output:
parsing
tool
and
code
generation
See also:
createReverseIterator createReverseIterator(), duplicateIterator duplicateIterator(), first first(), index index(), last last(), key key(), next next(), prec prec()
3.40 createReverseIterator
- function createReverseIterator(i : iterator, list : treeref) : bool
| Parameter | Type | Description |
| i |
iterator |
iterator to initialize |
| list |
treeref |
the iterator will point to the end of this list |
The variable i will become an iterator pointing to the last item of the list
and will iterate in the reverse order.
If the list is empty, there is no iterator created and the function returns false.
i must have been declared before.
Example:
local list = {"parsing", "tool", "and", "code", "generation"};
local it;
if !createReverseIterator(it, list) error("shouldn't be the case!");
do {
traceLine("\t" + it);
} while next(it);
Output:
generation
code
and
tool
parsing
See also:
createIterator createIterator(), duplicateIterator duplicateIterator(), first first(), index index(), last last(), key key(), next next(), prec prec()
3.41 createVirtualFile
- function createVirtualFile(handle : string, content : string) : bool
| Parameter | Type | Description |
| handle |
string |
the name of the virtual file to create |
| content |
string |
the content to put into the virtual file |
This function allows creating a virtual file. The handle parameter
corresponds to the name given to the virtual file, which may be any
sequence of characters. The virtual file is populated with the text assigned to
the content argument.
The function always returns true, but it may be changed in the future if
some naming rules will be imposed to the handles for instance. Calling the function
to an existing virtual file causes the content to be updated with the
new one.
CodeWorker manipulates the concept of file that isn't persistent on a physical
disk, but remains stored in memory. These virtual files may be used
everywhere a file is required so as to replace it: copy, parsing or text generation.
When CodeWorker tries to open a file for reading or writing, it starts looking
for a virtual file that has the same name.
Once a virtual file doesn't serve anymore, don't forget to free the
useless memory it takes up by calling the deleteVirtualFile() function
(see deleteVirtualFile()).
Example:
createVirtualFile("littleScript.cws",
"a protected area:" + endl() +
"@setProtectedArea(\"umbrella\");@finished!");
createVirtualFile("littleText.txt", "");
generate("littleScript.cws", project, "littleText.txt");
traceLine("generated (virtual) file:");
traceLine(loadVirtualFile("littleText.txt"));
deleteVirtualFile("littleText.txt");
deleteVirtualFile("littleScript.cws");
Output:
generated (virtual) file:
a protected area:
//##protect##"umbrella"
//##protect##"umbrella"
finished!
See also:
createVirtualTemporaryFile createVirtualTemporaryFile(), deleteVirtualFile deleteVirtualFile(), existVirtualFile existVirtualFile(), loadVirtualFile loadVirtualFile()
3.42 createVirtualTemporaryFile
- function createVirtualTemporaryFile(content : string) : string
| Parameter | Type | Description |
| content |
string |
the content to put into the virtual file |
This function allows creating a virtual file, for which the name of the
virtual file must be chosen by the routine. The virtual file is populated with
the text assigned to the content argument.
The function returns the name that the routine has composed for this virtual file.
The only difference with the function createVirtualFile() (see
createVirtualFile()) lies in the way to choose of the virtual file name.
After creating the file, it behaves as any other virtual file.
Example:
local sScriptFile = createVirtualTemporaryFile(
"a protected area:" + endl() +
"@setProtectedArea(\"umbrella\");@finished!");
traceLine("Name of the (virtual) script file = '" + sScriptFile + "':");
local sGeneratedFile = createVirtualTemporaryFile("");
generate(sScriptFile, project, sGeneratedFile);
traceLine("generated (virtual) file '" + sGeneratedFile + "':");
traceLine(loadVirtualFile(sGeneratedFile));
deleteVirtualFile(sGeneratedFile);
deleteVirtualFile(sScriptFile);
Output:
Name of the (virtual) script file = '.~#0':
generated (virtual) file '.~#1':
a protected area:
//##protect##"umbrella"
//##protect##"umbrella"
finished!
See also:
createVirtualFile createVirtualFile(), deleteVirtualFile deleteVirtualFile(), existVirtualFile existVirtualFile(), loadVirtualFile loadVirtualFile()
3.43 cutString
- procedure cutString(text : string, separator : string, list : stringlist)
| Parameter | Type | Description |
| text |
string |
the sequence of characters to split |
| separator |
string |
the substring that separates slices |
| list |
stringlist |
the list that will contain slices |
This procedure looks for slices into the argument text, which are
separated by the substring put into argument separator. These slices
are pushed into an array node as items called list.
If the argument text doesn't contain any occurrence of the argument
separator, the argument list will contain only one item that
is text.
Example:
local sText = "a yellow submarine";
local listOfItems;
traceLine("cutString('" + sText + "', ' ', listOfItems):");
cutString(sText, " ", listOfItems);
traceObject(listOfItems);
Output:
cutString('a yellow submarine', ' ', listOfItems):
Tracing variable 'listOfItems':
["0" -> "a", "1" -> "yellow", "2" -> "submarine"]
End of variable's trace 'listOfItems'.
See also:
charAt charAt(), coreString coreString(), joinStrings joinStrings(), leftString leftString(), lengthString lengthString(), midString midString(), rightString rightString(), rsubString rsubString(), subString subString()
3.44 decodeURL
- function decodeURL(URL : string) : string
| Parameter | Type | Description |
| URL |
string |
readable URL to encode |
Decode an URL from an HTTP request, meaning that the '+' character changes in a space and
all hexadecimal descriptions of bytes (2 digits preceded by '%') are
converted to characters.
Note that conversions are transparent while doing HTTP requests.
Example:
local sURL = "Roger+Rabbit%26%25%24%3D%21%3F";
traceLine("URL before HTTP decoding = '" + sURL + "'");
traceLine("URL after HTTP decoding = '" + decodeURL(sURL) + "'");
Output:
URL before HTTP decoding = 'Roger+Rabbit%26%25%24%3D%21%3F'
URL after HTTP decoding = 'Roger Rabbit&%$=!?'
See also:
encodeURL encodeURL()
3.45 decrement
- function decrement(number : doubleref) : double
| Parameter | Type | Description |
| number |
doubleref |
variable to decrement |
The result of decrement operation is the value of argument number minus one.
While the result is obtained, the variable number is decremented.
Example:
local iNumber = 32;
traceLine("iNumber = " + iNumber);
traceLine("decrement(iNumber) = " + decrement(iNumber));
// the variable 'number' has been decremented:
traceLine("iNumber = " + iNumber);
Output:
iNumber = 32
decrement(iNumber) = 31
iNumber = 31
See also:
increment increment(), floor floor(), ceil ceil()
3.46 deleteFile
- function deleteFile(filename : string) : bool
| Parameter | Type | Description |
| filename |
string |
name of the file to delete |
Deletes the file whose name is given by parameter filename. If the file
cannot be found or if it cannot be deleted, the function returns false.
Note that if the file name is a relative path, it is understood as being relative
to the current directory where the interpreter has been launched. So, the
interpreter doesn't search into include directories passed to the command line
(option -I), to offer a more secure use.
Example:
copyFile("readme.txt", "Documentation/readme.txt");
traceLine("Result of deleting file 'Documentation/readme.txt' = '" + deleteFile("Documentation/readme.txt") + "'");
Output:
Result of deleting file 'Documentation/readme.txt' = 'true'
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.47 deleteVirtualFile
- function deleteVirtualFile(handle : string) : bool
| Parameter | Type | Description |
| handle |
string |
the name of the virtual file to delete |
This function removes from memory the virtual file whose name is given
by the handle parameter.
It returns true if the virtual file was created before and has been
removed successfully.
See also:
createVirtualFile createVirtualFile(), createVirtualTemporaryFile createVirtualTemporaryFile(), existVirtualFile existVirtualFile(), loadVirtualFile loadVirtualFile()
3.48 div
- function div(dividend : double, divisor : double) : double
| Parameter | Type | Description |
| dividend |
double |
the dividend |
| divisor |
double |
the divisor |
Returns the result of arithmetic division dividend / divisor.
Members are converted from strings to numbers, supposed being worth 0 if a parsing error occurs;
then the division is processed, and the result is converted to a string,
skipping fractional part if all digits after the dot are 0.
Remember that the symbol '/' doesn't mean anything in the standard syntax of the
language, so there is no way to confuse for expressing a division.
However, it exists an escape mode that allows writing arithmetic expressions
between '$' symbols, as formula under LaTeX. So, $dividend / divisor$
is equivalent to div(dividend, divisor).
Example:
local a = 3.2;
traceLine(a + " / 2 = " + div(a, "2"));
traceLine(a + " / 0.2 = " + div(a, 0.2) + " <- integer value");
Output:
3.2 / 2 = 1.6
3.2 / 0.2 = 16 <- integer value
See also:
add add(), sub sub(), mult mult(), exp exp(), log log(), mod mod(), pow pow()
3.49 duplicateIterator
- function duplicateIterator(oldIt : iterator, newIt : treeref) : bool
| Parameter | Type | Description |
| oldIt |
iterator |
the original iterator to duplicate |
| newIt |
treeref |
copy of the original iterator |
Duplicates an iterator or returns false if oldIt isn't an iterator.
Example:
local list = {"parsing", "tool", "and", "code", "generation"};
foreach i in list {
local it;
if !duplicateIterator(i, it) error("shouldn't be the case!");
traceText("\t'" + it + "' - ");
if prec(it) traceLine("precedent value = '" + it + "'");
else traceLine("no precedent value!");
}
Output:
'parsing' - no precedent value!
'tool' - precedent value = 'parsing'
'and' - precedent value = 'tool'
'code' - precedent value = 'and'
'generation' - precedent value = 'code'
See also:
createIterator createIterator(), createReverseIterator createReverseIterator(), first first(), index index(), last last(), key key(), next next(), prec prec()
3.50 encodeURL
- function encodeURL(URL : string) : string
| Parameter | Type | Description |
| URL |
string |
readable URL to encode |
Encode an URL for an HTTP request, meaning that the space character changes in '+' and
all non-alphanumeric characters are encoded in hexadecimal, preceded by '%'.
Note that conversions are transparent while doing HTTP requests.
Example:
local sURL = "Roger Rabbit&%$=!?";
traceLine("URL before HTTP encoding = '" + sURL + "'");
traceLine("URL after HTTP encoding = '" + encodeURL(sURL) + "'");
Output:
URL before HTTP encoding = 'Roger Rabbit&%$=!?'
URL after HTTP encoding = 'Roger%20Rabbit%26%25%24%3D%21%3F'
See also:
decodeURL decodeURL()
3.51 endl
- function endl() : string
Returns an end of line, value depending on the platform on which the
script is executed. It returns "\r\n" under Windows,
and "\n" on any UNIX platform.
Example:
traceLine("endl() = '" + endl() + "'");
traceLine(" length = " + lengthString(endl()));
traceLine(" first ASCII character = " + charToInt(charAt(endl(), 0)));
Output:
endl() = '
'
length = 2
first ASCII character = 13
3.52 endString
- function endString(text : string, end : string) : bool
| Parameter | Type | Description |
| text |
string |
a sequence of characters to test |
| end |
string |
the postfix |
"true" if the argument end is a postfix of the character
sequence represented by text; "" otherwise. Note also that
"true" will be returned if end is an empty string or is
equal to argument text.
Example:
local sText = "airport";
traceLine("endString('" + sText + "', 'port') = '" + endString(sText, "port") + "'");
Output:
endString('airport', 'port') = 'true'
See also:
equalsIgnoreCase equalsIgnoreCase(), findFirstChar findFirstChar(), findLastString findLastString(), findNextString findNextString(), findString findString(), startString startString()
3.53 environTable
- procedure environTable(table : tree)
| Parameter | Type | Description |
| table |
tree |
will contain the list of all environment variable names |
The procedure returns the array of all environment variable in the argument table.
The name of the environment variable is assigned to the value of the item.
Example:
local theTable;
environTable(theTable);
foreach i in theTable {
if i.startString("PROCESSOR") traceLine(i);
}
Output:
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 15 Model 2 Stepping 7, GenuineIntel
PROCESSOR_LEVEL=15
PROCESSOR_REVISION=0207
See also:
getEnv getEnv(), existEnv existEnv(), putEnv putEnv(), system system()
3.54 equal
- function equal(left : double, right : double) : bool
| Parameter | Type | Description |
| left |
double |
first number to compare |
| right |
double |
second number to compare |
Compares two numbers and returns true if they are identical.
Sometimes, the operator '==' is suitable to compare numbers, in the
case where their decimal representation are strictly the same. But be careful
that expression "7.0" == "7" is false!
However, it exists an escape mode that allows writing arithmetic comparisons
between '$' symbols, as formula under LaTeX. So, $left == right$
is equivalent to equal(left, right).
Example:
traceLine("equal(7, '7.0') = '" + equal(7, "7.0") + "'");
traceLine("7 == '7.0' = '" + (7 == "7.0") + "'");
Output:
equal(7, '7.0') = 'true'
7 == '7.0' = ''
See also:
inf inf(), sup sup()
3.55 equalsIgnoreCase
- function equalsIgnoreCase(left : string, right : string) : bool
| Parameter | Type | Description |
| left |
string |
first string to compare |
| right |
string |
second string to compare |
Compares two strings, ignoring the case. It returns true when the comparison succeeds.
Example:
traceLine("equalsIgnoreCase('BANANA', 'Banana') = '" + equalsIgnoreCase("BANANA", "Banana") + "'");
traceLine("equalsIgnoreCase('BANANA', 'APPLE') = '" + equalsIgnoreCase("BANANA", "APPLE") + "'");
Output:
equalsIgnoreCase('BANANA', 'Banana') = 'true'
equalsIgnoreCase('BANANA', 'APPLE') = ''
See also:
endString endString()
3.56 equalTrees
- function equalTrees(firstTree : treeref, secondTree : treeref) : bool
| Parameter | Type | Description |
| firstTree |
treeref |
a parse tree |
| secondTree |
treeref |
another parse tree to compare with the first one |
Compares two parse trees and returns true if they are identical
(same sub-nodes, same values, same entry keys on arrays of node, repeated
recursively).
Example:
local myTree1 = "monkey";
insert myTree1.hobbies = "to eat bretzel";
insert myTree1["Everest"] = "mountain";
insert myTree1["Tea spoon"] = "silverware";
local myTree2 = "monkey";
insert myTree2.hobbies = "to eat bretzel";
insert myTree2["Everest"] = "mountain";
insert myTree2["Tea spoon"] = "silverware";
traceLine("equalTrees(myTree1, myTree2) = '" + equalTrees(myTree1, myTree2) + "'");
Output:
equalTrees(myTree1, myTree2) = 'true'
See also:
slideNodeContent slideNodeContent()
3.57 error
- procedure error(errorMessage : string)
| Parameter | Type | Description |
| errorMessage |
string |
an error message to throw |
It raises the argument errorMessage as an error that may be caught
into a try/catch statement catch.
Example:
try {
error("I have forced an error!");
traceLine("I shouldn't write this message...");
} catch(sError) {
traceLine("I caught the error: '" + sError + "'");
}
Output:
I caught the error: 'I have forced an error!
TEX-manual.cwt(508): main scope
writeFunctionDescription
'
3.58 executeString
- procedure executeString(this : tree, command : string)
| Parameter | Type | Description |
| this |
tree |
the current node that will be accessed via this variable |
| command |
string |
some instructions of the scripting language to execute |
This procedure interprets the argument command as instructions to
execute, written in the scripting language.
Example:
local myContext;
executeString(myContext,
"traceLine(\"Beginning of string execution:\");"
"insert this.name = \"execution\";"
"traceLine(\"End of string execution.\");");
traceLine("What we did during the string execution:");
traceObject(myContext);
Output:
Beginning of string execution:
End of string execution.
What we did during the string execution:
Tracing variable 'myContext':
name = "execution"
End of variable's trace 'myContext'.
See also:
executeStringQuiet executeStringQuiet()
3.59 executeStringQuiet
- function executeStringQuiet(this : tree, command : string) : string
| Parameter | Type | Description |
| this |
tree |
the current node that will be accessed with this variable |
| command |
string |
some instructions of the scripting language to execute |
This function interprets the argument command as instructions to
execute, written in the scripting language, but doesn't display messages to the
standard output stream. Messages are put into a string that is returned
by the function.
Example:
local myContext;
local sMessages = executeStringQuiet(myContext,
"traceLine(\"Beginning of string execution:\");"
"insert this.name = \"execution\";"
"traceLine(\"End of string execution.\");");
traceLine("What we did during the execution:");
traceObject(myContext);
traceLine("What was intended to the console during the execution:");
traceLine(sMessages);
Output:
What we did during the execution:
Tracing variable 'myContext':
name = "execution"
End of variable's trace 'myContext'.
What was intended to the console during the execution:
Beginning of string execution:
End of string execution.
See also:
executeString executeString()
3.60 existDirectory
3.61 existEnv
3.62 existFile
- function existFile(fileName : string) : bool
| Parameter | Type | Description |
| fileName |
string |
the name of a file to check for existence |
Checks whether a file exists or not, looking for include directories passed on
the command line.
This function doesn't work to check the existence of a directory; use exploreDirectory() instead.
Example:
local sFilename = "Documentation/CodeWorker.pdf";
traceLine("Checks existence of file '" + sFilename + "' = '" + existFile(sFilename) + "'");
Output:
Checks existence of file 'Documentation/CodeWorker.pdf' = 'true'
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.63 existVariable
- function existVariable(variable : treeref) : bool
| Parameter | Type | Description |
| variable |
treeref |
the name of a variable |
Checks whether a variable exists or not.
Example:
local alice;
traceLine("The variable 'alice' exists: '" + existVariable(alice) + "'");
traceLine("The variable 'wonderful' doesn't exist: '" + existVariable(wonderful) + "'");
Output:
(3,80): warning! you haven't declared the variable 'wonderful' before ; interpreted as 'this.wonderful', but obsolete soon!
The variable 'alice' exists: 'true'
The variable 'wonderful' doesn't exist: ''
See also:
clearVariable clearVariable(), findFirstSubstringIntoKeys findFirstSubstringIntoKeys(), findElement findElement(), findNextSubstringIntoKeys findNextSubstringIntoKeys(), getArraySize getArraySize(), getVariableAttributes getVariableAttributes(), invertArray invertArray(), isEmpty isEmpty(), removeVariable removeVariable()
3.64 existVirtualFile
- function existVirtualFile(handle : string) : bool
| Parameter | Type | Description |
| handle |
string |
the name of the virtual file to check |
Checks whether a virtual file exists or not, meaning that it has been
created via the function createVirtualFile().
See also:
createVirtualFile createVirtualFile(), createVirtualTemporaryFile createVirtualTemporaryFile(), deleteVirtualFile deleteVirtualFile(), loadVirtualFile loadVirtualFile()
3.65 exp
3.66 expand
- procedure expand(patternFileName : script, this : treeref, outputFileName : string)
| Parameter | Type | Description |
| patternFileName |
script<pattern> |
file name or block of instructions of the pattern script |
| this |
treeref |
the current node that will be accessed with this variable |
| outputFileName |
string |
the existing file to expand |
Expands an existing file whose name is passed to the argument outputFileName,
by executing the pattern script patternFileName on it.
Expanding a file consists of generating code into marked out areas only, the rest
of the file remaining the same. The markup is put into a comment, knowing that the
syntax of the comment must conform to the type of the expanded file outputFileName.
So, an HTML file expects <!- - and - ->, a JAVA file is waiting
for // and "\n", ... The markup is announced by
##markup## followed by a string that represents the markup key.
Don't forget to configure correctly the syntax of comment boundaries with procedures
setCommentBegin() (see setCommentBegin()) and setCommentEnd() (see setCommentEnd()).
When the procedure is called, CodeWorker jumps from a markup to another. To
handle a markup, it checks whether text was already generated, put between tags
##begin##"markup-key" and ##end##"markup-key",
added automatically the first time an expansion is required, to demarquate the
portion of code that doesn't belong to the user. Then, it extracts all protected
areas, if any, and it generates code at the position of the markup, adding
begin/end tags seen before.
If the interpreter finds the tag ##script## just after the markup,
it extracts the embedded text, considered as a script, eventually put between comments.
Otherwise, the interpreter executes the pattern script.
Note that some data might be put between tags ##data##, accessible
in the template-based script via the function getMarkupValue() (see getMarkupValue()).
This block of custom data comes after the ##script## tag, if present.
The same pattern script is called for all markups, so, to distinguish
them and not to generate always the same text, it controls the current markup key
being processed via the function getMarkupKey() (see getMarkupKey()).
Be careful not to confuse this prodedure with generate() that doesn't care
about markups and that overwrites the output file completely, except protected
areas of course.
See also:
autoexpand autoexpand(), generate generate(), generateString generateString(), translate translate(), parseAsBNF parseAsBNF(), parseFree parseFree(), parseFreeQuiet parseFreeQuiet(), parseStringAsBNF parseStringAsBNF(), translateString translateString()
3.67 exploreDirectory
- function exploreDirectory(directory : tree, path : string, subfolders : bool) : bool
| Parameter | Type | Description |
| directory |
tree |
node that will contain the name of all files and folders |
| path |
string |
the directory to explore |
| subfolders |
bool |
to explore sub directories recursively |
Explores the directory whose name is passed to the argument path. The list
of files is put into the node's array directory.files and the
list of directories are put into the node's array directory.directories.
Exploring sub directories is required by the argument subfolders and each
node of the node's array directory.directories repeats the same
process recursively. The key of an array's node is the short name of the file or
the directory and the value of a directory item is the relative path, whereas
the value of a file item is also the short name.
If the directory cannot be found, the variable directory doesn't change
and the function returns false. If the directory doesn't contain any
file, the attribute directory.files isn't created. If the
directory doesn't contain any subfolder, the attribute
directory.directories isn't created.
Example:
local theDirectory;
local sPathToExplore = project.winBinaries; // Windows package of CodeWorker
if !exploreDirectory(theDirectory, sPathToExplore, true) error("unable to find the directory");
// the complete path is too long: shorten it
traceLine("starting directory = '" + theDirectory.subString(sPathToExplore.length()) + "':");
foreach j in theDirectory.files {
traceLine(" '" + j + "'");
}
foreach i in cascading theDirectory.directories {
// the complete path is too long: shorten it
traceLine("- directory '" + i.subString(sPathToExplore.length()) + "':");
foreach j in i.directories {
traceLine(" subfolder '" + key(j) + "'");
// the complete path is too long: shorten it
traceLine(" path '" + j.subString(sPathToExplore.length()) + "'");
}
if key(i) == "GettingStarted" {
traceLine(" ... a lot of files!");
} else {
foreach j in i.files {
traceLine(" '" + j + "'");
}
}
}
Output:
starting directory = '/':
'GettingStarted.bat'
'readme.txt'
- directory '/bin/':
'CodeWorker.exe'
'libcurl.dll'
- directory '/include/':
'CGCompiler.h'
'CGExternalHandling.h'
'CGRuntime.h'
'CppParsingTree.h'
'CW4dl.h'
'DynPackage.h'
'ExternalValueNode.h'
'UtlException.h'
- directory '/Scripts/':
subfolder 'Tutorial'
path '/Scripts/Tutorial/'
- directory '/Scripts/Tutorial/':
subfolder 'GettingStarted'
path '/Scripts/Tutorial/GettingStarted/'
- directory '/Scripts/Tutorial/GettingStarted/':
... a lot of files!
See also:
changeDirectory changeDirectory(), canonizePath canonizePath(), copySmartDirectory copySmartDirectory(), getCurrentDirectory getCurrentDirectory(), relativePath relativePath(), removeDirectory removeDirectory(), resolveFilePath resolveFilePath(), scanDirectories scanDirectories(), existDirectory existDirectory()
3.68 extendExecutedScript
- procedure extendExecutedScript(scriptContent : string)
| Parameter | Type | Description |
| scriptContent |
string |
A piece of CodeWorker's script to compile at the end of the currently executed script |
Extend the currently executed CodeWorker's script with new instructions.
The argument scriptContent is a piece of script to compile at the end of the executed script.
3.69 extractGenerationHeader
- function extractGenerationHeader(filename : string, generator : stringref, version : stringref, date : stringref) : string
| Parameter | Type | Description |
| filename |
string |
generated file to check |
| generator |
stringref |
name of the application that has generated the file |
| version |
stringref |
version of the generator |
| date |
stringref |
date/time of the generation |
Looks for a generation header into the file passed to the argument filename.
It returns the comment that was put into the header (see procedure
setGenerationHeader() setGenerationHeader()) during the generation,
after having assigned the output parameters:
- generator with the name of the application that have generated the file, "CodeWorker" normally,
- version with the version of the generator, the version of CodeWorker normally,
- date with the date and time of the generation, conforming to
"%d%b%Y %H:%M:%S"; 12dec2002 10:00:23 for example,
The generation header is inlayed in the comment delimeters and conforms to the
format:
- if the comment holds on a single line:
begin-comment "##generation header##CodeWorker##"
version-number "##" generation-date "##"
'"' comment '"' end-comment
- if the comment holds on more than one line:
begin-comment "##generation header##CodeWorker##"
version-number "##" generation-date "##" end-comment
begin-comment "##header start##" end-comment
begin-comment line1 end-comment
...
begin-comment linen end-comment
begin-comment "##header end##" end-comment
Example:
setGenerationHeader("Popeye's Village\nGozo and Comino");
local sScriptFile = "GettingStarted/Tiny-JAVA.cwt";
local sFileName = "Documentation/" + project.listOfClasses#back.name + ".java";
generate(sScriptFile, project.listOfClasses#back, sFileName);
local sGenerator;
local sVersion;
local sDateTime;
traceLine("comment of the generation header = '" + extractGenerationHeader(sFileName, sGenerator, sVersion, sDateTime) + "'");
traceLine("generator = '" + sGenerator + "'");
traceLine("version = '" + sVersion + "'");
traceLine("date = '" + sDateTime + "'");
setGenerationHeader("");
Output:
comment of the generation header = 'Popeye's Village
Gozo and Comino'
generator = 'CodeWorker'
version = '3.10.4'
date = '30may2005 19:16:43'
See also:
setGenerationHeader setGenerationHeader(), getGenerationHeader getGenerationHeader()
3.70 fileCreation
- function fileCreation(filename : string) : string
| Parameter | Type | Description |
| filename |
string |
name of the file to ask for its creation time |
Returns the date-time of creation of file whose name is passed to the argument filename.
If an error occurs, it returns one code among the following:
- "-1": unknown error that shouldn't appear,
- "-2": permission denied,
- "-3": too many files have been opened,
- "-4": file not found,
Example:
local sFileName = "Documentation/CodeWorker.tex";
local sCreationTime = fileCreation(sFileName);
if startString(sCreationTime, "-") error("error code = " + sCreationTime + "!");
traceLine("creation of '" + sFileName + "' = " + sCreationTime);
Output:
creation of 'Documentation/CodeWorker.tex' = 17mar2004 22:32:18
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.71 fileLastAccess
- function fileLastAccess(filename : string) : string
| Parameter | Type | Description |
| filename |
string |
name of the file to ask for its last access time |
Returns the date-time of last access to file whose name is passed to the argument filename.
If an error occurs, it returns one code among the following:
- "-1": unknown error that shouldn't appear,
- "-2": permission denied,
- "-3": too many files have been opened,
- "-4": file not found,
Example:
local sFileName = "Documentation/CodeWorker.tex";
local sLastAccessTime = fileLastAccess(sFileName);
if startString(sLastAccessTime, "-") error("error code = " + sLastAccessTime + "!");
traceLine("last access to '" + sFileName + "' = " + sLastAccessTime);
Output:
last access to 'Documentation/CodeWorker.tex' = 02aug2008 00:41:19
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.72 fileLastModification
- function fileLastModification(filename : string) : string
| Parameter | Type | Description |
| filename |
string |
name of the file to ask for its last modification time |
Returns the date-time of last modification to file whose name is passed to the argument filename.
If an error occurs, it returns one code among the following:
- "-1": unknown error that shouldn't appear,
- "-2": permission denied,
- "-3": too many files have been opened,
- "-4": file not found,
Example:
local sFileName = "Documentation/CodeWorker.tex";
local sLastModificationTime = fileLastModification(sFileName);
if startString(sLastModificationTime, "-") error("error code = " + sLastModificationTime + "!");
traceLine("last modification of '" + sFileName + "' = " + sLastModificationTime);
Output:
last modification of 'Documentation/CodeWorker.tex' = 28jul2008 00:44:35
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.73 fileLines
- function fileLines(filename : string) : int
| Parameter | Type | Description |
| filename |
string |
name of the file where to count lines |
Returns the number of lines that the file passed to the argument filename
contains.
If the file cannot be found nor opened, the function returns -1.
Example:
local theFiles;
if !scanFiles(theFiles, "Generation", "*.cw?", true) error("impossible to scan the directory");
local iLines = 0;
foreach i in theFiles iLines = $iLines + fileLines(i)$;
traceLine("total of script lines to generate \"CodeWorker\" = " + iLines);
Output:
total of script lines to generate "CodeWorker" = 8708
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.74 fileMode
- function fileMode(filename : string) : string
| Parameter | Type | Description |
| filename |
string |
file to ask for its permission setting |
The chmod function returns the permission setting of the file specified by filename.
The permission setting controls read and write and execute access to the file.
The returned value holds the permission setting of the file as a concatenation of chars amongst the following:
- 'R' for reading permitted,
- 'W' for writing permitted,
- 'X' for executing permitted (ignored on Windows platform),
If an error occurs, the function returns one code among the following:
- "-1": unknown error that shouldn't appear,
- "-2": permission denied,
- "-3": too many files have been opened,
- "-4": file not found,
Example:
local sPermission = fileMode("Documentation/CodeWorker.tex");
if startString(sPermission, "-") error("error code = " + sPermission);
traceLine("permission on file 'Documentation/CodeWorker.tex' = '" + sPermission + "'");
Output:
permission on file 'Documentation/CodeWorker.tex' = 'RW'
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.75 fileSize
- function fileSize(filename : string) : int
| Parameter | Type | Description |
| filename |
string |
name of the file to ask for its size |
Returns the size of the file whose name is passed to the argument filename.
If an error occurs, it returns one code among the following:
- -1: unknown error that shouldn't appear,
- -2: permission denied,
- -3: too many files have been opened,
- -4: file not found,
Example:
local sFileName = "Documentation/CodeWorker.tex";
local iSize = fileSize(sFileName);
if isNegative(iSize) error("error code = " + iSize + "!");
traceLine("size of '" + sFileName + "' = " + iSize + " characters");
Output:
size of 'Documentation/CodeWorker.tex' = 929422 characters
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), loadBinaryFile loadBinaryFile(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.76 findElement
- function findElement(value : string, variable : treeref) : bool
| Parameter | Type | Description |
| value |
string |
a key as an array entry |
| variable |
treeref |
a variable that contains an array of nodes |
This function looks for a key, given by argument value, as an entry of
the nodes array passed to argument variable. If the key is found, the
function returns true, and and empty string otherwise.
Example:
local list;
insert list["everest"] = "everest";
insert list["karakorum"] = "karakorum";
insert list["kilimanjaro"] = "kilimanjaro";
insert list["twin peaks"] = "twin peaks";
traceLine("findElement('kilimanjaro', list) = '" + findElement("kilimanjaro", list) + "'");
Output:
findElement('kilimanjaro', list) = 'true'
Method: variable.findElement(value)
See also:
existVariable existVariable(), clearVariable clearVariable(), findFirstSubstringIntoKeys findFirstSubstringIntoKeys(), findNextSubstringIntoKeys findNextSubstringIntoKeys(), getArraySize getArraySize(), getVariableAttributes getVariableAttributes(), invertArray invertArray(), isEmpty isEmpty(), removeVariable removeVariable()
3.77 findFirstChar
- function findFirstChar(text : string, someChars : string) : int
| Parameter | Type | Description |
| text |
string |
the string to explore |
| someChars |
string |
a set of individual characters |
Returns the location into text of the first character encountered that
belongs to the set of characters passed to argument someChars. The
position starts counting at 0. If no occurrence has been found, the
negative value -1 is returned.
Example:
local sText = "looking for a token: \"...\" f(a,b) {...}";
traceLine("sText = '" + composeCLikeString(sText) + "'");
traceLine("findFirstChar(sText, '\"({') = " + findFirstChar(sText, "\"({"));
Output:
sText = 'looking for a token: \"...\" f(a,b) {...}'
findFirstChar(sText, '"({') = 21
See also:
endString endString(), findFirstChar findFirstChar(), findLastString findLastString(), findNextString findNextString(), findString findString(), startString startString()
3.78 findFirstSubstringIntoKeys
- function findFirstSubstringIntoKeys(substring : string, array : treeref) : int
| Parameter | Type | Description |
| substring |
string |
a sequence of characters to search into keys of a node's array |
| array |
treeref |
a variable that contains an array of nodes |
This function returns the position of the first item, such as its corresponding
entry key into the list owned byvariable contains the substring passed
to argument substring. The position starts counting at 0.
If no item is found, the negative value -1 is returned.
Example:
local list;
insert list["everest"] = 0;
insert list["karakorum"] = 1;
insert list["kilimanjaro"] = 2;
insert list["twin peaks"] = 3;
traceLine("findFirstSubstringIntoKeys('k', list) = " + findFirstSubstringIntoKeys("k", list));
Output:
findFirstSubstringIntoKeys('k', list) = 1
See also:
existVariable existVariable(), clearVariable clearVariable(), findElement findElement(), findNextSubstringIntoKeys findNextSubstringIntoKeys(), getArraySize getArraySize(), getVariableAttributes getVariableAttributes(), invertArray invertArray(), isEmpty isEmpty(), removeVariable removeVariable()
3.79 findLastString
- function findLastString(text : string, find : string) : int
| Parameter | Type | Description |
| text |
string |
a sequence of characters to explore |
| find |
string |
a substring to find into text |
Returns the position of the last occurrence of the substring find into
the sequence of characters passed to argument text. The position starts
counting to 0.
If the substring find doesn't belong to text, the negative value
-1 is returned.
Example:
local sText = "the lamp of experience";
traceLine("sText = '" + sText + "'");
traceLine("findLastString(sText, 'p') = '" + findLastString(sText, "p") + "'");
Output:
sText = 'the lamp of experience'
findLastString(sText, 'p') = '14'
See also:
findFirstChar findFirstChar(), endString endString(), findNextString findNextString(), findString findString(), startString startString()
3.80 findNextString
- function findNextString(text : string, find : string, position : int) : int
| Parameter | Type | Description |
| text |
string |
a sequence of characters to explore |
| find |
string |
a substring to find into text |
| position |
int |
the position in the string (starting at 0) the search must begin |
Returns the lowest beginning index of the substring find that matches
the sequence of characters passed to argument text, starting the search at position included. The index starts
counting to 0.
If the substring find doesn't belong to text (starting at position), the negative value
-1 is returned.
Example:
local sText = "the lamp of experience";
traceLine("sText = '" + sText + "'");
traceLine("findNextString(sText, 'p', 8) = '" + findNextString(sText, "p", 8) + "'");
Output:
sText = 'the lamp of experience'
findNextString(sText, 'p', 8) = '14'
See also:
findFirstChar findFirstChar(), endString endString(), findLastString findLastString(), findString findString(), startString startString()
3.81 findNextSubstringIntoKeys
- function findNextSubstringIntoKeys(substring : string, array : treeref, next : int) : int
| Parameter | Type | Description |
| substring |
string |
a sequence of characters to search into keys of a node's array |
| array |
treeref |
a variable that contains an array of nodes |
| next |
int |
the position after which looking for the next item |
Returns the position of the next item of list passed to argument variable,
whose entry key contains the substring given by argument substring. The
next item is searched after position passed to argument next. The
position starts counting at 0.
If no item is found, the negative value -1 is returned.
Example:
local list;
insert list["everest"] = 0;
insert list["karakorum"] = 1;
insert list["kilimanjaro"] = 2;
insert list["twin peaks"] = 3;
traceLine("findNextSubstringIntoKeys('k', list, 1) = " + findNextSubstringIntoKeys("k", list, 1));
Output:
findNextSubstringIntoKeys('k', list, 1) = 2
See also:
existVariable existVariable(), clearVariable clearVariable(), findFirstSubstringIntoKeys findFirstSubstringIntoKeys(), findElement findElement(), getArraySize getArraySize(), getVariableAttributes getVariableAttributes(), invertArray invertArray(), isEmpty isEmpty(), removeVariable removeVariable()
3.82 findString
- function findString(text : string, find : string) : int
| Parameter | Type | Description |
| text |
string |
a sequence of characters to explore |
| find |
string |
a substring to find into text |
Returns the position of the first occurrence of the substring find into
the sequence of characters passed to argument text. The position starts
counting to 0.
If the substring find doesn't belong to text, the negative value
-1 is returned.
Example:
local sText = "the lamp of experience";
traceLine("sText = '" + sText + "'");
traceLine("findString(sText, 'of') = '" + findString(sText, "of") + "'");
Output:
sText = 'the lamp of experience'
findString(sText, 'of') = '9'
See also:
findFirstChar findFirstChar(), endString endString(), findLastString findLastString(), findNextString findNextString(), startString startString()
3.83 first
- function first(i : iterator) : bool
| Parameter | Type | Description |
| i |
iterator |
iterator of a foreach statement or pointing to a list |
Returns true if the iterator argument i points to the first item
of the iterated list.
Example:
local myTree;
insert myTree["Everest"] = "mountain";
insert myTree["Tea spoon"] = "silverware";
foreach i in myTree {
if first(i) traceLine("The first item key of the list is '" + key(i) + "'");
}
Output:
The first item key of the list is 'Everest'
See also:
index index(), last last(), key key(), next next(), prec prec(), createIterator createIterator(), createReverseIterator createReverseIterator(), duplicateIterator duplicateIterator()
3.84 floor
3.85 formatDate
- function formatDate(date : string, format : string) : string
| Parameter | Type | Description |
| date |
string |
a date-time representation to transform |
| format |
string |
the format that will be applied to the date argument |
Converts a date to another format, or extracts just a part of the date. The date
is passed to argument date, and the format given by format.
Each field of the format specification is a single character or a format type
signifying a particular format option. A format option
starts with a percent sign. If a percent sign is followed by a character that
has no meaning as a format type, an error is raised. To print a percent-sign
character, use '%%'.
The format type determines how the associated argument, at the current location
to the date, must be interpreted:
- '%d' means that a 2-digits day of the month must be written,
- '%e' means that a day of the month must be written, such as
1 but not 01
- '%j' means that the day of the year must be written,
- '%m' means that a 2-digits month must be written,
- '%B' means that the complete english name of the month must
be written,
- '%b' means that the truncated english name of the month must
be written: only the 3 first characters,
- '%Y' means that a 4-digits year must be written,
- '%y' means that a 2-digits year must be written,
- '%t' means that the number of days since 30dec1899 must be written (WingZ format),
- '%w' means that the weekday must be written as an integer
(0-6; 0 is sunday),
- '%W' means that the weekday must be written as the complete english name,
- '%H' means that a 2-digits hour must be written,
- '%I' means that a 2-digits hour (12 max) must be written,
- '%p' means that "AM" / "PM" must be written,
- '%M' means that a 2-digits minute must be written,
- '%S' means that a 2-digits second must be written,
- '%L' means that a 3-digits millisecond must be written,
- '%D' is equivalent to '%m/%d/%y',
- '%r' is equivalent to '%I:%M:%S %p',
- '%T' is equivalent to '%H:%M:%S',
An error occurs if a temporal argument doesn't belong to those listed above, or if
the date to format doesn't conform to "%d%b%Y %H:%M:%S.%L".
Example:
traceLine("release of the documentation = '" + getNow() + "'");
traceLine("a new format = '" + formatDate(getNow(), "%B %d, %Y") + "'");
traceLine("the hour only = '" + formatDate(getNow(), "%H") + "'");
Output:
release of the documentation = '02aug2008 20:42:00.500'
a new format = 'august 02, 2008'
the hour only = '20'
See also:
addToDate addToDate(), compareDate compareDate(), completeDate completeDate(), getLastDelay getLastDelay(), getNow getNow(), setNow setNow()
3.86 generate
- procedure generate(patternFileName : script, this : treeref, outputFileName : string)
| Parameter | Type | Description |
| patternFileName |
script<pattern> |
file name of the pattern script |
| this |
treeref |
the current node that will be accessed via this variable |
| outputFileName |
string |
the output file to generate |
Generates a file whose name is passed to the argument outputFileName,
by executing the pattern script patternFileName on it.
Up to version 2.18, the pattern script was
necessary passed as a script file name. Since version 2.19,
the function admits to embed the script in the place of the corresponding
argument patternFileName, inlaying the script in brackets:
//generation of an HTML file, which shows the title and the content
//of some financial market news previously extracted
generate(
{<html>
<body>
@
foreach i in this.news {
@@composeHTMLLikeString(i.title)@<br>@endl()@@
@<table><tr><td>@endl()@@
@@composeHTMLLikeString(i.body) + endl()@@
@</td></tr></table>@endl()@@
}
@ </body>
</html>
@}, project, "news.html");
- It avoids the writing of 2 files, as it was unavoidable before:
generate("news2HTML.cwt", project, "news.html");
- such as "news2HTML.cwt", which contains:
<html>
<body>
@
foreach i in this.news {
@@composeHTMLLikeString(i.title)@<br>@endl()@@
@<table><tr><td>@endl()@@
@@composeHTMLLikeString(i.body) + endl()@@
@</td></tr></table>@endl()@@
}
@ </body>
</html>
Generating a file consists of extracting the protected areas from the output
file, before overwriting it with the text generated by the pattern script.
It is possible to put a header of generation at the beginning of the file that
will specify some information such as the name of the generating tool
(CodeWorker normally) and the version of the generator and the date of generation
and a custom field of data. This header of generation (see setGenerationHeader()
setGenerationHeader()) isn't taken into account while comparing the new
generated text with the precedent version of the file on disk.
If the output file may contain some protected areas, don't forget to configure
correctly the syntax of comment boundaries with procedures setCommentBegin()
(see setCommentBegin()) and setCommentEnd() (see setCommentEnd()).
Be careful not to use this prodedure instead of expand(). Expansion
saves all text, except into markups, while generation saves protected areas only
and overwrites the rest!
See also:
expand expand(), autoexpand autoexpand(), generateString generateString(), translate translate(), parseAsBNF parseAsBNF(), parseFree parseFree(), parseFreeQuiet parseFreeQuiet(), parseStringAsBNF parseStringAsBNF(), translateString translateString()
3.87 generateString
- procedure generateString(patternFileName : script, this : treeref, outputString : stringref)
| Parameter | Type | Description |
| patternFileName |
script<pattern> |
file name of the pattern script |
| this |
treeref |
the current node that will be accessed via this variable |
| outputString |
stringref |
the output text to generate |
Generates a sequence of characters, which is stored into the argument outputString,
by executing the pattern script patternFileName on it.
Generating a sequence of characters consists of extracting the protected areas from the
outputString string, before overwriting it with the text generated by the pattern script.
It is possible to put a header of generation at the beginning of the file that
will specify some information such as the name of the generating tool
(CodeWorker normally) and the version of the generator and the date of generation
and a custom field of data. This header of generation (see setGenerationHeader()
setGenerationHeader()) isn't taken into account while comparing the new
generated text with the precedent version of the file on disk.
If the output string may contain some protected areas, don't forget to configure
correctly the syntax of comment boundaries with procedures setCommentBegin()
(see setCommentBegin()) and setCommentEnd() (see setCommentEnd()).
See also:
expand expand(), autoexpand autoexpand(), generate generate(), translate translate(), parseAsBNF parseAsBNF(), parseFree parseFree(), parseFreeQuiet parseFreeQuiet(), parseStringAsBNF parseStringAsBNF(), translateString translateString()
3.88 getArraySize
3.89 getCommentBegin
- function getCommentBegin() : string
Returns the value of a beginning of comment, which is exploited by the procedures
taking in charge the source code generation, such as expand or generate.
CodeWorker must know the format of comments recognized by the output file,
to be able to extract or put protected areas, or to detect expansion
markups.
The beginning of comment assigned by default is worth '//'. This is
the symbol of C++ and JAVA comments that are the most frequently files
encountered for generation. Use the procedure setCommentBegin to change
it.
Some languages accept more than one format of comment. It is the case of C++ or
JAVA or non-standard HTML (Microsoft extended HTML with the
non-recommended tag '<COMMENT' that the W3C hasn't admitted).
CodeWorker can't handle more than one beginning of comment format for an
output file, but you'll haven't to suffer about it, because you have the control
on writing the markups into the output file, and so, to conform to a unique
representation of comments.
Be careful that if the beginning and the end of comments haven't been assigned
correctly before generating a file, the protected areas will not be extracted,
and so, lost for ever!
Example:
traceLine("This example is running while processing the documentation, so we are expecting a LaTeX comment: '" + getCommentBegin() + "'");
Output:
This example is running while processing the documentation, so we are expecting a LaTeX comment: '//'
See also:
getCommentEnd getCommentEnd(), setCommentBegin setCommentBegin(), setCommentEnd setCommentEnd()
3.90 getCommentEnd
- function getCommentEnd() : string
Returns the value of an end of comment, which is exploited by the procedures
taking in charge the source code generation, such as expand or generate.
CodeWorker must know the format of comments recognized by the output file,
to be able to extract or put protected areas, or to detect expansion
markups.
The end of comment assigned by default is worth '\r\n'. This is
the symbol of C++ and JAVA comments that are the most frequently files
encountered for generation. Use the procedure setCommentEnd to change
it.
Some languages accept more than one format of comment. It is the case of C++ or
JAVA or non-standard HTML (Microsoft extended HTML with the
non-recommended tag '/COMMENT>' that the W3C hasn't admitted).
CodeWorker can't handle more than one end of comment format for an
output file, but you'll haven't to suffer about it, because you have the control
on writing the markups into the output file, and so, to conform to a unique
representation of comments.
Be careful that if the beginning and the end of comments haven't been assigned
correctly before generating a file, the protected areas will not be extracted,
and so, lost for ever!
Example:
traceLine("This example is running while processing the documentation, so we are expecting a LaTeX comment: '" + composeCLikeString(getCommentEnd()) + "'");
Output:
This example is running while processing the documentation, so we are expecting a LaTeX comment: '\n'
See also:
getCommentBegin getCommentBegin(), setCommentBegin setCommentBegin(), setCommentEnd setCommentEnd()
3.91 getCurrentDirectory
3.92 getEnv
- function getEnv(variable : string) : string
| Parameter | Type | Description |
| variable |
string |
the environment variable name |
The function returns the environment table entry containing the variable.
An error message is thrown if variable is not found in the
environment table.
See function existEnv() to check the existence before getting.
Use the putenv function to modify the value of an environment variable.
Example:
traceLine("PATH='" + getEnv("PATH")+ "'");
Output:
PATH='E:\Win32App\MikTeX\miktex\bin;C:\Perl\bin\;C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem;C:\Program Files\Fichiers communs\Adaptec Shared\System;C:\PROGRA~1\ATT\Graphviz\bin;C:\PROGRA~1\ATT\Graphviz\bin\tools;E:\Projects\Generator\Release'
See also:
environTable environTable(), existEnv existEnv(), putEnv putEnv(), system system()
3.93 getGenerationHeader
- function getGenerationHeader() : string
Returns the comment that is added automatically to each file generated with the
procedure generate. Defining a comment for the generation header may be
required by passing the option -genheader on the command line or by
calling the procedure setGenerationHeader().
The generation header is inlayed in the comment delimeters and conforms to the
format:
- if the comment holds on a single line:
begin-comment "##generation header##CodeWorker##"
version-number "##" generation-date "##"
'"' comment '"' end-comment
- if the comment holds on more than one line:
begin-comment "##generation header##CodeWorker##"
version-number "##" generation-date "##" end-comment
begin-comment "##header start##" end-comment
begin-comment line1 end-comment
...
begin-comment linen end-comment
begin-comment "##header end##" end-comment
Example:
if !getGenerationHeader() traceLine("no generation header required for the moment");
setGenerationHeader("Popeye's Village\nKnights of Malta");
traceLine("new generation header = '" + getGenerationHeader() + "'");
local sFileName = "GettingStarted/Tiny-JAVA.cwt";
traceLine("script to execute:");
local sContent = replaceString("\r", "", loadFile(sFileName));
local lines;
cutString(sContent, "\n", lines);
foreach i in lines if !startString(i, "//")
traceLine("\t" + i);
traceLine("class to generate = '" + project.listOfClasses#front.name + "'");
local sOutputText;
generateString(sFileName, project.listOfClasses#front, sOutputText);
traceLine("generated text:");
traceLine(sOutputText);
setGenerationHeader("");
Output:
no generation header required for the moment
new generation header = 'Popeye's Village
Knights of Malta'
script to execute:
package tiny;
public class @
this.name@ @
if existVariable(this.parent) {
@ extends @this.parent.name@ @
}
@{
// attributes:
@
function getJAVAType(myAttribute : node) {
local sType = myAttribute.class.name;
if myAttribute.isArray {
set sType = "java.util.ArrayList/*<" + sType + ">*/";
}
return sType;
}
foreach i in this.listOfAttributes {
@ private @getJAVAType(i)@ _@i.name@ = null;
@
}
@
//constructor:
public @this.name@() {
}
// accessors:
@
foreach i in this.listOfAttributes {
@ public @getJAVAType(i)@ get@toUpperString(i.name)@() { return _@i.name@; }
public void set@toUpperString(i.name)@(@getJAVAType(i)@ @i.name@) { _@i.name@ = @i.name@; }
@
}
setProtectedArea("Methods");
@}
class to generate = 'Planet'
generated text:
//##generation header##CodeWorker##4.5.2##02aug2008 00:41:21##
//##header start##
//Popeye's Village
//Knights of Malta
//##header end##
package tiny;
public class Planet {
// attributes:
private _diameter = null;
//constructor:
public Planet() {
}
// accessors:
public getDIAMETER() { return _diameter; }
public void setDIAMETER( diameter) { _diameter = diameter; }
//##protect##"Methods"
//##protect##"Methods"
}
See also:
setGenerationHeader setGenerationHeader(), extractGenerationHeader extractGenerationHeader()
3.94 getHTTPRequest
- function getHTTPRequest(URL : string, HTTPSession : tree, arguments : tree) : string
| Parameter | Type | Description |
| URL |
string |
URL of the HTTP server |
| HTTPSession |
tree |
an object to describe the HTTP session |
| arguments |
tree |
list of the arguments to GET; the key contains the name of the argument and the element gives the value |
This function sends an HTTP's GET request to the HTTP server pointed to by the parameter
URL with the list of arguments put into the the parameter arguments.
The function returns the document read from the HTTP server.
The function sendHTTPRequest() (see sendHTTPRequest()) describes
the structure of the HTTP session object.
See also:
postHTTPRequest postHTTPRequest(), sendHTTPRequest sendHTTPRequest()
3.95 getIncludePath
- function getIncludePath() : string
It returns the include path passed to the command line with one or more times
the setting of option -I, or the latest include path set via the procedure
setIncludePath().
The include path is a concatenation of paths separated by semi-commas ( extbf{';'}).
Example:
traceLine("getIncludePath():");
local list;
cutString(getIncludePath(), ';', list);
foreach i in list traceLine(i);
Output:
getIncludePath():
e:\Projects\generator\Generation/
e:\Projects\Generator/
e:\Projects\generator\Scripts\Tutorial/
See also:
getProperty getProperty(), getVersion getVersion(), getWorkingPath getWorkingPath(), setIncludePath setIncludePath(), setProperty setProperty(), setVersion setVersion(), setWorkingPath setWorkingPath()
3.96 getLastDelay
- function getLastDelay() : double
The function returns the last duration that was measured by a statement modifier
delay (see delay). The duration is expressed in seconds, eventually
with a floating point.
If the function is called during the execution while measuring the time consuming
(controlling sequence under a delay statement modifier), it returns the
time elapsed since the beginning of the time-keeping.
Example:
local list;
local iIndex = 4;
delay while isPositive(decrement(iIndex)) {
pushItem list = "element " + iIndex;
traceLine("creating node '" + list#back + "'");
}
traceLine("time of execution = " + getLastDelay() + " seconds");
Output:
creating node 'element 3'
creating node 'element 2'
creating node 'element 1'
time of execution = 0.000042463497455682214 seconds
See also:
formatDate formatDate(), addToDate addToDate(), compareDate compareDate(), completeDate completeDate(), getNow getNow(), setNow setNow()
3.97 getNow
3.98 getProperty
3.99 getShortFilename
3.100 getTextMode
3.101 getVariableAttributes
- function getVariableAttributes(variable : treeref, list : tree) : int
| Parameter | Type | Description |
| variable |
treeref |
the variable to explore |
| list |
tree |
will contain the name and type (reference to another node or not) of each attribute |
Populates a list with all attribute names of a tree node.
The name of branches just below the node variable are put into list.
The attribute's name is a key in the list and there is no value assigned to the item,
except for attributes that point to another node (a reference). In that case, the
item is worth the complete name of the referenced node.
The function returns the number of attributes found, or a negative value (-1) if the
tree node variable doesn't exist.
Note: use #evaluateVariable() to navigate along a tree node, where the
complete name is determined at runtime.
Example:
local videostores;
insert videostores["Italia"].names["Video Coliseum"].town = "Roma";
local movies;
insert movies["Lock, Stock & Two Smoking Barrels"].director = "Guy Ritchie";
ref movies#front.shop = videostores["Italia"].names["Video Coliseum"];
local attributeNames;
getVariableAttributes(movies#front, attributeNames);
foreach i in attributeNames {
if i traceLine("movies#front." + key(i) + " -> " + i);
else traceLine("movies#front." + key(i) + " = \"" + composeCLikeString(#evaluateVariable("movies#front." + key(i))) + "\"");
}
Output:
movies#front.director = "Guy Ritchie"
movies#front.shop -> videostores["Italia"].names["Video Coliseum"]
See also:
existVariable existVariable(), clearVariable clearVariable(), findFirstSubstringIntoKeys findFirstSubstringIntoKeys(), findElement findElement(), findNextSubstringIntoKeys findNextSubstringIntoKeys(), getArraySize getArraySize(), invertArray invertArray(), isEmpty isEmpty(), removeVariable removeVariable()
3.102 getVersion
3.103 getWorkingPath
3.104 getWriteMode
- function getWriteMode() : string
Returns how text is written during a generation or during an implicit copy
while translating: "insert" or "overwrite" mode (default mode).
See also:
setWriteMode setWriteMode()
3.105 hexaToDecimal
3.106 hostToNetworkLong
3.107 hostToNetworkShort
3.108 increment
- function increment(number : doubleref) : double
| Parameter | Type | Description |
| number |
doubleref |
variable to increment |
The result of increment operation is the value of argument number minus one.
While the result is obtained, the variable number is incremented.
Example:
local iNumber = 32;
traceLine("iNumber = " + iNumber);
traceLine("increment(iNumber) = " + increment(iNumber));
// the variable 'number' has been incremented:
traceLine("iNumber = " + iNumber);
Output:
iNumber = 32
increment(iNumber) = 33
iNumber = 33
See also:
decrement decrement(), floor floor(), ceil ceil()
3.109 indentFile
- function indentFile(file : string, mode : string) : bool
| Parameter | Type | Description |
| file |
string |
name of a file to indent |
| mode |
string |
default value: ""
type of text to indent |
Indents the file passed to parameter file, forcing the indentation mode via the
argument mode. If the argument is empty or omited, the file extension drives the
indentation mode:
- cpp, cxx, h, hxx: will indent as expected for a C++ format,
- java: will indent as expected for a JAVA format,
More format will be recognized in the future.
The function returns true if the file needed to be indented,
meaning that it has changed after processing the indentation.
Example:
traceLine("We'll indent file 'Documentation/IndentSample.cpp' containing:");
copyFile("Documentation/IndentSample.txt", "Documentation/IndentSample.cpp");
traceLine(loadFile("Documentation/IndentSample.cpp"));
traceLine("File changed after indenting = '" + indentFile("Documentation/IndentSample.cpp") + "'");
traceLine("File 'Documentation/IndentSample.cpp' after indentation:");
traceLine(loadFile("Documentation/IndentSample.cpp"));
Output:
We'll indent file 'Documentation/IndentSample.cpp' containing:
int f(int i) {
switch (i) {
case 2:
case 3:
if (i == 2) {
h();
}
g(i - 1);
break;
}
}
File changed after indenting = 'true'
File 'Documentation/IndentSample.cpp' after indentation:
int f(int i) {
switch (i) {
case 2:
case 3:
if (i == 2) {
h();
}
g(i - 1);
break;
}
}
See also:
indentText indentText()
3.110 index
- function index(i : iterator) : int
| Parameter | Type | Description |
| i |
iterator |
iterator of a foreach statement |
Returns the position of the item the iterator points to.
The position in the list begins counting at 0.
Example:
local myTree;
insert myTree["Everest"] = "mountain";
insert myTree["Tea spoon"] = "silverware";
foreach i in myTree {
traceLine("The item '" + key(i) + "' is at position " + index(i) + "");
}
Output:
The item 'Everest' is at position 0
The item 'Tea spoon' is at position 1
See also:
first first(), last last(), key key(), next next(), prec prec(), createIterator createIterator(), createReverseIterator createReverseIterator(), duplicateIterator duplicateIterator()
3.111 inf
- function inf(left : double, right : double) : bool
| Parameter | Type | Description |
| left |
double |
the first member |
| right |
double |
the second member |
Compares two numbers and returns true if the first member given by
argument left is strictly smaller than the second member passed to
argument right.
Don't use the operator '<' to compare numbers in the classical syntax of
the interpreter: it only checks the lexicographical order. So, '12 < 3' is true.
However, it exists an escape mode that allows writing arithmetic comparisons
between '$' symbols, as formula under LaTeX. So, $left < right$
is equivalent to inf(left, right).
Example:
traceLine("inf(3, 12) = '" + inf(3, 12) + "'");
traceLine("3 < 12 = '" + (3 < 12) + "'");
Output:
inf(3, 12) = 'true'
3 < 12 = ''
See also:
equal equal(), sup sup()
3.112 inputKey
- function inputKey(echo : bool) : string
| Parameter | Type | Description |
| echo |
bool |
asks for echoing the standard input on the console |
Returns a character extracted from the standard input, the keyboard generally.
If no key was pressed, it returns an empty string.
See statement modifiers file_as_standard_input (file as standard input) and
string_as_standard_input (string as standard input) to change
the source of the standard input.
If the source of the standard input is the keyboard, the argument echo
has no effects. Otherwise, the input text is displayed into the console only if
echo is worth true.
3.113 inputLine
- function inputLine(echo : bool, prompt : string) : string
| Parameter | Type | Description |
| echo |
bool |
asks for echoing the standard input on the console |
| prompt |
string |
default value: ""
text to prompt at the beginning of the line |
Returns a line that was extracted from the standard input, the keyboard generally.
See statement modifiers file_as_standard_input (file as standard input) and
string_as_standard_input (string as standard input) to change
the source of the standard input.
If the prompt argument is populated and different of an empty string,
the corresponding text is displayed at the beginning of the line.
If the source of the standard input is the keyboard, the argument echo
has no effects. Otherwise, the input text is displayed into the console only if
echo is worth true.
Example:
traceText("Please enter something> ");
local sKeyboardText = inputLine(true);
traceLine("The user said: '" + sKeyboardText + "'");
Output:
Please enter something> These characters were typed by hand on the keyboard!
The user said: 'These characters were typed by hand on the keyboard!'
3.114 insertElementAt
- procedure insertElementAt(list : treeref, key : string, position : int)
| Parameter | Type | Description |
| list |
treeref |
an array of nodes |
| key |
string |
the entry key of the element to insert |
| position |
int |
where to insert the new element, starting at 0 |
Insert a new element to list, at a position given by the argument position.
The argument key indicates the key of this element, which is built empty.
If the key is an empty string, then the key is supposed to be worth the size of the list automatically.
You can access the new element by writing either:
list#[position]
or
list[key]
Example:
local list;
insert list["twin peaks"] = "twin peaks";
insert list["everest"] = "everest";
traceLine("before inserting the kilimanjaro:");
foreach i in list traceLine("\t" + i);
insertElementAt(list, "kilimanjaro", 1);
list#[1] = "kilimanjaro"; // assign a value to the new element
traceLine("after inserting the kilimanjaro at the second place:");
foreach i in list traceLine("\t" + i);
Output:
before inserting the kilimanjaro:
twin peaks
everest
after inserting the kilimanjaro at the second place:
twin peaks
kilimanjaro
everest
3.115 invertArray
- procedure invertArray(array : treeref)
| Parameter | Type | Description |
| array |
treeref |
the array to handle |
Inverts the elements of the array passed to the well-named argument array,
such as the first item becomes the last one, and the last item the first one.
Example:
local list;
insert list["twin peaks"] = "twin peaks";
insert list["karakorum"] = "karakorum";
insert list["everest"] = "everest";
insert list["kilimanjaro"] = "kilimanjaro";
traceLine("before inverting the array:");
foreach i in list traceLine("\t" + i);
invertArray(list);
traceLine("after inverting the array:");
foreach i in list traceLine("\t" + i);
Output:
before inverting the array:
twin peaks
karakorum
everest
kilimanjaro
after inverting the array:
kilimanjaro
everest
karakorum
twin peaks
See also:
existVariable existVariable(), clearVariable clearVariable(), findFirstSubstringIntoKeys findFirstSubstringIntoKeys(), findElement findElement(), findNextSubstringIntoKeys findNextSubstringIntoKeys(), getArraySize getArraySize(), getVariableAttributes getVariableAttributes(), isEmpty isEmpty(), removeVariable removeVariable()
3.116 isEmpty
3.117 isIdentifier
3.118 isNegative
3.119 isNumeric
3.120 isPositive
3.121 joinStrings
- function joinStrings(list : tree, separator : string) : string
| Parameter | Type | Description |
| list |
tree |
the list that contains the strings to join |
| separator |
string |
the sequence of chars that separates the strings |
This function returns the concatenation of all strings put into list,
putting a separator between each of them.
If the list is empty, the function will return an empty string.
Example:
local listOfItems = {"a", "yellow", "submarine"};
traceLine("joinStrings({'a', 'yellow', 'submarine'}, './.'):");
traceLine(joinStrings(listOfItems, "./."));
Output:
joinStrings({'a', 'yellow', 'submarine'}, './.'):
a./.yellow./.submarine
See also:
charAt charAt(), coreString coreString(), cutString cutString(), leftString leftString(), lengthString lengthString(), midString midString(), rightString rightString(), rsubString rsubString(), subString subString()
3.122 key
- function key(i : iterator) : string
| Parameter | Type | Description |
| i |
iterator |
iterator of a foreach statement or pointing to a list |
Returns the key that allows accessing the current item of the iterated list.
Example:
local myTree;
insert myTree["Everest"] = "mountain";
insert myTree["Tea spoon"] = "silverware";
foreach i in myTree {
traceLine("key = '" + key(i) + "' value = '" + i + "'");
}
Output:
key = 'Everest' value = 'mountain'
key = 'Tea spoon' value = 'silverware'
See also:
first first(), index index(), last last(), next next(), prec prec(), createIterator createIterator(), createReverseIterator createReverseIterator(), duplicateIterator duplicateIterator()
3.123 last
- function last(i : iterator) : bool
| Parameter | Type | Description |
| i |
iterator |
iterator of a foreach statement or pointing to a list |
Returns true if the iterator argument i points to the last item
of the iterated list.
Example:
local myTree;
insert myTree["Everest"] = "mountain";
insert myTree["Tea spoon"] = "silverware";
foreach i in myTree {
if last(i) traceLine("The last item key of the list is '" + key(i) + "'");
}
Output:
The last item key of the list is 'Tea spoon'
See also:
first first(), index index(), key key(), next next(), prec prec(), createIterator createIterator(), createReverseIterator createReverseIterator(), duplicateIterator duplicateIterator()
3.124 leftString
- function leftString(text : string, length : int) : string
| Parameter | Type | Description |
| text |
string |
a sequence of characters |
| length |
int |
a positive number |
Returns the first characters that belong to the string passed to the argument
text. The number of characters to take is given by argument
length. If the string contains less than length characters, the
function returns all of them.
Example:
traceLine("leftString('airport', 3) = '" + leftString("airport", 3) + "'");
traceLine("leftString('airport', 8) = '" + leftString("airport", 8) + "'");
Output:
leftString('airport', 3) = 'air'
leftString('airport', 8) = 'airport'
See also:
charAt charAt(), coreString coreString(), cutString cutString(), joinStrings joinStrings(), lengthString lengthString(), midString midString(), rightString rightString(), rsubString rsubString(), subString subString()
3.125 lengthString
- function lengthString(text : string) : int
| Parameter | Type | Description |
| text |
string |
a sequence of characters |
Returns the length of the sequence of characters represented by argument text.
Example:
local sText = "A rabbit ran in the garden"; // size of this string is 26 characters
traceLine("lengthString(\"" + sText + "\") = " + lengthString(sText));
Output:
lengthString("A rabbit ran in the garden") = 26
Method: text.length()
See also:
charAt charAt(), coreString coreString(), cutString cutString(), joinStrings joinStrings(), leftString leftString(), midString midString(), rightString rightString(), rsubString rsubString(), subString subString()
3.126 listAllGeneratedFiles
- procedure listAllGeneratedFiles(files : treeref)
| Parameter | Type | Description |
| files |
treeref |
populated with the names of all files generated since the interpreter has launched |
Populates the parameter files with the list of all output files generated
since the interpreter has launched.
The array files indexes each node with the name of the generated output file,
and each node owns a branch called scripts.
This branch gives the list of all template-based scripts that have contributed to the
generation of the output file (often one script only, but could be more).
The key index and the value of the nodes in the array scripts are worth the script file names.
The procedure raises an error if the tree parameter files doesn't exist.
Example:
local allOutputFiles;
listAllGeneratedFiles(allOutputFiles);
traceLine("List of all generated files:");
foreach i in allOutputFiles {
// A lot of output files are generated before building
// this document, such as C++ sources of CodeWorker:
// they are ignored
if i.endString(".cpp") || i.endString(".h") continue;
// Other files are displayed:
traceLine(" * '" + i.key() + "'");
traceText(" -> {");
foreach j in i.scripts {
if !j.first() traceText(", ");
traceText('\"' + j + '\"');
}
traceLine('}');
}
Output:
List of all generated files:
* '.#f2'
-> {"e:/Projects/generator/Generation/LaTeX2HTML.cwp"}
* 'e:/Projects/generator/Documentation/GeneratingExamples.cwt'
-> {"e:/Projects/Generator/Documentation/GeneratingExamplesBuilder.cwt"}
* 'e:/Projects/generator/Documentation/ParsingExamples.cws'
-> {"e:/Projects/Generator/Documentation/ParsingExamplesBuilder.cwt"}
* 'e:/Projects/generator/Scripts/Tutorial/GettingStarted/JAVA/solarsystem/Earth.java'
-> {"e:/Projects/generator/Scripts/Tutorial/GettingStarted/JAVAObject.cwt"}
* 'e:/Projects/generator/Scripts/Tutorial/GettingStarted/JAVA/solarsystem/Planet.java'
-> {"e:/Projects/generator/Scripts/Tutorial/GettingStarted/JAVAObject.cwt"}
* 'e:/Projects/generator/Scripts/Tutorial/GettingStarted/JAVA/solarsystem/SolarSystem.java'
-> {"e:/Projects/generator/Scripts/Tutorial/GettingStarted/JAVAObject.cwt"}
* 'e:/Projects/generator/Scripts/Tutorial/GettingStarted/SolarSystem.tex'
-> {"e:/Projects/generator/Scripts/Tutorial/GettingStarted/HTML2LaTeX.cwp"}
* 'e:/Projects/generator/Scripts/Tutorial/GettingStarted/SolarSystem0.html'
-> {"e:/Projects/generator/Scripts/Tutorial/GettingStarted/HTMLDocumentation.cwt"}
* 'e:/Projects/generator/Scripts/Tutorial/GettingStarted/SolarSystem1.html'
-> {"e:/Projects/generator/Scripts/Tutorial/GettingStarted/HTMLDocumentation.cwt"}
* 'e:/Projects/generator/WebSite/ScriptsRepository.html'
-> {"e:/Projects/generator/Generation/WebSite.cwt"}
* 'e:/Projects/generator/WebSite/repository/CodeWorker_grammar.cwp'
-> {"e:/Projects/generator/Generation/CWgrammar_expander.cwt"}
* 'e:/projects/generator/Documentation/SolarSystem.java'
-> {"e:/Projects/generator/Scripts/Tutorial/GettingStarted/Tiny-JAVA.cwt"}
* 'e:/projects/generator/Scripts/Tutorial/GettingStarted/Tiny0.html'
-> {"e:/Projects/Generator/Scripts/Tutorial/GettingStarted/Tiny-HTML.cwt"}
* 'e:/projects/generator/Scripts/Tutorial/GettingStarted/tiny/A.java'
-> {"e:/Projects/Generator/Scripts/Tutorial/GettingStarted/Tiny-JAVA.cwt"}
* 'e:/projects/generator/Scripts/Tutorial/GettingStarted/tiny/B.java'
-> {"e:/Projects/Generator/Scripts/Tutorial/GettingStarted/Tiny-JAVA.cwt"}
* 'e:/projects/generator/Scripts/Tutorial/GettingStarted/tiny/C.java'
-> {"e:/Projects/Generator/Scripts/Tutorial/GettingStarted/Tiny-JAVA.cwt"}
* 'e:/projects/generator/Scripts/Tutorial/GettingStarted/tiny/D.java'
-> {"e:/Projects/Generator/Scripts/Tutorial/GettingStarted/Tiny-JAVA.cwt"}
* 'e:/projects/generator/WebSite/examples/cdcatalog.cwt'
-> {"e:/projects/generator/WebSite/repository/GenBeautifier.cwp", "e:/projects/generator/WebSite/repository/XSLtoCodeWorker.cwt"}
* 'e:/projects/generator/WebSite/examples/cdcatalog.html'
-> {"e:/projects/generator/WebSite/examples/cdcatalog.cwt"}
* 'e:/projects/generator/WebSite/examples/ejb-jar_2_0-parser.cwp'
-> {"e:/projects/generator/WebSite/repository/DTDtoBNF.cwt"}
* 'e:/projects/generator/WebSite/highlighting/CWML.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/CWscript2HTML.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/CodeWorker_grammar.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/DTDparser.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/DTDtoBNF-example1.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/DTDtoBNF.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/RawProfiling-example1.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/RawProfilingCpp.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/RawProfilingCppTransformation.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/RawProfilingHpp.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/RawProfilingLeader.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/XMLparser-example1.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/XMLparser.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/XSLparser.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/XSLtoBNF-example1.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/XSLtoCodeWorker.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/basicInformation.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/classDiagram.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/classDiagramGraphViz.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/hitCounter.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/hitCounterParser.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
* 'e:/projects/generator/WebSite/highlighting/hitCounterUpdate.html'
-> {"e:/Projects/Generator/WebSite/repository/CWscript2HTML.cwp"}
3.127 loadBinaryFile
- function loadBinaryFile(file : string, length : int) : string
| Parameter | Type | Description |
| file |
string |
name of the binary file to load |
| length |
int |
default value: -1
number of bytes to read |
Returns the binary content of the file whose name is passed to argument file,
or the length first bytes only if this facultative argument isn't
negative.
The content concatenates a sequence of hexadecimal digits, so a byte is stored in
2 characters:
binary-content ::= [byte]*;
byte ::= ['0'..'9' | 'A'..'F' | 'a'..'f']2;
If the file doesn't exist or can't be read with success, an error occurs.
Example:
local sContent = loadBinaryFile("readme.txt");
local sFormatedContent;
local iLine = 0;
while sContent && $iLine < 10$ {
sFormatedContent += leftString(sContent, 40) + endl();
sContent = sContent.subString(40);
increment(iLine);
}
traceLine("the first 200 bytes of 'readme.txt' are:" + endl() + sFormatedContent);
Output:
the first 200 bytes of 'readme.txt' are:
2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F
2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F
2F2F2F2F2F2F2F2F2F2F0D0A2F2F202020202020
20202020202020202020202020436F6465576F72
6B65722020202020202020202020202020202020
2F2F0D0A2F2F2020202020202020202020202020
20202020202D2D2D2D2D2D2D2D2D2D2020202020
2020202020202020202020202F2F0D0A2F2F2F2F
2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F
2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadFile loadFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.128 loadFile
- function loadFile(file : string, length : int) : string
| Parameter | Type | Description |
| file |
string |
name of the file to load |
| length |
int |
default value: -1
number of characters to read |
Returns the content of the file whose name is passed to argument file,
or the length first characters only if this facultative argument isn't
negative.
If the file doesn't exist or couldn't be read with success, an error occurs.
Example:
local sText = loadFile("readme.txt");
sText = sText.leftString(200);
traceLine("the 200 first characters of 'readme.txt' are:" + endl() + sText);
Output:
the 200 first characters of 'readme.txt' are:
//////////////////////////////////////////////////
// CodeWorker //
// ---------- //
////////////////////////////////////////////
See also:
copyFile copyFile(), appendFile appendFile(), changeFileTime changeFileTime(), chmod chmod(), copyGenerableFile copyGenerableFile(), copySmartFile copySmartFile(), deleteFile deleteFile(), existFile existFile(), fileCreation fileCreation(), fileLastAccess fileLastAccess(), fileLastModification fileLastModification(), fileLines fileLines(), fileMode fileMode(), fileSize fileSize(), loadBinaryFile loadBinaryFile(), saveBinaryToFile saveBinaryToFile(), saveToFile saveToFile(), scanFiles scanFiles()
3.129 loadProject
- procedure loadProject(XMLorTXTFileName : string, nodeToLoad : tree)
| Parameter | Type | Description |
| XMLorTXTFileName |
string |
an input file whose content describes a node |
| nodeToLoad |
tree |
default value: project
the node to populate from the file; if omitted, it is defaulted to the global variable project |
Loads a parse tree previously saved thanks to saveProject().
See also:
saveProject saveProject(), saveProjectTypes saveProjectTypes()
3.130 loadVirtualFile
- function loadVirtualFile(handle : string) : string
| Parameter | Type | Description |
| handle |
string |
the name of the virtual file to load |
Returns the content of the virtual file whose name is passed to argument file.
If the virtual file doesn't exist or couldn't be read with success, an error occurs.
See also:
createVirtualFile createVirtualFile(), createVirtualTemporaryFile createVirtualTemporaryFile(), deleteVirtualFile deleteVirtualFile(), existVirtualFile existVirtualFile()
3.131 log
3.132 longToBytes
3.133 midString
- function midString(text : string, pos : int, length : int) : string
| Parameter | Type | Description |
| text |
string |
a sequence of characters |
| pos |
int |
a position into argument text |
| length |
int |
the number of characters to extract |
Returns a substring located into the string text to the position passed
to the argument pos. The position starts counting at 0. The
substring will be extracted for a size given by parameter length, or
less if it has reached the end of the string.
If the argument pos is greater than the length of text, the
function returns an empty string.
Example:
local sText = "Banks offer weapons without bullets";
traceLine("midString('" + sText + "', 12, 7) = '" + midString(sText, 12, 7) + "'");
Output:
midString('Banks offer weapons without bullets', 12, 7) = 'weapons'
See also:
charAt charAt(), coreString coreString(), cutString cutString(), joinStrings joinStrings(), leftString leftString(), lengthString lengthString(), rightString rightString(), rsubString rsubString(), subString subString()
3.134 mod
3.135 mult
- function mult(left : double, right : double) : double
| Parameter | Type | Description |
| left |
double |
the first operand |
| right |
double |
the second operand |
Returns the result of arithmetic multiplication left * right.
Members are converted from strings to numbers, supposed being worth 0 if a parsing error occurs;
then the multiplication is processed, and the result is converted to a string,
skipping fractional part if all digits after the dot are 0.
Remember that the symbol '*' doesn't mean anything in the standard syntax of the
language, so there is no way to confuse for