Index: /trunk/glueforge/glueforge.in
===================================================================
--- /trunk/glueforge/glueforge.in	(revision 3612)
+++ /trunk/glueforge/glueforge.in	(revision 3612)
@@ -0,0 +1,159 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2005  Joshua Hoblitt
+#
+# $Id: glueforge.in,v 1.1.1.1 2005-04-01 03:01:18 jhoblitt Exp $
+
+use strict;
+use warnings FATAL => qw( all );
+
+use vars qw( $VERSION );
+$VERSION = '0.01';
+
+use Data::Dumper;
+use PS::IPP::Metadata::Config;
+use Template;
+
+use Getopt::Long qw( GetOptions :config auto_help auto_version );
+use Pod::Usage qw( pod2usage );
+
+my ( $input, $output, $template );
+GetOptions(
+    'input=s'       => \$input,
+    'output=s'      => \$output,
+    'template=s'    => \$template,
+) || pod2usage( 2 );
+
+pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
+pod2usage( -msg => "Required option: --input|-i", -exitval => 2 ) unless $input;
+
+$template = "./template" unless $template;
+
+die "file doesn't exist: $input" unless -e $input;
+die "file isn't readable: $input" unless -r $input;
+
+my $config = parse_config( $input );
+
+my %data;
+
+# find table name
+for (my $i = 0; $i < @{$config}; $i++) {
+    my $elem = $config->[$i];
+
+    if ( $elem->{name} eq "table" ) {
+        $data{table_name} = $elem->{value};
+
+        # delete element from array
+        splice @$config, $i, 1;
+
+        last;
+    }
+}
+
+$data{data_type} = $data{table_name} . "Row";
+$data{namespace} = $data{table_name};
+
+my @items;
+
+# setup items
+for (my $i = 0; $i < @{$config}; $i++) {
+    my $elem = $config->[$i];
+
+    my $mdtypes = lookup_type( $elem->{type} );
+    next if ! defined $mdtypes;
+
+    push @items, {
+        name    => $elem->{name},
+        type    => $elem->{type},
+        ctype   => $mdtypes->{ctype},
+        mtype   => $mdtypes->{mtype},
+        comment => $elem->{comment},
+        value   => $elem->{value},
+    };
+}
+
+$data{columns} = \@items;
+
+#my ( $bootstrap, $configure, $m4, $topmake, $srcmake, $makefile, $header, $code );
+
+my %tt = (
+    'bootstrap_sh.tt'   => "$output/bootstrap.sh",
+    'configure_ac.tt'   => "$output/configure.ac",
+    'top_makefile_am.tt'=> "$output/Makefile.am",
+    'src_makefile_am.tt'=> "$output/src/Makefile.am",
+    'header.tt'         => "$output/src/$data{table_name}db.h",
+    'code.tt'           => "$output/src/$data{table_name}db.c",
+);
+
+my $mangler = Template->new({ INCLUDE_PATH => $template });
+
+if ( $output ) {
+    foreach my $t ( keys %tt ) {
+        $mangler->process( $t, \%data, $tt{$t})
+            or die $mangler->error;
+    }
+} else {
+    foreach my $t ( keys %tt ) {
+        $mangler->process( $t, \%data )
+            or die $mangler->error;
+    }
+}
+
+#$mangler->process( "bootstrap_sh.tt", \%data, $bootstrap)
+#    or die $mangler->error;
+#$mangler->process( "configure_ac.tt", \%data, $configure)
+#    or die $mangler->error;
+#$mangler->process( "top_makefile_am.tt", \%data, $topmake)
+#    or die $mangler->error;
+#$mangler->process( "ac_check_mysqlr.tt", \%data, $m4)
+#    or die $mangler->error;
+#$mangler->process( "src_makefile_am.tt", \%data, $srcmake)
+#    or die $mangler->error;
+#$mangler->process( "header.tt", \%data, $header)
+#    or die $mangler->error;
+#$mangler->process( "code.tt", \%data, $code)
+#    or die $mangler->error;
+
+sub parse_config {
+    my $file = shift;
+
+    my $mdparser = PS::IPP::Metadata::Config->new;
+    $mdparser->overwrite( 1 );
+
+    open( my $data, $file ) or die "can't open file: $!";
+    my $example = do { local $/; <$data> };
+    close( $data ) or die "can't close file: $!";
+
+    my $config = $mdparser->parse( $example )
+        or die "error parsing file: $input";
+
+    return $config;
+}
+
+sub lookup_type {
+    my $type = shift;
+
+    my %primitives = map { $_ => 1 } qw( S8 S16 S32 S64 U8 U16 U32 U64 F32 F64 );
+    my %mtypes = map { $_ => "PS_META_$_" } keys %primitives;
+    my %ctypes = map { $_ => "ps$_" } keys %primitives;
+
+    if ( $primitives{$type} ) {
+        return {
+            ctype   => $ctypes{$type},
+            mtype   => $mtypes{$type},
+        };
+    } elsif ( $type =~ /STR|STRING/ ) {
+        return {
+            ctype   => "char*",
+            mtype   => 'PS_META_STR',
+        };
+    } elsif ( $type =~ /BOOL/ ) {
+        return {
+            ctype   => "bool",
+            mtype   => 'PS_META_STR',
+        };
+    } else {
+        return undef;
+    }
+}
+
Index: /trunk/glueforge/templates/psdb/bootstrap_sh.tt
===================================================================
--- /trunk/glueforge/templates/psdb/bootstrap_sh.tt	(revision 3612)
+++ /trunk/glueforge/templates/psdb/bootstrap_sh.tt	(revision 3612)
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+libtoolize --automake --copy \
+&& aclocal \
+&& autoheader \
+&& automake --foreign --add-missing --copy \
+&& autoconf
Index: /trunk/glueforge/templates/psdb/pop_h.tt
===================================================================
--- /trunk/glueforge/templates/psdb/pop_h.tt	(revision 3612)
+++ /trunk/glueforge/templates/psdb/pop_h.tt	(revision 3612)
@@ -0,0 +1,10 @@
+/** Removes the last row from the database and returns it
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+[% data_type %] [% namespace %]Pop(
+    psDB            *dbh                ///< Database handle
+);
Index: /trunk/glueforge/templates/psdb/top_makefile_am.tt
===================================================================
--- /trunk/glueforge/templates/psdb/top_makefile_am.tt	(revision 3612)
+++ /trunk/glueforge/templates/psdb/top_makefile_am.tt	(revision 3612)
@@ -0,0 +1,4 @@
+ACLOCAL_AMFLAGS = -I m4
+
+AM_CFLAGS  = -g -O0 -pipe -fpic -Wall -pedantic -std=c99
+SUBDIRS = src
