Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

cueprint.c 6.9 KiB

il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
il y a 20 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * cueprint.c -- print cd information based on a template
  3. *
  4. * Copyright (C) 2004 Svend Sorensen
  5. * For license terms, see the file COPYING in this distribution.
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h> /* exit() */
  9. #include <string.h> /* strcmp() */
  10. #include <unistd.h> /* getopt() */
  11. #include <ctype.h> /* isdigit() */
  12. #include "cuefile.h"
  13. /* default templates */
  14. #define D_TEMPLATE "%P \"%T\" (%N tracks)\n"
  15. #define T_TEMPLATE "%n: %p \"%t\"\n"
  16. #define UNSPECIFIED -1
  17. char *progname;
  18. char *d_template = D_TEMPLATE; /* disc template */
  19. char *t_template = T_TEMPLATE; /* track template */
  20. void usage (int status)
  21. {
  22. if (0 == status) {
  23. fprintf(stdout, "%s: usage: cueprint [-h] [-i cue|toc] [-d TEMPLATE] [-t TEMPLATE] [file...]\n", progname);
  24. fputs("\
  25. \n\
  26. OPTIONS\n\
  27. -h print usage\n\
  28. -i cue|toc set format of file(s)\n\
  29. -d TEMPLATE set disc template (see TEMPLATE EXPANSION)\n\
  30. -t TEMPLATE set track template (see TEMPLATE EXPANSION)\n\
  31. \n\
  32. Template Expansion\n\
  33. Disc:\n\
  34. %A - album arranger\n\
  35. %C - album composer\n\
  36. %G - album genre\n\
  37. %M - album message\n\
  38. %N - number of tracks\n\
  39. %P - album performer\n\
  40. %S - album songwriter\n\
  41. %T - album title\n\
  42. %U - album UPC/EAN\n\
  43. Track:\n\
  44. %a - track arranger\n\
  45. %c - track composer\n\
  46. %g - track genre\n\
  47. %i - track ISRC\n\
  48. %m - track message\n\
  49. %n - track number\n\
  50. %p - track perfomer\n\
  51. %t - track title\n\
  52. %u - track ISRC (CD-TEXT)\n\
  53. \n\
  54. Any other %<character> is expanded to that character. For example, to get a\n\
  55. '%', use %%.\n\
  56. ", stdout);
  57. fprintf(stdout, "default disc template is:\n\"%s\"\n", D_TEMPLATE);
  58. fprintf(stdout, "default track template is:\n\"%s\"\n", T_TEMPLATE);
  59. } else {
  60. fprintf(stderr, "%s: syntax error\n", progname);
  61. fprintf(stderr, "run `%s -h' for usage\n", progname);
  62. }
  63. exit (status);
  64. }
  65. void disc_field (char *conv, int length, Cd *cd)
  66. {
  67. char *c; /* pointer to conversion character */
  68. Cdtext *cdtext = NULL;
  69. cdtext = cd_get_cdtext(cd);
  70. c = conv + length - 1;
  71. switch (*c) {
  72. case 'A':
  73. *c = 's';
  74. printf(conv, cdtext_get(PTI_ARRANGER, cdtext));
  75. break;
  76. case 'C':
  77. *c = 's';
  78. printf(conv, cdtext_get(PTI_COMPOSER, cdtext));
  79. break;
  80. case 'G':
  81. *c = 's';
  82. printf(conv, cdtext_get(PTI_GENRE, cdtext));
  83. break;
  84. case 'M':
  85. *c = 's';
  86. printf(conv, cdtext_get(PTI_MESSAGE, cdtext));
  87. break;
  88. case 'N':
  89. *c = 'd';
  90. printf(conv, cd_get_ntrack(cd));
  91. break;
  92. case 'P':
  93. *c = 's';
  94. printf(conv, cdtext_get(PTI_PERFORMER, cdtext));
  95. break;
  96. case 'R':
  97. *c = 's';
  98. printf(conv, cdtext_get(PTI_ARRANGER, cdtext));
  99. break;
  100. case 'S':
  101. *c = 's';
  102. printf(conv, cdtext_get(PTI_SONGWRITER, cdtext));
  103. break;
  104. case 'T':
  105. *c = 's';
  106. printf(conv, cdtext_get(PTI_TITLE, cdtext));
  107. break;
  108. case 'U':
  109. *c = 's';
  110. printf(conv, cdtext_get(PTI_UPC_ISRC, cdtext));
  111. break;
  112. default:
  113. putchar(*c);
  114. break;
  115. }
  116. }
  117. void track_field (char *conv, int length, Cd *cd, int trackno)
  118. {
  119. char *c; /* pointer to conversion character */
  120. Track *track = NULL;
  121. Cdtext *cdtext = NULL;
  122. track = cd_get_track(cd, trackno);
  123. cdtext = track_get_cdtext(track);
  124. c = conv + length - 1;
  125. switch (*c) {
  126. case 'a':
  127. *c = 's';
  128. printf(conv, cdtext_get(PTI_ARRANGER, cdtext));
  129. break;
  130. case 'c':
  131. *c = 's';
  132. printf(conv, cdtext_get(PTI_COMPOSER, cdtext));
  133. break;
  134. case 'f':
  135. *c = 's';
  136. printf(conv, track_get_filename(track));
  137. break;
  138. case 'g':
  139. *c = 's';
  140. printf(conv, cdtext_get(PTI_GENRE, cdtext));
  141. break;
  142. case 'i':
  143. *c = 's';
  144. printf(conv, track_get_isrc(track));
  145. break;
  146. case 'm':
  147. *c = 's';
  148. printf(conv, cdtext_get(PTI_MESSAGE, cdtext));
  149. break;
  150. case 'n':
  151. *c = 'd';
  152. printf(conv, trackno);
  153. break;
  154. case 'p':
  155. *c = 's';
  156. printf(conv, cdtext_get(PTI_PERFORMER, cdtext));
  157. break;
  158. case 's':
  159. *c = 's';
  160. printf(conv, cdtext_get(PTI_SONGWRITER, cdtext));
  161. break;
  162. case 't':
  163. *c = 's';
  164. printf(conv, cdtext_get(PTI_TITLE, cdtext));
  165. break;
  166. case 'u':
  167. *c = 's';
  168. printf(conv, cdtext_get(PTI_UPC_ISRC, cdtext));
  169. break;
  170. default:
  171. disc_field(conv, length, cd);
  172. break;
  173. }
  174. }
  175. /* print a % conversion specification
  176. * %[flag(s)][width][.precision]<conversion-char>
  177. */
  178. void print_conv (char *start, int length, Cd *cd, int trackno)
  179. {
  180. char *conv; /* copy of conversion specification */
  181. /* TODO: use strndup? */
  182. conv = malloc ((unsigned) (length + 1));
  183. strncpy(conv, start, length);
  184. conv[length] = '\0';
  185. /* conversion character */
  186. if (0 == trackno)
  187. disc_field(conv, length, cd);
  188. else
  189. track_field(conv, length, cd, trackno);
  190. }
  191. /* print an escaped character
  192. * `c' is the character after the `/'
  193. * NOTE: this does not handle octal and hexidecimal escapes
  194. */
  195. int print_esc (char *c)
  196. {
  197. /* ?, ', " are handled by the default */
  198. switch (*c) {
  199. case 'a':
  200. putchar('\a');
  201. break;
  202. case 'b':
  203. putchar('\b');
  204. break;
  205. case 'f':
  206. putchar('\f');
  207. break;
  208. case 'n':
  209. putchar('\n');
  210. break;
  211. case 'r':
  212. putchar('\r');
  213. break;
  214. case 't':
  215. putchar('\t');
  216. break;
  217. case 'v':
  218. putchar('\v');
  219. break;
  220. case '0':
  221. putchar('\0');
  222. break;
  223. default:
  224. putchar(*c);
  225. break;
  226. }
  227. }
  228. void cd_printf (char *format, Cd *cd, int trackno)
  229. {
  230. char *c; /* pointer into format */
  231. char *conv_start;
  232. int conv_length;
  233. for (c = format; '\0' != *c; c++) {
  234. switch (*c) {
  235. case '%':
  236. conv_start = c;
  237. conv_length = 1;
  238. c++;
  239. /* flags */
  240. while ( \
  241. '-' == *c \
  242. || '+' == *c \
  243. || ' ' == *c \
  244. || '0' == *c \
  245. || '#' == *c \
  246. ) {
  247. conv_length++;
  248. c++;
  249. }
  250. /* field width */
  251. /* '*' not recognized */
  252. while (0 != isdigit(*c)) {
  253. conv_length++;
  254. c++;
  255. }
  256. /* precision */
  257. /* '*' not recognized */
  258. if ('.' == *c) {
  259. conv_length++;
  260. c++;
  261. while (0 != isdigit(*c)) {
  262. conv_length++;
  263. c++;
  264. }
  265. }
  266. /* length modifier (h, l, or L) */
  267. /* not recognized */
  268. /* conversion character */
  269. conv_length++;
  270. print_conv(conv_start, conv_length, cd, trackno);
  271. break;
  272. case '\\':
  273. c++;
  274. print_esc(c);
  275. break;
  276. default:
  277. putchar(*c);
  278. break;
  279. }
  280. }
  281. }
  282. void print_info (Cd *cd)
  283. {
  284. int i; /* track */
  285. char *c;
  286. cd_printf(d_template, cd, 0);
  287. for (i = 1; i <= cd_get_ntrack(cd); i++) {
  288. cd_printf(t_template, cd, i);
  289. }
  290. }
  291. int info (char *name, int format)
  292. {
  293. Cd *cd = NULL;
  294. if (NULL == (cd = cf_parse(name, &format))) {
  295. fprintf(stderr, "%s: input file error\n", name);
  296. return -1;
  297. }
  298. print_info(cd);
  299. return 0;
  300. }
  301. int main (int argc, char **argv)
  302. {
  303. int format = UNKNOWN;
  304. /* getopt () variables */
  305. char c;
  306. extern char *optarg;
  307. extern int optind;
  308. progname = *argv;
  309. while (-1 != (c = getopt(argc, argv, "hi:d:t:"))) {
  310. switch (c) {
  311. case 'h':
  312. usage(0);
  313. break;
  314. case 'i':
  315. if (0 == strcmp("cue", optarg))
  316. format = CUE;
  317. else if (0 == strcmp("toc", optarg))
  318. format = TOC;
  319. break;
  320. case 'd':
  321. d_template = optarg;
  322. break;
  323. case 't':
  324. t_template = optarg;
  325. break;
  326. default:
  327. usage(1);
  328. break;
  329. }
  330. }
  331. if (optind == argc) {
  332. info("-", format);
  333. } else {
  334. for (; optind < argc; optind++)
  335. info(argv[optind], format);
  336. }
  337. return 0;
  338. }