LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 07-01-2009, 09:06 PM   #1
Kunsheng
Member
 
Registered: Mar 2009
Posts: 82

Rep: Reputation: 16
Use linux kernel function 'list_for_each_entry()' in Visual C++


Hello everyone,

I am trying to use Linux's implementation of 'list' in Visual C++ 2005.

The following is the 'list.h' code ( I replace 'typeof' with 'typeid' ) :

Code:
#ifndef __LIST_H
#define __LIST_H

/* This file is from Linux Kernel (include/linux/list.h) 
 * and modified by simply removing hardware prefetching of list items. 
 * Here by copyright, credits attributed to wherever they belong.
 * Kulesh Shanmugasundaram (kulesh [squiggly] isis.poly.edu)
 */

/*
 * Simple doubly linked list implementation.
 *
 * Some of the internal functions ("__xxx") are useful when
 * manipulating whole lists rather than single entries, as
 * sometimes we already know the next/prev entries and we can
 * generate better code by using them directly rather than
 * using the generic single-entry routines.
 */

struct list_head {
	struct list_head *next, *prev;
};

#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
	struct list_head name = LIST_HEAD_INIT(name)

#define INIT_LIST_HEAD(ptr) do { \
	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)

/*
 * Insert a new entry between two known consecutive entries. 
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_add(struct list_head *new_element,
			      struct list_head *prev,
			      struct list_head *next)
{
	next->prev = new_element;
	new_element->next = next;
	new_element->prev = prev;
	prev->next = new_element;
}

/**
 * list_add - add a new entry
 * @new: new entry to be added
 * @head: list head to add it after
 *
 * Insert a new entry after the specified head.
 * This is good for implementing stacks.
 */
static inline void list_add(struct list_head *new_element, struct list_head *head)
{
	__list_add(new_element, head, head->next);
}

/**
 * list_add_tail - add a new entry
 * @new: new entry to be added
 * @head: list head to add it before
 *
 * Insert a new entry before the specified head.
 * This is useful for implementing queues.
 */
static inline void list_add_tail(struct list_head *new_element, struct list_head *head)
{
	__list_add(new_element, head->prev, head);
}

/*
 * Delete a list entry by making the prev/next entries
 * point to each other.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
	next->prev = prev;
	prev->next = next;
}

/**
 * list_del - deletes entry from list.
 * @entry: the element to delete from the list.
 * Note: list_empty on entry does not return true after this, the entry is in an undefined state.
 */
static inline void list_del(struct list_head *entry)
{
	__list_del(entry->prev, entry->next);
	entry->next = (list_head *) 0;
	entry->prev = (list_head *) 0;
}

/**
 * list_del_init - deletes entry from list and reinitialize it.
 * @entry: the element to delete from the list.
 */
static inline void list_del_init(struct list_head *entry)
{
	__list_del(entry->prev, entry->next);
	INIT_LIST_HEAD(entry); 
}

/**
 * list_move - delete from one list and add as another's head
 * @list: the entry to move
 * @head: the head that will precede our entry
 */
static inline void list_move(struct list_head *list, struct list_head *head)
{
        __list_del(list->prev, list->next);
        list_add(list, head);
}

/**
 * list_move_tail - delete from one list and add as another's tail
 * @list: the entry to move
 * @head: the head that will follow our entry
 */
static inline void list_move_tail(struct list_head *list,
				  struct list_head *head)
{
        __list_del(list->prev, list->next);
        list_add_tail(list, head);
}

/**
 * list_empty - tests whether a list is empty
 * @head: the list to test.
 */
static inline int list_empty(struct list_head *head)
{
	return head->next == head;
}

static inline void __list_splice(struct list_head *list,
				 struct list_head *head)
{
	struct list_head *first = list->next;
	struct list_head *last = list->prev;
	struct list_head *at = head->next;

	first->prev = head;
	head->next = first;

	last->next = at;
	at->prev = last;
}

