#include #include #include #include #include #include #include #include "tmvtasidp.h" static void* asidp_new(TMPool,TMValueType vtype); static void* asidp_new_from_string(TMPool,TMValueType vtype,const char *s); static TMList asidp_get_tvals(TMValueType vtype,TMPool pool,void *value); static void asidp_free(TMPool,TMValueType vtype, void *s); static int asidp_equal(TMValueType, const void *, const void*); static int asidp_to_string(TMValueType, const void *asidp, char* buf, size_t size); static int asidp_to_xml(TMValueType, const void *asidp, char* buf, size_t size); static void *asidp_parse_argstring(TMPool,TMValueType vtype, int opcode, const char *argstring); static void* asidp_set_type(TMValueType, void *asidp,va_list args); static void* asidp_add_member(TMValueType, void *asidp,va_list args); static void* asidp_get_player(TMValueType, void *asidp,va_list args); static void* asidp_replace_topics(TMValueType, void *asidp,va_list args); static struct function_table ftab[] = { { "setType" , asidp_set_type }, { "addMember" , asidp_add_member }, { "getPlayer" , asidp_get_player }, { "replaceTopics" , asidp_replace_topics }, { NULL , NULL} }; static struct op_table ops[] = { { "HAS_TYPE" , TM_OP_ASIDP_HAS_TYPE }, { "HAS_PLAYER_PAIR" , TM_OP_ASIDP_HAS_PLAYER_PAIR }, { "HAS_PLAYER" , TM_OP_ASIDP_HAS_PLAYER }, { "VALUE_INCLUDES_TOPIC" , TM_OP_ASIDP_VALUE_INCLUDES_TOPICS }, { NULL, 0 } }; struct TMValueType ASIDP = { "ASIDP", 1, /* values contain topics */ asidp_new, asidp_new_from_string, asidp_to_string, asidp_to_xml, asidp_equal, asidp_free, ftab, ops, asidp_parse_argstring, asidp_get_tvals }; void* asidp_new(TMPool pool,TMValueType vtype) { struct asidp_value *p; TM_NEW(pool,p); p->type.topic = 0; p->type.N = 0; p->type.symbol = NULL; p->memberships = NULL; return p; } void* asidp_new_from_string(TMPool pool,TMValueType vtype, const char *s) { assert(0); /* struct asidp_value *p; TM_NEW(p); p->type = 0; p->memberships = NULL; return p; */ return NULL; } void asidp_free(TMPool pool,TMValueType vtype, void *v) { TMList lp; struct asidp_value *p; p = (struct asidp_value*)v; for(lp=p->memberships; lp; lp=lp->next) { struct a_membership *amp = (struct a_membership*)lp->content; TM_FREE(pool,amp); } tm_list_delete(pool, &(p->memberships) ); TM_FREE(pool,p); } int asidp_to_string(TMValueType vtype, const void *v, char* buf, size_t size) { int n; char locbuf[1024]; TMList lp; const struct asidp_value *asidp = (const struct asidp_value*)v; if(v == NULL) { *buf = '\0'; return (1); /* FIXME */ } bzero(locbuf,1024); for(lp=asidp->memberships;lp;lp=lp->next) { char b[64]; sprintf(b,"(R:%d,x:%d)", ((struct a_membership*)lp->content)->role.topic, ((struct a_membership*)lp->content)->player.topic ); strcat(locbuf,b); } n = snprintf(buf,size,"ASIDP(type=%d, memberships=[%s])",asidp->type.topic,locbuf); assert(n < size); return n; } int asidp_to_xml(TMValueType vtype,const void *asidp, char* buf, size_t size) { int n; #if 0 n = snprintf(buf,size," %s",(char*)asidp); assert(n < size); #endif return n; } int asidp_equal(TMValueType vtype, const void *lhs, const void *rhs) { assert(lhs); assert(rhs); assert(0); return ( strcmp((const char*)lhs,(const char *)rhs) == 0); } void *asidp_set_type(TMValueType vtype, void *asidp,va_list args) { int flag; flag = va_arg(args,int); switch (flag) { case TM_TVAL_TOPIC: ((struct asidp_value*)asidp)->type.topic = va_arg(args,TMTopic); break; case TM_TVAL_SUBJECT: { struct asidp_value *a = (struct asidp_value*)asidp; TMSubject sbj = va_arg(args,TMSubject); TM_SUBJECT_COPY_PROPS(&(a->type),sbj); break;} case TM_TVAL_SYMBOL: ((struct asidp_value*)asidp)->type.symbol = va_arg(args,char*); break; default: assert(0); exit(0); /* FIXME */ } return NULL; } TMList asidp_get_tvals(TMValueType vtype,TMPool pool,void *value) { TMList list = NULL; TMList lp; struct asidp_value *self; self = (struct asidp_value*)value; list = tm_list_push(pool,list,&(self->type)); for(lp=self->memberships;lp;lp=lp->next) { struct a_membership *mp; mp = (struct a_membership*)lp->content; list = tm_list_push(pool,list,&(mp->role)); list = tm_list_push(pool,list,&(mp->player)); } return list; } #if 0 /* FIXME */ static void *asidp_add_membership(TMValueType vtype, struct asidp_value *asidp,struct a_membership *mp) { TMList lp,prev; if( ! asidp->memberships) { asidp->memberships = tm_list_push(asidp->memberships,mp); } else { prev = NULL; for(lp=asidp->memberships;lp;lp=lp->next) { if( ((struct a_membership*)lp->content)->role > mp->role) break; prev = lp; } if(!prev) { asidp->memberships = tm_list_push(asidp->memberships,mp); } else { TMList tmp; tmp = tm_list_push(NULL,mp); tmp->next = prev->next; prev->next = tmp; } } assert(asidp->memberships); /* prev = asidp->memberships; for(lp=asidp->memberships->next;lp;lp=lp->next); { assert( ((struct a_membership*)prev->content)->role < ((struct a_membership*)lp->content)->role); prev = lp; } */ /* asidp_to_string(&ASIDP,asidp,buf,1024); fprintf(stderr,"\n%s\n\n" , buf ); getchar(); */ return NULL; } #endif void *asidp_add_member(TMValueType vtype, void *v,va_list args) { TMPool pool; struct a_membership *mp; int flag; struct asidp_value *asidp; asidp = (struct asidp_value*)v; pool = va_arg(args,TMPool); TM_NEW(pool,mp); TM_INIT_SUBJECT(&(mp->role)); TM_INIT_SUBJECT(&(mp->player)); flag = va_arg(args,int); switch (flag) { case TM_TVAL_TOPIC: mp->role.topic = va_arg(args,TMTopic); mp->player.topic = va_arg(args,TMTopic); break; case TM_TVAL_SUBJECT: { TMSubject rsbj = va_arg(args,TMSubject); TMSubject psbj = va_arg(args,TMSubject); TM_SUBJECT_COPY_PROPS(&(mp->role),rsbj); TM_SUBJECT_COPY_PROPS(&(mp->player),psbj); break;} case TM_TVAL_SYMBOL: mp->role.symbol = va_arg(args,char*); mp->player.symbol = va_arg(args,char*); break; default: assert(0); exit(0); /* FIXME */ } asidp->memberships = tm_list_push(pool,asidp->memberships,mp); return NULL; } void *asidp_replace_topics(TMValueType vtype, void *v,va_list args) { int changed = 0; struct asidp_value *asidp; int i,len; TMTopicSet merge_set; TMTopic new_topic; asidp = (struct asidp_value*)v; new_topic = va_arg(args,TMTopic); merge_set = va_arg(args,TMTopicSet); len = tm_topicset_size(merge_set); /* start at 1 because we skip stays */ for(i=0;itype.topic == disap) { asidp->type.topic = new_topic; changed = 1; } for(lp=asidp->memberships;lp;lp=lp->next) { mp = (struct a_membership*)lp->content; if(mp->role.topic == disap) { mp->role.topic = new_topic; changed = 1; } if(mp->player.topic == disap) { mp->player.topic = new_topic; changed = 1; } } } #if 0 if(changed) { TMList list,lp; list = asidp->memberships; asidp->memberships = NULL; for(lp=list;lp;lp=lp->next) { struct a_membership *p = (struct a_membership*)lp->content; asidp_add_membership(&ASIDP,asidp,p); } tm_list_delete(&list); } #endif return (void*)changed; } void *asidp_get_player(TMValueType vtype, void *v,va_list args) { #if 0 TMTopic role; TMList lp; struct asidp_value *asidp; asidp = (struct asidp_value*)v; role = (TMTopic)va_arg(args,TMTopic); for(lp= asidp->memberships; lp; lp=lp->next) { struct a_membership *mp = (struct a_membership *)lp->content; if(mp->role == role) return (void*)mp->player; } #endif return NULL; } void *asidp_parse_argstring(TMPool pool,TMValueType vtype, int opcode, const char *argstring) { #if 0 switch(opcode) { case TM_OP_ASIDP_HAS_TYPE: return (char*)argstring; /* FIXME: is that nice to do? */ case TM_OP_ASIDP_HAS_PLAYER_PAIR: { struct a_membership *mp; TM_NEW(mp); sscanf(argstring,"(%d,%d)", (int*)&(mp->role),(int*)&(mp->player)); return (mp); break; } default: assert(0); } #endif return NULL; }