/* * tvchannels.c: Translate channel-names from to tuning frequency * * $Id: tvchannels.c,v 1.2 1997/03/17 00:52:26 mb Exp mb $ * * Copyright (c) 1997 Martin Buck * Read COPYING for more information * */ #include #include #include #include #include #include "safe_malloc.h" #include "misc.h" #include "tvchannels.h" typedef struct tvchannel_s { char *name; int freq; struct tvchannel_s *next; } tvchannel_t; #define STR_MAXLEN 100 #define FNAME VTX_LIBDIR "/tv-channels" static int tvsys_count = -1; static char **tvsys_names; static tvchannel_t **tvsys_channels; static void tvch_init(void) { FILE *file; char line[256], tmpstr[STR_MAXLEN + 1], sep[2]; int lcount = 0, tvsys_found = 0, newentry = 0; tvsys_count = 0; if (!(file = fopen(FNAME, "r"))) { fprintf(stderr, "%s: Warning: %s\n", FNAME, strerror(errno)); return; } while (1) { if (!fgets(line, sizeof(line), file)) { if (feof(file)) break; tvsys_count = 0; fprintf(stderr, "%s: Warning: %s\n", FNAME, strerror(errno)); fclose(file); return; } lcount++; if (line[0] == '#') { continue; } else if (sscanf(line, " %1c ", tmpstr) <= 0) { tvsys_found = 0; continue; } else if (tvsys_found != 2) { if (sscanf(line, " system %" STRINGIFY(STR_MAXLEN) "[^\n\r] ", tmpstr) == 1) { int entry; newentry = tvsys_count; for (entry = 0; entry < tvsys_count; entry++) { if (!strcmp(tmpstr, tvsys_names[entry])) { newentry = entry; break; } } if (newentry == tvsys_count) { tvsys_names = srealloc(tvsys_names, (++tvsys_count) * sizeof(*tvsys_names)); tvsys_channels = srealloc(tvsys_channels, tvsys_count * sizeof(*tvsys_channels)); tvsys_names[newentry] = sstrdup(tmpstr); tvsys_channels[newentry] = NULL; } tvsys_found = 2; } else { if (tvsys_found != 1) { fprintf(stderr, "%s:%d: Warning: Missing system-name, succeeding entries ignored.\n", FNAME, lcount); tvsys_found = 1; } } } else { int freq; if (sscanf(line, " %" STRINGIFY(STR_MAXLEN) "[^\1- =] %1[=] %d ", tmpstr, sep, &freq) >= 2) { if (freq >= 0) { tvchannel_t **chan = &tvsys_channels[newentry]; while (*chan) { if (!strcmp(tmpstr, (*chan)->name)) { (*chan)->freq = freq; goto chan_done; } chan = &((*chan)->next); } *chan = smalloc(sizeof(**chan)); (*chan)->name = sstrdup(tmpstr); (*chan)->freq = freq; (*chan)->next = NULL; chan_done: ; } else { fprintf(stderr, "%s:%d: Warning: Frequency out of range, line ignored:\n%s\n", FNAME, lcount, line); } } else { fprintf(stderr, "%s:%d: Warning: Syntax error, line ignored:\n%s\n", FNAME, lcount, line); } } } fclose(file); } static int match_system(const char *system) { int entry, pos; for (entry = 0; entry < tvsys_count; entry++) { if (!strcmp(system, tvsys_names[entry])) { return entry; } } for (entry = 0; entry < tvsys_count; entry++) { if (!strcasecmp(system, tvsys_names[entry])) { return entry; } } /* Why is strncasecmp missing from ANSI C? */ for (entry = 0; entry < tvsys_count; entry++) { pos = 0; while (tvsys_names[entry][pos]) { if (!system[pos]) { return entry; } if (tolower(system[pos]) != tolower(tvsys_names[entry][pos])) { break; } pos++; } } return -1; } int tvch_get_systems(char const * const **sys_names) { if (tvsys_count < 0) { tvch_init(); } *sys_names = (char const * const *)tvsys_names; return tvsys_count; } int tvch_get_channels(const char *system, char const * const **ch_names) { int entry, count; static const char **ch_ptrs; tvchannel_t *chan; if (tvsys_count < 0) { tvch_init(); } if ((entry = match_system(system)) < 0) { return -1; } chan = tvsys_channels[entry]; count = 0; while (chan) { count++; chan = chan->next; } free(ch_ptrs); ch_ptrs = smalloc(count * sizeof(const char *)); chan = tvsys_channels[entry]; count = 0; while (chan) { ch_ptrs[count] = chan->name; count++; chan = chan->next; } *ch_names = (char const * const *)ch_ptrs; return count; } int tvch_chan2freq(const char *system, const char *chname, const char **real_sys_name, const char **real_chan_name) { int entry; tvchannel_t *chan; if (tvsys_count < 0) { tvch_init(); } if (!tvsys_count) return -1; if (!system) { entry = 0; } else { if ((entry = match_system(system)) < 0) { return -1; } } if (real_sys_name) { *real_sys_name = tvsys_names[entry]; } if (!chname) return entry; chan = tvsys_channels[entry]; while (chan) { if (!strcmp(chname, chan->name)) { if (real_chan_name) { *real_chan_name = chan->name; } return chan->freq; } chan = chan->next; } chan = tvsys_channels[entry]; while (chan) { if (!strcasecmp(chname, chan->name)) { if (real_chan_name) { *real_chan_name = chan->name; } return chan->freq; } chan = chan->next; } return -1; }