# fn <TAB> return type <TAB> function name <TAB> param1 [<TAB> param2 ]...
# sizeof <TAB> type - provide size of type in %SIZE_OF
# const <TAB> name - provide constant value as perl constant.
# enum <TAB> name - same as above, but don't #ifdef it. Sets undocumented 'macro' flag for ExtUtils::Constant.

# Following metadata can be attached to a fn:
# #? <text> - POD documentation for following item. Multiple doc lines are concatenated.
# #: <name> - XS macro name for generating wrapper implementation automatically.
# #+ <name> - set a specific flag for the item.

# Flags:
# #+ no_pthx - wrapper function does not have pTHX argument.
# #+ _needs_sp - force implementation to pass SP as first argument to macro (normally macros just use it directly, but few take it explicitly).
# #+ _parens - force implementation to have parens after macro invocation (normally they are generated only if there are arguments).

#? Initialize ouroboros_stack_t object. Must be first thing called by a XS-sub. Equivalent to C<dXSARGS> macro automatically inserted by C<xsubpp> into every XS sub.
fn	void	ouroboros_stack_init	ouroboros_stack_t*

#? Returns number of arguments on Perl stack. Equivalent to C<items> local variable in XS.
fn	int	ouroboros_stack_items	ouroboros_stack_t*

#: XSprePUSH
fn	void	ouroboros_stack_prepush	ouroboros_stack_t*

#: PUTBACK
fn	void	ouroboros_stack_putback	ouroboros_stack_t*

#? Read a value from the stack. Equivalent of:
#?
#?     return ST(a);
#?
#? Perl macro: C<ST(n)>
fn	SV*	ouroboros_stack_fetch	ouroboros_stack_t*	SSize_t

#? Store a value on the stack. Equivalent of:
#?
#?     ST(a) = sv;
#?
#? Perl macro: C<ST>
fn	void	ouroboros_stack_store	ouroboros_stack_t*	SSize_t	SV*

#: EXTEND
#+ _needs_sp
fn	void	ouroboros_stack_extend	ouroboros_stack_t*	SSize_t

#: PUSHMARK
#+ _needs_sp
fn	void	ouroboros_stack_pushmark	ouroboros_stack_t*

#: SPAGAIN
fn	void	ouroboros_stack_spagain	ouroboros_stack_t*

#: XPUSHs
fn	void	ouroboros_stack_xpush_sv	ouroboros_stack_t*	SV*
#: mXPUSHs
fn	void	ouroboros_stack_xpush_sv_mortal	ouroboros_stack_t*	SV*
#: mXPUSHi
fn	void	ouroboros_stack_xpush_iv	ouroboros_stack_t*	IV
#: mXPUSHu
fn	void	ouroboros_stack_xpush_uv	ouroboros_stack_t*	UV
#: mXPUSHn
fn	void	ouroboros_stack_xpush_nv	ouroboros_stack_t*	NV
#: mXPUSHp
fn	void	ouroboros_stack_xpush_pv	ouroboros_stack_t*	const char*	STRLEN

#: PUSHs
fn	void	ouroboros_stack_push_sv	ouroboros_stack_t*	SV*
#: mPUSHs
fn	void	ouroboros_stack_push_sv_mortal	ouroboros_stack_t*	SV*
#: mPUSHi
fn	void	ouroboros_stack_push_iv	ouroboros_stack_t*	IV
#: mPUSHu
fn	void	ouroboros_stack_push_uv	ouroboros_stack_t*	UV
#: mPUSHn
fn	void	ouroboros_stack_push_nv	ouroboros_stack_t*	NV
#: mPUSHp
fn	void	ouroboros_stack_push_pv	ouroboros_stack_t*	const char*	STRLEN

#: SvIV
fn	IV	ouroboros_sv_iv	SV*
#: SvUV
fn	UV	ouroboros_sv_uv	SV*
#: SvNV
fn	NV	ouroboros_sv_nv	SV*
#: SvPV(,*)
fn	const char*	ouroboros_sv_pv	SV*	STRLEN*
#: SvPV_nolen
fn	const char*	ouroboros_sv_pv_nolen	SV*
#: SvROK
fn	U32	ouroboros_sv_rok	SV*
#: SvRV
fn	SV*	ouroboros_sv_rv	SV*
#: SvTYPE
fn	IV	ouroboros_sv_type	SV*

#: GvSV
fn	SV*	ouroboros_gv_sv	GV*
#: GvAV
fn	AV*	ouroboros_gv_av	GV*
#: GvHV
fn	HV*	ouroboros_gv_hv	GV*
#: GvCV
fn	CV*	ouroboros_gv_cv	CV*

