Complete #pragma information

=?ISO-2022-JP?B?GyRCOGVGIyEhQDU8IxsoQg==?= (MXJ02154@niftyserve.or.jp)
Tue, 10 Jun 1997 22:20:00 +0900


Rooters,

Here is the first 1/3 of the special keyword reference. All of the #pragma
statements are explained. This is the 1st cut rough draft. Please forgive
me for giving not high enough quality of documentation.

Masaharu Goto

==========================================================================
Reference

This chapter will explain CINT's feature and functionality in alphabetical
order.

==========================================================================
==========================================================================
==========================================================================
$CINTSYSDIR

$CINTSYSDIR is an environment variable that contains name of directory
where CINT is installed.
A user must set CINTSYSDIR environment variable before using CINT.
Cint and makecint refers to files under $CINTSYSDIR at run time.
If $CINTSYSDIR is not properly set, cint and makecint will fail obtaining
platform dependent information or standard header files.
Platform dependent information is stored in $CINTSYSDIR/MAKEINFO and
standard header files exist under $CINTSYSDIR/include directory.

Following examples show how to setup CINTSYSDIR and PATH environment
variables
in UNIX and Windows-NT/95.

Example: UNIX, using either sh,ksh,bash, add following description to .
profile

CINTSYSDIR=[CINTをinstallしたdirectory]
PATH=$PATH:$CINTSYSDIR
MANPATH=$MANPATH:$CINTSYSDIR/doc
export PATH CINTSYSDIR MANPATH

Example: UNIX, using csh, add following description to .login

setenv CINTSYSDIR [CINTをinstallしたdirectory]
setenv PATH ($PATH $CINTSYSDIR)
setenv MANPATH ($MANPATH $CINTSYSDIR/doc)

Example: Windows-NT/95, add following description to AUTOEXEC.BAT

SET CINTSYSDIR=C:\CINT
SET PATH=%CINTSYSDIR%;%PATH%

==========================================================================
$CINTSYSDIR/G__ci.h

G__ci.h is a header file for CINT API.
G__ci.h must be included when using CINT API in a precompiled library.
-I$CINTSYSDIR option must be given to makecint when including G__ci.h.

Example:

$ makecint -mk Makefile -o src -H src.h -C++ src.cxx -I$CINTSYSDIR
$ make -f Makefile

// src.h /////////////////////////////////////////////////////////////
#include "G__ci.h" // G__ci.h must be included
void f();

// src.cxx /////////////////////////////////////////////////////////////
#include "src.h"
void f() {
G__loadfile("mysrc.C"); // API function is used
}

==========================================================================
$CINTSYSDIR/MAKEINFO

$CINTSYSDIR/MAKEINFO is an ASCII file containing platform dependent
information.
$CINTSYSDIR/MAKEINFO is created at installation by setup script.
It is important to have appropreate MAKEINFO file because cint and makecint
refers to this file at run time for following information.

* Name of C/C++ preprocessor command is obtained from MAKEINFO if -p or +P,
-P
command line option is given to cint and makecint. Preprocessor command
is set to CPREP (in case of C) and CPPPREP (in case of C++).

* MAKEINFO is copied as header part of Makefile when running makecint.
Makecint will add application specific description after that.

* CHDRPOST, CPPHDRPOST, CSRCPOST, CPPSRCPOST, DLLPOST variables in MAKEINFO
are refered by makecint and cint with -c[-1|-2] option. These variables
determines file extension of header, source and DLL files.

SEE ALSO:
platform dependency file.

==========================================================================
$CINTSYSDIR/src/Api.h

$CINTSYSDIR/src/Api.h contains definision of CINT ERTTI(Extensive Run Time
Type Identification).
Api.h must be included when ERTTI API is used in a precompiled library.
-I$CINTSYSDIR and -I$CINTSYSDIR/src must be given to makecint when doing
this.

SEE ALSO:
ERTTI

==========================================================================
#pragma

ANSI C/C++ standard defines #pragma as a mean to implement platform
dependent
functionality.
CINT defines several #progma statement to implement special functionality.

A user can define new #pragma statement by using G__addpragma() API.

SEE ALSO:
G__addpragma()

==========================================================================
#pragma ANSI

