Removed lib and tools dirs (again?).
This commit is contained in:
51
lib/Makefile
51
lib/Makefile
@@ -1,51 +0,0 @@
|
|||||||
YFLAGS+= -d
|
|
||||||
LEX=flex
|
|
||||||
|
|
||||||
TARGETS= libcuefile.a
|
|
||||||
OBJS= cd.o cdtext.o time.o cuefile.o
|
|
||||||
CUE_OBJS= cue_parse.o cue_scan.o cue_print.o
|
|
||||||
TOC_OBJS= toc_parse.o toc_scan.o toc_print.o
|
|
||||||
|
|
||||||
# There are multiple scanners/parsers
|
|
||||||
# so we need a prefix to aviod conflicts.
|
|
||||||
# (NOTE: these lines require GNU Make)
|
|
||||||
|
|
||||||
# these have been moved to the source files to prepare for automake
|
|
||||||
# for flex, used %option prefix="cue_yy"
|
|
||||||
#toc_scan.c: LFLAGS+= -Ptoc_yy
|
|
||||||
#cue_scan.c: LFLAGS+= -Pcue_yy
|
|
||||||
# for yacc, used cue_parse_prefix.h with defines
|
|
||||||
#toc_parse.c: YFLAGS+= -p toc_yy
|
|
||||||
#cue_parse.c: YFLAGS+= -p cue_yy
|
|
||||||
|
|
||||||
all: $(TARGETS)
|
|
||||||
|
|
||||||
libcuefile.a: libcuefile.a($(OBJS) $(CUE_OBJS) $(TOC_OBJS))
|
|
||||||
|
|
||||||
%.c: %.y
|
|
||||||
$(YACC) -o $@ $(YFLAGS) $<
|
|
||||||
|
|
||||||
install: all
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(TARGETS)
|
|
||||||
rm -f *.o *.a *.core *.output
|
|
||||||
rm -f toc_scan.c toc_parse.c toc_parse.h
|
|
||||||
rm -f cue_scan.c cue_parse.c cue_parse.h
|
|
||||||
|
|
||||||
# dependancies
|
|
||||||
# generated with `gcc -MM *.c'
|
|
||||||
# after building lex and yacc .c files
|
|
||||||
|
|
||||||
cd.o: cd.c cd.h cdtext.h
|
|
||||||
cdtext.o: cdtext.c cdtext.h
|
|
||||||
cuefile.o: cuefile.c cuefile.h cd.h cdtext.h cue.h toc.h
|
|
||||||
cue_parse.o: cue_parse.c cd.h cdtext.h time.h
|
|
||||||
cue_print.o: cue_print.c cd.h cdtext.h time.h
|
|
||||||
cue_scan.o: cue_scan.c cd.h cdtext.h cue_parse.h
|
|
||||||
time.o: time.c
|
|
||||||
toc_parse.o: toc_parse.c cd.h cdtext.h time.h
|
|
||||||
toc_print.o: toc_print.c cd.h cdtext.h time.h
|
|
||||||
toc_scan.o: toc_scan.c cd.h cdtext.h toc_parse.h
|
|
||||||
329
lib/cd.c
329
lib/cd.c
@@ -1,329 +0,0 @@
|
|||||||
/*
|
|
||||||
* cd.c -- cd functions
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* 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 */
|
|
||||||
int nindex; /* number of indexes */
|
|
||||||
long index[MAXINDEX]; /* indexes (in frames) (5.29.2.5)
|
|
||||||
* relative to start of track
|
|
||||||
* index[0] should always be zero */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Cd {
|
|
||||||
int mode; /* disc mode */
|
|
||||||
char *catalog; /* Media Catalog Number (5.22.3) */
|
|
||||||
Cdtext *cdtext; /* CD-TEXT */
|
|
||||||
int ntrack; /* number of tracks in album */
|
|
||||||
Track *track[MAXTRACK]; /* array of tracks */
|
|
||||||
};
|
|
||||||
|
|
||||||
Cd *cd_init ()
|
|
||||||
{
|
|
||||||
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->cdtext = cdtext_init();
|
|
||||||
cd->ntrack = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cd;
|
|
||||||
}
|
|
||||||
|
|
||||||
Track *track_init ()
|
|
||||||
{
|
|
||||||
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 = 0;
|
|
||||||
track->zero_pre.length = 0;
|
|
||||||
|
|
||||||
track->file.type = DATA_AUDIO;
|
|
||||||
track->file.name = NULL;
|
|
||||||
track->file.start = 0;
|
|
||||||
track->file.length = 0;
|
|
||||||
|
|
||||||
track->zero_post.type = DATA_ZERO;
|
|
||||||
track->zero_post.name = NULL;
|
|
||||||
track->zero_post.start = 0;
|
|
||||||
track->zero_post.length = 0;
|
|
||||||
|
|
||||||
track->mode = MODE_AUDIO;
|
|
||||||
track->sub_mode = SUB_MODE_RW;
|
|
||||||
track->flags = FLAG_NONE;
|
|
||||||
track->isrc = NULL;
|
|
||||||
track->cdtext = cdtext_init();
|
|
||||||
track->nindex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return track;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cd structure functions
|
|
||||||
*/
|
|
||||||
void cd_set_mode (Cd *cd, int mode)
|
|
||||||
{
|
|
||||||
cd->mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cd_get_mode (Cd *cd)
|
|
||||||
{
|
|
||||||
return cd->mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cd_set_catalog (Cd *cd, char *catalog)
|
|
||||||
{
|
|
||||||
if (cd->catalog)
|
|
||||||
free(cd->catalog);
|
|
||||||
|
|
||||||
cd->catalog = strdup(catalog);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *cd_get_catalog (Cd *cd)
|
|
||||||
{
|
|
||||||
return cd->catalog;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cdtext *cd_get_cdtext (Cd *cd)
|
|
||||||
{
|
|
||||||
return cd->cdtext;
|
|
||||||
}
|
|
||||||
|
|
||||||
Track *cd_add_track (Cd *cd)
|
|
||||||
{
|
|
||||||
if (MAXTRACK - 1 > 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 (Cd *cd)
|
|
||||||
{
|
|
||||||
return cd->ntrack;
|
|
||||||
}
|
|
||||||
|
|
||||||
Track *cd_get_track (Cd *cd, int i)
|
|
||||||
{
|
|
||||||
if (0 < i <= cd->ntrack)
|
|
||||||
return cd->track[i - 1];
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *track_get_filename (Track *track)
|
|
||||||
{
|
|
||||||
return track->file.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void track_set_start (Track *track, long start)
|
|
||||||
{
|
|
||||||
track->file.start = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
long track_get_start (Track *track)
|
|
||||||
{
|
|
||||||
return track->file.start;
|
|
||||||
}
|
|
||||||
|
|
||||||
void track_set_length (Track *track, long length)
|
|
||||||
{
|
|
||||||
track->file.length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
long track_get_length (Track *track)
|
|
||||||
{
|
|
||||||
return track->file.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
void track_set_mode (Track *track, int mode)
|
|
||||||
{
|
|
||||||
track->mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int track_get_mode (Track *track)
|
|
||||||
{
|
|
||||||
return track->mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void track_set_sub_mode (Track *track, int sub_mode)
|
|
||||||
{
|
|
||||||
track->sub_mode = sub_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int track_get_sub_mode (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 (Track *track, int flag)
|
|
||||||
{
|
|
||||||
return track->flags & flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
void track_set_zero_pre (Track *track, long length)
|
|
||||||
{
|
|
||||||
track->zero_pre.length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
long track_get_zero_pre (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 (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);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *track_get_isrc (Track *track)
|
|
||||||
{
|
|
||||||
return track->isrc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cdtext *track_get_cdtext (Track *track)
|
|
||||||
{
|
|
||||||
return track->cdtext;
|
|
||||||
}
|
|
||||||
|
|
||||||
void track_add_index (Track *track, long index)
|
|
||||||
{
|
|
||||||
if (MAXTRACK - 1 > track->nindex)
|
|
||||||
track->nindex++;
|
|
||||||
else
|
|
||||||
fprintf(stderr, "too many indexes\n");
|
|
||||||
|
|
||||||
/* this will overwrite last index if there were too many */
|
|
||||||
track->index[track->nindex - 1] = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
int track_get_nindex (Track *track)
|
|
||||||
{
|
|
||||||
return track->nindex;
|
|
||||||
}
|
|
||||||
|
|
||||||
long track_get_index (Track *track, int i)
|
|
||||||
{
|
|
||||||
if (0 <= i < track->nindex)
|
|
||||||
return track->index[i];
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dump cd information
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
printf("indexes: %d\n", track->nindex);
|
|
||||||
|
|
||||||
for (i = 0; i < track->nindex; ++i)
|
|
||||||
printf("index %d: %ld\n", i, track->index[i]);
|
|
||||||
|
|
||||||
if (NULL != track->cdtext) {
|
|
||||||
printf("cdtext:\n");
|
|
||||||
cdtext_dump(track->cdtext, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cd_dump (Cd *cd)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
printf("Disc Info\n");
|
|
||||||
printf("mode: %d\n", cd->mode);
|
|
||||||
printf("catalog: %s\n", cd->catalog);
|
|
||||||
if (NULL != cd->cdtext) {
|
|
||||||
printf("cdtext:\n");
|
|
||||||
cdtext_dump(cd->cdtext, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < cd->ntrack; ++i) {
|
|
||||||
printf("Track %d Info\n", i + 1);
|
|
||||||
cd_track_dump(cd->track[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
161
lib/cd.h
161
lib/cd.h
@@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* cd.h -- cd structure
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* references: MMC-3 draft revsion - 10g */
|
|
||||||
|
|
||||||
#ifndef CD_H
|
|
||||||
#define CD_H
|
|
||||||
|
|
||||||
#include "cdtext.h"
|
|
||||||
|
|
||||||
#define MAXTRACK 99 /* Red Book track limit */
|
|
||||||
#define MAXINDEX 99 /* Red Book index limit */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* disc modes
|
|
||||||
* DATA FORM OF MAIN DATA (5.29.2.8)
|
|
||||||
*/
|
|
||||||
enum DiscMode {
|
|
||||||
MODE_CD_DA, /* CD-DA */
|
|
||||||
MODE_CD_ROM, /* CD-ROM mode 1 */
|
|
||||||
MODE_CD_ROM_XA /* CD-ROM XA and CD-I */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* track modes
|
|
||||||
* 5.29.2.8 DATA FORM OF MAIN DATA
|
|
||||||
* Table 350 - Data Block Type Codes
|
|
||||||
*/
|
|
||||||
enum TrackMode {
|
|
||||||
MODE_AUDIO, /* 2352 byte block length */
|
|
||||||
MODE_MODE1, /* 2048 byte block length */
|
|
||||||
MODE_MODE1_RAW, /* 2352 byte block length */
|
|
||||||
MODE_MODE2, /* 2336 byte block length */
|
|
||||||
MODE_MODE2_FORM1, /* 2048 byte block length */
|
|
||||||
MODE_MODE2_FORM2, /* 2324 byte block length */
|
|
||||||
MODE_MODE2_FORM_MIX, /* 2332 byte block length */
|
|
||||||
MODE_MODE2_RAW /* 2352 byte block length */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sub-channel mode
|
|
||||||
* 5.29.2.13 Data Form of Sub-channel
|
|
||||||
* NOTE: not sure if this applies to cue files
|
|
||||||
*/
|
|
||||||
enum TrackSubMode {
|
|
||||||
SUB_MODE_RW, /* RAW Data */
|
|
||||||
SUB_MODE_RW_RAW /* PACK DATA (written R-W */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* track flags
|
|
||||||
* Q Sub-channel Control Field (4.2.3.3, 5.29.2.2)
|
|
||||||
*/
|
|
||||||
enum TrackFlag {
|
|
||||||
FLAG_NONE =0x00, /* no flags set */
|
|
||||||
FLAG_PRE_EMPHASIS =0x01, /* audio recorded with pre-emphasis */
|
|
||||||
FLAG_COPY_PERMITTED =0x02, /* digital copy permitted */
|
|
||||||
FLAG_DATA =0x04, /* data track */
|
|
||||||
FLAG_FOUR_CHANNEL =0x08, /* 4 audio channels */
|
|
||||||
FLAG_SCMS =0x10, /* SCMS (not Q Sub-ch.) (5.29.2.7) */
|
|
||||||
FLAG_ANY =0xff /* any flags set */
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DataType {
|
|
||||||
DATA_AUDIO,
|
|
||||||
DATA_DATA,
|
|
||||||
DATA_FIFO,
|
|
||||||
DATA_ZERO
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ADTs */
|
|
||||||
typedef struct Cd Cd;
|
|
||||||
typedef struct Track Track;
|
|
||||||
|
|
||||||
/* return pointer to CD structure */
|
|
||||||
Cd *cd_init ();
|
|
||||||
|
|
||||||
/* dump all info from CD structure
|
|
||||||
* in human readable format (for debugging)
|
|
||||||
*/
|
|
||||||
void cd_dump (Cd *cd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Cd functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
void cd_set_mode (Cd *cd, int mode);
|
|
||||||
int cd_get_mode (Cd *cd);
|
|
||||||
|
|
||||||
void cd_set_catalog (Cd *cd, char *catalog);
|
|
||||||
char *cd_get_catalog (Cd *cd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* return pointer to cd's Cdtext
|
|
||||||
*/
|
|
||||||
Cdtext *cd_get_cdtext (Cd *cd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* add a new track to cd, increment number of tracks
|
|
||||||
* and return pointer to new track
|
|
||||||
*/
|
|
||||||
Track *cd_add_track (Cd *cd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* return number of tracks in cd
|
|
||||||
*/
|
|
||||||
int cd_get_ntrack (Cd *cd);
|
|
||||||
|
|
||||||
Track *cd_get_track (Cd *cd, int i);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Track functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* filename of data file */
|
|
||||||
void track_set_filename (Track *track, char *filename);
|
|
||||||
char *track_get_filename (Track *track);
|
|
||||||
|
|
||||||
/* track start is starting position in data file */
|
|
||||||
void track_set_start (Track *track, long start);
|
|
||||||
long track_get_start (Track *track);
|
|
||||||
|
|
||||||
/* track length is length of data file to use */
|
|
||||||
void track_set_length (Track *track, long length);
|
|
||||||
long track_get_length (Track *track);
|
|
||||||
|
|
||||||
/* see enum TrackMode */
|
|
||||||
void track_set_mode (Track *track, int mode);
|
|
||||||
int track_get_mode (Track *track);
|
|
||||||
|
|
||||||
/* see enum TrackSubMode */
|
|
||||||
void track_set_sub_mode (Track *track, int sub_mode);
|
|
||||||
int track_get_sub_mode (Track *track);
|
|
||||||
|
|
||||||
/* see enum TrackFlag */
|
|
||||||
void track_set_flag (Track *track, int flag);
|
|
||||||
void track_clear_flag (Track *track, int flag);
|
|
||||||
int track_is_set_flag (Track *track, int flag);
|
|
||||||
|
|
||||||
/* zero data pregap */
|
|
||||||
void track_set_zero_pre (Track *track, long length);
|
|
||||||
long track_get_zero_pre (Track *track);
|
|
||||||
|
|
||||||
/* zero data postgap */
|
|
||||||
void track_set_zero_post (Track *track, long length);
|
|
||||||
long track_get_zero_post (Track *track);
|
|
||||||
|
|
||||||
void track_set_isrc (Track *track, char *isrc);
|
|
||||||
char *track_get_isrc (Track *track);
|
|
||||||
|
|
||||||
Cdtext *track_get_cdtext (Track *track);
|
|
||||||
|
|
||||||
void track_add_index (Track *track, long index);
|
|
||||||
int track_get_nindex (Track *track);
|
|
||||||
long track_get_index (Track *track, int i);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
166
lib/cdtext.c
166
lib/cdtext.c
@@ -1,166 +0,0 @@
|
|||||||
/*
|
|
||||||
* cdtext.c -- cdtext data structure and functions
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* 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 ()
|
|
||||||
{
|
|
||||||
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 */
|
|
||||||
char *cdtext_get (int pti, 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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
71
lib/cdtext.h
71
lib/cdtext.h
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* cdtext.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* references: MMC-3 draft revsion - 10g */
|
|
||||||
|
|
||||||
#ifndef CDTEXT_H
|
|
||||||
#define CDTEXT_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* cdtext pack type indicators */
|
|
||||||
enum Pti {
|
|
||||||
PTI_TITLE, /* title of album or track titles */
|
|
||||||
PTI_PERFORMER, /* name(s) of the performer(s) */
|
|
||||||
PTI_SONGWRITER, /* name(s) of the songwriter(s) */
|
|
||||||
PTI_COMPOSER, /* name(s) of the composer(s) */
|
|
||||||
PTI_ARRANGER, /* name(s) of the arranger(s) */
|
|
||||||
PTI_MESSAGE, /* message(s) from the content provider and/or artist */
|
|
||||||
PTI_DISC_ID, /* (binary) disc identification information */
|
|
||||||
PTI_GENRE, /* (binary) genre identification and genre information */
|
|
||||||
PTI_TOC_INFO1, /* (binary) table of contents information */
|
|
||||||
PTI_TOC_INFO2, /* (binary) second table of contents information */
|
|
||||||
PTI_RESERVED1, /* reserved */
|
|
||||||
PTI_RESERVED2, /* reserved */
|
|
||||||
PTI_RESERVED3, /* reserved */
|
|
||||||
PTI_RESERVED4, /* reserved for content provider only */
|
|
||||||
PTI_UPC_ISRC, /* UPC/EAN code of the album and ISRC code of each track */
|
|
||||||
PTI_SIZE_INFO, /* (binary) size information of the block */
|
|
||||||
PTI_END /* terminating PTI (for stepping through PTIs) */
|
|
||||||
};
|
|
||||||
|
|
||||||
enum PtiFormat {
|
|
||||||
FORMAT_CHAR, /* single or double byte character string */
|
|
||||||
FORMAT_BINARY /* binary data */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct Cdtext Cdtext;
|
|
||||||
|
|
||||||
/* return a pointer to a new Cdtext */
|
|
||||||
Cdtext *cdtext_init ();
|
|
||||||
|
|
||||||
/* release a Cdtext */
|
|
||||||
void cdtext_delete (Cdtext *cdtext);
|
|
||||||
|
|
||||||
/* returns non-zero if there are no CD-TEXT fields set, zero otherwise */
|
|
||||||
int cdtext_is_empty (Cdtext *cdtext);
|
|
||||||
|
|
||||||
/* set CD-TEXT field to value for PTI pti */
|
|
||||||
void cdtext_set (int pti, char *value, Cdtext *cdtext);
|
|
||||||
|
|
||||||
/* returns pointer to CD-TEXT value for PTI pti */
|
|
||||||
char *cdtext_get (int pti, Cdtext *cdtext);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* returns appropriate string for PTI pti
|
|
||||||
* if istrack is zero, UPC/EAN string will be returned for PTI_UPC_ISRC
|
|
||||||
* othwise ISRC string will be returned
|
|
||||||
*/
|
|
||||||
const char *cdtext_get_key (int pti, int istrack);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dump all cdtext info
|
|
||||||
* in human readable format (for debugging)
|
|
||||||
*/
|
|
||||||
void cdtext_dump (Cdtext *cdtext, int istrack);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
/*
|
|
||||||
* cue.h -- cue function declarations
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Cd *cue_parse (FILE *fp);
|
|
||||||
void cue_print (FILE *fp, Cd *cd);
|
|
||||||
280
lib/cue_parse.y
280
lib/cue_parse.y
@@ -1,280 +0,0 @@
|
|||||||
%{
|
|
||||||
/*
|
|
||||||
* cue_parse.y -- parser for cue files
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* 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"
|
|
||||||
#include "cue_parse_prefix.h"
|
|
||||||
|
|
||||||
#define YYDEBUG 1
|
|
||||||
|
|
||||||
extern int yylex();
|
|
||||||
void yyerror (char *s);
|
|
||||||
|
|
||||||
static Cd *cd = NULL;
|
|
||||||
static Track *track = NULL;
|
|
||||||
static Track *prev_track = NULL;
|
|
||||||
static Cdtext *cdtext = 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 */
|
|
||||||
%}
|
|
||||||
|
|
||||||
%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
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
cuefile
|
|
||||||
: new_cd global_statements track_list
|
|
||||||
;
|
|
||||||
|
|
||||||
new_cd
|
|
||||||
: /* empty */ {
|
|
||||||
cd = cd_init();
|
|
||||||
cdtext = cd_get_cdtext(cd);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
global_statements
|
|
||||||
: /* empty */
|
|
||||||
| global_statements global_statement
|
|
||||||
;
|
|
||||||
|
|
||||||
global_statement
|
|
||||||
: CATALOG STRING '\n' { cd_set_catalog(cd, $2); }
|
|
||||||
| CDTEXTFILE STRING '\n' { /* ignored */ }
|
|
||||||
| cdtext
|
|
||||||
| track_data
|
|
||||||
| error '\n'
|
|
||||||
;
|
|
||||||
|
|
||||||
track_data
|
|
||||||
: FFILE STRING file_format '\n' {
|
|
||||||
if (NULL != new_filename) {
|
|
||||||
yyerror("too many files specified\n");
|
|
||||||
free(new_filename);
|
|
||||||
}
|
|
||||||
new_filename = strdup($2);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
track_list
|
|
||||||
: track
|
|
||||||
| track_list track
|
|
||||||
;
|
|
||||||
|
|
||||||
track
|
|
||||||
: new_track track_def track_statements
|
|
||||||
;
|
|
||||||
|
|
||||||
file_format
|
|
||||||
: BINARY
|
|
||||||
| MOTOROLA
|
|
||||||
| AIFF
|
|
||||||
| WAVE
|
|
||||||
| MP3
|
|
||||||
;
|
|
||||||
|
|
||||||
new_track
|
|
||||||
: /*empty */ {
|
|
||||||
/* save previous track, to later set length */
|
|
||||||
prev_track = track;
|
|
||||||
|
|
||||||
track = cd_add_track(cd);
|
|
||||||
cdtext = track_get_cdtext(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
|
|
||||||
| 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' {
|
|
||||||
int i = track_get_nindex(track);
|
|
||||||
long prev_length;
|
|
||||||
|
|
||||||
if (0 == i) {
|
|
||||||
/* first index */
|
|
||||||
track_set_start(track, $3);
|
|
||||||
|
|
||||||
if (NULL != prev_track && NULL == cur_filename) {
|
|
||||||
/* track shares file with previous track */
|
|
||||||
prev_length = $3 - track_get_start(prev_track);
|
|
||||||
track_set_length(prev_track, prev_length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i <= $2; i++)
|
|
||||||
track_add_index(track, \
|
|
||||||
track_get_zero_pre(track) + $3 \
|
|
||||||
- track_get_start(track));
|
|
||||||
}
|
|
||||||
| 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); }
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
/* lexer interface */
|
|
||||||
extern int cue_lineno;
|
|
||||||
extern int yydebug;
|
|
||||||
extern FILE *cue_yyin;
|
|
||||||
|
|
||||||
void yyerror (char *s)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%d: %s\n", cue_lineno, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cd *cue_parse (FILE *fp)
|
|
||||||
{
|
|
||||||
cue_yyin = fp;
|
|
||||||
yydebug = 0;
|
|
||||||
|
|
||||||
if (0 == yyparse())
|
|
||||||
return cd;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/* Remap normal yacc names so we can have multiple parsers
|
|
||||||
* see http://www.gnu.org/software/automake/manual/html_node/Yacc-and-Lex.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define yymaxdepth cue_yymaxdepth
|
|
||||||
#define yyparse cue_yyparse
|
|
||||||
#define yylex cue_yylex
|
|
||||||
#define yyerror cue_yyerror
|
|
||||||
#define yylval cue_yylval
|
|
||||||
#define yychar cue_yychar
|
|
||||||
#define yydebug cue_yydebug
|
|
||||||
#define yypact cue_yypact
|
|
||||||
#define yyr1 cue_yyr1
|
|
||||||
#define yyr2 cue_yyr2
|
|
||||||
#define yydef cue_yydef
|
|
||||||
#define yychk cue_yychk
|
|
||||||
#define yypgo cue_yypgo
|
|
||||||
#define yyact cue_yyact
|
|
||||||
#define yyexca cue_yyexca
|
|
||||||
#define yyerrflag cue_yyerrflag
|
|
||||||
#define yynerrs cue_yynerrs
|
|
||||||
#define yyps cue_yyps
|
|
||||||
#define yypv cue_yypv
|
|
||||||
#define yys cue_yys
|
|
||||||
#define yy_yys cue_yy_yys
|
|
||||||
#define yystate cue_yystate
|
|
||||||
#define yytmp cue_yytmp
|
|
||||||
#define yyv cue_yyv
|
|
||||||
#define yy_yyv cue_yy_yyv
|
|
||||||
#define yyval cue_yyval
|
|
||||||
#define yylloc cue_yylloc
|
|
||||||
#define yyreds cue_yyreds
|
|
||||||
#define yytoks cue_yytoks
|
|
||||||
#define yylhs cue_yylhs
|
|
||||||
#define yylen cue_yylen
|
|
||||||
#define yydefred cue_yydefred
|
|
||||||
#define yydgoto cue_yydgoto
|
|
||||||
#define yysinde cue_yysindex
|
|
||||||
#define yyrindex cue_yyrindex
|
|
||||||
#define yygindex cue_yygindex
|
|
||||||
#define yytable cue_yytable
|
|
||||||
#define yycheck cue_yycheck
|
|
||||||
#define yyname cue_yyname
|
|
||||||
#define yyrule cue_yyrule
|
|
||||||
147
lib/cue_print.c
147
lib/cue_print.c
@@ -1,147 +0,0 @@
|
|||||||
/*
|
|
||||||
* cue_print.y -- print cue file
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "cd.h"
|
|
||||||
#include "time.h"
|
|
||||||
|
|
||||||
void cue_print_track (FILE *fp, Track *track, int trackno);
|
|
||||||
void cue_print_cdtext (Cdtext *cdtext, FILE *fp, int istrack);
|
|
||||||
void cue_print_index (long i, FILE *fp);
|
|
||||||
char *filename = ""; /* last track datafile */
|
|
||||||
long prev_length = 0; /* last track length */
|
|
||||||
|
|
||||||
/* prints cd in cue format */
|
|
||||||
void cue_print (FILE *fp, Cd *cd)
|
|
||||||
{
|
|
||||||
Cdtext *cdtext = cd_get_cdtext(cd);
|
|
||||||
int i; /* track */
|
|
||||||
Track *track = NULL;
|
|
||||||
|
|
||||||
/* print global information */
|
|
||||||
if (NULL != cd_get_catalog(cd))
|
|
||||||
fprintf(fp, "CATALOG %s\n", cd_get_catalog(cd));
|
|
||||||
|
|
||||||
cue_print_cdtext(cdtext, fp, 0);
|
|
||||||
|
|
||||||
/* print track information */
|
|
||||||
for (i = 1; i <= cd_get_ntrack(cd); i++) {
|
|
||||||
track = cd_get_track(cd, i);
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
cue_print_track(fp, track, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cue_print_track (FILE *fp, Track *track, int trackno)
|
|
||||||
{
|
|
||||||
Cdtext *cdtext = track_get_cdtext(track);
|
|
||||||
int i; /* index */
|
|
||||||
|
|
||||||
if (NULL != track_get_filename(track)) {
|
|
||||||
/*
|
|
||||||
* always print filename for track 1, afterwards only
|
|
||||||
* print filename if it differs from the previous track
|
|
||||||
*/
|
|
||||||
if (0 != strcmp(track_get_filename(track), filename)) {
|
|
||||||
filename = track_get_filename(track);
|
|
||||||
fprintf(fp, "FILE \"%s\" ", filename);
|
|
||||||
|
|
||||||
/* NOTE: what to do with other formats (MP3, etc)? */
|
|
||||||
if (MODE_AUDIO == track_get_mode(track))
|
|
||||||
fprintf(fp, "WAVE\n");
|
|
||||||
else
|
|
||||||
fprintf(fp, "BINARY\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(fp, "TRACK %02d ", trackno);
|
|
||||||
switch (track_get_mode(track)) {
|
|
||||||
case MODE_AUDIO:
|
|
||||||
fprintf(fp, "AUDIO\n");
|
|
||||||
break;
|
|
||||||
case MODE_MODE1:
|
|
||||||
fprintf(fp, "MODE1/2048\n");
|
|
||||||
break;
|
|
||||||
case MODE_MODE1_RAW:
|
|
||||||
fprintf(fp, "MODE1/2352\n");
|
|
||||||
break;
|
|
||||||
case MODE_MODE2:
|
|
||||||
fprintf(fp, "MODE2/2048\n");
|
|
||||||
break;
|
|
||||||
case MODE_MODE2_FORM1:
|
|
||||||
fprintf(fp, "MODE2/2336\n");
|
|
||||||
break;
|
|
||||||
case MODE_MODE2_FORM2:
|
|
||||||
fprintf(fp, "MODE2/2324\n");
|
|
||||||
break;
|
|
||||||
case MODE_MODE2_FORM_MIX:
|
|
||||||
fprintf(fp, "MODE2/2336\n");
|
|
||||||
break;
|
|
||||||
case MODE_MODE2_RAW:
|
|
||||||
fprintf(fp, "MODE2/2352\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cue_print_cdtext(cdtext, fp, 1);
|
|
||||||
|
|
||||||
if (0 != track_is_set_flag(track, FLAG_ANY)) {
|
|
||||||
fprintf(fp, "FLAGS");
|
|
||||||
if (0 != track_is_set_flag(track, FLAG_PRE_EMPHASIS))
|
|
||||||
fprintf(fp, " PRE");
|
|
||||||
if (0 != track_is_set_flag(track, FLAG_COPY_PERMITTED))
|
|
||||||
fprintf(fp, " DCP");
|
|
||||||
if (0 != track_is_set_flag(track, FLAG_FOUR_CHANNEL))
|
|
||||||
fprintf(fp, " 4CH");
|
|
||||||
if (0 != track_is_set_flag(track, FLAG_SCMS))
|
|
||||||
fprintf(fp, " SCMS");
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL != track_get_isrc(track))
|
|
||||||
fprintf(fp, "ISRC %s\n", track_get_isrc(track));
|
|
||||||
|
|
||||||
if (0 != track_get_zero_pre(track))
|
|
||||||
fprintf (fp, "PREGAP %s\n", time_frame_to_mmssff(track_get_zero_pre(track)));
|
|
||||||
|
|
||||||
/* don't print index 0 if index 1 = 0 */
|
|
||||||
if (track_get_index(track, 1) == 0)
|
|
||||||
i = 1;
|
|
||||||
else
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for (; i < track_get_nindex(track); i++) {
|
|
||||||
fprintf(fp, "INDEX %02d ", i);
|
|
||||||
cue_print_index( \
|
|
||||||
track_get_index(track, i) \
|
|
||||||
+ track_get_start(track) \
|
|
||||||
- track_get_zero_pre(track) , fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != track_get_zero_post(track))
|
|
||||||
fprintf (fp, "POSTGAP %s\n", time_frame_to_mmssff(track_get_zero_post(track)));
|
|
||||||
|
|
||||||
prev_length = track_get_length(track);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cue_print_cdtext (Cdtext *cdtext, FILE *fp, int istrack)
|
|
||||||
{
|
|
||||||
int pti;
|
|
||||||
char *value = NULL;
|
|
||||||
|
|
||||||
for (pti = 0; PTI_END != pti; pti++) {
|
|
||||||
if (NULL != (value = cdtext_get(pti, cdtext))) {
|
|
||||||
fprintf(fp, "%s", cdtext_get_key(pti, istrack));
|
|
||||||
fprintf(fp, " \"%s\"\n", value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cue_print_index (long i, FILE *fp)
|
|
||||||
{
|
|
||||||
fprintf (fp, "%s\n", time_frame_to_mmssff(i));
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
%{
|
|
||||||
/*
|
|
||||||
* cue_scan.l -- lexer for cue files
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "cd.h"
|
|
||||||
#include "cue_parse_prefix.h"
|
|
||||||
#include "cue_parse.h"
|
|
||||||
|
|
||||||
int cue_lineno = 1;
|
|
||||||
%}
|
|
||||||
|
|
||||||
ws [ \t\r]
|
|
||||||
nonws [^ \t\r\n]
|
|
||||||
|
|
||||||
%option noyywrap
|
|
||||||
%option prefix="cue_yy"
|
|
||||||
|
|
||||||
%s NAME
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
\'([^\']|\\\')*\' |
|
|
||||||
\"([^\"]|\\\")*\" {
|
|
||||||
yylval.sval = strdup(yytext + 1);
|
|
||||||
yylval.sval[strlen(yylval.sval) - 1] = '\0';
|
|
||||||
BEGIN(INITIAL);
|
|
||||||
return STRING;
|
|
||||||
}
|
|
||||||
|
|
||||||
<NAME>{nonws}+ {
|
|
||||||
yylval.sval = strdup(yytext);
|
|
||||||
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; }
|
|
||||||
|
|
||||||
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; }
|
|
||||||
|
|
||||||
^{ws}*REM.*\n { cue_lineno++; /* ignore comments */ }
|
|
||||||
{ws}+ { /* ignore whitespace */ }
|
|
||||||
|
|
||||||
[[:digit:]]+ { yylval.ival = atoi(yytext); return NUMBER; }
|
|
||||||
: { return yytext[0]; }
|
|
||||||
|
|
||||||
^{ws}*\n { cue_lineno++; /* blank line */ }
|
|
||||||
\n { cue_lineno++; return '\n'; }
|
|
||||||
. { fprintf(stderr, "bad character '%c'\n", yytext[0]); }
|
|
||||||
|
|
||||||
%%
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* cuefile.c -- cue/toc functions
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "cuefile.h"
|
|
||||||
#include "cue.h"
|
|
||||||
#include "toc.h"
|
|
||||||
|
|
||||||
Cd *cf_parse (char *name, int *format)
|
|
||||||
{
|
|
||||||
FILE *fp = NULL;
|
|
||||||
Cd *cd = NULL;
|
|
||||||
|
|
||||||
if (UNKNOWN == *format)
|
|
||||||
if (UNKNOWN == (*format = cf_format_from_suffix(name))) {
|
|
||||||
fprintf(stderr, "%s: unknown format\n", name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == strcmp("-", name)) {
|
|
||||||
fp = stdin;
|
|
||||||
} else if (NULL == (fp = fopen(name, "r"))) {
|
|
||||||
fprintf(stderr, "%s: error opening file\n", name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (*format) {
|
|
||||||
case CUE:
|
|
||||||
cd = cue_parse(fp);
|
|
||||||
break;
|
|
||||||
case TOC:
|
|
||||||
cd = toc_parse(fp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stdin != fp)
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
return cd;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cf_print (char *name, int *format, Cd *cd)
|
|
||||||
{
|
|
||||||
FILE *fp = NULL;
|
|
||||||
|
|
||||||
if (UNKNOWN == *format)
|
|
||||||
if (UNKNOWN == (*format = cf_format_from_suffix(name))) {
|
|
||||||
fprintf(stderr, "%s: unknown format\n", name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == strcmp("-", name)) {
|
|
||||||
fp = stdout;
|
|
||||||
} else if (NULL == (fp = fopen(name, "w"))) {
|
|
||||||
fprintf(stderr, "%s: error opening file\n", name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (*format) {
|
|
||||||
case CUE:
|
|
||||||
cue_print(fp, cd);
|
|
||||||
break;
|
|
||||||
case TOC:
|
|
||||||
toc_print(fp, cd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stdout != fp)
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cf_format_from_suffix (char *name)
|
|
||||||
{
|
|
||||||
char *suffix;
|
|
||||||
if (0 != (suffix = strrchr(name, '.'))) {
|
|
||||||
if (0 == strcasecmp(".cue", suffix))
|
|
||||||
return CUE;
|
|
||||||
else if (0 == strcasecmp(".toc", suffix))
|
|
||||||
return TOC;
|
|
||||||
}
|
|
||||||
|
|
||||||
return UNKNOWN;
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
* cuefile.h -- cue/toc public declarations
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "cd.h"
|
|
||||||
|
|
||||||
enum {CUE, TOC, UNKNOWN};
|
|
||||||
|
|
||||||
typedef struct Cue Cue;
|
|
||||||
|
|
||||||
Cd *cf_parse (char *fname, int *format);
|
|
||||||
int cf_print (char *fname, int *format, Cd *cue);
|
|
||||||
int cf_format_from_suffix (char *fname);
|
|
||||||
44
lib/time.c
44
lib/time.c
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* time.c -- time functions
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
long time_msf_to_frame (int m, int s, int f)
|
|
||||||
{
|
|
||||||
return (m * 60 + s) * 75 + f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void msf_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 */
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
msf_frame_to_msf(f, &minutes, &seconds, &frames);
|
|
||||||
sprintf(msf, "%02d:%02d:%02d", minutes, seconds, frames);
|
|
||||||
|
|
||||||
return msf;
|
|
||||||
}
|
|
||||||
15
lib/time.h
15
lib/time.h
@@ -1,15 +0,0 @@
|
|||||||
/* time.h -- time declarations
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TIME_H
|
|
||||||
#define TIME_H
|
|
||||||
|
|
||||||
long time_msf_to_frame (int m, int s, int f);
|
|
||||||
long time_mmssff_to_frame (char *mmssff);
|
|
||||||
void time_frame_to_msf (long frame, int *m, int *s, int *f);
|
|
||||||
char *time_frame_to_mmssff (long f);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
/*
|
|
||||||
* toc.h -- toc function declarations
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Cd *toc_parse (FILE *fp);
|
|
||||||
void toc_print (FILE *fp, Cd *cd);
|
|
||||||
346
lib/toc_parse.y
346
lib/toc_parse.y
@@ -1,346 +0,0 @@
|
|||||||
%{
|
|
||||||
/*
|
|
||||||
* toc_parse.y -- parser for toc files
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* 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"
|
|
||||||
#include "toc_parse_prefix.h"
|
|
||||||
|
|
||||||
#define YYDEBUG 1
|
|
||||||
|
|
||||||
extern int yylex();
|
|
||||||
void yyerror (char *s);
|
|
||||||
|
|
||||||
static Cd *cd = NULL;
|
|
||||||
static Track *track = NULL;
|
|
||||||
static Cdtext *cdtext = NULL;
|
|
||||||
%}
|
|
||||||
|
|
||||||
%start tocfile
|
|
||||||
|
|
||||||
%union {
|
|
||||||
long ival;
|
|
||||||
char *sval;
|
|
||||||
}
|
|
||||||
|
|
||||||
%token <ival> NUMBER
|
|
||||||
%token <sval> STRING
|
|
||||||
|
|
||||||
/* global (header) */
|
|
||||||
%token CATALOG
|
|
||||||
|
|
||||||
%token <ival> CD_DA
|
|
||||||
%token <ival> CD_ROM
|
|
||||||
%token <ival> CD_ROM_XA
|
|
||||||
|
|
||||||
/* track */
|
|
||||||
%token TRACK
|
|
||||||
%token <ival> AUDIO
|
|
||||||
%token <ival> MODE1
|
|
||||||
%token <ival> MODE1_RAW
|
|
||||||
%token <ival> MODE2
|
|
||||||
%token <ival> MODE2_FORM1
|
|
||||||
%token <ival> MODE2_FORM2
|
|
||||||
%token <ival> MODE2_FORM_MIX
|
|
||||||
%token <ival> MODE2_RAW
|
|
||||||
%token <ival> RW
|
|
||||||
%token <ival> RW_RAW
|
|
||||||
|
|
||||||
%token NO
|
|
||||||
%token <ival> COPY
|
|
||||||
%token <ival> PRE_EMPHASIS
|
|
||||||
%token <ival> TWO_CHANNEL_AUDIO
|
|
||||||
%token <ival> FOUR_CHANNEL_AUDIO
|
|
||||||
|
|
||||||
%token ISRC
|
|
||||||
%token SILENCE
|
|
||||||
%token ZERO
|
|
||||||
%token AUDIOFILE
|
|
||||||
%token DATAFILE
|
|
||||||
%token FIFO
|
|
||||||
%token START
|
|
||||||
%token PREGAP
|
|
||||||
%token INDEX
|
|
||||||
|
|
||||||
/* CD-TEXT */
|
|
||||||
%token CD_TEXT
|
|
||||||
%token LANGUAGE_MAP
|
|
||||||
%token LANGUAGE
|
|
||||||
|
|
||||||
%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> disc_mode
|
|
||||||
%type <ival> track_modes
|
|
||||||
%type <ival> track_mode
|
|
||||||
%type <ival> track_sub_mode
|
|
||||||
%type <ival> track_set_flag
|
|
||||||
%type <ival> track_clear_flag
|
|
||||||
%type <ival> time
|
|
||||||
%type <ival> cdtext_item
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
tocfile
|
|
||||||
: new_cd global_statements track_list
|
|
||||||
;
|
|
||||||
|
|
||||||
new_cd
|
|
||||||
: /* empty */ {
|
|
||||||
cd = cd_init();
|
|
||||||
cdtext = cd_get_cdtext(cd);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
global_statements
|
|
||||||
: /* empty */
|
|
||||||
| global_statements global_statement
|
|
||||||
;
|
|
||||||
|
|
||||||
global_statement
|
|
||||||
: CATALOG STRING '\n' { cd_set_catalog(cd, $2); }
|
|
||||||
| disc_mode '\n' { cd_set_mode(cd, $1); }
|
|
||||||
| CD_TEXT '{' opt_nl language_map cdtext_langs '}' '\n'
|
|
||||||
| error '\n'
|
|
||||||
;
|
|
||||||
|
|
||||||
disc_mode
|
|
||||||
: CD_DA
|
|
||||||
| CD_ROM
|
|
||||||
| CD_ROM_XA
|
|
||||||
;
|
|
||||||
|
|
||||||
track_list
|
|
||||||
: track
|
|
||||||
| track_list track
|
|
||||||
;
|
|
||||||
|
|
||||||
track
|
|
||||||
: new_track track_def track_statements {
|
|
||||||
while (2 > track_get_nindex(track))
|
|
||||||
track_add_index(track, 0);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
new_track
|
|
||||||
: /* empty */ {
|
|
||||||
track = cd_add_track(cd);
|
|
||||||
cdtext = track_get_cdtext(track);
|
|
||||||
/* add 0 index */
|
|
||||||
track_add_index(track, 0);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
track_def
|
|
||||||
: TRACK track_modes '\n' { track_set_mode(track, $2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
track_modes
|
|
||||||
: track_mode
|
|
||||||
| track_mode track_sub_mode { track_set_sub_mode(track, $2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
track_mode
|
|
||||||
: AUDIO
|
|
||||||
| MODE1
|
|
||||||
| MODE1_RAW
|
|
||||||
| MODE2
|
|
||||||
| MODE2_FORM1
|
|
||||||
| MODE2_FORM2
|
|
||||||
| MODE2_FORM_MIX
|
|
||||||
| MODE2_RAW
|
|
||||||
;
|
|
||||||
|
|
||||||
track_sub_mode
|
|
||||||
: RW
|
|
||||||
| RW_RAW
|
|
||||||
;
|
|
||||||
|
|
||||||
track_statements
|
|
||||||
: track_statement
|
|
||||||
| track_statements track_statement
|
|
||||||
;
|
|
||||||
|
|
||||||
track_statement
|
|
||||||
: track_flags
|
|
||||||
| ISRC STRING '\n' { track_set_isrc(track, $2); }
|
|
||||||
| CD_TEXT '{' opt_nl cdtext_langs '}' '\n'
|
|
||||||
| track_data
|
|
||||||
| track_pregap
|
|
||||||
| track_index
|
|
||||||
| error '\n'
|
|
||||||
;
|
|
||||||
|
|
||||||
track_flags
|
|
||||||
: track_set_flag { track_set_flag(track, $1); }
|
|
||||||
| track_clear_flag { track_clear_flag(track, $1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
track_set_flag
|
|
||||||
: COPY '\n'
|
|
||||||
| PRE_EMPHASIS '\n'
|
|
||||||
| FOUR_CHANNEL_AUDIO '\n'
|
|
||||||
;
|
|
||||||
|
|
||||||
track_clear_flag
|
|
||||||
: NO PRE_EMPHASIS '\n' { $$ = $2; }
|
|
||||||
| NO COPY '\n' { $$ = $2; }
|
|
||||||
| TWO_CHANNEL_AUDIO '\n'
|
|
||||||
;
|
|
||||||
|
|
||||||
track_data
|
|
||||||
: zero_data time '\n' {
|
|
||||||
if (NULL == track_get_filename(track))
|
|
||||||
track_set_zero_pre(track, $2);
|
|
||||||
else
|
|
||||||
track_set_zero_post(track, $2);
|
|
||||||
}
|
|
||||||
| AUDIOFILE STRING time '\n' {
|
|
||||||
track_set_filename(track, $2);
|
|
||||||
track_set_start(track, $3);
|
|
||||||
}
|
|
||||||
| AUDIOFILE STRING time time '\n' {
|
|
||||||
track_set_filename(track, $2);
|
|
||||||
track_set_start(track, $3);
|
|
||||||
track_set_length(track, $4);
|
|
||||||
}
|
|
||||||
| DATAFILE STRING '\n' {
|
|
||||||
track_set_filename(track, $2);
|
|
||||||
}
|
|
||||||
| DATAFILE STRING time '\n' {
|
|
||||||
track_set_filename(track, $2);
|
|
||||||
track_set_start(track, $3);
|
|
||||||
}
|
|
||||||
| FIFO STRING time '\n' {
|
|
||||||
track_set_filename(track, $2);
|
|
||||||
track_set_start(track, $3);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
zero_data
|
|
||||||
: SILENCE
|
|
||||||
| ZERO
|
|
||||||
;
|
|
||||||
|
|
||||||
track_pregap
|
|
||||||
: START '\n'
|
|
||||||
| START time '\n' {
|
|
||||||
track_add_index(track, $2);
|
|
||||||
}
|
|
||||||
| PREGAP time '\n' {
|
|
||||||
track_set_zero_pre(track, $2);
|
|
||||||
track_add_index(track, $2);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
track_index
|
|
||||||
: INDEX time '\n' { track_add_index(track, $2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
language_map
|
|
||||||
: LANGUAGE_MAP '{' opt_nl languages '}' '\n'
|
|
||||||
;
|
|
||||||
|
|
||||||
languages
|
|
||||||
: language
|
|
||||||
| languages language
|
|
||||||
;
|
|
||||||
|
|
||||||
language
|
|
||||||
: NUMBER ':' NUMBER opt_nl { /* not implemented */ }
|
|
||||||
;
|
|
||||||
|
|
||||||
cdtext_langs
|
|
||||||
: cdtext_lang
|
|
||||||
| cdtext_langs cdtext_lang
|
|
||||||
;
|
|
||||||
|
|
||||||
cdtext_lang
|
|
||||||
: LANGUAGE NUMBER '{' opt_nl cdtext_defs '}' '\n'
|
|
||||||
;
|
|
||||||
|
|
||||||
cdtext_defs
|
|
||||||
: /* empty */
|
|
||||||
| cdtext_defs cdtext_def
|
|
||||||
;
|
|
||||||
|
|
||||||
cdtext_def
|
|
||||||
: cdtext_item STRING '\n' {
|
|
||||||
cdtext_set ($1, $2, cdtext);
|
|
||||||
}
|
|
||||||
| cdtext_item '{' bytes '}' '\n' {
|
|
||||||
yyerror("binary CD-TEXT data not supported\n");
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
cdtext_item
|
|
||||||
: TITLE
|
|
||||||
| PERFORMER
|
|
||||||
| SONGWRITER
|
|
||||||
| COMPOSER
|
|
||||||
| ARRANGER
|
|
||||||
| MESSAGE
|
|
||||||
| DISC_ID
|
|
||||||
| GENRE
|
|
||||||
| TOC_INFO1
|
|
||||||
| TOC_INFO2
|
|
||||||
| UPC_EAN
|
|
||||||
| ISRC
|
|
||||||
| SIZE_INFO
|
|
||||||
;
|
|
||||||
|
|
||||||
bytes
|
|
||||||
: /* empty */
|
|
||||||
| bytes ',' NUMBER
|
|
||||||
;
|
|
||||||
|
|
||||||
time
|
|
||||||
: NUMBER
|
|
||||||
| NUMBER ':' NUMBER ':' NUMBER { $$ = time_msf_to_frame($1, $3, $5); }
|
|
||||||
;
|
|
||||||
|
|
||||||
opt_nl
|
|
||||||
: /* empty */
|
|
||||||
| '\n'
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
/* lexer interface */
|
|
||||||
extern int toc_lineno;
|
|
||||||
extern int yydebug;
|
|
||||||
extern FILE *toc_yyin;
|
|
||||||
|
|
||||||
void yyerror (char *s)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%d: %s\n", toc_lineno, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cd *toc_parse (FILE *fp)
|
|
||||||
{
|
|
||||||
toc_yyin = fp;
|
|
||||||
yydebug = 0;
|
|
||||||
|
|
||||||
if (0 == yyparse())
|
|
||||||
return cd;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/* Remap normal yacc names so we can have multiple parsers
|
|
||||||
* see http://www.gnu.org/software/automake/manual/html_node/Yacc-and-Lex.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define yymaxdepth toc_yymaxdepth
|
|
||||||
#define yyparse toc_yyparse
|
|
||||||
#define yylex toc_yylex
|
|
||||||
#define yyerror toc_yyerror
|
|
||||||
#define yylval toc_yylval
|
|
||||||
#define yychar toc_ychar
|
|
||||||
#define yydebug toc_yydebug
|
|
||||||
#define yypact toc_yypact
|
|
||||||
#define yyr1 toc_yyr1
|
|
||||||
#define yyr2 toc_yyr2
|
|
||||||
#define yydef toc_yydef
|
|
||||||
#define yychk toc_yychk
|
|
||||||
#define yypgo toc_yypgo
|
|
||||||
#define yyact toc_yyact
|
|
||||||
#define yyexca toc_yyexca
|
|
||||||
#define yyerrflag toc_yyerrflag
|
|
||||||
#define yynerrs toc_yynerrs
|
|
||||||
#define yyps toc_yyps
|
|
||||||
#define yypv toc_yypv
|
|
||||||
#define yys toc_yys
|
|
||||||
#define yy_yys toc_yy_yys
|
|
||||||
#define yystate toc_yystate
|
|
||||||
#define yytmp toc_yytmp
|
|
||||||
#define yyv toc_yyv
|
|
||||||
#define yy_yyv toc_yy_yyv
|
|
||||||
#define yyval toc_yyval
|
|
||||||
#define yylloc toc_yylloc
|
|
||||||
#define yyreds toc_yyreds
|
|
||||||
#define yytoks toc_yytoks
|
|
||||||
#define yylhs toc_yylhs
|
|
||||||
#define yylen toc_yylen
|
|
||||||
#define yydefred toc_yydefred
|
|
||||||
#define yydgoto toc_yydgoto
|
|
||||||
#define yysinde toc_yysindex
|
|
||||||
#define yyrindex toc_yyrindex
|
|
||||||
#define yygindex toc_yygindex
|
|
||||||
#define yytable toc_yytable
|
|
||||||
#define yycheck toc_yycheck
|
|
||||||
#define yyname toc_yyname
|
|
||||||
#define yyrule toc_yyrule
|
|
||||||
149
lib/toc_print.c
149
lib/toc_print.c
@@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
* toc_print.c -- print toc file
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "cd.h"
|
|
||||||
#include "time.h"
|
|
||||||
|
|
||||||
void toc_print_track (FILE *fp, Track *track);
|
|
||||||
void toc_print_cdtext (Cdtext *cdtext, FILE *fp, int istrack);
|
|
||||||
|
|
||||||
void toc_print (FILE *fp, Cd *cd)
|
|
||||||
{
|
|
||||||
Cdtext *cdtext = cd_get_cdtext(cd);
|
|
||||||
int i; /* track */
|
|
||||||
Track *track;
|
|
||||||
|
|
||||||
switch(cd_get_mode(cd)) {
|
|
||||||
case MODE_CD_DA:
|
|
||||||
fprintf(fp, "CD_DA\n");
|
|
||||||
break;
|
|
||||||
case MODE_CD_ROM:
|
|
||||||
fprintf(fp, "CD_ROM\n");
|
|
||||||
break;
|
|
||||||
case MODE_CD_ROM_XA:
|
|
||||||
fprintf(fp, "CD_ROM_XA\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL != cd_get_catalog(cd))
|
|
||||||
fprintf(fp, "CATALOG \"%s\"\n", cd_get_catalog(cd));
|
|
||||||
|
|
||||||
if(0 != cdtext_is_empty(cdtext)) {
|
|
||||||
fprintf(fp, "CD_TEXT {\n");
|
|
||||||
fprintf(fp, "\tLANGUAGE_MAP { 0:9 }\n");
|
|
||||||
fprintf(fp, "\tLANGUAGE 0 {\n");
|
|
||||||
toc_print_cdtext(cdtext, fp, 0);
|
|
||||||
fprintf(fp, "\t}\n");
|
|
||||||
fprintf(fp, "}\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i <= cd_get_ntrack(cd); i++) {
|
|
||||||
track = cd_get_track(cd, i);
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
toc_print_track(fp, track);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void toc_print_track (FILE *fp, Track *track)
|
|
||||||
{
|
|
||||||
Cdtext *cdtext = track_get_cdtext(track);
|
|
||||||
int i; /* index */
|
|
||||||
|
|
||||||
fprintf(fp, "TRACK ");
|
|
||||||
switch (track_get_mode(track)) {
|
|
||||||
case MODE_AUDIO:
|
|
||||||
fprintf(fp, "AUDIO");
|
|
||||||
break;
|
|
||||||
case MODE_MODE1:
|
|
||||||
fprintf(fp, "MODE1");
|
|
||||||
break;
|
|
||||||
case MODE_MODE1_RAW:
|
|
||||||
fprintf(fp, "MODE1_RAW");
|
|
||||||
break;
|
|
||||||
case MODE_MODE2:
|
|
||||||
fprintf(fp, "MODE2");
|
|
||||||
break;
|
|
||||||
case MODE_MODE2_FORM1:
|
|
||||||
fprintf(fp, "MODE2_FORM1");
|
|
||||||
break;
|
|
||||||
case MODE_MODE2_FORM2:
|
|
||||||
fprintf(fp, "MODE2_FORM2");
|
|
||||||
break;
|
|
||||||
case MODE_MODE2_FORM_MIX:
|
|
||||||
fprintf(fp, "MODE2_FORM_MIX");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
|
|
||||||
if (0 != track_is_set_flag(track, FLAG_PRE_EMPHASIS))
|
|
||||||
fprintf(fp, "PRE_EMPHASIS\n");
|
|
||||||
if (0 != track_is_set_flag(track, FLAG_COPY_PERMITTED))
|
|
||||||
fprintf(fp, "COPY\n");
|
|
||||||
if (0 != track_is_set_flag(track, FLAG_FOUR_CHANNEL))
|
|
||||||
fprintf(fp, "FOUR_CHANNEL_AUDIO\n");
|
|
||||||
|
|
||||||
if (NULL != track_get_isrc(track))
|
|
||||||
fprintf(fp, "ISRC \"%s\"\n", track_get_isrc(track));
|
|
||||||
|
|
||||||
if (0 != cdtext_is_empty(cdtext)) {
|
|
||||||
fprintf(fp, "CD_TEXT {\n");
|
|
||||||
fprintf(fp, "\tLANGUAGE 0 {\n");
|
|
||||||
toc_print_cdtext(cdtext, fp, 1);
|
|
||||||
fprintf(fp, "\t}\n");
|
|
||||||
fprintf(fp, "}\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != track_get_zero_pre(track)) {
|
|
||||||
fprintf(fp, "ZERO ");
|
|
||||||
fprintf(fp, "%s", time_frame_to_mmssff(track_get_zero_pre(track)));
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(fp, "FILE ");
|
|
||||||
fprintf(fp, "\"%s\" ", track_get_filename(track));
|
|
||||||
if (0 == track_get_start(track))
|
|
||||||
fprintf(fp, "0");
|
|
||||||
else
|
|
||||||
fprintf(fp, "%s", time_frame_to_mmssff(track_get_start(track)));
|
|
||||||
if (0 != track_get_length(track))
|
|
||||||
fprintf(fp, " %s", time_frame_to_mmssff(track_get_length(track)));
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
|
|
||||||
if (0 != track_get_zero_post(track)) {
|
|
||||||
fprintf(fp, "ZERO ");
|
|
||||||
fprintf(fp, "%s", time_frame_to_mmssff(track_get_zero_post(track)));
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (track_get_index(track, 1) != 0) {
|
|
||||||
fprintf(fp, "START ");
|
|
||||||
fprintf(fp, "%s\n", time_frame_to_mmssff(track_get_index(track, 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 2; i < track_get_nindex(track); i++) {
|
|
||||||
fprintf(fp, "INDEX ");
|
|
||||||
fprintf(fp, "%s\n", time_frame_to_mmssff( \
|
|
||||||
track_get_index(track, i) - track_get_index(track, 0) \
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void toc_print_cdtext (Cdtext *cdtext, FILE *fp, int istrack)
|
|
||||||
{
|
|
||||||
int pti;
|
|
||||||
char *value = NULL;
|
|
||||||
|
|
||||||
for (pti = 0; PTI_END != pti; pti++) {
|
|
||||||
if (NULL != (value = cdtext_get(pti, cdtext))) {
|
|
||||||
fprintf(fp, "\t\t");
|
|
||||||
fprintf(fp, "%s", cdtext_get_key(pti, istrack));
|
|
||||||
fprintf(fp, " \"%s\"\n", value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
105
lib/toc_scan.l
105
lib/toc_scan.l
@@ -1,105 +0,0 @@
|
|||||||
%{
|
|
||||||
/*
|
|
||||||
* toc_scan.l -- lexer for toc files
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "cd.h"
|
|
||||||
#include "toc_parse_prefix.h"
|
|
||||||
#include "toc_parse.h"
|
|
||||||
|
|
||||||
int toc_lineno = 1;
|
|
||||||
%}
|
|
||||||
|
|
||||||
ws [ \t\r]
|
|
||||||
nonws [^ \t\r\n]
|
|
||||||
|
|
||||||
%option noyywrap
|
|
||||||
%option prefix="toc_yy"
|
|
||||||
|
|
||||||
%s NAME
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
\'([^\']|\\\')*\' |
|
|
||||||
\"([^\"]|\\\")*\" {
|
|
||||||
yylval.sval = strdup(yytext + 1);
|
|
||||||
yylval.sval[strlen(yylval.sval) - 1] = '\0';
|
|
||||||
BEGIN(INITIAL);
|
|
||||||
return STRING;
|
|
||||||
}
|
|
||||||
|
|
||||||
<NAME>{nonws}+ {
|
|
||||||
yylval.sval = strdup(yytext);
|
|
||||||
BEGIN(INITIAL);
|
|
||||||
return STRING;
|
|
||||||
}
|
|
||||||
|
|
||||||
CATALOG { BEGIN(NAME); return CATALOG; }
|
|
||||||
|
|
||||||
CD_DA { yylval.ival = MODE_CD_DA; return CD_DA; }
|
|
||||||
CD_ROM { yylval.ival = MODE_CD_ROM; return CD_ROM; }
|
|
||||||
CD_ROM_XA { yylval.ival = MODE_CD_ROM_XA; return CD_ROM_XA; }
|
|
||||||
|
|
||||||
TRACK { return TRACK; }
|
|
||||||
AUDIO { yylval.ival = MODE_AUDIO; return AUDIO; }
|
|
||||||
MODE1 { yylval.ival = MODE_MODE1; return MODE1; }
|
|
||||||
MODE1_RAW { yylval.ival = MODE_MODE1_RAW; return MODE1_RAW; }
|
|
||||||
MODE2 { yylval.ival = MODE_MODE2; return MODE2; }
|
|
||||||
MODE2_FORM1 { yylval.ival = MODE_MODE2_FORM1; return MODE2_FORM1; }
|
|
||||||
MODE2_FORM2 { yylval.ival = MODE_MODE2_FORM2; return MODE2_FORM2; }
|
|
||||||
MODE2_FORM_MIX { yylval.ival = MODE_MODE2_FORM_MIX; return MODE2_FORM_MIX; }
|
|
||||||
MODE2_RAW { yylval.ival = MODE_MODE2_RAW; return MODE2_RAW; }
|
|
||||||
RW { yylval.ival = SUB_MODE_RW; return RW; }
|
|
||||||
RW_RAW { yylval.ival = SUB_MODE_RW_RAW; return RW_RAW; }
|
|
||||||
|
|
||||||
NO { return NO; }
|
|
||||||
COPY { yylval.ival = FLAG_PRE_EMPHASIS; return COPY; }
|
|
||||||
PRE_EMPHASIS { yylval.ival = FLAG_COPY_PERMITTED; return PRE_EMPHASIS; }
|
|
||||||
FOUR_CHANNEL_AUDIO { yylval.ival = FLAG_FOUR_CHANNEL; return FOUR_CHANNEL_AUDIO; }
|
|
||||||
TWO_CHANNEL_AUDIO { yylval.ival = FLAG_FOUR_CHANNEL; return TWO_CHANNEL_AUDIO; }
|
|
||||||
|
|
||||||
/* ISRC is with CD-TEXT items */
|
|
||||||
|
|
||||||
SILENCE { return SILENCE; }
|
|
||||||
ZERO { return ZERO; }
|
|
||||||
(AUDIO)?FILE { BEGIN(NAME); return AUDIOFILE; }
|
|
||||||
DATAFILE { BEGIN(NAME); return DATAFILE; }
|
|
||||||
FIFO { BEGIN(NAME); return FIFO; }
|
|
||||||
START { return START; }
|
|
||||||
PREGAP { return PREGAP; }
|
|
||||||
INDEX { return INDEX; }
|
|
||||||
|
|
||||||
CD_TEXT { return CD_TEXT; }
|
|
||||||
LANGUAGE_MAP { return LANGUAGE_MAP; }
|
|
||||||
LANGUAGE { return LANGUAGE; }
|
|
||||||
|
|
||||||
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 { BEGIN(NAME); yylval.ival = PTI_UPC_ISRC; return ISRC; }
|
|
||||||
SIZE_INFO { BEGIN(NAME); yylval.ival = PTI_SIZE_INFO; return SIZE_INFO; }
|
|
||||||
|
|
||||||
"//".*\n { toc_lineno++; /* ignore comments */ }
|
|
||||||
{ws}+ { /* ignore whitespace */ }
|
|
||||||
|
|
||||||
[[:digit:]]+ { yylval.ival = atoi(yytext); return NUMBER; }
|
|
||||||
:|,|\{|\} { return yytext[0]; }
|
|
||||||
|
|
||||||
^{ws}*\n { toc_lineno++; /* blank line */ }
|
|
||||||
\n { toc_lineno++; return '\n'; }
|
|
||||||
. { fprintf(stderr, "bad character '%c'\n", yytext[0]); }
|
|
||||||
|
|
||||||
%%
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
CPPFLAGS+= -I../lib
|
|
||||||
LDFLAGS+= -L../lib
|
|
||||||
LDLIBS+= -lcuefile
|
|
||||||
|
|
||||||
TARGETS= cuebreakpoints cueconvert cueprint
|
|
||||||
|
|
||||||
all: $(TARGETS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(TARGETS)
|
|
||||||
rm -f *.o
|
|
||||||
|
|
||||||
INSTALL= install -c
|
|
||||||
INSTALL_PROGRAM= $(INSTALL)
|
|
||||||
INSTALL_DATA= $(INSTALL) -m 644
|
|
||||||
|
|
||||||
prefix= /usr/local
|
|
||||||
exec_prefix= $(prefix)
|
|
||||||
bindir= $(exec_prefix)/bin
|
|
||||||
DESTDIR=
|
|
||||||
|
|
||||||
install: all
|
|
||||||
$(INSTALL) -d $(DESTDIR)$(bindir)
|
|
||||||
for i in $(TARGETS) ; do \
|
|
||||||
$(INSTALL_PROGRAM) $$i $(DESTDIR)$(bindir)/$$i ; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
-for i in $(TARGETS) ; do \
|
|
||||||
rm -f $(DESTDIR)$(bindir)/$$i ; \
|
|
||||||
done
|
|
||||||
|
|
||||||
# dependancies
|
|
||||||
# generated by `gcc -MM *.c'
|
|
||||||
|
|
||||||
cuebreakpoints.o: cuebreakpoints.c ../lib/cuefile.h ../lib/cd.h \
|
|
||||||
../lib/cdtext.h
|
|
||||||
cueconvert.o: cueconvert.c ../lib/cuefile.h ../lib/cd.h ../lib/cdtext.h
|
|
||||||
cueprint.o: cueprint.c ../lib/cuefile.h ../lib/cd.h ../lib/cdtext.h
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
/*
|
|
||||||
* cuebreakpoints.c -- print track break points
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include "cuefile.h"
|
|
||||||
#include "time.h"
|
|
||||||
|
|
||||||
char *progname;
|
|
||||||
|
|
||||||
/* pregap correction modes
|
|
||||||
* APPEND - append pregap to previous track (except for first track)
|
|
||||||
* PREPEND - prefix pregap to current track
|
|
||||||
* SPLIT - print breakpoints for beginning and end of pregap
|
|
||||||
*/
|
|
||||||
enum GapMode {APPEND, PREPEND, SPLIT};
|
|
||||||
|
|
||||||
void usage (int status)
|
|
||||||
{
|
|
||||||
if (0 == status) {
|
|
||||||
fprintf(stdout, "%s: usage: cuebreakpoints [option...] [file...]\n", progname);
|
|
||||||
fputs("\
|
|
||||||
\n\
|
|
||||||
OPTIONS\n\
|
|
||||||
-h, --help print usage\n\
|
|
||||||
-i, --input-format cue|toc set format of file(s)\n\
|
|
||||||
--append-gaps append pregaps to previous track (default)\n\
|
|
||||||
--prepend-gaps prefix pregaps to track\n\
|
|
||||||
--split-gaps split at beginning and end of pregaps\n\
|
|
||||||
", stdout);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "run `%s --help' for usage\n", progname);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_m_ss_ff (long frame)
|
|
||||||
{
|
|
||||||
int m, s, f;
|
|
||||||
|
|
||||||
time_frame_to_msf(frame, &m, &s, &f);
|
|
||||||
printf ("%d:%02d.%02d\n", m, s, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_breakpoint (long b)
|
|
||||||
{
|
|
||||||
/* do not print zero breakpoints */
|
|
||||||
if (0 != b)
|
|
||||||
print_m_ss_ff(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_breaks (Cd *cd, int gaps)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
long b;
|
|
||||||
Track *track;
|
|
||||||
|
|
||||||
for (i = 1; i <= cd_get_ntrack(cd); i++) {
|
|
||||||
track = cd_get_track(cd, i);
|
|
||||||
/* when breakpoint is at:
|
|
||||||
* index 0: gap is prepended to track
|
|
||||||
* index 1: gap is appended to previous track
|
|
||||||
*/
|
|
||||||
b = track_get_start(track);
|
|
||||||
|
|
||||||
if (gaps == PREPEND || gaps == SPLIT) {
|
|
||||||
print_breakpoint(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gaps == APPEND || gaps == SPLIT) {
|
|
||||||
/* there is no previous track to append the first tracks pregap to */
|
|
||||||
/* TODO: should first track's pregap be split when appending?
|
|
||||||
* this could be a suprising default
|
|
||||||
*/
|
|
||||||
if (1 < i) {
|
|
||||||
b += track_get_index(track, 1) - track_get_zero_pre(track);
|
|
||||||
print_breakpoint(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int breaks (char *name, int format, int gaps)
|
|
||||||
{
|
|
||||||
Cd *cd = NULL;
|
|
||||||
|
|
||||||
if (NULL == (cd = cf_parse(name, &format))) {
|
|
||||||
fprintf(stderr, "%s: input file error\n", name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_breaks(cd, gaps);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
int format = UNKNOWN;
|
|
||||||
int gaps = APPEND;
|
|
||||||
|
|
||||||
/* option variables */
|
|
||||||
char c;
|
|
||||||
/* getopt_long() variables */
|
|
||||||
extern char *optarg;
|
|
||||||
extern int optind;
|
|
||||||
|
|
||||||
static struct option longopts[] = {
|
|
||||||
{"help", no_argument, NULL, 'h'},
|
|
||||||
{"input-format", required_argument, NULL, 'i'},
|
|
||||||
{"append-gaps", no_argument, NULL, 'a'},
|
|
||||||
{"prepend-gaps", no_argument, NULL, 'p'},
|
|
||||||
{"split-gaps", no_argument, NULL, 's'},
|
|
||||||
{NULL, 0, NULL, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
progname = *argv;
|
|
||||||
|
|
||||||
while (-1 != (c = getopt_long(argc, argv, "hi:", longopts, NULL))) {
|
|
||||||
switch (c) {
|
|
||||||
case 'h':
|
|
||||||
usage(0);
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
if (0 == strcmp("cue", optarg))
|
|
||||||
format = CUE;
|
|
||||||
else if (0 == strcmp("toc", optarg))
|
|
||||||
format = TOC;
|
|
||||||
else
|
|
||||||
fprintf(stderr, "%s: illegal format `%s'\n", progname, optarg);
|
|
||||||
usage(1);
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
gaps = APPEND;
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
gaps = PREPEND;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
gaps = SPLIT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optind == argc) {
|
|
||||||
breaks("-", format, gaps);
|
|
||||||
} else {
|
|
||||||
for (; optind < argc; optind++)
|
|
||||||
breaks(argv[optind], format, gaps);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
* cueconvert.c -- convert between cue/toc formats
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include "cuefile.h"
|
|
||||||
|
|
||||||
char *progname;
|
|
||||||
|
|
||||||
void usage (int status)
|
|
||||||
{
|
|
||||||
if (0 == status) {
|
|
||||||
fprintf(stdout, "%s: usage: cueconvert [option...] [infile [outfile]]\n", progname);
|
|
||||||
fputs("\
|
|
||||||
\n\
|
|
||||||
OPTIONS\n\
|
|
||||||
-h, --help print usage\n\
|
|
||||||
-i, --input-format cue|toc set format of input file\n\
|
|
||||||
-o, --output-format cue|toc set format of output file\n\
|
|
||||||
", stdout);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "run `%s --help' for usage\n", progname);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
int convert (char *iname, int iformat, char *oname, int oformat)
|
|
||||||
{
|
|
||||||
Cd *cd = NULL;
|
|
||||||
|
|
||||||
if (NULL == (cd = cf_parse(iname, &iformat))) {
|
|
||||||
fprintf(stderr, "input file error\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UNKNOWN == oformat) {
|
|
||||||
/* first use file suffix */
|
|
||||||
if (UNKNOWN == (oformat = cf_format_from_suffix(oname))) {
|
|
||||||
/* then use opposite of input format */
|
|
||||||
switch(iformat) {
|
|
||||||
case CUE:
|
|
||||||
oformat = TOC;
|
|
||||||
break;
|
|
||||||
case TOC:
|
|
||||||
oformat = CUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cf_print(oname, &oformat, cd);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
int iformat = UNKNOWN;
|
|
||||||
int oformat = UNKNOWN;
|
|
||||||
/* option variables */
|
|
||||||
char c;
|
|
||||||
/* getopt_long() variables */
|
|
||||||
extern char *optarg;
|
|
||||||
extern int optind;
|
|
||||||
|
|
||||||
static struct option longopts[] = {
|
|
||||||
{"help", no_argument, NULL, 'h'},
|
|
||||||
{"input-format", required_argument, NULL, 'i'},
|
|
||||||
{"output-format", required_argument, NULL, 'o'},
|
|
||||||
{NULL, 0, NULL, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
progname = *argv;
|
|
||||||
|
|
||||||
while (-1 != (c = getopt_long(argc, argv, "hi:o:", longopts, NULL))) {
|
|
||||||
switch (c) {
|
|
||||||
case 'h':
|
|
||||||
usage(0);
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
if (0 == strcmp("cue", optarg))
|
|
||||||
iformat = CUE;
|
|
||||||
else if (0 == strcmp("toc", optarg))
|
|
||||||
iformat = TOC;
|
|
||||||
else
|
|
||||||
fprintf(stderr, "%s: illegal format `%s'\n", progname, optarg);
|
|
||||||
usage(1);
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
if (0 == strcmp("cue", optarg))
|
|
||||||
oformat = CUE;
|
|
||||||
else if (0 == strcmp("toc", optarg))
|
|
||||||
oformat = TOC;
|
|
||||||
else
|
|
||||||
fprintf(stderr, "%s: illegal format `%s'\n", progname, optarg);
|
|
||||||
usage(1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optind == argc) {
|
|
||||||
convert("-", iformat, "-", oformat);
|
|
||||||
} else if (optind == argc - 1) {
|
|
||||||
convert(argv[optind], iformat, "-", oformat);
|
|
||||||
} else if (optind == argc - 2) {
|
|
||||||
convert(argv[optind], iformat, argv[optind + 1], oformat);
|
|
||||||
} else {
|
|
||||||
usage(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
496
tools/cueprint.c
496
tools/cueprint.c
@@ -1,496 +0,0 @@
|
|||||||
/*
|
|
||||||
* cueprint.c -- print cd information based on a template
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Svend Sorensen
|
|
||||||
* For license terms, see the file COPYING in this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h> /* exit() */
|
|
||||||
#include <string.h> /* strcmp() */
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <ctype.h> /* isdigit() */
|
|
||||||
#include "cuefile.h"
|
|
||||||
|
|
||||||
/* default templates */
|
|
||||||
|
|
||||||
#define D_TEMPLATE "\
|
|
||||||
Disc Information\n\
|
|
||||||
arranger: %A\n\
|
|
||||||
composer: %C\n\
|
|
||||||
genre: %G\n\
|
|
||||||
message: %M\n\
|
|
||||||
no. of tracks: %N\n\
|
|
||||||
performer: %P\n\
|
|
||||||
songwriter: %S\n\
|
|
||||||
title: %T\n\
|
|
||||||
UPC/EAN: %U\n\
|
|
||||||
"
|
|
||||||
|
|
||||||
#define T_TEMPLATE "\
|
|
||||||
\n\
|
|
||||||
Track %n Information\n\
|
|
||||||
arranger: %a\n\
|
|
||||||
composer: %c\n\
|
|
||||||
genre: %g\n\
|
|
||||||
ISRC: %i\n\
|
|
||||||
message: %m\n\
|
|
||||||
track number: %n\n\
|
|
||||||
perfomer: %p\n\
|
|
||||||
title: %t\n\
|
|
||||||
ISRC (CD-TEXT): %u\n\
|
|
||||||
"
|
|
||||||
|
|
||||||
/* default string to print for unset (NULL) values */
|
|
||||||
#define VALUE_UNSET ""
|
|
||||||
|
|
||||||
/*
|
|
||||||
* *_get_* functions can return an int or char *
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
int ival;
|
|
||||||
char *sval;
|
|
||||||
char cval;
|
|
||||||
} Value;
|
|
||||||
|
|
||||||
char *progname;
|
|
||||||
|
|
||||||
void usage (int status)
|
|
||||||
{
|
|
||||||
if (0 == status) {
|
|
||||||
fprintf(stdout, "%s: usage: cueprint [option...] [file...]\n", progname);
|
|
||||||
fputs("\
|
|
||||||
\n\
|
|
||||||
OPTIONS\n\
|
|
||||||
-h, --help print usage\n\
|
|
||||||
-i, --input-format cue|toc set format of file(s)\n\
|
|
||||||
-n, --track-number <number> only print track information for single track\n\
|
|
||||||
-d, --disc-template <template> set disc template (see TEMPLATE EXPANSION)\n\
|
|
||||||
-t, --track-template <template> set track template (see TEMPLATE EXPANSION)\n\
|
|
||||||
\n\
|
|
||||||
Template Expansion\n\
|
|
||||||
Disc:\n\
|
|
||||||
%A - album arranger\n\
|
|
||||||
%C - album composer\n\
|
|
||||||
%G - album genre\n\
|
|
||||||
%M - album message\n\
|
|
||||||
%N - number of tracks\n\
|
|
||||||
%P - album performer\n\
|
|
||||||
%S - album songwriter\n\
|
|
||||||
%T - album title\n\
|
|
||||||
%U - album UPC/EAN\n\
|
|
||||||
Track:\n\
|
|
||||||
%a - track arranger\n\
|
|
||||||
%c - track composer\n\
|
|
||||||
%g - track genre\n\
|
|
||||||
%i - track ISRC\n\
|
|
||||||
%m - track message\n\
|
|
||||||
%n - track number\n\
|
|
||||||
%p - track perfomer\n\
|
|
||||||
%t - track title\n\
|
|
||||||
%u - track ISRC (CD-TEXT)\n\
|
|
||||||
\n\
|
|
||||||
Any other %<character> is expanded to that character. For example, to get a\n\
|
|
||||||
'%', use %%.\n\
|
|
||||||
\n\
|
|
||||||
", stdout);
|
|
||||||
fprintf(stdout, "default disc template is:\n%s\n", D_TEMPLATE);
|
|
||||||
fprintf(stdout, "default track template is:\n%s\n", T_TEMPLATE);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "run `%s --help' for usage\n", progname);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disc_field (char *conv, int length, Cd *cd, Value *value)
|
|
||||||
{
|
|
||||||
char *c; /* pointer to conversion character */
|
|
||||||
|
|
||||||
Cdtext *cdtext = NULL;
|
|
||||||
cdtext = cd_get_cdtext(cd);
|
|
||||||
|
|
||||||
c = conv + length - 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* after setting value, set *c to specify value type
|
|
||||||
* 'd' integer
|
|
||||||
* 's' string
|
|
||||||
* 'c' character
|
|
||||||
*/
|
|
||||||
switch (*c) {
|
|
||||||
case 'A':
|
|
||||||
value->sval = cdtext_get(PTI_ARRANGER, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
value->sval = cdtext_get(PTI_COMPOSER, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'G':
|
|
||||||
value->sval = cdtext_get(PTI_GENRE, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'M':
|
|
||||||
value->sval = cdtext_get(PTI_MESSAGE, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'N':
|
|
||||||
value->ival = cd_get_ntrack(cd);
|
|
||||||
*c = 'd';
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
value->sval = cdtext_get(PTI_PERFORMER, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
value->sval = cdtext_get(PTI_ARRANGER, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
value->sval = cdtext_get(PTI_SONGWRITER, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'T':
|
|
||||||
value->sval = cdtext_get(PTI_TITLE, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'U':
|
|
||||||
value->sval = cdtext_get(PTI_UPC_ISRC, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
value->cval = *c;
|
|
||||||
*c = 'c';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void track_field (char *conv, int length, Cd *cd, int trackno, Value *value)
|
|
||||||
{
|
|
||||||
char *c; /* pointer to conversion character */
|
|
||||||
|
|
||||||
Track *track = NULL;
|
|
||||||
Cdtext *cdtext = NULL;
|
|
||||||
|
|
||||||
track = cd_get_track(cd, trackno);
|
|
||||||
cdtext = track_get_cdtext(track);
|
|
||||||
|
|
||||||
c = conv + length - 1;
|
|
||||||
|
|
||||||
switch (*c) {
|
|
||||||
case 'a':
|
|
||||||
value->sval = cdtext_get(PTI_ARRANGER, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
value->sval = cdtext_get(PTI_COMPOSER, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
value->sval = track_get_filename(track);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
value->sval = cdtext_get(PTI_GENRE, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
value->sval = track_get_isrc(track);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
value->sval = cdtext_get(PTI_MESSAGE, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
value->ival = trackno;
|
|
||||||
*c = 'd';
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
value->sval = cdtext_get(PTI_PERFORMER, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
value->sval = cdtext_get(PTI_SONGWRITER, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
value->sval = cdtext_get(PTI_TITLE, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
value->sval = cdtext_get(PTI_UPC_ISRC, cdtext);
|
|
||||||
*c = 's';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
disc_field(conv, length, cd, value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* print a % conversion specification
|
|
||||||
* %[flag(s)][width][.precision]<conversion-char>
|
|
||||||
*/
|
|
||||||
void print_conv (char *start, int length, Cd *cd, int trackno)
|
|
||||||
{
|
|
||||||
char *conv; /* copy of conversion specification */
|
|
||||||
Value value;
|
|
||||||
char *c; /* pointer to conversion-char */
|
|
||||||
|
|
||||||
/* TODO: use strndup? */
|
|
||||||
conv = malloc ((unsigned) (length + 1));
|
|
||||||
strncpy(conv, start, length);
|
|
||||||
conv[length] = '\0';
|
|
||||||
|
|
||||||
/* conversion character */
|
|
||||||
if (0 == trackno)
|
|
||||||
disc_field(conv, length, cd, &value);
|
|
||||||
else
|
|
||||||
track_field(conv, length, cd, trackno, &value);
|
|
||||||
|
|
||||||
c = conv + length - 1;
|
|
||||||
|
|
||||||
switch (*c) {
|
|
||||||
case 'c':
|
|
||||||
printf(conv, value.cval);
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
printf(conv, value.ival);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
if (NULL == value.sval)
|
|
||||||
printf(conv, VALUE_UNSET);
|
|
||||||
else
|
|
||||||
printf(conv, value.sval);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("%d: ", strlen(conv));
|
|
||||||
printf("%s", conv);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(conv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cd_printf (char *format, Cd *cd, int trackno)
|
|
||||||
{
|
|
||||||
char *c; /* pointer into format */
|
|
||||||
char *conv_start;
|
|
||||||
int conv_length;
|
|
||||||
|
|
||||||
for (c = format; '\0' != *c; c++) {
|
|
||||||
if ('%' == *c) {
|
|
||||||
conv_start = c;
|
|
||||||
conv_length = 1;
|
|
||||||
c++;
|
|
||||||
|
|
||||||
/* flags */
|
|
||||||
while ( \
|
|
||||||
'-' == *c \
|
|
||||||
|| '+' == *c \
|
|
||||||
|| ' ' == *c \
|
|
||||||
|| '0' == *c \
|
|
||||||
|| '#' == *c \
|
|
||||||
) {
|
|
||||||
conv_length++;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* field width */
|
|
||||||
/* '*' not recognized */
|
|
||||||
while (0 != isdigit(*c)) {
|
|
||||||
conv_length++;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* precision */
|
|
||||||
/* '*' not recognized */
|
|
||||||
if ('.' == *c) {
|
|
||||||
conv_length++;
|
|
||||||
c++;
|
|
||||||
|
|
||||||
while (0 != isdigit(*c)) {
|
|
||||||
conv_length++;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* length modifier (h, l, or L) */
|
|
||||||
/* not recognized */
|
|
||||||
|
|
||||||
/* conversion character */
|
|
||||||
conv_length++;
|
|
||||||
|
|
||||||
print_conv(conv_start, conv_length, cd, trackno);
|
|
||||||
} else {
|
|
||||||
putchar(*c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int info (char *name, int format, int trackno, char *d_template, char *t_template)
|
|
||||||
{
|
|
||||||
Cd *cd = NULL;
|
|
||||||
int ntrack;
|
|
||||||
|
|
||||||
if (NULL == (cd = cf_parse(name, &format))) {
|
|
||||||
fprintf(stderr, "%s: input file error\n", name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ntrack = cd_get_ntrack(cd);
|
|
||||||
|
|
||||||
if (-1 == trackno) {
|
|
||||||
cd_printf(d_template, cd, 0);
|
|
||||||
|
|
||||||
for (trackno = 1; trackno <= ntrack; trackno++) {
|
|
||||||
cd_printf(t_template, cd, trackno);
|
|
||||||
}
|
|
||||||
} else if (0 == trackno) {
|
|
||||||
cd_printf(d_template, cd, trackno);
|
|
||||||
} else if (0 < trackno && ntrack >= trackno) {
|
|
||||||
cd_printf(t_template, cd, trackno);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "%s: track number out of range\n", progname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* translate escape sequences in a string
|
|
||||||
* string is overwritten and terminated
|
|
||||||
* TODO: this does not handle octal and hexidecimal escapes
|
|
||||||
* except for \0
|
|
||||||
*/
|
|
||||||
void translate_escapes(char *s)
|
|
||||||
{
|
|
||||||
char *read;
|
|
||||||
char *write;
|
|
||||||
|
|
||||||
read = s;
|
|
||||||
write = s;
|
|
||||||
|
|
||||||
while ('\0' != *read) {
|
|
||||||
if ('\\' == *read) {
|
|
||||||
read++;
|
|
||||||
|
|
||||||
switch (*read) {
|
|
||||||
case 'a':
|
|
||||||
*write = '\a';
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
*write = '\b';
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
*write = '\f';
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
*write = '\n';
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
*write = '\r';
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
*write = '\t';
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
*write = '\v';
|
|
||||||
break;
|
|
||||||
case '0':
|
|
||||||
*write = '\0';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* ?, ', " are handled by the default */
|
|
||||||
*write = *read;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*write = *read;
|
|
||||||
}
|
|
||||||
|
|
||||||
read++;
|
|
||||||
write++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*write = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
int format = UNKNOWN;
|
|
||||||
int trackno = -1; /* track number (-1 = unspecified, 0 = disc info) */
|
|
||||||
char *d_template = NULL; /* disc template */
|
|
||||||
char *t_template = NULL; /* track template */
|
|
||||||
/* getopt_long() variables */
|
|
||||||
char c;
|
|
||||||
extern char *optarg;
|
|
||||||
extern int optind;
|
|
||||||
|
|
||||||
static struct option longopts[] = {
|
|
||||||
{"help", no_argument, NULL, 'h'},
|
|
||||||
{"input-format", required_argument, NULL, 'i'},
|
|
||||||
{"track-number", required_argument, NULL, 'n'},
|
|
||||||
{"disc-template", required_argument, NULL, 'd'},
|
|
||||||
{"track-template", required_argument, NULL, 't'},
|
|
||||||
{NULL, 0, NULL, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
progname = *argv;
|
|
||||||
|
|
||||||
while (-1 != (c = getopt_long(argc, argv, "hi:n:d:t:", longopts, NULL))) {
|
|
||||||
switch (c) {
|
|
||||||
case 'h':
|
|
||||||
usage(0);
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
if (0 == strcmp("cue", optarg))
|
|
||||||
format = CUE;
|
|
||||||
else if (0 == strcmp("toc", optarg))
|
|
||||||
format = TOC;
|
|
||||||
else
|
|
||||||
fprintf(stderr, "%s: illegal format `%s'\n", progname, optarg);
|
|
||||||
usage(1);
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
trackno = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
d_template = optarg;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
t_template = optarg;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if no disc or track template is set, use the defaults for both */
|
|
||||||
/* TODO: alternative to strdup to get variable strings? */
|
|
||||||
if (NULL == d_template && NULL == t_template) {
|
|
||||||
d_template = strdup(D_TEMPLATE);
|
|
||||||
t_template = strdup(T_TEMPLATE);
|
|
||||||
} else {
|
|
||||||
if (NULL == d_template)
|
|
||||||
d_template = strdup("");
|
|
||||||
|
|
||||||
if (NULL == t_template)
|
|
||||||
t_template = strdup("");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* translate escape sequences */
|
|
||||||
translate_escapes(d_template);
|
|
||||||
translate_escapes(t_template);
|
|
||||||
|
|
||||||
if (optind == argc) {
|
|
||||||
info("-", format, trackno, d_template, t_template);
|
|
||||||
} else {
|
|
||||||
for (; optind < argc; optind++)
|
|
||||||
info(argv[optind], format, trackno, d_template, t_template);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user