dep: Add libcue

This commit is contained in:
Connor McLaughlin
2019-10-18 18:16:52 +10:00
parent c8bbd25f59
commit 52c16deba6
22 changed files with 7358 additions and 0 deletions

414
dep/libcue/src/cd.c Normal file
View File

@ -0,0 +1,414 @@
/*
* Copyright (c) 2004, 2005, 2006, 2007, Svend Sorensen
* Copyright (c) 2009, 2010 Jochen Keil
* For license terms, see the file COPYING in this distribution.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cd.h"
typedef struct Data Data;
struct Data {
int type; /* DataType */
char *name; /* data source name */
long start; /* start time for data */
long length; /* length of data */
};
struct Track {
Data zero_pre; /* pre-gap generated with zero data */
Data file; /* track data file */
Data zero_post; /* post-gap generated with zero data */
int mode; /* track mode */
int sub_mode; /* sub-channel mode */
int flags; /* flags */
char *isrc; /* IRSC Code (5.22.4) 12 bytes */
Cdtext *cdtext; /* CD-TEXT */
Rem* rem;
long index[MAXINDEX+1]; /* indexes (in frames) (5.29.2.5)
* relative to start of file */
};
struct Cd {
int mode; /* disc mode */
char *catalog; /* Media Catalog Number (5.22.3) */
char *cdtextfile; /* Filename of CDText File */
Cdtext *cdtext; /* CD-TEXT */
Rem* rem;
int ntrack; /* number of tracks in album */
Track *track[MAXTRACK]; /* array of tracks */
};
Cd *cd_init(void)
{
Cd *cd = NULL;
cd = malloc(sizeof(Cd));
if(NULL == cd) {
fprintf(stderr, "unable to create cd\n");
} else {
cd->mode = MODE_CD_DA;
cd->catalog = NULL;
cd->cdtextfile = NULL;
cd->cdtext = cdtext_init();
cd->rem = rem_new();
cd->ntrack = 0;
}
return cd;
}
void track_delete(struct Track* track)
{
if (track != NULL)
{
cdtext_delete(track_get_cdtext(track));
rem_free(track_get_rem(track));
free(track->isrc);
free(track->zero_pre.name);
free(track->zero_post.name);
free(track->file.name);
free(track);
}
}
void cd_delete(struct Cd* cd)
{
int i = 0;
if (cd != NULL)
{
free(cd->catalog);
free(cd->cdtextfile);
for (i = 0; i < cd->ntrack; i++)
track_delete(cd->track[i]);
cdtext_delete(cd_get_cdtext(cd));
rem_free(cd_get_rem(cd));
free(cd);
}
}
Track *track_init(void)
{
Track *track = NULL;
track = malloc(sizeof(Track));
if (NULL == track) {
fprintf(stderr, "unable to create track\n");
} else {
track->zero_pre.type = DATA_ZERO;
track->zero_pre.name = NULL;
track->zero_pre.start = -1;
track->zero_pre.length = -1;
track->file.type = DATA_AUDIO;
track->file.name = NULL;
track->file.start = -1;
track->file.length = -1;
track->zero_post.type = DATA_ZERO;
track->zero_post.name = NULL;
track->zero_post.start = -1;
track->zero_post.length = -1;
track->mode = MODE_AUDIO;
track->sub_mode = SUB_MODE_RW;
track->flags = FLAG_NONE;
track->isrc = NULL;
track->cdtext = cdtext_init();
track->rem = rem_new();
int i;
for (i=0; i<=MAXINDEX; i++)
track->index[i] = -1;
}
return track;
}
/*
* cd structure functions
*/
void cd_set_mode(Cd *cd, int mode)
{
cd->mode = mode;
}
enum DiscMode cd_get_mode(const Cd *cd)
{
return cd->mode;
}
void cd_set_catalog(Cd *cd, char *catalog)
{
if (cd->catalog)
free(cd->catalog);
cd->catalog = strdup(catalog);
}
void cd_set_cdtextfile(Cd *cd, char *cdtextfile)
{
if (cd->cdtextfile)
free(cd->cdtextfile);
cd->cdtextfile = strdup(cdtextfile);
}
const char *cd_get_cdtextfile(const Cd *cd)
{
return cd->cdtextfile;
}
Cdtext *cd_get_cdtext(const Cd *cd)
{
if (cd != NULL)
return cd->cdtext;
else
return NULL;
}
Rem*
cd_get_rem(const Cd* cd)
{
if (cd != NULL)
return cd->rem;
else
return NULL;
}
Track *cd_add_track(Cd *cd)
{
if (MAXTRACK > cd->ntrack)
cd->ntrack++;
else
fprintf(stderr, "too many tracks\n");
/* this will reinit last track if there were too many */
cd->track[cd->ntrack - 1] = track_init();
return cd->track[cd->ntrack - 1];
}
int cd_get_ntrack(const Cd *cd)
{
return cd->ntrack;
}
Track *cd_get_track(const Cd *cd, int i)
{
if ((0 < i) && (i <= cd->ntrack) && (cd != NULL))
return cd->track[i - 1];
else
return NULL;
}
/*
* track structure functions
*/
void track_set_filename(Track *track, char *filename)
{
if (track->file.name)
free(track->file.name);
track->file.name = strdup(filename);
}
const char *track_get_filename(const Track *track)
{
return track->file.name;
}
void track_set_start(Track *track, long start)
{
track->file.start = start;
}
long track_get_start(const Track *track)
{
return track->file.start;
}
void track_set_length(Track *track, long length)
{
track->file.length = length;
}
long track_get_length(const Track *track)
{
return track->file.length;
}
void track_set_mode(Track *track, int mode)
{
track->mode = mode;
}
enum TrackMode track_get_mode(const Track *track)
{
return track->mode;
}
void track_set_sub_mode(Track *track, int sub_mode)
{
track->sub_mode = sub_mode;
}
enum TrackSubMode track_get_sub_mode(const Track *track)
{
return track->sub_mode;
}
void track_set_flag(Track *track, int flag)
{
track->flags |= flag;
}
void track_clear_flag(Track *track, int flag)
{
track->flags &= ~flag;
}
int track_is_set_flag(const Track *track, enum TrackFlag flag)
{
return track->flags & flag;
}
void track_set_zero_pre(Track *track, long length)
{
track->zero_pre.length = length;
}
long track_get_zero_pre(const Track *track)
{
return track->zero_pre.length;
}
void track_set_zero_post(Track *track, long length)
{
track->zero_post.length = length;
}
long track_get_zero_post(const Track *track)
{
return track->zero_post.length;
}
void track_set_isrc(Track *track, char *isrc)
{
if (track->isrc)
free(track->isrc);
track->isrc = strdup(isrc);
}
const char *track_get_isrc(const Track *track)
{
return track->isrc;
}
Cdtext *track_get_cdtext(const Track *track)
{
if (track != NULL)
return track->cdtext;
else
return NULL;
}
Rem*
track_get_rem(const Track* track)
{
if (track != NULL)
return track->rem;
else
return NULL;
}
void track_set_index(Track *track, int i, long ind)
{
if (i > MAXINDEX) {
fprintf(stderr, "too many indexes\n");
return;
}
track->index[i] = ind;
}
long track_get_index(const Track *track, int i)
{
if ((0 <= i) && (i <= MAXINDEX))
return track->index[i];
return -1;
}
/*
* dump cd information
*/
static void cd_track_dump(Track *track)
{
int i;
printf("zero_pre: %ld\n", track->zero_pre.length);
printf("filename: %s\n", track->file.name);
printf("start: %ld\n", track->file.start);
printf("length: %ld\n", track->file.length);
printf("zero_post: %ld\n", track->zero_post.length);
printf("mode: %d\n", track->mode);
printf("sub_mode: %d\n", track->sub_mode);
printf("flags: 0x%x\n", track->flags);
printf("isrc: %s\n", track->isrc);
for (i = 0; i <= MAXINDEX; ++i)
if (track->index[i] != -1)
printf("index %d: %ld\n", i, track->index[i]);
if (NULL != track->cdtext) {
printf("cdtext:\n");
cdtext_dump(track->cdtext, 1);
}
if (track->rem != NULL)
{
printf("rem:\n");
rem_dump(track->rem);
}
}
void cd_dump(Cd *cd)
{
int i;
printf("Disc Info\n");
printf("mode: %d\n", cd->mode);
printf("catalog: %s\n", cd->catalog);
printf("cdtextfile: %s\n", cd->cdtextfile);
if (NULL != cd->cdtext) {
printf("cdtext:\n");
cdtext_dump(cd->cdtext, 0);
}
if (cd->rem != NULL)
{
printf("rem:\n");
rem_dump(cd->rem);
}
for (i = 0; i < cd->ntrack; ++i) {
printf("Track %d Info\n", i + 1);
cd_track_dump(cd->track[i]);
}
}

