If several users wish to develop QA Build programs on the same database, they must ALL use the −share command tail on PROGMAKE.
Programs are locked by PROGMAKE to prevent two users concurrently updating the same program. A program is unlocked when the user selects a new program name or exits from PROGMAKE.
When QAB programs are compilied on Unix the maximum program size will be 64K. This means that your programs may not execute on 16 bit operating systems unless you build a custom version of PROGRUN. Specify the command tail -size 42000 if you want your QAB programs to be able to execute using the standard progrun on MS-DOS or other 16 bit operating systems.
Up to release 4.523 you can convert DP4 DOS application programs that are operating system-independent (explained below) by using the EXE2UNIX utility. EXE2UNIX is not supported from release 4.525 (because 4.525 uses ELF only facilities for communicating with the DP4 database manager). EXE2UNIX needs a special, compiler-specific, dummy file. For example, when using Metaware High C, you use HCDUMMY.UNX. Not all versions of Unix support programs built this way, and it is very difficult to debug such programs on Unix, so you are recommended to compile a "native" version of your application whenever possible.
With the .EXE version of the application program and the dummy file in the current directory, the application can be converted with the following command line (this can be done wither on DOS or Unix):
exe2unix program.exeEnsure that the resulting file is set with the 'x' access mode when installed.
OS-independent programs must be compiled as small model programs and linked using the DP4 "root" module, xxroot2.obj, where xx represents the compiler used.
The DP4 Unix C library ccown.a, which is installed in the lib subdirectory of your DP4 install directory, contains the modules required to support the development of application programs written in DP4 C. (From release 4.525 and on Linux ccown.a is in fact a linker script that causes a number of other libraries to be seached.) You should install the appropriate DP4 C library package for your version of Unix. The QAB libary is ccqab.a or ccqabd.a for the debug version.
The easiest way to compile and link a program with one or more of these libraries is to add the full name of the library to the command line, not to try using the -l option. For example cc -o test test.c $DATAFIT/lib/ccown.a will compile and link a program test from test.c and the DP4 C library. If you leave the DP4 C libraries and headers in their default locations you will need to use the -I option, and from 4.525 the -L option:
The command given above for 4.525 causes the location of the DP4 shared libraries to be hard coded into the executable, which you may or may not consider to be desirable. If you want to avoid this happening copy the DP4 .so files from the bin subdirectory of your DP4 installation into the directory where you are building your program. The libraries will then be loaded from the current directory so the path won't be in the executable. In this case you will need the LD_LIBRARY_PATH environment variable to point to the appropriate location at run time.
Don't use C++ style comments in C programs. It's not valid C (at least not unless you have ISO C99) and some Unix C compilers reject them.
Include standard headers such as stdlib.h before DP4 header files. This gives DP4 a chance to undo any damage done by the standard header files.
Try not to use OS specific functions (such as WIN32 APIs) in C programs. If you have to then put OS specific stuff in separate modules, or inside #if defined(WIN32) sections so that you can port programs more easily.
There are special considerations when running on non Intel hardware. If you are ever asked to port programs to non Intel Unix, be very careful before agreeing. DP4 Programs designed to be object code portable, and which only access DP4 databases (not other files) are usually portable, other programs will need modification. Until you have a good understanding of the differences between Intel and SPARC chips your program will probably have non portabilities in it - especially if it casts pointers from one type to another.
The Unix program cc allows you to compile, link and assemble using one command. cc examines the input file extension and executes the appropriate code to process the file, as in:
cc test.c
Compile and link the C module
cc test.o
Link the object module
cc test.s
Assemble and link the assembler module
On some machines the C compiler may be called gcc or c89 rather than cc, or there may be several C compilers and the best one to use for DP4 may not be cc itself. There is almost always an environment variable CC which contains the name of the C compiler.
Although you can compile and link in one step we recommend using the Unix make program to build C programs. This allows you to construct a file showing exactly how each program in a system is built and what other files it depends on.
The C compiler normally accepts a large number of options which affect its behaviour. It is a good idea to use the environment variable CFLAGS to store the flags needed for a particular version of Unix. This avoids you having to store this value in make files, shell scripts etc. Our practice is to create a single shell script for each platform, always called startup.sh, which contains appropriate definitions of these and other similar variables used in building C programs. This allows us to build programs the same way on all platforms, using the same make file on all platforms. Porting DP4 to a new version of Unix is then almost as simple as creating the new version of the startup.sh file.
Prior to release 4.525, DP4 does not support use of multi-threading. If an application uses the pthreads library it must provide its own mechanism to ensure that at most one thread is inside the DP4 libraries, and save and restore DP4 global variables as required.
In 4.525 DP4DBAPI applications can multi-thread providing they set use_pthreads=1 in the [progname] section of dp4.ini. See documentation of the UNIX section in the Guide to DP4 Configuration for details. Please note that at the time of writing the use of multi-threading has not actually been tested on Linux/Unix, though the 4.525 DP4 libraries are almost source code identical to the Windows 4.621 release, which has been tested with multi-threading. Applications using the traditional DP4 C library should probably never use pthreads, unless only one thread calls DP4 functions, because this library makes such heavy use of global variables.
The use of fork() is also supported. A forked process should obtain a new connection to the database manager and re-open any databases it needs. Using fork() is potentially more efficient than using threads, because each process has its own queue into the DP4 database manager, whereas with threads all threads share a single queue.
On Intel processors DP4 C programs may require data to be packed on single byte boundaries, as this is the way the data is stored on the database, and historically, Intel processors were always able to access data efficiently however it is aligned. This can cause problems when compiling DP4 C.
#include <stdio.h>
int main()
{
struct FRED
{
char dummy;
double data;
} fred;
printf("%d\n",sizeof(fred));
}
|
The program will print out 9 if data is packed on 1 byte boundaries. Otherwise it will print out a value between 10 and 16 depending on how data is aligned. For a compiler to work with DP4 you must be able to find some method of compilation that causes the answer to be 9. (This is not the case on non Intel processors where DP4 can cope with data that is aligned on larger boundaries.)
On some versions of Unix System header files and libraries may misbehave with programs compiled with the Zp1 option or the #pragma pack(1) option.This problem has been observed on several different platforms including SCO Unix and Linux. If possible use the #pragma pack(1) option rather than Zp1, and include any non DP4 header files before the DP4 header files. If you do this you can set the pack() pragma only after the System header files have been included.
If you use number system 9 the data in your program will be aligned so that it satisfies all alignment restrictions. Nevertheless you must still compile in a way that forces single byte alignment. The reason for this is that where tables contains fields with roles the compiler may otherwise insert additional unecessary padding bytes to round up the aggregate size of the group of fields with a particular role, but the DP4 program MAKELINK does not.
From release 4.525 the standard DP4 include files and the header files generated by LIBMAKE contain appropriate calls to #pragma pack, so there should be no longer be any need to add your own #pragma pack calls.
MS-DOS filenames can have an eight character filename and a three character extension. Windows 95 and NT allows long filenames but no distinction is made between upper and lower case characters. The separator (.) between the filename and extension is implied, not explicit.
Unix filenames are also long. A distinction is made between upper and lower case characters in Unix. A period (.) is often used as a separator to show name and type, for example "hello.c", but in this case (.) is simply one of the characters in the filename. It is not uncommon to see files on Unix with several "suffixes" (as the part of a filename beginning with a dot is known).
Directories are separated with a forward slash (/) in Unix, but with a back slash (\) in DOS and Windows (though in fact a forward slash also works). This can cause minor problems with the shell where entering a back slash causes the next character to be taken as a literal, so that deleting an unintentionally typed back slash may require you to hit the backspace key several times.
When copying files between DOS and Unix, or when porting applications, you should be aware of these considerations. One point worth remembering is the padding of names with spaces when moving applications from DOS to Unix.
DP4 file-access functions, such as tf_open() and tf_check() , convert the filename argument to lower case before attempting to access the file you cannot access a file with a name containing upper case letters using dp4 functions. The following example illustrates the use of these functions, and why filenames must, when converted from DOS to Unix, never end with spaces. Suppose example1.txt exists as a file in the current directory, and NAMES is a table, containing a field called file_name defined as a character field twenty characters long.
This record exists on the database:
NAME_INDEX = 1
FILE_NAME = "example1.txt "
The C program extract is:
names.name_index = 1; if (ftchprm(EQUAL,&names.l)) ... if (tf_check(names.file_name)) ... |
Under MS-DOS, the file is found because the filename is restricted to 12 characters.
Under Unix, "example1.txt" is not found using release 4.523 or earlier because Unix includes the eight spaces at the end of the filename and looks for "example1.txt ". From release 4.525 Unix/Linux DP4 automatically strips trailing spaces from filenames. The Windows version of DP4 does not need to strip trailing spaces from filenames, because the operating system does this itself.
On most versions of Unix and Linux you can debug programs by compiling them with the -g option. You can debug at a source code level using a program such as sdb or gdb (the name will depend on the version of Unix/Linux and the C compiler you are using). It is worth remembering that if you use only ANSI and DP4 C APIs your program should be completely portable, so that you may be able to debug it on another platform if you prefer. For example we often debug problems reported in the Unix version of DP4 by reproducing them in the Windows version and debugging with Visual C++.
If you want to put diagnostics into a DP4 program you may find it more convenient to use sprintf() followed by showc(), or fprintf() than printf(). If you use printf() your diagnostics may interfere with terminal manager output, or be interfered with by it.
A quick and dirty method of narrowing down the area of a program where a problem occurs is to insert calls sys_request(2,a,b) where a and b are numbers that identify where you are in the program.