#pragma ANSI statement can be used in a parameter information file (=
header
file given to makecint by -h and -H option).
#pragma ANSI will force subsequent function prototypes to be registered as
ANSI C/C++ style function in a precompiled library.
Usually #pragma ANSI is not necessary because this is a default state.
#pragma ANSI is only necessary after #pragma K&R.

SEE ALSO:
#pragma K&R

==========================================================================
#pragma autocompile [on|off]

#pragma autocompile statement will turn on/off effect of #pragma compile
statement. Default is on.
If '#pragma autocompile off' appears in a source file, #pragma compile and
#pragma endcompile statements are ignored.

SEE ALSO:
#pragma compile

==========================================================================
#pragma bytecode

Functions enclosed by '#pragma bytecode' and '#pragma endbytecode' will
be compiled to a bytecode at loading time.
These functions are accelerated especially when they are called multiple
times in a loop.
This feature is experimental and premature.
Bytecode function has to comply following limitations.
+ must be 80 lines or less
+ must not have class/struct object as local variable or parameter
+ must not have reference type variable as local variable or paramter
+ may be a little slower if a bytecode function contains big loop.
These limitations will be cleared in future revision.

Example:

#pragma bytecode
// Compile a function to bytecode that is called multiple times in a loop
int BytecodeFunc(char *s,double d) {
int result;
result = sprintf(s,"BytecodeFunc %g\n",d);
return(result);
}
#pragma endbytecode

// function containing big loop may be faster without #pragma bytecode
int InterpretedFunc() {
int result;
for(int i=0;i<1000;i++) {
result += i;
}
return(result);
}

main() {
char buf[100];
for(int i=0;i<100;i++) {
BytecodeFunc(buf,i*1.2);
printf("%s\n",buf);
}
printf("%d\n",InterpretedFunc());
}

==========================================================================
#pragma compile

Source code that is enclosed by '#pragma compile' and '#pragma endcompile'
will be compiled as native code and dynamically loaded.
A user can enjoy native code performance in an interpreted source file.
This feature is only available with DLL or shared library capability of
the operating system.
makecint will be implicitly used.
Source code surrounded by '#pragma compile' and '#pragma endcompile' must
be a complete C or C++ source.
Multiple pairs of '#pragma compile' and '#pragma endcompile' can be used.
CINT must be installed with C/C++ compiler to utilize #pragma compile
statement.

Example: In example below, loop() function will be compiled to a native code.

/* auto.c */
main(int argc,char **argv) {
loop(atoi(argv[1]));
endfunc();
}

# pragma compile /* following part is compiled */
int sum=0;
loop(int num) {
int i=0;
for(i=num;num>0;num--) sum += num;
}
#pragma endcompile

endfunc() {
printf("end of execution sum=%d\n",sum);
}

==========================================================================
#pragma endbytecode

Refer to #pragma bytecode

==========================================================================
#pragma endcompile

Refer to #pragma compile

==========================================================================
#pragma eval [expression] ;

[expression] is evaluated whenever this line is parsed.
Do not use this statement. This statement exists for debugging CINT only.

==========================================================================
#pragma if defined([macro])
#pragma ifdef [macro]
#pragma ifndef [macro]
#pragma elif defined([macro])
#pragma endif

#pragma if, ifdef, ifndef, elif and endif statements behaves the same as
ordinary #if,#ifdef, #ifndef,#elif and #endif preprocessor statements.
If -p or +P,-P command line option is given to cint or makecint, source and
header files are processed by C/C++ preprocessor prior to the interpretation.
In such case, #pragma if,ifdef, ifndef, elif and endif statements are
ignored
in the preprocessor and left for cint to handle.
An ordinary user does not need to use these statements often.

==========================================================================
#pragma include "[DLL]"

#pragma include statement behaves the same as ordinary #include statement.
It is recommended to use #pragma include when loading DLL(Dynamic Link
Library)
in source file.
If -p or +P,-P command line option is given to cint or makecint, source and
header files are processed by C/C++ preprocessor prior to the interpretation.
In such case, #pragma include statement is ignored in the preprocessor and
left for cint to handle.
So, use #pragma include whenever you do not want include file to be
processed
by C/C++ preprocessor.

Example: Following example loads DLL fft.dl in source file.