167
dep/libcue/src/cdtext.c Normal file
View File

@ -0,0 +1,167 @@
/*
* Copyright (c) 2004, 2005, 2006, 2007, Svend Sorensen
* Copyright (c) 2009, 2010 Jochen Keil
* For license terms, see the file COPYING in this distribution.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cdtext.h"
struct Cdtext {
int pti;
int format;
char *value;
};
Cdtext *cdtext_init(void)
{
Cdtext *new_cdtext = NULL;
Cdtext cdtext[] = {
{PTI_TITLE, FORMAT_CHAR, NULL},
{PTI_PERFORMER, FORMAT_CHAR, NULL},
{PTI_SONGWRITER, FORMAT_CHAR, NULL},
{PTI_COMPOSER, FORMAT_CHAR, NULL},
{PTI_ARRANGER, FORMAT_CHAR, NULL},
{PTI_MESSAGE, FORMAT_CHAR, NULL},
{PTI_DISC_ID, FORMAT_BINARY, NULL},
{PTI_GENRE, FORMAT_BINARY, NULL},
{PTI_TOC_INFO1, FORMAT_BINARY, NULL},
{PTI_TOC_INFO2, FORMAT_BINARY, NULL},
{PTI_RESERVED1, FORMAT_CHAR, NULL},
{PTI_RESERVED2, FORMAT_CHAR, NULL},
{PTI_RESERVED3, FORMAT_CHAR, NULL},
{PTI_RESERVED4, FORMAT_CHAR, NULL},
{PTI_UPC_ISRC, FORMAT_CHAR, NULL},
{PTI_SIZE_INFO, FORMAT_BINARY, NULL},
{PTI_END, FORMAT_CHAR, NULL}
};
new_cdtext = (Cdtext *) calloc (sizeof (cdtext) / sizeof (Cdtext), sizeof (Cdtext));
if (NULL == new_cdtext)
fprintf (stderr, "problem allocating memory\n");
else
memcpy (new_cdtext, cdtext, sizeof(cdtext));
return new_cdtext;
}
void cdtext_delete(Cdtext *cdtext)
{
int i;
if (NULL != cdtext) {
for (i = 0; PTI_END != cdtext[i].pti; i++)
{
free (cdtext[i].value);
}
free (cdtext);
}
}
/* return 0 if there is no cdtext, returns non-zero otherwise */
int cdtext_is_empty(Cdtext *cdtext)
{
for (; PTI_END != cdtext->pti; cdtext++)
if (NULL != cdtext->value)
return -1;
return 0;
}
/* sets cdtext's pti entry to field */
void cdtext_set(int pti, char *value, Cdtext *cdtext)
{
if (NULL != value) /* don't pass NULL to strdup */
for (; PTI_END != cdtext->pti; cdtext++)
if (pti == cdtext->pti) {
free (cdtext->value);
cdtext->value = strdup (value);
}
}
/* returns value for pti, NULL if pti is not found */
const char *cdtext_get(enum Pti pti, const Cdtext *cdtext)
{
for (; PTI_END != cdtext->pti; cdtext++)
if (pti == cdtext->pti)
return cdtext->value;
return NULL;
}
const char *cdtext_get_key(int pti, int istrack)
{
const char *key = NULL;
switch (pti) {
case PTI_TITLE:
key = "TITLE";
break;
case PTI_PERFORMER:
key = "PERFORMER";
break;
case PTI_SONGWRITER:
key = "SONGWRITER";
break;
case PTI_COMPOSER:
key = "COMPOSER";
break;
case PTI_ARRANGER:
key = "ARRANGER";
break;
case PTI_MESSAGE:
key = "MESSAGE";
break;
case PTI_DISC_ID:
key = "DISC_ID";
break;
case PTI_GENRE:
key = "GENRE";
break;
case PTI_TOC_INFO1:
key = "TOC_INFO1";
break;
case PTI_TOC_INFO2:
key = "TOC_INFO1";
break;
case PTI_RESERVED1:
/* reserved */
break;
case PTI_RESERVED2:
/* reserved */
break;
case PTI_RESERVED3:
/* reserved */
break;
case PTI_RESERVED4:
/* reserved */
break;
case PTI_UPC_ISRC:
if (0 == istrack)
key = "UPC_EAN";
else
key = "ISRC";
break;
case PTI_SIZE_INFO:
key = "SIZE_INFO";
break;
}
return key;
}
void cdtext_dump(Cdtext *cdtext, int istrack)
{
int pti;
const char *value = NULL;
for (pti = 0; PTI_END != pti; pti++) {
if (NULL != (value = cdtext_get(pti, cdtext))) {
printf("%s: ", cdtext_get_key(pti, istrack));
printf("%s\n", value);
}
}
}

