diff options
-rw-r--r-- | examples/xsd2c/utils.c | 37 | ||||
-rw-r--r-- | examples/xsd2c/utils.h | 11 | ||||
-rwxr-xr-x | xsd2c/Makefile.am | 8 | ||||
-rw-r--r-- | xsd2c/TODO | 21 | ||||
-rw-r--r-- | xsd2c/formatter.c | 1232 | ||||
-rw-r--r-- | xsd2c/formatter.h | 36 | ||||
-rw-r--r-- | xsd2c/obj.c | 230 | ||||
-rw-r--r-- | xsd2c/obj.h | 65 | ||||
-rw-r--r-- | xsd2c/tr.c | 261 | ||||
-rw-r--r-- | xsd2c/tr.h | 44 | ||||
-rw-r--r-- | xsd2c/types.map | 38 | ||||
-rw-r--r-- | xsd2c/util.c | 105 | ||||
-rw-r--r-- | xsd2c/util.h | 31 | ||||
-rw-r--r-- | xsd2c/xsd2c.c | 835 |
14 files changed, 2954 insertions, 0 deletions
diff --git a/examples/xsd2c/utils.c b/examples/xsd2c/utils.c new file mode 100644 index 0000000..0be002b --- /dev/null +++ b/examples/xsd2c/utils.c @@ -0,0 +1,37 @@ + +#include "utils.h" + + +int Writer_Tab = 0; +int Writer_Ret = 0; + +void Writer_StartElement(const char* element_name, int attr_count, char **keys, char **values, void* userData) +{ + int i, j; + if (Writer_Ret) printf("\n"); + for (j=0;j<Writer_Tab;j++) printf("\t"); + printf("<%s", element_name); + for (i=0;i<attr_count;i++) + { + printf(" %s = \"%s\"", keys[i], values[i]); + } + printf(">"); + Writer_Tab++; + Writer_Ret = 1; +} + +void Writer_Characters(const char* element_name, const char* chars, void* userData) +{ + printf("%s", chars); +} + +void Writer_EndElement(const char* element_name, void* userData) +{ + int j; + Writer_Tab--; + if (!Writer_Ret) + for (j=0;j<Writer_Tab;j++) printf("\t"); + printf("</%s>\n", element_name); + Writer_Ret = 0; +} + diff --git a/examples/xsd2c/utils.h b/examples/xsd2c/utils.h new file mode 100644 index 0000000..17a2140 --- /dev/null +++ b/examples/xsd2c/utils.h @@ -0,0 +1,11 @@ + +#ifndef _EX_UTILS_H_ +#define _EX_UTILS_H_ + + +void Writer_StartElement(const char* element_name, int attr_count, char **keys, char **values, void* userData); +void Writer_Characters(const char* element_name, const char* chars, void* userData); +void Writer_EndElement(const char* element_name, void* userData); + + +#endif diff --git a/xsd2c/Makefile.am b/xsd2c/Makefile.am new file mode 100755 index 0000000..fbcdec0 --- /dev/null +++ b/xsd2c/Makefile.am @@ -0,0 +1,8 @@ +bin_PROGRAMS=xsd2c
+
+INCLUDES=$(LIBXML_CFLAGS)
+LDFLAGS=$(LIBXML_LIBS)
+
+xsd2c_SOURCES=tr.c util.c obj.c formatter.c xsd2c.c
+xsd2c_LDFLAGS=$(LDFLAGS)
+
diff --git a/xsd2c/TODO b/xsd2c/TODO new file mode 100644 index 0000000..5cf2916 --- /dev/null +++ b/xsd2c/TODO @@ -0,0 +1,21 @@ +-------------------------------------------------------- + xsd2c TODO +-------------------------------------------------------- +PROJECT: xsd2c +CREATED: 30.03.2003 +WRITTEN BY: Ferhat Ayaz +-------------------------------------------------------- +$Id: TODO,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ +$Log: TODO,v $ +Revision 1.1 2004/06/02 11:17:03 snowdrop +initial import + +Revision 1.1 2003/03/30 21:38:20 snowdrop +initial import + +-------------------------------------------------------- + ++ Add extension base functionality ++ Add deserialize functionality ++ Add simpleTypes (list, restriction?, ...) + diff --git a/xsd2c/formatter.c b/xsd2c/formatter.c new file mode 100644 index 0000000..80b96cf --- /dev/null +++ b/xsd2c/formatter.c @@ -0,0 +1,1232 @@ +/****************************************************************** + * $Id: formatter.c,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ + * + * CSOAP Project: A SOAP client/server library in C + * Copyright (C) 2003 Ferhat Ayaz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Email: ayaz@jprogrammer.net + ******************************************************************/ +#include "formatter.h" +#include "tr.h" +#include "util.h" + +int formatter_generate_sax_serializer = 0; + +/* ------------------------------------------------------------- */ + +typedef void (*FieldEnumCallBack)(FILE* , HFIELD); +static void enumFields(FILE* f, HCOMPLEXTYPE obj, FieldEnumCallBack callb); + +/* ------------------------------------------------------------- */ + +static int genFieldType(HFIELD field, char *buffer, int forceSingle); +static int genFunctionNameGetter(HFIELD field, char *buffer); +static int genFunctionNameSetter(HFIELD field, char *buffer); +static int genFunctionNameAdder(HFIELD field, char *buffer); +static int genFunctionNameCreate(HCOMPLEXTYPE obj, char *buffer); +static int genFunctionNameFree(HCOMPLEXTYPE obj, char *buffer); +static int genFunctionNameSaxSerialize(HCOMPLEXTYPE obj, char *buffer); +static int genFunctionNameDeserialize(HCOMPLEXTYPE obj, char *buffer); + +/* ------------------------------------------------------------- */ + +static void writeFieldDeclare(FILE* f, HFIELD field); +static void writeComplexTypeDeclare(FILE* f, HCOMPLEXTYPE obj); +static void writeFieldPrimitiveList(FILE* f, HFIELD field); +static void writeFieldSetter(FILE* f, HFIELD field); +static void writeFieldGetter(FILE* f, HFIELD field); +static void writeListAdder(FILE* f, HFIELD field); + +/* ------------------------------------------------------------- */ + +static void writeCodeCreate(FILE* f, HCOMPLEXTYPE obj); +static void writeCodeFree(FILE* f, HCOMPLEXTYPE obj); +static void writeCodeSaxSerialize(FILE* f, HCOMPLEXTYPE obj); +static void writeCodeBaseOnStartElement(FILE* f, HCOMPLEXTYPE obj); +static void writeCodeBaseOnEndElement(FILE* f, HCOMPLEXTYPE obj); +static void writeCodeDeserialize(FILE* f, HCOMPLEXTYPE obj); + +static void writeCodeFieldInitialize(FILE* f, HFIELD field); +static void writeCodeFieldFreeList(FILE* f, HFIELD field); +static void writeCodeFieldFree(FILE* f, HFIELD field); +static void writeCodeGetter(FILE* f, HFIELD field); +static void writeCodeSetter(FILE* f, HFIELD field); +static void writeCodeAdder(FILE* f, HFIELD field); + +/* ------------------------------------------------------------- */ + +void writeComplexTypeHeaderFile(FILE* f, HCOMPLEXTYPE obj) +{ + HFIELD field; + char buffer[1054]; + + if (obj == NULL) + { + fprintf(stderr, "Can not declare a null object!\n"); + return; + } + + fprintf(f, "/** Generated by xsd2c*/\n"); + fprintf(f, "#ifndef __%s_H__\n", obj->type); + fprintf(f, "#define __%s_H__\n\n\n", obj->type); + + /* search for includes */ + field = obj->head; + while (field != NULL) + { + if (trGetBuildInFlag(field->type) == 0) + { + fprintf(f, "#include \"%s_xsd.h\"\n", field->type); + } + field = field->next; + } + + if (obj->base_type != NULL) + { + fprintf(f, "#include \"%s_xsd.h\"\n", obj->base_type); + } + + /* include libxml library */ + fprintf(f, "\n#ifndef _DESERIALIZER_DISABLE_\n"); + fprintf(f, "\t#include <libxml/parser.h>\n"); + fprintf(f, "#endif\n\n"); + + /* write upcasting define macro */ + toUpperCase(obj->type, buffer); + fprintf(f, "\n#define TO_%s(derived) (derived->__base) \n\n", buffer); + + /* write extern "C" for __cplusplus linking */ + fprintf(f, "\n#ifdef __cplusplus\nextern \"C\" {\n#endif \n\n", buffer); + + /* write primitive type list structs */ + enumFields(f, obj, writeFieldPrimitiveList); + + /* write object struct */ + writeComplexTypeDeclare(f, obj); + + + /* write create function */ + if (genFunctionNameCreate(obj, buffer)) + fprintf(f, "%s;\n", buffer); + + /* write free function */ + if (genFunctionNameFree(obj, buffer)) + fprintf(f, "%s;\n", buffer); + + /* write sax serialize function */ + if (genFunctionNameSaxSerialize(obj, buffer)) + fprintf(f, "%s;\n", buffer); + + /* write derialize function */ + + if (genFunctionNameDeserialize(obj, buffer)) { + fprintf(f, "\n#ifndef _DESERIALIZER_DISABLE_\n"); + fprintf(f, "%s;\n", buffer); + fprintf(f, "#endif\n\n"); + } + + /* write setter functions */ + enumFields(f, obj, writeFieldSetter); + + /* write adder functions */ + enumFields(f, obj, writeListAdder); + + /* write getter functions */ + enumFields(f, obj, writeFieldGetter); + + /* write extern "C" for __cplusplus linking */ + fprintf(f, "\n\n#ifdef __cplusplus\n};\n#endif /*__cplusplus*/\n\n", buffer); + + fprintf(f, "\n\n#endif\n"); +} + +/* ------------------------------------------------------------- */ + +static +void writeComplexTypeDeclare(FILE* f, HCOMPLEXTYPE obj) +{ + HFIELD field; + char *type; + if (obj == NULL) + { + fprintf(stderr, "Can not declare a null object!\n"); + return; + } + + /* === */ + fprintf(f, "\n/**\n *\tOBJECT: %s\n */\n", obj->type); + fprintf(f, "struct %s\n{\n", obj->type); + + /* === */ + if (obj->base_type != NULL) + { + type = trXSD2C(obj->base_type); + if (type != NULL) + { + fprintf(f, "\t%s __base;\n", type); + } + } + + /* === */ + field = obj->head; + while (field != NULL) + { + writeFieldDeclare(f, field); + field = field->next; + } + fprintf(f, "};\n"); + + /* === */ + fprintf(f, "\n/**\n *\tLIST: %s_List\n */\n", obj->type); + fprintf(f, "struct %s_List\n{\n", obj->type); + fprintf(f, "\tstruct %s* value;\n", obj->type); + fprintf(f, "\tstruct %s_List* next;\n", obj->type); + fprintf(f, "};\n\n\n"); + +} + + +/* -------------------------------------------------------------- */ + +static +void writeFieldDeclare(FILE* f, HFIELD field) +{ + char buffer[1054]; + + if (!genFieldType(field, buffer, 0)) return; + + + if (field->maxOccurs > 1 || field->maxOccurs == -1) + { + fprintf(f, "\t%s %s_head;\n", buffer, field->name); + fprintf(f, "\t%s %s_tail;\n", buffer, field->name); + } + else + { + fprintf(f, "\t%s %s;\n", buffer, field->name); + } +} + +/* -------------------------------------------------------------- */ + +static +int genFunctionNameCreate(HCOMPLEXTYPE obj, char *buffer) +{ + const char *funcname = "struct %s* %s_Create()"; + sprintf(buffer, funcname, obj->type, obj->type); + return 1; +} + +/* -------------------------------------------------------------- */ + +static +int genFunctionNameFree(HCOMPLEXTYPE obj, char *buffer) +{ + const char *funcname = "void %s_Free(struct %s* obj)"; + sprintf(buffer, funcname, obj->type, obj->type); + return 1; +} + +/* -------------------------------------------------------------- */ + +static +int genFieldType(HFIELD field, char *buffer, int forceSingle) +{ + char *type; + const char* stlist = "struct %s_%s_List*"; + if ((field->maxOccurs > 1 || field->maxOccurs == -1) && !forceSingle) + { + type = trXSD2CList(field->type); + if (type == NULL) + sprintf(buffer, stlist, field->parentObj->type, field->name); + else + strcpy(buffer, type); + } + else + { + type = trXSD2C(field->type); + if (type == NULL) + { + fprintf(stderr, "WARNING: Unregistered type '%s'\n", field->type); + return 0; + } + strcpy(buffer, type); + } + + return 1; +} + +/* -------------------------------------------------------------- */ + +static int genFunctionNameGetter(HFIELD field, char *buffer) +{ + const char *funcname = "%s %s_Get_%s(struct %s* obj)"; + char type[1054]; + + if (!genFieldType(field, type, 0)) return 0; + + sprintf(buffer, funcname, type, field->parentObj->type, + field->name, field->parentObj->type); + + return 1; +} + +/* -------------------------------------------------------------- */ + +static int genFunctionNameSetter(HFIELD field, char *buffer) +{ + const char *funcname = "void %s_Set_%s(struct %s* obj, %s %s)"; + char type[1054]; + + if (!genFieldType(field, type, 0)) return 0; + + if (!strcmp(type, "char*")) + strcpy(type, "const char*"); + + sprintf(buffer, funcname, field->parentObj->type, field->name, + field->parentObj->type, type, field->name); + + return 1; +} + +/* -------------------------------------------------------------- */ + +static int genFunctionNameAdder(HFIELD field, char *buffer) +{ + const char *funcname = "void %s_Add_%s(struct %s* obj, %s %s)"; + char type[1054]; + + if (!genFieldType(field, type, 1)) return 0; + + if (!strcmp(type, "char*")) + strcpy(type, "const char*"); + + sprintf(buffer, funcname, field->parentObj->type, field->name, + field->parentObj->type, type, field->name); + + return 1; +} + +/* -------------------------------------------------------------- */ + +static int genFunctionNameSaxSerialize(HCOMPLEXTYPE obj, char *buffer) +{ + const char *funcname = "void %s_Sax_Serialize(struct %s* obj,\n\t\t const char *root_element_name,\n\t\t %s,\n\t\t %s,\n\t\t %s,\n\t\t void* userData)"; + const char *start = "void (*OnStartElement)(const char* element_name, int attr_count, char **keys, char **values, void* userData)"; + const char *chars = "void (*OnCharacters)(const char* element_name, const char* chars, void* userData)"; + const char *end = "void (*OnEndElement)(const char* element_name, void* userData)"; + + sprintf(buffer, funcname, obj->type, obj->type, start, chars, end); + return 1; +} + +/* -------------------------------------------------------------- */ + +static int genFunctionNameDeserialize(HCOMPLEXTYPE obj, char *buffer) +{ + const char *funcname = "struct %s* %s_Deserialize(xmlNodePtr xmlRoot)"; + + sprintf(buffer, funcname, obj->type, obj->type); + return 1; +} + +/* -------------------------------------------------------------- */ + +static +void writeFieldPrimitiveList(FILE* f, HFIELD field) +{ + char *type, buffer[1054]; + const char* stlist = "struct %s_%s_List"; + + if (!(field->maxOccurs > 1 || field->maxOccurs == -1)) return; + + if (trGetBuildInFlag(field->type) > 0) + { + type = trXSD2C(field->type); + if (type == NULL) return; + + sprintf(buffer, stlist, field->parentObj->type, field->name); + + fprintf(f, "\n%s {\n", buffer); + fprintf(f, "\t%s value;\n", type); + fprintf(f, "\t%s* next;\n", buffer); + fprintf(f, "};\n"); + } +} + + + +/* -------------------------------------------------------------- */ + +static void writeFieldSetter(FILE* f, HFIELD field) +{ + char buffer[1054]; + + if (field->maxOccurs != 1) return; + + if (!genFunctionNameSetter(field, buffer)) return; + fprintf(f, "%s;\n", buffer); +} + + +/* -------------------------------------------------------------- */ + +static void writeFieldGetter(FILE* f, HFIELD field) +{ + char buffer[1054]; + + if (!genFunctionNameGetter(field, buffer)) return; + fprintf(f, "%s;\n", buffer); +} + +/* -------------------------------------------------------------- */ + +static void writeListAdder(FILE* f, HFIELD field) +{ + char buffer[1054]; + + if (!((field->maxOccurs > 1 || field->maxOccurs == -1))) return; + + if (!genFunctionNameAdder(field, buffer)) return; + fprintf(f, "%s;\n", buffer); +} + +/* -------------------------------------------------------------- */ + +static void enumFields(FILE* f, HCOMPLEXTYPE obj, FieldEnumCallBack callb) +{ + HFIELD field; + if (obj == NULL) + { + fprintf(stderr, "Can not declare a null object!\n"); + return; + } + + field = obj->head; + while (field != NULL) + { + callb(f, field); + field = field->next; + } +} + + + +/* ------------------------------------------------------------- */ +/* SOURCE FILE */ +/* ------------------------------------------------------------- */ + +void writeComplexTypeSourceFile(FILE* f, HCOMPLEXTYPE obj) +{ + HFIELD field; + char buffer[1054]; + + if (obj == NULL) + { + fprintf(stderr, "Can not declare a null object!\n"); + return; + } + + fprintf(f, "/** Generated by xsd2c */\n"); + fprintf(f, "#include <stdio.h>\n", obj->type); + fprintf(f, "#include <string.h>\n", obj->type); + fprintf(f, "#include <stdlib.h>\n", obj->type); + fprintf(f, "#include \"%s_xsd.h\"\n\n\n", obj->type); + + + if (obj->base_type != NULL) + { + fprintf(f, "\nstruct Base_Sax_%s_Serializer\n{\n\tstruct %s* obj;\n", obj->type, obj->type); + fprintf(f, "\tvoid (*OnStartElement)(const char*,int,char**,char**, void*);\n"); + fprintf(f, "\tvoid (*OnCharacters)(const char*,const char*, void*);\n"); + fprintf(f, "\tvoid (*OnEndElement)(const char*, void*);\n"); + fprintf(f, "\tvoid* userData;\n\tint stackDeep;\n};\n\n"); + } + + /* write create function code */ + writeCodeCreate(f, obj); + + /* write free function code */ + writeCodeFree(f, obj); + + if (obj->base_type != NULL) + { + writeCodeBaseOnStartElement(f, obj); + writeCodeBaseOnEndElement(f, obj); + } + + /* write sax code */ + writeCodeSaxSerialize(f, obj); + + /* write deserializer code */ + writeCodeDeserialize(f, obj); + + /* write getters */ + enumFields(f, obj, writeCodeGetter); + + /* write setters */ + enumFields(f, obj, writeCodeSetter); + + /* write setters */ + enumFields(f, obj, writeCodeAdder); +} + +/* ------------------------------------------------------------- */ + +static void writeCodeCreate(FILE* f, HCOMPLEXTYPE obj) +{ + char buffer[1054]; + + if (!genFunctionNameCreate(obj, buffer)) return; + + fprintf(f, "%s\n", buffer); + fprintf(f, "{\n"); + + fprintf(f, "\tstruct %s* _res;\n", obj->type); + fprintf(f, "\t_res = (struct %s*)malloc(sizeof(struct %s));\n\n", + obj->type, obj->type); + + if (obj->base_type != NULL) + fprintf(f, "\t_res->__base = %s_Create();\n\n", obj->base_type); + + enumFields(f, obj, writeCodeFieldInitialize); + + fprintf(f, "\n\treturn _res;\n"); + fprintf(f, "}\n\n"); +} + +/* ------------------------------------------------------------- */ + +static void writeCodeFieldInitialize(FILE* f, HFIELD field) +{ + char ns[255]; + char type[255]; + char defvalue[255]; + + parseNS(field->type, ns, type); + + if (!strcmp(type, "int") || !strcmp(type, "integer") || !strcmp(type, "boolean")) + strcpy(defvalue, "0"); + else if (!strcmp(type, "float") || !strcmp(type, "double")) + strcpy(defvalue, "0.0"); + else if (!strcmp(type, "char")) + strcpy(defvalue, "'\\0'"); + else + strcpy(defvalue, "NULL"); + + if (field->maxOccurs > 1 || field->maxOccurs == -1) + { + fprintf(f, "\t_res->%s_head = NULL;\n", field->name); + fprintf(f, "\t_res->%s_tail = NULL;\n", field->name); + } + else + fprintf(f, "\t_res->%s = %s;\n", field->name, defvalue); +} + + +/* ------------------------------------------------------------- */ + + +static void writeCodeGetter(FILE* f, HFIELD field) +{ + char buffer[1054]; + + if (!genFunctionNameGetter(field, buffer)) return; + + fprintf(f, "%s\n", buffer); + fprintf(f, "{\n"); + if (field->maxOccurs > 1 || field->maxOccurs == -1) + { + fprintf(f, "\treturn obj->%s_head;\n", field->name); } + else + fprintf(f, "\treturn obj->%s;\n", field->name); + + fprintf(f, "}\n\n"); + +} + + +/* ------------------------------------------------------------- */ + + +static void writeCodeSetter(FILE* f, HFIELD field) +{ + char buffer[1054]; + char ns[255]; + char type[255]; + char ctype[1054]; + char defvalue[255]; + + if (field->maxOccurs > 1 || field->maxOccurs == -1) return; + + if (!genFunctionNameSetter(field, buffer)) return; + + + fprintf(f, "%s\n", buffer); + fprintf(f, "{\n"); + + parseNS(field->type, ns, type); /* xsd type */ + if (!genFieldType(field, ctype, 0)) return; /* ctype */ + + if (!strcmp(ctype, "char*")) +/* if (!strcmp(type, "string") ) */ /* work aroud for IDREF and IDREFS*/ + { + fprintf(f, "\tif (obj->%s != NULL) free(obj->%s);\n", + field->name, field->name); + fprintf(f, "\tobj->%s = (char*)malloc(strlen(%s)+1);\n"); + fprintf(f, "\tstrcpy(obj->%s, %s);\n", + field->name, field->name); + } + else + { + fprintf(f, "\tobj->%s = %s;\n", field->name, field->name); + } + + fprintf(f, "}\n\n"); +} + +/* ------------------------------------------------------------- */ + +static void writeCodeAdder(FILE* f, HFIELD field) +{ + char buffer[1054]; + char ns[255]; + char type[255]; + char fieldType[1054]; + char fieldTypeNP[1054]; + + if (!(field->maxOccurs > 1 || field->maxOccurs == -1)) return; + + if (!genFunctionNameAdder(field, buffer)) return; + if (!genFieldType(field, fieldType, 0)) return ; + + strcpy(fieldTypeNP, fieldType); + fieldTypeNP[strlen(fieldType)-1] = '\0'; + + fprintf(f, "%s\n", buffer); + fprintf(f, "{\n"); + + fprintf(f, "\t%s %s_node;\n", fieldType, field->name); + fprintf(f, "\t%s_node = (%s)malloc(sizeof(%s));\n", + field->name, fieldType, fieldTypeNP); + + parseNS(field->type, ns, type); + + if (!strcmp(type, "string")) + { + fprintf(f, "\t%s_node->value = (char*)malloc(strlen(%s)+1);\n", + field->name, field->name); + fprintf(f, "\tstrcpy(%s_node->value, %s);\n", + field->name, field->name); + } + else + { + fprintf(f, "\t%s_node->value = %s;\n", field->name, field->name); + } + + fprintf(f, "\t%s_node->next = NULL;\n", field->name); + fprintf(f, "\tif (obj->%s_tail)\n", field->name); + fprintf(f, "\t{\n\t\tobj->%s_tail->next = %s_node;\n\t}\n", + field->name, field->name); + fprintf(f, "\tif (obj->%s_head == NULL)\n", field->name); + fprintf(f, "\t{\n\t\tobj->%s_head = %s_node;\n\t}\n", + field->name, field->name); + fprintf(f, "\tobj->%s_tail = %s_node;\n", + field->name, field->name); + + fprintf(f, "}\n\n"); +} + +/* ------------------------------------------------------------- */ + +static void writeCodeFree(FILE* f, HCOMPLEXTYPE obj) +{ + char buffer[1054]; + + if (!genFunctionNameFree(obj, buffer)) return; + + fprintf(f, "%s\n", buffer); + fprintf(f, "{\n"); + enumFields(f, obj, writeCodeFieldFreeList); + fprintf(f, "\tif (obj == NULL) return;\n"); + + enumFields(f, obj, writeCodeFieldFree); + + fprintf(f, "\tfree(obj);\n"); + + fprintf(f, "}\n\n"); +} + +/* ------------------------------------------------------------- */ + +static void writeCodeFieldFreeList(FILE* f, HFIELD field) +{ + char buffer[1054]; + if (field->maxOccurs > 1 || field->maxOccurs == -1) + { + genFieldType(field, buffer, 0); + fprintf(f, "\t%s %s_cur;\n", buffer, field->name); + fprintf(f, "\t%s %s_tmp;\n", buffer, field->name); + } +} + +/* ------------------------------------------------------------- */ + +static void writeCodeFieldFree(FILE* f, HFIELD field) +{ + char ns[255]; + char type[255]; + char defvalue[255]; + + parseNS(field->type, ns, type); + + if (field->maxOccurs > 1 || field->maxOccurs == -1) + { + fprintf(f, "\n\t%s_cur = obj->%s_head;\n", field->name, field->name); + fprintf(f, "\twhile (%s_cur != NULL)\n\t{\n", field->name); + if (!strcmp(type, "string")) + { + fprintf(f, "\t\tif (%s_cur->value) free(%s_cur->value);\n", + field->name, field->name); + } + fprintf(f, "\t\t%s_tmp = %s_cur->next;\n", field->name, field->name); + fprintf(f, "\t\tfree(%s_cur);\n", field->name); + fprintf(f, "\t\t%s_cur = %s_tmp;\n", field->name, field->name); + fprintf(f, "\t}\n"); + } + else if (!strcmp(type, "int") || !strcmp(type, "integer") || !strcmp(type, "boolean")) + { + } + else if (!strcmp(type, "float") || !strcmp(type, "double")) + { + } + else if (!strcmp(type, "char")) + { + } + else if (!strcmp(type, "string")) + { + fprintf(f, "\tif (obj->%s != NULL) \n\t{\n\t\tfree(obj->%s);\n\t\tobj->%s = NULL;\n\t}\n", + field->name, field->name, field->name); + } +} + + +/* ------------------------------------------------------------- */ + +static void setSaxAttrs(FILE* f, HCOMPLEXTYPE obj) +{ + HFIELD field; + fprintf(f, "\n\tattrCount = 0;\n"); + + field = obj->head; + while (field != NULL) + { + if (field->attrName != NULL) + fprintf(f, "\tif (obj->%s != NULL) attrCount++;\n", field->name); + field = field->next; + } + + fprintf(f, "\n\tkeys = (char**)malloc(sizeof(char*)*attrCount);\n"); + fprintf(f, "\tvalues = (char**)malloc(sizeof(char*)*attrCount);\n"); + + fprintf(f, "\n\tcurCount = 0;\n\n"); + + field = obj->head; + while (field != NULL) + { + if (field->attrName != NULL) + { + fprintf(f, "\tif (obj->%s != NULL)\n\t{\n", field->name); + fprintf(f, "\t\tkeys[curCount] = \"%s\";\n", field->attrName); + fprintf(f, "\t\tvalues[curCount] = obj->%s;\n", field->name); + fprintf(f, "\t\tcurCount++;\n\t}\n"); + } + field = field->next; + } +} + +/* ------------------------------------------------------------- */ + +static void setSaxAttrsBase(FILE* f, HCOMPLEXTYPE obj) +{ + HFIELD field; + + field = obj->head; + while (field != NULL) + { + if (field->attrName != NULL) + fprintf(f, "\tif (bsce->obj->%s != NULL) attrCount++;\n", field->name); + field = field->next; + } + + fprintf(f, "\n\tkeys = (char**)realloc(keys, sizeof(char*)*(attrCount + attr_count));\n"); + fprintf(f, "\tvalues = (char**)realloc(values, sizeof(char*)*(attrCount + attr_count));\n"); + + fprintf(f, "\n\tcurCount = 0;\n\n"); + + field = obj->head; + while (field != NULL) + { + if (field->attrName != NULL) + { + fprintf(f, "\tif (bsce->obj->%s != NULL)\n\t{\n", field->name); + fprintf(f, "\t\tkeys[curCount + attr_count] = \"%s\";\n", field->attrName); + fprintf(f, "\t\tvalues[curCount + attr_count] = bsce->obj->%s;\n", field->name); + fprintf(f, "\t\tcurCount++;\n\t}\n"); + } + field = field->next; + } +} + +/* ------------------------------------------------------------- */ + +static void genFunctionNameBaseOnStartElement(HCOMPLEXTYPE obj, char *buffer, int onlyName) +{ + sprintf(buffer, "%sBase_Sax_%s_StartElement_Callback%s", onlyName?"":"void ", obj->type, onlyName?"":"(const char* element_name, int attr_count, char **keys, char **values, void* userData)"); +} + +/* ------------------------------------------------------------- */ +static void genFunctionNameBaseOnEndElement(HCOMPLEXTYPE obj, char *buffer, int onlyName) +{ + sprintf(buffer, "%sBase_Sax_%s_EndElement_Callback%s", onlyName?"":"void ", obj->type, onlyName?"":"(const char* element_name, void* userData)"); +} +/* ------------------------------------------------------------- */ + +static void writeCodeSaxSerialize(FILE* f, HCOMPLEXTYPE obj) +{ + char buffer[1054]; + char buffer2[1054]; + char ns[255]; + char type[255]; + HFIELD field; + + if (!genFunctionNameSaxSerialize(obj, buffer)) return; + + fprintf(f, "%s\n", buffer); + fprintf(f, "{\n"); + + fprintf(f, "\tint attrCount, curCount;\n\tchar **keys;\n\tchar **values;\n\tchar buffer[255];\n\n"); + + + if (obj->base_type != NULL) + { + + + fprintf(f, "\tstruct Base_Sax_%s_Serializer bsce = { obj, OnStartElement, OnCharacters, OnEndElement, userData, 0 };\n\n", obj->type); + genFunctionNameBaseOnStartElement(obj, buffer, 1); + genFunctionNameBaseOnEndElement(obj, buffer2, 1); + fprintf(f, "\n\t%s_Sax_Serialize(obj->__base, root_element_name, %s, OnCharacters, %s, (void*)&bsce);\n\n", + obj->base_type, buffer, buffer2); + } + else + { + field = obj->head; + while (field != NULL) + { + if (field->maxOccurs > 1 || field->maxOccurs == -1) + { + genFieldType(field, buffer, 0); + fprintf(f, "\t%s %s_cur;\n", buffer, field->name); + } + field = field->next; + } + + setSaxAttrs(f, obj); + fprintf(f, "\n\tOnStartElement(root_element_name, attrCount, keys, values, userData);\n"); + + field = obj->head; + while (field != NULL) + { + if (field->attrName != NULL) + { + field = field->next; + continue; + } + + if (field->maxOccurs > 1 || field->maxOccurs == -1) + { + fprintf(f, "\t%s_cur = obj->%s_head;\n", field->name, field->name); + fprintf(f, "\twhile (%s_cur != NULL)\n\t{\n", field->name); + + + if (trGetBuildInFlag(field->type) == 1) + { + fprintf(f, "\n\t\tOnStartElement(\"%s\", 0, NULL, NULL, userData);\n", field->name); + parseNS(field->type, ns, type); + + if (!strcmp(type, "string")) + { + fprintf(f, "\t\tif (%s_cur->value != NULL)\n\t\tOnCharacters(\"%s\", %s_cur->value, userData);\n", + field->name, field->name, field->name); + } + if (!strcmp(type, "int") || !strcmp(type, "integer")) + { + fprintf(f, "\t\tsprintf(buffer, \"%%d\", %s_cur->value);\n", field->name); + fprintf(f, "\t\tOnCharacters(\"%s\", buffer, userData);\n", + field->name); + } + if (!strcmp(type, "float") || !strcmp(type, "double")) + { + fprintf(f, "\t\tsprintf(buffer, \"%%f\", %s_cur->value);\n", field->name); + fprintf(f, "\t\tOnCharacters(\"%s\", buffer, userData);\n", + field->name); + } + fprintf(f, "\t\tOnEndElement(\"%s\", userData);\n", field->name); + } + else + { + sprintf(buffer, "%s_Sax_Serialize(%s_cur->value, \"%s\", OnStartElement, OnCharacters, OnEndElement, userData);\n", + field->type, field->name, field->name); + fprintf(f, "\t\t%s\n", buffer); + } + + fprintf(f, "\t\t%s_cur = %s_cur->next;\n", field->name , field->name); + fprintf(f, "\t}\n"); + } + else + { + if (trGetBuildInFlag(field->type) == 1) + { + fprintf(f, "\n\tOnStartElement(\"%s\", 0, NULL, NULL, userData);\n", field->name); + parseNS(field->type, ns, type); + + if (!strcmp(type, "string")) + { + fprintf(f, "\tif (obj->%s != NULL)\n\t\tOnCharacters(\"%s\", obj->%s, userData);\n", + field->name, field->name, field->name); + } + if (!strcmp(type, "int") || !strcmp(type, "integer")) + { + fprintf(f, "\tsprintf(buffer, \"%%d\", obj->%s);\n", field->name); + fprintf(f, "\tOnCharacters(\"%s\", buffer, userData);\n", + field->name); + } + if (!strcmp(type, "float") || !strcmp(type, "double")) + { + fprintf(f, "\tsprintf(buffer, \"%%f\", obj->%s);\n", field->name); + fprintf(f, "\tOnCharacters(\"%s\", buffer, userData);\n", + field->name); + } + fprintf(f, "\tOnEndElement(\"%s\", userData);\n", field->name); + } + else + { + sprintf(buffer, "%s_Sax_Serialize(obj->%s, \"%s\", OnStartElement, OnCharacters, OnEndElement, userData);", + field->type, field->name, field->name); + fprintf(f, "\t%s\n", buffer ); + } + } + field = field->next; + } + fprintf(f, "\n\tOnEndElement(root_element_name, userData);\n"); + } + + + fprintf(f, "}\n\n"); +} + + + +static void writeCodeBaseOnStartElement(FILE* f, HCOMPLEXTYPE obj) +{ + char buffer[1054]; + + genFunctionNameBaseOnStartElement(obj, buffer, 0); + + fprintf(f, "\n%s\n{\n", buffer); + fprintf(f, "\tint attrCount, curCount;\n\tchar buffer[255];\n\n"); + + fprintf(f, "\tstruct Base_Sax_%s_Serializer* bsce = (struct Base_Sax_%s_Serializer*)userData;\n", + obj->type, obj->type); + + fprintf(f, "\n\tattrCount = 0;\n"); + fprintf(f, "\tif (bsce->stackDeep == 0)\n{\n"); + setSaxAttrsBase(f, obj); + fprintf(f, "\t}\n"); + + fprintf(f, "\tbsce->OnStartElement(element_name, attrCount + attr_count, keys, values, bsce->userData);\n"); + fprintf(f, "\tbsce->stackDeep++;\n"); + + fprintf(f, "\n}\n\n"); +} + +static void writeCodeBaseOnEndElement(FILE* f, HCOMPLEXTYPE obj) +{ + char buffer[1054]; + HFIELD field; + char ns[255]; + char type[255]; + + genFunctionNameBaseOnEndElement(obj, buffer, 0); + + fprintf(f, "\n%s\n{\n", buffer); + fprintf(f, "\tchar buffer[255];\n\n"); + + fprintf(f, "\tstruct Base_Sax_%s_Serializer* bsce = (struct Base_Sax_%s_Serializer*)userData;\n", + obj->type, obj->type); + + field = obj->head; + while (field != NULL) + { + if (field->maxOccurs > 1 || field->maxOccurs == -1) + { + genFieldType(field, buffer, 0); + fprintf(f, "\t%s %s_cur;\n", buffer, field->name); + } + field = field->next; + } + + + fprintf(f, "\n\tbsce->stackDeep--;\n"); + + fprintf(f, "\tif (bsce->stackDeep > 0)\n\t{\n\t\tbsce->OnEndElement(element_name, bsce->userData);\n\t}\n"); + fprintf(f, "\telse\n\t{\n"); + + field = obj->head; + while (field != NULL) + { + if (field->attrName != NULL) + { + field = field->next; + continue; + } + + if (field->maxOccurs > 1 || field->maxOccurs == -1) + { + fprintf(f, "\t%s_cur = bsce->obj->%s_head;\n", field->name, field->name); + fprintf(f, "\twhile (%s_cur != NULL)\n\t{\n", field->name); + + + if (trGetBuildInFlag(field->type) == 1) + { + fprintf(f, "\n\t\tbsce->OnStartElement(\"%s\", 0, NULL, NULL, bsce->userData);\n", field->name); + parseNS(field->type, ns, type); + + if (!strcmp(type, "string")) + { + fprintf(f, "\t\tif (%s_cur->value != NULL)\n\t\tbsce->OnCharacters(\"%s\", %s_cur->value, bsce->userData);\n", + field->name, field->name, field->name); + } + if (!strcmp(type, "int") || !strcmp(type, "integer")) + { + fprintf(f, "\t\tsprintf(buffer, \"%%d\", %s_cur->value);\n", field->name); + fprintf(f, "\t\tbsce->OnCharacters(\"%s\", buffer, bsce->userData);\n", + field->name); + } + if (!strcmp(type, "float") || !strcmp(type, "double")) + { + fprintf(f, "\t\tsprintf(buffer, \"%%f\", %s_cur->value);\n", field->name); + fprintf(f, "\t\tbsce->OnCharacters(\"%s\", buffer, bsce->userData);\n", + field->name); + } + fprintf(f, "\t\tbsce->OnEndElement(\"%s\", bsce->userData);\n", field->name); + } + else + { + sprintf(buffer, "%s_Sax_Serialize(%s_cur->value, \"%s\", bsce->OnStartElement, bsce->OnCharacters, bsce->OnEndElement, bsce->userData);\n", + field->type, field->name, field->name); + fprintf(f, "\t\t%s\n", buffer); + } + + fprintf(f, "\t\t%s_cur = %s_cur->next;\n", field->name , field->name); + fprintf(f, "\t}\n"); + } + else + { + if (trGetBuildInFlag(field->type) == 1) + { + fprintf(f, "\n\tbsce->OnStartElement(\"%s\", 0, NULL, NULL, bsce->userData);\n", field->name); + parseNS(field->type, ns, type); + + if (!strcmp(type, "string")) + { + fprintf(f, "\tif (bsce->obj->%s != NULL)\n\t\tbsce->OnCharacters(\"%s\", bsce->obj->%s, bsce->userData);\n", + field->name, field->name, field->name); + } + if (!strcmp(type, "int") || !strcmp(type, "integer")) + { + fprintf(f, "\tsprintf(buffer, \"%%d\", bsce->obj->%s);\n", field->name); + fprintf(f, "\tbsce->OnCharacters(\"%s\", buffer, bsce->userData);\n", + field->name); + } + if (!strcmp(type, "float") || !strcmp(type, "double")) + { + fprintf(f, "\tsprintf(buffer, \"%%f\", bsce->obj->%s);\n", field->name); + fprintf(f, "\tbsce->OnCharacters(\"%s\", buffer, bsce->userData);\n", + field->name); + } + fprintf(f, "\tbsce->OnEndElement(\"%s\", bsce->userData);\n", field->name); + } + else + { + sprintf(buffer, "%s_Sax_Serialize(obj->%s, \"%s\", bsce->OnStartElement, bsce->OnCharacters, bsce->OnEndElement, bsce->userData);", + field->type, field->name, field->name); + fprintf(f, "\t%s\n", buffer ); + } + } + field = field->next; + } + fprintf(f, "\n\tbsce->OnEndElement(element_name, userData);\n"); + + + fprintf(f, "\t}\n"); + fprintf(f, "\n}\n\n"); +} + + +/* ------------------------------------------------------------------------------- */ + +static void writeCodeDeserialize(FILE* f, HCOMPLEXTYPE obj) +{ + char buffer[1054]; + HFIELD field; + char ns[255]; + char type[255]; + + if (!genFunctionNameDeserialize(obj, buffer)) return; + + fprintf(f, "#ifndef _DESERIALIZER_DISABLED_\n\n"); + fprintf(f, "%s\n", buffer); + fprintf(f, "{\n"); + + fprintf(f, "\txmlNodePtr cur;\n\txmlChar *key;\n"); + + fprintf(f, "\tstruct %s* obj;\n", obj->type); + fprintf(f, "\tobj = %s_Create();\n", obj->type); + + + + /* Begin deserialize base type */ + if (obj->base_type != NULL) + { + fprintf(f, "\n\tobj->__base = %s_Deserialize(xmlRoot);\n\n", obj->base_type); + } + + /* End deserialize base type */ + + /* Begin setting attributes */ + field = obj->head; + while (field != NULL) + { + if (field->attrName != NULL) + { + fprintf(f, "\tkey = xmlGetProp(xmlRoot, \"%s\");\n", field->attrName); + fprintf(f, "\tif (key != NULL) {\n"); + parseNS(field->type, ns, type); + + if (!strcmp(type, "string")) + { + fprintf(f, "\t\t%s_Set_%s(obj, (const char*)key);\n", field->parentObj->type, field->name); + } + else if (!strcmp(type, "int") || !strcmp(type, "integer")) + { + fprintf(f, "\t\t%s_Set_%s(obj, atoi((const char*)key));\n", field->parentObj->type, field->name); + } + else if (!strcmp(type, "float") || !strcmp(type, "double")) + { + fprintf(f, "\t\t%s_Set_%s(obj, atof((const char*)key));\n", field->parentObj->type, field->name); + } + else { + fprintf(stderr, "WARNING: Type '%s' not found as attribute\n", type); + } + + fprintf(f, "\t\txmlFree(key);\n"); + fprintf(f, "\t}\n"); + } + + field = field->next; + } + /* End setting attributes */ + + fprintf(f, "\tcur = xmlRoot->xmlChildrenNode;\n"); + fprintf(f, "\twhile (cur != NULL) {\n"); + fprintf(f, "\t\tif (cur->type != XML_ELEMENT_NODE) {\n"); + fprintf(f, "\t\t\tcur = cur->next;\n"); + fprintf(f, "\t\t\tcontinue;\n"); + fprintf(f, "\t\t}\n"); + + /* Just debug you can delete this */ + fprintf(f, "\t\tprintf(\"%s->%%s\\n\", cur->name);\n", obj->type); + + field = obj->head; + while (field != NULL) + { + + if (field->attrName != NULL) + { + field = field->next; + continue; + } + + fprintf(f, "\t\tif ((!xmlStrcmp(cur->name, (const xmlChar *)\"%s\"))){\n", field->name); + + if (trGetBuildInFlag(field->type) == 1) + { + parseNS(field->type, ns, type); + + if (!strcmp(type, "string")) + { + fprintf(f, "\t\t\tkey = xmlNodeListGetString(cur->doc, cur->xmlChildrenNode, 1);\n"); + if (field->maxOccurs > 1 || field->maxOccurs == -1) { + fprintf(f, "\t\t\t%s_Add_%s(obj, (const char*)key);\n", field->parentObj->type, field->name); + } else { + fprintf(f, "\t\t\t%s_Set_%s(obj, (const char*)key);\n", field->parentObj->type, field->name); + } + fprintf(f, "\t\t\txmlFree(key);\n"); + } + else if (!strcmp(type, "int") || !strcmp(type, "integer")) + { + fprintf(f, "\t\t\tkey = xmlNodeListGetString(cur->doc, cur->xmlChildrenNode, 1);\n"); + if (field->maxOccurs > 1 || field->maxOccurs == -1) { + fprintf(f, "\t\t\t%s_Add_%s(obj, atoi((const char*)key));\n", field->parentObj->type, field->name); + } else { + fprintf(f, "\t\t\t%s_Set_%s(obj, atoi((const char*)key));\n", field->parentObj->type, field->name); + } + fprintf(f, "\t\t\txmlFree(key);\n"); + } + else if (!strcmp(type, "float") || !strcmp(type, "double")) + { + fprintf(f, "\t\t\tkey = xmlNodeListGetString(cur->doc, cur->xmlChildrenNode, 1);\n"); + if (field->maxOccurs > 1 || field->maxOccurs == -1) { + fprintf(f, "\t\t\t%s_Add_%s(obj, atof((const char*)key));\n", field->parentObj->type, field->name); + } else { + fprintf(f, "\t\t\t%s_Set_%s(obj, atof((const char*)key));\n", field->parentObj->type, field->name); + } + fprintf(f, "\t\t\txmlFree(key);\n"); + } + } + else + { + fprintf(f, "\t\t\tobj->%s = %s_Deserialize(cur);\n", field->name, field->name); + } + + fprintf(f, "\t\t}\n"); + field = field->next; + } + + + fprintf(f, "\t// TODO: \n"); + fprintf(f, "\t\tcur = cur->next;\n"); + + fprintf(f, "\t}\n"); + + fprintf(f, "\treturn obj;\n"); + fprintf(f, "}\n"); + fprintf(f, "\n#endif\n"); + +} diff --git a/xsd2c/formatter.h b/xsd2c/formatter.h new file mode 100644 index 0000000..3833c96 --- /dev/null +++ b/xsd2c/formatter.h @@ -0,0 +1,36 @@ +/****************************************************************** + * $Id: formatter.h,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ + * + * CSOAP Project: A SOAP client/server library in C + * Copyright (C) 2003 Ferhat Ayaz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Email: ayaz@jprogrammet.net + ******************************************************************/ +#ifndef XSD2C_FORMATTER_H +#define XSD2C_FORMATTER_H + +#include "obj.h" + +#include <stdio.h> + +void writeComplexTypeHeaderFile(FILE* f, HCOMPLEXTYPE obj); +void writeComplexTypeSourceFile(FILE* f, HCOMPLEXTYPE obj); + +extern int formatter_generate_sax_serializer; + +#endif diff --git a/xsd2c/obj.c b/xsd2c/obj.c new file mode 100644 index 0000000..58598de --- /dev/null +++ b/xsd2c/obj.c @@ -0,0 +1,230 @@ +/****************************************************************** + * $Id: obj.c,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ + * + * CSOAP Project: A SOAP client/server library in C + * Copyright (C) 2003 Ferhat Ayaz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Email: ayaz@jprogrammet.net + ******************************************************************/ +#include "obj.h" +#include "tr.h" + +#include <stdio.h> +#include <string.h> + +struct tagObjRegistry +{ + HCOMPLEXTYPE head; + HCOMPLEXTYPE tail; +}objRegistry; + + +static HFIELD fieldCreate(const char* name, const char* type, int flag, int mino, int maxo, HCOMPLEXTYPE parentObj); +static void fieldFree(HFIELD field); +static void objAddField(HCOMPLEXTYPE obj, HFIELD field); +static void objFreeComplexType(HCOMPLEXTYPE obj); +static void objRegistryAddComplexType(HCOMPLEXTYPE obj); + +static char *targetNS = NULL; + +/* ------------------------------------------------------------------ */ + +void objInitModule(const char* tns) +{ + objRegistry.head = NULL; + objRegistry.tail = NULL; + + if (tns != NULL) { + targetNS = (char*)malloc(strlen(tns)+1); + strcpy(targetNS, tns); + } +} + +void objFreeModule() +{ + HCOMPLEXTYPE cur; + + cur = objRegistry.head; + while (cur != NULL) + { + objFreeComplexType(cur); + cur = cur->next; + } + + free(targetNS); +} + + +HCOMPLEXTYPE objCreateComplexType(const char* typename) +{ + HCOMPLEXTYPE ct; + char buf[1054]; + + ct = (HCOMPLEXTYPE)malloc(sizeof(struct COMPLEXTYPE)); + ct->type = (char*)malloc(strlen(typename)+1); + strcpy(ct->type, typename); + ct->head = ct->tail = NULL; + ct->next = NULL; + ct->base_type = NULL; + + objRegistryAddComplexType(ct); + + sprintf(buf, "struct %s*", typename); + trRegisterTypeNS(targetNS, typename, buf); + sprintf(buf, "struct %s_List*", typename); + trRegisterListTypeNS(targetNS, typename, buf); + return ct; +} + +HFIELD objAddElement(HCOMPLEXTYPE obj, const char* name, const char* type, int flag, int mino, int maxo) +{ + HFIELD field; + + field = fieldCreate(name, type, flag, mino, maxo, obj); + objAddField(obj, field); + + return field; +} + +HFIELD objAddAttribute(HCOMPLEXTYPE obj, const char* name, const char* type, int flag) +{ + char buffer[1054]; + HFIELD field; + + sprintf(buffer, "attr_%s", name); + + field = fieldCreate(buffer, type, flag, 1, 1, obj); + field->attrName = (char*)malloc(strlen(name)+1); + strcpy(field->attrName, name); + + objAddField(obj, field); + + return field; +} + +void objSetBaseType(HCOMPLEXTYPE obj, const char* typename) +{ + if (obj->base_type != NULL) free(obj->base_type); + obj->base_type = (char*)malloc(strlen(typename)+1); + strcpy(obj->base_type, typename); +} + +HCOMPLEXTYPE objRegistryGetComplexType(const char* typename) +{ + return NULL; +} + + +void objRegistryEnumComplexType(CT_ENUM callback) +{ + HCOMPLEXTYPE cur; + + cur = objRegistry.head; + while (cur != NULL) + { + if (!callback(cur)) return; + cur = cur->next; + } +} + + +/* ========================================================================= */ + +static +HFIELD fieldCreate(const char* name, const char* type, int flag, int mino, int maxo, HCOMPLEXTYPE parentObj) +{ + HFIELD field; + + field = (HFIELD)malloc(sizeof(struct FIELD)); + field->name = (char*)malloc(strlen(name)+1); + field->type = (char*)malloc(strlen(type)+1); + field->flag = flag; + field->next = NULL; + field->flag = 0; + field->minOccurs = mino; + field->maxOccurs = maxo; + field->parentObj = parentObj; + field->attrName = NULL; + + strcpy(field->name, name); + strcpy(field->type, type); + + return field; +} + + +static +void fieldFree(HFIELD field) +{ + if (field) + { + if (field->name) free(field->name); + if (field->type) free(field->type); + if (field->attrName) free(field->attrName); + if (field->next) fieldFree(field->next); + + free(field); + } +} + + +static +void objAddField(HCOMPLEXTYPE obj, HFIELD field) +{ + if (obj->tail) + { + obj->tail->next = field; + } + + if (!obj->head) + { + obj->head = field; + } + + obj->tail = field; +} + + +static +void objFreeComplexType(HCOMPLEXTYPE obj) +{ + if (obj) + { + if (obj->type) free(obj->type); + if (obj->base_type) free(obj->base_type); + if (obj->head) fieldFree(obj->head); + + free(obj); + } +} + + +static void objRegistryAddComplexType(HCOMPLEXTYPE obj) +{ + if (objRegistry.tail) + { + objRegistry.tail->next = obj; + } + + if (!objRegistry.head) + { + objRegistry.head = obj; + } + + objRegistry.tail = obj; +} diff --git a/xsd2c/obj.h b/xsd2c/obj.h new file mode 100644 index 0000000..6f1b753 --- /dev/null +++ b/xsd2c/obj.h @@ -0,0 +1,65 @@ +/****************************************************************** + * $Id: obj.h,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ + * + * CSOAP Project: A SOAP client/server library in C + * Copyright (C) 2003 Ferhat Ayaz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Email: ayaz@jprogrammet.net + ******************************************************************/ +#ifndef XSD2C_OBJ_H +#define XSD2C_OBJ_H + + +typedef struct FIELD* HFIELD; +typedef struct COMPLEXTYPE* HCOMPLEXTYPE; +typedef int (*CT_ENUM)(HCOMPLEXTYPE); + +struct FIELD +{ + char *name; + char *type; + int flag; + int minOccurs; + int maxOccurs; + char *attrName; + HFIELD next; + HCOMPLEXTYPE parentObj; +}; + +struct COMPLEXTYPE +{ + char *type; + char *base_type; + HFIELD head; + HFIELD tail; + HCOMPLEXTYPE next; +}; + + +void objInitModule(); +void objFreeModule(); + +HCOMPLEXTYPE objCreateComplexType(const char* typename); +void objSetBaseType(HCOMPLEXTYPE obj, const char* typename); +HFIELD objAddElement(HCOMPLEXTYPE obj, const char* name, const char* type, int flag, int mino, int maxo); +HFIELD objAddAttribute(HCOMPLEXTYPE obj, const char* name, const char* type, int flag); + +HCOMPLEXTYPE objRegistryGetComplexType(const char* typename); +void objRegistryEnumComplexType(CT_ENUM callback); + +#endif diff --git a/xsd2c/tr.c b/xsd2c/tr.c new file mode 100644 index 0000000..5756e91 --- /dev/null +++ b/xsd2c/tr.c @@ -0,0 +1,261 @@ +/****************************************************************** + * $Id: tr.c,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ + * + * CSOAP Project: A SOAP client/server library in C + * Copyright (C) 2003 Ferhat Ayaz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Email: ayaz@jprogrammet.net + ******************************************************************/ + +#include "tr.h" +#include <stdio.h> + +#define XSD2C_MAP(xsdtype, ctype) \ + trRegisterType(xsdtype, ctype); + +#define XSD2C_MAPNS(xsdtype, ctype) \ + trRegisterTypeNS(trXSDNS, xsdtype, ctype); + +#define XSD2C_MAPNS_LIST(xsdtype, ctype) \ + trRegisterListTypeNS(trXSDNS, xsdtype, ctype); + +struct XSD2C_TypeRegistry +{ + char *xsd_type; + char *c_type; + int isbuildin; + struct XSD2C_TypeRegistry* next; +}; + +static struct XSD2C_TypeRegistry* tr_head; +static struct XSD2C_TypeRegistry* tr_tail; +static struct XSD2C_TypeRegistry* trl_head; +static struct XSD2C_TypeRegistry* trl_tail; + + +static char trXSDNS[15]; + +static char* _trC2XSD(const char* cType, struct XSD2C_TypeRegistry* head); +static char* _trXSD2C(const char* xsdType, struct XSD2C_TypeRegistry* head); + + +void trInitModule(const char* ns) +{ + tr_head = NULL; + tr_tail = NULL; + trl_head = NULL; + trl_tail = NULL; + struct XSD2C_TypeRegistry* cur; + strcpy(trXSDNS, ns); + + #include "types.map" + + cur = tr_head; + + while (cur != NULL) + { + cur->isbuildin = 1; + cur = cur->next; + } +}; + + +void trFreeModule() +{ + struct XSD2C_TypeRegistry* cur, *tmp; + + cur = tr_head; + + while (cur != NULL) + { + if (cur->xsd_type) free(cur->xsd_type); + if (cur->c_type) free(cur->c_type); + tmp = cur->next; + free(cur); + cur = tmp; + } + cur = trl_head; + + while (cur != NULL) + { + if (cur->xsd_type) free(cur->xsd_type); + if (cur->c_type) free(cur->c_type); + tmp = cur->next; + free(cur); + cur = tmp; + } +} + + +int trGetBuildInFlag(const char* xsdType) +{ + struct XSD2C_TypeRegistry* cur; + + cur = tr_head; + + while (cur != NULL) + { + if (!strcmp(cur->xsd_type, xsdType)) + { + return cur->isbuildin; + } + cur = cur->next; + } + return -1; +} + + +char* trC2XSD(const char* cType) +{ + return _trC2XSD(cType, tr_head); +} + +char* trXSD2C(const char* xsdType) +{ + return _trXSD2C(xsdType, tr_head); +} + +char* trC2XSDList(const char* cType) +{ + return _trC2XSD(cType, trl_head); +} + +char* trXSD2CList(const char* xsdType) +{ + return _trXSD2C(xsdType, trl_head); +} + +void trRegisterType(const char* xsdType, const char* cType) +{ + trRegisterTypeNS(NULL, xsdType, cType); +} + +void trRegisterTypeNS(const char* ns, const char* xsdType, const char* cType) +{ + struct XSD2C_TypeRegistry* reg; + if (xsdType == NULL || cType == NULL) + { + fprintf(stderr, "WARNING: Can not register type\n"); + return; + } + + reg = (struct XSD2C_TypeRegistry*)malloc(sizeof(struct XSD2C_TypeRegistry)); + reg->xsd_type = (char*)malloc((ns?strlen(ns):0)+strlen(xsdType)+2); + reg->c_type = (char*)malloc(strlen(cType)+1); + reg->next = NULL; + reg->isbuildin = 0; + + if (ns) + sprintf(reg->xsd_type, "%s:%s",ns,xsdType); + else + strcpy(reg->xsd_type, xsdType); + + strcpy(reg->c_type, cType); + + if (tr_tail) + { + tr_tail->next = reg; + } + + if (tr_head == NULL) + { + tr_head = reg; + } + + tr_tail = reg; +} + + +void trRegisterListType(const char* xsdType, const char* cType) +{ + trRegisterListTypeNS(NULL, xsdType, cType); +} + +void trRegisterListTypeNS(const char* ns, const char* xsdType, const char* cType) +{ + struct XSD2C_TypeRegistry* reg; + if (xsdType == NULL || cType == NULL) + { + fprintf(stderr, "WARNING: Can not register type\n"); + return; + } + + reg = (struct XSD2C_TypeRegistry*)malloc(sizeof(struct XSD2C_TypeRegistry)); + reg->xsd_type = (char*)malloc((ns?strlen(ns):0)+strlen(xsdType)+2); + reg->c_type = (char*)malloc(strlen(cType)+1); + reg->next = NULL; + reg->isbuildin = 0; + + if (ns) + sprintf(reg->xsd_type, "%s:%s",ns,xsdType); + else + strcpy(reg->xsd_type, xsdType); + + strcpy(reg->c_type, cType); + + if (trl_tail) + { + trl_tail->next = reg; + } + + if (trl_head == NULL) + { + trl_head = reg; + } + + trl_tail = reg; +} + + +static +char* _trC2XSD(const char* cType, struct XSD2C_TypeRegistry* head) +{ + struct XSD2C_TypeRegistry* cur; + + cur = head; + + while (cur != NULL) + { + if (!strcmp(cur->c_type, cType)) + { + return cur->xsd_type; + } + cur = cur->next; + } + + return NULL; +} + +static char* _trXSD2C(const char* xsdType, struct XSD2C_TypeRegistry* head) +{ + struct XSD2C_TypeRegistry* cur; + + cur = head; + + while (cur != NULL) + { + /* printf("%s\n", cur->xsd_type);*/ + if (!strcmp(cur->xsd_type, xsdType)) + { + return cur->c_type; + } + cur = cur->next; + } + + return NULL; +} diff --git a/xsd2c/tr.h b/xsd2c/tr.h new file mode 100644 index 0000000..1beb3fa --- /dev/null +++ b/xsd2c/tr.h @@ -0,0 +1,44 @@ +/****************************************************************** + * $Id: tr.h,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ + * + * CSOAP Project: A SOAP client/server library in C + * Copyright (C) 2003 Ferhat Ayaz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Email: ayaz@jprogrammet.net + ******************************************************************/ +#ifndef XSD2C_TR_H +#define XSD2C_TR_H + +void trInitModule(const char* ns); +void trFreeModule(); + +char* trC2XSD(const char* cType); +char* trXSD2C(const char* xsdType); + +char* trC2XSDList(const char* cType); +char* trXSD2CList(const char* xsdType); + +void trRegisterType(const char* xsdType, const char* cType); +void trRegisterTypeNS(const char* ns, const char* xsdType, const char* cType); + +void trRegisterListType(const char* xsdType, const char* cType); +void trRegisterListTypeNS(const char* ns, const char* xsdType, const char* cType); + +int trGetBuildInFlag(const char* xsdType); + +#endif diff --git a/xsd2c/types.map b/xsd2c/types.map new file mode 100644 index 0000000..e6f4bc3 --- /dev/null +++ b/xsd2c/types.map @@ -0,0 +1,38 @@ +/****************************************************************** + * $Id: types.map,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ + * + * CSOAP Project: A SOAP client/server library in C + * Copyright (C) 2003 Ferhat Ayaz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Email: ayaz@jprogrammer.net + ******************************************************************/ +/* +XSD2C_MAPNS("string", "xsd_str") +XSD2C_MAPNS("integer", "xsd_int") +XSD2C_MAPNS("int", "xsd_int") +XSD2C_MAPNS("double", "xsd_double") +*/ + +XSD2C_MAPNS("ID", "char*") +XSD2C_MAPNS("IDREF", "char*") +XSD2C_MAPNS("IDREFS", "char*") +XSD2C_MAPNS("string", "char*") +XSD2C_MAPNS("integer", "int") +XSD2C_MAPNS("int", "int") +XSD2C_MAPNS("double", "double") +XSD2C_MAPNS("boolean", "int") diff --git a/xsd2c/util.c b/xsd2c/util.c new file mode 100644 index 0000000..7083c5d --- /dev/null +++ b/xsd2c/util.c @@ -0,0 +1,105 @@ +/****************************************************************** + * $Id: util.c,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ + * + * CSOAP Project: A SOAP client/server library in C + * Copyright (C) 2003 Ferhat Ayaz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Email: ayaz@jprogrammer.net + ******************************************************************/ + +#include <stdio.h> +#include <string.h> + +int parseNS(const char* fullname, char *ns, char *name) +{ + int len, i, found; + + if (fullname == NULL || ns == NULL || name == NULL) return 0; + + len = strlen(fullname); + + found = 0; + for (i = len - 1; i > 0; i--) + { + if (fullname[i] == ':') { found = 1; break; } + } + + if (found) strncpy(ns, fullname, i); + else ns[0] = '\0'; + + strcpy(name, + (fullname[i] == ':')? + (&fullname[i+1]):(&fullname[i])); + + return 1; +} + + +void toUpperCase(const char* src, char *dest) +{ + int i, len; + if (src == NULL) return; + + len = strlen(src); + for (i=0;i<len;i++) dest[i] = toupper(src[i]); + dest[i] = '\0'; +} + + +void toLowerCase(const char* src, char *dest) +{ + int i, len; + if (src == NULL) return; + + len = strlen(src); + for (i=0;i<len;i++) dest[i] = tolower(src[i]); + dest[i] = '\0'; +} + +int test_parseNS_main(int argc, char *argv[]) +{ + char ns[50]; + char name[50]; + + char *fullname1 = "xsd:test1"; + char *fullname2 = ":test2"; + char *fullname3 = "test3"; + char *fullname4 = "test4:"; + + ns[0] = '\0'; name[0] = '\0'; + if (parseNS(fullname1, ns, name)) { + printf("%-5s | %-10s\n", ns, name); + } + ns[0] = '\0'; name[0] = '\0'; + if (parseNS(fullname2, ns, name)) { + printf("%-5s | %-10s\n", ns, name); + } + ns[0] = '\0'; name[0] = '\0'; + if (parseNS(fullname3, ns, name)) { + printf("%-5s | %-10s\n", ns, name); + } + ns[0] = '\0'; name[0] = '\0'; + if (parseNS(fullname4, ns, name)) { + printf("%-5s | %-10s\n", ns, name); + } + + return 0; +} + + + diff --git a/xsd2c/util.h b/xsd2c/util.h new file mode 100644 index 0000000..7f7ef09 --- /dev/null +++ b/xsd2c/util.h @@ -0,0 +1,31 @@ +/****************************************************************** + * $Id: util.h,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ + * + * CSOAP Project: A SOAP client/server library in C + * Copyright (C) 2003 Ferhat Ayaz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Email: ayaz@jprogrammet.net + ******************************************************************/ +#ifndef XSD2C_UTIL_H +#define XSD2C_UTIL_H + +int parseNS(const char* fullname, char *ns, char *name); +void toUpperCase(const char* src, char *dest); +void toLowerCase(const char* src, char *dest); + +#endif diff --git a/xsd2c/xsd2c.c b/xsd2c/xsd2c.c new file mode 100644 index 0000000..973dbfa --- /dev/null +++ b/xsd2c/xsd2c.c @@ -0,0 +1,835 @@ +/****************************************************************** + * $Id: xsd2c.c,v 1.1 2004/06/02 11:17:03 snowdrop Exp $ + * + * CSOAP Project: A SOAP client/server library in C + * Copyright (C) 2003 Ferhat Ayaz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Email: ayaz@jprogrammet.net + ******************************************************************/ + +#include <libxml/xmlmemory.h> +#include <libxml/parser.h> + + +#include <stdio.h> +#include "obj.h" +#include "tr.h" +#include "formatter.h" + + +#define NODE_NAME_EQUALS(xmlnode, text) \ + (!xmlStrcmp(xmlnode->name, (const xmlChar *)text)) + + +#define XSD_ALL_STR "all" +#define XSD_ANNOTATION_STR "annotation" +#define XSD_ANY_STR "" +#define XSD_ANY_ATTRIBUTE_STR "any" +#define XSD_APPINFO_STR "appInfo" +#define XSD_ATTRIBUTE_STR "attribute" +#define XSD_ATTRIBUTE_GROUP_STR "attributeGroup" +#define XSD_CHOICE_STR "choice" +#define XSD_COMPLEX_TYPE_STR "complexType" +#define XSD_COMPLEX_CONTENT_STR "complexContent" +#define XSD_DOCUMENTATION_STR "documentation" +#define XSD_ELEMENT_STR "element" +#define XSD_EXTENSION_STR "extension" +#define XSD_FIELD_STR "field" +#define XSD_GROUP_STR "group" +#define XSD_IMPORT_STR "import" +#define XSD_INCLUDE_STR "include" +#define XSD_KEY_STR "key" +#define XSD_KEYREF_STR "keyref" +#define XSD_LIST_STR "list" +#define XSD_NOTATION_STR "notation" +#define XSD_REDEFINE_STR "redefine" +#define XSD_RESTRICTION_STR "restriction" +#define XSD_SCHEMA_STR "schema" +#define XSD_SELECTOR_STR "selector" +#define XSD_SEQUENCE_STR "sequence" +#define XSD_SIMPLE_CONTENT_STR "simpleContent" +#define XSD_SIMPLE_TYPE_STR "simpleType" +#define XSD_UNION_STR "union" +#define XSD_UNIQUE_STR "unique" + +#define ATTR_TYPE_STR "type" +#define ATTR_NAME_STR "name" +#define ATTR_BASE_STR "base" +#define ATTR_MIN_OCCURS_STR "minOccurs" +#define ATTR_MAX_OCCURS_STR "maxOccurs" + +#define ATTR_VALUE_UNBOUNDED "unbounded" + +enum _xsdAttr +{ + ATTR_UNKNOWN, + ATTR_TYPE, + ATTR_NAME, + ATTR_BASE, + ATTR_MIN_OCCURS, + ATTR_MAX_OCCURS +}; + +enum _xsdKeyword +{ + XSD_UNKNOWN, + XSD_ALL, + XSD_ANNOTATION, + XSD_ANY, + XSD_ANY_ATTRIBUTE, + XSD_APPINFO, + XSD_ATTRIBUTE, + XSD_ATTRIBUTE_GROUP, + XSD_CHOICE, + XSD_COMPLEX_TYPE, + XSD_COMPLEX_CONTENT, + XSD_DOCUMENTATION, + XSD_ELEMENT, + XSD_EXTENSION, + XSD_FIELD, + XSD_GROUP, + XSD_IMPORT, + XSD_INCLUDE, + XSD_KEY, + XSD_KEYREF, + XSD_LIST, + XSD_NOTATION, + XSD_REDEFINE, + XSD_RESTRICTION, + XSD_SCHEMA, + XSD_SELECTOR, + XSD_SEQUENCE, + XSD_SIMPLE_CONTENT, + XSD_SIMPLE_TYPE, + XSD_UNION, + XSD_UNIQUE +}; + +typedef enum _xsdKeyword xsdKeyword; +typedef enum _xsdAttr xsdAttr; + +static xmlNodePtr _xmlGetChild(xmlNodePtr node); +static xmlNodePtr _xmlGetNext(xmlNodePtr node); +static HCOMPLEXTYPE xsdProcComplexType(xmlNodePtr node, const char* type); + +static +xsdKeyword xsdGetKeyword(xmlNodePtr node) +{ + if (node == NULL) return XSD_UNKNOWN; + + if (NODE_NAME_EQUALS(node, XSD_ALL_STR)) return XSD_ALL; + if (NODE_NAME_EQUALS(node, XSD_ANNOTATION_STR)) return XSD_ANNOTATION; + if (NODE_NAME_EQUALS(node, XSD_ANY_STR)) return XSD_ANY; + if (NODE_NAME_EQUALS(node, XSD_ANY_ATTRIBUTE_STR)) return XSD_ANY_ATTRIBUTE; + if (NODE_NAME_EQUALS(node, XSD_APPINFO_STR)) return XSD_APPINFO; + if (NODE_NAME_EQUALS(node, XSD_ATTRIBUTE_STR)) return XSD_ATTRIBUTE; + if (NODE_NAME_EQUALS(node, XSD_ATTRIBUTE_GROUP_STR)) return XSD_ATTRIBUTE_GROUP; + if (NODE_NAME_EQUALS(node, XSD_CHOICE_STR)) return XSD_CHOICE; + if (NODE_NAME_EQUALS(node, XSD_COMPLEX_TYPE_STR)) return XSD_COMPLEX_TYPE; + if (NODE_NAME_EQUALS(node, XSD_COMPLEX_CONTENT_STR)) return XSD_COMPLEX_CONTENT; + if (NODE_NAME_EQUALS(node, XSD_DOCUMENTATION_STR)) return XSD_DOCUMENTATION; + if (NODE_NAME_EQUALS(node, XSD_ELEMENT_STR)) return XSD_ELEMENT; + if (NODE_NAME_EQUALS(node, XSD_EXTENSION_STR)) return XSD_EXTENSION; + if (NODE_NAME_EQUALS(node, XSD_FIELD_STR)) return XSD_FIELD; + if (NODE_NAME_EQUALS(node, XSD_GROUP_STR)) return XSD_GROUP; + if (NODE_NAME_EQUALS(node, XSD_IMPORT_STR)) return XSD_IMPORT; + if (NODE_NAME_EQUALS(node, XSD_INCLUDE_STR)) return XSD_INCLUDE; + if (NODE_NAME_EQUALS(node, XSD_KEY_STR)) return XSD_KEY; + if (NODE_NAME_EQUALS(node, XSD_KEYREF_STR)) return XSD_KEYREF; + if (NODE_NAME_EQUALS(node, XSD_LIST_STR)) return XSD_LIST; + if (NODE_NAME_EQUALS(node, XSD_NOTATION_STR)) return XSD_NOTATION; + if (NODE_NAME_EQUALS(node, XSD_REDEFINE_STR)) return XSD_REDEFINE; + if (NODE_NAME_EQUALS(node, XSD_RESTRICTION_STR)) return XSD_RESTRICTION; + if (NODE_NAME_EQUALS(node, XSD_SCHEMA_STR)) return XSD_SCHEMA; + if (NODE_NAME_EQUALS(node, XSD_SELECTOR_STR)) return XSD_SELECTOR; + if (NODE_NAME_EQUALS(node, XSD_SEQUENCE_STR)) return XSD_SEQUENCE; + if (NODE_NAME_EQUALS(node, XSD_SIMPLE_CONTENT_STR)) return XSD_SIMPLE_CONTENT; + if (NODE_NAME_EQUALS(node, XSD_SIMPLE_TYPE_STR)) return XSD_SIMPLE_TYPE; + if (NODE_NAME_EQUALS(node, XSD_UNION_STR)) return XSD_UNION; + if (NODE_NAME_EQUALS(node, XSD_UNIQUE_STR)) return XSD_UNIQUE; + + return XSD_UNKNOWN; +} + + +static char outDir[1054]; + + + +static +void usage(); + + +static +xmlNodePtr xmlFindSubElement(xmlNodePtr root, const char* element_name) +{ + xmlNodePtr cur; + + cur = root->xmlChildrenNode; + while (cur != NULL) { + + if (cur->type != XML_ELEMENT_NODE) { + cur = cur->next; + continue; + } + + if (!xmlStrcmp(cur->name, (const xmlChar*)element_name)) { + return cur; + } + + cur = cur->next; + } + + return NULL; +} + +static +xmlNodePtr xsdLoadFile(const char* filename) +{ + xmlDocPtr doc; + xmlNodePtr cur; + + doc = xmlParseFile(filename); + if (doc == NULL) return NULL; + + cur = xmlDocGetRootElement(doc); + + return cur; +} + + +static +xmlNodePtr wsdlLoadFile(const char* filename) +{ + xmlDocPtr doc; + xmlNodePtr cur; + xmlNodePtr sub; + xsdKeyword keyword; + + doc = xmlParseFile(filename); + if (doc == NULL) return NULL; + + cur = xmlDocGetRootElement(doc); + if (cur == NULL) { + return NULL; + } + + cur = xmlFindSubElement(cur, "types"); + if (cur == NULL) return NULL; +/* + sub = xmlFindSubElement(cur, "schema"); + if (sub != NULL) + return sub; +*/ + /* some wsdl's defines xsd without root <schema> element */ + sub = _xmlGetChild(cur); + keyword = xsdGetKeyword(sub); + switch (keyword) + { + case XSD_ELEMENT: + case XSD_COMPLEX_TYPE: + case XSD_SIMPLE_TYPE: + case XSD_SCHEMA: + return sub; + } + + return NULL; +} + + +static +xmlNodePtr _xmlGetChild(xmlNodePtr node) +{ + xmlNodePtr cur = NULL; + cur = node->xmlChildrenNode; + while (cur != NULL) { + if (cur->type != XML_ELEMENT_NODE) { + cur = cur->next; + continue; + } + return cur; + } + return cur; +} + +static +xmlNodePtr _xmlGetNext(xmlNodePtr node) +{ + xmlNodePtr cur = NULL; + cur = node->next; + while (cur != NULL) { + if (cur->type != XML_ELEMENT_NODE) { + cur = cur->next; + continue; + } + return cur; + } + return cur; +} + +static +void xsdProcAttribute(HCOMPLEXTYPE parent, xmlNodePtr node) +{ + char *name, *type; + xmlNodePtr cur; + char buffer[1054]; + + name = xmlGetProp(node, ATTR_NAME_STR); + type = xmlGetProp(node, ATTR_TYPE_STR); + + /* printf(" %s: %s\n", type?type:"(null)", + name?name:"(null)"); +*/ + if (name == NULL) + { + fprintf(stderr, "WARNING: Attribute without name!\n"); + return; + } + + if (type == NULL) + { + fprintf(stderr, "WARNING: Attribute '%s' has no type\n", name); + } + +/* sprintf(buffer, "attr_%s", name); */ + + objAddAttribute(parent, name, type, 0); +} + +static +void xsdProcElement(HCOMPLEXTYPE parent, xmlNodePtr node) +{ + char *name, *type, *minostr, *maxostr; + xmlNodePtr cur; + xsdKeyword keyword; + char buffer[1054]; + HCOMPLEXTYPE ct; + int mino, maxo; + + name = xmlGetProp(node, ATTR_NAME_STR); + type = xmlGetProp(node, ATTR_TYPE_STR); + minostr = xmlGetProp(node, ATTR_MIN_OCCURS_STR); + maxostr = xmlGetProp(node, ATTR_MAX_OCCURS_STR); + +/* printf(" %s: %s\n", type?type:"(null)", + name?name:"(null)"); +*/ + if (minostr == NULL) mino = 1; + else mino = atoi(minostr); + + if (maxostr == NULL) maxo = 1; + else { + if (!strcmp(maxostr, ATTR_VALUE_UNBOUNDED)) + maxo = -1; + else + maxo = atoi(maxostr); + } + + + if (type == NULL) + { + /* check for complexType */ + cur = _xmlGetChild(node); + if (cur == NULL) + { + fprintf(stderr, "WARNING: Element '%s' has no childs\n", name); + return; + } + + do + { + keyword = xsdGetKeyword(cur); + + switch (keyword) + { + case XSD_COMPLEX_TYPE: + /* + type = xmlGetProp(cur, ATTR_NAME_STR); + if (type == NULL) + { + fprintf(stderr, "WARNING: Type name not found\n"); + break; + } + */ + + sprintf(buffer, "%s_%s", parent->type, (const char*)name); + ct = xsdProcComplexType(cur, (const char*)buffer); + if (ct != NULL) + { + objAddElement(parent, name, buffer,0, mino, maxo); + } + break; + } + + } while ((cur = _xmlGetNext(cur)) != NULL); + } + else + { + objAddElement(parent, name, type,0, mino, maxo); + } + + if (name) xmlFree(name); + if (type) xmlFree(type); +} + +static +void xsdProcSequence(HCOMPLEXTYPE ct, xmlNodePtr node) +{ + xmlNodePtr cur = NULL; + xsdKeyword keyword; + + cur = _xmlGetChild(node); + if (cur == NULL) { + fprintf(stderr, "WARNING: Empty sequence\n"); + return; + } + + do { + keyword = xsdGetKeyword(cur); + + switch (keyword) + { + case XSD_ANNOTATION: + /* nothing to do*/ + break; + + case XSD_GROUP: + fprintf(stderr, "WARNING: %s not supported\n", XSD_GROUP_STR); + break; + + case XSD_CHOICE: + fprintf(stderr, "WARNING: %s not supported\n", XSD_CHOICE_STR); + break; + + case XSD_SEQUENCE: + fprintf(stderr, "WARNING: %s not supported\n", XSD_SEQUENCE_STR); + break; + + case XSD_ANY: + fprintf(stderr, "WARNING: %s not supported\n", XSD_ANY_STR); + break; + + case XSD_ELEMENT: + xsdProcElement(ct, cur); + break; + + default: + fprintf(stderr, "WARNING: Unknown child ('%s')!\n", (char*)cur->name); + }; + } while ((cur = _xmlGetNext(cur)) != NULL); +} + + +static +void xsdProcExtension(HCOMPLEXTYPE ct, xmlNodePtr node, const char* type) +{ + xmlNodePtr cur = NULL; + xsdKeyword keyword; + char * base; + + + base = xmlGetProp(node, ATTR_BASE_STR); + if (base == NULL) { + fprintf(stderr, "WARNING: No base defined\n"); + return; + } + + printf(" =[Base] -> %s\n", base); + objSetBaseType(ct, base); + xmlFree(base); + + cur = _xmlGetChild(node); + if (cur == NULL) { + fprintf(stderr, "WARNING: Empty node\n"); + return; + } + + do { + keyword = xsdGetKeyword(cur); + + switch (keyword) + { + case XSD_ANNOTATION: + /* nothing to do*/ + break; + + case XSD_ALL: + fprintf(stderr, " WARNING: %s not supported\n", XSD_ALL_STR); + break; + + case XSD_GROUP: + fprintf(stderr, "WARNING: %s not supported\n", XSD_GROUP_STR); + break; + + case XSD_CHOICE: + fprintf(stderr, "WARNING: %s not supported\n", XSD_CHOICE_STR); + break; + + case XSD_ATTRIBUTE: + xsdProcAttribute(ct, cur); + break; + + case XSD_ATTRIBUTE_GROUP: + fprintf(stderr, "WARNING: %s not supported\n", XSD_ATTRIBUTE_GROUP_STR); + break; + + case XSD_ANY_ATTRIBUTE: + fprintf(stderr, "WARNING: %s not supported\n", XSD_ANY_ATTRIBUTE_STR); + break; + + case XSD_SEQUENCE: + xsdProcSequence(ct, cur); + break; + + default: + fprintf(stderr, "WARNING: Unknown child ('%s')!\n", (char*)cur->name); + }; + + } while ((cur = _xmlGetNext(cur)) != NULL); +} + + +static +void xsdProcComplexContent(HCOMPLEXTYPE ct, xmlNodePtr node, const char* type) +{ + xmlNodePtr cur = NULL; + xsdKeyword keyword; + + cur = _xmlGetChild(node); + if (cur == NULL) { + fprintf(stderr, "WARNING: Empty sequence\n"); + return; + } + + do { + keyword = xsdGetKeyword(cur); + + switch (keyword) + { + case XSD_ANNOTATION: + /* nothing to do*/ + break; + + case XSD_EXTENSION: + xsdProcExtension(ct, cur, type); + break; + + case XSD_RESTRICTION: + fprintf(stderr, "WARNING: %s not supported\n", XSD_RESTRICTION_STR); + break; + + default: + fprintf(stderr, "WARNING: Unknown child ('%s')!\n", (char*)cur->name); + }; + + } while ((cur = _xmlGetNext(cur)) != NULL); +} + +static +HCOMPLEXTYPE xsdProcComplexType(xmlNodePtr node, const char* type) +{ + char *name; + xmlNodePtr cur = NULL; + xsdKeyword keyword; + HCOMPLEXTYPE ct; + + if (!type) + name = xmlGetProp(node, ATTR_NAME_STR); + else { + name = (char*)malloc(strlen(type)+1); + strcpy(name, type); + } + + if (!name) + { + fprintf(stderr, "\nWARNING: complexType has no typename!\n", name); + return NULL; + } + + ct = objCreateComplexType(name); + + printf("\ncomplexType->%s\n", name); + + cur = _xmlGetChild(node); + if (cur == NULL) { + fprintf(stderr, "WARNING: Empty complexType\n"); + return ct; + } + + + + do { + keyword = xsdGetKeyword(cur); + + switch (keyword) + { + case XSD_ANNOTATION: + /* nothing to do*/ + break; + + case XSD_SIMPLE_CONTENT: + fprintf(stderr, "WARNING: %s not supported\n", XSD_SIMPLE_CONTENT_STR); + break; + + case XSD_COMPLEX_CONTENT: + xsdProcComplexContent(ct, cur, name); + /* fprintf(stderr, "WARNING: %s not supported\n", XSD_COMPLEX_CONTENT_STR); */ + break; + + case XSD_ALL: + fprintf(stderr, "WARNING: %s not supported\n", XSD_ALL_STR); + break; + + case XSD_GROUP: + fprintf(stderr, "WARNING: %s not supported\n", XSD_GROUP_STR); + break; + + case XSD_CHOICE: + fprintf(stderr, "WARNING: %s not supported\n", XSD_CHOICE_STR); + break; + + case XSD_ATTRIBUTE: + xsdProcAttribute(ct, cur); + break; + + case XSD_ATTRIBUTE_GROUP: + fprintf(stderr, "WARNING: %s not supported\n", XSD_ATTRIBUTE_GROUP_STR); + break; + + case XSD_ANY_ATTRIBUTE: + fprintf(stderr, "WARNING: %s not supported\n", XSD_ANY_ATTRIBUTE_STR); + break; + + case XSD_SEQUENCE: + xsdProcSequence(ct, cur); + break; + + default: + fprintf(stderr, "WARNING: Unknown child ('%s')!\n", (char*)cur->name); + }; + + } while ((cur = _xmlGetNext(cur)) != NULL); + + xmlFree(name); + return ct; +} + + + +static +void runGenerator(xmlNodePtr xsdRoot) +{ + xmlNodePtr cur; + xmlNodePtr node; + xmlChar *type; + + cur = xsdRoot->xmlChildrenNode; + while (cur != NULL) { + + if (cur->type != XML_ELEMENT_NODE) { + cur = cur->next; + continue; + } + + if (xsdGetKeyword(cur) == XSD_COMPLEX_TYPE){ + + xsdProcComplexType(cur, NULL); + + } else if (xsdGetKeyword(cur) == XSD_ELEMENT) { + + type = xmlGetProp(cur, "name"); + if (type == NULL) { + fprintf(stderr, "WARNING: Element found without name ('%s')\n", cur->name); + } else { + + node = xmlFindSubElement(cur, XSD_COMPLEX_TYPE_STR); + if (node != NULL) { + xsdProcComplexType(node, type); + } + + } + + } + + cur = cur->next; + } +} + +int declareStructs(HCOMPLEXTYPE ct) +{ + char fname[255]; + FILE* f; + + sprintf(fname, "%s/%s_xsd.h", outDir, ct->type); + printf("Generating file '%s' ...\n", fname); + f = fopen(fname, "w"); + if (f == NULL) + { + fprintf(stderr, "Can not open '%s'\n", fname); + return 0; + } + + writeComplexTypeHeaderFile(f, ct); + fclose(f); + + return 1; +} + +int writeSource(HCOMPLEXTYPE ct) +{ + char fname[255]; + FILE* f; + + sprintf(fname, "%s/%s_xsd.c", outDir, ct->type); + printf("Generating file '%s' ...\n", fname); + f = fopen(fname, "w"); + if (f == NULL) + { + fprintf(stderr, "Can not open '%s'\n", fname); + return 0; + } + + writeComplexTypeSourceFile(f, ct); + fclose(f); + + return 1; +} + + +int xsdInitTrModule(xmlNodePtr xsdNode) +{ + xmlNsPtr ns; + + ns = xmlSearchNsByHref(xsdNode->doc, xsdNode, "http://www.w3.org/2001/XMLSchema"); + if (ns == NULL) { + fprintf(stderr, "XML Schema namespace not found!\n"); + return 0; + } + + if (ns->prefix == NULL) { + fprintf(stderr, "XML Schema namespace not found!\n"); + return 0; + } + + fprintf(stdout, "XMLSchema namespace prefix: '%s'\n", ns->prefix); + trInitModule(ns->prefix); + + return 1; +} + + +int xsdInitObjModule(xmlNodePtr xsdNode) +{ + xmlChar *tns; + xmlNsPtr ns; + + tns = xmlGetProp(xsdNode, (const xmlChar*)"targetNamespace"); + + if (tns == NULL) { + + objInitModule(NULL); + + } else { + + ns = xmlSearchNsByHref(xsdNode->doc, xsdNode, tns); + if (ns == NULL) { + fprintf(stderr, "WARNING: Target namespace not found!\n"); + return 0; + } + + if (ns->prefix == NULL) { + fprintf(stderr, "WARNING: Target namespace not found!\n"); + return 0; + } + + fprintf(stdout, "Target namespace ('%s') prefix: '%s'\n", tns, ns->prefix); + objInitModule(ns->prefix); + + } + + + return 1; +} + + +int main(int argc, char *argv[]) +{ + int i; + xmlNodePtr xsdNode = NULL; + char fname[255]; + int wsdl = 0; + + if (argc < 2) { + usage(argv[0]); + return 1; + } + + + strcpy(outDir, "."); + + for (i=1;i<argc;i++) + { + if (!strcmp(argv[i], "-d")) + if (i==argc-1) usage(argv[0]); + else strcpy(outDir, argv[++i]); + else if (!strcmp(argv[i], "-S")) + formatter_generate_sax_serializer = 1; + else if (!strcmp(argv[i], "-wsdl")) + wsdl = 1; + else strcpy(fname, argv[i]); + } + + mkdir(outDir, 000); + + if (wsdl) + xsdNode = wsdlLoadFile(fname); + else + xsdNode = xsdLoadFile(fname); + + if (xsdNode == NULL) { + fprintf(stderr, "can not load xsd file!\n"); + return 1; + } + + if (!xsdInitTrModule(xsdNode)) + return 1; + + if (!xsdInitObjModule(xsdNode)) + return 1; + + runGenerator(xsdNode); + objRegistryEnumComplexType(declareStructs); + objRegistryEnumComplexType(writeSource); + + xmlFreeDoc(xsdNode->doc); + trFreeModule(); + objFreeModule(); + + return 0; +} + + + +void usage(const char* execName) +{ + printf("usage: %s [-d <destdir> -S -D] <xsd filename>\n", execName); +} + + + + |