Author Archives: wudi

Sqlite DateTime compare in WebSQL

Sqlite has DateTime. However, in my test ‘DateTime’ is similar with ‘Text’.

for example, javascript moment.js,

1
2
3
4
5
6
 
var date = new moment().format('YYYY-MM-DD hh:mm');
saveToDatebase(date);
 
var date = new moment().format('YYYY-MM-DD h:mm a');
saveToDatebase(date);

in sqlite, two different format will saved as different string.

it is better not to compare two different format, such as ‘2016-10-10’ and ‘2016-10-10 10:10:10’. it is comparable, but it is meanless.

therefore, in my test, and date time should be save as YYYY-MM-DD hh:mm, such as ‘2016-10-10 10:10’ format.

then, sql statement like ‘select * from test where startDate < '2016-10-10 15:15' will work perfectly well.

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

TCC – struct CString for string process in compiler

struct CString is major struct for string process in TCC.
It also works some api such as cstr_reset(…),cstr_ccat(…).
Here is example on how to convert “char *” to s.data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  struct CString s;
 
  static char buf[STRING_MAX_SIZE + 1];
 
  char *p = "Test";
  char *p1 = p;
  char *p2 = p; 
 
  cstr_reset(&s);
 
  for(;;){
    if(*p2 != '\0')
      {
        p2++;
      }
    else
      break;
  }
 
  s.data = buf;  
 
  while (p1 < p2) {
    cstr_ccat(&s, *p1);
    p1++;
  }
 
  printf("%s",(char *)s.data);

Linux Kernel – start_kernel in main.c and task_struct for process management

Linux start with start_kernel function in main.c. It has lots of function, such mm_init for kernel memory allocators. Let’s start with some very basic components firstly.

task_struct is an basic and important struct for process.
It is defined in “include/linux/sched.h”

One process will be linked with others, for example, parent process and child process are linked together.

each member of task_struct is very critical and it is better to go though all of them to understand its better.

Check the definition of task_struct, you could print more information you want,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/errno.h>   /* error codes */
#include <linux/sched.h>
 
 
MODULE_LICENSE("Dual BSD/GPL");
 
/* Declaration of functions */
void device_exit(void);
int device_init(void);
 
/* Declaration of the init and exit routines */
module_init(device_init);
module_exit(device_exit);
 
int device_init(void)
{
    struct task_struct *task = current; // getting global current pointer
    printk(KERN_NOTICE "assignment: current process: %s, PID: %d", task->comm, task->pid);
    do
    {
        task = task->parent;
        printk(KERN_NOTICE "assignment: parent process: %s, PID: %d", task->comm, task->pid);
    } while (task->pid != 0);
    return 0;
}
 
void device_exit(void) {
  printk(KERN_NOTICE "assignment: exiting module");
}

Screenshot from 2016-02-12 01:39:43

Linux Kernel Analysis: Enable Linux Kernel Stack Dumping

As we know, if we want to know a special function and who will call it.
One of way is to use “cscope” to static analysis.

The following step is how we do it:

Enabling Stack Dumping in Linux Kernel
Enabling in Kernel Config
To enable the dump_stack() function in the kernel config the following options must be set. You can use make menuconfig or make xconfig to do this.

Kernel hacking -> Kernel debugging
Kernel hacking -> Verbose kernel error messages

1

Enabling these two options will change the dump_stack() function from a do nothing function to dumping the stack.

You need to rebuild your Linux kernel image after enabling these options.

Using dump_stack()
Using the dump_stack() function is as easy as calling dump_stack() wherever you wish to print out the stack. This will cause a stack trace to be printed at that point.

TCC source code — define_stack and tcc_alloc

define_stack is good example of lots of stack using TCC. The following is example of print Define Stack.

1
2
3
4
5
6
7
8
9
10
11
void printDefineStack(){
  Sym *p = define_stack;
  for(;;){
    if(p == NULL){
      break;
    }
 
    printf("%d\n",p -> v);
    p = p -> prev; 
  }
}

tcc_alloc is function which is allocated tcc object, It is very simple and used everywhere in tcc. Here is example on how to use it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void tcc_alloc_test()
{
  int i = 0;
  int len =  3;
  char *str = "int";
  TokenSym *ts;  
  table_ident = tcc_malloc((TOK_ALLOC_INCR) * sizeof(TokenSym *));
 
  ts = tcc_malloc(sizeof(TokenSym) + len);
  table_ident[i] = ts;
 
  ts->sym_define = NULL;
  ts->sym_label = NULL;
  ts->sym_struct = NULL;
  ts->sym_identifier = NULL;
  ts->len = len;
  ts->hash_next = NULL;
  memcpy(ts->str, str, len);
  ts->str[len] = '\0';
 
}

Google CodeJam – Mushroom Monster

Question URL is https://code.google.com/codejam/contest/4224486/dashboard

This question could be become two sub question.
1. less mushroom to eat.
for array 10 5 15 5, what is the sum of decreased numbers?
10 is decreased to 5, the decreased number is (10-5).
5 raises to 15, it will be ignored.
15 is decreased to 5, the decreased number is (15-5)

the sum of all decreased numbers that is (10-5)+(15-5) will be the answer.

2. eating mushroom in static speed.

find the max gap of decreased numbers. (15-5) is the max speed in 10 seconds.
there for, if mushroom number on the dish is greater than (15-5), Kaylin only eats(15-5).

if mushroom number on the dish is less that (15-5), Kaylin will finish all of them and waiting for next refill.

Here is Clang code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  int N;
  int L;
  int i,j,k;
  int array[MAXSIZE];
  int sum1 = 0;
  int sum2 = 0;
 
  scanf("%d\n",&N);
 
  for(i=0;i<N;i++)
  {
    scanf("%d",&L);
    memset(array,0,sizeof(int)*MAXSIZE);
    sum1 = 0;
    sum2 = 0;
    for(j = 0;j<L;j++){
      scanf("%d",&array[j]);
    }
 
    //start
    for(j = 0;j<L - 1;j++){
      if(array[j]>array[j + 1])
        sum1 += (array[j] - array[j + 1]); 
    }
 
    int max = 0;
 
    for(j = 0;j<L - 1;j++){
      if(array[j]>array[j + 1]){
        if(max<(array[j] - array[j + 1])){
          max = array[j] - array[j + 1];
        }
      }
    }
 
    for(j = 0;j<L - 1;j++){
      sum2 += (array[j]>max?max:array[j]); 
    }
 
    printf("Case #%d: %d %d\n",(i + 1),sum1,sum2);
  }