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.
 
 
 
 
 
 

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