You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

281 lines
4.5 KiB

  1. %{
  2. /*
  3. * cue_parse.y -- parser for cue files
  4. *
  5. * Copyright (C) 2004 Svend Sorensen
  6. * For license terms, see the file COPYING in this distribution.
  7. */
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "cd.h"
  12. #include "time.h"
  13. #include "cue_parse_prefix.h"
  14. #define YYDEBUG 1
  15. extern int yylex();
  16. void yyerror (char *s);
  17. static Cd *cd = NULL;
  18. static Track *track = NULL;
  19. static Track *prev_track = NULL;
  20. static Cdtext *cdtext = NULL;
  21. static char *prev_filename = NULL; /* last file in or before last track */
  22. static char *cur_filename = NULL; /* last file in the last track */
  23. static char *new_filename = NULL; /* last file in this track */
  24. %}
  25. %start cuefile
  26. %union {
  27. long ival;
  28. char *sval;
  29. }
  30. %token <ival> NUMBER
  31. %token <sval> STRING
  32. /* global (header) */
  33. %token CATALOG
  34. %token CDTEXTFILE
  35. %token FFILE
  36. %token BINARY
  37. %token MOTOROLA
  38. %token AIFF
  39. %token WAVE
  40. %token MP3
  41. /* track */
  42. %token TRACK
  43. %token <ival> AUDIO
  44. %token <ival> MODE1_2048
  45. %token <ival> MODE1_2352
  46. %token <ival> MODE2_2336
  47. %token <ival> MODE2_2048
  48. %token <ival> MODE2_2342
  49. %token <ival> MODE2_2332
  50. %token <ival> MODE2_2352
  51. /* ISRC is with CD_TEXT */
  52. %token TRACK_ISRC
  53. %token FLAGS
  54. %token <ival> PRE
  55. %token <ival> DCP
  56. %token <ival> FOUR_CH
  57. %token <ival> SCMS
  58. %token PREGAP
  59. %token INDEX
  60. %token POSTGAP
  61. /* CD-TEXT */
  62. %token <ival> TITLE
  63. %token <ival> PERFORMER
  64. %token <ival> SONGWRITER
  65. %token <ival> COMPOSER
  66. %token <ival> ARRANGER
  67. %token <ival> MESSAGE
  68. %token <ival> DISC_ID
  69. %token <ival> GENRE
  70. %token <ival> TOC_INFO1
  71. %token <ival> TOC_INFO2
  72. %token <ival> UPC_EAN
  73. %token <ival> ISRC
  74. %token <ival> SIZE_INFO
  75. %type <ival> track_mode
  76. %type <ival> track_flag
  77. %type <ival> time
  78. %type <ival> cdtext_item
  79. %%
  80. cuefile
  81. : new_cd global_statements track_list
  82. ;
  83. new_cd
  84. : /* empty */ {
  85. cd = cd_init();
  86. cdtext = cd_get_cdtext(cd);
  87. }
  88. ;
  89. global_statements
  90. : /* empty */
  91. | global_statements global_statement
  92. ;
  93. global_statement
  94. : CATALOG STRING '\n' { cd_set_catalog(cd, $2); }
  95. | CDTEXTFILE STRING '\n' { /* ignored */ }
  96. | cdtext
  97. | track_data
  98. | error '\n'
  99. ;
  100. track_data
  101. : FFILE STRING file_format '\n' {
  102. if (NULL != new_filename) {
  103. yyerror("too many files specified\n");
  104. free(new_filename);
  105. }
  106. new_filename = strdup($2);
  107. }
  108. ;
  109. track_list
  110. : track
  111. | track_list track
  112. ;
  113. track
  114. : new_track track_def track_statements
  115. ;
  116. file_format
  117. : BINARY
  118. | MOTOROLA
  119. | AIFF
  120. | WAVE
  121. | MP3
  122. ;
  123. new_track
  124. : /*empty */ {
  125. /* save previous track, to later set length */
  126. prev_track = track;
  127. track = cd_add_track(cd);
  128. cdtext = track_get_cdtext(track);
  129. cur_filename = new_filename;
  130. if (NULL != cur_filename)
  131. prev_filename = cur_filename;
  132. if (NULL == prev_filename)
  133. yyerror("no file specified for track");
  134. else
  135. track_set_filename(track, prev_filename);
  136. new_filename = NULL;
  137. }
  138. ;
  139. track_def
  140. : TRACK NUMBER track_mode '\n' {
  141. track_set_mode(track, $3);
  142. }
  143. ;
  144. track_mode
  145. : AUDIO
  146. | MODE1_2048
  147. | MODE1_2352
  148. | MODE2_2336
  149. | MODE2_2048
  150. | MODE2_2342
  151. | MODE2_2332
  152. | MODE2_2352
  153. ;
  154. track_statements
  155. : track_statement
  156. | track_statements track_statement
  157. ;
  158. track_statement
  159. : cdtext
  160. | FLAGS track_flags '\n'
  161. | TRACK_ISRC STRING '\n' { track_set_isrc(track, $2); }
  162. | PREGAP time '\n' { track_set_zero_pre(track, $2); }
  163. | INDEX NUMBER time '\n' {
  164. int i = track_get_nindex(track);
  165. long prev_length;
  166. if (0 == i) {
  167. /* first index */
  168. track_set_start(track, $3);
  169. if (NULL != prev_track && NULL == cur_filename) {
  170. /* track shares file with previous track */
  171. prev_length = $3 - track_get_start(prev_track);
  172. track_set_length(prev_track, prev_length);
  173. }
  174. }
  175. for (; i <= $2; i++)
  176. track_add_index(track, \
  177. track_get_zero_pre(track) + $3 \
  178. - track_get_start(track));
  179. }
  180. | POSTGAP time '\n' { track_set_zero_post(track, $2); }
  181. | track_data
  182. | error '\n'
  183. ;
  184. track_flags
  185. : /* empty */
  186. | track_flags track_flag { track_set_flag(track, $2); }
  187. ;
  188. track_flag
  189. : PRE
  190. | DCP
  191. | FOUR_CH
  192. | SCMS
  193. ;
  194. cdtext
  195. : cdtext_item STRING '\n' { cdtext_set ($1, $2, cdtext); }
  196. ;
  197. cdtext_item
  198. : TITLE
  199. | PERFORMER
  200. | SONGWRITER
  201. | COMPOSER
  202. | ARRANGER
  203. | MESSAGE
  204. | DISC_ID
  205. | GENRE
  206. | TOC_INFO1
  207. | TOC_INFO2
  208. | UPC_EAN
  209. | ISRC
  210. | SIZE_INFO
  211. ;
  212. time
  213. : NUMBER
  214. | NUMBER ':' NUMBER ':' NUMBER { $$ = time_msf_to_frame($1, $3, $5); }
  215. ;
  216. %%
  217. /* lexer interface */
  218. extern int cue_lineno;
  219. extern int yydebug;
  220. extern FILE *cue_yyin;
  221. void yyerror (char *s)
  222. {
  223. fprintf(stderr, "%d: %s\n", cue_lineno, s);
  224. }
  225. Cd *cue_parse (FILE *fp)
  226. {
  227. cue_yyin = fp;
  228. yydebug = 0;
  229. if (0 == yyparse())
  230. return cd;
  231. return NULL;
  232. }