/***************************************************************************
 * Module: c_project                                                       *
 *                                                                         *
 * Copyright (C) 1998 Mark Grosberg. All Rights Reserved.                  *
 *                                                                         *
 * The software is redistributable under the licence given in the          *
 * file "License" distributed in the AMC archive.                          *
 ***************************************************************************
 * Date:      98.12.04                                                     *
 * Author:    Mark Grosberg (myg)                                          *
 * Language:  CGL                                                          *
 ***************************************************************************
 * This file contains the standard definitions for AMC to handle projects  *
 * written in the 'C' programming language. It should be included in your  *
 * project files for projects involving the C language.                    *
 ***************************************************************************/

/* Set this to your tab-stop size or make it a \t */
proc _ = "   "; 

/* 
 * CommonHeader writes some standard header stuff to the interface of the 
 * module. It defines the module and makes the interface idempotent with 
 * respect to multiple inclusion. 
 */
proc CommonHeader =
     output_def("/* Definitions from module " mod_name
                " in "                         loc_name 
                "*/\n")
     module_id_symbol=(strupr(loc_name "_" fn_rmtype(fn_rmloc(src_fname))) 
                       "_"
                       strupr(fn_type(src_fname)))
     output_def("#ifndef " module_id_symbol "\n"
                "#define " module_id_symbol "\n")

     if 
     ( C_PutInModuleIdentifiers, 
       output_code
       (
          "\nstatic const char *module_id = \"" 
           write_as_c_string(loc_name "." mod_name)
          "\";\n"
       )
     )
     ;

/* 
 * C_ModuleHeader outputs the prolog for a C module header.
 */
proc C_ModuleHeader = 
     CommonHeader
     copy_intfc
     ;

/* 
 * C_ModuleFooter writes some standard footer stuff to the interface of the 
 * module. 
 */
proc C_ModuleFooter =
     output_def("#endif\n")
     ;

/*
 * C_HandleInterface defines some macros to help with avoiding
 * having to declare public variables twice (as C normally requires).
 *
 * This way you can declare global variables in the interface 
 * section of a module with this syntax:
 *
 *    shared unsigned long x init(= 7);
 *    shared int           y;
 *    shared FOO           myfoo init(= { 1, 2, "Hello" });
 *
 * 
 * This routine is called when the 'interface' keyword is processed
 * in source modules.
 */
proc C_HandleInterface = 
     output_both("\n")
     output_code("#define shared  /*Empty*/\n#define init(x) x\n")
     output_def("#define shared extern\n#define init(x) /*Empty*/\n")
     output_both(copy_c)
     output_both("\n#undef shared\n#undef init\n")
     ;

/*
 * C_HandleImplementation copies a body of code using the
 * 'C' code copier directly to the output file.
 * 
 * This routine is called when the 'implementation' keyword is processed
 * in source modules.
 */
proc C_HandleImplementation =
     "\n" 
     output_code(copy_c) 
     "\n"
     ;

/*
 * C_Body is called to parse the actual contents of a source module.
 * It uses the builtin CGL procedure 'parse_module' which processes
 * each keyword in the module and executes the appropriate CGL code.
 */
proc C_Body =
     parse_module
     (
          "implementation",  
             C_HandleImplementation,
          "interface",
             C_HandleInterface
     )
     ;

type c
{
   /* make: The OS command used to perform final processing on
    *       the output of AMC.
    */
   make  
   { 
     "gcc -c ${CFLAGS} " out_fname " -o " fn_rmtype(out_fname) ".o"  
   }

   /* compile: This CGL code is execute when compiling a module.
    */
   compile  
   {
     C_ModuleHeader
     C_Body  
     C_ModuleFooter   
   }

   /* out_ext: The output extension of the source files.
    */
   out_ext     "c";
}

proc main = 
          dynamic_call(~pre_init_hook, false)

          /* 
           * Disable the addition of module id's used for reporting
           * errors in embedded systems.
           */
          C_PutInModuleIdentifiers = (false)

          dynamic_call(~post_init_hook, false)
          ;

