Break out the frame macro code from qc-lex.l

This commit is contained in:
Bill Currie 2011-01-06 16:30:25 +09:00
parent 2b539ee4ae
commit 66ac56063f
4 changed files with 213 additions and 116 deletions

41
tools/qfcc/include/grab.h Normal file
View file

@ -0,0 +1,41 @@
/*
grab.h
frame macro grabbing
Copyright (C) 2011 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2011/01/06
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifndef __grab_h
#define __grab_h
extern int grab_frame;
extern int grab_other;
int do_grab (char *token);
void add_frame_macro (char *token);
#endif//__grab_h

View file

@ -49,12 +49,13 @@ bin_PROGRAMS= $(qfcc) $(qfprogs)
bin_SCRIPTS= $(qfpreqcc)
EXTRA_PROGRAMS= qfcc qfprogs
qfcc_SOURCES= \
class.c constfold.c cpp.c debug.c def.c emit.c expr.c function.c \
common_src=\
class.c constfold.c cpp.c debug.c def.c emit.c expr.c function.c grab.c \
idstuff.c immediate.c linker.c method.c obj_file.c opcodes.c options.c \
qc-lex.l qc-parse.y qfcc.c reloc.c strpool.c struct.c switch.c symtab.c \
qfcc.c reloc.c strpool.c struct.c switch.c symtab.c \
type.c
qfcc_SOURCES= qc-lex.l qc-parse.y $(common_src)
qfcc_LDADD= $(QFCC_LIBS)
qfcc_DEPENDENCIES= $(QFCC_DEPS)

148
tools/qfcc/source/grab.c Normal file
View file

@ -0,0 +1,148 @@
/*
grab.c
frame macro grabbing
Copyright (C) 2011 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2011/01/06
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] = "$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <ctype.h>
#include "QF/hash.h"
#include "expr.h"
#include "grab.h"
#include "options.h"
#include "qfcc.h"
int grab_frame;
int grab_other;
static hashtab_t *frame_tab;
static hashtab_t *grab_tab;
typedef struct frame_s {
struct frame_s *next;
const char *name;
int num;
} frame_t;
static frame_t *free_frames;
static frame_t grab_list[] = {
{0, "cd", 0},
{0, "origin", 0},
{0, "base", 0},
{0, "flags", 0},
{0, "scale", 0},
{0, "skin", 0},
};
static const char *
frame_get_key (void *f, void *unused)
{
return ((frame_t*)f)->name;
}
static void
frame_free (void *_f, void *unused)
{
frame_t *f = (frame_t *)_f;
f->next = free_frames;
free_frames = f;
}
int
do_grab (char *token)
{
static int initialized;
frame_t *frame;
if (!initialized) {
size_t i;
initialized = 1;
frame_tab = Hash_NewTable (1021, frame_get_key, frame_free, 0);
grab_tab = Hash_NewTable (1021, frame_get_key, 0, 0);
for (i = 0; i < sizeof (grab_list) / sizeof (grab_list[0]); i++)
Hash_Add (grab_tab, &grab_list[i]);
}
while (isspace ((unsigned char)*++token))
// advance over $ and leading space
;
if (!strcmp (token, "frame"))
return -grab_frame;
if (!strcmp (token, "frame_reset")) {
clear_frame_macros ();
return -grab_other;
}
if (Hash_Find (grab_tab, token))
return -grab_other;
frame = Hash_Find (frame_tab, token);
if (frame)
return frame->num;
return 0;
}
static int frame_number;
void
add_frame_macro (char *token)
{
frame_t *frame;
if (Hash_Find (frame_tab, token)) {
warning (0, "duplicate frame macro `%s'", token);
if (options.traditional)
frame_number++;
return;
}
ALLOC (1024, frame_t, frames, frame);
frame->name = save_string (token);
frame->num = frame_number++;
Hash_Add (frame_tab, frame);
}
void
clear_frame_macros (void)
{
frame_number = 0;
if (frame_tab)
Hash_FlushTable (frame_tab);
}

View file

@ -49,9 +49,10 @@ static __attribute__ ((used)) const char rcsid[] =
#include <QF/sys.h>
#include "qfcc.h"
#include "class.h"
#include "debug.h"
#include "expr.h"
#include "class.h"
#include "grab.h"
#include "immediate.h"
#include "options.h"
#include "struct.h"
@ -81,9 +82,7 @@ int yylex_destroy (void);
YY_DECL;
int type_or_name (char *token);
int do_grab (char *token);
void add_frame_macro (char *token);
static int type_or_name (char *token);
extern YYSTYPE yylval;
@ -98,16 +97,18 @@ s [ \t]
m ([\-+]?)
FRAMEID {ID}(\.{ID})*
%x grab_frame grab_other comment
%x GRAB_FRAME GRAB_OTHER COMMENT
%%
grab_frame = GRAB_FRAME;
grab_other = GRAB_OTHER;
"/*" { BEGIN (comment); }
<comment>"/*" { warning (0, "nested /* in comment"); }
<comment>"*/" { BEGIN (INITIAL); }
<comment>\r*\n { pr.source_line++; }
<comment>. /* nothing to do */
<comment><<EOF>> { error (0, "EOF in comment"); return 0; }
"/*" { BEGIN (COMMENT); }
<COMMENT>"/*" { warning (0, "nested /* in comment"); }
<COMMENT>"*/" { BEGIN (INITIAL); }
<COMMENT>\r*\n { pr.source_line++; }
<COMMENT>. /* nothing to do */
<COMMENT><<EOF>> { error (0, "EOF in comment"); return 0; }
"//".* /* nothing to do */
^#{s}+{DIGIT}+{s}+\"(\.|[^"\n])*\".*$ { line_info (yytext + 1); }
@ -233,14 +234,16 @@ FRAMEID {ID}(\.{ID})*
"$"{s}*{FRAMEID} {
int ret = do_grab (yytext);
if (ret > 0)
return ret;
else
if (ret >= 0) {
yylval.integer_val = ret;
return INT_VAL;
} else {
BEGIN (-ret);
}
}
<grab_frame>{FRAMEID} add_frame_macro (yytext);
<grab_other>[^\r\n]* /* skip */
<GRAB_FRAME>{FRAMEID} add_frame_macro (yytext);
<GRAB_OTHER>[^\r\n]* /* skip */
<*>\r*\n {
pr.source_line++;
@ -333,7 +336,7 @@ keyword_get_key (void *kw, void *unused)
return ((keyword_t*)kw)->name;
}
int
static int
type_or_name (char *token)
{
static hashtab_t *keyword_tab;
@ -374,102 +377,6 @@ type_or_name (char *token)
return NAME;
}
static hashtab_t *frame_tab;
static hashtab_t *grab_tab;
typedef struct frame_s {
struct frame_s *next;
const char *name;
int num;
} frame_t;
static frame_t *free_frames;
static frame_t grab_list[] = {
{0, "cd", 0},
{0, "origin", 0},
{0, "base", 0},
{0, "flags", 0},
{0, "scale", 0},
{0, "skin", 0},
};
static const char *
frame_get_key (void *f, void *unused)
{
return ((frame_t*)f)->name;
}
static void
frame_free (void *_f, void *unused)
{
frame_t *f = (frame_t *)_f;
f->next = free_frames;
free_frames = f;
}
int
do_grab (char *token)
{
static int initialized;
frame_t *frame;
if (!initialized) {
size_t i;
initialized = 1;
frame_tab = Hash_NewTable (1021, frame_get_key, frame_free, 0);
grab_tab = Hash_NewTable (1021, frame_get_key, 0, 0);
for (i = 0; i < sizeof (grab_list) / sizeof (grab_list[0]); i++)
Hash_Add (grab_tab, &grab_list[i]);
}
while (isspace ((unsigned char)*++token))
// advance over $ and leading space
;
if (!strcmp (token, "frame"))
return -grab_frame;
if (!strcmp (token, "frame_reset")) {
clear_frame_macros ();
return -grab_other;
}
if (Hash_Find (grab_tab, token))
return -grab_other;
frame = Hash_Find (frame_tab, token);
if (frame) {
yylval.integer_val = frame->num;
return INT_VAL;
}
return 0;
}
static int frame_number;
void
add_frame_macro (char *token)
{
frame_t *frame;
if (Hash_Find (frame_tab, token)) {
warning (0, "duplicate frame macro `%s'", token);
if (options.traditional)
frame_number++;
return;
}
ALLOC (1024, frame_t, frames, frame);
frame->name = save_string (token);
frame->num = frame_number++;
Hash_Add (frame_tab, frame);
}
void
clear_frame_macros (void)
{
frame_number = 0;
if (frame_tab)
Hash_FlushTable (frame_tab);
}
#ifdef YY_FLEX_REALLOC_HACK
static __attribute__ ((used)) void *(*const yy_flex_realloc_hack)(void *,yy_size_t) = yy_flex_realloc;
#else