--- /dev/null
+#!/usr/bin/perl
+use strict; use warnings;
+use Data::Dumper;
+use OpenILS::Utils::Fieldmapper;
+
+
+if(!$ARGV[1]) {
+ print "usage: $0 <header_file> <source_file>\n";
+ exit;
+}
+
+warn "Generating fieldmapper-c code...\n";
+
+#open(HEADER, ">fieldmapper.h");
+#open(SOURCE, ">fieldmapper.c");
+
+print $ARGV[0] . "\n";
+print $ARGV[1] . "\n";
+
+open(HEADER, ">$ARGV[0]");
+open(SOURCE, ">$ARGV[1]");
+
+my $map = $Fieldmapper::fieldmap;
+
+print HEADER <<C;
+
+#include "objson/object.h"
+#include "objson/json_parser.h"
+#include "utils.h"
+
+/* Fieldmapper-C. Autogenerated from fieldmapper-c.pl.\n\nNote that object*'s passed in as
+constructor parameters are copied in so the originals will need to be freed*/
+
+/* fm_obj is the generic placeholder object */
+struct fm_obj_struct {
+ char* classname;
+ object* array;
+};
+typedef struct fm_obj_struct fm_obj;
+
+/* takes a json object and builds a fieldmapper object. the object
+ is then cast into an fm_obj and returned. To verify an object is
+ what is expected, check fm_obj_thing->classname. */
+fm_obj* fm_factory(object*);
+
+/* builds a new fieldmapper object by class name */
+fm_obj* fm_factory_string(char*);
+
+void fm_free(fm_obj* fm);
+C
+
+print SOURCE <<C;
+#include "fieldmapper.h"
+
+void fm_free(fm_obj* fm) {
+ if(!fm) return;
+ free_object(fm->array);
+ free(fm);
+}
+C
+
+my $factory_string = <<C;
+fm_obj* fm_factory(object* obj) {
+
+ if(!obj) return NULL;
+ if(!obj->classname) return NULL;
+ fm_obj* fm = NULL;
+
+C
+
+my $fstring_string = <<C;
+fm_obj* fm_factory_string(char* string) {
+ if(!string) return NULL;
+ object* obj = new_object(NULL);
+ object* tmp = NULL;
+C
+
+for my $object (keys %$map) {
+
+ my $short_name = $map->{$object}->{hint};
+ my $func_header_string = "";
+ my $func_code_string = "";
+ my $constructor_string = "";
+
+ $factory_string .= <<CODE;
+ if(!strcmp(obj->classname,"$short_name"))
+ fm = (fm_obj*) fm_new_$short_name(obj);
+CODE
+
+ $fstring_string .= <<CODE;
+ if(!strcmp(string, "$short_name")) {
+ obj->set_class(obj, "$short_name");
+CODE
+
+ my $header_string = <<CODE;
+struct fm_${short_name}_struct {
+ char* classname;
+ object* array;
+ char*\t\t(*to_string) (struct fm_${short_name}_struct*);
+CODE
+
+ $func_header_string .= <<CODE;
+char* fm_${short_name}_to_string(fm_$short_name*);
+CODE
+
+ my $to_string = <<CODE;
+char* fm_${short_name}_to_string(fm_$short_name* fm) {
+ if(!fm || !fm->array) return NULL;
+ growing_buffer* buf = buffer_init(256);
+ buffer_fadd(buf, "%s => {\\n", fm->classname);
+ object* o;
+CODE
+
+ $constructor_string .= <<CODE;
+fm_$short_name* fm_new_$short_name(object* obj_array) {
+
+ fm_$short_name* fm = (fm_$short_name*) safe_malloc(sizeof(fm_$short_name));
+
+ /* build an empty array object */
+ if(!obj_array) {
+ fm->array = new_object(NULL);
+ fm->array->is_array = 1;
+ fm->array->set_class(fm->array, "$short_name");
+
+ } else {
+
+ /* we don't want invalid objects */
+ if (!obj_array->classname) return NULL;
+ if(strcmp(obj_array->classname, "$short_name")) return NULL;
+
+ char* s = obj_array->to_json(obj_array);
+ fm->array = json_parse_string(s);
+ free(s);
+ }
+
+ fm->classname = fm->array->classname;
+ fm->to_string = &fm_${short_name}_to_string;
+CODE
+
+ for my $field (keys %{$map->{$object}->{fields}}) {
+ my $position = $map->{$object}->{fields}->{$field}->{position};
+
+ $to_string .= <<CODE;
+ o = fm->array->get_index(fm->array, $position);
+ if(o) {
+ char* str = o->to_json(o);
+ buffer_fadd(buf, " $field\\t: %s\\n", str);
+ free(str);
+ };
+CODE
+
+ $fstring_string .= <<CODE;
+ tmp = new_object(NULL);
+ tmp->is_null = 1;
+ obj->add_index(obj, $position, tmp);
+CODE
+
+ $header_string .= <<CODE;
+ object*\t(*get_$field) (struct fm_${short_name}_struct*);
+ void\t\t(*set_$field) (struct fm_${short_name}_struct*, object*);
+CODE
+
+ $constructor_string .= <<CODE;
+ fm->set_$field = &fm_${short_name}_set_$field;
+ fm->get_$field = &fm_${short_name}_get_$field;
+CODE
+
+ $func_header_string .= <<CODE;
+object* fm_${short_name}_get_$field(fm_$short_name*);
+void fm_${short_name}_set_$field(fm_$short_name*, object*);
+CODE
+
+ $func_code_string .= <<CODE
+ object* fm_${short_name}_get_$field(fm_$short_name* fm) {
+ if(!fm || !fm->array) return NULL;
+ return fm->array->get_index(fm->array, $position);
+ }
+
+ void fm_${short_name}_set_$field(fm_$short_name* fm, object* obj) {
+ if(!fm || !fm->array || !obj) return;
+ fm->array->add_index(fm->array, $position, obj);
+ }
+CODE
+
+ }
+
+ $fstring_string .= <<CODE;
+ return (fm_obj*) fm_new_$short_name(obj);
+ }
+CODE
+
+ $to_string .= <<CODE;
+ buffer_add(buf,"}\\n");
+ char* b = buffer_data(buf);
+ buffer_free(buf);
+ return b;
+}
+CODE
+
+ $constructor_string .= "\treturn fm;\n}\n";
+ $header_string .= "};\n";
+ $func_code_string = $constructor_string . $to_string . $func_code_string;
+
+ $header_string .= "typedef struct fm_$short_name"."_struct fm_$short_name;\n\n";
+ $header_string .= "fm_$short_name* fm_new_$short_name(object*);\n";
+ $header_string .= "$func_header_string\n";
+
+ print HEADER "\n$header_string\n";
+ print SOURCE "\n$func_code_string\n";
+
+
+}
+
+$factory_string .= "\treturn fm;\n}\n";
+#$fstring_string .= "\treturn NULL;\n}\n";
+$fstring_string .= <<CODE;
+ free_object(obj);
+ return NULL;
+}
+CODE
+
+print SOURCE "\n$factory_string\n";
+print SOURCE "\n$fstring_string\n";
+
+close HEADER;
+close SOURCE;
+
+warn "done\n";
+