+ All Categories
Home > Documents > Advanced Programmers Reference Manual

Advanced Programmers Reference Manual

Date post: 04-Jun-2018
Category:
Upload: kbe64
View: 245 times
Download: 2 times
Share this document with a friend
200
  jBASE Advanced Programmers Reference Manual Part No: 42-M-JAPRM-20.1 Copyright © 1991 - 1997 James Anthony Computing. All rights reserved.
Transcript
Page 1: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 1/200

 

 jBASE

Advanced Programmers Reference

Manual

Part No: 42-M-JAPRM-20.1

Copyright © 1991 - 1997 James Anthony Computing. All rights reserved.

Page 2: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 2/200

 

ii

Copyright

All rights to this documentation are reserved. This document contains proprietary information that is protectedby copyright. No part of this document may be reproduced, transmitted, or made available directly or indirectlyto a third party without the express written agreement of James Anthony Computing.

While every effort has been made to ensure a complete and accurate document, no responsibility is expressed or

implied for problems arising from any inaccuracy contained herein. Additionally James Anthony Computingreserves the right to make changes to this document and the software described herein at any time and withoutnotice.

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.

Page 3: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 3/200

Advanced Programmers Reference Manual iii

Table of Contents

Using the Manual ......................................................... ...........................................viiSummary of Chapters.........................................................................................viiNotation Conventions ....................................................... ............................... viii

Errata and Comments ................................................... ............................................ ix

Chapter 1: Introduction

Introduction to jBASE.......... ............................................................ ..................... 1-1Run-Time Components............. ............................................................ ........... 1-1Development Components............................ ................................................... 1-1Administrative Components............................................................................. 1-1Requirements for Running jBASE........................................................ ........... 1-1

Application Development....................................................... ............................... 1-3Migration ...................................................... ................................................... 1-3Executable Paths..................................................... ......................................... 1-3C Code Extensions.................................................. ......................................... 1-3ICONV and OCONV Extensions. ........................................................ ........... 1-3

The IOCTL Function ........................................................ ............................... 1-3 jEDI Database Drivers.... ............................................................ ..................... 1-3

 jEDI API Calls....... ........................................................... ............................... 1-4Makefiles ...................................................... ................................................... 1-4

 jbc and BASIC Commands......................................................... ..................... 1-4 jBuildSLib and CATALOG Command............................................................ 1-4Advanced Tools ...................................................... ......................................... 1-4Notes on Examples ........................................................... ............................... 1-4

Chapter 2: Migration

Overview.................................................. ............................................................ . 2-1Application Source ........................................................... ............................... 2-1Application Security ......................................................... ............................... 2-2

Application Connectivity............................................................ ..................... 2-2Application Interchange.......................................... ......................................... 2-2Application Backup .......................................................... ............................... 2-3

Exporting Applications........................................................... ............................... 2-4

Importing Applications................................................. ......................................... 2-5Importing Accounts...................................................... ......................................... 2-6

Accountname v. Username ......................................................... ..................... 2-6User Port Numbers ........................................................... ............................... 2-6

Generating an Application Account ........................................................... ........... 2-7Converting an Application.......................................................................... ........... 2-9Compiling an Application ...................................................... ............................. 2-10

Cataloging an Application...................................................... ............................. 2-11

Chapter 3: Execute Paths

Introduction ........................................................ ................................................... 3-1Creating a Source ......................................................... ......................................... 3-2Compiling Object Code.......................................................... ............................... 3-3Creating a UNIX Executable.......... ............................................................ ........... 3-4Execute the Command.................................................. ......................................... 3-5

Program Execute Paths................... ............................................................ ........... 3-6Subroutine Execute Paths ....................................................... ............................... 3-7Copying Programs and Subroutines ........................................................... ........... 3-9

Chapter 4: C Extensions

Calling C Functions - Overview....................................................... ..................... 4-1

Simple C Example....... ........................................................... ............................... 4-2Fundamental Components of C Interfaces........................................ ..................... 4-3

Page 4: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 4/200

 

Advanced Programmers ReferenceManual

iv

 jBC Supplied Header File ......................................................... .......................4-3Naming Conventions....................................................... ................................. 4-3VAR Variable...................................................................................................4-3INT32 Variable ..................................................... ........................................... 4-3FLOAT Variable ................................................... ........................................... 4-4

STRING Variable.............................................................................................4-4Function Prototypes..........................................................................................4-4Automatic Type Conversion.............................................................................4-5C Function Type Conversion............................................................................4-5C Function Definition.......................................................................................4-6

A More Complex Example ................................................... ................................. 4-7Register v. User Variables. ................................................... ................................. 4-9Creation and Destruction of VAR Type Variables...............................................4-10

Supported Functions and Macros.........................................................................4-11Macros to Store Values into a Variable..........................................................4-11Variable Type Conversion..............................................................................4-12VAR Variable Creation and Destruction........................................................4-14STRING Type Manipulation..........................................................................4-15

Replacing SUBROUTINEs with C Functions......................................................4-16Compiling and Linking with C Functions. .......................................................... .4-18General Rules and Helpful Hints .................................................... .....................4-20

Chapter 5: ICONV and OCONV Extensions

Introduction............................................................................................................5-1Conversion Code Extensions .......................................................... .......................5-2User Exit Code Extensions.....................................................................................5-3

Chapter 6: IOCTL Function

Introduction............................................................................................................6-1

JBC_COMMAND_GETFILENAME Command .................................................. 6-2

JIOCTL_COMMAND_CONVERT Command.....................................................6-3JIOCTL_COMMAND_FILESTATUS Command ................................................ 6-5JIOCTL_COMMAND_FINDRECORD Command .............................................. 6-6JIOCTL_COMMAND_HASH_RECORD Command...........................................6-7JIOCTL_COMMAND_HASH_LOCK Command................................................ 6-8

Chapter 7: jEDI Database Drivers

Introduction............................................................................................................7-1Shared Object Database Drivers ..................................................... .......................7-2File Ajar Processing...............................................................................................7-5

File Descriptor Member ProcessAjar .................................................. .............7-5File Descriptor Member ProcessReopen....................................................... ...7-5

 jEDI Support Functions. ....................................................... ................................. 7-7

Memory Allocation Functions..........................................................................7-7Record Locking Function.......................................................... .......................7-7

 jEDI Base Code........................ ........................................................... .............7-8INIT - Initialisation of Database Driver.................................................................7-9OPEN - Open a File .................................................... ......................................... 7-11CLOSE - Close an Opened File ...................................................... .....................7-13SELECT - Select Record Keys from a File..........................................................7-14SELECTEND - Terminate a Selection Process ................................................... 7-16

READNEXT - Get Next Record Key from Selection..........................................7-18READ - Read a Record from a File .......................................................... ...........7-20WRITE - Write a Record to a File.......................................................................7-23DELETE - Delete a Record from a File...............................................................7-25CLEAR - Delete All Records from a File ........................................................... .7-26LOCK - Provide Record Locking Mechanism.....................................................7-28IOCTL - Support Database Driver Control Functions..............................................7-30

Page 5: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 5/200

Advanced Programmers Reference Manual v

SYNC - Synchronise the Data to Disk................................................................. 7-33

Chapter 8: jEDI API Calls

Introduction ........................................................ ................................................... 8-1Initialisation.............................................. ............................................................ . 8-2Making jEDI Database Requests........................ ................................................... 8-3

Program Termination........................................................................ ..................... 8-4Compiling and Linking a Program ................................................... ..................... 8-5

Finding the #include Files....................................... ......................................... 8-5Linking with the jEDI Library. ................................................... ..................... 8-5

Transaction Boundary Support......................................................... ..................... 8-6Starting a Transaction ....................................................... ............................... 8-6Ending (Committing) a Transaction...................................................... ........... 8-6Aborting (Rollback) a Transaction: ...................................................... ........... 8-6Query the Status of a Transaction:........................................................ ........... 8-7

 jEDI Environment Variables ............................................................ ..................... 8-8JediOpen - Open a File ........................................................... ............................... 8-9

JediOpenDeferred - Deferred Open.................................................. ................... 8-10JediClose - Close an Opened File............. ........................................................... 8-11JediSelect - Select Record Keys from a File........................................................ 8-12JediSelectEnd - Terminate a Selection Process ................................................... 8-13JediReadnext - Get Next Record Key.................................................................. 8-14JediReadRecord - Read a Record from a File ..................................................... 8-15JediWriteRecord - Write a Record to a File ........................................................ 8-16

JediDelete - Delete a Record from a File............................................................. 8-17JediLock - Provide Record Locking Mechanism................................................. 8-18JediIOCTL - Database Driver Control Functions......... ....................................... 8-19JediSync - Synchronise the Data to Disk................................ ............................. 8-20JediClearFile - Delete All Records from a File ................................................... 8-21JediPerror - Print Error Message.... ............................................................ ......... 8-22JediFileOp - General File Maintenance........................ ....................................... 8-23

JediReinitialise - Re-initialise jEDI Code............................................................ 8-25

Chapter 9: Makefiles

Introduction ........................................................ ................................................... 9-1

Chapter 10: jbc and BASIC

Introduction ........................................................ ................................................. 10-1 jbc Command ..................................................... ................................................. 10-2

 jBC Compiler Order of Processing..... ........................................................... 10-2

How to Use the jbc Command .................................................... ................... 10-2 jbc cc Only Options .......................................................... ............................. 10-3 jbc Common cc and jbc Options. .......................................................... ......... 10-3 jbc Only Standard Options.......................................................... ................... 10-4

 jbc SQL Options ..................................................... ....................................... 10-5 jbc C++ Options.......................................................................... ................... 10-5INCLUDE File and Library Processing........ ................................................. 10-6

Environment Variables and the jbc Command............................................... 10-6 jbc Examples........................................................... ....................................... 10-7 jpp Macro Pre-processor..................... ........................................................... 10-7

BASIC Command................................................................... ............................. 10-9Using the BASIC Command................................... ....................................... 10-9

 jbc and BASIC Warning Levels ....................................................... ................. 10-10

Chapter 11: jBuildSLIb and CATALOG

Introduction ........................................................ ................................................. 11-1 jBuildSLib Command....................................................................... ................... 11-2

Creating the Input Objects to jBuildSLib ...................................................... 11-3Using the jBuildSLib Command to Create a Shared Object .......................... 11-3

Page 6: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 6/200

 

Advanced Programmers ReferenceManual

vi

Referencing a Shared Object from a C or jBC Program.................................11-4CATALOG Command.......................................................... ............................... 11-6

CATALOGing a jBC Program.......................................................................11-6CATALOGing a jBC Subroutine ........................................................ ...........11-6Extending the Use of CATALOG ....................................................... ...........11-7

CATALOG Configuration File.......................................................................11-8

Chapter 12: Advanced Tools

Introduction..........................................................................................................12-1 jBC Run-time Options........................................................... ............................... 12-2 jPMLMsg Command......................................... ................................................... 12-4Profiling ................................................... ........................................................... .12-5

Enabling Profiling ........................................................... ............................... 12-5Reporting the Profiling Files ..................................................... .....................12-5

Example of Profiling ....................................................... ............................... 12-6Debugging - the JBCDEBUGGER Variable........................................................12-8Terminal Redirection .................................................. ......................................... 12-9

 jshow Program .................................................. ................................................. 12-10Extended terminfo Capabilities..........................................................................12-12

 jtic Program........................................................... ....................................... 12-12 jtic Description File........ ........................................................... ...................12-12

Examples of Using jtic .................................................... ............................. 12-13Extended Capabilities...................................................................................12-13

Run-time Error Messages...................................................................................12-17Modifying Entries in the Error Message File ............................................... 12-17

 jmakeerr Command ......................................................... ............................. 12-18

Index

Page 7: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 7/200

Advanced Programmers Reference Manual vii

Using the Manual

Summary of Chapters

1 Introduction gives an overview of jBASE and the advanced techniques described in

this manual.2 Migration shows how to perform a full migration from an existing alternate

development environment.

3 Execute Paths gives details on the where and why of positioning executable code.

4 C Extensions describes how to write your own functions, called by the jBC language,in C code.

5 ICONV and OCONV Extensions shows the extensions you can make to the conversion codes in the

ICONV and OCONV functions..

6 The IOCTL Function describes the highly specialised IOCTL function.

7 jEDI Database Drivers describes how to write your own database driver so that jBC programscan seamlessly access data on alternate databases.

8 jEDI API Calls gives details of calling the jEDI API from a non-jBASE program.9 Makefiles shows how to use the UNIX ‘make’ program with jBASE applications.

10 jbc and BASIC describes in full the two compilation front-end programs, jbc andBASIC.

11 jBuildSLib and CATALOG describes in full the two execute creation front-end programs, jBuildSLib and CATALOG.

12 Advanced Tools describes more development tools that the advanced jBASEprogrammer may use.

Page 8: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 8/200

 

Advanced Programmers ReferenceManual

viii

Notation Conventions

The manual uses the following conventions when describing command syntax:

BOLD TEXT Text in this format represents required user input. The exact characters as shown

should be entered at the keyboard.

 Italic text In a syntax specification, italics show parameters that must be entered and supplied bythe user.

Within descriptive text, italics are used to add emphasis, or to show a term that has beendefined elsewhere.

CAPITALS CAPITALS indicate keywords, file names or constants.

{ } Braces are used to surround optional parameters within command specifications.

... The use of ellipses indicates a command parameter that can be repeated as many timesas required.

<ENTER> Capitals surrounded by angled brackets refer to actual keys on the keyboard. A series

of keys inside angled brackets such as <CTRL A>, indicate that the combination ofkeys should be pressed simultaneously.

arg | arg  A vertical line separating arguments means that at least one, if not both arguments

must be provided.

code or variable  This style of text represents code or variables.

Page 9: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 9/200

Advanced Programmers Reference Manual ix

Errata and Comments

If you have any comments regarding this manual or you wish to report any errors in the documentation, pleasesend details to the address below:

Technical Publications Department

 JAC

599 Maxted Road

 Hemel Hempstead

 Hertfordshire

 HP2 7DX

 England

Tel: +44 (0)1442 235 515

Fax: +44 (0)1442 233 515

email - international: [email protected]

[email protected]

email - USA: [email protected]

[email protected]

Please include your name, company, address, phone, fax numbers and your email address if applicable.

Page 10: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 10/200

Page 11: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 11/200

 

Chapter 1: Introduction

Page 12: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 12/200

Page 13: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 13/200

Advanced Programmers Reference Manual Introduction1-1

Introduction to jBASE

 jBASE is an application development and database management system that enhances and extends the UNIX,Windows NT and Windows 95 Operating System. jBASE also allows existing applications to be easily migratedfrom other DBMS, including PICK and REALITY.

 jBASE was designed to be, and is, Database Independent. jBASE offers built-in Client/Server abilities,embedded SQL functionality, an easy-to-use spooler, and an easy-to-use enquiry language.

The Application Language, jBC is a super-set of Dartmouth BASIC and is ideal for developing businessapplications. The compiler can optionally produce C or C++ Source code from the original jBC (BASIC)Sources.

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-timeefficiency 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 whichallows 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 takesadvantage of all the administrative functionality of the host environments. However, there are some extrafacilities provided over and above those of the host environment.

They include:•  The jBASE Spooler (jLP)

•  Utility programs such as jbackup and jrestore

Requirements for Running jBASE

The basic requirement for jBASE is a standard UNIX system running on any hardware. This makes jBASE atruly Open Systems application development tool, with the resultant code being easily ported across many UNIXplatforms.

 jBC applications will run in a UNIX SVR3.2 or later environment without difficulty.

 jBASE allows a user to take full advantage of the capabilities of UNIX System V Release 4 environment

(SVR4.x). This offers many advantages over previous versions of the UNIX system. However, it is important tounderstand that jBC will produce applications of equal complexity in both environments.

Page 14: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 14/200

 

Introduction Advanced Programmers ReferenceManual

1-2

The jBASE system has been successfully implemented on Intel, HP, DG, IBM, Digital, Sun, Sequoia andMotorola 88K UNIX based platforms. Other systems (including Windows) are either in development or will beimplemented as they are required.

Page 15: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 15/200

Advanced Programmers Reference Manual Introduction1-3

Application Development

As a simple example of application development in a jBASE environment, the developer would perform thefollowing tasks:

•  Possibly migrate an existing application from another environment.

•  Create or modify application source code using a jBASE or UNIX editor.

•  Create object code by using the BASIC command.

•  Make the object code executable by using the CATALOG command.

•  Run and test the application.

There are many extensions to the above that are possible with jBASE. Later chapters discuss these extensions indetail, but a summary of each extension is given below.

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 themigration 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 foundby 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 liveenvironments.

C Code Extensions

The jBC language provide a rich set of intrinsic functions for the application programmer. There arecircumstances 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.

ICONV and OCONV Extensions.

Two of the intrinsic functions supplied with the jBC language are the ICONV and OCONV functions. Theseprovide general conversion of data between input and output formats. The type of conversion performed isdefined during the call to ICONV or OCONV and jBC provides a large set of standard conversions.

The user can extend this set of conversions. The OCONV Extensions chapter describes how this can beachieved.

The IOCTL Function

There is an intrinsic function of the jBC language called IOCTL. Its use is synonymous with the C ioctl function.It provides for miscellaneous control commands and queries to be sent and received to the database driver for anopened file. Its use is highly specialised and can vary between different database types.

 jEDI Database Drivers.

A set of database types are supplied with jBASE. The database types include support for UNIX directories andfor jBASE exclusive hashed files. There are circumstances when an application will want to perform databaseoperations on databases other than those supported explicitly by jBASE.

The chapter titled jEDI Database Drivers shows how a user can write their own database driver so that their

applications can interface seamlessly with other databases.

Page 16: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 16/200

 

Introduction Advanced Programmers ReferenceManual

1-4

 jEDI API Calls

Although mostly used through jBC programs, jEDI is equally at home with non-jBC programs. The jEDI APICalls chapter describes how a C program can access the database functionality through calls to the jEDI library.

Makefiles

A typical UNIX development environment will make use of a development tool called ‘make’. This same facilitycan be used with jBASE programs and allows a jBASE developer to describe to UNIX the application sourcesand a set of rules showing how to build the application from the sources. The chapter entitled Makefiles showshow to use this very useful UNIX facility within a jBASE development environment.

 jbc and BASIC Commands

The normal command used by a jBASE programmer to convert source code to compiled object is the BASICcommand. However, the BASIC command is really just a front end to a more useful command called ‘jbc’. Thechapter entitled jbc and BASIC shows the greater flexibility of the jbc command over BASIC, and also gives

more complete information on the BASIC command.

 jBuildSLib and CATALOG Command

The normal command used by a jBASE programmer to convert compiled object to an executable program orshared object (subroutine) is the CATALOG command. However, the CATALOG command is really just a frontend to a more useful command called ‘jBuildSLib’. The chapter entitled jBuildSLib and CATALOG shows the

greater flexibility of the jBuildSLib command over CATALOG, and also gives more complete information onthe CATALOG command.

Advanced Tools

There are several tools available to the advanced programmer, for profiling support for example. These tools aredetailed in the Advanced Tools chapter.

Notes on Examples

Throughout the manual there are many examples of programs being executed from the UNIX shell. All theexamples assume the command will be run from the Korn shell (or ksh) program. Of the many shells available toUNIX 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. Forexample:

% 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. Forexample, 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

Page 17: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 17/200

 

Chapter 2: Migration

Page 18: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 18/200

Page 19: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 19/200

Advanced Programmers Reference Manual Migration2-1

Overview

Historically, migrating an application from a proprietary environment has proved to be both technically complexand very expensive in terms of resource. Migrating via jBASE can alleviate the majority of the technicalcomplexities thus dramatically reducing the migration period.

To effect a smooth and successful migration, the following areas should be given careful consideration. Theseconsiderations can then be used to form the basis of an application migration plan.

•  Application source

•  Application security

•  Application connectivity

•  Application interchange

•  Application backup

Application Source

The application source can be categorised as shown below. The logical location of each category should benoted and any associated logistical problems resolved. The most common problem is how to effect a transfer ofthe 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.

Page 20: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 20/200

 

Migration Advanced Programmers ReferenceManual

2-2

•  Enabling/protection mechanisms.

•  License agreements.

•  Maintenance agreements.

•  System utilisation.•  User exits.

•  System utilities.

Data/Report Retrieval

Notes should be accumulated of any retrieval language requirements, especially with regard to the use of userexits 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 theapplication 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 anyanomalies.

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 theoriginal to the migrated application. It should be recognised that to retain database integrity the source andmigrated application should be closed to users for the duration of the application backup period and also for theduration of the restoration period.

Application Security

The current environment for application security should be reviewed with respect to the new environment. Thisshould be undertaken to ensure that the integrity of the application, and the files on which the applicationdepends, 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 thattend 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 withexternal 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 theinterchange media is the same - for example, EOT (end of tape) handling.

Page 21: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 21/200

Advanced Programmers Reference Manual Migration2-3

Application Backup

Consideration should be given to the methods by which the application and associated files are to be secured.Where possible, take advantage of any features not previously available. However, do take care that the integrityof the application database and associated files is preserved while executing backup procedures.

Page 22: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 22/200

 

Migration Advanced Programmers ReferenceManual

2-4

Exporting Applications

The majority of application source code tends to reside either within the live application account or in a paralleldevelopment account. The following important steps should be executed before the export of an application.

1.  Create the source account or source accounts which combine all necessary application source and datafiles required to create, migrate and test the application.

2.  Remove all redundant or experimental source code and include items from the source code. Ensurethe source account control files are initialised or set to a known state. The source files should beinspected to ensure that duplicate or old copies of routines do not exist. Any developing code shouldbe moved to independent development source files. Ideally, only the live source code should exist in

the source file. Any ‘includes’, data records and suchlike should be moved to alternative files.

3.  Save the source account in ACCOUNT-SAVE format on a media which is compatible with the targetenvironment. Where possible the SMA save format should be used. Multiple volumes of media should

be avoided. Care should be taken to ensure that pointer file or binary items are not included in theapplication save - the save format for these type of items varies considerably with each supplier, andthese items are not required for application migration. The save should be verified where possible toensure the media can be read back correctly.

Page 23: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 23/200

Page 24: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 24/200

 

Migration Advanced Programmers ReferenceManual

2-6

Importing Accounts

Before importing a source account, certain decisions must be made about how the migrated application and anyrelated applications will be used. The following discussions and instructions assume a knowledge of the UNIXenvironment.

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 thesame 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 processattempts 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 begranted 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 theaccount 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 theshell commands below.

JBCLOGNAME=ACCNAME ; export JBCLOGNAME

User Port Numbers

Some applications make use of port numbers in their application security routines and rely on the consistency ofthe port number to implement these systems. The user is automatically given a unique port number at login time.

However, networked and terminal server based systems may cause a different port number to be assigned foreach login session. This can cause a problem for port based security routines. The consistency of the portnumber can be guaranteed in jBASE by setting the environment variable, JBCPORTNO, to a unique port

number according to the name of the user who logged in. This can be achieved by executing the shell commandbelow.

JBCPORTNO=UseridBasedPortNo ; export JBCPORTNO

Page 25: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 25/200

Advanced Programmers Reference Manual Migration2-7

Generating an Application Account

The following instructions assume that jBASE has been installed and configured on the target UNIX system.Once a user id has been allocated for the application account, the application id should be created by thestandard UNIX sysadm, or equivalent utilities and the Korn shell (ksh) should be selected as the default login

shell.

The application id should be used to restore the application files and perform the migration. This will ensure thatall the files are created with the correct user and group permissions. The next step is to configure the applicationaccount or home directory for jBASE. The easiest way to configure the application home directory for jBASE is

to execute the IJU command. The IJU command will create or modify the home directory .profile script insertingshell commands to set-up various environment variables. To execute the IJU command enter the following shellcommands:

$ PATH=/usr/jbc/bin:$PATH

This command inserts the absolute jBASE command path into the current command path. This means that the jBASE command path will be searched before any other paths when looking for the command to be executed.

$ LD_LIBRARY_PATH=/usr/jbc/lib

This command defines the absolute jBASE shared library path. This environment variable is used by thedynamic linker to find jBASE shared library functions. The dynamic linker will default to system library paths

when the paths in the environment variable have been exhausted.

$ export PATH LD_LIBRARY_PATH

The export command adds the new environment variables to the list of environment variables to be exportedwhen a command is executed.

$ IJU

The IJU command will prompt the user with a series of simple questions on how to configure the home directory.profile script file. The default .profile file, which is allocated by the UNIX system when a new home directory iscreated, can be changed to include a default set of jBASE environment variables. The file location of the systemdefault .profile file can vary however, the location should be found by consulting the system documentation.

Once created, any additional environment assignment or processing can be included - although care should betaken to ensure that any system or jBASE environment variables are set-up before the execution of the‘jbcconnect’ command. This command performs internal jBASE initialisation.

The easiest method of executing the modifications made to the .profile script is to terminate the current loginshell process and then login again making sure that the application id is used.

To restore the application source account, login to the application directory using the application user id. Thenattach the media device by executing the following command:

T-ATT SCT

The device name will depend upon the devices available in the /usr/jbc/de file. The above example uses theStreaming Cartridge Tape mnemonic, SCT.

Before restoring the application source account, the buffer or frame size of the current system should beconsidered. The reason for this is that the restore command can be instructed to modify the file modulo as thesource files are recreated in the applications home directory. The format of the jBASE restore command isdetailed below. One of the blocking options should be selected, depending on the frame size of the sourcemachine. This command assumes that the original file modulo has been sized correctly for the existing system orthat the relevant reallocation parameters have been configured.

Blocking options:

-b8 use this option if the source machine uses 1/2k frame size.

-b4 use this option if the source machine uses 1k frame size.

-b2 use this option if the source machine uses 2k frame size.

% ACCOUNT-RESTORE {options} applicationid

Page 26: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 26/200

 

Migration Advanced Programmers ReferenceManual

2-8

Each source file is created in the application home directory as a jBASE hash source file. Once all the sourcefiles have been successfully restored, the notes of source location should be used to identify the basic sourcefiles. Each source file including any files containing includes should be converted by the jBASE PORTBASutility.

Page 27: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 27/200

Advanced Programmers Reference Manual Migration2-9

Converting an Application

The jBASE PORTBAS command will scan every program and prepare it for the jBASE compiler. There arevery few changes required to make the source code compatible with the jBASE compiler. The changes requiredare executed by the PORTBAS program as follows:

1.  A UNIX directory is created and a copy of the original source hash file will be copied to the savedirectory. The original source file will then remain untouched for reference purposes.

2.  Each BASIC program is scanned for keywords used as variable names, which is not allowed in the jBC language. Portbas will not change the variable name in this instance but will capitalise the name.Thus the variable names LOOP, DATE and DATA will become Loop, Date and Data respectively.This allows the program to be read in its original context.

3.  The BASIC program is reformatted to aid portation and maintenance. The reformatting is performedso that legacy source code, which used various compression techniques to overcome item sizeconstraints, can be viewed more easily now that item size is not a limiting factor.

4.  If the source file is a SUBROUTINE, the name supplied as the subroutine argument is forced to be thesame as the source file name. The compiler uses this to name the subroutine rather than the file name.

 Note: Because of certain ambiguities in the original language specification, it is sometimes impossible

 for PORTBAS to decide whether the use of a keyword is correct or not. In certain cases it may wrongly

decide that a valid keyword is being used as a variable name and change it. However, PORTBAS tends

to get it right far more often than it gets it wrong thus saving a great deal of time and effort. The jBASE

compiler will trap any incorrect keyword modifications made by the PORTBAS command.

As the PORTBAS program executes, it will list the number of the current source item followed by the number ofkeywords converted. Scripts are available or can be created to utilise the output of the PORTBAS command.

 Note: Before using the PORTBAS command you should take care to ensure that only basic code exists in

the source file. PORTBAS cannot readily distinguish between basic source code and any other type of

data. Use the COPY or DELETE commands to remove records that do not contain basic source code.

The PORTBAS command will ignore dollar items (those items whose name begins with a $), as these are

assumed to contain basic object code which is no longer required. Finally, the PORTBAS command willoverwrite the existing basic source item.

The conversion phase of the application migration is now complete.

Page 28: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 28/200

 

Migration Advanced Programmers ReferenceManual

2-10

Compiling an Application

Before starting to compile the basic source files, any include items required by the basic source code should belocated. If the include files reside within another account, that account should be restored under its own homedirectory. All include file records should have been converted by the PORTBAS command before attemptingsource code compilation. If include files are located in other directories, links should be created to hashed filesin the other directories.

For example, MAINPROG is a basic source code item with an include statement:

INCLUDE IncludeFile StandardEquates

The “IncludeFile” is located in a general purpose account, now a directory, called anotherdir.

A link should be created in the application directory to reference the “IncludeFile” file in the “anotherdir”

directory. The shell command to create this link is as follows.

ln /home/anotherdir/IncludeFile IncludeFile

This will create a link in the home directory IncludeFile to the file, IncludeFile, in the directory, anotherdir.

Alternately, if you have an MD file defined using the JEDIFILENAME_MD environment variable, you can usea Q pointer to define IncludeFile.

Once all include files references have been processed, the application is ready for compilation. The jBASEBASIC command should be used to compile the basic source code programs. The BASIC command should onlybe executed from the application directory - NOT from an alternate directory which makes use of the link file.

The application id should also be used when using the BASIC command. The reason for using the application idand directory is that the .profile script will have set-up the necessary environment variables for the compilationprocess so that all the permissions will be correct, whereas attempting to compile from another user id ordirectory may cause very confusing problems later due to incorrect permissions or pathname assignments. Theformat of the BASIC command is detailed below.

BASIC SourceFilename Itemlist

The jBASE BASIC command uses a sophisticated set of compilation tools to compile and link jBC basic sourcecode into C object code. The BASIC command will produce a dollar item - an item with the same name as the

source item but prefixed by a $. The dollar item will be placed in the same file as the original source item. TheBASIC command is a front end to the jbc compiler which is described in detail elsewhere in this document.

Page 29: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 29/200

Advanced Programmers Reference Manual Migration2-11

Cataloging an Application

The jBASE CATALOG command can be used to create UNIX executables and shared libraries for theapplication source code. The jBASE CATALOG command should be executed from the application directory,rather than using link names, and the application id should be used. The reasons for executing the CATALOG

command from the application directory and application id are that the .profile script will have set-up therequired environment variables correctly and that the correct file permission will be used when creating anddeleting UNIX executables and directories. The format of the jBASE CATALOG command is as follows.

CATALOG SourceFilename Itemlist

When first invoked, the CATALOG command will create a $HOME/bin directory into which the UNIXexecutables will be placed. A $HOME/lib directory will also be created into which any subroutines will beplaced. The lib directory contains a jLibDefinition file, which describes how to build the subroutines into sharedlibraries. The entries in the jLibDefinition file are described below:

libname naming convention for shared object files.

exportname export list of shared objects. Used as cross reference to find subroutine functions.