1842
dep/libcue/src/cue_parser.c Normal file

File diff suppressed because it is too large Load Diff

126
dep/libcue/src/cue_parser.h Normal file
View File

@ -0,0 +1,126 @@
/* A Bison parser, made by GNU Bison 3.3.2. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Undocumented macros, especially those whose name start with YY_,
are private implementation details. Do not rely on them. */
#ifndef YY_YY_CUE_PARSER_H_INCLUDED
# define YY_YY_CUE_PARSER_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
NUMBER = 258,
STRING = 259,
CATALOG = 260,
CDTEXTFILE = 261,
FFILE = 262,
BINARY = 263,
MOTOROLA = 264,
AIFF = 265,
WAVE = 266,
MP3 = 267,
FLAC = 268,
TRACK = 269,
AUDIO = 270,
MODE1_2048 = 271,
MODE1_2352 = 272,
MODE2_2336 = 273,
MODE2_2048 = 274,
MODE2_2342 = 275,
MODE2_2332 = 276,
MODE2_2352 = 277,
TRACK_ISRC = 278,
FLAGS = 279,
PRE = 280,
DCP = 281,
FOUR_CH = 282,
SCMS = 283,
PREGAP = 284,
INDEX = 285,
POSTGAP = 286,
TITLE = 287,
PERFORMER = 288,
SONGWRITER = 289,
COMPOSER = 290,
ARRANGER = 291,
MESSAGE = 292,
DISC_ID = 293,
GENRE = 294,
TOC_INFO1 = 295,
TOC_INFO2 = 296,
UPC_EAN = 297,
ISRC = 298,
SIZE_INFO = 299,
DATE = 300,
XXX_GENRE = 301,
REPLAYGAIN_ALBUM_GAIN = 302,
REPLAYGAIN_ALBUM_PEAK = 303,
REPLAYGAIN_TRACK_GAIN = 304,
REPLAYGAIN_TRACK_PEAK = 305
};
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 57 "cue_parser.y" /* yacc.c:1921 */
long ival;
char *sval;
#line 114 "cue_parser.h" /* yacc.c:1921 */
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
int yyparse (void);
#endif /* !YY_YY_CUE_PARSER_H_INCLUDED */

