AutoGen is an interesting code generation tool that I just stumbled upon.
What can you do with it? Well, let’s say that we have a simple specification for what an Employee class might look like:
autogen definitions employee;
class_name = Employee;
field = {
field_type = long;
field_name = id;
field_example_value = 1001;
};
field = {
field_type = string;
field_name = first_name;
field_example_value = "\"Marc\"";
};
field = {
field_type = string;
field_name = last_name;
field_example_value = "\"Abramowitz\"";
};
field = {
field_type = long;
field_name = department_id;
field_example_value = 500;
};
We can take this and then process it with a template to generate code automatically.
Here’s an example of such a template:
[+ AutoGen5 template h cpp +]
[+
(define (type-name underscored_name) (string-substitute (string-capitalize underscored_name) "_" ""))
+]
[+ CASE (suffix) +][+
== h +]
#include <string>
class [+ (get "class_name") +] {
public:
[+ (type-name (get "class_name")) +]([+ FOR field "," +]
[+ (get "field_type") +] [+ (get "field_name") +][+ ENDFOR list +]
);
// virtual ~[+ (type-name (get "class_name")) +]();
[+ FOR field "" +] [+ (get "field_type") +] get_[+ (get "field_name") +]() const;
[+ ENDFOR list +]
private:
[+ (get "class_name") +](const [+ (get "class_name") +]&); // prevent compiler-generated copy constructor
[+ FOR field "" +]
[+ (get "field_type") +] [+ (get "field_name") +];[+ ENDFOR list +]
};
[+ == cpp +]
#include <iostream>
#include "[+ (string-downcase (get "class_name")) +].h"
[+ (get "class_name") +]::[+ (get "class_name") +]([+ FOR field "," +]
[+ (get "field_type") +] [+ (get "field_name") +][+ ENDFOR list +]
)
{[+ FOR field "" +]
this->[+ (get "field_name") +] = [+ (get "field_name") +];[+ ENDFOR list +]
}
[+ FOR field "" +][+ (get "field_type") +] [+ (get "class_name") +]::get_[+ (get "field_name") +]() const
{
return this->[+ (get "field_name") +];
}
[+ ENDFOR list +]
int main(int argc, char* argv[])
{
[+ (get "class_name") +] [+ (string-downcase (get "class_name")) +]([+ FOR field ", " +][+ (get "field_example_value") +][+ ENDFOR list +]);
[+ FOR field "" +]
cout << "[+ (get "field_name") +] = " << [+ (string-downcase (get "class_name")) +].get_[+ (get "field_name") +]() << endl;[+ ENDFOR list +]
return 0;
}
[+ ESAC +]
You can generate code from this definition and template by doing:
$ autogen employee.def
This spits out a .h and a .cpp file which are ready to be used:
$ g++ -o employee employee.cpp && ./employee id = 1001 first_name = Marc last_name = Abramowitz department_id = 500
The template syntax is a little bit odd. Autogen is based on Guile, which is similar to Scheme, which is derived from Lisp (:-)). But as you can see even from this very simple example, there’s a lot of expressiveness here, allowing you to probably do some fairly sophisticated things.
Downloads
Updates
- Update 2006-03-17: I updated the files a bit so that more of the code is actually generated, including the example data in the
mainfunction. - Update 2006-03-20: I fixed the capitalization of AutoGen. Also, if you are interested in code generation tools in general, you may want to check out my post on CodeWorker.
