getch example
from a C answer on stack overflow:
-- two includes here as the termios functions need both
-- and I'm not sure if the FFI syntax permits multiple includes
## cinclude '<termios.h>'
## cinclude '<unistd.h>'
-- cinclude *required* in this next line, to prevent a separate struct definition
local termios: type <cimport, cinclude '<termios.h>', cincomplete, ctypedef> = @record{
c_lflag: cint
}
local function tcgetattr(fd: cint, termios_p: *termios): cint <cimport, nodecl> end
local function tcsetattr(fd: cint, optional_actions: cint, termios_p: *termios): cint <cimport, nodecl> end
local function getchar(): cint <cimport, nodecl, cinclude '<stdio.h>'> end
-- cinclude also required for these constants, or nelua demands an initial value
local ICANON: cint <const, cimport, cinclude '<unistd.h>'>
local ECHO: cint <const, cimport, cinclude '<unistd.h>'>
local TCSANOW: cint <const, cimport, cinclude '<unistd.h>'>
local function getch(): uint8
local oldattr: termios <noinit>
local newattr: termios <noinit>
tcgetattr(0, &oldattr)
newattr = oldattr
newattr.c_lflag = newattr.c_lflag & ~(ICANON | ECHO)
tcsetattr(0, TCSANOW, &newattr)
local ch = getchar()
tcsetattr(0, TCSANOW, &oldattr)
return ch
end
print('Press a key:')
local c = getch()
print('I read:', c)Emitted C for getch:
uint8_t n11_getch(void) {
termios oldattr;
termios newattr;
tcgetattr(0, (&oldattr));
newattr = oldattr;
newattr.c_lflag = (newattr.c_lflag & (~(ICANON | ECHO)));
tcsetattr(0, TCSANOW, (&newattr));
int ch = getchar();
tcsetattr(0, TCSANOW, (&oldattr));
return (uint8_t)ch;
}what about struct stat?
If you try to define an incomplete record like for struct termios above, you'll run into some complaints owing to C namespace issues: there's no conflict between the stat() syscall and struct stat, until you try to create a typedef for the latter.
The solution's to force a different name for the typedef, while still making sure that you name the right struct. This requires two string parameters to annotations, and they may be in the reverse order from what you expect:
local statbuf: type <cimport 'statbuf', nodecl, cinclude '<sys/stat.h>', cincomplete, ctypedef 'stat'> = @record{
st_size: off_t,
}