Mercurial > mplayer.hg
annotate gui/util/list.c @ 37160:bb15cab6c059
Add ZLIB_CONST to make the zlib API const-correct.
author | reimar |
---|---|
date | Sat, 23 Aug 2014 13:59:32 +0000 |
parents | ae4f30c4ef02 |
children |
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 /** | |
37067 | 353 * @brief Duplicate a string list (by allocating new memory). |
354 * | |
355 * @note The list must be NULL-terminated. | |
356 * | |
357 * @param list string list to be duplicated | |
358 * | |
359 * @return duplicated list | |
360 */ | |
361 char **listDup(const char *const *list) | |
362 { | |
363 char **dup = NULL; | |
364 | |
365 if (list) { | |
366 int i = 0; | |
367 | |
368 while (list[i]) | |
369 i++; | |
370 | |
371 dup = calloc(i + 1, sizeof(char *)); | |
372 | |
373 if (dup) { | |
374 while (--i >= 0) | |
375 dup[i] = strdup(list[i]); | |
376 } | |
377 } | |
378 | |
379 return dup; | |
380 } | |
381 | |
382 /** | |
35376 | 383 * @brief Append or insert a file to the playlist. |
384 * | |
385 * @param what file to be added | |
386 * @param how command (#PLAYLIST_ITEM_APPEND or #PLAYLIST_ITEM_INSERT) to be performed | |
387 * | |
35493 | 388 * @return #True (ok) or #False (error) |
35376 | 389 */ |
390 int add_to_gui_playlist(const char *what, int how) | |
391 { | |
35378 | 392 const char *file; |
393 char *path; | |
35376 | 394 plItem *item; |
395 | |
35386 | 396 if (!what || !*what || (how != PLAYLIST_ITEM_APPEND && how != PLAYLIST_ITEM_INSERT)) |
35493 | 397 return False; |
35376 | 398 |
35378 | 399 file = mp_basename(what); |
400 path = strdup(what); | |
35376 | 401 |
36154 | 402 if (!path) |
403 return False; | |
404 | |
35378 | 405 if (file > what) |
406 path[file - what - 1] = 0; | |
35376 | 407 else |
35378 | 408 strcpy(path, "."); |
35376 | 409 |
37083 | 410 item = calloc(1, sizeof(*item)); |
35376 | 411 |
36155 | 412 if (!item) { |
413 free(path); | |
35493 | 414 return False; |
36155 | 415 } |
35376 | 416 |
35378 | 417 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[list] adding %s/%s\n", path, file); |
35376 | 418 |
35378 | 419 item->name = strdup(file); |
420 item->path = path; | |
35376 | 421 |
422 listMgr(how, item); | |
423 | |
35493 | 424 return True; |
35376 | 425 } |