This repository has been archived on 2025-05-24. You can view files and clone it, but cannot push or open issues or pull requests.
Files
libcdio-osx/parse/toclexer.c

199 lines
5.3 KiB
C
Raw Normal View History

2005-01-31 10:20:51 +00:00
/*
$Id: toclexer.c,v 1.1 2005/01/31 10:20:51 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Lexical scanner for cdrdao's TOC. */
#include "toclexer.h"
#include "toc.tab.h"
#include <ctype.h>
#define YYEOF 0
/* A structure for associating a word with a token. */
typedef struct keyword_s
{
char const *psz_keyword;
token_t i_token;
} keyword_t;
/* These are all of the words that might appear in a TOC file and
the token association that the parser will use.
*/
const keyword_t keywords[] =
{
{"ARRANGER", ARRANGER},
{"AUDIO", AUDIO},
{"AUDIOFILE", AUDIOFILE},
{"CATALOG", CATALOG},
{"CD_DA", CD_DA},
{"CD_I", CD_I},
{"CD_ROM", CD_ROM},
{"CD_ROM_XA", CD_ROM_XA},
{"CD_TEXT", CD_TEXT},
{"COMPOSER", COMPOSER},
{"COPY", COPY},
{"DATAFILE", DATAFILE},
{"DISC_ID", DISC_ID},
{"EN", EN},
{"END", END},
{"FIFO", FIFO},
{"FILE", FILE_TOKEN},
{"FOUR_CHANNEL_AUDIO", FOUR_CHANNEL_AUDIO},
{"GENRE", GENRE},
{"INDEX", INDEX},
{"ISRC", ISRC},
{"LANGUAGE", LANGUAGE},
{"LANGUAGE_MAP", LANGUAGE_MAP},
{"MESSAGE", MESSAGE},
{"MODE0", MODE0},
{"MODE1", MODE1},
{"MODE1_RAW", MODE1_RAW},
{"MODE2", MODE2},
{"MODE2_FORM1", MODE2_FORM1},
{"MODE2_FORM2", MODE2_FORM2},
{"MODE2_FORM_MIX", MODE2_FORM_MIX},
{"MODE2_RAW", MODE2_RAW},
{"NO", NO},
{"PERFORMER", PERFORMER},
{"PREGAP", PREGAP},
{"PRE_EMPHASIS", PRE_EMPHASIS},
{"RESERVED1", RESERVED1},
{"RESERVED2", RESERVED2},
{"RESERVED3", RESERVED3},
{"RESERVED4", RESERVED4},
{"RW", RW},
{"RW_RAW", RW_RAW},
{"SILENCE", SILENCE},
{"SIZE_INFO", SIZE_INFO},
{"SONGWRITER", SONGWRITER},
{"START", START},
{"SWAP", SWAP},
{"TITLE", TITLE},
{"TOC_INFO1", TOC_INFO1},
{"TOC_INFO2", TOC_INFO2},
{"TRACK", TRACK},
{"TWO_CHANNEL_AUDIO", TWO_CHANNEL_AUDIO},
{"UPC_EAN", UPC_EAN},
{"ZERO", ZERO},
{0, 0}
};
static int
compare_keyword(const void *p_id, const void *p_keyword) {
char *psz_id = (char *) p_id;
char const *psz_keyword = ((keyword_t *) p_keyword)->psz_keyword;
return strcmp(psz_id, psz_keyword);
}
token_t
toclex (void)
{
int c;
start:
/* Skip white space. */
while ( isspace(c = fgetc (toc_in)) )
;
/* Process a number. */
if (isdigit (c))
{
ungetc (c, toc_in);
fscanf (toc_in, "%lu", &(toclval.val));
return Integer;
}
/* Process a comment. */
if ( '/' == c ) {
if ('/' == (c = fgetc (toc_in)) ) {
while ((c = fgetc (toc_in)) != EOF && c != '\n')
;
/* Return end-of-input. */
if (EOF == c) return YYEOF;
goto start;
}
/* Not a comment. So put back the character after the '/' and
return '/' */
ungetc (c, toc_in);
return '/';
}
/* Char starts an identifier => read the name. */
if (isalpha (c))
{
static char symbol[50] = "";
unsigned int i;
i = 0;
do
{
/* Add this character to the buffer. */
symbol[i++] = c;
/* Get another character. */
c = fgetc (toc_in);
}
while (isgraph (c));
ungetc (c, toc_in);
symbol[i] = '\0';
toclval.psz_str = symbol;
{
keyword_t *p_keyword;
p_keyword = bsearch(symbol, keywords,
(sizeof(keywords) / sizeof(keyword_t)) - 1,
sizeof(keyword_t), compare_keyword);
if (!p_keyword) return Id;
return p_keyword->i_token;
}
}
/* Process a string.
To do: save the value of the string and process octal numbers.
*/
if ( '"' == c ) {
int b_backslash = 0;
while ( EOF != (c = fgetc (toc_in))
&& (b_backslash || '"' != c ) ) {
b_backslash = ('\\' == c );
}
/* Return end-of-input. */
if (EOF == c) return YYEOF;
return String;
}
/* Return end-of-input. */
if (EOF == c) return YYEOF;
switch (c) {
case ':': return Colon;
case '{': return LeftBrace;
case '}': return RightBrace;
default:
/* Return a single char. */
return c;
}
}