ncurses "err 24 Invalid data types in mvaddstr()

External libraries (GTK, GSL, SDL, Allegro, OpenGL, etc) questions.
Post Reply
Axle
Posts: 67
Joined: May 31, 2022 6:49
Location: Australia

ncurses "err 24 Invalid data types in mvaddstr()

Post by Axle »

Hi forum

Question directly relating to curses "ncurses.bi" using FBC on Lubuntu 202.04.
FreeBASIC Compiler - Version 1.09.0 (2022-01-01), built for linux-x86_64 (64bit)

I am attempting to run the demo from pdcurs34\demos\firework.c (converted to FreeBASIC)
The original C source compiles and runs correctly under Windows 10 x64, and Lubuntu 20.04 x64
Lubuntu libraries:
libncurses5-dev
libncursesw5-dev
libncurses5
Also updated libtinfo5

My Windows FreeBASIC version of firework.bas compiles and runs without issue under FBC Version 1.09.0.

Under Lubuntu (Using Geany fbc -w all [-v -exx] "%f") I get multiple errors for mvaddstr()

firework.bas(112) error 24: Invalid data types in 'mvaddstr(LINES -1 - row, row * direction + start, IIf(direction < 0, aa, bb))'
firework.bas(142) error 24: Invalid data types in 'mvaddstr(row, col, "-")'
etc..