/**
 * list_splice - join two lists
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 */
static inline void list_splice(struct list_head *list, struct list_head *head)
{
	if (!list_empty(list))
		__list_splice(list, head);
}

/**
 * list_splice_init - join two lists and reinitialise the emptied list.
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 *
 * The list at @list is reinitialised
 */
static inline void list_splice_init(struct list_head *list,
				    struct list_head *head)
{
	if (!list_empty(list)) {
		__list_splice(list, head);
		INIT_LIST_HEAD(list);
	}
}

/**
 * list_entry - get the struct for this entry
 * @ptr:	the &struct list_head pointer.
 * @type:	the type of the struct this is embedded in.
 * @member:	the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) \
	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

/**
 * list_for_each	-	iterate over a list
 * @pos:	the &struct list_head to use as a loop counter.
 * @head:	the head for your list.
 */
#define list_for_each(pos, head) \
	for (pos = (head)->next; pos != (head); \
        	pos = pos->next)
/**
 * list_for_each_prev	-	iterate over a list backwards
 * @pos:	the &struct list_head to use as a loop counter.
 * @head:	the head for your list.
 */
#define list_for_each_prev(pos, head) \
	for (pos = (head)->prev; pos != (head); \
        	pos = pos->prev)
        	
/**
 * list_for_each_safe	-	iterate over a list safe against removal of list entry
 * @pos:	the &struct list_head to use as a loop counter.
 * @n:		another &struct list_head to use as temporary storage
 * @head:	the head for your list.
 */
#define list_for_each_safe(pos, n, head) \
	for (pos = (head)->next, n = pos->next; pos != (head); \
		pos = n, n = pos->next)

/**
 * list_for_each_entry	-	iterate over list of given type
 * @pos:	the type * to use as a loop counter.
 * @head:	the head for your list.
 * @member:	the name of the list_struct within the struct.
 */
#define list_for_each_entry(pos, head, member)				\
	for (pos = list_entry((head)->next, typeid(*pos), member);	\
	     &pos->member != (head); 					\
	     pos = list_entry(pos->member.next, typeid(*pos), member))

/**
 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 * @pos:	the type * to use as a loop counter.
 * @n:		another type * to use as temporary storage
 * @head:	the head for your list.
 * @member:	the name of the list_struct within the struct.
 */
#define list_for_each_entry_safe(pos, n, head, member)			\
	for (pos = list_entry((head)->next, typeid(*pos), member),	\
		n = list_entry(pos->member.next, typeid(*pos), member);	\
	     &pos->member != (head); 					\
	     pos = n, n = list_entry(n->member.next, typeid(*n), member))


#endif
The following is a sample code from internet that works in Linux:

Code:
#include <stdio.h>
#include <stdlib.h>

#include "list.h"


struct kool_list{
        int to;
        struct list_head list;
        int from;
        };

int main(int argc, char **argv){

        struct kool_list *tmp;
        struct list_head *pos, *q;
        unsigned int i;

        struct kool_list mylist;
        INIT_LIST_HEAD(&mylist.list);
        
        for(i=5; i!=0; --i){
                tmp= (struct kool_list *)malloc(sizeof(struct kool_list));

                
                printf("enter to and from:");
                scanf("%d %d", &tmp->to, &tmp->from);

                /* add the new item 'tmp' to the list of items in mylist */
                list_add(&(tmp->list), &(mylist.list));
                
        }
        printf("\n");



       
        printf("traversing the list using list_for_each()\n");
        list_for_each(pos, &mylist.list){

                
                 tmp= list_entry(pos, struct kool_list, list);

             

                 printf("to= %d from= %d\n", tmp->to, tmp->from);

        }
        printf("\n");
       
        printf("traversing the list using list_for_each_entry()\n");
		list_for_each_entry(tmp, &mylist.list, list)
                 printf("to= %d from= %d\n", tmp->to, tmp->from);
        printf("\n");


        printf("deleting the list using list_for_each_safe()\n");
        list_for_each_safe(pos, q, &mylist.list){
                 tmp= list_entry(pos, struct kool_list, list);
                 printf("freeing item to= %d from= %d\n", tmp->to, tmp->from);
                 list_del(pos);
                 free(tmp);
        }

        return 0;
}
in Visual Studio 2005, when compiling it reminds me missing ';' after 'list_for_each_entry(tmp, &mylist.list, list)'.