#include <stdio.h>
#pragma include <fft.dl>

main() {
...
}

==========================================================================
#pragma includepath "[path]"

#pragma includepath statement add header file include path.
It has the same effect as giving -I[includepath] command line option.
#pragma includepath statement accepts one path name at a time.
If you have multiple include pathes to add, you need multiple #pragma
include statements.

Example: Following example adds /home/proj/include and /usr/myinclude as
include
pathes.

#pragma includepath "/home/proj/include"
#pragma includepath "/usr/myinclude"
#include <mylib.h>


==========================================================================
#pragma K&R

#pragma K&R statement turns off parameter checking of precompiled functions.
Function parameter types are usually checked when calling precompiled
functions.
Parameter type checking is turned off for functions declared after
#pragma K&R statement in parameter information file (header file given to
makecint by -h or -H option).
There are such library that depends on the old K&R compiler does not check
parameters and calls function only by name matching.
#pragm K&R is introduced to support such library emulating K&R style
programming.
The K&R mode is active until #pragma ANSI statement appears.
#pragma K&R and #pragma ANSI statement can only appear in parameter
information files.

Example: Giving following prog.h to makecint with -c-2 option, f1() and f3()
are
handled as ANSI function. Parameter types will be checked at run time.
For f2() which is surrounded by #pragma K&R and #pragma ANSI, parameter
type checking is omitted when it is used in an interpreted source code.

$ makecint -mk Makefile -o obj -h prog.h -C prog.c

/* prog.h */
#ifdef __CINT__

long f1(int a,double b);
#pragma K&R
unsigned short f2();
#pragma ANSI
int f3(short c,float d);

#else

long f1();
unsigned short f2();
int f3();

#endif

==========================================================================
#pragma link [C|C++|off] all [class|function|global|typedef];
#pragma link [C|C++|off] [class|function|global|typedef] [name];

#pragma link statement selectively turns on/off symbol table registeration
of classes, global functions, global variables and typedefs.
All of the classes, global functions, global variables and typedefs are
registered to the symbol table by default.
A user can turn the registeration on/off by using '#pragma link' statement.
#pragma link statement can only appear in parameter information file which
is given to makecint with -h or -H option. (or given to cint with -c-1 or
-c-2 option)
If used with -h option of makecint (or -c-2 option of cint), only
'#pragma link C' and '#pragma link off' can be used.
If used with -H option of makecint (or -c-1 option of cint), only
'#pragma link C++' and '#pragma link off' can be used.

Example: In following example, symbol table registeration of classes,
functions,
global variables and typedefs are once turned off by '#pragma link off ...'
statements. Then registeration of selected class, function, global variabl
and typedef are turned on by '#pragma link C++ ...' statement.

$ makecint -mk Makefile -o obj -H myprog.h -C++ myprog.C

/* myprog.h */
class A { };
class B { };
class C { };
double f1();
A f2();
B f3();
A i;
double d;
short s;
typedef int Int_t;

#pragma link off all class;
#pragma link off all function;
#pragma link off all global;
#pragma link off all typedef;
#pragma link C++ class B;
#pragma link C++ function f2;
#pragma link C++ global s;
#pragma link C++ Int_t;

==========================================================================
#pragma preprocess [filename_prefix]

Cint normally reads source file directly. This is called one-path
processing. The one-path processing has some limitation in define macro.
To eliminate define macro limitations, a user sometimes needs to use
official C/C++ preprocessor prior to interpretation. Invokation of the
C/C++ preprocessor is done automatically by cint.
#pragma preprocess specifies that include files start with
[filename_prefix] should be processed by C/C++ preprocessor before cint
reads them.

Example: In following example, include files start with X11/X go through
preprocessor than read by cint. myheader.h is directly read by cint.

#pragma preprocess X11/X
#include "X11/Xlib.h"
#include "X11/Xutil.h"
#include "myheader.h"

SEE ALSO: -p option, +P,-P suboption, one-path processing,
two-path processing, preprocessor statements

==========================================================================
#pragma preprocessor [on|off]

