mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-12-11 21:31:30 +00:00
3e38c4aa48
qfcc now does local common subexpression elimination. It seems to work, but is optional (default off): use -O to enable. Also, uninitialized variable detection is finally back :) The progs engine now has very basic valgrind-like functionality for checking pointer accesses. Enable with pr_boundscheck 2
171 lines
3.4 KiB
C
171 lines
3.4 KiB
C
/*
|
|
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
|
|
|
|
#ifdef HAVE_STRING_H
|
|
# include <string.h>
|
|
#endif
|
|
#ifdef HAVE_STRINGS_H
|
|
# include <strings.h>
|
|
#endif
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "QF/alloc.h"
|
|
#include "QF/hash.h"
|
|
#include "QF/quakeio.h"
|
|
|
|
#include "diagnostic.h"
|
|
#include "expr.h"
|
|
#include "grab.h"
|
|
#include "options.h"
|
|
#include "qfcc.h"
|
|
#include "strpool.h"
|
|
|
|
int grab_frame;
|
|
int grab_other;
|
|
int grab_write;
|
|
|
|
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 *frame_list;
|
|
static frame_t **frame_tail = &frame_list;
|
|
|
|
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 (const void *f, void *unused)
|
|
{
|
|
return ((frame_t*)f)->name;
|
|
}
|
|
|
|
static void
|
|
frame_free (void *_f, void *unused)
|
|
{
|
|
frame_t *f = (frame_t *)_f;
|
|
FREE (frames, f);
|
|
}
|
|
|
|
int
|
|
do_grab (const 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 (!strcmp (token, "frame_write"))
|
|
return -grab_write;
|
|
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 (const 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_tail = frame;
|
|
frame_tail = &frame->next;
|
|
frame->name = save_string (token);
|
|
frame->num = frame_number++;
|
|
Hash_Add (frame_tab, frame);
|
|
}
|
|
|
|
void
|
|
clear_frame_macros (void)
|
|
{
|
|
frame_number = 0;
|
|
frame_tail = &frame_list;
|
|
frame_list = 0;
|
|
if (frame_tab)
|
|
Hash_FlushTable (frame_tab);
|
|
}
|
|
|
|
void
|
|
write_frame_macros (const char *filename)
|
|
{
|
|
frame_t *frame;
|
|
QFile *file;
|
|
|
|
if (!frame_list)
|
|
return;
|
|
file = Qopen (filename, "wt");
|
|
for (frame = frame_list; frame; frame = frame->next)
|
|
Qprintf (file, "%s %d\n", frame->name, frame->num);
|
|
Qclose (file);
|
|
}
|