I have attempted every different version of sending a String and zString that I can think of without avail :(
The closest I seamed to get was:
"firework.bas(118) warning 3(2): Passing different pointer types, at parameter 2 of WADDNSTR()"
"firework.bas(118) error 24: Invalid data types in 'mvaddstr(LINES -1 - row, row * direction + start, IIf(direction < 0, @aa, @bb))'"

Code: Select all

dim as string aa = !"\\"
dim as string bb = !"/"
mvaddstr(LINES -1 - row, row * direction + start, IIf(direction < 0, @aa, @bb))
I get firework.bas(148) error 24: Invalid data types in 'mvaddstr(row, col, "-")' for every mvaddstr( , , String type).


Defines from ncurses.bi for mvaddstr(...)

Code: Select all

declare function waddnstr(byval as WINDOW_ ptr, byval as const zstring ptr, byval as long) as long
#define mvwaddstr(win, y, x, str) iif(wmove(win, y, x) = ERR_, ERR_, waddnstr(win, str, -1))
#define mvaddstr(y, x, str) mvwaddstr(stdscr, y, x, str)
The FB source code for firework.bas (compiles on windows with curses.bi, pdcurses.bi) Error lines = keyword mvaddstr

Code: Select all

''------------------------------------------------------------------------------
'' Name:        \PDCurses-3.9\demos\firework.c
'' Purpose:     Modified by Axle. 
'' Title:       "PDCurses fireworks example"
''
'' Platform:    Win64, Ubuntu64
''
'' Compiler:    FreeBASIC Compiler-1.09.0-win64 TDM-GCC 9.2.0 32/64-bit
'' Depends:     PDCurses V3.9
''
'' Author:      Axle
'' Created:     30/10/2022
'' Updated:     
'' Version:     0.0.1.0 beta
'' Copyright:   (c) Axle 2022
'' Licence:     MIT No Attribution (MIT-0)
''------------------------------------------------------------------------------
'' NOTES:
'' Press any key to quit.
''------------------------------------------------------------------------------
'' The following symbols have been renamed:
''     constant TRUE => CTRUE
''     constant ERR => ERR_
''     typedef WINDOW => WINDOW_
''     struct SCREEN => SCREEN_
''     procedure beep => beep_
''     procedure clear => clear_
''     procedure erase => erase_
''     procedure instr => instr_
''     procedure getmouse => getmouse_

''#define __FB_WIN32__
''#define PDC_DLL_BUILD

#include once "curses.bi"
#ifdef __FB_LINUX__
#inclib "tinfo"
#endif

#define DELAYSIZE 200
'' LINES defined in n/curses number of lines on terminal screen
'' COLS defined in n/curses number of columns on terminal screen
'' Windows 10 CMD.EXE default
'' LINES = 30 DEBUG (NOTE = 0 to 29)
'' COLS = 120 DEBUG (NOTE = 0 to 119)
'' XTerm default
'' curses.LINES = 24 DEBUG (NOTE = 0 to 23)
'' curses.COLS = 80 DEBUG (NOTE = 0 to 79)

Declare Function main_procedure() As Integer

Declare Sub myrefresh()
Declare Sub get_color()
Declare Sub explode(row As Integer, col As Integer)

dim Shared As Short color_table(8) = { _
    COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, _
    COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE}

main_procedure()

Function main_procedure() As Integer  ' Main procedure

    Dim as Long start, end1, row, diff, flag, direction
    Dim As Short i

    '' stdscr is the main screen buffer. Smaller screens (Panels) can be placed 
    '' above the main screen.
    initscr()  '' Start curses mode 
    keypad(stdscr, CTRUE)  '' Get function keys without testing escape sequence
    nodelay(stdscr, CTRUE)  '' Forces non blocking of getch().
                            '' False make getch() wait (blocking) until a key press.
    noecho()  '' Disable printing user input to the sreen.

    If (has_colors()) Then  '' Check if the terminal can support colours.
        start_color()  '' initializes 8x8 colors, 8 forground, 8 background.
    End If

    for i = 0 To 8 -1 Step 1
        '' The second value (background) is always set to black in this example.
        init_pair(i, color_table(i), COLOR_BLACK)  '' COLOR_PAIR (color_table[i], Black)
    Next i

    Randomize , 1  '' generate random numbers table from Time.
    flag = 0

    '' You could change this to test for a specific key.
    while (getch() = ERR_)  '' loop until any key is hit.
            
        do  '' Loop through rand screen positions untill within boundaries.
            '' Note: rnd*100 will generate rnd numbers between 0 and 99.
            '' rnd*100 +1 or (rnd*100) +1 , 1 to 100.
            start = Rnd * (COLS - 3)
            end1 = Rnd * (COLS - 3)
            start = IIf(start < 2, 2, start)  '' Ternary conditional operator,
            end1 = IIf(end1 < 2, 2, end1)  '' ternary if, inline if (IIF).
            direction = IIf(start > end1, -1, 1)
            diff = Abs(start - end1)  '' Change -integer to +integer.
        Loop While (diff < 2 Or diff >= LINES - 2)  '' Conditional end do while.
        
        attrset(A_NORMAL)  '' set character attributes to normal.

        for row = 0 To diff -1 Step 1  '' Draw launch lines.
            mvaddstr(LINES -1 - row, row * direction + start, _
            IIf(direction < 0, !"\\", !"/"))

            flag += 1
            if (flag > 1) Then  '' >1 keeps 2 x \ or / displayed.
                myrefresh()
                erase_()  '' Clears all y,x in the screen. clear() clears the
                flag = 0  '' entire screen buffer.
            End If
        Next row

        flag += 1
        if (flag > 1) Then  '' >1 Diplays the last \ or / bfore explosion.
            myrefresh()
            flag = 0
        End If

        '' Draw fireworks explode from rnd values
        explode(LINES -1 - row, diff * direction + start)
        erase_()  '' Clears the fireworks for next launch.
        myrefresh()
    WEnd  '' end while

    endwin()  '' End curses mode

    Return 0
End Function  ' END main_procedure <---

'' Explode. Draw each ASCII frame.
Sub explode(row As Integer, col As Integer)  '' Maybe consider Long
    erase_()
    mvaddstr(row, col, "-")
    myrefresh()

    col = col - 1  '' Adjust left x boundary for string width centre

    get_color()
    mvaddstr(row - 1, col, " - ")
    mvaddstr(row,     col, "-+-")
    mvaddstr(row + 1, col, " - ")
    myrefresh()

    col = col - 1

    get_color()
    mvaddstr(row - 2, col, " --- ")  '' row - 2 expand to give explosion efect
    mvaddstr(row - 1, col, "-+++-")
    mvaddstr(row,     col, "-+#+-")
    mvaddstr(row + 1, col, "-+++-")
    mvaddstr(row + 2, col, " --- ")
    myrefresh()

    get_color()
    mvaddstr(row - 2, col, " +++ ")
    mvaddstr(row - 1, col, "++#++")
    mvaddstr(row,     col, "+# #+")
    mvaddstr(row + 1, col, "++#++")
    mvaddstr(row + 2, col, " +++ ")
    myrefresh()

    get_color()
    mvaddstr(row - 2, col, "  #  ")
    mvaddstr(row - 1, col, "## ##")
    mvaddstr(row,     col, "#   #")
    mvaddstr(row + 1, col, "## ##")
    mvaddstr(row + 2, col, "  #  ")
    myrefresh()

    get_color()
    mvaddstr(row - 2, col, " # # ")
    mvaddstr(row - 1, col, "#   #")
    mvaddstr(row,     col, "     ")
    mvaddstr(row + 1, col, "#   #")
    mvaddstr(row + 2, col, " # # ")
    myrefresh()
End Sub

Sub myrefresh()
    napms(DELAYSIZE)  '' sleeps for at least DELAYSIZE milliseconds
    move(LINES - 1, COLS - 1)  '' moves the cursor to the lower right corner
    refresh()
End Sub

'' Generate our random color set for each frame
Sub get_color()
    Dim As chtype bold = IIf(Rnd * 2, A_BOLD, A_NORMAL)  '' Rnd(0|1) bold/normal
    attrset(COLOR_PAIR((Rnd * 8) Or bold))  '' sets text color+[A_BOLD|A_NORMAL].
End Sub

'' A_NORMAL        Normal display (no highlight)
'' A_STANDOUT      Best highlighting mode of the terminal
'' A_UNDERLINE     Underlining
'' A_REVERSE       Reverse video
'' A_BLINK         Blinking
'' A_DIM           Half bright
'' A_BOLD          Extra bright or bold
'' A_PROTECT       Protected mode
'' A_INVIS         Invisible or blank mode
'' A_ALTCHARSET    Alternate character set
'' A_CHARTEXT      Bit-mask to extract a character
'' COLOR_PAIR(n)   Color-pair number n
Any thoughts on what form (data type) I should supply to mvaddstr()? or am I missing something else?

P.S. A simple hello world compiles and runs on FBC Lubutu as well as another example with overlayed windows. Both use printw() an wprintw() without error eg. printw(!"RED/BLACK\n"); wprintw(dbg_win, !"%s \n", value)

Axle
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by fxm »

'waddnstr()' expects as second parameter a Zstring Ptr, give it a Zstring Ptr argument !

Code: Select all

dim as string aa = !"\\"
dim as string bb = !"/"
mvaddstr(LINES -1 - row, row * direction + start, IIf(direction < 0, Strptr(aa), Strptr(bb)))
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by fxm »

'waddnstr()' expects as second parameter a Zstring Ptr, give it a Zstring Ptr argument !

Code: Select all

''------------------------------------------------------------------------------
'' Name:        \PDCurses-3.9\demos\firework.c
'' Purpose:     Modified by Axle. 
'' Title:       "PDCurses fireworks example"
''
'' Platform:    Win64, Ubuntu64
''
'' Compiler:    FreeBASIC Compiler-1.09.0-win64 TDM-GCC 9.2.0 32/64-bit
'' Depends:     PDCurses V3.9
''
'' Author:      Axle
'' Created:     30/10/2022
'' Updated:     
'' Version:     0.0.1.0 beta
'' Copyright:   (c) Axle 2022
'' Licence:     MIT No Attribution (MIT-0)
''------------------------------------------------------------------------------
'' NOTES:
'' Press any key to quit.
''------------------------------------------------------------------------------
'' The following symbols have been renamed:
''     constant TRUE => CTRUE
''     constant ERR => ERR_
''     typedef WINDOW => WINDOW_
''     struct SCREEN => SCREEN_
''     procedure beep => beep_
''     procedure clear => clear_
''     procedure erase => erase_
''     procedure instr => instr_
''     procedure getmouse => getmouse_

''#define __FB_WIN32__
''#define PDC_DLL_BUILD

#include once "curses.bi"
#ifdef __FB_LINUX__
#inclib "tinfo"
#endif

#define DELAYSIZE 200
'' LINES defined in n/curses number of lines on terminal screen
'' COLS defined in n/curses number of columns on terminal screen
'' Windows 10 CMD.EXE default
'' LINES = 30 DEBUG (NOTE = 0 to 29)
'' COLS = 120 DEBUG (NOTE = 0 to 119)
'' XTerm default
'' curses.LINES = 24 DEBUG (NOTE = 0 to 23)
'' curses.COLS = 80 DEBUG (NOTE = 0 to 79)

Declare Function main_procedure() As Integer

Declare Sub myrefresh()
Declare Sub get_color()
Declare Sub explode(row As Integer, col As Integer)

dim Shared As Short color_table(8) = { _
    COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, _
    COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE}

main_procedure()

Function main_procedure() As Integer  ' Main procedure

    Dim as Long start, end1, row, diff, flag, direction
    Dim As Short i

    '' stdscr is the main screen buffer. Smaller screens (Panels) can be placed 
    '' above the main screen.
    initscr()  '' Start curses mode 
    keypad(stdscr, CTRUE)  '' Get function keys without testing escape sequence
    nodelay(stdscr, CTRUE)  '' Forces non blocking of getch().
                            '' False make getch() wait (blocking) until a key press.
    noecho()  '' Disable printing user input to the sreen.

    If (has_colors()) Then  '' Check if the terminal can support colours.
        start_color()  '' initializes 8x8 colors, 8 forground, 8 background.
    End If

    for i = 0 To 8 -1 Step 1
        '' The second value (background) is always set to black in this example.
        init_pair(i, color_table(i), COLOR_BLACK)  '' COLOR_PAIR (color_table[i], Black)
    Next i

    Randomize , 1  '' generate random numbers table from Time.
    flag = 0

    '' You could change this to test for a specific key.
    while (getch() = ERR_)  '' loop until any key is hit.
            
        do  '' Loop through rand screen positions untill within boundaries.
            '' Note: rnd*100 will generate rnd numbers between 0 and 99.
            '' rnd*100 +1 or (rnd*100) +1 , 1 to 100.
            start = Rnd * (COLS - 3)
            end1 = Rnd * (COLS - 3)
            start = IIf(start < 2, 2, start)  '' Ternary conditional operator,
            end1 = IIf(end1 < 2, 2, end1)  '' ternary if, inline if (IIF).
            direction = IIf(start > end1, -1, 1)
            diff = Abs(start - end1)  '' Change -integer to +integer.
        Loop While (diff < 2 Or diff >= LINES - 2)  '' Conditional end do while.
        
        attrset(A_NORMAL)  '' set character attributes to normal.

        for row = 0 To diff -1 Step 1  '' Draw launch lines.
            mvaddstr(LINES -1 - row, row * direction + start, _
            IIf(direction < 0, @!"\\", @!"/"))

            flag += 1
            if (flag > 1) Then  '' >1 keeps 2 x \ or / displayed.
                myrefresh()
                erase_()  '' Clears all y,x in the screen. clear() clears the
                flag = 0  '' entire screen buffer.
            End If
        Next row

        flag += 1
        if (flag > 1) Then  '' >1 Diplays the last \ or / bfore explosion.
            myrefresh()
            flag = 0
        End If

        '' Draw fireworks explode from rnd values
        explode(LINES -1 - row, diff * direction + start)
        erase_()  '' Clears the fireworks for next launch.
        myrefresh()
    WEnd  '' end while

    endwin()  '' End curses mode

    Return 0
End Function  ' END main_procedure <---

'' Explode. Draw each ASCII frame.
Sub explode(row As Integer, col As Integer)  '' Maybe consider Long
    erase_()
    mvaddstr(row, col, @"-")
    myrefresh()

    col = col - 1  '' Adjust left x boundary for string width centre

    get_color()
    mvaddstr(row - 1, col, @" - ")
    mvaddstr(row,     col, @"-+-")
    mvaddstr(row + 1, col, @" - ")
    myrefresh()

    col = col - 1

    get_color()
    mvaddstr(row - 2, col, @" --- ")  '' row - 2 expand to give explosion efect
    mvaddstr(row - 1, col, @"-+++-")
    mvaddstr(row,     col, @"-+#+-")
    mvaddstr(row + 1, col, @"-+++-")
    mvaddstr(row + 2, col, @" --- ")
    myrefresh()

    get_color()
    mvaddstr(row - 2, col, @" +++ ")
    mvaddstr(row - 1, col, @"++#++")
    mvaddstr(row,     col, @"+# #+")
    mvaddstr(row + 1, col, @"++#++")
    mvaddstr(row + 2, col, @" +++ ")
    myrefresh()

    get_color()
    mvaddstr(row - 2, col, @"  #  ")
    mvaddstr(row - 1, col, @"## ##")
    mvaddstr(row,     col, @"#   #")
    mvaddstr(row + 1, col, @"## ##")
    mvaddstr(row + 2, col, @"  #  ")
    myrefresh()

    get_color()
    mvaddstr(row - 2, col, @" # # ")
    mvaddstr(row - 1, col, @"#   #")
    mvaddstr(row,     col, @"     ")
    mvaddstr(row + 1, col, @"#   #")
    mvaddstr(row + 2, col, @" # # ")
    myrefresh()
End Sub

Sub myrefresh()
    napms(DELAYSIZE)  '' sleeps for at least DELAYSIZE milliseconds
    move(LINES - 1, COLS - 1)  '' moves the cursor to the lower right corner
    refresh()
End Sub

'' Generate our random color set for each frame
Sub get_color()
    Dim As chtype bold = IIf(Rnd * 2, A_BOLD, A_NORMAL)  '' Rnd(0|1) bold/normal
    attrset(COLOR_PAIR((Rnd * 8) Or bold))  '' sets text color+[A_BOLD|A_NORMAL].
End Sub

'' A_NORMAL        Normal display (no highlight)
'' A_STANDOUT      Best highlighting mode of the terminal
'' A_UNDERLINE     Underlining
'' A_REVERSE       Reverse video
'' A_BLINK         Blinking
'' A_DIM           Half bright
'' A_BOLD          Extra bright or bold
'' A_PROTECT       Protected mode
'' A_INVIS         Invisible or blank mode
'' A_ALTCHARSET    Alternate character set
'' A_CHARTEXT      Bit-mask to extract a character
'' COLOR_PAIR(n)   Color-pair number n
Axle
Posts: 67
Joined: May 31, 2022 6:49
Location: Australia

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by Axle »

"'waddnstr()' expects as second parameter a Zstring Ptr, give it a Zstring Ptr argument !"
That was my first attempt @!"..." As per our previous discussion and answer from the limpv conversions:/
aka mvaddstr(LINES -1 - row, row * direction + start, IIf(direction < 0, @!"\\", @!"/"))
Except it failed with the same error... Just going back to recompile and see what happens...

[Edit]
Still the same error:

Code: Select all

mvaddstr(LINES -1 - row, row * direction + start, _
            IIf(direction < 0, @!"\\", @!"/"))
firework.bas(106) error 24: Invalid data types in 'IIf(direction < 0, @!"\\", @!"/"))'

mvaddstr(row, col, @"-")
firework.bas(148) error 24: Invalid data types in 'mvaddstr(row, col, @"-")'
[Edit 2]
I have also attempted:
'Dim As ZString Ptr aa
'Dim As ZString Ptr bb
'aa = Allocate( 8 )
'bb = Allocate( 8 )
'*aa = !"\\"
'*bb = !"/"

'Dim As zstring * 8 aa => !"\\"
'Dim As zstring * 8 bb => !"/"

Dim as String aa = !"\\" '' !"/" '' Strptr(aa)
Dim As String bb = !"/" '' "/" '' Strptr(bb)

'mvaddstr(LINES -1 - row, row * direction + start, IIf(direction < 0, @aa, @bb)) '' Strptr(aa), ...
Plus any other variation I could take off of zString help pages and my other conversions to zString from the libmpv discussion and later code.

Got me stumped lol

P.S. Thank you for the try :)
Axle
Posts: 67
Joined: May 31, 2022 6:49
Location: Australia

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by Axle »