Cint normally reads source file directly. This is called one-path
processing. The one-path processing has some limitation in define macro.
To eliminate define macro limitations, a user sometimes needs to use
official C/C++ preprocessor prior to interpretation. Invokation of the
C/C++ preprocessor is done automatically by cint.
Include files which are enclosed by '#pragma preprocessor on' and
'#pragma preprocessor off' are preprocessed by C/C++ preprocesso prior to
interpretation.

Example: In following example, only myheader2.h and myheader3.h are
processed by
C/C++ preprocessor. myheader1.h and myheader4.h are directly read by cint.

#include <stdio.h>
#include "myheader1.h"
#pragma preprocessor on
#include "myheader2.h"
#include "myheader3.h"
#pragma preprocessor off
#include "myheader4.h"

SEE ALSO: -p option, +P,-P suboption, one-path processing,
two-path processing, preprocessor statements

==========================================================================
#pragma security [level0-5]

#pragma security statement sets security and robustness mode of cint.
Security mode is normally set by -q[levelN] command line option.
-q option can set only one security level for all of the source files
given to cint.
Using #pragma security statement in source file enables having different
security level in different source file.
#pragma security statement can appear only once at the begenning of source
or header file.

Example: In following example, security level1 is set to prog1.c. Casting to
a
pointer is prohibited. Security level0 is set to prog2.c to allow casting
to pointer from long integer.

$ cint -qlevel1 prog2.c prog1.c

/* prog1.c */
#pragma security level1
void main() {
void *p = f2(0x4152368);
}

/* prog2.c */
#pragma security level0
void* f2(long l) {
return((void*)l);
}

SEE ALSO: security mode

==========================================================================
#pragma setertti

#pragma setertti will setup symbol table for Extensive Run Time Type
Identivication API. This is a special statement which only appears in
$CINTSYSDIR/ertti.h header file. Ordinaly user should not use this statement.

==========================================================================
#pragma setstdio

#pragma setstdio will setup starnderd I/O file pointers in the interpreter
environment. This is a special statement which only appears in
$CINTSYSDIR/stdio.h header file. Ordinaly user should not use this statement.

==========================================================================
#pragma setstream

#pragma setstream will setup symbol table for iostream library in the
interpreter environment. This is a special statement which only appears in
$CINTSYSDIR/iostream.h header file. Ordinaly user should not use this
statement.

==========================================================================
#pragma stub [C|C++|off] all functions;
#pragma stub [C|C++|off] function [name];

#pragma stub statement registers specified function as STUB function in
a precompiled library. This statement can only be used in parameter
information file.
It is usually unnecessary to use this statement because -i and -i++
command line option of makecint provide the same functionality.

==========================================================================
__CINT__

__CINT__ is a macro which is internally defined within cint interpreter.
This macro can be used to distinguish cint from other C/C++ processing
system. __CINT__ can not be disabled by #undef statement.

Example:

#ifdef __CINT__
#pragma include "myprog.dll"
#else
#include "myprog.h"
#endif

==========================================================================
__MAKECINT__

__MAKECINT__ macro is defined when processing parameter information files.
__MAKECINT__ macro is explicitly given to 'cint -c[-1|-2]' from command line.
This macro can be used to distinguish makecint from other C/C++ processing
system.

Example:

#ifdef __MAKECINT__
#pragma link C++ function myfunc;
#endif

SEE ALSO: parameter information file

==========================================================================
==========================================================================
==========================================================================
ANSI style function header

cint can read both ANSI and K&R style function header.
Cint does run-time parameter type checking for ANSI style function.
K&R style function is called with simple function name match.
ANSI style function is called only if type of parameter matches to
C++ function overloading rule.
If a function with no parameter is declared as f() it is regarded as
K&R style. ANSI style funciton must be explicitly declared as f(void).
Hence, f1() and f2() in following example behaves differently.

Example:

int f1() {} // interpreted as K&R style function
int f2(void) {} // interpreted as ANSI style function

main()
{
f1(1); // call f1() successfully
f2(1); // No match to f2(int), ERROR
}

==========================================================================
archived library

Archived library is a kind of precompiled library which is archived with
cint core as monolithic executable file.
Archived library contains following components.

* user program
* interface method to the user program
* interface method start-up program $CINTSYSDIR/main/G__setup.c
* interpreter core, $CINTSYSDIR/src/G__ci.a
* main() function

