From f4473f1788122a13a37d0b9114fc49750a0bde18 Mon Sep 17 00:00:00 2001 From: hummypkg Date: Mon, 6 Jun 2011 11:58:16 +0000 Subject: [PATCH] fix CRID extraction (changes parseable output API) and add -C filter option --- Makefile | 24 +++-------------- bst.c | 41 ---------------------------- bst.h | 21 --------------- descriptor.c | 1 + descriptor.h | 10 +++++-- epg.c | 43 +++++++++++++++++++++++------- epg.h | 3 ++- lint.h | 1 + main.c | 75 ++++++++++++++++++++++++++++++++++------------------ 9 files changed, 99 insertions(+), 120 deletions(-) delete mode 100644 bst.c delete mode 100644 bst.h diff --git a/Makefile b/Makefile index 25e2876..20cfd8a 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,9 @@ MAKE=gmake -# Setting these makes sure that the subsequent include files know that -# we are going to be threaded so they should do whatever they need to -# support this. In particular, this makes the global variable 'errno' -# become thread safe by replacing it with a call to the internal function -# ___errno() on Solaris - and should do something similar on other operating -# systems. Solaris also supports _TS_ERRNO to enable thread-safe errno -# _REENTRANT is also required for the tempnam() function to be properly -# thread-safe. -DEFS=-D_REENTRANT -D_TS_ERRNO -DHMT_PROTECT -# -DWITH_MPATROL +DEFS= -SRCS= bst.c \ - descriptor.c \ +SRCS= descriptor.c \ epg.c \ file.c \ huffman.c \ @@ -33,12 +23,6 @@ PROCESSOR=$(shell uname -p) CFLAGS=-g INCS= LIBS= -ifeq ($(PLATFORM),CYGWIN_NT) -CFLAGS=-g -mno-cygwin -endif -#ifeq ($(PLATFORM),Linux) -#CFLAGS=-static -g -#endif #CFLAGS=-g -O3 -fno-strict-aliasing #WARN=-pedantic -Wall -Wnested-externs -Wpointer-arith -Werror -Wno-unused WARN=-pedantic -Wall -W -Wnested-externs -Wpointer-arith -Wno-long-long @@ -58,9 +42,7 @@ epg: ${OBJS} clean: @-touch core - rm -f epg epg~ *.exe core tags asm ${OBJS} ${AROBJS} - rm -f *.raw *.raw.sum *.lh5 - rm -rf epg-* + rm -f epg epg~ core tags ${OBJS} tags: @-ctags *.[ch] 2>> /dev/null diff --git a/bst.c b/bst.c deleted file mode 100644 index c5b338c..0000000 --- a/bst.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lint.h" - -struct bsttab { - time_t tm; - int bst; -}; - -#include "bst.h" - -int -is_bst(time_t tm) -{ - int i, is_bst; - - is_bst = 0; - for (i = 0; bst[i].tm; i++) - { - if (bst[i].tm > tm) - break; - is_bst = bst[i].bst; - } - - return is_bst; -} - -void -bstise(time_t *tm) -{ - if (is_bst(*tm)) - *tm += 3600; -} - diff --git a/bst.h b/bst.h deleted file mode 100644 index 7cec365..0000000 --- a/bst.h +++ /dev/null @@ -1,21 +0,0 @@ -struct bsttab bst[] = { - { 1301187600, 1 }, - { 1319936400, 0 }, - { 1332637200, 1 }, - { 1351386000, 0 }, - { 1364691600, 1 }, - { 1382835600, 0 }, - { 1396141200, 1 }, - { 1414285200, 0 }, - { 1427590800, 1 }, - { 1445734800, 0 }, - { 1459040400, 1 }, - { 1477789200, 0 }, - { 1490490000, 1 }, - { 1509238800, 0 }, - { 1521939600, 1 }, - { 1540688400, 0 }, - { 1553994000, 1 }, - { 1572138000, 0 }, - { 0, 0 }, -}; diff --git a/descriptor.c b/descriptor.c index e3664f3..614072f 100644 --- a/descriptor.c +++ b/descriptor.c @@ -113,6 +113,7 @@ read_descriptor(struct epg *epg, struct descriptor *d) memcpy(crid, epg->bin + epg->offset, 1); epg->offset++; + crid->cridlen = crid->ref = 0; switch (crid->location) { diff --git a/descriptor.h b/descriptor.h index 0ce2965..ecbb44e 100644 --- a/descriptor.h +++ b/descriptor.h @@ -8,8 +8,14 @@ #define DS_USER_DEFINED 137 #define PARSER_SHORT_EVENT 0 -#define PARSER_CONTENT_ID 1 -#define PARSER_USER_DEFINED 2 +#define PARSER_USER_DEFINED 1 +#define PARSER_CRID_EVENT 2 +#define PARSER_CRID_SERIES 3 +#define PARSER_CRID_REC 4 + +#define CRIDT_EVENT '1' +#define CRIDT_SERIES '2' +#define CRIDT_REC '3' #pragma pack(1) struct crid { diff --git a/epg.c b/epg.c index 8956baa..69e9b5f 100644 --- a/epg.c +++ b/epg.c @@ -94,7 +94,6 @@ dump_data(struct data *d) DUMPINT(d, event_id); tm = mjd(d->start_date, d->start_hour, d->start_min, d->start_sec); - bstise(&tm); printf(" %30s: %#x %d:%02d:%02d (%s) [%ld]\n", "start_date", d->start_date, d->start_hour, d->start_min, d->start_sec, ctime_nl(&tm), tm); @@ -124,15 +123,23 @@ check_filter_range(struct epgfilter *f, enum epgfiltertype type, static inline int check_filter(struct epgfilter *f, enum epgfiltertype type, - unsigned long id, char *str __attribute__((unused))) + unsigned long id, char *str) { if (!f) return 1; for (; f; f = f->next) { - if (f->type == type && f->num != id) - return 0; + if (f->type == type) + { + if (type == FILTER_CRID) + { + if (strcmp(str, f->str)) + return 0; + } + else if (f->num != id) + return 0; + } } return 1; } @@ -142,7 +149,8 @@ parse(char *epgpath, void (*callback)(struct epg *, struct section *, struct data *, struct descriptor **, void *), void *val, struct epgfilter *filter) { - struct descriptor *dslist[3]; +#define DSLIST_SIZE 5 + struct descriptor *dslist[DSLIST_SIZE]; struct epg *epg; int i; @@ -207,7 +215,8 @@ parse(char *epgpath, } } - dslist[0] = dslist[1] = dslist[2] = NULL; + for (i = 0; i < DSLIST_SIZE; i++) + dslist[i] = NULL; while (epg->offset < dend) { @@ -233,7 +242,18 @@ parse(char *epgpath, case DS_CONTENT_IDENTIFIER: read_descriptor(epg, ds); - dslist[PARSER_CONTENT_ID] = ds; + switch (ds->content.d118.crids[0].type) + { + case CRIDT_EVENT: + dslist[PARSER_CRID_EVENT] = ds; + break; + case CRIDT_SERIES: + dslist[PARSER_CRID_SERIES] = ds; + break; + case CRIDT_REC: + dslist[PARSER_CRID_REC] = ds; + break; + } break; case DS_USER_DEFINED: @@ -248,9 +268,14 @@ parse(char *epgpath, } } - callback(epg, s, d, dslist, val); + if (!(sysopts & SYSOPT_CRIDFILTER) || + (dslist[PARSER_CRID_EVENT] && + check_filter(filter, FILTER_CRID, 0, + dslist[PARSER_CRID_EVENT]->content.d118. + crids[0].crid))) + callback(epg, s, d, dslist, val); - for (i = 0; i < 3; i++) + for (i = 0; i < DSLIST_SIZE; i++) if (dslist[i]) free_descriptor(dslist[i]); } diff --git a/epg.h b/epg.h index 5b6d800..226a129 100644 --- a/epg.h +++ b/epg.h @@ -63,7 +63,8 @@ enum epgfiltertype { FILTER_SERVICE = 0, FILTER_EVENT, FILTER_DESCRIPTOR, - FILTER_TIMESTAMP + FILTER_TIMESTAMP, + FILTER_CRID }; enum matchtype { FT_EQUAL, FT_RANGE, FT_GREATER, FT_LESS }; diff --git a/lint.h b/lint.h index 7443e66..f1b2593 100644 --- a/lint.h +++ b/lint.h @@ -6,6 +6,7 @@ #define SYSOPT_PARSABLE 0x1 #define SYSOPT_BRIEF 0x2 #define SYSOPT_TIMESTAMP 0x4 +#define SYSOPT_CRIDFILTER 0x8 extern int debug; extern const char *version; diff --git a/main.c b/main.c index 8c172b2..8b01b1d 100644 --- a/main.c +++ b/main.c @@ -17,7 +17,7 @@ #include "lint.h" int debug = 0; -const char *version = "0.0.1"; +const char *version = "1.0.1"; unsigned long sysopts = 0; int @@ -37,6 +37,7 @@ syntax() ); fprintf(stderr, " Filters: (can be specified multiple times, all must be true)\n" + " -C Show only events with this CRID.\n" " -D Show only selected descriptor type.\n" " -E Show only selected event.\n" " -S Show only selected service.\n" @@ -70,8 +71,12 @@ dumpraw(struct epg *epg __attribute__((unused)), dump_descriptor(ds[PARSER_SHORT_EVENT], 1); if (ds[PARSER_USER_DEFINED]) dump_descriptor(ds[PARSER_USER_DEFINED], 1); - if (ds[PARSER_CONTENT_ID]) - dump_descriptor(ds[PARSER_CONTENT_ID], 1); + if (ds[PARSER_CRID_EVENT]) + dump_descriptor(ds[PARSER_CRID_EVENT], 1); + if (ds[PARSER_CRID_SERIES]) + dump_descriptor(ds[PARSER_CRID_SERIES], 1); + if (ds[PARSER_CRID_REC]) + dump_descriptor(ds[PARSER_CRID_REC], 1); } void @@ -82,7 +87,6 @@ dump(struct epg *epg __attribute__((unused)), time_t tm; tm = mjd(d->start_date, d->start_hour, d->start_min, d->start_sec); - bstise(&tm); if (ds[PARSER_SHORT_EVENT]) { @@ -122,22 +126,24 @@ dump(struct epg *epg __attribute__((unused)), else printf("\t"); - if (ds[PARSER_CONTENT_ID]) + if (ds[PARSER_CRID_EVENT]) { - struct descriptor *d118 = ds[PARSER_CONTENT_ID]; - int i; - - printf("%d\t", d118->content.d118.i); - - for (i = 0; i < d118->content.d118.i; i++) - { - struct crid *crid = - &d118->content.d118.crids[i]; - - printf("%d\t%.*s\t", crid->type, - crid->cridlen, crid->crid); - } + struct descriptor *d = ds[PARSER_CRID_EVENT]; + printf("%.*s\t", d->content.d118.crids[0].cridlen, + d->content.d118.crids[0].crid); } + else + printf("\t"); + + if (ds[PARSER_CRID_SERIES]) + { + struct descriptor *d = ds[PARSER_CRID_SERIES]; + printf("%.*s\t", d->content.d118.crids[0].cridlen, + d->content.d118.crids[0].crid); + } + else + printf("\t"); + printf("\n"); return; } @@ -201,18 +207,26 @@ dump(struct epg *epg __attribute__((unused)), d137->content.d137.warninglen, d137->content.d137.warning); } - if (ds[PARSER_CONTENT_ID]) - { - struct descriptor *d118 = ds[PARSER_CONTENT_ID]; - int i; + if (ds[PARSER_CRID_EVENT]) + printf("%30s: %.*s\n", "Event CRID", + ds[PARSER_CRID_EVENT]->content.d118.crids[0].cridlen, + ds[PARSER_CRID_EVENT]->content.d118.crids[0].crid); - printf("%30s: %d\n", "CRIDs", d118->content.d118.i); + if (ds[PARSER_CRID_SERIES]) + printf("%30s: %.*s\n", "Series CRID", + ds[PARSER_CRID_SERIES]->content.d118.crids[0].cridlen, + ds[PARSER_CRID_SERIES]->content.d118.crids[0].crid); + + if (ds[PARSER_CRID_REC]) + { + struct descriptor *d118 = ds[PARSER_CRID_REC]; + int i; for (i = 0; i < d118->content.d118.i; i++) { struct crid *crid = &d118->content.d118.crids[i]; - printf("%30s: %d\n", "CRID Type", crid->type); - printf("%30s: %.*s\n", "CRID", + + printf("%30s: %.*s\n", "Recommended CRID", crid->cridlen, crid->crid); } } @@ -322,6 +336,17 @@ main(int argc, char **argv) sysopts |= SYSOPT_TIMESTAMP; goto nextopt; + case 'C': + GETOPT; + add_epgfilter(&filter, FILTER_CRID, + 0, 0, cp, FT_EQUAL); + /* Global flag to indicate that CRID filtering + * has been requested. Required so that + * events with no event CRID aren't shown + * when filtering. */ + sysopts |= SYSOPT_CRIDFILTER; + goto nextopt; + case 'D': GETOPT; add_epgfilter(&filter, FILTER_DESCRIPTOR,