summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-08-09 09:07:03 -0700
committerirungentoo <irungentoo@gmail.com>2013-08-09 09:07:03 -0700
commitb9991e1d3c51ba5096efcad6760025de7c21d091 (patch)
tree080fcbe128c2c22cd34f9f6a336df1ef6838cfdc
parent8542b5bac85ec068deac239d46954fa010128cd0 (diff)
parentfa6fd7566bb77f0daab7aec6e5d014860f60759a (diff)
Merge pull request #410 from KostyaKow/array
Array
-rw-r--r--testing/misc_tools.h151
1 files changed, 70 insertions, 81 deletions
diff --git a/testing/misc_tools.h b/testing/misc_tools.h
index 1abdb809..b8c90fa6 100644
--- a/testing/misc_tools.h
+++ b/testing/misc_tools.h
@@ -24,17 +24,14 @@
24#ifndef MISC_TOOLS_H 24#ifndef MISC_TOOLS_H
25#define MISC_TOOLS_H 25#define MISC_TOOLS_H
26 26
27unsigned char * hex_string_to_bin(char hex_string[]); 27#include <stdlib.h>
28 28#include <stdint.h>
29/* WARNING(msg) takes a printf()-styled string and prints it 29
30 * with some additional details. 30unsigned char* hex_string_to_bin(char hex_string[]);
31 * ERROR(exit_status, msg) does the same thing as WARNING(), but 31
32 * also exits the program with the given exit status. 32/*********************Debugging Macros********************
33 * Examples: 33 * wiki.tox.im/index.php/Internal_functions_and_data_structures#Debugging
34 * WARNING("<insert warning message here>"); 34 *********************************************************/
35 * int exit_status = 2;
36 * ERROR(exit_status, "exiting with status %i", exit_status);
37 */
38#ifdef DEBUG 35#ifdef DEBUG
39 #include <assert.h> 36 #include <assert.h>
40 #include <stdio.h> 37 #include <stdio.h>
@@ -51,6 +48,10 @@ unsigned char * hex_string_to_bin(char hex_string[]);
51 DEBUG_PRINT(__VA_ARGS__, ' '); \ 48 DEBUG_PRINT(__VA_ARGS__, ' '); \
52 } while (0) 49 } while (0)
53 50
51 #define INFO(...) do { \
52 DEBUG_PRINT(__VA_ARGS__, ' '); \
53 } while (0)
54
54 #undef ERROR 55 #undef ERROR
55 #define ERROR(exit_status, ...) do { \ 56 #define ERROR(exit_status, ...) do { \
56 fprintf(stderr, "error in "); \ 57 fprintf(stderr, "error in "); \
@@ -59,81 +60,20 @@ unsigned char * hex_string_to_bin(char hex_string[]);
59 } while (0) 60 } while (0)
60#else 61#else
61 #define WARNING(...) 62 #define WARNING(...)
63 #define INFO(...)
62 #undef ERROR 64 #undef ERROR
63 #define ERROR(...) 65 #define ERROR(...)
64#endif // DEBUG 66#endif // DEBUG
65 67
66/************************Linked List*********************** 68/************************Linked List***********************
67 * This is a simple linked list implementation, very similar 69 * http://wiki.tox.im/index.php/Internal_functions_and_data_structures#Linked_List
68 * to Linux kernel's /include/linux/list.h (which we can't
69 * use because Tox is GPLv3 and Linux is GPLv2.)
70 *
71 * TODO: Make the lists easier to use with some sweat pre-
72 * processor syntactic sugar.
73 **********************************************************/ 70 **********************************************************/
74 71
75/* Example usage
76
77This sample program makes a new struct which contains a
78character and a tox_list_t. It then prompts a user for
79input until he enters q or e. It then adds each character
80to the list, and uses a special for loop to print them.
81It then removes all the 'z' characters, and prints the list
82again.
83
84//Notice that the data to be put in the list *contains* tox_list_t;
85//usually, this is the other way around!
86typedef struct tox_string {
87 char c;
88 tox_list_t tox_lst; //Notice that tox_lst is *NOT* a pointer.
89} tox_string_t;
90
91int main()
92{
93 tox_list_t head;
94 tox_list_new(&head); //initialize head
95
96 //input a new character, until user enters q or e
97 char c = '\0';
98 while (c != 'q' && c != 'e') {
99 scanf("%c", &c);
100 tox_string_t* tmp = malloc(sizeof(tox_string_t));
101 tmp->c = c;
102 tox_list_add(&head, &tmp->tox_lst); //add it to the list
103 }
104
105TOX_LIST_FOR_EACH() takes a struct tox_list and a name for a temporary pointer to use in the loop.
106
107TOX_LIST_GET_VALUE() uses magic to return an instance of a structure that contains tox_list_t.
108You have to give it a temporary tox_string_t, name of tox_list_t member inside our structure (tox_lst),
109and the type of structure to return.
110
111 TOX_LIST_FOR_EACH(head, tmp)
112 printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c);
113
114 TOX_LIST_FOR_EACH(head, tmp) {
115 if (TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c == 'z') {
116 //If you delete tmp, you have to quit the loop, or it will go on infinitly.
117 //This will be fixed later on.
118 tox_list_remove(tmp);
119 break;
120 }
121 }
122
123 printf("\n");
124 TOX_LIST_FOR_EACH(head, tmp)
125 printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c);
126
127
128 return 0;
129}
130*/
131
132#define MEMBER_OFFSET(var_name_in_parent, parent_type) \ 72#define MEMBER_OFFSET(var_name_in_parent, parent_type) \
133 (&(((parent_type*)0)->var_name_in_parent)) 73 (&(((parent_type*)0)->var_name_in_parent))
134 74
135#define GET_PARENT(var, var_name_in_parent, parent_type) \ 75#define GET_PARENT(var, var_name_in_parent, parent_type) \
136 (*((parent_type*)((uint64_t)(&(var)) - (uint64_t)(MEMBER_OFFSET(var_name_in_parent, parent_type))))) 76 ((parent_type*)((uint64_t)(&(var)) - (uint64_t)(MEMBER_OFFSET(var_name_in_parent, parent_type))))
137 77
138#define TOX_LIST_FOR_EACH(lst, tmp_name) \ 78#define TOX_LIST_FOR_EACH(lst, tmp_name) \
139 for (tox_list_t* tmp_name = lst.next; tmp_name != &lst; tmp_name = tmp_name->next) 79 for (tox_list_t* tmp_name = lst.next; tmp_name != &lst; tmp_name = tmp_name->next)
@@ -145,12 +85,14 @@ typedef struct tox_list {
145} tox_list_t; 85} tox_list_t;
146 86
147/* Returns a new tox_list_t. */ 87/* Returns a new tox_list_t. */
148static inline void tox_list_new(tox_list_t* lst) { 88static inline void tox_list_new(tox_list_t* lst)
89{
149 lst->prev = lst->next = lst; 90 lst->prev = lst->next = lst;
150} 91}
151 92
152/* Inserts a new tox_lst after lst and returns it. */ 93/* Inserts a new tox_lst after lst and returns it. */
153static inline void tox_list_add(tox_list_t* lst, tox_list_t* new_lst) { 94static inline void tox_list_add(tox_list_t* lst, tox_list_t* new_lst)
95{
154 tox_list_new(new_lst); 96 tox_list_new(new_lst);
155 97
156 new_lst->next = lst->next; 98 new_lst->next = lst->next;
@@ -160,12 +102,59 @@ static inline void tox_list_add(tox_list_t* lst, tox_list_t* new_lst) {
160 new_lst->prev = lst; 102 new_lst->prev = lst;
161} 103}
162 104
163static inline void tox_list_remove(tox_list_t* lst) { 105static inline void tox_list_remove(tox_list_t* lst)
164#ifdef DEBUG /* TODO: check how debugging is done in Tox. */ 106{
165 assert(lst->next != lst && lst->prev != lst);
166#endif
167 lst->prev->next = lst->next; 107 lst->prev->next = lst->next;
168 lst->next->prev = lst->prev; 108 lst->next->prev = lst->prev;
169} 109}
170 110
111/****************************Array***************************
112 * Array to store pointers which tracks it's own size.
113 * TODO: Figure out if it shold store values instead of
114 * pointers?
115 * TODO: Add wiki info usage.
116 ************************************************************/
117
118struct tox_array {
119 void **data;
120 uint32_t size, length;
121};
122
123static inline void tox_array_init(struct tox_array *arr)
124{
125 arr->size = 1;
126 arr->length = 0;
127 arr->data = malloc(sizeof(void*));
128}
129
130static inline void tox_array_delete(struct tox_array *arr)
131{
132 free(arr->data);
133 arr->size = arr->length = 0;
134}
135
136/* shrinks arr so it will not have unused space. If you want to have
137 * addtional space, extra species the amount of extra space.
138 */
139static inline void tox_array_shrink_to_fit(struct tox_array *arr, int32_t extra)
140{
141 arr->size = arr->length + extra;
142 arr->data = realloc(arr->data, arr->size * sizeof(void*));
143}
144
145static inline void _tox_array_push(struct tox_array *arr, void *new)
146{
147 if (arr->length+1 >= arr->size)
148 tox_array_shrink_to_fit(arr, arr->size);
149 arr->data[arr->length++] = new;
150}
151#define tox_array_push(arr, new) _tox_array_push(arr, (void*)new)
152
153static inline void* tox_array_pop(struct tox_array *arr)
154{
155 if (arr->length-1 < arr->size/4)
156 tox_array_shrink_to_fit(arr, arr->length*2);
157 return arr->data[arr->length--];
158}
159
171#endif // MISC_TOOLS_H 160#endif // MISC_TOOLS_H