ScriptBasic development auxilliarry files

by Peter Verhas

Table of Contents

[Contents]

1. Introduction

This documentation describes some of the auxiliary files that were created and are used in the ScriptBasic project. These are UNIX shell scripts, Windows NT command files, Perl programs that ease the maintenance of the developers and automate such tasks as creating a new build.

It is not the intention of the creator of this document to have anyone to read this documentation throughly and to learn its content. This is rather a reference book that helps to understand, which file implements which tool and how to invoke them.

But I do not try to prevent you to read it in case you want.

[Contents]

2. Directory Structure

ScriptBasic is usually developed on a Windows 2000 Professional workstation. Linux is used to test the portability. Files are uploaded via SMB and GNU command line tools are used to build the binaries.

The source of ScriptBasic on the development station is `\MyProjects\sb\source'.

The actual location of the source code root should not affect the building of the source.

The directory structure of the source under this directory is the following:

--- ScriptBasic core C source files,
    def files, command files,
    shell scripts, Perl scripts

commands --- all C source files that implement ScriptBasic commands deb --- Debian package files deb/scriba --- temporary directory that is filled by the script mkdeb.sh when creating a Debian package deb/DEBIAN --- Debian package script files (source, these are copied into deb/scriba when building the package) examples --- example BASIC program files extensions --- module extension files extensions/berkeley_db --- Berkeley DB module extensions/cgi --- CGI module extensions/cio --- Console Input Output module only for Windows NT extensions/gd --- GD module to generate PNG graphics extensions/hash --- hash module extensions/japi --- Interface module to the graphics features of the Java AWT extensions/md5 --- md5 module extensions/mt --- Multi-thread support module with session, locks and global variables extensions/mysql --- MySQL interface extensions/noprint --- Example module that switches off printing extensions/nt --- Special Windows NT module extensions/re --- Regular Expression module extensions/tools --- Tools module extensions/trial --- Example module mainly for test purposes extensions/ux --- Special UNIX module extensions/zlib --- zlib compression module filesdoc --- auxilliary source file documentations gif --- banner.gif file html --- web page HTML source using the jamal preprocessor and ssplit.pl html/texi --- texi.jam documentation source files. Should be processed with jamal.pl first to get texi include --- BASIC include files for the modules preproc --- a sample preprocessor. Note that preprocessor is experimental and will change in future. test --- test programs tools --- tool programs variations --- different variations of ScriptBasic variations/apacmodu --- Apache module version of ScriptBasic. This variation was never developed and this thread of the development is stopped. Instead the httpd variation should be used together with the Apache web server. variations/httpd --- Standalone web server variation. variations/standalone --- Standalone version that allows BASIC compile to C and link together with the runtime environment. variations/standard --- The standard command line variation. variations/win32dll --- Win32dll version that allows embedding of the program into WIN32 applications. This thread of the development was stopped and is not supported anymore. There are plans to support similar variations. variations/winisapi --- Variation that executes web programs as ISAPI application. This version is not supported any more. Laster it may revitalized.

[Contents]

3. BASIC programs

In this chapter I list the BASIC programs that are used as utility programs. Note that the BASIC samples are documented in a separate document.

[Contents]

3.1. heber.bas

This BASIC program is an external preprocessor for ScriptBasic. This demonstrates how simple to write an external preprocessor, as it can even be done in BASIC itself.

This small program converts HTML Embedded BASIC (heb) into pure BASIC. HEB is something like PHP or Microsoft ASP BASIC, where the BASIC code is put between HTML code. This small preprocessor converts the heb file taking all HTML that is outside of the BASIC code and putting it into print statements, and all BASIC code that is inside HTML code putting outside.

This is a sample implementation and has significant shortages. In case the BASIC program inside some string has <% or >% (which is not likely though possible) the preprocessor crates false code.

The souce code of the file `heber.bas' is:

#!/usr/bin/scriba
' Sample ScriptBasic external preprocessor
'
' This preprocessor converts heb (Html Embedded Basic) files to BASIC
'
' You can embed basic code between
'                          <% basic program %>
' which is executed
'
' <%= basic expression %>
'
cmdlin = command()
split cmdlin by " " to InputFile,OutputFile
open InputFile for input as 1
InputText = input(lof(1),1)
close 1
if Mid$(InputText,1,3) = "#!/" then
  FirstLineLength = InStr(InputText,"\n")
  InputText = Mid$(InputText,FirstLineLength+1)
end if
' import the heb.bas file to get access to the cgi functions
OutputText = "import heb.bas\n"

while len(InputText) > 0 StringPosition = InStr(InputText,"<%") if not IsDefined(StringPosition) then goto Finished AppendString = Mid$(InputText,1,StringPosition-1) InputText = Mid$(InputText,StringPosition+2) if len(AppendString) > 0 Then AppendString = Replace(AppendString,"\\","\\\\") AppendString = Replace(AppendString,"\"","\\\"") OutputText = OutputText & "print \"\"\"" & AppendString & "\"\"\"\n" end if StringPosition = InStr(InputText,"%>") if not IsDefined(StringPosition) then error(1) AppendString = Mid$(InputText,1,StringPosition-1) InputText = Mid$(InputText,StringPosition+2) if len(AppendString) > 0 then if Mid$(AppendString,1,1) = "=" then AppendString = "print " & Mid$(AppendString,2) end if OutputText = OutputText & AppendString & "\n" end if wend

Finished:

if len(InputText) > 0 then InputText = Replace(InputText,"\"","\\\"") OutputText = OutputText & "print \"\"\"" & InputText & "\"\"\"\n" end if

open OutputFile for output as 1 print#1,OutputText close 1

[Contents]

3.2. newbuild.bas Start a new build

Whenever the development of a new build is started this program has to be executed. This will increase the build number stored in the file T<build.txt> and also creates the file `buildnum.c'

The souce code of the file `newbuild.bas' is:

import t.bas
import re.bas

fn = 0 open "build.txt" for input as fn line input#fn, BuildNumber close fn ' the terminating \n does not disturb, because ' we convert it to number on the fly BuildNumber = BuildNumber + 1

print "The next build is: ",BuildNumber

fn = 0 open "build.txt" for output as fn print#fn,BuildNumber

close fn

fn = 0 open "buildnum.h" for output as fn

print#fn,"""/* FILE: buildnum.h

This file was automatically created by newbuild.bas Each time a new build is to be released this program is ran and it increments the build number.

*/ #ifndef SCRIPTBASIC_BUILD #define SCRIPTBASIC_BUILD """,BuildNumber,""" #endif

""" close fn

fn = 0 open "buildnum.c" for output as fn print#fn,"""/* FILE: buildnum.c HEADER: buildnum.h This file was automatically created by newbuild.bas Each time a new build is to be released this program is ran and it increments the build number. TO_HEADER:

#ifndef SCRIPTBASIC_BUILD #define SCRIPTBASIC_BUILD """,BuildNumber,""" #endif */ """

close fn

fn = 0 s = t::LoadString("pack.cmd") re::m( s,"(.*)SET BUILD=([0-9]+)(.*)") s = re::$(1) & "SET BUILD=" & BuildNumber & re::$(3) t::SaveString "pack.cmd",s

[Contents]

3.3. cbbfc.bas Convert Basic Binary Format Command

This program reads a ScriptBasic binary format file and replaces the leading interpreter specification by the one specified by the user.

For example a program was developed on a machine having scriba in the directory /usr/bin. The first line of the bbf file is then #!/usr/bin/scriba To run this bbf file without having the original source file on a machine having scriba on /usr/local/bin this first line has to be replaced. This is not a simple task, because the bbf file is binary.

The souce code of the file `cbbfc.bas' is:

#!/usr/bin/scriba
' FILE: cbbfc.bas
'
' Convert Basic Binary Format Command
'
' This program reads a ScriptBasic binary format file
' and replaces the leading interpreter specification
' by the one specified by the user.
'
' For example a program was developed on a machine having
' scriba in the directory /usr/bin. The first line of the
' bbf file is then #!/usr/bin/scriba
' To run this bbf file without having the original source file
' on a machine having scriba on /usr/local/bin this first line
' has to be replaced. This is not a simple task, because
' the bbf file is binary

cmdlin = command()

split cmdlin by " " to FileName,Interpreter

on error goto usage

open FileName for input as 1 binmode 1 File$ = input(lof(1),1) close 1

if left(File$,1) = "#" then i = 1 while i < len(File$) and mid(File$,i,1) <> "\n" i = i+1 wend if mid(File$,i,1) = "\n" then File$ = "#!" & Interpreter & mid(File$,i,len(File$)) end if open FileName for output as 1 binmode 1 print#1,File$ close 1 end if stop usage: print """Usage:

