(For Japanese version: 0.9.7におけるAPIの変更)
We introduced several incompatible API changes in 0.9.7, to pave the way for cleaner API in 1.0 release.
All C extensions needs to be recompiled, and might be required to modify the code.
The new Gauche header defines GAUCHE_API_0_97
preprocessor symbol. If you need your extensions to compile with both 0.9.7 and pre-0.9.7, you can switch it like this:
#if GAUCHE_API_0_97 /* Using new API */ #else /* Using old API */ #endif
We casually used int
in some places that hold the
size of strings and arrays. When Gauche was born, int
and
long
are 32bits on most platforms that runs Gauche.
Now that the world has moved on, 64bit architecture is norm and
32bit is not enough to hold sizes.
So we've rewritten APIs that takes or returns sizes with the following two types:
ScmSize
: This is an alias of ssize_t
.
ScmSmallInt
: This is a signed integer type that has large enough
to hold entire range of Scheme fixnum, which is 2-bit smaller than
the word size; in C level, it's basically long
.
Since we limit Scheme string and vector length within fixnum range,
C functions that deals with those Scheme objects take ScmSmallInt
to represent sizes and lengths. Other places that generally requires
size_t
or ssize_t
, we use ScmSize
(we treat everything
sigend).
If you call string or vector C API you'll likely to need to change them.
Especially if you pass int*
, you'll get compilation errors.
(Passing int
value as ScmSize
isn't much a problem).
The following is a list of C functions that are changed.
/* pre-0.9.7 */ /* 0.9.7 */ ScmObj Scm_ArrayToList( ScmObj Scm_ArrayToList( ScmObj *elts, ScmObj *elts, int nelts) ScmSize nelts) ScmObj Scm_AraryToListWithTail( ScmObj Scm_AraryToListWithTail( ScmObj *elts, ScmObj *elts, int nelts, ScmSize netls, ScmObj tail) ScmObj tail) ScmObj *Scm_ListToArray( ScmObj *Scm_ListToArray( ScmObj list, ScmObj list, int *nelts, ScmSize *nelts, ScmObj *store, ScmObj *store, int alloc) int alloc) int Scm_Length(ScmObj obj) ScmSize Scm_Length(ScmObj obj) ScmObj Scm_CopyStringWithFlags( ScmObj Scm_CopyStringWithFlags( ScmString *str, ScmString *str, int flags, u_long flags, int mask) u_long mask) const char *Scm_GetStringContent( const char *Scm_GetStringContent( ScmString *str, ScmString *str, u_int *psize, ScmSmallInt *psize, u_int *plen, ScmSmallInt *plen, u_int *pflags) u_long *pflags) ScmObj Scm_CStringArrayToList( ScmObj Scm_CStringArrayToList( const char **array, const char **array, int size, ScmSmallInt size, int flags) u_long flags) int Scm_DStringSize( ScmSmallInt Scm_DStringSize( ScmDString *ds) ScmDString *ds) ScmObj Scm_DStringGet( ScmObj Scm_DStringGet( ScmDString *ds, ScmDString *ds, int flags) u_long flags) const char *Scm_DStringPeek( const char *Scm_DStringPeek( ScmDString *ds, ScmDString *ds, int *size, ScmSmallInt *size, int *len) ScmSmallInt *len) void Scm_DStringPutz( void Scm_DStringPutz( ScmDString *ds, ScmDString *ds, const char *str, constr char *str, int siz) ScmSmallInt siz) int Scm_DStringTruncate( int Scm_DStringTruncate( ScmDString *ds, ScmDString *ds, int newsize) ScmSmallInt newsize) const uint8_t *Scm_GetBytes( const uint8_t *Scm_GetBytes( ScmObj str_or_vec, ScmObj str_or_vec, size_t *size) ScmSize *size) long Scm_ReadDigitsAsLong( long Scm_ReadDigitsAsLong( ScmPort *port, ScmPort *port, ScmChar ch, ScmChar ch, int radix, int radix, ScmChar *next, ScmChar *next, int *numread) ScmSize *numread) long Scm_ParseDigitsAsLong( long Scm_ParseDigitsAsLong( const char *buf, const char *buf, size_t len, ScmSize len, int radix, int radix, int *numread) ScmSize *numread) void Scm_Putz(const char *s, void Scm_Putz(const char *s, int len, ScmSize len, ScmPort *port) ScmPort *port) void Scm_PutzUnsafe(const char *s, void Scm_PutzUnsafe(const char *s, int len, ScmSize len, ScmPort *port) ScmPort *port) int Scm_Getz(char *buf, ScmSize Scm_Getz(char *buf, int buflen, ScmSize buflen, ScmPort *port) ScmPort *port) int Scm_GetzUnsafe(char *buf, ScmSize Scm_GetzUnsafe(char *buf, int buflen, ScmSize buflen, ScmPort *port) ScmPort *port)
We changed arguments of several procedures. The change has actually been
in place for years if you define C preprocessor symbol GAUCHE_API_0_95
to be true. We just made it true by default.
The following is the list of changes. To port old code to new API,
just pass 0 to flags
argument, SCM_FALSE
to src
and
describer
, and SCM_OBJ(SCM_CURERR)
to out
argument,
to get the same behavior.
/* pre-0.9.7 */ /* 0.9.7 */ ScmObj Scm_MakeMacro( ScmObj Scm_MakeMacro( ScmSymbol *name, ScmObj name, ScmObj transformer) ScmObj transformer, ScmObj src, ScmObj describer) ScmObj Scm_Raise(ScmObj exc) ScmObj Scm_Raise(ScmObj exc, u_long flags) ScmObj Scm_ReportError(ScmObj e) ScmObj Scm_ReportError(ScmObj e, ScmObj out) ScmObj Scm_VMThrowException( ScmObj Scm_VMThrowException( ScmVM *vm, ScmVM *vm, ScmObj exc) ScmObj exc, u_long flags)
We've had two layers of parameters; C API provides a basic thread-local storage, and Scheme layer is built on top of it to provide additional features such as filter procedure. To make it clear, we now call the lower-level parameter as ScmPrimitiveParameter, and provides new set of APIs.
We keep old API for a while, but urge extension modules to move to new API.
Old API:
void Scm_DefinePrimitiveParameter(ScmModule *mod, const char *name, ScmObj initval, ScmParameterLoc *location); ScmObj Scm_ParameterRef(ScmVM *vm, const ScmParameterLoc *loc); ScmObj Scm_ParameterSet(ScmVM *vm, const ScmParameterLoc *loc, ScmObj val); ScmObj Scm_InitParameterLoc(ScmVM *vm, ScmParameterLoc *loc, ScmObj initval);
New API:
ScmPrimitiveParameter *ScmPMakePrimitiveParameter(ScmClass *klass, ScmObj name, ScmObj initval, u_long flags); ScmPrimitiveParameter *Scm_BindPrimitiveParameter(ScmModule *mod, const char *name, ScmObj initval, u_long flags); ScmObj Scm_PrimitiveParameterRef(ScmVM *vm, const ScmPrimitiveParameter *p); ScmObj Scm_PrimitiveParameterSet(ScmVM *vm, const Scm_rimitiveParameter *p, ScmObj val);
Boehm GC used to require a manual registration of data area
of dynamically linked objects, and Gauche supports it by
generating small files (*_head.c
, *_tail.c
).
The gauche-config --fixup-extension
command creates
those files during build time.
Boehm GC doesn't need this handling for quite a while,
so we finally drop gauche-config --fixup-extension
feature
(it accepts the argument but no longer generates files).
We removed references for generated files (*_head.c
, *_tail.c
)
from the template Makefile.in
long time ago. But if your
extention predates that, your Makefile.in
may still have the reference
to those files. You need to remove them, or make fails
complaining it can't find these files.