Interface method registers symbols in user program to cint symbol table.
It is automatically generated by makecint or 'cint -c[-1|-2]'.
User program must not include main() function because cint main() function
$CINTSYSDIR/main/G__cppmain.o is linked by default.
You must give -m option to makecint if you want to use different main()
function.
In this case, cint must be explicitly initialized by G__iniy_cint() API.

SEE ALSO: DLL, precompiled library, G__init_cint()

==========================================================================
==========================================================================
==========================================================================
cint

When written in lower case letter "cint", points C/C++ interpreter object.
Executable object $CINTSYSDIR/cint is a default C/C++ interpreter which only
includes ANSI C standard library and C++ iostream library.
You can create derivertive of cint by using makecint.
These derivartives have different name, however, same user inferface as cint.

==========================================================================
CINT

When written in all upper case letter "CINT", points entire cint/makecint
system.

==========================================================================
CINTSYSDIR

REFER to $CINTSYSDIR

==========================================================================
==========================================================================
==========================================================================
debugger interface

cint is not only an interpreter but also a source code debugger.
cint's debugger interface provides full set of debugger capability,
like step execution, break point, stack trace, source code trace, class
and function browsing, etc...
Debugger interface is invoked at following occasion.

* When main() function is not found in given source files
* When cint is invoked with step mode command line option -S,-s
* Break point event
* Keyboard interrupt by CTL-C or Break key
* When debugger interface function G__pause() is called explicitly
* Bus error, segmentation violation

SEE ALSO: G__pause() , G__atpause , debugger usage

==========================================================================
debugger prompt

Debugger prompt is a command prompt displayed by debugger interface.
It usually looks as follows,

FILE:xyz.C LINE:16 cint>

SEE ALSO: debugger interface, G__pause(), G__atpause, debugger usage

==========================================================================
DLL(Dynamic Link Library)

DLL(Dynamic Link Library) is a kind of precompiled library which can be
dynamically linked/unlinked with cint at run time.
DLL can be linked in the same way as you load source file.
DLL module has to have file extension .dl .dll .DLL .sl or .so because cint
distinguishes between source file and DLL by file extension.
DLL module contains following components.

* user program
* interface method to the user program

Interface method registers symbols in user program to cint symbol table.
It is automatically generated by makecint or 'cint -c[-1|-2]'.

In UNIX environment, DLL is implemented by shared library management
routine.
If operating system does not have shared library facility, DLL feature of
CINT can not be used. Precompiled library can be embedded only as archived
library in that case.
In Windows-95/NT, CINT utilizes Windows API to link DLL.

CCDLLOPT, LDDLLOPT, LDOPT, SYSMACRO and DLLPOST variables in
$CINTSYSDIR/MAKEINFO must be setup properly to use DLL.
There are currently following combination of SYSMACRO setting.

SYSMACRO = -DG__SHAREDLIB -DG__OSFDLL
Use OSF compliant dlopen(), dlsym(), dlclose() or emulated
version.

SYSMACRO = -DG__SHAREDLIB -DG__HPUXCPPDLL
Use HP-UX cxxshl_load(),shl_findsym(),cxxshl_unload()

SYSMACRO = -DG__SHAREDLIB
Use HP-UX shl_load(),shl_findsym(),shl_unload()

SYSMACRO = -DG__SHAREDLIB -D_WINDOWS
Use Win32 API LoadLibrary(),GetProcAddress(),FreeLibrary()

SEE ALSO: interface method, precompiled library

==========================================================================
==========================================================================
==========================================================================
ERTTI(Extensive Run Time Type Identification)

CINT's ERTTI (Extensive Run Time Type Identification) is a special
enhancement requested by Rene Brun and Fons Rademakers in CERN(European
Laboratory for Particle Physics).
ERTTI API consists of 8 classes, which is an interface to C/C++ interpreter
symbol table.
ERTTI API classes can be used both in interpreter environment and
precompiled
library.
<ertti.h> must be included to use ERTTI in interpreter environment.
-I$CINTSYSDIR/src and -I$CINTSYSDIR option must be given from command line
and <Api.h> must be included to use ERTTI in precompiled library.

See alos to explanation about following ERTTI API classes.

