void CopyList(Item **dest, const Item *source) /* Copy a list. */ { if (*dest != NULL) { ProgrammingError("CopyList - list not initialized"); } if (source == NULL) { return; } const Item *ip = source; CYCLE_DECLARE(ip, slow, toggle); Item *backwards = NULL; while (ip != NULL) { PrependFullItem(&backwards, ip->name, ip->classes, ip->counter, ip->time); ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } *dest = ReverseItemList(backwards); }
static void AddTopicAssociation(Topic *this_tp, TopicAssociation **list, char *fwd_name, char *bwd_name, Rlist *passociates, int ok_to_add_inverse, char *from_context, char *from_topic) { TopicAssociation *ta = NULL, *texist; char fwd_context[CF_MAXVARSIZE]; Rlist *rp; Topic *new_tp; char contexttopic[CF_BUFSIZE], ntopic[CF_BUFSIZE], ncontext[CF_BUFSIZE]; strncpy(ntopic, NormalizeTopic(from_topic), CF_BUFSIZE - 1); strncpy(ncontext, NormalizeTopic(from_context), CF_BUFSIZE - 1); snprintf(contexttopic, CF_MAXVARSIZE, "%s::%s", ncontext, ntopic); strncpy(fwd_context, CanonifyName(fwd_name), CF_MAXVARSIZE - 1); if (passociates == NULL || passociates->item == NULL) { CfOut(cf_error, "", " !! A topic must have at least one associate in association %s", fwd_name); return; } if ((texist = AssociationExists(*list, fwd_name, bwd_name)) == NULL) { ta = xcalloc(1, sizeof(TopicAssociation)); ta->fwd_name = xstrdup(fwd_name); if (bwd_name) { ta->bwd_name = xstrdup(bwd_name); } ta->fwd_context = xstrdup(fwd_context); ta->next = *list; *list = ta; } else { ta = texist; } /* Association now exists, so add new members */ if (ok_to_add_inverse) { CfOut(cf_verbose, "", " -> BEGIN add fwd associates for %s::%s", ncontext, ntopic); } else { CfOut(cf_verbose, "", " ---> BEGIN reverse associations %s::%s", ncontext, ntopic); } // First make sure topics pointed to exist so that they can point to us also for (rp = passociates; rp != NULL; rp = rp->next) { char normalform[CF_BUFSIZE] = { 0 }; strncpy(normalform, NormalizeTopic(rp->item), CF_BUFSIZE - 1); new_tp = IdempInsertTopic(normalform); if (strcmp(contexttopic, normalform) == 0) { CfOut(cf_verbose, "", " ! Excluding self-reference to %s", ScalarValue(rp)); continue; } if (ok_to_add_inverse) { CfOut(cf_verbose, "", " --> Adding '%s' with id %d as an associate of '%s::%s'", normalform, new_tp->id, this_tp->topic_context, this_tp->topic_name); } else { CfOut(cf_verbose, "", " ---> Reverse '%s' with id %d as an associate of '%s::%s' (inverse)", normalform, new_tp->id, this_tp->topic_context, this_tp->topic_name); } if (!IsItemIn(ta->associates, normalform)) { PrependFullItem(&(ta->associates), normalform, NULL, new_tp->id, 0); if (ok_to_add_inverse) { // inverse is from normalform to ncontext::ntopic char rev[CF_BUFSIZE], ndt[CF_BUFSIZE], ndc[CF_BUFSIZE]; Rlist *rlist = 0; snprintf(rev, CF_BUFSIZE - 1, "%s::%s", ncontext, ntopic); PrependRScalar(&rlist, rev, CF_SCALAR); // Stupid to have to declassify + reclassify, but .. DeClassifyTopic(normalform, ndt, ndc); AddTopicAssociation(new_tp, &(new_tp->associations), bwd_name, fwd_name, rlist, false, ndc, ndt); DeleteRlist(rlist); } } else { CfOut(cf_verbose, "", " -> Already in %s::%s's associate list", ncontext, ntopic); } CF_EDGES++; } if (ok_to_add_inverse) { CfOut(cf_verbose, "", " -> END add fwd associates for %s::%s", ncontext, ntopic); } else { CfOut(cf_verbose, "", " ---> END reverse associations %s::%s", ncontext, ntopic); } }