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
main
function. - 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.