Skip to content
Snippets Groups Projects
Commit be75595b authored by rds's avatar rds
Browse files

- change to xml factory

- towards consistent naming...
parent 7a4ec4d5
No related branches found
No related tags found
No related merge requests found
......@@ -27,17 +27,14 @@
*
* Exported functions: See XXXXXXXXXXXXX.h
* HISTORY:
* Last edited: Sep 5 18:19 2005 (rds)
* Last edited: Sep 9 12:41 2005 (rds)
* Created: Fri Aug 5 14:20:13 2005 (rds)
* CVS info: $Id: zmapXMLAttribute.c,v 1.1 2005-09-05 17:28:22 rds Exp $
* CVS info: $Id: zmapXMLAttribute.c,v 1.2 2005-09-20 17:18:11 rds Exp $
*-------------------------------------------------------------------
*/
#include <zmapXML_P.h>
static void freeAttr(gpointer data, gpointer unused);
zmapXMLAttribute zmapXMLAttribute_create(const XML_Char *name,
const XML_Char *value)
{
......@@ -54,14 +51,11 @@ zmapXMLAttribute zmapXMLAttribute_create(const XML_Char *name,
void zmapXMLAttribute_free(zmapXMLAttribute attr)
{
if(attr != NULL)
g_free(attr);
return ;
}
void zmapXMLAttribute_list_free(GList *attr_list)
{
g_list_foreach(attr_list, freeAttr, NULL);
g_list_free(attr_list);
{
attr->name = 0;
attr->value = 0;
g_free(attr);
}
return ;
}
......@@ -72,11 +66,3 @@ GQuark zMapXMLAttribute_getValue(zmapXMLAttribute attr)
/* Internal ! */
static void freeAttr(gpointer data, gpointer unused)
{
zmapXMLAttribute attr = (zmapXMLAttribute)data;
g_free(attr);
return ;
}
......@@ -27,9 +27,9 @@
*
* Exported functions: See XXXXXXXXXXXXX.h
* HISTORY:
* Last edited: Aug 10 12:53 2005 (rds)
* Last edited: Sep 9 12:53 2005 (rds)
* Created: Tue Aug 9 14:25:26 2005 (rds)
* CVS info: $Id: zmapXMLDocument.c,v 1.1 2005-09-05 17:28:22 rds Exp $
* CVS info: $Id: zmapXMLDocument.c,v 1.2 2005-09-20 17:18:11 rds Exp $
*-------------------------------------------------------------------
*/
......@@ -51,7 +51,7 @@ zmapXMLDocument zMapXMLDocument_create(const XML_Char *version,
return doc;
}
void zMapXMLDocument_set_root(zmapXMLDocument doc,
void zMapXMLDocument_setRoot(zmapXMLDocument doc,
zmapXMLElement root)
{
if(!(doc->root))
......@@ -71,7 +71,7 @@ char *zMapXMLDocument_encoding(zmapXMLDocument doc)
return g_strdup(g_quark_to_string(doc->encoding));
}
gboolean zMapXMLDocument_is_standalone(zmapXMLDocument doc)
gboolean zMapXMLDocument_isStandalone(zmapXMLDocument doc)
{
if(doc->standalone)
return TRUE;
......
......@@ -27,15 +27,16 @@
*
* Exported functions: See XXXXXXXXXXXXX.h
* HISTORY:
* Last edited: Sep 9 16:21 2005 (edgrif)
* Last edited: Sep 12 16:36 2005 (rds)
* Created: Fri Aug 5 14:33:49 2005 (rds)
* CVS info: $Id: zmapXMLElement.c,v 1.4 2005-09-09 15:21:53 edgrif Exp $
* CVS info: $Id: zmapXMLElement.c,v 1.5 2005-09-20 17:18:11 rds Exp $
*-------------------------------------------------------------------
*/
#include <zmapXML_P.h>
static void freeElement(gpointer data, gpointer unused);
static void freeAttributeListItems(gpointer item, gpointer data);
/* Creates a named element. That's it. */
zmapXMLElement zmapXMLElement_create(const XML_Char *name)
......@@ -70,19 +71,24 @@ void zmapXMLElement_addChild(zmapXMLElement parent, zmapXMLElement child)
child->parent = parent;
return ;
}
void zmapXMLElement_removeChild(zmapXMLElement parent, zmapXMLElement child)
gboolean zmapXMLElement_signalParentChildFree(zmapXMLElement child)
{
/* In case we get passed the root element as the the child, it's
/* In case we get passed the root element as the the child, its
parent is NULL! */
zmapXMLElement parent = NULL;
parent = child->parent;
if(parent == NULL)
return ; /* NOT SURE THIS IS RIGHT! */
return FALSE;
parent->children = g_list_remove(parent->children, child);
return ;
return TRUE;
}
void zmapXMLElement_add_content(zmapXMLElement ele,
const XML_Char *content,
int len)
void zmapXMLElement_addContent(zmapXMLElement ele,
const XML_Char *content,
int len)
{
/* N.B. we _only_ get away with this because XML_Char == char at the moment,
* this will need to be fixed in the future to support UNICODE/UTF-16 etc...
......@@ -237,8 +243,6 @@ zmapXMLAttribute zMapXMLElement_getAttributeByName(zmapXMLElement ele,
*/
void zmapXMLElement_free(zmapXMLElement ele)
{
GList *c;
if(ele == NULL)
return ;
......@@ -251,7 +255,7 @@ void zmapXMLElement_free(zmapXMLElement ele)
g_string_free(ele->contents, TRUE);
/* Now the attributes */
zmapXMLAttribute_list_free(ele->attributes);
zmapXMLElement_freeAttrList(ele);
/* my parent, doesn't need 2 b freed so set to null! */
/* I might want a handler here, but not sure
......@@ -265,6 +269,18 @@ void zmapXMLElement_free(zmapXMLElement ele)
return ;
}
void zmapXMLElement_freeAttrList(zmapXMLElement ele)
{
GList *list = NULL;
list = ele->attributes;
g_list_foreach(list, freeAttributeListItems, NULL);
g_list_free(list);
ele->attributes = NULL;
return ;
}
......@@ -277,3 +293,12 @@ static void freeElement(gpointer data, gpointer unused)
zmapXMLElement_free(ele);
return ;
}
static void freeAttributeListItems(gpointer item, gpointer data)
{
zmapXMLAttribute attr = (zmapXMLAttribute)item;
zmapXMLAttribute_free(attr);
return ;
}
......@@ -27,74 +27,284 @@
*
* Exported functions: See XXXXXXXXXXXXX.h
* HISTORY:
* Last edited: Sep 8 17:12 2005 (rds)
* Last edited: Sep 14 14:35 2005 (rds)
* Created: Tue Aug 16 14:40:59 2005 (rds)
* CVS info: $Id: zmapXMLFactory.c,v 1.2 2005-09-08 17:49:52 rds Exp $
* CVS info: $Id: zmapXMLFactory.c,v 1.3 2005-09-20 17:18:11 rds Exp $
*-------------------------------------------------------------------
*/
#include <zmapXML_P.h>
static
gboolean zmapXMLFactoryIntHandler(void *userData,
zmapXMLElement element,
zmapXMLParser parser,
gboolean isStart);
zmapXMLFactoryLiteItem zMapXMLFactoryLiteItem_create(int tag_type)
{
zmapXMLFactoryLiteItem item = NULL;
item = g_new0(zmapXMLFactoryLiteItemStruct, 1);
item->tag_type = tag_type;
item->list = NULL;
return item;
}
void zMapXMLFactoryLite_addItem(zmapXMLFactory factory,
zmapXMLFactoryLiteItem item,
char *tag)
{
/* Assert factory, item and tag */
if(tag && *tag)
g_hash_table_insert(factory->hash,
GINT_TO_POINTER(g_quark_from_string(g_ascii_strdown(tag, -1))),
item);
return ;
}
/* This might mean we can make elements private */
int zMapXMLFactoryDecodeElement(GHashTable *userTypesTable,
zmapXMLElement element,
GList **listout)
int zMapXMLFactoryLite_decodeElement(zmapXMLFactory factory,
zmapXMLElement element,
GList **listout)
{
return zMapXMLFactoryDecodeNameQuark(userTypesTable, element->name, listout);
return zMapXMLFactoryLite_decodeNameQuark(factory, element->name, listout);
}
int zMapXMLFactoryDecodeNameQuark(GHashTable *userTypesTable,
GQuark name,
GList **listout)
int zMapXMLFactoryLite_decodeNameQuark(zmapXMLFactory factory,
GQuark name,
GList **listout)
{
zmapXMLFactoryItem ptype = NULL;
zmapXMLFactoryLiteItem item = NULL;
int type = -1;
ptype = g_hash_table_lookup(userTypesTable,
item = g_hash_table_lookup(factory->hash,
GINT_TO_POINTER(name));
if(ptype)
if(item)
{
type = ptype->type;
type = item->tag_type;
if(listout)
*listout = ptype->list;
*listout = item->list;
}
return type;
}
void zMapXMLFactoryListAddItem(GHashTable *userTypesTable,
zmapXMLElement element,
void *listItem)
void zMapXMLFactoryLite_addOutput(zmapXMLFactory factory,
zmapXMLElement element,
void *listItem)
{
zmapXMLFactoryItem ptype = NULL;
zmapXMLFactoryLiteItem item = NULL;
if(!listItem)
return ;
ptype = g_hash_table_lookup(userTypesTable,
item = g_hash_table_lookup(factory->hash,
GINT_TO_POINTER(element->name));
if(ptype)
ptype->list = g_list_prepend(ptype->list, listItem);
if(item)
item->list = g_list_prepend(item->list, listItem);
return ;
}
void zMapXMLFactoryFreeListComplete(GHashTable *userTypesTable,
void zMapXMLFactoryFreeListComplete(zmapXMLFactory factory,
GQuark name,
GFunc func,
gpointer userData)
{
zmapXMLFactoryItem ptype = NULL;
zmapXMLFactoryLiteItem item = NULL;
ptype = g_hash_table_lookup(userTypesTable,
item = g_hash_table_lookup(factory->hash,
GINT_TO_POINTER(name));
g_list_foreach(ptype->list, func, userData);
g_list_free(ptype->list);
ptype->list = NULL;
if(func)
g_list_foreach(item->list, func, userData);
g_list_free(item->list);
item->list = NULL;
return ;
}
zmapXMLFactory zMapXMLFactory_create(gboolean useLite)
{
zmapXMLFactory factory = NULL;
factory = g_new0(zmapXMLFactoryStruct, 1);
factory->hash = g_hash_table_new(NULL, NULL);
factory->isLite = useLite;
return factory;
}
void zMapXMLFactory_setUserData(zmapXMLFactory factory, gpointer data)
{
factory->userData = data;
}
zmapXMLFactoryItem zMapXMLFactory_decodeElement(zmapXMLFactory factory,
zmapXMLElement element)
{
return zMapXMLFactory_decodeNameQuark(factory, element->name);
}
zmapXMLFactoryItem zMapXMLFactory_decodeNameQuark(zmapXMLFactory factory,
GQuark name)
{
zmapXMLFactoryItem item = NULL;
item = g_hash_table_lookup(factory->hash,
GINT_TO_POINTER(name));
return item;
}
GList *zMapXMLFactory_listFetchOutput(zmapXMLFactory factory,
GQuark name)
{
zmapXMLFactoryItem item = NULL;
GList *list = NULL;
item = zMapXMLFactory_decodeNameQuark(factory, name);
if(item && (item->datatype == ZMAP_XML_FACTORY_LIST))
list = item->storage.list;
return list;
}
GData *zMapXMLFactory_dataFetchOutput(zmapXMLFactory factory,
GQuark name)
{
zmapXMLFactoryItem item = NULL;
GData *data = NULL;
item = zMapXMLFactory_decodeNameQuark(factory, name);
if(item && (item->datatype == ZMAP_XML_FACTORY_DATALIST))
data = item->storage.datalist;
return data;
}
void zMapXMLFactory_createItemInsert(zmapXMLFactory factory,
char *tag,
zmapXMLFactoryFunc start,
zmapXMLFactoryFunc end,
zmapXMLFactoryStorageType type)
{
zmapXMLFactoryItem item = NULL;
item = g_new0(zmapXMLFactoryItemStruct, 1);
item->begin = start;
item->end = end;
item->datatype = type;
if(item->datatype == ZMAP_XML_FACTORY_DATALIST)
g_datalist_init(&(item->storage.datalist));
if(tag && *tag)
g_hash_table_insert(factory->hash,
GINT_TO_POINTER(g_quark_from_string(g_ascii_strdown(tag, -1))),
item);
return ;
}
/* parser start and end handlers */
gboolean zmapXML_FactoryEndHandler(void *userData,
zmapXMLElement element,
zmapXMLParser parser)
{
return zmapXMLFactoryIntHandler(userData, element, parser, FALSE);
}
gboolean zmapXML_FactoryStartHandler(void *userData,
zmapXMLElement element,
zmapXMLParser parser)
{
return zmapXMLFactoryIntHandler(userData, element, parser, TRUE);
}
void zMapXMLFactory_dataAddOutput(zmapXMLFactoryItem item,
gpointer data,
GQuark key,
GDestroyNotify notify)
{
if(key && (item->datatype == ZMAP_XML_FACTORY_DATALIST))
{
g_datalist_id_set_data_full(&(item->storage.datalist),
key, data, notify);
}
return ;
}
void zMapXMLFactory_listAddOutput(zmapXMLFactoryItem item,
gpointer data)
{
if(item->datatype == ZMAP_XML_FACTORY_LIST)
item->storage.list = g_list_prepend(item->storage.list, data);
return ;
}
void zMapXMLFactoryItem_dataListClear(zmapXMLFactoryItem item)
{
if(item->datatype == ZMAP_XML_FACTORY_DATALIST)
g_datalist_clear(&(item->storage.datalist));
return ;
}
/* INTERNAL */
static
gboolean zmapXMLFactoryIntHandler(void *userData,
zmapXMLElement element,
zmapXMLParser parser,
gboolean isStart)
{
zmapXMLFactory factory = (zmapXMLFactory)userData;
zmapXMLFactoryFunc func = NULL;
zmapXMLFactoryStorageType storage = 0;
gpointer output = NULL;
gboolean result = FALSE;
zmapXMLFactoryItem item;
item = zMapXMLFactory_decodeElement(factory,
element);
if(item != NULL)
{
storage = item->datatype;
func = (isStart ? item->begin : item->end);
if(func)
{
zmapXMLFactoryDetailStruct detail = {FALSE, 0, NULL};
switch (storage)
{
case ZMAP_XML_FACTORY_LIST:
if((output = (*func)(factory->userData, element, item->storage.list, &detail)) != NULL)
zMapXMLFactory_listAddOutput(item, output);
break;
case ZMAP_XML_FACTORY_DATALIST:
if(((output = (*func)(factory->userData, element, item->storage.datalist, &detail)) != NULL)
&& detail.key > 0)
zMapXMLFactory_dataAddOutput(item, output, detail.key, detail.notify);
break;
case ZMAP_XML_FACTORY_NONE:
(*func)(factory->userData, element, NULL, &detail);
break;
default:
break;
}
result = detail.result;
}
}
return result;
}
......@@ -27,9 +27,9 @@
*
* Exported functions: See XXXXXXXXXXXXX.h
* HISTORY:
* Last edited: Sep 9 11:57 2005 (rds)
* Last edited: Sep 12 16:45 2005 (rds)
* Created: Fri Aug 5 12:49:50 2005 (rds)
* CVS info: $Id: zmapXMLParse.c,v 1.4 2005-09-09 11:03:53 rds Exp $
* CVS info: $Id: zmapXMLParse.c,v 1.5 2005-09-20 17:18:11 rds Exp $
*-------------------------------------------------------------------
*/
......@@ -161,6 +161,21 @@ void zMapXMLParser_setMarkupObjectHandler(zmapXMLParser parser,
return ;
}
void zMapXMLParser_useFactory(zmapXMLParser parser,
zmapXMLFactory factory)
{
if(factory->isLite)
return ; /* Lite factories can't be used! */
/* The parser doesn't free any of the user data so just overwriting
here is fine. */
parser->user_data = factory;
zMapXMLParser_setMarkupObjectHandler(parser,
zmapXML_FactoryStartHandler,
zmapXML_FactoryEndHandler);
return ;
}
char *zMapXMLParser_lastErrorMsg(zmapXMLParser parser)
{
return parser->last_errmsg;
......@@ -169,6 +184,9 @@ char *zMapXMLParser_lastErrorMsg(zmapXMLParser parser)
gboolean zMapXMLParser_reset(zmapXMLParser parser)
{
gboolean result = TRUE;
printf("\n\n ++++ PARSER is being reset ++++ \n\n");
/* Clean up our data structures */
#warning FIX THIS MEMORY LEAK
/* Check out this memory leak.
......@@ -292,7 +310,7 @@ static void start_handler(void *userData,
/* In case there wasn't a <?xml version="1.0" ?> */
if(!(parser->document))
parser->document = zMapXMLDocument_create("1.0", "UTF-8", -1);
zMapXMLDocument_set_root(parser->document, current_ele);
zMapXMLDocument_setRoot(parser->document, current_ele);
}
else
{
......@@ -346,9 +364,10 @@ static void end_handler(void *userData,
{
if(((*handler)((void *)parser->user_data, current_ele, parser)) == TRUE)
{
/* We can free the current_ele and all it's children */
/* First we need to tell it's parent it's being freed. */
zmapXMLElement_removeChild(current_ele->parent, current_ele);
/* We can free the current_ele and all its children */
/* First we need to tell the parent that its child is being freed. */
if(!(zmapXMLElement_signalParentChildFree(current_ele)))
printf("Empty'ing document... this might cure memory leak...\n ");
zmapXMLElement_free(current_ele);
}
}
......@@ -369,11 +388,10 @@ static void character_handler(void *userData,
{
zmapXMLElement content4ele;
zmapXMLParser parser = (zmapXMLParser)userData ;
int i ;
content4ele = g_queue_peek_head(parser->elementStack);
zmapXMLElement_add_content(content4ele, s, len);
zmapXMLElement_addContent(content4ele, s, len);
return ;
}
......
......@@ -27,9 +27,9 @@
*
* Exported functions: See XXXXXXXXXXXXX.h
* HISTORY:
* Last edited: Sep 5 10:22 2005 (rds)
* Last edited: Sep 14 13:23 2005 (rds)
* Created: Fri Aug 5 12:50:44 2005 (rds)
* CVS info: $Id: zmapXML_P.h,v 1.1 2005-09-05 17:28:22 rds Exp $
* CVS info: $Id: zmapXML_P.h,v 1.2 2005-09-20 17:18:11 rds Exp $
*-------------------------------------------------------------------
*/
......@@ -88,6 +88,35 @@ typedef struct _zmapXMLParserStruct
} zmapXMLParserStruct ;
typedef struct _zmapXMLFactoryStruct
{
GHashTable *hash;
gboolean isLite;
gpointer userData; /* pointer to the user's data */
}zmapXMLFactoryStruct;
typedef struct _zmapXMLFactoryLiteItemStruct
{
int tag_type;
GList *list;
}zmapXMLFactoryLiteItemStruct;
typedef struct _zmapXMLFactoryItemStruct
{
zmapXMLFactory parent; /* pointer to the hash that holds us */
zmapXMLFactoryFunc begin;
zmapXMLFactoryFunc end;
zmapXMLFactoryStorageType datatype; /* What's in the below */
union{
GList *list;
GData *datalist;
} storage;
}zmapXMLFactoryItemStruct;
/* ATTRIBUTES */
zmapXMLAttribute zmapXMLAttribute_create(const XML_Char *name,
const XML_Char *value);
......@@ -99,166 +128,42 @@ gboolean zmapXMLElement_addAttribute(zmapXMLElement ele, zmapXMLAttribute attr);
gboolean zmapXMLElement_addAttrPair(zmapXMLElement ele,
const XML_Char *name,
const XML_Char *value);
void zmapXMLElement_addContent(zmapXMLElement ele,
const XML_Char *content,
int len);
void zmapXMLElement_addChild(zmapXMLElement parent, zmapXMLElement child);
void zmapXMLElement_removeChild(zmapXMLElement parent, zmapXMLElement child);
gboolean zmapXMLElement_signalParentChildFree(zmapXMLElement child);
void zmapXMLElement_free(zmapXMLElement ele);
void zmapXMLElement_freeAttrList(zmapXMLElement ele);
/* PARSER */
/* FACTORY */
#endif /* !ZMAP_XML_P_H */
gboolean zmapXML_FactoryEndHandler(void *userData,
zmapXMLElement element,
zmapXMLParser parser);
gboolean zmapXML_FactoryStartHandler(void *userData,
zmapXMLElement element,
zmapXMLParser parser);
#endif /* !ZMAP_XML_P_H */
#ifdef SOME_THOUGHTS_EXAMPLES_OF_WHAT_MIGHT_HAPPEN_HERE
typedef enum {
ZMAP_OBJ_TYPE_A,
ZMAP_OBJ_TYPE_B,
ZMAP_OBJ_TYPE_C,
ZMAP_OBJ_TYPE_D,
ZMAP_OBJ_TYPE_E,
ZMAP_OBJ_LAST
}zmapObjectType;
typedef struct beepBeep
{
zmapObjectType type;
char *elementname;
} BeepTable;
#ifdef NEWFACTORYINTERFACE
/* Lite Items */
typedef struct _zmapFactoryOutputStruct
{
zmapObjTypeA typeA;
zmapObjTypeB typeB;
zmapObjTypeC typeC;
zmapObjTypeD typeD;
zmapObjTypeE typeE;
} zmapFactoryOutputStruct, *zmapFactoryOutputStruct;
void factory2create(void *userData, zmapXMLElement element);
void factory2create(void *userData, zmapXMLElement element)
{
zmapFactoryOutput fo = (zmapFactoryOutput)userData;
zmapObjectType type;
/* This probably relies on tree of data....
*/
type = decodeElement(element);
switch (type){
case ZMAP_OBJ_TYPE_A:
fo->typeA = makeObjectAFrom(element);
break;
case ZMAP_OBJ_TYPE_B:
fo->typeB = makeObjectBFrom(element);
break;
case ZMAP_OBJ_TYPE_C:
fo->typeC = makeObjectCFrom(element);
break;
case ZMAP_OBJ_TYPE_D:
fo->typeD = makeObjectDFrom(element);
break;
case ZMAP_OBJ_TYPE_E:
fo->typeE = makeObjectEFrom(element);
break;
default:
zMapFatal("Something went WRONG");
break;
}
}
void factory2complete(void *userData, zmapXMLElement element);
void factory2complete(void *userData, zmapXMLElement element)
{
zmapFactoryOutput fo = (zmapFactoryOutput)userData;
zmapObjectType type;
/* This probably relies on tree of data....
*/
type = decodeElement(element);
switch (type){
case ZMAP_OBJ_TYPE_A:
completeObjectA(fo->typeA, element);
draw_or_do_something_else_with_it(fo->typeA);
fo->typeA = NULL;
break;
case ZMAP_OBJ_TYPE_B:
/* Same here, but for B... */
break;
case ZMAP_OBJ_TYPE_C:
break;
case ZMAP_OBJ_TYPE_D:
break;
case ZMAP_OBJ_TYPE_E:
break;
default:
zMapFatal("Something went WRONG");
break;
}
}
zmapObjectType decodeElement(zmapXMLElement element)
{
zmapObjectType type = ZMAP_OBJ_UNKNOWN;
GList *interestingElements = NULL;
int i = 0;
gboolean escape = FALSE;
interestingElements = getElementNames();
/* should step through ourselves, probably */
while(notEndOfList && !escape)
{
if(g_quark_from_string(listItem) == element->name)
{
type = (zmapObjectType)i;
escape = TRUE;
}
i++;
}
if(type >= ZMAP_OBJ_LAST)
zMapFatal("Inconsistency.\n");
return type;
}
zmapObjectType decodeElement(zmapXMLElement element)
{
static beepBeep[] = {
{ZMAP_OBJ_TYPE_A, "objectTypeA"},
{ZMAP_OBJ_TYPE_B, "objectTypeB"},
{ZMAP_OBJ_TYPE_C, "objectTypeC"},
{ZMAP_OBJ_TYPE_D, "objectTypeD"},
{ZMAP_OBJ_TYPE_E, "objectTypeE"},
{ZMAP_OBJ_LAST, NULL}
};
int i;
zmapObjectType type;
for(i = 0; beepBeep[i] != ZMAP_OBJ_LAST; i++)
{
if(element->name = g_quark_from_string((beepBeep[i])->elementname))
{
type = i;
i = ZMAP_OBJ_LAST;
}
}
return type;
}
#endif /* SOME_THOUGHTS_EXAMPLES_OF_WHAT_MIGHT_HAPPEN_HERE */
void zmapXMLFactoryDataAddItem(zmapXMLFactoryItem item,
gpointer output,
GQuark key);
void zmapXMLFactoryListAddItem(zmapXMLFactoryItem item,
gpointer output);
#endif
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment