void CPacketQueue::Add(CAutoPtr<Packet> p) { CAutoLock cAutoLock(this); if(p) { m_size += p->GetDataSize(); if(p->bAppendable && !p->bDiscontinuity && !p->pmt && p->rtStart == Packet::INVALID_TIME && !IsEmpty() && GetTail()->rtStart != Packet::INVALID_TIME) { Packet* tail = GetTail(); int oldsize = tail->GetCount(); int newsize = tail->GetCount() + p->GetCount(); tail->SetCount(newsize, max(1024, newsize)); // doubles the reserved buffer size memcpy(tail->GetData() + oldsize, p->GetData(), p->GetCount()); /* GetTail()->Append(*p); // too slow */ return; } } AddTail(p); }
void test_GetTail(void) { GENERALIZED_LIST_TYPE list = NULL; CU_ASSERT_EQUAL(GetTail(list), NULL); list = getGeneralizedList("(1,2)"); assertEqual(GetTail(list), "(2)"); list = getGeneralizedList( "((11,12,13),(21,22,23,24,25),3,(4,(51,52,53,(501,502))))"); assertEqual(GetTail(list), "(4,(51,52,53,(501,502)))"); }
void MarkedStack::DeleteAll() { ListItem* TopOfStack; TopOfStack = GetTail(); while (TopOfStack != NULL) // loop while the stack is not empty { Release(); // Deletes mark and all items before the mark TopOfStack = GetTail(); } // Make sure there are no marks left ENSURE(MarkStack.Pop() == NULL, "All marks have not been deleted from the MarkedStack"); }
void *GDList::rem_del(position rel,int mode) { NIDNode *node = 0; switch(rel) { case GDBase::liststart: node=GetHead(); break; case GDBase::listend: node=GetTail(); break; case GDBase::current: node=GetCurr(); break; case GDBase::before: if((node=GetCurr()) != 0) node = node->GetPrev(); break; case GDBase::after: if((node=GetCurr()) != 0) node = node->GetNext(); break; } if(node) { void *obj = node->object; remove(node); if(mode && cleanup() == ListBase::active) zap_object(obj); return obj; } return 0; }
///////////////////////////////////////////////////////////////////////////// // Note: The undo list must be maintained as a string of undos // You cannot, for example, log an undo event and then decide to // to skip a few. To skip, the entire log must be deleted. // The invoking routines typically accept a NULL undo description // to indicate continuation; to stop undo, destroy the chain and // call with a NULL, thus not creating an undo event. ///////////////////////////////////////////////////////////////////////////// POSITION CUndLst::CreUndEvt (CString csDesStr, CUndSta *pNewSta) { ///////////////////////////////////////////////////////////////////////// // Delete tail of undo chain ///////////////////////////////////////////////////////////////////////// while (!IsEmpty() && (m_vpUndPos != m_olUndLst.GetTailPosition())) RemoveTail(); ///////////////////////////////////////////////////////////////////////// // Return NULL if undo has been inhibited ///////////////////////////////////////////////////////////////////////// if (!m_usUndMax) return (NULL); ///////////////////////////////////////////////////////////////////////// // Delete head to enforce maximum undo count; leave room for next ///////////////////////////////////////////////////////////////////////// while ((WORD) m_olUndLst.GetCount() >= m_usUndMax) RemoveHead(); ///////////////////////////////////////////////////////////////////////// // Find previous files 3 digit extension and increment ///////////////////////////////////////////////////////////////////////// WORD usNxtExt = IsEmpty() ? 0 : GetTail()->GetSeqNum() + 1; ///////////////////////////////////////////////////////////////////////// // Add new undo file ///////////////////////////////////////////////////////////////////////// m_vpUndPos = m_olUndLst.AddTail (new CUndEvt (usNxtExt, m_csTmpPfx, csDesStr, pNewSta)); return (m_vpUndPos); }
int CParseString::Parse2(CString& item1, CString& item2, CString separ) { Init(separ); GetNextWord(item1); GetTail(item2); return (!item1.IsEmpty()) + (!item2.IsEmpty()); }
void OverrideList::AddTail( OverrideListItem* poliToAdd) { if (poliToAdd==NULL) { ERROR2RAW("OverrideList::AddTail - NULL parameter"); return; } //Get the last item in the list OverrideListItem* pliLast=(OverrideListItem*) GetTail(); //Was there anything in the list? if (pliLast!=NULL) { //Yes. So call our InsertAfter function InsertAfter(pliLast, poliToAdd); } else { //No. So we need do no special checking - simply insert //the list item List::AddTail(poliToAdd); } //And add our item after it InsertAfter(pliLast, poliToAdd); }
void MarkedStack::Release(void) { // Find the mark to stop at ListItemPtrItem* MarkRec = (ListItemPtrItem*)MarkStack.Pop(); ListItem* Mark; if (MarkRec == NULL) // There are no marks to find { Mark = NULL; } else { Mark = MarkRec->pListItem; } ListItem* TopOfStack = GetTail(); ListItem* AsGoodAsDead; while (TopOfStack != Mark) // Loop until we find Mark { ENSURE(TopOfStack != NULL, "A Mark could not be found in the Marked stack"); TopOfStack = GetPrev(TopOfStack); AsGoodAsDead = RemoveTail(); delete AsGoodAsDead; } if (MarkRec != NULL) { delete (MarkRec); // Restored State to that pointed to by Mark, so delete it } }
/*判断链表是否为空表*/ int IsEmpty(DList *plist) { if(GetSize(plist)==0&&GetTail(plist)==GetHead(plist)) return 1; else return 0; }
HRESULT CLR_RT_HeapBlock_Queue::CopyTo( CLR_RT_HeapBlock_Array* toArray, CLR_INT32 index ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_HeapBlock_Array* array = GetArray(); CLR_INT32 size = GetSize(); CLR_INT32 head = Head(); CLR_INT32 tail = GetTail(); // if the target array is of type Object, we don't need to call the complex Array::Copy() since there will be no casting involved HRESULT (*arrayCopy)( CLR_RT_HeapBlock_Array*, int, CLR_RT_HeapBlock_Array*, int, int ) = (toArray->m_typeOfElement == DATATYPE_OBJECT) ? ObjArrayMemcpy : CLR_RT_HeapBlock_Array::Copy; if(((CLR_INT32)toArray->m_numOfElements) - index < size) TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); if(size > 0) { if(head < tail) { TINYCLR_SET_AND_LEAVE(arrayCopy( array, head, toArray, index, size )); } else { CLR_INT32 firstPart = array->m_numOfElements - head; TINYCLR_CHECK_HRESULT(arrayCopy( array, head, toArray, index , firstPart )); TINYCLR_SET_AND_LEAVE(arrayCopy( array, 0 , toArray, index + firstPart, tail )); } } TINYCLR_NOCLEANUP(); }
HRESULT CLR_RT_HeapBlock_Queue::Clear() { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_HeapBlock_Array* array = GetArray(); CLR_INT32 size = GetSize(); CLR_INT32 head = Head(); CLR_INT32 tail = GetTail(); if(size > 0) { if(head < tail) { TINYCLR_CHECK_HRESULT(array->ClearElements( head, size )); } else { TINYCLR_CHECK_HRESULT(array->ClearElements( head, array->m_numOfElements - head )); TINYCLR_CHECK_HRESULT(array->ClearElements( 0 , tail )); } SetSize( 0 ); } SetHead( 0 ); SetTail( 0 ); TINYCLR_NOCLEANUP(); }
void SLList::Insert(int contents) { if(head_ == NULL) { InsertHead(contents); } else if(contents < GetHead()) { InsertHead(contents); } else if (head_->next_node() == NULL && head_ != NULL) { InsertTail(contents); } else if(contents > GetTail()) { InsertTail(contents); } else { SLNode* node = new SLNode(contents); SLNode* i = head_; SLNode* j = NULL; while(i->contents() <= contents && i->next_node() != NULL) { j = i; i = i->next_node(); } j->set_next_node(node); node->set_next_node(i); size_++; } }
int eFBCTunerManager::IsCompatibleWith(ePtr<iDVBFrontendParameters> &feparm, eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *&fbc_fe, bool simulate) const { eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend; eDVBRegisteredFrontend *fe_insert_point; int best_score, new_score; best_score = 0; for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(frontends.begin()); it != frontends.end(); ++it) { if (!it->m_frontend->is_FBCTuner()) continue; if (!IsRootFE(*it)) continue; if(!it->m_frontend->getEnabled()) continue; if(!IsSameFBCSet(FESlotID(link_fe), FESlotID(it))) continue; if(it->m_inuse == 0) continue; if(IsLinked(*it)) continue; if(IsSCR(*it)) continue; // temporarily add this leaf to the current "linked" chain, at the tail fe_insert_point = GetTail(*it); ConnectLink(link_fe, /*prev_fe*/fe_insert_point, /*next_fe*/(eDVBRegisteredFrontend *)0, simulate); link_fe->m_frontend->setEnabled(true); UpdateLNBSlotMask(FESlotID(link_fe), FESlotID(*it), false); // get score when leaf is added new_score = link_fe->m_frontend->isCompatibleWith(feparm); if (new_score > best_score) { best_score = new_score; fbc_fe = *it; } // now remove the leaf tuner again DisconnectLink(link_fe, /*prev_fe*/fe_insert_point, /*next_fe*/(eDVBRegisteredFrontend *)0, simulate); link_fe->m_frontend->setEnabled(false); UpdateLNBSlotMask(FESlotID(link_fe), FESlotID(*it), true); } return best_score; }
void *GIDList::remove(position rel) { IDNode *node = 0; switch(rel) { case GDBase::liststart: node=GetHead(); break; case GDBase::listend: node=GetTail(); break; case GDBase::current: node=GetCurr(); break; } if(node) unlink(node); return cast(node); }
/*将一个链表置为空表,释放原链表节点空间*/ void ClearList(DList *plist) { PNode temp,p; p = GetTail(plist); while(!IsEmpty(plist)) { temp = GetPrevious(p); FreeNode(p); p = temp; plist->tail = temp; plist->size--; } }
BOOL MarkedStack::Mark(void) { // Firstly create a mark ListItemPtrItem* pMark = new ListItemPtrItem(); // Return with an error if we could not create the mark if (pMark == NULL) return FALSE; pMark->pListItem = GetTail(); // This will be NULL if the list is empty // Push the mark onto the MarkStack MarkStack.Push(pMark); return TRUE; // Success }
bool SLList::RemoveFirstOccurence(int contents) { SLNode* node = new SLNode(contents); if (contents == GetHead()) { RemoveHead(); return true; } else if(contents == GetTail()) { RemoveTail(); return true; } else if(head_ == NULL) { return false; } else if (node == NULL) { return false; } else if (contents != GetHead() && contents != GetTail()) { SLNode* i = head_; SLNode* j = NULL; while (i->contents() != contents && i->next_node() != NULL) { j = i; i = i->next_node(); } if(i->next_node() == NULL && i->contents() != contents) { return false; } else { SLNode* temp = i->next_node(); SLNode* temp2 = i; delete temp2; j->set_next_node(temp); size_--; return true; } } else return false; }
/*删除链表中的尾节点并返回地址,改变链表的尾指针指向新的尾节点*/ PNode Remove(DList *plist) { Position p=NULL; if(IsEmpty(plist)) return NULL; else { p = GetTail(plist); p->previous->next = p->next; plist->tail = p->previous; plist->size--; return p; } }
/*将链表第一个节点删除,返回该节点的地址*/ PNode DelFirst(DList *plist) { Position head = GetHead(plist); Position p=head->next; if(p!=NULL) { if(p==GetTail(plist)) plist->tail = p->previous; head->next = p->next; head->next->previous = head; plist->size--; } return p; }
/*在链表中p位置之后插入新节点s*/ PNode InsAfter(DList *plist,Position p,PNode s) { s->next = p->next; s->previous = p; if(p->next != NULL) p->next->previous = s; p->next = s; if(p = GetTail(plist)) plist->tail = s; plist->size++; return s; }
int GIDList::del(position rel) { IDNode *node = 0; switch(rel) { case GDBase::liststart: node=GetHead(); break; case GDBase::listend: node=GetTail(); break; case GDBase::current: node=GetCurr(); break; } if(node) { unlink(node); if(cleanup() == ListBase::active) delete node; return 1; } return 0; }
// May Trigger GC, but parameter value will be protected HRESULT CLR_RT_HeapBlock_Queue::Enqueue( CLR_RT_HeapBlock* value ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_HeapBlock_Array* array = GetArray(); CLR_INT32 size = GetSize(); CLR_INT32 tail = GetTail(); CLR_INT32 capacity = array->m_numOfElements; if(size == capacity) { // Set new capacity CLR_RT_HeapBlock newArrayHB; // Protect value from GC, in case CreateInstance triggers one CLR_RT_HeapBlock valueHB; valueHB.SetObjectReference( value ); CLR_RT_ProtectFromGC gc( valueHB ); capacity *= 2; TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( newArrayHB, capacity, g_CLR_RT_WellKnownTypes.m_Object )); array = newArrayHB.DereferenceArray(); CopyTo( array, 0 ); tail = size; SetArray( array ); SetHead ( 0 ); SetTail ( tail ); } ((CLR_RT_HeapBlock*)array->GetElement( tail ))->SetObjectReference( value ); SetTail( (tail + 1) % capacity ); SetSize( size + 1 ); TINYCLR_NOCLEANUP(); }
void main() { char p[80]; GList l,m; HString t; /* 与main5-51.c不同 */ InitString(&t); /* 增加此句 */ InitGList(&l); InitGList(&m); printf("空广义表l的深度=%d l是否空?%d(1:是 0:否)\n",GListDepth(l),GListEmpty(l)); printf("请输入广义表l(书写形式:空表:(),单原子:a,其它:(a,(b),b)):\n"); gets(p); StrAssign(&t,p); CreateGList(&l,t); printf("广义表l的长度=%d\n",GListLength(l)); printf("广义表l的深度=%d l是否空?%d(1:是 0:否)\n",GListDepth(l),GListEmpty(l)); printf("遍历广义表l:\n"); Traverse_GL(l,visit); printf("\n复制广义表m=l\n"); CopyGList(&m,l); printf("广义表m的长度=%d\n",GListLength(m)); printf("广义表m的深度=%d\n",GListDepth(m)); printf("遍历广义表m:\n"); Traverse_GL(m,visit); DestroyGList(&m); m=GetHead(l); printf("\nm是l的表头,遍历广义表m:\n"); Traverse_GL(m,visit); DestroyGList(&m); m=GetTail(l); printf("\nm是l的表尾,遍历广义表m:\n"); Traverse_GL(m,visit); InsertFirst_GL(&m,l); printf("\n插入l为m的表头,遍历广义表m:\n"); Traverse_GL(m,visit); printf("\n删除m的表头,遍历广义表m:\n"); DestroyGList(&l); DeleteFirst_GL(&m,&l); Traverse_GL(m,visit); printf("\n"); DestroyGList(&m); }
void main() { char p[80]; SString t; GList l,m; InitGList(&l); InitGList(&m); printf("空广义表l的深度=%d l是否空?%d(1:是 0:否)\n",GListDepth(l),GListEmpty(l)); printf("请输入广义表l(书写形式:空表:(),单原子:(a),其它:(a,(b),c)):\n"); gets(p); StrAssign(t,p); CreateGList(&l,t); printf("广义表l的长度=%d\n",GListLength(l)); printf("广义表l的深度=%d l是否空?%d(1:是 0:否)\n",GListDepth(l),GListEmpty(l)); printf("遍历广义表l:\n"); Traverse_GL(l,visit); printf("\n复制广义表m=l\n"); CopyGList(&m,l); printf("广义表m的长度=%d\n",GListLength(m)); printf("广义表m的深度=%d\n",GListDepth(m)); printf("遍历广义表m:\n"); Traverse_GL(m,visit); DestroyGList(&m); m=GetHead(l); printf("\nm是l的表头元素,遍历m:\n"); Traverse_GL(m,visit); DestroyGList(&m); m=GetTail(l); printf("\nm是由l的表尾形成的广义表,遍历广义表m:\n"); Traverse_GL(m,visit); InsertFirst_GL(&m,l); printf("\n插入广义表l为m的表头,遍历广义表m:\n"); Traverse_GL(m,visit); printf("\n删除m的表头,遍历广义表m:\n"); DestroyGList(&l); DeleteFirst_GL(&m,&l); Traverse_GL(m,visit); printf("\n"); DestroyGList(&m); }
void AddRelocInfo(short srcHunk, short dstHunk, long size, short flags, long offset, Symbol *sym) { RelocInfo *ri = malloc(sizeof(RelocInfo)); RelocInfo *r; if (ri == NULL) cerror(EFATAL, "malloc Failed"); clrmem(ri, sizeof(RelocInfo)); ri->ri_Sym = sym; ri->ri_SrcHunk = srcHunk; ri->ri_DstHunk = dstHunk; ri->ri_RelocSize = size; ri->ri_RelocFlags= flags; ri->ri_SrcOffset = offset; for (r = GetTail(&RelList); r; r = GetPred((Node *)&r->ri_Node)) { if (r->ri_SrcOffset < ri->ri_SrcOffset) break; } Insert(&RelList, (Node *)&ri->ri_Node, (Node *)&r->ri_Node); }
void SubtitleFile::SegmentList::Insert(float start, float stop, Definition* pDef) { if(start >= stop) {ASSERT(0); return;} m_index.RemoveAll(); SegmentItem si = {pDef, start, stop}; if(IsEmpty()) { AddTail(Segment(start, stop, &si)); return; } Segment& head = GetHead(); Segment& tail = GetTail(); if(start >= tail.m_stop && stop > tail.m_stop) { if(start > tail.m_stop) AddTail(Segment(tail.m_stop, start)); AddTail(Segment(start, stop, &si)); } else if(start < head.m_start && stop <= head.m_start) { if(stop < head.m_start) AddHead(Segment(stop, head.m_start)); AddHead(Segment(start, stop, &si)); } else { if(start < head.m_start) { AddHead(Segment(start, head.m_start, &si)); start = head.m_start; } if(stop > tail.m_stop) { AddTail(Segment(tail.m_stop, stop, &si)); stop = tail.m_stop; } for(POSITION pos = GetHeadPosition(); pos; GetNext(pos)) { Segment& s = GetAt(pos); if(start >= s.m_stop) continue; if(stop <= s.m_start) break; if(s.m_start < start && start < s.m_stop) { Segment s2 = s; s2.m_start = start; InsertAfter(pos, s2); s.m_stop = start; } else if(s.m_start == start) { if(stop > s.m_stop) { start = s.m_stop; } else if(stop < s.m_stop) { Segment s2 = s; s2.m_start = stop; InsertAfter(pos, s2); s.m_stop = stop; } s.AddTail(si); } } } }
BOOL ReadStruct ( /* SYNOPSIS */ struct Hook * hook, APTR * dataptr, void * stream, const IPTR * sd) /* FUNCTION Reads one big endian structure from a streamhook. INPUTS hook - Streamhook dataptr - Put the data here stream - Read from this stream sd - Description of the structure to be read. The first element is the size of the structure. RESULT The function returns TRUE on success. On success, the value read is written into dataptr. On failure, FALSE is returned and the contents of dataptr are not changed. NOTES This function reads big endian values from a streamhook even on little endian machines. EXAMPLE See below. BUGS SEE ALSO ReadByte(), ReadWord(), ReadLong(), ReadFloat(), ReadDouble(), ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(), WriteFloat(), WriteDouble(), WriteString(), WriteStruct() HISTORY ******************************************************************************/ { struct MinList _list; struct ReadLevel * curr; # define list ((struct List *)&_list) NEWLIST(list); if (!(curr = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) ) return FALSE; AddTail (list, (struct Node *)curr); curr->sd = sd; curr->pos = 0; curr->s = NULL; # define DESC curr->sd[curr->pos] # define IDESC curr->sd[curr->pos ++] for (;;) { if (!curr->pos) { if (!(curr->s = AllocMem (IDESC, MEMF_CLEAR)) ) goto error; } if (DESC == SDT_END) break; switch (IDESC) { case SDT_UBYTE: /* Read one 8bit byte */ if (!ReadByte (hook, (UBYTE *)(curr->s + IDESC), stream)) goto error; break; case SDT_UWORD: /* Read one 16bit word */ if (!ReadWord (hook, (UWORD *)(curr->s + IDESC), stream)) goto error; break; case SDT_ULONG: /* Read one 32bit long */ if (!ReadLong (hook, (ULONG *)(curr->s + IDESC), stream)) goto error; break; case SDT_FLOAT: /* Read one 32bit IEEE */ if (!ReadFloat (hook, (FLOAT *)(curr->s + IDESC), stream)) goto error; break; case SDT_DOUBLE: /* Read one 64bit IEEE */ if (!ReadDouble (hook, (DOUBLE *)(curr->s + IDESC), stream)) goto error; break; case SDT_STRING: { /* Read a string */ UBYTE valid_ptr; STRPTR * sptr; sptr = (STRPTR *)(curr->s + IDESC); if (!ReadByte (hook, &valid_ptr, stream)) goto error; if (valid_ptr) { if (!ReadString (hook, sptr, stream)) goto error; } else { *sptr = NULL; } break; } case SDT_STRUCT: { /* Read a structure */ struct ReadLevel * next; IPTR * desc; APTR aptr; aptr = (APTR)(curr->s + IDESC); desc = (IPTR *)IDESC; curr->pos -= 3; /* Go back to type */ if (!(next = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) ) goto error; AddTail (list, (struct Node *)next); next->sd = desc; next->pos = 1; next->s = aptr; curr = next; break; } case SDT_PTR: { /* Follow a pointer */ struct ReadLevel * next; UBYTE valid_ptr; IPTR * desc; APTR * aptr; aptr = ((APTR *)(curr->s + IDESC)); desc = (IPTR *)IDESC; if (!ReadByte (hook, &valid_ptr, stream)) goto error; if (valid_ptr) { curr->pos -= 3; if (!(next = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) ) goto error; AddTail (list, (struct Node *)next); next->sd = desc; next->pos = 0; curr = next; } else { *aptr = NULL; } break; } case SDT_IGNORE: { /* Ignore x bytes */ struct BEIOM_Ignore ig = {BEIO_IGNORE, IDESC}; if (CallHookA (hook, stream, &ig) == EOF) goto error; break; } case SDT_FILL_BYTE: { /* Fill x bytes */ IPTR offset; UBYTE value; IPTR count; offset = IDESC; value = IDESC; count = IDESC; memset (curr->s + offset, value, count); break; } case SDT_FILL_LONG: { /* Fill x longs */ ULONG * ulptr; ULONG value; IPTR count; ulptr = (ULONG *)(curr->s + IDESC); value = IDESC; count = IDESC; while (count --) *ulptr ++ = value; break; } case SDT_IFILL_BYTE: { /* Fill x bytes */ IPTR offset; UBYTE value; IPTR count; offset = IDESC; value = IDESC; count = IDESC; struct BEIOM_Ignore ig = {BEIO_IGNORE, count}; if (CallHookA (hook, stream, &ig) == EOF) goto error; memset (curr->s + offset, value, count); break; } case SDT_IFILL_LONG: { /* Fill x longs */ ULONG * ulptr; ULONG value; IPTR count; ulptr = (ULONG *)(curr->s + IDESC); value = IDESC; count = IDESC; struct BEIOM_Ignore ig = {BEIO_IGNORE, count << 2}; if (CallHookA (hook, stream, &ig) == EOF) goto error; while (count --) *ulptr ++ = value; break; } case SDT_SPECIAL: { /* Call user hook */ struct Hook * uhook; struct SDData data; data.sdd_Dest = ((APTR)(curr->s + IDESC)); data.sdd_Mode = SDV_SPECIALMODE_READ; data.sdd_Stream = stream; uhook = (struct Hook *)IDESC; if (!CallHookA (uhook, hook, &data)) goto error; break; } default: goto error; } /* switch */ /* End of the description list ? */ if (DESC == SDT_END) { struct ReadLevel * last; /* Remove the current level */ last = curr; Remove ((struct Node *)last); /* Get the last level */ if ((curr = (struct ReadLevel *)GetTail (list))) { switch (IDESC) { case SDT_STRUCT: curr->pos += 2; /* Skip 2 parameters */ break; case SDT_PTR: { APTR * aptr; aptr = ((APTR *)(curr->s + IDESC)); curr->pos ++; /* Skip description parameter */ /* Now put the result of the current level in the struct of the previous level. */ *aptr = last->s; break; } } FreeMem (last, sizeof (struct ReadLevel)); } else { curr = last; } } } /* while */ *dataptr = curr->s; FreeMem (curr, sizeof (struct ReadLevel)); return TRUE; error: curr = (struct ReadLevel *)GetHead (list); if (curr && curr->s) FreeStruct (curr->s, curr->sd); while ((curr = (struct ReadLevel *)RemTail (list))) FreeMem (curr, sizeof (struct ReadLevel)); return FALSE; } /* ReadStruct */
int Tab(Node *resultHead, const char *info,\ const char *path, int ti,\ char *cmd) { int mode = 0; int i = 0; int len = 0; int times = 2; int flag = -1; int pos = -1; char tmp[BUFFSIZE] = {0}; struct stat buf = {0}; char child[BUFFSIZE] = {0}; const char *s = NULL; assert(NULL != resultHead); assert(NULL != path); strcpy(tmp, path); if('\0' == *tmp) { strcpy(tmp, "."); } //The path is exist or not exist? while((times--)\ && (-1 == (flag = lstat(tmp, &buf)))) { if(ENOENT != errno) { return -1; } if(times > 0) { s = GetTail(tmp, '/'); //If string tmp is not equal to it's //tail string s(is a part of string tmp //which contain the last '/' int tmp), //delete the tail(string s) of string //tmp (maybe the new string tmp[the old //string tmp delete tail s] is exist). //But if string tmp is equal to string s //means the string tmp(as same as string // path) doesn't contain a '/'(break). if(strcmp(tmp, s)) { tmp[strlen(tmp) - strlen(s)] = '\0'; } else { break; } } } //Get string child from the tail of //string path. strcpy(child, GetTail(path, '/')); //If 'times = 1', means the path isn't //contain '/' or the path is exist. /////And in this section string path is //equal to string tmp. //Else if 'times = -1', means the string //tmp is a part of string path. Maybe tmp //is exist or not exist. if(1 == times) { //If 'flag = -1', maybe the path is //a part of file name in current //directory. //Else if 'flag = 0', means the path //is exist. if(-1 == flag) { strcpy(tmp, "."); } else { if(! S_ISDIR(buf.st_mode)) { write(STDOUT_FILENO, " ", 1); strcat(cmd, " "); } else { if( ('\0' != path[0]) && ('/' != path[strlen(path) - 1]) && (('.' != path[strlen(path) - 1]) || ('.') == path[strlen(path) - 2])) { write(STDOUT_FILENO, "/", 1); strcat(cmd, "/"); } } s = GetTail(tmp, '/'); if( strcmp(path, ".") && ( ('.' != path[strlen(path) - 1]) || ('.') == path[strlen(path) - 2])) { //Because path is exist so click button //'Tab' means to get other file name of //the specified directory(name of 'path' //is also included in this directory). strcpy(child, "\0"); } //If path is not a directory. //If string path isn't equal to string //s(is tail of string path), means the //s(file) is exist in 'path-s'. //Else string path is a file exist in //current directory. if(! S_ISDIR(buf.st_mode)) { if(0 != strcmp(tmp, s)) { tmp[strlen(path) - strlen(s)] = '\0'; } else { strcpy(tmp, "."); } } } } else { //If 'flag = -1', the path and tmp //is not exist. //Else the tmp(delete the tail of path) //is exist. if(-1 == flag) { return -1; } } if( -1 == (flag = FindFileName(resultHead, tmp, child)) ) { return -1; } if((len = GetLen(resultHead)) > 0) { if(len > 1) { if(ti > 0) { if(-1 == ShowResult(resultHead, NULL,\ 1, cmd)) { return -1; } write(STDOUT_FILENO, info, strlen(info)); write(STDOUT_FILENO, cmd, strlen(cmd)); } } else { strcpy(tmp, GetVal(resultHead, 1)); flag = ( flag ? 0 : ('/' != tmp[strlen(tmp) - 1]) ); if( -1 == ShowResult(resultHead, child, flag, cmd) ) { return -1; } } } return 0; }