forked from len0rd/rockbox
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
This commit is contained in:
parent
c7240cf844
commit
58e9412bff
4 changed files with 104 additions and 122 deletions
113
apps/misc.c
113
apps/misc.c
|
@ -89,7 +89,7 @@ char *output_dyn_value(char *buf, int buf_size, int value,
|
||||||
tbuf[i] = '\0';
|
tbuf[i] = '\0';
|
||||||
|
|
||||||
talk_number(value, true);
|
talk_number(value, true);
|
||||||
if (strlen(tbuf))
|
if (tbuf[0] != 0)
|
||||||
{
|
{
|
||||||
talk_id(LANG_POINT, true);
|
talk_id(LANG_POINT, true);
|
||||||
talk_spell(tbuf, true);
|
talk_spell(tbuf, true);
|
||||||
|
@ -99,10 +99,78 @@ char *output_dyn_value(char *buf, int buf_size, int value,
|
||||||
return buf;
|
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 (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
|
* 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
|
* 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
|
* read). A line is terminated by a LF char. Neither LF nor CR chars are
|
||||||
* stored in buffer.
|
* stored in buffer.
|
||||||
*/
|
*/
|
||||||
int read_line(int fd, char* buffer, int buffer_size)
|
int read_line(int fd, char* buffer, int buffer_size)
|
||||||
|
@ -212,44 +280,9 @@ void screen_dump(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_RTC
|
#ifdef HAVE_RTC
|
||||||
struct tm *tm = get_time();
|
create_datetime_filename(filename, "", "dump ", ".bmp");
|
||||||
|
|
||||||
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);
|
|
||||||
#else
|
#else
|
||||||
{
|
create_numbered_filename(filename, "", "dump_", ".bmp", 4);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fh = creat(filename, O_WRONLY);
|
fh = creat(filename, O_WRONLY);
|
||||||
|
|
|
@ -27,6 +27,14 @@
|
||||||
void output_dyn_value(char *buf, int buf_size, int value,
|
void output_dyn_value(char *buf, int buf_size, int value,
|
||||||
const unsigned char **units, bool bin_scale);
|
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 (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
|
* 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
|
* an error occurs, -1 is returned (and buffer contains whatever could be
|
||||||
|
|
|
@ -164,56 +164,15 @@ void adjust_cursor(void)
|
||||||
|
|
||||||
char *rec_create_filename(char *buffer)
|
char *rec_create_filename(char *buffer)
|
||||||
{
|
{
|
||||||
int fpos;
|
|
||||||
|
|
||||||
if(global_settings.rec_directory)
|
if(global_settings.rec_directory)
|
||||||
getcwd(buffer, MAX_PATH);
|
getcwd(buffer, MAX_PATH);
|
||||||
else
|
else
|
||||||
strncpy(buffer, rec_base_directory, MAX_PATH);
|
strncpy(buffer, rec_base_directory, MAX_PATH);
|
||||||
|
|
||||||
fpos = strlen(buffer);
|
#ifdef HAVE_RTC
|
||||||
#ifdef HAVE_RTC
|
create_datetime_filename(buffer, buffer, "R", ".mp3");
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
{
|
create_numbered_filename(buffer, buffer, "rec_", ".mp3", 4);
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 settings_save_config(void)
|
||||||
{
|
{
|
||||||
bool done = false;
|
int fd;
|
||||||
int fd, i;
|
|
||||||
char filename[MAX_PATH];
|
char filename[MAX_PATH];
|
||||||
|
|
||||||
/* find unused filename */
|
create_numbered_filename(filename, ROCKBOX_DIR, "config", ".cfg", 2);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allow user to modify filename */
|
/* allow user to modify filename */
|
||||||
while (!done) {
|
while (true) {
|
||||||
if (!kbd_input(filename, sizeof filename)) {
|
if (!kbd_input(filename, sizeof filename)) {
|
||||||
fd = creat(filename,0);
|
fd = creat(filename,0);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
lcd_clear_display();
|
lcd_clear_display();
|
||||||
lcd_puts(0,0,str(LANG_FAILED));
|
splash(HZ, true, str(LANG_FAILED));
|
||||||
lcd_update();
|
|
||||||
sleep(HZ);
|
|
||||||
}
|
}
|
||||||
else
|
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 */
|
fdprintf(fd, "# .cfg file created by rockbox %s - "
|
||||||
if (!done) {
|
"http://www.rockbox.org\r\n#\r\n"
|
||||||
lcd_clear_display();
|
"#\r\n# wps / language / font \r\n#\r\n", appsversion);
|
||||||
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");
|
|
||||||
|
|
||||||
if (global_settings.wps_file[0] != 0)
|
if (global_settings.wps_file[0] != 0)
|
||||||
fdprintf(fd, "wps: %s/%s.wps\r\n", ROCKBOX_DIR,
|
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)
|
if (global_settings.lang_file[0] != 0)
|
||||||
fdprintf(fd, "lang: %s/%s.lng\r\n", ROCKBOX_DIR LANG_DIR,
|
fdprintf(fd, "lang: %s/%s.lng\r\n", ROCKBOX_DIR LANG_DIR,
|
||||||
global_settings.lang_file);
|
global_settings.lang_file);
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
if (global_settings.font_file[0] != 0)
|
if (global_settings.font_file[0] != 0)
|
||||||
fdprintf(fd, "font: %s/%s.fnt\r\n", ROCKBOX_DIR FONT_DIR,
|
fdprintf(fd, "font: %s/%s.fnt\r\n", ROCKBOX_DIR FONT_DIR,
|
||||||
global_settings.font_file);
|
global_settings.font_file);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* here's the action: write values to file, specified via table */
|
/* here's the action: write values to file, specified via table */
|
||||||
|
@ -1279,10 +1263,8 @@ bool settings_save_config(void)
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
lcd_clear_display();
|
lcd_clear_display();
|
||||||
lcd_puts(0,0,str(LANG_SETTINGS_SAVED1));
|
splash(HZ, true, "%s %s", str(LANG_SETTINGS_SAVED1),
|
||||||
lcd_puts(0,1,str(LANG_SETTINGS_SAVED2));
|
str(LANG_SETTINGS_SAVED2));
|
||||||
lcd_update();
|
|
||||||
sleep(HZ);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue