/* "CodeWorker": a scripting language for parsing and generating text. Copyright (C) 1996-1997, 1999-2006 Cédric Lemaire This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA To contact the author: codeworker@free.fr */ // HEADINGS: // array // command // conversion // datetime // directory // file // generation // iterator // interpreter // node // numeric // socket // standard // string // system // unknown // URL procedure appendFile(filename : string = "name of the file to append", content : string = "sequence of characters to write at the end of the file") = "Writes the text \\samp{content} at the end of the file \\samp{filename}." "" "If the file doesn't exist, the function creates it." heading "Writes the content of a string to the end of a file" file; procedure autoexpand(outputFileName : string = "the existing file to expand", this : treeref = "the current node that will be accessed with \\textit{this} variable") [info] = "Expands an existing file whose name is passed to the argument \\samp{outputFileName}," "executing \\textit{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 \\samp{outputFileName}." "So, an HTML file expects \\textbf{}, a JAVA file is waiting" "for \\textbf{//} and \\textbf{\"$\\backslash$n\"}, ... The markup is announced by" "\\textbf{\\#\\#markup\\#\\#} followed by a string that represents the \\textit{markup key}." "Don't forget to configure correctly the syntax of comment boundaries with procedures" "\\samp{setCommentBegin()} (see \\ref{setCommentBegin()}) and \\samp{setCommentEnd()} (see \\ref{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" "\\textbf{\\#\\#begin\\#\\#\"\\textit{markup-key}\"} and \\textbf{\\#\\#end\\#\\#\"\\textit{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" "\\textit{begin}/\\textit{end} tags seen before." "" "The interpreter reclaims the tags \\samp{\\#\\#script\\#\\#} just after the markup." "It extracts the embedded text, considered as a \\samp{template-based} script, eventually" "put between comments, and the interpreter executes this embedded script." "" "Note that some data might be put between tags \\samp{\\#\\#data\\#\\#}, accessible" "in the \\textit{template-based} script via the function \\samp{getMarkupValue()} (see \\ref{getMarkupValue()})." "This block of custom data comes after the \\samp{\\#\\#script\\#\\#} tag, if present." "" "Be careful not to confuse this prodedure with \\samp{generate()} that doesn't care" "about markups and that overwrites the output file completely, except protected" "areas of course." heading "Expands a file on markups, following the directives self-contained in the file." interpreter, generation; procedure clearVariable(node : treeref = "the node to clear") = "All attributes of the argument \\samp{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 \\samp{removeVariable()} for that." heading "Removes the subtree and assigns an empty value." node 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);" deprecated clearNode "3.8.7"; procedure compileToCpp(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 \\samp{scriptFileName} and all scripts" "that might be reclaimed during the execution. The corresponding C++ files are" "stored into \\samp{projectDirectory} with the makefile (a Visual C++'s \\textit{DSP}" "file). The path to libraries and the origin of some important include files is" "determined thanks to the path to \\CodeWorker\\ put into \\samp{CodeWorkerDirectory}." "" "The script file cannot be a \\textit{pattern script} or a \\textit{parsing} script." "" "If an error occurs, an error message is raised." heading "Translates a script to C++." command example "local sScriptFile = \"GettingStarted/LeaderScript6.cws\";" "local sDirectory = getWorkingPath() +" "\t\t\t\"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(\"\t\" + i);"; procedure copyFile(sourceFileName : string = "the name of the file to copy", destinationFileName : string = "the name of the copy") = "This procedure copies a file \\samp{sourceFileName} to another location " "\\samp{destinationFileName}. It raises an error if something wrong has happened" "(either the source file doesn't exist or permissions are insufficient for copy)." heading "Copies a file." file example "deleteFile(\"Documentation/readme.txt\");" "copyFile(\"readme.txt\", \"Documentation/readme.txt\");" "traceLine(\"file 'readme.txt' has been copied successfully!\");" see appendFile, changeFileTime, chmod, copyGenerableFile, copySmartFile, deleteFile, existFile, fileCreation, fileLastAccess, fileLastModification, fileLines, fileMode, fileSize, loadBinaryFile, loadFile, saveBinaryToFile, saveToFile, scanFiles; procedure copyGenerableFile(sourceFileName : string = "the name of the file to copy", destinationFileName : string = "the name of the copy") = "This procedure copies a generable file \\samp{sourceFileName} to another location " "\\samp{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." heading "Copies a file with protected areas or expandable markups, only if the hand-typed code differs between source and destination." file; procedure copySmartDirectory(sourceDirectory : string = "the name of the directory to copy", destinationPath : string = "the path where to copy the directory") = "This procedure copies a directory \\samp{sourceDirectory} to another location" "\\samp{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." heading "Copies files of a directory recursively only when destination files differ from source files." directory; procedure cutString(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 \\samp{text}, which are" "separated by the substring put into argument \\samp{separator}. These slices" "are pushed into an array node as items called \\samp{list}." "" "If the argument \\samp{text} doesn't contain any occurrence of the argument" "\\samp{separator}, the argument \\samp{list} will contain only one item that" "is \\samp{text}." heading "Cuts a string at each separator encountered." string example "local sText = \"a yellow submarine\";" "local listOfItems;" "traceLine(\"cutString('\" + sText + \"', ' ', listOfItems):\");" "cutString(sText, \" \", listOfItems);" "traceObject(listOfItems);"; procedure environTable(table : tree = "will contain the list of all environment variable names") = "The procedure returns the array of all environment variable in the argument \\samp{table}." "The name of the environment variable is assigned to the value of the item." heading "Equivalent of \\samp{environ()} in C" system example "local theTable;" "environTable(theTable);" "foreach i in theTable {" "\tif i.startString(\"PROCESSOR\") traceLine(i);" "}"; procedure error(errorMessage : string = "an error message to throw") [info] = "It raises the argument \\samp{errorMessage} as an error that may be caught" "into a \\samp{try/catch} statement \\ref{catch}." heading "Raises an error message" standard example "try {" "\terror(\"I have forced an error!\");" "\ttraceLine(\"I shouldn't write this message...\");" "} catch(sError) {" "\ttraceLine(\"I caught the error: '\" + sError + \"'\");" "}"; procedure executeString(this : tree = "the current node that will be accessed via \\textit{this} variable", command : string = "some instructions of the scripting language to execute") [info] = "This procedure interprets the argument \\samp{command} as instructions to" "execute, written in the scripting language." heading "Executes a script given in a string." interpreter, string 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);" see executeStringQuiet; procedure expand(patternFileName : script = "file name or block of instructions of the \\textit{pattern script}", this : treeref = "the current node that will be accessed with \\textit{this} variable", outputFileName : string = "the existing file to expand") [info] = "Expands an existing file whose name is passed to the argument \\samp{outputFileName}," "by executing the \\textit{pattern script} \\samp{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 \\samp{outputFileName}." "So, an HTML file expects \\textbf{}, a JAVA file is waiting" "for \\textbf{//} and \\textbf{\"$\\backslash$n\"}, ... The markup is announced by" "\\textbf{\\#\\#markup\\#\\#} followed by a string that represents the \\textit{markup key}." "Don't forget to configure correctly the syntax of comment boundaries with procedures" "\\samp{setCommentBegin()} (see \\ref{setCommentBegin()}) and \\samp{setCommentEnd()} (see \\ref{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" "\\textbf{\\#\\#begin\\#\\#\"\\textit{markup-key}\"} and \\textbf{\\#\\#end\\#\\#\"\\textit{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" "\\textit{begin}/\\textit{end} tags seen before." "" "If the interpreter finds the tag \\samp{\\#\\#script\\#\\#} just after the markup," "it extracts the embedded text, considered as a script, eventually put between comments." "Otherwise, the interpreter executes the \\textit{pattern script}." "" "Note that some data might be put between tags \\samp{\\#\\#data\\#\\#}, accessible" "in the \\textit{template-based} script via the function \\samp{getMarkupValue()} (see \\ref{getMarkupValue()})." "This block of custom data comes after the \\samp{\\#\\#script\\#\\#} tag, if present." "" "The same \\textit{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 \\samp{getMarkupKey()} (see \\ref{getMarkupKey()})." "" "Be careful not to confuse this prodedure with \\samp{generate()} that doesn't care" "about markups and that overwrites the output file completely, except protected" "areas of course." heading "Expands a file on markups, following the directives of a template-based script." interpreter, generation see autoexpand, generate, generateString, translate; procedure generate(patternFileName : script = "file name of the \\textit{pattern script}", this : treeref = "the current node that will be accessed via \\textit{this} variable", outputFileName : string = "the output file to generate") [info] = "Generates a file whose name is passed to the argument \\samp{outputFileName}," "by executing the \\textit{pattern script} \\samp{patternFileName} on it." "" "Up to version \\samp{\\textit{2.18}}, the \\textit{pattern script} was" "necessary passed as a script file name. Since version \\samp{\\textit{2.19}}," "the function admits to embed the script in the place of the corresponding" "argument \\samp{patternFileName}, inlaying the script in brackets:\\\\" "\\texttt{\\textit{//generation of an HTML file, which shows the title and the content\\\\" "//of some financial market news previously extracted}\\\\" "\\textbf{generate(\\\\" "\\{}\\\\" "\\makebox[0.4cm][r]{} \\\\" "@\\\\" "foreach i in this.news \\{\\\\" "\t\\makebox[0.8cm][r]{} @@composeHTMLLikeString(i.title)@
@endl()@@\\\\" "\t\\makebox[0.8cm][r]{} @
@endl()@@\\\\" "\t\\makebox[1.2cm][r]{} @@composeHTMLLikeString(i.body) + endl()@@\\\\" "\t\\makebox[0.8cm][r]{} @
@endl()@@\\\\" "\\}\\\\" "@\\makebox[0.4cm][r]{} \\\\" "\\\\" "@\\textbf{\\}, project, \"news.html\");}}" "" "\\begin{itemize}" "\t\\item It avoids the writing of 2 files, as it was unavoidable before:\\\\" "\\texttt{generate(\"news2HTML.cwt\", project, \"news.html\");}" "\t\\item such as \\samp{\"news2HTML.cwt\"}, which contains:\\\\" "\\texttt{\\\\" "\\makebox[0.4cm][r]{} \\\\" "@\\\\" "foreach i in this.news \\{\\\\" "\t\\makebox[0.8cm][r]{} @@composeHTMLLikeString(i.title)@
@endl()@@\\\\" "\t\\makebox[0.8cm][r]{} @
@endl()@@\\\\" "\t\\makebox[1.2cm][r]{} @@composeHTMLLikeString(i.body) + endl()@@\\\\" "\t\\makebox[0.8cm][r]{} @
@endl()@@\\\\" "\\}\\\\" "@\\makebox[0.4cm][r]{} \\\\" "}" "\\end{itemize}" "" "Generating a file consists of extracting the protected areas from the output" "file, before overwriting it with the text generated by the \\textit{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 \\samp{setGenerationHeader()}" "\\ref{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 \\samp{setCommentBegin()}" "(see \\ref{setCommentBegin()}) and \\samp{setCommentEnd()} (see \\ref{setCommentEnd()})." "" "Be careful not to use this prodedure instead of \\samp{expand()}. Expansion" "saves all text, except into markups, while generation saves protected areas only" "and overwrites the rest!" heading "Generates a file, following the directives of a template-based script." interpreter, generation; procedure generateString(patternFileName : script = "file name of the \\textit{pattern script}", this : treeref = "the current node that will be accessed via \\textit{this} variable", outputString : stringref = "the output text to generate") [info] = "Generates a sequence of characters, which is stored into the argument \\samp{outputString}," "by executing the \\textit{pattern script} \\samp{patternFileName} on it." "" "Generating a sequence of characters consists of extracting the protected areas from the" "\\samp{outputString} string, before overwriting it with the text generated by the \\textit{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 \\samp{setGenerationHeader()}" "\\ref{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 \\samp{setCommentBegin()}" "(see \\ref{setCommentBegin()}) and \\samp{setCommentEnd()} (see \\ref{setCommentEnd()})." heading "Generates a string, following the directives of a template-based script." interpreter, generation, string; procedure insertElementAt(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 \\samp{list}, at a position given by the argument \\samp{position}." "The argument \\samp{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:\\\\" "\\texttt{list\\textbf{\\#}[\\textit{position}]}\\\\" "or\\\\" "\\texttt{list[\\textit{key}]}" heading "Inserts a new element to a list, at a given position." array 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);"; procedure invertArray(array : treeref = "the array to handle") = "Inverts the elements of the array passed to the well-named argument \\samp{array}," "such as the first item becomes the last one, and the last item the first one." heading "Inverts the order of items in an array." array 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);"; procedure listAllGeneratedFiles(files : treeref = "populated with the names of all files generated since the interpreter has launched") = "Populates the parameter \\samp{files} with the list of all output files generated" "since the interpreter has launched." "" "The array \\samp{files} indexes each node with the name of the generated output file," "and each node owns a branch called \\samp{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 \\samp{scripts} are worth the script file names." "" "The procedure raises an error if the tree parameter \\samp{files} doesn't exist." heading "Gives the list of all generated files." generation example "local allOutputFiles;" "listAllGeneratedFiles(allOutputFiles);" "traceLine(\"List of all generated files:\");" "foreach i in allOutputFiles {" "\t// A lot of output files are generated before building" "\t// this document, such as C++ sources of CodeWorker:" "\t// they are ignored" "\tif i.endString(\".cpp\") || i.endString(\".h\") continue;" "\t// Other files are displayed:" "\ttraceLine(\"\t* '\" + i.key() + \"'\");" "\ttraceText(\"\t\t-> {\");" "\tforeach j in i.scripts {" "\t\tif !j.first() traceText(\", \");" "\t\ttraceText('\\\"' + j + '\\\"');" "\t}" "\ttraceLine('}');" "}"; procedure openLogFile(filename : string = "name of the file where log information will be put") = "Creates (or erases if already exists) a log file, which remains valid upto the end of the execution." "Each \\textit{trace} function (\\samp{traceLine()}, \\samp{traceText()}, \\samp{traceStack()})" "will write in the log file.\\\\" "This function is very convenient for debugging a CGI script, where the standard" "output is devoted to the result page." "" "Note that passing an empty filename stops the log mechanism." heading "Opens a log file for logging every console trace." system; procedure parseAsBNF(BNFFileName : script = "the name of the \\textit{BNF-driven} parsing script", this : tree = "the current node that will be accessed with \\samp{this} variable", inputFileName : string = "the file to parse") [info] = "Parses an input file whose name is given by the argument \\samp{inputFileName}." "It executes the \\samp{BNF-driven} script called \\samp{BNFFileName}; see section" "\\ref{BNF syntax} for more information." heading "Parses a file with a BNF script." interpreter, parsing see parseFree, parseFreeQuiet, parseStringAsBNF, translate, translateString; procedure parseStringAsBNF(BNFFileName : script = "the name of the \\textit{BNF-driven} parsing script", this : tree = "the current node that will be accessed with \\samp{this} variable", content : string = "the text to parse") [info] = "Parses a text, which is given by the argument \\samp{content} as a sequence of characters." "It executes the \\samp{BNF-driven} script called \\samp{BNFFileName}; see section" "\\ref{BNF syntax} for more information." heading "Parses a string with a BNF script." interpreter, parsing, string; procedure parseFree(designFileName : script = "the name of the parsing script that reads tokens in a procedural way", this : tree = "the current node that will be accessed with \\textit{this} variable", inputFileName : string = "the file to parse") [info] = "Parses an input file whose name is given by the argument \\samp{inputFileName}." "It executes the \\samp{procedural-driven} script called \\samp{designFileName}; see section" "\\ref{Reading tokens for parsing} for more information." heading "Parses a file with an imperative script." interpreter, parsing deprecated loadDesign "1.6"; procedure produceHTML(scriptFileName : string = "a script file of \\CodeWorker\\ to highlight", HTMLFileName : string = "the HTML file that represents the highlighted script") = "This procedure proposes to highlight a script written for \\CodeWorker\\ and" "to provide the resulting colored script into an HTML file. Only \\textbf{'@'}" "and the text to put into the ouput stream are highlighted." heading unknown example "produceHTML(\"Scripts/Tutorial/GettingStarted/Tiny-JAVA.cwt\", getWorkingPath() + \"Scripts/Tutorial/GettingStarted/Tiny-JAVAhighlight.html\");" "traceLine(\"the script file has been highlighted into 'Tiny-JAVAhighlight.html'\");" bugs "The procedure needs to be improved, so as to highlight tokens and keywords of the" "language too. It doesn't work yet on BNF-driven scripts intended to a translation."; procedure putEnv(name : string = "name of the variable environment", value : string = "new value to assign to the variable environment") = "If variable \\samp{name} is already part of the environment, its value is" "replaced by \\samp{value}; otherwise, the new variable and its value are added" "to the environment. You can remove a variable from the environment by specifying" "an empty string." "" "This procedure affects only the environment that is local to the current" "process; you cannot use them to modify the \\textit{command-level} environment." "That is, these functions operate only on data structures accessible to the" "run-time library and not on the environment \\samp{\"segment\"} created for a" "process by the operating system. When the current process terminates, the" "environment reverts to the level of the calling process (in most cases, the" "operating-system level). However, the modified environment can be passed to" "any new processes created by the instruction \\samp{system}, and these new" "processes get any new items added by \\samp{putEnv}." heading "Puts a value to an environment variable." system example "putEnv(\"JUST_FOR_FUN\", \"I'd like to finish reading my newspaper\");" "traceLine(\"getEnv('JUST_FOR_FUN') = '\" + getEnv(\"JUST_FOR_FUN\") + \"'\");"; procedure randomSeed(seed : int = "a new seed for generating pseudorandom integers") = "Sets the seed for generating a series of pseudorandom integers. To change the seed" "to a given starting point, choose any positive value different of \\samp{1} as the seed argument." "A value of \\samp{1} reinitializes the generator. Any negative value let \\CodeWorker\\ choose" "a random seed for you." heading "Changes the seed of the pseudorandom generator." standard see randomInteger; procedure removeAllElements(variable : treeref = "an array of nodes") = "Removes all elements of the array pointed to by \\samp{variable}." heading "Removes all items of the array." array example "local myTree = \"monkey\";" "pushItem myTree[\"Everest\"];" "pushItem myTree[\"Tea spoon\"];" "traceLine(\"the array 'myTree' has \" + myTree.size() + \" elements\");" "traceLine(\"all elements are removed\");" "removeAllElements(myTree);" "traceLine(\"Is the array 'myTree' empty now? = '\" + myTree.empty() + \"'\");" see removeElement, removeFirstElement, removeLastElement; procedure removeElement(variable : treeref = "an array of nodes", key : string = "the entry key of the element to remove") = "Removes the element whose entry key is passed to the argument \\samp{key} from" "the array of nodes called \\samp{variable}." heading "Removes an item, given its entry key." array example "local myTree = \"monkey\";" "pushItem myTree[\"Everest\"];" "pushItem myTree[\"Tea spoon\"];" "traceLine(\"the array 'myTree' has \" + myTree.size() + \" elements\");" "traceLine(\"element 'Tea spoon' is removed\");" "removeElement(myTree, \"Tea spoon\");" "traceLine(\"the array 'myTree' has \" + myTree.size() + \" elements now\");"; procedure removeFirstElement(list : treeref = "an array of nodes") = "Removes the first element from the array of nodes called \\samp{list}." "" "Nothing occurs if \\samp{list} doesn't exist or is empty." heading "Removes the first item of the array." array example "local myTree = \"monkey\";" "pushItem myTree[\"Everest\"];" "pushItem myTree[\"Tea spoon\"];" "traceLine(\"the array 'myTree' has \" + myTree.size() + \" elements\");" "traceLine(\"the first element is removed:\");" "removeFirstElement(myTree);" "traceObject(myTree);"; procedure removeLastElement(list : treeref = "an array of nodes") = "Removes the last element from the array of nodes called \\samp{list}." "" "Nothing occurs if \\samp{list} doesn't exist or is empty." heading "Removes the last item of the array." array example "local myTree = \"monkey\";" "pushItem myTree[\"Everest\"];" "pushItem myTree[\"Tea spoon\"];" "traceLine(\"the array 'myTree' has \" + myTree.size() + \" elements\");" "traceLine(\"the last element is removed:\");" "removeLastElement(myTree);" "traceObject(myTree);"; procedure removeRecursive(variable : treeref = "points to a node of a parse tree", attribute : string = "the name of an attribute to remove") = "Removes recursively the attribute called \\samp{attribute} from a parse tree" "given by \\samp{variable}. It checks also recursively the nodes put into arrays." heading "Removes a given attribute from the subtree." node example "local myTree = \"to keep\";" "insert myTree.toKeep = \"to keep\";" "insert myTree.toRemove = \"to remove\";" "insert myTree.toKeep.toRemove = \"to remove\";" "insert myTree.list[\"keep\"].toKeep = \"to keep\";" "insert myTree.list[\"remove\"].toRemove = \"to remove\";" "removeRecursive(myTree, \"toRemove\");" "local theGoal = \"to keep\";" "insert theGoal.toKeep = \"to keep\";" "insert theGoal.list[\"remove\"] = \"\";" "insert theGoal.list[\"keep\"].toKeep = \"to keep\";" "if !equalTrees(myTree, theGoal) error(\"removeRecursive() doesn't work!\");" "traceLine(\"the attribute 'toRemove' has been removed from 'myTree' recursively\");"; procedure removeVariable(node : treeref = "the node to remove from the tree") = "All attributes of the argument \\samp{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. Once these task are completed, the variable" "\\samp{node} is removed from the tree it belongs to (as an attribute or an" "element)." "" "Note that trying to remove a local variable throws an error." heading "Removes a given variable." node example "local myTree;" "insert myTree.nodeToRemove = \"the value\";" "localref myNode = myTree.nodeToRemove;" "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 removed:\");" "removeVariable(myNode);" "traceObject(myTree);"; procedure saveBinaryToFile(filename : string = "name of the binary file to write into", content : string = "sequence of bytes (2 hexadecimal digits) to write into the file") = "Saves the binary \\samp{content} to the file \\samp{filename}." "The parameter \\samp{content} concatenates a sequence of hexadecimal digits, so a byte is stored in" "2 characters:\\\\" "\\samp{\\textit{binary-content} ::= [\\textit{byte}]*;\\\\" "\t\\textit{byte} ::= [\\textbf{'0'..'9'} | \\textbf{'A'..'F'} | \\textbf{'a'..'f'}]2;}\\\\" "" "The hexadecimal pairs of digit are converted to binary (8 bits) before writing the content." "" "If the file cannot be created, an error is raised. If the file already exists," "its content is replaced by the new binary content." heading "Saves binary data to a file." file; procedure saveProject(XMLFileName : string = "an output file that will contain the XML description of the main parse tree called \\samp{project}", nodeToSave : tree : project = "the node to save to XML; if omitted, it is about the global variable \\samp{project}") [user] = "Saves the parse tree of the project as an XML file. Each element of the XML" "hierarchy takes the name of the corresponding attribute in the parse tree." "" "When a value is assigned to an attribute, it is reported into an XML attribute" "called \\samp{\_\_VALUE}. When an attribute represents an array of nodes, all" "nodes are inlayed in the body of the XML element like it: each node is put" "into an XML element called \\samp{\_\_ARRAY\_ENTRY} where the XML attribute" "\\samp{\_\_KEY} contains the entry key." heading "Saves the parse tree of the project to XML." unknown example new_project "parseAsBNF(\"Scripts/Tutorial/GettingStarted/Tiny-BNFparsing1.cwp\", project, \"Scripts/Tutorial/GettingStarted/Tiny.tml\");" "saveProject(getWorkingPath() +" "\t\t\t\"Scripts/Tutorial/GettingStarted/Tiny-tree.xml\");" "traceLine(loadFile(\"Scripts/Tutorial/GettingStarted/Tiny-tree.xml\"));" see saveProjectTypes; procedure saveProjectTypes(XMLFileName : string = "an output file that will contain the XML description of the structure of the main parse tree called \\samp{project}") [user] = "Factorizes nodes of the parse tree of the project to distinguish an implicit" "type for nodes, depending on their locations into the graph. The typed tree is" "saved as an XML file." heading "Factorizes nodes of the projects to distinguish implicit types for node and saves it to XML." unknown example new_project "parseAsBNF(\"Scripts/Tutorial/GettingStarted/Tiny-BNFparsing1.cwp\", project, \"Scripts/Tutorial/GettingStarted/Tiny.tml\");" "saveProjectTypes(getWorkingPath() +" "\t\t\t\t\"Scripts/Tutorial/GettingStarted/Tiny-types.xml\");" "traceLine(loadFile(\"Scripts/Tutorial/GettingStarted/Tiny-types.xml\"));" bugs "Sometimes, when a type is encountered twice in very different locations of the" "parse tree, a mistake on the proportion of presence may occur. It will be" "corrected later."; procedure saveToFile(filename : string = "name of the text file to write into", content : string = "sequence of characters to write into the file") = "Saves the text \\samp{content} to the file \\samp{filename}." "" "If the file cannot be created, an error is raised. If the file already exists," "its content is replaced by the new text content." heading "Saves the content of a string to a file" file; procedure setCommentBegin(commentBegin : string = "a sequence of characters that represents the beginning of a comment for an output file to handle") = "Sets the value of a beginning of comment, which is exploited by the procedures" "taking in charge the source code generation, such as \\samp{expand} or \\samp{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 \\textit{expansion" "markups}." "This procedure should be called \\samp{before} calling the source code generation," "otherwise the new value is ignored by the preprocessing of output files that" "looks for protected areas and markups." "" "The beginning of comment assigned by default is worth \\textbf{'//'}. This is" "the symbol of C++ and JAVA comments that are the most frequently files" "encountered for generation. However, depending on the output file to generate," "you'll change the beginning of comment to:" "\\begin{itemize}" "\t\\item \\textbf{'/*'} to work on a C file," "\t\\item \\textbf{'- -'} to work on a ADA file," "\t\\item \\textbf{''} to work on a HTML or XML file," "\\end{itemize}" "" "The function \\samp{getCommentEnd} allows asking for the last assigned value." heading "Changes what an end of comment looks like, perhaps before expanding a file." generation example "setCommentEnd(\"-->\");" "traceLine(\"An HTML-XML comment ends with: '\" + getCommentEnd() + \"'\");" "setCommentEnd(\"\\n\");" "traceLine(\"A LaTeX comment ends with: '\" + composeCLikeString(getCommentEnd()) + \"'\");"; procedure setGenerationHeader(comment : string = "comment to put into the header") = "If the text passed to the argument \\samp{comment} isn't empty, a comment is added" "automatically to each file generated with the procedure \\samp{generate}. Passing" "the option \\samp{-genheader} on the command line may require the functionality." "" "This generation header is inlayed in the comment delimeters and conforms to the" "format:\\\\" "\\begin{itemize}" "\t\\item if the comment holds on a single line:\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#generation header\\#\\#CodeWorker\\#\\#\"}}\\\\" "\t\t\\makebox[1cm][r]{} \\samp{\\textit{version-number} \\textbf{\"\\#\\#\"} \\textit{generation-date} \\textbf{\"\\#\\#\"}}\\\\" "\t\t\\makebox[1cm][r]{} \\samp{\\textbf{'\"'} \\textit{comment} \\textbf{'\"'} \\textit{end-comment}}" "\t\\item if the comment holds on more than one line:\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#generation header\\#\\#CodeWorker\\#\\#\"}}\\\\" "\t\t\\makebox[1cm][r]{} \\samp{\\textit{version-number} \\textbf{\"\\#\\#\"} \\textit{generation-date} \\textbf{\"\\#\\#\"} \\textit{end-comment}}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#header start\\#\\#\"} \\textit{end-comment}}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textit{line\\tiny{1}} \\textit{end-comment}}\\\\" "\t\t\\samp{...}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textit{line\\tiny{n}} \\textit{end-comment}}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#header end\\#\\#\"} \\textit{end-comment}}" "\\end{itemize}" "Changing the generation header doesn't lead to modify the generated file necessary:" "the header is ignored while comparing two files." heading "Specifies a comment to put at the beginning of every generated file." generation example "setGenerationHeader(\"Popeye's Village\\nOlive hates spinash\");" "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, \"//\")" "\ttraceLine(\"\\t\" + i);" "traceLine(\"class to generate = '\" + project.listOfClasses#[1].name + \"'\");" "local sOutputText;" "generateString(sFileName, project.listOfClasses#[1], sOutputText);" "traceLine(\"generated text:\");" "traceLine(sOutputText);" "setGenerationHeader(\"\");" see extractGenerationHeader, getGenerationHeader; procedure setIncludePath(path : string = "a concatenation of paths separated by \\textbf{';'}") = "It changes the include path passed to the command line with one or more times" "the setting of the option \\samp{-I}." "" "The include path expects a concatenation of paths separated by semi-commas (\\textbf{';'})." heading "Changes the option \\samp{-I} while running." command example "local sOldPath = getIncludePath();" "setIncludePath(\"Here/is;better/than;before\");" "traceLine(\"one changes the path: '\" + getIncludePath() + \"'\");" "setIncludePath(sOldPath);"; procedure setNow(constantDateTime : string = "the current date-time is fixed to this value") = "Fixes the current date-time to the value passed to argument \\samp{constantDateTime}," " conforming to the format:\\\\" "\\samp{\\%d\\%b\\%Y \\%H:\\%M:\\%S.\\%L}" "" "The procedure doesn't change the system time. \\textit{now} is just frozen for the" "scripting language when calling \\samp{getNow()}. One passes an empty date-time to" "unfreeze the time." "" "For explanations about \\textit{format types}, see function \\samp{formatDate}" "at \\ref{formatDate()}." heading "Fixes the current date-time." datetime example "// the time is already frozen for building the documentation" "local sOldFrozenTime = getNow();" "traceLine(\"now = \" + getNow());" "traceLine(\"one freezes the time to '19jan2003 06:30:00.100'\");" "setNow(\"19jan2003 06:30:00.100\");" "traceLine(\"now = '\" + getNow() + \"' is frozen to this value\");" "setNow(sOldFrozenTime);"; procedure setProperty(define : string = "name of a property", value : string = "value to assign to the property") = "It assigns the value held by the argument \\samp{value} to a property whose name" "is given by parameter \\samp{define}. It is equivalent of writing" "\\samp{'-D \\textit{define}=\\textit{value}'} on the command line." "" "An error is raised if the \\samp{define} argument is an empty string." heading "Adds/changes a property (option \\samp{-D}) while running." command example "setProperty(\"JUST_FOR_FUN\", \"Monty Python\");" "traceLine(\"getProperty('JUST_FOR_FUN') = '\" + getProperty(\"JUST_FOR_FUN\") + \"'\");" deprecated setDefineTarget "1.30"; procedure setTextMode(textMode : string = "text mode (binary or not)") = "" "Sets the mode of text that must be retained for parsing and source code generation. The" "argument \\samp{textMode} is worth one of the following values:" "\\begin{itemize}" "\t\\item \\textbf{\"DOS\"}: the default value if the interpreter is running under a \\textit{Windows} platform," "\t\\item \\textbf{\"UNIX\"}: the default value if the interpreter isn't running under a \\textit{Windows} platform," "\t\\item \\textbf{\"BINARY\"}: not exploited yet, but intended to specify later that" "\t\tthe parsing and the source code generation are applied on binary files," "\\end{itemize}" "An exception is raised if the argument \\samp{textMode} passes a bad value." "" "The impact of choosing \samp{\"DOS\"} instead of any other mode is that special" "comments, which announce markup keys and protected areas, will finish by" "\"$\\backslash$r$\\backslash$n\" when the end of comment is a newline '$\\backslash$n\'." heading "\\textbf{\"DOS\"}, \\textbf{\"UNIX\"} or \\textbf{\"BINARY\"}" generation example "local sTextMode = getTextMode();" "traceLine(\"This documentation is generated under '\" + sTextMode + \"' text mode\");" "setTextMode(\"BINARY\");" "traceLine(\"Now, it is generated under '\" + getTextMode() + \"'!\");" "setTextMode(sTextMode);" see getTextMode; procedure setVersion(version : string = "version number of scripts") = "Indicates to the \\CodeWorker\\ interpreter that scripts must be considered" "as written in an older version of the scripting language, given by the parameter" "\\samp{version}." "" "It allows \\CodeWorker\\ to behave as if it was an ancient interpreter and" "eventually, to adapt deprecated forms." heading "Gives the version of scripts currently interpreted by \\textit{CodeWorker}." command example "local sVersion = getVersion();" "traceLine(\"The version of scripts is '\" + sVersion + \"'\");" "setVersion(\"1.5.2\");" "traceLine(\"Now, the version of scripts is '\" + getVersion() + \"'\");" "setVersion(sVersion);"; procedure setWriteMode(mode : string = "is worth \\samp{\"insert\"} or \\samp{\"overwrite\"}") = "Selects how to write text during a generation and how to apply an implicit copy" "during a translation." "" "By default, a text is written in overwrite mode (\\samp{mode} = \\samp{\"overwrite\"}):" "if the file cursor doesn't point to the end of the current output file, the new text" "overwrites the old one and the remaining, if any, is inserted at the end.\\\\" "The insert mode (\\samp{mode} = \\samp{\"insert\"}) causes a shift of the old text, so" "as to preserve it." heading "Selects how to write text during a generation (insert/overwrite)." generation see getWriteMode; procedure setWorkingPath(path : string = "the new working path") = "Changes the output directory that was assigned to the option" "\\textbf{-path} on the command line." heading "Does the job of the option \\samp{-path}." command example "local sOldWorkingPath = getWorkingPath();" "setWorkingPath(\"WebSite/\");" "traceLine(\"'old path' = '\" + sOldWorkingPath + \"'\");" "traceLine(\"'new path' = '\" + getWorkingPath() + \"'\");" "setWorkingPath(sOldWorkingPath);"; procedure sleep(millis : int = "how many milliseconds the execution must be suspended") = "The procedure suspends the execution for \\samp{millis} milliseconds." heading "Suspends the execution for \\samp{millis} milliseconds." system; procedure slideNodeContent(orgNode : treeref = "points to a node of a parse tree", destNode : treexpr = "a branch starting at the \\samp{orgNode} node") = "Moves the entire content (both attributes and array nodes) of the node passed" "to the argument \\samp{orgNode}, so as to put it at the extremity of a new" "branch, added to the original node \\samp{orgNode} once its content has been" "taken off." "" "For instance, \\samp{slideNodeContent(\\textit{pExpr}, \\textit{left})} means" "that the content of \\textit{pExpr} slides to \\textit{pExpr.left}." heading "Moves the subtree elsewhere on a branch." node example "local pExpr;" "// a given parsing leads to populate an expression:" "insert pExpr.operator = \"*\";" "insert pExpr.left = 3.141592;" "insert pExpr.right = \"X\";" "traceLine(\"'pExpr' represents '3.141592 * X'\");" "// the parsing continues and reveals that the precedent" "// expression was the left part of a bigger arithmetic" "// expression:" "traceLine(\"After moving, the content of 'pExpr' becomes the left hand:\");" "slideNodeContent(pExpr, left);" "traceLine(\"'\t- 'pExpr' contains only the sub-node 'left'\");" "traceLine(\"'\t- 'pExpr.left' represents '3.141592 * X'\");" "insert pExpr.operator = \"+\";" "insert pExpr.right = \"Y\";" "traceLine(\"'pExpr' describes now '(3.141592 * X) + Y'\");"; procedure sortArray(array : tree = "the array node to sort") = "Sort an array in the lexicographical order of the entry keys." heading "Sort an array, considering the entry keys." node example "local myArray;" "insert myArray[\"Garfield\"];" "insert myArray[\"Tea spoon\"];" "insert myArray[\"Everest\"];" "traceLine(\"Sort the array 'myArray':\");" "sortArray(myArray);" "foreach i in myArray {" "\ttraceLine(\"\\t\\\"\" + i.key() + \"\\\"\");" "}"; procedure traceEngine() = "Traces some states about the interpreter and the current script." heading "Displays the state of the interpreter." interpreter; procedure traceLine(line : string = "a string expression to display to the console") = "Evaluates the expression passed to argument \\samp{line}, and displays the" "resulting string to the console. An end of line is added automatically." "" "In case of \\textit{quiet} execution, there is no output to the console," "but the line will be kept:" "\\begin{itemize}" " \\item for processing if used through the JNI interface, to raise all" " messages to the JAVA application that exploit the \\CodeWorker\\" " library," " \\item for concatenating it into a string that collects all messages and" " that returns it after calling function \\samp{executeStringQuiet}" " (see \\ref{executeStringQuiet()})," "\\end{itemize}" heading "Displays a message to the console, adding a carriage return." standard example "traceLine(\"A text to display, and then\");" "traceLine(\"I go to the next line\");" see traceEngine, traceObject, traceStack, traceText; procedure traceObject(object : tree = "a tree node, means any kind of variable", depth : int : 0 = "display depth of the tree") = "Displays all sub-nodes (called \\textit{attributes}) and the node item's array," " if any, belonging to an object passed to argument \\samp{object}." "" "The value assigned to the object is displayed too, when it isn't an empty" "string. If an array of nodes exists, then all entry keys are display, followed" "by the value assigned to the item node if not empty." heading "Displays the content of a node to the console." standard example "local myTree = \"monkey\";" "insert myTree.hobbies = \"to eat bretzel\";" "insert myTree[\"Everest\"] = \"mountain\";" "insert myTree[\"Tea spoon\"] = \"silverware\";" "traceObject(myTree);"; procedure traceStack() [visibility] = "Displays the stack of local variables recursively." "" "In case of \\textit{quiet} execution, there is no output to the console," "but the entire call stack description will be kept:" "\\begin{itemize}" " \\item for processing if used through the JNI interface, raising all" " messages to the JAVA application that exploit the \\CodeWorker\\" " library," " \\item for concatenating it into a string that collects all messages and" " that returns it after calling function \\samp{executeStringQuiet}" " (see \\ref{executeStringQuiet()})," "\\end{itemize}" heading "Displays the stack to the console." standard example "traceStack();"; procedure traceText(text : string = "a string expression to display to the console") = "Evaluates the expression passed to argument \\samp{line}, and displays the" "resulting string to the console. On the contrary of \\samp{traceLine}, there" "is no carriage return at the end." "" "In case of \\textit{quiet} execution, there is no output to the console," "but the text will be kept:" "\\begin{itemize}" " \\item for processing if used through the JNI interface, to raise all" " messages to the JAVA application that exploit the \\CodeWorker\\" " library," " \\item for concatenating it into a string that collects all messages and" " that returns it after calling function \\samp{executeStringQuiet}" " (see \\ref{executeStringQuiet()})," "\\end{itemize}" heading "Displays a message to the console." standard example "traceText(\"A text to display, \");" "traceText(\"but I refuse to go to line!\");" "traceLine(\"\");"; procedure translate(patternFileName : script = "file name of the \\textit{pattern script}, which merges both the BNF syntax and the source code generation tags", this : tree = "the current node that will be accessed via \\textit{this} variable", inputFileName : string = "the input file to parse", outputFileName : string = "the output file to generate") [info] = "Parses an input file whose name is given by the argument \\samp{inputFileName}" "and generates a translated file given by the argument \\samp{outputFileName}," "following the instructions of the \\textit{pattern script} called \\samp{patternFileName}." "" "The pattern script merges the BNF syntax presented section \\ref{BNF syntax} with" "the source code generation syntax described section \\ref{source code generation}." heading "Performs a \\textit{source-to-source translation} or a \\textit{program transformation}." interpreter, parsing, generation; procedure[parse] attachInputToSocket(socket : int = "a client socket descriptor") = "Joins the input stream of a parsing script to a socket stream: each time that" "the input stream pointer reaches the end, the interpreter waits for bytes" "coming from the socket." "" "Waiting for bytes is a blocking process, so once you don't expect for other bytes" "anymore, don't forget to detach the socket via the procedure \\samp{detachInputFromSocket()}" "before reaching the end of the stream." heading "Attaches the input stream of a parsing script to a socket." socket see detachInputFromSocket; procedure[parse] detachInputFromSocket(socket : int = "a client socket descriptor") = "Disconnects the input stream of a parsing script from a socket stream. You" "should have join the socket to the input stream before, via the procedure \\samp{attachInputToSocket()}." heading "The current parsing script doesn't use the socket as input stream anymore." socket; procedure[parse] goBack() = "Moves back the position of the input stream, pointing to the character just" "before. If the current position was pointing to the beginning of the input" "stream, the function has no effect." heading "Moves back one byte before." parsing example "traceLine(\"we move further into the input file, just after '$'\");" "readNextText(\"$\");" "traceLine(\"and now, we go back to it\");" "goBack();" "if !readIfEqualTo(\"$\") error(\"'$' expected\");"; procedure[parse] setInputLocation(location : int = "points to a position of the input stream") = "This procedure moves the position of the input stream elsewhere. The position" "starts at 0." heading "Changes the position in the input stream." parsing example "traceLine(\"we jump to identifier 'potatoes' at position 12\");" "setInputLocation(12);" "if !readIfEqualToIdentifier(\"_potatoes41\") error(\"identifier '_potatoes41' expected\");" deprecated setLocation "3.7.1" see goBack, getInputLocation; procedure[generate] allFloatingLocations(list : tree = "floating location names and their position") = "Populates the argument \\samp{list} with all floating location registered" "to the current output stream, such as the entry key is the floating location name and" "the entry value is the position in the stream." heading "Gives all floating locations registered to the output stream." generation; procedure[generate] attachOutputToSocket(socket : int = "a client socket descriptor") = "Joins the output stream of a \\textit{template-based} or \\textit{translation} script" "so that to send the generated text to the socket." "" "The generated text is sent at the end of the complete script execution." heading "Attaches the output stream of a template-based script to a socket." socket see detachOutputFromSocket, flushOutputToSocket; procedure[generate] detachOutputFromSocket(socket : int = "a client socket descriptor") = "Disconnects the output stream of a parsing script from a socket stream. You" "should have join the socket to the output stream before, via the procedure \\samp{attachOutputToSocket()}." "" "To call only if you have changed your mind and don't want the generated text" "to be sent to the socket at the end of the \\textit{template-based} script" "execution anymore." heading "Once completed, the current output stream won't be sent to a socket." socket; function[generate] flushOutputToSocket(socket : int = "a client socket descriptor") : bool = "Sends to a socket the complete text or binary data already generated by the" "\\textit{template-based} or \\textit{translation} script. The function" "then purges the output stream." "" "This function has no link with \\samp{attachOutputToSocket()}. It only requires" "that the socket descriptor exists and is opened correctly." heading "Flushes the output stream of a template-based script to a socket." socket; procedure[generate] incrementIndentLevel(level : int : 1 = "depth of indentation to add") = "Increments the indentation level, used to indenting output files automatically while writing." "" "If first call, it enables the indent-mode: each time a text will have to be written at the" "beginning of a line, the line will be indented, depending on the indentation level." "" "Call the function \\samp{decrementIndentLevel()} to decrease the indentation." heading "Increments the indentation level, used to indenting output files automatically while writing." generation see decrementIndentLevel; procedure[generate] insertText(location : int = "points to a position of the output stream", text : string = "sequence of characters to insert") [user] = "Inserts a sequence of characters passed to argument \\samp{text}, at the position" "of the output stream given by argument \\samp{location}. The position starts" "counting at 0. All \\textit{floating locations} that point to \\samp{location}," "or after, are impacted by the insertion, and shift for an offset that is worth" "the size of the text to insert." "" "If the position isn't valid, negative or bigger than the end of the output" "stream, an error is raised." "" "In \\textit{expansion mode}, the position 0 points to the first character written" "for expansion and cannot exceed the last character written for expansion." "" "Generally, the position is given by the function \\samp{getFloatingLocation()}." heading "Inserts text at a given position." generation example "I'll drink a bottle of 'Margaux' year 1994@" "newFloatingLocation(\"You'll be drunk!\");" "@ before smoking a cigar.@" "traceLine(\"My glass is empty, let's try another bottle, year 1996\");" "insertText(getFloatingLocation(\"You'll be drunk!\"), \" and year 1996\");" "traceLine(\"My glass is empty once again, let's try another bottle, year 2000\");" "insertText(getFloatingLocation(\"You'll be drunk!\"), \" and year 2000\");" see insertTextOnce, insertTextOnceToFloatingLocation, insertTextToFloatingLocation, overwritePortion, writeBytes, writeText, writeTextOnce; procedure[generate] insertTextOnce(location : int = "points to a position of the output stream", text : string = "sequence of characters to insert") [user] = "Inserts a sequence of characters passed to argument \\samp{text}, at the position" "of the output stream given by argument \\samp{location}, only if the text has" "never been encountered previously by a \\samp{insertTextOnce()} or a \\samp{writeTextOnce()}" "procedure. The position starts counting at 0. All \\textit{floating locations}" "that point to \\samp{location}, or after, are impacted by the insertion, and" "shift for an offset that is worth the size of the text to insert." "" "If the position isn't valid, negative or bigger than the end of the output" "stream, an error is raised." "" "In \\textit{expansion mode}, the position 0 points to the first character written" "for expansion and cannot exceed the last character written for expansion." "" "Generally, the position is given by the function \\samp{getFloatingLocation()}." heading "Inserts text at a given position, if never inserted before." generation example "@" "newFloatingLocation(\"include files\");" "@" "void f(const std::string& s) {" "..." "}" "@" "traceLine(\"I need an include: !\");" "insertTextOnce(getFloatingLocation(\"include files\"), \"#include \" + endl());" "@std::vector g() {" "..." "}" "@" "traceLine(\"I need two includes: and !\");" "insertTextOnce(getFloatingLocation(\"include files\"), \"#include \" + endl());" "insertTextOnce(getFloatingLocation(\"include files\"), \"#include \" + endl());"; procedure[generate] insertTextToFloatingLocation(location : string = "the name of a floating location", text : string = "sequence of characters to insert") [user] = "Inserts a sequence of characters passed to argument \\samp{text}, at the position" "of the floating location, whose name is given by the argument \\samp{location}." "" "If the floating location doesn't exist, the function raises an error." "" "In \\textit{expansion mode}, the floating location might point into a markup area" "previously generated. So, on the contrary of \\samp{insertText()}, the function" "permits to insert text out of the current markup area." heading "Inserts text at a given floating location." generation; procedure[generate] insertTextOnceToFloatingLocation(location : string = "the name of a floating location", text : string = "sequence of characters to insert") [user] = "Inserts a sequence of characters passed to argument \\samp{text}, at the position" "of the floating location, whose name is given by the argument \\samp{location}, but" "only if the text has never been encountered previously by a \\samp{insertTextOnce()}" " or a \\samp{writeTextOnce()}procedure." "" "If the floating location doesn't exist, the function raises an error." "" "In \\textit{expansion mode}, the floating location might point into a markup area" "previously generated. So, on the contrary of \\samp{insertTextOnce()}, the function" "permits to insert text out of the current markup area." heading "Inserts text at a given floating location, if never inserted before." generation; procedure[generate] overwritePortion(location : int = "points to a position of the output stream", text : string = "sequence of characters to write", size : int = "size of the portion to overwrite") [user] = "Writes a sequence of characters passed to argument \\samp{text}, at the position" "of the output stream given by argument \\samp{location}. The text overwrites up to" "\\samp{size} characters and inserts the rest if any. The position starts" "counting at 0.\\\\" "About the behaviour of the overwriting:" "\\begin{itemize}" "\t\\item If there are more than \\samp{size} characters in \\samp{text}," "all \\textit{floating locations} that point to \\samp{location + size}," "or after, are impacted by the insertion of the remaining characters of \\samp{text}," "and shift for an offset that is worth the size of the text minus the size of the" "portion to overwrite." "\t\\item \\samp{overwritePortion(\\textit{pos}, \\textit{text}, 0)} is worth \\samp{insertText(\\textit{pos}, \\textit{text})}." "\t\\item If the portion to overwrite is bigger than the length of \\samp{text}," "all not overwritten characters of the portion are removed." "\t\\item \\samp{overwritePortion(\\textit{pos}, \"\", \\textit{size})} removes \\samp{\\textit{size}} characters from the output stream at position \\samp{\\textit{pos}}." "\\end{itemize}" "" "If the position isn't valid, negative or bigger than the end of the output" "stream, an error is raised." "" "In \\textit{expansion mode}, the position 0 points to the first character written" "for expansion and cannot exceed the last character written for expansion." "" "Generally, the position is given by the function \\samp{getFloatingLocation()}." heading "Overwrites text at a given position." generation example "I'll drink a bottle of '@" "newFloatingLocation(\"You'll be drunk!\");" "@Margaux' year 1994 before smoking a cigar.@" "traceLine(\"Finally, I prefer to drink a bottle of Saint-Estephe,\");" "traceLine(\"I correct the output:\");" "local iPosition = getFloatingLocation(\"You'll be drunk!\");" "overwritePortion(iPosition, \"Saint-Estephe\", 7 /*size of 'Margaux'*/);"; procedure[generate] populateProtectedArea(protectedAreaName : string = "name of the protected area ; must be unique into the output stream", content : string = "the content to copy into the protected area") [user] = "This procedure assigns a content to the protected area whose name is passed to" "argument \\samp{protectedAreaName} and puts the protected area at the current" "position of the output stream." "" "An error is raised if the protected area had already been put into the output stream." heading "Puts a protected area at the current position, giving its content." generation example "code to generate" "@" "if !getProtectedArea(\"reserved for the user\")" "\tpopulateProtectedArea(\"reserved for the user\", \"I can't stand an empty protected area\" + endl());" "@I continue the code to generate@" see getProtectedArea, getProtectedAreaKeys, remainingProtectedAreas, removeProtectedArea, setProtectedArea; procedure[generate] resizeOutputStream(newSize : int = "new size of the output stream") = "This procedure changes the size of the output stream to \\samp{newSize}. The" "only allowed resizing is to reduce the stream (the request is ignored otherwise)." "If the current position becomes out of the boundaries, it points to the new end" "of the output stream." heading "Reduces the size of the output, loosing the text out of bound." generation example "I write 22 characters.@" "traceLine(\"Current position to the output stream = \" + getOutputLocation());" "setOutputLocation(8);" "@15@" "resizeOutputStream(15);"; procedure[generate] setFloatingLocation(key : string = "name of a floating position to put into the output stream", location : int = "the position into the output stream to assign to the key, starting at \\samp{0}") = "Assigns a position to the \\textit{floating location} whose name is passed to argument \\samp{key}." heading "Defines a file position that will move when text will be inserted before or just on it." generation example "Roger Rabbit doesn't like spinash@" "setFloatingLocation(\"Roger Rabbit\", 5);" "traceLine(\"the floating location 'Roger Rabbit' points just after 'Roger' = \" + getFloatingLocation(\"Roger Rabbit\"));"; procedure[generate] setOutputLocation(location : int = "points to a position of the output stream") = "This procedure moves the position of the output stream elsewhere. The position" "passed to the argument \\samp{location} starts at 0." "" "If \\samp{location} is worth \\textbf{\\samp{-1}}, the cursor moves to the end of the output stream." heading "Changes the location of the output file pointer." generation example "I write 22 characters.@" "traceLine(\"Current position to the output stream = \" + getOutputLocation());" "setOutputLocation(8);" "@one sentence, finally!@"; procedure[generate] setProtectedArea(protectedAreaName : string = "name of the protected area ; must be unique into the output stream") [user] = "This procedure puts a protected area at the current position of the output stream," "and allows preserving the code of the user between two code generations." "" "A protected area is bounded by the sequence \\samp{\\#\\#protect\\#\\#\"...\"}, put into a comment." "The syntax of the comment must conform to the type of the target language expected in the" "file \\samp{outputFileName}." "So, an HTML file expects \\textbf{}, a JAVA file is waiting" "for \\textbf{//} and \\textbf{\"$\\backslash$n\"}, ... " "Don't forget to configure correctly the syntax of comment boundaries with procedures" "\\samp{setCommentBegin()} (see \\ref{setCommentBegin()}) and \\samp{setCommentEnd()} (see \\ref{setCommentEnd()})." "" "An error is raised if the protected area had already been put into the output stream." heading "Puts a protected area at the current location." generation example "code to generate" "@" "setProtectedArea(\"reserved for the user\");" "@I continue the code to generate@"; procedure[generate] writeBytes(bytes : string = "sequence of bytes to write at the current position of the output stream") [user] = "Writes a sequence of bytes passed to argument \\samp{bytes}, at the current" "position of the output stream." "" "A byte is a couple of hexadecimal digits." heading "Writes a series of bytes at the current position." generation example "codeworker@" "writeBytes(\"4066726565\");" "@.fr@"; procedure[generate] writeText(text : string = "sequence of characters to write at the current position of the output stream") [user] = "Writes a sequence of characters passed to argument \\samp{text}, at the current" "position of the output stream. It does the same work as the \\textbf{@} tag, but" "it puts a string into the output stream." "" "This is the common way to write the symbol \\textbf{'@'} into the output stream." heading "Imperative form of the template writing \\samp{@...@}." generation example "codeworker@" "writeText(\"@\");" "@free.fr@"; procedure[generate] writeTextOnce(text : string = "sequence of characters to write at the current position of the output stream") [user] = "Writes a sequence of characters passed to argument \\samp{text}, at the current" "position of the output stream, only if the text has never been encountered" "previously by a \\samp{insertTextOnce()} or a \\samp{writeTextOnce()} procedure." heading "Writes the text only if it wasn't encountered before in this function or when inserting." generation example "@" "traceLine(\"Do you know that Roger Rabbit is tired?\");" "writeTextOnce(\"Roger Rabbit is tired\");" "traceLine(\"Once again, Roger Rabbit is tired!\");" "writeTextOnce(\"Roger Rabbit is tired\");" "traceLine(\"Once more, Roger Rabbit is tired!\");" "writeTextOnce(\"Roger Rabbit is tired\");" "traceLine(\"The message hasn't been repeated into the generated text.\");"; function acceptSocket(serverSocket : int = "a server socket previously created via \\samp{createINETServerSocket()}") : int = "This function blocks until a client connection arrives, and returns the corresponding" "socket descriptor." "" "Once a connection has been established, use directly the \\textit{send}/\\textit{receive} functions" "or \\samp{attachInputToSocket()}/\\samp{attachOutputToSocket} for reading/writing" "to the socket via a \\textit{BNF-parsing}/\\textit{template-based} script." heading "Listens for a client connection and accepts it." socket; function add(left : double = "left arithmetic member", right : double = "right arithmetic member") : double = "Returns the result of arithmetic addition \\samp{left} \\textbf{+} \\samp{right}." "Members are converted from strings to numbers, supposed being worth \\samp{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 \\textit{0}." "" "Remember that the symbol \\textbf{'+'} means the concatenation of text. Using" "this operator instead of function \\samp{add} will concatenate digits!" "However, it exists an escape mode that allows writing arithmetic expressions" "between \\textbf{'\\$'} symbols, as formula under \\textit{LaTeX}. So, \\samp{\\$\\textit{left} \\textbf{+} \\textit{right}\\$}" "is equivalent to \\samp{add(\\textit{left}, \\textit{right})}." heading "Equivalent admitted writing is \\samp{\\$a + b\\$}." numeric example "local a = 3.2;" "traceLine(a + \" + 4.5 = \" + add(a, \"4.5\"));" "traceLine(a + \" + 2.8 = \" + add(a, 2.8) + \" <- integer value\");" see sub, mult, div, exp, log, mod, pow; function addGenerationTagsHandler(key : string = "designates the handler", reader : script = "extended-BNF script of the reader", writer : script = "template-based script of the writer") : bool [user] = "Adds a new generation tags handler, designated by \\samp{key}." "" "Returns \\samp{true} if \\samp{key} isn't reserved yet for another generation tags handler." heading "Adds your own CodeWorker's tags handler" generation see removeGenerationTagsHandler, selectGenerationTagsHandler; function addToDate(date : string = "the date to change", format : string = "the format to apply on the reading of the \\samp{shifting} argument", shifting : string = "the offset values to apply on the date, whose meanings are known by the \\samp{offset} argument") : string = "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 \\samp{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." heading "Change a date by shifting its internal fields days/months/years or time." datetime 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);"; function byteToChar(byte : string = "an hexadecimal number of 2 digits exactly") : string = "Converts a byte to a character. A byte is considered as an hexadecimal number of" "2 digits exactly." "" "If the argument \\samp{byte} doesn't contain an hexadecimal number of 2 digits," "an error is raised. If \\samp{byte} is worth '00', the function returns an empty" "string." heading "Converts a byte (hexadecimal representation of 2 digits) to a character." conversion example "traceLine(\"byteToChar('20') = '\" + byteToChar(\"20\") + \"'\");" "traceLine(\"byteToChar('61') = '\" + byteToChar(\"61\") + \"'\");" see bytesToLong, bytesToShort, charToByte, charToInt, hexaToDecimal, longToBytes, octalToDecimal, shortToBytes; function bytesToLong(bytes : string = "a 4-bytes representation of an unsigned long integer (host bytes order)") : ulong = "Converts a 4-bytes representation of an unsigned long integer to its decimal representation." "Bytes are ordered in the host order (memory storage)." "" "If the argument \\samp{bytes} is malformed, the function raises an error." heading "Converts a 4-bytes sequence to an unsigned long integer in its decimal representation." conversion example "traceLine(\"bytesToLong('FFFFFFFF')\ = '\" + bytesToLong(\"FFFFFFFF\") + \"'\");"; function bytesToShort(bytes : string = "a 2-bytes representation of an unsigned short integer (host bytes order)") : ushort = "Converts a 2-bytes representation of an unsigned short integer to its decimal representation." "Bytes are ordered in the host order (memory storage)." "" "If the argument \\samp{bytes} is malformed, the function raises an error." heading "Converts a 2-bytes sequence to an unsigned short integer in its decimal representation." conversion example "traceLine(\"bytesToShort('FFFF')\ = '\" + bytesToShort(\"FFFF\") + \"'\");"; function canonizePath(path : string = "the path to canonize") : string = "Returns the path passed to the argument \\samp{path} after having canonized it." "" "To canonize a path means that:" "\\begin{itemize}" "\t\\item \\samp{\\textbf{'..'}} and \\samp{\\textbf{'.'}} directories are processed," "\t\\item backslashes are changed to forward slashes," "\t\\item if the \\samp{path} is relative, it is converted to a full path, starting" "at the current directory." "\\end{itemize}" heading "Builds an absolute path, starting to the current directory." file example "traceLine(\"current directory = '\" + getCurrentDirectory() + \"'\");" "local sPath = \"WebSite/downloads/CodeWorker.zip\";" "traceLine(\"\tpath = '\" + sPath + \"'\");" "traceLine(\"\tresult = '\" + canonizePath(sPath) + \"'\");" "local sCurrentDirectory = getCurrentDirectory();" "changeDirectory(sCurrentDirectory + \"Documentation\");" "traceLine(\"current directory = '\" + getCurrentDirectory() + \"'\");" "set sPath = \"../Scripts/Tutorial/GettingStarted/tiny.html\";" "traceLine(\"\tpath = '\" + sPath + \"'\");" "traceLine(\"\tresult = '\" + canonizePath(sPath) + \"'\");" "changeDirectory(sCurrentDirectory);" "traceLine(\"current directory = '\" + getCurrentDirectory() + \"'\");" "set sPath = \".\";" "traceLine(\"\tpath = '\" + sPath + \"'\");" "traceLine(\"\tresult = '\" + canonizePath(sPath) + \"'\");"; function changeDirectory(path : string = "path name of the directory") : bool = "The function changes the current directory of \\CodeWorker\\ to the directory" "specified by the \\samp{path} argument. The parameter must refer to an existing" "directory." heading "Changes the current directory (\\samp{chdir()} in C)." 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);" see canonizePath, copySmartDirectory, exploreDirectory, getCurrentDirectory, relativePath, removeDirectory, resolveFilePath, scanDirectories; function changeFileTime(filename : string = "name of the file to set", accessTime : string = "date-time of the last access", modificationTime : string = "date-time of the last modification") : int = "The function changes the access and modification times of the file \\samp{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:" "\\begin{itemize}" "\t\\item \\textbf{-1}: unknown error that shouldn't appear," "\t\\item \\textbf{-2}: permission denied," "\t\\item \\textbf{-3}: too many files have been opened," "\t\\item \\textbf{-4}: file not found," "\t\\item \\textbf{-5}: invalid \\textit{times} argument," "\\end{itemize}" heading "Changes the access and modification times of a file." file 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!\");"; function charAt(text : string = "a sequence of characters", index : int = "the index of the character to extract from \\samp{text}") : string = "Returns the character at the specified \\samp{index}. An index ranges from \\textit{0} to \\textbf{lengthString(}\\samp{text}\\textbf{) - 1}. The first character of the sequence is at index \\textit{0}, the next at index \\textit{1}, and so on. If the \\samp{index} argument is out of bounds (negative or not less than the length of \\samp{text}), it returns an empty string." heading "Returns the characters present at a given position of a string." 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\");" see coreString, cutString, joinStrings, leftString, lengthString, midString, rightString, rsubString, subString; function charToByte(char : string = "a character") : string = "Converts a character to its hexadecimal representation, taking 2 digits, even if" "less than 0x10." "" "If the argument \\samp{char} is empty, the function returns '00'. If it contains" "more than one character, an error is raised." heading "Converts a character to a byte (hexadecimal representation of 2 digits)." conversion example "traceLine(\"charToByte('A') = '\" + charToByte(\"A\") + \"'\");" "traceLine(\"charToByte('\\\\n') = '\" + charToByte(\"\\n\") + \"'\");"; function charToInt(char : string = "a string containing just one char") : int = "Returns the conversion of \\samp{char} as an unsigned integer, corresponding to its ASCII form generally. If \\samp{char} doesn't contain just one char, it returns an empty string." heading "Converts a character to the integer value of the corresponding ASCII." conversion example "traceLine(\"charToInt('A') = \" + charToInt(\"A\") + \" <- ASCII code of 'A'\");"; function chmod(filename : string = "file to which change the permission setting", mode : string = "permission setting as a concatenation of 'R' and/or 'W' and/or 'X'") : bool = "The \\samp{chmod} function changes the permission setting of the file specified by \\samp{filename}." "The permission setting controls \\textit{read} and \\textit{write} and \\textit{execute} access to the file." "The argument \\samp{mode} holds the permission setting of the file as a concatenation of chars amongst the following:" "\\begin{itemize}" " \\item \\textbf{'R'} for \\textbf{r}eading permitted," " \\item \\textbf{'W'} for \\textbf{w}riting permitted," " \\item \\textbf{'X'} for e\\textbf{x}ecuting permitted (ignored on \\textit{Windows} platform)," "\\end{itemize}" "The function fails when the file given by the argument \\samp{filename} is not found, and an error is thrown when the argument \\samp{mode} contains an unexpected character." heading "Changes the permissions of a file." file 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'\");"; function ceil(number : double = "the floating-point number to ceil") : int = "Returns the smallest integer that is greater than or equal to \\samp{number}. If" "\\samp{number} isn't a number, the function returns \\textit{0}." heading "Returns the smallest integer greater that or equal to a number" numeric example "traceLine(\"ceil(5.369e+1) = \" + ceil(5.369e1));"; procedure closeSocket(socket : int = "a \\textit{client}/\\textit{server} socket descriptor") = "This procedure closes the socket descriptor specified to the argument \\samp{socket}." heading "Closes a socket descriptor." socket; function compareDate(date1 : string = "a date that conforms to the following format: \\samp{\"\\%d\\%b\\%Y \\%H:\\%M:\\%S.\\%L\"}", date2 : string = "second date to compare to \\samp{date1}") : int = "The function returns:" "\\begin{itemize}" "\t\\item a \\textbf{negative value} when \\samp{\\textit{date1} < \\textit{date2}}," "\t\\item \\textbf{zero} when \\samp{\\textit{date1} is equal to \\textit{date2}}," "\t\\item a \\textbf{positive value} when \\samp{\\textit{date1} > \\textit{date2}}." "\\end{itemize}" "If an argument doesn't conform to the expected syntax for a date" "(meaning that it must match with \\samp{\"\\%d\\%b\\%Y \\%H:\\%M:\\%S.\\%L\"})," "an error is raised." heading "Compares two dates." datetime 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));"; function completeDate(date : string = "a date-time representation to complete", format : string = "the format that the \\samp{date} argument conforms to") : string = "Completes the date passed to the argument \\samp{date}, so as it conforms to the" "syntax of a date in \\CodeWorker\\ meaning: \\samp{\"\\%d\\%b\\%Y \\%H:\\%M:\\%S.\\%L\"}." "" "Starting from today date with reset time (\\samp{00:00:00.0}), it replaces date-time" "characteristics with those of the parameter \\samp{date} and returns the result" "of the substitutions." "" "See \\ref{formatDate()} to reading the description of a date format." "A format type was added for this function: \\textbf{\\samp{'\\%|'}}." "Once the date has been iterated up to the end, if the format wasn't applied on it completely," "an error occurs, except if \\textbf{\\samp{'\\%|'}} stands at the current position in the format." heading "Extends an incomplete date with \\textit{today} characteristics." datetime 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\") + \"'\");"; function completeLeftSpaces(text : string = "a sequence of characters", length : int = "the length to obtain for \\samp{text}") : string = "Completes the string given by argument \\samp{text} with spaces to the left, so" "that the resulting string takes up \\samp{length} characters long. If the" "argument \\samp{text} contains more than \\samp{length} characters, it returns" "\\samp{text}." heading "Completes a string with spaces to the left so that it reaches a given size." string example "traceLine(\"completeLeftSpaces(1, 3) = '\" + completeLeftSpaces(1, 3) + \"'\");" "traceLine(\"completeLeftSpaces(123, 3) = '\" + completeLeftSpaces(123, 3) + \"'\");" "traceLine(\"completeLeftSpaces(1234, 3) = '\" + completeLeftSpaces(1234, 3) + \"'\");"; function completeRightSpaces(text : string = "a sequence of characters", length : int = "the length to obtain for \\samp{text}") : string = "Completes the string given by argument \\samp{text} with spaces to the right, so" "that the resulting string takes up \\samp{length} characters long. If the" "argument \\samp{text} contains more than \\samp{length} characters, it returns" "\\samp{text}." heading "Completes a string with spaces to the right so that it reaches a given size." string example "traceLine(\"completeRightSpaces(1, 3) = '\" + completeRightSpaces(1, 3) + \"'\");" "traceLine(\"completeRightSpaces(123, 3) = '\" + completeRightSpaces(123, 3) + \"'\");" "traceLine(\"completeRightSpaces(1234, 3) = '\" + completeRightSpaces(1234, 3) + \"'\");"; function composeAdaLikeString(text : string = "a sequence of character to convert to a Ada-like string") : string = "Returns the conversion of the sequence of characters given by argument" "\\samp{text} to a Ada-like string, without double quote delimiters." "If \\samp{text} contains a double-quote, it is repeated in the sequence." heading "Converts a sequence of characters to a Ada-like string without double quote delimiters." string example "local sText = \"double-quote \\\" inlayed in the sequence\";" "traceLine(\"composeAdaLikeString('\" + sText + \"') = '\" + composeAdaLikeString(sText) + \"'\");"; function composeCLikeString(text : string = "a sequence of character to convert to a C-like string") : string = "Returns the conversion of the sequence of characters given by argument" "\\samp{text} to a C-like string, without double quote delimiters. It means that special characters of \\samp{text}" " are replaced by their escape sequence, the rest remaining the same." "" "It recognizes the following escape sequences:" "\\begin{itemize}" "\t\\item \\textbf{'$\\backslash$$\\backslash$'} as \\textit{backslash} ($\\backslash$), ASCII value 92," "\t\\item \\textbf{'$\\backslash$' '} as \\textit{single quotation mark} ('), ASCII value 39," "\t\\item \\textbf{'$\\backslash$\"'} as \\textit{double quotation mark} (\"), ASCII value 34," "\t\\item \\textbf{'$\\backslash$a'} as \\textit{alert} (BEL), ASCII value 7," "\t\\item \\textbf{'$\\backslash$b'} as \\textit{backspace} (BS), ASCII value 8," "\t\\item \\textbf{'$\\backslash$f'} as \\textit{formfeed} (FF), ASCII value 12," "\t\\item \\textbf{'$\\backslash$n'} as \\textit{newline} (LF), ASCII value 10," "\t\\item \\textbf{'$\\backslash$r'} as \\textit{carriage return} (CR), ASCII value 13," "\t\\item \\textbf{'$\\backslash$t'} as \\textit{horizontal tab} (HT), ASCII value 9," "\t\\item \\textbf{'$\\backslash$v'} as \\textit{vertical tab} (VT), ASCII value 11," "\\end{itemize}" heading "Converts a sequence of characters to a C-like string without double quote delimiters." string example "local sText = \"\\t=tabulation,\\n=newline\";" "traceLine(\"composeCLikeString('\" + sText + \"') = '\" + composeCLikeString(sText) + \"'\");" see composeAdaLikeString, composeHTMLLikeString, composeSQLLikeString; function composeHTMLLikeString(text : string = "a sequence of character to convert to an HTML-like string") : string = "Returns the conversion of the sequence of characters given by argument" "\\samp{tex} to an HTML-like string. It means that special characters of \\samp{text}" "are replaced by their HTML escape sequence (\\textbf{\\&...;}), the rest remaining the same." heading "Converts a sequence of characters to an HTML-like text" string example "local sText = \"< & > aren't admitted by HTML\";" "traceLine(\"composeHTMLLikeString('\" + sText + \"') = '\" + composeHTMLLikeString(sText) + \"'\");"; function composeSQLLikeString(text : string = "a sequence of character to convert to a SQL-like string") : string = "Returns the conversion of the sequence of characters given by argument" "\\samp{text} to a SQL-like string, without single quote delimiters. It means that special characters of \\samp{text}" " are replaced by their escape sequence, the rest remaining the same." "" "It recognizes the following escape sequences:" "\\begin{itemize}" "\t\\item \\textbf{'$\\backslash$$\\backslash$'} as \\textit{backslash} ($\\backslash$), ASCII value 92," "\t\\item \\textbf{'$\\backslash$' '} as \\textit{single quotation mark} ('), ASCII value 39," "\t\\item \\textbf{'$\\backslash$\"'} as \\textit{double quotation mark} (\"), ASCII value 34," "\t\\item \\textbf{'$\\backslash$a'} as \\textit{alert} (BEL), ASCII value 7," "\t\\item \\textbf{'$\\backslash$b'} as \\textit{backspace} (BS), ASCII value 8," "\t\\item \\textbf{'$\\backslash$f'} as \\textit{formfeed} (FF), ASCII value 12," "\t\\item \\textbf{'$\\backslash$n'} as \\textit{newline} (LF), ASCII value 10," "\t\\item \\textbf{'$\\backslash$r'} as \\textit{carriage return} (CR), ASCII value 13," "\t\\item \\textbf{'$\\backslash$t'} as \\textit{horizontal tab} (HT), ASCII value 9," "\t\\item \\textbf{'$\\backslash$v'} as \\textit{vertical tab} (VT), ASCII value 11," "\\end{itemize}" "The function translates the single quote to an escape sequence \\textbf{\"$\\backslash$'\"}, 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 \\samp{replaceString()} to change \\textbf{\"$\\backslash$'\"} in \\textbf{\"''\"}." heading "Converts a sequence of characters to a SQL-like string without single quote delimiters." string example "local sText = \"\\t=tabulation,\\n=newline,'=single quote,\\\"=double quote\";" "traceLine(\"composeSQLLikeString('\" + sText + \"') = '\" + composeSQLLikeString(sText) + \"'\");"; function computeMD5(text : string = "the string to encrypt in MD5") : string = "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" heading "Computes the MD5 of a string." system example "local sSentence = \"Garfield squashed 5 spiders yesterday\";" "local sCode = computeMD5(sSentence);" "if sCode != \"B2D989F0C0501E9A9D4A9F1B4D06E2C5\" {" "\terror(\"bad result from 'computeMD5()'!\");" "}" "traceLine(\"computeMD5('\" + sSentence + \"') = \" + sCode);"; function copySmartFile(sourceFileName : string = "the name of the file to copy", destinationFileName : string = "the name of the copy") : bool = "This function copies a file \\samp{sourceFileName} to another location " "\\samp{destinationFileName} only if either file \\samp{destinationFileName}" "doesn't exist yet or the content of file \\samp{destinationFileName} is" "different of the content of file \\samp{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 \\samp{true}." heading "Copies a file only if the destination differs." file 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\");"; function coreString(text : string = "the string to work on", pos : int = "the beginning position, inclusive, starting at \\textit{0}", lastRemoved : int = "the number of characters to ignore at the end of \\samp{text}") : string = "Returns a substring of argument \\samp{text}." "The substring begins at the position specified by argument \\samp{pos} and ignores the last characters, which number is specifier by argument \\samp{lastRemoved}." "The first character starts at position \\textit{0}, the next at position \\textit{1}, and so on." heading "Extracts the core of a string, leaving the beginning and the end." string example "local sSentence = \"Do you believe in human being?\";" "traceLine(\"coreString('\" + sSentence + \"', 18, 7) = '\" + coreString(sSentence, 18, 7) + \"'\");"; function countStringOccurences(string : string = "sequence of characters where occurrences of substring \\samp{text} are to be counted", text : string = "substring to count") : int = "Returns the number of times the substring specified by argument \\samp{text} is found into the sequence of characters held by argument \\samp{string}." heading "How many occurences of a string to another." string example "local sSentence = \"Do you believe in human being?\";" "traceLine(\"countStringOccurences('\" + sSentence + \"', 'in') = \" + countStringOccurences(sSentence, \"in\"));" see completeLeftSpaces, completeRightSpaces, repeatString, replaceString, replaceTabulations, toLowerString, toUpperString, trimLeft, trimRight, trim, truncateAfterString, truncateBeforeString; function createDirectory(path : string = "the path of directories to create") : bool = "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." heading "Creates a new directory." directory; function createINETClientSocket(remoteAddress : string = "a remote IP address (Internet namespace)", port : int = "a remote port number") : int = "This function creates a client socket and connects it to the specified remote \\samp{port}," "at the specified address IP \\samp{remoteAddress}, and returns a new socket" "descriptor. The socket is of type \\textit{stream}." "" "Once the creation has achieved, use directly the \\textit{send}/\\textit{receive} functions" "or \\samp{attachInputToSocket()}/\\samp{attachOutputToSocket} for reading/writing" "to the socket via a \\textit{BNF-parsing}/\\textit{template-based} script." heading "Creates a stream socket connected to the specified port and IP address." socket see createINETServerSocket, acceptSocket, attachInputToSocket, detachInputFromSocket, attachOutputToSocket, detachOutputFromSocket, receiveBinaryFromSocket, receiveFromSocket, receiveTextFromSocket, sendTextToSocket, sendBinaryToSocket, closeSocket; function createINETServerSocket(port : int = "a local port number", backLog : int = "maximum queue length for incoming connection (1-5)") : int = "This function creates a server socket bound to \\samp{port} and returns a" "new socket descriptor. The socket is of type \\textit{stream}." "" "The argument \\samp{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 \\samp{acceptSocket()} to wait for" "a new client connection (blocking call)." heading "Creates a server stream socket bound to a specified port." socket; function createIterator(i : iterator = "iterator to initialize", list : treeref = "the iterator will point to the beginning of this list") : bool = "The variable \\samp{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 \\samp{false}." "" "\\samp{i} must have been declared before." heading "Creates an iterator pointing to the beginning of a list." iterator example "local list = {\"parsing\", \"tool\", \"and\", \"code\", \"generation\"};" "local it;" "if !createIterator(it, list) error(\"shouldn't be the case!\");" "do {" "\ttraceLine(\"\\t\" + it);" "} while next(it);" see createReverseIterator, duplicateIterator, first; function createReverseIterator(i : iterator = "iterator to initialize", list : treeref = "the iterator will point to the end of this list") : bool = "The variable \\samp{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 \\samp{false}." "" "\\samp{i} must have been declared before." heading "Creates a reverse iterator pointing to the end of a list." iterator example "local list = {\"parsing\", \"tool\", \"and\", \"code\", \"generation\"};" "local it;" "if !createReverseIterator(it, list) error(\"shouldn't be the case!\");" "do {" "\ttraceLine(\"\\t\" + it);" "} while next(it);"; function createVirtualFile(handle : string = "the name of the virtual file to create", content : string = "the content to put into the virtual file") : bool = "This function allows creating a \\textit{virtual} file. The \\samp{handle} parameter" "corresponds to the name given to the \\textit{virtual} file, which may be any" "sequence of characters. The virtual file is populated with the text assigned to" "the \\samp{content} argument." "" "The function always returns \\samp{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 \\textit{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 \\textit{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 \\textit{virtual} file that has the same name.\\\\" "Once a \\textit{virtual} file doesn't serve anymore, don't forget to free the" "useless memory it takes up by calling the \\samp{deleteVirtualFile()} function" "(see \\ref{deleteVirtualFile()})." heading "Creates a transient file in memory." file example "createVirtualFile(\"littleScript.cws\"," "\t\t\t\t\"a protected area:\" + endl() +" "\t\t\t\t\"@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\");" see createVirtualTemporaryFile, deleteVirtualFile, existVirtualFile, loadVirtualFile; function createVirtualTemporaryFile(content : string = "the content to put into the virtual file") : string = "This function allows creating a \\textit{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 \\samp{content} argument." "" "The function returns the name that the routine has composed for this virtual file." "The only difference with the function \\samp{createVirtualFile()} (see" "\\ref{createVirtualFile()}) lies in the way to choose of the virtual file name." "After creating the file, it behaves as any other virtual file." heading "Creates a transient file in memory, \\CodeWorker\\ choosing its name." file example "local sScriptFile = createVirtualTemporaryFile(" "\t\t\t\t\"a protected area:\" + endl() +" "\t\t\t\t\"@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);"; function decodeURL(URL : string = "readable URL to encode") : string = "Decode an URL from an HTTP request, meaning that the \\textbf{'+'} character changes in a space and" "all hexadecimal descriptions of bytes (2 digits preceded by \\textbf{'\\%'}) are" "converted to characters." "" "Note that conversions are transparent while doing HTTP requests." heading "Decodes an HTTP URL." URL example "local sURL = \"Roger+Rabbit%26%25%24%3D%21%3F\";" "traceLine(\"URL before HTTP decoding = '\" + sURL + \"'\");" "traceLine(\"URL after HTTP decoding = '\" + decodeURL(sURL) + \"'\");" see encodeURL; function decrement(number : doubleref = "variable to decrement") : double = "The result of \\samp{decrement} operation is the value of argument \\samp{number} \\textit{minus} one." "While the result is obtained, the variable \\samp{number} is decremented." heading "Equivalent admitted writing is \\samp{set a = \\$a - 1\\$;}." numeric example "local iNumber = 32;" "traceLine(\"iNumber = \" + iNumber);" "traceLine(\"decrement(iNumber) = \" + decrement(iNumber));" "// the variable 'number' has been decremented:" "traceLine(\"iNumber = \" + iNumber);" see increment, floor, ceil; function deleteFile(filename : string = "name of the file to delete") : bool = "Deletes the file whose name is given by parameter \\samp{filename}. If the file" "cannot be found or if it cannot be deleted, the function returns \\samp{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 \\samp{-I}), to offer a more secure use." heading "Deletes a file on the disk." file example "copyFile(\"readme.txt\", \"Documentation/readme.txt\");" "traceLine(\"Result of deleting file 'Documentation/readme.txt' = '\" + deleteFile(\"Documentation/readme.txt\") + \"'\");"; function deleteVirtualFile(handle : string = "the name of the virtual file to delete") : bool = "This function removes from memory the \\textit{virtual} file whose name is given" "by the \\samp{handle} parameter." "" "It returns \\samp{true} if the virtual file was created before and has been" "removed successfully." heading "Deletes a transient file from memory." file; function div(dividend : double = "the dividend", divisor : double = "the divisor") : double = "Returns the result of arithmetic division \\samp{dividend} \\textbf{/} \\samp{divisor}." "Members are converted from strings to numbers, supposed being worth \\samp{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 \\textit{0}." "" "Remember that the symbol \\textbf{'/'} 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 \\textbf{'\\$'} symbols, as formula under \\textit{LaTeX}. So, \\samp{\\$\\textit{dividend} \\textbf{/} \\textit{divisor}\\$}" "is equivalent to \\samp{div(\\textit{dividend}, \\textit{divisor})}." heading "Equivalent admitted writing is \\samp{\\$a / b\\$}."numeric example "local a = 3.2;" "traceLine(a + \" / 2 = \" + div(a, \"2\"));" "traceLine(a + \" / 0.2 = \" + div(a, 0.2) + \" <- integer value\");"; function duplicateIterator(oldIt : iterator = "the original iterator to duplicate", newIt : treeref = "copy of the original iterator") : bool = "Duplicates an iterator or returns \\samp{false} if \\textit{oldIt} isn't an iterator." heading "Duplicates an iterator." iterator example "local list = {\"parsing\", \"tool\", \"and\", \"code\", \"generation\"};" "foreach i in list {" "\tlocal it;" "\tif !duplicateIterator(i, it) error(\"shouldn't be the case!\");" "\ttraceText(\"\\t'\" + it + \"' - \");" "\tif prec(it) traceLine(\"precedent value = '\" + it + \"'\");" "\telse traceLine(\"no precedent value!\");" "}"; function encodeURL(URL : string = "readable URL to encode") : string = "Encode an URL for an HTTP request, meaning that the space character changes in \\textbf{'+'} and" "all non-alphanumeric characters are encoded in hexadecimal, preceded by \\textbf{'\\%'}." "" "Note that conversions are transparent while doing HTTP requests." heading "Encodes an URL to HTTP." URL example "local sURL = \"Roger Rabbit&%$=!?\";" "traceLine(\"URL before HTTP encoding = '\" + sURL + \"'\");" "traceLine(\"URL after HTTP encoding = '\" + encodeURL(sURL) + \"'\");"; function endl() : string = "Returns an end of line, value depending on the platform on which the" "script is executed. It returns \\samp{\"$\\backslash$r$\\backslash$n\"} under \\textit{Windows}," "and \\samp{\"$\\backslash$n\"} on any \\textit{UNIX} platform." heading "Returns an end-of-line, depending on the operating system." string example "traceLine(\"endl() = '\" + endl() + \"'\");" "traceLine(\"\tlength = \" + lengthString(endl()));" "traceLine(\"\tfirst ASCII character = \" + charToInt(charAt(endl(), 0)));"; function endString(text : string = "a sequence of characters to test", end : string = "the postfix") : bool = "\\samp{\"true\"} if the argument \\samp{end} is a postfix of the character" "sequence represented by \\samp{text}; \\samp{\"\"} otherwise. Note also that" "\\samp{\"true\"} will be returned if \\samp{end} is an empty string or is" "equal to argument \\samp{text}." heading "Compares the end of the string." string example "local sText = \"airport\";" "traceLine(\"endString('\" + sText + \"', 'port') = '\" + endString(sText, \"port\") + \"'\");"; function equal(left : double = "first number to compare", right : double = "second number to compare") : bool = "Compares two numbers and returns \\samp{true} if they are identical." "" "Sometimes, the operator \\textbf{'=='} is suitable to compare numbers, in the" "case where their decimal representation are strictly the same. But be careful" "that expression \\textit{\"7.0\" == \"7\"} is \\samp{false}!" "" "However, it exists an escape mode that allows writing arithmetic comparisons" "between \\textbf{'\\$'} symbols, as formula under \\textit{LaTeX}. So, \\samp{\\$\\textit{left} \\textbf{==} \\textit{right}\\$}" "is equivalent to \\samp{equal(\\textit{left}, \\textit{right})}." heading "Equivalent admitted writing is \\samp{\\$a == b\\$}." numeric example "traceLine(\"equal(7, '7.0') = '\" + equal(7, \"7.0\") + \"'\");" "traceLine(\"7 == '7.0' = '\" + (7 == \"7.0\") + \"'\");" see inf, sup; function equalsIgnoreCase(left : string = "first string to compare", right : string = "second string to compare") : bool = "Compares two strings, ignoring the case. It returns \\samp{true} when the comparison succeeds." heading "Compares two strings, ignoring the case." string example "traceLine(\"equalsIgnoreCase('BANANA', 'Banana') = '\" + equalsIgnoreCase(\"BANANA\", \"Banana\") + \"'\");" "traceLine(\"equalsIgnoreCase('BANANA', 'APPLE') = '\" + equalsIgnoreCase(\"BANANA\", \"APPLE\") + \"'\");" see endString; function equalTrees(firstTree : treeref = "a parse tree", secondTree : treeref = "another parse tree to compare with the first one") : bool = "Compares two parse trees and returns \\samp{true} if they are identical" "(same sub-nodes, same values, same entry keys on arrays of node, repeated" "recursively)." heading "Compares two subtrees." node 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) + \"'\");" see slideNodeContent; function executeStringQuiet(this : tree = "the current node that will be accessed with \\textit{this} variable", command : string = "some instructions of the scripting language to execute") : string = "This function interprets the argument \\samp{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." heading "Interprets a string as a script and returns all traces intended to the console." interpreter, string 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);"; function existEnv(variable : string = "the environment variable name") : bool = "The function returns \\samp{true} if the environment table entry contains" "the \\samp{variable}." heading "Checks the existence of an environment variable." system example "traceLine(\"PATH='\" + existEnv(\"PATH\")+ \"'\");"; function existFile(fileName : string = "the name of a file to check for existence") : bool = "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 \\samp{exploreDirectory()} instead." heading "Checks the existence of a file." file example "local sFilename = \"Documentation/CodeWorker.pdf\";" "traceLine(\"Checks existence of file '\" + sFilename + \"' = '\" + existFile(sFilename) + \"'\");"; function existVirtualFile(handle : string = "the name of the virtual file to check") : bool = "Checks whether a \\textit{virtual} file exists or not, meaning that it has been" "created via the function \\samp{createVirtualFile()}." heading "Checks the existence of a transient file, created in memory." file; function existVariable(variable : treeref = "the name of a variable") : bool = "Checks whether a variable exists or not." heading "Checks the existence of a node." node example "local alice;" "traceLine(\"The variable 'alice' exists: '\" + existVariable(alice) + \"'\");" "traceLine(\"The variable 'wonderful' doesn't exist: '\" + existVariable(wonderful) + \"'\");" see clearVariable, findFirstSubstringIntoKeys, findElement, findNextSubstringIntoKeys, getArraySize, getVariableAttributes, invertArray, isEmpty, removeVariable; function exp(x : double = "the floating-point whose exponential is to compute") : double = "Returns the exponential of \\samp{x}." "" "On underflow, it returns \\textit{0}.\\\\" "On overflow, it returns \\textit{infinite}." heading "Returns the exponential of a value." numeric example "traceLine(\"exp(0.693147) = \" + $exp(0.693147)$);"; function exploreDirectory(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") : bool = "Explores the directory whose name is passed to the argument \\samp{path}. The list" "of files is put into the node's array \\samp{directory.\\textbf{files}} and the" "list of directories are put into the node's array \\samp{directory.\\textbf{directories}}." "Exploring sub directories is required by the argument \\samp{subfolders} and each" "node of the node's array \\samp{directory.\\textbf{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 \\samp{directory} doesn't change" "and the function returns \\samp{false}. If the directory doesn't contain any" "file, the attribute \\samp{directory.\\textit{files}} isn't created. If the" "directory doesn't contain any subfolder, the attribute" "\\samp{directory.\\textit{directories}} isn't created." heading "Browses all files of a directory, recursively or not." directory, file 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 {" "\ttraceLine(\"\t'\" + j + \"'\");" "}" "foreach i in cascading theDirectory.directories {" "\t// the complete path is too long: shorten it" "\ttraceLine(\"- directory '\" + i.subString(sPathToExplore.length()) + \"':\");" "\tforeach j in i.directories {" "\t\ttraceLine(\"\tsubfolder '\" + key(j) + \"'\");" "\t// the complete path is too long: shorten it" "\t\ttraceLine(\"\t\tpath '\" + j.subString(sPathToExplore.length()) + \"'\");" "\t}" "\tif key(i) == \"GettingStarted\" {" "\t\ttraceLine(\"\t... a lot of files!\");" "\t} else {" "\t\tforeach j in i.files {" "\t\t\ttraceLine(\"\t'\" + j + \"'\");" "\t\t}" "\t}" "}"; function extractGenerationHeader(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") : string = "Looks for a generation header into the file passed to the argument \\samp{filename}." "It returns the comment that was put into the header (see procedure" "\\samp{setGenerationHeader()} \\ref{setGenerationHeader()}) during the generation," "after having assigned the output parameters:" "\\begin{itemize}" "\t\\item \\samp{generator} with the name of the application that have generated the file, \\textit{\"CodeWorker\"} normally," "\t\\item \\samp{version} with the version of the generator, the version of \\CodeWorker\\ normally," "\t\\item \\samp{date} with the date and time of the generation, conforming to" "\t\t\\samp{\"\\%d\\%b\\%Y \\%H:\\%M:\\%S\"}; \\textit{12dec2002 10:00:23} for example," "\\end{itemize}" "" "The generation header is inlayed in the comment delimeters and conforms to the" "format:\\\\" "\\begin{itemize}" "\t\\item if the comment holds on a single line:\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#generation header\\#\\#CodeWorker\\#\\#\"}}\\\\" "\t\t\\makebox[1cm][r]{} \\samp{\\textit{version-number} \\textbf{\"\\#\\#\"} \\textit{generation-date} \\textbf{\"\\#\\#\"}}\\\\" "\t\t\\makebox[1cm][r]{} \\samp{\\textbf{'\"'} \\textit{comment} \\textbf{'\"'} \\textit{end-comment}}" "\t\\item if the comment holds on more than one line:\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#generation header\\#\\#CodeWorker\\#\\#\"}}\\\\" "\t\t\\makebox[1cm][r]{} \\samp{\\textit{version-number} \\textbf{\"\\#\\#\"} \\textit{generation-date} \\textbf{\"\\#\\#\"} \\textit{end-comment}}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#header start\\#\\#\"} \\textit{end-comment}}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textit{line\\tiny{1}} \\textit{end-comment}}\\\\" "\t\t\\samp{...}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textit{line\\tiny{n}} \\textit{end-comment}}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#header end\\#\\#\"} \\textit{end-comment}}" "\\end{itemize}" heading "Gives the generation header of a generated file, if any." generation 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(\"\");"; function fileCreation(filename : string = "name of the file to ask for its creation time") : string = "Returns the date-time of creation of file whose name is passed to the argument \\samp{filename}." "" "If an error occurs, it returns one code among the following:" "\\begin{itemize}" "\t\\item \\textbf{\"-1\"}: unknown error that shouldn't appear," "\t\\item \\textbf{\"-2\"}: permission denied," "\t\\item \\textbf{\"-3\"}: too many files have been opened," "\t\\item \\textbf{\"-4\"}: file not found," "\\end{itemize}" heading "Returns the creation date of a file." file, datetime example "local sFileName = \"Documentation/CodeWorker.tex\";" "local sCreationTime = fileCreation(sFileName);" "if startString(sCreationTime, \"-\") error(\"error code = \" + sCreationTime + \"!\");" "traceLine(\"creation of '\" + sFileName + \"' = \" + sCreationTime);"; function fileLastAccess(filename : string = "name of the file to ask for its last access time") : string = "Returns the date-time of last access to file whose name is passed to the argument \\samp{filename}." "" "If an error occurs, it returns one code among the following:" "\\begin{itemize}" "\t\\item \\textbf{\"-1\"}: unknown error that shouldn't appear," "\t\\item \\textbf{\"-2\"}: permission denied," "\t\\item \\textbf{\"-3\"}: too many files have been opened," "\t\\item \\textbf{\"-4\"}: file not found," "\\end{itemize}" heading "Returns the last access date of a file." file, datetime example "local sFileName = \"Documentation/CodeWorker.tex\";" "local sLastAccessTime = fileLastAccess(sFileName);" "if startString(sLastAccessTime, \"-\") error(\"error code = \" + sLastAccessTime + \"!\");" "traceLine(\"last access to '\" + sFileName + \"' = \" + sLastAccessTime);"; function fileLastModification(filename : string = "name of the file to ask for its last modification time") : string = "Returns the date-time of last modification to file whose name is passed to the argument \\samp{filename}." "" "If an error occurs, it returns one code among the following:" "\\begin{itemize}" "\t\\item \\textbf{\"-1\"}: unknown error that shouldn't appear," "\t\\item \\textbf{\"-2\"}: permission denied," "\t\\item \\textbf{\"-3\"}: too many files have been opened," "\t\\item \\textbf{\"-4\"}: file not found," "\\end{itemize}" heading "Returns the last modification date of a file." file, datetime example "local sFileName = \"Documentation/CodeWorker.tex\";" "local sLastModificationTime = fileLastModification(sFileName);" "if startString(sLastModificationTime, \"-\") error(\"error code = \" + sLastModificationTime + \"!\");" "traceLine(\"last modification of '\" + sFileName + \"' = \" + sLastModificationTime);"; function fileLines(filename : string = "name of the file where to count lines") : int = "Returns the number of lines that the file passed to the argument \\samp{filename}" "contains." "" "If the file cannot be found nor opened, the function returns \\samp{-1}." heading "Returns the number of lines in a file." file 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);"; function fileMode(filename : string = "file to ask for its permission setting") : string = "The \\samp{chmod} function returns the permission setting of the file specified by \\samp{filename}." "The permission setting controls \\textit{read} and \\textit{write} and \\textit{execute} access to the file." "The returned value holds the permission setting of the file as a concatenation of chars amongst the following:" "\\begin{itemize}" " \\item \\textbf{'R'} for \\textbf{r}eading permitted," " \\item \\textbf{'W'} for \\textbf{w}riting permitted," " \\item \\textbf{'X'} for e\\textbf{x}ecuting permitted (ignored on \\textit{Windows} platform)," "\\end{itemize}" "If an error occurs, the function returns one code among the following:" "\\begin{itemize}" "\t\\item \\textbf{\"-1\"}: unknown error that shouldn't appear," "\t\\item \\textbf{\"-2\"}: permission denied," "\t\\item \\textbf{\"-3\"}: too many files have been opened," "\t\\item \\textbf{\"-4\"}: file not found," "\\end{itemize}" heading "Returns the permissions of a file." file example "local sPermission = fileMode(\"Documentation/CodeWorker.tex\");" "if startString(sPermission, \"-\") error(\"error code = \" + sPermission);" "traceLine(\"permission on file 'Documentation/CodeWorker.tex' = '\" + sPermission + \"'\");"; function fileSize(filename : string = "name of the file to ask for its size") : int = "Returns the size of the file whose name is passed to the argument \\samp{filename}." "" "If an error occurs, it returns one code among the following:" "\\begin{itemize}" "\t\\item \\textbf{-1}: unknown error that shouldn't appear," "\t\\item \\textbf{-2}: permission denied," "\t\\item \\textbf{-3}: too many files have been opened," "\t\\item \\textbf{-4}: file not found," "\\end{itemize}" heading "Returns the size of a file." file example "local sFileName = \"Documentation/CodeWorker.tex\";" "local iSize = fileSize(sFileName);" "if isNegative(iSize) error(\"error code = \" + iSize + \"!\");" "traceLine(\"size of '\" + sFileName + \"' = \" + iSize + \" characters\");"; function findElement(value : string = "a key as an array entry", variable : treeref = "a variable that contains an array of nodes") : bool = "This function looks for a key, given by argument \\samp{value}, as an entry of" "the nodes array passed to argument \\samp{variable}. If the key is found, the" "function returns \\samp{true}, and and empty string otherwise." heading "Checks the existence of an entry key in an array." array 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) + \"'\");"; function findFirstChar(text : string = "the string to explore", someChars : string = "a set of individual characters") : int = "Returns the location into \\samp{text} of the first character encountered that" "belongs to the set of characters passed to argument \\samp{someChars}. The" "position starts counting at \\samp{0}. If no occurrence has been found, the" "negative value \\samp{-1} is returned." heading "Returns the position of the first character amongst a set, encountered into a string." string example "local sText = \"looking for a token: \\\"...\\\" f(a,b) {...}\";" "traceLine(\"sText = '\" + composeCLikeString(sText) + \"'\");" "traceLine(\"findFirstChar(sText, '\\\"({') = \" + findFirstChar(sText, \"\\\"({\"));" see endString, findFirstChar, findLastString, findNextString, findString, startString; function findFirstSubstringIntoKeys(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") : int = "This function returns the position of the first item, such as its corresponding" "entry key into the list owned by\\samp{variable} contains the substring passed" "to argument \\samp{substring}. The position starts counting at \\samp{0}." "" " If no item is found, the negative value \\samp{-1} is returned." heading "Returns the first entry key of an array, containing a given string." array 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));"; function findLastString(text : string = "a sequence of characters to explore", find : string = "a substring to find into \\samp{text}") : int = "Returns the position of the last occurrence of the substring \\samp{find} into" "the sequence of characters passed to argument \\samp{text}. The position starts" "counting to \\samp{0}." "" "If the substring \\samp{find} doesn't belong to \\samp{text}, the negative value" "\\samp{-1} is returned." heading "Returns the position of the last occurence of a string to another." string example "local sText = \"the lamp of experience\";" "traceLine(\"sText = '\" + sText + \"'\");" "traceLine(\"findLastString(sText, 'p') = '\" + findLastString(sText, \"p\") + \"'\");"; function findNextString(text : string = "a sequence of characters to explore", find : string = "a substring to find into \\samp{text}", position : int = "the position in the string (starting at 0) the search must begin") : int = "Returns the lowest beginning index of the substring \\samp{find} that matches" "the sequence of characters passed to argument \\samp{text}, starting the search at \\samp{position} included. The index starts" "counting to \\samp{0}." "" "If the substring \\samp{find} doesn't belong to \\samp{text} (starting at \\samp{position}), the negative value" "\\samp{-1} is returned." heading "Returns the next occurence of a string to another." string example "local sText = \"the lamp of experience\";" "traceLine(\"sText = '\" + sText + \"'\");" "traceLine(\"findNextString(sText, 'p', 8) = '\" + findNextString(sText, \"p\", 8) + \"'\");"; function findNextSubstringIntoKeys(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") : int = "Returns the position of the next item of list passed to argument \\samp{variable}," "whose entry key contains the substring given by argument \\samp{substring}. The" "next item is searched after position passed to argument \\samp{next}. The" "position starts counting at \\samp{0}." "" " If no item is found, the negative value \\samp{-1} is returned." heading "Returns the next entry key of an array, containing a given string." array 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));"; function findString(text : string = "a sequence of characters to explore", find : string = "a substring to find into \\samp{text}") : int = "Returns the position of the first occurrence of the substring \\samp{find} into" "the sequence of characters passed to argument \\samp{text}. The position starts" "counting to \\samp{0}." "" "If the substring \\samp{find} doesn't belong to \\samp{text}, the negative value" "\\samp{-1} is returned." heading "Returns the first occurence of a string to another." string example "local sText = \"the lamp of experience\";" "traceLine(\"sText = '\" + sText + \"'\");" "traceLine(\"findString(sText, 'of') = '\" + findString(sText, \"of\") + \"'\");"; function first(i : iterator = "iterator of a \\samp{foreach} statement or pointing to a list") : bool [info] = "Returns \\samp{true} if the iterator argument \\samp{i} points to the first item" "of the iterated list." heading "Returns \\samp{true} if the iterator points to the first item." iterator example "local myTree;" "insert myTree[\"Everest\"] = \"mountain\";" "insert myTree[\"Tea spoon\"] = \"silverware\";" "foreach i in myTree {" "\tif first(i) traceLine(\"The first item key of the list is '\" + key(i) + \"'\");" "}" see index, last, key, next, prec; function floor(number : double = "the floating-point number to floor") : int = "Returns the largest integer that is less than or equal to \\samp{number}. If" "\\samp{number} isn't a number, the function returns \\textit{0}." heading "Returns the largest integer less that or equal to a number" numeric example "traceLine(\"floor(5.369e+1) = \" + floor(5.369e1));"; function formatDate(date : string = "a date-time representation to transform", format : string = "the format that will be applied to the \\samp{date} argument") : string = "Converts a date to another format, or extracts just a part of the date. The date" "is passed to argument \\samp{date}, and the format given by \\samp{format}." "" "Each field of the format specification is a single character or a format type" "signifying a particular \\textit{format option}. A \\textit{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 \\textbf{'\\%\\%'}." "" "The format type determines how the associated argument, at the current location" "to the date, must be interpreted:" "\\begin{itemize}" "\t\\item \\textbf{'\\%d'} means that a 2-digits day of the month must be written," "\t\\item \\textbf{'\\%e'} means that a day of the month must be written, such as" "\t\t\\textit{1} but not \\textit{01}" "\t\\item \\textbf{'\\%j'} means that the day of the year must be written," "\t\\item \\textbf{'\\%m'} means that a 2-digits month must be written," "\t\\item \\textbf{'\\%B'} means that the complete english name of the month must" "\t\tbe written," "\t\\item \\textbf{'\\%b'} means that the truncated english name of the month must" "\t\tbe written: only the 3 first characters," "\t\\item \\textbf{'\\%Y'} means that a 4-digits year must be written," "\t\\item \\textbf{'\\%y'} means that a 2-digits year must be written," "\t\\item \\textbf{'\\%t'} means that the number of days since 30dec1899 must be written (\\textit{WingZ} format)," "\t\\item \\textbf{'\\%w'} means that the weekday must be written as an integer" "\t\t(\\samp{0-6}; \\samp{0} is \\textit{sunday})," "\t\\item \\textbf{'\\%W'} means that the weekday must be written as the complete english name," "\t\\item \\textbf{'\\%H'} means that a 2-digits hour must be written," "\t\\item \\textbf{'\\%I'} means that a 2-digits hour (12 max) must be written," "\t\\item \\textbf{'\\%p'} means that \\samp{\"AM\"} / \\samp{\"PM\"} must be written," "\t\\item \\textbf{'\\%M'} means that a 2-digits minute must be written," "\t\\item \\textbf{'\\%S'} means that a 2-digits second must be written," "\t\\item \\textbf{'\\%L'} means that a 3-digits millisecond must be written," "\t\\item \\textbf{'\\%D'} is equivalent to \\samp{'\\%m/\\%d/\\%y'}," "\t\\item \\textbf{'\\%r'} is equivalent to \\samp{'\\%I:\\%M:\\%S \\%p'}," "\t\\item \\textbf{'\\%T'} is equivalent to \\samp{'\\%H:\\%M:\\%S'}," "\\end{itemize}" "An error occurs if a temporal argument doesn't belong to those listed above, or if" "the date to format doesn't conform to \\samp{\"\\%d\\%b\\%Y \\%H:\\%M:\\%S.\\%L\"}." heading "Changes the format of a date." datetime example "traceLine(\"release of the documentation = '\" + getNow() + \"'\");" "traceLine(\"a new format = '\" + formatDate(getNow(), \"%B %d, %Y\") + \"'\");" "traceLine(\"the hour only = '\" + formatDate(getNow(), \"%H\") + \"'\");" see addToDate, compareDate, completeDate, getLastDelay, getNow, setNow; function getArraySize(variable : treeref = "any node of a tree") : int = "Returns the number of items the argument \\samp{variable} contains" "into its embedded array, or \\textit{0} if the array doesn't exist." heading "Returns the number of items in an array." array example "local myTree;" "insert myTree[\"Everest\"] = \"mountain\";" "insert myTree[\"Tea spoon\"] = \"silverware\";" "traceLine(\"getArraySize(myTree) = '\" + getArraySize(myTree) + \"'\");" deprecated getVariableSize "1.30"; 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 \\samp{expand} or \\samp{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 \\textit{expansion" "markups}." "" "The beginning of comment assigned by default is worth \\textbf{'//'}. This is" "the symbol of C++ and JAVA comments that are the most frequently files" "encountered for generation. Use the procedure \\samp{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 (\\textit{Microsoft} extended HTML with the" "non-recommended tag \\textit{''} that the \\textit{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!" heading "Returns the current format of a comment's end." generation example "traceLine(\"This example is running while processing the documentation, so we are expecting a LaTeX comment: '\" + composeCLikeString(getCommentEnd()) + \"'\");"; function getCurrentDirectory() : string = "Returns the current directory’s name as a fully qualified path, where separators" "are always forward slashes \\textbf{/} like in UNIX. Note that the current" "directory is closed by a separator." "" "The function returns an empty string if the path is longer than 1024 characters." heading "Returns the current directory (\\samp{getcwd()} in C)." directory example "traceLine(\"current directory = '\" + getCurrentDirectory() + \"'\");"; function getEnv(variable : string = "the environment variable name") : string = "The function returns the environment table entry containing the \\samp{variable}." "An error message is thrown if \\samp{variable} is not found in the" "environment table." "" "See function \\samp{existEnv()} to check the existence before getting.\\\\" "Use the \\samp{putenv} function to modify the value of an environment variable." heading "Returns an environment variable, or raises an error if not exist." system example "traceLine(\"PATH='\" + getEnv(\"PATH\")+ \"'\");" see environTable, existEnv, putEnv, system; function getGenerationHeader() : string = "Returns the comment that is added automatically to each file generated with the" "procedure \\samp{generate}. Defining a comment for the generation header may be" "required by passing the option \\samp{-genheader} on the command line or by" "calling the procedure \\samp{setGenerationHeader()}." "" "The generation header is inlayed in the comment delimeters and conforms to the" "format:\\\\" "\\begin{itemize}" "\t\\item if the comment holds on a single line:\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#generation header\\#\\#CodeWorker\\#\\#\"}}\\\\" "\t\t\\makebox[1cm][r]{} \\samp{\\textit{version-number} \\textbf{\"\\#\\#\"} \\textit{generation-date} \\textbf{\"\\#\\#\"}}\\\\" "\t\t\\makebox[1cm][r]{} \\samp{\\textbf{'\"'} \\textit{comment} \\textbf{'\"'} \\textit{end-comment}}" "\t\\item if the comment holds on more than one line:\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#generation header\\#\\#CodeWorker\\#\\#\"}}\\\\" "\t\t\\makebox[1cm][r]{} \\samp{\\textit{version-number} \\textbf{\"\\#\\#\"} \\textit{generation-date} \\textbf{\"\\#\\#\"} \\textit{end-comment}}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#header start\\#\\#\"} \\textit{end-comment}}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textit{line\\tiny{1}} \\textit{end-comment}}\\\\" "\t\t\\samp{...}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textit{line\\tiny{n}} \\textit{end-comment}}\\\\" "\t\t\\samp{\\textit{begin-comment} \\textbf{\"\\#\\#header end\\#\\#\"} \\textit{end-comment}}" "\\end{itemize}" heading "Returns the comment to put into the header of generated files." file, generation 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, \"//\")" "\ttraceLine(\"\\t\" + i);" "traceLine(\"class to generate = '\" + project.listOfClasses#front.name + \"'\");" "local sOutputText;" "generateString(sFileName, project.listOfClasses#front, sOutputText);" "traceLine(\"generated text:\");" "traceLine(sOutputText);" "setGenerationHeader(\"\");"; function getHTTPRequest(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") : string = "This function sends an HTTP's GET request to the HTTP server pointed to by the parameter" "\\samp{URL} with the list of arguments put into the the parameter \\samp{arguments}." "" "The function returns the document read from the HTTP server." "" "The function \\samp{sendHTTPRequest()} (see \\ref{sendHTTPRequest()}) describes" "the structure of the HTTP session object." heading "Sends an HTTP's GET request." URL see postHTTPRequest, sendHTTPRequest; function getIncludePath() : string = "It returns the include path passed to the command line with one or more times" "the setting of option \\samp{-I}, or the latest include path set via the procedure" "\\samp{setIncludePath()}." "" "The include path is a concatenation of paths separated by semi-commas (\textbf{';'})." heading "Returns the include path passed via the option \\samp{-I}." command example "traceLine(\"getIncludePath():\");" "local list;" "cutString(getIncludePath(), ';', list);" "foreach i in list traceLine(i);"; function getLastDelay() : double = "The function returns the last duration that was measured by a statement modifier" "\\samp{delay} (see \\ref{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 \\samp{delay} statement modifier), it returns the" "time elapsed since the beginning of the time-keeping." heading "Returns the time consumed to execute a statement." datetime example "local list;" "local iIndex = 4;" "delay while isPositive(decrement(iIndex)) {" "\tpushItem list = \"element \" + iIndex;" "\ttraceLine(\"creating node '\" + list#back + \"'\");" "}" "traceLine(\"time of execution = \" + getLastDelay() + \" seconds\");"; function getNow() : string = "Returns the current date-time, conforming to the format:\\\\" "\\samp{\\%d\\%b\\%Y \\%H:\\%M:\\%S.\\%L}" "" "For explanations about \\textit{format types}, see function \\samp{formatDate}" "at \\ref{formatDate()}." heading "Returns the current date-time." datetime example "traceLine(\"now is '\" + getNow() + \"'\");" deprecated today "2.09"; function getProperty(define : string = "name of a property") : string = "Returns the value of a property that:" "\\begin{itemize}" "\t\\item was passed to the command line via the option \\samp{'-D'} or \\samp{'-define'}," "\t\\item was built by the procedure \\samp{setProperty()}," "\\end{itemize}" heading "Returns the value of a property passed via the option \\samp{-D}." command example "traceLine(\"getProperty('documentation') = '\" + getProperty(\"documentation\") + \"'\");" deprecated getDefineTarget "1.30" see getIncludePath, getVersion, getWorkingPath, setIncludePath, setProperty, setVersion, setWorkingPath; function getShortFilename(pathFilename : string = "a file name with its path") : string = "Returns the short name of a file, meaning without the path." "It is composed of a radical + an extension." heading "Returns the short name of a file" file example "traceLine(\"getShortFilename('src/steakhouse\\\\chicken.cpp') = \\\"\" + getShortFilename(\"src/steakhouse\\\\chicken.cpp\") + \"\\\"\");"; function getTextMode() : string = "Returns the mode of text that has been retained for parsing and source code generation:" "\\begin{itemize}" "\t\\item \\textbf{\"DOS\"}: the default value if the interpreter is running under a \\textit{Windows} platform," "\t\\item \\textbf{\"UNIX\"}: the default value if the interpreter isn't running under a \\textit{Windows} platform," "\t\\item \\textbf{\"BINARY\"}: not exploited yet, but intended to specify later that" "\t\tthe parsing and the source code generation are applied on binary files," "\\end{itemize}" "The impact of having \samp{\"DOS\"} instead of any other mode is that special" "comments, which announce markup keys and protected areas, will finish by" "\"$\\backslash$r$\\backslash$n\" when the end of comment is a newline '$\\backslash$n\'." heading "Returns the text mode amongst \\textbf{\"DOS\"}, \\textbf{\"UNIX\"} and \\textbf{\"BINARY\"}." generation example "traceLine(\"This documentation is generated under '\" + getTextMode() + \"' text mode\");"; function getVariableAttributes(variable : treeref = "the variable to explore", list : tree = "will contain the name and type (reference to another node or not) of each attribute") : int = "Populates a list with all attribute names of a tree node." "The name of branches just below the node \\samp{variable} are put into \\samp{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 \\samp{variable} doesn't exist." "" "Note: use \\samp{\\#evaluateVariable()} to navigate along a tree node, where the" "complete name is determined at runtime." heading "Extract all attribute names of a tree node." node 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 {" "\tif i traceLine(\"movies#front.\" + key(i) + \" -> \" + i);" "\telse traceLine(\"movies#front.\" + key(i) + \" = \\\"\" + composeCLikeString(#evaluateVariable(\"movies#front.\" + key(i))) + \"\\\"\");" "}"; function getVersion() : string = "Returns the \\textit{version number} of the \\CodeWorker\\ interpreter or, if a" "\\textit{version name} has been passed to the command line via the option" "\\samp{-version}, the version of old scripts being executed." heading "Returns the version of the interpreter." command example "traceLine(\"The version of the interpreter is '\" + getVersion() + \"'\");"; function getWorkingPath() : string = "Returns the output directory that has been assigned to the option" "\\textbf{-path} on the command line." heading "Returns the output directory passed via option \\samp{-path}." command example "traceLine(\"'-path' = '\" + getWorkingPath() + \"'\");"; function getWriteMode() : string = "Returns how text is written during a generation or during an implicit copy" "while translating: \\samp{\"insert\"} or \\samp{\"overwrite\"} mode (default mode)." heading "Returns how text is written during a generation (insert/overwrite)." generation; function hexaToDecimal(hexaNumber : string = "an hexadecimal integer to convert to a decimal number") : int = "Converts an hexadecimal integer, passed to the argument \\samp{hexaNumber}, to a" "signed decimal integer and returns the result. If \\samp{hexaNumber} doesn't conform to" "the syntax of an hexadecimal number (\\samp{\\textit{hexaNumber} ::= \\#!ignore [\\textbf{'0'..'9'} | \\#noCase \\textbf{'A'..'F'}]+})," "the function raises an error." heading "Converts an hexadecimal representation to an integer." conversion example "traceLine(\"hexaToDecimal('FE8') = \" + hexaToDecimal(\"FE8\"));"; function hostToNetworkLong(bytes : string = "a 4-bytes representation of a long integer sorted in the host bytes order") : string = "Converts a 4-bytes representation of a long integer to the network bytes order." "\\CodeWorker\\ stores a byte as a 2-hexadecimal digits; the function raises" "an error if the argument \\samp{bytes} is malformed." "" "Use \\samp{longToBytes()} and \\samp{bytesToLong()} to swap between decimal" "and host binary representation of a long integer." heading "Converts a 4-bytes representation of a long integer to the network bytes order." conversion example "traceLine(\"hostToNetworkLong('89ABCDEF') = '\" + hostToNetworkLong(\"89ABCDEF\") + \"'\");" see networkLongToHost, hostToNetworkShort, networkShortToHost; function hostToNetworkShort(bytes : string = "a 2-bytes representation of a short integer sorted in the host bytes order") : string = "Converts a 2-bytes representation of a short integer to the network bytes order." "\\CodeWorker\\ stores a byte as a 2-hexadecimal digits; the function raises" "an error if the argument \\samp{bytes} is malformed." "" "Use \\samp{shortToBytes()} and \\samp{bytesToShort()} to swap between decimal" "and host binary representation of a short integer." heading "Converts a 2-bytes representation of a short integer to the network bytes order." conversion example "traceLine(\"hostToNetworkShort('12EF') = '\" + hostToNetworkShort(\"12EF\") + \"'\");"; function increment(number : doubleref = "variable to increment") : double = "The result of \\samp{increment} operation is the value of argument \\samp{number} \\textit{minus} one." "While the result is obtained, the variable \\samp{number} is incremented." heading "Equivalent admitted writing is \\samp{set a = \\$a + 1\\$;}." numeric example "local iNumber = 32;" "traceLine(\"iNumber = \" + iNumber);" "traceLine(\"increment(iNumber) = \" + increment(iNumber));" "// the variable 'number' has been incremented:" "traceLine(\"iNumber = \" + iNumber);"; function indentFile(file : string = "name of a file to indent", mode : string : false = "type of text to indent") : bool = "Indents the file passed to parameter \\samp{file}, forcing the indentation mode via the" "argument \\samp{mode}. If the argument is empty or omited, the file extension drives the" "indentation mode:" "\\begin{itemize}" "\t\\item \\textit{cpp}, \\textit{cxx}, \\textit{h}, \\textit{hxx}: will indent as expected for a \\textbf{C++} format," "\t\\item \\textit{java}: will indent as expected for a \\textbf{JAVA} format," "\\end{itemize}" "More format will be recognized in the future." "" "The function returns \\samp{true} if the file needed to be indented," "meaning that it has changed after processing the indentation." heading "Indents a file, depending on the target language." file 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\"));" see indentText; function index(i : iterator = "iterator of a \\samp{foreach} statement") : int [info] = "Returns the position of the item the iterator points to." "The position in the list begins counting at 0." heading "Returns the position of an item in a list." iterator example "local myTree;" "insert myTree[\"Everest\"] = \"mountain\";" "insert myTree[\"Tea spoon\"] = \"silverware\";" "foreach i in myTree {" "\ttraceLine(\"The item '\" + key(i) + \"' is at position \" + index(i) + \"\");" "}"; function inf(left : double = "the first member", right : double = "the second member") : bool = "Compares two numbers and returns \\samp{true} if the first member given by" "argument \\samp{left} is strictly smaller than the second member passed to" "argument \\samp{right}." "" "Don't use the operator \\samp{'<'} to compare numbers in the classical syntax of" "the interpreter: it only checks the lexicographical order. So, \\textit{'12 < 3'} is \\samp{true}." "However, it exists an escape mode that allows writing arithmetic comparisons" "between \\textbf{'\\$'} symbols, as formula under \\textit{LaTeX}. So, \\samp{\\$\\textit{left} \\textbf{<} \\textit{right}\\$}" "is equivalent to \\samp{inf(\\textit{left}, \\textit{right})}." heading "Equivalent admitted writing is \\samp{\\$a < b\\$}."numeric example "traceLine(\"inf(3, 12) = '\" + inf(3, 12) + \"'\");" "traceLine(\"3 < 12 = '\" + (3 < 12) + \"'\");"; function inputKey(echo : bool = "asks for echoing the standard input on the console") : string = "Returns a character extracted from the standard input, the keyboard generally." "If no key was pressed, it returns an empty string." "" "See statement modifiers \\samp{file\_as\_standard\_input} (\\ref{file as standard input}) and" "\\samp{string\_as\_standard\_input} (\\ref{string as standard input}) to change" "the source of the standard input." "" "If the source of the standard input is the keyboard, the argument \\samp{echo}" "has no effects. Otherwise, the input text is displayed into the console only if" "\\samp{echo} is worth \\samp{true}." heading "If any, returns the last key pressed on the standard input." standard; function inputLine(echo : bool = "asks for echoing the standard input on the console", prompt : string : "" = "text to prompt at the beginning of the line") : string = "Returns a line that was extracted from the standard input, the keyboard generally." "See statement modifiers \\samp{file\_as\_standard\_input} (\\ref{file as standard input}) and" "\\samp{string\_as\_standard\_input} (\\ref{string as standard input}) to change" "the source of the standard input." "" "If the \\samp{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 \\samp{echo}" "has no effects. Otherwise, the input text is displayed into the console only if" "\\samp{echo} is worth \\samp{true}." heading "Wait for the standard input to the console." standard example standard_input("These characters were typed by hand on the keyboard!") "traceText(\"Please enter something> \");" "local sKeyboardText = inputLine(true);" "traceLine(\"The user said: '\" + sKeyboardText + \"'\");"; function isEmpty(array : treeref = "any node of a tree") : bool = "Returns \\samp{\\textbf{true}} if the argument \\samp{array} embeds an" "array of trees, and \\samp{\\textbf{false}} otherwise." heading "Checks whether a node has items or not." array example "local myTree;" "insert myTree[\"Everest\"] = \"mountain\";" "insert myTree[\"Tea spoon\"] = \"silverware\";" "traceLine(\"isEmpty(myTree) = '\" + isEmpty(myTree) + \"'\");"; function isIdentifier(identifier : string = "an identifier is a string composed of letters and underscores ; digits are admitted too, except at the first place") : bool = "This predicate checks whether the string passed by parameter is an identifier" "or not." heading "Checks whether a string is a C-like identifier or not." standard example "traceLine(\"isIdentifier('atom') = '\" + isIdentifier(\"atom\") + \"'\");" "traceLine(\"isIdentifier('$money') = '\" + isIdentifier(\"$money\") + \"'\");"; function isNegative(number : double = "a number to check") : bool = "This predicate checks whether the number passed by parameter is strictly" "negative or not." "" "If the argument isn't recognized as a number, the number is supposed to be worth" "\\samp{0}, so the function returns \\samp{false}." "" "Be careful if you choose the expression \\samp{'< 0'} to compare numbers in the" "classical syntax of the interpreter: it only checks the lexicographical order." "So, \\textit{'+0.0 <= 0'} is \\samp{false}!" "However, it exists an escape mode that allows writing arithmetic comparisons" "between \\textbf{'\\$'} symbols, as formula under \\textit{LaTeX}. So, \\samp{\\$\\textit{number} \\textbf{<= 0}\\$}" "is equivalent to \\samp{isNegative(\\textit{number})}." heading "Equivalent admitted writing is \\samp{\\$a < 0\\$}." numeric example "traceLine(\"isNegative(0) = '\" + isNegative(0) + \"'\");" "traceLine(\"isNegative(-1) = '\" + isNegative(-1) + \"'\");" see isPositive; function isNumeric(number : string = "a floating-point number in text representation") : bool = "This predicate checks whether the string passed by parameter is a floating-point" "or not." heading "Checks whether a string is a floating-point number or not." standard example "traceLine(\"isNumeric('atom') = '\" + isNumeric(\"atom\") + \"'\");" "traceLine(\"isNumeric('3.14') = '\" + isNumeric(\"3.14\") + \"'\");"; function isPositive(number : double = "a number to check") : bool = "This predicate checks whether the number passed by parameter is strictly" "positive or not." "" "If the argument isn't recognized as a number, the number is supposed to be worth" "\\samp{0}, so the function returns \\samp{false}." "" "Be careful if you choose the expression \\samp{'> 0'} to compare numbers in the" "classical syntax of the interpreter: it only checks the lexicographical order." "So, \\textit{'-0.0 >= 0'} is \\samp{false}!" "However, it exists an escape mode that allows writing arithmetic comparisons" "between \\textbf{'\\$'} symbols, as formula under \\textit{LaTeX}. So, \\samp{\\$\\textit{number} \\textbf{>= 0}\\$}" "is equivalent to \\samp{isPositive(\\textit{number})}." heading "Equivalent admitted writing is \\samp{\\$a > 0\\$}." numeric example "traceLine(\"isPositive(0) = '\" + isPositive(0) + \"'\");" "traceLine(\"isPositive(1) = '\" + isPositive(1) + \"'\");"; function joinStrings(list : tree = "the list that contains the strings to join", separator : string = "the sequence of chars that separates the strings") : string = "This function returns the concatenation of all strings put into \\samp{list}," "putting a separator between each of them." "" "If the list is empty, the function will return an empty string." heading "Joins a list of strings, adding a separator between them." string example "local listOfItems = {\"a\", \"yellow\", \"submarine\"};" "traceLine(\"joinStrings({'a', 'yellow', 'submarine'}, './.'):\");" "traceLine(joinStrings(listOfItems, \"./.\"));"; function key(i : iterator = "iterator of a \\samp{foreach} statement or pointing to a list") : string [info] = "Returns the key that allows accessing the current item of the iterated list." heading "Returns the entry key of the item pointed to by the iterator." iterator example "local myTree;" "insert myTree[\"Everest\"] = \"mountain\";" "insert myTree[\"Tea spoon\"] = \"silverware\";" "foreach i in myTree {" "\ttraceLine(\"key = '\" + key(i) + \"' value = '\" + i + \"'\");" "}"; function last(i : iterator = "iterator of a \\samp{foreach} statement or pointing to a list") : bool [info] = "Returns \\samp{true} if the iterator argument \\samp{i} points to the last item" "of the iterated list." heading "Returns \\samp{true} if the iterator points to the last item." iterator example "local myTree;" "insert myTree[\"Everest\"] = \"mountain\";" "insert myTree[\"Tea spoon\"] = \"silverware\";" "foreach i in myTree {" "\tif last(i) traceLine(\"The last item key of the list is '\" + key(i) + \"'\");" "}"; function leftString(text : string = "a sequence of characters", length : int = "a positive number") : string = "Returns the first characters that belong to the string passed to the argument" "\\samp{text}. The number of characters to take is given by argument" "\\samp{length}. If the string contains less than \\samp{length} characters, the" "function returns all of them." heading "Returns the beginning of a string." string example "traceLine(\"leftString('airport', 3) = '\" + leftString(\"airport\", 3) + \"'\");" "traceLine(\"leftString('airport', 8) = '\" + leftString(\"airport\", 8) + \"'\");"; function lengthString(text : string = "a sequence of characters") : int = "Returns the length of the sequence of characters represented by argument \\samp{text}." heading "Returns the length of a string." string example "local sText = \"A rabbit ran in the garden\"; // size of this string is 26 characters" "traceLine(\"lengthString(\\\"\" + sText + \"\\\") = \" + lengthString(sText));"; function loadBinaryFile(file : string = "name of the binary file to load", length : int : -1 = "number of bytes to read") : string = "Returns the binary content of the file whose name is passed to argument \\samp{file}," "or the \\textit{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:\\\\" "\\samp{\\textit{binary-content} ::= [\\textit{byte}]*;\\\\" "\t\\textit{byte} ::= [\\textbf{'0'..'9'} | \\textbf{'A'..'F'} | \\textbf{'a'..'f'}]2;}" "" "If the file doesn't exist or can't be read with success, an error occurs." heading "Loads a binary file and stores each byte in a hexadecimal representation of 2 digits." file example "local sContent = loadBinaryFile(\"readme.txt\");" "local sFormatedContent;" "local iLine = 0;" "while sContent && $iLine < 10$ {" "\tsFormatedContent += leftString(sContent, 40) + endl();" "\tsContent = sContent.subString(40);" "\tincrement(iLine);" "}" "traceLine(\"the first 200 bytes of 'readme.txt' are:\" + endl() + sFormatedContent);"; function loadFile(file : string = "name of the file to load", length : int : -1 = "number of characters to read") : string = "Returns the content of the file whose name is passed to argument \\samp{file}," "or the \\textit{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." heading "Returns the content of a file or raises an error if not found." file example "local sText = loadFile(\"readme.txt\");" "sText = sText.leftString(200);" "traceLine(\"the 200 first characters of 'readme.txt' are:\" + endl() + sText);"; function loadVirtualFile(handle : string = "the name of the virtual file to load") : string = "Returns the content of the \\textit{virtual} file whose name is passed to argument \\samp{file}." "" "If the \\textit{virtual} file doesn't exist or couldn't be read with success, an error occurs." heading "Returns the content of a transient file or raises an error if not found." file; function log(x : double = "the floating-point whose logarithm is to compute") : double = "Returns the logarithm of \\samp{x}." "" "If \\samp{x} is negative, it throws an error.\\\\" "If \\samp{x} is 0, it returns \\textit{infinite}." heading "Returns the Neperian logarithm." numeric example "traceLine(\"log(5.369e+14)/log(10) = \" + $log(5.369e+14)/log(10)$);" "traceLine(\"log(0) = \" + log(0));"; function longToBytes(long : ulong = "an unsigned long integer using the decimal base") : string = "Converts an unsigned long integer in decimal base to its 4-bytes representation." "Bytes are ordered in the host order (memory storage)." heading "Converts an unsigned long integer in decimal base to its 4-bytes representation." conversion example "traceLine(\"longToBytes(65535)\ = '\" + longToBytes(65535) + \"'\");"; function midString(text : string = "a sequence of characters", pos : int = "a position into argument \\samp{text}", length : int = "the number of characters to extract") : string = "Returns a substring located into the string \\samp{text} to the position passed" "to the argument \\samp{pos}. The position starts counting at \\samp{0}. The" "substring will be extracted for a size given by parameter \\samp{length}, or" "less if it has reached the end of the string." "" "If the argument \\samp{pos} is greater than the length of \\samp{text}, the" "function returns an empty string." heading "Returns a substring starting at a point for a given length." string example "local sText = \"Banks offer weapons without bullets\";" "traceLine(\"midString('\" + sText + \"', 12, 7) = '\" + midString(sText, 12, 7) + \"'\");"; function mod(dividend : int = "the first operand", divisor : int = "the second operand") : int = "Returns the remainder when the first operand is divided by the second. It" "applies the modulus operator." "Members are converted from strings to integers, supposed being worth \\samp{0} if a parsing error occurs;" "then the modulus is processed, and the result is converted to a string." "" "Remember that the symbol \\textbf{'\\%'} doesn't mean anything in the standard syntax of the" "language, so there is no way to confuse for expressing a modulus operator." "However, it exists an escape mode that allows writing arithmetic expressions" "between \\textbf{'\\$'} symbols, as formulae under \\textit{LaTeX}. So, \\samp{\\$\\textit{dividend} \\textbf{\\%} \\textit{divisor}\\$}" "is equivalent to \\samp{mod(\\textit{dividend}, \\textit{divisor})}." heading "Equivalent admitted writing is \\samp{\\$a \\% b\\$}." numeric example "traceLine(\"mod(5, 2) = '\" + mod(5, 2) + \"'\");"; function mult(left : double = "the first operand", right : double = "the second operand") : double = "Returns the result of arithmetic multiplication \\samp{left} \\textbf{*} \\samp{right}." "Members are converted from strings to numbers, supposed being worth \\samp{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 \\textit{0}." "" "Remember that the symbol \\textbf{'*'} doesn't mean anything in the standard syntax of the" "language, so there is no way to confuse for expressing a multiplication." "However, it exists an escape mode that allows writing arithmetic expressions" "between \\textbf{'\\$'} symbols, as formulae under \\textit{LaTeX}. So, \\samp{\\$\\textit{left} \\textbf{*} \\textit{right}\\$}" "is equivalent to \\samp{mult(\\textit{left}, \\textit{right})}." heading "Equivalent admitted writing is \\samp{\\$a * b\\$}." numeric example "traceLine(\"mult(5.5, 2) = '\" + mult(5.5, 2) + \"'\");"; function networkLongToHost(bytes : string = "a 4-bytes representation of a long integer sorted in the network bytes order") : string = "Converts a 4-bytes representation of a long integer to the host bytes order." "\\CodeWorker\\ stores a byte as a 2-hexadecimal digits; the function raises" "an error if the argument \\samp{bytes} is malformed." "" "Use \\samp{longToBytes()} and \\samp{bytesToLong()} to swap between decimal" "and host binary representation of a long integer." heading "Converts a 4-bytes representation of a long integer to the host bytes order." conversion example "traceLine(\"networkLongToHost('EFCDAB89') = '\" + networkLongToHost(\"EFCDAB89\") + \"'\");"; function networkShortToHost(bytes : string = "a 2-bytes representation of a short integer sorted in the network bytes order") : string = "Converts a 2-bytes representation of a short integer to the host bytes order." "\\CodeWorker\\ stores a byte as a 2-hexadecimal digits; the function raises" "an error if the argument \\samp{bytes} is malformed." "" "Use \\samp{shortToBytes()} and \\samp{bytesToShort()} to swap between decimal" "and host binary representation of a short integer." heading "Converts a 2-bytes representation of a short integer to the host bytes order." conversion example "traceLine(\"networkShortToHost('EF12') = '\" + networkShortToHost(\"EF12\") + \"'\");"; function next(i : iterator = "iterator of a \\samp{foreach} statement or pointing to items of a list") : bool [info] = "The iterator will now point to the next item of the list and returns \\samp{true} if exists." heading "Move an iterator to the next item of a list." iterator; function not(expression : bool = "any kind of expression") : bool [info] = "This function does the same work as the unary operator \\textbf{'!'}: it returns" "\\samp{true} if the evaluation of the \\samp{expression} is an empty string, and" "\\samp{false} otherwise." heading "The boolean negation, equivalent to \\samp{!a}." unknown example "local myVariable;" "traceLine(\"not(existVariable(myVariable)) = '\" + not(existVariable(myVariable)) + \"'\");"; function octalToDecimal(octalNumber : string = "an octal integer to convert to a decimal number") : int = "Converts an octal integer, passed to the argument \\samp{octalNumber}, to a" "signed decimal integer and returns the result. If \\samp{octalNumber} doesn't conform to" "the syntax of an octal number (\\samp{\\textit{octalNumber} ::= \\#!ignore [\\textbf{'0'..'8'}]+})," "the function raises an error." heading "Converts an octal representation to a decimal integer." conversion example "traceLine(\"octalToDecimal('765') = \" + octalToDecimal(\"765\"));"; function parseFreeQuiet(designFileName : string = "the name of the parsing script that reads tokens in a procedural way", this : tree = "the current node that will be accessed with \\textit{this} variable", inputFileName : string = "the file to parse") : string [user] = "This function parses the file passed to argument \\samp{inputFileName}, following" "the instructions of the procedure-driven parsing script given by parameter" "\\samp{designFileName}, but doesn't display messages to the standard output" "stream. Messages are put into a string that is returned by the function." heading "Parses a file with an imperative script, reroute all console messages and returns them as a string." interpreter, parsing example "local sScript = \"GettingStarted/SimpleML-token-reading.cws\";" "local sDesign = \"GettingStarted/SolarSystem0.sml\";" "traceLine(\"sScript = '\" + sScript + \"'\");" "traceLine(\"sDesign = '\" + sDesign + \"'\");" "traceLine(\"messages of parseFreeQuiet(sScript, project, sDesign):\");" "traceLine(parseFreeQuiet(sScript, project, sDesign));"; function pathFromPackage(package : string = "a package path") : string = "Converts a package path to a directory path. A \\textit{package path} is a" "sequence of identifiers separated by dots. All dots (\\textbf{'.'}) encountered" "are replaced by a path separator (\\textbf{'$\\backslash\\backslash$} under" "\\textit{Windows} and \\textbf{'/'} on \\textit{UNIX} platforms). A path" "separator is added at the end." heading "Converts a package path to a directory path." file example "traceLine(\"pathFromPackage('java.solarsystem') = '\" + pathFromPackage(\"java.solarsystem\") + \"'\");"; function postHTTPRequest(URL : string = "URL of the HTTP server", HTTPSession : treeref = "an object to describe the HTTP session", arguments : treeref = "list of the arguments to POST; the key contains the name of the argument and the element gives the value") : string = "This function sends an HTTP's POST request to the HTTP server pointed to by the parameter" "\\samp{URL} with the list of arguments put into the the parameter \\samp{arguments}." "" "The function returns the document read from the HTTP server." "" "The function \\samp{sendHTTPRequest()} (see \\ref{sendHTTPRequest()}) describes" "the structure of the HTTP session object." heading "Sends an HTTP's POST request." URL; function pow(x : double = "the base", y : double = "the exponent") : double = "Returns value of the argument \\samp{x} raised to the power of the second" "argument \\samp{y}. The arguments are converted to numerics, being worth" "\\textit{0} when a conversion fails. The power is then processed, and the" "result is converted to a string, skipping fractional part if all digits after" "the dot are \\textit{0}." heading "Raises a number to the power of another." numeric example "traceLine(\"pow(3, 4) = \" + pow(3, 4));"; function prec(i : iterator = "iterator of a \\samp{foreach} statement or pointing to items of a list") : bool [info] = "The iterator will now point to the precedent item of the list and returns \\samp{true} if exists." heading "Move an iterator to the precedent item of a list." iterator; function randomInteger() : int = "Generates a pseudorandom number." heading "Generates a pseudorandom number." standard; function receiveBinaryFromSocket(socket : int = "a client socket descriptor", length : int = "number of bytes to read") : string = "This function waits for \\samp{length} bytes to read from \\samp{socket}, and" "returns a sequence of bytes (\\CodeWorker\\ represents a byte with 2 hexadecimal digits)." "" "If an error occurs, the function returns an empty string." heading "Reads binary data from the socket, knowing the size." socket; function receiveFromSocket(socket : int = "a client socket descriptor", isText : boolref = "the function will populate this parameter with \\samp{true} if read bytes designate a string and \\samp{false} if they are binary data") : string = "This function waits for bytes to read from \\samp{socket} and returns them." "If an error occurs, the function returns an empty string." "" "The function sets \\samp{isText} to:\\\\" "\\begin{itemize}" "\t\\item \\samp{true} if it has received a text," "\t\\item \\samp{false} if it has received binary data: the returned string is" "\t\tthen a sequence of bytes (\\CodeWorker\\ represents a byte with 2 hexadecimal digits)," "\\end{itemize}" heading "Reads text or binary data from a socket." socket; function receiveTextFromSocket(socket : int = "a client socket descriptor", length : int = "size of the text to read") : string = "This function waits for \\samp{length} bytes to read from \\samp{socket}, and" "returns a string." "" "If an error occurs, the function returns an empty string." heading "Reads text from a socket, knowing the size." socket; function relativePath(path : string = "the path to give as relative to \\samp{reference}", reference : string = "a path that serves as the reference to determine the relative path") : string = "Returns the relative path that allow going to the well-named \\samp{path}," "considering the \\samp{reference} path as the starting point (like a current" "directory). Under the \\textit{Windows} platform, if the two arguments don't" "hold on the same drive, the absolute path of the first argument is returned." "" "Note that the arguments are converted to canonical paths (see \\samp{canonicalPath()} \\samp{canonicalPath()} for more information)." heading "Returns the relative path, which allows going from a path to another." file example "local sPath = getCurrentDirectory() + \"Documentation/CodeWorker.pdf\";" "traceLine(\"path = '\" + sPath + \"'\");" "local sReference = \"WebSite/downloads\";" "traceLine(\"reference = '\" + sReference + \"'\");" "traceLine(\"result = '\" + relativePath(sPath, sReference) + \"'\");"; function removeDirectory(path : string = "the directory to remove") : bool = "The function removes the directory specified by \\samp{path}. The directory must" "not be the current working directory or the root directory." "" "The function returns \\samp{false} if the path is invalid or cannot be deleted." heading "Removes a directory from the disk." directory example "local sDirectory = getWorkingPath() + \"Scripts/Tutorial/GettingStarted/bin\";" "if !removeDirectory(sDirectory) error(\"impossible to remove '\" + sDirectory + \"'\");"; function removeGenerationTagsHandler(key : string = "designates the handler to remove") : bool = "Removes the current generation tags handler amongst those previously registered" "thanks to the function \\samp{addGenerationTagsHandler()}." "If the current generation tags handler is worth this one, no custom handler is selected." "" "Returns \\samp{true} if \\samp{key} designates a registered handler." heading "Removes a custom generation tags handler" generation; function repeatString(text : string = "the string to repeat", occurrences : int = "number of times the string must be repeated") : string = "Returns the result of repeating the sequence of characters passed to argument" "\\samp{text} a number of times given by the parameter \\samp{occurrences}." heading "Returns the concatenation of a string repeated a few times." string example "traceLine(\"repeatString('Hungry!', 3') = '\" + repeatString(\"Hungry!\", 3) + \"'\");"; function replaceString(old : string = "the substring to be replaced", new : string = "the string replacing the old one", text : string = "the sequence of characters to handle") : string = "Returns the result of replacing all occurrences of substring passed to argument" "\\samp{old} by the substring \\samp{new}, when found into \\samp{text}." heading "Replaces a substring with another." string example "local sText = \"first in, first out\";" "traceLine(\"replaceString('fir', 'la', '\" + sText + \"') = '\" + replaceString(\"fir\", \"la\", sText) + \"'\");"; function replaceTabulations(text : string = "a sequence of characters where spaces must be inserted instead of tabulations", tab : int = "size of a tabulation") : string = "Returns the result of replacing all tabulations (character \\textbf{'$\\backslash$t'}) of" "the string passed to argument \\samp{text} by spaces. The maximum of spaces to" "insert instead of tabulation is given by the parameter \\samp{tab}." "" "Notice that spaces to insert are determined according to the position of the" "tabulation in the string and the beginning of the \\textit{line} (it means that" "\\textbf{'$\\backslash$n'} characters are taken into account) and the tabulation size. So," "this function isn't equivalent to \\samp{replaceString()} \\ref{replaceString()}." heading "Replaces tabulations with spaces." string example "local sText = \"\ta\tlittle\tjoke\";" "traceLine(\"replaceTabulations(sText, 4) = '\" + replaceTabulations(sText, 4) + \"'\");" "traceLine(\"replaceString('\\t', \" \", sText) = '\" + replaceString(\"\\t\", \" \", sText) + \"'\");"; function resolveFilePath(filename : string = "the path of the file to resolve") : string = "Searches the file \\samp{filename} in the current directory and, if fails, it" "continues searching it in the include directories (\\samp{'-I'} switch on the" "command line)." "" "It returns the location of the file in directories, removing any ambiguity.\\\\" "If the file doesn't exist, the function returns an empty string.\\\\" "If \\samp{filename} points to a virtual file, the function returns \\samp{filename}.\\\\" heading "Gives the location of a file with no ambiguity." file example "local sIncludePath = getIncludePath();" "setIncludePath(sIncludePath + \";Documentation\");" "traceLine(\"resolveFilePath('CodeWorker.tex') = '\" + resolveFilePath(\"CodeWorker.tex\") + \"'\");" "setIncludePath(sIncludePath);"; function rightString(text : string = "a sequence of characters", length : int = "a positive number") : string = "Returns the last characters that belong to the string passed to the argument" "\\samp{text}. The number of characters to take is given by argument" "\\samp{length}. If the string contains less than \\samp{length} characters, the" "function returns all of them." heading "Returns the end of a string." string example "traceLine(\"rightString('airport', 4) = '\" + rightString(\"airport\", 4) + \"'\");" "traceLine(\"rightString('airport', 8) = '\" + rightString(\"airport\", 8) + \"'\");"; function rsubString(text : string = "a sequence of characters", pos : int = "a position starting at 0, and relative to the end of the \\samp{text} string") : string = "Returns the sequence of characters passed to argument \\samp{text} after skipping" "the last \\samp{pos} characters. It is a \\textit{reverse} subString()." heading "Returns the left part of a string, ignoring last characters." string example "local sText = \"The lamp of experience\";" "traceLine(\"sText = '\" + sText + \"'\");" "traceLine(\"rsubString(sText, 5) = '\" + rsubString(sText, 5) + \"'\");"; function scanDirectories(directory : tree = "node that will contain the name of filtered files and folders", path : string = "the directory from where to start the exploration", pattern : string = "the filter to apply on files to keep") : bool = "Explores the directory whose name is passed to the argument \\samp{path} and " "filters all files that validate the \\samp{pattern}. The list of files is put" "into the node's array \\samp{directory.\\textbf{files}} and the list of" "directories are put into the node's array \\samp{directory.\\textbf{directories}}." "The argument \\samp{subfolders} requires exploring sub-directories and each" "node of the node's array \\samp{directory.\\textbf{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 \\samp{directory} doesn't change" "and the function returns \\samp{false}. If the directory doesn't contain any" "file, the attribute \\samp{directory.\\textit{files}} isn't created. If the" "directory doesn't contain any subfolder, the attribute" "\\samp{directory.\\textit{directories}} isn't created." heading "Explores a directory, filtering filenames." directory, file example "local theDirectory;" "local sPathToExplore = project.winBinaries; // Windows package of CodeWorker" "if !scanDirectories(theDirectory, sPathToExplore, \"Leader*.cws\") 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 {" "\ttraceLine(\"\t'\" + j + \"'\");" "}" "foreach i in cascading theDirectory.directories {" "\t// the complete path is too long: shorten it" "\ttraceLine(\"- directory '\" + i.subString(sPathToExplore.length()) + \"':\");" "\tforeach j in i.directories {" "\t\ttraceLine(\"\tsubfolder '\" + key(j) + \"'\");" "\t// the complete path is too long: shorten it" "\t\ttraceLine(\"\t\tpath '\" + j.subString(sPathToExplore.length()) + \"'\");" "\t}" "\tforeach j in i.files {" "\t\ttraceLine(\"\t'\" + j + \"'\");" "\t}" "}"; function scanFiles(files : tree = "node that will contain files that validate the \\samp{pattern}", path : string = "the directory where to scan files", pattern : string = "the filter to apply on files to keep", subfolders : bool = "to scan sub directories recursively") : bool = "Explores the directory \\samp{path} and filters all files that validate the \\samp{pattern}" "given by parameter. Files are put into the node's array called \\samp{files} with" "their relative path, which is assigned to the value of the item. The scan is" "applied on subfolders if the argument \\samp{subfolders} passes \\samp{true}." "" "The \\samp{pattern} argument accepts the standard jocker characters (\\textbf{'*'} and" "\\textbf{'?'}). If empty, \\samp{pattern} is considered as being worth \"*\"." "" "The function returns \\samp{true} if the directory to scan exists." heading "Returns a flat list of all filenames matching with a filter." directory, file example "local files;" "local sDirectory = \"Scripts/Tutorial/GettingStarted\";" "if !scanFiles(files, sDirectory, \"Leader*.cws\", true) error(\"impossible to find the directory\");" "traceLine(\"filtering recursively all files that conform to 'Leader*.cws'\");" "foreach i in files {" "\ttraceLine(\"\t\" + subString(i, lengthString(sDirectory)));" "}"; function sendBinaryToSocket(socket : int = "a client socket descriptor", bytes : string = "a sequence of bytes to write") : bool = "This function writes binary data to a socket and returns \\samp{true} if it has achieved successfully." "" "The function raises an error if a byte passed to \\samp{bytes} is malformed:" "\\CodeWorker\\ expects 2 hexadecimal digits to represent a byte." heading "Writes binary data to a socket." socket; function sendHTTPRequest(URL : string = "URL of the HTTP server", HTTPSession : treeref = "an object to describe the HTTP session") : string = "This function sends an HTTP request to the HTTP server pointed to by the argument" "\\samp{URL}, and returns the document read from the HTTP server." "" "If the request fails, an error message is thrown." "" "The well-named argument \\samp{HTTPSession} specifies some information into devoted attributes:" "\\begin{itemize}" "\t\\item \\textbf{agent} \\textit{(optional)} is the browser name, \"\\CodeWorker\\\" by default," "\t\\item \\textbf{referer} \\textit{(optional)}," "\t\\item \\textbf{proxy} \\textit{(optional)}:" "\t\t\\begin{itemize}" "\t\t\t\\item \\textbf{proxy.host} \\textit{(compulsory)}," "\t\t\t\\item \\textbf{proxy.port} \\textit{(compulsory)}," "\t\t\t\\item \\textbf{proxy.userpwd} \\textit{(optional)} is worth \"\\textit{user}\\textbf{:}\\textit{password}\"," "\t\t\\end{itemize}" "\t\\item \\textbf{cookies} \\textit{(optional)} is a list of nodes such as:" "\t\t\\begin{itemize}" "\t\t\t\\item \\textbf{name} \\textit{(compulsory)}," "\t\t\t\\item \\textbf{value} \\textit{(optional)} is worth \\samp{\"\"} by default," "\t\t\t\\item \\textbf{path} \\textit{(optional)}, populated from the HTTP header (see below)" "\t\t\t\\item \\textbf{domain} \\textit{(optional)}, populated from the HTTP header (see below)" "\t\t\t\\item \\textbf{expires} \\textit{(optional)} for a permanent cookie, populated from the HTTP header (see below)" "\t\t\\end{itemize}" "\\end{itemize}" "" "After processing the request successfully, you'll find information about the returned data.\\\\" "If the data is a binary format, such as an archive or an image, the field \\samp{HTTPSession\\textbf{.binary_data}}" "is worth \\samp{true}.\\\\" "If the data is a textual format, the detail of the received header lines are filled in" "the array \\samp{HTTPSession\\textbf{.header_lines}}. The array \\samp{HTTPSession\\textbf{.cookies}}" "is updated with the cookies extracted from the header." "The entry nodes of the array \\samp{HTTPSession\\textbf{.header_lines}} are indexed with the name of" "the header directive. These entry nodes just contain the list of all header values attached to such a directive." "" "\\textbf{Example:}\\\\" "\\texttt{" "HTTP/1.1 200 OK\\\\" "Cache-Control: private\\\\" "Date: Wed, 10 Mar 2004 13:41:03 GMT\\\\" "Server: Microsoft-IIS/6.0\\\\" "Set-Cookie: SESSIONID=Garfield; expires=Wed, 10-Mar-2004 15:03:19 GMT; path=/\\\\" "Set-Cookie' PREFERENCES=yellow; domain=jupiter; path=/\\\\" "Content-Type: text/html\\\\" "Content-Length: 4469" "}" "" "These fields are then injected in the array \\samp{HTTPSession\\textbf{.header_lines}}." "The header directive \\samp{Set-Cookie} appears twice, but gives rise to only one entry node:" "\\samp{HTTPSession.header_lines[\\textbf{\"Set-Cookie\"}]}. This entry node is a list containing" "two elements. The first one defines all characteristics of \\samp{SESSIONID} and" "the second one provides the characteristics of the cookie \\samp{PREFERENCES}.\\\\" "Here, a piece of code that displays the header lines:\\\\" "\\texttt{foreach i in theSession.header_lines \{\\\\" "\\makebox[0.4cm][r]{}foreach j in i \{\\\\" "\\makebox[0.8cm][r]{}traceLine(\"'\" + i.key() + \"' = '\" + j + \"'\");\\\\" "\\makebox[0.4cm][r]{}\}\\\\" "\}" "}" "" "\\textbf{Output:}\\\\" "\\texttt{" "\t'HTTP/1.1 200 OK' = ''\\\\" "\t'Cache-Control' = 'private'\\\\" "\t'Date' = 'Wed, 10 Mar 2004 13:41:03 GMT'\\\\" "\t'Server' = 'Microsoft-IIS/6.0'\\\\" "\t'Set-Cookie' = 'SESSIONID=Garfield; expires=Wed, 10-Mar-2004 15:03:19 GMT; path=/'\\\\" "\t'Set-Cookie' = 'PREFERENCES=yellow; domain=jupiter; path=/'\\\\" "\t'Content-Type' = 'text/html'\\\\" "\t'Content-Length' = '4469'" "}" heading "Sends an HTTP request." URL; function sendTextToSocket(socket : int = "a client socket descriptor", text : string = "the text to write") : bool = "This function writes a text to a socket and returns \\samp{true} if it has achieved successfully." heading "Writes text to a socket." socket; function selectGenerationTagsHandler(key : string = "designates the handler to take") : bool = "Selects the current generation tags handler amongst those previously registered" "thanks to the function \\samp{addGenerationTagsHandler()}." "If the parameter \\samp{key} is worth \\textit{false} (empty string), the default" "generation tags handler is used." "" "Returns \\samp{true} if \\samp{key} designates a registered handler." heading "Selects your own CodeWorker's tags handler for processing generation tasks" generation; function shortToBytes(short : ushort = "an unsigned short integer using the decimal base") : string = "Converts an unsigned short integer in decimal base to its 2-bytes representation." "Bytes are ordered in the host order (memory storage)." heading "Converts an unsigned short integer in decimal base to its 2-bytes representation." conversion example "traceLine(\"shortToBytes(255)\ = '\" + shortToBytes(255) + \"'\");"; function sqrt(x : double = "the number we want to calculate the square root") : double = "Calculates the square root of \\samp{x}." "" "An invalid number causes the function to throw an error." heading "Calculates the square root." numeric example "traceLine(\"sqrt(25) = \" + sqrt(25));"; function startString(text : string = "a sequence of characters to test", start : string = "the prefix") : bool = "\\samp{\"true\"} if the argument \\samp{start} is a prefix of the character" "sequence represented by \\samp{text}; \\samp{\"\"} otherwise. Note also that" "\\samp{\"true\"} will be returned if \\samp{start} is an empty string or is" "equal to argument \\samp{text}." heading "Checks the beginning of a string." string example "local sText = \"airport\";" "traceLine(\"startString('\" + sText + \"', 'air') = '\" + startString(sText, \"air\") + \"'\");"; function sub(left : double = "first arithmetic member", right : double = "second arithmetic member") : double = "Returns the result of arithmetic subtraction \\samp{left} \\textbf{-} \\samp{right}." "Members are converted from strings to numbers, supposed being worth \\samp{0} if a parsing error occurs;" "then the subtraction is processed, and the result is converted to a string," "skipping fractional part if all digits after the dot are \\textit{0}." "" "Remember that the symbol \\textbf{'-'} doesn't mean anything in the standard syntax of the" "language, so there is no way to confuse for expressing a subtraction." "However, it exists an escape mode that allows writing arithmetic expressions" "between \\textbf{'\\$'} symbols, as formula under \\textit{LaTeX}. So, \\samp{\\$\\textit{left} \\textbf{-} \\textit{right}\\$}" "is equivalent to \\samp{sub(\\textit{left}, \\textit{right})}." heading "Equivalent admitted writing is \\samp{\\$a - b\\$}." numeric example "local a = 4.5;" "traceLine(a + \" - 2.8 = \" + sub(a, \"2.8\"));" "traceLine(a + \" - 2.5 = \" + sub(a, 2.5) + \" <- integer value\");"; function subString(text : string = "a sequence of characters", pos : int = "a position starting at 0, and relative to the beginning of the \\samp{text} string") : string = "Returns the sequence of characters passed to argument \\samp{text} after skipping" "the first \\samp{pos} characters." heading "Returns a substring, ignoring the first characters." string example "local sText = \"The lamp of experience\";" "traceLine(\"sText = '\" + sText + \"'\");" "traceLine(\"subString(sText, 4) = '\" + subString(sText, 4) + \"'\");"; function sup(left : double = "the first member", right : double = "the second member") : bool = "Compares two numbers and returns \\samp{true} if the first member given by" "argument \\samp{left} is strictly greater than the second member passed to" "argument \\samp{right}." "" "Don't use the operator \\samp{'>'} to compare numbers in the classical syntax of" "the interpreter: it only checks the lexicographical order. So, \\textit{'3 > 12'} is \\samp{true}." "However, it exists an escape mode that allows writing arithmetic comparisons" "between \\textbf{'\\$'} symbols, as formula under \\textit{LaTeX}. So, \\samp{\\$\\textit{left} \\textbf{>} \\textit{right}\\$}" "is equivalent to \\samp{inf(\\textit{left}, \\textit{right})}." heading "Equivalent admitted writing is \\samp{\\$a > b\\$}." numeric example "traceLine(\"sup(12, 3) = '\" + sup(12, 3) + \"'\");" "traceLine(\"12 > 3 = '\" + (12 > 3) + \"'\");"; function system(command : string = "the command interpreter will execute it") : string = "This function passes \\samp{command} to the command interpreter, which executes" "the string as an operating-system command. If \\samp{command} is empty, the" "function simply checks to see whether the command interpreter exists and returns" "an empty string. If an error occurs, it returns the corresponding error message." heading "Equivalent to the C function \\samp{system()}." system example "local sScript = getWorkingPath() + \"Documentation/System.cws\";" "local sCommand;" "if existFile(\"CodeWorker.exe\") set sCommand = \"CodeWorker.exe\";" "else set sCommand = \"Release\\\\CodeWorker\";" "set sCommand += \" -script \" + sScript;" "local sOutput = getWorkingPath() + \"Documentation/System.out\";" "traceLine(\"another \\\"CodeWorker\\\" is launched from here,\");" "local sError = system(sCommand + \" > \" + sOutput);" "if sError error(sError);" "traceLine(\"and executes the following script:\");" "traceLine(loadFile(sScript));" "traceLine(\"the trace was put into a file:\");" "traceLine(loadFile(sOutput));"; function toLowerString(text : string = "string to make in lower case") : string = "Converts each uppercase letter in \\samp{text} to lowercase, and returns the result. Other characters are not affected" heading "Converts a string to lowercase." string example "local sText = \"BE AFRAID ABOUT the \\\"WORLD COMPANY\\\"\";" "traceLine(\"toLowerString('\" + sText + \"') = '\" + toLowerString(sText) + \"'\");"; function toUpperString(text : string = "string to capitalize") : string = "Converts each lowercase letter in \\samp{text} to uppercase, and returns the result. Other characters are not affected." heading "Converts a string to uppercase." string example "local sText = \"THINK different, LEARN about other civilizations\";" "traceLine(\"toUpperString('\" + sText + \"') = '\" + toUpperString(sText) + \"'\");"; function translateString(patternFileName : script = "file name of the \\textit{pattern script}, which merges both the BNF syntax and the source code generation tags", this : tree = "the current node that will be accessed via \\textit{this} variable", inputString : string = "the input string to parse") : string [user] = "Parses the input string given by the argument \\samp{inputString}" "and returns the output string resulting of the translation," "following the instructions of the \\textit{pattern script} called \\samp{patternFileName}." "" "The pattern script merges the BNF syntax presented section \\ref{BNF syntax} with" "the source code generation syntax described section \\ref{source code generation}." heading "Performs a \\textit{source-to-source translation} or a \\textit{program transformation} on strings." interpreter, parsing, generation; function trimLeft(string : stringref = "variable that contains the characters to be trimmed") : int = "This function trims leading whitespace characters from the argument" "\\samp{string} and returns the number of characters that were removed. It" "removes newline, space, and tab characters." heading "Eliminates the leading whitespaces." string example "local sText = \" Spaces for sale! \";" "traceLine(\"trimLeft(sText) = '\" + trimLeft(sText) + \"'\");" deprecated trimLeftString "1.40"; function trimRight(string : stringref = "variable that contains the characters to be trimmed") : int = "This function trims trailing whitespace characters from the referenced argument" "\\samp{string} and returns the number of characters that were removed. It" "removes newline, space, and tab characters." heading "Eliminates the trailing whitespaces." string example "local sText = \" Spaces for sale! \";" "traceLine(\"trimRight(sText) = '\" + trimRight(sText) + \"'\");" deprecated trimRightString "1.40"; function trim(string : stringref = "variable that contains the characters to be trimmed") : int = "This function trims heading and trailing whitespace characters from the referenced" "argument \\samp{string} and returns the number of characters that were removed." "It removes newline, space, and tab characters." heading "Eliminates heading and trailing whitespaces." string example "local sText = \" Spaces for sale! \";" "traceLine(\"trim(sText) = '\" + trim(sText) + \"'\");" deprecated trimString "1.40"; function truncateAfterString(variable : treeref = "this parameter passes a string to handle and receives its truncation", text : string = "a sequence of characters to find into the value held by \\samp{variable}") : string = "This function:" "\\begin{itemize}" "\t\\item searches the sequence of characters passed to the argument \\samp{text}" "\t\tinto the string given by the parameter \\samp{variable}," "\t\\item assigns the substring standing on the right of \\samp{text} (so," "\t\t\\samp{text} is excluded) to the parameter \\samp{variable}," "\t\\item returns the left part of the substring that hasn't been assigned." "\\end{itemize}" "" "If the sequence of characters \\samp{text} isn't found into the value of" "\\samp{variable}, the function returns an empty string, and the variable doesn't" "change." heading "Special truncation of a string." string example "local sVariable = \"my tongue fell out with my teeth\";" "traceLine(\"sentence = '\" + sVariable + \"'\");" "local sResult = truncateAfterString(sVariable, \"out\");" "traceLine(\"Now, the variable is worth '\" + sVariable + \"'\");" "traceLine(\"And the result = '\" + sResult + \"'\");"; function truncateBeforeString(variable : treeref = "this parameter passes a string to handle and receives its truncation", text : string = "a sequence of characters to find into the value held by \\samp{variable}") : string = "This function:" "\\begin{itemize}" "\t\\item searches the sequence of characters passed to the argument \\samp{text}" "\t\tinto the string given by the parameter \\samp{variable}," "\t\\item assigns the substring standing on the left of \\samp{text} (so," "\t\t\\samp{text} is excluded) to the parameter \\samp{variable}," "\t\\item returns the right part of the substring that hasn't been assigned." "\\end{itemize}" "" "If the sequence of characters \\samp{text} isn't found into the value of" "\\samp{variable}, the function returns an empty string, and the variable doesn't" "change." heading "Special truncation of a string." string example "local sVariable = \"my tongue fell out with my teeth\";" "traceLine(\"sentence = '\" + sVariable + \"'\");" "local sResult = truncateBeforeString(sVariable, \"out\");" "traceLine(\"Now, the variable is worth '\" + sVariable + \"'\");" "traceLine(\"And the result = '\" + sResult + \"'\");"; function UUID() : string = "This function generates an UUID and returns it as a string. An UUID is a 128-bit" "universally unique id, used by Microsoft and being proposed as an internet standard." heading "Generates an UUID." standard example "traceLine(\"generation of an UUID = '\" + UUID() + \"'\");" "traceLine(\"generation of another one = '\" + UUID() + \"'\");"; function[parse] countInputCols() : int = "Determines the column number in the line where the parse cursor points to." heading "Column number in the line where the parse cursor points to." parsing see countInputLines; function[parse] countInputLines() : int = "Determines the current line number where the parse cursor points to." heading "Line number where the parse cursor points to." parsing; function[parse] getInputFilename() : string = "Returns the path of the input file being parsed." heading "Returns the path of the input file being parsed." parsing; function[parse] getLastReadChars(length : int = "number of characters to read") : string = "Returns the last \\samp{length} characters that have been read: it takes up to" "the number of characters passed to the argument \\samp{length}, characters that" "are preceding the current position of the input file." heading "Returns the last scanned characters." parsing example "// we move further into the input file" "readNextText(\"$\");" "traceLine(\"getLastReadChars(12) = '\" + getLastReadChars(12) + \"'\");" deprecated readLastChars "1.30"; function[parse] getInputLocation() : int = "Returns the current file position for reading the input stream." heading "Returns the current position in the input stream." parsing example "// we move further into the input file, just after the '$' character" "readNextText(\"$\");" "traceLine(\"The character following '$' is put at position \" + getInputLocation() + \", starting at 0\");" deprecated getLocation "3.7.1"; function[parse] lookAhead(text : string = "a sequence of characters to match") : bool = "Checks whether the next characters of the input stream match with the string" "passed to argument \\samp{text}. If so, the function returns \\samp{true} and" "the position of the input stream hasn't moved." heading "Scans the next characters without moving the input file position." parsing example "// we move further into the input file," "// just after 'C++: '" "readNextText(\"C++: \");" "local iPosition = getInputLocation();" "traceLine(\"lookAhead('/*') = '\" + lookAhead(\"/*\") + \"'\");" "if iPosition != getInputLocation() error(\"What did I say? The file position shouldn't have moved!\");" see readIfEqualTo, readIfEqualToIgnoreCase, readIfEqualToIdentifier; function[parse] peekChar() : string = "Returns the character found at the current input stream position, or an empty" "string if the end of file has been reached. If succeeded, the position of the" "input file \\textbf{doesn't move} to the next character." heading "Scans the current position without moving the file pointer." parsing example "setInputLocation(10);" "traceLine(\"at position 10, peekChar() = '\" + peekChar() + \"'\");" "if !equal(getInputLocation(), 10) error(\"the position of the input stream shouldn't have moved!\");" "traceLine(\"the position didn't change, peekChar() = '\" + peekChar() + \"' again\");" see getLastReadChars, readByte, readBytes, readChar, readChars, readCharAsInt, readIdentifier, readLine, readAdaString, readNumber, readPythonString, readString, readWord; function[parse] readAdaString(text : stringref = "a variable that will contain the string literal extracted from the input stream") : bool = "Reads a string literal surrounded by double quotes, and where the double-quote character has to be repeated." "" "If succeeded, the position moves just after the trailing double quote and the" "function returns \\samp{true}." heading "Reads a Ada-like string between double quotes." parsing; function[parse] readByte() : string = "Returns the byte read at the current file position, or an empty" "string if the end of file has been reached. If succeeded, the position of the" "input file moves to the next character." "" "The byte is returned as a 2-hexadecimal digit." heading "Reads the current character as a byte (hexadecimal representation of 2 digits)." parsing example "while !lookAhead(\":\") traceText(\"0x\" + readByte() + \" \");"; function[parse] readBytes(length : int = "number of bytes to read") : string = "Returns the sequence of \\samp{length} bytes read at the current file position, or an empty" "string if the end of file has been reached. If succeeded, the position of the" "input file moves just after." "" "The sequence of bytes is returned as a concatenation of 2-hexadecimal digits." heading "Reads a sequence of bytes, given the length." parsing example "traceLine(\"6 first bytes = 0x\" + readBytes(6));"; function[parse] readCChar() : string = "Returns the \\textbf{C-like} constant character read at the current file position." "A C-like character stands between single quotes and admits the escape character \\textbf{$\\backslash$r}." "If succeeded, the position of the input file moves to the trailing single quote." heading "Reads a C-like constant character." parsing; function[parse] readChar() : string = "Returns the character read at the current file position, or an empty" "string if the end of file has been reached. If succeeded, the position of the" "input file moves to the next character." heading "Reads the current character." parsing example "while !lookAhead(\":\") traceText(readChar());"; function[parse] readCharAsInt() : int = "Returns the ASCII value of character read at the current file position, or" "a negative number \\samp{-1} if the end of file has been reached. If succeeded," "the position of the input file moves to the next character." heading "Reads the current character as an integer." parsing example "traceLine(\"we move to the end of a line,\");" "readNextText(\"$\");" "traceLine(\"so carriage return or newline is \" + readCharAsInt());"; function[parse] readChars(length : int = "number of characters to read") : string = "Returns the sequence of \\samp{length} characters read at the current file position, or an empty" "string if the end of file has been reached. If succeeded, the position of the" "input file moves just after." heading "Reads a sequence of characters, given the length." parsing example "traceLine(\"6 first characters = '\" + readChars(6) + \"'\");"; function[parse] readIdentifier() : string = "Returns the \\textit{identifier} token read at the position of the input file," "or an empty string if it doesn't match." "" "An \\textit{identifier} begins with an alphabetical character (letter without" "accent) or an underscore and" "may be followed by any of them or by digits." heading "Reads an identifier." parsing example "traceLine(\"we jump just before the identifier:\");" "readNextText(\"identifier: \");" "traceLine(\"identifier = '\" + readIdentifier() + \"'\");"; function[parse] readIfEqualTo(text : string = "a sequence of characters to match") : bool = "Checks whether the next characters of the input stream match with the string" "passed to argument \\samp{text}. If so, the function returns \\samp{true} and" "the position of the input stream moves just after." heading "Reads a given string or returns false if it doesn't match." parsing example "// we move further into the input file," "// just after 'C++: '" "readNextText(\"C++: \");" "local iPosition = getInputLocation();" "traceLine(\"readIfEqualTo('/*') = '\" + readIfEqualTo(\"/*\") + \"'\");" "if iPosition == getInputLocation() error(\"The file position should have moved after '/*'!\");"; function[parse] readIfEqualToIgnoreCase(text : string = "a sequence of characters to match") : bool = "Checks whether the next characters of the input stream match with the string" "passed to argument \\samp{text}, ignoring the case. If so, the function returns" "\\samp{true} and the position of the input stream moves just after." heading "Reads a given string ignoring the case, or returns false if it doesn't match." parsing example "traceLine(\"readIfEqualToIgnoreCase('IDENTIFIER') = '\" + readIfEqualToIgnoreCase(\"IDENTIFIER\") + \"'\");" "if !readIfEqualTo(\":\") error(\"':' expected after matching with 'IDENTIFIER'!\");"; function[parse] readIfEqualToIdentifier(identifier : string = "an \\textit{identifier} is a string composed of letters and underscores ; digits are admitted too, except at the first place") : bool = "Checks whether the next characters of the input stream match with the" "\\textit{identifier} passed to argument. If so, the function returns" "\\samp{true} and the position of the input stream moves just after." "" "This function warrants that the character just before the beginning of the" "\\textit{identifier} into the input stream is neither a letter nor a digit nor" "an underscore, to assure that the identifier really starts at the current" "position of the input stream." heading "Reads a given identifier or returns false if it doesn't match." parsing example "traceLine(\"readIfEqualTo('ident') = '\" + readIfEqualTo(\"ident\") + \"'\");" "traceLine(\"readIfEqualTo('identifier') = '\" + readIfEqualTo(\"identifier\") + \"'\");"; function[parse] readLine(text : stringref = "a variable that will contain the line") : bool = "Reads the next line, starting at the current position of the input file, and" "puts it into parameter \\samp{text}. Characters \\textbf{'$\\backslash$r'} or" "\\textbf{'$\\backslash$n} are ignored, and the position points to the beginning" "of the next line or at the end of file if reached." "" "If succeeded, the function returns \\samp{true}." heading "Reads a line." parsing example "traceLine(\"Reads the 2 first lines:\");" "local sLine;" "if !readLine(sLine) error(\"line 1 expected, instead of end of file\");" "traceLine(\"\\t\" + sLine);" "if !readLine(sLine) error(\"line 2 expected, instead of end of file\");" "traceLine(\"\\t\" + sLine);"; function[parse] readNextText(text : string = "a sequence of characters to find") : bool = "Looks for the next occurrence of the expression given by argument \\samp{text}," "starting at the current position of the input file." "" "If succeeded, the position moves just after the expression given by \\samp{text}" "and the function returns \\samp{true}." heading "Searches the next occurence of a string." parsing example "traceLine(\"position of the input stream = \" + getInputLocation());" "if !readNextText(\"word:\") error(\"where is 'word:'?\");" "traceLine(\"we jump to 'word:', and the new position is \" + getInputLocation());" see readUptoJustOneChar; function[parse] readNumber(number : doubleref = "a variable that will contain the number read into the input stream") : bool = "Reads a number at the current position of the input stream, and puts it into" "the variable \\samp{number}. A number is either an integer or a floating-point" "representation as encountered ordinary." "" "If succeded, the position moves just after the token and the function returns" "\\samp{true}." heading "Reads a number." parsing example "traceLine(\"we jump just before the numbers:\");" "readNextText(\"numbers: \");" "local dNumber;" "if !readNumber(dNumber) error(\"integer expected!\");" "traceLine(\"integer = \" + dNumber);" "skipBlanks();" "if !readNumber(dNumber) error(\"double expected!\");" "traceLine(\"double = \" + dNumber);"; function[parse] readPythonString(text : stringref = "a variable that will contain the string literal extracted from the input stream") : bool = "Reads a string literal as defined in \\textit{Python}, a scripting language. Notably," "it accepts triple-quoted strings." "" "If succeeded, the position moves just after the trailing double quote and the" "function returns \\samp{true}." heading "Reads a Python-like string (triple-quoted strings recognized)." parsing; function[parse] readString(text : stringref = "a variable that will contain the string literal extracted from the input stream") : bool = "Reads a string literal surrounded by double quotes, and where escape sequences" "are written as presented in function \\samp{composeCLikeString()}" "(\\ref{composeCLikeString()}). The token is then put into the variable passed to" "argument \\samp{text}, without double quotes and after converting the escape" "sequences into their ASCII representation." "" "If succeeded, the position moves just after the trailing double quote and the" "function returns \\samp{true}." heading "Reads a string between double quotes." parsing example "traceLine(\"we jump just before the string:\");" "readNextText(\"string: \");" "local sText;" "if !readString(sText) error(\"constant string expected!\");" "traceLine(\"string = '\" + sText + \"'\");"; function[parse] readUptoJustOneChar(oneAmongChars : string = "a set of characters") : string = "Reads the input stream up to encountering a character that belongs to the" "parameter \\samp{oneAmongChars}, and returns the sequence of characters read." "" "The position of the input stream points to the first character that belongs to" "the parameter \\samp{oneAmongChars}. Calling \\samp{readChar()} or \\samp{readIfEqualTo()}" "just after allows determining what character, amongst those put into \\samp{oneAmongChars}," "was encountered first." heading "Searches the first occurence of a character amongst a set of characters and points on it." parsing example "traceLine(\"readUptoJustOneChar('$_:') = '\" + readUptoJustOneChar(\"$_:\") + \"'\");"; function[parse] readWord() : string = "Returns the \\textit{word} token read at the position of the input file," "or an empty string if it doesn't match." "" "\\CodeWorker\\ understands a \\textit{word} token as a sequence of alphabetical" "characters, including letters with an accent as existing in French or Germany, or" "underscores or digits." heading "Reads a word." parsing example "traceLine(\"we jump just before the word:\");" "readNextText(\"word: \");" "traceLine(\"readWord() = '\" + readWord() + \"'\");"; function[parse] skipBlanks() : bool = "Ignores all blank characters. The current file position moves to the first" "character that isn't a blank. A blank character is a space, a newline, a" "carriage return, a tabulation and, more generally, any ASCII character smaller" "that 32." heading "Skips all whitespaces and carriage returns." parsing example "readNextText(\"blanks: \");" "traceLine(\"we skip blank characters\");" "skipBlanks();" "traceText(\"now, we read the string token: \");" "local sText;" "if !readString(sText) error(\"constant string expected\");" "traceLine(\"'\" + sText + \"'\");" see skipEmptyCpp, skipEmptyCppExceptDoxygen, skipEmptyHTML, skipEmptyLaTeX; function[parse] skipEmptyCpp() : bool = "Ignores all blank characters and all C++/JAVA-like comments. The current file" "position moves to the first character that must be kept." heading "Skips blanks and C++-like comments." parsing example "readNextText(\"C++: \");" "traceLine(\"we skip C++ empty tokens\");" "skipEmptyCpp();" "traceText(\"now, we read the string token: \");" "local sText;" "if !readString(sText) error(\"constant string expected\");" "traceLine(\"'\" + sText + \"'\");"; function[parse] skipEmptyCppExceptDoxygen() : bool = "Ignores all blank characters and all C++/JAVA-like comments, except when the comment conforms to the \\textit{Doxygen} format. The current file" "position moves to the first character that must be kept." heading "Skips blanks and C++ comments, except comments like Doxygen." parsing example "readNextText(\"C++: \");" "traceLine(\"we skip C++ empty tokens, except Doxygen comments\");" "skipEmptyCppExceptDoxygen();" "traceText(\"now, we read the string token: \");" "local sText;" "if !readString(sText) error(\"constant string expected\");" "traceLine(\"'\" + sText + \"'\");";function[parse] skipEmptyHTML() : bool = "Ignores all blank characters and all HTML/XML-like comments. The current file" "position moves to the first character that must be kept." heading "Skips blanks and HTML-like comments." parsing example "readNextText(\"HTML: \");" "traceLine(\"we skip HTML empty tokens\");" "skipEmptyHTML();" "traceText(\"now, we read the string token: \");" "local sText;" "if !readString(sText) error(\"constant string expected\");" "traceLine(\"'\" + sText + \"'\");"; function[parse] skipEmptyLaTeX() : bool = "Ignores all LaTeX comments. A LaTeX comment is announced by the character" "\\samp{percent} and finishes at the end of the line. The current file" "position moves to the first character that must be kept." heading "Skips blanks and LaTeX-like comments." parsing example "readNextText(\"LaTeX: \");" "traceLine(\"we skip LaTeX comments\");" "skipEmptyLaTeX();" "traceText(\"now, we read the string token: \");" "local sText;" "if !readString(sText) error(\"constant string expected\");" "traceLine(\"'\" + sText + \"'\");"; function[generate] countOutputCols() : int = "Determines the column number in the line where the output stream cursor points to." heading "Column number in the line where the cursor points to." generation see countOutputLines; function[generate] countOutputLines() : int = "Determines the line number where the output stream cursor points to." heading "Line number where the cursor points to." generation; function[generate] decrementIndentLevel(level : int : 1 = "depth of indentation to remove") : bool = "Decrements the indentation level, used to indenting output files automatically while writing." "" "The function returns \\samp{false} if the \\textit{level} parameter is greater than" "the current indentation depth." "If the function returns \\samp{false}, the indentation level is worth zero and it disables" "the indent-mode." "Otherwise, each time a text will have to be written at the beginning of a line," "the line will be indented, depending on the indentation level." "" "Call the function \\samp{incrementIndentLevel()} to increase the indentation." heading "Decrements the indentation level, used to indenting output files automatically while writing." generation; function[generate] existFloatingLocation(key : string = "name of a floating position into the output stream", parent : bool = "while expanding a file, search into precedent markup area if this floating location exists or not") : bool = "Returns \\samp{true} if the \\textit{floating location}, whose name is passed to argument \\samp{key}, already exists." "" "If required (parameter \\samp{parent} set to \\samp{true}) and if the current output" "file is being expanded, the function searches the floating location in precedent" "visited markup areas." heading "Checks whether a floating location exists or not." generation example "Roger Rabbit@" "newFloatingLocation(\"Roger Rabbit\");" "@ doesn't like spinash@" "traceLine(\"Does the floating location 'Roger Rabbit' exists? '\" + existFloatingLocation(\"Roger Rabbit\", false) + \"'\");"; function[generate] getFloatingLocation(key : string = "name of an existing floating position into the output stream") : int = "Returns the position into the output stream attached to a \\textit{floating location}" "whose name is passed to argument \\samp{key}." "" "The function raises an error if the floating location doesn't exist or is present" "in a precedent markup area of a being-expanded file, but not in the current markup" "area." heading "Returns the position attached to a key of floating location." generation example "Roger Rabbit@" "newFloatingLocation(\"Roger Rabbit\");" "@ doesn't like spinash@" "traceLine(\"Position just after 'Roger Rabbit' is \" + getFloatingLocation(\"Roger Rabbit\"));" see allFloatingLocations, existFloatingLocation, getOutputLocation, newFloatingLocation, removeFloatingLocation, setFloatingLocation, setOutputLocation; function[generate] getLastWrittenChars(NbChars : int = "how many characters to ask for") : string = "Returns the last characters written in the output file, up to \\samp{NbChars}" "or less if the beginning of the file is encountered too early." heading "Recalls the last written characters." generation example "let's write some characters@" "traceLine(\"getLastWrittenChars(10) = '\" + getLastWrittenChars(10) + \"'\");"; function[generate] getMarkupKey() : string = "This function must be called into a pattern script that runs in \\textit{expansion mode}." "It returns the current markup key where code has to be expanded now." heading "Returns the key of the current markup." generation example "@" "if getMarkupKey() == \"examples\" {" "\t@A little example?@" "} else {" "\t@We are doing the LaTeX documentation in expansion mode!@" "\ttraceLine(\"current markup of the LaTeX documentation = '\" + getMarkupKey() + \"'\");" "}" deprecated getMarkerKey "2.14"; function[generate] getMarkupValue() : string = "This function must be called into a pattern script that runs in \\textit{expansion mode}." "It returns the current markup value, if any, put between tags '\\#\\#data\\#\\#' after declaring the markup key." heading "Returns the value attached to the current markup." generation input "... extension of C++/Java: implements a 'switch' on strings" "//##markup##\"switch(sText)\"" "//##data##" "//Product" "//RentalItem" "//Customer" "//RentalOrder" "//Figurine" "//Movie" "//DVD" "//VideoStore" "//##data##" "... next code" example expand "{" " int iHashCode = 0;" " std::string sKey = @coreString(getMarkupKey(), 7, 1)@;" " for (int i = 0; i < sKey.length(); i++) {" " unsigned char c = sKey[i];" " iHashCode = (31*iHashCode + (c%31)) % 64000000;" " }" " switch(iHashCode) {" "@" "local sData = getMarkupValue();" "while sData {" " local iIndex = sData.findString('\\n');" " if $iIndex < 0$ || !sData.startString(\"//\") error(\"syntax error\");" " local sKey = sData.midString(2, $iIndex - 2$);" " if sKey.endString('\\r') set sKey = sKey.rsubString(1);" " local iHashCode = 0;" " local i = 0;" " while $i < sKey.length()$ {" " local c = sKey.charAt(i);" " iHashCode = $(31*iHashCode + (c.charToInt()%31)) % 64000000$;" " increment(i);" " }" " @ case @iHashCode@: // \"@sKey@\"" "@" " setProtectedArea(\"case \\\"\" + sKey + \"\\\":\");" " set sData = sData.subString($iIndex + 1$);" "}" "@ default:" "@" "setProtectedArea(\"default:\");" "@ }" "}" "@" see getMarkupKey; function[generate] getOutputFilename() : string = "Returns the path of the output file being generated." heading "Returns the path of the output file being generated." generation; function[generate] getOutputLocation() : int = "Returns the current file position for writing to the output stream." heading "Returns the current output file position." generation example "I write 22 characters.@" "traceLine(\"Current position to the output stream = \" + getOutputLocation());"; function[generate] getProtectedArea(protection : string = "unique ID of a protected area") : string = "Returns the content of the protected area whose name is given by parameter" "\\samp{protection}. If the protected area wasn't found into the ancient version" "of the output stream, and if it hasn't been put yet via \\samp{setProtectedArea}" "into the output stream, it returns an empty string." heading "Returns the content of a given protected area, if not put into the file yet." generation example "@" "setProtectedArea(\"keep this code for me, please!\");" "if !getProtectedArea(\"keep this code for me, please!\") {" "\ttraceLine(\"you have never populated the protected area!\");" "}"; function[generate] getProtectedAreaKeys(keys : tree = "it will contain keys of all protected areas that were found into the output stream before the generation") : int = "Looks for all protected areas that were found into the output stream before processing" "the source code generation and puts their keys into the well-named argument \\samp{keys}." "" "Note: \\samp{keys} stores the ID of protected areas in the lexicographical order." "" "The function returns how many protected areas were found into the output stream." "Both key and value of items are worth the protected area key. If the list wasn't" "declared as \\textit{local} or \\textit{global} or as belonging to \\samp{this}," "a negative value is returned." heading "Returns the list of all protected area keys found into the file before generation." generation input "My first protected area:" "//##protect##\"hand-typed code\"" "I don't want to loose this portion of text" "after another generation!" "//##protect##\"hand-typed code\"" "My second protected area:" "//##protect##\"don't forget me, please!\"" "This portion of text is also very important." "//##protect##\"don't forget me, please!\"" "Now, you can erase text, I don't care." example "My first protected area:" "@" "local listOfKeys;" "local iNbKeys = getProtectedAreaKeys(listOfKeys);" "traceLine(\"Number of preserved area at the beginning = \" + iNbKeys + \":\");" "foreach i in listOfKeys traceLine(\"\t'\" + i + \"'\");" "setProtectedArea(\"hand-typed code\");" "traceLine(\"after removing and setting protected areas,\");" "traceLine(\"the function behaves the same\");" "removeProtectedArea(\"don't forget me, please!\");" "if $getProtectedAreaKeys(listOfKeys) != 2$ error(\"bad behavior\");" "@Now, you can erase text, I don't care." "@"; function[generate] indentText(mode : string = "type of text to indent") : bool = "Indents the output stream, conforming to a given type of file, to choose amongst:" "\\begin{itemize}" "\t\\item \\textbf{C++}" "\t\\item \\textbf{JAVA}" "\\end{itemize}" "More format will be recognized in the future." "" "The function returns \\samp{true} if the output stream needed to be indented," "meaning that it has changed after processing the indentation." "" "Be careful that if you are expanding a file, only the expanded area will be" "indented. In that case, it is better to use \\samp{indentFile} once the generation" "has completed." heading "Indents the output stream." generation example "int f(int i) {" "switch (i) {" "case 1:" "g(i + 1);" "break;" "case 2:" "case 3:" "if (i == 2) {" "h();" "}" "g(i - 1);" "break;" "\t\t\t}" "}@" "if indentText(\"C++\") traceLine(\"the output stream wasn't indented correctly\");"; function[generate] newFloatingLocation(key : string = "name of a floating position into the output stream") : bool = "Assigns the current position into the output stream to a \\textit{floating location}" "whose name is passed to argument \\samp{key}. If the \\textit{floating location}" "already exists, its position is updated." heading "Assigns the current file pointer to a floating location." generation example "Roger Rabbit@" "newFloatingLocation(\"Roger Rabbit\");" "@ doesn't like spinash@" "traceLine(\"Position just after 'Roger Rabbit' is \" + getFloatingLocation(\"Roger Rabbit\"));" see newFloatingLocation; function[generate] remainingProtectedAreas(keys : tree = "it will contain keys of all protected areas that haven't been placed into the output stream yet") : int = "Looks for all protected areas that haven't been placed into the output stream yet" "and puts their keys into the well-named argument \\samp{keys}. Both key and value" "of items are worth the protected area key." "" "The list is sorted in the lexicographical order rather than the order of entrance." "" "The function returns how many protected areas are waiting for being put into the" "output stream. If the variable \\samp{keys} wasn't declared (\\textit{local} or" "\\textit{global} or as an attribute of \\samp{this}), \samp{-1} is returned." heading "Returns the list of all protected area keys remaining to put into the file." generation input "My first protected area:" "//##protect##\"hand-typed code\"" "I don't want to loose this portion of text" "after another generation!" "//##protect##\"hand-typed code\"" "My second protected area:" "//##protect##\"don't forget me, please!\"" "This portion of text is also very important." "//##protect##\"don't forget me, please!\"" "Now, you can erase text, I don't care." example "My first protected area:" "@" "local listOfKeys;" "local iHowMany = remainingProtectedAreas(listOfKeys);" "traceLine(\"It remains \" + iHowMany + \" keys to set into the output file:\");" "foreach i in listOfKeys traceLine(\"\t'\" + i + \"'\");" "traceLine(\"writing of protected area 'hand-typed code'\");" "setProtectedArea(\"hand-typed code\");" "@My second protected area:" "@" "set iHowMany = remainingProtectedAreas(listOfKeys);" "traceLine(\"It remains \" + iHowMany + \" keys to set into the output file:\");" "foreach i in listOfKeys traceLine(\"\t'\" + i + \"'\");" "traceLine(\"writing of protected area '\" + listOfKeys#front + \"'\");" "setProtectedArea(listOfKeys#front);" "@Now, you can erase text, I don't care." "@" "set iHowMany = remainingProtectedAreas(listOfKeys);" "if $iHowMany != 0$ error(\"shouldn't remain any protected area!\");" "traceLine(\"It doesn't remain any area to set into the output file\");"; function[generate] removeFloatingLocation(key : string = "name of an existing floating position into the output stream") : int = "Removes the \\textit{floating location} attached to \\samp{key} and returns its position." "If the floating location belongs to a parent output stream, it is removed from the parent." "" "The function returns a negative integer if the floating location doesn't exist." heading "Removes the floating location attached to a given key." generation; function[generate] removeProtectedArea(protectedAreaName : string = "name of the protected area to remove") : bool = "Removes the protected area whose name is passed to the argument \\samp{protectedAreaName}" "from the list of protected areas that were found into the output file before the" "generation and that aren't been put into the output stream yet via the \\samp{setProtectedArea()}" "or \\samp{populateProtectedArea()} functions." heading "Removes a protected area remaining to put into the file." generation input "My first protected area:" "//##protect##\"hand-typed code\"" "I don't want to loose this portion of text" "after another generation!" "//##protect##\"hand-typed code\"" "My second protected area:" "//##protect##\"don't forget me, please!\"" "This portion of text is also very important." "//##protect##\"don't forget me, please!\"" "Now, you can erase text, I don't care." example "Finally, I have changed my mind and I keep only one protected area:" "@" "local listOfKeys;" "local iHowMany = remainingProtectedAreas(listOfKeys);" "traceLine(\"It remains \" + iHowMany + \" keys to set into the output file:\");" "foreach i in listOfKeys traceLine(\"\t'\" + i + \"'\");" "traceLine(\"Protected area 'don't forget me, please!' is removed\");" "removeProtectedArea(\"don't forget me, please!\");" "set iHowMany = remainingProtectedAreas(listOfKeys);" "traceLine(\"It remains \" + iHowMany + \" keys to set into the output file:\");" "foreach i in listOfKeys traceLine(\"\t'\" + i + \"'\");" "traceLine(\"writing of protected area 'hand-typed code'\");" "setProtectedArea(\"hand-typed code\");"; method size is getArraySize; method length is lengthString; method empty is isEmpty; method replaceString is replaceString(text); method findElement is findElement(variable);