maxsize maximum size of a shared object library before creating another.

When the maximum size of a shared library object is reached, a new shared library object will be created by theCATALOG command. The new shared library objects are named according to the definition of libname and arenumbered sequentially. For example:

libname=lib%a%n.so

where

%a = account or directory name

%n = number in sequence.

If subroutines were cataloged in the user account name fred, the shared object libraries would be named,libfred0.so, libfred1.so, libfred2.so and so on.

 Note: To guard against libraries being cataloged incorrectly, under the wrong user account name for

example, the definition of libname should be changed to libfred%n.so. This will ensure that any shared

objects are created using the proper user account name.

The shared library objects (.so files) contain the UNIX executables for subroutine source code. The sharedlibrary objects are linked at runtime by the jBASE call function which utilises the dynamic linker programminginterface. The dynamic linker will link shared libraries at the start of program execution time, or when requestedby the jBASE call function. For example, each executable created using the jBASE compiler will be linked withthe jBASE jEDI library functions (libjedi.so) at compilation time. This shared library enables database record

retrieval and update. It will be loaded into memory by the dynamic linker when an application executable startsexecution. However, the shared library containing any subroutines required by the executing program will onlybe loaded into memory when initially requested by the subroutine call. Only one copy of any shared library isrequired in memory at any time, thus reducing program memory requirements.

The $HOME/lib directory also contains a directory where all the subroutine objects (.o files) are held. These arerequired for making the shared library (.so) files.

The $HOME/lib directory also contains an export list (.el file), built by the CATALOG command, which is used

as a cross reference when dynamically linking shared objects at run time.

The main application program executables are placed in the $HOME/bin directory.

To enable the application executables to be found, the $HOME/bin path should be added to the PATHenvironment variable.

Page 30: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 30/200

 

Migration Advanced Programmers ReferenceManual

2-12

To enable the executing application to call the correct application subroutines, the JBCOBJECTLISTenvironment variable should be assigned to the application shared library path $HOME/lib. If the mainapplication program or any subroutine programs make calls to subroutines in other directories, the path of theshared library directories should also be added to the JBCOBJECTLIST environment variable. It isrecommended that executables or subroutines of the same name are not available from different directories. This

can make application execution very confusing and is reliant on assigning the lib or bin directories to theenvironment variable in the correct sequence. The assignment of the environment variables should be includedand exported in the .profile script file.

Executables and shared library objects can be removed from the bin and lib directories by using the DELETE-CATALOG command.

Once all the required application source code has been cataloged, the application can be executed for testing,either from the shell prompt or via a start-up procedure. The jsh will attempt to execute a start-up procedurefrom the MD file using the JBCLOGNAME environment variable, when invoked with a dash i.e. jsh -

Page 31: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 31/200

Page 32: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 32/200

Page 33: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 33/200

Advanced Programmers Reference Manual Execute Paths3-1

Introduction

The usual states for developing a small application can be summarised as:

1.  Create a source using ED, jED, vi, emacs or any other editor.

2.  Compile the source to object code using the BASIC command.

3.  Create a UNIX executable using the CATALOG command.

4.  Execute the command.

The above is a gross simplification, but acts as a template to explain the mechanics of the steps involved.Although the above steps are adequate for small applications, they can prove limiting for larger applications or

installations. For example, you may want separate development and live environments, a release mechanism, orthe ability to share SUBROUTINEs with different accounts and so on.

Remember that there are two fundamental source types in the jBC language. The first is the program type, thesecond is the subroutine type. The subroutine type has the statement ‘SUBROUTINE xxx’ in the code and is

treated as a subroutine rather than a main program. Subroutine sources, when compiled and cataloged, are turnedinto shared objects that can only be referenced by the CALL statement in another jBC program. Programs on the

other hand are turned into UNIX executable programs that can be executed using any of the standard UNIXmechanisms.

To start with, the above steps are explained in more detail to reveal the underlying mechanism.

Page 34: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 34/200

 

Execute Paths Advanced Programmers ReferenceManual

3-2

Creating a Source

There are two main file types used to contain jBC source, a jBASE hashed file and a UNIX directory. If a jBASE hashed file is used, the source items must be accessed using jBASE tools such as ED and BASIC.Therefore the most flexible file type for containing jBC source is a UNIX directory.

The following are examples of creating a source in a UNIX directory, and using the BASIC or jbc command to

compile it. Note that when using UNIX directories, it is quite acceptable to use a period ‘.’ to denote the currentdirectory when using jBASE programs. For example you can LIST the current directory using the command“LIST .”.

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

Page 35: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 35/200

Advanced Programmers Reference Manual Execute Paths3-3

Compiling Object Code

The general mechanism for compiling jBC code to object is the BASIC command.

The BASIC command will take a source record from a jBC file and create an object record in the same file. Thefile type can be any type supported by jEDI - a hashed file, or a UNIX directory for example. The name of the

output record can be in one of two formats. If the input record key ends in ‘.b’, the output record key will havethe same prefix but with a ‘.o’ suffix. If the input record key does not end in ‘.b’, the output record key will bethe input record key prefixed with a ‘$’ character.

Example

Create a main program and a subroutine, and compile them.

% mkdir src% vi src/mainprog% vi src/sub1% BASIC src mainprog sub1

Page 36: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 36/200

 

Execute Paths Advanced Programmers ReferenceManual

3-4

Creating a UNIX Executable

The general mechanism for converting object code to an executable program is the CATALOG command.

The CATALOG command will take a source record from a jBC file and will either create an executable program

or a shared object function. The only input record keys used by the CATALOG command are those with anextension of ‘.o’ or a prefix of ‘$’. If the input record was originally a SUBROUTINE, it will create shared

object in the directory specified by the expression $HOME/lib. If the input record was not a SUBROUTINE, itwill create a UNIX executable in the directory given by the expression $HOME/bin.

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 sharedobject containing the SUBROUTINE in the directory $HOME/lib.

Page 37: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 37/200

Advanced Programmers Reference Manual Execute Paths3-5

Execute the Command

Once the program and subroutine have been created, you can execute the program from any of the UNIX shells,from the jBASE shell (jsh), from a UNIX script, from a jBASE script, from jBASE program and so on.

In the example shown in ‘Creating a UNIX Executable’ above, the executable will have been placed in directory

$HOME/bin. Assuming that this directory is part of your PATH environment variable, there are a number ofways of executing it.

Example 1

Execute from a shell.

% mainprog

Example 2

Execute from another jBC program.

% COPY src a.n.other.b \(Ta.n.other.b

001 EXECUTE “mainprog”

Example 3

Use an explicit path name

% $HOME/bin/mainprog

Page 38: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 38/200

 

Execute Paths Advanced Programmers ReferenceManual

3-6

Program Execute Paths

Once an application source has been turned into a UNIX executable program (using BASIC/CATALOG/jbc),you have to think about how to access the program.

By default, the CATALOG command puts the executable programs into the directory $HOME/bin and so bydefault you should have $HOME/bin somewhere in your PATH environment variable. Supplied with jBASE is a

script called IJU (Install jBASE User ) that allows the systems administrator to create a template .profile scriptfor a user. Happily, the .profile created using IJU will include $HOME/bin as part of the users executable path.

As the jBASE programs created are pure UNIX programs, they can be placed anywhere on your UNIX system.Then, to execute them, you can either use a full path name (such as /home2/pipe/slipsource/fired) or, assuming

that the directory is part of the PATH environment variable, just the program name.

As with all UNIX programs, the order of directories in the PATH environment variable is important. UNIX willattempt to load programs in left to right order of the directory names in the PATH variable.

There is an exception to this rule, which happens when you attempt to execute a jBASE program from another jBASE program (or from a jCL script). If you have a Master Dictionary (or MD for short) file defined using the

JEDIFILENAME_MD environment variable, jBASE will first look in this file to see if the program to beexecuted is a jCL script. This takes precedence over external UNIX programs found in the PATH of the user.

Page 39: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 39/200

Advanced Programmers Reference Manual Execute Paths3-7

Subroutine Execute Paths

When a source is a subroutine rather than a program, the CATALOG command will created a shared objectrather than an executable program. The default for CATALOG is to place the result in the directory $HOME/lib,although this can be over-ridden - see the ‘jBuildSLib and CATALOG’ chapter.

Subroutines are executed through the CALL statement in a jBC program. When the first CALL statement isexecuted, the library code will perform the following initialisations:

•  Find details of all shared objects in the components given by the expression $JBCOBJECTLIST. TheJBCOBJECTLIST environment variable is a list of UNIX directories (which must be absolute path

names) or individual shared objects. Each component in the list delimited by a ‘:’ character.

•  If the environment variable JBCOBJECTLIST has not been established, find details of all sharedobjects in the directory $HOME/lib.

•  Find details of all shared objects in the directory $JBCRELEASEDIR/lib.

•  If the environment variable JBCRELEASEDIR has not been established, find details of all sharedobjects in the directory /usr/jbc/lib.

•  Should a duplicate subroutine name be found while searching the different shared objects, the firstsubroutine will be given precedence and subsequent duplicate subroutine names will be ignored.

A shared object has two components. The first is the actual object, which will have a ‘.so’ suffix. The second is adescription of the exported symbols in the shared object, and this will have a ‘.el’ suffix.

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 sharedobjects that either have already been parsed, or the shared objects that are currently in use by the jBCrun-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 looksomething like this:

% COPY . apps.com.el \(Tapps.com.el

001 JBC_SUB1002 JBC_DOTHIS003 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 looksomething like this:

% COPY . libpipeman.el \(Tlibpipeman.el

001 JBC_SUB1\JBC_DOTHIS]JBC_SUB2\JBC_DOTHAT002 libpipeman0.so]libpipeman1.so003 SUB1.o\DOTHIS.o]SUB2.o\DOTHAT.o

Page 40: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 40/200

 

Execute Paths Advanced Programmers ReferenceManual

3-8

004 2512\9090]1221\16399

This says that there are 4 subroutines defined, as shown in line 1. The first 2 subroutines SUB1 and DOTHIS arein shared object libpipeman0.so. The second 2 subroutines SUB2 and DOTHAT are in shared object

libpipeman2.so. Lines 3 and 4 contain statistical information for use by the CATALOG command.

Page 41: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 41/200

Advanced Programmers Reference Manual Execute Paths3-9

Copying Programs and Subroutines

The above descriptions give an insight into how jBASE uses the PATH variable for finding executable programsand the JBCOBJECTLIST variable for finding subroutines.

By default, the CATALOG command will place programs in the directory $HOME/bin, and subroutines in

directory $HOME/lib. All the user needs to do is to set the PATH variable to include $HOME/bin and you canexecute programs that can call subroutines. Note the JBCOBJECTLIST need not be set in this case, as it willdefault to $HOME/lib.

The following examples show how to copy your programs and subroutines around the system to make themaccessible to other users.

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 programis ‘/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, orare 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, orthe 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 iscopied. 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 thecopy and then allow users to log back on by using the ENABLE-LOGONS command. The followingexample 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 \*

Page 42: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 42/200

 

Execute Paths Advanced Programmers ReferenceManual

3-10

Example 3

Make subroutines accessible to others.

You can allow other users to access your subroutines simply by the user adding the directory of your subroutinesto their JBCOBJECTLIST environment variable. For example, if user ‘d4live’ wanted to access the subroutines

in account ‘dev’ while running program ‘smokeup’ they could do this:

% JBCOBJECTLIST=~dev/lib:$JBCOBJECTLIST smokeup

or alternately, if you want to access subroutines in a number of directories:

% JBCOBJECTLIST=$HOME/lib% JBCOBJECTLIST=~dev/lib:$JBCOBJECTLIST% JBCOBJECTLIST=$JBCOBJECTLIST:~supp/com/lib% export JBCOBJECTLIST% smokeup

In this example the final components of JBCOBJECTLIST will be ~dev/lib, $HOME/lib and ~supp/com/lib.This is the order that subroutines will be searched for. If duplicate subroutine names be found, the firstoccurrence takes precedence and the duplicates will be ignored.

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 libdirectory of account ‘live’. You must copy not only the shared object, but also the descriptor file - the files thathave 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 CATALOGcommand, the name of the account is relevant. For example, if you were to have a number of subroutines thathave 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 havebeen made into shared objects in the ‘live’ account using the CATALOG command. The names of these fileswould 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 firstcopy 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 youCATALOG 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 mayhave a ‘SECURITY’ subroutine that is common to all applications on your system, that resides in an accountcalled ‘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 - securityPassword:

Page 43: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 43/200

Advanced Programmers Reference Manual Execute Paths3-11

•  Change directory to where the objects were stored during the CATALOG procedure. This is in directorylib/objsecurity. Note these are standard archive objects, not shared objects.

% cd lib/objsecurity

•  Copy the new version of the object from the ‘dev’ account to the ‘security’ account. Note that in this casethe cp command uses the copy that was created by the CATALOG command - you could just as easily

use the copy created by the BASIC command.

% cp ~dev/lib/objdev/SECURITY.o .

•  Re-CATALOG the object.

% CATALOG . SECURITY.o

Page 44: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 44/200

Page 45: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 45/200

 

Chapter 4: C Extensions

Page 46: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 46/200

Page 47: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 47/200

Advanced Programmers Reference Manual C Extensions4-1

Calling C Functions - Overview

The jBC language provides a number of mechanisms for extending the language. The three main mechanisms forachieving this are:

1.  Calling external functions written in the C language.

2.  Extending the scope of the OCONV() and ICONV() functions.

3.  Extending the scope of user-exits, used mainly in legacy applications.

Points 2 and 3 are addressed in later chapters. This chapter deals with the most commonly used form ofextending the jBC language - calling external C functions.

There are a number of reasons why you might want to call an external C function rather than write thefunctionality directly in jBC:

•  Performance. Although jBC is highly tuned for the language, there is no doubt that under certaincircumstances re-writing application functionality in a C function can yield impressive results. Anexample of this is when code needs to examine each character (or even each bit) of a string ofinformation and perform different functionality according to the character or bit detected. You might

need to do this to parse a complex string or calculate CRC checksums for example.

•  Functionality. There are some things that the jBC language just does not cater for, such as OS systemcalls and communication functions.

•  External libraries. The mechanism provides a means of calling functionality written by otherdevelopment environments. For example, a jBC application may want to call a geographical databasepackage written in C.

There are an equal number of reasons why you should not  write C functions. Digest the list below before rushingheadlong into writing C functions just because it seemed like a good idea at the time.

•  Portability. Writing C code using an ANSI C compiler provides quite good portable code. However,quite good isn’t the same as completely portable. The programmer will need to write C functions with

portability in mind. Many books have been written on the subject of writing portable C code, andmost competent system level C programmers will already be knowledgeable in this area. Amongst the

common reasons for lack of portability are:

∗  Byte ordering can differ between machines of different architecture.

∗  Differences between signed and unsigned arithmetic.

∗  Compiler defaults for undefined aspects of C such as order of precedence in equal precedencestatements.

∗  The availability and functionality of library function calls.

•  Speed of writing. It will take considerably longer to write the same functionality in C than it will in jBC.

•  Performance. Care must be taken not to actually decrease performance. While writing in C willgenerate good results for some operations, other operations may provide negligible or even worseresults. For example, if you perform a lot of database operations, the time spent in the C code may beminimal compared to the time spent actually performing the database operation, so the overallimprovement is negligible. Also, as jBC has been highly tuned for string manipulations and storage

allocations, doing the same thing in a C function is not only ‘re-inventing the wheel’, but will take alot of care to give the same performance as jBC code.

•  Maintainability. A jBC program is much easier to maintain than a C function.

It is therefore recommended that writing C functions be limited to fairly small functions when the equivalent

functionality cannot be written in jBC, or when a small, often used code subset can yield high performance gains,or when interfacing to external third party software.

Page 48: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 48/200

 

C Extensions Advanced Programmers ReferenceManual

4-2

Simple C Example

A very simple example of calling an external C function would be:

DEFC getpid()

PRINT “The process ID for this program is “ : getpid()

In this simple example, the first line provides the compiler with information about the external C function. Thesecond line simply uses the function in the same way it would any other intrinsic function, such as COUNT() orINDEX().

A further modification to the above example could be:

DEFC INT getpid()pid = getpid()pid += 100PRINT “The process id + 100 = “ : pid

Again, the first line defines the function but this time explicitly tells the compiler that an integer value will bereturned (this is the default). The second line assigns the variable ‘pid’ to the return value from the getpid()

function call.In this example we are calling a standard C library function and no further source code is required. It can simplybe compiled and executed, for example:

% jbc prog1.b -o prog1% prog1The process id + 100 = 20678

That is really all you need to know in order to write complex C functions that can be called by a jBC application.The remainder of this chapter explains the interfaces between the jBC application and the C function, and theability of the C function to utilise standard jBASE macros and functions. If your C functions are going to be

isolated from jBC, such as when interfacing to a third party software package, most of information in theremainder of this chapter is unnecessary.

Page 49: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 49/200

Advanced Programmers Reference Manual C Extensions4-3

Fundamental Components of C Interfaces

 jBC Supplied Header File

A header file is supplied with jBASE for inclusion in C functions. The file is named jsystem.h and resides in the

directory $JBCRELEASEDIR/include. If you compile the C source using the ‘cc’ command you will need toinclude this directory in the include path, for example:

% cc func1.c -c -I $JBCRELEASEDIR/include

If you use the ‘jbc’ command instead, the directory is automatically included and your command is simply:

% jbc func1.c -c

The jsystem.h header file contains all the definitions required to support C function calls from a jBC program,including definitions for VAR, INT32, FLOAT and STRING as detailed below. Your C source would normallyinclude this file at the beginning. For example:

#include <jsystem.h>INT32 MyFunc(FLOAT Param1){

/* */}

Note that the jsystem.h file also includes the standard C header file stdio.h, as well as other jBASE providedheaders.

Naming Conventions

The supported jBASE functions and macros follow a simple naming convention which follows the formatFUNCNAME_RPPPPP where FUNCNAME describes the functionality, R describes the return value from thefunction/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 COUNTfunction, the function returns a 32 bit integer and requires 2 parameters, both of them the address of a jBASEVAR 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 andcan assume many types, such as an INT32 integer, a FLOAT floating point value and so on. There are manyfunction 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 use64 bit integers. Therefore, when interfacing with jBC variables, always use the ‘INT32’ definition instead of‘int’.

Page 50: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 50/200

 

C Extensions Advanced Programmers ReferenceManual

4-4

FLOAT Variable

This is a definition of a floating point value used internally by jBC. The format is not exactly as a C programmermight expect, and is subject to change in future versions of jBASE. As long as the C function uses the definitions

and macros supplied with jBASE for the FLOAT variable, future compatibility is assured.

You cannot manipulate these floating point values in the same way that you can manipulate C floating pointvalues. For example, if you wish to multiply two FLOAT variables, then instead of using the ‘*’ operator in a Cfunction, you should use the supplied MUL_FFF macro to perform the operation.

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 ofunsigned 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 unsignedcharacters 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 providedto the compiler. These descriptions are called function prototypes. They tell the compiler the name of thefunction, 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 = 12V2 = 34V3 = “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 andparameters that the C function expects:

INT  A 32 bit integer. Although INT is the keyword used in the function prototype, in the C source codeyou 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 normallyuse ‘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 arenoted later). Although VAR is the keyword used in the function prototype, in the C source codeyou 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.

Page 51: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 51/200

Advanced Programmers Reference Manual C Extensions4-5

Automatic Type Conversion

The variables in a jBC program are typeless. This means that the programmer doesn’t have to be concerned withthe format of the variable. Consider the following:

Var1 = 12Var2 = 12.34

Var3 = “12.34”Var4 = Var1 + Var2 + Var3

In the above example, Var1 will become a variable of type INT32 ( a 32 bit integer), Var2 will become avariable of type FLOAT (a floating point unit) and Var3 will become a variable of type STRING * (an array of

unsigned characters). The last line, where Var4 is assigned a value of type FLOAT means Var1 will have to beconverted from type INT32 to type FLOAT and Var3 converted from type STRING * to type FLOAT before thecalculation and subsequent assignment can occur. This type conversion is handled automatically by the compiler.

Similar type conversion is handled by the compiler when calling C functions. Consider the following:

DEFC INT MyFunc(STRING, INT)Var1 = 12Var2 = “123”PRINT “The result of MyFunc is “ : MyFunc(Var1, Var2)

In this example, Var1 is initially assigned as an INT32 of value 12, and Var2 will be assigned as a STRING * ofvalue “123”. This conflicts with the types that the function ‘MyFunc’ is expecting. So, prior to the function beingcalled, the compiler ensures that the INT32 with a value 12 will be converted to a type STRING * with a value“12” and that the STRING * type with a value “123” will be converted to an INT32 type of value 123.

Finally, the return from MyFunc is a 32 bit integer, whereas the PRINT and the string concatenation requireSTRING types -- again the compiler will force the conversion.

C Function Type Conversion

As described above, the compiler will cater for all the type conversions required for the parameters and returnvalue of the function. Within the C function there may be times when type conversion is required. Supplied with

 jBASE in the header file jsystem.h are a number of defined macros and functions to support this.These conversions are mostly used when a VAR type parameter is used. In other words we use the address of the

 jBC variable which at this point is typeless. Consider the following example of jBC code and C code:

DEFC MyFunc(VAR)PRINT “Enter details : “:INPUT DetailPRINT “This result of MyFunc is “:MyFunc(Detail)

#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 notype conversion has occurred. When function MyFunc wants to examine the variable passed as the firstparameter (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.

Page 52: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 52/200

 

C Extensions Advanced Programmers ReferenceManual

4-6

C Function Definition

Once a function has been prototyped in a jBC source, the C function definition usually has to follow the samepattern. For example, if the jBC source contains:

DEFC MyFunc(INT, VAR, STRING)

The C function might look something like this:

#include <jsystem.h>INT32 MyFunc(INT32 V1, VAR * V2, STRING * V3){

/* */}

There is an exception to this rule when the return type is VAR. In the C language the structure can be returned,but C does not have the flexibility of say, C++ for variable construction and destruction which we need. So,when the return type is VAR, the first parameter passed to the C function is actually the address of a variable(allocated by the compiler) that the function should amend as if it were the return variable. For example, if the

 jBC source contains:

DEFC VAR MyFunc(INT)PRINT “Result of MyFunc(3) is “:MyFunc(3)

The C code would look something like this:

#include <jsystem.h>VAR * MyFunc(VAR * result, INT32 param){

char buffer[128] ;sprintf(buffer,”MyFunc[%d]”,param);STORE_VBS(result, (STRING*) buffer);return result ;

}

Page 53: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 53/200

Advanced Programmers Reference Manual C Extensions4-7

A More Complex Example

This example allows the user to enter a string of characters and a number, call function ParseIt and then print theresult of function ParseIt. The C function ParseIt will extract a number of space delimited fields, and return justthat number of fields.

First, the jBC source which we will assume to be in file prog2.b:

DEFC VAR ParseIt(INT, VAR )PRINT "Enter sting to parse : ":INPUT StringInPRINT "Enter number of fields to parse : ":INPUT FieldQtyPRINT "Result = " : ParseIt(FieldQty, StringIn)

Now the C source which we will assume to be in file prog2C.c:

/** Include the header definitions.*/#include <jsystem.h>

/** Start off the function definition.*/VAR *ParseIt(VAR *result,INT32 qty,VAR *string_in){

/** Declare the automatic C variables we require.*/

STRING * start, * end ;/** Make sure input is a 0 terminated string.*/

start = end = CONV_SFB(string_in) ;/*

* Scan through 'qty' occurrences of* space characters.*/

while(*end != '\0' && qty > 0){

if (*end++ == ' ')qty--;

}/** Store all characters between the start and end.*/

STRING_MAKE_NEW_VBIS(result,(end-start),start);/** Return correct address to caller.

*/return result ;

}

The two sources can be compiled to create an executable program with:

% jbc prog2.b prog2C.c -o prog2

Notes:

•  Because the return type is VAR, the first parameter passed to ParseIt will be the address of a variableallocated by the compiler. The function ParseIt uses this as its return variable, and upon return must alwaysprovide this as the return parameter.

•  The macro STRING_MAKE_NEW_VBIS will create a variable of type STRING given the length and

address of the string to create. This macro is described in more detail later.

Page 54: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 54/200

 

C Extensions Advanced Programmers ReferenceManual

4-8

•  In the program prog2.b, the user enters variable ‘FieldQty’. Following an INPUT statement the variable willbe of type STRING. However, the function assumes an INT32 will be passed, so automatic type conversion

occurs. Should the user not have entered an integer, an error message is displayed at run-time and the jBCdebugger is entered (the program could always test for this using the NUM() function).

•  Should the user have entered a floating point value such as ‘3.4’, this will be truncated to an integer.

Page 55: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 55/200

Page 56: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 56/200

 

C Extensions Advanced Programmers ReferenceManual

4-10

Creation and Destruction of VAR Type Variables

Within a C function there may be a need to create VAR type variables as part of the function. There are anumber of macros and functions to enable the variable to be created and destroyed.

The variable first needs to be declared within you C function like this:

#include <jsystem.h>INT32 MyFunc(INT32 param1){

VAR WorkVar, DoThis ;

Before using the variable, you must initialise the elements of the structure. You can do this with one of twomacros, the first to create a register variable, and the second to create a user variable. You will most likely usethe second and create a user variable. For example:

#include <jsystem.h>INT32 MyFunc(INT32 param1){

VAR WorkVar, DoThis ;

STRING_INITIALISE_REG_VB(&WorkVar);STRING_INITIALISE_USER_VB(&DoThis);

In the above example the variable ‘WorkVar’ is initialised to be a register variable, and the variable ‘DoThis’ isinitialised to be a user variable.

Once initialised from a C point of view, they are now the equivalent of ‘uninitialised variable’ in the jBClanguage. Therefore, before they can be referenced they need to have data added to them. For example, youmight do this:

STORE_VBI(&WorkVar, 123) ;STORE_VBS(&DoThis, (STRING*) “Value of WorkVar ”);CRT_VB(&DoThis);CRTN_VB(&WorkVar);

Finally, at the end of the program, any storage space used by the variable needs to be released (or if a filedescriptor, the file needs to be closed). The macro to release all space and close files isSTRING_RELEASE_EXT_VB, for example:

STRING_RELEASE_EXT_VB(&WorkVar) ;STRING_RELEASE_EXT_VB(&DoThis) ;

Page 57: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 57/200

Advanced Programmers Reference Manual C Extensions4-11

Supported Functions and Macros

Within the supplied header file jsystem.h there are a large number of functions and macros to enable you tomanipulate VAR type variables. The functions and macros explicitly supported are detailed here. You can alsouse the macros generated by the jBC compiler, such as DCOUNT_IBB. While these are not explicitly supported

and are subject to change, the nature of their usage means that it is highly unlikely they will change.

All the defined functions and macros have the name format ‘NAME_rpppp’. The first part of the name ‘NAME’describes the action, such as COUNT or INDEX. The second part of the name describes the return value and thepassed parameters. For example, the macro INDEX_IBBI describes the INDEX function, the return value is I for

INT32, and there are 3 passed parameters, B for BASIC variable address, B for BASIC variable address and Ifor INT32.

There are often two forms of the macro or function you will see defined in jsystem.h. For example

‘JLibECOUNT_IBB’ and ‘COUNT_IBB’. Always use the second form.

The supported functions and macros are defined in the following paragraphs.

Macros to Store Values into a Variable.

STORE_BBF(Target,Numeric)

Store a FLOAT type variable into a VAR variable, and return the address of the Target VAR variable. Considera function that takes two floating point values, multiplies them and returns the result. The jBC source would looklike this:

DEFC VAR Mul2(FLOAT, FLOAT)INPUT float1INPUT float2res = 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 isa performance feature - what actually happens is that instead of the Source variable being copied, just thepointers 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 sourcewould look like this:

Page 58: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 58/200

 

C Extensions Advanced Programmers ReferenceManual

4-12

DEFC VAR xor2(FLOAT, FLOAT)INPUT int1INPUT int2res = xor2(int1, int2)PRINT “The first value is “ : OCONV(int1,”MCDX”)PRINT “The second value is “ : OCONV(int2,”MCDX”)

PRINT “The result is “ : OCONV(res,”MCDX”)

The C function source would look like this:

#include <jsystem.h>VAR * xor2(VAR * result, INT32 int1, INT32 int2){

return STORE_BBI(result, int1 ^ int2) ;}

STORE_VBI(Target, Numeric)

Same as STORE_BBI except a void is returned.

STORE_BBS (Target, String)Store a 0 terminated array of characters into a VAR type variable. Consider the following example where wegenerate two record keys, each with a random element based on a seed value passed. The jBC source may looklike this:

DEFC MakeKeys(VAR, VAR, INT)PRINT "Enter seed : ":INPUT SeedMakeKeys(Key1, Key2, Seed)PRINT "Record key 1 = " : Key1PRINT "Record key 2 = " : Key2

The C source would look something like this:

#include <jsystem.h>

INT32 MakeKeys(VAR * Key1, VAR * Key2, INT32 Seed){

char buffer[128] ;sprintf(buffer,"key_cust_no*%d",rand() % Seed);STORE_BBS(Key1, (STRING*)buffer);sprintf(buffer,"product/*%d",rand() % Seed);STORE_BBS(Key2, (STRING*)buffer);return 0;

}

STORE_VBS (Target, String)

Same as STORE_BBS except a void is returned.

Variable Type Conversion

CONV_FI(Integer)

Given a 32 bit integer, convert it to a FLOAT. For example, could be used to multiply a FLOAT with an INT32as 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.

Page 59: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 59/200

Advanced Programmers Reference Manual C Extensions4-13

CONV_FB(Source)

Given the address of a VAR type BASIC variable, perform type conversions on the variable and return theFLOAT 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 isalready a FLOAT, a simple extraction takes place.

CONV_IB(Source)

Given the address of a VAR type BASIC variable, perform type conversions on the variable and return theINT32 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 isalready an INT32, a simple extraction takes place. Consider the previous example where we generate two recordkeys, each with a random element, based on a seed value passed. This time the third parameter is passed as aVAR pointer instead of an INT32, and the MakeKeys function has to perform its own type conversion. The jBCsource may look like this:

DEFC MakeKeys(VAR, VAR, VAR)PRINT "Enter seed : ":INPUT SeedMakeKeys(Key1, Key2, Seed)PRINT "Record key 1 = " : Key1PRINT "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. UseCONVLEN_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 thestring.

CONV_SFB(Source)

Similar to CONV_SB except the STRING will be terminated with a 0 (null) character. This is often useful forpassing 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

Page 60: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 60/200

 

C Extensions Advanced Programmers ReferenceManual

4-14

IF LEN(FileName) AND Exists(FileName) THENPRINT "File exists"

END ELSEPRINT "File does not exist"

END

Now the C function:

#include <jsystem.h>INT32 Exists(VAR * FileName){

struct stat si ;return (!lstat((char*)CONV_SFB(FileName),&si);

}

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.