374
dep/libcue/src/cue_parser.y Normal file
View File

@ -0,0 +1,374 @@
%{
/*
* Copyright (c) 2004, 2005, 2006, 2007, Svend Sorensen
* Copyright (c) 2009, 2010 Jochen Keil
* For license terms, see the file COPYING in this distribution.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cd.h"
#include "time.h"
#ifdef YY_BUF_SIZE
#undef YY_BUF_SIZE
#endif
#define YY_BUF_SIZE 16384
#define YYDEBUG 1
char fnamebuf[PARSER_BUFFER];
/* debugging */
//int yydebug = 1;
extern int yylineno;
extern FILE* yyin;
static Cd *cd = NULL;
static Track *track = NULL;
static Track *prev_track = NULL;
static Cdtext *cdtext = NULL;
static Rem *rem = NULL;
static char *prev_filename = NULL; /* last file in or before last track */
static char *cur_filename = NULL; /* last file in the last track */
static char *new_filename = NULL; /* last file in this track */
/* lexer interface */
typedef struct yy_buffer_state* YY_BUFFER_STATE;
int yylex(void);
void yyerror(const char*);
YY_BUFFER_STATE yy_scan_string(const char*);
YY_BUFFER_STATE yy_create_buffer(FILE*, int);
void yy_switch_to_buffer(YY_BUFFER_STATE);
void yy_delete_buffer(YY_BUFFER_STATE);
/* parser interface */
int yyparse(void);
Cd *cue_parse_file(FILE *fp);
Cd *cue_parse_string(const char*);
%}
%start cuefile
%union {
long ival;
char *sval;
}
%token <ival> NUMBER
%token <sval> STRING
/* global (header) */
%token CATALOG
%token CDTEXTFILE
%token FFILE
%token BINARY
%token MOTOROLA
%token AIFF
%token WAVE
%token MP3
%token FLAC
/* track */
%token TRACK
%token <ival> AUDIO
%token <ival> MODE1_2048
%token <ival> MODE1_2352
%token <ival> MODE2_2336
%token <ival> MODE2_2048
%token <ival> MODE2_2342
%token <ival> MODE2_2332
%token <ival> MODE2_2352
/* ISRC is with CD_TEXT */
%token TRACK_ISRC
%token FLAGS
%token <ival> PRE
%token <ival> DCP
%token <ival> FOUR_CH
%token <ival> SCMS
%token PREGAP
%token INDEX
%token POSTGAP
/* CD-TEXT */
%token <ival> TITLE
%token <ival> PERFORMER
%token <ival> SONGWRITER
%token <ival> COMPOSER
%token <ival> ARRANGER
%token <ival> MESSAGE
%token <ival> DISC_ID
%token <ival> GENRE
%token <ival> TOC_INFO1
%token <ival> TOC_INFO2
%token <ival> UPC_EAN
%token <ival> ISRC
%token <ival> SIZE_INFO
%type <ival> track_mode
%type <ival> track_flag
%type <ival> time
%type <ival> cdtext_item
/* REM */
%type <ival> rem_item
%token <ival> DATE
%token <ival> XXX_GENRE /* parsed in REM but stored in CD-TEXT */
%token <ival> REPLAYGAIN_ALBUM_GAIN
%token <ival> REPLAYGAIN_ALBUM_PEAK
%token <ival> REPLAYGAIN_TRACK_GAIN
%token <ival> REPLAYGAIN_TRACK_PEAK
%%
cuefile
: new_cd global_statements track_list
;
new_cd
: /* empty */ {
cd = cd_init();
cdtext = cd_get_cdtext(cd);
rem = cd_get_rem(cd);
}
;
global_statements
: /* empty */
| global_statements global_statement
;
global_statement
: CATALOG STRING '\n' { cd_set_catalog(cd, $2); }
| CDTEXTFILE STRING '\n' { cd_set_cdtextfile(cd, $2); }
| cdtext
| rem
| track_data
| error '\n'
;
track_data
: FFILE STRING file_format '\n' {
if (NULL != new_filename) {
yyerror("too many files specified\n");
}
if (track && track_get_index(track, 1) == -1) {
track_set_filename (track, $2);
} else {
new_filename = strncpy(fnamebuf, $2, sizeof(fnamebuf));
new_filename[sizeof(fnamebuf) - 1] = '\0';
}
}
;
track_list
: track
| track_list track
;
track
: new_track track_def track_statements
;
file_format
: BINARY
| MOTOROLA
| AIFF
| WAVE
| MP3
| FLAC
;
new_track
: /*empty */ {
/* save previous track, to later set length */
prev_track = track;
track = cd_add_track(cd);
cdtext = track_get_cdtext(track);
rem = track_get_rem(track);
cur_filename = new_filename;
if (NULL != cur_filename)
prev_filename = cur_filename;
if (NULL == prev_filename)
yyerror("no file specified for track");
else
track_set_filename(track, prev_filename);
new_filename = NULL;
}
;
track_def
: TRACK NUMBER track_mode '\n' {
track_set_mode(track, $3);
}
;
track_mode
: AUDIO
| MODE1_2048
| MODE1_2352
| MODE2_2336
| MODE2_2048
| MODE2_2342
| MODE2_2332
| MODE2_2352
;
track_statements
: track_statement
| track_statements track_statement
;
track_statement
: cdtext
| rem
| FLAGS track_flags '\n'
| TRACK_ISRC STRING '\n' { track_set_isrc(track, $2); }
| PREGAP time '\n' { track_set_zero_pre(track, $2); }
| INDEX NUMBER time '\n' {
long prev_length;
/* Set previous track length if it has not been set */
if (NULL != prev_track && NULL == cur_filename
&& track_get_length (prev_track) == -1) {
/* track shares file with previous track */
prev_length = $3 - track_get_start(prev_track);
track_set_length(prev_track, prev_length);
}
if (1 == $2) {
/* INDEX 01 */
track_set_start(track, $3);
long idx00 = track_get_index (track, 0);
if (idx00 != -1 && $3 != 0)
track_set_zero_pre (track, $3 - idx00);
}
track_set_index (track, $2, $3);
}
| POSTGAP time '\n' { track_set_zero_post(track, $2); }
| track_data
| error '\n'
;
track_flags
: /* empty */
| track_flags track_flag { track_set_flag(track, $2); }
;
track_flag
: PRE
| DCP
| FOUR_CH
| SCMS
;
cdtext
: cdtext_item STRING '\n' { cdtext_set ($1, $2, cdtext); }
;
cdtext_item
: TITLE
| PERFORMER
| SONGWRITER
| COMPOSER
| ARRANGER
| MESSAGE
| DISC_ID
| GENRE
| TOC_INFO1
| TOC_INFO2
| UPC_EAN
| ISRC
| SIZE_INFO
;
time
: NUMBER
| NUMBER ':' NUMBER ':' NUMBER { $$ = time_msf_to_frame($1, $3, $5); }
;
rem
: rem_item STRING '\n' { rem_set($1, $2, rem); }
| XXX_GENRE STRING '\n' { cdtext_set($1, $2, cdtext); }
;
rem_item
: DATE
| REPLAYGAIN_ALBUM_GAIN
| REPLAYGAIN_ALBUM_PEAK
| REPLAYGAIN_TRACK_GAIN
| REPLAYGAIN_TRACK_PEAK
;
%%
/* lexer interface */
void yyerror (const char *s)
{
fprintf(stderr, "%d: %s\n", yylineno, s);
}
static void reset_static_vars()
{
cd = NULL;
track = NULL;
prev_track = NULL;
cdtext = NULL;
rem = NULL;
prev_filename = NULL;
cur_filename = NULL;
new_filename = NULL;
}
Cd *cue_parse_file(FILE *fp)
{
YY_BUFFER_STATE buffer = NULL;
yyin = fp;
buffer = yy_create_buffer(yyin, YY_BUF_SIZE);
yy_switch_to_buffer(buffer);
Cd *ret_cd = NULL;
if (0 == yyparse()) ret_cd = cd;
else ret_cd = NULL;
yy_delete_buffer(buffer);
reset_static_vars();
return ret_cd;
}
Cd *cue_parse_string(const char* string)
{
YY_BUFFER_STATE buffer = NULL;
buffer = yy_scan_string(string);
Cd *ret_cd = NULL;
if (0 == yyparse()) ret_cd = cd;
else ret_cd = NULL;
yy_delete_buffer(buffer);
reset_static_vars();
return ret_cd;
}

