Blocks ------ C++ code is incredibly complex before you consider things such as template metaprogramming and the preprocessor. Figuring out a way to correctly handle any possible combinations of C++ constructs in a way that would be universally applicable as well as intuitive is beyond the powers of Macaroni. That's OK though because Macaroni includes a way to insert naked C++ code when the parser itself is not accomodating enough to do what you might need. The ~block keyword ^^^^^^^^^^^^^^^^^^ Usage: .. code-block:: c++ ~block "id" { /* code */ } The keyword "~block" tells Macaroni to put a block of text as-is into a generated file. ~block should be followed by a string containing the short ID of the generated file. This ID only makes sense in the context of what's being parsed. For example, if you place a "~block" into a class, then you usually want the text to appear in the class's H or CPP file. *Caution*: The block ID is dependent on the Macaroni source code generators, so in principle any "ID" is OK. However, unless you use the IDs specified below nothing will get written to the generated source CPP and H files. This may sound confusing but its actually pretty simple. Here are the possible use cases: Classes ~~~~~~~ Blocks put in classes end up in the class header of implementation file depending on the ID. Here's some examples: * *h-predef* - Appears in the header file, before the class definition. * h - Appears in the header file, inside the class definition. * *h-postdef* - Appears in the header file, after the class definition. * *cpp-include* - Appears in the implementation file, after the internal include statements but before the function definitions. * *cpp* - Appears in the implementation file, after the include statements, and interspersed with the function definitions. note: Note: The placement of "h" and "cpp" blocks depends on the order they are defined in the Macaroni source file. The following example shows all how all class blocks are applied. .. code-block:: c++ class BlocksExample { // This block gets put at the top of both files after the include guard. // This is an ideal spot for compile guards if a class should only work // with some specific configuration. ~block "top" { /* DISTRIBUTED BY ACME INC. PLEASE READ LICENSE.TXT FOR TERMS OF USE. */ } // This gets put at the bottom of both files. ~block "bottom" { /* THANK YOU FOR PLAYING! */ } private int field1; // This block gets put after the include statements in both the // header and internal header. ~block "h-predef" { #include } // This gets put inside the class defintion, in the order it was defined. // So this should appear after field1, but before field3. ~block "h" { private: int field2; } private int field3; // This will get put after the class definition. ~block "h-postdef" { void global_function(BlocksExample & ex); } public void Method1() { } // This gets put into the cpp file, after all the include and using // statements. This will be after the definition of Method1. ~block "cpp" { void global_function(BlocksExample & ex) { // ... } } // "cpp-include" gets put after the #include statements for the cpp file, // which happen after the internal header, and before the using statements. ~block "cpp-include" { #include } }; .. code-block:: c++ #ifndef MACARONI_UNIT_COMPILE_GUARD_BlocksExample_H #define MACARONI_UNIT_COMPILE_GUARD_BlocksExample_H #line 8 "Blocks.mcpp" /* DISTRIBUTED BY ACME INC. PLEASE READ LICENSE.TXT FOR TERMS OF USE. */ #line 8 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.h" #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif // Forward declaration for BlocksExample. class BlocksExample; #line 23 "Blocks.mcpp" #include #line 23 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.h" // Define class BlocksExample class MACARONI_LIB_DECL_Macaroni_46_Examples___Blocks____49__46_0_46_0_46_0___lib BlocksExample { private : int field1; #line 30 "Blocks.mcpp" private: int field2; #line 35 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.h" private : int field3; public : void Method1(); }; // End of class BlocksExample #line 38 "Blocks.mcpp" void global_function(BlocksExample & ex); #line 47 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.h" #line 14 "Blocks.mcpp" /* THANK YOU FOR PLAYING! */ #line 52 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.h" #endif //MACARONI_UNIT_COMPILE_GUARD_BlocksExample_H .. code-block:: c++ #ifndef MACARONI_UNIT_COMPILE_GUARD_BlocksExample_Cpp #define MACARONI_UNIT_COMPILE_GUARD_BlocksExample_Cpp // Force the use of the Internal Header: #define MACARONI_UNIT_COMPILE_GUARD_BlocksExample_H // The following configures symbols for export if needed. #define MACARONI_LIB_CREATE_Macaroni_46_Examples___Blocks____49__46_0_46_0_46_0___lib #line 8 "Blocks.mcpp" /* DISTRIBUTED BY ACME INC. PLEASE READ LICENSE.TXT FOR TERMS OF USE. */ #line 13 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.cpp" /*--------------------------------------------------------------------------* * Internal Header * *--------------------------------------------------------------------------*/ #include // Forward declaration for BlocksExample. class BlocksExample; #line 23 "Blocks.mcpp" #include #line 27 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.cpp" // Define class BlocksExample class MACARONI_LIB_DECL_Macaroni_46_Examples___Blocks____49__46_0_46_0_46_0___lib BlocksExample { private : int field1; #line 30 "Blocks.mcpp" private: int field2; #line 39 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.cpp" private : int field3; public : void Method1(); }; // End of class BlocksExample #line 38 "Blocks.mcpp" void global_function(BlocksExample & ex); #line 51 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.cpp" /*--------------------------------------------------------------------------* * Implementation * *--------------------------------------------------------------------------*/ #line 60 "Blocks.mcpp" #include #line 62 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.cpp" MACARONI_LIB_DECL_Macaroni_46_Examples___Blocks____49__46_0_46_0_46_0___lib void BlocksExample::Method1() { #line 43 "Blocks.mcpp" #line 73 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.cpp" } #line 50 "Blocks.mcpp" void global_function(BlocksExample & ex) { // ... } #line 82 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.cpp" #line 14 "Blocks.mcpp" /* THANK YOU FOR PLAYING! */ #line 89 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/BlocksExample.cpp" #endif //MACARONI_UNIT_COMPILE_GUARD_BlocksExample_Cpp Units ~~~~~ The ~unit keyword explicitly defines a Macaroni source file as belonging to a C++ translation unit which in Macaroni receives its own header and implementation file. The ~block keyword can be used here to make arbitrary C++ code appear in the generated file, which may be easier than writing Macaroni code if macros or other complex constructs are being used. Usually, the "till EOF" syntax should be used here to tell Macaroni the block of code ends at the end of the file. * *cpp - Appears in the cpp unit file. The following example shows how a cpp block is used with ~unit. .. code-block:: c++ ~unit Main type=exe ; ~import std::cout; ~import std::endl; ~block "cpp":= int main() { cout << "Hello world." << endl; } .. code-block:: c++ #ifndef MACARONI_UNIT_COMPILE_GUARD__126_unit_126_Main_Cpp #define MACARONI_UNIT_COMPILE_GUARD__126_unit_126_Main_Cpp // Force the use of the Internal Header: #define MACARONI_UNIT_COMPILE_GUARD__126_unit_126_Main_H // The following configures symbols for export if needed. #define MACARONI_LIB_CREATE_Macaroni_46_Examples___Blocks____49__46_0_46_0_46_0___Main /*--------------------------------------------------------------------------* * Internal Header * *--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------* * Implementation * *--------------------------------------------------------------------------*/ #include #include using std::cout; using std::endl; #line 8 "Main.mcpp" int main() { cout << "Hello world." << endl; } #line 29 "C:/Work/github/TimSimpson/Macaroni/Next/Tests/Examples/Blocks/target/Main.cpp" #endif //MACARONI_UNIT_COMPILE_GUARD__126_unit_126_Main_Cpp