VAR Variable Creation and Destruction

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 exampleis:

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 jBCfunctions.

STRING_RELEASE_EXT_VB(Source)

All the external resources associated with the variable ‘Source’ are released. For example, if it were an openedfile descriptor then the file will be released. If it were a STRING type variable, then the storage space associatedwith 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 usefulwhere 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”);

Page 61: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 61/200

Advanced Programmers Reference Manual C Extensions4-15

/* More C code *//* Tidy up the allocated variables */STRING_RELEASE_REG_VB(&Var);return 0;

}

In this example, ‘Var’ is created as a register variable of type STRING of length 10 bytes. Just prior to the

function returning, the STRING_RELEASE_REG_VB is used. However, as it is only a small string, the spacewill not be released. Thus every time the function is called, space will be lost.

There are two ways to avoid this conflict.

Firstly, use the STRING_RELEASE_EXT_VB definition instead of the STRING_RELEASE_REG_VB. Thiswill release all space used by the variable.

Secondly, don’t always initialise the variable by making it static, as in:

INT32 MyFunc(){

static VAR Var ;if (CONVTYPE_IB(&Var) == 0){

STRING_INITIALISE_REG_VB(&Var) ;}STORE_VBS(&Var, (STRING*) “1234567890”);/* More C code *//* Tidy up the allocated variables */STRING_RELEASE_REG_VB(&Var);return 0;

}

STRING Type Manipulation

STRING_RESIZE_VBI(Target, Length)

This will re-size the variable ‘Target’ of type STRING to become length ‘Length’ in size. The original contentswill 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 filedescriptor, the file will be closed. If you do not want to retain the original contents of the variable, use theSTRING_MAKE_NEW_VBIS functionality - keeping the contents is a potential overhead you do not need.

STRING_MAKE_NEW_VBIS (Target, Length, Source)

This will make the variable ‘Target’ into a type STRING variable of length ‘Length’ bytes. The contents aspointed to by ‘Source’ will then be copied to the newly allocated STRING.

If the variable ‘Target’ is not already of type STRING, the contents of the variable will be lost, or if a filedescriptor, the file will be closed.

If you want to retain the original contents of the variable, use the STRING_RESIZE_VBI functionality.

The parameter ‘Source’ can optionally be a NULL pointer, in which case the STRING is still created but thecontents of it are indeterminate.

Page 62: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 62/200

Page 63: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 63/200

Advanced Programmers Reference Manual C Extensions4-17

VAR * _jb_p2;VAR * _jb_p3;VAR * _jb_p4;{

SUBROUTINE_DATA(4)SUBROUTINE_INIT(&StackData, GlobalBasicVars, &JBCLevel, SubroutineArgs,

SubroutineArgsFlags, ActualFlags, "VVVV", _jb_p1, _jb_p2, _jb_p3,

 _jb_p4);SUBROUTINE_INIT_COMMONMCAT_BBI(_jb_p4, 3, _jb_p1, _jb_p2, _jb_p3);RETURN_V;

 _jl_main_end: _jl_function_end:SUBROUTINE_ENDRETURN_SWITCHPROGRAM_END

The above C source can be used as a full replacement for the jBC source code equivalent. This is because the

compilation of jBC source code involves translating to C code and then compiling the C code. All we have doneis to intercept the two stages, and will just carry on with stage 2 in future.

However, the above code can be stripped further leaving just the following:#include <jsystem.h>JBC_MyFunc(ActualFlags, _jb_p1, _jb_p2,

 _jb_p3, _jb_p4)char * ActualFlags;VAR * _jb_p1;VAR * _jb_p2;VAR * _jb_p3;VAR * _jb_p4;{

MCAT_BBI(_jb_p4, 3, _jb_p1, _jb_p2, _jb_p3);return 0 ;

}

The additional parameter ‘ActualFlags’ is a 0 terminated string detailing what parameters the calling program isactually passing, and can be used to ensure the calling program passes four parameters. In our example, thevariable ‘ActualFlags’ should point to a string “VVVV”. If it doesn’t, the calling program has passed an invalidnumber of parameters.

Page 64: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 64/200

 

C Extensions Advanced Programmers ReferenceManual

4-18

Compiling and Linking with C Functions.

There are a number of ways that a jBC source can be compiled and linked with C functions to create anexecutable program. In practice, many of the examples below would be performed using make files, rather thanthe developer typing the commands in at the shell prompt.

Compiling sources together. For example, to compile a jBC source with the two C functions it requires:

% jbc prog1.b func1.c func2.c -o prog1

Compiling sources with objects. Separately compile the jBC source and the C source:

% jbc -c prog1.b% jbc -c func1.c% jbc -c func2.c% jbc prog1.o func[12].o -o prog1

Compiling sources with libraries. You would create a pool of functions and allow the linker to decide whichobjects to link with the jBC code. For example:

% jbc -Jamylib.a func[12].c

% jbc prog1.b mylib.a -o prog1

An alternate mechanism for achieving exactly the same result as above is:

% jbc -c func1.c% jbc -c func2.c% jbc -c prog1.b% ar -r mylib.a func1.o% ar -r mylib.a func2.o% jbc prog1.o mylib.a -o prog1

Now an example of a main program, one SUBROUTINE written in jBC, and two C functions, all linkedtogether:

% jbc prog1.b sub1.b func1.c func2.c -o prog1 -JLS

During a normal CALL statement execution, the jBC code will look in all the defined shared objects to resolvethe SUBROUTINE call. However, the -JLS option means the SUBROUTINE must be statically linked with theprogram, which it is.

All the above examples result in the C functions being linked statically with the program. Thus, if you have ten

programs all using a common C function, there will be ten copies of the function linked with the programs. Thistechnique has a number of drawbacks:

•  If all ten programs are run simultaneously, there will be ten copies of the function in main memory.

•  If the C function is changed, all ten programs need to be re-linked (not too difficult if you havecreated a suitable make file).

•  Any SUBROUTINEs that call the C functions must also be linked in statically.

The way round the above limitations is to create shared objects of the C functions. This topic is discussed ingreater detail in the ‘jbc and BASIC’ chapter.

However, as a small example, the following shows how two C function sources can be generated into a sharedobject:

% jbc -c func1.c func2.c% jBuildSLib func[12].o -o myfunc.so

The main program that references the two shared objects can now be compiled by referencing the shared objectlike this:

% jbc prog1.b -o prog1 myfunc.so

Before the program ‘prog1’ can be executed, the shared object needs to become known to the operating system.

This can be done in two ways:

Page 65: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 65/200

Advanced Programmers Reference Manual C Extensions4-19

The first is to update the environment variable LD_LIBRARY_PATH (or LIBPATH if using AIX) to point tothe directory that the shared object resides in. For example:

% export LD_LIBRARY_PATH=`pwd` : $LD_LIBRARY_PATH

The second is to copy the shared object to a directory already pointed to by LD_LIBRARY_PATH (orLIBPATH if using AIX). For example:

% cp myfunc.so $JBCRELEASEDIR/lib

Page 66: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 66/200

 

C Extensions Advanced Programmers ReferenceManual

4-20

General Rules and Helpful Hints

This section gives a list of useful rules and hints to apply to your C code.

•  Always use the supported functions, macros and definitions. In the future, the internal workings of jBASE

may change, but by using supported functionality, at the very worst a re-compilation will be necessary.

•  Try to make your C code portable, even if you believe the code will only ever run on a single architecture.Many books have been written on this issue, and some examples were described earlier in this chapter.

•  Try to build your C functions into shared objects where possible.

•  Make the most of make files to build your code.

•  Remember that when the C function is called, some of the parameters may point to the same variable.Consider the following jBC source:

DEFC myfunc(VAR, VAR )Var1 = “This is Var1”myfunc(Var1, Var1 )

The C code for myfunc would look something like this:

#include <jsystem.h>INT32 myfunc(VAR * p1, VAR * p2){

The variables ‘p1’ and ‘p2’ would point to the same variable. If you modified the variable at ‘p1’, itwould affect the data pointed to by ‘p2’.

•  You should be careful of register variables. These can be created using the STRING_INITIALISE_REG_VBmacro described earlier, or more likely passed to your C function by the compiler. If you call some of the

 jBC functions such as DCOUNT_IBB, they will potentially release any external space associated with aregister variable. This can be used to your advantage in some cases. Consider the following C function thatsimply appends the string “xyz” to the parameter p1 and places the result in parameter p2:

#include <jsystem.h>INT32 cat(VAR * p1, VAR * p2){

STORE_VBB(p2, p1 );STRING_RESIZE_VBI(p2, CONVLEN_IB(p2)+3);memcpy(CONV_SB(p2)+CONVLEN_IB(p2)-3,"xyz",3);return 0;

}

If the above C function were called from the following jBC source:

DEFC cat(VAR, VAR)p1 = "this is"cat(p1:" from here", p2)

parameter ‘p1’ in the C function will point to a register variable. This will mean the subsequentSTORE_VBB executes much quicker, as it recognises the source variable is a register variable, and so

 just copies pointers and voids the source, rather than actually copying the data. This subject is alsodiscussed in the earlier description of STORE_VBB.

•  Do not use the chdir() function call directly. This is because, for jEDI functionality, we always need to know

the current working directory, and for performance reasons we cannot continually call getcwd(). Instead, ifyou want to change the current directory, use the jBC macro CHDIR_IB. The following is an example ofchanging the current working directory to /home2, and returning 1 if it succeeded or returning 0 on error(although as an example, it would be easier for the calling jBC code to use the intrinsic CHDIR() function).

#include <jsystem.h>INT32 ChdirToHome2(){

VAR WorkVar ;int rc ;

Page 67: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 67/200

Advanced Programmers Reference Manual C Extensions4-21

STRING_INITIALISE_USER_VB(&WorkVar);STORE_VBS(&WorkVar, (STRING*)"/home2" );rc = CHDIR_IB(&WorkVar);STRING_RELEASE_EXT_VB(&WorkVar);return rc ;

}

•  Always use ‘unsigned char’ definitions (STRING types) when dealing with character arrays that may containsystem delimiters. Be wary of different environments that require different definitions. For example, to lookfor an attribute mark in a string, some environments require:

ptr = memchr(start, 0xfe, len);

Whereas other environments require:

ptr = memchr(start, (char) 0xfe, len);

Page 68: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 68/200

Page 69: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 69/200

 

Chapter 5: ICONV and OCONVExtensions

Page 70: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 70/200

Page 71: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 71/200

Advanced Programmers Reference Manual OCONV Extensions5-1

Introduction

The OCONV and ICONV functions, built into the jBC language, provide a means of performing conversions tostring’s of data. The OCONV function is used for Output conversions where an internal representation of thedata is converted to one more understandable by a user. The ICONV function is used for Input conversions

where formats entered by the user are converted into an internal representation.

An example of an OCONV would be to convert a time in internal format to an external representation, like this:

PRINT OCONV(TIME(), “MTS”)

This will cause the current time to be printed in the format HH:MM:SS.

Similarly, the code

INPUT CurrentTimeITIME = ICONV(CurrentTime, “MTS”)

allows the user to enter the time in HH:MM:SS format, and the ICONV will convert it to an internalrepresentation in the variable ITIME.

A full list of these conversion codes is available in the Programmers Reference Manual.

Historically, an application developer has been able to write specialised functionality in assembler code andexecute this assembler code through a mechanism known as a user exit. This takes the following form:

OutputData = OCONV(InputData,”Uxxxx”)InputData = ICONV(OutputData,”Uxxxx”)

The value xxxx is a 1 to 4 digit hex value that describes the location of the user exit code.

With jBASE it is possible to extend the scope of the conversion codes and user exits. This should really only be

done for legacy code - any new code written should use the C function interface, documented in an earlierchapter.

In both cases, the extensions are made possible by writing a SUBROUTINE with a name conforming to aspecific naming convention. In the examples shown, we always use the jBC language. However, these extensions

can be written as C code instead of jBC code. The section ‘Replacing SUBROUTINEs with C Functions’ in the‘C Extensions’ chapter explains this mechanism.

Should any extensions to conversion codes or user exits clash with those provided by jBASE, the jBASE version

will take precedence. For example, you cannot write your own version of the existing “MT” conversion code.

Page 72: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 72/200

 

OCONV Extensions Advanced Programmers ReferenceManual

5-2

Conversion Code Extensions

As an example, assume you want to support the conversion code “BF” with an OCONV or ICONV function. Thecalling jBC source may look like this:

PRINT OCONV(“I am on a diet”, “BF”)

Under normal circumstances this would fail and the debugger would be entered with an illegal conversion codemessage.

You can write an extension to the conversion codes by creating a normal SUBROUTINE with the nameJBCUserConversions with five parameters. An example of source code to handle the “BF” conversion codeextension is:

SUBROUTINE JBCUserConversions( result, source, code,type, error)

BEGIN CASECASE code = "BF"

IF type THENresult = source : " was OCONV"

END ELSEresult = source : " was ICONV"

ENDCASE 1

error = 1END CASERETURN

Use the BASIC and CATALOG commands to make the subroutine available, and call it using the normalSUBROUTINE calling mechanism.

The five parameters passed to the SUBROUTINE are:

result This is the variable to be updated with the conversion.

source This is the original variable passed to ICONV or OCONV that is to have the conversion performedupon it.

code This is the actual conversion code specified in the ICONV or OCONV call. In the above example itwill be “BF”.

type This is set to 0 if the SUBROUTINE is called as an ICONV, or to 1 if the SUBROUTINE is calledas an OCONV.

error This can be updated in the event of an error. By default, jBASE will assume that the conversion ishandled correctly by the user-written extension. In the event that the conversion code is also

unknown to the user-written extension, this variable can be set to non-zero causing a conversionerror to be displayed and the debugger to be entered.

Page 73: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 73/200

Advanced Programmers Reference Manual OCONV Extensions5-3

User Exit Code Extensions

As explained previously, the ability to write assembler code and call the assembler code as a ‘user-exit’ isprovided purely for legacy applications. This technique is not recommended for new applications.

A user-exit can be called by a user application via the ‘U’ conversion code in an ICONV or an OCONV

function. For example, the jBC code might be:

user = OCONV(“”,”U50BB”)

In this example, the user-exit 50BB is a historic user-exit and is already supplied by the jBASE developmentsystem (it returns the port number and name of the user).

In the above example, the value “50BB” is a description of the user exit number and is split into twocomponents. The first character is historically called the entry-point, and in this case the entry-point is “5”. Thenext 3 characters are historically called the frame-id which in this case is “0BB”.

The user-exit number is a 1 to 4 digit hex value, case insensitive. If fewer than 4 characters are used, it is paddedwith leading zeroes. For example, user-exit “U23” means “U0023”, or entry point “0” in frame-id “023”.

Let us consider the example below where we call user-exit 90fb:

res = OCONV(“input details”, “U90fb”)

Under normal circumstances this would fail and the debugger would be entered with an illegal conversion codemessage.

You can write extensions to the conversion codes by creating a normal SUBROUTINE with the name Uxxx for

each of the frame-id’s you wish to support. There are 5 parameters passed to a subroutine, as for the ConversionCode extensions described earlier.

A simple example of such a source code to handle just the “U90fb” user-exit is:

SUBROUTINE U0FB( result, source, code,type, error)

UCASE = OCONV(code, “MCU”)[1,5]BEGIN CASE

CASE UCASE = "U90FB”IF type THEN

result = source : " was OCONV"END ELSE

result = source : " was ICONV"END

CASE 1error = 1

END CASERETURN

The SUBROUTINE is functionally very similar to that for the Conversion Code Extensions. There maindifference is the line:

UCASE = OCONV(code, “MCU”)[1,5]

This is to make the conversion code quicker and more reliable to parse. For example, the user exit “U90fb”

could take the following formats:

PRINT OCONV(“”,“U90fb”)PRINT OCONV(“”,”u90FB”)PRINT OCONV(“”,”U90Fb” : CHAR(253) : “Extra detail” )

Page 74: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 74/200

Page 75: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 75/200

 

Chapter 6: IOCTL Function

Page 76: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 76/200

Page 77: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 77/200

Advanced Programmers Reference Manual IOCTL Function6-1

Introduction

The jBC language provides an intrinsic function called IOCTL that behaves in a similar manner to the C functionioctl(). It’s purpose is to allow commands to be sent to the database driver for a particular file, and then toreceive a reply from the database driver.

As with the C function ioctl, the use of IOCTL is highly dependent upon the database driver it is talking to. Eachdatabase driver may choose to provide certain common functionality, or may add its own commands and so on.This is especially true of user-written database drivers.

First, an example of a jBC source that opens a file and finds the type of file:

INCLUDE JBC.hOPEN “MD” TO DSCB ELSE STOP 201,”MD”status=“”IF IOCTL(DSCB,JIOCTL_COMMAND_FILESTATUS,status) THEN

PRINT “Type of file = “:DQUOTE(status<1>)END ELSE

PRINT “IOCTL FAILED !! unknown file type”END

If the ELSE clause is taken, it does not necessarily mean there is an error, it only means that the database driverfor file “MD” does not support the command that was requested from it. The file JBC.h is supplied with jBASEin the directory $JBCRELEASEDIR/include. If the source is compiled with the jbc or BASIC command, thisdirectory is automatically included in the search path and no special action is needed by the programmer for the“INCLUDE JBC.h” statement.

The format of the IOCTL function is:

IOCTL(filevar, command, parameter)

Where:

filevar is an variable that has had a file opened against it using the OPEN statement. However, if youwant to use the default file variable, use -1 in this position. For example:

OPEN “MD” ELSE STOPfilevar = -1IF IOCTL(filevar,JIOCTL_COMMAND_xxx,status) ...

command can be any numeric value (or variable containing a numeric). However, it is up to thedatabase driver to support that particular command number. The remainder of this chapterdescribes 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, andwill 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 beenrecognised.

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  databasedrivers.

Page 78: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 78/200

 

IOCTL Function Advanced Programmers ReferenceManual

6-2

JBC_COMMAND_GETFILENAME Command

Using this command to the IOCTL function, you can determine the exact UNIX file name that was used to openthe file. This is helpful because jEDI uses Q pointers, F pointers and the JEDIFILEPATH environment variableto actually open the file, and the application can never be totally sure where the resultant file was really opened.Normally of course, this is of no concern to the application.

Example

Open the file CUSTOMERS and find out the exact UNIX path that was used to open the file.

INCLUDE JBC.hOPEN “CUSTOMERS” TO DSCB ELSE STOP 201,”CUSTOMERS”filename = “”IF IOCTL(DSCB,JBC_COMMAND_GETFILENAME,filename) ELSE

CRT “IOCTL failed !!” ; EXIT(2)ENDPRINT “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 itcan be run against a file descriptor for any file type.

Page 79: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 79/200

Advanced Programmers Reference Manual IOCTL Function6-3

JIOCTL_COMMAND_CONVERT Command

Some of the jBC database drivers will perform an automatic conversion of the input and output record whenperforming reads and writes.

An example of this is when writing to a UNIX directory. In this case, the attribute marks will be converted to

new-line characters and a trailing new-line character added. Similarly for reading from a UNIX directory thenew-line characters will be replaced with attribute marks, and the trailing new-line character will be deleted.

The above example is what happens for the database driver for UNIX directories. It assumes by default that therecord being read or written is a text file and that the conversion is necessary. It tries to apply some intelligenceto reading UNIX files, as text files always have a trailing new-line character. Therefore, if a UNIX file is readwithout a trailing new-line character, the database driver assumes the file must be a binary file rather than a textfile, and no conversion takes place.

This conversion of data works in most cases and usually requires no special intervention from the programmer.

There are cases however, when this conversion needs to be controlled and interrogated, and the IOCTL functioncall with the JIOCTL_COMMAND_CONVERT command provides the jBASE database drivers that supportthis conversion with commands to control it.

The call to IOCTL, if successful, will only affect file operations that use the same file descriptor. Consider the

following code:

INCLUDE JBC.hOPEN “MD” TO FILEVAR1 ELSE ...OPEN “MD” TO FILEVAR2 ELSE ...IF IOCTL(FILEVAR1,JIOCTL_COMMAND_CONVERT,”RB”) ..

In the above example, any future file operations using variable FILEVAR1 will be controlled by the changeforced in the IOCTL request. Any file operations using variable FILEVAR2 will not be affected and will use thedefault file operation.

Input to the IOCTL is a string of controls delimited by a comma that tell the database driver what to do. Theoutput from the IOCTL can optionally be a string to show the last conversion that the driver performed on the

file.

The description of the available controls that can be passed as input to this IOCTL function are:

Control code Description

"RB" All future reads to be in binary (no conversion)

"RT" All future reads to be in text format (always do a conversion)

"RI" All future reads to decide themselves whether binary or text

"RS" Return to caller the status of the last read ('B' = binary, 'T' = textconversion)

"WB" All future writes to be in binary (no conversion)

"WT" All future writes to be in text format (always do a conversion)

"WI" All future writes to decide themselves whether binary or text

"WS" Return to caller the status of the last write ('B' = binary, 'T' = textconversion)

"KB" All future reads/writes have the record key unaltered (no recordkey conversion)

"KT" All future reads/writes have the record key modified (always do aconversion)

"KI" All future reads/writes to decide if to do a conversion

"KS" Return to caller the status of the last record key conversion ('B' =binary, 'T' = text conversion)

Page 80: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 80/200

 

IOCTL Function Advanced Programmers ReferenceManual

6-4

Example 1

The application wants to open a file, and to ensure that all reads and writes to that file are in binary, and that notranslation such as new-lines to attribute marks are performed.

INCLUDE JBC.hOPEN “FILE” TO DSCB ELSE STOP 201,”FILE”IF IOCTL(DSCB,JIOCTL_COMMAND_CONVERT,”RB,WB”) ELSE

CRT “UNABLE TO IOCTL FILE ‘FILE’” ; EXIT(2)END

Example 2

Read a record from a file, and find out if the last record read was in text format (were new-lines converted toattribute marks and the trailing new-line deleted), or in binary format (with no conversion at all)

INCLUDE JBC.hOPEN “.” 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” THENPRINT “prog.o read in TEXT format”

END ELSEPRINT “prog.o read in BINARY format”

ENDEND ELSE

CRT “The IOCTL failed !!”END

Page 81: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 81/200

Advanced Programmers Reference Manual IOCTL Function6-5

JIOCTL_COMMAND_FILESTATUS Command

The JIOCTL_COMMAND_FILESTATUS command will return an attribute delimited list of the status of thefile to the caller.

Attribute Description

<1> File type, as a string.

<2> FileFlags, as decimal number, showing the LOG, BACKUP andTRANSACTION permissions.

<3> BucketQty, as decimal number, number of buckets in the file.

<4> BucketSize, as decimal number, size of each bucket in bytes.

<5> SecSize, as decimal number, size of secondary data space.

<6> Restore Spec, a string showing any restore re-size specification.

<7> Locking identifiers, separated by multi-values.

<8> FileFlags showing LOG, BACKUP and TRANSACTIONpermissions.

<8,1> Set to non-zero to suppress logging on this file.

<8,2> Set to non-zero to suppress transaction boundaries on this file.

<8,3> Set to no-zero to suppress backup of the file using jbackup.

<9> Hashing algorithm used.

Example 1

Open a file and see if the file type is a UNIX directory.

INCLUDE JBC.hOPEN “..” TO DSCB ELSE STOP 201,”..”status = “”IF IOCTL(DSCB,JIOCTL_COMMAND_FILESTATUS,status) ELSE

CRT “IOCTL failed !!” ; EXIT(2)ENDIF 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 2Open a file ready to perform file operations in a transaction against it. Make sure the file has not been removedas a transaction type file by a previous invocation of the command ‘jchmod -T CUSTOMERS’.

INCLUDE JBC.hOPEN “CUSTOMERS” TO DSCB ELSE STOP 201,”CUSTOMERS”IF IOCTL(DSCB,JIOCTL_COMMAND_FILESTATUS,status) ELSE

CRT “IOCTL failed !!” ; EXIT(2)ENDIF status<8,2> THEN

CRT “Error ! File CUSTOMERS is not”CRT “part of transaction boundaries !!”CRT “Use ‘jchmod +T CUSTOMERS’ !!”EXIT(2)

END

Page 82: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 82/200

 

IOCTL Function Advanced Programmers ReferenceManual

6-6

JIOCTL_COMMAND_FINDRECORD Command

This command will find out if a record exists on a file without the need to actually read in the record. This canprovide large performance gains in certain circumstances.

Example

Before writing out a control record, make sure it doesn’t already exist. As the control record is quite large, it willprovide performance gains to simply test if the output record already exists, rather than reading it in using theREAD statement to see if it exists.

INCLUDE JBC.hOPEN “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 CASECASE rc EQ 0

CRT “No further action, record already exists”

CASE rc GT 0WRITE output ON DSCB,keyPRINT “Data written to key “ : key

CASE 1CRT “IOCTL not supported for file type”

END CASE

Page 83: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 83/200

Advanced Programmers Reference Manual IOCTL Function6-7

JIOCTL_COMMAND_HASH_RECORD Command

For jBASE hashed files such as j1 and j2, each record is pseudo-randomly written to one of the buckets (orgroups) of the hashed file. The actual bucket it is written to depends upon two factors:

1.  The actual record key (or item-id)

2.  The number of buckets in the file (or modulo)

This IOCTL command shows which bucket number the record would be found in, given the input record key.The bucket number is in the range 0 to (b-1) where b is the number of buckets in the file specified when the filewas created (probably using CREATE-FILE).

The command only returns the expected  bucket number, as is no indication that the record actually exists in thefile.

Two attributes are returned by this command. The first is the hash value that the record key has hashed to, andthe second attribute is the bucket number.

Example

Open a file, and find out what bucket number the record “PIPE&SLIPPER” would be found in.INCLUDE JBC.hOPEN “WEDDING-PRESENTS” TO DSCB ELSE STOPkey = “PIPE&SLIPPER”parm = keyIF 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

Page 84: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 84/200

 

IOCTL Function Advanced Programmers ReferenceManual

6-8

JIOCTL_COMMAND_HASH_LOCK Command

The jEDI locking mechanism for records in jEDI provided database drivers is not strictly a 100% record lockingmechanism. Instead, it uses the hashed value of the record key to give a value from 0 to 2 30-1  to describe therecord key. The IOCTL command can be used to determine how a record key would be converted into a hashedvalue for use by the locking mechanism.

Example

Lock a record in a file and find out what the lock id of the record key is. The example then calls the jRLAlocking demon and the display of locks taken should include the lock taken by this program

INCLUDE JBC.hDEFC getpid()OPEN “WEDDING-PRESENTS” TO DSCB ELSE STOPkey = “PIPE&SLIPPER”parm = keyIF IOCTL(DSCB,JIOCTL_COMMAND_HASH_LOCK,parm) ELSE

CRT “IOCTL failed, command not supported”

EXIT(2)ENDPRINT “The lock ID for the key is “:parmPRINT “Our process id is “ : getpid()READU rec FROM DSCB,key ELSE NULLPRINT “Locks taken so far : “EXECUTE “jRLA -dv”

Page 85: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 85/200

 

Chapter 7: jEDI Database Drivers

Page 86: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 86/200

Page 87: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 87/200

Advanced Programmers Reference Manual jEDI Database Drivers7-1

Introduction

This chapter describes how a third party software provider can write a new database driver, and interface it toexisting jBASE applications. This is provided through the jEDI API (jBASE External Database Interface). Itallows an application that performs its database requests through jEDI (all jBASE applications use jEDI for their

database access) to access databases not directly supported by jEDI itself.

Note that non-jBASE applications can used jEDI as their database management system, as described in thefollowing chapter ‘jEDI API Calls’.

A number of standard database drivers built into the jEDI library code are supplied with jBASE, including the j1and j2 file systems. It is possible to write alternate filing systems conforming to the jEDI API so that all existingapplications can use the new database seamlessly, through the new database drivers.

The directory $JBCRELEASEDIR/src contains examples of some of the functionality described in thisdocument. The directory $JBCRELEASEDIR/include contains two source files to be included in user-writtencode, jsystem.h and jedi.h.

The source file jsystem.h provides all the necessary definitions for writing external C functions and interfacingthem with jBC source files. The source file jedi.h provides all the necessary definitions to allow users to write

new database drivers.

The following code segment shows an example of a jBASE program accessing two files, and simply copying therecords from one file to another:

InputFileName = “InputFile”OutputFileName = “OutputFile”OPEN InputFileName TO InputDSCB ELSE

STOP 201,InputFileNameENDOPEN OutputFileName TO OutputDSCB ELSE

STOP 201,OutputFileNameENDCLEARFILE OutputFileNameSELECT InputDSCB

LOOP WHILE READNEXT RecordKey DOCRT RecordKeyREAD Record FROM InputDSCB,RecordKey ELSE

STOP 202,RecordKeyENDWRITE Record ON OutputDSCB,RecordKey

REPEAT

This shows typical uses of the database access statements available in jBC, such as OPEN, READ, WRITE,CLEARFILE, SELECT and READNEXT. All of these statements cause, at program execution, a call to the

 jEDI API. The jEDI API will route the database request to the appropriate database driver for the file type. Forexample, the input file could be a j1 file while the output file could be a UNIX directory.

It is important to note that the application itself is unaware of the database type it is connected to. In some

extreme circumstances it may specifically need to know, and can use the IOCTL () function to do so, but this useis rare.

The jEDI API has a number of database drivers built in. These include drivers for the various hashed databases,for treating UNIX directories like database files, and so on. For a basic jBASE installation, these drivers aresufficient for all your normal application needs - no knowledge of jEDI, or of setting up jEDI is required.

It is possible to write your own database drivers than can be loosely bound to jEDI, so that the OPEN, READ,

WRITE etc. calls from an application can be routed to your own code rather than to a supplied database driver.

Page 88: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 88/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-2

Shared Object Database Drivers

A shared object database driver is the mechanism by which a program using the jEDI API to access a file (suchas a jBC program) can use a database driver, contained in a standard shared object, to provide the necessarydatabase I/O functionality. The application that is calling the jEDI interfaces will remain unaware of whereexactly the data is coming from, or from what sort of database the data is contained in.

There are six steps to creating a shared object database driver. An example of a shared object database driver issupplied with jBASE in the source file $JBCRELEASEDIR/src/jediDExample.c. It may also be useful toexamine the supplied source $JBCRELEASEDIR/src/jediCExample.c, which shows an example of a C programusing calls to jEDI to perform database operations.

The following short example is a useful introduction to building a shared object database driver. It isrecommended the reader attempts this example first of all.

Step 1 The first step involves creating an external database driver source. This of course is the hardeststep and will be expanded upon in much more detail later on. For now though, we will use the supplied example

source code. Use the following steps at shell:

% cd ;# Change to home directory% mkdir sosrc ;# Create a source directory% cd sosrc ;# Change to the new source directory% cp $JBCRELEASEDIR/src/jediDExample.c ./mydd.c

;# Copy source to file ‘mydd.c’

