Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
proper use of the HAVE_TRACING variable defined by Cmake through -Dtracing=on
[simgrid.git] / src / xbt / dict_cursor.c
1 /* $Id$ */
2
3 /* dict_cursor - iterators over dictionnaries                               */
4
5 /* Copyright (c) 2003, 2004 Martin Quinson. All rights reserved.            */
6
7 /* This program is free software; you can redistribute it and/or modify it
8  * under the terms of the license (GNU LGPL) which comes with this package. */
9
10 #include "xbt/misc.h"
11 #include "xbt/ex.h"
12 #include "dict_private.h"
13
14 #include <string.h>             /* strlen() */
15
16 XBT_LOG_EXTERNAL_CATEGORY(xbt_dict);
17 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_dict_cursor, xbt_dict,
18                                 "To traverse dictionaries");
19
20
21 /*####[ Dict cursor functions ]#############################################*/
22 /* To traverse (simple) dicts                                               */
23 /* Don't add or remove entries to the dict while traversing !!!             */
24 /*###########################################################################*/
25 struct xbt_dict_cursor_ {
26   xbt_dictelm_t current;
27   int line;
28   xbt_dict_t dict;
29 };
30
31 #undef xbt_dict_CURSOR_DEBUG
32 /*#define xbt_dict_CURSOR_DEBUG 1*/
33
34 /** @brief Creator
35  *  @param dict the dict
36  */
37 XBT_INLINE xbt_dict_cursor_t xbt_dict_cursor_new(const xbt_dict_t dict)
38 {
39   xbt_dict_cursor_t res = NULL;
40
41   res = xbt_new(s_xbt_dict_cursor_t, 1);
42   res->dict = dict;
43
44   xbt_dict_cursor_rewind(res);
45
46   return res;
47 }
48
49 /**
50  * @brief Destructor
51  * @param cursor poor victim
52  */
53 XBT_INLINE void xbt_dict_cursor_free(xbt_dict_cursor_t * cursor)
54 {
55   if (*cursor) {
56     xbt_free(*cursor);
57     *cursor = NULL;
58   }
59 }
60
61 /*
62  * Sanity check to see if the head contains something
63  */
64 static XBT_INLINE void __cursor_not_null(xbt_dict_cursor_t cursor)
65 {
66   xbt_assert0(cursor, "Null cursor");
67 }
68
69
70 /** @brief Reinitialize the cursor. Mandatory after removal or add in dict. */
71 XBT_INLINE void xbt_dict_cursor_rewind(xbt_dict_cursor_t cursor)
72 {
73   CDEBUG0(xbt_dict_cursor, "xbt_dict_cursor_rewind");
74   xbt_assert(cursor);
75
76   cursor->line = 0;
77   if (cursor->dict != NULL) {
78     cursor->current = cursor->dict->table[0];
79   } else {
80     cursor->current = NULL;
81   }
82 }
83
84 /**
85  * @brief Create the cursor if it does not exists. Rewind it in any case.
86  *
87  * @param      dict   on what to let the cursor iterate
88  * @param[out] cursor dest address
89  */
90 XBT_INLINE void xbt_dict_cursor_first(const xbt_dict_t dict, xbt_dict_cursor_t * cursor)
91 {
92   DEBUG0("xbt_dict_cursor_first");
93   if (!*cursor) {
94     DEBUG0("Create the cursor on first use");
95     *cursor = xbt_dict_cursor_new(dict);
96   } else {
97     xbt_dict_cursor_rewind(*cursor);
98   }
99   if (dict != NULL && (*cursor)->current == NULL) {
100     xbt_dict_cursor_step(*cursor);      /* find the first element */
101   }
102 }
103
104
105 /**
106  * \brief Move to the next element.
107  */
108 XBT_INLINE void xbt_dict_cursor_step(xbt_dict_cursor_t cursor)
109 {
110   xbt_dictelm_t current;
111   int line;
112
113   DEBUG0("xbt_dict_cursor_step");
114   xbt_assert(cursor);
115
116   current = cursor->current;
117   line = cursor->line;
118
119   if (cursor->dict != NULL) {
120
121     if (current != NULL) {
122       DEBUG0("current is not null, take the next element");
123       current = current->next;
124       DEBUG1("next element: %p", current);
125     }
126
127     while (current == NULL && ++line <= cursor->dict->table_size) {
128       DEBUG0("current is NULL, take the next line");
129       current = cursor->dict->table[line];
130       DEBUG1("element in the next line: %p", current);
131     }
132     DEBUG2("search finished, current = %p, line = %d", current, line);
133
134     cursor->current = current;
135     cursor->line = line;
136   }
137 }
138
139 /**
140  * @brief Get current data, or free the cursor if there is no data left
141  *
142  * @returns true if it's ok, false if there is no more data
143  */
144 XBT_INLINE int xbt_dict_cursor_get_or_free(xbt_dict_cursor_t * cursor,
145                                 char **key, void **data)
146 {
147
148   xbt_dictelm_t current;
149
150   DEBUG0("xbt_dict_get_or_free");
151
152
153   if (!cursor || !(*cursor))
154     return FALSE;
155
156   current = (*cursor)->current;
157   if (current == NULL) {        /* no data left */
158     xbt_dict_cursor_free(cursor);
159     return FALSE;
160   }
161
162   *key = current->key;
163   *data = current->content;
164   return TRUE;
165 }
166
167 /**
168  * @brief Get current key
169  * @param cursor: the cursor
170  * @returns the current key
171  */
172 XBT_INLINE char *xbt_dict_cursor_get_key(xbt_dict_cursor_t cursor)
173 {
174   __cursor_not_null(cursor);
175
176   return cursor->current->key;
177 }
178
179 /**
180  * @brief Get current data
181  * @param cursor the cursor
182  * @returns the current data
183  */
184 XBT_INLINE void *xbt_dict_cursor_get_data(xbt_dict_cursor_t cursor)
185 {
186   __cursor_not_null(cursor);
187
188   return cursor->current->content;
189 }