cbbfc.bas program.bbf /usr/bin/scriba """

[Contents]

4. Batch (.CMD) files

These command files can be used to maintain the source files under Windows NT.

[Contents]

4.1. mkdoc.cmd

Create the on-line documentation

This batch file creates the on-line documentations

The souce code of the file `mkdoc.cmd' is:

@echo off
echo Creating on-line source documentation.
echo Each C source file contains the documentation
echo of the source is a special format.
echo esd2html.pl extracts the HTML format documentation
echo files from the source files.
perl esd2html.pl scriba.sdd
perl esd2html.pl modules.sdd
perl esd2html.pl files.sdd
echo ---------------------------------------------------
echo Now you should have all files to run
echo the C compiler.
echo
echo Good luck.

[Contents]

4.2. mkcdoc.cmd

Create the command reference

This batch file creates the `command.html' file that contains the user reference documentation of the BASIC commands. The source of the documentation is maintained on the C source files that are in the directory `commands'. This way the reference documentation of a BASIC command is maintained together with the actual C code implementing the command.

The souce code of the file `mkcdoc.cmd' is:

perl mkcdoc.pl

[Contents]

4.3. install.cmd

This command file copies all the generated and documentation files into the root directory `\ScriptBasic' that belong to the final installation set under Win32.

The souce code of the file `install.cmd' is:

@echo off
rmdir /s /q \ScriptBasic
mkdir \ScriptBasic
mkdir \ScriptBasic\bin
mkdir \ScriptBasic\doc
mkdir \ScriptBasic\doc\slides
mkdir \ScriptBasic\include
mkdir \ScriptBasic\modules
xcopy /q license.txt \ScriptBasic
xcopy /q *.exe \ScriptBasic\bin
copy scriba.dll \ScriptBasic\bin
copy scriba.conf \ScriptBasic\bin
copy scriba.conf.lsp \ScriptBasic
xcopy /q *.dll \ScriptBasic\modules
del \ScriptBasic\modules\scriba.dll
xcopy /q include \ScriptBasic\include

[Contents]

4.4. makerrs.cmd

This command file creates the files `errcodes.c' and `errcodes.h' file from the file T<errors.def>. The file T<errors.def> contains the error messages in an easy to maintain and easy to read format. This bacth file using the Perl script `generrh.pl' creates the C source files for the error codes.

The souce code of the file `makerrs.cmd' is:

perl generrh.pl
perl headerer.pl errcodes.c

[Contents]

4.5. mkweb.cmd

This command file compiles the ScriptBasic web content. It has to be executed from the source root directory.

The souce code of the file `mkweb.cmd' is:

cd html
perl ..\ssplit.pl source.txt
perl ..\mkweb.pl
del *.jam
del *.jim
cd ..

[Contents]

4.6. mksyntax.cmd

This command file runs the Perl script `syntaxer.pl' to create the `syntax.c' file from the file `syntax.def'

The syntax definition of the BASIC language is defined in an easy to maintain text file named `syntax.def' and a Perl script `syntaxer.pl' creates the human-unreadable C source file from it that contains all the tables that drive the syntax analyzer.

The souce code of the file `mksyntax.cmd' is:

@echo off
echo Creating syntax.c from the source file syntax.def.
echo Syntax.c contains the tables that hold the syntax
echo definition of the BASIC commands.
perl syntaxer.pl

[Contents]

4.7. precompile.cmd

This command file performs all the tasks that are needed before the C compilation of ScriptBasic can start. This is

The souce code of the file `precompile.cmd' is:

@echo off
perl syntaxer.pl
perl generrh.pl
for %%i in (*.c) do perl headerer.pl %%i

[Contents]

4.8. pack.cmd

This command file compiles all the ScriptBasic package for the Windows NT platform, copies the resulting files to the `\ScriptBasic' directory and creates the distribution ZIP files.

Before releasing a new release this batch file has to be edited to alter the %BUILD% variable for the actual build.

The souce code of the file `pack.cmd ' is:

@echo off
nmake -f Makefile.nt
perl mkcdoc.pl
rm -rf ..\html\texi\*
call mkath

rmdir /s /q \ScriptBasic mkdir \ScriptBasic mkdir \ScriptBasic\bin mkdir \ScriptBasic\doc mkdir \ScriptBasic\doc\slides mkdir \ScriptBasic\include mkdir \ScriptBasic\modules xcopy /q /y license.txt \ScriptBasic xcopy /q /y *.exe \ScriptBasic\bin copy /y scriba.dll \ScriptBasic\bin xcopy /q /y *.dll \ScriptBasic\modules del \ScriptBasic\modules\scriba.dll xcopy /q /y include \ScriptBasic\include

xcopy /q /y ..\html\texi\*.chm \ScriptBasic\doc xcopy /q /y ..\html\texi\*.pdf \ScriptBasic\doc

SET BUILD=27 del ..\download\scriba-v10b%BUILD%-source.zip wzzip -a -r -P ..\download\scriba-v10b%BUILD%-source.zip @source.ziplist -x@source.exziplist del ..\download\scriba-v10b%BUILD%-libs.zip wzzip -a -r -P ..\download\scriba-v10b%BUILD%-libs.zip extensions\*.lib extensions\*.dll del ..\download\scriba-v10b%BUILD%-bin.zip wzzip -a -r -P ..\download\scriba-v10b%BUILD%-bin.zip \ScriptBasic\* del ..\download\pdf-v10b%BUILD%.zip wzzip -a ..\download\pdf-v10b%BUILD%.zip ..\html\texi\*.pdf del ..\download\text-v10b%BUILD%.zip wzzip -a ..\download\text-v10b%BUILD%.zip ..\html\texi\*.texi del ..\download\chm-v10b%BUILD%.zip wzzip -a ..\download\chm-v10b%BUILD%.zip ..\html\texi\*.chm del ..\download\html-v10b%BUILD%.zip wzzip -a ..\download\html-v10b%BUILD%.zip ..\html\texi\*.html call mkweb

[Contents]

4.9. mksamples.cms

This command file converts a .texi.jam file in the directory `./html/texi' using `jamal.pl' to .texi files and then converts it using the Perl script t2h.pl to html files into the directory `../html/texi'. The command also starts TeX to convert the texi file to dvi, ps and pdf as well as the Microsoft hhc help compiler to result compiled html file (chm).

Running Jamal may result several .bas files in the temporary directory. This command file puts them into a tgz archive and copies to the directory `html/texi'.

The command file deletes all auxiliary files when done.

The script has to be executed from the source directory and should get a single argument that is the name of the documentation file without any extension. For example

call mkth samplebas

This command is similar to mkth.com except that this file also cares the resulting BASIC sample files.

[Contents]

4.10. mkth.cmd

This command file converts a .texi.jam files in the directory `./html/texi' using `jamal.pl' to .texi files and then converts it using the Perl script t2h.pl to html files into the directory `../html/texi'. The command also starts TeX to convert the texi file to dvi, ps and pdf as well as the Microsoft hhc help compiler to result compiled html file (chm). The command file deletes all auxiliary files when done.

The script has to be executed from the source directory and should get a single argument that is the name of the documentation file without any extension. For example

call mkth auxfiles

will convert the file `auxfiles.texi.jam' (the source file for this text) to `auxfiles_toc.html' and `auxfiles_xxx.html' files in the appropriate html directory.

The command file mkath.cmd calls this command file for each .texi.jam file.

The souce code of the file `mkth.cmd' is:

cd html\texi
mkdir tmp
cd tmp

perl ..\..\..\jamal.pl ..\%1.texi.jam %1.texi perl ..\..\..\t2h.pl %1.texi %1 mkdir ..\..\..\..\html\texi\

copy %1.texi ..\..\..\..\html\texi\ copy %1.rtf ..\..\..\..\html\texi\

gzip %1.rtf copy %1.rtf.gz ..\..\..\..\html\texi\

copy %1.html ..\..\..\..\html\texi\ gzip %1.html copy %1.html.gz ..\..\..\..\html\texi\

hhc %1.hhp copy %1.chm ..\..\..\..\html\texi\

tar cfz %1.html.tgz *.html copy %1.html.tgz ..\..\..\..\html\texi\

rm -rf ..\..\..\..\html\texi\%1 mkdir ..\..\..\..\html\texi\%1 copy *.html ..\..\..\..\html\texi\%1\

tex -silent %1.texi tex -silent %1.texi dvips %1.dvi gzip %1.ps dvipdfm %1.dvi copy %1.ps.gz ..\..\..\..\html\texi\ copy %1.pdf ..\..\..\..\html\texi\ gzip %1.pdf copy %1.pdf.gz ..\..\..\..\html\texi\ gzip %1.texi copy %1.texi.gz ..\..\..\..\html\texi\

cd .. rm -rf tmp cd ..\..

[Contents]

4.11. mkthl.cmd

This command file should be used the same way as mkth.cmd. This command file performs only minimal compilation, running only `jamal.pl' and `t2h.pl' on the documentation file, but does not run TeX or dviXX or Microsoft help compiler.

This command file is to be used instead of mkth.cmd when editing the documentation and there is a need for a fast proof reading, but you do not need all versions of the document.

[Contents]

4.12. mkath.cmd

This is a simple command script that calls mkth.cmd for each .texi.jam file that is in the `./html/texi' directory.

The souce code of the file `mkath.cmd' is:

call mkth devguide
call mkth ug
call mkth auxfiles
call mkth source
call mkth eszterengine
call mkth docudoc
call mkth mod_cio
call mkth mod_cgi
call mkth mod_mt
call mkth mod_md5
call mkth mod_nt
call mkth mod_re
call mkth mod_zlib
call mkth mod_ux
call mkth mod_tools
call mkth mod_hash
call mkth mod_bdb
call mkth mod_mysql
call mkth mod_gd
call prep_dbg
call mksamples samplebas
call mksamples regtest

[Contents]

5. C source files

The C source files are documented in a separate document in more detail that the scope of this document.

[Contents]

6. Configuration files

Configuration files in the source package hold default values that are shipped with the program. Each "setuper" has to edit the configuration file according to the local needs and recompile it using `cftc.exe' or `cftc' (UNIX).

There are two configuration files currently in the source:

[Contents]

7. Definition files

This chapter lists the definition files. These files are used to have a maintainable format instead of complex C syntax. The definition files have simple syntax and are converted into C source file.

[Contents]

7.1. errors.def

This file contains the error constant definitions. This file is converted to C source file using the Perl script `generrh.pl'

The source code of the file is not included in this documentation because the file itself is too long for the purpose.

[Contents]

7.2. syntax.def

This file contains the syntax definition of the language ScriptBasic. This syntax definition is converted to C source file containing syntax definition tables using the Perl script `syntaxer.pl'.

The souce code of the file `syntax.def' is:

# lines starting with # are comments
# spaces before # is not allowed for good reason
# lines starting with % start a new session
# empty lines are ignored

%FILE syntax #%HFILE syntax.h #%CFILE syntax.c

# Define the commands here. # A command can be redefined, both forms will have the same op code # be sure that they accept the same parameters. # # You can use terminals between ' characters, like 'function' which means # the characters 'f' 'u' 'n' 'c' 't' 'i' 'o' and 'n'. # You can also use non terminal symbols. These are: # # thisfn the name of the currently defined function or procedure # expression an expression # expression_list list of expressions separated by commas # string a string constant # integer an integer value # nl end of line ('\n' character) # tab tab character ('\t' character) # float a numeric value # symbol a symbol (name space modifications are applied) # absolute_symbol an absolute symbol # name_space an absolute symbol that sets the name space # end_name_space end a name space # lval a left value # lval_list a left value list separated by commas # local_start star a local scope (see the defintion of FUNCTION) # local_end end of local scope # local local variable # local_list list of local variables # function a function or procedure name where it is defined (usually after the keyword function) # arg_num placeholder to store the number of arguments # label a label used in goto # label_def a label when defined # cname constant name # cval constant value corresponding to constant value # go_back # go_forward # come_back # come_forward # * star character # noexec no code is generated from the line

%COMMANDS EMPTY: nl noexec

MODULE: 'module' name_space nl noexec ENDMODULE: 'end' 'module' end_name_space nl noexec

LOCAL: 'local' local_list nl noexec

STOP: 'stop' nl END: 'end' nl

OPTION: 'option' absolute_symbol expression # Compare ! sbCaseSensitive 0x00000000 ! sbCaseInsensitive 0x00000001 ! sbMathErrDiv 0x00000001 ! sbMathErrUndef 0x00000002 ! sbMathErrUndefCompare 0x00000004

# note that FLET and LET have similar syntax and an FLET would match the syntax defintion of # LET Therefore FLET should preceede LET LABEL: label_def ':' noexec CONST: 'const' cname '=' cval nl noexec GCONST: 'global' 'const' gcname '=' cval nl noexec VAR: 'var' cname nl noexec FPRINTNL: 'printnl' '#' expression nl FPRINT: 'print' '#' expression ',' expression_list nl PRINTNL: 'printnl' nl PRINTNL: 'print' nl PRINT: 'print' expression_list nl FUNCTIONARG: 'function' function '(' local_start local_list arg_num ')' go_forward(FUNCTION) nl FUNCTION: 'function' function nl local_start arg_num go_forward(FUNCTION) EXITFUNC: 'exit' 'function' nl ENDFUNC: 'end' 'function' local_end come_forward(FUNCTION) nl SUBARG: 'sub' function '(' local_start local_list arg_num ')' go_forward(SUB) nl SUB: 'sub' function nl local_start arg_num go_forward(SUB) EXITSUB: 'exit' 'sub' nl ENDSUB: 'end' 'sub' local_end come_forward(SUB) nl CALL/CALL: 'call' expression nl ICALL: 'icall' expression_list nl FLET: thisfn '=' expression nl LET/LET: lval '=' expression nl LETM: lval '-=' expression nl LETP: lval '+=' expression nl LETS: lval '*=' expression nl LETD: lval '/=' expression nl LETI: lval '\=' expression nl LETC: lval '&=' expression nl REF: 'ref' lval '=' lval nl # DO NOT move this syntax definition before LET NLABEL: label_def noexec GOTO: 'goto' label nl GOTO: 'go' 'to' label nl GOSUB: 'gosub' label nl GOSUB: 'go' 'sub' label nl RETURNC: 'return' nl

CUNDEF: 'undef' lval_list nl CBYVAL: 'byval' lval_list nl

ONERRORGOTONULL: 'on' 'error' 'goto' 'null' nl ONERRORGOTO: 'on' 'error' 'goto' label nl ONERRORRESUMENEXT: 'on' 'error' 'resume' 'next' nl ONERRORRESUMELABEL: 'on' 'error' 'resume' label nl RESUME: 'resume' nl RESUMENEXT: 'resume' 'next' nl RESUMELABEL: 'resume' label nl CERROR: 'error' expression nl

# the different looping statements that are common in BASIC # the ordering of the defintion *IS* important WHILE: 'while' expression go_forward(WHILE) come_back(WHILE) nl WEND: 'wend' go_back(WHILE) come_forward(WHILE) nl DOWHILE: 'do' 'while' expression go_forward(DO) come_back(DO) nl DOUNTIL: 'do' 'until' expression go_forward(DO) come_back(DO) nl LOOPWHILE: 'loop' 'while' expression go_back(LOOP) come_forward(LOOP) nl LOOPUNTIL: 'loop' 'until' expression go_back(LOOP) come_forward(LOOP) nl UNTIL: 'until' expression go_back(REPEAT) come_forward(REPEAT) nl LOOP: 'loop' go_back(DO) come_forward(DO) nl REPEAT: 'repeat' go_forward(REPEAT) come_back(REPEAT) nl DO: 'do' go_forward(LOOP) come_back(LOOP) nl

# This is a bit tricky and allows some weird instructions if the user is aware # how this loop construct is defined. Fortunately there is little chanche that # a programming mistake goes unnotices by this. FOR: 'for' lval '=' expression come_back(FORTO) FORTO: 'to' expression go_back(FORTO) go_forward(FOR) come_back(FOR) FORSTEP: 'step' expression nl

# we allow a symbol after the next, but it does not help to recongnise nexting errors NEXTI: 'next' symbol go_back(FOR) come_forward(FOR) nl NEXT: 'next' go_back(FOR) come_forward(FOR) nl

# for come and go we do not need to distinguish between IF and ELSIF IF/IF: 'if' * expression 'then' go_forward(IF) nl ELSIF: 'elseif' * expression 'then' come_forward(IF) go_forward(IF) nl ELSIF: 'else' 'if' * expression 'then' come_forward(IF) go_forward(IF) nl ELSIF: 'elif' * expression 'then' come_forward(IF) go_forward(IF) nl ELSIF: 'elsif' * expression 'then' come_forward(IF) go_forward(IF) nl ELSE: 'else' * come_forward(IF) go_forward(ELSE) nl ENDIF: 'endif' * come_forward(IF,ELSE) nl ENDIF: 'end' 'if' * come_forward(IF,ELSE) nl # SLIF is recognised by IsCommandIF. IsCommandSLIF just returns false if called SLIF/SLIF: 'if' * expression 'then'

#directory operations # for example # open directory "/usr/bin" pattern "*.*" option sbCollectDirs and sbSortByName as 1

OPENDIR: 'open' 'directory' expression 'pattern' expression 'option' expression 'as' expression nl # predefined global constants ! sbCollectDirectories 0xFFFFFFFE ! sbCollectDots 0xFFFFFFFD ! sbCollectRecursively 0xFFFFFFFB ! sbCollectFullPath 0xFFFFFDFF ! sbCollectFiles 0xFFFFFFFF ! sbSortBySize 0xFFFFFFF7 ! sbSortByCreateTime 0xFFFFFFEF ! sbSortByAccessTime 0xFFFFFFDF ! sbSortByModifyTime 0xFFFFFFBF ! sbSortByName 0xFFFFFF7F ! sbSortByPath 0xFFFFFEFF ! sbSortAscending 0xFFFFFBFF ! sbSortDescending 0xFFFFFFFF ! sbSortByNone 0xFFFFFFFF

RESETDIR: 'reset' 'directory' '#' expression nl RESETDIR: 'reset' 'directory' expression nl CLOSEDIR: 'close' 'directory' '#' expression nl CLOSEDIR: 'close' 'directory' expression nl

# file operations OPEN/OPEN: 'open' expression 'for' absolute_symbol 'as' expression 'len' '=' expression nl CLOSE: 'close' '#' expression nl CLOSE: 'close' expression nl SEEK: 'seek' '#' expression ',' expression nl SEEK: 'seek' expression ',' expression nl REWIND: 'rewind' '#' expression nl REWIND: 'rewind' expression nl RESET: 'reset' nl LINPUTF: 'line' 'input' '#' expression ',' lval nl LINPUT: 'line' 'input' lval nl TRUNCATEF: 'truncate' '#' expression ',' expression nl RLOCK: 'lock' 'region' '#' expression 'from' expression 'to' expression 'for' absolute_symbol nl RLOCK: 'lock' 'region' expression 'from' expression 'to' expression 'for' absolute_symbol nl FLOCK: 'lock' '#' expression ',' absolute_symbol nl FLOCK: 'lock' expression ',' absolute_symbol nl MKDIR: 'mkdir' expression nl DELETEF: 'deltree' expression nl DELETE: 'delete' expression nl CHDIR: 'chdir' expression nl SETFILE: 'set' 'file' expression absolute_symbol '=' expression nl BINMO: 'binmode' 'output' nl BINMI: 'binmode' 'input' nl TXTMO: 'textmode' 'output' nl TXTMI: 'textmode' 'input' nl BINMF: 'binmode' '#' expression nl BINMF: 'binmode' expression nl TXTMF: 'textmode' '#' expression nl TXTMF: 'textmode' expression nl

#string commands SPLITA: 'splita' expression 'by' expression 'to' lval nl SPLIT: 'split' expression 'by' expression 'to' lval_list nl UNPACK: 'unpack' expression 'by' expression 'to' lval_list nl

# a single joker # set joker "&" = "0123456789abcdefABCDEF" # a multiple joker: # set wild "&" = "0123456789abcdefABCDEF" SETJOKER: 'set' 'joker' expression 'to' expression nl SETWILD: 'set' 'wild' expression 'to' expression nl SETNOJO: 'set' 'no' 'joker' expression nl SETNOJO: 'set' 'no' 'wild' expression nl

SLEEP: 'sleep' expression nl

# define a function of an external module (dll) EXTERNAL: 'declare' 'sub' * function 'alias' string 'lib' string nl EXTERNAM: 'declare' 'command' * function 'alias' string 'lib' string nl

# list of unary operators %UNARIES PLUS: + MINUS: - NOT: not BYVAL: byval

EXTOPF: ? EXTOPK: ! EXTOPL: # EXTOPO: ` EXTOPQ: @

EXTOPAC: +^ EXTOPAD: +< EXTOPAE: +> EXTOPAF: +? EXTOPAG: += EXTOPAH: +* EXTOPAI: +/ EXTOPAJ: +% EXTOPAK: +! EXTOPAL: +# EXTOPAM: +& EXTOPAN: +\ EXTOPAO: +` EXTOPAP: +' EXTOPAQ: +@ EXTOPBC: -^ EXTOPBD: -< EXTOPBE: -> EXTOPBF: -? EXTOPBG: -= EXTOPBH: -* EXTOPBI: -/ EXTOPBJ: -% EXTOPBK: -! EXTOPBL: -# EXTOPBM: -& EXTOPBN: -\ EXTOPBO: -` EXTOPBP: -' EXTOPBQ: -@ EXTOPCC: ^^ EXTOPCD: ^< EXTOPCE: ^> EXTOPCF: ^? EXTOPCG: ^= EXTOPCH: ^* EXTOPCI: ^/ EXTOPCJ: ^% EXTOPCK: ^! EXTOPCL: ^# EXTOPCM: ^& EXTOPCN: ^\ EXTOPCO: ^` EXTOPCP: ^' EXTOPCQ: ^@ EXTOPDC: <^ EXTOPDD: << EXTOPDF: <? EXTOPDH: <* EXTOPDI: </ EXTOPDJ: <% EXTOPDK: <! EXTOPDL: <# EXTOPDM: <& EXTOPDN: <\ EXTOPDO: <` EXTOPDP: <' EXTOPDQ: <@ EXTOPEC: >^ EXTOPED: >< EXTOPEE: >> EXTOPEF: >? EXTOPEH: >* EXTOPEI: >/ EXTOPEJ: >% EXTOPEK: >! EXTOPEL: ># EXTOPEM: >& EXTOPEN: >\ EXTOPEO: >` EXTOPEP: >' EXTOPEQ: >@ EXTOPFC: ?^ EXTOPFD: ?< EXTOPFE: ?> EXTOPFF: ?? EXTOPFG: ?= EXTOPFH: ?* EXTOPFI: ?/ EXTOPFJ: ?% EXTOPFK: ?! EXTOPFL: ?# EXTOPFM: ?& EXTOPFN: ?\ EXTOPFO: ?` EXTOPFP: ?' EXTOPFQ: ?@ EXTOPGC: =^ EXTOPGD: =< EXTOPGE: => EXTOPGF: =? EXTOPGG: == EXTOPGH: =* EXTOPGI: =/ EXTOPGJ: =% EXTOPGK: =! EXTOPGL: =# EXTOPGM: =& EXTOPGN: =\ EXTOPGO: =` EXTOPGP: =' EXTOPGQ: =@ EXTOPHC: *^ EXTOPHD: *< EXTOPHE: *> EXTOPHF: *? EXTOPHG: *= EXTOPHH: ** EXTOPHI: */ EXTOPHJ: *% EXTOPHK: *! EXTOPHL: *# EXTOPHM: *& EXTOPHN: *\ EXTOPHO: *` EXTOPHP: *' EXTOPHQ: *@ EXTOPIC: /^ EXTOPID: /< EXTOPIE: /> EXTOPIF: /? EXTOPIG: /= EXTOPIH: /* EXTOPII: // EXTOPIJ: /% EXTOPIK: /! EXTOPIL: /# EXTOPIM: /& EXTOPIN: /\ EXTOPIO: /` EXTOPIP: /' EXTOPIQ: /@ EXTOPJC: %^ EXTOPJD: %< EXTOPJE: %> EXTOPJF: %? EXTOPJG: %= EXTOPJH: %* EXTOPJI: %/ EXTOPJJ: %% EXTOPJK: %! EXTOPJL: %# EXTOPJM: %& EXTOPJN: %\ EXTOPJO: %` EXTOPJP: %' EXTOPJQ: %@ EXTOPKC: !^ EXTOPKD: !< EXTOPKE: !> EXTOPKF: !? EXTOPKG: != EXTOPKH: !* EXTOPKI: !/ EXTOPKJ: !% EXTOPKK: !! EXTOPKL: !# EXTOPKM: !& EXTOPKN: !\ EXTOPKO: !` EXTOPKP: !' EXTOPKQ: !@ EXTOPLC: #^ EXTOPLD: #< EXTOPLE: #> EXTOPLF: #? EXTOPLG: #= EXTOPLH: #* EXTOPLI: #/ EXTOPLJ: #% EXTOPLK: #! EXTOPLL: ## EXTOPLM: #& EXTOPLN: #\ EXTOPLO: #` EXTOPLP: #' EXTOPLQ: #@ EXTOPMC: &^ EXTOPMD: &< EXTOPME: &> EXTOPMF: &? EXTOPMG: &= EXTOPMH: &* EXTOPMI: &/ EXTOPMJ: &% EXTOPMK: &! EXTOPML: &# EXTOPMM: && EXTOPMN: &\ EXTOPMO: &` EXTOPMP: &' EXTOPMQ: &@ EXTOPNC: \^ EXTOPND: \< EXTOPNE: \> EXTOPNF: \? EXTOPNG: \= EXTOPNH: \* EXTOPNI: \/ EXTOPNJ: \% EXTOPNK: \! EXTOPNL: \# EXTOPNM: \& EXTOPNN: \\ EXTOPNO: \` EXTOPNP: \' EXTOPNQ: \@ EXTOPOC: `^ EXTOPOD: `< EXTOPOE: `> EXTOPOF: `? EXTOPOG: `= EXTOPOH: `* EXTOPOI: `/ EXTOPOJ: `% EXTOPOK: `! EXTOPOL: `# EXTOPOM: `& EXTOPON: `\ EXTOPOO: `` EXTOPOP: `' EXTOPOQ: `@ EXTOPPC: '^ EXTOPPD: '< EXTOPPE: '> EXTOPPF: '? EXTOPPG: '= EXTOPPH: '* EXTOPPI: '/ EXTOPPJ: '% EXTOPPK: '! EXTOPPL: '# EXTOPPM: '& EXTOPPN: '\ EXTOPPO: '` EXTOPPP: '' EXTOPPQ: '@ EXTOPQC: @^ EXTOPQD: @< EXTOPQE: @> EXTOPQF: @? EXTOPQG: @= EXTOPQH: @* EXTOPQI: @/ EXTOPQJ: @% EXTOPQK: @! EXTOPQL: @# EXTOPQM: @& EXTOPQN: @\ EXTOPQO: @` EXTOPQP: @' EXTOPQQ: @

# list of binary operators %BINARIES

EXTOPF: ? EXTOPK: ! EXTOPL: # EXTOPO: ` EXTOPQ: @

EXTOPAC: +^ EXTOPAD: +< EXTOPAE: +> EXTOPAF: +? EXTOPAG: += EXTOPAH: +* EXTOPAI: +/ EXTOPAJ: +% EXTOPAK: +! EXTOPAL: +# EXTOPAM: +& EXTOPAN: +\ EXTOPAO: +` EXTOPAP: +' EXTOPAQ: +@ EXTOPBC: -^ EXTOPBD: -< EXTOPBE: -> EXTOPBF: -? EXTOPBG: -= EXTOPBH: -* EXTOPBI: -/ EXTOPBJ: -% EXTOPBK: -! EXTOPBL: -# EXTOPBM: -& EXTOPBN: -\ EXTOPBO: -` EXTOPBP: -' EXTOPBQ: -@ EXTOPCC: ^^ EXTOPCD: ^< EXTOPCE: ^> EXTOPCF: ^? EXTOPCG: ^= EXTOPCH: ^* EXTOPCI: ^/ EXTOPCJ: ^% EXTOPCK: ^! EXTOPCL: ^# EXTOPCM: ^& EXTOPCN: ^\ EXTOPCO: ^` EXTOPCP: ^' EXTOPCQ: ^@ EXTOPDC: <^ EXTOPDD: << EXTOPDF: <? EXTOPDH: <* EXTOPDI: </ EXTOPDJ: <% EXTOPDK: <! EXTOPDL: <# EXTOPDM: <& EXTOPDN: <\ EXTOPDO: <` EXTOPDP: <' EXTOPDQ: <@ EXTOPEC: >^ EXTOPED: >< EXTOPEE: >> EXTOPEF: >? EXTOPEH: >* EXTOPEI: >/ EXTOPEJ: >% EXTOPEK: >! EXTOPEL: ># EXTOPEM: >& EXTOPEN: >\ EXTOPEO: >` EXTOPEP: >' EXTOPEQ: >@ EXTOPFC: ?^ EXTOPFD: ?< EXTOPFE: ?> EXTOPFF: ?? EXTOPFG: ?= EXTOPFH: ?* EXTOPFI: ?/ EXTOPFJ: ?% EXTOPFK: ?! EXTOPFL: ?# EXTOPFM: ?& EXTOPFN: ?\ EXTOPFO: ?` EXTOPFP: ?' EXTOPFQ: ?@ EXTOPGC: =^ EXTOPGD: =< EXTOPGE: => EXTOPGF: =? EXTOPGG: == EXTOPGH: =* EXTOPGI: =/ EXTOPGJ: =% EXTOPGK: =! EXTOPGL: =# EXTOPGM: =& EXTOPGN: =\ EXTOPGO: =` EXTOPGP: =' EXTOPGQ: =@ EXTOPHC: *^ EXTOPHD: *< EXTOPHE: *> EXTOPHF: *? EXTOPHG: *= EXTOPHH: ** EXTOPHI: */ EXTOPHJ: *% EXTOPHK: *! EXTOPHL: *# EXTOPHM: *& EXTOPHN: *\ EXTOPHO: *` EXTOPHP: *' EXTOPHQ: *@ EXTOPIC: /^ EXTOPID: /< EXTOPIE: /> EXTOPIF: /? EXTOPIG: /= EXTOPIH: /* EXTOPII: // EXTOPIJ: /% EXTOPIK: /! EXTOPIL: /# EXTOPIM: /& EXTOPIN: /\ EXTOPIO: /` EXTOPIP: /' EXTOPIQ: /@ EXTOPJC: %^ EXTOPJD: %< EXTOPJE: %> EXTOPJF: %? EXTOPJG: %= EXTOPJH: %* EXTOPJI: %/ EXTOPJJ: %% EXTOPJK: %! EXTOPJL: %# EXTOPJM: %& EXTOPJN: %\ EXTOPJO: %` EXTOPJP: %' EXTOPJQ: %@ EXTOPKC: !^ EXTOPKD: !< EXTOPKE: !> EXTOPKF: !? EXTOPKG: != EXTOPKH: !* EXTOPKI: !/ EXTOPKJ: !% EXTOPKK: !! EXTOPKL: !# EXTOPKM: !& EXTOPKN: !\ EXTOPKO: !` EXTOPKP: !' EXTOPKQ: !@ EXTOPLC: #^ EXTOPLD: #< EXTOPLE: #> EXTOPLF: #? EXTOPLG: #= EXTOPLH: #* EXTOPLI: #/ EXTOPLJ: #% EXTOPLK: #! EXTOPLL: ## EXTOPLM: #& EXTOPLN: #\ EXTOPLO: #` EXTOPLP: #' EXTOPLQ: #@ EXTOPMC: &^ EXTOPMD: &< EXTOPME: &> EXTOPMF: &? EXTOPMG: &= EXTOPMH: &* EXTOPMI: &/ EXTOPMJ: &% EXTOPMK: &! EXTOPML: &# EXTOPMM: && EXTOPMN: &\ EXTOPMO: &` EXTOPMP: &' EXTOPMQ: &@ EXTOPNC: \^ EXTOPND: \< EXTOPNE: \> EXTOPNF: \? EXTOPNG: \= EXTOPNH: \* EXTOPNI: \/ EXTOPNJ: \% EXTOPNK: \! EXTOPNL: \# EXTOPNM: \& EXTOPNN: \\ EXTOPNO: \` EXTOPNP: \' EXTOPNQ: \@ EXTOPOC: `^ EXTOPOD: `< EXTOPOE: `> EXTOPOF: `? EXTOPOG: `= EXTOPOH: `* EXTOPOI: `/ EXTOPOJ: `% EXTOPOK: `! EXTOPOL: `# EXTOPOM: `& EXTOPON: `\ EXTOPOO: `` EXTOPOP: `' EXTOPOQ: `@ EXTOPPC: '^ EXTOPPD: '< EXTOPPE: '> EXTOPPF: '? EXTOPPG: '= EXTOPPH: '* EXTOPPI: '/ EXTOPPJ: '% EXTOPPK: '! EXTOPPL: '# EXTOPPM: '& EXTOPPN: '\ EXTOPPO: '` EXTOPPP: '' EXTOPPQ: '@ EXTOPQC: @^ EXTOPQD: @< EXTOPQE: @> EXTOPQF: @? EXTOPQG: @= EXTOPQH: @* EXTOPQI: @/ EXTOPQJ: @% EXTOPQK: @! EXTOPQL: @# EXTOPQM: @& EXTOPQN: @\ EXTOPQO: @` EXTOPQP: @' EXTOPQQ: @

%PRECEDENCE

POWER: ^

%PRECEDENCE MULT: * DIV: / IDIV: \ MOD: %

# go one precedence level deeper %PRECEDENCE PLUS: + MINUS: -

%PRECEDENCE CONCATENATE: &

%PRECEDENCE LIKEOP: like

%PRECEDENCE EQ: = LT: < LE: <= GT: > GE: >= NE: <>

%PRECEDENCE AND: and

%PRECEDENCE OR: or XOR: xor

# built-in functions: name, min args, max args %FUNCTIONS SIN: sin 1 1 ASIN: asin 1 1 COS: cos 1 1 ACOS: acos 1 1 SGN: sgn 1 1 ODD: odd 1 1 EVEN: even 1 1 SQR: sqr 1 1 RND: rnd 0 0 ABS: abs 1 1 VAL: val 1 1 PI: pi 0 0 TRUE: true 0 0 FALSE: false 0 0 FIX: fix 1 1 INT: int 1 1 FRAC: frac 1 1 UNDEF: undef 0 0 ROUND: round 1 2 LOG: log 1 1 LOG10: log10 1 1 POW: pow 1 1 EXP: exp 1 1 LEN: len 1 1 ASC: asc 1 1

UCASE: ucase 1 1 LCASE: lcase 1 1 LTRIM: ltrim 1 1 RTRIM: rtrim 1 1 TRIM: trim 1 1 MID: mid 2 3 LEFT: left 2 2 RIGHT: right 2 2 SPACE: space 1 1 STRING: string 2 2 CHR: chr 1 1 STRREVERSE: strreverse 1 1 STR: str 1 1 HEX: hex 1 1 OCT: oct 1 1 JOKER: joker 1 1 CHOMP: chomp 1 1

LBOUND: lbound 1 1 UBOUND: ubound 1 1

ISARRAY: isarray 1 1 ISSTRING: isstring 1 1 ISLONG: isinteger 1 1 ISDOUBLE: isreal 1 1 ISNUMERIC: isnumeric 1 1 ISDEF: isdefined 1 1 ISUNDEF: isundef 1 1 ISEMPTY: isempty 1 1 TYPE: type 1 1

UCASE: ucase$ 1 1 LCASE: lcase$ 1 1 LTRIM: ltrim$ 1 1 RTRIM: rtrim$ 1 1 TRIM: trim$ 1 1 MID: mid$ 2 3 LEFT: left$ 2 2 RIGHT: right$ 2 2 SPACE: space$ 1 1 STRING: string$ 2 2 CHR: chr$ 1 1 STRREVERSE: strreverse$ 1 1 STR: str$ 1 1 HEX: hex$ 1 1 OCT: oct$ 1 1 INSTR: instr 2 3 INSTRREV: instrrev 2 3 REPLACE: replace 3 5 # 100000 arguments are practically unlimited JOIN: join 2 100000

OPTIONF: option 1 1

ERROR: error 0 0

LOC: loc 1 1 LOF: lof 1 1 FILELEN: filelen 1 1 FREEFILE: freefile 0 1 INPUTFUN: input 1 2 EOFFUN: eof 1 1 EODFUN: eod 1 1 FTACCESS: fileaccesstime 1 1 FTMODIFY: filemodifytime 1 1 FTCREATED: filecreatetime 1 1 FOWNER: fileowner 1 1 ISDIR: isdirectory 1 1 ISREG: isfile 1 1 FILEXISTS: fileexists 1 1 NEXTFILE: nextfile 1 1 ENVIRON: environ 1 1 CURDIR: curdir 0 0 COMMANDF: command 0 0 ADDRESSF: address 1 1

FORMATDATE: formatdate 1 2 FORMATDATE: formattime 1 2 FORMAT: format 1 2000000 PACK: pack 1 2000000 NOW: time 0 0 NOW: now 0 0 GMTIME: gmtime 0 0 YEAR: year 0 1 MONTH: month 0 1 DAY: day 0 1 WDAY: weekday 0 1 YDAY: yearday 0 1 MINUTE: minute 0 1 SEC: sec 0 1 HOUR: hour 0 1 TIMEVALUE: timevalue 0 6 GM2LOCAL: gmtimetolocaltime 1 1 LOCAL2GM: localtimetogmtime 1 1 ADDYEAR: addyear 2 2 ADDMONTH: addmonth 2 2 ADDDAY: addday 2 2 ADDHOUR: addhour 2 2 ADDMINUTE: addminute 2 2 ADDSECOND: addsecond 2 2 ADDWEEK: addweek 2 2 HOSTNAME: hostname 0 0

KILL: kill 1 1 ICALLFUN: icall 1 2000000 FCRYPT: crypt 2 2 CREATEPROCESS: system 1 1 CREATEPROCESSEX: execute 3 3 FORK: fork 0 0

[Contents]

7.3. source.ziplist

List of files and extensions to include into the source distribution of ScriptBasic WIN32 distribution.

The souce code of the file `source.ziplist' is:

; List of source files to zip into the source distribution
*.c
*h
commands\*.c
commands\*.h
Makefile.nt
build.txt
*.def
*.pl
*.bat
*.cmd
*.sdd
scriba.conf.lsp
extensions

[Contents]

7.4. source.exziplist

List of files and extensions to exclude from the source distribution of ScriptBasic WIN32 distribution.

The souce code of the file `source.exziplist' is:

; list of files that are to be excluded from the source distribution
*.exe
*.lib
*.dll
*.obj
*.exp

[Contents]

8. Perl files

The Perl program used to automate the code maintenance are listed in this chapter.

[Contents]

8.1. ssplit.pl

This file splits the file `html/source.txt' into several Jamal files. This file is called from mkweb.pl

The souce code of the file `ssplit.pl' is:

#!/usr/bin/perl
# LEGAL WARNING:
#
# This software is provided on an "AS IS", basis,
# without warranty of any kind, including without
# limitation the warranties of merchantability, fitness for
# a particular purpose and non-infringement. The entire
# risk as to the quality and performance of the Software is
# borne by you. Should the Software prove defective, you
# and not the author assume the entire cost of any service
# and repair.
#
$version = '1.0';

if( $#ARGV == 0 && $ARGV[0] eq '-h' ){ print <<END__HELP; Source Splitter $version Usage:

ssplit source_file [directory]

This program splits a text file. The primary purpose of this tool was to maintain many small HTML files as a one somewhat larger jamal source, compile it using jamal and then split to small html files. The source file should contain lines

\%file file_name

to start a new file. The default directory is .

For further information see on-line documentation at

http://www.isys.hu/c/verhas/progs/perl/ssplit END__HELP exit; }

$file = shift; $dir = shift; $dir = '.' unless $dir; $subdir = ''; $output_opened = 0; $buffer = ''; $output = '';

open(F,$file) or die "Can not open $file\n"; while( <F> ){

if( /^\s*%\s*file\s+(.*?)\s*$/ ){ my $new_output = $1; &save_buffer($output); $buffer = ''; $output = "$dir/$subdir/${new_output}"; $output =~ s{//}{/}; next; }

if( /^\s*%\s*dir\s+(.*?)\s*$/ ){ $subdir = $1; next; }

$buffer .= $_; } &save_buffer($output); close F; exit;

sub save_buffer { my $file = shift;

return unless $output || $buffer ; if( $buffer && !$output ){ die "Is there text before the first '%file' ??"; }

if( open(OUT,"<$file") ){ my $os = $/; undef $/; my $sbuffer = <OUT>; $/ = $os; close OUT; return if $buffer eq $sbuffer; } &make_dir($file); open(OUT,">$file") or die "Can not output $file"; print OUT $buffer; close OUT; }

sub make_dir { my $dir = shift; my @dlist = split '/' , $dir; pop @dlist; # pop off file name return if $#dlist == -1;

$root = ''; for( @dlist ){ $root .= '/' if $root; $root .= $_; # take the next subdirectory mkdir $root, 0777 unless -d $root } }

[Contents]

8.2. mkweb.pl

This Perl script is invoked by mkweb.cmd and it executes several Jamal processes for the web jamal files.

The souce code of the file `mkweb.pl' is:

opendir(D,".");
@f = grep /\.jam$/ , readdir D;
closedir D;
for( @f ){
  $src = $_;
  $res = $_;
  $res =~ s/\.jam$//;
  print "Processing $src ...\n";
  `perl ..\\jamal.pl -m macros.jim $src ../../html/$res`;
  }

[Contents]

8.3. convert.pl

This small utility opens all files in the current directory and below recursively and converts the files to contain UNIX line-feeds. This is needed when the files are copied from a DOS development station to UNIX via SMB.

The souce code of the file `convert.pl' is:

#!/usr/bin/perl

# # convert.pl # This small utility opens all files in the current directory and below recirsively and # converts the files to contain UNIX line-feeds. This is needed when the files are # copied from a DOS development station to to UNIX via SMB. # # The conversion does not harm files that are already UNIX LF. #

@BINARY = ( 'o','a','dll','lib','exe','out','so','conf','conf_old','doc','deb', ); @ASCII = ( 'c','h','txt','h_bas','bat','lsp','heb','bas','pl','html','def','bas','mak','inc','ini','tpl','sh','sdd', );

%BADS = [];

# # decide if a file is binary or ascii based on the file name extension # if the file has no extension that it opens the file and reads the first line # if the file starts with #!/ then this is text othervise binary file # sub isbinary { my $fn = shift; my $i;

if( $fn !~ /\./ ){ #if there is no extension in the file name at all return 0 if $fn =~ /Makefile$/; open(F,$fn) or die "cannot open $fn for reading to decide file type"; my $l = <F>; close F; chomp $l; if( $l =~ /^\#\!\// ){ return 0; } return 1; }

for $i ( @BINARY ){ return 1 if substr($fn,length($fn)-length($i)-1) eq ".$i"; } for $i ( @ASCII ){ return 0 if substr($fn,length($fn)-length($i)-1) eq ".$i"; } $fn =~ /\.(.*)$/; $BADS{$1}++; return -1 if $BADS{$1} == 1; return 0; }

opendir(D,'.'); @f = readdir(D); closedir(D); @DirsLeft = (); $qdir = ''; while(1){ $qdir = $qdir . '/' if $qdir; for( @f ){ if( -d "$qdir$_" ){ push @DirsLeft , "$qdir$_" unless $_ eq '.' || $_ eq '..'; }else{ push @filist , "$qdir$_"; } } last if $#DirsLeft == -1; $qdir = pop @DirsLeft; opendir(D,"$qdir"); @f = readdir(D); closedir(D); }

$badcount = 0; for $i ( @filist ){ $t = isbinary($i); if( $t == -1 ){ $badcount++; $i =~ /\.(.*)$/; print "$1 is unknown type\n"; } }

for $i ( @filist ){ if( ! isbinary($i) ){ open(F,$i) or die "cannot read $i for converting\n"; $ofile = ''; $file = ''; while( <F> ){ $ofile .= $_; while( /\r$/ || /\n$/ ){chop;} $file .= "$_\n"; } if( $ofile ne $file ){ open(F,">$i") or die "cannot write the file $i for converting\n"; print F $file; close F; } } } exit 0;

[Contents]

8.4. esd2html.pl

Create on-line documentation based on SDD files. This program was NOT developed for ScriptBasic. This is a general purpose source documentation package that was developed first for the Perl language but turned out to be useful for other languages like C.

This tool is not going to be used anymore for the documentation of ScriptBasic. However you can still find the old definition files in the source tree and some source code may still contain old esd formatted documentation.

The source code of the file is not included in this documentation because the file itself is too long for the purpose.

[Contents]

8.5. generrh.pl

This script reads the files `errors.def', `build.txt' and creates the files `errcodes.c' and `include/error.bas'

The file `errors.def' contains the used error symbols in an easy to maintain text format.

The souce code of the file `generrh.pl' is:

open(F,"<errors.def") or die "Can not open errors.def";

open(OUT,">errcodes.c") or die "Can not output errcodes.c"; open(BAS,">include/error.bas") or die "Can nor output include/error.bas";

open(Q,"<build.txt") or die "Can not open the build file."; $BUILD = <Q>; close Q; chomp $BUILD;

print BAS <<BASEND; ' This file was automatically generated by the program generrh.pl ' using the error code definition file errors.def from the ' ScriptBasic distribution ' ' This file is part of the ScriptBasic distribution and is ' specific to the actual build it was shipped. Do not use ' this file for any version or build of the ScriptBasic ' interpreter other than the one this file was shipped. ' ' THIS FILE IS FOR V1.0 BUILD $BUILD ' Global Const sbErrorOK = 0 Global Const sbErrorMemory = 1

BASEND

print OUT <<END; /* FILE: errcodes.c HEADER: errcodes.h

This file was automatically generated by generrh.pl from the file errors.def Do not edit this file. Modify errors.def and run generrh.pl to regenerate this file.

TO_HEADER:

END

$module = ''; $CurrentErrorCode = 2; $LastErrorCode = 0; $TextHashes = {}; $ErrorType = 0; # 0 is compile type, 1 is run time error

while( <F> ){ chomp; next if /^\s*$/;

next if /^\s*\#/;

if( /\%RT\s*$/ ){ $ErrorType = 1; next; }

if( /\%CT\s*$/ ){ $ErrorType = 0; next; }

if( /\%MODULE\s+(.*)\s*$/ ){ $module = $1; print OUT "#define ${module}_ERROR_SUCCESS 0\n"; print OUT "#define ${module}_ERROR_MEMORY_LOW 1\n"; $TextHashes->{'en'}->[1] = 'Not enough memory'; $LastErrorSymbol = ''; next; }

if( m{(\w\w)/(.*)} ){ my $language = $1; my $message = $2; $TextHashes->{$language} = [] unless defined $TextHashes->{$language}; $TextHashes->{$language}->[$LastErrorCode] = $message; if( $language eq 'en' && $ErrorType ){ print BAS "' $message\n' "; print BAS "-" x length($message) ,"\n\n"; } next; } if( /^(.+)\s+(.+)$/ ){ $_ = $1; $ErrorSymbol = $2; }else{ $ErrorSymbol = undef; } if( $ErrorType ){ $ErrorSymbol = lc $_ unless defined $ErrorSymbol; my $i; for( $i=0 ; $i < length $ErrorSymbol ; $i++ ){ if( substr($ErrorSymbol,$i,1) eq "_" ){ substr($ErrorSymbol,$i+1,1) = uc substr($ErrorSymbol,$i+1,1); } } substr($ErrorSymbol,0,1) = uc substr($ErrorSymbol,0,1); $ErrorSymbol =~ s/\_//g; print BAS "Global Const sbError$ErrorSymbol = $CurrentErrorCode\n"; } print OUT "#define ${module}_ERROR_$_ $CurrentErrorCode\n"; $LastErrorCode = $CurrentErrorCode++;

} close F;

print OUT "#define MAX_ERROR_CODE $CurrentErrorCode\n";

print OUT "typedef struct { char *language; char **array; } tErrorMessageArray;\n"; print OUT "extern tErrorMessageArray ErrorMessageArray[];\n";

while( ($language,$array) = each %{$TextHashes} ){ print OUT "extern char *${language}_error_messages[];\n"; }

print OUT "*/\n";

print OUT "#include <stdio.h>\n#include \"errcodes.h\"\n";

while( ($language,$array) = each %{$TextHashes} ){ print OUT "char *${language}_error_messages[] ={\n"; for( $i = 0 ; $i < $CurrentErrorCode ; $i++ ){ print OUT '"',$TextHashes->{$language}->[$i],'"',",\n"; } print OUT "NULL\n};\n"; }

print OUT "tErrorMessageArray ErrorMessageArray[]={\n"; while( ($language,$array) = each %{$TextHashes} ){ print OUT "\"$language\",${language}_error_messages,\n"; } print OUT "NULL,NULL\n};\n"; close OUT;

[Contents]

8.6. headerer.pl

This Perl script reads the C source files one-by-one that are given on the command line and extracts the header information from the C file and creates the `.h' files.

Note that in case the C file was not changed and thus the new header file is the same as the old one the program does not touch the header file and this way it does not force and make utility to recompile the source useless.

The souce code of the file `headerer.pl' is:

# read a C file and create a header file from it
#
#  Lines processed: HEADER: headerfilename
#                   FILE:   name of the file (used to create header file name unless HEADER is defined)
#                   TO_HEADER:
#                      lines until a single */ on a line are put to the header file
#
#                   /*FUNCTION*/
#                   lines are put to the header file until a single { is found on a line
#                   ; is added after these lines
#
#                   GLOBAL declaration
#                   is put to the header file replcing 'GLOBAL' to 'extern'
#                   define GLOBAL to nothing in the source file
#

START_HERE: $file = shift; exit unless defined $file;

$input_file_name = ''; $header_file_name = ''; $header_file_opened = 0; $header_file = undef; $podon = 0;

open(F,"<$file") or die "Can not open the input file $file"; $header_content = '';

while( defined( $_ = <F>) ){ chomp;

if( /^\s*FILE\s*:\s*(\S+)/ ){ $input_file_name = $1; next; }

if( /^\s*HEADER\s*:\s*(\S+)/ ){ $header_file_name = $1; next; }

if( /^\s*TO_HEADER\s*:/ ){ &open_header_file; $podon = 0; # no =POD is on by default while( <F> ){ chomp; if( m{^\s*=POD\s*$} ){ # start POD $podon = 1; next; } if( m{^\s*=CUT\s*$} ){ # finish POD $podon = 0; next; } last if m{^\s*\*/\s*$}; # finish copiing when the */ is reached if( m{^(.*)//(.*)} ){ # chop off // comments $_ = $1; } s/\\\s*$/\\/; # delete trailing space after \ $header_content .= "$_\n" unless $podon; } next; }

if( m{^\s*/\*FUNCTION\*/\s*$} ){ &open_header_file; while( <F> ){ chomp; last if m{^\s*\)\s*\{\s*$}; $header_content .= "\n$_"; } $header_content .= ");\n"; next; } }

$header_content .= <<END; #ifdef __cplusplus } #endif #endif END

close F;

if( $header_file_opened ){ if( open(H,"<$open_header_file_name") ){ # check if the file is identical my $oldsep = $/; undef $/; $q = <H>; close H; $/ = $oldsep; goto START_HERE if $q eq $header_content; } open(H,">$open_header_file_name") or die "Can not open header file $open_header_file_name"; print H $header_content; close H; }else{ print STDERR "No header was created for $file\n"; } goto START_HERE;

sub open_header_file {

return if $header_file_opened;

$header_file_opened = 1;

if( ! $header_file_name && ! $input_file_name ){ $header_file_name = $file; $header_file_name =~ s/\.\w+$/.h/; } if( ! $header_file_name ){ $header_file_name = $input_file_name; $header_file_name =~ s/\.\w+$/.h/; } if( ! $header_file_name ){ die "No header file name."; }

# modify the header name so that it is created in the same directory as the source my $dir = $file; $dir =~ s/\\/\//g; # leaning toothpicks effect :-) (convert \ to / for Win32 users) if( $dir =~ s/\/[^\/]+$// ){ $open_header_file_name = "$dir/$header_file_name"; }else{ $open_header_file_name = $header_file_name; } $header_symbol = uc $header_file_name; $header_symbol =~ s{^.*/}{}; $header_symbol = '__'.$header_symbol.'__'; $header_symbol =~ s/\./_/g; $header_content .= <<END; /* $header_file_name */ #ifndef $header_symbol #define $header_symbol 1 #ifdef __cplusplus extern "C" { #endif END }

[Contents]

8.7. heber.pl

Html Embedded Basic sample preprocessor.

The souce code of the file `heber.pl' is:

# Sample ScriptBasic external preprocessor
#
# This preprocessor converts heb (Html Embedded Basic) files to BASIC
#
# <% basic program %>
# <%= basic expression %>
#
$inputfile = shift;
$outputfile = shift;

# we want to read the whole file into memory $/ = undef; # open the file or exit 0 telling ScriptBasic that it has failed open(F,"<$inputfile") or exit(0); $input = <F>; close F; $output = '';

while( length($input) > 0 ){ $end = index($input,'<%'); last if $end < 0 ; $append = substr($input,0,$end); $input = substr($input,$end+2); if( length($append) > 0 ){ $append =~ s/\"/\\\"/g; $output .= 'print """' . $append . '"""' . "\n"; } $end = index($input,'%>'); exit 0 if $end == -1; $append = substr($input,0,$end); $input = substr($input,$end+2); if( length($append) > 0 ){ if( substr($append,0,1) eq '=' ){ $append = 'print ' . substr($append,1); } $output .= $append . "\n"; } }

if( length($input) > 0 ){ $input =~ s/\"/\\\"/g; $output .= 'print """' . $input . '"""' . "\n"; } # open the output file or exit 0 telling ScriptBasic that it has failed open(F,">$outputfile") or exit(0); print F $output; close F; exit(0);

[Contents]

8.8. mkcdoc.pl

Extract the BASIC command reference documentation from the C source files that are in the C source file in the directory `commands'

The souce code of the file `mkcdoc.pl' is:

#use strict;

my %SECTION; my %COMMAND; my %TITLE; # the title line of the command my %SUBTITLE; # the subtitle of the command my %DISPLAY; # the display of the command in the TOC my @files; my $SourceFile;

opendir(D,"commands") or die "Can not open directory commands."; @files = readdir(D); closedir D;

for $SourceFile ( @files ){ &ProcessFile( $SourceFile ); }

my %SAVE_SECTION = %SECTION; my %SAVE_COMMAND = %COMMAND;

&CreateOutput;

%SECTION = %SAVE_SECTION; %COMMAND = %SAVE_COMMAND;

&CreateTexiOutput; exit;

sub ProcessFile { my $file = shift; my $line; my $ActualCommand = undef; my @sections; my $section;

return unless open(F,"commands/$file"); while( defined($line = <F>) ){

# /**SectionName starts a new command

if( $line =~ /^\/\*\*(.*)\s*$/ ){ if( defined($ActualCommand) ){ warn "The command $ActualCommand was not closed. Closing implicitly."; $ActualCommand = undef; } $ActualCommand = $1; next; }

next if ! defined $ActualCommand;

if( $line =~ /^\*\// ){ $ActualCommand = undef; next; }

# =section list of sections the command has to be listed in

if( $line =~ /^=section\s+(.*)/ ){ my @sections = split /\s+/ , $1; for $section ( @sections ){ push @{$SECTION{$section}},$ActualCommand; } next; }

# =title title line of the actual command

if( $line =~ /^=title\s+(.*)/ ){ if( defined($TITLE{$ActualCommand}) ){ my $err; $err = "Title is double defined for $ActualCommand\n" . " " . $TITLE{$ActualCommand} . "\n" . " " . $1 . "\n" ; warn $err; } $TITLE{$ActualCommand} = $1; next; }

# =subtitle title line of the actual command

if( $line =~ /^=subtitle\s+(.*)/ ){ if( defined($SUBTITLE{$ActualCommand}) ){ warn "Subtitle is double defined for $ActualCommand"; } $SUBTITLE{$ActualCommand} = $1; next; }

# =display title line of the actual command

if( $line =~ /^=display\s+(.*)/ ){ if( defined($DISPLAY{$ActualCommand}) ){ warn "Title is double defined for $ActualCommand"; } $DISPLAY{$ActualCommand} = $1; next; }

push @{$COMMAND{$ActualCommand}},$line; next; } close F; }

sub CreateOutput { my $command; my $lines; my @commands; my $section; my @sections;

@commands = sort keys %COMMAND; @sections = sort keys %SECTION;

open(F,">../html/commands.html") or die "Can not open output file."; print F <<END; <HTML> <HEAD> <TITLE></TITLE> </HEAD> <BODY> <H1>ScriptBasic commands and functions reference</H1>

<H2>List of Sections</H2> END

for $section ( @sections ){ print F "<a href=\"#section_$section\">$section</A>\n"; }

print F <<END; <H2>List of Commands</H2> <FONT SIZE="1"> END

for $command ( @commands ){ my $display; $display = $command; $display = $DISPLAY{$command} if defined $DISPLAY{$command}; print F "<a href=\"#command_$command\">$display</A>\n"; }

print F <<END; </FONT> <H2>List of Commands by Sections</H2> END

for $section ( @sections ){ print F "<H3><a name=\"#section_$section\">$section</A></H3>\n"; print F "<FONT SIZE=\"1\">\n"; my @scommands = sort @{$SECTION{$section}}; my $scommand; for $scommand (@scommands){ my $display; $display = $scommand; $display = $DISPLAY{$scommand} if defined $DISPLAY{$scommand}; print F "<a href=\"#command_$scommand\">$display</A>\n"; } print F "</FONT\>\n"; }

print F <<END; <H2>Commands</H2> END

for $command ( @commands ){ my $title = $command; my $line; my $verbatim = 0; my $subtitle; my $FH;

$title = $TITLE{$command} if defined $TITLE{$command}; $subtitle = undef; $subtitle = $SUBTITLE{$command} if defined $SUBTITLE{$command};

# # print lines that start a command #

print F "<H3><a name=\"#command_$command\">$title</A></H3>\n"; print F "<H4>$subtitle</H4>\n" if defined $subtitle; print F "<BLOCKQUOTE>\n"; $FH = 0; for $line ( @{$COMMAND{$command}} ){ if( $line =~ /^\s*=details\s*$/ ){ print F <<END; <a href="commands/$command.html">details</A> END mkdir "../html/commands",0777; open(DF,">../html/commands/$command.html") or die "Can not open file ../html/commands/$command.html"; $FH = 1; print DF <<END; <HTML> <HEAD> <TITLE>$command</TITLE> </HEAD> <BODY> <H1>$title</H1> <a href="../commands.html#command_$command">BACK</a><P> END next; } if( $line =~ /^\s*=verbatim\s*$/ ){ $verbatim++; if( $FH ){ print DF "<PRE>\n"; }else{ print F "<PRE>\n"; } next; } if( $line =~ /^\s*=noverbatim\s*$/ ){ $verbatim--; if( $FH ){ print DF "</PRE>\n"; }else{ print F "</PRE>\n"; } next; } if( $verbatim ){ if( $FH ){ print DF $line; }else{ print F $line; } next; }

if( $line =~ /^\s*=itemize\s*$/ ){ if( $FH ){ print DF "<UL>\n"; }else{ print F "<UL>\n"; } next; } if( $line =~ /^\s*=noitemize\s*$/ ){ if( $FH ){ print DF "</UL>\n"; }else{ print F "</UL>\n"; } next; }

if( $line =~ /^\s*$/ ){ if( $FH ){ print DF "<P>\n"; }else{ print F "<P>\n"; } next; }

my $l_line = $line; while( $l_line =~ /R\<(\w+?)\>/ ){ my $d = $1; $d = $DISPLAY{$d} if defined $DISPLAY{$d}; $l_line =~ s/R\<(\w+?)\>/\001a href=\"#command_$1\">$d\001\/a>/; } $l_line =~ s/T\<(.+?)\>/\001tt>$1\001\/tt>/g; $l_line =~ s/B\<(.+?)\>/\001B>$1\001\/B>/g; $l_line =~ s/I\<(.+?)\>/\001I>$1\001\/I>/g;

$l_line =~ s/^\s*=item\s+/\001LI>/g;

$l_line =~ tr{\001}{<}; if( $FH ){ print DF $l_line; }else{ print F $l_line; } } # # print lines that close a command # print F "</BLOCKQUOTE>\n"; if( $FH ){ print DF <<END; <P><a href="../commands.html#command_$command">BACK</a> </BODY> </HTML> END close DF; # if it was opened } }

# # print lines that close the entire HTML file # print F <<END; </BODY> </HTML> END close F; }

#################################################

sub CreateTexiOutput { my $command; my $lines; my @commands; my $section; my @sections;

@commands = sort keys %COMMAND; @sections = sort keys %SECTION;

open(F,">commands.texi") or die "Can not open commands.texi output file.";

print F "\@chapter Command reference\n";

for $command ( @commands ){ my $title = $command; my $line; my $verbatim = 0; my $subtitle; my $FH;

$title = $TITLE{$command} if defined $TITLE{$command}; $subtitle = undef; $subtitle = $SUBTITLE{$command} if defined $SUBTITLE{$command};

# # print lines that start a command #

print F "\n\@section $title\n\n"; print F "\@b{$subtitle}\n" if defined $subtitle; for $line ( @{$COMMAND{$command}} ){ if( $line =~ /^\s*=details\s*$/ ){ print F "\@subsection $command Details\n"; next; } if( $line =~ /^\s*=verbatim\s*$/ ){ $verbatim++; print F "\@example\n"; next; } if( $line =~ /^\s*=noverbatim\s*$/ ){ $verbatim--; print F "\@end example\n"; next; } if( $verbatim ){ print F $line; next; }

if( $line =~ /^\s*=itemize\s*$/ ){ print F "\@itemize\n"; next; } if( $line =~ /^\s*=noitemize\s*$/ ){ print F "\@end itemize\n"; next; }

if( $line =~ /^\s*$/ ){ print F "\n\n"; next; }

my $l_line = $line; $l_line =~ s[\<tt\>][\@code\{]gi; $l_line =~ s[\<\/tt\>][\}]gi; $l_line =~ s[<UL>][\@itemize ]gi; $l_line =~ s[</UL>][\@end itemize ]gi; $l_line =~ s[<LI>][\@item ]gi;

$l_line =~ s/\@/\@\@/g; $l_line =~ s/\$/\@\$/g; $l_line =~ s/\{/\@\{/g; $l_line =~ s/\}/\@\}/g; $l_line =~ s[<a href=".*?">(.*?)</a>][\@xref{$1}]gi; $l_line =~ s/R\<(.+?)\>/\@xref\{$1\}/g; $l_line =~ s/T\<(.+?)\>/\@code\{$1\}/g; $l_line =~ s/B\<(.+?)\>/\@b\{$1\}>/g; $l_line =~ s/I\<(.+?)\>/\@emph\{$1\}>/g;

$l_line =~ s/^\s*=item\s+/\@item /g;

print F $l_line; } }

close F; }

[Contents]

8.9. syntaxer.pl

Read the file `syntax.def' and create the file `syntax.c' converting the syntax definition from an easy to read and maintain format to C source file.

The source code of the file is not included in this documentation because the file itself is too long for the purpose.

[Contents]

8.10. preparedeb.pl

This Perl script alters the `deb/DEBIAN/control' file so that it contains the actual build version.

The souce code of the file `preparedeb.pl' is:

#!/usr/bin/perl

open(F,"deb/DEBIAN/control") or die; undef $/; $control_file = <F>; close F; open(F,"build.txt") or die; $build = <F>; close F; $build = $build +0; $control_file =~ s/(Version\:\s+\d+\.\d+\.)\d+(\-\d+)/$1$build$2/; open(F,">deb/DEBIAN/control") or die; print F $control_file; close F;

[Contents]

8.11. lmt_make.pl

This perl script reads a file named `lmt_XXX.def' and creates the file `lmt_XXX.c' to help the linking of the external modules into ScriptBasic static.

The souce code of the file `lmt_make.pl' is:

#!/usr/bin/perl

# # Use this program to automatically create the C table that lists the modules that are going to be # linked statically to ScriptBasic. Do not edit the created C file, rather maintain one or more # linkedmodules.def file and create one or more linkedmodules.c file #

while(1){

exit 0 unless defined($InputFile = shift); $OutputFile = $InputFile;

$OUTL = <<END; /* FILE: $OutputFile

This file was automatically created by the program lmt_make.pl

DO NOT EDIT THIS FILE!!!

Rather edit the file $InputFile that is the source

*/ #include <stdio.h> #include "basext.h"

END

@ModuleList = ();

unless( open(F,$InputFile) ){ print "Cannot open $InputFile\n"; exit 1; }

while( <F> ){ chomp; next if /^\s*\#/; next if /^\s*$/; @words = split /\s+/; push @ModuleList, $words[0]; }

for $module (@ModuleList ){ $OUTL .= "extern SLFST " . uc($module) ."_SLFST[];\n" }

$OUTL .= "MODLIST StaticallyLinkedModules[] ={\n"; for $module (@ModuleList ){ $OUTL .= " {\"$module\" , (void *)" . uc($module) . "_SLFST },\n" }

close F; $OUTL .= " { NULL, NULL },\n"; $OUTL .= " };\n";

$OutputFile =~ s{def$}{c};

if( open(OUT,$OutputFile) ){ my @old = <OUT>; close OUT; $oldfile = join( '' , @old); if( $oldfile eq $OUTL ){ next; } close OUT; }

open(OUT,">$OutputFile") or die "Cannot open output file $OutputFile"; print OUT $OUTL; close OUT;

}

[Contents]

8.12. t2h.pl

A special purpose texi-to-html converter used to document ScriptBasic.

The source code of the file is not included in this documentation because the file itself is too long for the purpose.

[Contents]

8.13. jamal.pl

The jamal preprocessor.

The source code of the file is not included in this documentation because the file itself is too long for the purpose.

[Contents]

9. UNIX Shell scripts

This chapter lists the UNIX shell scripts that are used to automate the code maintenance under the UNIX version of ScriptBasic.

[Contents]

9.1. install.sh

This script copies the compiled files to the installation directory and sets the various permissions. You have to be root to run this script. This is used by `Makefile'

The souce code of the file `install.sh' is:

# This script is invoked by the tool make when compiling ScriptBasic
#
# make install
#
# This script copies the compiled files to the installation
# directories and sets the owner, group and permissions of the
# files.
#
CONFIGDIR=/etc/scriba
INCLUDE=/usr/share/scriba/include
SOURCE=/usr/share/scriba/source
MODULE=/usr/lib/scriba
LIB=/usr/lib
CACHE=/var/cache/scriba/cache
HEBTEMP=/var/cache/scriba/hebtemp
BIN=/usr/bin
LOG=/var/log/scriba
ETC=/etc/init.d

mkdir -p $LOG chmod a+rw $LOG mkdir -p $CONFIGDIR chmod a+r $CONFIGDIR mkdir -p $INCLUDE chmod a+r $INCLUDE mkdir -p $SOURCE chmod a+r $SOURCE mkdir -p $MODULE chmod a+r $MODULE mkdir -p $LIB chmod a+r $LIB

# # clean old cache files that may # have been created by previous version # if [ -e $CACHE ] ; then rm -rf $CACHE/* fi mkdir -p $CACHE chmod a+rw $CACHE

if [ -e $HEBTEMP ] ; then rm -rf $HEBTEMP/* fi mkdir -p $HEBTEMP chmod a+rw $HEBTEMP

cp ./scriba $BIN/scriba chown root:root $BIN/scriba chmod a+rx $BIN/scriba

cp ./cftc $BIN/cftc chown root:root $BIN/cftc chmod a+rx $BIN/cftc

echo "Now I stop the Eszter SB Engine. This may fail if the" echo "engine is not running. Do not mind the error message." echo /etc/init.d/sbhttpd stop cp ./sbhttpd $BIN/sbhttpd chown root:root $BIN/sbhttpd chmod a+rx $BIN/sbhttpd cp ./etc-init.d-sbhttpd $ETC/sbhttpd chmod a+rx $ETC/sbhttpd echo echo "************************************************************" echo "The Eszter SB Application Engine (if it was running) was" echo "stopped to allow upgrade. It may happen that it was not" echo "running at all though. No problem." echo echo "Due to security reasons the installation process does not" echo "start or in case it was already running restart the server." echo echo "If you need Eszter SB Application Engine running then please" echo "start it saying:" echo echo "/etc/init.d/sbhttpd start" echo "************************************************************" echo

# this is commented out because we do not want to install # and start a http daemon on any system so that the system # manager may not be aware of it #/etc/init.d/sbhttpd start

# copy all the shared object modules cp ./*.so $MODULE chown root:root $MODULE/* chmod a+r $MODULE/*

# copy all the .bas include files cp ./include/* $INCLUDE chown root:root $INCLUDE/* chmod a+r $INCLUDE/*

# copy the scriba library file # it has to be changed to something libscriba.a or alike? cp ./basicc.a $LIB chown root:root $LIB/basicc.a chmod a+r $LIB/basicc.a

# copy the example preprocessor to the source directory cp ./heber.bas $SOURCE chown root:root $SOURCE/* chmod a+r $SOURCE/*

# # note that there is no reason to save the old CONFIGDIR file # because this CONFIGDIR file is a compiled binary file and # the 'real' information that the system manager should not # loose is at a location where he/she decided to store # usually under the name scriba.conf.unix.lsp # ./cftc scriba.conf.unix.lsp $CONFIGDIR/basic.conf

echo "************************************************************" echo "The ScriptBasic configuration file was updated using the" echo "default sample configuration file. In case you have already" echo "a configuration file that you have used reinstall it" echo "using the configuration compiler program saying:" echo echo "/usr/bin/cftc your_old_config_file $CONFIGDIR/basic.conf" echo echo "If you did not have a configuration from an older installation" echo "then start using the default configuration and save the text" echo "version of the default config file at a location you wish." echo "The text version of the default configuration is stored in" echo "the file scriba.conf.unix.lsp" echo "************************************************************"

[Contents]

9.2. convert.sh

Converts `convert.pl' to the UNIX CR/LF convention and then runs it to convert all the files. You have to execute this script after you have uploaded to source files froma Win32 workstation to a UNIX machine and have all the files with the wrong CR/LF line termination.

The souce code of the file `convert.sh' is:

#!/usr/bin/sh
perl uncr convert.pl > temp
mv temp convert.pl
perl convert.pl

[Contents]

9.3. uncr

A simple Perl script that converts stdin to stdout CR/LF to UNIX LF. This file is a one liner thus there is no CR/LF issue when this file is transferred.

Actually convert.sh converts `convert.pl' using this Perl script and then `convert.pl' converts the uploaded files safely.

The souce code of the file `uncr' is:

while( <> ){  while( /\r$/ || /\n$/ ){chop;}print "$_\n";}

[Contents]

9.4. mkdeb.sh

This shell script (used by `Makefile') cleans the directory `deb' and then copies all neccessary files, sets permissions and starts dpkg to create a Debian package of ScriptBasic.

The souce code of the file `mkdeb.sh' is:

CONFIGDIR=deb/scriba/etc/scriba
INCLUDE=deb/scriba/usr/share/scriba/include
SOURCE=deb/scriba/usr/share/scriba/source
MODULE=deb/scriba/usr/lib/scriba
LIB=deb/scriba/usr/lib
CACHE=deb/scriba/var/cache/scriba/cache
HEBTEMP=deb/scriba/var/cache/scriba/hebtemp
BIN=deb/scriba/usr/bin
LOG=deb/scriba/var/log/scriba
ETC=deb/scriba/etc/init.d

# # clean old version of the package # rm -rf deb/scriba/* rm deb/*.deb

# # insert the current build number into the control file # perl preparedeb.pl

# # copy the control files to the place where they have to be # to build the debian package # cp -R deb/DEBIAN deb/scriba chown root:root deb/scriba/DEBIAN chown root:root deb/scriba/DEBIAN/* chmod 075 deb/scriba/DEBIAN chmod 075 deb/scriba/DEBIAN/*

mkdir -p $CONFIGDIR mkdir -p $BIN mkdir -p $INCLUDE mkdir -p $SOURCE mkdir -p $MODULE mkdir -p $LIB mkdir -p $CACHE mkdir -p $HEBTEMP mkdir -p $LOG mkdir -p $ETC

cp ./scriba $BIN cp ./sbhttpd $BIN cp ./etc-init.d-sbhttpd $ETC/sbhttpd cp ./cftc $BIN cp ./*.so $MODULE cp ./*.a $LIB cp ./include/* $INCLUDE ./cftc scriba.conf.unix.lsp $CONFIGDIR/basic.conf cp ./heber.bas $SOURCE

chown -R root:root deb/scriba chmod -R 0755 deb chmod -R 0777 $CACHE chmod -R 0777 $HEBTEMP chmod -R 0777 $LOG cd deb dpkg --build scriba mv scriba.deb scriba-v10b`cat ../build.txt`-1_i386.deb

[Contents]

9.5. Makefile

Well, the Debian Linux Makefile to create ScriptBasic binaries.

Use, like:

The souce code of the file `Makefile' is:

CC=cc
LDOPTIONS=-shared
LD=ld
CCFLAGS=
CFLAGSS=-DSTATIC_LINK=1
LIBS=-lm -ldl -lpthread
OBJS=builder.o conftree.o dynlolib.o execute.o\
     expression.o filesys.o getopt.o lexer.o match.o\
     memory.o myalloc.o options.o reader.o report.o sym.o\
     syntax.o errcodes.o hookers.o modumana.o extops.o\
     uniqfnam.o epreproc.o md5.o ipreproc.o scriba.o
COBJS=environ.o external.o file.o function.o goto.o\
      if.o let.o mathfunc.o mathops.o print.o\
      string.o time.o while.o logger.o thread.o hndlptr.o\
      mygmtime.o basext.o
CHEADERS=command.h errcodes.h report.h sym.h\
         lexer.h expression.h builder.h memory.h\
         syntax.h execute.h syntax.h myalloc.h filesys.h ipreproc.h prepext.h\
         options.h uniqfnam.h

.PHONY: headers clean install all

all: headers scriba cftc cgi.so hash.so re.so basicc.a sbhttpd ux.so md5.so mt.so basic.conf gd.so zlib.so mysql.so dbg.so

deb: all sh mkdeb.sh

dpkg: deb echo "Next time type: make deb"

install: all sh install.sh

sourcepack : clean rm -rf scriba-1.0b`cat build.txt` mkdir scriba-1.0b`cat build.txt` ls -1|grep -v scriba-1.0b`cat build.txt` >tmp cp -R `cat tmp` scriba-1.0b`cat build.txt` rm tmp tar czf scriba-v1.0b`cat build.txt`-source.tar.gz scriba-1.0b`cat build.txt` rm -rf scriba-1.0b`cat build.txt`

rpm: sourcepack cp scriba-v1.0b`cat build.txt`-source.tar.gz /usr/src/redhat/SOURCES perl scriba-rpm.pl rpm -ba /usr/src/redhat/SPECS/scriba-rpm.spec

clean : rm -f *.a *.so *.o *.h syntax.c errcodes.c ./scriba ./sbhttpd ./cftc rm -rf deb/scriba/* rm -f deb/*.deb rm -f `find . -name \*.lib -print` rm -f `find . -name \*.dll -print` rm -f `find . -name \*.exe -print` rm -f `find . -name \*.cmd -print` rm -f `find . -name \*.bat -print` rm -f `find . -name \*.zip -print` rm -f `find . -name \*.gz -print` rm -f `find . -name \*.tar -print` rm -f `find . -name \*.aux -print` rm -f `find . -name \*.dvi -print` rm -f `find . -name \*.ps -print` rm -f `find . -name \*.tex -print` rm -f `find . -name \*.toc -print` rm -f `find . -name \*.exp -print` rm -f `find . -name \*.bbf -print` rm -f `find . -name \*.bkg -print` rm -f `find . -name \*.obj -print` rm -f `find . -name \*.ps -print` rm -f `find . -name \*.jar -print` rm -f `find . -name \*.tex -print` rm -f `find . -name \*.h_bas -print` rm -f `find . -name \*.pbt -print` rm -f `find . -name \*.log -print` rm -f `find . -name \*.c_ -print` rm -f `find . -name \*~ -print` rm -f `find . -name \*.thtml -print` rm -rf `find . -name \*Debug\* -print` rm -rf `find . -name \*imDebug\* -print` rm -rf `find . -name \*Release\* -print` rm -rf `find . -name \*imRelease\* -print` rm -f *.conf rm -rf gif rm -rf html rm -rf filesdoc rm -rf extensions/japi/reference rm -rf extensions/japi/c-examples rm -f Makefile.nt rm -f Makefile.OSF

headers : *.c extensions/cgi/cgi.c errcodes.c perl headerer.pl $?

scriba : $(OBJS) $(COBJS) scribacmd.o lmt_none.o $(CC) -o $@ $(LIBS) $(OBJS) $(COBJS) scribacmd.o lmt_none.o strip scriba ./scriba -v

sbhttpd : $(OBJS) $(COBJS) httpd.o websrv.o lmt_httpd.o cgi.o s_cgiinterface.o s_mt.o $(CC) -o $@ $(LIBS) $(OBJS) $(COBJS) httpd.o websrv.o lmt_httpd.o cgi.o s_cgiinterface.o s_mt.o strip sbhttpd

# -------------------------------------------------------------------- # # STATIC LINK MODULE LIST TABLE FILES # # -------------------------------------------------------------------- lmt_none.c : lmt_none.def perl lmt_make.pl $?

lmt_httpd.c : lmt_httpd.def perl lmt_make.pl $?

cftc : cftc.o confpile.o conftree.o lsp.o $(CC) -o $@ $(LIBS) cftc.o confpile.o conftree.o lsp.o

cftc.o : cftc.c $(CC) $(CCFLAGS) -c -o $@ cftc.c

confpile.o : confpile.c $(CC) $(CCFLAGS) -c -o $@ confpile.c

ipreproc.o : ipreproc.c $(CC) $(CCFLAGS) -c -o $@ ipreproc.c

lsp.o : lsp.c $(CC) $(CCFLAGS) -c -o $@ lsp.c

hash.so : hash.o $(LD) $(LDOPTIONS) -o $@ hash.o -lc

re.so : reinterf.o regcomp.o regerror.o regexec.o regfree.o $(LD) $(LDOPTIONS) -o $@ reinterf.o regcomp.o regerror.o regexec.o regfree.o -lc

ux.so : ux.o $(LD) $(LDOPTIONS) -o $@ ux.o -lc

cgi.so : cgi.o cgiinterface.o $(LD) $(LDOPTIONS) -o $@ cgi.o cgiinterface.o -lc

basicc.a : $(OBJS) $(COBJS) basicc.o lmt_none.o ar -r basicc.a $(OBJS) $(COBJS) basicc.o lmt_none.o

scribacmd.o : variations/standard/scribacmd.c getopt.h report.h\ lexer.h sym.h expression.h syntax.h reader.h myalloc.h\ builder.h memory.h execute.h buildnum.h conftree.h\ filesys.h $(CC) $(CCFLAGS) -c -o $@ variations/standard/scribacmd.c

websrv.o : variations/httpd/websrv.c getopt.h report.h\ lexer.h sym.h expression.h syntax.h reader.h myalloc.h\ builder.h memory.h execute.h buildnum.h conftree.h\ filesys.h $(CC) $(CCFLAGS) -c -o $@ variations/httpd/websrv.c

basicc.o : variations/standalone/basicc.c getopt.h report.h\ lexer.h sym.h expression.h syntax.h reader.h myalloc.h\ builder.h memory.h execute.h buildnum.h conftree.h\ filesys.h $(CC) $(CCFLAGS) -c -o $@ variations/standalone/basicc.c

hash.o : extensions/hash/hash.c $(CC) $(CFLAGS) -c -o $@ extensions/hash/hash.c

s_hash.o : extensions/hash/hash.c $(CC) $(CFLAGSS) -c -o $@ extensions/hash/hash.c

reinterf.o : extensions/re/reinterf.c $(CC) $(CFLAGS) -c -o $@ extensions/re/reinterf.c

s_reinterf.o : extensions/re/reinterf.c $(CC) $(CFLAGSS) -c -o $@ extensions/re/reinterf.c

regcomp.o : extensions/re/hsregex/regcomp.c $(CC) $(CFLAGS) -c -o $@ extensions/re/hsregex/regcomp.c

regerror.o : extensions/re/hsregex/regerror.c $(CC) $(CFLAGS) -c -o $@ extensions/re/hsregex/regerror.c

regexec.o : extensions/re/hsregex/regexec.c $(CC) $(CFLAGS) -c -o $@ extensions/re/hsregex/regexec.c

regfree.o : extensions/re/hsregex/regfree.c $(CC) $(CFLAGS) -c -o $@ extensions/re/hsregex/regfree.c

cgi.o : extensions/cgi/cgi.c extensions/cgi/cgi.h $(CC) $(CFLAGS) -c -o $@ extensions/cgi/cgi.c

ux.o : extensions/ux/ux.c $(CC) $(CFLAGS) -c -o $@ extensions/ux/ux.c

s_ux.o : extensions/ux/ux.c $(CC) $(CFLAGSS) -c -o $@ extensions/ux/ux.c

cgiinterface.o : extensions/cgi/cginterf.c extensions/cgi/cgi.h $(CC) $(CFLAGS) -c -o $@ extensions/cgi/cginterf.c

s_cgiinterface.o : extensions/cgi/cginterf.c extensions/cgi/cgi.h $(CC) $(CFLAGSS) -c -o $@ extensions/cgi/cginterf.c

scriba.o : scriba.c $(CC) $(CCFLAGS) -c -o $@ scriba.c

builder.o : builder.c filesys.h report.h lexer.h sym.h\ expression.h myalloc.h builder.h errcodes.h buildnum.h $(CC) $(CCFLAGS) -c -o $@ builder.c

lmt_none.o : lmt_none.c $(CC) $(CCFLAGS) -c -o $@ lmt_none.c

lmt_httpd.o : lmt_httpd.c $(CC) $(CCFLAGS) -c -o $@ lmt_httpd.c

conftree.o : conftree.c conftree.h errcodes.h filesys.h $(CC) $(CCFLAGS) -c -o $@ conftree.c

dynlolib.o : dynlolib.c $(CC) $(CCFLAGS) -c -o $@ dynlolib.c

execute.o : execute.c sym.h errcodes.h report.h lexer.h\ expression.h builder.h memory.h syntax.h execute.h myalloc.h $(CC) $(CCFLAGS) -c -o $@ execute.c

expression.o : expression.c errcodes.h report.h lexer.h\ sym.h expression.h myalloc.h $(CC) $(CCFLAGS) -c -o $@ expression.c

filesys.o : filesys.c filesys.h errcodes.h $(CC) $(CCFLAGS) -c -o $@ filesys.c

httpd.o : httpd.c httpd.h $(CC) $(CCFLAGS) -c -o $@ httpd.c

getopt.o : getopt.c $(CC) $(CCFLAGS) -c -o $@ getopt.c

lexer.o : lexer.c errcodes.h report.h lexer.h $(CC) $(CCFLAGS) -c -o $@ lexer.c

match.o : match.c match.h errcodes.h $(CC) $(CCFLAGS) -c -o $@ match.c

logger.o : logger.c logger.h $(CC) $(CCFLAGS) -c -o $@ logger.c

mygmtime.o : mygmtime.c mygmtime.h $(CC) $(CCFLAGS) -c -o $@ mygmtime.c

thread.o : thread.c thread.h $(CC) $(CCFLAGS) -c -o $@ thread.c

hndlptr.o : hndlptr.c hndlptr.h $(CC) $(CCFLAGS) -c -o $@ hndlptr.c

memory.o : memory.c errcodes.h memory.h myalloc.h $(CC) $(CCFLAGS) -c -o $@ memory.c

modumana.o : modumana.c basext.h sym.h errcodes.h report.h lexer.h expression.h\ builder.h memory.h syntax.h execute.h myalloc.h\ dynlolib.h modumana.h $(CC) $(CCFLAGS) -c -o $@ modumana.c

hookers.o : hookers.c basext.h sym.h errcodes.h report.h lexer.h\ expression.h builder.h memory.h syntax.h execute.h\ myalloc.h dynlolib.h hookers.h $(CC) $(CCFLAGS) -c -o $@ hookers.c

myalloc.o : myalloc.c myalloc.h $(CC) $(CCFLAGS) -c -o $@ myalloc.c

epreproc.o : epreproc.c epreproc.h myalloc.h $(CC) $(CCFLAGS) -c -o $@ epreproc.c

options.o : options.c sym.h errcodes.h report.h lexer.h\ expression.h builder.h memory.h syntax.h execute.h myalloc.h $(CC) $(CCFLAGS) -c -o $@ options.c

reader.o : reader.c filesys.h report.h errcodes.h conftree.h reader.h $(CC) $(CCFLAGS) -c -o $@ reader.c

report.o : report.c report.h errcodes.h $(CC) $(CCFLAGS) -c -o $@ report.c

sym.o : sym.c sym.h $(CC) $(CCFLAGS) -c -o $@ sym.c

basext.o : basext.c basext.h $(CC) $(CCFLAGS) -c -o $@ basext.c

uniqfnam.o : uniqfnam.c uniqfnam.h $(CC) $(CCFLAGS) -c -o $@ uniqfnam.c

md5.o : tools/md5.c tools/md5.h tools/global.h $(CC) $(CCFLAGS) -c -o $@ tools/md5.c

errcodes.c : errors.def perl generrh.pl

errcodes.o : errcodes.c errcodes.h $(CC) $(CCFLAGS) -c -o $@ errcodes.c

syntax.h : syntax.c perl headerer.pl syntax.c

syntax.c : syntax.def perl syntaxer.pl

syntax.o : syntax.c report.h lexer.h sym.h expression.h syntax.h $(CC) $(CCFLAGS) -c -o $@ syntax.c

command.h : command.c perl headerer.pl command.c

extops.o : commands/extops.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/extops.c

environ.o : commands/environ.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/environ.c

external.o : commands/external.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/external.c

file.o : commands/file.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/file.c

function.o : commands/function.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/function.c

goto.o : commands/goto.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/goto.c

if.o : commands/if.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/if.c

let.o : commands/let.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/let.c

mathfunc.o : commands/mathfunc.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/mathfunc.c

mathops.o : commands/mathops.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/mathops.c

print.o : commands/print.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/print.c

string.o : commands/string.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/string.c

time.o : commands/time.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/time.c

while.o : commands/while.c $(CHEADERS) $(CC) $(CCFLAGS) -c -o $@ commands/while.c

md5.so : md5interf.o $(LD) $(LDOPTIONS) -o $@ md5interf.o

mt.so : mt.o $(LD) $(LDOPTIONS) -o $@ mt.o

md5interf.o : extensions/md5/md5interf.c $(CC) $(CFLAGS) -c -o $@ extensions/md5/md5interf.c

s_md5interf.o : extensions/md5/md5interf.c $(CC) $(CFLAGSS) -c -o $@ extensions/md5/md5interf.c

mt.o : extensions/mt/mt.c $(CC) $(CFLAGS) -c -o $@ extensions/mt/mt.c

s_mt.o : extensions/mt/mt.c $(CC) $(CFLAGSS) -c -o $@ extensions/mt/mt.c

# # Preprocessor objects # dbg.o : preproc/dbg/dbg.c preproc/dbg/dbg.h preproc/dbg/dbg_comm.h $(CC) $(CFLAGS) -c -o $@ preproc/dbg/dbg.c

dbg_con.o : preproc/dbg/dbg_con.c preproc/dbg/dbg.h preproc/dbg/dbg_comm.h $(CC) $(CFLAGS) -c -o $@ preproc/dbg/dbg_con.c

gd.so : extensions/gd/gdinterf.c $(CC) -shared -o $@ extensions/gd/gdinterf.c -lc -lpng -lz -lgd

zlib.so : extensions/zlib/zlbintrf.c $(CC) -shared -o $@ extensions/zlib/zlbintrf.c -lc -lz

# The currently available version in Debian is 3.22 therefore this # macro is defined to compile the interface program for the version 3.22 mysqlinterf.o : extensions/mysql/mysqlinterf.c $(CC) -c -o $@ -DVERSION323=0 extensions/mysql/mysqlinterf.c

mysql.so : mysqlinterf.o $(LD) $(LDOPTIONS) -o $@ mysqlinterf.o -lc -lmysqlclient

dbg.so : dbg.o dbg_con.o $(LD) $(LDOPTIONS) -o $@ dbg.o dbg_con.o -lc

basic.conf : scriba.conf.unix.lsp cftc ./cftc scriba.conf.unix.lsp $@