If you look at the new source mydd.c, you will see that there is only one exported symbol, namely ExampleInit().You can change this to be any name you like. For this short tutorial, we will assume the name is left atExampleInit, as the name has significance later on.

Step 2 Compile the database driver and create a shared object out of it. The following steps at shellprovide an example of this:

% cd $HOME/sosrc ;# Make sure in correct directory% cc -c -I$JBCRELEASEDIR/include mydd.c

;# Compile source to an object% jBuildSLib mydd.o -o $HOME/lib/mydd.so

;# Create shared object out of mydd.o

Note that during the building of the shared object stage, the jBuildSLib command will create a shared object at$HOME/lib/mydd.so that contains a single object. You can include other objects on the command line so thatmydd.so contains many objects. For example, you could execute:

% jBuildSLib mylib.a mydd.o newdd.o -o libfb.so

In the above example, the objects mydd.o and newdd.o, plus all the objects in the archive file mylib.a, will bebuilt into a single shared object.

Step 3 Create a file definition. There needs to be a UNIX file that tells jBASE “This is really a referenceto a file contained in a shared object database driver”. You can create one using any UNIX mechanism, normally

via an editor such as vi. However, the command at shell shown below is equally valid:

% echo “JBC__SOB ExampleInit .d” > $HOME/myfile

The above example creates a UNIX file at $HOME/myfile. The first 8 characters are always the same, and are“JBC__SOB” (note there are two _ characters). The next part, ExampleInit, gives the name of the

initialisation function in the database driver, as noted in Step 1. The remainder of the definition can be anythingat all - it is up to the database driver to interpret it how it likes. In the supplied database driver, we take the nameof the UNIX file opened and append the remainder of the definition to arrive at the name of the file required.This mechanism will become clearer later on.

Step 4 Create the database itself. The example given simply uses flat UNIX files in a normal UNIXdirectory as a crude sort of database. Given the naming convention in Step 3, we can create the database itselfwith the shell command:

% mkdir $HOME/myfile.d

Page 89: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 89/200

Advanced Programmers Reference Manual jEDI Database Drivers7-3

Step 5 Create some data records. We will create 3 data records of zero length with the following simpleUNIX shell commands:

% touch $HOME/myfile.d/reca% touch $HOME/myfile.d/recb% touch $HOME/myfile.d/recc

Step 6 Either create your own jBC program to access the database in $HOME/myfile.d, or use an existingapplication. For example,

% LIST myfilePAGE 1 11:46:55 30 AUG 1994

myfile........

recarecbrecc

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 theJBCOBJECTLIST variable is not set.

At this stage is it worthwhile understanding the chain of event that occur when accessing the newly createdshared object database driver in the above example. The mechanism inside the jBASE run-time library is asfollows:

•  The OPEN “myfile” statement in the jBC source generates a function call to the JLibFOPEN function, assupplied 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 beopened.

•  The jEDI OPEN function will now ask all the established database drivers if the file is one that belongs totheir 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 functiontaken from shared objects called “ExampleInit”. The mechanism happens to be the same mechanism that isused for the CALL statement. This will succeed, and the ExampleInit() function will establish itself as adatabase driver in its own right.

•  The shared object database driver will now pass control to the OPEN function defined when the databasedriver was established in the call to ExampleInit. Control of the OPEN now passes outside of jEDI and intothe user-written OPEN code.

•  The user-written OPEN code now has freedom to do anything it likes. In the example code, it will simplyconcatenate the strings “$HOME/myfile” and “.d” to create a name “$HOME/myfile.d” and expect this to bean existing UNIX directory.

•  Assuming the user-written OPEN returned a successful code, the OPEN statement now completes. Anyfuture database operations such as READ, WRITE and so on will now be passed to the functions defined bythe 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 conformingto the jEDI API. They would normally be in one source code. Only a single function is required to be visible, theremainder can be defined as ‘static’.

Page 90: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 90/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-4

The functions can have any name, and the names described in this document are purely examples. The onlyconsideration is that the visible initialisation function name is referenced in the file definition. For example, ifyou changed the function name ExampleInit to MyInit, the file definition described in Step 3 above would haveto reference MyInit instead of ExampleInit.

The handle for a jEDI opened file is of type JediFileDescriptor and is defined in the supplied source file$JBCRELEASEDIR/include/jedi.h. Once the file is opened, this handle is passed to the jEDI API and so to thedatabase driver for all future database operations on the file.

The jEDI interface does not provide opportunities to create the file nor to delete the file. It is assumed that thedatabase to which you are interfacing will have its own facilities to do this.

The functions required to build a database driver conforming to the jEDI API are:

1.  Database driver initialisation. This is the only visible function in the database driver source code. Theremainder will probably be declared as static functions (not visible outside the source code). It iscalled when the first file is opened in the program, and is responsible for establishing itself as adatabase driver.

2.  Open file. Performs all necessary functionality to open a file.

3.  Close file. Called when a file is closed.

4.  Select record keys in a file. The application wants to select some or all of the records in the file.

5.  Terminate the selection process. The selection process is terminated.

6.  Read the next record from a selection. Following the selection call, the application will repeatedly callthis to read the next record key selected.

7.  Read a record from the file. Read a single record from the database.

8.  Write a record to the file. Write a single record to the database.

9.  Delete a record from the file. Delete a single record from the file.

10. Clear all records from the file. Delete all records from the file.

11. Provide locking support. Provide the record locking mechanism to support record locks defined in theapplication.

12. Provide database specific IOCTL functionality. General functionality mostly unique to the databasedriver itself, in the same manner as the ioctl() function is fairly device dependent in the C library code.

13. Synchronise the database (flush any cached data). This function is called when the application wantsto ‘checkpoint’ the database and needs to force any data in the cache buffers to disk.

Page 91: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 91/200

Advanced Programmers Reference Manual jEDI Database Drivers7-5

File Ajar Processing

There is a limit to the number of files that a process can have open at any one time. Depending upon theoperating system and its configuration, this is often in the region of 50 to 200. Unfortunately, this clashes withmany applications that require hundreds of files open simultaneously.

The mechanism to work around this is called file ajar processing. This involves temporarily closing the file to theoperating system, but the application still believes the file is opened. Then, when a database operation isrequested on a file that is temporary closed (or ajar), a different file is closed and made ajar, and the requestedfile is re-opened. This mechanism works on a least used file algorithm so that the most frequently used files do

not suffer the performance penalty.

This ability to temporarily close and reopen files depends upon the database driver itself, and a database drivercan choose to implement it or not.

The jEDI API provides this functionality itself, but uses two extra functions supplied by the database driver toaccommodate this. During the OPEN function call, detailed later, there are two members to the file descriptorcalled ProcessAjar and ProcessReopen. By default these members are initialised to NULL and the databasedriver will not support ajar file processing. If you want to support file ajar processing, these two members need

to be set to the address of two support functions within the database driver to handle the following functionality.

File Descriptor Member ProcessAjar

Set the member ProcessAjar in the file descriptor (see the OPEN function description later) to the address of adatabase driver support function that will be called by the jEDI API each time a file is required to be temporarilyclosed. The description of this function supplied by the database driver is:

Synopsis:

static void MakeFileAjar( FileDescriptor )JediFileDescriptor * FileDescriptor ;

Parameters:

FileDescriptor. (Input and Output parameter). This is the file descriptor that was returned when the filewas originally opened.

Return Value:

None.

Operation:

The address of this function is made available to jEDI during the OPEN function described later. For

example, in the OPEN function you might do:

FileDescriptor->ProcessAjar = MakeFileAjar ;

Hence, the actual name of the function is not important as jEDI will do the call through a functionpointer.

This function should perform all necessary functionality to temporarily close the file and return. It isassumed the function always succeeds. If it fails, no error is reported and jEDI will try to make anotherfile ajar.

The jEDI code will, by default, assume a UNIX file at FileDescriptor->PathName with a UNIX file

descriptor at FileDescriptor->FileFd is part of the file operation, and will close these automatically.

Remember that this type of functionality should only be supported by the database driver if closing thefiles doesn’t cause any harm, such as losing any UNIX file locks that were set.

File Descriptor Member ProcessReopen

Set the member ProcessReopen in the file descriptor (see the OPEN function description later) to the address of

a database driver support function that will be called by the jEDI API each time a file is that has previously beentemporarily closed needs to be re-opened. The description of this function is:

Page 92: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 92/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-6

Synopsis:

static int ReopenAjarFile( FileDescriptor )JediFileDescriptor * FileDescriptor ;

Parameters:

FileDescriptor. (Input and Output parameter). This is the file descriptor that was returned when the filewas originally opened.

Return Value:

The return value is 0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.

Operation:

The address of this function is made available to jEDI during the OPEN function described later. Forexample, in the OPEN function you might do:

FileDescriptor->ProcessReopen = ReopenAjarFile ;

Hence, the actual name of the function is not important as jEDI will do the call through a functionpointer.

This function should re-open the file previously made ajar.

The jEDI code will, by default, assume a UNIX file at FileDescriptor->PathName with a UNIX file

descriptor at FileDescriptor->FileFd is part of the file operation, and will re-open these automatically.

Page 93: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 93/200

Page 94: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 94/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-8

hash is a 32 bit integer that describes the record key to lock or unlock. It is ignored if the command value isJEDI_UNLOCK_ALL. This means it doesn’t support full record locking, but a simpler scheme with only anextremely remote chance that hash values will clash for different record keys. The hash value can be anything thedatabase driver likes. The database drive can use the JediBaseHash function (see later) to convert a record keyinto a 32 bit hash value.

The function can return the following values:

0 indicates that the operation was successful.

JEDI_ERRNO_LOCK_TAKEN indicates that the command was JEDI_LOCK_NOWAIT and therequested lock was already taken by another process.

Any other value indicates a fatal error. The values are usual UNIX error numbers,described in header file errno.h.

 jEDI Base Code

There is some functionality provided by jEDI for all database drivers which is provided within jEDI without theneed for the database drivers to provide it themselves:

•  Database journaling.  Updates to the database, such as record updates, file clears and so on will be journaled automatically by jEDI assuming the facility is operational. The database driver need not performany specific operation. There are options in the code for the OPEN to prevent a particular file from being

 journaled if required.

•  Transaction boundaries. Within jEDI the notion of single level transaction boundaries are supported. Thisis done by the base code of jEDI. The database driver need not perform any specific operation. There areoptions in the code for the OPEN to prevent a particular file from being part of a transaction if required.

•  File ajar processing. The routine closing and re-opening of files on a temporary measure is done by the jEDI API, and was described fully in the earlier section ‘File Ajar Processing’.

Page 95: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 95/200

Advanced Programmers Reference Manual jEDI Database Drivers7-9

INIT - Initialisation of Database Driver

The first function to write is the main initialisation function that will be called just once, the first time thedatabase driver is referenced. It should set up a structure that defines the database driver, and then call a jEDIfunction to register the database driver. The name of this function, as explained earlier, can be anything but the

name you decide is the name you must specify in the UNIX file that is the file descriptor. For example, if youname this function INIT, typically the UNIX file that describes the shared object database driver would be:

% COUNT ./THISFILE

169 RECORDS COUNTED% cat ./THISFILEJBC__OBJ INIT XYZ-INFO^TBAGS

Synopsis:

int INIT()

Parameters:

None.

Return Value:

The return value is the database driver number this has been registered as (using function callJediBaseAddDriver()).

If an error occurs, return a negative value and set errno set to show the reason for the failure.

Operation:

The code for this function will look pretty much the same for each database driver. While the user can ofcourse add any extra initialisations they like, the bulk of the code will look like this:

int OPEN(), CLOSE(), SELECT(), SELECTEND() ;int READNEXT(), READ(), WRITE();int DELETE(), LOCK(), IOCTL () ;

int CLEAR(), SYNC() ;struct JediDriverStruct p1 ;int DriverNumber ;/** Initialise the members of the 'p1' structure* with our device driver function addresses.*/memset(&p1,0,sizeof(p1));p1.FileTypeDescr = "OurDatabase" ;p1.OpenCodePtr = OPEN ;p1.JediClose = CLOSE ;p1.JediSelect = SELECT ;p1.JediSelectEnd = SELECTEND ;p1.JediReadnext = READNEXT ;

p1.JediReadRecord = READ ;p1.JediWriteRecord = WRITE ;p1.JediDeleteRecord = DELETE ;p1.JediLock = LOCK ;p1.JediIOCTL = IOCTL ;p1.JediClearFile = CLEAR ;p1.JediSync = SYNC ;/** Add this to the list of supported* database drivers and return.*/return JediBaseAddDriver(&p1);

Basically, all this function does is to set up a structure with details of all its functions to support all the

required database I/O requests, and then call JediBaseAddDriver() to register it as a database driver.

Page 96: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 96/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-10

Once this initialisation code has completed successfully, any database I/O requests for this databasedriver will be re-directed to the functions declared in the above code.

Page 97: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 97/200

Advanced Programmers Reference Manual jEDI Database Drivers7-11

OPEN - Open a File

This function is called whenever the application performs an OPEN request for this particular database driver.

Synopsis:

static int OPEN(FileDescriptor, HeaderInfo,HeaderInfoLen )

JediFileDescriptor * FileDescriptor;char * HeaderInfo ;int HeaderInfoLen ;

Parameters:

FileDescriptor. (Input and Output parameter). This is the address of a file descriptor that has beenpartially filled in by the calling jEDI code. The members of the structure filled in before the call toOPEN, and the expected members to be filled in if the OPEN succeeds, are detailed later.

HeaderInfo. (Input parameter). This is a pointer to the first ‘n’ bytes of the UNIX file that was opened.For example, in the case of shared object database drivers, this would typically point to:

JBC__SOB INIT AnyOtherCode

Second line of description.

HeaderInfoLen. (Input parameter). This describes the amount of data pointed to by HeaderInfo.

Return Value:

0 shows the file was opened successfully.

ENOENT shows the file could not be opened but there is no reason why other database drivers should notattempt to open the file.

Any other positive value if a fatal error occurred and no more database drivers should be given theopportunity to open the file.

Operation:

The OPEN function will now use the information passed in the above three parameters to try to open therelevant file in the foreign database it is accessing. If the OPEN succeeds, the database driver will fill inother parts of FileDescriptor and return a value of 0.

How you make the correspondence between the information in FileDescriptor and the foreign databasefile name is entirely up to the driver. For example, the UNIX file may look like this:

JBC__SOB INIT -rcoffice -ausers CUSTOMERS

and the database driver may interpret this to mean to open the file CUSTOMERS in remote machinecoffice in account users. The example program provided with jBASE, as described earlier, simplyconcatenates the actual UNIX file name opened with the operands that follow the database function nameINIT.

Any security and access permissions are entirely the responsibility of the database driver. Just because theuser has had access to the file definition doesn’t necessarily mean the user is entitled to access the file. Itwould be too easy for a user simply to edit their own definition of the file and then try to open it.

Notes:

As mentioned earlier, the information for the user is mostly passed in parameter ‘FileDescriptor’.

The following is a list of members of FileDescriptor that are initialised by the jEDI code before callingINIT:

•  ProcessId. The process id of the calling process.

•  CurrentDir. The current working directory of the process.

•  PathName. The path name of the file description originally opened.

•  OptionalArgs. The list of text that followed the ‘JBC__SOB FuncName’ text in the file descriptionoriginally opened.

Page 98: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 98/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-12

•  StatInfo. The details returned by function stat() describing the file description originally opened.

•  Status. Set to one or more of the JEDI_STATUS_READ and JEDI_STATUS_WRITE bits to show

if the original file description was opened in read only mode, or read and write mode.

The following is a list of members of FileDescriptor that INIT should fill in, assuming the open is

successful:

•  ConvertFlags. Some database drivers will perform conversions on the data read in. For example,

when reading records from a UNIX directory, the new-line characters will be replaced with attributemarks (i.e. 0x0a characters replaced with 0xfe). If the database driver supports conversion of data, itshould initialise this entry with one or more of the JEDI_CONVERT_xxx bits defined in jedi.h.These bits can subsequently be modified by the application by a call to IOCTL.

•  FilesUsed. Enter here the approximate number of system files that will remain open for the file. Thisallows the ajar processing to try to estimate when files need closing. The value here need not beaccurate, it will just be a minor performance hit if wrong.

•  Status. Set additional bits to this field. Note that some may already be initialised by jEDI, so thefollowing bits should be OR’ed:

∗  JEDI_STATUS_FIELDREAD Set if the READ function can perform field read operations.

∗  JEDI_STATUS_FIELDWRITE Set if the WRITE function can perform field write operations.

∗  JEDI_STATUS_CANBEAJAR Set if this file supports ajar processing.

∗  JEDI_STATUS_USING_RLA Set if the file driver is using the jBASE supplied

JediSystemLock locking mechanism. See earlier description of the JediSystemLock() functioncall.

∗  JEDI_STATUS_WRAPUP_LOCKS_ONLY When a process terminates, then if this bit is setthe jBC run-time code will not call the CLOSE function for this file, but will merely ensurethat the locks for this file are released.

∗  JEDI_STATUS_READ User is allowed to READ from the file.

∗  JEDI_STATUS_WRITE User is allowed to WRITE to the file.

•  TypePtr. This is a ‘void *’ pointer and allows the database driver to optionally insert any addresshere of their choosing. This is typically used to store a control block for the file unique to thedatabase driver.

•  FileFlags. Controls operation of the file, and can be one or more of the following bits

∗  JEDI_FILE_NOLOG If set, then updates to the file will not be sent to the jEDI database journaler.

∗  JEDI_FILE_NOTRANS If set, then updates to the file will not become part of any transaction.

•  FileType. Any unique integer here, for the use of the database driver only, so long as it doesn’t clashwith any internally defined values (they have a value less than 256).

•  LockId1. If using the JediSyslockLock() function, then this is the first of two integer required touniquely identify the file. This is usually set to the expression ‘FileDescriptor->StatInfo.st_dev &0xffff’.

•  LockId2. If using the JediSystemLock() function, then this is the second of two integer required touniquely identify the file. This is usually set to the expression ‘FileDescriptor->StatInfo.st_ino’.

•  ProcessAjar. If the database driver supports ajar processing, then this is the address of the function tocall to change the status of a file from ‘open’ to ‘ajar’. This mechanism was described in the earliersection ‘File Ajar Processing’.

•  ProcessReopen. If the database driver supports ajar processing, this is the address of the function to

call to change the status of a file from ‘ajar to ‘open’. This mechanism was described in the earliersection ‘File Ajar Processing’.

Page 99: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 99/200

Advanced Programmers Reference Manual jEDI Database Drivers7-13

CLOSE - Close an Opened File

This function is called when a file descriptor is closed.

Synopsis:

static int CLOSE(FileDescriptor, Flags)JediFileDescriptor * FileDescriptor;int Flags ;

Parameters:

FileDescriptor. (Input and Output parameter). This is the file descriptor that was returned when the filewas originally opened.

Flags. (Input parameter). This parameter is not used at present.

Return Value:

The return value is 0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.

Operation:

The close operation should typically release all resources that was allocated uniquely by the database

driver itself. This includes closing down file descriptors, flushing any cache data, releasing workspaceuniquely allocated to the file descriptor that was allocated by the database driver etc.

The file descriptor may be associated with SELECT structures allocated against the file descriptor.Therefore, any SELECT structures that were allocated against the file descriptor (see “SELECT” later)

must be terminated. Note there can be more than one SELECT associated with a single file descriptor.You should traverse the linked list to clean up these multiple selects. An example is given in the sourcefile jediDExample.c.

Once the close functionality has cleaned up its own allocated resources, it must call functionJediFreeFileDescriptor as shown below:

JediFreeFileDescriptor(FileDescriptor);

This will release all the resources allocated by jEDI for the file descriptor, including the structure pointedto by FileDescriptor. Therefore, this call is the last operation you should perform.

Notes:

The database driver should remove all locks associated with this file with a call to the LOCK functionbefore actually closing a file.

Page 100: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 100/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-14

SELECT - Select Record Keys from a File

This function is called when the user wants to perform some sort of selection of the file. At present, the selectfunction is called from a jBC program to select all records in the file. However, calls from C programs and future

 jBC programs may add selection criteria.

Synopsis:

static int SELECT(FileDescriptor, SelectPtr,SelectDetails, Index )

JediFileDescriptor * FileDescriptor;struct JediSelectPtr ** SelectPtr;char * SelectDetails;int Index ;

Parameters:

FileDescriptor. (Input and Output parameter). This is the file descriptor that was returned when the file

was originally opened.

SelectPtr. (Input and Output parameter). The caller passes here the address of a “struct JediSelectPtr *”variable. If the SELECT works, then this function will return here the address of an allocatedJediSelectPtr structure. This address will be passed to future calls to SELECTEND and READNEXT.

SelectDetails. (Input parameter). This is a NULL terminated string describing the selection details. Forexample, to select all record keys that match the regular expression “^MJI.*PIPE” the caller will set thisvariable to point to the string “^MJI.*PIPE”. Note that none of the supplied database drivers as of release

3.0 support this feature. Future database driver may do so. Currently the language for jBC does notsupport this either, but again may do so in the future.

Index. (Input parameter). For database drivers that support multiple indexed file, this shows the indexnumber to perform the select against. As of release 3.0, the jBC language does not directly support

multiple indexed databases. However, this may change in future releases.

Return Value:The return value is 0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.

Operation:

The SELECT function will allocate a structure of its own design that describes this selection call. Theapplication will then make repeated calls to the READNEXT function to retrieve the record keys asdesignated by this SELECT process call. It is up to the designer of the database driver to decide if tomake a list of all the record keys during this function call, or just to establish selection criteria and let theREADNEXT do the actual selection.

A segment of the code to achieve the SELECT would look like this:

struct JediSelectPtr *BlockPtr, **LoopPtr;/** Allocate space for the standard* JediSelectPtr structure.*/

if ((BlockPtr=JediMalloc(FileDescriptor,sizeof(struct JediSelectPtr))) == NULL)

{return errno ;

}/** Now to allocate a structure for our own

* use. The structure name is* called Select, and it can be anything our* own database driver wants

Page 101: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 101/200

Advanced Programmers Reference Manual jEDI Database Drivers7-15

* it to be. The ‘TypePtr’ member of the* previously allocated structure will* contain a pointer to it.*/if ((BlockPtr->TypePtr=JediMalloc(

FileDescriptor,sizeof(struct Select)

)) == NULL){

return errno ;}/** The new structure ‘BlockPtr’ now needs to* be added to the end of* a linked list of selection structures* allocated against* this file descriptor.*/LoopPtr = &FileDescriptor->SelectPtr;while(*LoopPtr != NULL){

LoopPtr = (struct JediSelectPtr **)(*LoopPtr);}*LoopPtr = BlockPtr ;/** Set up our ‘NextPtr’ to be NULL to show we* are at end of linked list.*/BlockPtr->NextPtr = NULL;/** Return the address of the select* structure allocated to the caller.*/*SelectPtr = BlockPtr ;return 0;

In the above code, the first memory allocation (using JediMalloc()) is the standard structure that needs tobe allocated. This structure is the one passed to the SelectEnd and Readnext functions (described below).

The second memory allocation is optional and is a structure entirely of the making of the database driver.This allows the database driver to have its own data associated with a selection.

Note that there can be multiple selections associated with a single file descriptor. For example, a jBCsource program could contain the following:

OPEN “FileName” TO FileVar ELSE STOP 201,”FileName”SELECT FileVar TO SelectList1.....SELECT FileVar TO SelectList2

In the above example there will have been two calls to the SELECT function, both calls passing the samefile descriptor. Therefore, on the linked list pointed to by FileDescriptor->SelectPtr  there will

be two select structures. Your SELECT, SELECTEND and CLOSE functions must be able to handlethese instances.

Page 102: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 102/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-16

SELECTEND - Terminate a Selection Process

This function is called when the selection process is terminated. For example, in a jBC program this could be inone of the two manners:

OPEN “FileName” TO FileVar ELSE ...SELECT FileVar TO SelectVarLOOP WHILE READNEXT RecordKey FROM SelectVar DO ......REPEAT

or  

OPEN “FileName” TO FileVar ELSE ...SELECT FileVar TO SelectVar......SelectVar = 0

In the first example the selection process is exhausted. In the second example, the selection process is terminatedprematurely,

Synopsis:static int SELECTEND(FileDescriptor, SelectPtr )JediFileDescriptor * FileDescriptor;struct JediSelectPtr * SelectPtr;

Parameters:

FileDescriptor. (Input and Output parameter). This is the file descriptor that was returned when the filewas originally opened.

SelectPtr. (Input and Output parameter). This is the address of the structure that was created during theSELECT function.

Return Value:

The return value is 0 if the operation succeeded.Any other value shows the reason the operation failed using the values defined in errno.h.

Operation:

The select has ended. This function should clear up all space allocated by the SELECT function call, andremove the SelectPtr structure from the linked list of select structure pointed to in the FileDescriptorstructure.

In the example code with the call to function SELECT(), there were two structures allocated, and the firstwas positioned at the end of the linked list. Carrying on from that example, the following code wouldclean up the resources allocated during the call to SELECT().

struct JediSelectPtr *Next, ** LoopPtr ;/** Free the structure allocated specifically* for the use of this database driver.* This can be used for whatever purposes* the database driver likes.* It is at this stage the database driver* would clean up all the members* pointed to by SelectPtr->TypePtr.*/

JediFree(FileDescriptor,SelectPtr->TypePtr);/** Extract the pointer to the next structure* in the linked list.*/

Next = SelectPtr->NextPtr ;

/** Now to free the other structure allocated in

Page 103: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 103/200

Advanced Programmers Reference Manual jEDI Database Drivers7-17

* the call to SELECT()*/JediFree(FileDescriptor,SelectPtr);/** The structure passed to us is part of a* linked list of workspaces that* begin at address FileDescriptor->SelectPtr.

* The address of our workspace is given* by the variable 'SelectPtr' and the forward* pointer for our linked workspace is* given by the variable 'Next'.** We now have to go through the list and remove* our workspace from the linked list.*/LoopPtr = &FileDescriptor->SelectPtr;for(;;){

if (*LoopPtr == NULL) break;if (*LoopPtr == SelectPtr){

*LoopPtr = Next ;break;

}LoopPtr = (struct JediSelectPtr **)(*LoopPtr);

}/** Finished, so return a good completion code.*/return 0 ;

Page 104: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 104/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-18

READNEXT - Get Next Record Key from Selection

This function is typically called many times following a call to the SELECT function. This function will returnthe next record that has been selected following a call to the SELECT function.

Synopsis:

static int READNEXT(FileDescriptor, SelectPtr,RecordKeyPtr, RecordKeyLenPtr)

JediFileDescriptor * FileDescriptor;struct JediSelectPtr * SelectPtr;char ** RecordKeyPtr ;int * RecordKeyLenPtr ;

Parameters:

FileDescriptor. (Input parameter). This is the file descriptor that was returned when the file was originallyopened.

SelectPtr. (Input parameter). This is the address of the structure that was created during the SELECT

function.RecordKeyPtr. (Input and Output parameter). The application passes in the parameter a pointer to apointer to a buffer. This is where the next selected record key will be returned. If the buffer is not largeenough (See RecordKeyLenPtr), then the READNEXT function should allocate sufficient memory andreturn at RecordKeyPtr the address of the allocated memory. It is up to the calling application to detect ifthis has been performed, and to free any allocated memory.

RecordKeyLenPtr. (Input and Output parameter). This is the address of an integer that describes thelength of the buffer given by the expression “*RecordKeyPtr”. When we have selected the next recordkey and placed it in the buffer “*RecordKeyPtr”, we return here the length of the record key. If there areno more record keys, then -1 is returned here.

Return Value:

0 if the operation succeeded. This includes when the list of record keys are exhausted (in this case,*RecordKeyLenPtr set to -1).

Any other value shows the reason the operation failed using the values defined in errno.h.

Operation:

This function simply reads the next record key from the select list and returns details of the record key. Atthe end of processing all keys, we return -1 in the RecordKeyLenPtr variable.

This process is best illustrated by example. The example below will simply return 3 record keys called

RecordKey1, RecordKey2 and RecordKey3. It is assumed that the previous call to SELECT will haveresulted in the members maxkey being set to 3 and currkey set to 0.

struct Sel {

int maxkey ;int currkey ;} ;

struct Sel *OurPtr ;char recordkey[128];int recordkeylen ;/** Extract the structure for SELECTs that is unique* to our database driver.*/

OurPtr = ((struct Sel *)SelectPtr->TypePtr);/** We simply return up to 3 record keys, namely

* "RecordKey1", "RecordKey2" and "RecordKey3".* Check to make sure that we have not already* returned 3 keys.

Page 105: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 105/200

Advanced Programmers Reference Manual jEDI Database Drivers7-19

*/if (++OurPtr->currkey > OurPtr->maxkey) {

/** No more valid record keys, so return -1* in the length field.*/

*RecordKeyLenPtr = -1;

return 0 ;}/** Create our actual record key in an* automatic variable*/recordkeylen = sprintf(recordkey,

"RecordKey%d",OurPtr->currkey);/** Make sure the length of the record key* buffer is big enough.*/if (recordkeylen > *RecordKeyLenPtr){

if ((*RecordKeyPtr = JediMalloc(FileDescriptor,recordkeylen)) == NULL)

{return errno;

}}/** Return the actual record key and length* of record key.*/memcpy(*RecordKeyPtr,recordkey,recordkeylen);*RecordKeyLenPtr = recordkeylen ;return 0 ;

Page 106: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 106/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-20

READ - Read a Record from a File

This function is called when the application wants to read a record from the opened file.

Synopsis:

static int READ(FileDescriptor, Flags,RecordKey,RecordKeyLen, BufferPtr,BufferLenPtr, FieldNumber)

JediFileDescriptor * FileDescriptor;int Flags ;char * RecordKey ;int RecordKeyLen ;char ** BufferPtr ;int * BufferLenPtr ;int FieldNumber ;

Parameters:

FileDescriptor. (Input parameter). This is the file descriptor that was returned when the file was originally

opened.

Flags. (Input parameter). One or more of the following bits.

•  JEDI_RECORD_FIELDREADWRITE. If set, then the value at parameter ‘FieldNumber’ containsthe field number (or attribute) to read, instead of the entire record. If the database drive doesn’t

support the reading of individual fields, then it should have not set theJEDI_STATUS_FIELDREAD bit during the OPEN function (see the OPEN function for details ofthe ‘Status’ member of JediFileDescriptor) and this can be ignored.

RecordKey. (Input parameter). Pointer to a character array describing the record key to read in. The array

does not need to be 0 terminated.

RecordKeyLen. (Input parameter). The length of the RecordKey parameter.

BufferPtr. (Input and Output parameter). This is the address of a character array where we will place therecord data. The length of this is given by the BufferLenPtr parameter. Should this buffer not be largeenough to accommodate the record, we will allocate more space using JediReadMalloc() and return herethe address of the data space allocated. Thus the calling function can determine where the record wasplaced, and thus whether it was placed in the character array supplied to READ, or the character arrayallocated by READ. It is up to the calling function to free any allocated space using JediFree() if

