Syntax and Semantics of MetaC by Example
      /* the following
is a metaprogram that adds
control flow tracing */
      #include
"internal.mh"   /*
here compiler internal metafunctions are declared */
      
      /*
This metafuction will add
code for control flow tracing 
 * of branches within functions for a single function passed as 
 * parameter my_func with the new metadata type func, which 
 * represents a function.
 */
      meta void
trace_branch_entries(func my_func)
      {
       
/* The
following defines an array of statements called all_brances.
        
* Be
aware that MetaC arrays grow in size when the element after 
        
* the
last element is accessed. This is an extension to ISO-C99 for 
   * meta-functions. ISO-C99
has undefined behaviour for this operation.
        
*
Additionally, a pointer to meta-data-type statement is defined
        
*
called branch.
        
*/
         
stmt
all_branches[], *branch;
         
      strg msg;   /*
the meta-data-type strg represents
string literals */
         
msg = "entering
branch of " + ((strg) my_func);
         
msg += " at line
%i\n";
    /*
The
following line defines a statement code-structure-pattern,
     * which will be used to
instantiate code at the branches in 
     * control flow.
          
*/
    new_stm
:=
printf(msg,l);
    /*
now ask
the compiler for all branches within function my_func */
         
$get_all_branches(my_func,all_branches);
         
branch =
all_branches;
         
while (*branch) { 
    /*
The following line defines a
variable of metadatatype symbol,
          
* which can refer to a declaration with an identifier and type
          
*/
         
    symb l =
$get_symbol("__LINE__"); 
         
    /* insert code at the beginning of branch, pointed
to by branch */
   
    $begin(codeof
new_stm,*branch); 
         
   
++branch; 
         
}
      }
      
      /*
This is
the $main entry point of the meta-program. It
       *
gets
its parameters as array of string litterals, by
       *
convention.
       */
      meta void $main(strg
arg[])
{
      {
         
      func functions[], *f =
functions;
         
$get_all_functions(functions);
         
while (*f) { 
         
   
trace_branch_entries(*f); 
         
   
++f;
         
}
      } 
      
      
/* This is the C source code of the program we want to instrument. */
      /*
Code in bold fase has been inserted by the metaprogram
during execution in the MetaC compiler. */
      extern
int strlen(const char *);
      extern int printf(const
char *, ...);
      void
handle_args(char *arg)
      {
             
if ((strlen(arg) == 2)
&& (arg[0] == '-')) {
                     
      printf("entering
branch of handle_args at line %i\n", 6);
                     
switch (arg[1]) {
                             
case 'a': {
                                     
      printf("entering
branch of handle_args at line %i\n", 9);
                                     
printf("argument a\n");
                             
}
                             
break;
                             
case 'e': {
                                       printf("entering
branch of handle_args at line %i\n", 14);
                                     
printf("argument e\n");
                             
}
                             
break;
                             
default: {
                                     
      printf("entering
branch of handle_args at line %i\n", 19);
                                     
printf("unknown argument\n");
                             
}
                     
}
             
} else {
                     
      printf("entering
branch of handle_args at line %i\n", 24);
                     
printf("parameter: %s\n", arg);
             
}
      }
      
      int
main(int argc, char **argv)
      {
             
if (argc > 1) {
                     
int i = 1;
                     
      printf("entering
branch of main at line %i\n", 33);
                     
for (int x = argc - 1; x > 0; --x) {
                             
      printf("entering
branch of main at line %i\n", 35);
                             
printf("arg[%i] = \"
                                     
%s\"
                                     
\n", i, argv[i]);
                             
handle_args(argv[i]);
                             
++i;
                     
}
             
} else {
                     
      printf("entering
branch of main at line %i\n", 43);
                     
printf("no arguments");
             
}
             
return 0;
      }