Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

cueprint.c 5.5 KiB

20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
20 anos atrás
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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. char *progname;
  17. char *d_template = D_TEMPLATE; /* disc template */
  18. char *t_template = T_TEMPLATE; /* track template */
  19. void usage (int status)
  20. {
  21. if (0 == status) {
  22. fprintf(stdout, "%s: usage: cueprint [-h] [-i cue|toc] [-d TEMPLATE] [-t TEMPLATE] [file...]\n", progname);
  23. fputs("\
  24. \n\
  25. OPTIONS\n\
  26. -h print usage\n\
  27. -i cue|toc set format of file(s)\n\
  28. -d TEMPLATE set disc template (see TEMPLATE EXPANSION)\n\
  29. -t TEMPLATE set track template (see TEMPLATE EXPANSION)\n\
  30. \n\
  31. Template Expansion\n\
  32. Disc:\n\
  33. %A - album arranger\n\
  34. %C - album composer\n\
  35. %G - album genre\n\
  36. %M - album message\n\
  37. %N - number of tracks\n\
  38. %P - album performer\n\
  39. %S - album songwriter\n\
  40. %T - album title\n\
  41. %U - album UPC/EAN\n\
  42. Track:\n\
  43. %a - track arranger\n\
  44. %c - track composer\n\
  45. %g - track genre\n\
  46. %i - track ISRC\n\
  47. %m - track message\n\
  48. %n - track number\n\
  49. %p - track perfomer\n\
  50. %t - track title\n\
  51. %u - track ISRC (CD-TEXT)\n\
  52. \n\
  53. Any other %<character> is expanded to that character. For example, to get a\n\
  54. '%', use %%.\n\
  55. ", stdout);
  56. fprintf(stdout, "default disc template is:\n\"%s\"\n", D_TEMPLATE);
  57. fprintf(stdout, "default track template is:\n\"%s\"\n", T_TEMPLATE);
  58. } else {
  59. fprintf(stderr, "%s: syntax error\n", progname);
  60. fprintf(stderr, "run `%s -h' for usage\n", progname);
  61. }
  62. exit (status);
  63. }
  64. void disc_field (char *c, Cd *cd)
  65. {
  66. Cdtext *cdtext = NULL;
  67. cdtext = cd_get_cdtext(cd);
  68. switch (*c) {
  69. case 'A':
  70. printf("%s", cdtext_get(PTI_ARRANGER, cdtext));
  71. break;
  72. case 'C':
  73. printf("%s", cdtext_get(PTI_COMPOSER, cdtext));
  74. break;
  75. case 'G':
  76. printf("%s", cdtext_get(PTI_GENRE, cdtext));
  77. break;
  78. case 'M':
  79. printf("%s", cdtext_get(PTI_MESSAGE, cdtext));
  80. break;
  81. case 'N':
  82. printf("%0*d", 2, cd_get_ntrack(cd));
  83. break;
  84. case 'P':
  85. printf("%s", cdtext_get(PTI_PERFORMER, cdtext));
  86. break;
  87. case 'R':
  88. printf("%s", cdtext_get(PTI_ARRANGER, cdtext));
  89. break;
  90. case 'S':
  91. printf("%s", cdtext_get(PTI_SONGWRITER, cdtext));
  92. break;
  93. case 'T':
  94. printf("%s", cdtext_get(PTI_TITLE, cdtext));
  95. break;
  96. case 'U':
  97. printf("%s", cdtext_get(PTI_UPC_ISRC, cdtext));
  98. break;
  99. default:
  100. putchar(*c);
  101. break;
  102. }
  103. }
  104. void track_field (char *c, Cd *cd, int trackno, int width)
  105. {
  106. Track *track = NULL;
  107. Cdtext *cdtext = NULL;
  108. track = cd_get_track(cd, trackno);
  109. cdtext = track_get_cdtext(track);
  110. switch (*c) {
  111. case 'a':
  112. printf("%*s", width, cdtext_get(PTI_ARRANGER, cdtext));
  113. break;
  114. case 'c':
  115. printf("%*s", width, cdtext_get(PTI_COMPOSER, cdtext));
  116. break;
  117. case 'f':
  118. printf("%*s", width, track_get_filename(track));
  119. break;
  120. case 'g':
  121. printf("%*s", width, cdtext_get(PTI_GENRE, cdtext));
  122. break;
  123. case 'i':
  124. printf("%*s", width, track_get_isrc(track));
  125. break;
  126. case 'm':
  127. printf("%*s", width, cdtext_get(PTI_MESSAGE, cdtext));
  128. break;
  129. case 'n':
  130. printf("%0*d", width, trackno);
  131. break;
  132. case 'p':
  133. printf("%*s", width, cdtext_get(PTI_PERFORMER, cdtext));
  134. break;
  135. case 's':
  136. printf("%*s", width, cdtext_get(PTI_SONGWRITER, cdtext));
  137. break;
  138. case 't':
  139. printf("%*s", width, cdtext_get(PTI_TITLE, cdtext));
  140. break;
  141. case 'u':
  142. printf("%*s", width, cdtext_get(PTI_UPC_ISRC, cdtext));
  143. break;
  144. default:
  145. disc_field(c, cd);
  146. break;
  147. }
  148. }
  149. void print_info (Cd *cd)
  150. {
  151. int i; /* track */
  152. char *c;
  153. /* field flags */
  154. int flag = 1; /* flags remain */
  155. int zeropad = 0;
  156. /* field width */
  157. int width;
  158. for (c = d_template; '\0' != *c; c++) {
  159. if ('%' == *c) {
  160. c++;
  161. disc_field(c, cd);
  162. } else {
  163. putchar(*c);
  164. }
  165. }
  166. for (i = 1; i <= cd_get_ntrack(cd); i++) {
  167. for (c = t_template; '\0' != *c; c++) {
  168. /* TODO: should apply escapes and width to disc
  169. * template as well
  170. */
  171. if ('\\' == *c) {
  172. c++;
  173. /* TODO: add more (all?) escapes */
  174. switch (*c) {
  175. case 'n':
  176. putchar('\n');
  177. break;
  178. case 't':
  179. putchar('\t');
  180. break;
  181. default:
  182. putchar(*c);
  183. break;
  184. }
  185. } else if ('%' == *c) {
  186. c++;
  187. /* parse flags */
  188. /* TODO: zero-padding does nothing */
  189. do {
  190. switch (*c) {
  191. case '0': /* zero-padding */
  192. c++;
  193. zeropad = 1;
  194. break;
  195. default:
  196. flag = 0;
  197. }
  198. } while (0 != flag);
  199. /* parse width */
  200. width = 0;
  201. while (0 != isdigit(*c)) {
  202. width = width * 10 + *c++ - '0';
  203. }
  204. track_field(c, cd, i, width);
  205. } else {
  206. putchar(*c);
  207. }
  208. }
  209. }
  210. }
  211. int info (char *name, int format)
  212. {
  213. Cd *cd = NULL;
  214. if (NULL == (cd = cf_parse(name, &format))) {
  215. fprintf(stderr, "%s: input file error\n", name);
  216. return -1;
  217. }
  218. print_info(cd);
  219. return 0;
  220. }
  221. int main (int argc, char **argv)
  222. {
  223. int format = UNKNOWN;
  224. /* getopt () variables */
  225. char c;
  226. extern char *optarg;
  227. extern int optind;
  228. progname = *argv;
  229. while (-1 != (c = getopt(argc, argv, "hi:d:t:"))) {
  230. switch (c) {
  231. case 'h':
  232. usage(0);
  233. break;
  234. case 'i':
  235. if (0 == strcmp("cue", optarg))
  236. format = CUE;
  237. else if (0 == strcmp("toc", optarg))
  238. format = TOC;
  239. break;
  240. case 'd':
  241. d_template = optarg;
  242. break;
  243. case 't':
  244. t_template = optarg;
  245. break;
  246. default:
  247. usage(1);
  248. break;
  249. }
  250. }
  251. if (optind == argc) {
  252. info("-", format);
  253. } else {
  254. for (; optind < argc; optind++)
  255. info(argv[optind], format);
  256. }
  257. return 0;
  258. }