|
|
* | * |
* Copyright (C) 2004 Svend Sorensen | * Copyright (C) 2004 Svend Sorensen |
* For license terms, see the file COPYING in this distribution. | * For license terms, see the file COPYING in this distribution. |
|
* |
|
* Modified 2005-08-23 by Branden Robinson. |
*/ | */ |
| |
#include <stdio.h> |
#include <ctype.h> /* isdigit() */ |
#include <stdlib.h> /* exit() */ |
#include <getopt.h> /* getopt_long() */ |
#include <string.h> /* strcmp() */ |
#include <stdio.h> /* fprintf(), printf(), snprintf(), stderr */ |
#include <getopt.h> |
#include <stdlib.h> /* exit() */ |
#include <ctype.h> /* isdigit() */ |
#include <string.h> /* strcasecmp() */ |
#include "cuefile.h" | #include "cuefile.h" |
| |
/* default templates */ | /* default templates */ |
|
|
| |
void usage (int status) | void usage (int status) |
{ | { |
|
char synopsis[1024]; |
|
|
|
/* TODO: We could use asprintf() if we know we're using GNU libc. */ |
|
snprintf(synopsis, 1023, "usage: %s [option ...] [file ...]\n", |
|
progname); |
|
|
if (0 == status) { | if (0 == status) { |
fprintf(stdout, "%s: usage: cueprint [option...] [file...]\n", progname); |
printf("%s", synopsis); |
fputs("\ |
printf("Report disc and track information from a CUE or TOC" |
\n\ |
" file.\n" |
OPTIONS\n\ |
"\n" |
\n\ |
"Options:\n" |
Template Expansion\n\ |
"-d TEMPLATE, --disc-template=TEMPLATE\tset disc" |
Disc:\n\ |
" template\n" |
%A - album arranger\n\ |
"-h, --help\t\t\t\tdisplay this message and exit\n" |
%C - album composer\n\ |
"-i {cue|toc}, --input-format={cue|toc}\tset format of" |
%G - album genre\n\ |
" input file(s)\n" |
%M - album message\n\ |
"-n N, --track-number=N\t\t\treport information for" |
%N - number of tracks\n\ |
" track N only\n" |
%P - album performer\n\ |
"-t TEMPLATE, --track-template=TEMPLATE\tset track" |
%S - album songwriter\n\ |
" template\n" |
%T - album title\n\ |
"\n" |
%U - album UPC/EAN\n\ |
"TEMPLATE is a printf(3)-style format string.\n" |
Track:\n\ |
"\n" |
%a - track arranger\n\ |
"Default disc template: %s\n" |
%c - track composer\n\ |
"Default track template: %s\n" |
%g - track genre\n\ |
"See the %s(1) manual page for more information.\n", |
%i - track ISRC\n\ |
D_TEMPLATE, T_TEMPLATE, progname); |
%m - track message\n\ |
|
%n - track number\n\ |
|
%p - track perfomer\n\ |
|
%t - track title\n\ |
|
%u - track ISRC (CD-TEXT)\n\ |
|
\n\ |
|
Any other %<character> is expanded to that character. For example, to get a\n\ |
|
'%', use %%.\n\ |
|
\n\ |
|
", stdout); |
|
fprintf(stdout, "default disc template is:\n%s\n", D_TEMPLATE); |
|
fprintf(stdout, "default track template is:\n%s\n", T_TEMPLATE); |
|
} else { | } else { |
fprintf(stderr, "run `%s --help' for usage\n", progname); |
fprintf(stderr, "%sRun \"%s --help\" for more information.\n", |
|
synopsis, progname); |
} | } |
| |
exit (status); |
exit(status); |
} | } |
| |
|
/* TODO: Shouldn't we be using vprintf() to help us out with this stuff? */ |
|
|
void disc_field (char *conv, int length, Cd *cd, Value *value) | void disc_field (char *conv, int length, Cd *cd, Value *value) |
{ | { |
char *c; /* pointer to conversion character */ | char *c; /* pointer to conversion character */ |
|
|
| |
} | } |
| |
/* print a % conversion specification |
/* |
* %[flag(s)][width][.precision]<conversion-char> |
* Print a conversion specification. |
|
* [flag(s)][width][.precision]<conversion-char> |
*/ | */ |
void print_conv (char *start, int length, Cd *cd, int trackno) | void print_conv (char *start, int length, Cd *cd, int trackno) |
{ | { |
|
|
char *c; /* pointer to conversion-char */ | char *c; /* pointer to conversion-char */ |
| |
/* TODO: use strndup? */ | /* TODO: use strndup? */ |
conv = malloc ((unsigned) (length + 1)); |
conv = malloc((unsigned) (length + 1)); |
strncpy(conv, start, length); | strncpy(conv, start, length); |
conv[length] = '\0'; | conv[length] = '\0'; |
| |
|
|
conv_length++; | conv_length++; |
c++; | c++; |
} | } |
|
|
/* precision */ | /* precision */ |
/* '*' not recognized */ | /* '*' not recognized */ |
if ('.' == *c) { | if ('.' == *c) { |
|
|
} | } |
} | } |
| |
int info (char *name, int format, int trackno, char *d_template, char *t_template) |
int info (char *name, int format, int trackno, char *d_template, |
|
char *t_template) |
{ | { |
Cd *cd = NULL; | Cd *cd = NULL; |
int ntrack; | int ntrack; |
|
|
return 0; | return 0; |
} | } |
| |
/* translate escape sequences in a string |
/* |
* string is overwritten and terminated |
* Translate escape sequences in a string. |
|
* The string is overwritten and terminated. |
* TODO: this does not handle octal and hexidecimal escapes | * TODO: this does not handle octal and hexidecimal escapes |
* except for \0 | * except for \0 |
*/ | */ |
|
|
int main (int argc, char **argv) | int main (int argc, char **argv) |
{ | { |
int format = UNKNOWN; | int format = UNKNOWN; |
int trackno = -1; /* track number (-1 = unspecified, 0 = disc info) */ |
int trackno = -1; /* track number (-1 = unspecified, |
|
0 = disc info) */ |
char *d_template = NULL; /* disc template */ | char *d_template = NULL; /* disc template */ |
char *t_template = NULL; /* track template */ | char *t_template = NULL; /* track template */ |
|
int ret = 0; /* return value of info() */ |
/* getopt_long() variables */ | /* getopt_long() variables */ |
char c; |
int c; |
extern char *optarg; | extern char *optarg; |
extern int optind; | extern int optind; |
| |
|
|
{NULL, 0, NULL, 0} | {NULL, 0, NULL, 0} |
}; | }; |
| |
progname = *argv; |
progname = argv[0]; |
| |
while (-1 != (c = getopt_long(argc, argv, "hi:n:d:t:", longopts, NULL))) { |
while (-1 != (c = getopt_long(argc, argv, "hi:n:d:t:", longopts, NULL))) |
|
{ |
switch (c) { | switch (c) { |
case 'h': | case 'h': |
usage(0); | usage(0); |
break; | break; |
case 'i': | case 'i': |
if (0 == strcmp("cue", optarg)) { |
if (0 == strcasecmp("cue", optarg)) { |
format = CUE; | format = CUE; |
} else if (0 == strcmp("toc", optarg)) { |
} else if (0 == strcasecmp("toc", optarg)) { |
format = TOC; | format = TOC; |
} else { | } else { |
fprintf(stderr, "%s: illegal format `%s'\n", progname, optarg); |
fprintf(stderr, "%s: error: unknown input file" |
|
" format \"%s\"\n", progname, optarg); |
usage(1); | usage(1); |
} | } |
break; | break; |
case 'n': | case 'n': |
trackno = atoi(optarg); | trackno = atoi(optarg); |
|
|
} | } |
} | } |
| |
/* if no disc or track template is set, use the defaults for both */ |
/* If no disc or track template is set, use the defaults for both. */ |
/* TODO: alternative to strdup to get variable strings? */ | /* TODO: alternative to strdup to get variable strings? */ |
if (NULL == d_template && NULL == t_template) { | if (NULL == d_template && NULL == t_template) { |
d_template = strdup(D_TEMPLATE); | d_template = strdup(D_TEMPLATE); |
|
|
t_template = strdup(""); | t_template = strdup(""); |
} | } |
| |
/* translate escape sequences */ |
/* Translate escape sequences. */ |
translate_escapes(d_template); | translate_escapes(d_template); |
translate_escapes(t_template); | translate_escapes(t_template); |
| |
|
/* What we do depends on the number of operands. */ |
if (optind == argc) { | if (optind == argc) { |
info("-", format, trackno, d_template, t_template); |
/* No operands: report information about stdin. */ |
|
ret = info("-", format, trackno, d_template, t_template); |
} else { | } else { |
for (; optind < argc; optind++) |
/* Report information for each operand. */ |
info(argv[optind], format, trackno, d_template, t_template); |
for (; optind < argc; optind++) { |
|
ret = info(argv[optind], format, trackno, d_template, |
|
t_template); |
|
/* Bail out if info() returns nonzero. */ |
|
if (!ret) |
|
break; |
|
} |
} | } |
| |
return 0; |
return ret; |
} | } |