void appendNode(Node **node, const char *name, const char *function) { if (*node == NULL) { *node = createNode(name, function); } else { appendNode(&(*node)->next, name, function); } }
AST_NODE* parseSexpr(TOKEN* tokens, AST_NODE* rootNode, int* numConsumed) { AST_NODE_LIST* parentStack = (AST_NODE_LIST*)malloc(sizeof(AST_NODE_LIST)); parentStack->head = rootNode; parentStack->tail = 0; do { TOKEN currentToken = tokens[(*numConsumed)++]; if (currentToken.type == RPAREN) { parentStack = parentStack->tail; // pop } else if (currentToken.type == QUOTE) { AST_NODE* newASTNode = (AST_NODE*)malloc(sizeof(AST_NODE)); newASTNode->payload = currentToken; newASTNode->children = 0; parseSexpr(tokens, newASTNode, numConsumed); parentStack->head->children = appendNode(parentStack->head->children, newASTNode); } else if (currentToken.type != WHITESPACE && currentToken.type != ENDOFFILE) { AST_NODE* newASTNode = (AST_NODE*)malloc(sizeof(AST_NODE)); newASTNode->payload = currentToken; newASTNode->children = 0; parentStack->head->children = appendNode(parentStack->head->children, newASTNode); if (currentToken.type == LPAREN) { parentStack = consNode(newASTNode, parentStack); // push } } } while (parentStack->tail); // assume the fake "root" node has exactly one child for now return parentStack->head; }
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { ListNode* head = NULL; ListNode* tail = NULL; ListNode* nav1 = l1; ListNode* nav2 = l2; int a,b,c, carry = 0; while (nav1 && nav2) { a = nav1->val; b = nav2->val; c = (a + b + carry) % 10; carry = (a + b + carry) / 10; appendNode(head, tail, c); nav1 = nav1->next; nav2 = nav2->next; } while (nav1) { a = nav1->val; c = (a + carry) % 10; carry = (a + carry) / 10; appendNode(head, tail, c); nav1 = nav1->next; } while (nav2) { b = nav2->val; c = (b + carry) % 10; carry = (b + carry) / 10; appendNode(head, tail, c); nav2 = nav2->next; } if (carry) { appendNode(head, tail, carry); } return head; }
void ModifySelectionListLevelCommand::appendSiblingNodeRange(Node* startNode, Node* endNode, Element* newParent) { Node* node = startNode; while (1) { Node* next = node->nextSibling(); removeNode(node); appendNode(node, newParent); if (node == endNode) break; node = next; } }
int main(void) { appendNode(&list1, 10); appendNode(&list1, 20); appendNode(&list1, 30); appendNode(&list1, 40); appendNode(&list2, 1); appendNode(&list2, 2); appendNode(&list2, 3); appendNode(&list2, 4); printList(list1); printList(list2); return 0; }
PassRefPtr<Element> InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock(const Vector<RefPtr<Element> >& ancestors, PassRefPtr<Element> blockToInsert) { // Make clones of ancestors in between the start node and the start block. RefPtr<Element> parent = blockToInsert; for (size_t i = ancestors.size(); i != 0; --i) { RefPtr<Element> child = ancestors[i - 1]->cloneElementWithoutChildren(); // It should always be okay to remove id from the cloned elements, since the originals are not deleted. child->removeAttribute(HTMLNames::idAttr); appendNode(child, parent); parent = child.release(); } return parent.release(); }
bool enqueue(char *str) { if (end == NULL && head == NULL) { head = newNode(str); end = head; } else { end = appendNode(end,str); } if (head != NULL) return true; else return false; }
void DOMBuilder::startElement(const XMLString& uri, const XMLString& localName, const XMLString& qname, const Attributes& attributes) { AutoPtr<Element> pElem = _namespaces ? _pDocument->createElementNS(uri, qname.empty() ? localName : qname) : _pDocument->createElement(qname); const AttributesImpl& attrs = dynamic_cast<const AttributesImpl&>(attributes); Attr* pPrevAttr = 0; for (AttributesImpl::iterator it = attrs.begin(); it != attrs.end(); ++it) { AutoPtr<Attr> pAttr = new Attr(_pDocument, 0, it->namespaceURI, it->localName, it->qname, it->value, it->specified); pPrevAttr = pElem->addAttributeNodeNP(pPrevAttr, pAttr); } appendNode(pElem); _pParent = pElem; }
// adds a url to the list, or increase rank of an existing url, making // sure to bump it up the list if needed void PopularUrls::addUrl(const QUrl& url) { QUrl tmpurl = url; tmpurl.setPassword(QString()); // make sure no passwords are permanently stored if (!tmpurl.path().endsWith('/')) // make a uniform trailing slash policy tmpurl.setPath(tmpurl.path() + '/'); UrlNodeP pnode; decreaseRanks(); if (!head) { // if the list is empty ... (assumes dict to be empty as well) pnode = new UrlNode; pnode->rank = STARTING_RANK; pnode->url = tmpurl; appendNode(pnode); ranks.insert(tmpurl.url(), head); } else { if (ranks.find(tmpurl.url()) == ranks.end()) { // is the added url new? if so, append it pnode = new UrlNode; pnode->rank = STARTING_RANK; pnode->url = tmpurl; appendNode(pnode); ranks.insert(tmpurl.url(), pnode); } else { pnode = ranks[ tmpurl.url()]; pnode->rank += INCREASE; } } // do we need to change location for this one? relocateIfNeeded(pnode); // too many urls? if (count > maxUrls) removeNode(tail); //dumpList(); }
AST_NODE makeTestTree() { AST_NODE* root = (AST_NODE*)malloc(sizeof(AST_NODE)); TOKEN rootToken; rootToken.length = 1; rootToken.text = getCharactersFromString("("); root->payload = rootToken; AST_NODE* define = (AST_NODE*)malloc(sizeof(AST_NODE)); TOKEN defToken; defToken.length = 6; defToken.text = getCharactersFromString("define"); define->payload = defToken; define->children = 0; AST_NODE* foo = (AST_NODE*)malloc(sizeof(AST_NODE)); TOKEN fooToken; fooToken.length = 3; fooToken.text = getCharactersFromString("foo"); foo->payload = fooToken; foo->children = 0; AST_NODE* bar = (AST_NODE*)malloc(sizeof(AST_NODE)); TOKEN barToken; barToken.length = 3; barToken.text = getCharactersFromString("bar"); bar->payload = barToken; bar->children = 0; root->children = 0; root->children = appendNode(root->children, define); appendNode(root->children, foo); appendNode(root->children, bar); return *root; }
int addNode(ChainList *pList, void *data) { if (pList->type == CHAIN_TYPE_INSERT) { return insertNodePrior(pList, data); } else if (pList->type == CHAIN_TYPE_APPEND) { return appendNode(pList, data); } else { return insertNodeAsc(pList, data); } }
void CreateLinkCommand::doApply() { if (endingSelection().isNone()) return; RefPtr<HTMLAnchorElement> anchorElement = HTMLAnchorElement::create(document()); anchorElement->setHref(m_url); if (endingSelection().isRange()) applyStyledElement(anchorElement.get()); else { insertNodeAt(anchorElement.get(), endingSelection().start()); RefPtr<Text> textNode = Text::create(document(), m_url); appendNode(textNode.get(), anchorElement.get()); setEndingSelection(VisibleSelection(positionInParentBeforeNode(anchorElement.get()), positionInParentAfterNode(anchorElement.get()), DOWNSTREAM)); } }
void Tree::crudeBalance() { if (d_root.get() == NULL) { return; } // if std::vector<Node> nodes; appendNode(nodes, *d_root); std::sort(nodes.begin(), nodes.end()); for (size_t i = 0; i < nodes.size(); ++i) { deleteVal(nodes[i].value()); } // for balanceBySortedArray(nodes, 0, nodes.size() - 1); }
void CreateLinkCommand::doApply() { if (endingSelection().isNone()) return; RefPtrWillBeRawPtr<HTMLAnchorElement> anchorElement = HTMLAnchorElement::create(document()); anchorElement->setHref(AtomicString(m_url)); if (endingSelection().isRange()) { applyStyledElement(anchorElement.get()); } else { insertNodeAt(anchorElement.get(), endingSelection().start()); RefPtrWillBeRawPtr<Text> textNode = Text::create(document(), m_url); appendNode(textNode.get(), anchorElement.get()); setEndingSelection(VisibleSelection(positionInParentBeforeNode(*anchorElement), positionInParentAfterNode(*anchorElement), TextAffinity::Downstream, endingSelection().isDirectional())); } }
/* adds data to the end of the list. Note that the return value is the same list as the list passed in, but returning the list from the function allows one to "chain" calls to addData like so: addData(addData(addData (x, list), y), z) */ LinkedList * addData (LinkedList * list, NodeData data) { Node * newTail = createNode (data); /* if list is empty, update both head & tail */ if (list->head == NULL) { assert (list->tail == NULL); list->head = list->tail = newTail; } else { appendNode (list->tail, newTail); list->tail = newTail; } return list; }
void CreateLinkCommand::doApply() { if (endingSelection().isNone()) return; RefPtr<HTMLAnchorElement> anchorElement = new HTMLAnchorElement(document()); anchorElement->setHref(m_url); if (endingSelection().isRange()) { pushPartiallySelectedAnchorElementsDown(); applyStyledElement(anchorElement.get()); } else { insertNodeAt(anchorElement.get(), endingSelection().start()); RefPtr<Text> textNode = new Text(document(), m_url); appendNode(textNode.get(), anchorElement.get()); setEndingSelection(Selection(positionBeforeNode(anchorElement.get()), positionAfterNode(anchorElement.get()), DOWNSTREAM)); } }
//returns an uninitialized linked list with 'n' nodes Node newList(int n){ if(n <= 0){ return NULL; } //first node Node root = newNode(NULL, NULL, NULL, NULL, 0); //create (n-1) more nodes int i; Node temp; for(i = 1; i < n; i++){ temp = newNode(NULL, NULL, NULL, NULL, 0); appendNode(temp, root); } return root; }
int main() { char line[BUFSIZE]; char name[NAME]; /*name of the sale itme*/ double uPrice, sMass; /*unit price and sold mass of the item*/ pSALE head; pSALE sd; FILE *stream; /*** Read the sales data into four structures s1,s2,s3,s4 and link them together ***/ stream = fopen("sale.dat","r"); if(stream == NULL) { fprintf(stderr,"Error: cannot open 'sale.dat'\n"); return NULL; } head = NULL; fgets(line, BUFSIZE, stream); // read a line into a buffer while(!feof(stream)) { while(line[0] == '#') { fgets(line,BUFSIZE,stream); } sscanf(line, "%s%lf%lf",name,&uPrice,&sMass); sd = createNode(name,uPrice,sMass); appendNode(&head, sd); printf("%s %lf %lf\n",sd->name, sd->unitPrice, sd->soldMass); fgets(line,BUFSIZE,stream); } fclose(stream); double maxWeight, maxDollar; pSALE tmp = head; while(tmp->next) { if(maxWeight < tmp->soldMass) maxWeight = tmp->soldMass; if(maxDollar < ((tmp->soldMass)*(tmp->unitPrice))) maxDollar = (tmp->soldMass)*(tmp->unitPrice); tmp = tmp->next; } printf("The largest volume in weight is %lf\n", maxWeight); printf("The largest volume in weight is %lf\n", maxDollar); // clear the link list clearList(head); return 0; }
void main() { int value; //struct node* head = NULL; struct node* copy = NULL; push(2); push(3); push(5); value = pop(); printf("value = %d\n", value); printf("Length of list = %d\n", length()); printList(head); appendNode(8); printList(head); printf("Length of list = %d\n", length()); copy = copyList(head); printList(copy); // add additional tests here.... }
struct node *read_from_list(struct node **tokens) { struct node *token; token = pop(tokens); if(token != NULL && (token->t == 's' || token->t == 'S') && strcmp(token->s,"(") == 0){ struct node *L = (struct node *)malloc(sizeof(struct node));; L->t = 'l'; L->head = NULL; L->next = NULL; while((*tokens)->t != 'S' || strcmp((*tokens)->s,")") != 0) appendNode(&(L->head),read_from_list(tokens)); pop(tokens); // pop off ')' return L; } else return token; }
AST_NODE_LIST* appendNode(AST_NODE_LIST* nodeList, AST_NODE* toAdd) { if(!nodeList) { AST_NODE_LIST* toAddListItem = (AST_NODE_LIST*)malloc(sizeof(AST_NODE_LIST)); toAddListItem->head = toAdd; toAddListItem->tail = 0; return toAddListItem; } if (nodeList->tail) { appendNode(nodeList->tail, toAdd); return nodeList; } else { AST_NODE_LIST* toAddListItem = (AST_NODE_LIST*)malloc(sizeof(AST_NODE_LIST)); toAddListItem->head = toAdd; toAddListItem->tail = 0; nodeList->tail = toAddListItem; return nodeList; } }
void AdjList::buildAdjList() { //Vertices: //**************************************** //Make sure nodePtrs is empty nodePtrs = {}; // - Loop through and build up the linked list of nodes // - Fill the vertex number data element // - Store each node location in nodePtrs for( int i = 0; i <= initForm.size() - 1; ++i) { Node* newPtr = appendNode({initForm[i][0]}); nodePtrs.push_back( newPtr ); //Edges: //**************************************** // - Edge data members will be indices of nodePtrs // - As nodePtrs is updated, edges is updated for( int j = 1; j <= initForm[i].size()-1; ++j) { //Make edge //Must subtract one since input file starts at 1 int l = initForm[i][0] - 1; int r = initForm[i][j] - 1; if( l < r ) { Edge newEdge(initForm[i][0] - 1, initForm[i][j] - 1 ); //Add to edge list edges.push_back( newEdge ); } } } //**************************************** //Clear and reallocate initForm //It has served us well vector<vector<int>> ().swap(initForm); }
int main() { node N1, N2, N3, N4, N5; node* pHead; N1.data = 'A'; pHead = &N1; N2.data = 'B'; N1.pNext = &N2; N3.data = 'C'; N2.pNext = &N3; N4.data = 'D'; N3.pNext = &N4; N4.pNext = NULL; printList(pHead); //deleting at position 3 means deleteNode(3,pHead); printList(pHead); node NA; NA.data='X'; NA.pNext=NULL; appendNode(pHead,&NA); printList(pHead); return 0; }
NODE* newNodes(int arg_num, ...) { va_list args; int i; int value; NODE *node; if (arg_num < 1) { return NULL; } va_start(args, arg_num); value = va_arg(args, int); node = newNode(value, NULL); for (i = 0; i < arg_num - 1; i++) { value = va_arg(args, int); appendNode(value, &node); } return node; }
void PopularUrls::load() { KConfigGroup svr(krConfig, "Private"); QStringList urlList = svr.readEntry("PopularUrls", QStringList()); QList<int> rankList = svr.readEntry("PopularUrlsRank", QList<int>()); if (urlList.count() != rankList.count()) { KMessageBox::error(krMainWindow, i18n("The saved 'Popular URLs' are invalid. The list will be cleared.")); return; } clearList(); count = 0; // iterate through both lists and QStringList::Iterator uit; QList<int>::Iterator rit; for (uit = urlList.begin(), rit = rankList.begin(); uit != urlList.end() && rit != rankList.end(); ++uit, ++rit) { UrlNodeP node = new UrlNode; node->url = QUrl(*uit); node->rank = *rit; appendNode(node); ranks.insert(*uit, node); } }
DeprecatedValueListImplIterator DeprecatedValueListImpl::insert(const DeprecatedValueListImplIterator &iterator, DeprecatedValueListImplNode *node) { copyOnWrite(); DeprecatedValueListImplNode *next = iterator.nodeImpl; if (next == NULL) return appendNode(node); if (next == d->head) return prependNode(node); DeprecatedValueListImplNode *prev = next->prev; node->next = next; node->prev = prev; next->prev = node; prev->next = node; d->count++; return node; }
//求两个排序有序结合交集(增序) struct node *sortIntersection(struct node *first, struct node *second) { struct node *intersect = NULL; while (first != NULL && second != NULL) { if (first->data == second->data) { appendNode(&intersect, first->data); first = first->next; second = second->next; } else if (first->data < second->data) { first = first->next; } else { second = second->next; } } return intersect; }
// // main: runs a simple test to check the hashList functions // void main(int argc, char* argv[]){ //First create log file to log output FILE *log; log = open_log("hashListText.log"); Log(log, " ---- Testing HashList Functions ---- \n"); //Declare a new hashList Log(log, " ---- Test 1: newHashList() ---- \n"); hashList *list = newHashList(); if (list == NULL) Log(log, " Error: creating newHashList\n"); else{ Log(log, " Success: Created newHashList\n"); Log(log, " size of list: %d\n", list->size); } //create chunk hashes for adding to hashList char ch1[HASHSIZE], ch2[HASHSIZE], ch3[HASHSIZE]; char *t1 = "ac2972d828a1c1af10401368a136f5a27b1e592c"; char *t2 = "a727b711e4f2986fbe9e3add54a0ec3bc015ddc9"; char *t3 = "2d448a28ea58e6f884a31c7666b55189a37f40a1"; Log(log, " ---- Test 2: hexCharsToBinary ---- \n"); if (hexCharsToBinary(t1, ch1, sizeof(t1)) == 1) Log(log, " Created chunkHash ch1: %x\n", ch1); else Log(log, " Error: creating chunkHash ch1\n"); if (hexCharsToBinary(t2, ch2, sizeof(t2)) == 1) Log(log, " Created chunkHash ch2: %x\n", ch2); else Log(log, " Error: creating chunkHash ch2\n"); if(hexCharsToBinary(t3, ch3, sizeof(t3)) == 1) Log(log, " Created chunkHash ch3: %x\n", ch3); else Log(log, " Error: creating chunkHash ch3\n"); //Create the hashNodes Log(log, " ---- Test 3: newHashNode ---- \n"); hashNode *node1 = newHashNode(ch1, 0); hashNode *node2 = newHashNode(ch2, 1); hashNode *node3 = newHashNode(ch3, 0); if (node1 != NULL) Log(log, " Created new hashNode 1\n"); if (node2 != NULL) Log(log, " Created new hashNode 2\n"); if (node3 != NULL) Log(log, " Created new hashNode 3\n"); //Add the nodes to the hashList Log(log, " ---- Test 4: appendNode ---- \n"); appendNode(list, node1); if (list->size == 1) Log(log, " Appended node1, size of list: %d\n", list->size); appendNode(list, node2); if(list->size == 2) Log(log, " Appended node2, size of list: %d\n", list->size); //Look for the nodes in the hashList Log(log, " ---- Test 5: findHashNode ---- \n"); if(node1 == findHashNode(list, ch1)) Log(log, " Found hashNode in list: node1\n"); if(node2 == findHashNode(list, ch2)) Log(log, " Found hashNode in list: node2\n"); if(node3 != findHashNode(list, ch2)) Log(log, " Did not find node3 in list. Correctly returned NULL\n"); //remove a node from the hashList Log(log, " ---- Test 6: removeNode ---- \n"); Log(log, " size of list: %d\n", list->size); removeNode(list, node2); Log(log, " Removed hashNode from list: node2\n"); if(node2 != findHashNode(list, ch2)){ Log(log, " size of list: %d\n", list->size); } if(removeNode(list, node2) == FAILURE){ Log(log, " Good. Cannot remove node that doesn't exist in list: node2\n"); Log(log, " size of list: %d\n", list->size); } removeNode(list, node1); Log(log, " Removed hashNode from list: node1\n"); if(node1 != findHashNode(list, ch1)){ Log(log, " size of list: %d\n", list->size); } if(removeNode(list, node3) == FAILURE){ Log(log, " Good. Cannot remove node that doesn't exist in list: node3\n"); Log(log, " size of list: %d\n", list->size); } if(removeNode(list, node1) == FAILURE){ Log(log, " Good. Cannot remove node that doesn't exist in list: node1\n"); Log(log, " size of list: %d\n", list->size); } Log(log, " ---- Test 7: freeNode ---- \n"); if(freeNode(node1) == SUCCESS) Log(log, " Freed: node1\n"); if(freeNode(node2) == SUCCESS) Log(log, " Freed: node2\n"); Log(log, " ---- Test 8: freeList ---- \n"); if(freeList(list) == SUCCESS) Log(log, " Freed Empty List: list\n"); Log(log, " Creating new list with node3.\n"); hashList *list2 = newHashList(); appendNode(list2, node3); appendNode(list2, node3); Log(log, " Size of list: %d\n", list2->size); if(freeList(list2) == FAILURE) Log(log, " FAILED to free list with nodes: list2\n"); else Log(log, " Freed list with nodes: list2\n"); /* The following functions from hashList should ideally also be tested. * However, until we can identify a problem to be within one of these functions * prior to testing, they will be assumed to be working, because thus far, * they are and are not causing any problems. * Log(log, " -- Test 9: findAddrNode -- \n"); Log(log, " -- Test 10: getChunkID -- \n"); Log(log, " -- Test 11: getNextHashFromFile -- \n"); Log(log, " -- Test 12: putTimeout -- \n"); Log(log, " -- Test 13: putAddr -- \n"); */ }
int main(int argc, char* argv[]) { /* Declarations */ List list; List list_1; List list_2; List list_3; List list_4; List list_5; List list_6; Position pos; Position pos_1; Position pos_2; Position pos_3; Position pos_4; Position pos_a, pos_b; int len; int idx; ElementType elem; /* Initialize list */ list=createList(); /* Test functions 'insertNode' and 'appendNode' */ printf("Test functions 'insertNode' and 'appendNode'\n\n"); printf("Before 'insertNode':\n"); printList(list); pos_1=getHeaderNode(list); insertNode(11, list, pos_1); pos_2=advanceNode(pos_1); insertNode(2, list, pos_2); pos_3=advanceNode(pos_2); insertNode(3, list, pos_3); pos_4=advanceNode(pos_3); insertNode(10, list, pos_4); insertNode(9, list, pos_2); printf("After 'insertNode':\n"); printList(list); printf("Before 'appendNode':\n"); printList(list); appendNode(7, list); appendNode(2, list); printf("After 'appendNode'\n"); printList(list); printf("\n"); /* Test functions 'cloneList', 'deleteNode' and 'deleteList' */ printf("Test functions 'cloneList', 'deleteNode' and 'deleteList'\n\n"); list_1=cloneList(list); printf("Before 'deleteNode':\n"); printList(list_1); deleteNode(2, list_1); printf("After 'deleteNode':\n"); printList(list_1); printf("Before 'deleteList':\n"); printList(list_1); deleteList(list_1); printf("After 'deleteList':\n"); printList(list_1); printf("\n"); /* Test function 'getListLength' */ printf("Test function 'getListLength'\n\n"); len=getListLength(list); printf("Length: %d\n", len); printf("\n"); /* Test functions 'findNode', 'findNodePrevious' and 'getNodeIndex' */ printf("Test functions 'findNode', 'findNodePrevious' and 'getNodeIndex'\n\n"); elem=2; pos=findNode(elem, list); if(pos!=NULL) { idx=getNodeIndex(pos, list); printList(list); printf("finding %d, Element at index %d found\n", elem, idx); } else { printf("finding %d, not found\n", elem); } elem=3; pos=findNodePrevious(elem, list); /* Check whether elem is found in list */ if(pos->m_next!=NULL) { idx=getNodeIndex(pos, list); printf("finding previous element of %d, Element at index %d found\n", elem, idx); } else { /* elem is not in list */ printf("finding previous element of %d, not found\n", elem); } printf("\n"); /* Test functions 'makeListEmpty' and 'isListEmpty' */ printf("Test functions 'makeListEmpty' and 'isListEmpty'\n\n"); list_2=cloneList(list); printf("Before 'makeListEmpty':\n"); printList(list_2); list_2=makeListEmpty(list_2); if(isListEmpty(list_2)) { printf("List emptied successfully\n"); printf("After 'makeListEmpty'\n"); printList(list_2); } printf("\n"); /* Test functions 'getHeaderNode', 'getFirstNode', 'getLastNode', 'advanceNode' and 'getNodeElem' */ printf("Test functions 'getHeaderNode', 'getFirstNode', 'getLastNode', 'advanceNode' and 'getNodeElem'\n\n"); printList(list); pos=getHeaderNode(list); printf("Header at index %d\n", getNodeIndex(pos, list)); pos=getFirstNode(list); printf("First element at index %d have value %d\n", getNodeIndex(pos, list), getNodeElem(pos)); pos=getLastNode(list); printf("Last element at index %d have value %d\n", getNodeIndex(pos, list), getNodeElem(pos)); pos=getFirstNode(list); pos=advanceNode(pos); printf("Second element at index %d have value %d\n", getNodeIndex(pos, list), getNodeElem(pos)); printf("\n"); /* Test function 'reverseList' */ printf("Test function 'reverseList'\n\n"); list_3=cloneList(list); printf("Before 'reverseList':\n"); printList(list_3); list_3=reverseList(list_3); printf("After 'reverseList':\n"); printList(list_3); printf("\n"); /* Test function 'swapNode' */ printf("Test function 'swapNode'\n\n"); list_4=cloneList(list); printf("Before 'swapNode':\n"); printList(list_4); pos_a=getHeaderNode(list_4); pos_a=advanceNode(pos_a); pos_a=advanceNode(pos_a); pos_b=advanceNode(pos_a); swapNode(pos_a, pos_b, list_4); printf("After 'swapNode':\n"); printList(list_4); printf("\n"); /* Test function 'bubbleSortList' */ printf("Test function 'bubbleSortList'\n\n"); list_5=cloneList(list); printf("Before 'bubbleSortList':\n"); printList(list_5); bubbleSortList(list_5); printf("After 'bubbleSortList':\n"); printList(list_5); printf("\n"); /* Test function 'connectList' */ printf("Test function 'connectList'\n\n"); printf("List 1:\n"); printList(list); printf("Length: %d\n", getListLength(list)); printf("List 2:\n"); printList(list_5); printf("Length: %d\n", getListLength(list_5)); list_6=connectList(list, list_5); printf("Connected list:\n"); printList(list_6); printf("Length: %d\n", getListLength(list_6)); printf("\n"); /* Cleanup memory */ destroyList(list); destroyList(list_1); destroyList(list_2); destroyList(list_3); destroyList(list_4); destroyList(list_5); destroyList(list_6); return 0; }
void InsertParagraphSeparatorCommand::doApply() { if (!endingSelection().isNonOrphanedCaretOrRange()) return; Position insertionPosition = endingSelection().start(); EAffinity affinity = endingSelection().affinity(); // Delete the current selection. if (endingSelection().isRange()) { calculateStyleBeforeInsertion(insertionPosition); deleteSelection(false, true); insertionPosition = endingSelection().start(); affinity = endingSelection().affinity(); } // FIXME: The parentAnchoredEquivalent conversion needs to be moved into enclosingBlock. RefPtr<Element> startBlock = enclosingBlock(insertionPosition.parentAnchoredEquivalent().containerNode()); Position canonicalPos = VisiblePosition(insertionPosition).deepEquivalent(); if (!startBlock || !startBlock->nonShadowBoundaryParentNode() // FIXME: If the node is hidden, we don't have a canonical position so we will do the wrong thing for tables and <hr>. https://bugs.webkit.org/show_bug.cgi?id=40342 || (!canonicalPos.isNull() && isRenderedTableElement(canonicalPos.deprecatedNode()))) { applyCommandToComposite(InsertLineBreakCommand::create(document())); return; } // Use the leftmost candidate. insertionPosition = insertionPosition.upstream(); if (!insertionPosition.isCandidate()) insertionPosition = insertionPosition.downstream(); // Adjust the insertion position after the delete insertionPosition = positionAvoidingSpecialElementBoundary(insertionPosition); VisiblePosition visiblePos(insertionPosition, affinity); calculateStyleBeforeInsertion(insertionPosition); //--------------------------------------------------------------------- // Handle special case of typing return on an empty list item if (breakOutOfEmptyListItem()) return; //--------------------------------------------------------------------- // Prepare for more general cases. bool isFirstInBlock = isStartOfBlock(visiblePos); bool isLastInBlock = isEndOfBlock(visiblePos); bool nestNewBlock = false; // Create block to be inserted. RefPtr<Element> blockToInsert = nullptr; if (startBlock->isRootEditableElement()) { blockToInsert = createDefaultParagraphElement(document()); nestNewBlock = true; } else if (shouldUseDefaultParagraphElement(startBlock.get())) { blockToInsert = createDefaultParagraphElement(document()); } else { blockToInsert = startBlock->cloneElementWithoutChildren(); } //--------------------------------------------------------------------- // Handle case when position is in the last visible position in its block, // including when the block is empty. if (isLastInBlock) { if (nestNewBlock) { if (isFirstInBlock && !lineBreakExistsAtVisiblePosition(visiblePos)) { // The block is empty. Create an empty block to // represent the paragraph that we're leaving. RefPtr<HTMLElement> extraBlock = createDefaultParagraphElement(document()); appendNode(extraBlock, startBlock); } appendNode(blockToInsert, startBlock); } else { // Most of the time we want to stay at the nesting level of the startBlock (e.g., when nesting within lists). However, // for div nodes, this can result in nested div tags that are hard to break out of. Element* siblingElement = startBlock.get(); insertNodeAfter(blockToInsert, siblingElement); } // Recreate the same structure in the new paragraph. Vector<RefPtr<Element> > ancestors; getAncestorsInsideBlock(positionOutsideTabSpan(insertionPosition).deprecatedNode(), startBlock.get(), ancestors); RefPtr<Element> parent = cloneHierarchyUnderNewBlock(ancestors, blockToInsert); setEndingSelection(VisibleSelection(firstPositionInNode(parent.get()), DOWNSTREAM, endingSelection().isDirectional())); return; } //--------------------------------------------------------------------- // Handle case when position is in the first visible position in its block, and // similar case where previous position is in another, presumeably nested, block. if (isFirstInBlock || !inSameBlock(visiblePos, visiblePos.previous())) { Node* refNode = 0; insertionPosition = positionOutsideTabSpan(insertionPosition); if (isFirstInBlock && !nestNewBlock) { refNode = startBlock.get(); } else if (isFirstInBlock && nestNewBlock) { // startBlock should always have children, otherwise isLastInBlock would be true and it's handled above. ASSERT(startBlock->hasChildren()); refNode = startBlock->firstChild(); } else if (insertionPosition.deprecatedNode() == startBlock && nestNewBlock) { refNode = NodeTraversal::childAt(*startBlock, insertionPosition.deprecatedEditingOffset()); ASSERT(refNode); // must be true or we'd be in the end of block case } else refNode = insertionPosition.deprecatedNode(); // find ending selection position easily before inserting the paragraph insertionPosition = insertionPosition.downstream(); if (refNode) insertNodeBefore(blockToInsert, refNode); // Recreate the same structure in the new paragraph. Vector<RefPtr<Element> > ancestors; getAncestorsInsideBlock(positionAvoidingSpecialElementBoundary(positionOutsideTabSpan(insertionPosition)).deprecatedNode(), startBlock.get(), ancestors); // In this case, we need to set the new ending selection. setEndingSelection(VisibleSelection(insertionPosition, DOWNSTREAM, endingSelection().isDirectional())); return; } //--------------------------------------------------------------------- // Handle the (more complicated) general case, // Move downstream. Typing style code will take care of carrying along the // style of the upstream position. insertionPosition = insertionPosition.downstream(); // At this point, the insertionPosition's node could be a container, and we want to make sure we include // all of the correct nodes when building the ancestor list. So this needs to be the deepest representation of the position // before we walk the DOM tree. insertionPosition = positionOutsideTabSpan(VisiblePosition(insertionPosition).deepEquivalent()); // If the returned position lies either at the end or at the start of an element that is ignored by editing // we should move to its upstream or downstream position. if (editingIgnoresContent(insertionPosition.deprecatedNode())) { if (insertionPosition.atLastEditingPositionForNode()) insertionPosition = insertionPosition.downstream(); else if (insertionPosition.atFirstEditingPositionForNode()) insertionPosition = insertionPosition.upstream(); } // Make sure we do not cause a rendered space to become unrendered. // FIXME: We need the affinity for pos, but pos.downstream() does not give it Position leadingWhitespace = leadingWhitespacePosition(insertionPosition, VP_DEFAULT_AFFINITY); // FIXME: leadingWhitespacePosition is returning the position before preserved newlines for positions // after the preserved newline, causing the newline to be turned into a nbsp. if (leadingWhitespace.isNotNull() && leadingWhitespace.deprecatedNode()->isTextNode()) { Text* textNode = toText(leadingWhitespace.deprecatedNode()); ASSERT(!textNode->renderer() || textNode->renderer()->style()->collapseWhiteSpace()); replaceTextInNodePreservingMarkers(textNode, leadingWhitespace.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); } // Split at pos if in the middle of a text node. Position positionAfterSplit; if (insertionPosition.anchorType() == Position::PositionIsOffsetInAnchor && insertionPosition.containerNode()->isTextNode()) { RefPtr<Text> textNode = toText(insertionPosition.containerNode()); bool atEnd = static_cast<unsigned>(insertionPosition.offsetInContainerNode()) >= textNode->length(); if (insertionPosition.deprecatedEditingOffset() > 0 && !atEnd) { splitTextNode(textNode, insertionPosition.offsetInContainerNode()); positionAfterSplit = firstPositionInNode(textNode.get()); insertionPosition.moveToPosition(textNode->previousSibling(), insertionPosition.offsetInContainerNode()); visiblePos = VisiblePosition(insertionPosition); } } // If we got detached due to mutation events, just bail out. if (!startBlock->parentNode()) return; // Put the added block in the tree. if (nestNewBlock) { appendNode(blockToInsert.get(), startBlock); } else { insertNodeAfter(blockToInsert.get(), startBlock); } document().updateLayoutIgnorePendingStylesheets(); // Move the start node and the siblings of the start node. if (VisiblePosition(insertionPosition) != VisiblePosition(positionBeforeNode(blockToInsert.get()))) { Node* n; if (insertionPosition.containerNode() == startBlock) n = insertionPosition.computeNodeAfterPosition(); else { Node* splitTo = insertionPosition.containerNode(); if (splitTo->isTextNode() && insertionPosition.offsetInContainerNode() >= caretMaxOffset(splitTo)) splitTo = NodeTraversal::next(*splitTo, startBlock.get()); ASSERT(splitTo); splitTreeToNode(splitTo, startBlock.get()); for (n = startBlock->firstChild(); n; n = n->nextSibling()) { VisiblePosition beforeNodePosition(positionBeforeNode(n)); if (!beforeNodePosition.isNull() && comparePositions(VisiblePosition(insertionPosition), beforeNodePosition) <= 0) break; } } moveRemainingSiblingsToNewParent(n, blockToInsert.get(), blockToInsert); } // Handle whitespace that occurs after the split if (positionAfterSplit.isNotNull()) { document().updateLayoutIgnorePendingStylesheets(); if (!positionAfterSplit.isRenderedCharacter()) { // Clear out all whitespace and insert one non-breaking space ASSERT(!positionAfterSplit.containerNode()->renderer() || positionAfterSplit.containerNode()->renderer()->style()->collapseWhiteSpace()); deleteInsignificantTextDownstream(positionAfterSplit); if (positionAfterSplit.deprecatedNode()->isTextNode()) insertTextIntoNode(toText(positionAfterSplit.containerNode()), 0, nonBreakingSpaceString()); } } setEndingSelection(VisibleSelection(firstPositionInNode(blockToInsert.get()), DOWNSTREAM, endingSelection().isDirectional())); }