G__ClassInfo
G__BaseClassInfo
G__DataMemberInfo
G__MethodInfo
G__MethodArgInfo
G__TypeInfo
G__TypedefInfo
G__CallFunc

Every ERTTI class has member function 'long Property()'. This function
returns
property of concerned symbol as combination of following bit patter.

#define G__BIT_ISTAGNUM 0x0000000f
#define G__BIT_ISCLASS 0x00000001
#define G__BIT_ISSTRUCT 0x00000002
#define G__BIT_ISUNION 0x00000004
#define G__BIT_ISENUM 0x00000008
#define G__BIT_ISTYPEDEF 0x00000010
#define G__BIT_ISFUNDAMENTAL 0x00000020
#define G__BIT_ISABSTRACT 0x00000040
#define G__BIT_ISVIRTUAL 0x00000080
#define G__BIT_ISPUREVIRTUAL 0x00000100
#define G__BIT_ISPUBLIC 0x00000200
#define G__BIT_ISPROTECTED 0x00000400
#define G__BIT_ISPRIVATE 0x00000800
#define G__BIT_ISPOINTER 0x00001000
#define G__BIT_ISARRAY 0x00002000
#define G__BIT_ISSTATIC 0x00004000
#define G__BIT_ISDEFAULT 0x00008000
#define G__BIT_ISREFERENCE 0x00010000
#define G__BIT_ISDIRECTINHERIT 0x00020000
#define G__BIT_ISCCOMPILED 0x00040000
#define G__BIT_ISCPPCOMPILED 0x00080000
#define G__BIT_ISCOMPILED 0x000c0000
#define G__BIT_ISCONSTANT 0x00100000
#define G__BIT_ISVIRTUALBASE 0x00200000
#define G__BIT_ISPCONSTANT 0x00400000

==========================================================================
ertti.h

ertti.h is a header file which must be included to use ERTTI API in
interpreter environment.

SEE ALSO: ERTTI

==========================================================================
==========================================================================
==========================================================================
file extention

cint recognizes following file extensions. cint does not check file
extension strictly except for DLL.

* C/C++ header file
.h .H

* C++ header file
.hxx .HXX .hpp .HPP

* C source file
.c

* C++ soruce file
.C .cc .CC .cxx .CXX .cpp .CPP

* DLL (Dynamic Link Library)
.dl .dll .DLL .sl .so

==========================================================================
==========================================================================
==========================================================================
G__[????]

CINT reserves symbol name starts with 'G__'. Symbol name start with G__
must not be used. It may cause name conflict.

==========================================================================
G__addpragma()

void G__addpragma(char *comname,void (*p2f)(char*));

G__addpragma() API adds user defined #praga statement to cint parser.
It takes command keyword followed by #pragma and pointer to callback
function. The callback function must take string argument (char*).
String given to matching #pragma statement is given to the callback function
as argument.
G__addpragma() API can be used only in compiled program.
WildC++ interpreter , merger of CINT and Tcl/Tk, is implemented using
this API.
(Refer to $CINTSYSDIR/lib/WildCard or $CINTSYSDIR/lib/wintcldl directory)

Example: Embedding MyCmd.c as precompiled library will add '#pragma
MyCommand'
statement in the cint parser.
-B command line option of makecint registers user specific initialization
routine.
When interpreting Example.C using MyCmd C/C++ interpreter, MyCallBack()
function should parse lines between '#pragma MyCommad' and
'#pragma endMyCommand'.

$ makecint -mk Makefile -o MyCmd -h MyCmd.h -C MyCmd.c -B MyCommandInit
$ make
$ MyCmd Example.C

/* MyCmd.c */
#include <stdio.h>
void MyCallBack(char *args) {
printf("MyCommand callback with argument %s\n",args);
/* source file must be parsed here */
}
void MyCommandInit() {
G__addpragma("MyCommand",MyCallBack);
}


/* MyCmd.h */
void MyCallBack(char *args);
void MyCommandInit();


// Example.C
main() {
// C/C++ statements here
// This part is given as callback function argument
// |
// -----------
#pragma MyCommand abc def efg
This part is parsed by MyCallBack function.
#pragma endMyCommand must be detected by the callback function.
#pragma endMyCommand
// Back to C/C++ statement
}

==========================================================================