#: SvREFCNT
fn	U32	ouroboros_sv_refcnt	SV*

# The next four functions actually wrap SvREFCNT_inc_simple_* macros.
# SvREFCNT_inc(_void)?(_nn)? are implemented as static functions to force
# one-time evaluation of their argument - we have it for free because
# we are wrapping it. These wrappers are necessary because SvREFCNT_*
# functions are declared as static and their symbols are not exported by Perl
# executable.

#: SvREFCNT_inc_simple
fn	SV*	ouroboros_sv_refcnt_inc	SV*
#: SvREFCNT_inc_simple_NN
fn	SV*	ouroboros_sv_refcnt_inc_nn	SV*
#: SvREFCNT_inc_simple_void
fn	void	ouroboros_sv_refcnt_inc_void	SV*
#: SvREFCNT_inc_simple_void_NN
fn	void	ouroboros_sv_refcnt_inc_void_nn	SV*

#: SvREFCNT_dec
fn	void	ouroboros_sv_refcnt_dec	SV*
#: SvREFCNT_dec_NN
fn	void	ouroboros_sv_refcnt_dec_nn	SV*

#: ENTER
fn	void	ouroboros_enter
#: LEAVE
fn	void	ouroboros_leave
#: SAVETMPS
fn	void	ouroboros_savetmps
#: FREETMPS
fn	void	ouroboros_freetmps

#: PERL_SYS_INIT3
#+ no_pthx
fn	void	ouroboros_sys_init3	int*	char***	char***
#: PERL_SYS_TERM
#+ no_pthx
#+ _parens
fn	void	ouroboros_sys_term

# Sizes of various types
sizeof	bool
sizeof	svtype
sizeof	PADOFFSET
sizeof	Optype
sizeof	ouroboros_stack_t

# Elements of svtype
enum	SVt_NULL
enum	SVt_IV
enum	SVt_NV
enum	SVt_PV
enum	SVt_PVIV
enum	SVt_PVNV
enum	SVt_PVMG
enum	SVt_REGEXP
enum	SVt_PVGV
enum	SVt_PVLV
enum	SVt_PVAV
enum	SVt_PVHV
enum	SVt_PVCV
enum	SVt_PVFM
enum	SVt_PVIO
enum	SVt_LAST

# Assorted SV related flags and constants. SV_CONST is not a const, but all SV_CONST_* are.
# r !awk '/\#define SV_/ && \!/SV_CHECK_/ && \!/SV_CONST[^_]/ { print("const\t" $2) }' sv.h

const	SV_IMMEDIATE_UNREF
const	SV_GMAGIC
const	SV_COW_DROP_PV
const	SV_UTF8_NO_ENCODING
const	SV_NOSTEAL
const	SV_CONST_RETURN
const	SV_MUTABLE_RETURN
const	SV_SMAGIC
const	SV_HAS_TRAILING_NUL
const	SV_COW_SHARED_HASH_KEYS
const	SV_COW_OTHER_PVS
const	SV_UNDEF_RETURNS_NULL
const	SV_FORCE_UTF8_UPGRADE
const	SV_SKIP_OVERLOAD
const	SV_CATBYTES
const	SV_CATUTF8
const	SV_CONST_TIESCALAR
const	SV_CONST_TIEARRAY
const	SV_CONST_TIEHASH
const	SV_CONST_TIEHANDLE
const	SV_CONST_FETCH
const	SV_CONST_FETCHSIZE
const	SV_CONST_STORE
const	SV_CONST_STORESIZE
const	SV_CONST_EXISTS
const	SV_CONST_PUSH
const	SV_CONST_POP
const	SV_CONST_SHIFT
const	SV_CONST_UNSHIFT
const	SV_CONST_SPLICE
const	SV_CONST_EXTEND
const	SV_CONST_FIRSTKEY
const	SV_CONST_NEXTKEY
const	SV_CONST_SCALAR
const	SV_CONST_OPEN
const	SV_CONST_WRITE
const	SV_CONST_PRINT
const	SV_CONST_PRINTF
const	SV_CONST_READ
const	SV_CONST_READLINE
const	SV_CONST_GETC
const	SV_CONST_SEEK
const	SV_CONST_TELL
const	SV_CONST_EOF
const	SV_CONST_BINMODE
const	SV_CONST_FILENO
const	SV_CONST_CLOSE
const	SV_CONST_DELETE
const	SV_CONST_CLEAR
const	SV_CONST_UNTIE
const	SV_CONST_DESTROY

# vim: set ts=12 tw=0 noet