I think I will try directly:

Code: Select all

#define win stdscr
wmove(win, y, x)
waddnstr(win, str, -1)
And see if it works, and then walk back the #defines if it does:

Code: Select all

declare function waddnstr(byval as WINDOW_ ptr, byval as const zstring ptr, byval as long) as long
#define mvwaddstr(win, y, x, str) iif(wmove(win, y, x) = ERR_, ERR_, waddnstr(win, str, -1))
#define mvaddstr(y, x, str) mvwaddstr(stdscr, y, x, str)
It's almost midnight here and my eyes are dragging on my keyboard lol
I'll give it another shot tomorrow.
Thanks agian for the suggestions
Axle
Axle
Posts: 67
Joined: May 31, 2022 6:49
Location: Australia

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by Axle »

P.S.

I just tried:

Code: Select all

Sub explode(row As Integer, col As Integer)  '' Maybe consider Long
    erase_()
    wmove(stdscr, row, col)
    waddnstr(stdscr, "-", -1)  '' No error
    'mvaddstr(row, col, "-")
    myrefresh()
...
and

Code: Select all

Sub explode(row As Integer, col As Integer)  '' Maybe consider Long
    erase_()
    wmove(stdscr, row, col)
    waddnstr(stdscr, @"-", -1)  '' No error
    'mvaddstr(row, col, "-")
    myrefresh()
