diff options
author | William Wilgus <wilgus.william@gmail.com> | 2022-11-25 09:49:12 -0500 |
---|---|---|
committer | William Wilgus <wilgus.william@gmail.com> | 2022-11-25 23:39:47 -0500 |
commit | 88ecaf2b8cbee654d66ef3f559679d8d1c390949 (patch) | |
tree | 9cc3493916229ca4783a7a86bce5771e5af7b206 /apps | |
parent | 853d70e938f6b32dc965e92f9d34905fbe7ff0a8 (diff) | |
download | rockbox-88ecaf2b8cbee654d66ef3f559679d8d1c390949.tar.gz rockbox-88ecaf2b8cbee654d66ef3f559679d8d1c390949.zip |
bookmark.c remove static bookmark buffer
Change-Id: Ie23760890e76177acf3700fb8eb73ca7f81f112e
Diffstat (limited to 'apps')
-rw-r--r-- | apps/bookmark.c | 379 |
1 files changed, 210 insertions, 169 deletions
diff --git a/apps/bookmark.c b/apps/bookmark.c index 16bfe1cd2b..f3c712240a 100644 --- a/apps/bookmark.c +++ b/apps/bookmark.c | |||
@@ -43,6 +43,9 @@ | |||
43 | #include "file.h" | 43 | #include "file.h" |
44 | #include "pathfuncs.h" | 44 | #include "pathfuncs.h" |
45 | 45 | ||
46 | /*#define LOGF_ENABLE*/ | ||
47 | #include "logf.h" | ||
48 | |||
46 | #define MAX_BOOKMARKS 10 | 49 | #define MAX_BOOKMARKS 10 |
47 | #define MAX_BOOKMARK_SIZE 350 | 50 | #define MAX_BOOKMARK_SIZE 350 |
48 | #define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark" | 51 | #define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark" |
@@ -66,7 +69,8 @@ struct bookmark_list | |||
66 | #define BM_SPEED 0x02 | 69 | #define BM_SPEED 0x02 |
67 | 70 | ||
68 | /* bookmark values */ | 71 | /* bookmark values */ |
69 | static struct { | 72 | static struct resume_info{ |
73 | const struct mp3entry *id3; | ||
70 | int resume_index; | 74 | int resume_index; |
71 | unsigned long resume_offset; | 75 | unsigned long resume_offset; |
72 | int resume_seed; | 76 | int resume_seed; |
@@ -76,15 +80,12 @@ static struct { | |||
76 | /* optional values */ | 80 | /* optional values */ |
77 | int pitch; | 81 | int pitch; |
78 | int speed; | 82 | int speed; |
79 | } bm; | 83 | } resume_info; |
80 | 84 | ||
81 | /* Temp buffer used for reading and filename creation */ | 85 | /* Temp buffer used for reading, create_bookmark and filename creation */ |
82 | #define TEMP_BUF_SIZE (MAX(MAX_BOOKMARK_SIZE, MAX_PATH + 1)) | 86 | #define TEMP_BUF_SIZE (MAX(MAX_BOOKMARK_SIZE, MAX_PATH + 1)) |
83 | static char global_temp_buffer[TEMP_BUF_SIZE]; | 87 | static char global_temp_buffer[TEMP_BUF_SIZE]; |
84 | 88 | ||
85 | /* Bookmark created by create_bookmark*/ | ||
86 | static char global_bookmark[MAX_BOOKMARK_SIZE]; | ||
87 | |||
88 | static const char* skip_token(const char* s) | 89 | static const char* skip_token(const char* s) |
89 | { | 90 | { |
90 | while (*s && *s != ';') | 91 | while (*s && *s != ';') |
@@ -116,10 +117,10 @@ static const char* long_token(const char* s, long* dest) | |||
116 | /* Get the name of the playlist and the name of the track from a bookmark. */ | 117 | /* Get the name of the playlist and the name of the track from a bookmark. */ |
117 | /* Returns true iff both were extracted. */ | 118 | /* Returns true iff both were extracted. */ |
118 | /*-------------------------------------------------------------------------*/ | 119 | /*-------------------------------------------------------------------------*/ |
119 | static bool get_playlist_and_track(const char *bookmark, | 120 | static bool bookmark_get_playlist_and_track(const char *bookmark, |
120 | char **pl_start, | 121 | char **pl_start, |
121 | char **pl_end, | 122 | char **pl_end, |
122 | char **track) | 123 | char **track) |
123 | { | 124 | { |
124 | *pl_start = strchr(bookmark,'/'); | 125 | *pl_start = strchr(bookmark,'/'); |
125 | if (!(*pl_start)) | 126 | if (!(*pl_start)) |
@@ -158,20 +159,20 @@ static bool parse_bookmark(char *filenamebuf, | |||
158 | } | 159 | } |
159 | 160 | ||
160 | /* extract all original bookmark tokens */ | 161 | /* extract all original bookmark tokens */ |
161 | GET_INT_TOKEN(bm.resume_index); | 162 | GET_INT_TOKEN(resume_info.resume_index); |
162 | GET_LONG_TOKEN(bm.resume_offset); | 163 | GET_LONG_TOKEN(resume_info.resume_offset); |
163 | GET_INT_TOKEN(bm.resume_seed); | 164 | GET_INT_TOKEN(resume_info.resume_seed); |
164 | if (!new_format) /* skip deprecated token */ | 165 | if (!new_format) /* skip deprecated token */ |
165 | s = skip_token(s); | 166 | s = skip_token(s); |
166 | GET_LONG_TOKEN(bm.resume_time); | 167 | GET_LONG_TOKEN(resume_info.resume_time); |
167 | GET_INT_TOKEN(bm.repeat_mode); | 168 | GET_INT_TOKEN(resume_info.repeat_mode); |
168 | GET_BOOL_TOKEN(bm.shuffle); | 169 | GET_BOOL_TOKEN(resume_info.shuffle); |
169 | 170 | ||
170 | /* extract all optional bookmark tokens */ | 171 | /* extract all optional bookmark tokens */ |
171 | if (opt_flags & BM_PITCH) | 172 | if (opt_flags & BM_PITCH) |
172 | GET_INT_TOKEN(bm.pitch); | 173 | GET_INT_TOKEN(resume_info.pitch); |
173 | if (opt_flags & BM_SPEED) | 174 | if (opt_flags & BM_SPEED) |
174 | GET_INT_TOKEN(bm.speed); | 175 | GET_INT_TOKEN(resume_info.speed); |
175 | 176 | ||
176 | if (*s == 0) | 177 | if (*s == 0) |
177 | { | 178 | { |
@@ -217,7 +218,15 @@ static int open_temp_bookmark(char *buf, | |||
217 | const char* filename) | 218 | const char* filename) |
218 | { | 219 | { |
219 | /* Opening up a temp bookmark file */ | 220 | /* Opening up a temp bookmark file */ |
220 | return open_pathfmt(buf, bufsz, oflags, "%s.tmp", filename); | 221 | int fd = open_pathfmt(buf, bufsz, oflags, "/%s.tmp", filename); |
222 | #ifdef LOGF_ENABLE | ||
223 | if (oflags & O_PATH) | ||
224 | logf("tempfile path %s", buf); | ||
225 | else | ||
226 | logf("opening tempfile %s", buf); | ||
227 | #endif | ||
228 | return fd; | ||
229 | |||
221 | } | 230 | } |
222 | 231 | ||
223 | /* ----------------------------------------------------------------------- */ | 232 | /* ----------------------------------------------------------------------- */ |
@@ -228,30 +237,31 @@ static bool add_bookmark(const char* bookmark_file_name, | |||
228 | const char* bookmark, | 237 | const char* bookmark, |
229 | bool most_recent) | 238 | bool most_recent) |
230 | { | 239 | { |
231 | int temp_bookmark_file = 0; | 240 | char fnamebuf[MAX_PATH]; |
232 | int bookmark_file = 0; | 241 | int temp_bookmark_file = 0; |
233 | int bookmark_count = 0; | 242 | int bookmark_file = 0; |
234 | char *pl_start = NULL, *bm_pl_start; | 243 | int bookmark_count = 0; |
235 | char *pl_end = NULL, *bm_pl_end; | 244 | char *pl_start = NULL, *bm_pl_start; |
236 | int pl_len = 0, bm_pl_len; | 245 | char *pl_end = NULL, *bm_pl_end; |
237 | char *track = NULL, *bm_track; | 246 | int pl_len = 0, bm_pl_len; |
238 | bool comp_playlist = false; | 247 | char *track = NULL, *bm_track; |
239 | bool comp_track = false; | 248 | bool comp_playlist = false; |
240 | bool equal; | 249 | bool comp_track = false; |
250 | bool equal; | ||
241 | 251 | ||
242 | /* Opening up a temp bookmark file */ | 252 | /* Opening up a temp bookmark file */ |
243 | temp_bookmark_file = open_temp_bookmark(global_temp_buffer, | 253 | temp_bookmark_file = open_temp_bookmark(fnamebuf, |
244 | sizeof(global_temp_buffer), | 254 | sizeof(fnamebuf), |
245 | O_WRONLY | O_CREAT | O_TRUNC, | 255 | O_WRONLY | O_CREAT | O_TRUNC, |
246 | bookmark_file_name); | 256 | bookmark_file_name); |
247 | 257 | ||
248 | if (temp_bookmark_file < 0) | 258 | if (temp_bookmark_file < 0 || !bookmark) |
249 | return false; /* can't open the temp file */ | 259 | return false; /* can't open the temp file or no bookmark */ |
250 | 260 | ||
251 | if (most_recent && ((global_settings.usemrb == BOOKMARK_ONE_PER_PLAYLIST) | 261 | if (most_recent && ((global_settings.usemrb == BOOKMARK_ONE_PER_PLAYLIST) |
252 | || (global_settings.usemrb == BOOKMARK_ONE_PER_TRACK))) | 262 | || (global_settings.usemrb == BOOKMARK_ONE_PER_TRACK))) |
253 | { | 263 | { |
254 | if (get_playlist_and_track(bookmark, &pl_start, &pl_end, &track)) | 264 | if (bookmark_get_playlist_and_track(bookmark, &pl_start, &pl_end, &track)) |
255 | { | 265 | { |
256 | comp_playlist = true; | 266 | comp_playlist = true; |
257 | pl_len = pl_end - pl_start; | 267 | pl_len = pl_end - pl_start; |
@@ -259,13 +269,14 @@ static bool add_bookmark(const char* bookmark_file_name, | |||
259 | comp_track = true; | 269 | comp_track = true; |
260 | } | 270 | } |
261 | } | 271 | } |
262 | 272 | logf("adding bookmark to %s [%s]", fnamebuf, bookmark); | |
263 | /* Writing the new bookmark to the begining of the temp file */ | 273 | /* Writing the new bookmark to the begining of the temp file */ |
264 | write(temp_bookmark_file, bookmark, strlen(bookmark)); | 274 | write(temp_bookmark_file, bookmark, strlen(bookmark)); |
265 | write(temp_bookmark_file, "\n", 1); | 275 | write(temp_bookmark_file, "\n", 1); |
266 | bookmark_count++; | 276 | bookmark_count++; |
267 | 277 | ||
268 | /* Reading in the previous bookmarks and writing them to the temp file */ | 278 | /* Reading in the previous bookmarks and writing them to the temp file */ |
279 | logf("opening old bookmark %s", bookmark_file_name); | ||
269 | bookmark_file = open(bookmark_file_name, O_RDONLY); | 280 | bookmark_file = open(bookmark_file_name, O_RDONLY); |
270 | if (bookmark_file >= 0) | 281 | if (bookmark_file >= 0) |
271 | { | 282 | { |
@@ -283,8 +294,8 @@ static bool add_bookmark(const char* bookmark_file_name, | |||
283 | equal = false; | 294 | equal = false; |
284 | if (comp_playlist) | 295 | if (comp_playlist) |
285 | { | 296 | { |
286 | if (get_playlist_and_track(global_temp_buffer, &bm_pl_start, | 297 | if (bookmark_get_playlist_and_track(global_temp_buffer, |
287 | &bm_pl_end, &bm_track)) | 298 | &bm_pl_start, &bm_pl_end, &bm_track)) |
288 | { | 299 | { |
289 | bm_pl_len = bm_pl_end - bm_pl_start; | 300 | bm_pl_len = bm_pl_end - bm_pl_start; |
290 | equal = (pl_len == bm_pl_len) && | 301 | equal = (pl_len == bm_pl_len) && |
@@ -297,6 +308,7 @@ static bool add_bookmark(const char* bookmark_file_name, | |||
297 | if (!equal) | 308 | if (!equal) |
298 | { | 309 | { |
299 | bookmark_count++; | 310 | bookmark_count++; |
311 | /*logf("copying old bookmark [%s]", global_temp_buffer);*/ | ||
300 | write(temp_bookmark_file, global_temp_buffer, | 312 | write(temp_bookmark_file, global_temp_buffer, |
301 | strlen(global_temp_buffer)); | 313 | strlen(global_temp_buffer)); |
302 | write(temp_bookmark_file, "\n", 1); | 314 | write(temp_bookmark_file, "\n", 1); |
@@ -307,12 +319,12 @@ static bool add_bookmark(const char* bookmark_file_name, | |||
307 | close(temp_bookmark_file); | 319 | close(temp_bookmark_file); |
308 | 320 | ||
309 | /* only retrieve the path*/ | 321 | /* only retrieve the path*/ |
310 | open_temp_bookmark(global_temp_buffer, | 322 | open_temp_bookmark(fnamebuf, |
311 | sizeof(global_temp_buffer), | 323 | sizeof(fnamebuf), |
312 | O_PATH, | 324 | O_PATH, |
313 | bookmark_file_name); | 325 | bookmark_file_name); |
314 | remove(bookmark_file_name); | 326 | remove(bookmark_file_name); |
315 | rename(global_temp_buffer, bookmark_file_name); | 327 | rename(fnamebuf, bookmark_file_name); |
316 | 328 | ||
317 | return true; | 329 | return true; |
318 | } | 330 | } |
@@ -327,7 +339,8 @@ static bool add_bookmark(const char* bookmark_file_name, | |||
327 | /* ----------------------------------------------------------------------- */ | 339 | /* ----------------------------------------------------------------------- */ |
328 | static bool generate_bookmark_file_name(char *filenamebuf, | 340 | static bool generate_bookmark_file_name(char *filenamebuf, |
329 | size_t filenamebufsz, | 341 | size_t filenamebufsz, |
330 | const char *bmarknamein) | 342 | const char *bmarknamein, |
343 | size_t bmarknamelen) | ||
331 | { | 344 | { |
332 | /* if this is a root dir MP3, rename the bookmark file root_dir.bmark */ | 345 | /* if this is a root dir MP3, rename the bookmark file root_dir.bmark */ |
333 | /* otherwise, name it based on the bmarknamein variable */ | 346 | /* otherwise, name it based on the bmarknamein variable */ |
@@ -335,35 +348,129 @@ static bool generate_bookmark_file_name(char *filenamebuf, | |||
335 | strmemccpy(filenamebuf, "/root_dir.bmark", filenamebufsz); | 348 | strmemccpy(filenamebuf, "/root_dir.bmark", filenamebufsz); |
336 | else | 349 | else |
337 | { | 350 | { |
351 | size_t len = strlcpy(filenamebuf, bmarknamein, | ||
352 | MIN(filenamebufsz, bmarknamelen)); | ||
353 | if(len >= filenamebufsz) | ||
354 | return false; | ||
338 | #ifdef HAVE_MULTIVOLUME | 355 | #ifdef HAVE_MULTIVOLUME |
339 | /* The "root" of an extra volume need special handling too. */ | 356 | /* The "root" of an extra volume need special handling too. */ |
340 | const char *filename; | 357 | const char *filename; |
341 | path_strip_volume(bmarknamein, &filename, true); | 358 | path_strip_volume(filenamebuf, &filename, true); |
342 | bool volume_root = *filename == '\0'; | 359 | bool volume_root = *filename == '\0'; |
343 | #endif | 360 | #endif |
344 | size_t len = strlcpy(filenamebuf, bmarknamein, filenamebufsz); | ||
345 | if(len >= filenamebufsz) | ||
346 | return false; | ||
347 | |||
348 | if(filenamebuf[len-1] == '/') { | 361 | if(filenamebuf[len-1] == '/') { |
349 | filenamebuf[len-1] = '\0'; | 362 | filenamebuf[len-1] = '\0'; |
350 | len--; | 363 | len--; |
351 | } | 364 | } |
352 | 365 | ||
366 | const char *name = ".bmark"; | ||
353 | #ifdef HAVE_MULTIVOLUME | 367 | #ifdef HAVE_MULTIVOLUME |
354 | if (volume_root) | 368 | if (volume_root) |
355 | len = strlcat(filenamebuf, "/volume_dir.bmark", filenamebufsz); | 369 | name = "/volume_dir.bmark"; |
356 | else | ||
357 | #endif | 370 | #endif |
358 | len = strlcat(filenamebuf, ".bmark", filenamebufsz); | 371 | len = strlcat(filenamebuf, name, filenamebufsz); |
359 | 372 | ||
360 | if(len >= filenamebufsz) | 373 | if(len >= filenamebufsz) |
361 | return false; | 374 | return false; |
362 | } | 375 | } |
363 | 376 | logf ("generated name '%s' from '%.*s'", | |
377 | filenamebuf, (int)bmarknamelen, bmarknamein); | ||
364 | return true; | 378 | return true; |
365 | } | 379 | } |
366 | 380 | ||
381 | /* GCC 7 and up complain about the snprintf in create_bookmark() when | ||
382 | compiled with -D_FORTIFY_SOURCE or -Wformat-truncation | ||
383 | This is a false positive, so disable it here only */ | ||
384 | /* SHOULD NO LONGER BE NEEDED --Bilgus 11-2022 */ | ||
385 | #if 0 /* __GNUC__ >= 7 */ | ||
386 | #pragma GCC diagnostic push | ||
387 | #pragma GCC diagnostic ignored "-Wformat-truncation" | ||
388 | #endif | ||
389 | /* ----------------------------------------------------------------------- */ | ||
390 | /* This function takes the system resume data and formats it into a valid */ | ||
391 | /* bookmark. */ | ||
392 | /* playlist name and name len are passed back through the name/namelen */ | ||
393 | /* Return is not NULL on successful bookmark format. */ | ||
394 | /* ----------------------------------------------------------------------- */ | ||
395 | static char* create_bookmark(char **name, size_t *namelen) | ||
396 | { | ||
397 | const char *file; | ||
398 | char *buf = global_temp_buffer; | ||
399 | size_t bufsz = sizeof(global_temp_buffer); | ||
400 | |||
401 | if(!resume_info.id3) | ||
402 | return NULL; | ||
403 | |||
404 | size_t bmsz = snprintf(buf, bufsz, | ||
405 | /* new optional bookmark token descriptors should | ||
406 | be inserted just after ';"' in this line... */ | ||
407 | #if defined(HAVE_PITCHCONTROL) | ||
408 | ">%d;%d;%ld;%d;%ld;%d;%d;%ld;%ld;", | ||
409 | #else | ||
410 | ">%d;%d;%ld;%d;%ld;%d;%d;", | ||
411 | #endif | ||
412 | /* ... their flags should go here ... */ | ||
413 | #if defined(HAVE_PITCHCONTROL) | ||
414 | BM_PITCH | BM_SPEED, | ||
415 | #else | ||
416 | 0, | ||
417 | #endif | ||
418 | resume_info.resume_index, | ||
419 | resume_info.id3->offset, | ||
420 | resume_info.resume_seed, | ||
421 | resume_info.id3->elapsed, | ||
422 | resume_info.repeat_mode, | ||
423 | resume_info.shuffle, | ||
424 | /* ...and their values should go here */ | ||
425 | #if defined(HAVE_PITCHCONTROL) | ||
426 | (long)resume_info.pitch, | ||
427 | (long)resume_info.speed | ||
428 | #endif | ||
429 | ); /*sprintf*/ | ||
430 | /* mandatory tokens */ | ||
431 | if (bmsz >= bufsz) /* include NULL*/ | ||
432 | return NULL; | ||
433 | buf += bmsz; | ||
434 | bufsz -= bmsz; | ||
435 | |||
436 | /* create the bookmark */ | ||
437 | playlist_get_name(NULL, buf, bmsz); | ||
438 | bmsz = strlen(buf); | ||
439 | |||
440 | if (bmsz == 0 || (bmsz + 1) >= bufsz) /* include the separator & NULL*/ | ||
441 | return NULL; | ||
442 | |||
443 | *name = buf; /* return the playlist name through the *pointer */ | ||
444 | *namelen = bmsz; /* return the name length through the pointer */ | ||
445 | |||
446 | /* Get the currently playing file minus the path */ | ||
447 | /* This is used when displaying the available bookmarks */ | ||
448 | file = strrchr(resume_info.id3->path,'/'); | ||
449 | if(NULL == file) | ||
450 | return NULL; | ||
451 | |||
452 | if (buf[bmsz - 1] != '/') | ||
453 | file = resume_info.id3->path; | ||
454 | else file++; | ||
455 | |||
456 | buf += bmsz; | ||
457 | bufsz -= (bmsz + 1); | ||
458 | buf[0] = ';'; | ||
459 | buf[1] = '\0'; | ||
460 | |||
461 | strlcat(buf, file, bufsz); | ||
462 | |||
463 | logf("%s [%s]", __func__, global_temp_buffer); | ||
464 | /* checking to see if the bookmark is valid */ | ||
465 | if (parse_bookmark(NULL, 0, global_temp_buffer, false)) | ||
466 | return global_temp_buffer; | ||
467 | else | ||
468 | return NULL; | ||
469 | } | ||
470 | #if 0/* __GNUC__ >= 7*/ | ||
471 | #pragma GCC diagnostic pop /* -Wformat-truncation */ | ||
472 | #endif | ||
473 | |||
367 | /* ----------------------------------------------------------------------- */ | 474 | /* ----------------------------------------------------------------------- */ |
368 | /* This function takes the current current resume information and writes */ | 475 | /* This function takes the current current resume information and writes */ |
369 | /* that to the beginning of the bookmark file. */ | 476 | /* that to the beginning of the bookmark file. */ |
@@ -375,31 +482,43 @@ static bool generate_bookmark_file_name(char *filenamebuf, | |||
375 | /* possible that a bookmark is successfully added to the most recent */ | 482 | /* possible that a bookmark is successfully added to the most recent */ |
376 | /* bookmark list but fails to be added to the bookmark file or vice versa. */ | 483 | /* bookmark list but fails to be added to the bookmark file or vice versa. */ |
377 | /* ------------------------------------------------------------------------*/ | 484 | /* ------------------------------------------------------------------------*/ |
378 | static bool write_bookmark(bool create_bookmark_file, const char *bookmark) | 485 | static bool write_bookmark(bool create_bookmark_file) |
379 | { | 486 | { |
380 | char bm_filename[MAX_PATH]; | 487 | char bm_filename[MAX_PATH]; |
381 | bool ret=true; | 488 | bool ret=true; |
382 | 489 | ||
383 | if (!bookmark) | 490 | char *name = NULL; |
384 | { | 491 | size_t namelen = 0; |
385 | ret = false; /* something didn't happen correctly, do nothing */ | 492 | char* bm; |
386 | } | 493 | |
387 | else | 494 | if (bookmark_is_bookmarkable_state()) |
388 | { | 495 | { |
496 | /* Get some basic resume information */ | ||
497 | playlist_get_resume_info(&(resume_info.resume_index)); | ||
498 | resume_info.resume_seed = playlist_get_seed(NULL); | ||
499 | resume_info.id3 = audio_current_track(); | ||
500 | resume_info.repeat_mode = global_settings.repeat_mode; | ||
501 | resume_info.shuffle = global_settings.playlist_shuffle; | ||
502 | #if defined(HAVE_PITCHCONTROL) | ||
503 | resume_info.pitch = sound_get_pitch(); | ||
504 | resume_info.speed = dsp_get_timestretch(); | ||
505 | #endif | ||
506 | /* writing the most recent bookmark */ | ||
389 | if (global_settings.usemrb) | 507 | if (global_settings.usemrb) |
390 | ret = add_bookmark(RECENT_BOOKMARK_FILE, bookmark, true); | 508 | { |
391 | 509 | /* since we use the same buffer bookmark needs created each time */ | |
510 | bm = create_bookmark(&name, &namelen); | ||
511 | ret = add_bookmark(RECENT_BOOKMARK_FILE, bm, true); | ||
512 | } | ||
392 | 513 | ||
393 | /* writing the bookmark */ | 514 | /* writing the directory bookmark */ |
394 | if (create_bookmark_file) | 515 | if (create_bookmark_file) |
395 | { | 516 | { |
396 | char* name = playlist_get_name(NULL, global_temp_buffer, | 517 | bm = create_bookmark(&name, &namelen); |
397 | sizeof(global_temp_buffer)); | ||
398 | |||
399 | if (generate_bookmark_file_name(bm_filename, | 518 | if (generate_bookmark_file_name(bm_filename, |
400 | sizeof(bm_filename), name)) | 519 | sizeof(bm_filename), name, namelen)) |
401 | { | 520 | { |
402 | ret = ret & add_bookmark(bm_filename, bookmark, false); | 521 | ret &= add_bookmark(bm_filename, bm, false); |
403 | } | 522 | } |
404 | else | 523 | else |
405 | { | 524 | { |
@@ -407,6 +526,8 @@ static bool write_bookmark(bool create_bookmark_file, const char *bookmark) | |||
407 | } | 526 | } |
408 | } | 527 | } |
409 | } | 528 | } |
529 | else | ||
530 | ret = false; | ||
410 | 531 | ||
411 | splash(HZ, ret ? ID2P(LANG_BOOKMARK_CREATE_SUCCESS) | 532 | splash(HZ, ret ? ID2P(LANG_BOOKMARK_CREATE_SUCCESS) |
412 | : ID2P(LANG_BOOKMARK_CREATE_FAILURE)); | 533 | : ID2P(LANG_BOOKMARK_CREATE_FAILURE)); |
@@ -585,9 +706,10 @@ static const char* get_bookmark_info(int list_index, | |||
585 | { | 706 | { |
586 | char time_buf[32]; | 707 | char time_buf[32]; |
587 | 708 | ||
588 | format_time(time_buf, sizeof(time_buf), bm.resume_time); | 709 | format_time(time_buf, sizeof(time_buf), resume_info.resume_time); |
589 | snprintf(buffer, buffer_len, "%s, %d%s", time_buf, bm.resume_index + 1, | 710 | snprintf(buffer, buffer_len, "%s, %d%s", time_buf, |
590 | bm.shuffle ? (char*) str(LANG_BOOKMARK_SHUFFLE) : ""); | 711 | resume_info.resume_index + 1, |
712 | resume_info.shuffle ? (char*) str(LANG_BOOKMARK_SHUFFLE) : ""); | ||
591 | return buffer; | 713 | return buffer; |
592 | } | 714 | } |
593 | } | 715 | } |
@@ -623,13 +745,13 @@ static void say_bookmark(const char* bookmark, | |||
623 | TALK_IDARRAY(LANG_PLAYLIST), true); | 745 | TALK_IDARRAY(LANG_PLAYLIST), true); |
624 | } | 746 | } |
625 | 747 | ||
626 | if(bm.shuffle) | 748 | if(resume_info.shuffle) |
627 | talk_id(LANG_SHUFFLE, true); | 749 | talk_id(LANG_SHUFFLE, true); |
628 | 750 | ||
629 | talk_id(VOICE_BOOKMARK_SELECT_INDEX_TEXT, true); | 751 | talk_id(VOICE_BOOKMARK_SELECT_INDEX_TEXT, true); |
630 | talk_number(bm.resume_index + 1, true); | 752 | talk_number(resume_info.resume_index + 1, true); |
631 | talk_id(LANG_TIME, true); | 753 | talk_id(LANG_TIME, true); |
632 | talk_value(bm.resume_time / 1000, UNIT_TIME, true); | 754 | talk_value(resume_info.resume_time / 1000, UNIT_TIME, true); |
633 | 755 | ||
634 | /* Track filename */ | 756 | /* Track filename */ |
635 | if(!is_dir) | 757 | if(!is_dir) |
@@ -865,106 +987,28 @@ static bool play_bookmark(const char* bookmark) | |||
865 | char fnamebuf[MAX_PATH]; | 987 | char fnamebuf[MAX_PATH]; |
866 | #if defined(HAVE_PITCHCONTROL) | 988 | #if defined(HAVE_PITCHCONTROL) |
867 | /* preset pitch and speed to 100% in case bookmark doesn't have info */ | 989 | /* preset pitch and speed to 100% in case bookmark doesn't have info */ |
868 | bm.pitch = sound_get_pitch(); | 990 | resume_info.pitch = sound_get_pitch(); |
869 | bm.speed = dsp_get_timestretch(); | 991 | resume_info.speed = dsp_get_timestretch(); |
870 | #endif | 992 | #endif |
871 | 993 | ||
872 | if (parse_bookmark(fnamebuf, sizeof(fnamebuf), bookmark, true)) | 994 | if (parse_bookmark(fnamebuf, sizeof(fnamebuf), bookmark, true)) |
873 | { | 995 | { |
874 | global_settings.repeat_mode = bm.repeat_mode; | 996 | global_settings.repeat_mode = resume_info.repeat_mode; |
875 | global_settings.playlist_shuffle = bm.shuffle; | 997 | global_settings.playlist_shuffle = resume_info.shuffle; |
876 | #if defined(HAVE_PITCHCONTROL) | 998 | #if defined(HAVE_PITCHCONTROL) |
877 | sound_set_pitch(bm.pitch); | 999 | sound_set_pitch(resume_info.pitch); |
878 | dsp_set_timestretch(bm.speed); | 1000 | dsp_set_timestretch(resume_info.speed); |
879 | #endif | 1001 | #endif |
880 | if (!warn_on_pl_erase()) | 1002 | if (!warn_on_pl_erase()) |
881 | return false; | 1003 | return false; |
882 | return bookmark_play(global_temp_buffer, bm.resume_index, | 1004 | return bookmark_play(global_temp_buffer, resume_info.resume_index, |
883 | bm.resume_time, bm.resume_offset, bm.resume_seed, fnamebuf); | 1005 | resume_info.resume_time, resume_info.resume_offset, |
1006 | resume_info.resume_seed, fnamebuf); | ||
884 | } | 1007 | } |
885 | 1008 | ||
886 | return false; | 1009 | return false; |
887 | } | 1010 | } |
888 | 1011 | ||
889 | /* GCC 7 and up complain about the snprintf in create_bookmark() when | ||
890 | compiled with -D_FORTIFY_SOURCE or -Wformat-truncation | ||
891 | This is a false positive, so disable it here only */ | ||
892 | #if __GNUC__ >= 7 | ||
893 | #pragma GCC diagnostic push | ||
894 | #pragma GCC diagnostic ignored "-Wformat-truncation" | ||
895 | #endif | ||
896 | /* ----------------------------------------------------------------------- */ | ||
897 | /* This function takes the system resume data and formats it into a valid */ | ||
898 | /* bookmark. */ | ||
899 | /* Returns not NULL on successful bookmark format. */ | ||
900 | /* ----------------------------------------------------------------------- */ | ||
901 | static char* create_bookmark(void) | ||
902 | { | ||
903 | int resume_index = 0; | ||
904 | char *file; | ||
905 | |||
906 | if (!bookmark_is_bookmarkable_state()) | ||
907 | return NULL; /* something didn't happen correctly, do nothing */ | ||
908 | |||
909 | /* grab the currently playing track */ | ||
910 | struct mp3entry *id3 = audio_current_track(); | ||
911 | if(!id3) | ||
912 | return NULL; | ||
913 | |||
914 | /* Get some basic resume information */ | ||
915 | /* queue_resume and queue_resume_index are not used and can be ignored.*/ | ||
916 | playlist_get_resume_info(&resume_index); | ||
917 | |||
918 | /* Get the currently playing file minus the path */ | ||
919 | /* This is used when displaying the available bookmarks */ | ||
920 | file = strrchr(id3->path,'/'); | ||
921 | if(NULL == file) | ||
922 | return NULL; | ||
923 | |||
924 | /* create the bookmark */ | ||
925 | playlist_get_name(NULL, global_temp_buffer, sizeof(global_temp_buffer)); | ||
926 | if (global_temp_buffer[strlen(global_temp_buffer) - 1] != '/') | ||
927 | file = id3->path; | ||
928 | else file++; | ||
929 | snprintf(global_bookmark, sizeof(global_bookmark), | ||
930 | /* new optional bookmark token descriptors should be inserted | ||
931 | just before the "%s;%s" in this line... */ | ||
932 | #if defined(HAVE_PITCHCONTROL) | ||
933 | ">%d;%d;%ld;%d;%ld;%d;%d;%ld;%ld;%s;%s", | ||
934 | #else | ||
935 | ">%d;%d;%ld;%d;%ld;%d;%d;%s;%s", | ||
936 | #endif | ||
937 | /* ... their flags should go here ... */ | ||
938 | #if defined(HAVE_PITCHCONTROL) | ||
939 | BM_PITCH | BM_SPEED, | ||
940 | #else | ||
941 | 0, | ||
942 | #endif | ||
943 | resume_index, | ||
944 | id3->offset, | ||
945 | playlist_get_seed(NULL), | ||
946 | id3->elapsed, | ||
947 | global_settings.repeat_mode, | ||
948 | global_settings.playlist_shuffle, | ||
949 | /* ...and their values should go here */ | ||
950 | #if defined(HAVE_PITCHCONTROL) | ||
951 | (long)sound_get_pitch(), | ||
952 | (long)dsp_get_timestretch(), | ||
953 | #endif | ||
954 | /* more mandatory tokens */ | ||
955 | global_temp_buffer, | ||
956 | file); | ||
957 | |||
958 | /* checking to see if the bookmark is valid */ | ||
959 | if (parse_bookmark(NULL, 0, global_bookmark, false)) | ||
960 | return global_bookmark; | ||
961 | else | ||
962 | return NULL; | ||
963 | } | ||
964 | #if __GNUC__ >= 7 | ||
965 | #pragma GCC diagnostic pop /* -Wformat-truncation */ | ||
966 | #endif | ||
967 | |||
968 | /*-------------------------------------------------------------------------*/ | 1012 | /*-------------------------------------------------------------------------*/ |
969 | /* PUBLIC INTERFACE -------------------------------------------------------*/ | 1013 | /* PUBLIC INTERFACE -------------------------------------------------------*/ |
970 | /*-------------------------------------------------------------------------*/ | 1014 | /*-------------------------------------------------------------------------*/ |
@@ -976,9 +1020,8 @@ static char* create_bookmark(void) | |||
976 | /* ----------------------------------------------------------------------- */ | 1020 | /* ----------------------------------------------------------------------- */ |
977 | bool bookmark_create_menu(void) | 1021 | bool bookmark_create_menu(void) |
978 | { | 1022 | { |
979 | return write_bookmark(true, create_bookmark()); | 1023 | return write_bookmark(true); |
980 | } | 1024 | } |
981 | |||
982 | /* ----------------------------------------------------------------------- */ | 1025 | /* ----------------------------------------------------------------------- */ |
983 | /* This function acts as the load interface from the context menu. */ | 1026 | /* This function acts as the load interface from the context menu. */ |
984 | /* This function determines the bookmark file name and then loads that file*/ | 1027 | /* This function determines the bookmark file name and then loads that file*/ |
@@ -998,7 +1041,7 @@ int bookmark_load_menu(void) | |||
998 | 1041 | ||
999 | char* name = playlist_get_name(NULL, global_temp_buffer, | 1042 | char* name = playlist_get_name(NULL, global_temp_buffer, |
1000 | sizeof(global_temp_buffer)); | 1043 | sizeof(global_temp_buffer)); |
1001 | if (generate_bookmark_file_name(bm_filename, sizeof(bm_filename), name)) | 1044 | if (generate_bookmark_file_name(bm_filename, sizeof(bm_filename), name, -1)) |
1002 | { | 1045 | { |
1003 | ret = select_bookmark(bm_filename, false, &bookmark); | 1046 | ret = select_bookmark(bm_filename, false, &bookmark); |
1004 | if (bookmark != NULL) | 1047 | if (bookmark != NULL) |
@@ -1039,7 +1082,6 @@ bool bookmark_mrb_load() | |||
1039 | /* ----------------------------------------------------------------------- */ | 1082 | /* ----------------------------------------------------------------------- */ |
1040 | bool bookmark_autobookmark(bool prompt_ok) | 1083 | bool bookmark_autobookmark(bool prompt_ok) |
1041 | { | 1084 | { |
1042 | char* bookmark; | ||
1043 | bool update; | 1085 | bool update; |
1044 | 1086 | ||
1045 | if (!bookmark_is_bookmarkable_state()) | 1087 | if (!bookmark_is_bookmarkable_state()) |
@@ -1047,21 +1089,20 @@ bool bookmark_autobookmark(bool prompt_ok) | |||
1047 | 1089 | ||
1048 | audio_pause(); /* first pause playback */ | 1090 | audio_pause(); /* first pause playback */ |
1049 | update = (global_settings.autoupdatebookmark && bookmark_exists()); | 1091 | update = (global_settings.autoupdatebookmark && bookmark_exists()); |
1050 | bookmark = create_bookmark(); | ||
1051 | 1092 | ||
1052 | if (update) | 1093 | if (update) |
1053 | return write_bookmark(true, bookmark); | 1094 | return write_bookmark(true); |
1054 | 1095 | ||
1055 | switch (global_settings.autocreatebookmark) | 1096 | switch (global_settings.autocreatebookmark) |
1056 | { | 1097 | { |
1057 | case BOOKMARK_YES: | 1098 | case BOOKMARK_YES: |
1058 | return write_bookmark(true, bookmark); | 1099 | return write_bookmark(true); |
1059 | 1100 | ||
1060 | case BOOKMARK_NO: | 1101 | case BOOKMARK_NO: |
1061 | return false; | 1102 | return false; |
1062 | 1103 | ||
1063 | case BOOKMARK_RECENT_ONLY_YES: | 1104 | case BOOKMARK_RECENT_ONLY_YES: |
1064 | return write_bookmark(false, bookmark); | 1105 | return write_bookmark(false); |
1065 | } | 1106 | } |
1066 | const char *lines[]={ID2P(LANG_AUTO_BOOKMARK_QUERY)}; | 1107 | const char *lines[]={ID2P(LANG_AUTO_BOOKMARK_QUERY)}; |
1067 | const struct text_message message={lines, 1}; | 1108 | const struct text_message message={lines, 1}; |
@@ -1069,9 +1110,9 @@ bool bookmark_autobookmark(bool prompt_ok) | |||
1069 | if(prompt_ok && gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES) | 1110 | if(prompt_ok && gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES) |
1070 | { | 1111 | { |
1071 | if (global_settings.autocreatebookmark == BOOKMARK_RECENT_ONLY_ASK) | 1112 | if (global_settings.autocreatebookmark == BOOKMARK_RECENT_ONLY_ASK) |
1072 | return write_bookmark(false, bookmark); | 1113 | return write_bookmark(false); |
1073 | else | 1114 | else |
1074 | return write_bookmark(true, bookmark); | 1115 | return write_bookmark(true); |
1075 | } | 1116 | } |
1076 | return false; | 1117 | return false; |
1077 | } | 1118 | } |
@@ -1093,7 +1134,7 @@ int bookmark_autoload(const char* file) | |||
1093 | return BOOKMARK_DONT_RESUME; | 1134 | return BOOKMARK_DONT_RESUME; |
1094 | 1135 | ||
1095 | /*Checking to see if a bookmark file exists.*/ | 1136 | /*Checking to see if a bookmark file exists.*/ |
1096 | if(!generate_bookmark_file_name(bm_filename, sizeof(bm_filename), file)) | 1137 | if(!generate_bookmark_file_name(bm_filename, sizeof(bm_filename), file, -1)) |
1097 | { | 1138 | { |
1098 | return BOOKMARK_DONT_RESUME; | 1139 | return BOOKMARK_DONT_RESUME; |
1099 | } | 1140 | } |
@@ -1182,7 +1223,7 @@ bool bookmark_exists(void) | |||
1182 | 1223 | ||
1183 | char* name = playlist_get_name(NULL, global_temp_buffer, | 1224 | char* name = playlist_get_name(NULL, global_temp_buffer, |
1184 | sizeof(global_temp_buffer)); | 1225 | sizeof(global_temp_buffer)); |
1185 | if (generate_bookmark_file_name(bm_filename, sizeof(bm_filename), name)) | 1226 | if (generate_bookmark_file_name(bm_filename, sizeof(bm_filename), name, -1)) |
1186 | { | 1227 | { |
1187 | exist = file_exists(bm_filename); | 1228 | exist = file_exists(bm_filename); |
1188 | } | 1229 | } |