Mercurial > mplayer.hg
annotate gui/util/list.c @ 37066:1843c6aaae4d
Add listFree().
Use it in listSet().
(This is the only purpose of use at the moment, but we will need
listFree() later which is the reason behind setting the pointer
to NULL after freeing.)
author | ib |
---|---|
date | Thu, 24 Apr 2014 11:56:18 +0000 |
parents | b28b632efeef |
children | b03e0fd957fd |
rev | line source |
---|---|
33741 | 1 /* |
2 * This file is part of MPlayer. | |
3 * | |
4 * MPlayer is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; either version 2 of the License, or | |
7 * (at your option) any later version. | |
8 * | |
9 * MPlayer is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License along | |
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
17 */ | |
18 | |
34683 | 19 /** |
20 * @file | |
21 * @brief List management | |
22 */ | |
23 | |
36772
0da6c7ff95d2
Revise code of listMgr() command PLAYLIST_ITEM_GET_POS.
ib
parents:
36155
diff
changeset
|
24 #include <stdint.h> |
33741 | 25 #include <stdlib.h> |
26 #include <string.h> | |
27 | |
28 #include "list.h" | |
37066 | 29 #include "mem.h" |
35530 | 30 #include "string.h" |
35525 | 31 #include "gui/app/gui.h" |
33741 | 32 |
35376 | 33 #include "mp_msg.h" |
34 #include "path.h" | |
35 | |
34667 | 36 static plItem *plList; |
34664
4df4d842d5fb
Remove global variable pointing to current playlist item.
ib
parents:
34663
diff
changeset
|
37 static plItem *plCurrent; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
38 |
34668 | 39 static urlItem *urlList; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
40 |
34683 | 41 /** |
42 * @brief Manage playlists and URL lists. | |
43 * | |
44 * @param cmd task to be performed | |
45 * @param data list item for the task | |
46 * | |
47 * @return pointer to top of list (GET command), | |
48 * pointer to current list item (ITEM command) or | |
49 * NULL (DELETE or unknown command) | |
50 * | |
37065 | 51 * @note PLAYLIST_ITEM_GET_POS returns the position number as pointer value |
35487
58a221f73d75
Enhance PLAYLIST_ITEM_GET_POS to provide total number of items.
ib
parents:
35460
diff
changeset
|
52 * (if @a data is NULL the last position number, i.e. number of items), |
35458 | 53 * and position 0 means "not found" |
34683 | 54 */ |
34610 | 55 void *listMgr(int cmd, void *data) |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
56 { |
36772
0da6c7ff95d2
Revise code of listMgr() command PLAYLIST_ITEM_GET_POS.
ib
parents:
36155
diff
changeset
|
57 uintptr_t pos; |
34673 | 58 plItem *pdat = (plItem *)data; |
59 urlItem *udat = (urlItem *)data; | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
60 |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
61 switch (cmd) { |
34684 | 62 /* playlist */ |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
63 |
34667 | 64 case PLAYLIST_GET: |
65 | |
66 return plList; | |
67 | |
34681 | 68 case PLAYLIST_ITEM_APPEND: |
34674 | 69 |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
70 if (plList) { |
34673 | 71 plItem *item = plList; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
72 |
34673 | 73 while (item->next) |
74 item = item->next; | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
75 |
34673 | 76 item->next = pdat; |
77 pdat->prev = item; | |
78 pdat->next = NULL; | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
79 } else { |
34674 | 80 pdat->next = pdat->prev = NULL; |
34673 | 81 plCurrent = plList = pdat; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
82 } |
34674 | 83 |
84 return plCurrent; | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
85 |
34663 | 86 case PLAYLIST_ITEM_INSERT: |
34675 | 87 |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
88 if (plCurrent) { |
34675 | 89 pdat->next = plCurrent->next; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
90 |
34673 | 91 if (pdat->next) |
92 pdat->next->prev = pdat; | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
93 |
34675 | 94 pdat->prev = plCurrent; |
95 plCurrent->next = pdat; | |
96 | |
97 plCurrent = pdat; | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
98 |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
99 return plCurrent; |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
100 } else |
34681 | 101 return listMgr(PLAYLIST_ITEM_APPEND, pdat); |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
102 |
35460 | 103 case PLAYLIST_ITEM_FIND: |
104 | |
105 if (plList) { | |
106 plItem *item = plList; | |
107 | |
108 do { | |
109 if (gstrcmp(item->path, pdat->path) == 0 && gstrcmp(item->name, pdat->name) == 0) | |
110 return item; | |
111 | |
112 item = item->next; | |
113 } while (item); | |
114 } | |
115 | |
116 return NULL; | |
117 | |
34682
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
118 case PLAYLIST_ITEM_SET_CURR: |
34676
207272df4aef
Cosmetic: Insert some blank lines and remove commented code.
ib
parents:
34675
diff
changeset
|
119 |
34682
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
120 plCurrent = pdat; |
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
121 return plCurrent; |
34676
207272df4aef
Cosmetic: Insert some blank lines and remove commented code.
ib
parents:
34675
diff
changeset
|
122 |
34682
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
123 case PLAYLIST_ITEM_GET_CURR: |
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
124 |
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
125 return plCurrent; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
126 |
35458 | 127 case PLAYLIST_ITEM_GET_POS: |
128 | |
129 pos = 0; | |
130 | |
131 if (plList) { | |
36772
0da6c7ff95d2
Revise code of listMgr() command PLAYLIST_ITEM_GET_POS.
ib
parents:
36155
diff
changeset
|
132 uintptr_t i = 0; |
36773 | 133 plItem *item = plList; |
35458 | 134 |
135 do { | |
136 i++; | |
137 | |
138 if (item == pdat) { | |
139 pos = i; | |
140 break; | |
141 } | |
142 | |
143 item = item->next; | |
144 } while (item); | |
35487
58a221f73d75
Enhance PLAYLIST_ITEM_GET_POS to provide total number of items.
ib
parents:
35460
diff
changeset
|
145 |
58a221f73d75
Enhance PLAYLIST_ITEM_GET_POS to provide total number of items.
ib
parents:
35460
diff
changeset
|
146 if (!pdat) |
58a221f73d75
Enhance PLAYLIST_ITEM_GET_POS to provide total number of items.
ib
parents:
35460
diff
changeset
|
147 pos = i; |
35458 | 148 } |
149 | |
150 return (void *)pos; | |
151 | |
34663 | 152 case PLAYLIST_ITEM_GET_PREV: |
34676
207272df4aef
Cosmetic: Insert some blank lines and remove commented code.
ib
parents:
34675
diff
changeset
|
153 |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
154 if (plCurrent && plCurrent->prev) { |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
155 plCurrent = plCurrent->prev; |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
156 return plCurrent; |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
157 } |
34676
207272df4aef
Cosmetic: Insert some blank lines and remove commented code.
ib
parents:
34675
diff
changeset
|
158 |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
159 return NULL; |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
160 |
34682
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
161 case PLAYLIST_ITEM_GET_NEXT: |
34676
207272df4aef
Cosmetic: Insert some blank lines and remove commented code.
ib
parents:
34675
diff
changeset
|
162 |
34682
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
163 if (plCurrent && plCurrent->next) { |
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
164 plCurrent = plCurrent->next; |
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
165 return plCurrent; |
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
166 } |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
167 |
34682
c3ab7bd64ab3
Cosmetic: Arrange listMgr() commands in switch statement.
ib
parents:
34681
diff
changeset
|
168 return NULL; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
169 |
35962 | 170 case PLAYLIST_ITEM_GET_LAST: |
171 | |
172 if (plList) { | |
173 plItem *item = plList; | |
174 | |
175 while (item->next) | |
176 item = item->next; | |
177 | |
178 return item; | |
179 } | |
180 | |
181 return NULL; | |
182 | |
34663 | 183 case PLAYLIST_ITEM_DEL_CURR: |
34677 | 184 |
185 if (plCurrent) { | |
34678 | 186 plItem *curr = plCurrent; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
187 |
34678 | 188 if (curr->prev) |
189 curr->prev->next = curr->next; | |
190 if (curr->next) | |
191 curr->next->prev = curr->prev; | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
192 |
34678 | 193 plCurrent = curr->next; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
194 |
34678 | 195 if (curr == plList) |
196 plList = plCurrent; | |
34677 | 197 |
34678 | 198 free(curr->path); |
199 free(curr->name); | |
200 free(curr); | |
201 } | |
34677 | 202 |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
203 return plCurrent; |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
204 |
34663 | 205 case PLAYLIST_DELETE: |
34676
207272df4aef
Cosmetic: Insert some blank lines and remove commented code.
ib
parents:
34675
diff
changeset
|
206 |
34602 | 207 while (plList) { |
34673 | 208 plItem *item = plList->next; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
209 |
34602 | 210 free(plList->path); |
211 free(plList->name); | |
212 free(plList); | |
213 | |
34673 | 214 plList = item; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
215 } |
34676
207272df4aef
Cosmetic: Insert some blank lines and remove commented code.
ib
parents:
34675
diff
changeset
|
216 |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
217 plCurrent = NULL; |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
218 return NULL; |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
219 |
34684 | 220 /* URL list */ |
34668 | 221 |
222 case URLLIST_GET: | |
223 | |
224 return urlList; | |
225 | |
34663 | 226 case URLLIST_ITEM_ADD: |
34679 | 227 |
33748 | 228 if (urlList) { |
34673 | 229 urlItem *item = urlList; |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
230 |
34679 | 231 while (item) { |
232 if (strcmp(udat->url, item->url) == 0) { | |
233 free(udat->url); | |
234 free(udat); | |
235 return NULL; | |
236 } | |
237 | |
238 if (item->next) | |
239 item = item->next; | |
240 else { | |
241 item->next = udat; | |
242 udat->next = NULL; | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
243 break; |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
244 } |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
245 } |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
246 } else { |
34673 | 247 udat->next = NULL; |
248 urlList = udat; | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
249 } |
34679 | 250 |
251 return udat; | |
34599 | 252 |
34663 | 253 case URLLIST_DELETE: |
34676
207272df4aef
Cosmetic: Insert some blank lines and remove commented code.
ib
parents:
34675
diff
changeset
|
254 |
34599 | 255 while (urlList) { |
34673 | 256 urlItem *item = urlList->next; |
34601 | 257 |
34599 | 258 free(urlList->url); |
34601 | 259 free(urlList); |
260 | |
34673 | 261 urlList = item; |
34599 | 262 } |
34676
207272df4aef
Cosmetic: Insert some blank lines and remove commented code.
ib
parents:
34675
diff
changeset
|
263 |
34599 | 264 return NULL; |
34680 | 265 |
266 default: | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
267 |
34680 | 268 return NULL; |
269 } | |
33742
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
270 } |
e1539e14d60f
Move purely list related parts of gtkSet() from interface.c to list.c.
ib
parents:
33741
diff
changeset
|
271 |
33741 | 272 /** |
37066 | 273 * @brief Free a string list. |
274 * | |
275 * @param list pointer to the string list | |
276 */ | |
277 void listFree(char ***list) | |
278 { | |
279 if (*list) { | |
280 char **l = *list; | |
281 | |
282 while (*l) { | |
283 free(*l); | |
284 l++; | |
285 } | |
286 | |
287 nfree(*list); | |
288 } | |
289 } | |
290 | |
291 /** | |
37065 | 292 * @brief Set string list to @a entry. |
34622 | 293 * |
37065 | 294 * @param list pointer to the string list |
34622 | 295 * @param entry the new (and only) element of the list |
296 * | |
297 * @note Actually, a new list will be created and the old list will be freed. | |
33741 | 298 */ |
34610 | 299 void listSet(char ***list, const char *entry) |
33741 | 300 { |
37066 | 301 listFree(list); |
33741 | 302 |
34623 | 303 *list = malloc(2 * sizeof(char *)); |
34622 | 304 |
305 if (*list) { | |
34623 | 306 (*list)[0] = gstrdup(entry); |
307 (*list)[1] = NULL; | |
34622 | 308 } |
33741 | 309 } |
310 | |
311 /** | |
37065 | 312 * @brief Replace the first element in a string list that starts with @a search. |
34627 | 313 * |
314 * @note If no such element is found, @a replace will be appended. | |
315 * | |
37065 | 316 * @param list pointer to the string list |
34627 | 317 * @param search element to search |
318 * @param replace replacement element | |
33741 | 319 */ |
34610 | 320 void listRepl(char ***list, const char *search, const char *replace) |
33741 | 321 { |
34627 | 322 int i = 0; |
323 char **org = *list; | |
324 | |
325 if (!replace) | |
326 return; | |
33741 | 327 |
328 if (*list) { | |
34627 | 329 size_t len = (search ? strlen(search) : 0); |
330 | |
33741 | 331 for (i = 0; (*list)[i]; i++) { |
34627 | 332 if (gstrncmp((*list)[i], search, len) == 0) { |
33741 | 333 free((*list)[i]); |
34627 | 334 (*list)[i] = strdup(replace); |
33741 | 335 return; |
336 } | |
337 } | |
338 | |
339 *list = realloc(*list, (i + 2) * sizeof(char *)); | |
340 } else | |
341 *list = malloc(2 * sizeof(char *)); | |
342 | |
34627 | 343 if (!*list) { |
344 *list = org; | |
345 return; | |
346 } | |
347 | |
348 (*list)[i] = strdup(replace); | |
33741 | 349 (*list)[i + 1] = NULL; |
350 } | |
35376 | 351 |
352 /** | |
353 * @brief Append or insert a file to the playlist. | |
354 * | |
355 * @param what file to be added | |
356 * @param how command (#PLAYLIST_ITEM_APPEND or #PLAYLIST_ITEM_INSERT) to be performed | |
357 * | |
35493 | 358 * @return #True (ok) or #False (error) |
35376 | 359 */ |
360 int add_to_gui_playlist(const char *what, int how) | |
361 { | |
35378 | 362 const char *file; |
363 char *path; | |
35376 | 364 plItem *item; |
365 | |
35386 | 366 if (!what || !*what || (how != PLAYLIST_ITEM_APPEND && how != PLAYLIST_ITEM_INSERT)) |
35493 | 367 return False; |
35376 | 368 |
35378 | 369 file = mp_basename(what); |
370 path = strdup(what); | |
35376 | 371 |
36154 | 372 if (!path) |
373 return False; | |
374 | |
35378 | 375 if (file > what) |
376 path[file - what - 1] = 0; | |
35376 | 377 else |
35378 | 378 strcpy(path, "."); |
35376 | 379 |
380 item = calloc(1, sizeof(plItem)); | |
381 | |
36155 | 382 if (!item) { |
383 free(path); | |
35493 | 384 return False; |
36155 | 385 } |
35376 | 386 |
35378 | 387 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[list] adding %s/%s\n", path, file); |
35376 | 388 |
35378 | 389 item->name = strdup(file); |
390 item->path = path; | |
35376 | 391 |
392 listMgr(how, item); | |
393 | |
35493 | 394 return True; |
35376 | 395 } |