...
And neither gave error 24: Invalid data types in...
So it may be in the 2 #defines.

I'll redo it it tomorrow and see if I can trace where where the #defines are throwing me off.
Axle
Posts: 67
Joined: May 31, 2022 6:49
Location: Australia

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by Axle »

Hi forum

I think I have nailed this problem down to the #defines in the header. mvaddstr(...) -> mvwaddstr(...) -> wmove() + waddnstr()
wmove() + waddnstr() work as expected, mvaddstr() and mvwaddstr() both give error 24: Invalid data types in...

C declaration from ncurses.h (requires const char *, aka NULL terminated array of char, string literal)
'extern NCURSES_EXPORT(int) waddnstr (WINDOW *,const char *,int); /* implemented */

Code: Select all

'declare function waddnstr(byval as WINDOW_ ptr, byval as const zstring ptr, byval as long) as long  '' Works as expected
'#define mvwaddstr(win, y, x, str) iif(wmove(win, y, x) = ERR_, ERR_, waddnstr(win, str, -1))  '' Fails error 24:
'#define mvaddstr(y, x, str) mvwaddstr(stdscr, y, x, str)  '' Fails error 24:
Can anyone see why the 2 #defines are not accepting the zString Ptr?
Are the #defines tricking the compiler error message?
Are the #defines unusable invalidating most of the compatibility wrappers from ncurses.bi line 484 to 614?
Am I just missing something simple here?

