Linking ncurses with root

Hi there,
I’m trying to create a custom root interpreter that gives me access to
the ncurses functions. I have succesfully linked a simple class object
with the interpreter and accessed the class from within ROOT, so I know
my principle approach works. I have used the general procedure
described at hep.phy.uct.ac.za/root_tree/CintGenerator.html . See
my other post in the cint mailing list for further details.

I am now trying to do the same with ncurses. I fail when running rootcint
on the header file: “rootcint mydict.C -c /usr/include/ncurses.h” gives me
lots of errors:

Error: Symbol __BEGIN_DECLS#include is not defined in current scope /usr/include/sys/types.h:35:
Error: Symbol bits is not defined in current scope /usr/include/sys/types.h:35:
Error: Symbol types is not defined in current scope /usr/include/sys/types.h:35:
Error: Failed to evaluate types.hError: operator ‘/’ divided by zero /usr/include/sys/types.h:35:
Error: Symbol #ifdef__USE_BSD#ifndef__u_char_definedtypedef__u_charu_char is not defined in current scope /usr/include/sys/types.h:35:
Error: class,struct,union or type __u_short not defined /usr/include/sys/types.h:36:

and so on. I have then tried to add the switch “-p”, which gives me:

rootcint mydict.C -c -p /usr/include/ncurses.h

Error: link requested for unknown class ncurses G__auto17498LinkDef.h:7:
Warning: Error occurred during reading source files
Warning: Error occurred during dictionary source generation
!!!Removing mydict.C mydict.h !!!
Error: rootcint: error loading headers…

Any clue ?

Thanks in any case (and a happy new year !).

Best Regards,
Ruediger Berlich

Hi Ruediger,

Try the following:

root [0] .L /usr/lib/libcurses.so root [1] .L /usr/include/ncurses.h+ root [2] _win_st aa
Rene

Dear Rene,
first: a happy new year :slight_smile:

This is what happens (SuSE Linux 10.0 system, freshly compiled root 5.08,
ncurses 5.4):

root [0] .L /usr/lib/libncurses.so
root [1] .L /usr/include/ncurses.h+
Warning in : /usr/include is not writeable!
Warning in : Output will be written to /tmp
Info in TUnixSystem::ACLiC: creating shared library /tmp//usr/include/ncurses_h.so
/tmp//usr/include/fileQGtiKL.cxx: In function ‘int G__fileQGtiKL__9_76(G__value*, const char*, G__param*, int)’:
/tmp//usr/include/fileQGtiKL.cxx:2785: error: base operand of ‘->’ is not a pointer
g++: /tmp//usr/include/fileQGtiKL.o: Datei oder Verzeichnis nicht gefunden
Error in : Compilation failed!
root [2] .L /home/ruediger/ncurses.h+
Info in TUnixSystem::ACLiC: creating shared library /home/ruediger/ncurses_h.so
/home/ruediger/file5sLwiS.cxx: In function ‘int G__file5sLwiS__9_76(G__value*, const char*, G__param*, int)’:
/home/ruediger/file5sLwiS.cxx:2785: error: base operand of ‘->’ is not a pointer
g++: /home/ruediger/file5sLwiS.o: Datei oder Verzeichnis nicht gefunden
Error in : Compilation failed!

In the second attempt, I have tried the same with a local copy of ncurses.h, just for safe measure (although the error messages
seam to indicate that this does not have an impact).

Thanks and have a good day,
Ruediger

Ruediger,

Note that I did

root [0] .L /usr/lib/libcurses.so and not

This works for me under SLC3 and FC4 with gcc3.2.3 or gcc3.3

Under SLC3 I have to do twice (in a different session)

May be Philippe will give some help as soon he is back online.

Rene

Hi there,

o.k., I’m not sure I will be able to follow this advice properly, as
a SuSE system seems to be somewhat different from FC4 or SLC3.
E.g., while there is a separate libcurses.so, it can be found
under /usr/lib/curses/ and is part of the termcap package (and thus
seems to be there for compatibility reasons only).

