This service takes two kinds of input and outputs C++ code which 
    can be used to help debug your program.  The two kinds of input 
    are C++ include files and "Middle" language files. 

    Input:

    The Middle language is something we made up and is used to control what 
    gets written and how.  Here is an example of Middle code:

    MessageManager
       (vector<vector<double> >, map<string, double>)
       (list<Account>, string [10]) 
       //(vector<Account*>, string [10]) 
    }

    The name you give, in this case, MessageManager, is used as the name of 
    the generated class.  
     
    After the name, you specify one or more lines as needed.  The program 
    will write a method based on each line.  The lines have the following 
    general form:

       (T1 [@as], T2 [@as], .... Tn [@as])
    
    Each line begins with a left paren.  T1 through Tn are types and should
    follow C++ syntax.  The braces indicate that what is contained in 
    them is optional.  Here are some more examples:                       

    MessageManager
       (double, string)
       (long, long)
    } 

    This will produce a class called MessageManager. Methods called  
    Print will be written.  The prototypes for the methods would be:

      void Print(std::ostream&, const double, const string&);
      void Print(std::ostream&, const long, const long);
 

    Sometimes one only wants to check a subset of a container.  The
    adaptive send(print) option, @as, is helpful in such circumstances.  
    This option is only applicable with container classes and makes 
    the most sense with a container that is sorted:

    Message
       (set<string> @as, double) 
    }


    In this example, the generated Print function would take a 
    set<string>::const_iterator and an integer count of how many 
    items to print.  This is handy because it helps to avoid printing 
    more information than is needed.  @as may only be used at the top 
    most level.  In other words, this won't work:

    Message
       (vector<set<int> @as >)
    }

Options have to be in lower case. // or /* ... */ comments are acceptable in Middle code. A lone } is used to indicate the end of the construct.

The other kind of input is regular C++ include files. There are some restrictions on the subset of C++ that we accept. We don't support:

   We accept namespace definitions, but we don't organize types with 
   respect to namespaces.  If you have two types with the same name 
   in different namespaces we will flag that as an error. 
    

   Here is an example of an include file that is acceptable to the program:

    #ifndef MENU
    #define MENU

    #include <string>
    #include <vector>
    #include <iostream>

    class Buffer;

    namespace llama {

    struct Base
    {
      Base() {}
      int Send(Buffer*, int = 0) const;    // These prototypes have to 
      int Receive(Buffer*);                // be added to your code.

      std::vector<std::string> baseFileNames;
    };

    const short insert = 301;
    const short remove = 302;

    class Derived : public Base
    {
     public:
      Derived() {}
      int Send(Buffer*, int = 0) const;  
      int Receive(Buffer*);              
  
     private:
      short op[12];
      unsigned int offset;
    };

   
    class FileInfo
    {
     public:
      FileInfo() 
      {}  
      
      ~FileInfo()
      {}
      
      friend struct FWKey;
      int Send(Buffer*, int = 0) const;
      int Receive(Buffer*);
      void Reset();
  
     private:
    #ifdef  SERVER
      short isnew;
      long modTime;
    #endif

      std::string introducedFileName;
      Derived  parts;
    };


    struct FWKey
    {
      const std::string& operator() (const FileInfo* inst)
      {
        return inst->introducedFileName;
      }
    };

    }
    #endif

 
    Given the above definitions we can write Middle code that uses
    the types:

    Messages
       (FileInfo*, string) 
       (vector<Base*>, short)
    }
 
    Of the two kinds of input, the middle file is required.  Include 
    files are optional.

    The Indentation Delta is used to control how many spaces you want 
    inserted before the data.  The members of a class are offset by this 
    value.  The value of this field must be greater than zero.
    
   Output: 

    Output is returned as text on the screen.


Setup Instructions:

  1. Modification to user defined types.
           The following function prototype has to be added to types that 
           you want to debug.
    
           int Print(std::ostream&, int) const;
    
           It is your responsibility to add this to your code.  The function
           definitions will be written by the program.
           
    
  2. Building

    If you sent header files as input, make sure those files are included prior to the generated file.

     

 

   Warnings:
 
    We support Boost::multi_index_container, but with some limitations:  
         1.   At most one sequenced index.
         2.   If a sequenced index is part of the class makeup, it 
              must be the first index listed in the "IndexSpecifierList." 
         3.   Transmission of a multi_index_container will probably not
              preserve the relative order of elements that are 
              considered equal under a ordered_non_unique index.
 
    These limitations permit the transmission of a multi_index_container
    to a "single index container" such as vector or list if desired.

   Tips:

    Make sure any header files you send as input compile before you 
    send them. 
    


Home