/* * $Id: xtm_simple.c,v 1.2 2004/09/15 11:39:27 jan Exp $ * * Copyright (c) 2002 Jan Algermissen * See the file "COPYING" for copying permission. * */ #include /* #include "df.h" */ #include #include #include "omnivore.h" #define SAM_NAME "http://purl.org/tm/CORE/" #define PATH(t) (strcmp(elem_path(elem),(t)) == 0) /* element subtrees that we want to skip entirely: */ static struct TMList l3 = { NULL, "scope" }; static struct TMList l4 = { &l3, "variant" }; static struct TMList tel0 = { NULL, "property" }; static struct TMList tel1 = { &tel0, "resourceData" }; static struct TMList tel2 = { &tel1, "baseNameString" }; static int xtm_start_element(void *data, Omnivore ov, element *elem, const char **attr); static int xtm_end_element(void *data, Omnivore ov, element *elem); static char *PSYM[TM_MAXMEMBERS] = { "player-0", "player-1", "player-2", "player-3", "player-4", "player-5", "player-6", "player-7" }; static const char * _get_att_val(const char **attr, const char *name) { int i; for (i = 0; attr[i]; i += 2) { if( strcmp(name,attr[i]) == 0 ) { return attr[i + 1]; } } return NULL; } /* data that the proc model needs; will be passed to all the callbacks */ struct data { TMTopicMap tm; TMPool pool; Omnivore omnivore; char last_topic_source_locator[MAXLINE]; /* FIXME */ TMTable symtab; TMTable atomtab; char last_modelname[1024]; /* FIXME */ char last_propertyname[1024]; /* FIXME */ void *asidp_value; char *a_topic_source_locator; char *occ_sloc; char *occ_isa_sloc; char *occ_class_sloc; char *occ_class_sid; char *occ_resref; TMProperty occ_prop; char *last_role_ref; int member_count; }; static const char* atom(struct data* self,const char *s) { char *atom; if( (atom = tm_table_get(self->atomtab,s)) == NULL) { atom = tm_strdup(self->pool,s); tm_table_put(self->atomtab,atom,atom); } return (atom); } /* * */ static int add_node_demander(struct data* self,const char *uri,const char *sym); /* * */ static int add_node_demander2(struct data* self,const char *uri,const char *sym); static char* assure_is_loaded(struct data* self,const char *uri); static void assertion_init(struct data *self); static void assertion_set_a(struct data *self,const char *a_sym); static int assertion_set_type(struct data *self,const char *at_sym); static int assertion_add_member(struct data *self,const char *role_sym, const char *player_sum); static int add_assertion(struct data *self,const char *symbol); static TMError _init(Omnivore omnivore,void*arg,void**data) { struct data *dp; /* struct TMList list; */ TM_NEW( tm_omnivore_get_pool(omnivore),dp); dp->pool = tm_omnivore_get_pool(omnivore); dp->tm = tm_omnivore_get_topicmap(omnivore); dp->omnivore = omnivore; /* FIXME: the require stuff could be part of proc model structure! */ if(dp->tm) { TMModel core; TMError e; if( (e = tm_lookup_model(tm_omnivore_get_tm(omnivore),SAM_NAME,&core)) != TM_OK) { assert(0); return(e); } if( (e = tm_topicmap_require_model(dp->tm,core)) != TM_OK) { assert(0); return(e); } } dp->symtab = tm_table_new(dp->pool,100,tm_strcmp_v,tm_strhash_v); dp->atomtab = tm_table_new(dp->pool,100,tm_strcmp_v,tm_strhash_v); dp->asidp_value = NULL; dp->a_topic_source_locator = NULL; dp->occ_sloc = NULL; dp->occ_isa_sloc = NULL; dp->occ_class_sloc = NULL; dp->occ_class_sid = NULL; dp->occ_resref = NULL; dp->occ_prop = NULL; dp->last_role_ref = NULL; dp->member_count = 0; *data = dp; return TM_OK; } static void _delete(void **pself) { TMPool pool; struct data* self; assert(pself && *pself); self = (struct data*)*pself; pool = self->pool; /* FIXME: free atoms in both */ tm_table_apply(self->symtab,tm_free_keys,pool); tm_table_delete(&( self->symtab)); tm_table_apply(self->atomtab,tm_free_keys,pool); tm_table_delete(&( self->atomtab)); TM_FREE(pool,self); } /* A processing model for a subset of XTM */ struct TMProcModel xtm_simple = { "xtm_simple", /* name */ _init, /* init callback */ _delete, /* delete callback */ "topicMap", /* root element name (for lookup) */ "http://www.topicmaps.org/xtm/1.0/", /* XML namespace */ "-//TopicMaps.Org//DTD XML Topic Map (XTM) 1.0//EN", /* DTD Public Identifier */ "http://www.topicmaps.org/xtm/1.0/xtm1.dtd", /* URL of DTD */ /* NULL, -- elements member of struct; unused */ "id", /* id_attribute_name */ "href", /* ref_attribute_name */ &l4, /* subtrees to skip */ &tel2, /* text elements */ &xtm_start_element, /* Omnivore XML start callback */ &xtm_end_element, /* Omnivore XML end callback */ NULL, /* no line-event handler needed in XML proc model */ NULL /* no RDF Statement-Handler-Table */ }; int xtm_start_element(void *s,Omnivore ov, element *elem, const char **attr) { struct data *self = (struct data *)s; TMTRACE(TM_PARSE_TRACE,"enter for path %s\n" _ elem_path(elem)); TMTRACE(TM_PARSE_TRACE,"elem URI: %s\n" _ elem_uri(elem)); if(!self->tm) { TMTRACE(TM_PARSE_TRACE,"exit (no topicmap)\n"); return (1); } if( PATH("/topicMap") ) { char *p; char buf[1024]; const char *require; const char *sp; require = _get_att_val(attr,"require"); if(!require) return (1); sp = require; while( (p = tm_strtok(&sp,"; \t\n",buf,sizeof(buf) )) != NULL) { TMError e; TMModel model; if( (e = tm_lookup_model(tm_omnivore_get_tm(ov),p,&model)) != TM_OK) { tm_omnivore_set_error(ov, "xtm_simple: error : %s" , tm_get_error(tm_omnivore_get_tm(ov))); return(0); } if( tm_topicmap_require_model(self->tm,model) != TM_OK) { tm_omnivore_set_error(ov, "xtm_simple: error: %s" , tm_get_error(tm_omnivore_get_tm(ov))); return (0); } } } else if( PATH("/topicMap/topic") ) { if(!add_node_demander(self,elem_uri(elem),"last-topic")) return 0; /* FIXME */ assert(strlen(elem_uri(elem)) < sizeof(self->last_topic_source_locator)); strcpy(self->last_topic_source_locator,elem_uri(elem)); } else if( PATH("/topicMap/topic/subjectIdentity") ) { ; } else if( PATH("/topicMap/topic/instanceOf") ) { if(!add_node_demander(self,elem_uri(elem),"a-topic")) return 0; assertion_init(self); assertion_set_a(self,elem_uri(elem)); if(!assertion_set_type(self,SAM_NAME"at-class-instance")) return(0); if(!assertion_add_member(self,SAM_NAME"role-instance","last-topic")) return(0); } else if( PATH("/topicMap/topic/instanceOf/topicRef") ) { /* FIXME: propably use a table since classes are likely * to be used often (also next if)*/ if(!add_node_demander(self,elem_ref_uri(elem),"class-topic")) return (0); if(!assertion_add_member(self,SAM_NAME"role-class", "class-topic")) return (0); if(!add_assertion(self,NULL)) return (0); } else if( PATH("/topicMap/topic/instanceOf/subjectIndicatorRef") ) { if(!add_node_demander2(self,elem_ref_uri(elem),"class-topic")) return 0; if(!assertion_add_member(self,SAM_NAME"role-class", "class-topic")) return (0); if(!add_assertion(self,NULL)) return (0); } else if( PATH("/topicMap/topic/subjectIdentity/resourceRef") ) { struct TMSubject sbj; struct TMList sirs; assert(elem_ref_uri(elem) && *elem_ref_uri(elem)); sirs.next = NULL; sirs.content = self->last_topic_source_locator; TM_SET_SUBJECT_N2(&sbj, SAM_NAME,"SourceLocators",&sirs, SAM_NAME,"SubjectAddress",elem_ref_uri(elem)); if( tm_topicmap_add_topic(self->tm,&sbj,NULL ) != TM_OK) { tm_omnivore_set_error(ov, "cannot add subject %s (element URI is %s)" , tm_get_error(tm_omnivore_get_tm(ov) ), elem_uri(elem) ); return (0); } } else if( PATH("/topicMap/topic/subjectIdentity/topicRef") ) { struct TMSubject sbj; struct TMList sirs; struct TMList list; assert(elem_ref_uri(elem) && *elem_ref_uri(elem)); list.next = NULL; list.content = (char*)elem_ref_uri(elem); sirs.next = &list; sirs.content = self->last_topic_source_locator; TM_SET_SUBJECT_N1(&sbj, SAM_NAME,"SourceLocators",&sirs); if( tm_topicmap_add_topic(self->tm,&sbj,NULL ) != TM_OK) { tm_omnivore_set_error(ov, "cannot add subject %s (element URI is %s)" , tm_get_error(tm_omnivore_get_tm(ov) ), elem_uri(elem) ); return (0); } } else if(PATH("/topicMap/topic/subjectIdentity/subjectIndicatorRef")){ struct TMSubject sbj; struct TMList sirs; struct TMList list; assert(elem_ref_uri(elem) && *elem_ref_uri(elem)); list.next = NULL; list.content = (char*)elem_ref_uri(elem); sirs.next = NULL; sirs.content = self->last_topic_source_locator; TM_SET_SUBJECT_N2(&sbj, SAM_NAME,"SourceLocators",&sirs, SAM_NAME,"SubjectIndicators",&list); if( tm_topicmap_add_topic(self->tm,&sbj,NULL ) != TM_OK) { tm_omnivore_set_error(ov, "cannot add subject %s (element URI is %s)" , tm_get_error(tm_omnivore_get_tm(ov) ), elem_uri(elem) ); return (0); } /* * ---------------------------------------------------------------- * * and subelements * * ---------------------------------------------------------------- */ } else if( PATH("/topicMap/topic/baseName") ) { if(!add_node_demander(self,elem_uri(elem),"bn-topic")) return 0; assertion_init(self); assertion_set_a(self,elem_uri(elem)); if(!assertion_set_type(self,SAM_NAME"at-basenamed-basename")) return(0); if(!assertion_add_member(self,SAM_NAME"role-basenamed","last-topic")) return(0); } else if( PATH("/topicMap/topic/baseName/baseNameString") ) { ; /* * ---------------------------------------------------------------- * * and subelements * * ---------------------------------------------------------------- */ } else if( PATH("/topicMap/topic/occurrence") ) { self->occ_sloc = tm_strdup(self->pool,elem_uri(elem)); } else if( PATH("/topicMap/topic/occurrence/instanceOf") ) { self->occ_isa_sloc = tm_strdup(self->pool,elem_uri(elem)); } else if( PATH("/topicMap/topic/occurrence/instanceOf/topicRef") ){ self->occ_class_sloc =tm_strdup(self->pool,elem_ref_uri(elem)); } else if( PATH("/topicMap/topic/occurrence/instanceOf/subjectIndicatorRef") ) { self->occ_class_sid = tm_strdup(self->pool,elem_ref_uri(elem)); tm_topicmap_get_property_by_name(self->tm, self->occ_class_sid,&(self->occ_prop)); } else if(PATH("/topicMap/topic/occurrence/resourceData") ) { ; /* handled in end element */ } else if( PATH("/topicMap/topic/occurrence/resourceRef") ) { self->occ_resref = tm_strdup(self->pool,elem_ref_uri(elem)); /* * ---------------------------------------------------------------- * * and subelements * * ---------------------------------------------------------------- */ } else if( PATH("/topicMap/association") ) { assertion_init(self); assertion_set_a(self,elem_uri(elem)); } else if( PATH("/topicMap/association/instanceOf") ) { ; } else if( PATH("/topicMap/association/instanceOf/topicRef") ){ assert(0); /* we need special handling later on */ } else if(PATH("/topicMap/association/instanceOf/subjectIndicatorRef")){ if(!assertion_set_type(self,elem_ref_uri(elem)) ) return(0); } else if( PATH("/topicMap/association/member") ) { ; } else if( PATH("/topicMap/association/member/roleSpec") ) { ; } else if( PATH("/topicMap/association/member/roleSpec/topicRef")){ assert(0); /* we need special handling later on */ } else if( PATH("/topicMap/association/member/roleSpec/subjectIndicatorRef")) { assert(elem_ref_uri(elem) && *elem_ref_uri(elem)); self->last_role_ref = tm_strdup(self->pool,elem_ref_uri(elem)); } else if( PATH("/topicMap/association/member/topicRef")){ if(!add_node_demander(self,elem_ref_uri(elem),PSYM[self->member_count])) return(0); if(!assertion_add_member(self,self->last_role_ref,PSYM[self->member_count])) return(0); } else if(PATH("/topicMap/association/member/subjectIndicatorRef")){ if(!add_node_demander2(self,elem_ref_uri(elem),PSYM[self->member_count])) return(0); if(!assertion_add_member(self,self->last_role_ref,PSYM[self->member_count])) return(0); } else if( PATH("/topicMap/topic/property")) { const char *fullname; const char *propertyname; const char *p; fullname = _get_att_val(attr,"name"); if(!fullname) { tm_omnivore_set_error(ov, "syntax error: missing attribute 'name'"); return (0); } TMTRACE(TM_PARSE_TRACE,"propertyname=%s\n" _ fullname); p = strrchr(fullname,'/'); assert(p); /* FIXME: error handling */ assert(((p-fullname)+1) < sizeof(self->last_modelname)); bzero(self->last_modelname,sizeof(self->last_modelname)); strncpy(self->last_modelname,fullname, (p-fullname)+1 ); p++; /* skip '/' */ propertyname = p; assert(strlen(propertyname) < sizeof(self->last_propertyname)); strcpy(self->last_propertyname,propertyname); /* FIXME: this does not work because it may cause a fully_merge and * that invalidates the last_topic variable !! if( tm_topicmap_require_model(self->tm,self->last_modelname) != TM_OK) { tm_omnivore_set_error(ov,"xtm_simple: error: %s" , tm_get_error(tm_omnivore_get_tm(ov))); return (0); } */ } else { tm_omnivore_set_error(ov, "syntax error: unsupported path %s", elem_uri(elem)); return (0); } return 1; } int xtm_end_element(void *s,Omnivore ov, element *elem) { TMError e; struct data *self = (struct data *)s; TMTRACE(TM_PARSE_TRACE,"enter\n"); if(!self->tm) { TMTRACE(TM_PARSE_TRACE,"exit (no topicmap)\n"); return (1); } if(!self->tm) return (1); if( PATH("/topicMap") ) { ; /* * ---------------------------------------------------------------- * * and subelements * * ---------------------------------------------------------------- */ } else if( PATH("/topicMap/topic/baseName/baseNameString") ) { struct TMSubject sbj; struct TMList sirs; sirs.next = NULL; sirs.content = (void*)elem_uri(elem); TM_SET_SUBJECT_N2(&sbj, SAM_NAME,"SourceLocators",&sirs, SAM_NAME,"IndicatorData",elem_text(elem)); if( tm_topicmap_add_topic(self->tm,&sbj,"b-topic" ) != TM_OK) { tm_omnivore_set_error(ov, "xtm_simple: proce error: %s" , tm_get_error(tm_omnivore_get_tm(ov))); return (0); } if(!assertion_add_member(self,SAM_NAME"role-basename", "b-topic")) return (0); { struct TMSubject sbj2; struct TMList sirs2; struct TMList list; list.next = NULL; list.content = (char*)elem_text(elem); sirs2.next = NULL; sirs2.content = self->last_topic_source_locator; TM_SET_SUBJECT_N2(&sbj2, SAM_NAME,"SourceLocators",&sirs2, SAM_NAME,"BaseNames",&list); if( tm_topicmap_add_topic(self->tm,&sbj2,NULL ) != TM_OK) { tm_omnivore_set_error(ov, "cannot add subject %s (element URI is %s)" , tm_get_error(tm_omnivore_get_tm(ov) ) , elem_uri(elem) ); return (0); } } } else if( PATH("/topicMap/topic/baseName") ) { if(!add_assertion(self,NULL)) return (0); /* * ---------------------------------------------------------------- * * and subelements * * ---------------------------------------------------------------- */ } else if( PATH("/topicMap/topic/occurrence/resourceData")) { struct TMSubject sbj; if(self->occ_prop) { struct TMSubject sbj; struct TMList sirs; void *value; sirs.next = NULL; sirs.content = self->last_topic_source_locator; value = tm_value_new_from_string( self->pool, self->occ_prop->value_type, elem_text(elem)); /* here we use the prop fullname feature by setting * modelname to NULL */ TM_SET_SUBJECT_N2(&sbj, SAM_NAME,"SourceLocators",&sirs, NULL,self->occ_class_sid,value ); if(tm_topicmap_add_topic(self->tm,&sbj,NULL )!= TM_OK) { tm_omnivore_set_error(ov, "cannot add subject %s (element URI is %s)" , tm_get_error(tm_omnivore_get_tm(ov) ), elem_uri(elem) ); return (0); } return(1); } TM_SET_SUBJECT_N2(&sbj, SAM_NAME,"SubjectAddress",elem_uri(elem), SAM_NAME,"SubjectData",elem_text(elem)); if( (e = tm_topicmap_add_topic(self->tm,&sbj,"r-topic")) != TM_OK) { tm_omnivore_set_error(ov, "xtm_simple: proce error: %s" , tm_get_error(tm_omnivore_get_tm(ov))); return (0); } } else if( PATH("/topicMap/topic/occurrence/resourceRef")) { struct TMSubject sbj; if(self->occ_prop) { /* do we report that? (FIXME) */ /* we set it to NULL, to make occurrence end elem * correctly handle the assertion. Usually, it * uses occ_prop as test if occ has already * been handled as a property. */ self->occ_prop = NULL; } TM_SET_SUBJECT_N1(&sbj, SAM_NAME,"SubjectAddress",self->occ_resref); if( (e = tm_topicmap_add_topic(self->tm,&sbj,"r-topic")) != TM_OK) { tm_omnivore_set_error(ov, "xtm_simple: proce error: %s" , tm_get_error(tm_omnivore_get_tm(ov))); return (0); } } else if(PATH("/topicMap/topic/occurrence") ) { /* if prop-as-occ, we are already done */ if(self->occ_prop) return(1); assertion_init(self); assertion_set_a(self,self->occ_sloc); if(!assertion_set_type(self,SAM_NAME"at-occurring-occurrence")) return(0); if(!assertion_add_member(self,SAM_NAME"role-occurring","last-topic")) return(0); if(!assertion_add_member(self,SAM_NAME"role-occurrence","r-topic")) return(0); if(!add_assertion(self,"occ-topic")) return(0); if(!self->occ_isa_sloc) return (1); if(self->occ_class_sloc) { if(!add_node_demander(self, self->occ_class_sloc,"occ-class")) return(0); } else { assert(self->occ_class_sid); if(!add_node_demander2(self, self->occ_class_sid,"occ-class")) return(0); } assertion_init(self); assertion_set_a(self,self->occ_isa_sloc); if(!assertion_set_type(self,SAM_NAME"at-class-instance")) return(0); if(!assertion_add_member(self,SAM_NAME"role-class","occ-class")) return(0); if(!assertion_add_member(self,SAM_NAME"role-instance","occ-topic")) return(0); if(!add_assertion(self,NULL)) return(0); if(self->occ_sloc) TM_FREE(self->pool,self->occ_sloc); if(self->occ_isa_sloc) TM_FREE(self->pool,self->occ_isa_sloc); if(self->occ_class_sloc) TM_FREE(self->pool,self->occ_class_sloc); if(self->occ_class_sid) TM_FREE(self->pool,self->occ_class_sid); if(self->occ_resref) TM_FREE(self->pool,self->occ_resref); } else if( PATH("/topicMap/association/member") ) { TM_FREE(self->pool,self->last_role_ref); } else if( PATH("/topicMap/association") ) { if(!add_assertion(self,NULL)) return (0); } else if( PATH("/topicMap/mergeMap") ) { ; /* FIXME: added themes !*/ /* if(ov->merge_map_handler) ov->merge_map_handler(ov->user_data, elem_ref_uri(elem)); */ } else if(strcmp(elem_path(elem),"/topicMap/topic/property") == 0) { TMError e; TMValueType vtype; void *value; struct TMSubject sbj; struct TMList sirs; sirs.next = NULL; sirs.content = self->last_topic_source_locator; if( (e = tm_topicmap_get_valuetype(self->tm,self->last_modelname, self->last_propertyname,&vtype)) != TM_OK) { tm_omnivore_set_error(ov,"cannot get value type for %s%s, %s at %s" , self->last_modelname,self->last_propertyname, tm_get_error(tm_omnivore_get_tm(ov) ) , elem_uri(elem) ); return (0); } value = tm_value_new_from_string(self->pool,vtype,elem_text(elem)); TM_SET_SUBJECT_N2(&sbj, SAM_NAME,"SourceLocators",&sirs, self->last_modelname,self->last_propertyname,value ); if( (e = tm_topicmap_add_topic(self->tm,&sbj,NULL )) != TM_OK) { tm_omnivore_set_error(ov,"cannot add subject %s (element URI is %s)" , tm_get_error(tm_omnivore_get_tm(ov) ) , elem_uri(elem) ); return (0); } tm_value_delete(self->pool,vtype,&value); } else { /* no action for other paths. Syntax errors have been * handled by start element. */ } return 1; } /* ------------------------------------------------------------------------*/ /* ------------------------------------------------------------------------*/ /* ------------------------------------------------------------------------*/ /* ------------------------------------------------------------------------*/ int add_node_demander(struct data* self,const char *uri,const char *sym) { struct TMSubject sbj; struct TMList sirs; sirs.next = NULL; sirs.content = (void*)uri; TM_SET_SUBJECT_N1(&sbj,SAM_NAME,"SourceLocators",&sirs); if( tm_topicmap_add_topic(self->tm,&sbj,sym) != TM_OK) { tm_omnivore_set_error(self->omnivore, "cannot add topic %s (element URI is %s)" , tm_get_error(tm_omnivore_get_tm(self->omnivore) ), uri); return (0); } return (1); } int add_node_demander2(struct data* self,const char *uri,const char *sym) { struct TMSubject sbj; struct TMList sirs; sirs.next = NULL; sirs.content = (void*)uri; TM_SET_SUBJECT_N1(&sbj,SAM_NAME,"SubjectIndicators",&sirs); if( tm_topicmap_add_topic(self->tm,&sbj,sym) != TM_OK) { tm_omnivore_set_error(self->omnivore, "cannot add topic %s (element URI is %s)" , tm_get_error(tm_omnivore_get_tm(self->omnivore) ), uri); return (0); } return (1); } char* assure_is_loaded(struct data* self,const char *uri) { char *uri_atom; if( (uri_atom = tm_table_get(self->symtab,uri)) == NULL) { struct TMSubject sbj; struct TMList sirs; sirs.next = NULL; sirs.content = (void*)uri; TM_SET_SUBJECT_N1(&sbj,SAM_NAME,"SubjectIndicators",&sirs); /* uri is symbol! */ if( tm_topicmap_add_topic(self->tm,&sbj,uri) != TM_OK) { tm_omnivore_set_error(self->omnivore, "cannot add topic %s (element URI is %s)" , tm_get_error(tm_omnivore_get_tm(self->omnivore) ), uri); return (NULL); } uri_atom = tm_strdup(self->pool,uri); tm_table_put(self->symtab,uri_atom,uri_atom); } return (uri_atom); } void assertion_init(struct data *self) { assert(self->asidp_value == 0); self->asidp_value = tm_value_new(self->pool,&ASIDP); self->member_count = 0; } void assertion_set_a(struct data *self,const char *a_source_loc) { assert(self->a_topic_source_locator == NULL); self->a_topic_source_locator = tm_strdup(self->pool,a_source_loc); } int assertion_set_type(struct data *self,const char *at_sym) { char *sym_atom; if( (sym_atom = assure_is_loaded(self,at_sym)) == NULL ) return (0); tm_value_call(&ASIDP,self->asidp_value,"setType",TM_TVAL_SYMBOL,sym_atom); return(1); } int assertion_add_member(struct data *self,const char *role_sym, const char *player_sym) { char *role_sym_atom; TM_ENTER; assert(self->member_count < TM_MAXMEMBERS ); if( (role_sym_atom = assure_is_loaded(self,role_sym)) == NULL ) return (0); tm_value_call(&ASIDP,self->asidp_value,"addMember", self->pool, TM_TVAL_SYMBOL, role_sym_atom,atom(self,player_sym) ); self->member_count++; TM_RETURN (1); } int add_assertion(struct data *self,const char *symbol) { struct TMList list; struct TMSubject a_sbj; TM_ENTER; assert(self->a_topic_source_locator); list.next = NULL; list.content = self->a_topic_source_locator; TM_SET_SUBJECT_N2(&a_sbj, "http://purl.org/tm/BASE/","a-sidp", self->asidp_value, SAM_NAME,"SourceLocators",&list ); if( tm_topicmap_add_topic(self->tm,&a_sbj,symbol) != TM_OK) { tm_omnivore_set_error(self->omnivore, "cannot add assertion, %s" , tm_get_error(tm_omnivore_get_tm(self->omnivore))); assert(0); } TM_FREE(self->pool,self->a_topic_source_locator); tm_value_delete(self->pool,&ASIDP,&self->asidp_value); self->a_topic_source_locator = NULL; self->asidp_value = NULL; TM_RETURN(1); }