If I nevertheless try load the libcurses library (as opposed to libncurses),
I get again tons of errors when loading ncurses.h (or curses.h, for that
matter).

gcc is 4.02, by the way, so maybe this is part of the problem ?

Have a good day,
Ruediger

Forgot: Loading ncurses.h+ twice in different sessions (this had worked for
you in SL) does not work either.
Thanks in any case,
Ruediger

[quote=“rberlich”]Hi there,

o.k., I’m not sure I will be able to follow this advice properly, as
a SuSE system seems to be somewhat different from FC4 or SLC3.
E.g., while there is a separate libcurses.so, it can be found
under /usr/lib/curses/ and is part of the termcap package (and thus
seems to be there for compatibility reasons only).

If I nevertheless try load the libcurses library (as opposed to libncurses),
I get again tons of errors when loading ncurses.h (or curses.h, for that
matter).

gcc is 4.02, by the way, so maybe this is part of the problem ?

Have a good day,
Ruediger[/quote]

[quote]/tmp//usr/include/fileQGtiKL.cxx:2785: error: base operand of ‘->’ is not a pointer [/quote]indicates that somehow cint is mistaken about the type of one of the ‘items’ in ncurses.h. They are several possibilities why this would happens (including that cint and the compilation of the dictionary do not see the same header files OR that some forward declaration is not fully resolved).

To debug the problem you would need to do:root [] gDebug = 7 root [] .L /usr/include/ncurses.h+This will leave the temporary file on the disk. You will then be able to look at line 2785 and see what the problem is. If you are lucky it might be enough to add a few more header files includes to your local copy of ncurses.h

Cheers,
Philippe.

Hi there,
o.k., here are a few lines from the output file. Please note the line numbers. The error happens in line 2785 .

2779 static int G__file95ZLoh__8_76(G__value *result7,G__CONST char funcname,struct G__param libp,int hash) {
2780 G__letint(result7,105,(long)wget_wstr((WINDOW
)G__int(libp->para[0]),(wint_t
)G__int(libp->para[1])));
2781 return(1 || funcname || hash || result7 || libp) ;
2782 }
2783
2785 static int G__file95ZLoh__9_76(G__value *result7,G__CONST char funcname,struct G__param libp,int hash) {
2785 G__letint(result7,105,(long)wgetbkgrnd((WINDOW
)G__int(libp->para[0]),(cchar_t
)G__int(libp->para[1])));
2786 return(1 || funcname || hash || result7 || libp) ;
2787 }
2788
2789 static int G__file95ZLoh__0_77(G__value *result7,G__CONST char funcname,struct G__param libp,int hash) {
2790 G__letint(result7,105,(long)wgetn_wstr((WINDOW
)G__int(libp->para[0]),(wint_t
)G__int(libp->para[1])
2791 ,(int)G__int(libp->para[2])));
2792 return(1 || funcname || hash || result7 || libp) ;
2793 }

The “bad” statement seems to be either libp->para[0] or libp->para[1] .
From the function’s argument list, however, it appears as if everything
is in order, i.e., libp is a pointer to a struct, the error message seems
to refer to libp. Also, this function seems in no way different from the one
preceeding it or the one after it. I have also checked the parantheses in
line 2785, which seem to be o.k. . So I cannot see any reason for the error
here.

Anyway, thanks a lot for the help!

Best Regards,
Ruediger Berlich

