summaryrefslogtreecommitdiff
path: root/testing/misc_tools.h
diff options
context:
space:
mode:
Diffstat (limited to 'testing/misc_tools.h')
-rw-r--r--testing/misc_tools.h111
1 files changed, 110 insertions, 1 deletions
diff --git a/testing/misc_tools.h b/testing/misc_tools.h
index 5079e15d..4e09d40d 100644
--- a/testing/misc_tools.h
+++ b/testing/misc_tools.h
@@ -25,5 +25,114 @@
25#define MISC_TOOLS_H 25#define MISC_TOOLS_H
26 26
27unsigned char * hex_string_to_bin(char hex_string[]); 27unsigned char * hex_string_to_bin(char hex_string[]);
28 28
29
30
31
32
33/************************Linked List***********************
34 * This is a simple linked list implementation, very similar
35 * to Linux kernel's /include/linux/list.h (which we can't
36 * use because Tox is GPLv3 and Linux is GPLv2.)
37 *
38 * TODO: Make the lists easier to use with some sweat pre-
39 * processor syntactic sugar.
40 **********************************************************/
41
42/* Example usage
43
44This sample program makes a new struct which contains a
45character and a tox_list_t. It then prompts a user for
46input until he enters q or e. It then adds each character
47to the list, and uses a special for loop to print them.
48It then removes all the 'z' characters, and prints the list
49again.
50
51//Notice that the data to be put in the list *contains* tox_list_t;
52//usually, this is the other way around!
53typedef struct tox_string {
54 char c;
55 tox_list_t tox_lst; //Notice that tox_lst is *NOT* a pointer.
56} tox_string_t;
57
58int main()
59{
60 tox_list_t head;
61 tox_list_new(&head); //initialize head
62
63 //input a new character, until user enters q or e
64 char c = '\0';
65 while (c != 'q' && c != 'e') {
66 scanf("%c", &c);
67 tox_string_t* tmp = malloc(sizeof(tox_string_t));
68 tmp->c = c;
69 tox_list_add(&head, &tmp->tox_lst); //add it to the list
70 }
71
72TOX_LIST_FOR_EACH() takes a struct tox_list and a name for a temporary pointer to use in the loop.
73
74TOX_LIST_GET_VALUE() uses magic to return an instance of a structure that contains tox_list_t.
75You have to give it a temporary tox_string_t, name of tox_list_t member inside our structure (tox_lst),
76and the type of structure to return.
77
78 TOX_LIST_FOR_EACH(head, tmp)
79 printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c);
80
81 TOX_LIST_FOR_EACH(head, tmp) {
82 if (TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c == 'z') {
83 //If you delete tmp, you have to quit the loop, or it will go on infinitly.
84 //This will be fixed later on.
85 tox_list_remove(tmp);
86 break;
87 }
88 }
89
90 printf("\n");
91 TOX_LIST_FOR_EACH(head, tmp)
92 printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c);
93
94
95 return 0;
96}
97*/
98
99#define MEMBER_OFFSET(var_name_in_parent, parent_type) \
100 (&(((parent_type*)0)->var_name_in_parent))
101
102#define GET_PARENT(var, var_name_in_parent, parent_type) \
103 (*((parent_type*)((uint64_t)(&(var)) - (uint64_t)(MEMBER_OFFSET(var_name_in_parent, parent_type)))))
104
105#define TOX_LIST_FOR_EACH(lst, tmp_name) \
106 for (tox_list_t* tmp_name = lst.next; tmp_name != &lst; tmp_name = tmp_name->next)
107
108#define TOX_LIST_GET_VALUE(tmp_name, name_in_parent, parent_type) GET_PARENT(tmp_name, name_in_parent, parent_type)
109
110typedef struct tox_list {
111 struct tox_list *prev, *next;
112} tox_list_t;
113
114/* Returns a new tox_list_t. */
115static inline void tox_list_new(tox_list_t* lst) {
116 lst->prev = lst->next = lst;
117}
118
119/* Inserts a new tox_lst after lst and returns it. */
120static inline void tox_list_add(tox_list_t* lst, tox_list_t* new_lst) {
121 tox_list_new(new_lst);
122
123 new_lst->next = lst->next;
124 new_lst->next->prev = new_lst;
125
126 lst->next = new_lst;
127 new_lst->prev = lst;
128}
129
130static inline void tox_list_remove(tox_list_t* lst) {
131#ifdef DEBUG /* TODO: check how debugging is done in Tox. */
132 assert(lst->next != lst && lst->prev != lst);
133#endif
134 lst->prev->next = lst->next;
135 lst->next->prev = lst->prev;
136}
137
29#endif // MISC_TOOLS_H 138#endif // MISC_TOOLS_H