diff options
Diffstat (limited to 'testing/misc_tools.h')
-rw-r--r-- | testing/misc_tools.h | 111 |
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 | ||
27 | unsigned char * hex_string_to_bin(char hex_string[]); | 27 | unsigned 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 | |||
44 | This sample program makes a new struct which contains a | ||
45 | character and a tox_list_t. It then prompts a user for | ||
46 | input until he enters q or e. It then adds each character | ||
47 | to the list, and uses a special for loop to print them. | ||
48 | It then removes all the 'z' characters, and prints the list | ||
49 | again. | ||
50 | |||
51 | //Notice that the data to be put in the list *contains* tox_list_t; | ||
52 | //usually, this is the other way around! | ||
53 | typedef 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 | |||
58 | int 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 | |||
72 | TOX_LIST_FOR_EACH() takes a struct tox_list and a name for a temporary pointer to use in the loop. | ||
73 | |||
74 | TOX_LIST_GET_VALUE() uses magic to return an instance of a structure that contains tox_list_t. | ||
75 | You have to give it a temporary tox_string_t, name of tox_list_t member inside our structure (tox_lst), | ||
76 | and 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 | |||
110 | typedef struct tox_list { | ||
111 | struct tox_list *prev, *next; | ||
112 | } tox_list_t; | ||
113 | |||
114 | /* Returns a new tox_list_t. */ | ||
115 | static 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. */ | ||
120 | static 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 | |||
130 | static 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 |