Hi there,
o.k., I have now managed to create a custom root interpreter with at least
some ncurses functions (I did not try them all). As this thread has been
quite long, here is the complete procedure:

  • I have created a main function (quoted below)
  • I have created a LinkDef.h file for a number of ncurses functions
    (quoted below). Please note that the 5.08 documentation refers to
    #pragma link C function xyz;
    to which rootcint reacts with the warning that “C++” should be
    used instead of “C”.
  • I have executed rootcint in the following way:
    rootcint mydict.C -c -p /usr/include/ncurses.h LinkDef.h
  • I have done the linking with the Makefile quoted below. Please note
    that I’m not linking with all ROOT libraries (e.g. xrootd stuff is missing).
  • I then could execute the unnamed script quoted below, which uses
    the ncurses functions listed in LinkDef.h . I have attached a
    screenshot of the output, which looks just as expected.

I still do not understand:

  • Is there a way to include all functions., macros, etc. from a header
    file without having to specifically mention each one of them ?
  • When do I need to give arguments to the functions listed in
    the #pragma statements ? E.g., printw has one fixed argument and
    can, just like printf, accept a number of optional arguments. Not
    mentioning any arguments in the #pragma statement seems to work
    fine. However, apparently I do need to give arguments e.g. move(int,int),
    if there is more than one function argument ?

In any case, thanks for all the help !

Best Regards,
Ruediger

/********************** main.C **********************/

//--------------------------------------------------
#include “TROOT.h”
#include “TRint.h”

int Error; //left undefined by Motif

extern void InitGui(); // initializer for GUI needed for interactive interface
VoidFuncPtr_t initfuncs[] = { InitGui, 0 };

// Initialize the ROOT system
TROOT root(“Rint”,“The ROOT Interactive Interface”, initfuncs);

int main(int argc, char **argv)
{
// Create interactive interface
TRint *theApp = new TRint(“ROOT example”, &argc, argv, NULL, 0);

// Run interactive interface
theApp->Run();

return(0);

}
//--------------------------------------------------

/********************** LinkDef.h **********************/

#ifdef CINT
#pragma link C++ function initscr;
#pragma link C++ function move(int,int);
#pragma link C++ function printw;
#pragma link C++ function refresh;
#pragma link C++ function getch;
#pragma link C++ function endwin;
#endif /* CINT */

/********************** Makefile **********************/

#---------------------------------------------------
CXXFLAGS = -g -I$(ROOTSYS)/include/root
LDFLAGS = -g
LD = g++

LIBS = -L/usr/X11R6/lib/ -L$(ROOTSYS)/lib/root -lXpm -lX11 -lm -lGpad -lGraf -lGraf3d -lHist -lMatrix -lRint -lCore -lCint -ldl -lc -lm -lz -lncurses

SRCS = main.C mydict.C

OBJS = main.o mydict.o

PROGRAM = myroot

all: $(PROGRAM)

(PROGRAM): (OBJS)
@echo "Linking (PROGRAM) ..." @(LD) (LDFLAGS) (OBJS) (LIBS) -o (PROGRAM)
@echo “done”

clean:; @rm -f $(OBJS) core

mydict.C:
@echo “Generating dictionary …”
@rootcint mydict.C -c -p /usr/include/ncurses.h LinkDef.h
#---------------------------------------------------

/*************** unnamed ncurses script **********************/

{
initscr(); /* Start curses mode /
move(10,10); /
Move cursor to position 10/10 /
printw(“Hello World !!!”); /
Print Hello World /
refresh(); /
Print it on to the real screen /
getch(); /
Wait for user input /
endwin(); /
End curses mode */

    return 0;

}

2785 G__letint(result7,105,(long)wgetbkgrnd((WINDOW*)G__int(libp->para[0]),(cchar_t*)G__int(libp->para[1]))); tmp//usr/include/fileQGtiKL.cxx:2785: error: base operand of ‘->’ is not a pointer
My best bet is that wgetbkgrnd or cchar_t is actually a ‘macro’ and is not properly expanded in this context. (You would need to compile the file with the -E option to figure this out).

[quote]Is there a way to include all functions., macros, etc. from a header
file without having to specifically mention each one of them ?[/quote]Yes, use #pragma link C++ defined_in fullpathname_of_the_file;Cheers,
Philippe.