Form my tests related to firework.bas example above:

Code: Select all

'' Explode. Draw each ASCII frame.
Sub explode(row As Integer, col As Integer)  '' Maybe consider Long
	erase_()
	wmove(stdscr, row, col)
	waddnstr(stdscr, "-", -1)  '' Success

	'mvwaddstr(stdscr, row, col, @"-")  '' Fails

	'Dim As ZString Ptr pz = @"-"
	'mvwaddstr(stdscr, row, col, *pz)  '' Fails

	'mvaddstr(row, col, "-")  '' or , @"-") Fails (original call)
	myrefresh()
	...
[Additional context]
It may seem simple to just use wmove() and waddnstr() directly, but considering there are some 100 wrapper #defines in the header it will break any compatibility with the original curses, ncurses, pdcurses official examples. I have to write examples plus refer to the official examples and do so using the same function calls in C, FB, and python on both Windows and Ubuntu.
Alternatively I could write up some function wrappers instead of the defines, but that seams like a big effort if there is a simple solution here somewhere :)

Axle
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by fxm »

Resulting in only an IIF keyword (which returns a value), the macros 'mvaddstr' and 'mvwaddstr' should be used in expressions and not alone.

Example:

Code: Select all

Dim As Long result
result = mvaddstr(LINES -1 - row, row * direction + start, IIf(direction < 0, Strptr(aa), Strptr(bb)))
result = mvaddstr(row, col, @"-")

