From 58e9412bff9947e4514c0d55152bfad91049a60c Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Fri, 2 Sep 2005 01:15:35 +0000 Subject: Added universal functions for creation of numbered filenames and date+time filenames (units with RTC only). Some size optimisations within code using these new functions. Everything should behave as before, except config saving will always find the highest file number + 1 even if the sequence is non-contiguous. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7449 a1c6a512-1295-4272-9138-f99709370657 --- apps/misc.c | 113 ++++++++++++++++++++++++++++++---------------- apps/misc.h | 8 ++++ apps/recorder/recording.c | 47 ++----------------- apps/settings.c | 58 ++++++++---------------- 4 files changed, 104 insertions(+), 122 deletions(-) (limited to 'apps') diff --git a/apps/misc.c b/apps/misc.c index f27263b6b7..6751da9d69 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -89,7 +89,7 @@ char *output_dyn_value(char *buf, int buf_size, int value, tbuf[i] = '\0'; talk_number(value, true); - if (strlen(tbuf)) + if (tbuf[0] != 0) { talk_id(LANG_POINT, true); talk_spell(tbuf, true); @@ -99,10 +99,78 @@ char *output_dyn_value(char *buf, int buf_size, int value, return buf; } +/* Create a filename with a number part in a way that the number is 1 + higher than the highest numbered file matching the same pattern. + It is allowed that buffer and path point to the same memory location, + saving a strcpy(). Path must always be given without trailing slash,. */ +char *create_numbered_filename(char *buffer, const char *path, + const char *prefix, const char *suffix, + int numberlen) +{ + DIR *dir; + struct dirent *entry; + int max_num = 0; + int pathlen; + int prefixlen = strlen(prefix); + char fmtstring[12]; + + if (buffer != path) + strncpy(buffer, path, MAX_PATH); + + pathlen = strlen(buffer); + + dir = opendir(pathlen ? buffer : "/"); + if (!dir) + return NULL; + + while ((entry = readdir(dir))) + { + int curr_num; + + if (strncasecmp(entry->d_name, prefix, prefixlen) + || strcasecmp(entry->d_name + prefixlen + numberlen, suffix)) + continue; + + curr_num = atoi(entry->d_name + prefixlen); + if (curr_num > max_num) + max_num = curr_num; + } + closedir(dir); + + snprintf(fmtstring, sizeof(fmtstring), "/%%s%%0%dd%%s", numberlen); + snprintf(buffer + pathlen, MAX_PATH - pathlen, fmtstring, prefix, + max_num + 1, suffix); + + return buffer; +} + +#ifdef HAVE_RTC +/* Create a filename with a date+time part. + It is allowed that buffer and path point to the same memory location, + saving a strcpy(). Path must always be given without trailing slash. */ +char *create_datetime_filename(char *buffer, const char *path, + const char *prefix, const char *suffix) +{ + struct tm *tm = get_time(); + int pathlen; + + if (buffer != path) + strncpy(buffer, path, MAX_PATH); + + pathlen = strlen(buffer); + snprintf(buffer + pathlen, MAX_PATH - pathlen, + "/%s%02d%02d%02d-%02d%02d%02d%s", prefix, + tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, suffix); + + return buffer; +} +#endif /* HAVE_RTC */ + /* Read (up to) a line of text from fd into buffer and return number of bytes * read (which may be larger than the number of bytes stored in buffer). If - * an error occurs, -1 is returned (and buffer contains whatever could be - * read). A line is terminated by a LF char. Neither LF nor CR chars are + * an error occurs, -1 is returned (and buffer contains whatever could be + * read). A line is terminated by a LF char. Neither LF nor CR chars are * stored in buffer. */ int read_line(int fd, char* buffer, int buffer_size) @@ -212,44 +280,9 @@ void screen_dump(void) #endif #ifdef HAVE_RTC - struct tm *tm = get_time(); - - snprintf(filename, MAX_PATH, "/dump %04d-%02d-%02d %02d-%02d-%02d.bmp", - tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); + create_datetime_filename(filename, "", "dump ", ".bmp"); #else - { - DIR* dir; - int max_dump_file = 1; /* default to dump_0001.bmp */ - dir = opendir("/"); - if (dir) /* found */ - { - /* Search for the highest screendump filename present, - increment behind that. So even with "holes" - (deleted files), the newest will always have the - highest number. */ - while(true) - { - struct dirent* entry; - int curr_dump_file; - /* walk through the directory content */ - entry = readdir(dir); - if (!entry) - { - closedir(dir); - break; /* end of dir */ - } - if (strncasecmp(entry->d_name, "dump_", 5)) - continue; /* no screendump file */ - curr_dump_file = atoi(&entry->d_name[5]); - if (curr_dump_file >= max_dump_file) - max_dump_file = curr_dump_file + 1; - } - } - snprintf(filename, MAX_PATH, - "/dump_%04d.bmp", max_dump_file); - } - + create_numbered_filename(filename, "", "dump_", ".bmp", 4); #endif fh = creat(filename, O_WRONLY); diff --git a/apps/misc.h b/apps/misc.h index 757eee7377..5e7450a7b2 100644 --- a/apps/misc.h +++ b/apps/misc.h @@ -27,6 +27,14 @@ void output_dyn_value(char *buf, int buf_size, int value, const unsigned char **units, bool bin_scale); +char *create_numbered_filename(char *buffer, const char *path, + const char *prefix, const char *suffix, + int numberlen); +#ifdef HAVE_RTC +char *create_datetime_filename(char *buffer, const char *path, + const char *prefix, const char *suffix); +#endif + /* Read (up to) a line of text from fd into buffer and return number of bytes * read (which may be larger than the number of bytes stored in buffer). If * an error occurs, -1 is returned (and buffer contains whatever could be diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c index ea71538322..3fcf97b177 100644 --- a/apps/recorder/recording.c +++ b/apps/recorder/recording.c @@ -164,56 +164,15 @@ void adjust_cursor(void) char *rec_create_filename(char *buffer) { - int fpos; - if(global_settings.rec_directory) getcwd(buffer, MAX_PATH); else strncpy(buffer, rec_base_directory, MAX_PATH); - fpos = strlen(buffer); -#ifdef HAVE_RTC - { - struct tm *tm = get_time(); - - /* Append filename to path: RYYMMDD-HH.MM.SS.mp3 */ - snprintf(&buffer[fpos], MAX_PATH-fpos, - "/R%02d%02d%02d-%02d%02d%02d.mp3", - tm->tm_year%100, tm->tm_mon+1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - } +#ifdef HAVE_RTC + create_datetime_filename(buffer, buffer, "R", ".mp3"); #else - { - DIR* dir; - int max_rec_file = 1; /* default to rec_0001.mp3 */ - dir = opendir(buffer); - if (dir) /* found */ - { - /* Search for the highest recording filename present, - increment behind that. So even with "holes" - (deleted recordings), the newest will always have the - highest number. */ - while(true) - { - struct dirent* entry; - int curr_rec_file; - /* walk through the directory content */ - entry = readdir(dir); - if (!entry) - { - closedir(dir); - break; /* end of dir */ - } - if (strncasecmp(entry->d_name, "rec_", 4)) - continue; /* no recording file */ - curr_rec_file = atoi(&entry->d_name[4]); - if (curr_rec_file >= max_rec_file) - max_rec_file = curr_rec_file + 1; - } - } - snprintf(&buffer[fpos], MAX_PATH-fpos, - "/rec_%04d.mp3", max_rec_file); - } + create_numbered_filename(buffer, buffer, "rec_", ".mp3", 4); #endif return buffer; } diff --git a/apps/settings.c b/apps/settings.c index 6649ce3f89..00ca6c82c3 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -1215,61 +1215,45 @@ static void save_cfg_table(const struct bit_entry* p_table, int count, int fd) bool settings_save_config(void) { - bool done = false; - int fd, i; + int fd; char filename[MAX_PATH]; - - /* find unused filename */ - for (i=0; ; i++) { - snprintf(filename, sizeof filename, ROCKBOX_DIR "/config%02d.cfg", i); - fd = open(filename, O_RDONLY); - if (fd < 0) - break; - close(fd); - } + + create_numbered_filename(filename, ROCKBOX_DIR, "config", ".cfg", 2); /* allow user to modify filename */ - while (!done) { + while (true) { if (!kbd_input(filename, sizeof filename)) { fd = creat(filename,0); if (fd < 0) { lcd_clear_display(); - lcd_puts(0,0,str(LANG_FAILED)); - lcd_update(); - sleep(HZ); + splash(HZ, true, str(LANG_FAILED)); } else - done = true; + break; + } + else { + lcd_clear_display(); + splash(HZ, true, str(LANG_RESET_DONE_CANCEL)); + return false; } - else - break; - } - - /* abort if file couldn't be created */ - if (!done) { - lcd_clear_display(); - lcd_puts(0,0,str(LANG_RESET_DONE_CANCEL)); - lcd_update(); - sleep(HZ); - return false; } - fdprintf(fd, "# .cfg file created by rockbox %s - ", appsversion); - fdprintf(fd, "http://www.rockbox.org\r\n#\r\n"); - fdprintf(fd, "#\r\n# wps / language / font \r\n#\r\n"); + fdprintf(fd, "# .cfg file created by rockbox %s - " + "http://www.rockbox.org\r\n#\r\n" + "#\r\n# wps / language / font \r\n#\r\n", appsversion); if (global_settings.wps_file[0] != 0) fdprintf(fd, "wps: %s/%s.wps\r\n", ROCKBOX_DIR, - global_settings.wps_file); + global_settings.wps_file); if (global_settings.lang_file[0] != 0) - fdprintf(fd, "lang: %s/%s.lng\r\n", ROCKBOX_DIR LANG_DIR, - global_settings.lang_file); + fdprintf(fd, "lang: %s/%s.lng\r\n", ROCKBOX_DIR LANG_DIR, + global_settings.lang_file); #ifdef HAVE_LCD_BITMAP if (global_settings.font_file[0] != 0) fdprintf(fd, "font: %s/%s.fnt\r\n", ROCKBOX_DIR FONT_DIR, - global_settings.font_file); + global_settings.font_file); #endif /* here's the action: write values to file, specified via table */ @@ -1279,10 +1263,8 @@ bool settings_save_config(void) close(fd); lcd_clear_display(); - lcd_puts(0,0,str(LANG_SETTINGS_SAVED1)); - lcd_puts(0,1,str(LANG_SETTINGS_SAVED2)); - lcd_update(); - sleep(HZ); + splash(HZ, true, "%s %s", str(LANG_SETTINGS_SAVED1), + str(LANG_SETTINGS_SAVED2)); return true; } -- cgit v1.2.3