/* Included headerfiles */ #include "thot_gui.h" #include "thot_sys.h" #include "application.h" #include "browser.h" #include "content.h" #include "dialog.h" #include "app.h" #include "interface.h" #include "message.h" #include "reference.h" #include "selection.h" /*#include "thotmsg.h"*/ #include "tree.h" #define VSTATUS extern #include "trans.h" static int LastRulePlace; static strmatch *TabMenuTrans[20]; /* pointer to the last generated element */ static Element generationStack[MAXSTACK]; static int topGenStack; static strmatch *TabMenuTrans[20]; static boolean ResultTrans; /* variables memoire de la selection */ static int ffc,flc,lfc,llc; static int maxMatchDepth; static Element MyFirstSelect, OrigFirstSelect; static Element MyLastSelect, OrigLastSelect; static Element MySelect; static boolean isClosed; /* fonctions du parser trans et pattern matching utilisees ici */ #ifdef __STDC__ extern void freelist(ListSymb *pl); extern int ppStartParser(char *name); extern void PatternMatching(TagTree t); #else extern void freelist(/* ListSymb *pl */); extern int ppStartParser(/* char *name */); extern void PatternMatching(/* TagTree t */); #endif /* ---------------------------------------------------------------------- */ /* liberation d'un arbre de tags. */ #ifdef __STDC__ static void freeTagTree (TagTree t) #else /* __STDC__*/ static void freeTagTree (t) TagTree t; #endif /* __STDC__*/ { strmatch *m, *m2; strmatchchildren *mc, *mc2; Tagnode *c, *n; if (t!=NULL) { m=t->matches; while(m!=NULL) { mc = m->childmatches; while(mc!=NULL) { mc2=mc->next; TtaFreeMemory((char *)mc); mc=mc2; } m2=m->next; TtaFreeMemory((char *)m); m=m2; } c=t->child; while(c !=NULL) { n=c->next; freeTagTree(c); c=n; } TtaFreeMemory((char *)t); } } /* --------------------------------------------------------------------- */ /* liberation de l'environnement de matching. */ #ifdef __STDC__ static void FreeMatchEnv() #else /* __STDC__*/ static void FreeMatchEnv() #endif /* __STDC__*/ { ListChild *l, *l1; ListElem *le, *le1; /* liberation de la liste des sous-arbres transferes*/ l = match_env.listSubTrees; while(l != NULL) { l1 = l; le = l1->children; while (le != NULL) { le1 = le; le = le->next; TtaFreeMemory ((char *)le1); } l = l->next; TtaFreeMemory ((char *)l1); } match_env.listSubTrees = NULL; /* liberation de l'arbre des tags*/ freeTagTree (match_env.subjecttree); match_env.subjecttree = NULL; } /* ---------------------------------------------------------------------- */ /* initialisation de l'application */ /* ---------------------------------------------------------------------- */ #ifdef __STDC__ void InitTransform() #else /* __STDC__*/ void InitTransform() #endif /* __STDC__*/ { TRANSDIAL=TtaGetMessageTable("transdialogue" , TRANS_MSG_MAX); /* TransBaseDialog = TtaSetCallback(TransCallbackDialog, MAX_TRANS_DLG); */ } /* ---------------------------------------------------------------------- */ /* construction des TagTrees */ /* ---------------------------------------------------------------------- */ /* allocation d'un noeud */ #ifdef __STDC__ static TagTree newNode() #else /* __STDC__*/ static TagTree newNode() #endif /* __STDC__*/ { TagTree res; res = (TagTree)TtaGetMemory(sizeof(Tagnode)); res->matches=NULL; res->inter=NULL; res->element = NULL; res->transsymb=NULL; res->parent = NULL; res->child = NULL; res->next = NULL; res->prev = NULL; res->isTrans = FALSE; res->depth=0; return res; } /* ---------------------------------------------------------------------- */ /* arbre thot -> arbre tag */ /* ---------------------------------------------------------------------- */ #ifdef __STDC__ static void BuildTagTree(Element elem,Document doc,TagTree father,int maxdepth,int depth) #else /* __STDC__*/ static void BuildTagTree(elem,doc,father,maxdepth,depth) Element elem; Document doc; TagTree father; int maxdepth; int depth; #endif /* __STDC__*/ { Element elemcour; ElementType elemType; TagTree new, child; #ifdef DEBUG int i; #endif if (depth > maxdepth) return; new = newNode (); new->eltype = TtaGetElementType (elem); new->element = elem; new->parent = father; new->depth = depth; #ifdef DEBUG for (i = 0; i < depth; i++) printf (" "); printf ("%s\n", TtaGetElementTypeOriginalName (new->eltype)); #endif if (father->child == NULL) { father->child = new; new->prev = NULL; } else { child = father->child; while (child->next != NULL) child = child->next; child->next = new; new->prev = child; } depth++; /* builds the descendance of the node */ elemcour = TtaGetFirstChild(elem); while (elemcour != NULL) { elemType = TtaGetElementType (elemcour); if (elemType.ElTypeNum != TYPE_NUM_PAGE_BREAK) BuildTagTree (elemcour, doc, new, maxdepth, depth); TtaNextSibling (&elemcour); } } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ #ifdef __STDC__ static boolean FindTypeInSubSchemas(char *NameType,ElementType elTypePere,ElementType *newType) #else static boolean FindTypeInSubSchemas(NameType, elTypePere, newType) char *NameType; ElementType elTypePere; ElementType *newType; #endif /* __STDC__ */ { int i; SSchema strsch; Construct constructor; ElementType *typeArray; boolean found=FALSE; int nbConst; constructor=TtaGetConstructOfType(elTypePere); nbConst = TtaGetCardinalOfType(elTypePere); typeArray = (ElementType *)TtaGetMemory((nbConst)*sizeof(ElementType)); TtaGiveConstructorsOfType(&typeArray,&nbConst,elTypePere); switch (constructor) { case ConstructNature: /* le type pere est un schema externe */ /* on verifie que le schema est celui demande */ if (!strcmp (NameType, TtaGetElementTypeOriginalName (elTypePere))) { newType->ElSSchema = typeArray[0].ElSSchema; if (newType->ElSSchema==NULL) { /* on charge le schema externe */ newType->ElSSchema=TtaNewSchemaExtension(TransDoc,NameType,""); } if(newType->ElSSchema!=NULL) /* le schema externe est charge*/ { TtaGiveTypeFromOriginalName(newType, NameType); found = TRUE; } else newType->ElTypeNum = 0; } else newType->ElTypeNum = 0; break; case ConstructBasicType: case ConstructReference: case ConstructConstant: case ConstructPair: newType->ElTypeNum = 0; break; case ConstructIdentity: elTypePere.ElTypeNum = typeArray[0].ElTypeNum; found = FindTypeInSubSchemas(NameType,elTypePere, newType); break; case ConstructList: elTypePere.ElTypeNum=typeArray[0].ElTypeNum; found = FindTypeInSubSchemas(NameType,elTypePere, newType); break; case ConstructChoice: switch(nbConst) { case -1: /* c'est une nature*/ /* on cherche dans les natures deja chargees si le type existe */ /* c'est fait pas TtaNewNature */ strsch = TtaGetDocumentSSchema(TransDoc); newType->ElSSchema=TtaNewNature(strsch,NameType,""); if(newType->ElSSchema!=NULL) { /* le schema externe est charge*/ TtaGiveTypeFromOriginalName(newType,NameType); found = TRUE; } break; case 0: /* c'est une unite */ break; default: /* c'est un choix */ for(i=0;iNameType); NameAncetre = TtaGetMemory(NAME_LENGTH); buftext = TtaGetMemory(MAX_PATH); result = FALSE; /* le type a generer ne fait pas partie du schema de son pere */ if (newType.ElTypeNum == 0) { FindTypeInSubSchemas(New->NameType, TtaGetElementType(generationStack[topGenStack]), &newType); } if (newType.ElTypeNum != 0) { newEl = TtaNewElement(TransDoc,newType); if (newEl!=NULL) { if (topGenStack>0 || MyLastSelect == NULL) lastEl = TtaGetLastChild(generationStack[topGenStack]); else { lastEl=MyLastSelect; TtaPreviousSibling(&lastEl); } if(lastEl == NULL) TtaInsertFirstChild(&newEl,generationStack[topGenStack],TransDoc); else TtaInsertSibling(newEl,lastEl,FALSE,TransDoc); if (TtaGetErrorCode()==0) result = TRUE; } } if(result) { /* update the last generated element and the depth */ generationStack[++topGenStack]=newEl; /* creer les attributs */ Attr= New->Attributes; while(Attr!=NULL) { TtaGiveAttributeTypeFromName (Attr->NameAttr,newEl,&newAttrType,&newAttrKind); if (TtaGetErrorCode()==0) {/* attribut valide */ newAttr=TtaGetAttribute(newEl,newAttrType); if (newAttr==NULL) { newAttr=TtaNewAttribute(newAttrType); if(newAttr!=NULL) TtaAttachAttribute(newEl,newAttr,TransDoc); } if(newAttr!=NULL) { if (!Attr->IsTransf) switch (newAttrKind) { case 0: /* enumere */ case 1: /* entier */ TtaSetAttributeValue(newAttr,atoi(Attr->Value),newEl,TransDoc); break; case 2: /* texte */ TtaSetAttributeText(newAttr,Attr->Value,newEl,TransDoc); break; case 3: /* reference */ break; } else { /* c'est un transfert de valeur d'attribut */ /* on cherche dans les ancetres de l'element original */ /* un element de type Attr -> TransType */ found =FALSE; elemAncetre = Original->element; do { typeAncetre = TtaGetElementType(elemAncetre); strcpy (NameAncetre, TtaGetElementTypeOriginalName(typeAncetre)); if(strcmp(NameAncetre,Attr->TransType)) {/* on cherche un attribut de nom Attr -> TransAttr */ attrAncetre = NULL; do { TtaNextAttribute(elemAncetre,&attrAncetre); if(attrAncetre!=NULL) { TtaGiveAttributeType(attrAncetre,&attrTypeAncetre,&attrKindAncetre); found = !strcmp(TtaGetAttributeName(attrTypeAncetre),Attr->TransAttr); } } while(!found && attrAncetre!=NULL); } if (!found) elemAncetre=TtaGetParent(elemAncetre); } while(!found && elemAncetre!=NULL); if (found && attrKindAncetre==newAttrKind) switch(newAttrKind) { case 0: /* enumere */ case 1: /* entier */ value = TtaGetAttributeValue(attrAncetre); TtaSetAttributeValue(newAttr,value,newEl,TransDoc); break; case 2: /* texte */ lenbuf=MAX_PATH; TtaGiveTextAttributeValue(attrAncetre,buftext,&lenbuf); TtaSetAttributeText(newAttr,buftext,newEl,TransDoc); break; case 3: /* reference */ TtaCopyAttributeReference(newAttr,newEl,attrAncetre); break; } } } } Attr=Attr->next; } } TtaFreeMemory(NameAncetre); TtaFreeMemory(buftext); return result; } /* ---------------------------------------------------------------------- */ /* TransfertChildren : copies the children of node into the result instance */ /* ---------------------------------------------------------------------- */ #ifdef __STDC__ static boolean TransfertChildren(Tagnode *node) #else static boolean TransfertChildren(node) Tagnode *node; #endif /* __STDC__ */ { Element parent, child, elPrec; boolean result; ListChild *lchild; ListElem *lelem; result = TRUE; if (topGenStack>0 || MyLastSelect==NULL) elPrec = TtaGetLastChild(generationStack[topGenStack]); else { elPrec=MyLastSelect; TtaPreviousSibling(&elPrec); } parent = node->element; /* create a new node in the subtree relation list */ lchild = match_env.listSubTrees; while (lchild->next != NULL && lchild->elemParent != parent) lchild = lchild->next; if (lchild->next == NULL && lchild->elemParent != parent) { lchild->next = (ListChild *)TtaGetMemory (sizeof (ListChild)); lchild = lchild->next; lchild->elemParent = parent; lchild->next = NULL; lchild->children = NULL; } child = TtaGetFirstChild (parent); lelem = NULL; /*transfering each children*/ while (result && child != NULL) { if (TtaGetElementVolume(child)!=0) {/* if the element is empty: no transfert */ TtaRemoveTree (child, TransDoc); if (elPrec!=NULL) { TtaInsertSibling (child, elPrec, FALSE, TransDoc); } else { TtaInsertFirstChild (&(child), generationStack[topGenStack], TransDoc); } result = !TtaGetErrorCode (); if (result) { if (lelem == NULL) { lchild->children = (ListElem *)TtaGetMemory (sizeof (ListElem)); lelem = lchild->children; } else { lelem->next = (ListElem *)TtaGetMemory (sizeof (ListElem)); lelem = lelem->next; } lelem->elem = child; lelem->next = NULL; } elPrec = child; TtaNextSibling(&child); } } return result; } /* ---------------------------------------------------------------------- */ /* TransfertNode : copies a node and its content into the result instance */ /* ---------------------------------------------------------------------- */ #ifdef __STDC__ static boolean TransfertNode(Tagnode *node,boolean inplace) #else static boolean TransfertNode(node,inplace) Tagnode *node; boolean inplace; #endif /* __STDC__ */ { Element parent,prevp,elem,lastelem,elPrec; ElementType eltype,typeparent; Construct constparent; int ancestlevel; boolean result; ListChild *lchild, *oldlc; ListElem *lelem; result = TRUE; parent = TtaGetParent(node->element); /* create / search a new node in the subtree relation list */ lchild = match_env.listSubTrees; while (lchild->next != NULL && lchild->elemParent != parent) lchild = lchild->next; if (lchild->next == NULL && lchild->elemParent != parent) { lchild->next = (ListChild *) TtaGetMemory (sizeof (ListChild)); lchild = lchild->next; lchild->elemParent = parent; lchild->children = NULL; lchild->next = NULL; } lelem = lchild->children; if (lelem != NULL) while (lelem->next != NULL) lelem = lelem->next; if (TtaGetElementVolume (node->element) != 0) {/* if the element is empty: no transfert */ if (!inplace) /* on ferme les elements generes par le regle precedente */ while (topGenStack >= LastRulePlace) { topGenStack--; } if (topGenStack > 0 || MyLastSelect == NULL) elPrec = TtaGetLastChild (generationStack[topGenStack]); else { elPrec = MyLastSelect; TtaPreviousSibling (&elPrec); } if (lelem == NULL) { lchild->children = (ListElem *)TtaGetMemory(sizeof(ListElem)); lelem = lchild->children; } else /* lelem->next IS null */ { lelem->next = (ListElem *)TtaGetMemory(sizeof(ListElem)); lelem = lelem->next; } lelem->elem = node->element; lelem->next = NULL; TtaRemoveTree (node->element, TransDoc); if (elPrec != NULL) { parent = TtaGetParent(elPrec); typeparent = TtaGetElementType(parent); constparent = TtaGetConstructOfType(typeparent); prevp = NULL; ancestlevel = 0; while (parent != NULL && (constparent == ConstructChoice || constparent == ConstructIdentity)) { prevp = parent; parent = TtaGetParent(parent); if(parent !=NULL) { ancestlevel++; typeparent = TtaGetElementType (parent); constparent = TtaGetConstructOfType (typeparent); } } if (prevp != NULL) { lastelem = TtaNewElement (TransDoc, TtaGetElementType(prevp)); TtaInsertSibling (lastelem, prevp, FALSE, TransDoc); while ((--ancestlevel)>0) { prevp = TtaGetFirstChild(prevp); elem = TtaNewElement(TransDoc,TtaGetElementType(prevp)); TtaInsertFirstChild(&elem,lastelem,TransDoc); lastelem = prevp; } TtaInsertFirstChild (&(node->element),lastelem,TransDoc); if (topGenStack>=0) generationStack[++topGenStack] = node->element; } else TtaInsertSibling(node->element, elPrec, FALSE, TransDoc); } else { /* TtaInsertFirstChild peut <> les elements node->element */ /* et generationStack[topGenStack]: on retient l'ancien element */ /* node->element dans elPrec avant de l'ajouter dans la liste des */ /* element a reinserer en cas d'echec de la transformation */ eltype = TtaGetElementType(node->element); TtaInsertFirstChild(&(node->element), generationStack[topGenStack], TransDoc); if(!TtaGetErrorCode() && node->element == generationStack[topGenStack]) { lelem->elem = TtaNewElement (TransDoc, eltype); oldlc = lchild->next; lchild->next = (ListChild *) TtaGetMemory (sizeof (ListChild)); lchild = lchild->next; lchild->children = NULL; lchild->next = oldlc; lchild->elemParent = lelem->elem; lelem = NULL; elPrec = TtaGetFirstChild (node->element); while (elPrec != NULL) { if(lelem==NULL) { lchild->children = (ListElem *) TtaGetMemory (sizeof (ListElem)); lelem = lchild->children; } else /* lelem->next IS null */ { lelem->next = (ListElem *) TtaGetMemory (sizeof (ListElem)); lelem = lelem->next; } lelem->elem = elPrec; lelem->next = NULL; TtaNextSibling (&elPrec); } } } result = !TtaGetErrorCode (); } return result; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* | Fonctions de transformation par regles | */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ #ifdef __STDC__ static boolean TransformNode(strmatchchildren *sm); #else static boolean TransformNode(sm); #endif /* __STDC__ */ #ifdef __STDC__ static boolean ApplyTransChild(strmatchchildren *smc) #else static boolean ApplyTransChild(smc) strmatchchildren *smc; #endif /* __STDC__ */ { strmatchchildren *smc2; strmatch *sm; boolean found,result; result =TRUE; smc2=smc; while(result && smc2!=NULL) { smc2->node->isTrans=TRUE; if (smc2->patsymb->Rule==NULL) { /* pas de regle de transformation pour ce noeud */ /* on cherche si l'un de ses descendants a ete matche */ sm=smc2->node->matches; found =FALSE; while(!found && sm!=NULL) { found = (sm->patsymb == smc2->patsymb); if(!found) sm=sm->next; } if (found) { /* il existe un matching pour au moins un fils du noeud courant */ result = ApplyTransChild(sm->childmatches); } else { /* il n'y a pas de matching pour les fils de ce noeud */ result = TransfertNode(sm->node,FALSE); } } else {/* il existe une regle de transformation pour ce noeud */ /* on applique la regle de transformation */ result = TransformNode(smc2); } smc2=smc2->next; } return result; } #ifdef __STDC__ static boolean TransformNode(strmatchchildren *sm) #else static boolean TransformNode(sm) strmatchchildren *sm; #endif /* __STDC__ */ { int cournode; strmatch *sm2; NodeDesc *RNodeCour; boolean stop,sonsmatch,result; ElementType eltype; result = TRUE; sm2=sm->node->matches; sonsmatch=FALSE; while (sm2!=NULL && !sonsmatch) { sonsmatch = (sm2->patsymb==sm->patsymb && sm2->childmatches!=NULL); if (!sonsmatch) sm2=sm2->next; } /* sonsmatch est vrai s'il existe un matching pour au moins un fils du noeud Source*/ sm->node->transsymb=sm->patsymb; cournode=1; RNodeCour=sm->patsymb->Rule->OptNodes; stop=(RNodeCour==NULL || cournode > topGenStack); while(!stop) { /* pour chaque noeud optionnel */ eltype=TtaGetElementType(generationStack[cournode]); if(!strcmp(TtaGetElementTypeOriginalName(eltype),RNodeCour->NameType)) {/* le tag est deja present : on ne genere rien*/ RNodeCour=RNodeCour->next; cournode++; stop=(RNodeCour==NULL || cournode > topGenStack); } else { /* il faut creer une nouvelle branche dans la destination */ stop = TRUE; } } while(topGenStack>=cournode) { /* on ferme les tags de la pile (crees par la regle precedente)*/ topGenStack--; } while (result && RNodeCour!=NULL) {/* on genere des noeuds optionnels non deja presents*/ result = GenereElement(RNodeCour,sm->node); cournode++; RNodeCour=RNodeCour->next; } LastRulePlace = cournode; RNodeCour=sm->patsymb->Rule->NewNodes; while (result && RNodeCour!=NULL && strcmp (RNodeCour->NameType, "*")) {/* on genere les nouveaux noeuds */ result = GenereElement(RNodeCour,sm->node); cournode++; RNodeCour=RNodeCour->next; } if(result) if (RNodeCour!=NULL && !strcmp(RNodeCour->NameType,"*")) { result = TransfertNode(sm->node, TRUE); } /* on traite les fils du noeud */ else if (sonsmatch) { /* si les fils ont ete matches */ result = ApplyTransChild(sm2->childmatches); } else { /*Les fils ne matchent pas : on les transfere */ result = TransfertChildren (sm->node); } return result; } /*---------------------------------------------------------------------- ApplyTransformation parcours de l'arbre source upside down en appliquant la transformation d'indice t dans TabPatterns ---------------------------------------------------------------------- */ #ifdef __STDC__ static boolean ApplyTransformation (strmatch *sm, Document doc) #else /* __STDC__*/ static boolean ApplyTransformation (sm, doc) strmatch *sm; Document doc; #endif /* __STDC__*/ { strmatchchildren *DMatch; boolean res; ListElem *lelem, *listoldelem; ListChild *lchild; Element elCour, elNext; res = FALSE; if(sm != NULL && sm->childmatches != NULL) { match_env.listSubTrees = (ListChild *)TtaGetMemory (sizeof (ListChild)); match_env.listSubTrees->elemParent = sm->node->element; match_env.listSubTrees->next = NULL; match_env.listSubTrees->children = NULL; lelem = NULL; DMatch = sm->childmatches; /* memorize the previous sibling of the first matched element */ MyFirstSelect = DMatch->node->element; TtaPreviousSibling (&MyFirstSelect); if (MyFirstSelect == NULL) { /* if there is no previous sibling, memorize the father */ MyFirstSelect = sm->node->element; isClosed = FALSE; } else isClosed = TRUE; while (DMatch != NULL) { if(DMatch->node->element != NULL) { if(lelem == NULL) { match_env.listSubTrees->children = (ListElem *)TtaGetMemory (sizeof (ListElem)); lelem = match_env.listSubTrees->children; } else { lelem->next = (ListElem *)TtaGetMemory(sizeof(ListElem)); lelem = lelem->next; } lelem->elem = DMatch->node->element; lelem->next = NULL; /* memorize the next sibling of the last matched element */ MyLastSelect = TtaGetSuccessor(DMatch->node->element); TtaRemoveTree (DMatch->node->element, TransDoc); } DMatch = DMatch->next; } /* initialize the transformation stack */ topGenStack=0; generationStack[topGenStack]=sm->node->element; LastRulePlace=1; /* apply the transformation */ res=ApplyTransChild(sm->childmatches); while(topGenStack>0) { /*here close the element at the top of the stack */ topGenStack--; } if (!res) /*transformation failure : restore the old structure*/ { /*remove the generated structure */ listoldelem=NULL; if (isClosed) { elCour = MyFirstSelect; TtaNextSibling(&elCour); } else elCour = TtaGetFirstChild(MyFirstSelect); while(elCour!=NULL && elCour != MyLastSelect) { elNext = elCour; TtaNextSibling(&elNext); TtaRemoveTree(elCour,TransDoc); if(listoldelem==NULL) { listoldelem=(ListElem *)TtaGetMemory(sizeof(ListElem)); lelem= listoldelem; } else { lelem->next= (ListElem *)TtaGetMemory(sizeof(ListElem)); lelem = lelem->next; } lelem->elem = elCour; lelem->next = NULL; elCour=elNext; } /* re-insert the old higher-level elements */ lchild = match_env.listSubTrees; if ((isClosed && TtaGetParent(MyFirstSelect)== lchild->elemParent) ||(!isClosed && MyFirstSelect==lchild->elemParent)) { elCour = NULL; if (isClosed) elCour = MyFirstSelect; lelem= lchild->children; while (lelem != NULL) { if (elCour!=NULL) TtaInsertSibling(lelem->elem,elCour,FALSE,TransDoc); else TtaInsertFirstChild(&lelem->elem,lchild->elemParent,TransDoc); elCour=lelem->elem; lelem=lelem->next; } /* re - insert the leaves */ lchild=match_env.listSubTrees->next; while (lchild!=NULL) { elCour = NULL; lelem= lchild->children; while (lelem != NULL) { TtaRemoveTree(lelem->elem,TransDoc); if (elCour!=NULL) TtaInsertSibling(lelem->elem,elCour,FALSE,TransDoc); else TtaInsertFirstChild(&lelem->elem,lchild->elemParent,TransDoc); elCour=lelem->elem; lelem=lelem->next; } lchild = lchild->next; } } /* destroy the generated structure */ lelem=listoldelem; while(lelem!=NULL) { TtaDeleteTree(lelem->elem,TransDoc); listoldelem = lelem; lelem = lelem->next; TtaFreeMemory((char *)listoldelem); } } } TtaSetErrorMessages(1); return res; } /* ---------------------------------------------------------------------- CheckSelection checks if all the selected element are at the same level. Extends the selction to an element if all its children are selected ---------------------------------------------------------------------- */ #ifdef __STDC__ static boolean CheckSelectionLevel(Document doc) #else /* __STDC__*/ static boolean CheckSelectionLevel(doc) Document doc; #endif /* __STDC__*/ { Element prevFirst,parentFirst,nextLast,parentLast; boolean result; TtaGiveFirstSelectedElement(doc,&OrigFirstSelect,&ffc,&flc); TtaGiveLastSelectedElement(doc,&OrigLastSelect,&lfc,&llc); MyFirstSelect=OrigFirstSelect; MyLastSelect=OrigLastSelect; parentFirst=NULL; match_env.maxSelDepth=0; if (MyFirstSelect!=MyLastSelect) { if(MyFirstSelect!=NULL && ffc<=1) {/* searching for the first selected element */ prevFirst=MyFirstSelect; TtaPreviousSibling(&prevFirst); parentFirst=TtaGetParent(MyFirstSelect); while(parentFirst!=NULL && prevFirst==NULL && TtaIsBefore(parentFirst,MyLastSelect)) { MyFirstSelect=parentFirst; prevFirst=MyFirstSelect; TtaPreviousSibling(&prevFirst); parentFirst=TtaGetParent(MyFirstSelect); } } if(MyLastSelect!=NULL && (llc==0||(llc>0 && llc>=TtaGetTextLength( MyLastSelect)))) {/* searching for the last selected element */ nextLast=MyLastSelect; TtaNextSibling(&nextLast); parentLast=TtaGetParent(MyLastSelect); while(parentLast!=NULL && nextLast==NULL && TtaIsBefore(MyFirstSelect,parentLast)) { MyLastSelect=parentLast; nextLast=MyLastSelect; TtaNextSibling(&nextLast); parentLast=TtaGetParent(MyLastSelect); } } } else { prevFirst=TtaGetFirstChild(MyFirstSelect); nextLast=TtaGetLastChild(MyFirstSelect); while (prevFirst!=NULL && prevFirst==nextLast) { MyFirstSelect=prevFirst; prevFirst=TtaGetFirstChild(MyFirstSelect); nextLast=TtaGetLastChild(MyFirstSelect); } if(prevFirst!=NULL) { MyFirstSelect=prevFirst; MyLastSelect=nextLast; } else { MyLastSelect=MyFirstSelect; } parentFirst=parentLast=TtaGetParent(MyFirstSelect); } MySelect = NULL; result = MyFirstSelect!=NULL && (parentFirst==parentLast); if (result && parentFirst!=NULL) {/* if all selected elements are at the same level, checking if ancestors have any sibling */ /* if it is not the case, they become the first selected element*/ nextLast=MyLastSelect; prevFirst=MyFirstSelect; TtaNextSibling(&nextLast); TtaPreviousSibling(&prevFirst); while(parentFirst!=NULL && nextLast==NULL && prevFirst==NULL) { match_env.maxSelDepth++; MySelect=parentFirst; parentFirst=TtaGetParent(parentFirst); if(parentFirst!=NULL) { nextLast=MySelect; prevFirst=MySelect; TtaNextSibling(&nextLast); TtaPreviousSibling(&prevFirst); } } } return result; } /* ---------------------------------------------------------------------- */ /* Give the next selected element, accordingly to extension given by CheckSelectionLevel */ /* ---------------------------------------------------------------------- */ #ifdef __STDC__ static void MyNextSelectedElement(Document doc,Element *elselect) #else /* __STDC__*/ static void MyNextSelectedElement(doc,elselect) Document doc; Element *elselect; #endif /* __STDC__*/ { Element elfirst; int fc,lc; if(*elselect==NULL || *elselect==MySelect || *elselect==MyLastSelect) {/* if the selection is an unique element, or elselect is the last */ *elselect=NULL; } else { if(*elselect==MyFirstSelect) { TtaGiveFirstSelectedElement(doc, &elfirst,&fc,&lc); if(elfirst==MyFirstSelect) TtaGiveNextSelectedElement(doc, &elfirst,&fc,&lc); else while (elfirst!=NULL && TtaIsAncestor(elfirst,MyFirstSelect)) TtaGiveNextSelectedElement(doc, &elfirst,&fc,&lc); } else { elfirst=*elselect; TtaGiveNextSelectedElement(doc, &elfirst,&fc,&lc); } if(elfirst!=NULL && TtaIsAncestor(elfirst,MyLastSelect)) *elselect=MyLastSelect; else *elselect=elfirst; } } /* ------------------------------------------------------------- */ /* IsValidChildInContext */ /* ------------------------------------------------------------- */ #ifdef __STDC__ static boolean IsValidChildInContext(char *nameNewType,ElementType elTypeParent,char *namePrevType) #else /* __STDC__*/ static boolean IsValidChildInContext(nameNewType,elTypeParent,namePrevType) char *nameNewType; ElementType elTypeParent; char *namePrevType; #endif /* __STDC__*/ { Construct constparent; int cardparent, i; boolean found, result = FALSE; ElementType *subtypes; if (elTypeParent.ElSSchema != NULL) { constparent = TtaGetConstructOfType (elTypeParent); cardparent = TtaGetCardinalOfType (elTypeParent); subtypes = (ElementType *) TtaGetMemory (cardparent * sizeof (ElementType)); TtaGiveConstructorsOfType(&subtypes, &cardparent, elTypeParent); switch(constparent) { case ConstructChoice : case ConstructUnorderedAggregate: for (i = 0; i < cardparent && !result; i++) { if(!strcmp (nameNewType, TtaGetElementTypeOriginalName (subtypes[i]))) result = TRUE; } if (!result) for (i = 0; i < cardparent && !result; i++) result = IsValidChildInContext (nameNewType, subtypes[i], ""); break; case ConstructOrderedAggregate: if (!strcmp (namePrevType, "") && !strcmp (nameNewType, TtaGetElementTypeOriginalName (subtypes[0]))) result = TRUE; for (i = 0; i < cardparent && !found; i++) { if (!strcmp (namePrevType, TtaGetElementTypeOriginalName (subtypes[i]))) found = TRUE; } if(found) { result = ((i < cardparent-1) && !strcmp (nameNewType, TtaGetElementTypeOriginalName (subtypes[i+1]))); if(!result) result = IsValidChildInContext (nameNewType, subtypes[i+1], ""); } break; case ConstructNature: if (subtypes[0].ElSSchema != NULL && subtypes[0].ElTypeNum == 0) subtypes[0].ElTypeNum = 8; default: result = !strcmp (nameNewType, TtaGetElementTypeOriginalName (subtypes[0])); if(!result) result = IsValidChildInContext (nameNewType, subtypes[0], ""); break; } TtaFreeMemory ((char *)subtypes); } return result; } /* ------------------------------------------------------------- */ /* CheckValidTransRoot */ /* checks if the higher-level generated elements are possible children of the */ /* transformation root element */ /* sm is the higher couple descriptor (sm->patsymb->Tag = pattern_root) */ /* elTypeRoot is the type of the first common ancestor of all matched elements */ /* ------------------------------------------------------------- */ #ifdef __STDC__ static boolean CheckValidTransRoot(strmatch *sm,ElementType elTypeRoot,char *NameTypePrev) #else /* __STDC__*/ static boolean CheckValidTransRoot(sm,elTypeRoot,NameTypePrev) strmatch *sm; ElementType elTypeRoot; char *NameTypePrev; #endif /* __STDC__*/ { strmatchchildren *smc; strmatch *sm2; NodeDesc *node; boolean result,sonsmatch; char *curNameType; curNameType = TtaGetMemory(NAME_LENGTH); result = FALSE; smc = sm->childmatches; /* while there are matched elements */ while (smc != NULL) { if(smc->patsymb->Rule == NULL) {/* if there is no rule for the current node*/ sm2 = smc->node->matches; /* sm2 is the matching descriptor list of the first matched child */ sonsmatch = FALSE; while (sm2 != NULL && !sonsmatch) { /* searches the children matching descriptor */ sonsmatch = (sm2->patsymb == smc->patsymb && sm2->childmatches != NULL); if (!sonsmatch) sm2=sm2->next; } if(sonsmatch) {/* if they have been, checks the elements generated by these children*/ result = CheckValidTransRoot(sm2,elTypeRoot,NameTypePrev); } else { /* if the children of the element have not been matched */ /* checks if the node can be transferred in the destination */ if(TtaGetElementVolume(smc->node->element) != 0) { /* if the element is empty, it is ignored in transformation */ if(IsValidChildInContext(TtaGetElementTypeOriginalName(smc->node->eltype), elTypeRoot, NameTypePrev)) { result = TRUE; strcpy(NameTypePrev, TtaGetElementTypeOriginalName(smc->node->eltype)); } } } } else {/* there is a rule for the current node*/ node = smc->patsymb->Rule->OptNodes; if (node != NULL) {/* if there is at least one place node */ if(strcmp(NameTypePrev, node->NameType)) if(IsValidChildInContext(node->NameType, elTypeRoot, NameTypePrev)) { result = TRUE; strcpy(NameTypePrev, node->NameType); } } else { node = smc->patsymb->Rule->NewNodes; if(node != NULL) { if(!strcmp(node->NameType, "*")) strcpy(curNameType, TtaGetElementTypeOriginalName(smc->node->eltype)); else strcpy(curNameType, node->NameType); if(IsValidChildInContext(curNameType, elTypeRoot, NameTypePrev)) { result = TRUE; strcpy(NameTypePrev, curNameType); } } } } if (result) smc = smc->next; else smc = NULL; } TtaFreeMemory(curNameType); return result; } /* ---------------------------------------------------------------------- */ /* callback of the transformation selection menu */ /* ---------------------------------------------------------------------- */ #ifdef __STDC__ void TransCallback (int data) #else /* __STDC__*/ void TransCallback (data) int data; #endif /* __STDC__*/ { DisplayMode olddispl; olddispl = TtaGetDisplayMode(TransDoc); /* annule la selection */ if (olddispl != DisplayImmediately) TtaSetDisplayMode (TransDoc, DisplayImmediately); TtaSelectElement (TransDoc, NULL); /* passe en mode display differe */ #ifndef DEBUG TtaSetDisplayMode (TransDoc, DeferredDisplay); #endif /* DEBUG */ ResultTrans = ApplyTransformation (TabMenuTrans[data], TransDoc); TtaSetDisplayMode(TransDoc,olddispl); if (!ResultTrans) { /* transformation has failed, restoring the old selection */ if(ffc==0 && flc==0) TtaSelectElement(TransDoc,OrigFirstSelect); else TtaSelectString(TransDoc,OrigFirstSelect,ffc,flc); TtaExtendSelection(TransDoc,OrigLastSelect,llc); /* displaying an error message */ TtaDisplaySimpleMessage(TRANSDIAL,INFO,TRANS_FAILED); } else { /* transformation was succesful, selecting the new elements*/ if(MyLastSelect==NULL) if(!isClosed) MyLastSelect=TtaGetLastChild(MyFirstSelect); else MyLastSelect=TtaGetLastChild(TtaGetParent(MyFirstSelect)); else TtaPreviousSibling(&MyLastSelect); if(isClosed) TtaNextSibling(&MyFirstSelect); else MyFirstSelect=TtaGetFirstChild(MyFirstSelect); TtaSelectElement(TransDoc,MyFirstSelect); if(MyLastSelect!=NULL && TtaIsBefore(MyFirstSelect,MyLastSelect)) TtaExtendSelection(TransDoc,MyLastSelect,0); } FreeMatchEnv(); } /* ---------------------------------------------------------------------- */ /* */ #ifdef __STDC__ void BuildMenuChangeType(char *BufMenu,int *nbEntreesMenu,Document doc) #else /* __STDC__*/ void BuildMenuChangeType(BufMenu,nbEntreesMenu,doc) char *BufMenu; int *nbEntreesMenu; Document doc; #endif /* __STDC__*/ { Element elemselect,courelem; int i,j,k; char *tag; strmatch *sm; TagTree node; trans_sch* transSch; SSchema strsch,prevstrsch; boolean ok; match_env.subjecttree=NULL; match_env.listSubTrees=NULL; ResultTrans=FALSE; TransDoc=doc; if(CheckSelectionLevel(TransDoc)) { transSch = match_env.transSet; while (transSch!=NULL) { transSch->active = FALSE; transSch=transSch->next; } /* initialisation du contexte de matching (lecture & parsing des patterns) */ courelem = MyFirstSelect; prevstrsch = NULL; ok = TRUE; /* tous les elements selectionnes appartiennent ils au meme schema ? */ while (ok && courelem!=NULL) { strsch = TtaGetElementType(courelem).ElSSchema; ok = (prevstrsch==NULL || TtaSameSSchemas(strsch,prevstrsch)); if (ok) { prevstrsch=strsch; MyNextSelectedElement(TransDoc,&courelem); } } /* parsing des fichiers de transformation associes aux schemas de tous les */ /* ascendants des elements selectionnes */ if (!ok) courelem=TtaGetParent(MyFirstSelect); else courelem=MyFirstSelect; prevstrsch = NULL; ok = FALSE; while (courelem!=NULL) { strsch = TtaGetElementType(courelem).ElSSchema; if (prevstrsch==NULL || ! TtaSameSSchemas(strsch,prevstrsch)) { ok = ok || ppStartParser(TtaGetSSchemaName(strsch)); prevstrsch=strsch; } courelem = TtaGetParent(courelem); } if (ok) { /* contruction de l'arbre de tags */ transSch = match_env.transSet; maxMatchDepth=0; while (transSch!=NULL) { if(transSch->active && transSch->maxdepth>maxMatchDepth) maxMatchDepth=transSch->maxdepth; transSch=transSch->next; } maxMatchDepth+=match_env.maxSelDepth; match_env.subjecttree=newNode(); if(MySelect!=NULL) { (match_env.subjecttree)->element=TtaGetParent(MySelect); BuildTagTree(MySelect,TransDoc,match_env.subjecttree,maxMatchDepth,0); } else { (match_env.subjecttree)->element=TtaGetParent(MyFirstSelect); elemselect=MyFirstSelect; while (elemselect!=NULL) { BuildTagTree(elemselect,TransDoc,match_env.subjecttree,maxMatchDepth,0); MyNextSelectedElement(TransDoc,&elemselect); } } (match_env.subjecttree)->eltype=TtaGetElementType((match_env.subjecttree)->element); /* pattern matching */ PatternMatching(match_env.subjecttree); /* inserts the transformation names in the menu buffer */ j=0; for (i=0; i< *nbEntreesMenu;i++) { j+=strlen(&(BufMenu[j])); j++; } node=match_env.subjecttree; i=0; tag = TtaGetMemory(NAME_LENGTH); do {/* for each node above the first selected */ sm=node->matches; while(sm!=NULL) { /* for each matching of the node */ if(!strcmp(sm->patsymb->Tag,"pattern_root")) { /* if it is matching a pattern root : insert the transformation name */ /* in the menu buffer */ strcpy(tag,""); if(CheckValidTransRoot(sm, sm->node->eltype, tag)) { for (k=0;kpatsymb->Name,sm->patsymb->Name);k++); if(k==i) { sprintf (&BufMenu[j],"%s%s","B",sm->patsymb->Name); j += strlen(&BufMenu[j]) + 1; TabMenuTrans[i++]=(strmatch *)sm; } /* else */ /* TabMenuTrans[k]=(strmatch *)sm; */ } } sm=sm->next; } node=node->child; } while (node!=NULL && (!TtaIsAncestor( node->element,MyFirstSelect))); TtaFreeMemory(tag); if (i>0) {/* if some transformations have been matched */ *nbEntreesMenu +=i; /* succes : exit the function */ return ; } } } /* failure : display an status message */ TtaDisplaySimpleMessage(TRANSDIAL,INFO,NO_TRANS); }