Bug Summary

File:changrp.c
Location:line 276, column 6
Description:Value stored to 'chIntEnd' is never read

Annotated Source Code

1/* -*- c++ -*-
2Copyright (C) 2004-2013 Christian Wieninger
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18
19The author can be reached at cwieninger@gmx.de
20
21The project's page is at http://winni.vdr-developer.org/epgsearch
22*/
23
24#include "changrp.h"
25#include "epgsearchtools.h"
26#include "epgsearchcfg.h"
27#include "epgsearchext.h"
28#include <vdr/interface.h>
29
30// -- cChannelGroup -----------------------------------------------------------------
31cChannelGroup::cChannelGroup(void)
32{
33 strcpy(name, "");
34 channels.Clear();
35}
36
37cChannelGroup::~cChannelGroup(void)
38{
39 channels.Clear();
40}
41
42bool cChannelGroup::Parse(const char *s)
43{
44 char *line;
45 char *pos;
46 char *pos_next;
47 int parameter = 1;
48 int valuelen;
49#define MAXVALUELEN(10 * 255) (10 * MaxFileName255)
50
51 char value[MAXVALUELEN(10 * 255)];
52
53 pos = line = strdup(s);
54 pos_next = pos + strlen(pos);
55 if (*pos_next == '\n') *pos_next = 0;
56 while (*pos) {
57 while (*pos == ' ') pos++;
58 if (*pos) {
59 if (*pos != '|') {
60 pos_next = strchr(pos, '|');
61 if (!pos_next)
62 pos_next = pos + strlen(pos);
63 valuelen = pos_next - pos + 1;
64 if (valuelen > MAXVALUELEN(10 * 255))
65 {
66 LogFile.eSysLog("entry '%s' is too long. Will be truncated!", pos);
67 valuelen = MAXVALUELEN(10 * 255);
68 }
69 strn0cpy(value, pos, valuelen);
70 pos = pos_next;
71 switch (parameter) {
72 case 1: strcpy(name,value);
73 break;
74 default:
75 {
76#ifdef __FreeBSD__
77 char *channelbuffer = MALLOC(char, 32)(char *)malloc(sizeof(char) * (32));
78 int numChannels = sscanf(value, "%31[^|]", channelbuffer);
79#else
80 char *channelbuffer = NULL__null;
81 int numChannels = sscanf(value, "%m[^|]", &channelbuffer);
82#endif
83 if (numChannels == 1)
84 {
85 cChannel* channel = Channels.GetByChannelID(tChannelID::FromString(channelbuffer), true, true);
86 if (channel)
87 {
88 cChannelGroupItem* channelitem = new cChannelGroupItem(channel);
89 channels.Add(channelitem);
90 }
91 }
92 free(channelbuffer);
93 }
94 break;
95 } //switch
96 }
97 parameter++;
98 }
99 if (*pos) pos++;
100 } //while
101
102 free(line);
103 return (parameter >= 1) ? true : false;
104}
105
106const char *cChannelGroup::ToText(void)
107{
108 char* channelbuffer = NULL__null;
109 cChannelGroupItem* ChannelGroupItem = channels.First();
110 int index = 0;
111 while (ChannelGroupItem)
112 {
113 cChannel* channel = ChannelGroupItem->channel;
114 if (index++ == 0)
115 channelbuffer = strdup(CHANNELSTRING(channel)(*channel->GetChannelID().ToString()));
116 else
117 {
118 char* temp = channelbuffer;
119 msprintf(&channelbuffer, "%s|%s", channelbuffer, CHANNELSTRING(channel)(*channel->GetChannelID().ToString()));
120 free(temp);
121 }
122 ChannelGroupItem = channels.Next(ChannelGroupItem);
123 }
124 char* buffer = NULL__null;
125 msprintf(&buffer, "%s|%s", name, channelbuffer);
126 free(channelbuffer);
127 return buffer;
128}
129
130int* cChannelGroup::CreateChannelSel()
131{
132 int* channelSel = (int*) malloc(Channels.Count() * sizeof(int));
133 cChannel* channel = Channels.First();
134 int index = 0;
135 while (channel)
136 {
137 if (channel->GroupSep())
138 {
139 channel = Channels.Next(channel);
140 continue;
141 }
142 channelSel[index] = 0;
143 cChannelGroupItem* channelInGroup = channels.First();
144 while (channelInGroup)
145 {
146 if (channel == channelInGroup->channel)
147 {
148 channelSel[index] = 1;
149 break;
150 }
151 channelInGroup = channels.Next(channelInGroup);
152 }
153 index++;
154 channel = Channels.Next(channel);
155 }
156 return channelSel;
157}
158
159void cChannelGroup::CreateChannelList(int* channelSel)
160{
161 channels.Clear();
162 cChannel* channel = Channels.First();
163 int index = 0;
164 while (channel)
165 {
166 if (!channel->GroupSep())
167 {
168 if (channelSel[index] == 1)
169 channels.Add(new cChannelGroupItem(channel));
170 index++;
171 }
172 channel = Channels.Next(channel);
173 }
174}
175
176bool cChannelGroup::Save(FILE *f)
177{
178 return fprintf(f, "%s\n", ToText()) > 0;
179}
180
181bool cChannelGroup::ChannelInGroup(cChannel* channel)
182{
183 cChannelGroupItem* channelInGroup = channels.First();
184 while (channelInGroup)
185 {
186 if (channel == channelInGroup->channel)
187 return true;
188 channelInGroup = channels.Next(channelInGroup);
189 }
190 return false;
191}
192
193// -- cChannelGroups -----------------------------------------------------------------
194int cChannelGroups::GetIndex(char* channelGroup)
195{
196 if (!channelGroup)
197 return -1;
198 cChannelGroup* ChannelGroup = First();
199 int index = 0;
200 while (ChannelGroup)
201 {
202 if (strcmp(channelGroup, ChannelGroup->name) == 0)
203 return index;
204 index++;
205 ChannelGroup = Next(ChannelGroup);
206 }
207 return -1;
208}
209
210cChannelGroup* cChannelGroups::GetGroupByName(const char* channelGroup)
211{
212 if (!channelGroup)
213 return NULL__null;
214 cChannelGroup* ChannelGroup = First();
215 while (ChannelGroup)
216 {
217 if (strcmp(channelGroup, ChannelGroup->name) == 0)
218 return ChannelGroup;
219 ChannelGroup = Next(ChannelGroup);
220 }
221 return NULL__null;
222}
223
224cSearchExt* cChannelGroups::Used(cChannelGroup* group)
225{
226 if (!group)
227 return NULL__null;
228
229 if (SearchExts.Count() == 0)
230 SearchExts.Load(AddDirectory(CONFIGDIR(!ConfigDir?cPlugin::ConfigDirectory():ConfigDir), "epgsearch.conf"));
231
232 cMutexLock SearchExtsLock(&SearchExts);
233 cSearchExt *SearchExt = SearchExts.First();
234 while (SearchExt)
235 {
236 if (SearchExt->useChannel == 2 && strcmp(SearchExt->channelGroup, group->name) == 0)
237 return SearchExt;
238 SearchExt = SearchExts.Next(SearchExt);
239 }
240 return NULL__null;
241}
242
243char** cChannelGroups::CreateMenuitemsList()
244{
245 char** menuitemsChGr = new char*[ChannelGroups.Count()+1];
246 cChannelGroup* ChannelGroup = First();
247 menuitemsChGr[0] = strdup("");
248 int index = 1;
249 while (ChannelGroup)
250 {
251 menuitemsChGr[index++] = ChannelGroup->name;
252 ChannelGroup = Next(ChannelGroup);
253 }
254 return menuitemsChGr;
255}
256
257// -- cMenuChannelGroupItem -----------------------------------------------------------------
258cMenuChannelGroupItem::cMenuChannelGroupItem(cChannelGroup* Group)
259{
260 group = Group;
261 Set();
262}
263
264void cMenuChannelGroupItem::Set(void)
265{
266 cString channelbuffer;
267
268 cChannelGroupItem* channelInGroup = group->channels.First();
269 int channelNr, chIntBegin = -1, chIntEnd = -1, chLast = -1;
270 while (channelInGroup)
271 {
272 channelNr = channelInGroup->channel->Number();
273 if (chIntBegin == -1)
274 chIntBegin = channelNr;
275 if (chIntEnd == -1)
276 chIntEnd = channelNr;
Value stored to 'chIntEnd' is never read
277
278 if (chLast == channelNr-1)
279 chIntEnd = channelNr;
280 else
281 {
282 chIntEnd = chLast;
283 if(chIntBegin == chIntEnd)
284 channelbuffer = cString::sprintf("%s %d", *channelbuffer?*channelbuffer:"", chIntBegin);
285 else if (chIntEnd != -1)
286 channelbuffer = cString::sprintf("%s %d-%d", *channelbuffer?*channelbuffer:"", chIntBegin, chIntEnd);
287 chIntBegin = chIntEnd = channelNr;
288 }
289
290 chLast = channelNr;
291 channelInGroup = group->channels.Next(channelInGroup);
292 if (!channelInGroup)
293 {
294 if(chLast == chIntBegin)
295 channelbuffer = cString::sprintf("%s %d", *channelbuffer?*channelbuffer:"", chIntBegin);
296 else
297 channelbuffer = cString::sprintf("%s %d-%d", *channelbuffer?*channelbuffer:"", chIntBegin, chLast);
298 }
299 }
300
301 SetText(cString::sprintf("%s\t%s", group->name, *channelbuffer?*channelbuffer:""));
302}
303
304// --- cMenuChannelGroups ----------------------------------------------------------
305cMenuChannelGroups::cMenuChannelGroups(char** GroupName)
306:cOsdMenu(tr("Channel groups")I18nTranslate("Channel groups", "vdr-" "epgsearch"),20)
307{
308#if VDRVERSNUM20005 >= 10734
309 SetMenuCategory(mcSetupPlugins);
310#endif
311 groupSel = -1;
312 groupName = GroupName;
313 if (groupName && *groupName)
314 groupSel = ChannelGroups.GetIndex(*groupName);
315
316 cChannelGroup* ChannelGroup = ChannelGroups.First();
317 int index = 0;
318 while (ChannelGroup)
319 {
320 Add(new cMenuChannelGroupItem(ChannelGroup), (index == groupSel?true:false));
321 ChannelGroup = ChannelGroups.Next(ChannelGroup);
322 index++;
323 }
324
325 if (groupName && *groupName)
326 SetHelp(trVDR("Button$Edit")I18nTranslate("Button$Edit"), trVDR("Button$New")I18nTranslate("Button$New"), trVDR("Button$Delete")I18nTranslate("Button$Delete"), tr("Button$Select")I18nTranslate("Button$Select", "vdr-" "epgsearch"));
327 else
328 SetHelp(trVDR("Button$Edit")I18nTranslate("Button$Edit"), trVDR("Button$New")I18nTranslate("Button$New"), trVDR("Button$Delete")I18nTranslate("Button$Delete"), NULL__null);
329 Sort();
330 Display();
331}
332
333cChannelGroup *cMenuChannelGroups::CurrentGroup(void)
334{
335 cMenuChannelGroupItem *item = (cMenuChannelGroupItem *)Get(Current());
336 return item ? item->group : NULL__null;
337}
338
339eOSState cMenuChannelGroups::New(void)
340{
341 if (HasSubMenu())
342 return osContinue;
343 return AddSubMenu(new cMenuEditChannelGroup(new cChannelGroup, true));
344}
345
346eOSState cMenuChannelGroups::Delete(void)
347{
348 cChannelGroup *curGroup = CurrentGroup();
349 if (curGroup) {
350 cSearchExt* search = ChannelGroups.Used(curGroup);
351 if (search)
352 {
353 cString Message = cString::sprintf("%s %s", tr("Channel group used by:")I18nTranslate("Channel group used by:", "vdr-" "epgsearch"), search->search);
354 INFO(Message)Skins.Message(mtInfo, Message);
355 return osContinue;
356 }
357 if (Interface->Confirm(tr("Edit$Delete group?")I18nTranslate("Edit$Delete group?", "vdr-" "epgsearch"))) {
358 ChannelGroups.Del(curGroup);
359 ChannelGroups.Save();
360 cOsdMenu::Del(Current());
361 Display();
362 }
363 }
364 return osContinue;
365}
366
367eOSState cMenuChannelGroups::ProcessKey(eKeys Key)
368{
369 int GroupNumber = HasSubMenu() ? Count() : -1;
370
371 eOSState state = cOsdMenu::ProcessKey(Key);
372 if (state == osUnknown)
373 {
374 if (HasSubMenu())
375 return osContinue;
376 switch (Key)
377 {
378 case kRed:
379 if (CurrentGroup())
380 state = AddSubMenu(new cMenuEditChannelGroup(CurrentGroup()));
381 else
382 state = osContinue;
383 break;
384 case kGreen: state = New(); break;
385 case kYellow: state = Delete(); break;
386
387 case kOk:
388 case kBlue:
389 if (groupName && *groupName)
390 {
391 free(*groupName);
392 *groupName = strdup(CurrentGroup()->name);
393 return osBack;
394 }
395 default: break;
396 }
397 }
398 if (GroupNumber >= 0 && !HasSubMenu() && ChannelGroups.Get(GroupNumber))
399 {
400 // a newly created group was confirmed with Ok
401 cChannelGroup* group = ChannelGroups.Get(GroupNumber);
402 Add(new cMenuChannelGroupItem(group), true);
403 Display();
404 }
405
406 return state;
407}
408
409// --- cMenuEditChannelGroup --------------------------------------------------------
410cMenuEditChannelGroup::cMenuEditChannelGroup(cChannelGroup *Group, bool New)
411:cOsdMenu(tr("Edit channel group")I18nTranslate("Edit channel group", "vdr-" "epgsearch"),30)
412{
413#if VDRVERSNUM20005 >= 10734
414 SetMenuCategory(mcSetupPlugins);
415#endif
416 group = Group;
417 channelSel = group->CreateChannelSel();
418 strcpy(name, group->name);
419 addIfConfirmed = New;
420 Set();
421}
422
423cMenuEditChannelGroup::~cMenuEditChannelGroup()
424{
425 free(channelSel);
426}
427
428void cMenuEditChannelGroup::Set()
429{
430 int current = Current();
431 Clear();
432
433 Add(new cMenuEditStrItem( tr("Group name")I18nTranslate("Group name", "vdr-" "epgsearch"), name, sizeof(group->name), trVDR(FileNameChars)I18nTranslate(FileNameChars)));
434 cChannel* channel = Channels.First();
435 int index = 0;
436 while (channel)
437 {
438 if (channel->GroupSep())
439 {
440 channel = Channels.Next(channel);
441 continue;
442 }
443 Add(new cMenuEditBoolItem( CHANNELNAME(channel)(channel ? channel->ShortName(true) : ""), &channelSel[index++], trVDR("no")I18nTranslate("no"), trVDR("yes")I18nTranslate("yes")));
444 channel = Channels.Next(channel);
445 }
446
447 SetCurrent(Get(current));
448
449}
450
451eOSState cMenuEditChannelGroup::ProcessKey(eKeys Key)
452{
453 eOSState state = cOsdMenu::ProcessKey(Key);
454
455 const char* ItemText = Get(Current())->Text();
456 if (strlen(ItemText) > 0 && strstr(ItemText, tr("Group name")I18nTranslate("Group name", "vdr-" "epgsearch")) != ItemText)
457 SetHelp(tr("Button$Invert selection")I18nTranslate("Button$Invert selection", "vdr-" "epgsearch"), tr("Button$All yes")I18nTranslate("Button$All yes", "vdr-" "epgsearch"), tr("Button$All no")I18nTranslate("Button$All no", "vdr-" "epgsearch"), NULL__null);
458 else if (!InEditMode(ItemText, tr("Group name")I18nTranslate("Group name", "vdr-" "epgsearch"), name))
459 SetHelp(NULL__null, NULL__null, NULL__null, NULL__null);
460
461 if (state == osUnknown) {
462 switch (Key) {
463 case kOk:
464 if (strlen(name) == 0)
465 {
466 ERROR(tr("Group name is empty!"))Skins.Message(mtError, I18nTranslate("Group name is empty!", "vdr-"
"epgsearch"))
;
467 return osContinue;
468 }
469 if (addIfConfirmed && ChannelGroups.GetGroupByName(name))
470 {
471 ERROR(tr("Group name already exists!"))Skins.Message(mtError, I18nTranslate("Group name already exists!"
, "vdr-" "epgsearch"))
;
472 return osContinue;
473 }
474
475 {
476 bool saveSearchExts = false;
477 if (strcmp(group->name, name) != 0 && !addIfConfirmed) // if group name changed, update searches
478 {
479 cMutexLock SearchExtsLock(&SearchExts);
480 cSearchExt *SearchExt = SearchExts.First();
481 while (SearchExt) {
482 if (SearchExt->useChannel == 2 &&
483 SearchExt->channelGroup &&
484 strcmp(SearchExt->channelGroup, group->name) == 0)
485 {
486 free(SearchExt->channelGroup);
487 SearchExt->channelGroup = strdup(name);
488 }
489 SearchExt = SearchExts.Next(SearchExt);
490 }
491 saveSearchExts = true; // save them after groups are saved!
492 }
493
494 strcpy(group->name, name);
495 group->CreateChannelList(channelSel);
496 if (addIfConfirmed)
497 ChannelGroups.Add(group);
498 ChannelGroups.Save();
499 if (saveSearchExts)
500 SearchExts.Save();
501 }
502 addIfConfirmed = false;
503 return osBack;
504 break;
505 case kRed:
506 case kGreen:
507 case kYellow:
508 {
509 cChannel* channel = Channels.First();
510 int index = 0;
511 while (channel)
512 {
513 if (channel->GroupSep())
514 {
515 channel = Channels.Next(channel);
516 continue;
517 }
518
519 channelSel[index] = (Key == kGreen?1:(Key == kRed?1-channelSel[index]:0));
520 index++;
521 channel = Channels.Next(channel);
522 }
523 Set();
524 Display();
525 return osContinue;
526 }
527
528 default: break;
529 }
530 }
531 return state;
532}