necessary.

BufferLenPtr. (Input and Output parameter). This is the address of an integer, originally set up to describethe size of the character array pointed to by ‘* BufferPtr’. Upon return from READ, this will indicate the

size of the record that was read in.

FieldNumber. (Input parameter). If the caller wishes to read an individual field instead of the entirerecord, then they will set the JEDI_RECORD_FIELDREADWRITE bit in the Flags parameter and set

this parameter to be the field number to read in. If the database driver does not support this operation, youcan ignore this field (see earlier description of JEDI_RECORD_FIELDREADWRITE).

Return Value:

0 is returned if the record is read in successfully.

ENOENT is returned if the record does not exist.

Any other value shows the reason the operation failed using the values defined in errno.h.

Note: Although the database driver is only responsible for the above return values, the jEDI code mayreturn other codes to the calling application outside the control of the database driver. These codes areEDEADLK (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 alreadytaken by another process).

Page 107: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 107/200

Advanced Programmers Reference Manual jEDI Database Drivers7-21

Operation:

The READ function should, by default, read in an entire record. If the bit defined by (Flags &JEDI_RECORD_FIELDREADWRITE) is set, then the database driver should just return a single fieldfrom the record, as given by parameter FieldNumber. Note that if database driver doesn’t want to supportreading of individual fields, then it should not set the JEDI_STATUS_FIELDREAD bit in the Status fieldof the file descriptor during the OPEN function call, leaving it up to the application to extract the

individual field from the entire record.

It will return the data at the address *BufferPtr and return the length of the record at *BufferLenPtr.

The database accessed by the database driver will probably have an entirely different record structure tothat expected by the application. Therefore it is up to the database driver to convert the record from theforeign database into a format understandable by the calling application. For example, if the database haddefined the record layout as:

INT UserId 4 byte integer field.STRING Name(20) 20 character name field.FLOAT Balance 8 byte monetary value field.

Then it would be up to the database driver to convert it to a format acceptable to the calling application.

Using the above example, the following code would perform the conversion:char record[32];char output[128];int outputlen ;

/** 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 beneeded 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 seewhat 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 fielddelimited 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 ;

Page 108: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 108/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-22

linecount < 4 ; linecount++){

memcpy(&temprecord[temprecordlen],RecordKey,RecordKeyLen);

if (linecount == 3){

temprecordlen += RecordKeyLen ;}else{

temprecord[temprecordlen+RecordKeyLen]= 0376 ;

temprecordlen += (RecordKeyLen +1) ;}

}/** Make sure the caller has provided enough space* for the data to be copied to. If not, then* allocate more space.*/

if (temprecordlen > (*BufferLenPtr)) {if (((*BufferPtr) = JediReadMalloc(

FileDescriptor,temprecordlen)) == NULL){

return errno;}

}/** Copy the data to the users buffer and return to* the caller the length of the record returned.*/

memcpy(*BufferPtr,temprecord,temprecordlen);*BufferLenPtr = temprecordlen ;return 0 ;

Note that when the buffer was allocated, instead of using JediMalloc() we actually usedJediReadMalloc(). This is a special case for performance reasons and the database driver should use acall to JediReadMalloc() only when it is creating a buffer for data to be read into. There are no otheroccasions when you use JediReadMalloc(). The application can make use of this by trapping calls toJediReadMalloc(), as it knows that during these calls the database driver is creating a data space to returnthe record. Thus, the application can make sure the data is read into the final resting place for the data,rather than into some temporary buffer allocated created by JediMalloc(), that then needs copying

elsewhere.

There is no locking flags passed to the READ function. The is because the application request to read arecord with a lock goes through some base code in jEDI, and before the request reaches the database

driver, jEDI will make a call to the LOCK function (detailed later) to do any record locking. Hence, there

is no requirement for the READ functionality in the database driver to explicitly worry about locks.The database driver may support the conversion of data, for example when reading in UNIX files it mayconvert new-line characters to attribute marks (from 0x0a to 0xfe). If this is supported by the database

driver, the ConvertFlags member in the FileDescriptor structure passed to this function will show whatsort of conversion, if any, to perform. This ConvertFlags member is a number of bits defined byJEDI_CONVERT_xxx in the header file jedi.h, and is initialised during the OPEN call. Subsequent callsby the application to IOCTL can modify this field. It is up to the database driver to decide if to supportthis functionality or not.

Page 109: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 109/200

Advanced Programmers Reference Manual jEDI Database Drivers7-23

WRITE - Write a Record to a File

This function is called when the application wants to write a record to the file.

Synopsis:

static int WRITE(FileDescriptor, Flags,RecordKey, RecordKeyLen,BufferPtr, BufferLen,FieldNumber)

JediFileDescriptor * FileDescriptor;int Flags ;char * RecordKey ;int RecordKeyLen ;char * BufferPtr ;int BufferLen ;int FieldNumber ;

Parameters:

FileDescriptor. (Input parameter). This is the file descriptor that was returned when the file was originally

opened.Flags. (Input parameter). One or more of the following bits.

•  JEDI_RECORD_FIELDREADWRITE. If set, then the value at parameter ‘FieldNumber’ containsthe field number (or attribute) to write, instead of the entire record. If the database drive doesn’tsupport the writing of individual fields, then it should have not set theJEDI_STATUS_FIELDWRITE bit during the OPEN function (see the OPEN function for details ofthe ‘Status’ member of JediFileDescriptor) and this can be ignored.

RecordKey. (Input parameter). This points to a array of characters that define the record key for which towrite the record as. The array is not a 0 terminated string.

RecordKeyLen. (Input parameter). Shows the length of the record key as pointed to by the parameterRecordKey.

BufferPtr. (Input parameter). This points to the actual data to write out, and is of length BufferLen bytes.

BufferLen. (Input parameter). This shows the amount of data to be written, as pointed to by the BufferPtrparameter.

FieldNumber. (Input parameter). If the caller wishes to write an individual field instead of the entirerecord, then they will set the JEDI_RECORD_FIELDREADWRITE bit in the Flags parameter and setthis parameter to be the field number to write out. If the database driver does not support this operation,you can ignore this field (see earlier description of JEDI_RECORD_FIELDREADWRITE).

Return Value:

The return value is 0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.Operation:

The WRITE function should, by default, write out an entire record. If the bit defined by (Flags &

JEDI_RECORD_FIELDREADWRITE) is set, then the database driver should just write a single field, asgiven by parameter FieldNumber. Note that if database driver doesn’t want to support writing ofindividual fields, then it should not set the JEDI_STATUS_FIELDWRITE bit in the Status field of thefile descriptor during the OPEN function call, leaving it up to the application to insert the individual fieldand write the entire record.

There is no locking flags passed to the WRITE function. The is because the application request to write arecord and maintain or release a lock goes through some base code in jEDI, and before the requestreaches the database driver, jEDI will make a call to the LOCK function (detailed later) to do any record

locking releases. Hence, there is no requirement for the WRITE functionality in the database driver toexplicitly worry about locks.

Page 110: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 110/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-24

The foreign database accessed by the database driver will probably have an entirely different recordstructure to that expected by the application. Therefore it is up to the database driver to convert the recordfrom the format by the application to the format of the foreign database. This is the reverse process asdetailed in the READ record function described previously. The format of the record that is pointed to bythe BufferPtr parameter is that whereby all the fields in the record are string fields delimited by a 0xfe (or

octal 0376) characters. Like the READ record function, the database driver has to convert the fields asnecessary.

This conversion process can specifically be bypassed by the calling application if required. This may beneeded from time to time for certain applications to write out the data in binary format without anyconversions. The write 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 write record process that simply writes the record out to a UNIX flatfile. No account of writing single fields is allowed for and no account of any conversions is used.

char ActualPathName[PATH_MAX+1];int i1, fd1 ;/** Make up the name of a UNIX file to write to.* This is basically the concatenation of the file* name that was opened plus the record key.*/

i1 = strlen(FileDescriptor->PathName);memcpy(ActualPathName,FileDescriptor->PathName,i1);ActualPathName[i1] = '/';memcpy(&ActualPathName[i1+1],RecordKey,

RecordKeyLen);ActualPathName[i1+1+RecordKeyLen] = NULL;/** Now to try to open the file.*/

if ((fd1=open(ActualPathName,O_WRONLY|O_TRUNC|O_CREAT,0666)) < 0)

{return errno;

}/** Now to write the data to the actual file.*/

if (write(fd1,BufferPtr,BufferLen) != BufferLen){

close(fd1);return (errno == 0 ? EIO : errno);

}/** Write succeeded. Close the file and return 0.*/

close(fd1);return 0 ;

The database driver may support the conversion of data so that for example, it will convert new-linecharacters to attribute marks when reading in UNIX files. If this is supported by the database driver, theConvertFlags member in the FileDescriptor structure passed to this function will show the type ofconversion, if any, to perform. This ConvertFlags member is a number of bits defined byJEDI_CONVERT_xxx in the header file jedi.h, and is initialised during the OPEN call. Subsequent calls

by the application to IOCTL can modify this field. It is up to the database driver to decide if to supportthis functionality or not.

Page 111: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 111/200

Advanced Programmers Reference Manual jEDI Database Drivers7-25

DELETE - Delete a Record from a File

This function is called when the application wants to delete a record from the file.

Synopsis:

static int DELETE(FileDescriptor, Flags,RecordKey, RecordKeyLen )

JediFileDescriptor * FileDescriptor;int Flags ;char * RecordKey ;int RecordKeyLen ;

Parameters:

FileDescriptor. (Input parameter). This is the file descriptor that was returned when the file was originallyopened.

Flags. (Input parameter). This parameter not used at present.

RecordKey. (Input parameter). Points to a string describing the record key to delete. Note the record keyis not a 0 terminated string.

RecordKeyLen. (Input parameter). This is the length of the record key as passed by RecordKey.

Return Value:

0 is returned if the record is deleted successfully.

ENOENT is returned if the record did not exist.

Any other value shows the reason the operation failed using the values defined in errno.h.

Operation:

The DELETE function simply removes the record from the database. The following is a very simpleexample of deleting a record, where we have assumed the database is simply a UNIX flat file.

char ActualPathName[PATH_MAX+1];int i1, fd1 ;/** Make up the name of a UNIX file to delete.*/i1 = strlen(FileDescriptor->PathName);memcpy(ActualPathName,FileDescriptor->PathName,i1);ActualPathName[i1] = '/';memcpy(&ActualPathName[i1+1],RecordKey,

RecordKeyLen);ActualPathName[i1+1+RecordKeyLen] = NULL;/** Now to delete the actual record.*/

if (unlink(ActualPathName) != 0){return (errno == 0 ? ENOENT : errno);

}return 0 ;

There is no locking flags passed to the DELETE function. The is because the application request to deletea record goes through some base code in jEDI, and before the request reaches the database driver, jEDIwill make a call to the LOCK function (detailed later) to release any record locking. Hence, there is norequirement for the DELETE functionality in the database driver to explicitly worry about locks.

Page 112: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 112/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-26

CLEAR - Delete All Records from a File

This function is called by an application to delete all the records from a file. No file locks are taken, so otherapplications could be writing to the file at the same time.

Synopsis:

static int CLEAR(FileDescriptor)JediFileDescriptor *FileDescriptor;

Parameters:

FileDescriptor. (Input parameter). This is the file descriptor that was returned when the file was originallyopened.

Return Value:

The return value is 0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.

Operation:The database driver simply clears all records from the file in the most efficient manner it can. It is up tothe database driver to decide if to return an error code if some of the records cannot be deleted. For

example, in the driver supplied with jBASE to use UNIX files as a database, if some of the recordscannot be deleted (i.e. the UNIX file cannot be unlinked), for example because of file permissions, thenno error is reported. However, the database driver is free to choose whether to ignore such failures or not.

The following crude example shows how a database drive that uses the UNIX files as a database mightdelete all records (i.e. UNIX files).

DIR *DirPtr;struct dirent *Next;char PathName[PATH_MAX*2];struct stat stat_info ;

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;

Page 113: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 113/200

Page 114: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 114/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-28

LOCK - Provide Record Locking Mechanism

This function is called by the application to provide record locking support. It can also be called intrinsically viathe jEDI code to support record locking functions. For example, if an application performs a request to READ arecord with a lock, then the jEDI function will call the LOCK function directly, rather than the READ functiondoing the call itself.

Synopsis:

static int LOCK(FileDescriptor, Flags,RecordKey, RecordKeyLen )

JediFileDescriptor * FileDescriptor;int Flags ;char * RecordKey ;int RecordKeyLen ;

Parameters:

FileDescriptor. (Input parameter). This is the file descriptor that was returned when the file was originallyopened.

Flags. (Input parameter). Can be one of the following bits to show what operation is to be performed bythe LOCK function:

JEDI_RECORD_LOCKRECORD Take a record lock and wait.

JEDI_RECORD_LOCKRECORD_NOWAIT Take a record lock, but return if lock already taken(The function return code is JEDI_ERRNO_LOCK_TAKEN).

JEDI_RECORD_UNLOCKRECORD Remove a record lock.

RecordKey. (Input parameter). This is a pointer to a character array which shows what record key is to belocked or unlocked. Note that this array is not a 0 terminated string (See RecordKeyLen parameter).

A special case exists for when NULL is passed in this field. This means the calling application wants to

release all the locks for all the records in the file held by this application.RecordKeyLen. (Input parameter). This is the length of data passed in the RecordKey parameter.

Return Value:

0 shows the locks were created/removed successfully.

JEDI_ERRNO_LOCK_TAKEN the JEDI_RECORD_LOCKRECORD_NOWAIT bit was set, and the record/field

was already locked by another process.

EDEADLK shows one of the lock bits was set, and a deadly embrace situation was detected and avoided.

Any other value shows the reason the operation failed using the values defined in errno.h.

Operation:

The function should check if RecordKey is NULL. If it is, then release all locks held by this applicationfor this file. If the RecordKey is not NULL, then the function should either take or release an individualrecord key lock.

A locking function is supplied with jBASE called JediSystemLock that can be used to provide a recordlocking scheme. It is not a 100% genuine record locking scheme, but a scheme whereby a pseudo-randominteger value is created from the record key and the pseudo-random value is the value that is locked.While not a 100% record locking scheme, the chances of a clash whereby different record keys generate

the same pseudo-random value are very small.

The following shows how the LOCK function could be written using the supplied JediSystemLock()function. However, the database driver is free to use alternate locking mechanisms if required. In this casethe LOCK function will probably become an interface to the record locking scheme provided by the

foreign database.unsigned int HashValue ;

Page 115: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 115/200

Advanced Programmers Reference Manual jEDI Database Drivers7-29

unsigned char c1, c2 ;/** First of all, create a HASH value for* the RecordKey.*/if (RecordKey != NULL){

HashValue = JediBaseHash(RecordKey,RecordKeyLen, 1);

/** Mask off the top bit to make it a signed* positive value. Due to bug in a previous* compiler, we mask the top two bits.*/HashValue &= 0x3fffffff;

}/** Secondly, see if we are to remove locks.*/if (Flags & JEDI_RECORD_UNLOCKRECORD){

if (RecordKey == NULL){

/** Release ALL locks on the file.*/return JediSystemLock(FileDescriptor,

JEDI_UNLOCK_ALL, 0) ;}/** Release a single lock on the file.*/return JediSystemLock(FileDescriptor,

JEDI_UNLOCK, HashValue ) ;}

/** Thirdly, we must be setting a lock. Do we have* to wait or not ?*/return JediSystemLock(FileDescriptor,

(Flags & JEDI_RECORD_LOCKRECORD_NOWAIT ?JEDI_LOCK_NOWAIT : JEDI_LOCK ),HashValue ) ;

Page 116: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 116/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-30

IOCTL - Support Database Driver Control Functions

This function is called to provide general database driver operations. Like the ioctl() function in C programs,there are some standard commands that most database drivers will be expected to perform, some that areoptional, and some that are unique to the database driver.

Synopsis:

static int IOCTL (FileDescriptor, SubCommand,IoctlAddr, IoctlLen,IoctlReturnAddr, IoctlReturnLen)

JediFileDescriptor * FileDescriptor;int SubCommand ;void * IoctlAddr ;int IoctlLen ;void * IoctlReturnAddr ;int * IoctlReturnLen;

Parameters:

FileDescriptor. (Input parameter). This is the file descriptor that was returned when the file was originallyopened.

SubCommand. (Input parameter). This shows actually what sort of operation to perform. There are somecommon commands given by the JEDI_IOCTL_xxx definition, but the database driver can add support

for other commands if required.

IoctlAddr. (Input parameter). This gives the address of any optional buffer that may be necessary toprovide extra specification depending on the SubCommand. Therefore it’s use is highly dependent uponSubCommand. The application may pass NULL here.

IoctlLen. (Input parameter). This is the size of data that is pointed to by the IoctlAddr parameter.

IoctlReturnAddr. (Input and Output parameter). This is the address of a buffer or length IoctlReturnLenbytes where the IOCTLfunction can return any data depending upon the command to be executed (SeeSubCommand).

IoctlReturnLen. (Input and Output parameter). This is the address of an integer that shows the length ofthe return buffer pointed to by IoctlReturnAddr. Upon exit, the database driver should update this to showthe amount of valid data that the IOCTL function has returned in IoctlReturnAddr.

Return Value:

The return value is highly dependent on the database driver. By convention though you should return -1 ifthe operation failed, 0 if the operation was successful. In the example code given, if you decide to includethe standard IOCTL functions, then return the same return code as given in the example code.

Operation:

The use of IOCTL is highly database driver dependent. However, there are some common functions that a

database driver may be expected to perform. The code example below shows all these common functions.All the functionality is optional, and all the jBC utilities that make IOCTL calls have suitable defaultsshould the database driver decide not to support the command.

int ReturnValue;int i1, ReturnBufferLen ;char ReturnBuffer[4096];char FullName[4096];char *Ptr1, *Ptr2 ;struct stat RecStat ;char ActualPathName[PATH_MAX+1];int SaveErrno ;int fd1 ;

ReturnValue = 0;switch(SubCommand)

Page 117: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 117/200

Advanced Programmers Reference Manual jEDI Database Drivers7-31

{case JEDI_IOCTL_CONVERT:

/** The application wants to change the status* of the conversion flags, which are usually* examined to see if to read a record in* binary format without conversion, or to do

* the conversion between fields on the foreign* database and the format expected by the* application.* The input string will be something like* “RB,WB”, which means all the reads should* be binary and the writes should be binary.*/if (IoctlReturnAddr != NULL &&

IoctlAddr != NULL){

FileDescriptor->ConvertFlags =JediBaseIoctlConvert(

FileDescriptor->ConvertFlags,IoctlAddr, IoctlLen,

IoctlReturnAddr, IoctlReturnLen) ;}break;

case JEDI_IOCTL_FILESTATUS:/*** The application wants details of the file.** Return details as an attribute delimited* record as follows :* <1> File Type as a string* <2> FileFlags, as decimal number,* showing the LOG, BACKUP and* TRANSACTION permissions.* <3> BucketQty, as decimal number,

* number of buckets in the file.* Not applicable in this example.* <4> BucketSize, as decimal number, size* of each bucket in bytes.* Not applicable.* <5> SecSize, as decimal number, size of* secondary data space.* Not applicable in this example.* <6> Restore Spec, a string showing any* restore re-size specification.* Not applicable in this example.* <7> Locking identifiers, delimited by* multi-values.* <8> FileFlags showing LOG, BACKUP and

* TRANSACTION permissions. Multi-values* are :* <8,1> set to 1 if no logging.* <8,2> set to 1 if no transaction.* <8,3> set to 1 if no file backup.*/ReturnBufferLen =

sprintf(ReturnBuffer,"Example\3760\376\376\376\376\376%d\375%d\3760\3750\3750",FileDescriptor-LockId1,FileDescriptor->LockId2);

if (IoctlReturnAddr != NULL){

i1 = min(ReturnBufferLen,*IoctlReturnLen);memcpy(IoctlReturnAddr,ReturnBuffer,i1);*IoctlReturnLen = i1 ;

Page 118: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 118/200

 

 jEDI Database Drivers Advanced Programmers ReferenceManual

7-32

}else{

ReturnValue = EINVAL;}break;

case JEDI_IOCTL_HASH_LOCK:/*

* Find the HASH value used in any locking* scheme.*/

if (IoctlReturnAddr != NULL &&IoctlAddr != NULL)

{i1 = JediBaseHash(IoctlAddr, IoctlLen,1);/** Mask off the top bit to make it a* signed positive value.* Due to bug in a previous compiler,* we mask the top two bits.

*/i1 &= 0x3fffffff;*IoctlReturnLen =

sprintf(IoctlReturnAddr,"%d",i1);}break;

case JEDI_IOCTL_FINDRECORD:/** Test whether record exists.* Work out a full path name to use.*/i1 = strlen(FileDescriptor->PathName);memcpy(ActualPathName,

FileDescriptor->PathName,i1);

ActualPathName[i1] = '/';memcpy(&ActualPathName[i1+1],I

IoctlAddr,IoctlLen);ActualPathName[i1+1+Ioctl] = NULL;if ((fd1=open(ActualPathName,O_RDONLY)) < 0){

ReturnValue = errno;}close(fd1);if ( IoctlReturnAddr != NULL ){

i1 = min(IoctlLen,*IoctlReturnLen);memcpy(IoctlReturnAddr,IoctlAddr,i1);*IoctlReturnLen = i1 ;

}break;

default:ReturnValue = -1;break;

}return ReturnValue ;

Page 119: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 119/200

Advanced Programmers Reference Manual jEDI Database Drivers7-33

SYNC - Synchronise the Data to Disk

This function is called to flush any cache data to the disk. This is quite specialised and if necessary the databasedriver can choose to do nothing except give a return code of 0.

Synopsis:

static int SYNC(FileDescriptor)JediFileDescriptor *FileDescriptor;

Parameters:

FileDescriptor. (Input parameter). This is the file descriptor that was returned when the file was originallyopened.

Return Value:

The return value is 0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.

Operation:

The following code example shows the use of the UNIX fsync() function to provide this functionality.Note that not all derivatives of UNIX support fsync().

errno = 0;if (fsync(FileDescriptor->FileFd) == 0) return(0);return errno;

Page 120: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 120/200

Page 121: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 121/200

Page 122: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 122/200

Page 123: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 123/200

Advanced Programmers Reference Manual jEDI API Calls8-1

Introduction

The previous chapter concentrated on creating new database drivers, enabling existing jBC or C programs toaccess alternative databases. The most common uses of jEDI will be through statements such as READ, WRITE,OPEN etc.. within a jBC application.

 jEDI is designed to be a completely autonomous component of jBASE, and while it is used extensively by a jBCprogram, it is very capable of being used by a C program that has no jBC code anywhere in sight.

The purpose of this section is to describe how to write a C program that calls the jEDI API. Many of the toolsprovided with jBASE use jEDI in this manner.

An example source of a C program calling jEDI directly is provided with jBASE in the file$JBCRELEASEDIR/src/jediCExample.c. This program performs a simple file copy from one jEDI supportedfile to another jEDI supported files, and shows the use of many of the functionality described later.

Provided with jBASE are a number of #include files you will need in your program. These files are jsystem.h

and jedi.h and are found in directory $JBCRELEASEDIR/include. All the non-standard definitions described inthe section, such as JEDI_TRANSLOG_COMMAND_QUERY are defined in one of these two files, so youshould #include both of them. Note that jsystem.h also does a ‘#include <stdio.h>‘.

The stages of calling jEDI directly from a C program can be summarised as:

•  Initialisation.

•  Making jEDI database requests. 

•  Program termination. 

The operations of transaction boundaries and transaction journaling are done automatically by jEDI and nointervention on the part of the C program is required - with the exception of abnormal program termination,which is discussed later.

Page 124: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 124/200

 

 jEDI API Calls Advanced Programmers ReferenceManual

8-2

Initialisation

There are two operations to perform before making the first database operation, both of them are optional.

Set up signal handlers.  You should ideally set up signal handlers such that in the event of an unexpected

program termination, you can still perform the wrap-up operations detailed in ‘Program Termination’ later.Basically, at program termination you will abort any transaction and close all opened files (thus releasing all the

locks). Most database drivers, including the ones supplied with jBASE, can cope with abnormal exits that do notwrap-up properly. Thus, while setting up signal handlers and wrapping up cleanly is the preferred option, it is notmandatory.

Connect to the database. This involves calling the function ‘JediConnect’ to return a jEDI connection handle.This connection handle is then passed to all subsequent OPEN requests. If this stage is omitted, you can always

use the default connect handle of 0. However, the connection function provides defines for the storage allocationfunctions to call (malloc, strdup, etc.) and as we shall see later, this may provide performance improvements inyour code. A typical call to JediConnect might be:

static void * readalloc() ;int ConnectHandle ;

struct JediConnectBlock ConnectBlock ;/** Set up the database name to connect to.* This is reserved at present, so use “” string.*/ConnectBlock.dbname = "" ;/** Set up the addresses of all the memory* allocation functions we shall require.* Note the ‘readmallocptr’ member, which is to* our own allocation function called ‘readalloc’* As we see later, this will provide performance* improvements.*/

ConnectBlock.mallocptr = (void *(*)())malloc ;ConnectBlock.readmallocptr=(void *(*)())readalloc;ConnectBlock.reallocptr = (void *(*)())realloc ;ConnectBlock.freeptr = free ;ConnectBlock.strdupptr = (char *(*)())strdup ;/** Connect to jedi and check return code.*/if ((ConnectHandle=JediConnect(&ConnectBlock))<0){

perror("JediConnect");exit(1);

}/*

* We use the variable ConnectHandle in all* subsequent calls to jedi.*/

Page 125: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 125/200

Advanced Programmers Reference Manual jEDI API Calls8-3

Making jEDI Database Requests

Once any initialisation has been performed, you can start calling jEDI API functions. The first call is usually toJediOpen, followed by a number of requests using the returned file descriptor.

One of the limitations during this phase is that the C program must keep the environment variable PWD up to

date. The variable PWD is initialised to the current directory by jEDI when the first ever JediOpen function callis made. However, should the program change the directory using calls to ‘chdir’, they must also update thePWD directory.

Here is a summary of the function calls, a full description is given later,:

JediOpen  Open a file.

JediOpenDeferred Open a file in deferred mode. The file is only partially opened, and will be genuinelyopened on the first database access using the returned file descriptor.

JediClose Close a file.

JediSelect Initiate a selection of a list of record keys.

JediSelectEnd Terminate the selection of the list of record keys.

JediReadnext Read the next record key following a selection.

JediReadRecord Read a record (or a field from a record) from the file.

JediWriteRecord Write a record (or a field within a record) to a file.

JediDelete Delete an entire record.

JediLock Perform record locking.

JediIOCTL General purpose file control.

JediSync Flush updates to the journaler and to disk.

JediClearFile Clear all records from the file.

JediPerror  Similar to the C library function perror, except it has allowances for the extensions to

the range of errno values that can be returned.

JediFileOp  Provides general mechanism to create, delete and clear files that are supported as aresident jEDI database type.

JediReinitialise  Allows a certain amount of re-initialisation of jEDI under certain circumstances.

Page 126: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 126/200

 

 jEDI API Calls Advanced Programmers ReferenceManual

8-4

Program Termination

There are basically two things to do when a program terminates, whether it terminates normally or because of asignal. You should first abort any outstanding transactions (assuming you have used transaction support), andsecondly close any opened files.

Aborting outstanding transactions. If you are using transaction boundaries in your program, you should check

to see if you have an open transaction, and handle appropriately to your application. The following code shows acheck to see if a transaction was open. If it was, the transaction is aborted and an error message is printed.

if (JediTransLog(JEDI_TRANSLOG_COMMAND_QUERY)){

JediTransLog(JEDI_TRANSLOG_COMMAND_ABORT, 0,“Abort from program xxx” );

fprintf(stderr,”Forced transaction abort\n”);}

Close opened files. You should ideally keep a list of all currently opened files so that you can close them at alater stage. The closing of files will also release all the locks on the file.

Page 127: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 127/200

Advanced Programmers Reference Manual jEDI API Calls8-5

Compiling and Linking a Program

Once you have written your C application, you need to compile it and link it. There are two considerations here.First, where to find the #include files jsystem.h and jedi.h and second, where to find the jedi library.

Finding the #include Files.If you use the cc command to build your application, you need to specify on the command line where the includefiles are, for example:

% cc -c myprog.c -I $JBCRELEASEDIR/include

If you use the jbc command to build your application, the command is simplified:

% jbc -c myprog.c

Linking with the jEDI Library.

If you use the cc command to build your application, you need to specify where the the jEDI API functionslibrary can be found. There are a number of ways to achieve this. The following examples may vary slightly withdifferent UNIX development environments. The first example shows linking with shared objects using the cccommand:

% cc myprog.o -o myprog -L $JBCRELEASEDIR/lib -l jedi

The next example shows linking with archive libraries:

% cc myprog.o -o myprog -s $JBCRELEASEDIR/lib/libjedi.a

Note the use of the -s option to strip the symbol table, debugging and line number information from theexecutable. These are not needed and will significantly reduce the size of the executable program.

The command is simplified if you use the jbc command to build your application,. There are basically two waysof building your application. The first is the normal method, using jEDI shared libraries. The second uses jEDIarchive libraries. For example, to link the object to create an executable program using the jbc command andshared libraries:

% jbc myprog.o -o myprog

To link with archive libraries, the command would become:

% jbc myprog.o -o myprog -JLa

When linked with jEDI shared libraries, you must ensure the environment variable LD_LIBRARY_PATH showswhere it can find these shared libraries (use LIBPATH for AIX systems). For example, you could do this in your.profile:

export LD_LIBRARY_PATH=$JBCRELEASEDIR/lib

Page 128: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 128/200

 

 jEDI API Calls Advanced Programmers ReferenceManual

8-6

Transaction Boundary Support

This can be provided within a C program using the calls to the supplied function JediTransLog. There arebasically four calls - start, end (commit), abort (rollback) and query.

Transactions cannot be nested, so if you start a transaction when a transaction is already active, an error code isreturned.

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 thetransaction though an abort or commit, the updates will be flushed to disk and if the transaction journaling isoperative, the update information flushed to the output media. This gives greater database integrity in theevent of a failure at the cost of an additional overhead. If no synchronisation is required, pass 0 in thisparameter.

“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 toexamine the updates later though the transaction journaling mechanism.

The return value is 0 if successful, and any other value if there is an error.

Ending (Committing) a Transaction

if (JediTransLog(JEDI_TRANSLOG_COMMAND_END, Flags,“message”) != 0)

{perror(“TRANSEND”);

}

Where:

JEDI_TRANSLOG_COMMAND_END Tells the function to end or commit a transaction.

Flags Not used with this function call.

“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 toexamine the updates later though the transaction journaling mechanism.

The return value is 0 if successful, and any other value if there is an error.

