본문 바로가기

Job Notes/Embedded System & RTOS

linked list 사용 예

#include "linux/list.h"

typedef struct {
 struct list_head ListHead;
 fs_enum_data_type data_info;
 U16 ino;
 U16 index;
} DirInfo_List;

struct list_head g_DirListHead;
DirInfo_List *gp_CurrentDirList;


S32 DirListInsert(DirInfo_List *dir_list )
{
 struct list_head *tmp;
 int i = 0;
 if (!dir_list->index)
 {
  list_add_tail(&dir_list->ListHead, &g_DirListHead);
  return 0;
 }
 else
 {
  list_for_each(tmp, &g_DirListHead) {
   DirInfo_List *n = (DirInfo_List *)tmp;
   if (dir_list->ino < n->ino)
   {
    dir_list->index = i;
    n->index = i+1;
    list_add_tail(&dir_list->ListHead, tmp);
    return 0;
   }
   i++;
  }
 }

 dir_list->index = i;
 list_add_tail(&dir_list->ListHead, &g_DirListHead);
 return 0;
}

DirInfo_List *DirListFind(U16 nIndex)
{
 struct list_head *tmp;
 list_for_each(tmp, &g_DirListHead) {
  DirInfo_List *n = (DirInfo_List *)tmp;
  if (nIndex == n->index)
   return n;
 }
 return NULL;
}

S32 DirListDestroy(struct list_head * head)
{
 struct list_head * n = head->next, *next;

 if (!head || !n)
  return 0;
 
 while(n !=head) {
  next = n->next;
  list_del(n);
  free((DirInfo_List *)n);
  n = next;
 }
 
 return 0;
}

S32 DirListBuild(
const char *dirname,   /* root directory name */
fs_enum_type                enum_kind        /* file or directory list */
)

{
 DirInfo_List *pDirList;

   pDirList = malloc(sizeof(DirInfo_List));

...

   DirListInsert(pDirList);

...

 if (ret >= 0)
 {
  gp_CurrentDirList = (DirInfo_List *)(g_DirListHead.next);
  gp_CurrentDirList = DirListFind(0);
  ret = EO_FILE_SUCCESS;
 }
 return ret;

}

fs_enum_move
(
fs_enum_data_type           *data_ptr,        /* file or dir info */
fs_enum_iterator_type       *iterator_ptr,    /* ptr to control struct */
S32 direction
)

{
 U32                  last_good_sequence;
 DirInfo_List *dir_list;

 /* Remember the current sequence position and back up to it if we run off
 * the end. */
 last_good_sequence = iterator_ptr->fsequence;
 

 if (direction < 0)
 {
  if (iterator_ptr->fsequence == 0)
  {
   /* Restore the sequence number. */
   iterator_ptr->fsequence = last_good_sequence;

   
   return ENUMDONE;
  }
 }
 iterator_ptr->fsequence += direction;

 if (gp_CurrentDirList != NULL)
 {
  dir_list = gp_CurrentDirList;//DirListFind (iterator_ptr->fsequence-1);
  if (&g_DirListHead == gp_CurrentDirList->ListHead.next)
   gp_CurrentDirList = NULL;
  else
   gp_CurrentDirList = (DirInfo_List *)(gp_CurrentDirList->ListHead.next);
 }
 else //if (dir_list == NULL)
 {
  /* We "fell" off the end, so backup the iterator. */
  iterator_ptr->fsequence = last_good_sequence;
  return ENUMDONE;
 }

 memcpy(data_ptr, &dir_list->data_info, sizeof(fs_enum_data_type));

}