Info-Basic Programming (JBC) AbrhamB
Info-Basic Programming (JBC) AbrhamB
By Abrham Bokan
Program Management Office (PMO)
CBE
Contents
Overview
Benefits of jBC
Program Structure
Compiling and cataloging jBC programs
Variables, data types, comments, Statements…
Operators
Control statements
Looping Constructs
Arrays
Strings and string functions
Subroutines
T24 programming standards
Introduction to OFS
Overview
It is a sophisticated superset of Dartmouth BASIC supporting
structured programming techniques
The terms Info-basic, jBC, Jbase Basic, JBasic are used interchangeably
to refer the same language
It is compiled language
The compilation process first converts the source code to C, which in
turn is compiled for the target platform with the usage of standard c
compiler.
It is aimed primarily at writing business applications that can utilize a
multi value database or third party DBMS depending on the
configuration it is given.
It contains all the constructs needed to access and modify files and
their data efficiently
Benefits of jBC
jBC Program
1. PROGRAM programName
2. IncludeStatements ($INCLUDE)
3. Comments
4. Statements
5. END
Program components explained
PROGRAM - a keyword that tells the compiler that the jBC code is to
be executed from shell
SUBROUTINE – a keyword that tells the compiler that the jBC code is
to be executed from within GLOBUS
IncludeStatements – files whose contents are accessed/referenced
with in the body of the program and therefore should be included
Comments – can appear anywhere with in the source file. They are
used for documentation (code explanation).
Statements – A unit with which a program is constructed.
RETURN –transfer control to the caller
END –
Compiling, Cataloging, and Decataloging
Compile - creates the object code and put it in the same directory by
prefixing ‘$’ sign
BASIC dirName pgmFileName
E.g. If we have a program named HELLO in directory TEST.BP
BASIC TEST.BP HELLO
Catalog - command is used to create UNIX executables and shared
libraries from the application source code. Once you have cataloged your
programs, you can run them like any other command on the system.
CATALOG dirName pgmFileName
E.g. E.g. If we have a program named HELLO in directory TEST.BP
CATALOG TEST.BP HELLO
Decatalog - commands are used to remove the run-time versions of
cataloged jBC programs. Executables and shared library objects can be
removed from the bin and lib directories by using the DECATALOG
command.
DECATALOG dirName pgmFileName
E.g. E.g. If we have a program named HELLO in directory TEST.BP
DECATALOG TEST.BP HELLO
Exercise 1
Note: To print a string to screen you can use the commands PRINT,
CRT, or DISPLAY.
Exercise 1
Assignment
Assignment statement is used to allocate a value to a variable
Syntax: variable = expression
Expression – could be a literal or statement
E.g.
Literal: age = 25
Data Types –
in many programming languages, variables are typed. I.e. they can hold
certain type of data (int, char, string, …). In jBC variables are type less
allowing any type of data to be stored within them.
Since there are no data types there is no variable declaration
Implicit type conversion is performed by jBC compiler
Variables, Data types, Comments, Statements…
Comments
Has no effect on the program execution. I.e. ignored by compiler
Should start with one of the following tokens
REM, !, *
E.g
REM This a a comment that starts with REM
token
* This comment starts with asterisk
* Another asterisk comment
! Exclamation mark comment
GOSUB
The GOSUB command is used to branch to a local subroutine, which is
identified by the line label used. When a RETURN statement is encountered
in the subroutine, the program is transferred back, and execution continues
at the line following the GOSUB.
Care should be taken to structure the usage of GOSUB, and not to exit a
subroutine other than with the RETURN command. RETURN always
returns to the statement following the last executed GOSUB.
Syntax: GOSUB label
PRINT “Your Name”
INPUT name
GOSUB DISPLAY;
PRINT “After GOTO statement”; *Executed after DISPLAY statements
DISPLAY:
PRINT name: “Welcome to jBC programming”
PRINT “From DISPLAY local subroutine”
RETURN
Control statements
CASE statement
Syntax
BEGIN CASE
CASE expression
statement(s)
CASE expression
statement(s)
END CASE
The IF condition allows nested processing of tests, but can become unwieldy
in practice. For a number of mutually exclusive possibilities you can use the
CASE construction instead.
The CASE construction sets up a series of tests with the actions to take if the
test evaluates true. However only the first test which evaluates true is
taken; at the next CASE statement processing jumps beyond the end of the
case statement.
It makes the program much more modular and easier to follow.
Control statements
CASE statement
BEGIN CASE
CASE ROLE EQ “CSM”
CALL DISPLAY.MENU (“CSM”)
CASE ROLE EQ “FMAKER”
CALL DISPLAY.MENU (“FMAKER”)
CASE ROLE EQ “FCHECKER”
CALL DISPLAY.MENU (“FCHECKER”)
CASE 1
PRINT “ERROR: INVALID ROLE”
END CASE
Exercise 2
FOR loop
Syntax
FOR I = X TO Y
statement(s)
NEXT
OPEN loop
Syntax
LOOP
statements
WHILE condition DO
statements
REPEAT
* Receive any number of numbers from the user and display their sum
MYSUM = 0
I=1
PRINT “Enter Your Numbers or ‘Y’ when you finish”
LOOP
PRINT “Num”:I
INPUT USRNUM
WHILE USRNUM NE “Y” DO
MYSUM +=USRNUM
++I
REPEAT
PRINT “The sum of your numbers is: “:MYSUM
Arrays
Dynamic arrays
A dynamic array is just a string of characters that contain one or more
delimiter characters. The delimiter characters are :
Field Marker (FM), Value Marker (VM), and Sub-value Marker (SM)
E.g. WorldCities = “Africa]Ethiopia\Addis Ababa\Adama\Bahir
Dar]Egypt\Cairo\Alexandria^Europe]Germany\Berlin\Frankfurt]France\Paris\
Lyon”
Declaration
Dynamic arrays do not need any explicit declaration. Initialisation would suffice.
ARRAY = ‘’ A dynamic array being initialised.
Accessing elements of dimensioned array
arrayName <field#,value#,sub-value#>
E.g. WorldCities <1,1,1> is Addis Ababa
WorldCities <2,1,2> is Frankfurt
Strings and String functions
String
Is a sequence of numeric, alphabetic, or alphanumeric characters
String Concatenation
Strings are concatenated using the operator “:”
“Addis Ababa”:”,“:” Ethiopia” = Addis Ababa, Ethiopia
Concatenation of two strings appends the second string to the first. Concatenation
of a series of strings is done in order from left to right, and parentheses may be
used to make a particular operation take precedence.
Substring Extraction and Assignment
Substring extraction takes out part of a string and assignment allocates that part to
a variable or expression or as a value.
Syntax: S[start#,extract#]
S is the original string variable, and start# gives the starting character position, whilst
extract# gives the number of characters to extract from the string.
E.g. A="abcdef" ; X=A[3,2] assigns characters cd to X
Strings and String functions
Write a program that displays the name and rank of students sorted by
students’ rank. The students are taking five subjects
Input: comma separated name and marks of a given student. You should
continue to accept student records until the user finishes.
E.g. Abiy, 89,86,98,90,88
Trump,56,53,42,58,69
Output
Name (in all CAPS), average, rank sorted by rank
ABIY 90.2 1
TRUMP 55.6 2
Use
Open loops, counted loops
Dynamic arrays, Dimensioned arrays
String functions where appropriate
More on programs
Program Arguments
The SENTENCE function allows a program to locate the command used to
invoke it and the arguments it was given. It has the general form
SENTENCE ({expression})
expression should always evaluate to +ve integer. –ve integer will return a null string
SENTENCE (0) – returns the command itself. I.e. the program name. SENTENCE (i) –
the ith argument
Alternatively you can use @SENTENCE system variable. This variable holds
the full text of the last sentence executed.
EXERCISE 4
PROGRAM A1
Param = ""
ProgName = SENTENCE (0)
PRINT ProgName
FOR I = 1 TO 4
Param <I> = SENTENCE (I)
PRINT Param <I>
NEXT I
END
PROGRAM A2
PRINT @SENTENCE
END
Run the programs
jsh> A1 125 456 563 ASD ERT
A1
125
456
563
ASD
jsh> A1 125 456 563 ASD ERT
A1 125 456 563 ASD ERT
Subroutines
Programs that are executed within Globus (T24) are called subroutines.
They make use of Globus (T24) Files
They have to capacity to read, write, modify, delete data in Globus
(T24) files.
jBC subroutine
1. SUBROUTINE subroutineName
2. IncludeStatements ($INCLUDE)
$INSERT I_COMMON
$INSERT I_EQUATE
3. Comments
4. Statements
5. RETURN
6. END
Subroutines
3. Read the Customer file and extract the record with id myCustId =
1001383883 – we have twp ways
Using jBase command “READ”
READ FBNK.CUSTOMER……………
The jBase READ statement can be used to read data from a file in T24. But it has the
same problem as that of OPEN. The programs written using READ are not portable
across lead companies of the same bank.
Using the T24 subroutine F.READ(1,2,3,4,5)
1 - File name
2 - Id of the record to be read
3 - Dynamic array that will hold the read record
4 - File Path
5 – ErrorVariable
CALL F.READ(FN.CUS,” 1001383883”,R.CUSTOMER,F.CUS,CUS.ERR1)
The error variable will contain null(‘’) if the read is successful else will contain
either 1 or 2.
EXERCISE 5 - Solution
4. From the extracted record obtain the mnemonic and nationality
Contents of R.CUSTOMER
BAD0004565^ESHETIE WORKU ADEM^ESHETIE WORKU ADEM^^BDAR
03^B97^^^ET^^^^^^^^^^^^^^1000^6022^^1499^1^ET^1^ET^^^7030004565^^^^^^^^^^^
^1^^^ET0010023^^^^NO^^^^^^^^^^^MALE^^^^203377^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^NULL^NULL^^^NULL^NULL^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]3000^^^1^7026_
GTUSER__OFS_DM.OFS.SRC^1206021938^7026_GTUSER_OFS_DM.OFS.SRC^ET0010001^1
Once a record is extracted this is how it will be stored in the dynamic array. All fields
will be delimited by a field markers, multi values by value markers and sub values by
sub value markers. From this array we can extract the necessary details.
EXERCISE 5 - Solution
Most of the files in T24 have insert files which begin with ‘I_F.’ followed by
the name of the file. They will be available under T24.BP. These files hold
the definitions for all the fields. The fields could have prefixes/suffixes.
They hold the names and the field positions of the various fields.
In the customer file the prefix used is EB.CUS. suffix used is NIL
Y.MNEMONIC = R.CUSTOMER<EB.CUS.MNEMONIC>
Y.NATIONALITY = R.CUSTOMER<EB.CUS.NATIONALITY>
To extract values from a dynamic array, angular brackets “< >” need to be
used.(Use ‘()’ for dimensioned arrays)
We can extract data from the dynamic array by specifying field positions as follows
Y.MNEMONIC = R.CUSTOMER<1> or by specifying the actual name of the field
like above.
It is always advisable to use field names ‘coz field positions could change from one
release of Globus to another.
Here 1 is the field position of the field mnemonic in the CUSTOMER file. Refer the
I_F.CUSTOMER file for field names and field positions.
EXERCISE 5 - Solution
OPENFILES:
CALL OPF(FN.CUS,F.CUS)
RETURN
PROCESS:
CALL F.READ(FN.CUS,Y.CUS.ID,R.CUSTOMER,F.CUS,CUS.ERR1)
Y.MNEMONIC = R.CUSTOMER<EB.CUS.MNEMONIC>
Y.NATIONALITY = R.CUSTOMER<EB.CUS.NATIONALITY>
CRT “Customer Id: “:Y.CUS.ID
CRT “Customer Mnemonic: “:Y.MNEMONIC
CRT ‘Customer Nationality: “:Y.NATIONALITY
RETURN
END
DEBUG commands
S – execute next line
V variableName – display the value of variableName
A – executes abort statement. Returns control to T24.
Q - Quit program, issue a STOP statement
EXERCISE 6
Algorithm
Step 1. Open the Customer File
Step 2. Select random 10 the customer ids
Step 3. Remove one customer id from the selected list
Step 4. For the extracted customer id extract the corresponding record from the customer file
Step 5. From the extracted record extract the mnemonic and nationality
Step 6. Display the customer id, mnemonic and the nationality
Repeat Steps 3 to 6 for all customers
EXERCISE 6 - Solution
EB.READLIST(1,2,3,4,5)
EB.READLIST takes in 5 parameters.
1 - The select statement to be executed. Give the name of the variable that holds the
select statement here.
2 - The name of a dynamic array that will hold the result of the select statement
Please note that a select statement here can only select ids from the respective file.
Therefore this dynamic arrays will only hold the ids of the records that have been
selected. All the ids will be delimited by a field marker(FM).
3 - This is an optional parameter. This is the name of a file in the hard disk that can
hold the result of the select statement. Usually this is set to NULL (‘’)
4 - A variable that will hold the number of records selected.
5 - A variable to hold the return code. Will contain null if the select statement was
successful else will contain 1 or 2.
EXERCISE 6 - Solution
OPENFILES:
CALL OPF(FN.CUS,F.CUS)
RETURN
PROCESS:
SEL.CMD = "SELECT ":FN.CUS
CALL EB.READLIST(SEL.CMD,SEL.LIST,'',NO.OF.REC,RET.CODE)
LOOP
REMOVE Y.CUS.ID FROM SEL.LIST SETTING POS
WHILE Y.CUS.ID:POS
CALL F.READ(FN.CUS,Y.CUS.ID,R.CUSTOMER,F.CUS,CUS.ERR1)
Y.MNEMONIC = R.CUSTOMER<EB.CUS.MNEMONIC>
Y.NATIONALITY = R.CUSTOMER<EB.CUS.NATIONALITY>
CRT "Customer Id: ":Y.CUS.ID
CRT "Customer Mnemonic: ":Y.MNEMONIC
CRT "Customer Nationality: ":Y.NATIONALITY
REPEAT
RETURN
END
•Put DEBUG statement where you want to start debugging from
•Compile and catalog the subroutine
•Execute the routine from T24
EXERCISE 7
Modify Exercise 7
to store the extracted mnemonic and nationality of all customers in an
array(do not display them) delimited by a ‘,’. The array should contain data
as follows
CusId,Mnemonic,NationalityFMCusId,Mnemoic,nationalityFM…
Write the array to file
Algorithm
Step 1. Open the Customer File
Step 2. Select random 10 the customer ids
Step 3. Remove one customer id from the selected list
Step 4. For the extracted customer id extract the corresponding record from the customer file
Step 5. From the extracted record extract the mnemonic and nationality
Step 6 Store the customer id, mnemonic and the nationality in a dynamic array
Repeat Steps 3 to 6 for all customers
Step 7 Write the contents of the array to file
EXERCISE 7 - SOLUTION
RETURN
EXERCISE 7 - SOLUTION
OPENFILES:
CALL OPF(FN.CUS,F.CUS)
OPENSEQ FILE.NAME TO FILE.PATH ELSE
CREATE FILE.PATH ELSE ABORT
END
RETURN
PROCESS:
SEL.CMD = "SELECT FBNK.CUSTOMER SAMPLE 10”
CALL EB.READLIST(SEL.CMD,SEL.LIST,'',NO.OF.REC,RET.CODE)
LOOP
REMOVE Y.CUS.ID FROM SEL.LIST SETTING POS
WHILE Y.CUS.ID:POS
CALL F.READ(FN.CUS,Y.CUS.ID,R.CUSTOMER,F.CUS,CUS.ERR1)
Y.MNEMONIC = R.CUSTOMER<EB.CUS.MNEMONIC>
Y.NATIONALITY = R.CUSTOMER<EB.CUS.NATIONALITY>
CUS.DETAILS.ARRAY<-1> =
Y.CUS.ID:’,':Y.MNEMONIC:’,':Y.NATIONALITY
REPEAT
WRITESEQF Y.CUS.ID TO FILE.NAME THEN
CRT “Array written to file successfully”
END
ELSE
CRT “Unable to write to file”
END
RETURN
END
More T24 APIs
F.WRITE(1,2,3) - Write data on to files
1 - File name
2 - Id of the record to be written
3 - Actual Record to be written
CALL F.WRITE(FN.CUS,Y.CUS.ID,R.CUSTOMER)
CALL F.DELETE(FN.CUS,Y.CUS.ID)
T24 programming standards
All routines in T24 are called subroutines. Routines must not be written in such
a way that they are executed directly from jSHELL.
TEMPLATE programs should be less than 2000 lines. New template programs
should contain very little code, all code should be called from the subroutines
defined in the template e.g. FIELD.DEFINITIONS, CHECK.FIELDS &
CROSSVAL.
Subroutines should be less than 600 lines. Ideally the code should be broken
down into internal subroutines that can be viewed in its entirety on one screen
(i.e. 80 character wide by 23 lines deep).
Do not write TOP DOWN code. Each routine should have one main
controlling section with the detailed code written as subroutines. Do not
assume field 1 will be input before field 2;
Labels, Variables and Routines should not use the same names.
Labels and variables should have meaningful names. Numeric labels should
not be used. Labels must exist on their own line with no other text appended to
the label.
T24 programming standards
All code should be structured in a modular fashion and broken into small
units/paragraphs (less than 100 lines) and each unit should have a single entry and
exit point.
Avoid deeply nested IF's and large case constructs. If an IF construct exceeds 20
lines then use a GOSUB - nothing is harder to follow in a program than an IF that
starts on page 1 and ends on page 21.
DO NOT comment out existing code DELETE it.
DO NOT use asterisks (*) to create coding breaks, either use the “*---------------“
Subroutine names should be in upper case and should be as long as necessary to
describe their purpose. However subroutine names are limited to 35 characters. In
addition subroutine names should begin with the product prefix and then describe
the routine, e.g. RP.CHECK.FIELDS.
Subroutine names should not include the “$” or “_” character.
Subroutine names cannot be named with an extension of B (i.e. SC.CALC.YIELD.B).
The extension b is a reserved extension for c code and case insensitive systems such
as Windows and iSeries machines treat B the same as b. To ensure that no problems
are encountered, it is best to avoid using program names that end with ‘extensions’
that may be interpreted by the underlying system, i.e. Windows extensions .doc,
.xls, .txt, Language extensions .c, .C, .cpp, .jar, .java, .class.
T24 programming standards
OFS is a standard module within T24, with a module code OF. It is the
ONLY standard gateway to TEMENOS T24. Simply put, it means that
every single interaction with T24 is driven through OFS.
OFS is message driven , i.e. it works on a request-response based system.
The OFS syntax, or message structure is proprietary to TEMENOS T24. It is
the native way to represent requests to execute T24 transactions, enquiries
or routines.
The OFS module provides the infrastructure necessary to process the OFS
TEMENOS T24 technology platform products like TEMENOS Connector,
TEMENOS T24 Browser and TEMENOS Internet Bank use OFS to interact
with TEMENOS T24 Applications. This implies that when we input a
transaction , say a Funds Transfer in Browser, T24 actually receives an OFS
message for Funds Transfer. This also implies that the OFS processing is
not merely an update to the database, but goes through the same level of
validations, including SMS, as in a manual effort. messages.
Introduction to OFS
OFS - Syntax
Transaction ID
The Transaction Id part of the message contains the transaction id of the
record used in the transaction. This is optional for new transactions if the
underlying application is designed to allow this. In a case where it is allowed,
the ID may be automatically generated by the application.
The transaction ID is mandatory for See , Authorize , Delete functions. The
transaction ID can also contain an optional Message ID for the message.
For eg 20548/20081010001 .
In this case the 20548 is the record id and 20081010001 is the message id. This
message id could be used by external systems to uniquely identify each OFS
message.
OFS – Syntax
Message Data
The message data portion of the message structure contains the data
required to create or update the transaction. Message portion follows the
format
Fieldname=data
Eg CUSTOMER=100297
When you need to assign values to multi values or sub values , you may
follow the format
Fieldname :multi value number : sub value number = data
Eg CUSTOMER:1:1=100297
This implies the first sub value belonging to the first multi value of the field
CUSTOMER is assigned a value of 100297. The first multi value or sub value
is taken as the default in the absence of positions If ‘NULL’ is specified as
field data, OFS will blank the field of all data.
The message data portion of the message can be repeated for each field
separated by a comma (,).
OFS – Syntax
EXERCISE 8
OFS – Syntax