mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Fixed a crash in the Schedule menu with events that have no title (cEvent::FixEpgBugs() now assigns a "No title" string to events that have no title)
This commit is contained in:
parent
c60129ed78
commit
837f5e2ea9
@ -936,6 +936,7 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi>
|
|||||||
for reporting a bug in handling key macros with keys after @plugin
|
for reporting a bug in handling key macros with keys after @plugin
|
||||||
for adding compiler options "-fPIC -g" to all plugins
|
for adding compiler options "-fPIC -g" to all plugins
|
||||||
for adding a leading '0' to the day in the DayDateTime() function
|
for adding a leading '0' to the day in the DayDateTime() function
|
||||||
|
for reporting a crash in the Schedule menu with events that have no title
|
||||||
|
|
||||||
Ralf Klueber <ralf.klueber@vodafone.com>
|
Ralf Klueber <ralf.klueber@vodafone.com>
|
||||||
for reporting a bug in cutting a recording if there is only a single editing mark
|
for reporting a bug in cutting a recording if there is only a single editing mark
|
||||||
|
3
HISTORY
3
HISTORY
@ -4202,3 +4202,6 @@ Video Disk Recorder Revision History
|
|||||||
pointers from cChannel objects (reported by Malte Schröder).
|
pointers from cChannel objects (reported by Malte Schröder).
|
||||||
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
|
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
|
||||||
- Improved NULL checking in strreplace().
|
- Improved NULL checking in strreplace().
|
||||||
|
- Fixed a crash in the Schedule menu with events that have no title (reported by
|
||||||
|
Rolf Ahrenberg). cEvent::FixEpgBugs() now assigns a "No title" string to events
|
||||||
|
that have no title.
|
||||||
|
361
epg.c
361
epg.c
@ -7,7 +7,7 @@
|
|||||||
* Original version (as used in VDR before 1.3.0) written by
|
* Original version (as used in VDR before 1.3.0) written by
|
||||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||||
*
|
*
|
||||||
* $Id: epg.c 1.50 2006/01/20 13:42:38 kls Exp $
|
* $Id: epg.c 1.51 2006/01/20 14:09:48 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "epg.h"
|
#include "epg.h"
|
||||||
@ -422,197 +422,196 @@ void cEvent::FixEpgBugs(void)
|
|||||||
strreplace(description, '\x86', ' ');
|
strreplace(description, '\x86', ' ');
|
||||||
strreplace(description, '\x87', ' ');
|
strreplace(description, '\x87', ' ');
|
||||||
|
|
||||||
|
if (!title) {
|
||||||
|
// we don't want any "(null)" titles
|
||||||
|
title = strcpyrealloc(title, tr("No title"));
|
||||||
|
EpgBugFixStat(12, ChannelID());
|
||||||
|
}
|
||||||
|
|
||||||
if (Setup.EPGBugfixLevel == 0)
|
if (Setup.EPGBugfixLevel == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Some TV stations apparently have their own idea about how to fill in the
|
// Some TV stations apparently have their own idea about how to fill in the
|
||||||
// EPG data. Let's fix their bugs as good as we can:
|
// EPG data. Let's fix their bugs as good as we can:
|
||||||
if (title) {
|
|
||||||
|
|
||||||
// Some channels put the ShortText in quotes and use either the ShortText
|
// Some channels put the ShortText in quotes and use either the ShortText
|
||||||
// or the Description field, depending on how long the string is:
|
// or the Description field, depending on how long the string is:
|
||||||
//
|
//
|
||||||
// Title
|
// Title
|
||||||
// "ShortText". Description
|
// "ShortText". Description
|
||||||
//
|
//
|
||||||
if ((shortText == NULL) != (description == NULL)) {
|
if ((shortText == NULL) != (description == NULL)) {
|
||||||
char *p = shortText ? shortText : description;
|
char *p = shortText ? shortText : description;
|
||||||
if (*p == '"') {
|
if (*p == '"') {
|
||||||
const char *delim = "\".";
|
const char *delim = "\".";
|
||||||
char *e = strstr(p + 1, delim);
|
char *e = strstr(p + 1, delim);
|
||||||
if (e) {
|
if (e) {
|
||||||
*e = 0;
|
*e = 0;
|
||||||
char *s = strdup(p + 1);
|
char *s = strdup(p + 1);
|
||||||
char *d = strdup(e + strlen(delim));
|
char *d = strdup(e + strlen(delim));
|
||||||
free(shortText);
|
|
||||||
free(description);
|
|
||||||
shortText = s;
|
|
||||||
description = d;
|
|
||||||
EpgBugFixStat(1, ChannelID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some channels put the Description into the ShortText (preceded
|
|
||||||
// by a blank) if there is no actual ShortText and the Description
|
|
||||||
// is short enough:
|
|
||||||
//
|
|
||||||
// Title
|
|
||||||
// Description
|
|
||||||
//
|
|
||||||
if (shortText && !description) {
|
|
||||||
if (*shortText == ' ') {
|
|
||||||
memmove(shortText, shortText + 1, strlen(shortText));
|
|
||||||
description = shortText;
|
|
||||||
shortText = NULL;
|
|
||||||
EpgBugFixStat(2, ChannelID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sometimes they repeat the Title in the ShortText:
|
|
||||||
//
|
|
||||||
// Title
|
|
||||||
// Title
|
|
||||||
//
|
|
||||||
if (shortText && strcmp(title, shortText) == 0) {
|
|
||||||
free(shortText);
|
|
||||||
shortText = NULL;
|
|
||||||
EpgBugFixStat(3, ChannelID());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some channels put the ShortText between double quotes, which is nothing
|
|
||||||
// but annoying (some even put a '.' after the closing '"'):
|
|
||||||
//
|
|
||||||
// Title
|
|
||||||
// "ShortText"[.]
|
|
||||||
//
|
|
||||||
if (shortText && *shortText == '"') {
|
|
||||||
int l = strlen(shortText);
|
|
||||||
if (l > 2 && (shortText[l - 1] == '"' || (shortText[l - 1] == '.' && shortText[l - 2] == '"'))) {
|
|
||||||
memmove(shortText, shortText + 1, l);
|
|
||||||
char *p = strrchr(shortText, '"');
|
|
||||||
if (p)
|
|
||||||
*p = 0;
|
|
||||||
EpgBugFixStat(4, ChannelID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Setup.EPGBugfixLevel <= 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Some channels apparently try to do some formatting in the texts,
|
|
||||||
// which is a bad idea because they have no way of knowing the width
|
|
||||||
// of the window that will actually display the text.
|
|
||||||
// Remove excess whitespace:
|
|
||||||
title = compactspace(title);
|
|
||||||
shortText = compactspace(shortText);
|
|
||||||
description = compactspace(description);
|
|
||||||
|
|
||||||
#define MAX_USEFUL_EPISODE_LENGTH 40
|
|
||||||
// Some channels put a whole lot of information in the ShortText and leave
|
|
||||||
// the Description totally empty. So if the ShortText length exceeds
|
|
||||||
// MAX_USEFUL_EPISODE_LENGTH, let's put this into the Description
|
|
||||||
// instead:
|
|
||||||
if (!isempty(shortText) && isempty(description)) {
|
|
||||||
if (strlen(shortText) > MAX_USEFUL_EPISODE_LENGTH) {
|
|
||||||
free(description);
|
|
||||||
description = shortText;
|
|
||||||
shortText = NULL;
|
|
||||||
EpgBugFixStat(6, ChannelID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some channels put the same information into ShortText and Description.
|
|
||||||
// In that case we delete one of them:
|
|
||||||
if (shortText && description && strcmp(shortText, description) == 0) {
|
|
||||||
if (strlen(shortText) > MAX_USEFUL_EPISODE_LENGTH) {
|
|
||||||
free(shortText);
|
free(shortText);
|
||||||
shortText = NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
free(description);
|
free(description);
|
||||||
description = NULL;
|
shortText = s;
|
||||||
|
description = d;
|
||||||
|
EpgBugFixStat(1, ChannelID());
|
||||||
}
|
}
|
||||||
EpgBugFixStat(7, ChannelID());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some channels use the ` ("backtick") character, where a ' (single quote)
|
|
||||||
// would be normally used. Actually, "backticks" in normal text don't make
|
|
||||||
// much sense, so let's replace them:
|
|
||||||
strreplace(title, '`', '\'');
|
|
||||||
strreplace(shortText, '`', '\'');
|
|
||||||
strreplace(description, '`', '\'');
|
|
||||||
|
|
||||||
if (Setup.EPGBugfixLevel <= 2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// The stream components have a "description" field which some channels
|
|
||||||
// apparently have no idea of how to set correctly:
|
|
||||||
if (components) {
|
|
||||||
for (int i = 0; i < components->NumComponents(); i++) {
|
|
||||||
tComponent *p = components->Component(i);
|
|
||||||
switch (p->stream) {
|
|
||||||
case 0x01: { // video
|
|
||||||
if (p->description) {
|
|
||||||
if (strcasecmp(p->description, "Video") == 0 ||
|
|
||||||
strcasecmp(p->description, "Bildformat") == 0) {
|
|
||||||
// Yes, we know it's video - that's what the 'stream' code
|
|
||||||
// is for! But _which_ video is it?
|
|
||||||
free(p->description);
|
|
||||||
p->description = NULL;
|
|
||||||
EpgBugFixStat(8, ChannelID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!p->description) {
|
|
||||||
switch (p->type) {
|
|
||||||
case 0x01:
|
|
||||||
case 0x05: p->description = strdup("4:3"); break;
|
|
||||||
case 0x02:
|
|
||||||
case 0x03:
|
|
||||||
case 0x06:
|
|
||||||
case 0x07: p->description = strdup("16:9"); break;
|
|
||||||
case 0x04:
|
|
||||||
case 0x08: p->description = strdup(">16:9"); break;
|
|
||||||
case 0x09:
|
|
||||||
case 0x0D: p->description = strdup("HD 4:3"); break;
|
|
||||||
case 0x0A:
|
|
||||||
case 0x0B:
|
|
||||||
case 0x0E:
|
|
||||||
case 0x0F: p->description = strdup("HD 16:9"); break;
|
|
||||||
case 0x0C:
|
|
||||||
case 0x10: p->description = strdup("HD >16:9"); break;
|
|
||||||
}
|
|
||||||
EpgBugFixStat(9, ChannelID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x02: { // audio
|
|
||||||
if (p->description) {
|
|
||||||
if (strcasecmp(p->description, "Audio") == 0) {
|
|
||||||
// Yes, we know it's audio - that's what the 'stream' code
|
|
||||||
// is for! But _which_ audio is it?
|
|
||||||
free(p->description);
|
|
||||||
p->description = NULL;
|
|
||||||
EpgBugFixStat(10, ChannelID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!p->description) {
|
|
||||||
switch (p->type) {
|
|
||||||
case 0x05: p->description = strdup("Dolby Digital"); break;
|
|
||||||
// all others will just display the language
|
|
||||||
}
|
|
||||||
EpgBugFixStat(11, ChannelID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// we don't want any "(null)" titles
|
// Some channels put the Description into the ShortText (preceded
|
||||||
title = strcpyrealloc(title, tr("No title"));
|
// by a blank) if there is no actual ShortText and the Description
|
||||||
EpgBugFixStat(12, ChannelID());
|
// is short enough:
|
||||||
|
//
|
||||||
|
// Title
|
||||||
|
// Description
|
||||||
|
//
|
||||||
|
if (shortText && !description) {
|
||||||
|
if (*shortText == ' ') {
|
||||||
|
memmove(shortText, shortText + 1, strlen(shortText));
|
||||||
|
description = shortText;
|
||||||
|
shortText = NULL;
|
||||||
|
EpgBugFixStat(2, ChannelID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sometimes they repeat the Title in the ShortText:
|
||||||
|
//
|
||||||
|
// Title
|
||||||
|
// Title
|
||||||
|
//
|
||||||
|
if (shortText && strcmp(title, shortText) == 0) {
|
||||||
|
free(shortText);
|
||||||
|
shortText = NULL;
|
||||||
|
EpgBugFixStat(3, ChannelID());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some channels put the ShortText between double quotes, which is nothing
|
||||||
|
// but annoying (some even put a '.' after the closing '"'):
|
||||||
|
//
|
||||||
|
// Title
|
||||||
|
// "ShortText"[.]
|
||||||
|
//
|
||||||
|
if (shortText && *shortText == '"') {
|
||||||
|
int l = strlen(shortText);
|
||||||
|
if (l > 2 && (shortText[l - 1] == '"' || (shortText[l - 1] == '.' && shortText[l - 2] == '"'))) {
|
||||||
|
memmove(shortText, shortText + 1, l);
|
||||||
|
char *p = strrchr(shortText, '"');
|
||||||
|
if (p)
|
||||||
|
*p = 0;
|
||||||
|
EpgBugFixStat(4, ChannelID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Setup.EPGBugfixLevel <= 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Some channels apparently try to do some formatting in the texts,
|
||||||
|
// which is a bad idea because they have no way of knowing the width
|
||||||
|
// of the window that will actually display the text.
|
||||||
|
// Remove excess whitespace:
|
||||||
|
title = compactspace(title);
|
||||||
|
shortText = compactspace(shortText);
|
||||||
|
description = compactspace(description);
|
||||||
|
|
||||||
|
#define MAX_USEFUL_EPISODE_LENGTH 40
|
||||||
|
// Some channels put a whole lot of information in the ShortText and leave
|
||||||
|
// the Description totally empty. So if the ShortText length exceeds
|
||||||
|
// MAX_USEFUL_EPISODE_LENGTH, let's put this into the Description
|
||||||
|
// instead:
|
||||||
|
if (!isempty(shortText) && isempty(description)) {
|
||||||
|
if (strlen(shortText) > MAX_USEFUL_EPISODE_LENGTH) {
|
||||||
|
free(description);
|
||||||
|
description = shortText;
|
||||||
|
shortText = NULL;
|
||||||
|
EpgBugFixStat(6, ChannelID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some channels put the same information into ShortText and Description.
|
||||||
|
// In that case we delete one of them:
|
||||||
|
if (shortText && description && strcmp(shortText, description) == 0) {
|
||||||
|
if (strlen(shortText) > MAX_USEFUL_EPISODE_LENGTH) {
|
||||||
|
free(shortText);
|
||||||
|
shortText = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
free(description);
|
||||||
|
description = NULL;
|
||||||
|
}
|
||||||
|
EpgBugFixStat(7, ChannelID());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some channels use the ` ("backtick") character, where a ' (single quote)
|
||||||
|
// would be normally used. Actually, "backticks" in normal text don't make
|
||||||
|
// much sense, so let's replace them:
|
||||||
|
strreplace(title, '`', '\'');
|
||||||
|
strreplace(shortText, '`', '\'');
|
||||||
|
strreplace(description, '`', '\'');
|
||||||
|
|
||||||
|
if (Setup.EPGBugfixLevel <= 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The stream components have a "description" field which some channels
|
||||||
|
// apparently have no idea of how to set correctly:
|
||||||
|
if (components) {
|
||||||
|
for (int i = 0; i < components->NumComponents(); i++) {
|
||||||
|
tComponent *p = components->Component(i);
|
||||||
|
switch (p->stream) {
|
||||||
|
case 0x01: { // video
|
||||||
|
if (p->description) {
|
||||||
|
if (strcasecmp(p->description, "Video") == 0 ||
|
||||||
|
strcasecmp(p->description, "Bildformat") == 0) {
|
||||||
|
// Yes, we know it's video - that's what the 'stream' code
|
||||||
|
// is for! But _which_ video is it?
|
||||||
|
free(p->description);
|
||||||
|
p->description = NULL;
|
||||||
|
EpgBugFixStat(8, ChannelID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!p->description) {
|
||||||
|
switch (p->type) {
|
||||||
|
case 0x01:
|
||||||
|
case 0x05: p->description = strdup("4:3"); break;
|
||||||
|
case 0x02:
|
||||||
|
case 0x03:
|
||||||
|
case 0x06:
|
||||||
|
case 0x07: p->description = strdup("16:9"); break;
|
||||||
|
case 0x04:
|
||||||
|
case 0x08: p->description = strdup(">16:9"); break;
|
||||||
|
case 0x09:
|
||||||
|
case 0x0D: p->description = strdup("HD 4:3"); break;
|
||||||
|
case 0x0A:
|
||||||
|
case 0x0B:
|
||||||
|
case 0x0E:
|
||||||
|
case 0x0F: p->description = strdup("HD 16:9"); break;
|
||||||
|
case 0x0C:
|
||||||
|
case 0x10: p->description = strdup("HD >16:9"); break;
|
||||||
|
}
|
||||||
|
EpgBugFixStat(9, ChannelID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x02: { // audio
|
||||||
|
if (p->description) {
|
||||||
|
if (strcasecmp(p->description, "Audio") == 0) {
|
||||||
|
// Yes, we know it's audio - that's what the 'stream' code
|
||||||
|
// is for! But _which_ audio is it?
|
||||||
|
free(p->description);
|
||||||
|
p->description = NULL;
|
||||||
|
EpgBugFixStat(10, ChannelID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!p->description) {
|
||||||
|
switch (p->type) {
|
||||||
|
case 0x05: p->description = strdup("Dolby Digital"); break;
|
||||||
|
// all others will just display the language
|
||||||
|
}
|
||||||
|
EpgBugFixStat(11, ChannelID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user