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:
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.
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.