2413
dep/libcue/src/cue_scanner.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,139 @@
%{
/*
* Copyright (c) 2004, 2005, 2006, 2007, Svend Sorensen
* Copyright (c) 2009, 2010 Jochen Keil
* For license terms, see the file COPYING in this distribution.
*/
#include <stdlib.h>
#include <string.h>
#include "cd.h"
#include "cue_parser.h"
char yy_buffer[PARSER_BUFFER];
int yylex(void);
%}
ws [ \t\r]
nonws [^ \t\r\n]
%option yylineno
%option noyywrap
%option noinput
%option nounput
%s NAME
%x REM
%x RPG
%x SKIP
%%
\'([^\']|\\\')*\' |
\"([^\"]|\\\")*\" {
yylval.sval = strncpy( yy_buffer,
++yytext,
(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng));
yylval.sval[(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng) - 2] = '\0';
BEGIN(INITIAL);
return STRING;
}
<NAME>{nonws}+ {
yylval.sval = strncpy( yy_buffer,
yytext,
(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng));
yylval.sval[(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng)] = '\0';
BEGIN(INITIAL);
return STRING;
}
CATALOG { BEGIN(NAME); return CATALOG; }
CDTEXTFILE { BEGIN(NAME); return CDTEXTFILE; }
FILE { BEGIN(NAME); return FFILE; }
BINARY { return BINARY; }
MOTOROLA { return MOTOROLA; }
AIFF { return AIFF; }
WAVE { return WAVE; }
MP3 { return MP3; }
FLAC { return FLAC; }
TRACK { return TRACK; }
AUDIO { yylval.ival = MODE_AUDIO; return AUDIO; }
MODE1\/2048 { yylval.ival = MODE_MODE1; return MODE1_2048; }
MODE1\/2352 { yylval.ival = MODE_MODE1_RAW; return MODE1_2352; }
MODE2\/2336 { yylval.ival = MODE_MODE2; return MODE2_2336; }
MODE2\/2048 { yylval.ival = MODE_MODE2_FORM1; return MODE2_2048; }
MODE2\/2342 { yylval.ival = MODE_MODE2_FORM2; return MODE2_2342; }
MODE2\/2332 { yylval.ival = MODE_MODE2_FORM_MIX; return MODE2_2332; }
MODE2\/2352 { yylval.ival = MODE_MODE2_RAW; return MODE2_2352; }
FLAGS { return FLAGS; }
PRE { yylval.ival = FLAG_PRE_EMPHASIS; return PRE; }
DCP { yylval.ival = FLAG_COPY_PERMITTED; return DCP; }
4CH { yylval.ival = FLAG_FOUR_CHANNEL; return FOUR_CH; }
SCMS { yylval.ival = FLAG_SCMS; return SCMS; }
PREGAP { return PREGAP; }
INDEX { return INDEX; }
POSTGAP { return POSTGAP; }
TITLE { BEGIN(NAME); yylval.ival = PTI_TITLE; return TITLE; }
PERFORMER { BEGIN(NAME); yylval.ival = PTI_PERFORMER; return PERFORMER; }
SONGWRITER { BEGIN(NAME); yylval.ival = PTI_SONGWRITER; return SONGWRITER; }
COMPOSER { BEGIN(NAME); yylval.ival = PTI_COMPOSER; return COMPOSER; }
ARRANGER { BEGIN(NAME); yylval.ival = PTI_ARRANGER; return ARRANGER; }
MESSAGE { BEGIN(NAME); yylval.ival = PTI_MESSAGE; return MESSAGE; }
DISC_ID { BEGIN(NAME); yylval.ival = PTI_DISC_ID; return DISC_ID; }
GENRE { BEGIN(NAME); yylval.ival = PTI_GENRE; return GENRE; }
TOC_INFO1 { BEGIN(NAME); yylval.ival = PTI_TOC_INFO1; return TOC_INFO1; }
TOC_INFO2 { BEGIN(NAME); yylval.ival = PTI_TOC_INFO2; return TOC_INFO2; }
UPC_EAN { BEGIN(NAME); yylval.ival = PTI_UPC_ISRC; return UPC_EAN; }
ISRC/{ws}+\" { BEGIN(NAME); yylval.ival = PTI_UPC_ISRC; return ISRC; }
SIZE_INFO { BEGIN(NAME); yylval.ival = PTI_SIZE_INFO; return SIZE_INFO; }
ISRC { BEGIN(NAME); return TRACK_ISRC; }
REM { BEGIN(REM); /* exclusive rules for special exceptions */ }
<REM>DATE { BEGIN(NAME); yylval.ival = REM_DATE; return DATE; }
<REM>GENRE { BEGIN(NAME); yylval.ival = PTI_GENRE; return XXX_GENRE; }
<REM>REPLAYGAIN_ALBUM_GAIN { BEGIN(RPG); yylval.ival = REM_REPLAYGAIN_ALBUM_GAIN;
return REPLAYGAIN_ALBUM_GAIN; }
<REM>REPLAYGAIN_ALBUM_PEAK { BEGIN(RPG); yylval.ival = REM_REPLAYGAIN_ALBUM_PEAK;
return REPLAYGAIN_ALBUM_PEAK; }
<REM>REPLAYGAIN_TRACK_GAIN { BEGIN(RPG); yylval.ival = REM_REPLAYGAIN_TRACK_GAIN;
return REPLAYGAIN_TRACK_GAIN; }
<REM>REPLAYGAIN_TRACK_PEAK { BEGIN(RPG); yylval.ival = REM_REPLAYGAIN_TRACK_PEAK;
return REPLAYGAIN_TRACK_PEAK; }
<REM>{ws}+ { BEGIN(REM); }
<REM>. { BEGIN(REM); }
<REM>\n { BEGIN(INITIAL); }
<RPG>{nonws}+ {
yylval.sval = strncpy( yy_buffer,
yytext,
(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng));
yylval.sval[(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng)] = '\0';
BEGIN(SKIP);
return STRING;
}
<RPG>{ws}+ { BEGIN(RPG); }
<SKIP>.*\n { BEGIN(INITIAL); yylineno++; return '\n'; }
{ws}+ { /* ignore whitespace */ }
[[:digit:]]+ { yylval.ival = atoi(yytext); return NUMBER; }
: { return yytext[0]; }
^{ws}*\n { yylineno++; /* blank line */ }
\n { yylineno++; return '\n'; }
. { fprintf(stderr, "bad character '%c'\n", yytext[0]); }
%%