Aborting (Rollback) a Transaction:

if (JediTransLog(JEDI_TRANSLOG_COMMAND_ABORT, Flags,“message”) != 0)

{perror(“TRANSABORT”);

}

Where:

JEDI_TRANSLOG_COMMAND_ABORT  Tells the function to abort (or rollback) a transaction.

Flags Not used with this function call.

Page 129: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 129/200

Advanced Programmers Reference Manual jEDI API Calls8-7

“message” Can be any 0 terminated string of characters, and is used simply by the transaction journalerto record information about the transaction. This string should be meaningful - you might want to examinethe updates later though the transaction journaling mechanism.

The return value is 0 if successful, and any other value if there is an error.

Query the Status of a Transaction:if (JediTransLog(JEDI_TRANSLOG_COMMAND_QUERY)){

printf(“A transaction is active\n”);}else{

printf(“No transaction open\n”);}

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.

Page 130: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 130/200

 

 jEDI API Calls Advanced Programmers ReferenceManual

8-8

 jEDI Environment Variables

When using a program with jEDI, you should be aware of some of the environment variables used by the jEDIlibrary:

PWD. This will be initialised by jEDI following the first call to JediOpen. Once set up by jEDI, the programmust keep this up to date should the program call chdir() at any point to change the current working directory.

HOME. This defines the home directory of the logged on user. It is used by jEDI when resolving Q pointerswhich point to an alternative user name.

LD_LIBRARY_PATH. Used by most UNIX systems to define the path to look for shared objects. If you writea C program that was linked with jEDI shared objects, before the program can be executed you must setLD_LIBRARY_PATH to include, as one of its components, the name of the directory where it can find the jEDIshared object.

LIBPATH. Same as LD_LIBRARY_PATH, but for AIX systems.

JEDIFILENAME_MD. This defines whether you have a Master Dictionary file in operation. If so, during a callto JediOpen the function will look in this file to see if the file is defined here. If a record exists in the file definedby JEDIFILENAME_MD, and the first field is Q, this is a Q pointer and is resolved as such.

JEDIFILENAME_SYSTEM. If this variable is set, it is used by jEDI to find out more about pseudo jBASEaccount names during Q pointer resolution.

JEDIFILEPATH. When a file is opened, it is usually by a relative name such as “CUSTOMERS” or “PIPES”.This variable can contain a number of directory names, delimited by a colon, to describe the search path to lookfor the file. For example, if the environment variable JEDIFILEPATH contained “/home/greg:/home/fat”, jEDIwould first try to open file “/home/greg/CUSTOMERS” followed by “/home/fat/CUSTOMERS”. If this variableis not defined, jEDI defaults to the home directory followed by the current directory.

JBCOBJECTLIST. This is used when attempting to load user-written database drivers. It gives a list ofdirectories where the shared objects may exist.

See also the description of the JediReinitialise() function later on in this chapter. JediReinitialise may need to becalled if you change these environment variables within your program.

Page 131: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 131/200

Advanced Programmers Reference Manual jEDI API Calls8-9

JediOpen - Open a File

This function is called whenever the application needs to open a file.

Synopsis:

int JediOpen(ConnectHandle, FilePointer,PathName, FilePath );

int ConnectHandle ;JediFileDescriptor ** FilePointer ;char * PathName ;char * FilePath ;

Parameters:

ConnectHandle. This is the value passed back by the call to JediConnect, that was documented earlier inthis chapter. If the call to JediConnect was omitted, simply pass 0 in this parameter.

FilePointer. The address of a file descriptor pointer. If the open is successful, we return here the filedescriptor. This file descriptor is passed on all subsequent jEDI API calls to define the opened file.

PathName. This is the name of the file to open, and can be in a number of formats. Examples are:

“CUSTOMERS”. The file name to open is CUSTOMERS, and the open function will make use ofthe ‘FilePath’ parameter to establish the directory that CUSTOMERS is contained in.

“./CUSTOMERS”. The file name to open is CUSTOMERS, but the use of the preceding ./ means weignore the ‘FilePath’ parameter and just look in the current directory.

“../CUSTOMERS]D”. Open the dictionary section of file CUSTOMERS, which will have a UNIXfile name of CUSTOMERS]D. The use of the preceding ../ means we ignore the ‘FilePath’ parameterand just look in the parent directory.

“DICT PROSPECTS”. Open the dictionary section of file PROSPECTS. The open function willmake use of the ‘FilePath’ parameter to establish the directory that CUSTOMERS is contained in.

“/home2/accts/ORDERS,1995”. Open the section 1995 of the file ORDERS, which is in directory

 /home2/accts. The ‘FilePath’ parameter will not be used.

FilePath. If a simple file name is given to be opened, without a leading “/” or “./” or “../”,we use thisparameter to establish what directories to look in. Each directory name in this parameter is delimited by acolon. You would normally pass NULL here, and JediOpen will use the environment variableJEDIFILEPATH instead. Note that if FilePath is NULL, and JEDIFILEPATH is undefined, we search for

the file in the users home directory followed by the current working directory.

Return Value:

0 shows the file was opened successfully.

ENOENT shows the file could not be opened.

Any other value shows the reason the operation failed using the values defined in errno.h.

Page 132: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 132/200

Page 133: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 133/200

Advanced Programmers Reference Manual jEDI API Calls8-11

JediClose - Close an Opened File

This function is called to close an opened file. Any locks that exist will be released.

If the file is currently part of a transaction, the jEDI code will defer the close until the end of the transaction - noeffort is required on the part of the application and it should assume the file is really closed.

Synopsis:

int JediClose(FileDescriptor, Flags)JediFileDescriptor * FileDescriptor;int Flags ;

Parameters:

FileDescriptor. This is the file descriptor that was returned when the file was originally opened.

Flags. This parameter is not used at present.

Return Value:

0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.

Page 134: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 134/200

 

 jEDI API Calls Advanced Programmers ReferenceManual

8-12

JediSelect - Select Record Keys from a File

This function is called when the user wants to perform some sort of selection of the file. At present, the selectfunction is called to select all records in the file. However, calls from future programs may add selection criteria.

Synopsis:

int JediSelect(FileDescriptor, SelectPtr,SelectDetails, Index )

JediFileDescriptor * FileDescriptor;struct JediSelectPtr ** SelectPtr;char * SelectDetails;int Index ;

Parameters:

FileDescriptor. This is the file descriptor that was returned when the file was originally opened.

SelectPtr. The caller passes the address of a “struct JediSelectPtr *” variable here. If the SELECT works,this function will return here the address of an allocated JediSelectPtr structure. This address will be

passed to future calls to SELECTEND and READNEXT.SelectDetails. This is a NULL terminated string describing the selection details. For example, to select allrecord keys that match the regular expression “^MJI.*PIPE”, the caller will set this variable to point tothe string “^MJI.*PIPE”. Note that none of the supplied database drivers as of release 3.0 support thisfeature. Future database driver may do so. Currently the language for jBC does not support this either, butagain may do so in the future.

Index. For database drivers that support multiple indexed file, this shows the index number to performthe select against. As of release 3.0, the jBC language does not directly support multiple indexeddatabases. However, this may change in future releases.

Return Value:

0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.

Page 135: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 135/200

Page 136: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 136/200

 

 jEDI API Calls Advanced Programmers ReferenceManual

8-14

JediReadnext - Get Next Record Key

This function is typically called many times following a call to the SELECT function. This function will returnthe next record that has been selected following a call to the SELECT function.

Synopsis:

int JediReadnext(FileDescriptor, SelectPtr,RecordKeyPtr, RecordKeyLenPtr)

JediFileDescriptor * FileDescriptor;struct JediSelectPtr * SelectPtr;char ** RecordKeyPtr ;int * RecordKeyLenPtr ;

Parameters:

FileDescriptor. This is the file descriptor that was returned when the file was originally opened.

SelectPtr. This is the address of the structure that was created during the SELECT function.

RecordKeyPtr. The application passes in the parameter a pointer to a pointer to a buffer. This is where

the next selected record key will be returned. If the buffer is not large enough (See RecordKeyLenPtr),the JediReadnext function will allocate sufficient memory and return at RecordKeyPtr the address of theallocated memory. It is up to the calling application to detect if this has been performed, and to free anyallocated memory.

RecordKeyLenPtr. This is the address of an integer that describes the length of the buffer given by theexpression “*RecordKeyPtr”. When we have selected the next record key and placed it in the buffer

“*RecordKeyPtr”, we return here the length of the record key. If there are no more record keys, -1 isreturned here.

Return Value:

0  if the operation succeeded. This includes when the list of record keys are exhausted (in this case,*RecordKeyLenPtr set to -1).

Any other value shows the reason the operation failed using the values defined in errno.h.

Page 137: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 137/200

Page 138: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 138/200

Page 139: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 139/200

Advanced Programmers Reference Manual jEDI API Calls8-17

JediDelete - Delete a Record from a File

This function is called when the application wants to delete a record from the file.

Synopsis:

int JediDelete(FileDescriptor, Flags,RecordKey, RecordKeyLen )

JediFileDescriptor * FileDescriptor;int Flags ;char * RecordKey ;int RecordKeyLen ;

Parameters:

FileDescriptor. This is the file descriptor that was returned when the file was originally opened.

Flags. This parameter not used at present.

RecordKey. Points to a string describing the record key to delete. Note the record key is not a 0 (null)terminated string.

RecordKeyLen. This is the length of the record key as passed by RecordKey.

Return Value:

0 is returned if the record is deleted successfully.

ENOENT is returned if the record did not exist.

Any other value shows the reason the operation failed using the values defined in errno.h.

Page 140: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 140/200

 

 jEDI API Calls Advanced Programmers ReferenceManual

8-18

JediLock - Provide Record Locking Mechanism

This function is called by the application to provide record locking support. It can also be called intrinsically viathe jEDI code to support record locking functions. For example, if an application performs a request to READ arecord with a lock, the jEDI function will call the JediLock function directly, rather than the JediReadRecordfunction doing the call itself.

Synopsis:

int JediLock(FileDescriptor, Flags,RecordKey, RecordKeyLen )

JediFileDescriptor * FileDescriptor;int Flags ;char * RecordKey ;int RecordKeyLen ;

Parameters:

FileDescriptor. This is the file descriptor that was returned when the file was originally opened.

Flags. Can be one of the following bits to show what operation is to be performed by the LOCK function:JEDI_RECORD_LOCKRECORD Take a record lock and wait.

JEDI_RECORD_LOCKRECORD_NOWAIT  Take a record lock, but return if lock alreadytaken (The function return code is JEDI_ERRNO_LOCK_TAKEN).

JEDI_RECORD_UNLOCKRECORD Remove a record lock.

RecordKey. This is a pointer to a character array which shows what record key is to be locked orunlocked. Note that this array is not a 0 terminated string (See RecordKeyLen parameter).

A special case exists for when NULL is passed in this field. This means the calling application wants torelease all the locks for all the records in the file held by this application.

RecordKeyLen. This is the length of data passed in the RecordKey parameter.

Return Value:

0 shows the locks were created/removed okay.

JEDI_ERRNO_LOCK_TAKEN  the JEDI_RECORD_LOCKRECORD_NOWAIT  bit was set, and therecord/field was already locked by another process.

EDEADLK shows one of the lock bits was set, and a deadly embrace situation was detected and avoided.

Any other value shows the reason the operation failed using the values defined in errno.h.

Page 141: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 141/200

Advanced Programmers Reference Manual jEDI API Calls8-19

JediIOCTL - Database Driver Control Functions

This function is called to provide general database driver operations. Like the ioctl() function in C programs,there are some standard commands that most database drivers will be expected to perform, some that areoptional, and some that are unique to the database driver.

Synopsis:

int JediIOCTL(FileDescriptor, SubCommand,IoctlAddr, IoctlLen,IoctlReturnAddr, IoctlReturnLen)

JediFileDescriptor * FileDescriptor;int SubCommand ;void * IoctlAddr ;int IoctlLen ;void * IoctlReturnAddr ;int * IoctlReturnLen;

Parameters:

FileDescriptor. This is the file descriptor that was returned when the file was originally opened.

SubCommand. This shows actually what sort of operation to perform. There are some commoncommands given by the JEDI_IOCTL_xxx definition, but the database driver can add support for othercommands if required.

IoctlAddr. This gives the address of any optional buffer that may be necessary to provide extraspecification, depending on the SubCommand. Therefore its use is highly dependent upon SubCommand.The application may pass NULL here.

IoctlLen. This is the size of data that is pointed to by the IoctlAddr parameter.

IoctlReturnAddr. This is the address of a buffer or length IoctlReturnLen bytes where the IOCTLfunction can return any data depending upon the command to be executed (See SubCommand).

IoctlReturnLen. This is the address of an integer that shows the length of the return buffer pointed to byIoctlReturnAddr. Upon exit, the database driver should update this to show the amount of valid data thatthe JediIOCTL function has returned in IoctlReturnAddr.

Return Value:

The return value is highly dependent on the database driver. By convention, -1 is returned if the operation

failed, and 0 if the operation was successful.

Page 142: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 142/200

 

 jEDI API Calls Advanced Programmers ReferenceManual

8-20

JediSync - Synchronise the Data to Disk

This function is called to flush any cache data to the disk. Not all database drivers support this - those that don’tsimply return 0.

Synopsis:

int JediSync(FileDescriptor)JediFileDescriptor *FileDescriptor;

Parameters:

FileDescriptor. This is the file descriptor that was returned when the file was originally opened.

Return Value:

0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.

Page 143: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 143/200

Advanced Programmers Reference Manual jEDI API Calls8-21

JediClearFile - Delete All Records from a File

This function is called by an application to delete all the records from a file. No file locks are taken, so otherapplications could be writing to the file at the same time.

Synopsis:

int JediClearFile(FileDescriptor)JediFileDescriptor *FileDescriptor;

Parameters:

FileDescriptor. This is the file descriptor that was returned when the file was originally opened.

Return Value:

0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.

Page 144: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 144/200

 

 jEDI API Calls Advanced Programmers ReferenceManual

8-22

JediPerror - Print Error Message

This function is similar to the standard C library function perror(). However, some of the values for 'errno' thatcan be returned by certain jEDI function calls are an extension to the standard values for errno. The replacementfunction for perror() allows for the extensions.

Synopsis:

int JediPerror (ErrorValue , Description )int ErrorValue ;char * Description ;

Parameters:

ErrorValue. This is the error number for which you want the appropriate error message displayed. Undernormal circumstances you would pass the global 'errno' value in this parameter.

Description. The text associated with the error, in the same was you pass text to the perror() function.

Return Value:

Always the same as the 'ErrorValue' parameter.

Example:

