diff --git a/doc/ezstream.1.in b/doc/ezstream.1.in index 8cdd8d2..58fab94 100644 --- a/doc/ezstream.1.in +++ b/doc/ezstream.1.in @@ -12,7 +12,7 @@ .Sh SYNOPSIS .Nm .Bk -words -.Op Fl hqVv +.Op Fl hnqVv .Op Fl c Ar configfile .Ek .Sh DESCRIPTION @@ -36,6 +36,8 @@ Use the XML configuration in .It Fl h Print a summary of available command line parameters with short descriptions and exit. +.It Fl n +Normalize metadata strings by removing excess whitespaces. .It Fl q Be more quiet. Suppress the output that external programs send to standard error. diff --git a/src/ezstream.c b/src/ezstream.c index f471156..d02e4a4 100644 --- a/src/ezstream.c +++ b/src/ezstream.c @@ -74,6 +74,7 @@ extern char *__progname; char *__progname; #endif /* HAVE___PROGNAME */ +int nFlag; int qFlag; int vFlag; int metadataFromProgram; @@ -445,7 +446,7 @@ getMetadata(const char *fileName) metadata_t *mdata; if (metadataFromProgram) { - if ((mdata = metadata_program(fileName)) == NULL) + if ((mdata = metadata_program(fileName, nFlag)) == NULL) return (NULL); if (!metadata_program_update(mdata, METADATA_ALL)) { @@ -453,7 +454,7 @@ getMetadata(const char *fileName) return (NULL); } } else { - if ((mdata = metadata_file(fileName)) == NULL) + if ((mdata = metadata_file(fileName, nFlag)) == NULL) return (NULL); if (!metadata_file_update(mdata)) { @@ -1018,7 +1019,7 @@ ez_shutdown(int exitval) void usage(void) { - printf("usage: %s [-hqVv] [-c configfile]\n", __progname); + printf("usage: %s [-hnqVv] [-c configfile]\n", __progname); } void @@ -1027,6 +1028,7 @@ usageHelp(void) printf("\n"); printf(" -c configfile use XML configuration in configfile\n"); printf(" -h display this additional help and exit\n"); + printf(" -n normalize metadata strings\n"); printf(" -q suppress STDERR output from external en-/decoders\n"); printf(" -V print the version number and exit\n"); printf(" -v verbose output (use twice for more effect)\n"); @@ -1061,10 +1063,11 @@ main(int argc, char *argv[]) __progname = getProgname(argv[0]); pezConfig = getEZConfig(); + nFlag = 0; qFlag = 0; vFlag = 0; - while ((c = getopt(argc, argv, "c:hqVv")) != -1) { + while ((c = getopt(argc, argv, "c:hnqVv")) != -1) { switch (c) { case 'c': if (configFile != NULL) { @@ -1078,6 +1081,9 @@ main(int argc, char *argv[]) usage(); usageHelp(); return (ez_shutdown(0)); + case 'n': + nFlag = 1; + break; case 'q': qFlag = 1; break; diff --git a/src/metadata.c b/src/metadata.c index 900098e..b7276d5 100644 --- a/src/metadata.c +++ b/src/metadata.c @@ -54,6 +54,7 @@ struct metadata { char *artist; char *title; int songLen; + int normalize; int program; }; @@ -74,6 +75,7 @@ void metadata_clean_md(metadata_t *); void metadata_get_extension(char *, size_t, const char *); char * metadata_get_name(const char *); void metadata_process_md(metadata_t *); +void metadata_normalize_string(char **); metadata_t * metadata_create(const char *filename) @@ -324,10 +326,47 @@ metadata_process_md(metadata_t *md) if (md->string == NULL) md->string = metadata_assemble_string(md); + + if (md->normalize) { + metadata_normalize_string(&md->string); + metadata_normalize_string(&md->artist); + metadata_normalize_string(&md->title); + } +} + +void +metadata_normalize_string(char **s) +{ + char *str, *cp, *tmpstr, *tp; + int is_space; + + if (s == NULL || (str = *s) == NULL || strlen(str) == 0) + return; + + tmpstr = xcalloc(strlen(str) + 1, sizeof(char)); + + tp = tmpstr; + is_space = 1; + for (cp = str; *cp != '\0'; cp++) { + if (*cp == ' ') { + if (!is_space && strlen(tmpstr) > 0 && + tmpstr[strlen(tmpstr) - 1] != ' ') + *tp++ = ' '; + is_space = 1; + } else { + *tp++ = *cp; + is_space = 0; + } + } + if (strlen(tmpstr) > 0 && tmpstr[strlen(tmpstr) - 1] == ' ') + tmpstr[strlen(tmpstr) - 1] = '\0'; + + xfree(str); + *s = xrealloc(tmpstr, strlen(tmpstr) + 1, sizeof (char)); } metadata_t * -metadata_file(const char *filename) +metadata_file(const char *filename, int normalize) { metadata_t *md; @@ -343,11 +382,13 @@ metadata_file(const char *filename) return (NULL); } + md->normalize = normalize; + return (md); } metadata_t * -metadata_program(const char *program) +metadata_program(const char *program, int normalize) { metadata_t *md; #ifdef HAVE_STAT @@ -392,6 +433,8 @@ metadata_program(const char *program) fclose(filep); #endif /* HAVE_STAT */ + md->normalize = normalize; + return (md); } @@ -560,6 +603,12 @@ metadata_program_update(metadata_t *md, enum metadata_request md_req) abort(); } + if (md->normalize) { + metadata_normalize_string(&md->string); + metadata_normalize_string(&md->artist); + metadata_normalize_string(&md->title); + } + return (1); } diff --git a/src/metadata.h b/src/metadata.h index 331e575..05409a9 100644 --- a/src/metadata.h +++ b/src/metadata.h @@ -33,7 +33,8 @@ typedef struct metadata metadata_t; * success, or NULL on failure. The returned handle is "branded" for reading * metadata from media files. */ -metadata_t * metadata_file(const char * /* filename */); +metadata_t * metadata_file(const char * /* filename */, + int /* normalize strings */); /* * Create a metadata handle that is "branded" for acquiring metadata from an @@ -52,7 +53,8 @@ metadata_t * metadata_file(const char * /* filename */); * metadata, or an empty string if no artist information is available. * - Return at most METADATA_MAX characters, or the result will be truncated. */ -metadata_t * metadata_program(const char * /* program name */); +metadata_t * metadata_program(const char * /* program name */, + int /* normalize strings */); /* * Free all memory used by a metadata handle that has been created with