140
dep/libcue/src/rem.c Normal file
View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2009, 2010 Jochen Keil
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY Jochen Keil ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Jochen Keil BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rem.h"
struct Rem {
unsigned int cmt;
char *value;
};
Rem*
rem_new( void)
{
Rem* new_rem = NULL;
Rem rem[] = {
{REM_DATE, NULL},
{REM_REPLAYGAIN_ALBUM_GAIN, NULL},
{REM_REPLAYGAIN_ALBUM_PEAK, NULL},
{REM_REPLAYGAIN_TRACK_GAIN, NULL},
{REM_REPLAYGAIN_TRACK_PEAK, NULL},
{REM_END, NULL}
};
/* sizeof(rem) = number of elements in rem[] * sizeof(Rem) */
new_rem = (Rem*)calloc(sizeof(rem) / sizeof(Rem), sizeof(Rem));
if (new_rem == NULL)
fprintf(stderr, "rem_new(): problem allocating memory\n");
else
memcpy(new_rem, rem, sizeof(rem));
return new_rem;
}
void
rem_free( Rem* rem)
{
if (rem == NULL)
return;
Rem* ptr = rem;
do
{
free(ptr->value);
}
while ((++ptr)->cmt != REM_END);
free(rem);
}
int
rem_is_emtpy( Rem* rem)
{
if (rem == NULL)
return 1;
do
{
if (rem->value != NULL)
return 0;
} while ((++rem)->cmt != REM_END);
return 1;
}
void
rem_set( unsigned int cmt,
char* value,
Rem* rem)
{
if (rem == NULL || value == NULL)
return;
do
{
if (rem->cmt == cmt)
{
free(rem->value);
rem->value = strdup(value);
return;
}
} while ((++rem)->cmt != REM_END);
}
const char*
rem_get( RemType cmt,
Rem* rem)
{
if (rem == NULL)
return NULL;
do
{
if (rem->cmt == cmt)
{
if (rem->value != NULL)
return rem->value;
else
return NULL;
}
} while ((++rem)->cmt != REM_END);
return NULL;
}
void
rem_dump( Rem* rem)
{
if (rem == NULL)
return;
do
{
printf("REM %u: %s\n", rem->cmt, rem->value);
} while ((++rem)->cmt != REM_END);
}

36
dep/libcue/src/time.c Normal file
View File

@ -0,0 +1,36 @@
/*
* time.c -- time functions
*
* Copyright (C) 2004, 2005, 2006, 2007 Svend Sorensen
* For license terms, see the file COPYING in this distribution.
*/
#include "time.h"
#include <stdio.h>
#include <stdlib.h>
long time_msf_to_frame(int m, int s, int f)
{
return (m * 60 + s) * 75 + f;
}
void time_frame_to_msf(long frame, int *m, int *s, int *f)
{
*f = frame % 75; /* 0 <= frames <= 74 */
frame /= 75;
*s = frame % 60; /* 0 <= seconds <= 59 */
frame /= 60;
*m = frame; /* 0 <= minutes */
}
/* print frame in mm:ss:ff format */
char *time_frame_to_mmssff(long f)
{
static char msf[9];
int minutes, seconds, frames;
time_frame_to_msf(f, &minutes, &seconds, &frames);
sprintf(msf, "%02d:%02d:%02d", minutes, seconds, frames);
return msf;
}