rktio: add standalone build mode
Also, add a script to extract the "rktio.h" header information to an S-expression form suitable for FFI use, and refine the "rktio.h" information to improve that output.
This commit is contained in:
parent
81f1c90ee0
commit
316df0af7a
|
@ -12,6 +12,15 @@ STATIC_AR = @STATIC_AR@
|
|||
ARFLAGS = @ARFLAGS@
|
||||
RANLIB = @RANLIB@
|
||||
|
||||
# Used only for standalone builds:
|
||||
AR = @AR@
|
||||
ICP_LIB = @ICP_LIB@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
libdir = @libdir@
|
||||
|
||||
RACKET = racket
|
||||
|
||||
RKTIO_HEADERS = $(srcdir)/rktio.h $(srcdir)/rktio_private.h rktio_config.h
|
||||
|
||||
OBJS = rktio_fs.@LTO@ \
|
||||
|
@ -34,9 +43,15 @@ OBJS = rktio_fs.@LTO@ \
|
|||
rktio_wide.@LTO@ \
|
||||
rktio_main.@LTO@
|
||||
|
||||
librktio.@LTA@: $(OBJS)
|
||||
$(NICEAR) $(STATIC_AR) $(ARFLAGS) librktio.@LTA@ $(OBJS)
|
||||
$(RANLIB) librktio.@LTA@
|
||||
default_rktio:
|
||||
$(MAKE) @HIDE_STANDALONE@@HIDE_NOT_STANDALONE@librktio
|
||||
|
||||
@HIDE_STANDALONE@librktio:
|
||||
$(MAKE) librktio.@LTA@
|
||||
|
||||
@HIDE_NOT_STANDALONE@librktio.@LTA@: $(OBJS)
|
||||
$(NICEAR) $(STATIC_AR) $(ARFLAGS) @HIDE_NOT_STANDALONE@librktio.@LTA@ $(OBJS)
|
||||
$(RANLIB) @HIDE_NOT_STANDALONE@librktio.@LTA@
|
||||
|
||||
demo: rktio_demo
|
||||
./rktio_demo $(ARGS)
|
||||
|
@ -106,3 +121,22 @@ demo.@LTO@: $(srcdir)/demo.c $(RKTIO_HEADERS)
|
|||
|
||||
clean:
|
||||
rm -f $(OBJS) librktio.@LTA@ rktio_demo demo_fifo
|
||||
|
||||
# ----------------------------------------
|
||||
|
||||
@HIDE_NOT_STANDALONE@librktio:
|
||||
$(MAKE) librktio.@LIBSFX@
|
||||
|
||||
# Builds a shared object; requires `configure --enable-standalone`
|
||||
@HIDE_STANDALONE@librktio.@LIBSFX@: $(OBJS)
|
||||
$(NICEAR) $(AR) @HIDE_STANDALONE@librktio.@LIBSFX@ $(OBJS) $(LDFLAGS) $(LIBS)
|
||||
|
||||
# Builds a shared object and installs it to `configure --prefix=...` target
|
||||
install-shared-object:
|
||||
$(MAKE) librktio.@LIBSFX@
|
||||
mkdir -p "$(DESTDIR)$(libdir)/"
|
||||
$(ICP_LIB) librktio.@LIBSFX@ "$(DESTDIR)$(libdir)/librktio.@LIBSFX@"
|
||||
|
||||
# Builds an S-expression form of "rktio.h"
|
||||
rktio.rktl: $(srcdir)/rktio.h $(srcdir)/parse.rkt
|
||||
$(RACKET) $(srcdir)/parse.rkt -o rktio.rktl $(srcdir)/rktio.h
|
||||
|
|
60
racket/src/rktio/configure
vendored
60
racket/src/rktio/configure
vendored
|
@ -621,9 +621,12 @@ ac_includes_default="\
|
|||
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
HIDE_STANDALONE
|
||||
HIDE_NOT_STANDALONE
|
||||
LTA
|
||||
LTO
|
||||
LIBSFX
|
||||
ICP_LIB
|
||||
STATIC_AR
|
||||
ARFLAGS
|
||||
AR
|
||||
|
@ -694,6 +697,7 @@ ac_subst_files=''
|
|||
ac_user_opts='
|
||||
enable_option_checking
|
||||
enable_shared
|
||||
enable_standalone
|
||||
enable_pthread
|
||||
enable_iconv
|
||||
'
|
||||
|
@ -1319,6 +1323,7 @@ Optional Features:
|
|||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
--enable-shared create shared libraries (ok, but not recommended)
|
||||
--enable-standalone create a standalone shared library
|
||||
--enable-pthread link with pthreads (usually auto-enabled if needed)
|
||||
--enable-iconv use iconv (usually auto-enabled)
|
||||
|
||||
|
@ -2247,6 +2252,11 @@ if test "${enable_shared+set}" = set; then :
|
|||
enableval=$enable_shared;
|
||||
fi
|
||||
|
||||
# Check whether --enable-standalone was given.
|
||||
if test "${enable_standalone+set}" = set; then :
|
||||
enableval=$enable_standalone;
|
||||
fi
|
||||
|
||||
# Check whether --enable-pthread was given.
|
||||
if test "${enable_pthread+set}" = set; then :
|
||||
enableval=$enable_pthread;
|
||||
|
@ -2262,6 +2272,13 @@ if test "${enable_iconv}" = "" ; then
|
|||
enable_iconv=yes
|
||||
fi
|
||||
|
||||
skip_iconv_check=no
|
||||
|
||||
# For standalone builds:
|
||||
rktio_version=1.0
|
||||
HIDE_STANDALONE=hide_standalone_
|
||||
HIDE_NOT_STANDALONE=
|
||||
|
||||
###### Autoconfigure #######
|
||||
|
||||
ac_ext=c
|
||||
|
@ -3349,6 +3366,14 @@ case "$host_os" in
|
|||
|
||||
# -pthread is not needed and triggers a warning
|
||||
use_flag_pthread=no
|
||||
|
||||
# Use custom non-libtool build for a shared object
|
||||
if test "${enable_standalone}" = "yes" ; then
|
||||
if test "${enable_shared}" = "" ; then
|
||||
enable_shared=no
|
||||
make_darwin_dylib=yes
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
nto-qnx*)
|
||||
use_flag_pthread=no
|
||||
|
@ -4168,9 +4193,20 @@ fi
|
|||
|
||||
############## libtool ################
|
||||
|
||||
if test "${enable_standalone}" = "yes" ; then
|
||||
HIDE_STANDALONE=""
|
||||
HIDE_NOT_STANDALONE=hide_not_standalone_
|
||||
if test "${enable_shared}" = "" ; then
|
||||
enable_shared=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${enable_shared}" = "yes" ; then
|
||||
echo "Configuring libtool"
|
||||
|
||||
# Assuming an absolute "${libdir}":
|
||||
abslibdir="${libdir}"
|
||||
|
||||
if test ! -d "../lt" ; then
|
||||
mkdir "../lt"
|
||||
fi
|
||||
|
@ -4193,24 +4229,35 @@ if test "${enable_shared}" = "yes" ; then
|
|||
fi
|
||||
fi
|
||||
|
||||
AR="${LIBTOOLPROG} --mode=link --tag=CC $CC${need_gcc_static_libgcc}${ar_libtool_no_undefined} -release ${plt_lib_version} \$(ARLIBFLAGS) -o"
|
||||
# Use only for standalone builds:
|
||||
AR="${LIBTOOLPROG} --mode=link --tag=CC $CC${need_gcc_static_libgcc}${ar_libtool_no_undefined} -release ${rktio_version} -rpath ${abslibdir} \$(ARLIBFLAGS) -o"
|
||||
# Used for a librktio convenience library:
|
||||
STATIC_AR="${LIBTOOLPROG} --mode=link --tag=CC $CC -o"
|
||||
ARFLAGS=""
|
||||
RANLIB=":"
|
||||
|
||||
RKTLINKER="${LIBTOOLPROG} --mode=link --tag=CC $CC${need_gcc_static_libgcc}"
|
||||
CC="${LIBTOOLPROG} --mode=compile --tag=CC $CC"
|
||||
LIBSFX=la
|
||||
LTO="lo"
|
||||
LTA="la"
|
||||
STRIP_LIB_DEBUG=":"
|
||||
LIBSFX=la
|
||||
ICP_LIB="${LIBTOOLPROG} --mode=install install -s"
|
||||
else
|
||||
LIBSFX=a
|
||||
ICP=cp
|
||||
ICP_LIB=cp
|
||||
LTO="o"
|
||||
LTA="a"
|
||||
RKTLINKER='$(CC)'
|
||||
STATIC_AR="$AR"
|
||||
LIBSFX=so
|
||||
ICP_LIB=cp
|
||||
if test "${make_darwin_dylib}" = "yes" ; then
|
||||
LIBSFX="dylib"
|
||||
AR='$(RKTLINKER) --shared -o'
|
||||
ARFLAGS=""
|
||||
LIBS="${LIBS} -framework CoreFoundation"
|
||||
ICP_LIB=cp
|
||||
fi
|
||||
fi
|
||||
|
||||
############## final output ################
|
||||
|
@ -4228,6 +4275,11 @@ fi
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
makefiles="Makefile"
|
||||
|
||||
ac_config_files="$ac_config_files $makefiles"
|
||||
|
|
|
@ -10,14 +10,22 @@ AC_CONFIG_HEADERS([rktio_config.h])
|
|||
AC_CONFIG_AUX_DIR(../lt)
|
||||
AC_CANONICAL_SYSTEM
|
||||
|
||||
AC_ARG_ENABLE(shared, [ --enable-shared create shared libraries (ok, but not recommended)])
|
||||
AC_ARG_ENABLE(pthread, [ --enable-pthread link with pthreads (usually auto-enabled if needed)])
|
||||
AC_ARG_ENABLE(iconv, [ --enable-iconv use iconv (usually auto-enabled)])
|
||||
AC_ARG_ENABLE(shared, [ --enable-shared create shared libraries (ok, but not recommended)])
|
||||
AC_ARG_ENABLE(standalone, [ --enable-standalone create a standalone shared library])
|
||||
AC_ARG_ENABLE(pthread, [ --enable-pthread link with pthreads (usually auto-enabled if needed)])
|
||||
AC_ARG_ENABLE(iconv, [ --enable-iconv use iconv (usually auto-enabled)])
|
||||
|
||||
if test "${enable_iconv}" = "" ; then
|
||||
enable_iconv=yes
|
||||
fi
|
||||
|
||||
skip_iconv_check=no
|
||||
|
||||
# For standalone builds:
|
||||
rktio_version=1.0
|
||||
HIDE_STANDALONE=hide_standalone_
|
||||
HIDE_NOT_STANDALONE=
|
||||
|
||||
###### Autoconfigure #######
|
||||
|
||||
AC_PROG_CC
|
||||
|
@ -100,6 +108,14 @@ case "$host_os" in
|
|||
|
||||
# -pthread is not needed and triggers a warning
|
||||
use_flag_pthread=no
|
||||
|
||||
# Use custom non-libtool build for a shared object
|
||||
if test "${enable_standalone}" = "yes" ; then
|
||||
if test "${enable_shared}" = "" ; then
|
||||
enable_shared=no
|
||||
make_darwin_dylib=yes
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
nto-qnx*)
|
||||
use_flag_pthread=no
|
||||
|
@ -301,9 +317,20 @@ fi
|
|||
|
||||
############## libtool ################
|
||||
|
||||
if test "${enable_standalone}" = "yes" ; then
|
||||
HIDE_STANDALONE=""
|
||||
HIDE_NOT_STANDALONE=hide_not_standalone_
|
||||
if test "${enable_shared}" = "" ; then
|
||||
enable_shared=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${enable_shared}" = "yes" ; then
|
||||
echo "Configuring libtool"
|
||||
|
||||
# Assuming an absolute "${libdir}":
|
||||
abslibdir="${libdir}"
|
||||
|
||||
if test ! -d "../lt" ; then
|
||||
mkdir "../lt"
|
||||
fi
|
||||
|
@ -326,24 +353,35 @@ if test "${enable_shared}" = "yes" ; then
|
|||
fi
|
||||
fi
|
||||
|
||||
AR="${LIBTOOLPROG} --mode=link --tag=CC $CC${need_gcc_static_libgcc}${ar_libtool_no_undefined} -release ${plt_lib_version} \$(ARLIBFLAGS) -o"
|
||||
# Use only for standalone builds:
|
||||
AR="${LIBTOOLPROG} --mode=link --tag=CC $CC${need_gcc_static_libgcc}${ar_libtool_no_undefined} -release ${rktio_version} -rpath ${abslibdir} \$(ARLIBFLAGS) -o"
|
||||
# Used for a librktio convenience library:
|
||||
STATIC_AR="${LIBTOOLPROG} --mode=link --tag=CC $CC -o"
|
||||
ARFLAGS=""
|
||||
RANLIB=":"
|
||||
|
||||
RKTLINKER="${LIBTOOLPROG} --mode=link --tag=CC $CC${need_gcc_static_libgcc}"
|
||||
CC="${LIBTOOLPROG} --mode=compile --tag=CC $CC"
|
||||
LIBSFX=la
|
||||
LTO="lo"
|
||||
LTA="la"
|
||||
STRIP_LIB_DEBUG=":"
|
||||
LIBSFX=la
|
||||
ICP_LIB="${LIBTOOLPROG} --mode=install install -s"
|
||||
else
|
||||
LIBSFX=a
|
||||
ICP=cp
|
||||
ICP_LIB=cp
|
||||
LTO="o"
|
||||
LTA="a"
|
||||
RKTLINKER='$(CC)'
|
||||
STATIC_AR="$AR"
|
||||
LIBSFX=so
|
||||
ICP_LIB=cp
|
||||
if test "${make_darwin_dylib}" = "yes" ; then
|
||||
LIBSFX="dylib"
|
||||
AR='$(RKTLINKER) --shared -o'
|
||||
ARFLAGS=""
|
||||
LIBS="${LIBS} -framework CoreFoundation"
|
||||
ICP_LIB=cp
|
||||
fi
|
||||
fi
|
||||
|
||||
############## final output ################
|
||||
|
@ -351,16 +389,21 @@ fi
|
|||
AC_SUBST(CC)
|
||||
AC_SUBST(CFLAGS)
|
||||
AC_SUBST(LDFLAGS)
|
||||
AC_SUBST(LIBS)
|
||||
AC_SUBST(RKTLINKER)
|
||||
AC_SUBST(AR)
|
||||
AC_SUBST(ARFLAGS)
|
||||
AC_SUBST(RANLIB)
|
||||
AC_SUBST(STATIC_AR)
|
||||
AC_SUBST(ICP_LIB)
|
||||
|
||||
AC_SUBST(LIBSFX)
|
||||
AC_SUBST(LTO)
|
||||
AC_SUBST(LTA)
|
||||
|
||||
AC_SUBST(HIDE_NOT_STANDALONE)
|
||||
AC_SUBST(HIDE_STANDALONE)
|
||||
|
||||
makefiles="Makefile"
|
||||
|
||||
AC_OUTPUT($makefiles)
|
||||
|
|
|
@ -63,7 +63,7 @@ static rktio_ltps_t *try_check_ltps(rktio_t *rktio,
|
|||
if (!h1
|
||||
&& (rktio_get_last_error_kind(rktio) == RKTIO_ERROR_KIND_RACKET)
|
||||
&& (rktio_get_last_error(rktio) == RKTIO_ERROR_UNSUPPORTED)) {
|
||||
check_valid(rktio_ltps_close(rktio, lt));
|
||||
rktio_ltps_close(rktio, lt);
|
||||
return NULL;
|
||||
}
|
||||
check_expected_racket_error(!h1, RKTIO_ERROR_LTPS_NOT_FOUND);
|
||||
|
@ -240,7 +240,7 @@ static void check_read_write_pair(rktio_t *rktio, rktio_fd_t *fd, rktio_fd_t *fd
|
|||
check_valid(rktio_poll_read_ready(rktio, fd) == RKTIO_POLL_READY);
|
||||
if (lt) {
|
||||
check_ltps_read_ready(rktio, lt, h1);
|
||||
check_valid(rktio_ltps_close(rktio, lt));
|
||||
rktio_ltps_close(rktio, lt);
|
||||
}
|
||||
|
||||
if (rktio_fd_is_udp(rktio, fd)) {
|
||||
|
@ -742,7 +742,7 @@ int main(int argc, char **argv)
|
|||
lt = try_check_ltps(rktio, fd, fd2, &h1, &h2);
|
||||
check_valid(lt);
|
||||
check_ltps_read_and_write_ready(rktio, lt, h1, h2);
|
||||
check_valid(rktio_ltps_close(rktio, lt));
|
||||
rktio_ltps_close(rktio, lt);
|
||||
check_valid(rktio_close(rktio, fd));
|
||||
check_valid(rktio_close(rktio, fd2));
|
||||
}
|
||||
|
|
192
racket/src/rktio/parse.rkt
Normal file
192
racket/src/rktio/parse.rkt
Normal file
|
@ -0,0 +1,192 @@
|
|||
#lang racket/base
|
||||
(require racket/cmdline
|
||||
racket/pretty
|
||||
parser-tools/lex
|
||||
(prefix-in : parser-tools/lex-sre)
|
||||
parser-tools/yacc)
|
||||
|
||||
(define output-file #f)
|
||||
|
||||
(define input-file
|
||||
(command-line
|
||||
#:once-each
|
||||
[("-o") file "Write output to <file>"
|
||||
(set! output-file file)]
|
||||
#:args
|
||||
(file)
|
||||
file))
|
||||
|
||||
(define-tokens content-tokens
|
||||
(ID NUM))
|
||||
|
||||
(define-empty-tokens delim-tokens
|
||||
(EOF WHITESPACE
|
||||
OPEN CLOSE COPEN CCLOSE SEMI COMMA STAR LSHIFT EQUAL
|
||||
__RKTIO_H__ EXTERN EXTERN/NOERR EXTERN/STEP
|
||||
DEFINE TYPEDEF ENUM STRUCT VOID UNSIGNED SHORT INT CONST))
|
||||
|
||||
(define lex
|
||||
(lexer-src-pos
|
||||
[(eof) 'EOF]
|
||||
[";" 'SEMI]
|
||||
["(" 'OPEN]
|
||||
[")" 'CLOSE]
|
||||
["{" 'COPEN]
|
||||
["}" 'CCLOSE]
|
||||
["*" 'STAR]
|
||||
["," 'COMMA]
|
||||
["<<" 'LSHIFT]
|
||||
["=" 'EQUAL]
|
||||
[(:seq "#" (:* whitespace) "define") 'DEFINE]
|
||||
["typedef" 'TYPEDEF]
|
||||
["enum" 'ENUM]
|
||||
["struct" 'STRUCT]
|
||||
["void" 'VOID]
|
||||
["unsigned" 'UNSIGNED]
|
||||
["short" 'SHORT]
|
||||
["int" 'INT]
|
||||
["const" 'CONST]
|
||||
["__RKTIO_H__" '__RKTIO_H__]
|
||||
["RKTIO_EXTERN" 'EXTERN]
|
||||
["RKTIO_EXTERN_NOERR" 'EXTERN/NOERR]
|
||||
["RKTIO_EXTERN_STEP" 'EXTERN/STEP]
|
||||
[(:seq (:or #\_ (:/ #\A #\Z #\a #\z))
|
||||
(:* (:or #\_ (:/ #\A #\Z #\a #\z #\0 #\9))))
|
||||
(token-ID (string->symbol lexeme))]
|
||||
[(:seq (:? "-") (:+ (:/ "0" "9")))
|
||||
(token-NUM (string->number lexeme))]
|
||||
[(:seq "0x" (:+ (:/ "0" "9") (:/ "A" "F") (:/ "a" "f")))
|
||||
(token-NUM (string->number (substring lexeme 2) 16))]
|
||||
[(:+ (:or whitespace
|
||||
(:seq (:or "#include" "#if" "#endif") (:* (:~ "\n")))
|
||||
(:seq "/*"
|
||||
(:* (:or (:~ "*")
|
||||
(:seq (:+ "*") (:~ "/"))))
|
||||
"*/")))
|
||||
'WHITESPACE]))
|
||||
|
||||
(define parse
|
||||
(parser
|
||||
(start <prog>)
|
||||
(end EOF)
|
||||
(tokens content-tokens
|
||||
delim-tokens)
|
||||
(error (lambda (a t v start end)
|
||||
(error 'parse "failed at ~s" (list a t v start end))))
|
||||
(src-pos)
|
||||
(grammar
|
||||
(<prog> [() null]
|
||||
[(<decl> <prog>) (cons $1 $2)])
|
||||
(<decl> [(DEFINE ID <expr>) `(define ,$2 ,$3)]
|
||||
[(DEFINE __RKTIO_H__ <expr>) #f]
|
||||
[(DEFINE EXTERN ID) #f]
|
||||
[(DEFINE EXTERN/NOERR EXTERN) #f]
|
||||
[(DEFINE EXTERN/STEP EXTERN) #f]
|
||||
[(STRUCT ID SEMI) #f]
|
||||
[(TYPEDEF <type> <id> SEMI)
|
||||
(if (eq? $2 $3)
|
||||
#f
|
||||
`(define-type ,(unstar $3) ,(shift-stars $3 $2)))]
|
||||
[(TYPEDEF <type> COPEN <fields> ID SEMI)
|
||||
(if (eq? $2 $5)
|
||||
`(define-struct-type ,$2 ,$4)
|
||||
(error 'parse "typedef struct names don't match at ~s" $5))]
|
||||
[(<extern> <return-type> <id> OPEN <params> SEMI)
|
||||
(let ([r-type (shift-stars $3 $2)])
|
||||
`(,(adjust-errno $1 r-type) ,r-type ,(unstar $3) ,$5))]
|
||||
[(ENUM COPEN <enumeration> SEMI) `(begin . ,(enum-definitions $3))])
|
||||
(<extern> [(EXTERN) 'define-function/errno]
|
||||
[(EXTERN/STEP) 'define-function/errno+step]
|
||||
[(EXTERN/NOERR) 'define-function])
|
||||
(<params> [(VOID CLOSE) null]
|
||||
[(<paramlist>) $1])
|
||||
(<paramlist> [(<type> <id> CLOSE) `((,(shift-stars $2 $1) ,(unstar $2)))]
|
||||
[(<type> <id> COMMA <paramlist>) (cons `(,(shift-stars $2 $1) ,(unstar $2)) $4)])
|
||||
(<enumeration> [(CCLOSE) null]
|
||||
[(ID CCLOSE) (list $1)]
|
||||
[(ID COMMA <enumeration>) (cons $1 $3)]
|
||||
[(ID EQUAL <expr> COMMA <enumeration>)
|
||||
(cons `(,$1 ,$3) $5)])
|
||||
(<fields> [(CCLOSE) null]
|
||||
[(<type> <ids> <fields>)
|
||||
(append (map (lambda (id) `(,(shift-stars id $1) ,(unstar id))) $2)
|
||||
$3)])
|
||||
(<id> [(ID) $1]
|
||||
[(STAR <id>) `(* ,$2)])
|
||||
(<ids> [(<id> SEMI) (list $1)]
|
||||
[(<id> COMMA <ids>) (cons $1 $3)])
|
||||
(<expr> [(ID) $1]
|
||||
[(NUM) $1]
|
||||
[(OPEN <expr> CLOSE) $2]
|
||||
[(OPEN <expr> LSHIFT <expr> CLOSE) `(<< ,$2 ,$4)])
|
||||
(<type> [(ID) $1]
|
||||
[(CONST <type>) $2]
|
||||
[(UNSIGNED SHORT) `unsigned-short]
|
||||
[(UNSIGNED INT) `unsigned]
|
||||
[(UNSIGNED) 'unsigned]
|
||||
[(INT) 'int]
|
||||
[(SHORT) 'short]
|
||||
[(VOID) 'void]
|
||||
[(STRUCT ID) $2])
|
||||
(<return-type> [(<type>) $1]))))
|
||||
|
||||
(define (adjust-errno def-kind r)
|
||||
(cond
|
||||
[(eq? r 'rktio_bool_t) 'define-function]
|
||||
[(eq? r 'void) 'define-function]
|
||||
[else def-kind]))
|
||||
|
||||
(define (shift-stars from to)
|
||||
(if (and (pair? from)
|
||||
(eq? '* (car from)))
|
||||
`(* ,(shift-stars (cadr from) to))
|
||||
to))
|
||||
|
||||
(define (unstar from)
|
||||
(if (and (pair? from)
|
||||
(eq? '* (car from)))
|
||||
(unstar (cadr from))
|
||||
from))
|
||||
|
||||
(define (enum-definitions l)
|
||||
(let loop ([l l] [i 0])
|
||||
(cond
|
||||
[(null? l) null]
|
||||
[(pair? (car l))
|
||||
(let ([i (cadar l)])
|
||||
(cons
|
||||
`(define ,(caar l) ,i)
|
||||
(loop (cdr l) (add1 i))))]
|
||||
[else
|
||||
(cons
|
||||
`(define ,(car l) ,i)
|
||||
(loop (cdr l) (add1 i)))])))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(define content
|
||||
(call-with-input-file input-file
|
||||
(lambda (i)
|
||||
(port-count-lines! i)
|
||||
(parse (lambda ()
|
||||
(let loop ()
|
||||
(let ([v (lex i)])
|
||||
(cond
|
||||
[(eq? (position-token-token v) 'WHITESPACE) (loop)]
|
||||
[else v]))))))))
|
||||
|
||||
(define (show-content)
|
||||
(for ([e (in-list content)]
|
||||
#:when e)
|
||||
(if (and (pair? e)
|
||||
(eq? 'begin (car e)))
|
||||
(for ([e (in-list (cdr e))])
|
||||
(pretty-write e))
|
||||
(pretty-write e))))
|
||||
|
||||
(if output-file
|
||||
(with-output-to-file output-file
|
||||
#:exists 'truncate
|
||||
(lambda () (show-content)))
|
||||
(show-content))
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __RKTIO_H__
|
||||
#define __RKTIO_H__
|
||||
#define __RKTIO_H__ 1
|
||||
|
||||
/*
|
||||
|
||||
|
@ -45,6 +45,16 @@ Return type conventions:
|
|||
error reported by `rktio_get_last_error_kind` and
|
||||
`rktio_get_last_error`.
|
||||
|
||||
- A function annotated with `RKTIO_EXTERN_NOERR` always succeeds, so
|
||||
it never sets the error reported by `rktio_get_last_error_kind` and
|
||||
`rktio_get_last_error`. If a function returns `void` or
|
||||
`rktio_bool_t`, then `RKTIO_EXTERN` is implicitly
|
||||
`RKTIO_EXTERN_NOERR`.
|
||||
|
||||
- A function annotated with `RKTIO_EXTERN_STEP` sets the value
|
||||
to be reported by `rktio_get_last_error_step` when it returns a
|
||||
value that indicates an error.
|
||||
|
||||
Thread and signal conventions:
|
||||
|
||||
- A given `rktio_t` can be used from only one thread at a time.
|
||||
|
@ -72,6 +82,9 @@ Thread and signal conventions:
|
|||
# define RKTIO_EXTERN extern
|
||||
#endif
|
||||
|
||||
#define RKTIO_EXTERN_NOERR RKTIO_EXTERN
|
||||
#define RKTIO_EXTERN_STEP RKTIO_EXTERN
|
||||
|
||||
/*************************************************/
|
||||
/* Initialization and general datatypes */
|
||||
|
||||
|
@ -84,7 +97,7 @@ RKTIO_EXTERN rktio_t *rktio_init(void);
|
|||
`rktio_init` must return before any additional calls (in other
|
||||
threads), but there's no ordering requirement after that. */
|
||||
|
||||
RKTIO_EXTERN void rktio_destroy(rktio_t *);
|
||||
RKTIO_EXTERN void rktio_destroy(rktio_t *rktio);
|
||||
/* Call `rktio_destroy` as the last thing. Everything else must be
|
||||
explicitly deallocated/closed/forgotten before calling
|
||||
`rktio_destroy`. */
|
||||
|
@ -166,7 +179,7 @@ RKTIO_EXTERN rktio_fd_t *rktio_system_fd(rktio_t *rktio, intptr_t system_fd, int
|
|||
should include include `RKTIO_OPEN_SOCKET` and be non-blocking or
|
||||
use `RKTIO_OPEN_INIT`. */
|
||||
|
||||
RKTIO_EXTERN intptr_t rktio_fd_system_fd(rktio_t *rktio, rktio_fd_t *rfd);
|
||||
RKTIO_EXTERN_NOERR intptr_t rktio_fd_system_fd(rktio_t *rktio, rktio_fd_t *rfd);
|
||||
/* Extracts a native file descriptor or socket. */
|
||||
|
||||
RKTIO_EXTERN rktio_bool_t rktio_fd_is_regular_file(rktio_t *rktio, rktio_fd_t *rfd);
|
||||
|
@ -180,7 +193,7 @@ RKTIO_EXTERN rktio_bool_t rktio_fd_is_text_converted(rktio_t *rktio, rktio_fd_t
|
|||
/* Reports whether RKTIO_OPEN_TEXT was use and has an effect. The
|
||||
RKTIO_OPEN_TEXT flag has an effect only on Windows. */
|
||||
|
||||
RKTIO_EXTERN int rktio_fd_modes(rktio_t *rktio, rktio_fd_t *rfd);
|
||||
RKTIO_EXTERN_NOERR int rktio_fd_modes(rktio_t *rktio, rktio_fd_t *rfd);
|
||||
/* Returns all of the recorded mode flags, including those provided to
|
||||
`rktio_system_fd` and those that are inferred. The
|
||||
`RKTIO_OPEN_INIT` flag is not recorded, however. */
|
||||
|
@ -246,8 +259,8 @@ RKTIO_EXTERN intptr_t rktio_read_converted(rktio_t *rktio, rktio_fd_t *fd, char
|
|||
originally two characters that were converted to a single newline for
|
||||
text mode. */
|
||||
|
||||
RKTIO_EXTERN intptr_t rktio_buffered_byte_count(rktio_t *rktio, rktio_fd_t *fd);
|
||||
/* Reports the number of bytes that are buffered kfrom the file descriptor.
|
||||
RKTIO_EXTERN_NOERR intptr_t rktio_buffered_byte_count(rktio_t *rktio, rktio_fd_t *fd);
|
||||
/* Reports the number of bytes that are buffered from the file descriptor.
|
||||
The result is normally zero, but text-mode conversion and the rare
|
||||
uncooperative corner of an OS can make the result 1 byte. */
|
||||
|
||||
|
@ -280,7 +293,7 @@ RKTIO_EXTERN rktio_ok_t rktio_file_unlock(rktio_t *rktio, rktio_fd_t *rfd);
|
|||
|
||||
typedef rktio_int64_t rktio_filesize_t;
|
||||
|
||||
rktio_ok_t rktio_set_file_position(rktio_t *rktio, rktio_fd_t *rfd, rktio_filesize_t pos, int whence);
|
||||
RKTIO_EXTERN rktio_ok_t rktio_set_file_position(rktio_t *rktio, rktio_fd_t *rfd, rktio_filesize_t pos, int whence);
|
||||
/* Can report `RKTIO_ERROR_CANNOT_FILE_POSITION` on Windows. */
|
||||
/* For `whence`: */
|
||||
enum {
|
||||
|
@ -288,23 +301,23 @@ enum {
|
|||
RKTIO_POSITION_FROM_END
|
||||
};
|
||||
|
||||
rktio_filesize_t *rktio_get_file_position(rktio_t *rktio, rktio_fd_t *rfd);
|
||||
RKTIO_EXTERN rktio_filesize_t *rktio_get_file_position(rktio_t *rktio, rktio_fd_t *rfd);
|
||||
/* Returns the file position, not taking into account rare input
|
||||
buffering (see `rktio_read`). On Windows, can report
|
||||
`RKTIO_ERROR_CANNOT_FILE_POSITION`, which doesn't have a
|
||||
corresponding Windows error code. */
|
||||
|
||||
rktio_ok_t rktio_set_file_size(rktio_t *rktio, rktio_fd_t *rfd, rktio_filesize_t sz);
|
||||
RKTIO_EXTERN rktio_ok_t rktio_set_file_size(rktio_t *rktio, rktio_fd_t *rfd, rktio_filesize_t sz);
|
||||
/* Can report `RKTIO_ERROR_CANNOT_FILE_POSITION` on Windows. */
|
||||
|
||||
/*************************************************/
|
||||
/* Pipes */
|
||||
|
||||
rktio_fd_t **rktio_make_pipe(rktio_t *rktio, int flags);
|
||||
RKTIO_EXTERN rktio_fd_t **rktio_make_pipe(rktio_t *rktio, int flags);
|
||||
/* Makes a pair of file descriptors for a pipe. The first one
|
||||
is the read end, and the second is the write end. The `flags`
|
||||
can declare the intended sharing of the file descriptors
|
||||
with a child process, and it useful mainly on Windows. */
|
||||
with a child process, and is useful only on Windows. */
|
||||
/* For `flags`: */
|
||||
#define RKTIO_NO_INHERIT_INPUT (1<<0)
|
||||
#define RKTIO_NO_INHERIT_OUTPUT (1<<1)
|
||||
|
@ -320,7 +333,7 @@ RKTIO_EXTERN rktio_addrinfo_lookup_t *rktio_start_addrinfo_lookup(rktio_t *rktio
|
|||
int family, rktio_bool_t passive, rktio_bool_t tcp);
|
||||
/* The `family` argument should be one of the following: */
|
||||
#define RKTIO_FAMILY_ANY (-1)
|
||||
RKTIO_EXTERN int rktio_get_ipv4_family(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR int rktio_get_ipv4_family(rktio_t *rktio);
|
||||
|
||||
RKTIO_EXTERN rktio_tri_t rktio_poll_addrinfo_lookup_ready(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
|
||||
/* Check whether an address is available for a lookup request. */
|
||||
|
@ -331,7 +344,7 @@ RKTIO_EXTERN rktio_addrinfo_t *rktio_addrinfo_lookup_get(rktio_t *rktio, rktio_a
|
|||
RKTIO_EXTERN void rktio_addrinfo_lookup_stop(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
|
||||
/* Abandons a lookup whose result (or error) is not yet received. */
|
||||
|
||||
RKTIO_EXTERN void rktio_addrinfo_free(rktio_t *rktio, struct rktio_addrinfo_t *a);
|
||||
RKTIO_EXTERN void rktio_addrinfo_free(rktio_t *rktio, rktio_addrinfo_t *a);
|
||||
/* Frees the result of a lookup. */
|
||||
|
||||
typedef struct rktio_listener_t rktio_listener_t;
|
||||
|
@ -375,7 +388,7 @@ RKTIO_EXTERN rktio_fd_t *rktio_connect_trying(rktio_t *rktio, rktio_connect_t *c
|
|||
poll set, unregister it before trying to finish or stop the
|
||||
connection). */
|
||||
|
||||
RKTIO_EXTERN int rktio_socket_shutdown(rktio_t *rktio, rktio_fd_t *rfd, int mode);
|
||||
RKTIO_EXTERN rktio_ok_t rktio_socket_shutdown(rktio_t *rktio, rktio_fd_t *rfd, int mode);
|
||||
/* Useful for TCP to report an EOF to the other end. Does not close the socket,
|
||||
but may make it ineligible for forther use.
|
||||
`mode` values: */
|
||||
|
@ -486,7 +499,9 @@ typedef struct rktio_process_t rktio_process_t;
|
|||
|
||||
typedef struct rktio_process_result_t {
|
||||
rktio_process_t *process;
|
||||
rktio_fd_t *stdin_fd, *stdout_fd, *stderr_fd;
|
||||
rktio_fd_t *stdin_fd;
|
||||
rktio_fd_t *stdout_fd;
|
||||
rktio_fd_t *stderr_fd;
|
||||
} rktio_process_result_t;
|
||||
|
||||
RKTIO_EXTERN rktio_process_result_t *rktio_process(rktio_t *rktio,
|
||||
|
@ -500,12 +515,14 @@ RKTIO_EXTERN rktio_process_result_t *rktio_process(rktio_t *rktio,
|
|||
#define RKTIO_PROCESS_WINDOWS_EXACT_CMDLINE (1<<2)
|
||||
#define RKTIO_PROCESS_WINDOWS_CHAIN_TERMINATION (1<<3)
|
||||
|
||||
RKTIO_EXTERN int rktio_process_allowed_flags(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR int rktio_process_allowed_flags(rktio_t *rktio);
|
||||
/* Reports the flags that are accepted by `rktio_process` on the
|
||||
current OS. */
|
||||
|
||||
RKTIO_EXTERN int rktio_process_pid(rktio_t *rktio, rktio_process_t *sp);
|
||||
/* Always succeeds, whether or not the process is still running. */
|
||||
RKTIO_EXTERN_NOERR int rktio_process_pid(rktio_t *rktio, rktio_process_t *sp);
|
||||
/* Always succeeds, whether or not the process is still running, so
|
||||
the result is generally not meaningful if the process is not
|
||||
running. */
|
||||
|
||||
RKTIO_EXTERN rktio_ok_t rktio_process_kill(rktio_t *rktio, rktio_process_t *sp);
|
||||
RKTIO_EXTERN rktio_ok_t rktio_process_interrupt(rktio_t *rktio, rktio_process_t *sp);
|
||||
|
@ -536,7 +553,7 @@ RKTIO_EXTERN void rktio_reap_processes(rktio_t *rktio);
|
|||
/*************************************************/
|
||||
/* Filesystem-change events */
|
||||
|
||||
RKTIO_EXTERN int rktio_fs_change_properties(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR int rktio_fs_change_properties(rktio_t *rktio);
|
||||
/* Reports properties of the filesystem-change event implementation: */
|
||||
#define RKTIO_FS_CHANGE_SUPPORTED (1 << 0)
|
||||
#define RKTIO_FS_CHANGE_SCALABLE (1 << 1)
|
||||
|
@ -621,7 +638,7 @@ typedef struct rktio_ltps_handle_t rktio_ltps_handle_t;
|
|||
|
||||
RKTIO_EXTERN rktio_ltps_t *rktio_ltps_open(rktio_t *rktio);
|
||||
|
||||
RKTIO_EXTERN int rktio_ltps_close(rktio_t *rktio, rktio_ltps_t *lt);
|
||||
RKTIO_EXTERN void rktio_ltps_close(rktio_t *rktio, rktio_ltps_t *lt);
|
||||
/* Closing will signal all remianing handles and free all signaled
|
||||
handles, but use `rktio_ltps_remove_all` and
|
||||
`rktio_ltps_get_signaled_handle` is you need to clean up any
|
||||
|
@ -649,9 +666,9 @@ enum {
|
|||
};
|
||||
|
||||
RKTIO_EXTERN void rktio_ltps_handle_set_data(rktio_t *rktio, rktio_ltps_handle_t *h, void *data);
|
||||
RKTIO_EXTERN void *rktio_ltps_handle_get_data(rktio_t *rktio, rktio_ltps_handle_t *h);
|
||||
RKTIO_EXTERN_NOERR void *rktio_ltps_handle_get_data(rktio_t *rktio, rktio_ltps_handle_t *h);
|
||||
|
||||
void rktio_ltps_remove_all(rktio_t *rktio, rktio_ltps_t *lt);
|
||||
RKTIO_EXTERN void rktio_ltps_remove_all(rktio_t *rktio, rktio_ltps_t *lt);
|
||||
/* Removes all additions, signaling all handles. */
|
||||
|
||||
RKTIO_EXTERN rktio_ok_t rktio_ltps_poll(rktio_t *rktio, rktio_ltps_t *lt);
|
||||
|
@ -681,10 +698,10 @@ RKTIO_EXTERN void rktio_sleep(rktio_t *rktio, float nsecs, rktio_poll_set_t *fds
|
|||
/*************************************************/
|
||||
/* Files, directories, and links */
|
||||
|
||||
RKTIO_EXTERN int rktio_file_exists(rktio_t *rktio, const char *filename);
|
||||
RKTIO_EXTERN int rktio_directory_exists(rktio_t *rktio, const char *dirname);
|
||||
RKTIO_EXTERN int rktio_link_exists(rktio_t *rktio, const char *filename);
|
||||
RKTIO_EXTERN int rktio_is_regular_file(rktio_t *rktio, const char *filename);
|
||||
RKTIO_EXTERN rktio_bool_t rktio_file_exists(rktio_t *rktio, const char *filename);
|
||||
RKTIO_EXTERN rktio_bool_t rktio_directory_exists(rktio_t *rktio, const char *dirname);
|
||||
RKTIO_EXTERN rktio_bool_t rktio_link_exists(rktio_t *rktio, const char *filename);
|
||||
RKTIO_EXTERN rktio_bool_t rktio_is_regular_file(rktio_t *rktio, const char *filename);
|
||||
|
||||
RKTIO_EXTERN rktio_ok_t rktio_delete_file(rktio_t *rktio, const char *fn, int enable_write_on_fail);
|
||||
|
||||
|
@ -722,7 +739,7 @@ RKTIO_EXTERN rktio_filesize_t *rktio_file_size(rktio_t *rktio, const char *filen
|
|||
RKTIO_EXTERN rktio_timestamp_t *rktio_get_file_modify_seconds(rktio_t *rktio, const char *file);
|
||||
RKTIO_EXTERN rktio_ok_t rktio_set_file_modify_seconds(rktio_t *rktio, const char *file, rktio_timestamp_t secs);
|
||||
|
||||
typedef struct {
|
||||
typedef struct rktio_identity_t {
|
||||
uintptr_t a, b, c;
|
||||
int a_bits, b_bits, c_bits; /* size of each in bits */
|
||||
} rktio_identity_t;
|
||||
|
@ -775,20 +792,20 @@ RKTIO_EXTERN char **rktio_filesystem_roots(rktio_t *rktio);
|
|||
|
||||
typedef struct rktio_file_copy_t rktio_file_copy_t;
|
||||
|
||||
RKTIO_EXTERN rktio_file_copy_t *rktio_copy_file_start(rktio_t *rktio, const char *dest, const char *src,
|
||||
rktio_bool_t exists_ok);
|
||||
RKTIO_EXTERN_STEP rktio_file_copy_t *rktio_copy_file_start(rktio_t *rktio, const char *dest, const char *src,
|
||||
rktio_bool_t exists_ok);
|
||||
/* Starts a file copy. Depending on the OS, this step may perform the
|
||||
whole copy, or it may just get started. Can report
|
||||
`RKTIO_ERROR_EXISTS`, and sets an error step as listed further below. */
|
||||
|
||||
RKTIO_EXTERN rktio_bool_t rktio_copy_file_is_done(rktio_t *rktio, rktio_file_copy_t *fc);
|
||||
RKTIO_EXTERN rktio_ok_t rktio_copy_file_step(rktio_t *rktio, rktio_file_copy_t *fc);
|
||||
RKTIO_EXTERN_STEP rktio_ok_t rktio_copy_file_step(rktio_t *rktio, rktio_file_copy_t *fc);
|
||||
/* As long as the copy isn't done, call `rktio_copy_file_step` to make
|
||||
a little progress. Use `rktio_copy_file_finish_permissions`
|
||||
(optionally) and then `rktio_copy_file_stop` when done. An error
|
||||
sets an error step as listed further below. */
|
||||
|
||||
RKTIO_EXTERN rktio_ok_t rktio_copy_file_finish_permissions(rktio_t *rktio, rktio_file_copy_t *fc);
|
||||
RKTIO_EXTERN_STEP rktio_ok_t rktio_copy_file_finish_permissions(rktio_t *rktio, rktio_file_copy_t *fc);
|
||||
/* Depending on the OS, copies permissions from the source to the
|
||||
destination. This step can be performed at any time between the
|
||||
start and stop. Reports success if this step isn't needed (e.g.,
|
||||
|
@ -842,7 +859,7 @@ typedef struct rktio_signal_handle_t rktio_signal_handle_t;
|
|||
causes any `rktio_sleep` for that `rktio_t` to return (or causes
|
||||
the next `rktio_sleep` to return if one is not in progress. */
|
||||
|
||||
RKTIO_EXTERN rktio_signal_handle_t *rktio_get_signal_handle(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR rktio_signal_handle_t *rktio_get_signal_handle(rktio_t *rktio);
|
||||
/* Gets the handle for the given `rktio_t`. */
|
||||
|
||||
RKTIO_EXTERN void rktio_signal_received_at(rktio_signal_handle_t *h);
|
||||
|
@ -874,13 +891,13 @@ typedef struct rktio_date_t {
|
|||
char *zone_name; /* can be NULL; otherwise, free it */
|
||||
} rktio_date_t;
|
||||
|
||||
RKTIO_EXTERN intptr_t rktio_get_milliseconds(void);
|
||||
RKTIO_EXTERN double rktio_get_inexact_milliseconds(void);
|
||||
RKTIO_EXTERN_NOERR intptr_t rktio_get_milliseconds(void);
|
||||
RKTIO_EXTERN_NOERR double rktio_get_inexact_milliseconds(void);
|
||||
|
||||
RKTIO_EXTERN intptr_t rktio_get_process_milliseconds(rktio_t *rktio);
|
||||
RKTIO_EXTERN intptr_t rktio_get_process_children_milliseconds(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR intptr_t rktio_get_process_milliseconds(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR intptr_t rktio_get_process_children_milliseconds(rktio_t *rktio);
|
||||
|
||||
RKTIO_EXTERN rktio_timestamp_t rktio_get_seconds(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR rktio_timestamp_t rktio_get_seconds(rktio_t *rktio);
|
||||
RKTIO_EXTERN rktio_date_t *rktio_seconds_to_date(rktio_t *rktio, rktio_timestamp_t seconds, int nanoseconds, int get_gmt);
|
||||
|
||||
/*************************************************/
|
||||
|
@ -901,20 +918,20 @@ enum {
|
|||
RKTIO_SW_SHOWNORMAL
|
||||
};
|
||||
|
||||
rktio_ok_t rktio_shell_execute(rktio_t *rktio,
|
||||
const char *verb,
|
||||
const char *target,
|
||||
const char *arg,
|
||||
const char *dir,
|
||||
int show_mode);
|
||||
RKTIO_EXTERN rktio_ok_t rktio_shell_execute(rktio_t *rktio,
|
||||
const char *verb,
|
||||
const char *target,
|
||||
const char *arg,
|
||||
const char *dir,
|
||||
int show_mode);
|
||||
/* Supported only on Windows to run `ShellExecute`. The `dir` argument
|
||||
needs to have normalized path separators. */
|
||||
|
||||
/*************************************************/
|
||||
/* Path conversion */
|
||||
|
||||
rktio_char16_t *rktio_path_to_wide_path(rktio_t *rktio, const char *p);
|
||||
char *rktio_wide_path_to_path(rktio_t *rktio, const rktio_char16_t *wp);
|
||||
RKTIO_EXTERN rktio_char16_t *rktio_path_to_wide_path(rktio_t *rktio, const char *p);
|
||||
RKTIO_EXTERN_NOERR char *rktio_wide_path_to_path(rktio_t *rktio, const rktio_char16_t *wp);
|
||||
/* Convert to/from the OS's native path representation. These
|
||||
functions are useful only on Windows. The `rktio_path_to_wide_path`
|
||||
function can fail and report `RKTIO_ERROR_INVALID_PATH`. */
|
||||
|
@ -922,8 +939,8 @@ char *rktio_wide_path_to_path(rktio_t *rktio, const rktio_char16_t *wp);
|
|||
/*************************************************/
|
||||
/* Logging */
|
||||
|
||||
rktio_ok_t rktio_syslog(rktio_t *rktio, int level, const char *name, const char *msg,
|
||||
const char *exec_name);
|
||||
RKTIO_EXTERN rktio_ok_t rktio_syslog(rktio_t *rktio, int level, const char *name, const char *msg,
|
||||
const char *exec_name);
|
||||
/* Adds a message to the system log. The `name` argument can be NULL,
|
||||
and it is added to the front of the message with a separating ": "
|
||||
if non_NULL. The `exec_name` is the current executable name; it's
|
||||
|
@ -941,7 +958,7 @@ enum {
|
|||
/*************************************************/
|
||||
/* Encoding conversion */
|
||||
|
||||
int rktio_convert_properties(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR int rktio_convert_properties(rktio_t *rktio);
|
||||
/* Returns a combination of the following flags. */
|
||||
|
||||
#define RKTIO_CONVERTER_SUPPORTED (1 << 0)
|
||||
|
@ -950,16 +967,16 @@ int rktio_convert_properties(rktio_t *rktio);
|
|||
|
||||
typedef struct rktio_converter_t rktio_converter_t;
|
||||
|
||||
rktio_converter_t *rktio_converter_open(rktio_t *rktio, const char *to_enc, const char *from_enc);
|
||||
RKTIO_EXTERN rktio_converter_t *rktio_converter_open(rktio_t *rktio, const char *to_enc, const char *from_enc);
|
||||
/* Creates an encoding converter. */
|
||||
|
||||
void rktio_converter_close(rktio_t *rktio, rktio_converter_t *cvt);
|
||||
RKTIO_EXTERN void rktio_converter_close(rktio_t *rktio, rktio_converter_t *cvt);
|
||||
/* Destroys an encoding converter. */
|
||||
|
||||
intptr_t rktio_convert(rktio_t *rktio,
|
||||
rktio_converter_t *cvt,
|
||||
char **in, intptr_t *in_left,
|
||||
char **out, intptr_t *out_left);
|
||||
RKTIO_EXTERN intptr_t rktio_convert(rktio_t *rktio,
|
||||
rktio_converter_t *cvt,
|
||||
char **in, intptr_t *in_left,
|
||||
char **out, intptr_t *out_left);
|
||||
/* Converts some bytes, following the icon protocol: each consumed by
|
||||
increments `*in` and decrements `*in_left`, and each produced by
|
||||
increments `*out` and decrements `*out_left`. In case of an error,
|
||||
|
@ -972,15 +989,15 @@ intptr_t rktio_convert(rktio_t *rktio,
|
|||
|
||||
#define RKTIO_CONVERT_ERROR (-1)
|
||||
|
||||
char *rktio_locale_recase(rktio_t *rktio,
|
||||
rktio_bool_t to_up,
|
||||
char *in);
|
||||
RKTIO_EXTERN char *rktio_locale_recase(rktio_t *rktio,
|
||||
rktio_bool_t to_up,
|
||||
char *in);
|
||||
/* Upcases (of `to_up`) or downcases (if `!to_up`) the content of `in`
|
||||
using the current locale's encoding and case conversion. */
|
||||
|
||||
rktio_char16_t *rktio_recase_utf16(rktio_t *rktio,
|
||||
rktio_bool_t to_up, rktio_char16_t *s1,
|
||||
intptr_t len, intptr_t *olen);
|
||||
RKTIO_EXTERN rktio_char16_t *rktio_recase_utf16(rktio_t *rktio,
|
||||
rktio_bool_t to_up, rktio_char16_t *s1,
|
||||
intptr_t len, intptr_t *olen);
|
||||
/* Converts the case of a string encoded in UTF-16 for the system's
|
||||
default locale if the OS provided direct support for it. The
|
||||
`RKTIO_CONVERT_RECASE_UTF16 property from
|
||||
|
@ -988,15 +1005,15 @@ rktio_char16_t *rktio_recase_utf16(rktio_t *rktio,
|
|||
Takes and optionally returns a length (`olen` can be NULL), but the
|
||||
UTF-16 sequence is expected to have no nuls. */
|
||||
|
||||
int rktio_locale_strcoll(rktio_t *rktio, char *s1, char *s2);
|
||||
RKTIO_EXTERN int rktio_locale_strcoll(rktio_t *rktio, char *s1, char *s2);
|
||||
/* Returns -1 if `s1` is less than `s2` by the current locale's
|
||||
comparison, positive is `s1` is greater, and 0 if the strings
|
||||
are equal. */
|
||||
|
||||
int rktio_strcoll_utf16(rktio_t *rktio,
|
||||
rktio_char16_t *s1, intptr_t l1,
|
||||
rktio_char16_t *s2, intptr_t l2,
|
||||
rktio_bool_t cvt_case);
|
||||
RKTIO_EXTERN int rktio_strcoll_utf16(rktio_t *rktio,
|
||||
rktio_char16_t *s1, intptr_t l1,
|
||||
rktio_char16_t *s2, intptr_t l2,
|
||||
rktio_bool_t cvt_case);
|
||||
/* Compares two strings encoded in UTF-16 for the system's default
|
||||
locale if the OS provided direct support for it. The
|
||||
`RKTIO_CONVERT_STRCOLL_UTF16 property from
|
||||
|
@ -1004,29 +1021,29 @@ int rktio_strcoll_utf16(rktio_t *rktio,
|
|||
Takes lengths, but the UTF-16 sequences are expected to have
|
||||
no include nuls. */
|
||||
|
||||
char *rktio_locale_encoding(rktio_t *rktio);
|
||||
RKTIO_EXTERN char *rktio_locale_encoding(rktio_t *rktio);
|
||||
/* Returns the name of the current locale's encoding. */
|
||||
|
||||
void rktio_set_locale(rktio_t *rktio, char *name);
|
||||
RKTIO_EXTERN void rktio_set_locale(rktio_t *rktio, char *name);
|
||||
/* Sets the current locale, which affects string comparisons and
|
||||
conversions. It can also affect the C library's character-property
|
||||
predicates and number printing/parsing. The empty string
|
||||
corresponds to the OS's native locale. */
|
||||
|
||||
char *rktio_push_c_numeric_locale(rktio_t *rktio);
|
||||
void rktio_pop_c_numeric_locale(rktio_t *rktio, char *prev);
|
||||
RKTIO_EXTERN_NOERR char *rktio_push_c_numeric_locale(rktio_t *rktio);
|
||||
RKTIO_EXTERN void rktio_pop_c_numeric_locale(rktio_t *rktio, char *prev);
|
||||
/* Use this pair of funtions to temporarily switch the locale to the C
|
||||
locale for number parsing and printing. The result of the first
|
||||
function is deallocated when passed to second function. */
|
||||
|
||||
char *rktio_system_language_country(rktio_t *rktio);
|
||||
RKTIO_EXTERN char *rktio_system_language_country(rktio_t *rktio);
|
||||
/* Returns the current system's language in country in a 5-character
|
||||
format such as "en_US". */
|
||||
|
||||
/*************************************************/
|
||||
/* Errors */
|
||||
|
||||
RKTIO_EXTERN int rktio_get_last_error_kind(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR int rktio_get_last_error_kind(rktio_t *rktio);
|
||||
|
||||
/* Kinds of error values: */
|
||||
enum {
|
||||
|
@ -1036,7 +1053,7 @@ enum {
|
|||
RKTIO_ERROR_KIND_RACKET
|
||||
};
|
||||
|
||||
RKTIO_EXTERN int rktio_get_last_error(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR int rktio_get_last_error(rktio_t *rktio);
|
||||
|
||||
/* Error IDs of kind RKTIO_ERROR_KIND_RACKET */
|
||||
enum {
|
||||
|
@ -1073,7 +1090,7 @@ enum {
|
|||
RKTIO_ERROR_CONVERT_OTHER,
|
||||
};
|
||||
|
||||
RKTIO_EXTERN int rktio_get_last_error_step(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR int rktio_get_last_error_step(rktio_t *rktio);
|
||||
/* Some operations report further information about the step that
|
||||
failed. The meaning of a step number is operation-specific. */
|
||||
|
||||
|
@ -1086,8 +1103,8 @@ RKTIO_EXTERN void rktio_remap_last_error(rktio_t *rktio);
|
|||
for an OS-supplied error. This function can sometimes undo the
|
||||
substitition, modifying the current error and kind. */
|
||||
|
||||
RKTIO_EXTERN const char *rktio_get_last_error_string(rktio_t *rktio);
|
||||
RKTIO_EXTERN const char *rktio_get_error_string(rktio_t *rktio, int kind, int errid);
|
||||
RKTIO_EXTERN_NOERR const char *rktio_get_last_error_string(rktio_t *rktio);
|
||||
RKTIO_EXTERN_NOERR const char *rktio_get_error_string(rktio_t *rktio, int kind, int errid);
|
||||
/* The returned strings for `rktio_...error_string` should not be
|
||||
deallocated, but it only lasts reliably until the next call to
|
||||
either of the functions. */
|
||||
|
|
|
@ -147,7 +147,7 @@ rktio_poll_set_t *rktio_ltps_get_fd_set(rktio_ltps_t *lt)
|
|||
}
|
||||
#endif
|
||||
|
||||
int rktio_ltps_close(rktio_t *rktio, rktio_ltps_t *lt)
|
||||
void rktio_ltps_close(rktio_t *rktio, rktio_ltps_t *lt)
|
||||
{
|
||||
rktio_ltps_handle_t *s;
|
||||
|
||||
|
@ -167,8 +167,6 @@ int rktio_ltps_close(rktio_t *rktio, rktio_ltps_t *lt)
|
|||
#else
|
||||
rktio_poll_set_forget(rktio, lt->fd_set);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rktio_ltps_handle_t *rktio_ltps_get_signaled_handle(rktio_t *rktio, rktio_ltps_t *lt)
|
||||
|
|
Loading…
Reference in New Issue
Block a user