Note:
'IIf ( condition, expr_if_true, expr_if_false )' can be used alone only if:
- 'expr_if_true' and 'expr_if_false' are both compatible function returns,
- and 'condition' can be solved at compile time.
Axle
Posts: 67
Joined: May 31, 2022 6:49
Location: Australia

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by Axle »

Thanks @fmx

mvwaddstr(stdscr, row, col, "-") '' error 24: Invalid data types, found ''' in 'mvwaddstr(stdscr, row, col, "-")
vs
result = mvwaddstr(stdscr, row, col, "-") '' Compilation finished successfully.

So iif(wmove(win, y, x) = ERR_, ERR_, waddnstr(win, str, -1)) The "Preprocessor" forces the requirement of a return value as an expression?
'#define mvwaddstr(win, y, x, str) iif(wmove(win, y, x) = ERR_, ERR_, waddnstr(win, str, -1))
mvwaddstr(byval win byval as WINDOW_ ptr, byval x as long,byval x as long, byval str as const zstring ptr) as long <- Required

Thanks @fmx
It's the first time I have encountered this, or maybe I have previously and didn't realize. Many of the other macros in ncurses.h/bi also contain the inline IF or conditional ternary so I will need make note of this in my examples that use the mvwxxxx macros.

Also wondering if this is true for the C Preprocessor with (?:) macros? Typically we would just naturally use the conditional in an expression without thinking about it lol
return = (condition) ? Expression2 : Expression3;

Again, I am very much appreciative of your insights :)
best regards
Axle

P.S. I am near finished the Book and examples. Just a few bits like rechecking the curses examples on Linux and a Python example to do on libmpv.
You will have the opportunity to smile and smack me on the knuckles for any poor coding practice I have picked up in the past lol

P.S.S. Even though the above compiles using just "-" I will add the address of before the literals @"-" because we are working with zString Ptr.
Axle
Posts: 67
Joined: May 31, 2022 6:49
Location: Australia

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by Axle »

Solution as per @fmx recommendation:
Resulting in only an IIF keyword (which returns a value), the macros 'mvaddstr' and 'mvwaddstr' should be used in expressions and not alone.
Full source of the conversion from \PDCurses-3.9\demos\firework.c to FreeBASIC
For anyone that may have an interest in the outcome of this question and discussion.

Code: Select all

''------------------------------------------------------------------------------
'' Name:        \PDCurses-3.9\demos\firework.c
'' Purpose:     Modified by Axle. 
'' Title:       "PDCurses fireworks example"
''
'' Platform:    Win64, Ubuntu64
''
'' Compiler:    FreeBASIC Compiler-1.09.0-win64 TDM-GCC 9.2.0 32/64-bit
'' Depends:     PDCurses V3.9
''
'' Author:      Axle
'' Created:     30/10/2022
'' Updated:     30/06/2023
'' Version:     0.0.1.2 beta
'' Copyright:   (c) Axle 2022
'' Licence:     MIT No Attribution (MIT-0)
''------------------------------------------------------------------------------
'' NOTES:
'' Press any key to quit.
''
'' Functions #define as MACROS in ncurses.bi containing
'' IIf ( condition, expr_if_true, expr_if_false ) must receive a return value
'' as an expression.
'' ie. The MACRO
'' #define mvwaddstr(win, y, x, str) iif(wmove(win, y, x) = ERR_, ERR_, waddnstr(win, str, -1))
'' requires
'' Dim As Long result = mvwaddstr(stdscr, row, col, @"-")
'' SEE: check_error()
''------------------------------------------------------------------------------
'' The following symbols have been renamed:
''     constant TRUE => CTRUE
''     constant ERR => ERR_
''     typedef WINDOW => WINDOW_
''     struct SCREEN => SCREEN_
''     procedure beep => beep_
''     procedure clear => clear_
''     procedure erase => erase_
''     procedure instr => instr_
''     procedure getmouse => getmouse_

''#define __FB_WIN32__
''#define PDC_DLL_BUILD

#include once "curses.bi"
#ifdef __FB_LINUX__
#inclib "tinfo"
#endif

#define DELAYSIZE 200
'' LINES defined in n/curses number of lines on terminal screen
'' COLS defined in n/curses number of columns on terminal screen
'' Windows 10 CMD.EXE default
'' LINES = 30 DEBUG (NOTE = 0 to 29)
'' COLS = 120 DEBUG (NOTE = 0 to 119)
'' XTerm default
'' curses.LINES = 24 DEBUG (NOTE = 0 to 23)
'' curses.COLS = 80 DEBUG (NOTE = 0 to 79)

Declare Function main_procedure() As Integer

Declare Sub myrefresh()
Declare Sub get_color()
Declare Sub explode(row As Long, col As Long)
Declare Function check_error(Byval status As Long) As Long  '' Eror check routine.

dim Shared As Short color_table(8) = { _
    COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, _
    COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE}

main_procedure()

Function main_procedure() As Integer  ' Main procedure

    Dim as Long start, end1, row, diff, flag, direction
    Dim As Short i

    '' stdscr is the main screen buffer. Smaller screens (Panels) can be placed 
    '' above the main screen.
    initscr()  '' Start curses mode 
    keypad(stdscr, CTRUE)  '' Get function keys without testing escape sequence
    nodelay(stdscr, CTRUE)  '' Forces non blocking of getch().
                            '' False make getch() wait (blocking) until a key press.
    noecho()  '' Disable printing user input to the sreen.

    If (has_colors()) Then  '' Check if the terminal can support colours.
        start_color()  '' initializes 8x8 colors, 8 forground, 8 background.
    End If

    for i = 0 To 8 -1 Step 1
        '' The second value (background) is always set to black in this example.
        init_pair(i, color_table(i), COLOR_BLACK)  '' COLOR_PAIR (color_table[i], Black)
    Next i

    Randomize , 1  '' generate random numbers table from Time.
    flag = 0

    '' You could change this to test for a specific key.
    while (getch() = ERR_)  '' loop until any key is hit.
            
        do  '' Loop through rand screen positions untill within boundaries.
            '' Note: rnd*100 will generate rnd numbers between 0 and 99.
            '' rnd*100 +1 or (rnd*100) +1 , 1 to 100.
            start = Rnd * (COLS - 3)
            end1 = Rnd * (COLS - 3)
            start = IIf(start < 2, 2, start)  '' Ternary conditional operator,
            end1 = IIf(end1 < 2, 2, end1)  '' ternary if, inline if (IIF).
            direction = IIf(start > end1, -1, 1)
            diff = Abs(start - end1)  '' Change -integer to +integer.
        Loop While (diff < 2 Or diff >= LINES - 2)  '' Conditional end do while.
        
        attrset(A_NORMAL)  '' set character attributes to normal.

        for row = 0 To diff -1 Step 1  '' Draw launch lines.
            check_error(mvaddstr(LINES -1 - row, row * direction + start, _
            IIf(direction < 0, @!"\\", @!"/")))

            flag += 1
            if (flag > 1) Then  '' >1 keeps 2 x \ or / displayed.
                myrefresh()
                erase_()  '' Clears all y,x in the screen. clear() clears the
                flag = 0  '' entire screen buffer.
            End If
        Next row

        flag += 1
        if (flag > 1) Then  '' >1 Diplays the last \ or / bfore explosion.
            myrefresh()
            flag = 0
        End If

        '' Draw fireworks explode from rnd values
        explode(LINES -1 - row, diff * direction + start)
        erase_()  '' Clears the fireworks for next launch.
        myrefresh()
    WEnd  '' end while

    endwin()  '' End curses mode

    Return 0
End Function  ' END main_procedure <---

'' Explode. Draw each ASCII frame.
Sub explode(row As Long, col As Long)  '' Maybe consider Long
    erase_()
    check_error(mvaddstr(row, col, @"-"))
    myrefresh()

    col = col - 1  '' Adjust left x boundary for string width centre

    get_color()
    check_error(mvaddstr(row - 1, col, @" - "))
    check_error(mvaddstr(row,     col, @"-+-"))
    check_error(mvaddstr(row + 1, col, @" - "))
    myrefresh()

    col = col - 1

    get_color()
    check_error(mvaddstr(row - 2, col, @" --- "))  '' row - 2 expand to give explosion efect
    check_error(mvaddstr(row - 1, col, @"-+++-"))
    check_error(mvaddstr(row,     col, @"-+#+-"))
    check_error(mvaddstr(row + 1, col, @"-+++-"))
    check_error(mvaddstr(row + 2, col, @" --- "))
    myrefresh()

    get_color()
    check_error(mvaddstr(row - 2, col, @" +++ "))
    check_error(mvaddstr(row - 1, col, @"++#++"))
    check_error(mvaddstr(row,     col, @"+# #+"))
    check_error(mvaddstr(row + 1, col, @"++#++"))
    check_error(mvaddstr(row + 2, col, @" +++ "))
    myrefresh()

    get_color()
    check_error(mvaddstr(row - 2, col, @"  #  "))
    check_error(mvaddstr(row - 1, col, @"## ##"))
    check_error(mvaddstr(row,     col, @"#   #"))
    check_error(mvaddstr(row + 1, col, @"## ##"))
    check_error(mvaddstr(row + 2, col, @"  #  "))
    myrefresh()

    get_color()
    check_error(mvaddstr(row - 2, col, @" # # "))
    check_error(mvaddstr(row - 1, col, @"#   #"))
    check_error(mvaddstr(row,     col, @"     "))
    check_error(mvaddstr(row + 1, col, @"#   #"))
    check_error(mvaddstr(row + 2, col, @" # # "))
    myrefresh()
End Sub

Sub myrefresh()
    napms(DELAYSIZE)  '' sleeps for at least DELAYSIZE milliseconds
    move(LINES - 1, COLS - 1)  '' moves the cursor to the lower right corner
    refresh()
End Sub

'' Generate our random color set for each frame
Sub get_color()
    Dim As chtype bold = IIf(Rnd * 2, A_BOLD, A_NORMAL)  '' Rnd(0|1) bold/normal
    attrset(COLOR_PAIR((Rnd * 8) Or bold))  '' sets text color+[A_BOLD|A_NORMAL].
    
	'' A_NORMAL        Normal display (no highlight)
	'' A_STANDOUT      Best highlighting mode of the terminal
	'' A_UNDERLINE     Underlining
	'' A_REVERSE       Reverse video
	'' A_BLINK         Blinking
	'' A_DIM           Half bright
	'' A_BOLD          Extra bright or bold
	'' A_PROTECT       Protected mode
	'' A_INVIS         Invisible or blank mode
	'' A_ALTCHARSET    Alternate character set
	'' A_CHARTEXT      Bit-mask to extract a character
	'' COLOR_PAIR(n)   Color-pair number n
End Sub

'' Eror check routine. 
Function check_error(Byval status As Long) As Long
	'' ncurses(.bi) only has 2 error return values.
	'' ERR_ = -1
	'' OK = 0
	If status = -1 Then  '' If status = ERR_ Then
		Print "curses API error!"  '' DEBUG
        '' Handle error appropriately...
        'endwin()  '' End curses mode
        'End 1  '' Terminate the application
        ' or
		'Return 1  '' return an error value to main_procedure()
    End If
    return 0
End Function
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by fxm »

Axle wrote: Jun 29, 2023 22:36 P.S.S. Even though the above compiles using just "-" I will add the address of before the literals @"-" because we are working with zString Ptr.

From C Standard Library Functions documentation page:
Note: In order to make calling the C runtime functions very easy, any string type argument may be directly passed to a procedure referring to a parameter declared as 'zstring ptr'. The compiler performs itself an automatic conversion (without warning message) between any string type argument and the 'zstring ptr' type parameter.


P.S.
I updated the IIF documentation page ('Description' paragraph):
KeyPgIif → fxm [completed description]
Axle
Posts: 67
Joined: May 31, 2022 6:49
Location: Australia

Re: ncurses "err 24 Invalid data types in mvaddstr()

Post by Axle »

Thanks @fmx
From C Standard Library Functions documentation page:

Note: In order to make calling the C runtime functions very easy, any string type argument may be directly passed to a procedure referring to a parameter declared as 'zstring ptr'. The compiler performs itself an automatic conversion (without warning message) between any string type argument and the 'zstring ptr' type parameter.
This was my experience when I create convenience wrappers and examples for SQLite. Passing a string (Not an array()) as an argument to a function was fine ( no @"" or StrPtr(string) required). Retrieving returns from a CDECL dll/so required the type cast return = *Cast(zString Ptr,C_function()).
I updated the IIF documentation page ('Description' paragraph):
KeyPgIif → fxm [completed description]
Thanks for that, I am sure others will appreciate it. Prob the other side is when they occur in the header file MACROs making them a little Opaque. I have/will make a note in header any source I create from now on that contains IIF in a wrapper or other header file. GCC doesn't appear to enforce the return on a (?:) so it thew my off on that one lol.
Live and learn :)
Axle
Post Reply