summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2022-11-26 21:21:25 -0500
committerWilliam Wilgus <me.theuser@yahoo.com>2022-12-01 22:29:35 -0500
commit177a15b2edfd370a1dc441cad45d32b7492ffd2b (patch)
treedd1e55e43bafabbd26ad2e289d543e5634cb29c7
parent773fa7874d1f1fcec65120fcafd746947a8939ee (diff)
downloadrockbox-177a15b2edfd370a1dc441cad45d32b7492ffd2b.tar.gz
rockbox-177a15b2edfd370a1dc441cad45d32b7492ffd2b.zip
playlist_catalog remove static playlist_dir in favor of generation at runtime
this needs tested by the heavy playlist users with the addition of initialize_catalog_buf there shouldn't be any stack overflow concerns since we are no longer creating another max_path sized buffer when one is already available this also simplifies the code a bit rather than carrying around the playlist directory just generate it on the fly copies the directory to the supplied buffer add catbroswe_status to keep track of what browse context(s) are currently in use Change-Id: I145ec501f601c84bb52f2241ed28c6aefab6897b
-rw-r--r--apps/menus/playlist_menu.c4
-rw-r--r--apps/playlist_catalog.c161
-rw-r--r--apps/playlist_catalog.h2
3 files changed, 88 insertions, 79 deletions
diff --git a/apps/menus/playlist_menu.c b/apps/menus/playlist_menu.c
index 357efe6b29..89c93edc2e 100644
--- a/apps/menus/playlist_menu.c
+++ b/apps/menus/playlist_menu.c
@@ -61,8 +61,8 @@ int save_playlist_screen(struct playlist_info* playlist)
61 61
62 if (!dot && len <= 1) 62 if (!dot && len <= 1)
63 { 63 {
64 snprintf(temp, sizeof(temp), "%s%s", 64 catalog_get_directory(temp, sizeof(temp));
65 catalog_get_directory(), DEFAULT_DYNAMIC_PLAYLIST_NAME); 65 strlcat(temp, DEFAULT_DYNAMIC_PLAYLIST_NAME, sizeof(temp));
66 } 66 }
67 67
68 dot = strrchr(temp, '.'); 68 dot = strrchr(temp, '.');
diff --git a/apps/playlist_catalog.c b/apps/playlist_catalog.c
index 619293377c..b160d6c3f4 100644
--- a/apps/playlist_catalog.c
+++ b/apps/playlist_catalog.c
@@ -54,73 +54,73 @@ struct add_track_context {
54 int count; 54 int count;
55}; 55};
56 56
57enum catbrowse_status_flags{
58 CATBROWSE_NOTHING = 0,
59 CATBROWSE_CATVIEW,
60 CATBROWSE_PLAYLIST
61};
62
57/* keep track of most recently used playlist */ 63/* keep track of most recently used playlist */
58static char most_recent_playlist[MAX_PATH]; 64static char most_recent_playlist[MAX_PATH];
65/* we need playlist_dir_length for easy removal of playlist dir prefix */
66static size_t playlist_dir_length;
67/* keep track of what browser(s) are current to prevent reentry */
68static int browser_status = CATBROWSE_NOTHING;
59 69
60/* directory where our playlists our stored */ 70static size_t get_directory(char* dirbuf, size_t dirbuf_sz)
61static char playlist_dir[MAX_PATH];
62static int playlist_dir_length;
63static bool playlist_dir_exists = false;
64
65/* Retrieve playlist directory from config file and verify it exists */
66static bool initialized = false;
67static int initialize_catalog(void)
68{ 71{
72 char *pl_dir = PLAYLIST_CATALOG_DEFAULT_DIR;
69 73
70 if (!initialized) 74 /* directory config is of the format: "dir: /path/to/dir" */
75 if (global_settings.playlist_catalog_dir[0] != '\0')
71 { 76 {
72 bool default_dir = true; 77 pl_dir = global_settings.playlist_catalog_dir;
73 78 }
74 /* directory config is of the format: "dir: /path/to/dir" */
75 if (global_settings.playlist_catalog_dir[0] &&
76 strcmp(global_settings.playlist_catalog_dir,
77 PLAYLIST_CATALOG_DEFAULT_DIR))
78 {
79 strcpy(playlist_dir, global_settings.playlist_catalog_dir);
80 default_dir = false;
81 }
82
83 /* fall back to default directory if no or invalid config */
84 if (default_dir)
85 {
86 strcpy(playlist_dir, PLAYLIST_CATALOG_DEFAULT_DIR);
87 if (!dir_exists(playlist_dir))
88 mkdir(playlist_dir);
89 }
90 79
91 playlist_dir_length = strlen(playlist_dir); 80 /* remove duplicate leading '/' */
81 if (pl_dir[0] == '/' && pl_dir[1] == '/')
82 {
83 pl_dir++;
84 }
92 85
93 /* remove duplicate leading '/' */ 86 return strlcpy(dirbuf, pl_dir, dirbuf_sz);
94 if (playlist_dir[0] == '/' && playlist_dir[1] == '/') 87}
95 {
96 memmove(&playlist_dir[0], &playlist_dir[1], playlist_dir_length); /* gets the \0 too */
97 playlist_dir_length--;
98 }
99 88
100 if (dir_exists(playlist_dir)) 89/* Retrieve playlist directory from config file and verify it exists
101 { 90 * attempts to create directory
102 playlist_dir_exists = true; 91 * catalog dir is returned in dirbuf */
103 memset(most_recent_playlist, 0, sizeof(most_recent_playlist)); 92static int initialize_catalog_buf(char* dirbuf, size_t dirbuf_sz)
104 initialized = true; 93{
105 } 94 playlist_dir_length = get_directory(dirbuf, dirbuf_sz);
95 if (playlist_dir_length >= dirbuf_sz)
96 {
97 return -2;
106 } 98 }
107 99
108 if (!playlist_dir_exists) 100 if (!dir_exists(dirbuf))
109 { 101 {
110 if (mkdir(playlist_dir) < 0) { 102 if (mkdir(dirbuf) < 0) {
111 splashf(HZ*2, ID2P(LANG_CATALOG_NO_DIRECTORY), playlist_dir); 103 splashf(HZ*2, ID2P(LANG_CATALOG_NO_DIRECTORY), dirbuf);
112 return -1; 104 return -1;
113 } 105 }
114 else { 106 else {
115 playlist_dir_exists = true;
116 memset(most_recent_playlist, 0, sizeof(most_recent_playlist)); 107 memset(most_recent_playlist, 0, sizeof(most_recent_playlist));
117 initialized = true;
118 } 108 }
119 } 109 }
120 110
121 return 0; 111 return 0;
122} 112}
123 113
114/* Retrieve playlist directory from config file and verify it exists
115 * attempts to create directory
116 * Don't inline as we want the stack to be freed ASAP */
117static NO_INLINE int initialize_catalog(void)
118{
119 char playlist_dir[MAX_PATH];
120
121 return initialize_catalog_buf(playlist_dir, sizeof(playlist_dir));
122}
123
124void catalog_set_directory(const char* directory) 124void catalog_set_directory(const char* directory)
125{ 125{
126 if (directory == NULL) 126 if (directory == NULL)
@@ -132,36 +132,44 @@ void catalog_set_directory(const char* directory)
132 strmemccpy(global_settings.playlist_catalog_dir, 132 strmemccpy(global_settings.playlist_catalog_dir,
133 directory, sizeof(global_settings.playlist_catalog_dir)); 133 directory, sizeof(global_settings.playlist_catalog_dir));
134 } 134 }
135 initialized = false;
136 initialize_catalog(); 135 initialize_catalog();
137} 136}
138 137
139const char* catalog_get_directory(void) 138void catalog_get_directory(char* dirbuf, size_t dirbuf_sz)
140{ 139{
141 if (initialize_catalog() == -1) 140 if (initialize_catalog_buf(dirbuf, dirbuf_sz) < 0)
142 return ""; 141 {
143 return playlist_dir; 142 dirbuf[0] = '\0';
143 return;
144 }
144} 145}
145 146
146/* Display all playlists in catalog. Selected "playlist" is returned. 147/* Display all playlists in catalog. Selected "playlist" is returned.
147 If "view" mode is set then we're not adding anything into playlist. */ 148 * If status is CATBROWSE_CATVIEW then we're not adding anything into playlist */
148static int display_playlists(char* playlist, bool view) 149static int display_playlists(char* playlist, enum catbrowse_status_flags status)
149{ 150{
150 static bool reopen_last_playlist = false; 151 static bool reopen_last_playlist = false;
151 static int most_recent_selection = 0; 152 static int most_recent_selection = 0;
152 struct browse_context browse; 153 struct browse_context browse;
153 char selected_playlist[MAX_PATH];
154 int result = -1; 154 int result = -1;
155 char selected_playlist[MAX_PATH];
156 selected_playlist[0] = '\0';
157
158 browser_status |= status;
159 bool view = (status == CATBROWSE_CATVIEW);
155 160
156 browse_context_init(&browse, SHOW_M3U, 161 browse_context_init(&browse, SHOW_M3U,
157 BROWSE_SELECTONLY|(view? 0: BROWSE_NO_CONTEXT_MENU), 162 BROWSE_SELECTONLY|(view? 0: BROWSE_NO_CONTEXT_MENU),
158 str(LANG_CATALOG), NOICON, 163 str(LANG_CATALOG), NOICON,
159 playlist_dir, playlist_dir_length + 1 + most_recent_playlist); 164 selected_playlist,
165 playlist_dir_length + 1 + most_recent_playlist);
160 166
161 browse.buf = selected_playlist; 167 browse.buf = selected_playlist;
162 browse.bufsize = sizeof(selected_playlist); 168 browse.bufsize = sizeof(selected_playlist);
163 169
164restart: 170restart:
171 /* set / restore the root directory for the browser */
172 catalog_get_directory(selected_playlist, sizeof(selected_playlist));
165 browse.flags &= ~BROWSE_SELECTED; 173 browse.flags &= ~BROWSE_SELECTED;
166 174
167 if (view && reopen_last_playlist) 175 if (view && reopen_last_playlist)
@@ -169,13 +177,18 @@ restart:
169 switch (playlist_viewer_ex(most_recent_playlist, &most_recent_selection)) 177 switch (playlist_viewer_ex(most_recent_playlist, &most_recent_selection))
170 { 178 {
171 case PLAYLIST_VIEWER_OK: 179 case PLAYLIST_VIEWER_OK:
180 {
172 result = 0; 181 result = 0;
173 break; 182 break;
183 }
174 case PLAYLIST_VIEWER_CANCEL: 184 case PLAYLIST_VIEWER_CANCEL:
185 {
175 reopen_last_playlist = false; 186 reopen_last_playlist = false;
176 goto restart; 187 goto restart;
188 }
177 case PLAYLIST_VIEWER_USB: 189 case PLAYLIST_VIEWER_USB:
178 case PLAYLIST_VIEWER_MAINMENU: 190 case PLAYLIST_VIEWER_MAINMENU:
191 /* Fall through */
179 default: 192 default:
180 break; 193 break;
181 } 194 }
@@ -208,13 +221,18 @@ restart:
208 { 221 {
209 switch (playlist_viewer_ex(selected_playlist, &most_recent_selection)) { 222 switch (playlist_viewer_ex(selected_playlist, &most_recent_selection)) {
210 case PLAYLIST_VIEWER_OK: 223 case PLAYLIST_VIEWER_OK:
224 {
211 reopen_last_playlist = true; 225 reopen_last_playlist = true;
212 result = 0; 226 result = 0;
213 break; 227 break;
228 }
214 case PLAYLIST_VIEWER_CANCEL: 229 case PLAYLIST_VIEWER_CANCEL:
230 {
215 goto restart; 231 goto restart;
232 }
216 case PLAYLIST_VIEWER_USB: 233 case PLAYLIST_VIEWER_USB:
217 case PLAYLIST_VIEWER_MAINMENU: 234 case PLAYLIST_VIEWER_MAINMENU:
235 /* Fall through */
218 default: 236 default:
219 reopen_last_playlist = true; 237 reopen_last_playlist = true;
220 break; 238 break;
@@ -227,7 +245,7 @@ restart:
227 strmemccpy(playlist, selected_playlist, MAX_PATH); 245 strmemccpy(playlist, selected_playlist, MAX_PATH);
228 } 246 }
229 } 247 }
230 248 browser_status &= ~status;
231 return result; 249 return result;
232} 250}
233 251
@@ -356,32 +374,26 @@ exit:
356 close(fd); 374 close(fd);
357 return result; 375 return result;
358} 376}
359static bool in_cat_viewer = false; 377
360bool catalog_view_playlists(void) 378bool catalog_view_playlists(void)
361{ 379{
362 bool retval = true; 380 if ((browser_status & CATBROWSE_CATVIEW) == CATBROWSE_CATVIEW)
363 if (in_cat_viewer)
364 return false; 381 return false;
365 382
366 if (initialize_catalog() == -1) 383 if (initialize_catalog() < 0)
367 return false; 384 return false;
368 385
369 in_cat_viewer = true; 386 return (display_playlists(NULL, CATBROWSE_CATVIEW) >= 0);
370 retval = (display_playlists(NULL, true) != -1);
371 in_cat_viewer = false;
372 return retval;
373} 387}
374 388
375static bool in_add_to_playlist = false;
376bool catalog_add_to_a_playlist(const char* sel, int sel_attr, 389bool catalog_add_to_a_playlist(const char* sel, int sel_attr,
377 bool new_playlist, char *m3u8name) 390 bool new_playlist, char *m3u8name)
378{ 391{
379 int result;
380 char playlist[MAX_PATH + 7]; /* room for /.m3u8\0*/ 392 char playlist[MAX_PATH + 7]; /* room for /.m3u8\0*/
381 if (in_add_to_playlist) 393 if ((browser_status & CATBROWSE_PLAYLIST) == CATBROWSE_PLAYLIST)
382 return false; 394 return false;
383 395
384 if (initialize_catalog() == -1) 396 if (initialize_catalog_buf(playlist, sizeof(playlist)) < 0)
385 return false; 397 return false;
386 398
387 if (new_playlist) 399 if (new_playlist)
@@ -391,7 +403,7 @@ bool catalog_add_to_a_playlist(const char* sel, int sel_attr,
391 { 403 {
392 const char *name; 404 const char *name;
393 /* If sel is empty, root, or playlist directory we use 'all' */ 405 /* If sel is empty, root, or playlist directory we use 'all' */
394 if (!sel || !strcmp(sel, "/") || !strcmp(sel, playlist_dir)) 406 if (!sel || !strcmp(sel, "/") || !strcmp(sel, playlist))
395 { 407 {
396 sel = "/"; 408 sel = "/";
397 name = "/all"; 409 name = "/all";
@@ -399,9 +411,10 @@ bool catalog_add_to_a_playlist(const char* sel, int sel_attr,
399 else /*If sel is a folder, we prefill the text field with its name*/ 411 else /*If sel is a folder, we prefill the text field with its name*/
400 name = strrchr(sel, '/'); 412 name = strrchr(sel, '/');
401 413
402 snprintf(playlist, MAX_PATH + 1, "%s/%s", 414 if (name == NULL || ((sel_attr & ATTR_DIRECTORY) != ATTR_DIRECTORY))
403 playlist_dir, 415 name = "/";
404 (name!=NULL && (sel_attr & ATTR_DIRECTORY))?name+1:""); 416
417 strlcat(playlist, name, sizeof(playlist));
405 } 418 }
406 else 419 else
407 strmemccpy(playlist, m3u8name, MAX_PATH); 420 strmemccpy(playlist, m3u8name, MAX_PATH);
@@ -417,11 +430,7 @@ bool catalog_add_to_a_playlist(const char* sel, int sel_attr,
417 } 430 }
418 else 431 else
419 { 432 {
420 in_add_to_playlist = true; 433 if (display_playlists(playlist, CATBROWSE_PLAYLIST) < 0)
421 result = display_playlists(playlist, false);
422 in_add_to_playlist = false;
423
424 if (result == -1)
425 return false; 434 return false;
426 } 435 }
427 436
diff --git a/apps/playlist_catalog.h b/apps/playlist_catalog.h
index 17efd0ea7e..bb16e2dad9 100644
--- a/apps/playlist_catalog.h
+++ b/apps/playlist_catalog.h
@@ -22,7 +22,7 @@
22#define _PLAYLIST_CATALOG_H_ 22#define _PLAYLIST_CATALOG_H_
23 23
24/* Gets the configured playlist catalog dir */ 24/* Gets the configured playlist catalog dir */
25const char* catalog_get_directory(void); 25void catalog_get_directory(char* dirbuf, size_t dirbuf_sz);
26 26
27/* Set the playlist catalog dir */ 27/* Set the playlist catalog dir */
28void catalog_set_directory(const char* directory); 28void catalog_set_directory(const char* directory);