This change set adds support for the C preprocessor to SLANG.
Two new methods are supported:
Object>>cppDirective
Object>>cppIfDef:inSmalltalk:comment:ifTrue:ifFalse:
Examples:
The Smalltalk expression:
self cppDirective: 'ifdef HAS_FOO'.
self doFooStuff.
self cppDirective: 'endif'.
is translated to:
# ifdef HAS_FOO
doFooStuff();
# endif
The Smalltalk expression:
self cppIfDef: 'HAVE_FOO'
inSmalltalk: [if self haveFoo]
comment: 'some platforms do not support foo properly'
ifTrue: [self doThingsThatWorkIfFooIsPresent]
ifFalse: [self doSomethingElseInstead].
is translated to:
# ifdef SOMETHING // system supports foo
doThingsThatWorkIfFooIsPresent();
# else
doSomethingElseInstead();
# endif // SOMETHING
Here is an example of a method that uses the C preprocessor:
primitiveUnsetEnv
"Unset an environment variable."
| cStringPtr keyString |
self export: true.
self var: 'cStringPtr' declareC: 'char *cStringPtr'.
keyString _ interpreterProxy stackObjectValue: 0.
cStringPtr _ self transientCStringFromString: keyString.
self cppIfDef: 'HAVE_UNSETENV'
inSmalltalk: [true]
comment: 'unsetenv() is not portable'
ifTrue: [self unsetenv: cStringPtr]
ifFalse: [interpreterProxy primitiveFail].
interpreterProxy pop: 1
The generated C code in the plugin is:
EXPORT(int) primitiveUnsetEnv(void) {
int keyString;
char *cStringPtr;
keyString = interpreterProxy->stackObjectValue(0);
cStringPtr = transientCStringFromString(keyString);
# ifdef HAVE_UNSETENV // unsetenv() is not portable
unsetenv(cStringPtr);
# else
interpreterProxy->primitiveFail();
# endif // HAVE_UNSETENV
interpreterProxy->pop(1);
}
Dave