if ((returncode = JediReadRecord(FileDescriptor .....{

return JediPerror (returncode , "filename") ;}

Page 145: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 145/200

Advanced Programmers Reference Manual jEDI API Calls8-23

JediFileOp - General File Maintenance

This function allows the caller to create, clear and delete files in the database types that are supportedintrinsically by jEDI. The calls to this function will not allow these file operations on external databases, andoperations such as delete file should be performed by calling the services provided by the external database.

You can also call an external program to perform the functionality rather than call this function directly. Forexample, instead of calling JediFileOp to create a file, perform the following code :

if (system("CREATE-FILE FILENAME 1,1 23,1") != 0){

fprintf(stderr,"CREATE-FILE failed\n");}

Synopsis:

int JediFileOp (command, flags, filespec,unixoptions, legacyoptions,errormessage, interrupt)

int command ;int flags ;

char * filespec ;char * unixoptions ;char * legacyoptions ;char * errormessage ;void (* interrupt)() ;

Parameters:

command. One of the following values :

JEDI_FILEOP_CREATE_FILE Create a file

JEDI_FILEOP_DELETE_FILE Delete a file

JEDI_FILEOP_CLEAR_FILE Clear a file

flags. This is one of the following values :

JEDI_FILEOP_DICT_ONLY Create only the DICTionary

JEDI_FILEOP_DATA_ONLY Create only the data section.

filespec. This string defines the specification of the file, such as "DICT Filename 1,1 TYPE=HASH1"

unixoptions. The options that would normally be specified on the command line in the Unix manner.This is a string with one or more of the following characters:

B File not Backed up using jbackup.

L File not Logged to the logger.

T File not part of Transaction boundaries.

H Do not fill holes when creating files.

legacyoptions. The options that would normally be specified on the command line in the manner oflegacy applications. This is a string with the same characters and meaning as for the unixoptions

parameter.

errormessage. Address if a 1024 byte buffer where an error message string should be stored if an erroroccurs. The error strings define record keys in the jBASE error message file (usually$JBCRELEASEDIR/jbcmessages). You can find the error messages by typing the following command

from a UNIX shell :

LIST $JBCRELEASEDIR/jbcmessage EQ \"JEDI_FILEOP]\"

Note that the string returned here is actually a number of fields delimited by value marks, 0xFC. The first

field is the actual error message key, and the remaining fields are the operands to the message key - suchas the name of the file.

Page 146: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 146/200

 

 jEDI API Calls Advanced Programmers ReferenceManual

8-24

interrupt. The address of a function to call to establish all your signal handlers. When youcall JediFileOp, it has to set up some of its own signal handlers to handle the SIGINT and SIGQUITsignals. By passing the address of a function, you can cause it to re-establish your signal handlers uponcompletion. You can also pass -1 here to ignore this functionality.

Return Value:

0 if the operation succeeded.

Any other value shows that the operation failed. The errormessage buffer is updated with an appropriateerror message - held in the jBASE error message file, with appended operands delimited by value marks,0xFC.

Example:

We wish to create a file called 'SLIPPER', but only the DICTionary part of it. The file will be a j2 type (denoted

by HASH2), will have 17 buckets, and we do not want the file backed up using the jbackup command.

#include <jsystem.h>#include <jedi.h>main()

{char buffer[1024] ;int returncode ;if ((returncode = JediFileOp (

JEDI_FILEOP_CREATE_FILE ,JEDI_FILEOP_DICT_ONLY ,"SLIPPER 17,1 TYPE=HASH2" ,"B" ,"" ,buffer ,(void (*)())-1)) != 0)

{fprintf(stderr,"Cannot create file SLIPPER\n");

}

exit (returncode) ;}

Page 147: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 147/200

Advanced Programmers Reference Manual jEDI API Calls8-25

JediReinitialise - Re-initialise jEDI Code

This function is called by an application to re-initialise certain aspects of jEDI when the underlying controlenvironment variables have been changed since the first call to jEDI. The environment variables are:

. HOME - The home directory of the user.

. JEDIFILEPATH - The list of directories to look in when opening a file.

. JEDIFILENAME_MD - The name of the MD file, if any, to use to resolve Q pointers, F pointers and soon.

. JEDIFILENAME_SYSTEM - The name of the SYSTEM file, if any, to use to find any pseudo accountnames during the resolution of Q pointers. Unless you change any of the above environment variableswithin a program, you will not need to call JediReinitialise.

Synopsis:

int JediReinitialise ()

Parameters:

None.

Return Value:

0 if the operation succeeded.

Any other value shows the reason the operation failed using the values defined in errno.h.

Example:

/** About to change the JEDIFILEPATH environment* variable.*/putenv("JEDIFILEPATH=.:/home2/pipeman/files");/*

* If we do not call JediReinitialise, the changed* environment variable will have no effect.*/if ((returncode = JediReinitialise ()) != 0){

JediPerror (returncode , "JediReinitialise");}

Page 148: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 148/200

Page 149: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 149/200

 

Chapter 9: Makefiles

Page 150: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 150/200

Page 151: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 151/200

Advanced Programmers Reference Manual Makefiles9-1

Introduction

The standard UNIX development facility called 'make' is designed to help programmers manage many sourcefiles, and to build applications from the source files automatically. In its simplest form, make keeps track ofchanges in source files and when asked to, it will recompile all the parts of the program that have been affected

by changes.

When invoked, the make command looks for a file called Makefile (or makefile) in the current directory. Itexpects this file to describe the rules for building your application. An example of a small makefile is given later.

The make facility is fully documented in your UNIX development documentation. The remainder of this chapterwill show you how an example jBASE application could use the make facility, but it will not attempt todocument make itself.

Remember that if you do not feel comfortable with using make files, you can carry on using the BASIC andCATALOG commands that you are used to. However, most application developers find than once they havegone through the ‘pain’ of creating their make files, it is well worth the initial effort.

Make files work best when the sources have a defined extension to their file name. jBC source code does nothave any particular naming convention when using BASIC or CATALOG, but when you use the jbc command

or make files the source code files should have a ‘.b’ extension.

As an example, assume we have two programs, 2 subroutines and 2 C functions. These are in source file namesprog1.b, prog2.b, sub1.b, sub2.b, func1.c and func2.c respectively. Assume also that they are all in the samedirectory and there is a make description file in the directory called Makefile. This is what the Makefile mightlook like:

## This is the example make file for the sources# prog1.b, prog2.b , sub1.b , sub2.b , func1.c and# func2.c.## Declare the fact some of the suffixes are .b#.SUFFIXES: .b## Declare the options we will use to the jbc compiler.#OPTIONS = -JO2## Declare the name of the library we keep the C object# and the SUBROUTINE object in.#LIBCFUNCS = libFUNC.aLIBSUBS = libSUBS.a## Declare the name of the shared object we will build# when we have built the subroutines into archive# libraries.#LIBSUBSOUTPUT = libSUBS.so## Declare the objects that will go in the archive# libraries#LIBCOBJS = $(LIBCFUNCS)(func1.o) \

$(LIBCFUNCS)(func2.o)LIBSOBJS = $(LIBSUBS)(sub1.o) \

$(LIBSUBS)(sub2.o)## Declare the programs to build.#PROGRAMS = prog1 prog2

## Stop the make utility from deleting these libraries

Page 152: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 152/200

 

Makefiles Advanced Programmers ReferenceManual

9-2

# if you interrupt the make.#.PRECIOUS: $(LIBCFUNCS) $(LIBSUBS)## Declare the programs to execute when we need to# re-compile a C source or jbc source, and put it in

# the library.#.c.a:

cc -c $< -I$(JBCRELEASEDIR)/includear -rv $@ $(?:.c=.o)

.b.a:jbc -Ja$@ $<

## The first target name we defined below is the target# name that make will try to build if you just enter# 'make' on the command line.#all: $(LIBCFUNCS) $(LIBSUBS) $(PROGRAMS)#

# We can now define another target name called 'clean'# that will update the time stamp for all the sources# and then call 'make all' to re-build all the# programs regardless.#clean:

touch *.[bc]-rm *.[oa]make all

## Create a target name called 'release'. This copies# all the programs from the current directory to the# directory where they will actually be run from, and# copies the shared objects containing the SUBROUTINES

# to the target directory.#release:

cp $(PROGRAMS) $(HOME)/bincp $(LIBSUBSOUTPUT) $(LIBSUBSOUTPUT).el $(HOME)/lib

## Describe how to build the libraries.# The libraries are built initially using the rules# '.c.a' and '.b.a' that were defined earlier. For the# SUBROUTINE library, we additionally call jBuildSLib# to create a shared object from the archive library.#$(LIBCFUNCS): $(LIBCOBJS)$(LIBSUBS): $(LIBSOBJS)

jBuildSLib $(LIBSUBS) $(LIBCFUNCS) -o $(LIBSUBSOUTPUT)## Describe the rules for building the programs. Note# that we describe the C functions as dependencies, so# they will get built first.#$(PROGRAMS): $$(@).b $(LIBCFUNCS)

jbc [email protected] -o $@ $(LIBCFUNCS)

The make file has a number of target names to allow you to develop the example application using the followingsteps:

1.  Set your environment to use local copies of the programs and subroutines using the followingcommands:

% export PATH=`pwd`:$PATH% export JBCOBJECTLIST=`pwd`:$JBCOBJECTLIST

Page 153: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 153/200

Advanced Programmers Reference Manual Makefiles9-3

2.  Edit the sources prog1.b, prog2.b , sub1.b, sub2.b, func1.c, func2.c

3.  Create the file 'Makefile' as shown above.

4.  Build the programs using the following command :

% make

or% make all

5.  If there are any compilation errors, edit the source and re-build the application using 'make' or 'makeall'.

6.  Test the application. If there are any application errors, edit the source and re-build using 'make' or'make all'. The make command will only re-build the sources that have been affected by changes.

7.  Once you have the application working, you may like to re-compile ALL the sources again just to be100% sure, using the following command :

% make clean

8.  In the first step you modified JBCOBJECTLIST and PATH to give the current directory precedence

so, up to this point, these program and subroutines will all have been built in the current directory, andonly you will have access to them. The following command will copy the executable programs andshared object subroutines into the directory used by other users in the account. Do this when you havefinished testing your application and want to make it generally available:

% make release

Although not intended as a make tutorial, you may find the following points helpful when you are looking at theabove example:

•  The make command contains a large number of command line options, internal rules, default rules, macrosand so on. These are all explained by executing 'man make' from your shell command line. They are worthlooking at in some detail.

•  When you execute the make command you give it a target name to describe what to actually make. Your

make file can have one or more target names. If you omit the target name on the command line, make willuse the first target name it finds. In the above example, the target names are 'all', 'clean' and 'release'. So, fromthe command line, any of the following are valid :

% make # Uses the 'all' target as default

% make all # Uses target name 'all' , currently default

% make release # Uses the target name 'release'.

% make all release # Builds all programs then releases them.

•  Notice how the 'clean' target name actually calls the make utility recursively after it has forced a re-build of

all the objects.

•  By default, should any of the executed programs return a completion code other than 0, make will abort thebuild at this point and return a completion code other than 0. This can be turned off by using the -i optionwhen invoking make, for example:

% make -i release

Note you can also stop the checking of the return code of individual commands in the make file by preceding itwith - , as we have used in the example '-rm *.[oa]'. This is useful if you are unconcerned if the commandfails. In our example the rm may fail if the files to delete do not exist already, and so we are not concerned

with this error.

•  The example shows the use of jbc and jBuildSLib instead of BASIC and CATALOG. You can amend themake files to use BASIC and CATALOG, but this will make the files more complicated.

•  There are a number of macros used in the make file, such as $@, @<, @(?:.c=.o). These perform generalsubstitution of object names. Use 'man make' for more information.

Page 154: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 154/200

 

Makefiles Advanced Programmers ReferenceManual

9-4

•  The make files support the use of 'include' to include other make files. This is synonymous with the use ofINCLUDE or #include in jBC and C source code. For example, instead of using the command jBuildSLib,

you could define the command in a common make file, and use the definition in another make file. If weassume the file at $HOME/makecommon has the following line in it :

BUILDCMD = jBuildSLib

in your own make file you could do the following :

include $(JBASEHOME)/makecommon$(BUILDCMD) $(LIBSUBS) $(LIBCFUNCS) -o $(LIBSUBSOUTPUT)

Page 155: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 155/200

 

Chapter 10: jbc and BASIC

Page 156: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 156/200

Page 157: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 157/200

Advanced Programmers Reference Manual jbc and BASIC10-1

Introduction

There are two main mechanisms for compiling a source to an object.

The jbc command provides all the functionality to compile source to an object, and optionally to createexecutable programs or archive libraries from the object. It has many options to control the compilation and

linking. It only works on UNIX files, so any source files in jBASE hashed files, for example, cannot be usedwith the jbc command. This is not normally a problem, as developers tend to keep their source code in UNIXdirectories and they can use UNIX tools on the sources such as make, grep, vi, ar, cc and so on.

The BASIC command is a simple-to-use command that is really just a front-end program to the jbc command. Ithas fewer options and less flexibility than the jbc command, but for a substantial number of developers itprovides all the functionality they need. The BASIC command works with any files supported by jEDI, such asUNIX directories, hashed files and so on. The output of the BASIC command is the creation of a compiled

object that is placed in the same file as the source but with a slightly different name.

Page 158: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 158/200

 

 jbc and BASIC Advanced Programmers ReferenceManual

10-2

 jbc Command

The jBC compiler consists of a sophisticated set of compilation tools used to compile and link jBC, C,assembler, libraries and object code to produce UNIX executable files. It provides new UNIX tools to process

 jBC files and uses the same tools as the UNIX C compiler for processing C code.

The compilation tools consist of a jBC pre-processor (jpp), a jBC cross compiler (jbccom), jBC optimiser

(jbcoptim), a C pre-processor (cpp), C compiler (ccom), assembler optimiser (coptim), assembler (as), and linker(ld). The compiler is driven through the jbc interface command. The interface accepts many options that controlthe relevant tools in the compilation process. It also provides transparent access to the tools mentionedpreviously.

The jbc command accepts several different file types as source file arguments and performs the requiredprocessing on each. The order of processing is shown in the figure on the next page. As illustrated, the jbccommand can process jBC source programs, C source programs, UNIX assembler source, libraries and objectprograms to produce a UNIX executable file. The compilation process can be halted at any of the stages shownby providing the appropriate options to jbc. Compilation of the intermediate files can subsequently becompleted, again using the jbc command.

 jBC source code is compiled into machine code and, as there is no CPU overhead involved with interpretingpseudo object code, the resulting code executes extremely quickly.

 jBC Compiler Order of Processing

How to Use the jbc Command

The jbc command is primarily used for the compilation of source programs written in the jBC applicationprogramming language. Although designed for jBC, the jbc command also compiles source programs written inC, enabling the programmer to mix and manage both languages in one compilation process.

The jbc command normally produces an executable UNIX file with all stages in between transparent to the user,in the same way the UNIX command cc handles C code. jbc effectively replaces the cc command for jBC

application programmers.

Page 159: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 159/200

Advanced Programmers Reference Manual jbc and BASIC10-3

The default operation of jbc is to compile a number of sources and create an executable file named a.out.Optionally, the user may halt the compilation process at any stage and examine the resultant code.

As the compiler also makes use of the UNIX compiler, pre-processor and link-loader, the options for theseutilities are also available to the jBC compiler. Some common options are described later.

 jbc command syntax is:

jbc {-option {...-option}} file {{file}...}

file  This is a list of programs as arguments, separated by spaces. The source provided can be jBC, C,assembler or an object program, and is processed accordingly.

-option  This is a character string representing one or more jbc options.

Options passed to the command must be preceded by a hyphen, or they will be interpreted as a file which jbcwill try (and fail) to compile.

The options directly supported by the jbc command mostly begin with -J. The other options supported are reallyfor the UNIX cc command. The options available to jbc can be split broadly into five categories:

1.  cc only. These options are not used by jbc and are passed directly to the cc command when the cccommand is called.

2.  Common cc and jbc options. These options are used by both the cc command and the jbc command.

3.   jbc only standard options. Normal options used purely by the jbc program.

4.   jbc SQL options. These options are only used when compiling sources with embedded SQL statements,which is an optional feature of jBASE.

5.   jbc C++ options. These options are used to create C++ code instead of C code from a jBC source.

 jbc cc Only Options

There are a number of options supported by the jbc command that are passed directly to the cc command duringthe C source compilation and linking phases. The exact meanings of these options depend upon the C

development system and the command ‘man cc’ or ‘man ld’ will usually describe them. These options are:-a -d -e -f -g -p -q -r -s -t -u-x -z -D -E -H -M -N -O -P -U -V-W -X -Z

 jbc Common cc and jbc Options.

These options are used by both the cc command and the jbc command.

Option Description

-c Suppress the generation of the executable. This will normallyresult 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 tocreate an executable called a.out.

-Idirname Specifies the name of a directory (or a jBC file) where sourcescan be included from. This is used when compiling theINCLUDE 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 thecompilation of jBC source code to be terminated after the

Page 160: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 160/200

 

 jbc and BASIC Advanced Programmers ReferenceManual

10-4

creation of the .c and .j files. This way, the user can examine theC code generated by the jbccom compiler. This C source can thenbe used later as an input file to jbc (or cc) if required.

-Yb,dirname Shows the directory for the jbccom compiler. By default, we use$JBCRELEASEDIR/bin/jbccom, but use this option for any otherdirectory.

 jbc Only Standard Options

These are normal options used purely by the jbc program.

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 producedwhile compiling native C code remain.

-Jm Do not run the mcs command after an executable program hasbeen created. This may be useful when using other UNIX toolsagainst an executable program.

-Jo This allows an easy way of defining the output executable namebased on the first jBC source name. For example, if the first jBCsource name was prog1.b and the -Jo option was used, the outputexecutable 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-programsit calls to complete the command. This is very useful to get athorough 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 beforeprinting 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 sectionentitled ‘jbc and BASIC warning levels’.

-JCA Ensure that ANSI code is produced (this may be the default ifyour 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 betimes when you want to link with jBC archive libraries though,

Page 161: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 161/200

Page 162: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 162/200

 

 jbc and BASIC Advanced Programmers ReferenceManual

10-6

intended for inclusion in other C++ source files using #include.Files INCLUDEd in this source will however be expanded in thegenerated include file.

-JGtn Translate the file and parse INCLUDE files for data definitionsand DEFC/DEFCPP statements etc. However, the jBC statementINCLUDE is translated to the equivalent #include in C++.

-JGtin Translate the file, which is an INCLUDEd file as per option -JGtiabove. However, in addition, any INCLUDE statements aretranslated to the equivalent #include in C++; like the -Jgtn optionabove.

INCLUDE File and Library Processing

When the jbc command is used to compile jBC and C sources, the sources themselves can declare other sourcesto be included with the INCLUDE and $INCLUDE statements in a jBC source, and a #include statement in a Csource. The path for searching for these statements is:

•  Look in any directories specified by the -Idir option to jbc. If more than one -Idir option is used, left to rightsearching is used.

•  Look in the directory $JBCRELEASEDIR/include. If the environment variable JBCRELEASEDIR is not

set, look in directory /usr/jbc/include.

•  If a jBC source, the current working directory is next searched.

•  If a C source, the remaining search paths are exactly as for the cc command.

When the jbc command is used to create an executable, various libraries are referenced to resolve the external

symbol processing during the linking phase. The mechanism for doing this is:

•  Look in the libraries defined by the JBCLIBFILE environment variable.

•  Look in the libraries defined by the -lname options to the jbc program. As with cc, the ‘name’ is expanded to‘libname.so’ if it exists, or ‘libname.a’ otherwise.

•  Always look in the libraries libjbc.so and libjedi.so (or libjbc.a and libjedi.a if the -JLa option used).

•  Always look in libraries such as curses, ld, math etc. The actual list depends on the platform that jBASE is

loaded onto. Use the -Jv option to get the full list.

•  Always look in the default C library.

•  When searching for libraries, look in the directories specified with the JBCLIBDIR environment variable.

•  When searching for libraries, look in the directories specified with the -Ldirname option. If more than one -Ldirname option is used, left to right searching is used.

•  When searching for libraries, use the library directories as per the cc command.

•  Always link the program with libraries specified on the command line to the jbc program in the formatname.a and name.so.

Environment Variables and the jbc Command

The use of the -options to the jbc program is the main mechanism for controlling the work of the jbc program.There are a number of additional environment variables that may be used for controlling the jbc program.

CC Setting this environment variable to the name of a program causes us to use the command defined by the CCvariable instead of the default ‘cc’ command.

JBCLIBDIR You can specify new library directories to search by using this environment variable. Thesedirectories have the highest precedence. For example:

% export JBCLIBDIR=“-L /home/test/lib -L/home/libdir”

Page 163: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 163/200

Advanced Programmers Reference Manual jbc and BASIC10-7

JBCLIBFILE You can specify default libraries to look in by using this environment variable. These librarynames have the highest precedence. For example:

% export JBCLIBFILE=“-l comms -l dothis”

 jbc Examples

% jbc invoices.b

The simplest form of the command compiles the jBC source program invoices.b, held in the current directorythen 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 resultantobject 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 causesthe 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 theobject 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.

 jpp Macro Pre-processor

The compiler also incorporates a sophisticated macro pre-processor that provides complex conditionalcompilation facilities. It supports compiler directives compatible with C compilers and BASIC compilers.

A complete description of pre-processor directives follows.

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 6EQUATE 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. Theword 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.

# ifdef and #endif

#ifdef symbol....#endif

You can also create definitions at compile time using the -JCDxxx option to jbc

Page 164: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 164/200

 

 jbc and BASIC Advanced Programmers ReferenceManual

10-8

The #ifdef statement checks the equate (#define) definitions and if an EQUATE or #define has been declared forsymbol, it allows the code up to the #endif statement to be given to the compiler. If symbol has not been defined,the pre processor will stop passing code to the compiler until it encounters the #endif statement.

Page 165: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 165/200

Advanced Programmers Reference Manual jbc and BASIC10-9

BASIC Command

The BASIC command is used to create a program or subroutine object from a jBC source code. The BASICcommand has been touched on already in the Programmers Reference Manual. This section is designed to givean insight into the workings of the command, and how it can be extended.

Imagine the following command was executed to compile program source PROGRAM1 and subroutine sourcesub1.b:

% BASIC BP PROGRAM1 sub1.b

The BASIC command would create the object records $PROGRAM1 and sub1.o in file BP. The BP file can be

any  file type supported by jBASE, whether it is a hashed file, UNIX directory and so on. The steps used by

BASIC are:

•  Any supplied record keys with a $ prefix or a .o suffix are ignored.

•  The source is moved to the current working directory as a temporary UNIX file called BASIC_nn.c, wherenn is the users port number.

•  The source is compiled using the jbc command. Assuming the compilation works, a new file BASIC_nn.o

will have been created.

•  The object file BASIC_nn.o is moved back to the original file. If the original record key had a suffix of .b,the object will be moved with a .o suffix. If not, the object will be moved with a $ prefix.

•  The BASIC command cleans up any scratch files it created.

Using the BASIC Command

The full syntax of the BASIC command is:

BASIC {-v} {-w[0-3]} {DICT} filename{recordkey | * } {(OC[W0-3]})

-v Verbose mode. The CATALOG command will display details of external commands being executed

-w[0-3] Set the warning level to 0, 1, 2 or 3. See later.

DICT Optional DICTionary specifier for the file name.

filename Name of the file to get the sources from. Can be any file supported by jEDI, such as a hashed file or aUNIX directory.

recordkey The list of sources to process.

* Shows to process all sources in the file.

(O) Optimise the code. No debugging information is generated with this option. This O option is synonymouswith the (E) option.

(E) Optimise the code. No debugging information is generated with this option. This E option is synonymous

with the (O) option and is provided for backwards compatibility with legacy applications.

(W0-3) Set warning level to 0, 1, 2 or 3. See later

If both recordkey and * are omitted, BASIC will use any preceding select list. If the BASIC command has noselect list, it will use all records in the specified file.

When processing the list of record keys, the BASIC command will ignore any $ prefixes and .o suffixes andbuild up a list of source names. Using this mechanism, you can safely use BASIC on all records in a file, and itwill only process the sources you intended.

Page 166: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 166/200

 

 jbc and BASIC Advanced Programmers ReferenceManual

10-10

 jbc and BASIC Warning Levels

The jbc and BASIC commands allows 4 levels of warning to be generated.

The BASIC command uses the -wn option or the (Wn) option. For example, to set warning level 3 use either of

the following commands:

% BASIC -w3 FILENAME SOURCENAME% BASIC FILENAME SOURCENAME \(W3

The jbc command uses the -JCwn option, where n is the warning level from 0 to 3. For example, to set warninglevel 3 use something like the following:

% jbc -Jcw3 FILENAME.b -c

The default level is level 1. The four levels are:

Level Types of warning reported.

0 None. No warnings generated at all.

1 Reasonable. Only reports those things that are quite likely to be an errorand really should be looked at. There are few of these. This is the defaultwarning level.

2 Pedantic. Reports all of the Reasonable errors plus a few more that are badpractice and should really be seen to.

3 Highly Pedantic. Reports every little transgression of the rules.

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 begenerated.

SUBROUTINE abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

varx = 1COMMON varxvary = varzFOR I = 1 TO 10NEXT LBREAKCONTINUEformat = varx "L#10" "L#20" "L#30"

ENDEND

Page 167: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 167/200

 

Chapter 11: jBuildSLIb andCATALOG

Page 168: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 168/200

Page 169: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 169/200

Advanced Programmers Reference Manual jBuildSLib and CATALOG11-1

Introduction

The jBuildSLib and CATALOG commands are both involved with creating a shared object from archive objects.The CATALOG command can also create an executable program.

The CATALOG command was briefly described in the Programmers Reference Manual. This chapter explores

its advanced operation.

Page 170: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 170/200

 

 jBuildSLib and CATALOG Advanced Programmers ReferenceManual

11-2

 jBuildSLib Command

This command will basically take any number of existing objects that have previously been compiled (usingtools such as ar, jbc, cc, BASIC or as) and will create a shared object from the input objects. Similarfunctionality can be provided by the UNIX cc command, but jBuildSLib makes the interface easier as well asproviding command syntax portability across different C development systems.

The shared object is then accessible to other programs in two different ways:

1.  By using the CALL statement from a jBC source.

2.  By calling a C function from a C source or a jBC source.

The syntax of the command is:

jBuildSLib {-o output} {-v} {-llib} {-Iimport}{name.o} {name.so} {name.a}

Where:

-o output The name of the output file, default is a.out

-v Verbose mode.-llib Specify a library using normal ‘cc’ command syntax.

-Iimport Used by AIX system and specifies a import list.

name.o An existing compiled object.

name.a An existing archive library.

name.so An existing shared object.

Output is to file a.out, although this can be overridden with the -o option. The command also creates an ‘export’list, which is a list of all symbols contained in the new shared objects. This export list is used in 2 ways:

1.  By AIX systems as an import list, when using the created shared object.

2.  By the jBC run-time when executing a CALL statement.

Example

The example below shows two C sources being compiled into a library, and a shared object being created out ofthem

% 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 Csources, 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 iscompiled 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 CALLto 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, asused by program prog1.b. They make calls to other external functions in a comms package.

Page 171: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 171/200

Advanced Programmers Reference Manual jBuildSLib and CATALOG11-3

•  libcomms.a  is a comms package supplied by a third party vendor, for which only the archive library isavailable. It is called by C functions func1, func2 and func3.

•  sub1.b is a jBC subroutine, called by program prog1.b

•  sub2.b is a jBC subroutine, called by program prog2.b

•  func4.o is a pre-compiled object, called by program prog2.b

Creating the Input Objects to jBuildSLib

This stage is quite simple, and just involves converting the source code into object code.

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.

Using the jBuildSLib Command to Create a Shared Object

Given objects in the form of .o files, archive libraries or existing shared objects, you would now create a sharedobject using the inputs.

In our rolling example, we will create two shared objects, one called libfuncs.so (with an export list calledlibfuncs.so.el) and one called libutils.so (with an export list called libutils.so.el).

Example

Create the libfuncs.so from three input files:

% jBuildSLib -o libfuncs.so libfuncs.a libcomms.asub1.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

Page 172: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 172/200

 

 jBuildSLib and CATALOG Advanced Programmers ReferenceManual

11-4

Referencing a Shared Object from a C or jBC Program

There are two ways a program can call functions inside a shared object:

1.  Through a standard C function call. This is done inside a jBC program with a defined C function call, orthrough the CALL statement compiled with the -JLS flag. In these cases, the function must be visible whenthe executable is created, and the shared object must be available to the UNIX dynamic linker when theprogram starts up. In our example, the program prog1.b will work this way.

2.  Through the CALL statement. If we assume the jBC program had a CALL statement, but was not  compiledwith the -JLS flag, the binding of the function to the jBC program is done entirely dynamically at run-time.In fact, the function need not even be written when the jBC source is originally compiled. In our example,the program prog2.b will work this way.

Before proceeding with the example, take a look at a parts of program prog1.b and prog2.b:

prog1.b

DEFC func1()DEFC func2()DEFC func3()func1()func2()func3()CALL sub1

prog2.b

DEFC func4()func4()CALL sub2

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 environmentvariable 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 isreferenced as the previous example, but the subroutine sub2 is called through the jBC run-time CALL statementand 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

Page 173: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 173/200

Advanced Programmers Reference Manual jBuildSLib and CATALOG11-5

% jbc prog2.b -o prog2 func4.o% prog2

Page 174: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 174/200

 

 jBuildSLib and CATALOG Advanced Programmers ReferenceManual

11-6

CATALOG Command

The CATALOG command is used to create an executable program from a compiled jBC program, or a sharedobject, accessible through the CALL statement, from a compiled jBC subroutine. The CATALOG command hasbeen referred to in the Programmers Reference Manual. This section is designed to give an insight into theworkings of the command, and how it can be extended.

Imagine the following commands were executed to compile program source PROGRAM1 and subroutine sourcesub1.b:

% BASIC BP PROGRAM1% BASIC BP sub1.b

The BASIC command would create the object records $PROGRAM1 and sub1.o in file BP. The BP file can beany file type supported by jBASE, whether it is a hashed file, a UNIX directory and so on.

The CATALOG command can now be used to create an executable program PROGRAM1 and a shared objectsubroutine sub1 with the following command:

% CATALOG BP PROGRAM1 sub1

Alternative forms of this could be:

% CATALOG BP \$PROGRAM1 sub1.o

or  

% CATALOG BP PROGRAM1.o% CATALOG BP \$sub1

This simple example shows the most common usage of the CATALOG command. There are extensions toCATALOG, but before proceeding to examine them, is worth explaining what happens when a program and

subroutine are CATALOGed.

CATALOGing a jBC Program

These are the steps when a command such as:

% CATALOG BP PROGRAM1

is executed:

•  Any leading ‘$’ and trailing ‘.o’ are removed from the name.

•  A check is made for duplicate names - in the following command only one object would be processed:

% CATALOG BP $PROGRAM1 PROGRAM1 PROGRAM1.o

•  The $PROGRAM1 or PROGRAM1.o object is looked for in file BP. It is moved to the current workingdirectory as a temporary UNIX file called BASIC_nn.o, where nn is the user’s port number.

•  The symbols in the object are examined so that it can be determined as a program, rather than a subroutine.

•  The directory $HOME/bin is created, if it doesn’t already exist.

•  The jbc command is invoked to create an executable program in directory $HOME/bin, something like this:

% jbc BASIC_xx.o -o $HOME/bin/PROGRAM1

•  The CATALOG command cleans up any scratch files created.

CATALOGing a jBC Subroutine

These are the steps when a command such as:

% CATALOG BP sub1.o

is executed:•  Any leading ‘$’ and trailing ‘.o’ are removed from the name.

Page 175: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 175/200

Advanced Programmers Reference Manual jBuildSLib and CATALOG11-7

•  A check is made for duplicate names - in the following command only one object is processed:

% CATALOG BP $sub1 sub1 sub1.o

•  The $sub1 or sub1.o object is looked for in file BP. It is moved to the current working directory as atemporary UNIX file called BASIC_nn.o, where nn is the user’s port number.

•  The symbols in the object are examined so that it can be determined as a subroutine, rather than a program.•  The directory $HOME/lib is created, if it doesn’t already exist.

•  The object is moved to the directory $HOME/lib/objAAA where AAA is the user’s account name.

•  The file $HOME/lib/libAAA.el is examined. This contains the size and description of all objects catalogedso far. The CATALOG command will select which shared object the new object is to be placed in, or

whether to allocate a new shared object.

•  Using the $HOME/lib/libAAA.el file, the CATALOG command can determine what objects in directory$HOME/lib/objAAA will be used, along with the new object, to create a single shared object.

•  The jBuildSLib command is invoked to create a shared object in directory $HOME/lib, something like this:

% jBuildSLib -o $HOME/lib/libAAAnn.so

$HOME/lib/objAAA/sub1.o $HOME/lib/objAAA/sub2.o

AAA is the user’s account name, nn is the number of the shared object chosen by the CATALOG command(using $HOME/lib/libAAA.el) and there can be any number of objects defined (only 2 in this example).

•  The CATALOG command cleans up any scratch files created.

Extending the Use of CATALOG

The full syntax of the CATALOG command is:

CATALOG {-v} {-obindir} {-Llibdir} {DICT} filename{recordkey | * }

-v Verbose mode. The CATALOG command will display details of external commands being executed

-obindir If you are cataloging a program, the output directory will be bindir instead of the default $HOME/bin.

-Llibdir If you are cataloging a subroutine, the output directory will be libdir instead of the default $HOME/lib.

DICT Optional DICTionary specifier for the file name.

filename Name of the file to get the objects from. Can be any file type supported by jEDI, such as a hashed file

or a UNIX directory.

recordkey The list of objects to process.

* Process all objects in the file.

If both recordkey and * are omitted, CATALOG will use any preceding select list. If the CATALOG commandhas no select list, it will use all records in the specified file.

When processing the list of record keys, the CATALOG command will ignore any $ prefixes and .o suffixes andbuild up a list of object names. It then removes duplicate names from its list. Finally, it looks for an object with a$ prefix, and failing that, it looks for an object with a .o suffix. Using this mechanism, you can safely useCATALOG on all records in a file - it will only process the objects you intend.

Instead of the -obindir option, you can set the JBCDEV_BIN environment variable. Similarly, instead of the -Llibdir option you can set the JBCDEV_LIB environment variable.

For example, let us assume you don’t want subroutines to be placed in $HOME/lib, but in directory /home/commonlib. There are two ways to achieve this:

1  Use the -Llibdir option.

% CATALOG -L/home/commonlib BP sub1.o

2  Use the JBCDEV_LIB environment variable.

Page 176: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 176/200

 

 jBuildSLib and CATALOG Advanced Programmers ReferenceManual

11-8

% export JBCDEV_LIB=/home/commonlib% CATALOG BP sub1.o

In the above examples, you will probably need to edit the file /home/commonlib/jLibDefinition for accountname, see the next topic.

CATALOG Configuration File

When the CATALOG command is executed against one or more subroutines, it will use a file$HOME/lib/jLibDefinition to obtain some details about the way CATALOG is to be used. If the file doesn’texist, a default one will be created using $JBCRELEASEDIR/config/jLibDefinition as a template. If the -Llibdiroption is used, or the JBCDEV_LIB environment variable is set, the jLibDefinition file in that directory will be

used.

This jLibDefinition definition file gives the CATALOG command information about the following:

•  The format of the shared object library name it creates.

•  The format of the export list associated with the shared object library name it creates.

•  The name of the directory where the archive objects are placed prior to creating a shared object from them.•  The approximate maximum size of a shared object.

If you look at file $JBCRELEASEDIR/config/jLibDefinition using any UNIX editor, it will give you moreinformation on the layout of the file. The default values provided with jBASE will usually be sufficient for mostneeds.

There is one circumstance when the definition file may need to be changed. This is when you are using

CATALOG into the directory from more that one account The definition file contains lots of ‘%a’ strings whichtells CATALOG to substitute the string %a with the current users account. As this will vary between differentaccount users, you may wish to replace the %a string in all the definitions to be some constant value (any valuewill do!).

Page 177: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 177/200

 

Chapter 12: Advanced Tools

Page 178: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 178/200

Page 179: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 179/200

Page 180: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 180/200

 

Advanced Tools Advanced Programmers ReferenceManual

12-2

 jBC Run-time Options

A number of options may follow the invocation of a jBC program. The command line format is:

progname { -Joption(s) {-Joption(s)} progparam

{ progparam..}

Options available are:

-Jb Run as a background process. A background port number will be allocated from the available list (see

 jPML in the Systems Administrators Manual) and control will return to the calling program.

-Jc To check the variables on exiting the program. This may be useful for debugging code with user-written C function when looking for corrupted variables.

-Jd To enter the debugger before execution of the first program line. The debugger prompt is displayedimmediately.

-JD Same as the -Jd option, to immediately enter the debugger, but will set the JBCDEBUGGERenvironment variable so that all programs executed by the parent will also immediately enter the

debugger.-Jp Normally the debugger will try to display the line of source code associated with the current program

position. The debugger will, by default, only look in the current working directory for the source file.You can use the -Jp option to give a list of file names to search in, each name delimited by a colon.The file can be any supported by jEDI, including hashed files and UNIX directories. The followingexample tells the debugger to look first in the file BP in the home directory and then in the currentworking directory:

% prog -Jp$HOME/BP:.

You can also use the ‘p’ command from the debugger prompt to achieve the same effect.

-Jr Redirects debugger input/output to the specified file. This allows you to debug on a different terminalfrom that running the application. This is very useful when debugging applications where screen

layout is important. You can also use the ‘r’ command from the debugger prompt to achieve the sameeffect.

-Js To display the CPU usage on exiting the program.

-Ju To set the terminal output to be unbuffered. Under normal circumstances, data printed to the terminalwill only be actually be displayed under the following circumstances:

•  A new line character is printed.

•  The maximum number of characters have been buffered.

•  The program terminates, or calls another program through the PERFORM, EXECUTE,CHAIN or ENTER command.

•  The program pauses due to execution of an INPUT, SLEEP or RQM statement.

For example, in the following code, the data is not actually printed until the very last line:

FOR Loop = 1 TO 10PRINT @(0,23):”Loop “:Loop:@(-4):CALL DOTHIS

NEXT LoopPRINT “Completed”

Some legacy applications do this sort of thing, and the status message is not displayed when it isrequired. There are a number of ways to force each PRINT or CRT statement to be displayed:

•  Use this -Ju option.

•  Append a CHAR(0) to the end of the string. For example

PRINT @(0,23):”Loop “:Loop:@(-4):CHAR(0):

Page 181: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 181/200

Advanced Programmers Reference Manual Advanced Tools12-3

Note that this incurs a performance penalty and should be avoided if possible. Small terminalpopulations will probably not see much degradation, but large terminal populations performing lots of

screen based activity will incur a significant penalty.

-Jw Prevents the debugger being entered when warning messages are issued. By default, when a run-timeerror occurs and a warning message is issued, the debugger will be entered. The later section on errormessages describes this more fully. This option will not affect fatal run-time errors, where the

debugger will still be entered if possible.

-Jx Causes the contents of the all variables in a program to be displayed at the end of a program.

-JP Turns on profiling support. This is discussed later in this chapter.

The use of the -J options is usually hidden from the application. Consider the following jBC program:

001 PRINT DQUOTE(SENTENCE())

Assume the program was started like this:

% testprog -Jw -JP filename recordkey

The output from the program would be:

“testprog filename recordkey”The same is true for the SYSTEM(1000) function call. However the application can use the SYSTEM(1001)function call to obtain all the command line arguments, for example if you changed the source code to become:

001 PRINT DQUOTE(CHANGE(SYSTEM(1001),CHAR(254),” “))

And ran it the same way, the output would be:

“testprog -Jw -JP filename recordkey”.

Note that the reason for using the CHANGE function is that SYSTEM(1000) and SYSTEM(1001) return thecommand line with the arguments delimited by an attribute mark, whereas the SENTENCE function delimits the

arguments with a space character.

Page 182: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 182/200

 

Advanced Tools Advanced Programmers ReferenceManual

12-4

 jPMLMsg Command

The basic purpose of jPMLMsg is to allow a root user to pass messages to a particular port number. Thesemessages are all pre-defined, so only a known set of commands can be executed. The jPMLMsg command willbe extended in future releases of jBASE, but for the present it is restricted to allowing debug requests to be sentfrom a root user to another jBASE program.

The syntax for jPMLMsg is:

% jPMLMsg {-v} {-pPid} PortNo Command {arg}{Command {arg} ...}

Where:

-v  Verbose, message to stdout.

-Ppid  Restrict message to process id Pid instead of all pids for port PortNo.

PortNo  The port number to send the message to.

arg Optional command argument, depends upon message.

Command  Can be one or more of the following:

ENTERDEBUG causes the port to enter the debugger regardless of the status of the BREAKflags, TCL Restart and END restart. Note that the debugger will only usually be entered on thenext command executed. If a terminal is at an INPUT statement, the debugger is enteredimmediately. If, for example, the terminal is at a SLEEP statement, you will need to press the INT

key (or send the SIGINT signal) to enter the debugger.

EXITDEBUG restores the original status of the environment to that prior to a ENTERDEBUG.

DEBUGTTY ttyname causes the debugger tty output to be redirected to device 'ttyname'.

Example

A terminal needs debugging, but you cannot debug it because TCL restart is enabled, or BREAK-OFF has beenset to disable break key etc. So, you need to not only over-ride the security in the program, but also debug itfrom 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

Page 183: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 183/200

Advanced Programmers Reference Manual Advanced Tools12-5

Profiling

There are simple profiling tools available with UNIX SVR4 and AIX systems. The library calls are notuniversally supported so not all jBASE platforms will support this profiling feature.

By default, no profiling is done in the program. Programs do not have to be compiled in any special manner to

enable profiling for that program. All that is required is that the programs were not compiled with optimisation,as this discards the debug information which is required for profiling.

The mechanism works by receiving a signal at every clock tick and keeping note of where the program was whenthe signal arrived. Thus, for the profiling to be accurate, the application must be run for a relatively long time. Itwill not show particularly good results if, for example, a program executes in less than a second. Several minutesor longer is preferred.

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 FilenameThis 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 isactive, in the format:

'jprof_pid_n'.

Where 'pid' is the process id, and 'n' is an incrementing number starting at the value 'JBCPROFILE' wasset 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 systemcalls is not included. Therefore, doing a lot of file I/O (especially for j1 files), means that this time will not beincluded in the profiling statistics. Note that time spent in j2 files which are in memory (when there are no framefaults) will be counted, as this is user CPU time.

Reporting the Profiling Files

The profiling files can be reported with the 'jprof' command. If you simply enter 'jprof' you get the help screen:

Called as :jprof {-n} {-i} {-fFilename {-fFilename}} jprof_nnnWhere :

-n Additionally sort by name-i Sort by increasing ticks, rather thandecreasing tick.

-fName Name of file to extract source from.prof_nnn Profile name

A typical use of jprof would be:

% jprof -f$HOME/BP -f. ./jprof

This would produce a report on the file jprof, which was created by a previous jBASE program run with the -JPoption. When running the report, it will attempt to display the source code associated with the lines, first trying

file $HOME/BP and then the current working directory.

The -i option can be used so the report is given with the least used lines of code first, and the most used lines of

code at the end of the report.

Page 184: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 184/200

 

Advanced Tools Advanced Programmers ReferenceManual

12-6

The -n option can be used to split the report into file names. For example, if the profiled program called lots ofsubroutines, each subroutine would be reported separately. By default, the section of the application that causedthe most CPU usage would be reported first. If the -n option is used with the -i option, the section of theapplication that caused the least CPU usage will be reported first.

Example of Profiling

Imagine the source 'test1.b' below has been edited into file BP, where BP is a regular UNIX directory. Notice theINCLUDE 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 JRec<I> = LineNEXT IWRITE Rec ON DSCB,Id

NEXT IdPRINT "Phase 1 -- end, CPU = ":SYSTEM(9)-S1INCLUDE test2.bPRINT 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 sourcecode listings from the file BP.

% jprof -f BP jprof

Profile of program test1 from profile jprof Page 1Source Line Ticks % Source

test2.b 8 166 32.93 READ Rec FROM DSCB,Key ELtest1.b 9 160 31.74 Line := CHAR(SEQ("A")+RND(test1.b 11 128 25.39 Rec<I> = Linetest2.b 7 28 5.55 WHILE READNEXT Key DOtest1.b 10 9 1.78 NEXT Jtest2.b 9 5 0.99 C1++test1.b 13 3 0.59 WRITE Rec ON DSCB,Idtest2.b 5 2 0.39 SELECT DSCBtest1.b 7 2 0.39 Line = ""test2.b 10 1 0.19 REPEAT

The -i option would sort the output with incrementing Ticks counts.

Page 185: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 185/200

Advanced Programmers Reference Manual Advanced Tools12-7

The -n option would additionally sort it by file name, so the 'test1.b' entries will be displayed separately to the‘test2.b’ entries.

Note that the output shown here is only a small sample of the real output.

Page 186: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 186/200

 

Advanced Tools Advanced Programmers ReferenceManual

12-8

Debugging - the JBCDEBUGGER Variable

The debugger is normally entered in a variety of ways:

•  The -Jd option can be used at the command line.

•  The application can execute a DEBUG statement.

•  A run-time error or warning might be detected by the library code.

By default, the debug status is not exported to any other programs that are executed via the PERFORM,EXECUTE, CHAIN or ENTER statement. Often a developer will not know which program inside an applicationis producing errors, and may want to debug a number of programs.

By setting the JBCDEBUGGER environment variable (to any value), when any jBASE program is started, it willimmediately enter the debugger. This means the developer can start an application and debug each program inthe application without the need to add DEBUG statements or amend the code in any way.

This functionality can also be initiated by using the -JD option when a jBASE program is first started. In fact, all

the -JD option does is to set the JBCDEBUGGER environment variable and then process the same as the -Jd

option.

Page 187: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 187/200

Advanced Programmers Reference Manual Advanced Tools12-9

Terminal Redirection

Quite often an application works in a full screen data entry format. When a developer debugs this type ofapplication, the screen that is being generated by the application becomes corrupted due to interaction with thedebugger. Whether this is a problem or not depends on the type of application and the issue you are trying to

resolve.

As an example, you may want to find the point at which the cursor moves unexpectedly from one field on thescreen to another, or to find out when unexpected character sequences are printed. These types of problem areharder to resolve when the screen format is corrupted by the debugger while you are trying to find the cause of

the original screen corruption.

A jBASE program is a normal UNIX program so you could always re-direct the output to another terminal. Forexample:

% MAINPROG > /dev/pts004 < /dev/pts004

In this example, the keyboard input and terminal output will be to terminal /dev/pts004, but unfortunately thedebugger interaction will also take place on /dev/pts004.

The solution is to allow just the debugger output to be re-directed to another terminal. This can be done using

either the -Jr option when an application starts, or by using the ‘r’ command once you are inside the debugger.

The following example runs a program from one terminal, but debugs it from another terminal. Let us assume theterminal for debugging is /dev/pts004, and the terminal to run the application from is /dev/tty01s.

From the debug terminal /dev/pts004, halt any other activity:.

% sleep 99999

From the program terminal, start the program:

% MAINPROG -Jr/dev/pts004 -Jd

You are now debugging from terminal /dev/pts004, but the application still works with /dev/tts01s.

Some points to remember when using this mechanism:

•  Ideally both terminals should be logged in to the same account. This will help prevent problems with thepermissions of the tty devices. If they are logged in to different accounts, you may find the debugger in

 /dev/tty01s does not have the correct permissions to write to file /dev/pts004.

•  The terminal debugging the application should never be running anything else that requires terminal input.For example, if the terminal /dev/pts004 still had the shell active, any keyboard data that is received might

go to the jBASE debugger or  it might go to the shell. A good solution is to use the sleep command, as in theexample above.

•  The debugger output can also be re-directed with the ‘r’ command, as well as the -Jr command when theprogram is first started.

•  To enter the debugger other than on an error or DEBUG statement, you need to generate a SIGINT or

SIGQUIT from the terminal that is running the application, and not the terminal where the debugger isrunning. In the above example, this would be from terminal /dev/tty01s.

•  To get the best out of the debugger, both terminals should be of the same terminal type. If not, you may finda few of the debugger features don’t display properly - the debugger will use the terminal type theapplication is running under to provide its terminal control characters.

Page 188: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 188/200

 

Advanced Tools Advanced Programmers ReferenceManual

12-10

 jshow Program

When running a jBASE application there can be confusion about three components of execution:

1.  When a program is executed, whereabouts in the UNIX system does the program get loaded from? It could

be from the user’s Master Dictionary file, or from any directory in the PATH environment variable.

2.  When a file is opened, whereabouts in the UNIX system is the actual file to be found? It could be from anycomponent in the JEDIFILEPATH environment variable, or from the resolution of a Q pointer and so on.

3.  When a SUBROUTINE is called, what library is the subroutine to be found in? It could be any sharedobject in the JBCOBJECTLIST environment variable, or the defaults for this variable, or from the$JBCRELEASEDIR/lib directory and so on.

A common experience amongst developers is to alter part of an application and then to wonder why the changehas not taken effect. Another is to run an application and wonder how seemingly impossible results have beengenerated from the current files.

The answer to a lot of these questions is that the program being loaded, file being opened or subroutine being

called is not the one you expected. The jshow program can help you to resolve these problems.

The syntax of the command is:

jshow {-fhpsv} Name {Name ...}

Where:

-f Restricts the search to file names.

-h Displays the help screen.

-p Restricts the search to executable programs.

-s Restricts the search to subroutines only.

-v Verbose mode.

Name Is the name of the object to find.

By default jshow will take each Name supplied and first see if it exists as a file, then if it exists as a jBCSUBROUTINE, then if it exists as an executable program. If any of the above are found, jshow displays the filetype and the path the object type was found on.

You can restrict the search to just jBASE files using the -f option. Similarly, you can use the -p and -s options torestrict the search to executable programs and subroutines respectively.

The program uses all the environment variables that a real jBASE program would use. For example, if the

variable JBCOBJECTLIST is not set, it uses the same defaults. If the file JEDIFILENAME_MD is set, it usesthat to resolve Q pointers when looking for files, and to look for jCL scripts when looking for executableprograms.

If duplicates are found, they will be displayed with a warning symbol (DUP!!). This is not always an error, itmay be a "feature" of the development environment. It is up to the developer to determine if the duplicate isexpected or not.

The -v option shows the path that the run-time would take while looking for files, subroutines and executableprograms.

Example 1

Find the exact location where file CUSTOMERS is being opened:

% jshow -f CUSTOMERSFile: /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.

Page 189: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 189/200

Advanced Programmers Reference Manual Advanced Tools12-11

Example 2

Find which shared object the subroutine INITVAR is being loaded from:

% jshow -s INITVARSubroutine: /home2/live/lib/liblive0.soSubroutine (DUP!!): /home2/live/lib/libfb10.so

This example shows that there are two versions of the subroutine INITVAR. The jBASE run-time will alwaysuse the first occurrence, ignoring any subsequent occurrences. The developer should determine if the correct

version is being loaded.

Example 3

The program MAIN is not behaving as expected. Use jshow to gain more information:

% jshow MAINjCL script: /home2/live/MD/MAINExecutable (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. Thereis 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 PIPEFile path: /home2/liveFile path: .File: /home2/live/PIPESubroutine object: main()Subroutine object: /home2/live/lib/liblive0.soSubroutine object: /home2/live/lib/fb1.soSubroutine object: /home2/live/lib/libfb10.soSubroutine object: /usr/jbc3.0/lib/libinternal.so

Subroutine object: /usr/jbc3.0/lib/libutils.soSubroutine object: /usr/jbc3.0/lib/libqueries.soSubroutine object: /usr/jbc3.0/lib/libjpq.soSubroutine object: /usr/jbc3.0/lib/libjrem.soSubroutine object: /usr/jbc3.0/lib/libjconnect.soSubroutine: /home2/live/lib/liblive0.soMD Name: /home2/live/MDExecute path: /usr/jbc3.0/binExecute path: /usr/binExecute path: /usr/merge/dosroot/ubinExecute path: /usr/ccs/binExecute path: /home2/live/toolsExecute path: /usr/local/binExecute path: /opt/bin

Execute path: /home2/live/binExecute path: .Execute path: /usr/ccs/binExecute path: /usr/ucbjCL script: /home2/live/MD/PIPE

Page 190: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 190/200

 

Advanced Tools Advanced Programmers ReferenceManual

12-12

Extended terminfo Capabilities

The ability exists to add extra terminal and printer independent control characters, available to a jBC programusing the @() function. These extensions only apply when the jBC source has been compiled using ROSemulation (by setting the UNIX environment variable JBCEMULATE to ROS).

The standard @(-nn) function utilises entries defined in the UNIX terminfo database for operations such as clear

to end of line, or cursor positioning. However, the extensions to the @(-nn) functionality do not map easily to theUNIX terminfo database.

Therefore, a jBASE utility called 'jtic' exists which will take a description of the terminal and printer capabilities,and create a compiled binary that can be accessed by jBC programs, through the @(-nn) functions.

This program also allows jBASE to work with operating systems that do not support UNIX style terminfocapabilities, such as Windows NT.

Usage of the jtic program, and the format of the description file are very similar to that of the UNIX tic program.

 jtic Program

The jtic program takes a description of the capabilities and creates a binary definition of the file in similarfashion 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 standardterminfo names. The output will be to a file called /usr/lib/terminfo/x/xyz, where x/xyz depends upon theterminal name as contained in the description file.

You can use any alternative description file to terminfo.src by specifying the description file name on thecommand line.

You can specify an alternative output directory to /usr/lib/terminfo by amending the TERMINFO environmentvariable. 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.

 jtic Description File

To run jtic you need a description file to describe the capabilities. This file is very similar to that required by theUNIX tic command. It has the following format:

Comment. Comment lines start with # as the first character of each line. Blank lines are also counted ascomment lines. Example:

# This is just a comment.

Terminal names. This tells jtic the names of the terminal definition. It is a list of names delimited by |

characters. The final field is treated as a comment. Following the terminal names will be the binary definitions,integer values and string values for those terminals. When another set of terminal names are defined, the currentdefinitions are written to file and the current definitions nulled. Example:

vt100|vt100am|prism-ans|Simple vt100 support

Binary definition. These are just the name of the definition. Example:

Page 191: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 191/200

Advanced Programmers Reference Manual Advanced Tools12-13

xon

Integer value. The name of the definition followed by # followed by the value. Example:

cols#132

String value. The name of the definition followed by = followed by the string value. jtic supports all  thefunctionality of tic, such as defining characters 1 to 26 using ^A through ^Z, specials such as \E for escape, \s forspace, \t for tab. It also supports the if/else/endif structure and logical/arithmetic operations supported by tic.Example:

if_prtr_letter=\E[02l,

use=name. Resets the definition to that of a previously defined name in the definition. You can use this to createa terminfo definition for one or more names, and then base subsequent definitions on that. An example of using

this can be found in the source $JBCRELEASEDIR/src/prism. Example:

use=ansi

The comments and terminal names must all start at column 1. The binaries, integers, strings and use=name mustall have a leading tab character. There can be more than one binary, integer or string on a line, and eachdefinition should be delimited by a comma.

Examples of Using jtic

This example shows how, on a UNIX machine, you can get a description file of your current capabilities usinginfocmp, and then use jtic to re-compile that definition. This is for example purposes only, and is actuallymeaningless in the UNIX environment as jBASE uses the UNIX terminfo database for normal terminfodefinitions, rather than the binary that jtic produces.

% infocmp vt100 > vt100.tic% jtic -v vt100.tic

/usr/lib/terminfo/v/vt100_jbase/usr/lib/terminfo/v/vt100-am_jbase

The next example shows a description file with extended capabilities, how to compile the file, and how to accessit using a jBC program. Note the use of the -x option on jtic to create extended capabilities, and the setting of the

JBCEMULATE variable before compiling the source.

% cat lj.ticlj1|lj2| Laser jet stations.#if_prtr_letter=\E[02l,if_prtr_utray=\E[90x,

% jtic -xv lj.tic/usr/lib/terminfo/l/lj1_ext_jbase/usr/lib/terminfo/l/lj2_ext_jbase

% cat prog1.bEXECUTE "TERM lj1"

PRINT "@(-70), if_prpt_letter, = " :SQUOTE(OCONV(@(-70),"MCPU"))

PRINT "@(-76), if_prpt_utray , = " :SQUOTE(OCONV(@(-76),"MCPU"))

% JBCEMULATE=ROS jbc prog1.b -Jo

% ./prog1@(-70), if_prpt_letter, = '^[[02l'@(-76), if_prpt_utray , = '^[[90x'

Extended Capabilities

The table below shows the extended capabilities.

Page 192: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 192/200

 

Advanced Tools Advanced Programmers ReferenceManual

12-14

Note that they are all strings - there are no binaries or integers. Within a jBC program, it is assumed that thestrings are all string constants. This means that they are not passed through the tparm() function for conditionalarithmetic operations and so on.

The first column “Access” shows how to access the capability in a jBC program. The second column “Longname” shows the name to use in the description file that is compiled using the jtic program. The third column“Description” is a description of the effect.

Access Long name Description

@(-53) if_slave_only Send data to slave printer only. No VDT display

@(-54) if_crt_type Returns VDT terminal type

@(-55) if_crt_graphics Returns a 1 if Regis graphics available

@(-59) if_crt_cuprot Clear all unprotected fields

@(-27) if_crt_132 Switch VDT to 132 column mode

@(-28) if_crt_80 Switch VDT to 80 column mode

@(-29) if_crt_dwide Display double wide characters

@(-30) if_crt_swide Display single wide characters

@(-32) if_crt_sron Set-up scrolling region. (Enter ? for help)

@(-33) if_crt_sroff Reset scrolling region to normal

@(-47) if_crt_udhdw Top half of double height line

@(-48) if_crt_bdhdw Bottom half of double height line

@(-60) if_prtr_executive Change paper size to executive

@(-61) if_prtr_a4 Change paper size to A4

@(-62) if_prtr_monarch Envelope type "Monarch"

@(-63) if_prtr_comm10 Envelope type "Commercial 10"

@(-64) if_prtr_interntldl Envelope type "International DL"@(-65) if_prtr_reset Reset printer defaults

@(-66) if_prtr_envfeed Envelope feeder

@(-70) if_prtr_letter Change paper size to letter

@(-71) if_prtr_legal Change paper size to legal

@(-72) if_prtr_chgcpy Change number of copies to print on Laser

Access Long name Description

@(-73) if_prtr_cpwo1 Compressed print for Service WO form 1

@(-74) if_prtr_spcol Start printing at specified column@(-75) if_prtr_sprow Start printing at specified row

@(-76) if_prtr_utray Use Upper Tray

@(-77) if_prtr_ltray Use Lower Tray

@(-78) if_prtr_portrt Portrait orientation

@(-79) if_prtr_land Landscape orientation

@(-80) if_prtr_simplx Simplex binding

@(-81) if_prtr_duplxl Duplex, long edge binding

@(-82) if_prtr_duplxs Duplex, short edge binding

@(-83) if_prtr_macro Call MACRO

@(-84) if_prtr_setdef Set default ( Font size, HMI, VMI )

Page 193: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 193/200

Advanced Programmers Reference Manual Advanced Tools12-15

@(-85) if_prtr_lpi2 2 lines per inch

@(-86) if_prtr_lpi3 3 lines per inch

@(-87) if_prtr_lpi4 4 lines per inch

@(-88) if_prtr_lpi6 6 lines per inch

@(-89) if_prtr_lpi8 8 lines per inch@(-90) if_prtr_lpi12 12 lines per inch

@(-91) if_prtr_dwide Double wide mode

@(-92) if_prtr_swide Single wide mode

@(-93) if_prtr_96 96 column mode

@(-94) if_prtr_pld 1/2 line down

@(-95) if_prtr_plu 1/2 line up

@(-96) if_prtr_suon Superscript mode

@(-97) if_prtr_sbon Subscript mode

@(-98) if_prtr_ssoff Superscript and subscript off

@(-99) if_prtr_40 Double wide for 80 column mode (5 pitch)

@(-100) if_prtr_48 Double wide for 96 column mode (6 pitch)

@(-101) if_prtr_ff Top of form

@(-102) if_prtr_80 80 column mode (10 pitch)

Access Long name Description

@(-103) if_prtr_132 132 column mode (16 pitch)

@(-104) if_prtr_bold Bold

@(-105) if_prtr_ul Underline

@(-106) if_prtr_norm Turn off bold and underline

@(-107) if_prtr_hmi Set horizontal motion index to U-1

@(-108) if_prtr_vmi Set vertical motion index to U-1

@(-109) if_prtr_pson Proportional spacing on

@(-110) if_prtr_psoff Proportional spacing off

@(-111) if_prtr_1key Linefeed and backspace

@(-112) if_prtr_2key Linefeed

@(-113) if_prtr_3key Linefeed and space

@(-114) if_prtr_4key Backspace

@(-115) if_prtr_6key Space@(-116) if_prtr_7key Negative linefeed and backspace

@(-117) if_prtr_8key Negative linefeed

@(-118) if_prtr_9key Negative linefeed and space

@(-119) if_prtr_cvd Coarse vertical distance ( 1 line = 1 inch )

@(-120) if_prtr_mvd Medium vertical distance ( 1 line = 1/6 inch )

@(-121) if_prtr_type Returns slave/printer type

@(-122) if_prtr_fvd Fine vertical distance ( 1 line = 1/48 inch )

@(-123) if_prtr_chd Coarse horizontal distance ( 1 space = 1 inch )

@(-124) if_prtr_mhd Medium horizontal distance ( 1 space = 1/12 inch )

@(-125) if_prtr_fhd Fine horizontal distance ( 1 space = 1/120 inch )

Page 194: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 194/200

 

Advanced Tools Advanced Programmers ReferenceManual

12-16

@(-126) if_prtr_status Retrieve slave/printer device status

Page 195: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 195/200

Page 196: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 196/200

 

Advanced Tools Advanced Programmers ReferenceManual

12-18

The first 2 lines are formatted by the error message ZERO_USED from file $JBCRELEASEDIR/jbcmessages.This message is a warning message because it contains the string ^WARNING^. The debugger is thereforetriggered and the 3rd line is generated by the debugger as it is entered.

A common requirement is to change an error message so that the debugger is not entered when the message isdisplayed. You can achieve this by changing the error message from a warning to a normal message through theED editor:

% ED $JBCRELEASEDIR/jbcmessages ZERO_USEDTOP. <RETURN>001 Invalid or uninitialised variable -- ZERO USED,

^NEWLINE^Var ^VARNAME^, Line ^LINENO^, Source^SOURCENAME^ ^WARNING^

.R/^WARNING^//001 Invalid or uninitialised variable -- ZERO USED,

^NEWLINE^Var ^VARNAME^, Line ^LINENO^, Source^SOURCENAME^

. FIRecord ‘ZERO_USED’ written to ‘/usr/jbc/jbcmessages’

 jmakeerr Command

The jmakeerr command is provided for converting error messages in alternative formats to the format requiredby 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 formatrequired 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 backinto a jBASE system and then use the jmakeerr command as follows:

% SELECT ERRMSG EQ \”USER]\”97 Records selected% jmakeerr ERRMSG \(MOTO: (/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.

Page 197: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 197/200

Advanced Programmers Reference Manual Index19

Index—#— 

# ifdef , 10-7  

#define, 4-16, 10-7 , 10-8 

#endif , 10-7  #include, 4-3, 4-5, 4-6, 4-7, 4-9, 4-10, 4-11, 4-12,

4-13, 4-14, 4-16, 4-17, 4-20, 8-1, 8-5, 10-3, 10-

6, 10-6

—.— 

.b. See file types

.el. See file types

.o. See file types

.profile file, 2-6, 2-7, 2-10, 2-11, 2-12, 3-6, 8-5

.so. See file types

—A— ACCOUNT-RESTORE, 2-5, 2-8ACCOUNT-SAVE, 2-4Ajar. See File Ajar ProcessingAPI calls, 8-1API Calls, 1-4

—B— 

BASIC, 1-3, 1-4, 2-5, 2-10, 3-1, 3-2, 3-3, 3-4, 3-11,5-2, 6-1, 9-1, 10-1, 10-10, 11-2, 11-4, 11-6, 12-6

BASIC Command, 10-9 

—C— 

C Extensions, 1-3, 4-1 C function definition, 4-6

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,11-6, 12-2

calloc, 7-7CATALOG, 1-3, 1-4, 2-5, 2-11, 3-1, 3-4, 3-6, 3-7,

3-8, 3-9, 3-10, 3-11, 5-2, 9-1, 10-9, 11-1, 11-4,12-6

CATALOG Command, 11-6  

cc, 4-3, 7-2, 8-5, 10-1, 10-2, 10-3, 10-4, 10-6, 11-2,11-3

CC, 10-6CHDIR_IB, 4-20, 4-21CLEAR, 7-9, 7-27  CLOSE, 7-9, 7-12, 7-14, 7-16Compiling, 2-10, 3-3, 4-18, 8-5

CONV_FB,  4-13 CONV_FI,  4-12, 4-13 

CONV_IB, 4-5,  4-13 

CONV_IF,  4-13 

CONV_SB,  4-13, 4-14, 4-20

CONV_SFB, 4-6, 4-7, 4-14 CONVLEN_IB, 4-13, 4-20

CONVTYPE_IB,  4-14, 4-15 COPY , 2-9, 3-5, 3-7COUNT_IBB, 4-11

—D— 

Database Drivers, 1-3, 7-1DCOUNT_IBB, 4-9, 4-11, 4-20Debug, 10-5Debugging, 12-8

 DELETE , 2-9, 7-9, 7-26

DELETE-CATALOG, 2-12

—E— 

ED, 3-1, 3-2, 12-17, 12-18ENABLE-LOGONS, 3-9, 3-10

Environment Variables, 8-8, 10-6

EQUATE, 10-7 , 10-8 

ERRMSG, 12-18Error Message File, 12-17  Executable Paths, 1-3Exporting Applications, 2-4 External libraries, 4-1

—F— 

File ajar processing, 7-8File Ajar Processing, 7-5, 7-12, 7-13file types

.b, 3-3, 10-9

.el, 2-11, 3-7, 3-10

.o, 2-11, 3-3, 3-4, 10-3, 10-4, 10-9, 11-3, 11-6,11-7

Page 198: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 198/200

 

Index Advanced Programmers ReferenceManual

20

.so, 2-11, 3-7

FLOAT, 4-3, 4-4, 4-5, 4-11, 4-12, 4-13, 7-22free, 7-7, 7-17, 8-2Function Prototypes, 4-4 

—H— 

HOME, 1-3, 2-6, 2-11, 2-12, 3-2, 3-4, 3-5, 3-6, 3-7,3-9, 3-10, 7-2, 7-3, 8-8, 10-7, 11-4, 11-6, 11-7,11-8, 12-2, 12-5

—I— 

ICONV, 1-3, 4-1, 5-1 ICONV Extensions, 5-1 IJU, 2-7, 3-6Importing Accounts, 2-6  Importing Applications, 2-5 

INCLUDE, 2-10, 6-1, 6-2, 6-3, 6-4, 6-5, 6-7, 6-8,6-9, 10-3, 10-5, 10-6, 10-7, 12-6

INDEX_IBBI, 4-9, 4-11infocmp, 12-13INHIBIT-LOGONS, 3-9, 3-10INIT, 7-9, 7-11, 7-12

INT, 4-2, 4-4, 4-5, 4-6, 4-7, 4-12, 4-13, 7-22, 12-4

INT32, 4-3, 4-4, 4-5, 4-6, 4-7, 4-8, 4-9, 4-10, 4-11,

4-12, 4-13, 4-14, 4-15, 4-20ioctl, 1-3, 6-1, 7-4, 7-31, 8-19IOCTL Function, 1-3, 6-1, 7-1, 7-4, 7-9, 7-12, 7-

22, 7-23, 7-25, 7-31, 8-19

—J—  j1, 1-1, 6-8, 7-1, 12-5 j2, 1-1, 6-8, 7-1, 12-5 jbackup, 1-1, 6-5

 jbc, 1-1, 1-4, 2-10, 3-2, 4-2, 4-3, 4-7, 4-16, 4-18, 6-1, 8-5, 10-1, 10-9, 10-10, 11-2, 11-3, 11-4, 11-5, 11-6, 12-6, 12-13

 jBC, 1-1, 1-3, 4-9 jbc Command, 10-2  jBC Run-time Options, 12-2 JBC.h, 6-1, 6-2, 6-3, 6-4, 6-5, 6-7, 6-8, 6-9JBC_COMMAND_GETFILENAME, 6-1, 6-2 

JBCDEBUGGER, 12-2, 12-8  JBCLIBDIR, 10-6, 10-7JBCLIBFILE, 10-6, 10-7

JBCLOGNAME, 2-6, 2-12JBCOBJECTLIST, 2-12, 3-7, 3-9, 3-10, 7-3, 8-8,

9-3, 11-4, 12-10JBCPORTNO, 2-6JBCPROFILE, 12-5JBCRELEASEDIR, 3-7, 4-3, 4-19, 6-1, 7-1, 7-2, 7-

4, 8-1, 8-5, 10-4, 10-6, 11-8, 12-10, 12-13, 12-

17, 12-18 jBuildSLib, 1-4, 3-7, 4-18, 7-2, 11-7 jBuildSLIb, 11-1 

 jBuildSLib Command, 11-2  jCL, 1-1, 3-6, 12-10, 12-11

 jED, 3-1 jEDI, 1-1, 1-3, 1-4, 2-11, 3-3, 4-20, 6-2, 6-9, 7-1,

8-1, 10-1, 10-9, 11-7, 12-2 jEDI API calls, 8-1  jEDI Database Drivers, 7-1 

 jedi.h, 7-1, 7-4, 7-12, 7-23, 7-25, 8-1, 8-5JEDI_LOCK, 7-7JEDI_LOCK_NOWAIT, 7-7, 7-8JEDI_TRANSLOG_COMMAND_ABORT, 8-4, 8-6JEDI_TRANSLOG_COMMAND_END, 8-6JEDI_TRANSLOG_COMMAND_QUERY, 8-1,

8-4, 8-7JEDI_TRANSLOG_COMMAND_START, 8-6

JEDI_UNLOCK, 7-7, 7-30JEDI_UNLOCK_ALL, 7-7, 7-8, 7-30JediCalloc, 7-7JediClearFile, 7-9, 8-3, 8-21 JediClose, 7-9, 8-3, 8-11 JediDelete, 8-17  JEDIFILENAME_MD, 2-10, 3-6, 8-8, 12-10JEDIFILENAME_SYSTEM, 8-8

JediFileOp, v, 8-3, 8-23 JEDIFILEPATH, 6-2, 7-3, 8-8, 8-9, 8-10, 12-10JediFree, 7-7, 7-17, 7-18, 7-21JediIOCTL, 7-9, 8-3, 8-19 JediLock, 7-9, 8-3, 8-18  JediMalloc, 7-7, 7-15, 7-16, 7-20, 7-23JediOpen, 8-3, 8-8, 8-9, 8-10, 8-15, 8-16

JediOpenDeferred, 8-3, 8-10 JediPerror, v, 8-3, 8-22 

JediReadMalloc, 7-7, 7-21, 7-23JediReadnext, 7-9, 8-3, 8-14 JediReadRecord, 7-9, 8-3, 8-15, 8-18JediRealloc, 7-7JediReinitialise, v, 8-3, 8-8, 8-25 

JediSelect, 7-9, 8-3, 8-12, 8-13JediSelectEnd, 7-9, 8-3, 8-13 JediSelectPtr, 7-15, 7-16, 7-17, 7-18, 7-19, 8-12, 8-

13, 8-14JediStrdup, 7-7JediSync, 7-9, 8-3, 8-20 JediSystemLock, 7-7, 7-12, 7-29, 7-30

JediWriteRecord, 7-9, 8-3, 8-16  

JIOCTL_COMMAND_CONVERT, 6-3, 6-4JIOCTL_COMMAND_FILESTATUS, 6-1, 6-5 JIOCTL_COMMAND_FINDRECORD, 6-7  JIOCTL_COMMAND_HASH_LOCK, 6-9 JIOCTL_COMMAND_HASH_RECORD,6-8  

 jLibDefinition, 11-8

 jLibDefinition file, 2-11JLibECOUNT_IBB, 4-11JLibFOPEN, 7-3

 jLP, 1-1 jmakeerr, 12-17 jmakeerr Command, 12-18   jPMLMsg Command, 12-4  jpp, 10-2, 10-7  

 jQL, 1-1

Page 199: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 199/200

Advanced Programmers Reference Manual Index21

 jrestore, 1-1 jsh, 2-12, 3-5

 jshow, 12-10 

 jsystem.h, 4-3, 4-5, 4-6, 4-7, 4-9, 4-10, 4-11, 4-12,

4-13, 4-14, 4-16, 4-17, 4-20, 7-1, 8-1, 8-5 jtic, 12-12, 12-13, 12-14

 jtic ,Program, 12-12 

—L— 

LD_LIBRARY_PATH, 2-7, 4-19, 8-5, 8-8, 11-4LIBPATH, 4-19, 8-5, 8-8, 11-4Linking, 4-18, 8-5LOCK, 7-7, 7-9, 7-14, 7-23, 7-25, 7-26, 7-29, 8-18LOGOFF, 3-9, 3-10

—M— 

Macro Pre-processor - jpp, 10-7  Macros, 4-11 make command, 9-1

Makefile, 9-1makefiles, 9-1 Makefiles, 1-4malloc, 7-7, 8-2Migration, 1-3

—O— 

OCONV, 1-3, 4-1, 4-12, 5-1, 12-13OCONV Extensions, 5-1 OPEN, 6-1, 6-2, 6-3, 6-4, 6-5, 6-7, 6-8, 6-9, 7-1, 7-

3, 7-5, 7-6, 7-7, 7-8, 7-9, 7-11, 7-16, 7-17, 7-21,

7-22, 7-23, 7-24, 7-25, 8-1, 8-2, 12-6, 12-10

—P— 

PATH, 2-7, 2-11, 3-5, 3-6, 3-9, 9-3, 12-10Performance, 4-1Portability, 4-1

PORTBAS, 2-8, 2-9, 2-10

PROC, 2-1 ProcessAjar, 7-5, 7-12ProcessReopen, 7-5, 7-13Profiling, 12-5 PWD, 8-3, 8-8

—R— 

READ, 6-4, 6-7, 7-1, 7-3, 7-7, 7-9, 7-12, 7-21, 7-25, 7-29, 8-1, 8-15, 8-18, 12-6

READNEXT, 7-1, 7-9, 7-15, 7-17, 7-19, 8-12, 12-6realloc, 7-7, 8-2

Record Locking, 7-7, 7-29, 8-18

register variables, 4-9, 4-16, 4-20

—S— 

security, 2-1, 2-6, 7-11, 12-4

Security, 2-2SELECT, 7-1, 7-9, 7-14, 7-15, 7-17, 7-19, 8-12, 8-14, 12-6, 12-18

SELECTEND, 7-9, 7-15, 7-16, 7-17 , 8-12shared library objects, 2-11, 2-12

SMA save format, 2-4SQL, 1-1, 10-3, 10-5stdio.h, 4-3, 8-1

STORE_BBB,  4-11 

STORE_BBF,  4-11 STORE_BBI,  4-12 

STORE_BBS,  4-12 

STORE_VBB,  4-11, 4-20

STORE_VBF,  4-11 

STORE_VBI, 4-10,  4-12 

STORE_VBS, 4-4, 4-6, 4-10, 4-12, 4-13, 4-15, 4-21

strdup, 7-7, 8-2

STRING, 4-3, 4-4, 4-5, 4-6, 4-7, 4-8, 4-10, 4-12, 4-

13, 4-14, 4-15, 4-21, 7-22

STRING_INITIALISE_REG_VB, 4-10, 4-14, 4-

15, 4-20STRING_INITIALISE_USER_VB, 4-10, 4-14, 4-

21

STRING_MAKE_NEW_VBIS, 4-7, 4-15 

STRING_RELEASE_EXT_VB, 4-10, 4-14, 4-15,4-21

STRING_RELEASE_REG_VB ,  4-15 

STRING_RESIZE_VBI,  4-15, 4-20

SUBROUTINE, 1-3, 2-9, 3-1, 3-4, 4-16, 4-18, 5-1,

5-2, 5-3, 10-10, 11-6, 12-10SYNC, 7-9, 7-34 

—T— 

Terminal Redirection, 12-9 

terminfo, 12-12 Transaction Boundary, 7-8, 8-6

type conversion, 4-5, 4-12 

—U— 

UNIX, 1-1, 1-2, 1-3, 1-4, 2-6, 2-7, 2-11, 3-1, 3-4,4-14, 12-5, 12-12, 12-13

UNIX executable, 3-4user variables, 4-9user-exit, 5-3

—V— 

VAR, 4-3, 4-4, 4-5, 4-6, 4-7, 4-9, 4-10, 4-11, 4-12,

4-13, 4-14, 4-15, 4-17, 4-20VAR_TYPE_FILE, 4-14VAR_TYPE_FLOAT, 4-14VAR_TYPE_FLOAT_INT, 4-14VAR_TYPE_INT, 4-14

VAR_TYPE_SELECT, 4-14VAR_TYPE_STRING, 4-14, 4-16

—W— 

Windows, 1-1, 1-2, 12-12Windows 95, 1-1Windows NT, 1-1, 12-12

Page 200: Advanced Programmers Reference Manual

8/13/2019 Advanced Programmers Reference Manual

http://slidepdf.com/reader/full/advanced-programmers-reference-manual 200/200

 WRITE, 6-7, 7-1, 7-3, 7-9, 7-12, 7-24, 8-1, 12-6


Recommended