C fieldmapper stuff
authorerickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Mon, 6 Jun 2005 17:52:07 +0000 (17:52 +0000)
committererickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Mon, 6 Jun 2005 17:52:07 +0000 (17:52 +0000)
git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@329 9efc2488-bf62-4759-914b-345cdb29e865

src/utils/Makefile
src/utils/fieldmapper-c.pl [new file with mode: 0755]

index 12e8ce9..e168156 100644 (file)
@@ -2,15 +2,23 @@ CC                            = gcc
 LIB_DIR                = ../../lib
 CC_OPTS                = -fPIC -Wall -O2  -I ../../include 
 EXE_LD_OPTS = -L $(LIB_DIR) 
+INCLUDE                = ../../include
+FM_HEADER      = $(INCLUDE)/opensrf/fieldmapper.h
+FM_SOURCE      = fieldmapper.c
 
-all: util 
+all: util fieldmapper
 
 util: md5
 
 md5: md5.c
        $(CC) -c $(CC_OPTS) md5.c -o md5.o 
        $(CC) -shared -W1 md5.o -o $(LIB_DIR)/libmd5.so
-       /bin/rm -f md5.o
+
+fieldmapper: fieldmapper-c.pl
+       perl fieldmapper-c.pl $(FM_HEADER) $(FM_SOURCE)
+       $(CC) -c $(CC_OPTS) fieldmapper.c -o fieldmapper.o
+       $(CC) -shared -W1 fieldmapper.o -o $(LIB_DIR)/libopensrf_fm.so
 
 clean:
-       /bin/rm -f $(LIB_DIR)/libmd5.so
+       /bin/rm -f md5.o
+       /bin/rm -f $(FM_SOURCE) $(FM_HEADER)
diff --git a/src/utils/fieldmapper-c.pl b/src/utils/fieldmapper-c.pl
new file mode 100755 (executable)
index 0000000..a362f41
--- /dev/null
@@ -0,0 +1,229 @@
+#!/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";
+