! Inline "C" Code operator
Purpose: BCX allows you pass inline "C" code using the exclamation mark (!) as an operator.
Syntax: ! /* "C" statement goes here */ |
Remarks: When ! is used outside of a BCX FUNCTION or SUB procedure, the emitted "C" code is located in the main function of the "C" translation.
Example: The following sample shows how to create a "C" coded local DWORD variable.
PRINT GetMachineName$() FUNCTION GetMachineName$ LOCAL A$ ! DWORD b; /* allocate a local variable in "C" and include "C" comments! */ b = 256 GetComputerName(A$, &b) ' the & operator means "PASS THE ADDRESS" of b FUNCTION = A$ END FUNCTION
$CCODE directive
Purpose: BCX allows you pass inline "C" code using a $CCODE directive placed before and after the "C" code.
Syntax 1: $CCODE /* "C" statements go here */ $CCODE |
Remarks: When $CCODE ... $CCODE is used without an optional parameter or if it is outside of a BCX FUNCTION or SUB procedure, the emitted "C" code is located in the main function of the "C" translation..
Example:
PRINT "BCX Code Here." $CCODE // declare the variables: int nNumber; int *pPointer; // now, give a value to them: nNumber = 15; pPointer = &nNumber; // print out the value of nNumber: printf("nNumber is equal to : %d\n", nNumber); // now, alter nNumber through pPointer: *pPointer = 25; // prove that nNumber has changed as a result of the above // by printing its value again: printf("nNumber is equal to : %d\n", nNumber); $CCODE PRINT "BCX Code Here."
Result:
BCX Code Here. nNumber is equal to : 15 nNumber is equal to : 25 BCX Code Here.
Syntax 2: $CCODE HEADER /* "C" statements go here */ $CCODE Parameters:
|
Example:
$CCODE HEADER #if VERSION == 1 #define INCFILE "vers1.h" #elif VERSION == 2 #define INCFILE "vers2.h" // and so on #else #define INCFILE "versN.h" #endif #include INCFILE $CCODE
Syntax 3: $CCODE ENUM /* "C" statements go here */ $CCODE Parameters:
|
Example:
$CCODE ENUM enum a{a=100,b,c,d=200,e,f}; $CCODE PRINT a, b, c, d, e, f
Result:
100 101 102 200 201 202
Syntax 4: $CCODE CONST /* "C" statements go here */ $CCODE Parameters:
|
Syntax 5: $CCODE UDT /* "C" statements go here */ $CCODE Parameters:
|
Example:
For $CCODE CONST and $CCODE UDT.
$CCODE CONST #define QWERTY_CLASS struct _QWERTY* $CCODE $CCODE UDT typedef struct _QWERTY { int a; float b; char c[80]; } QWERTY, *LPQWERTY; $CCODE GLOBAL MyType [10,10,10] AS QWERTY MyType [2,3,4].a = 1 MyType [2,3,4].b! = 2.345 MyType [2,3,4].c$ = "hello world from a poly-dimensional udt!" PRINT MyType[2,3,4].a PRINT MyType[2,3,4].b! PRINT UCASE$(MyType[2,3,4].c$)
Result:
1 2.345 HELLO WORLD FROM A POLY-DIMENSIONAL UDT!
Syntax 6: $CCODE SET /* "C" statements go here */ $CCODE Parameters:
|
Example:
TYPE foo A AS INTEGER B AS INTEGER C AS BYTE END TYPE $CCODE SET static foo MyFoo[]= { {12,13}, {19,20} }; $CCODE ? MyFoo[0].A ? MyFoo[0].B ? MyFoo[0].C ? MyFoo[1].A ? MyFoo[1].B ? MyFoo[1].C
Result:
12 13 0 19 20 0
Syntax 7: $CCODE FUNCSUB /* "C" statements go here */ $CCODE Parameters:
|
Remarks: $CCODE FUNCSUB is used to enclose a complete "C" code procedure. A prototype is not needed in this case because the placement in the emitted "C" source is before the main procedure.
Example:
DIM a$ DIM b$ a$ = " this is a test " b$ = Remove_All_White_Space(a$) PRINT b$ END PROGRAM $CCODE FUNCSUB char* Remove_All_White_Space(char* str1) { char *obuf,*nbuf; if (str1) { for (obuf=str1,nbuf=str1;*obuf; ++obuf) { if (!isspace(*obuf)) *nbuf++=*obuf; } *nbuf=0; } return str1; } $CCODE
Remarks: The top to bottom order of placement of the "C" code translated from the $CCODE directives is
$HEADER directive
Purpose: The $HEADER directive works like $CCODE except everything sandwiched between two $HEADER statements is placed at the file scope level of the emitted "C" source. $HEADER is useful particularly for pragma statements and declaring prototypes for inlined "C" source functions. A $HEADER directive is placed before and after the "C" code.
Syntax: $HEADER /* "C" statements go here */ $HEADER |
Example:
$HEADER #define KitchenSinkIsIncluded $HEADER $HEADER #ifndef KitchenSinkIsIncluded #include <KitchenSink.h> #else #define CallThePlumber 1 #endif $HEADER
$CPROTO directive
Purpose: The $CPROTO directive is used for declaring prototypes for inlined "C" source functions.
Syntax 1: $CPROTO ! ProcedureDataType ProcedureName(ParameterDataType); |
Remarks: When using $CPROTO with a
"C" language prototype, a space-exclamation mark-space must precede
the prototype. Also remember, that in "C", a semicolon is required
at the end of of the prototype.
Everything following the $CPROTO ! is
placed at the file scope level of the emitted "C" source in the
'User's Prototypes' section.
Example:
$CPROTO ! char* Remove_All_White_Space(char*); DIM a$ DIM b$ a$ = " this is a test " b$ = Remove_All_White_Space(a$) PRINT b$ END PROGRAM $CCODE char* Remove_All_White_Space(char* str1) { char *obuf,*nbuf; if (str1) { for (obuf=str1,nbuf=str1;*obuf; ++obuf) { if (!isspace(*obuf)) *nbuf++=*obuf; } *nbuf=0; } return str1; } $CCODE
Syntax 2: $CPROTO [FUNCTION/SUB] Foo$(a%, b$) |
Remarks: $CPROTO, also, will accept a BCX FUNCTION or SUB declaration which will be translated to "C" code and placed correctly in the 'User Prototypes' section of the "C" translation.
Example:
$CPROTO FUNCTION Remove_All_White_Space$(a$) DIM a$ DIM b$ a$ = " this is a test " b$ = Remove_All_White_Space(a$) PRINT b$ END PROGRAM ! char* Remove_All_White_Space(char* str1) ! { ! char *obuf,*nbuf; ! if (str1) ! { ! for (obuf=str1,nbuf=str1;*obuf; ! ++obuf) ! { ! if (!isspace(*obuf)) ! *nbuf++=*obuf; ! } ! *nbuf=0; ! } ! return str1; ! }
$PRAGMA directive
Purpose : The $PRAGMA directive is translated to the C keyword #pragma. The utility and syntax varies between compilers for the #pragma directives.
Syntax: $PRAGMA compiler specific instruction and arguments |
Example: To include the Dwmapi.lib library to a code compilation using Microsoft or Pelles C, use this
$PRAGMA comment(LIB, "Dwmapi.lib")
For a MinGW compiler use this
$PRAGMA LIB "Dwmapi.lib"
Remarks:
Details for using pragma directives with the Microsoft compiler are available on their Microsoft Pragma directives and the __pragma and _Pragma keywords page.
Pragma information for the MinGW compilers can be found at Pragmas Accepted by GCC page.
Here is a snippet of code from the BCX translator which shows how $PRAGMA is used to suppress a MinGW compiler generated warning. A $PRAGMA "diagnostic ignored" is placed immediately before the cast to CPP_FARPROC that causes the warning. The $PRAGMA "diagnosic pop" restores the diagnostics to their previous condition.
$IFDEF (__GNUC__) $PRAGMA GCC diagnostic ignored "-Wcast-function-type" PPProc = (CPP_FARPROC) GetProcAddress (PPDLL_HANDLE,"ProcessLine"); $PRAGMA GCC diagnostic pop $ELSE PPProc = (CPP_FARPROC) GetProcAddress (PPDLL_HANDLE,"ProcessLine"); $ENDIF