mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
Break out the frame macro code from qc-lex.l
This commit is contained in:
parent
2b539ee4ae
commit
66ac56063f
4 changed files with 213 additions and 116 deletions
41
tools/qfcc/include/grab.h
Normal file
41
tools/qfcc/include/grab.h
Normal 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
|
|
@ -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
148
tools/qfcc/source/grab.c
Normal 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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue