Professional Documents
Culture Documents
Advanced Programmers Reference Manual
Advanced Programmers Reference Manual
Acknowledgements
jBASE, jBC, jED, jSHELL, jLP, jEDI, jCL, jQL, j1, j2 and j3 are trademarks of James Anthony Computing.
UNIX® is a registered trademark of X/Open Co. Ltd.
REALITY is a trademark of MDIS plc.
PICK is a trademark of Pick Systems Inc.
All other trademarks are acknowledged.
ii
Table of Contents
Using the Manual ....................................................................................................vii
Summary of Chapters.........................................................................................vii
Notation Conventions ...................................................................................... viii
Errata and Comments ...............................................................................................ix
Chapter 1: Introduction
Introduction to jBASE........................................................................................... 1-1
Run-Time Components .................................................................................... 1-1
Development Components............................................................................... 1-1
Administrative Components............................................................................. 1-1
Requirements for Running jBASE................................................................... 1-1
Application Development...................................................................................... 1-3
Migration ......................................................................................................... 1-3
Executable Paths.............................................................................................. 1-3
C Code Extensions........................................................................................... 1-3
ICONV and OCONV Extensions. ................................................................... 1-3
The IOCTL Function ....................................................................................... 1-3
jEDI Database Drivers..................................................................................... 1-3
jEDI API Calls................................................................................................. 1-4
Makefiles ......................................................................................................... 1-4
jbc and BASIC Commands .............................................................................. 1-4
jBuildSLib and CATALOG Command............................................................ 1-4
Advanced Tools ............................................................................................... 1-4
Notes on Examples .......................................................................................... 1-4
Chapter 2: Migration
Overview ............................................................................................................... 2-1
Application Source .......................................................................................... 2-1
Application Security ........................................................................................ 2-2
Application Connectivity ................................................................................. 2-2
Application Interchange................................................................................... 2-2
Application Backup ......................................................................................... 2-3
Exporting Applications.......................................................................................... 2-4
Importing Applications.......................................................................................... 2-5
Importing Accounts ............................................................................................... 2-6
Accountname v. Username .............................................................................. 2-6
User Port Numbers .......................................................................................... 2-6
Generating an Application Account ...................................................................... 2-7
Converting an Application..................................................................................... 2-9
Compiling an Application ................................................................................... 2-10
Cataloging an Application ................................................................................... 2-11
Chapter 4: C Extensions
Calling C Functions - Overview ............................................................................ 4-1
Simple C Example................................................................................................. 4-2
Fundamental Components of C Interfaces............................................................. 4-3
Chapter 9: Makefiles
Introduction ........................................................................................................... 9-1
Index
Run-Time Components
The run-time components are designed for freedom of choice, efficiency and ease of use.
They consist of:
• The jBASE External Device Interface (jEDI), which provides database independence and distributed
processing capabilities;
• jBASE’s own family of NF2 file systems, namely j1 and j2 files;
• The jBASE query language (jQL).
Development Components
The development tools are designed for highly productive development, simple migration and run-time
efficiency of resulting software.
They consist of:
• A set of tools for easy migration to jBASE from existing environments;
• The jBC Programming Language - a compiled language and a superset of Dartmouth BASIC which
allows structured programming. Note that the jbc compiler can also be directed to produce C or C++
source code;
• A set of development editors and debugging tools;
• The jBASE job control language (jCL).
Administrative Components
Being an enhancement and extension of the UNIX and the Windows family of Operating Systems, jBASE takes
advantage of all the administrative functionality of the host environments. However, there are some extra
facilities provided over and above those of the host environment.
They include:
• The jBASE Spooler (jLP)
• Utility programs such as jbackup and jrestore
Migration
The normal migration path simply involves a save of the application source code and data in one environment,
and then restoring and converting it in the jBASE environment. The Migration chapter gives more details of the
migration path.
Executable Paths
By default, executable programs will be found in the directory given by the expression $HOME/bin. This
directory is where the CATALOG command will create UNIX executables. Any SUBROUTINE objects found
by the CATALOG command will be placed in the directory $HOME/lib.
The Execute Paths chapter shows how these defaults can be amended to suit your development and live
environments.
C Code Extensions
The jBC language provide a rich set of intrinsic functions for the application programmer. There are
circumstances when you may want to extend the standard set by writing your own functions in the C language.
The C Extensions chapter gives details on how you can do this.
Makefiles
A typical UNIX development environment will make use of a development tool called ‘make’. This same facility
can be used with jBASE programs and allows a jBASE developer to describe to UNIX the application sources
and a set of rules showing how to build the application from the sources. The chapter entitled Makefiles shows
how to use this very useful UNIX facility within a jBASE development environment.
Advanced Tools
There are several tools available to the advanced programmer, for profiling support for example. These tools are
detailed in the Advanced Tools chapter.
Notes on Examples
Throughout the manual there are many examples of programs being executed from the UNIX shell. All the
examples assume the command will be run from the Korn shell (or ksh) program. Of the many shells available to
UNIX systems, this is the most popular.
Use of the Korn shell is usually denoted by a % (percent) character at the start of the command line. For
example:
% jbc prog.b -Jo
If you use a different shell, such as the C shell or 'csh', you will need to amend the command slightly. For
example, the Korn shell (ksh) command:
% LD_LIBRARY_PATH=/home/lib prog > progout 2>&1
would look like this under the csh program
% setenv LD_LIBRARY_PATH=/home/lib
% prog >& progout
Application Source
The application source can be categorised as shown below. The logical location of each category should be
noted and any associated logistical problems resolved. The most common problem is how to effect a transfer of
the application source from one environment to the other.
BASIC Source
• In-house source
• Code items.
• Include items.
• Enabling/protection mechanisms.
• Third party source.
• Code items.
• Include items.
• Enabling/protection mechanisms.
• License agreements.
• Maintenance agreements.
• System utilisation.
• User exits.
• Function anomalies.
• Language anomalies.
PROC Source
Any frequently used PROCs provided by the system should be noted, as similar functionality may be required.
The type of procedural source style (i.e. PQ or PQN), should be noted for in-house or third party generated
source code.
• In-house source
• Code items.
• Enabling/protection mechanisms.
• Third party source.
• Code items.
Data/Report Retrieval
Notes should be accumulated of any retrieval language requirements, especially with regard to the use of user
exits and external file cross references.
Control Source
All control records (e.g. execution control records, etc.) should be set to an initialised or known state before the
application is saved for transfer. Any utilisation of existing system files and records (e.g. logon records, etc.)
should be recognised and noted.
• In-house control records.
• Third party control records.
• System utilisation.
DATA Source
The location of data files and records external to, but utilised by, the application should be noted. Once
migrated, the application should be able to be fully tested with ‘real’ test data in order to highlight any
anomalies.
Before an application can go ‘live’, application dependent data files must be transferred from the current source
environment. These data file transfers represent the minimum delay period between switching users from the
original to the migrated application. It should be recognised that to retain database integrity the source and
migrated application should be closed to users for the duration of the application backup period and also for the
duration of the restoration period.
Application Security
The current environment for application security should be reviewed with respect to the new environment. This
should be undertaken to ensure that the integrity of the application, and the files on which the application
depends, cannot be jeopardised by unauthorised users.
A view should also be taken as to modifying the existing security arrangements to utilise any new more secure or
powerful features not previously available.
Application Connectivity
The application connection methods for both incoming and outgoing application connections by users,
background processes, clients and servers should be reviewed with respect to the new environment. Areas that
tend to become afterthoughts are modem connections and printing requirements. An appraisal of both system and
local printing requirements along with terminal and special device connectivity should be undertaken.
Application Interchange
Any currently employed transfer techniques, which allow interchange of data or control information with
external systems or applications, should be fully considered. Magnetic tape media transfers tend to be the most
problematic, due to the wide range of manufacturers specifications. Careful attention should be given to
understanding the full implications of media mismatch. Interchange problems may still occur even though the
interchange media is the same - for example, EOT (end of tape) handling.
Accountname v. Username
It is likely that the existing application is executed from a single account and that all users logon to the
application Accountname. This approach is still possible on the UNIX system, in that all users may login to the
same UNIX user id, which would be set to the application Accountname.
The application account name or user id would normally be a lower case version of the original account name -
limited to 8 characters. The reason for lower case is historically related to the way the UNIX login process
attempts to handle upper case only devices, by converting upper case to lower case at login time. Once logged in,
the user’s .profile file runs the application start up program.
An alternative method is to allocate each user a unique personal user id. UNIX systems are able to implement
security on a user id basis. The users may all utilise the same $HOME directory and different users may then be
granted individual group and execution permissions - providing useful security checks within the application.
Some applications rely on the account name to implement their own security routines or it may be that the
account name has been hard-coded within the application. This situation can be handled in jBASE by setting the
environment variable, JBCLOGNAME, to the original Accountname. This can be achieved by executing the
shell commands below.
JBCLOGNAME=ACCNAME ; export JBCLOGNAME
Example 1
% mkdir mysource
% cd mysource
% vi prog.b
% cd ..
% BASIC mysource prog.b
Example 2
% vi ./prog2.b
% BASIC . prog2.b
Example 3
% mkdir $HOME/src
% JED $HOME/src/prog3.b
% jbc $HOME/src/prog3.b -o $HOME/bin/prog3
Example
Create a main program and a subroutine, and compile them.
% mkdir src
% vi src/mainprog
% vi src/sub1
% BASIC src mainprog sub1
Example
Create a main program and a subroutine, compile them and create executables.
% mkdir src
% vi src/mainprog
% vi src/sub1
% BASIC src mainprog sub1
% CATALOG src mainprog sub1
Following the above steps, there will be an executable UNIX program at $HOME/bin/mainprog and a shared
object containing the SUBROUTINE in the directory $HOME/lib.
Example 1
Execute from a shell.
% mainprog
Example 2
Execute from another jBC program.
% COPY src a.n.other.b \(T
a.n.other.b
001 EXECUTE “mainprog”
Example 3
Use an explicit path name
% $HOME/bin/mainprog
Example
Assume the environment variable JBCOBJECTLIST is set up as:
% export JBCOBJECTLIST=
/home2/pipe/lib/libtest.el:/home2/slip/release
and that environment variable JBCRELEASEDIR is set up as:
% export JBCRELEASEDIR=/usr/jbcdev
When the first CALL statement is executed, the library code will:
• Open file /home2/pipe/lib/libtest.el and parse the file.
• Open directory /home2/slip/release and parse for all files with a ‘.el’ suffix.
• Open directory /usr/jbcdev and parse all files with a ‘.el’ suffix. The exception to this are the shared
objects that either have already been parsed, or the shared objects that are currently in use by the jBC
run-time library.
The parsing of the ‘.el’ files tells the library code about the shared object. There are two formats of an ‘.el’ file.
The first format of an ‘.el’ file is that created by the jBuildSLib command. In this case, the file might look
something like this:
% COPY . apps.com.el \(T
apps.com.el
001 JBC_SUB1
002 JBC_DOTHIS
003 JBC_DOTHAT
This tells the library code that a file named ‘apps.com.so’ exists and that it contains three jBC subroutines,
SUB1, DOTHIS and DOTHAT.
The second format of a ‘.el’ file is that created by the CATALOG command. In this case, the file might look
something like this:
% COPY . libpipeman.el \(T
libpipeman.el
001 JBC_SUB1\JBC_DOTHIS]JBC_SUB2\JBC_DOTHAT
002 libpipeman0.so]libpipeman1.so
003 SUB1.o\DOTHIS.o]SUB2.o\DOTHAT.o
Example 1
Make program accessible to others.
It is very easy to allow other users to access the programs you have created in a directory. Assuming the program
is ‘/home/pipex/bin/countslip’, the user simply has to do one of the following:
• Put the directory /home/pipex/bin into their HOME environment variable, for example:
% export PATH=$PATH:/home/pipex/bin
% countslip
• Call the program using an absolute path name, for example:
% /home/pipex/bin/countslip
Note that UNIX permissions apply to these programs.
Example 2
Copy a program to a common ‘live’ directory. This example shows how a program can be copied from say, a
development account to a live account.
To copy program countslip from the account ‘dev’ (which we assume the user is logged on to) to the account
‘d4live’ (which the live users log on to), you would do something like this:
% cp $HOME/bin/countslip ~d4live/bin
Before you make the copy, you must to consider if any users are currently using the live program countslip, or
are about to use it. You can check for current usage with the WHERE command, for example:
% WHERE | grep countslip
Depending upon the implementation of UNIX, if you copy over an active program, either the copy will fail, or
the copy will succeed but the user running the original copy will probably get a segmentation violation.
You can ensure you don’t have any segmentation violations by one of two methods:
• Remove the original live program before copying the new one. This will works but means that the live
application may fail if it tries to load the program after the old one is removed and before the new one is
copied. Note that removing a program does not affect any users currently using it. For example:
% rm ~d4live/bin/countslip
% cp $HOME/bin/countslip ~d4live/bin
• Inhibit logons to jBASE using the INHIBIT-LOGONS command, log off all current users, perform the
copy and then allow users to log back on by using the ENABLE-LOGONS command. The following
example assumes you are root user:
% INHIBIT-LOGONS \*
% MSG \* Please log off in the next 60 seconds ...
% SLEEP 60
% WHERE
% LOGOFF nnnn # repeat for all users logged on
% cp $HOME/bin/countslip ~d4live/bin
% ENABLE-LOGONS \*
Example 4
Copy subroutines to another ‘live’ directory.
This entails copying all your subroutines to another directory. The example assumes that subroutines in a
development account are being copied to a ‘live’ account - from the lib directory of account ‘dev’ to the lib
directory of account ‘live’. You must copy not only the shared object, but also the descriptor file - the files that
have a ‘.el’ suffix.
% find ~dev/lib \( -name ‘*.so’ -o -name ‘*.el’ \)
-exec cp {} ~/live/lib \;
As for Example 2 above, you must not overwrite the shared object if a user is using the shared objects. Again,
some versions of UNIX allow the copy to proceed and the final result is a segmentation violation, other versions
of UNIX will make the copy fail. Use the same techniques as described earlier for copying programs, e.g.
INHIBIT-LOGONS, LOGOFF, ENABLE-LOGONS.
A common mistake made during this procedure is the naming of the shared objects. When using the CATALOG
command, the name of the account is relevant. For example, if you were to have a number of subroutines that
have been made into shared objects using the CATALOG command, in account dev, you might also have files
libdev0.so, libdev1.so, libdev.el. Now assume that the account ‘live’ also has the same subroutines that have
been made into shared objects in the ‘live’ account using the CATALOG command. The names of these files
would be liblive0.so, liblive1.so and liblive.el. Therefore, when you copy the files from account ‘dev’ to account
‘live’, they would not over-write whatever is there because the names of the files differ. Instead, they would
“complement” the existing files. Because of these duplicates, it is impossible to say which would be the first
copy accessed when a jBC program that accesses subroutines in the ‘live’ account is run.
Example 5
Copy selected subroutines to a common ‘live’ directory.
When you use the CATALOG command, it puts the object code into a shared library. For performance reasons,
it will build a number of small shared libraries, rather than one large shared library. This means that when you
CATALOG an object you cannot be sure which shared library is has gone into in the $HOME/lib directory, or
what other subroutines are also in the library.
There may be occasions when you want to selectively copy objects to another destination. For example, you may
have a ‘SECURITY’ subroutine that is common to all applications on your system, that resides in an account
called ‘security’. You have a new version of SECURITY that you have CATALOGed and tested from account
‘dev’. The basic steps are:
• Log into the target account, in this example the target account name is security.
% su - security
Password:
Naming Conventions
The supported jBASE functions and macros follow a simple naming convention which follows the format
FUNCNAME_RPPPPP where FUNCNAME describes the functionality, R describes the return value from the
function/macro and P describes any number of parameters to be passed to the function/macro. The values for R
and P can be any of the following:
I 32 bit integer
F Floating point value in jBASE floating format
B The address of a jBASE VAR structure.
V Void
S An array of STRING type characters that are not necessarily 0 terminated.
For example, the macro COUNT_IBB is provided. This shows the functionality belongs to the COUNT
function, the function returns a 32 bit integer and requires 2 parameters, both of them the address of a jBASE
VAR structure.
VAR Variable
This is the definition of the fundamental variable used throughout a jBC program. It has a complex structure, and
definitions have been provided for access to the various elements. The VAR variable is a typeless variable and
can assume many types, such as an INT32 integer, a FLOAT floating point value and so on. There are many
function calls and macros provided to convert between these types, to access these types within a VAR variable,
or to update a VAR variable with various types. These are all documented later.
INT32 Variable
This is a definition of a 32 bit integer used internally by jBC. This provides portability with architectures that use
64 bit integers. Therefore, when interfacing with jBC variables, always use the ‘INT32’ definition instead of
‘int’.
STRING Variable
This is a definition of an unsigned character. The usual format within a C function is to use the ‘STRING *’
type, which is a pointer to an array of unsigned characters. The array may or may not be terminated with a 0
(null) character.
The ‘char *’ type is a pointer to an array of signed characters, and ‘STRING *’ is a pointer to an array of
unsigned characters. You can usually cast one to another freely in order to avoid compilation warning messages.
For example:
char buffer[128] ;
sprintf(buffer,”KEY_%d”,rand());
STORE_VBS(Var, (STRING*) buffer);
In the above example, sprintf() requires a pointer to an array of signed characters, whereas STORE_VBS
requires a pointer to an array of unsigned characters. Usually these are transposable and can be cast.
The reason for using unsigned character arrays is that within code it is easier and more correct to use unsigned
characters when dealing with values above 127, such as delimiters and attribute marks. For example, the
following code is incorrect:
char buffer[128] ;
buffer[0] = 254 ;
Function Prototypes
For each different external C function you want to reference, there must be a description of the function provided
to the compiler. These descriptions are called function prototypes. They tell the compiler the name of the
function, the return type from the function, and the type of each parameter passed.
For example, consider a C function which has 3 parameters (2 integers and 1 VAR), and returns an integer. The
jBC code might look something like this:
DEFC INT MyFunc(INT, INT, VAR )
V1 = 12
V2 = 34
V3 = “Where are my pipe and slippers ?”
PRINT “Result of MyFunc = “ : MyFunc(V1, V2, V3 )
The following keywords can be used in the function prototype in a jBC program to define the return value and
parameters that the C function expects:
INT A 32 bit integer. Although INT is the keyword used in the function prototype, in the C source code
you would use the INT32 type.
STRING A pointer to an array of STRING types, the last element in the array being a 0 (null). Although
STRING is the keyword used in the function prototype, in the C source code you would normally
use ‘STRING *’ to show it is a pointer to an array of STRING characters.
VAR A pointer to a jBC variable, which can be a user variable or register variable (the differences are
noted later). Although VAR is the keyword used in the function prototype, in the C source code
you would normally use ‘VAR *’ to show that it is a pointer to a VAR type. Within this complex
typeless structure can be INT32 variables, or FLOAT variable and so on. A range of function and
macros are detailed later to extract and insert these types from and into the VAR structure.
FLOAT A floating point number using jBC internal representation.
#include <jsystem.h>
INT32 MyFunc( VAR * param1)
{
/* ??? */
return 123;
}
When the function MyFunc is called, the parameter passed is the address of the variable ‘Detail’. At this point no
type conversion has occurred. When function MyFunc wants to examine the variable passed as the first
parameter (in the C variable param1), it will usually want to force it to be a certain type.
If it needs to be of type INT32, the function could do this:
INT32 I1 ;
I1 = CONV_IB(param1);
If it needs to be a 0 (null) terminated string, it could do this:
STRING * S1 ;
S1 = CONV_SFB(param1);
A full list of conversion functions and macros are provided later in this chapter.
STORE_BBF(Target,Numeric)
Store a FLOAT type variable into a VAR variable, and return the address of the Target VAR variable. Consider
a function that takes two floating point values, multiplies them and returns the result. The jBC source would look
like this:
DEFC VAR Mul2(FLOAT, FLOAT)
INPUT float1
INPUT float2
res = Mul2(float1,float2)
PRINT “The result is “ :res
The C function source would look like this:
#include <jsystem.h>
VAR * Mul2(VAR * result, FLOAT value1, FLOAT value2)
{
return STORE_BBF(result,
MUL_FFF(value1, value2));
}
STORE_VBF(Target,Numeric)
Same as STORE_BBF, except a void is returned.
STORE_BBB(Target,Source)
Make an identical copy of a VAR variable, and return the address of the Target VAR variable.
The Source variable can be of any type, for example integer, float, file descriptor, select list and so on.
If Source is the same as Target, no operation is performed.
If the Source variable is a register variable, the contents of Source are deleted and become indeterminate. This is
a performance feature - what actually happens is that instead of the Source variable being copied, just the
pointers are copied and the operation is substantially quicker.
STORE_VBB(Target,Source)
Same as STORE_BBB except a void is returned.
STORE_BBI(Target, Numeric)
Store an INT32 type variable into a VAR variable, and return the address of the Target VAR variable. Consider
a function that takes two integer values, performs a logical XOR on them and returns the result. The jBC source
would look like this:
STORE_VBI(Target, Numeric)
Same as STORE_BBI except a void is returned.
CONV_FI(Integer)
Given a 32 bit integer, convert it to a FLOAT. For example, could be used to multiply a FLOAT with an INT32
as follows:
FLOAT result, value1 ;
INT32 int1 ;
/* Set up value1 and int1 */
result = MUL_FFF(value1, CONV_FI(int1)) ;
CONV_IF(Float)
Given a FLOAT return a 32 bit integer.
CONV_IB(Source)
Given the address of a VAR type BASIC variable, perform type conversions on the variable and return the
INT32 value. If the Source variable contains a value that cannot be converted, such as a non-numeric STRING, a
file descriptor, or a select list, an error message is displayed and the debugger is entered. If the variable is
already an INT32, a simple extraction takes place. Consider the previous example where we generate two record
keys, each with a random element, based on a seed value passed. This time the third parameter is passed as a
VAR pointer instead of an INT32, and the MakeKeys function has to perform its own type conversion. The jBC
source may look like this:
DEFC MakeKeys(VAR, VAR, VAR)
PRINT "Enter seed : ":
INPUT Seed
MakeKeys(Key1, Key2, Seed)
PRINT "Record key 1 = " : Key1
PRINT "Record key 2 = " : Key2
The C source would look something like this:
#include <jsystem.h>
INT32 MakeKeys(VAR * Key1, VAR * Key2, VAR *Seed)
{
char buffer[128] ;
INT32 SeedConv ;
/*
* Convert the STRING in ‘Seed’ to an integer.
*/
SeedConv = CONV_IB(Seed) ;
sprintf(buffer,"key_cust_no*%d",rand() % SeedConv);
STORE_BBS(Key1, (STRING*)buffer);
sprintf(buffer,"product/*%d",rand() % SeedConv);
STORE_BBS(Key2, (STRING*)buffer);
return 0;
}
CONV_SB(Source)
Ensures a variable is of type STRING and returns the address of the first character of the array of characters. Use
CONVLEN_IB to find the length of the string. If the type was one of the numeric types, a type conversion will
take place as well. For example, an INT of 123 will be converted to a STRING of “123”.
If the type was neither a STRING, nor any type that could be converted to a STRING (such as a file descriptor
or a select list), an error message is displayed and the debugger entered. If the user then enters ‘c’ to continue,
this function will convert Source to a 0 length string.
CONVLEN_IB(Source)
Similar to CONV_SB except instead of returning the address of the start of the string, it returns the length of the
string.
CONV_SFB(Source)
Similar to CONV_SB except the STRING will be terminated with a 0 (null) character. This is often useful for
passing as a parameter to other C functions that depend on 0 terminated strings. The following example shows a
C function returning 1 if a UNIX file exists, or 0 if it does not exist. First the jBC code
DEFC Exists(VAR)
PRINT "Enter UNIX file name to test : ":
INPUT FileName
CONVTYPE_IB(Source)
This returns the type of the jBC variable. The different types that can be returned include:
VAR_TYPE_FLOAT The variable is in the format of a FLOAT.
VAR_TYPE_INT The variable is in the format of an INT32.
VAR_TYPE_FLOAT_INT The variable is in both the FLOAT and INT32 formats.
VAR_TYPE_STRING The variable is a STRING type.
VAR_TYPE_FILE The variable is an opened file descriptor.
VAR_TYPE_SELECT The variable is a list of record keys, or select list.
STRING_INITIALISE_REG_VB(Variable)
Initialise the elements of a VAR variable so that it looks like an uninitialised register variable to other jBC
functions. This must always be used on a variable before attempting to modify that variable. A typical example
is:
INT32 MyFunc()
{
VAR Var ;
STRING_INITIALISE_REG_VB(&Var);
STRING_INITIALISE_USER_VB(Variable)
Initialise the elements of a VAR variable so that it looks like an uninitialised user variable to other jBC
functions.
STRING_RELEASE_EXT_VB(Source)
All the external resources associated with the variable ‘Source’ are released. For example, if it were an opened
file descriptor then the file will be released. If it were a STRING type variable, then the storage space associated
with it will be released, even if it is a 0 length string.
STRING_RELEASE_REG_VB(Source)
Similar to STRING_RELEASE_EXT_VB except that small STRINGs are not released. This function is useful
where variables are going to be re-used more than once, and can bring performance benefits by not repeatedly
allocating and freeing small strings. You should not use it for automatic variables declared in the C function.
Consider the following example:
INT32 MyFunc()
{
VAR Var ;
STRING_INITIALISE_REG_VB(&Var) ;
STORE_VBS(&Var, (STRING*) “1234567890”);
STRING_RESIZE_VBI(Target, Length)
This will re-size the variable ‘Target’ of type STRING to become length ‘Length’ in size. The original contents
will be preserved. This is useful, for example, to make a variable larger to add some extra information at the end.
It is also useful to truncate the current contents of a variable.
If the variable ‘Target’ is not already of type STRING, the content of the variable will be lost, or if a file
descriptor, the file will be closed. If you do not want to retain the original contents of the variable, use the
STRING_MAKE_NEW_VBIS functionality - keeping the contents is a potential overhead you do not need.
command can be any numeric value (or variable containing a numeric). However, it is up to the
database driver to support that particular command number. The remainder of this chapter
describes the common IOCTL command numbers supported by the jBASE database drivers
provided.
status pass here a jBC variable. The use of this variable depends upon the command parameter, and
will be described later for each command supported.
The return value is 0 for failure, or 1 for success. A value of -1 generally shows the command has not been
recognised.
This remainder of this chapter will deal with the IOCTL commands that are supported by the provided jBASE
database drivers, and the JBC_COMMAND_GETFILENAME command that is supported for all database
drivers.
Example
Open the file CUSTOMERS and find out the exact UNIX path that was used to open the file.
INCLUDE JBC.h
OPEN “CUSTOMERS” TO DSCB ELSE STOP 201,”CUSTOMERS”
filename = “”
IF IOCTL(DSCB,JBC_COMMAND_GETFILENAME,filename) ELSE
CRT “IOCTL failed !!” ; EXIT(2)
END
PRINT “Full file path = “:DQUOTE(filename)
This command is executed by the jBC library code rather than the jEDI library code or the database drivers, so it
can be run against a file descriptor for any file type.
Example 2
Read a record from a file, and find out if the last record read was in text format (were new-lines converted to
attribute marks and the trailing new-line deleted), or in binary format (with no conversion at all)
INCLUDE JBC.h
OPEN “.” TO DSCB ELSE STOP 201,”.”
READ rec FROM DSCB,”prog.o” ELSE STOP 202,”prog.o”
status = “RS”
IF IOCTL(DSCB,JIOCTL_COMMAND_CONVERT,status) THEN
IF status EQ “T” THEN
PRINT “prog.o read in TEXT format”
END ELSE
PRINT “prog.o read in BINARY format”
END
END ELSE
CRT “The IOCTL failed !!”
END
Example 1
Open a file and see if the file type is a UNIX directory.
INCLUDE JBC.h
OPEN “..” TO DSCB ELSE STOP 201,”..”
status = “”
IF IOCTL(DSCB,JIOCTL_COMMAND_FILESTATUS,status) ELSE
CRT “IOCTL failed !!” ; EXIT(2)
END
IF status<1> EQ “UD” THEN
PRINT “File is a UNIX directory”
END ELSE
PRINT “File type is “:DQUOTE(status<1>)
PRINT “This is not expected for ..”
END
Example 2
Open a file ready to perform file operations in a transaction against it. Make sure the file has not been removed
as a transaction type file by a previous invocation of the command ‘jchmod -T CUSTOMERS’.
INCLUDE JBC.h
OPEN “CUSTOMERS” TO DSCB ELSE STOP 201,”CUSTOMERS”
IF IOCTL(DSCB,JIOCTL_COMMAND_FILESTATUS,status) ELSE
CRT “IOCTL failed !!” ; EXIT(2)
END
IF status<8,2> THEN
CRT “Error ! File CUSTOMERS is not”
CRT “part of transaction boundaries !!”
CRT “Use ‘jchmod +T CUSTOMERS’ !!”
EXIT(2)
END
Example
Before writing out a control record, make sure it doesn’t already exist. As the control record is quite large, it will
provide performance gains to simply test if the output record already exists, rather than reading it in using the
READ statement to see if it exists.
INCLUDE JBC.h
OPEN “outputfile” TO DSCB ELSE STOP 201,”outputfile”
... Make up the output record to write out in ‘output’
key = “output.out”
rc = IOCTL(DSCB,JIOCTL_COMMAND_FINDRECORD,key)
BEGIN CASE
CASE rc EQ 0
CRT “No further action, record already exists”
CASE rc GT 0
WRITE output ON DSCB,key
PRINT “Data written to key “ : key
CASE 1
CRT “IOCTL not supported for file type”
END CASE
Example
Open a file, and find out what bucket number the record “PIPE&SLIPPER” would be found in.
INCLUDE JBC.h
OPEN “WEDDING-PRESENTS” TO DSCB ELSE STOP
key = “PIPE&SLIPPER”
parm = key
IF IOCTL(DSCB,JIOCTL_COMMAND_HASH_RECORD,parm) THEN
PRINT “key “:key:” would be in bucket “:parm<2>
END ELSE
CRT “IOCTL failed, command not supported”
END
Example
Lock a record in a file and find out what the lock id of the record key is. The example then calls the jRLA
locking demon and the display of locks taken should include the lock taken by this program
INCLUDE JBC.h
DEFC getpid()
OPEN “WEDDING-PRESENTS” TO DSCB ELSE STOP
key = “PIPE&SLIPPER”
parm = key
IF IOCTL(DSCB,JIOCTL_COMMAND_HASH_LOCK,parm) ELSE
CRT “IOCTL failed, command not supported”
EXIT(2)
END
PRINT “The lock ID for the key is “:parm
PRINT “Our process id is “ : getpid()
READU rec FROM DSCB,key ELSE NULL
PRINT “Locks taken so far : “
EXECUTE “jRLA -dv”
myfile........
reca
recb
recc
3 Records Listed
Some assumptions have been made in this example:
• That the directory $HOME is a component part of the JEDIFILEPATH environment variable, or the
JEDIFILEPATH variable is not set.
• That the directory $HOME/lib is a component part of the JBCOBJECTLIST environment variable or the
JBCOBJECTLIST variable is not set.
At this stage is it worthwhile understanding the chain of event that occur when accessing the newly created
shared object database driver in the above example. The mechanism inside the jBASE run-time library is as
follows:
• The OPEN “myfile” statement in the jBC source generates a function call to the JLibFOPEN function, as
supplied by the jBASE run-time libraries.
• The JLibFOPEN function generates a call to the generic OPEN function inside the jEDI library.
• The jEDI OPEN function will attempt to open a UNIX file called “myfile” in all the directories that are
contained in the JEDIFILEPATH environment variable. Eventually the UNIX file $HOME/myfile will be
opened.
• The jEDI OPEN function will now ask all the established database drivers if the file is one that belongs to
their type. The database driver for shared objects will understand this as the first 8 characters are JBC__SOB.
• The shared object database driver will attempt to use code in the jBC run-time library to execute a function
taken from shared objects called “ExampleInit”. The mechanism happens to be the same mechanism that is
used for the CALL statement. This will succeed, and the ExampleInit() function will establish itself as a
database driver in its own right.
• The shared object database driver will now pass control to the OPEN function defined when the database
driver was established in the call to ExampleInit. Control of the OPEN now passes outside of jEDI and into
the user-written OPEN code.
• The user-written OPEN code now has freedom to do anything it likes. In the example code, it will simply
concatenate the strings “$HOME/myfile” and “.d” to create a name “$HOME/myfile.d” and expect this to be
an existing UNIX directory.
• Assuming the user-written OPEN returned a successful code, the OPEN statement now completes. Any
future database operations such as READ, WRITE and so on will now be passed to the functions defined by
the ExampleInit() function as being responsible for the various operations.
The remainder of this topic details all the functions required to create a shared object database driver conforming
to the jEDI API. They would normally be in one source code. Only a single function is required to be visible, the
remainder can be defined as ‘static’.
Note: Although the database driver is only responsible for the above return values, the jEDI code may
return other codes to the calling application outside the control of the database driver. These codes are
EDEADLK (when a deadly embrace has been detected and avoided), and
JEDI_ERRNO_LOCK_TAKEN (when a lock with NO WAIT was specified, and the lock was already
taken by another process).
/*
* Create the first field as a string followed
* by a field delimiter, taken from a 4
* byte integer.
*/
outputlen = sprintf(output,
”%d\376”,*((int*)&record[0]));
/*
* Now add the second field to the output record.
* This is a 20 character field.
*/
memcpy(&output[outputlen],&record[4],20);
/*
* Finally add the field delimiter for the
* second field, and create the third field taken
* from a floating point number.
*/
outputlen += (20 + sprintf(
&output[outputlen+20],
”\376%f”,*((float*)&record[24]));
This conversion process can specifically be bypassed by the calling application if required. This may be
needed from time to time for certain applications to read in the data in binary format without any
conversions. The read record function should check the integer at FileDescriptor->ConvertFlags to see
what sort of conversion should take place (see the OPEN and IOCTL functions).
The example below shows a simple read record process that simply returns 4 fields in a record, each field
delimited by 0xfe (or 0376 in octal). No account of any record locks is made, no account of reading
single fields is allowed for and no account of any conversions is used.
char temprecord[4096];
int temprecordlen ;
int linecount ;
/*
* Create the record, delimited by 0xfe
* (or 376 in octal), in a temporary automatic
* variable. This record will just be the name of
* the record key copied 4 times. This means
* we will have 3 field delimiters.
*/
for (temprecordlen = linecount = 0 ;
if ((DirPtr = opendir(FileDescriptor->PathName))
== NULL)
{
return errno;
}
while ((Next = readdir(DirPtr)) != NULL)
{
if ((ReturnValue=JediBaseSignalCheck()) != 0)
{
break;
}
strcpy(PathName,FileDescriptor->PathName);
strcat(PathName,"/");
strcat(PathName,Next->d_name);
/*
* Find out the type of the entry. We will not
* attempt to delete anything other than
* regular files.
*/
if (stat(PathName, &stat_info) == 0)
{
if (stat_info.st_mode & S_IFREG)
{
unlink(PathName);
}
}
}
closedir(DirPtr);
return 0;
ReturnValue = 0;
switch(SubCommand)
Starting a Transaction
if (JediTransLog(JEDI_TRANSLOG_COMMAND_START, Flags,
“message”) != 0)
{
perror(“TRANSTART”);
}
Where:
JEDI_TRANSLOG_COMMAND_START Tells the function to start a transaction boundary.
Flags If the JEDI_TRANSLOG_FLAGS_SYNC bit is set, following the termination of the
transaction though an abort or commit, the updates will be flushed to disk and if the transaction journaling is
operative, the update information flushed to the output media. This gives greater database integrity in the
event of a failure at the cost of an additional overhead. If no synchronisation is required, pass 0 in this
parameter.
“message” Can be any 0 (null) terminated string of characters, and is used simply by the transaction
journaler to record information about the transaction. This string should be meaningful - you might want to
examine the updates later though the transaction journaling mechanism.
The return value is 0 if successful, and any other value if there is an error.
Where:
JEDI_TRANSLOG_COMMAND_QUERY Tells the function that this is a query.
The return value is 0 if the process is not in a transaction, or non-zero if the process is inside a transaction.
Option Description
-c Suppress the generation of the executable. This will normally
result in just the object code (the .o file) being created. If the -Ja
option has been used, the -c flag is assumed.
-llibname Specifies additional library names.
-ofilename Overrides the name of the output executable file. The default is to
create an executable called a.out.
-Idirname Specifies the name of a directory (or a jBC file) where sources
can be included from. This is used when compiling the
INCLUDE or $INCLUDE statement in a jBC source, and the
#include statement in a C source. See ‘Include File and Library
Processing’ later.
-Ldirname Specifies alternate directories in which to find the libraries.
-S Synonymous with the -S option in the C compiler. Causes the
compilation of jBC source code to be terminated after the
Option Description
-h Display the help text.
-Jalibname Add input sources or objects to the archive library libname. The
link phase (where an executable is created) is omitted.
-Jd Delete any intermediate object (.o) files produced in the
compilation process of a jBC source. The object files produced
while compiling native C code remain.
-Jm Do not run the mcs command after an executable program has
been created. This may be useful when using other UNIX tools
against an executable program.
-Jo This allows an easy way of defining the output executable name
based on the first jBC source name. For example, if the first jBC
source name was prog1.b and the -Jo option was used, the output
executable name will be prog1, instead of the default of a.out.
-Js Display statistics about compilation times.
-Jv Verbose mode. The jbc program will display all the sub-programs
it calls to complete the command. This is very useful to get a
thorough grasp of exactly what jbc is doing.
-JCi Check that COMMON variables are assigned in the program.
-JCl Suppress warnings of unresolved labels.
-JCm{num} {num} specifies how many source code lines to count before
printing the lines compiled indicator when -JCv is specified.
-JCt Produce compilation statistics about the source file.
-JCu Suppress warnings of unassigned variables.
-JCv Operate in verbose mode. Indicate the current source file and
print the lines compiled indicator.
-JCw[0-3] Specify the warning level from 0 to 3. See the later section
entitled ‘jbc and BASIC warning levels’.
-JCA Ensure that ANSI code is produced (this may be the default if
your system has an ANSI compiler).
-JCDsymbol Define symbol for use in #ifdef directives.
Option Description
-JLa Select archive libraries. Normally a jBC program is linked using
shared object libraries. This makes the link phase much quicker,
as well as making the executable much smaller. There may be
times when you want to link with jBC archive libraries though,
Option Description
-JkKey Specify SQL key
-Jqi Shows the embedded SQL statements are in Ingres format.
-Jqo Shows the embedded SQL statements are in Oracle format.
-Jqx Shows the embedded SQL statements are in Informix format.
-Jqm Shows the embedded SQL statement are in Microsoft format.
This is the default for embedded SQL statements.
Option Description
-JGg Operate as normal but generate C++ code and use the C++
compiler to generate object code;
-JGt{in} Specifies that the compiler should translate to C++ then stop. The
jbc command will only operate on one file at a time.
-JGt Translate the file and follow include files, generating code for
any include files as well. In other words, expand INCLUDE
statements so that there is only 1 final C++ .C file.
-JGti The file to translate is an INCLUDEd file and therefore do not
generate a .j data file or generate code for the main() or function()
section of a C++ source code. Files translated in this way are
jbc Examples
% jbc invoices.b
The simplest form of the command compiles the jBC source program invoices.b, held in the current directory
then writes the resultant executable code into the default file a.out in the same directory.
% jbc -JO4 myjbc.b cfunctions.c anobject.o -o myapp
This command compiles the jBC code in the file myjbc.b, the C code in cfunctions.c, and links the resultant
object code with the existing object code anobject.o to produce the UNIX executable myapp. The parameter
-JO4 informs the compiler that full optimisation is to be carried out on the jBC and C code.
% jbc -Jalibfuncs.a func1.b func2.c obj3.o -Jdvs
This command will compile the jBC source func1.b and the C source func2.o to object file. The files func1.o,
func2.o and obj3.o will then be added to the archive library libfuncs.a. The -Jd option causes the object func1.o
to be deleted afterwards. The -Jv option causes jbc to display all the programs it executes. The -Js option causes
the time taken to execute the jbc command to be displayed.
% jbc prog1.b -I$HOME/INCLUDES -I$HOME/BP -c
This example shows the source code prog1.b being compiled. The -c option stops the compilation once the
object prog1.o has been created. The -I option shows that any INCLUDE (or $INCLUDE) statements seen in the
source prog1.b can be found by first looking in file $HOME/INCLUDES and then $HOME/BP.
EQUATE
EQUATE symbol TO substitute
The EQUATE directive instructs the pre-processor to replace any occurrence of symbol with the text substitute.
The substitute text will first be checked against any existing EQUATE directives and re-substituted. This re-
substitution is carried out only once to prevent infinite loops in substitution. For example:
EQUATE Day TO DATE()/7 ;* Day is 0 TO 6
EQUATE Monday TO Day = 1 ;* Check for Monday
.....
IF Monday THEN ;* IF today is Monday
In this example the substitute text for Monday (Day = 1) is checked against the existing EQUATE for Day. The
word Day is then substituted to generate the final text DATE()/7 = 1.
#define
#define symbol substitute
This directive is an alternative form of the EQUATE directive above.
The following source code can be used to show the different warning levels in action. Each warning level will
produce a different set of warning messages. The higher the warning level the more warning messages will be
generated.
SUBROUTINE abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
varx = 1
COMMON varx
vary = varz
FOR I = 1 TO 10
NEXT L
BREAK
CONTINUE
format = varx "L#10" "L#20" "L#30"
END
END
Example
The example below shows two C sources being compiled into a library, and a shared object being created out of
them
% cc -c func1.c func2.c
% ar -rv libcommon.a func1.o func2.o
% jBuildSLib -o libshared.so libcommon.a
In this example, the shared object libshared.so will be created, together with the export list libshared.so.el.
There are three stages to using shared objects and jBuildSLib:
1. Create the input objects to jBuildSLib.
2. Use the jBuildSLib command to create a shared object.
3. Reference a shared object from a C or jBC program.
These three stages will be dealt with separately in more detail. There will be a rolling example of the use of
jBuildSLib in these explanations. The example shows the creation of an application with 2 jBC programs, 3 C
sources, 2 jBC subroutines, 1 compiled object and one library:
• program prog1.b calls C functions func1, func2 and func3, as well as the jBC subroutine sub1. It is
compiled with the -JLS switch so the call to the jBC subroutine is through a direct call, rather than a run-
time search through all the available shared objects.
• program prog2.b calls C function func4, and jBC subroutine sub2. It is compiled normally and the CALL
to sub2 uses the normal mechanism of looking in all the shared objects at run-time.
• functions func1.c, func2.c and func3.c are C sources containing the functions func1, func2 and func3, as
used by program prog1.b. They make calls to other external functions in a comms package.
Example
Compile sources func1.c, func2.c and func3.c into archive library libfuncs.a:
% cc -c func1.c func2.c func3.c
% ar -rv libfuncs.a func1.o func2.o func3.o
or
% jbc -Jalibfuncs.a func[1-3].c
Example
Compile sources sub1.b and sub2.b, leaving them as object files:
% jbc -c sub[12].b
To summarise our rolling example, following the above steps we have these significant UNIX files:
• libfuncs.a contains the objects func1.o, func2.o and func3.o.
• libcomms.a - existing comms library.
• sub1.o and sub2.o - the jBC subroutines.
• func4.o - existing pre-compiled object.
Example
Create the libfuncs.so from three input files:
% jBuildSLib -o libfuncs.so libfuncs.a libcomms.a
sub1.o
Example
Create the libutils.so from two input files.
% jBuildSLib -o libutils.so sub2.o func4.o
To summarise our rolling example, following the above steps we have these significant UNIX files:
• libfuncs.so contains the objects func1.o, func2.o, func3.o, libcomms.a and sub1.o.
• libutils.so contains the objects sub2.o and func4.o
Example
Compile program prog1 to be able to reference functions func1, func2, func3 and subroutine sub1 using shared
objects. Following compilation, the shared objects will be moved to a library directory, and the environment
variable LD_LIBRARY_PATH modified so the UNIX dynamic loaded can find the shared objects.
% jbc prog1.b -o prog1 libfuncs.so -JLS
% mv libfuncs.so $HOME/lib
% export LD_LIBRARY_PATH=$HOME/lib:$LD_LIBRARY_PATH
% prog1
Note that for AIX systems the environment variable is LIBPATH.
Example
Compile program prog2 to be able to reference functions func4 and subroutine sub4. The function func4 is
referenced as the previous example, but the subroutine sub2 is called through the jBC run-time CALL statement
and needs to be placed in the JBCOBJECTLIST path.
% jbc prog2.b -o prog2 libutils.so
% mv libutils.so libutils.so.el $HOME/newfunc
% export
LD_LIBRARY_PATH=$HOME/newfunc:$LD_LIBRARY_PATH
% export JBCOBJECTLIST=$HOME/newfunc:$JBCOBJECTLIST
% prog2
Note that the JBCOBJECTLIST variable may not be set up in which case jBC run-time would default to
$HOME/lib. Hence an alternative way of setting the JBCOBJECTLIST variable would be to:
% export JBCOBJECTLIST=$HOME/newfunc:$HOME/lib
In reality, for subroutine sub2 you would normally use the CATALOG command as this is much easier to use.
An alternative way of creating program prog2, calling function func4 and subroutine sub2 would be:
% BASIC . sub2.b
% CATALOG . sub2.b
Example
A terminal needs debugging, but you cannot debug it because TCL restart is enabled, or BREAK-OFF has been
set to disable break key etc. So, you need to not only over-ride the security in the program, but also debug it
from a different terminal. Enter the following command:
% jPMLMsg -v 47 DEBUGTTY /dev/pts005 ENTERDEBUG
This assumes that:
• The port number you want to debug is 47.
• The programmer is logged on as root on device /dev/pts005.
• The account that port 47 is logged on to has read/write permissions for device /dev/pts005.
• The terminal at /dev/pts005 is currently inactive, for example 'sleep 99999'
A similar example to start debugging another process from the device you are logged on to is:
% jPMLMsg -v 47 DEBUGTTY `tty` ENTERDEBUG ;sleep 999
Enabling Profiling
There are two ways of enabling profiling for a program.
1. Use the -JP option when the program is executed. For example:
% MAINPROG -JP Filename
This generates a profiling file called 'jprof' in the user’s current directory. Note that when the application
stops, or chains to another program, profiling is terminated.
2. Set the environment variable JBCPROFILE. For example:
% JBCPROFILE=0 MAINPROG Filename
This generates a different profiling file for each process executed, while the environment variable is
active, in the format:
'jprof_pid_n'.
Where 'pid' is the process id, and 'n' is an incrementing number starting at the value 'JBCPROFILE' was
set to. This allows processes that do a CHAIN or ENTER (and so retain the same process id) to still
generate different profiling files.
The profiling file generated will only contain information about user CPU time. The time spent in kernel system
calls is not included. Therefore, doing a lot of file I/O (especially for j1 files), means that this time will not be
included in the profiling statistics. Note that time spent in j2 files which are in memory (when there are no frame
faults) will be counted, as this is user CPU time.
Example of Profiling
Imagine the source 'test1.b' below has been edited into file BP, where BP is a regular UNIX directory. Notice the
INCLUDE of another source file 'test2.b'.
OPEN "fb1" TO DSCB ELSE STOP 201,"fb1"
PRINT "Phase 1 -- start"
S1 = SYSTEM(9)
FOR Id = 1 TO 100
Rec = ""
FOR I = 1 TO 100
Line = ""
FOR J = 1 TO 20
Line := CHAR(SEQ("A")+RND(26))
NEXT J
Rec<I> = Line
NEXT I
WRITE Rec ON DSCB,Id
NEXT Id
PRINT "Phase 1 -- end, CPU = ":SYSTEM(9)-S1
INCLUDE test2.b
PRINT C1:" records in file fb1"
PRINT "End"
The program can be created normally with the following command:
% cd BP
% jbc test1.b -o ../test1
% cd ..
or it can be created with BASIC and CATALOG:
% BASIC BP test1.b
% CATALOG BP test1.b
By default, when the program is run, no profiling will take place.
Now run the program with the -JP switch to create a file 'jprof':
% test1 -JP
We can now examine the profile file with the 'jprof' command, using the -f option to generate optional source
code listings from the file BP.
% jprof -f BP jprof
Profile of program test1 from profile jprof Page 1
Source Line Ticks % Source
The -i option would sort the output with incrementing Ticks counts.
Example 1
Find the exact location where file CUSTOMERS is being opened:
% jshow -f CUSTOMERS
File: /home2/live/DATA/CUSTOMERS
This shows that if a jBC program were to execute:
OPEN "CUSTOMERS" TO ....
The file open would succeed, and the actual UNIX file opened would be /home2/live/DATA/CUSTOMERS.
Example 3
The program MAIN is not behaving as expected. Use jshow to gain more information:
% jshow MAIN
jCL script: /home2/live/MD/MAIN
Executable (DUP!!): /home2/live/bin/MAIN
In this example we can see that program MAIN exists as both a jCL script and as an executable program. There
is a clear case of conflict here, and it is possible the application is using the wrong version. The run-time will
execute the jCL script in preference to the executable program.
Example 4
Find out as much as possible about the object PIPE, and report the paths that were used when searching for it.
% jshow -v PIPE
File path: /home2/live
File path: .
File: /home2/live/PIPE
Subroutine object: main()
Subroutine object: /home2/live/lib/liblive0.so
Subroutine object: /home2/live/lib/fb1.so
Subroutine object: /home2/live/lib/libfb10.so
Subroutine object: /usr/jbc3.0/lib/libinternal.so
Subroutine object: /usr/jbc3.0/lib/libutils.so
Subroutine object: /usr/jbc3.0/lib/libqueries.so
Subroutine object: /usr/jbc3.0/lib/libjpq.so
Subroutine object: /usr/jbc3.0/lib/libjrem.so
Subroutine object: /usr/jbc3.0/lib/libjconnect.so
Subroutine: /home2/live/lib/liblive0.so
MD Name: /home2/live/MD
Execute path: /usr/jbc3.0/bin
Execute path: /usr/bin
Execute path: /usr/merge/dosroot/ubin
Execute path: /usr/ccs/bin
Execute path: /home2/live/tools
Execute path: /usr/local/bin
Execute path: /opt/bin
Execute path: /home2/live/bin
Execute path: .
Execute path: /usr/ccs/bin
Execute path: /usr/ucb
jCL script: /home2/live/MD/PIPE
jtic Program
The jtic program takes a description of the capabilities and creates a binary definition of the file in similar
fashion to the UNIX tic program. It is called as:
% jtic {-x} {-v} {DescFile}
where:
-x The descriptions are the extended capabilities.
-v Verbose mode.
By default, the program jtic will take a source description file called terminfo.src and assume it contains standard
terminfo names. The output will be to a file called /usr/lib/terminfo/x/xyz, where x/xyz depends upon the
terminal name as contained in the description file.
You can use any alternative description file to terminfo.src by specifying the description file name on the
command line.
You can specify an alternative output directory to /usr/lib/terminfo by amending the TERMINFO environment
variable. However, when you run a jBC program that accesses these definitions in an alternative directory, the
TERMINFO variable needs to match that when the definition was compiled.
By default the jtic program assumes the description file contains standard terminfo definitions such as
cuu1=\E[1A, cols#80,
If you want to create a binary with the extended capabilities, use the -x option.
Remember when running jtic you will probably require root privileges to write to the /usr/lib/terminfo directory.
% cat prog1.b
EXECUTE "TERM lj1"
PRINT "@(-70), if_prpt_letter, = " :
SQUOTE(OCONV(@(-70),"MCPU"))
PRINT "@(-76), if_prpt_utray , = " :
SQUOTE(OCONV(@(-76),"MCPU"))
% ./prog1
@(-70), if_prpt_letter, = '^[[02l'
@(-76), if_prpt_utray , = '^[[90x'
Extended Capabilities
The table below shows the extended capabilities.
jmakeerr Command
The jmakeerr command is provided for converting error messages in alternative formats to the format required
by jBASE. The originating format can be either jBASE internal format, or legacy type ERRMSG file format.
The command is therefore mainly used to convert error messages from their ERRMSG file format to the format
required by jBASE. The command syntax is:
jmakeerr inputfile {Key {Key ..}} | * {(MNOR)}
TO : (outputfile
Where:
inputfile is the input file containing the original records to be converted.
outputfile is the output file for the converted records.
Key is a list of record keys to convert.
* specifies that all records from inputfile are to be used.
(M) indicates a migration from legacy versions of ERRMSG.
(N) converts numeric record keys only.
(O) overwrites any existing records in outputfile.
(R) lists record keys as they are converted.
A typical use would be for a user to T-DUMP the file ERRMSG from their existing system, to T-LOAD it back
into a jBASE system and then use the jmakeerr command as follows:
% SELECT ERRMSG EQ \”USER]\”
97 Records selected
% jmakeerr ERRMSG \(MO
TO: (/usr/jbc/jbcmessages
In the above example, the user is selecting all the error messages they have created themselves, and then using
jmakeerr to convert them from the original ERRMSG file and format to the file and format used by jBASE,
namely /usr/jbc/jbcmessages.
—B— —E—
BASIC, 1-3, 1-4, 2-5, 2-10, 3-1, 3-2, 3-3, 3-4, 3-11, ED, 3-1, 3-2, 12-17, 12-18
5-2, 6-1, 9-1, 10-1, 10-10, 11-2, 11-4, 11-6, 12- ENABLE-LOGONS, 3-9, 3-10
6 Environment Variables, 8-8, 10-6
BASIC Command, 10-9 EQUATE, 10-7, 10-8
ERRMSG, 12-18
—C— Error Message File, 12-17
Executable Paths, 1-3
C Extensions, 1-3, 4-1
Exporting Applications, 2-4
C function definition, 4-6
External libraries, 4-1
C Functions, 4-1, 4-16, 4-18
CALL, 3-1, 3-7, 4-16, 4-18, 7-3, 10-5, 11-2, 11-4,
—F—
11-6, 12-2
calloc, 7-7 File ajar processing, 7-8
CATALOG, 1-3, 1-4, 2-5, 2-11, 3-1, 3-4, 3-6, 3-7, File Ajar Processing, 7-5, 7-12, 7-13
3-8, 3-9, 3-10, 3-11, 5-2, 9-1, 10-9, 11-1, 11-4, file types
12-6 .b, 3-3, 10-9
CATALOG Command, 11-6 .el, 2-11, 3-7, 3-10
cc, 4-3, 7-2, 8-5, 10-1, 10-2, 10-3, 10-4, 10-6, 11-2, .o, 2-11, 3-3, 3-4, 10-3, 10-4, 10-9, 11-3, 11-6,
11-3 11-7