diff --git a/apps/logfdisp.c b/apps/logfdisp.c index bfe37bc3fb..d55b3ba773 100644 --- a/apps/logfdisp.c +++ b/apps/logfdisp.c @@ -62,8 +62,8 @@ bool logfdisplay(void) #endif :LCD_WIDTH)/w; - if (columns > MAX_LOGF_ENTRY) - columns = MAX_LOGF_ENTRY; + if (columns > MAX_LOGF_ENTRY+1) + columns = MAX_LOGF_ENTRY+1; if(!lines) return false; @@ -83,7 +83,12 @@ bool logfdisplay(void) } memcpy(buffer, logfbuffer[index], columns); - buffer[columns]=0; + if (logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_CONTINUE_LINE) + buffer[columns-1] = '>'; + else if (logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_MULTI_LINE) + buffer[columns-1] = '\0'; + buffer[columns] = '\0'; + lcd_puts(0, i, buffer); } lcd_update(); @@ -113,24 +118,61 @@ bool logfdump(void) fd = open(ROCKBOX_DIR "/logf.txt", O_CREAT|O_WRONLY|O_TRUNC); if(-1 != fd) { - unsigned char buffer[MAX_LOGF_ENTRY +1]; + unsigned char buffer[MAX_LOGF_ONE_LINE_SIZE +1]; + unsigned char *ptr; int index = logfindex-1; int stop = logfindex; + int tindex; + bool dumpwrap = false; + bool multiline; - - while(index != stop) { + while(!dumpwrap || (index >= stop)) { if(index < 0) { if(logfwrap) + { index = MAX_LOGF_LINES-1; + dumpwrap = true; + } else break; /* done */ } + + multiline = false; + if (logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_MULTI_LINE) + { + multiline = true; + do { + index--; + if(index < 0) { + if(logfwrap) + { + index = MAX_LOGF_LINES-1; + dumpwrap = true; + } + else + goto end_loop; + } + } while(logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_CONTINUE_LINE); + index++; + if (index >= MAX_LOGF_LINES) + index = 0; + } + + tindex = index-1; + ptr = buffer; + do { + tindex++; + memcpy(ptr, logfbuffer[tindex], MAX_LOGF_ENTRY); + ptr += MAX_LOGF_ENTRY; + if (tindex >= MAX_LOGF_LINES) + tindex = 0; + } while(logfbuffer[tindex][MAX_LOGF_ENTRY] == LOGF_TERMINATE_CONTINUE_LINE); + *ptr = '\0'; - memcpy(buffer, logfbuffer[index], MAX_LOGF_ENTRY); - buffer[MAX_LOGF_ENTRY]=0; fdprintf(fd, "%s\n", buffer); index--; } +end_loop: close(fd); } return false; diff --git a/firmware/export/logf.h b/firmware/export/logf.h index d3644b5985..4926fe5ef2 100644 --- a/firmware/export/logf.h +++ b/firmware/export/logf.h @@ -29,10 +29,14 @@ #ifndef __PCTOOL__ #define MAX_LOGF_LINES 1000 -#define MAX_LOGF_ENTRY 30 -#define MAX_LOGF_DATASIZE (MAX_LOGF_ENTRY*MAX_LOGF_LINES) +#define MAX_LOGF_ENTRY 29 +#define MAX_LOGF_ONE_LINE_SIZE 200 -extern unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY]; +#define LOGF_TERMINATE_ONE_LINE 0x00 +#define LOGF_TERMINATE_CONTINUE_LINE 0x01 +#define LOGF_TERMINATE_MULTI_LINE 0x02 + +extern unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY+1]; extern int logfindex; extern bool logfwrap; #endif /* __PCTOOL__ */ diff --git a/firmware/logf.c b/firmware/logf.c index 9599547907..539c2af9da 100644 --- a/firmware/logf.c +++ b/firmware/logf.c @@ -20,10 +20,23 @@ ****************************************************************************/ /* - * logf() logs MAX_LOGF_ENTRY (21) bytes per entry in a circular buffer. Each + * logf() logs MAX_LOGF_ENTRY (29) bytes per entry in a circular buffer. Each * logged string is space- padded for easier and faster output on screen. Just * output MAX_LOGF_ENTRY characters on each line. MAX_LOGF_ENTRY bytes fit * nicely on the iRiver remote LCD (128 pixels with an 8x6 pixels font). + * + * When the length of log exceeds MAX_LOGF_ENTRY bytes, dividing into the + * string of length is MAX_LOGF_ENTRY-1 bytes. + * + * logfbuffer[*]: + * + * |<- MAX_LOGF_ENTRY bytes ->|1| + * | log data area |T| + * + * T : log terminate flag + * == LOGF_TERMINATE_ONE_LINE(0x00) : log data end (one line) + * == LOGF_TERMINATE_CONTINUE_LINE(0x01) : log data continues + * == LOGF_TERMINATE_MULTI_LINE(0x02) : log data end (multi line) */ #include @@ -43,7 +56,7 @@ #ifdef ROCKBOX_HAS_LOGF #ifndef __PCTOOL__ -unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY]; +unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY+1]; int logfindex; bool logfwrap; #endif @@ -84,6 +97,15 @@ static void displayremote(void) #define displayremote() #endif +static void check_logfindex(void) +{ + if(logfindex >= MAX_LOGF_LINES) { + /* wrap */ + logfwrap = true; + logfindex = 0; + } +} + #ifdef __PCTOOL__ void _logf(const char *format, ...) { @@ -98,17 +120,17 @@ void _logf(const char *format, ...) void _logf(const char *format, ...) { int len; + int tlen; + unsigned char buf[MAX_LOGF_ONE_LINE_SIZE]; unsigned char *ptr; va_list ap; - va_start(ap, format); + bool multiline = false; - if(logfindex >= MAX_LOGF_LINES) { - /* wrap */ - logfwrap = true; - logfindex = 0; - } - ptr = logfbuffer[logfindex]; - len = vsnprintf(ptr, MAX_LOGF_ENTRY, format, ap); + va_start(ap, format); + vsnprintf(buf, MAX_LOGF_ONE_LINE_SIZE, format, ap); + va_end(ap); + + len = strlen(buf); #ifdef HAVE_SERIAL serial_tx(ptr); serial_tx("\r\n"); @@ -118,10 +140,26 @@ void _logf(const char *format, ...) usb_serial_send("\r\n",2); #endif - va_end(ap); + tlen = 0; + check_logfindex(); + while(len > MAX_LOGF_ENTRY) + { + ptr = logfbuffer[logfindex]; + strncpy(ptr, buf + tlen, MAX_LOGF_ENTRY); + ptr[MAX_LOGF_ENTRY] = LOGF_TERMINATE_CONTINUE_LINE; + logfindex++; + check_logfindex(); + len -= MAX_LOGF_ENTRY; + tlen += MAX_LOGF_ENTRY; + multiline = true; + } + ptr = logfbuffer[logfindex]; + strcpy(ptr, buf + tlen); + if(len < MAX_LOGF_ENTRY) /* pad with spaces up to the MAX_LOGF_ENTRY byte border */ memset(ptr+len, ' ', MAX_LOGF_ENTRY-len); + ptr[MAX_LOGF_ENTRY] = (multiline)?LOGF_TERMINATE_MULTI_LINE:LOGF_TERMINATE_ONE_LINE; logfindex++; /* leave it where we write the next time */