Monthly Archives: March 2016

change Storyboard to xib project

as we know, project with xib now is no allowed to create. It only allow Storyboard project, xcode 6.4 for example,

However, following the steps you could still be able to create a project with xib.

1. create a Storyboard, you have no choices but make storyboard

2. right click on project file, choose iOS->”User Interface”->View

Screen Shot 2016-03-19 at 上午1.53.28

3. after you add xib to project, make sure move it to right folder.

4. right click on project property, find “App Icons and Launch Images”
-> Lanuch Screen File
Screen Shot 2016-03-19 at 上午2.02.00

RPM and RPM source code

src.rpm contains both patchs and original source code.
rpmbuild and some related rpm command will not be introduced in this article.
some important file such as file.spec in rpm configuration will be ignored as well

It only talk about how to uncompress source code and patch source code and build the final binary.

take ftp-0.17-65.fc20.src.rpm for example.

1. uncompress rpm to source code folder

1
rpm2cpio ftp-0.17-65.fc20.src.rpm | cpio -idmv --no-absolute-filenames

2. patch patch file

1
patch -p1 < *.patch

3. build ftp project using ./configure && make.
2

Linux Kernel – Data structure List in include/linux/list.h

Linux Kernel has lots of data structure such as list (including linked list, double linked lists), red-black tree, B Tree , Interval tree, Heap, Radix tree, spin locks and so on.
I will put some articles for these interesting data structures.

List is most simple data structure we could start with.

Even for such simple data structure, Linux Kernel still has some operation which User-Space data structure didn’t use.

the definition of list_head

1
2
3
struct list_head {
    struct list_head *next, *prev;
};

It is a double linked list.

1
2
3
4
5
static inline void
INIT_LIST_HEAD(struct list_head *list)
{
    list->next = list->prev = list;
}
1
2
3
4
5
6
7
8
9
static inline void
__list_add(struct list_head *entry,
                struct list_head *prev, struct list_head *next)
{
    next->prev = entry;
    entry->next = next;
    entry->prev = prev;
    prev->next = entry;
}

what this function todo is put entry between next and prev.

prev –> entry <--- next

1
2
3
4
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
	__list_add(new, head->prev, head);
}

append something into tail is to add entry between head and tail(head and tail are linked together)

1
2
3
4
5
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
	next->prev = prev;
	prev->next = next;
}

del is to delete all items between prev and next. therefore, set next’s prev to prev node.
and prev node’s next to be next node.

1
2
3
4
5
6
7
8
9
static inline void list_replace(struct list_head *old,
				struct list_head *new)
{
	new->next = old->next;
	new->next->prev = new;
	new->prev = old->prev;
	new->prev->next = new;
}
INIT_LIST_HEAD(old); // let old's all pointer pointed to itself.

delete old one and linked new one to old one’s postion.

1
2
3
4
5
static inline void list_move(struct list_head *list, struct list_head *head)
{
	__list_del_entry(list);
	list_add(list, head);
}

delete from one list and add as another’s head

1
2
3
4
5
6
7
8
9
static inline void list_rotate_left(struct list_head *head)
{
	struct list_head *first;
 
	if (!list_empty(head)) {
		first = head->next;
		list_move_tail(first, head);
	}
}

move head->next to head and tail.

some other functions such as list_cut_position is to split list into two.
and list_splice is to join two lists

1
2
3
4
#define list_for_each_prev_safe(pos, n, head) \
	for (pos = (head)->prev, n = pos->prev; \
	     pos != (head); \
	     pos = n, n = pos->prev)

some macro are defined in such format, there for developer don’t have to write “for” every time