Even if 'typeid' might not a good replacement of 'typeof' here, I though it should compile successfully anyway yet it wasn't.

Does anyone have some idea ?


Thanks in advance,

-Kun
 
Old 07-03-2009, 07:36 AM   #2
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Does anyone have some idea ?
Can you explain why you are using C++ but are not using its features?
This may contain typos as I have not compiled it.
Code:
#include <list>
#include <iostream>

typedef std::pair<int,int> entry_t;
typedef std::list<entry_t > List;
void print_entry(entry_t& i)
{
	std::cout <<"to :" <<i.first <<" from :" <<i.second <<std::endl;
}

int main()
{
	List mylist;
	
	for(int i = 0; i <5; ++i)
	{
		int to,from;
		std::cout <<"please enter to:";
		std::cin >>to;
		std::cout <<"please enter from:";
		std::cin >>from;
		
		mylist.push_back( std::make_pair(to,from) );
	}
	
	std::cout<< "traversing the list" <<std::endl;
	std::for_each(mylist.begin(), mylist.end(), &print_entry);
}
 
Old 07-03-2009, 06:05 PM   #3
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 64
I see you’ve already made two posts about this same problem. Why start a third, when you can just add on to a previous one?
Quote:
Originally Posted by Kunsheng View Post
Even if 'typeid' might not a good replacement of 'typeof' here, I though it should compile successfully anyway yet it wasn't.
Why would you think so when it has already been pointed out that they are completely different constructs and things will break if you simply substitute one for the other?
Quote:
Originally Posted by Kunsheng View Post
Does anyone have some idea ?
Yes, as has been said time and again, use C++. Additionally, you have been given a MSVC-specific solution as well, but have failed to use it. Btw, you have many ways to traverse lists in C++:
Code:
#include <list>
#include <iostream>
#include <algorithm>
#include <boost/foreach.hpp>

using std::list;
using std::cout;
using std::cin;
using std::for_each;

struct kool_list {
	int to;
	int from;
};

inline void print(kool_list &t) {
	cout << "to = " << t.to << " from = " << t.from << "\n";
}

int main(int argc, char *argv[]) {
	list<kool_list> mylist;

	for (int i = 5; i != 0; --i) {
		kool_list tmp;
		cout << "enter to and from: ";
		cin >> tmp.to >> tmp.from;
		mylist.push_back(tmp);
	}

	cout << "Traversing list with iterators\n";
	for (list<kool_list>::iterator i = mylist.begin(); i != mylist.end(); i++)
		cout << "to = " << i->to << " from = " << i->from << "\n";

	cout << "Traversing list with std::for_each\n";
	for_each(mylist.begin(), mylist.end(), print);

	cout << "Traversing list through BOOST_FOREACH\n";
	BOOST_FOREACH(kool_list t, mylist)
		cout << "to = " << t.to << " from = " << t.from << "\n";

	cout << "Deleting the entire list at once using list.clear()\n";
	mylist.clear();
	
	return 0;
}

Last edited by osor; 07-03-2009 at 06:33 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Way to convert Macro Defined functions from linux Kernel in Visual C++ Kunsheng Programming 5 06-29-2009 09:25 AM
running Visual Basic/Visual Fox Pro in Linux? depam Linux - Software 9 02-11-2006 03:42 PM
gcc equivalent for Visual C++ function: PeekNamedPipe () m3rc_2004 Programming 1 07-29-2005 05:58 AM
getopt() function in visual C++ KissDaFeetOfSean Programming 1 07-14-2005 11:47 PM


All times are GMT -5. The time now is 07:43 AM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration