From a9a169e820bbf99326816c34fb76e27fa268ad57 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 28 Feb 2003 05:35:27 +0000 Subject: [PATCH] make the more relevant parts of qfs available to progs. bi_file.c will eventually be moving into bi_qfs.c --- include/QF/csqc.h | 9 +- libs/console/menu.c | 1 + libs/gamecode/builtins/Makefile.am | 2 +- libs/gamecode/builtins/bi_file.c | 10 +- libs/gamecode/builtins/bi_init.c | 3 +- libs/gamecode/builtins/bi_qfile.c | 166 ++++++++++++++--------------- libs/gamecode/builtins/bi_qfs.c | 140 ++++++++++++++++++++++++ 7 files changed, 239 insertions(+), 92 deletions(-) create mode 100644 libs/gamecode/builtins/bi_qfs.c diff --git a/include/QF/csqc.h b/include/QF/csqc.h index 070a0705c..b6bfdda63 100644 --- a/include/QF/csqc.h +++ b/include/QF/csqc.h @@ -53,8 +53,15 @@ void InputLine_Progs_SetDraw (struct progs_s *pr, void Key_Progs_Init (struct progs_s *pr); +#include "QF/quakeio.h" +#define QFILE_MAX_HANDLES 20 +typedef struct { + QFile *handles[QFILE_MAX_HANDLES]; +} qfile_resources_t; + void QFile_Progs_Init (struct progs_s *pr, int secure); -int QFile_open (struct progs_s *pr, const char *path, const char *mode); +QFile **QFile_AllocHandle (struct progs_s *pr, qfile_resources_t *res); +void QFS_Progs_Init (struct progs_s *pr); void String_Progs_Init (struct progs_s *pr); diff --git a/libs/console/menu.c b/libs/console/menu.c index 707a14c7f..acc29f8e0 100644 --- a/libs/console/menu.c +++ b/libs/console/menu.c @@ -449,6 +449,7 @@ Menu_Init (void) InputLine_Progs_Init (&menu_pr_state); Key_Progs_Init (&menu_pr_state); QFile_Progs_Init (&menu_pr_state, 1); + QFS_Progs_Init (&menu_pr_state); PR_Cmds_Init (&menu_pr_state); R_Progs_Init (&menu_pr_state); String_Progs_Init (&menu_pr_state); diff --git a/libs/gamecode/builtins/Makefile.am b/libs/gamecode/builtins/Makefile.am index a94dbae0e..92c0203df 100644 --- a/libs/gamecode/builtins/Makefile.am +++ b/libs/gamecode/builtins/Makefile.am @@ -11,4 +11,4 @@ libQFgamecode_builtins_la_SOURCES= pr_cmds.c libQFcsqc_la_LDFLAGS= -version-info 1:0:0 libQFcsqc_la_SOURCES=\ bi_cbuf.c bi_cmd.c bi_cvar.c bi_file.c bi_init.c bi_inputline.c \ - bi_qfile.c bi_string.c bi_strhash.c + bi_qfile.c bi_qfs.c bi_string.c bi_strhash.c diff --git a/libs/gamecode/builtins/bi_file.c b/libs/gamecode/builtins/bi_file.c index fe52e0cbe..8479f28e4 100644 --- a/libs/gamecode/builtins/bi_file.c +++ b/libs/gamecode/builtins/bi_file.c @@ -117,6 +117,8 @@ file_writeable (char *path) static void bi_File_Open (progs_t *pr) { + qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); + QFile **file = QFile_AllocHandle (pr, res); const char *pth = P_STRING (pr, 0); const char *mode = P_STRING (pr, 1); char *path; @@ -159,8 +161,12 @@ bi_File_Open (progs_t *pr) goto error; if (do_write && !file_writeable (path)) goto error; - R_INT (pr) = QFile_open (pr, va ("%s/%s/%s", fs_userpath->string, - qfs_gamedir->dir.def, path), mode); + + *file = Qopen (va ("%s/%s/%s", fs_userpath->string, + qfs_gamedir->dir.def, path), mode); + if (!*file) + goto error; + R_INT (pr) = (file - res->handles) + 1; free (path); return; error: diff --git a/libs/gamecode/builtins/bi_init.c b/libs/gamecode/builtins/bi_init.c index 001eb9ef3..9a4f20503 100644 --- a/libs/gamecode/builtins/bi_init.c +++ b/libs/gamecode/builtins/bi_init.c @@ -37,8 +37,9 @@ static __attribute__ ((unused)) const char rcsid[] = static void (*const cbuf_progs_init)(progs_t *) = Cbuf_Progs_Init; static void (*const cvar_progs_init)(progs_t *) = Cvar_Progs_Init; static void (*const cmd_progs_init)(progs_t *) = Cmd_Progs_Init; -static void (*const file_progs_init)(progs_t *) = File_Progs_Init; static void (*const inputline_progs_init)(progs_t *) = InputLine_Progs_Init; +static void (*const qfile_progs_init)(progs_t *, int) = QFile_Progs_Init; +static void (*const qfs_progs_init)(progs_t *) = QFS_Progs_Init; static void (*const string_progs_init)(progs_t *) = String_Progs_Init; static void (*const stringhashe_progs_init)(progs_t *) = StringHash_Progs_Init; diff --git a/libs/gamecode/builtins/bi_qfile.c b/libs/gamecode/builtins/bi_qfile.c index ac1718acb..dd5a98690 100644 --- a/libs/gamecode/builtins/bi_qfile.c +++ b/libs/gamecode/builtins/bi_qfile.c @@ -59,21 +59,30 @@ int fnmatch (const char *__pattern, const char *__string, int __flags); #include "QF/va.h" #include "QF/zone.h" -#define MAX_HANDLES 20 -static QFile *handles[MAX_HANDLES]; +static void +bi_qfile_clear (progs_t *pr, void *data) +{ + qfile_resources_t *res = (qfile_resources_t *) data; + int i; + + for (i = 0; i < QFILE_MAX_HANDLES; i++) + if (res->handles[i]) { + Qclose (res->handles[i]); + res->handles[i] = 0; + } +} -int -QFile_open (struct progs_s *pr, const char *path, const char *mode) +QFile ** +QFile_AllocHandle (struct progs_s *pr, qfile_resources_t *res) { int h; - for (h = 0; h < MAX_HANDLES && handles[h]; h++) + for (h = 0; h < QFILE_MAX_HANDLES && res->handles[h]; h++) ; - if (h == MAX_HANDLES) + if (h == QFILE_MAX_HANDLES) goto error; - if (!(handles[h] = Qopen (path, mode))) - goto error; - return h + 1; + res->handles[h] = (QFile *) 1; + return res->handles + h; error: return 0; } @@ -104,34 +113,47 @@ bi_Qremove (progs_t *pr) static void bi_Qopen (progs_t *pr) { + qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); const char *path = P_STRING (pr, 0); const char *mode = P_STRING (pr, 1); + QFile **h = QFile_AllocHandle (pr, res); - R_INT (pr) = QFile_open (pr, path, mode); + if (!h) { + R_INT (pr) = 0; + return; + } + *h = Qopen (path, mode); + R_INT (pr) = (h - res->handles) + 1; +} + +static QFile ** +get_qfile (progs_t *pr, int handle, const char *func) +{ + qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); + + if (handle < 1 || handle > QFILE_MAX_HANDLES || !res->handles[handle - 1]) + PR_RunError (pr, "%s: Invalid QFile", func); + return res->handles + handle - 1; } static void bi_Qclose (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qclose"); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) - return; - Qclose (handles[h]); - handles[h] = 0; + Qclose (*h); + *h = 0; } static void bi_Qgetline (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qgetline"); const char *s; - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = 0; - return; - } - s = Qgetline (handles[h]); + s = Qgetline (*h); RETURN_STRING (pr, s); } @@ -148,151 +170,121 @@ check_buffer (progs_t *pr, pr_type_t *buf, int count, const char *name) static void bi_Qread (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qread"); pr_type_t *buf = P_POINTER (pr, 1); int count = P_INT (pr, 2); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } check_buffer (pr, buf, count, "Qread"); - R_INT (pr) = Qread (handles[h], buf, count); + R_INT (pr) = Qread (*h, buf, count); } static void bi_Qwrite (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qwrite"); pr_type_t *buf = P_POINTER (pr, 1); int count = P_INT (pr, 2); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } check_buffer (pr, buf, count, "Qwrite"); - R_INT (pr) = Qwrite (handles[h], buf, count); + R_INT (pr) = Qwrite (*h, buf, count); } static void bi_Qputs (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qputs"); const char *str = P_STRING (pr, 1); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } - R_INT (pr) = Qputs (handles[h], str); + R_INT (pr) = Qputs (*h, str); } #if 0 static void bi_Qgets (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qgets"); pr_type_t *buf = P_POINTER (pr, 1); int count = P_INT (pr, 2); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } check_buffer (pr, buf, count, "Qgets"); - R_INT (pr) = POINTER_TO_PROG (pr, Qgets (handles[h], (char *) buf, count)); + R_INT (pr) = POINTER_TO_PROG (pr, Qgets (*h, (char *) buf, count)); } #endif static void bi_Qgetc (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qgetc"); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } - R_INT (pr) = Qgetc (handles[h]); + R_INT (pr) = Qgetc (*h); } static void bi_Qputc (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qputc"); int c = P_INT (pr, 1); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } - R_INT (pr) = Qputc (handles[h], c); + R_INT (pr) = Qputc (*h, c); } static void bi_Qseek (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qseek"); int offset = P_INT (pr, 1); int whence = P_INT (pr, 2); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } - R_INT (pr) = Qseek (handles[h], offset, whence); + R_INT (pr) = Qseek (*h, offset, whence); } static void bi_Qtell (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qtell"); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } - R_INT (pr) = Qtell (handles[h]); + R_INT (pr) = Qtell (*h); } static void bi_Qflush (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qflush"); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } - R_INT (pr) = Qflush (handles[h]); + R_INT (pr) = Qflush (*h); } static void bi_Qeof (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qeof"); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } - R_INT (pr) = Qeof (handles[h]); + R_INT (pr) = Qeof (*h); } static void bi_Qfilesize (progs_t *pr) { - int h = P_INT (pr, 0) - 1; + int handle = P_INT (pr, 0); + QFile **h = get_qfile (pr, handle, "Qfilesize"); - if (h < 0 || h >= MAX_HANDLES || !handles[h]) { - R_INT (pr) = -1; - return; - } - R_INT (pr) = Qfilesize (handles[h]); + R_INT (pr) = Qfilesize (*h); } void QFile_Progs_Init (progs_t *pr, int secure) { + qfile_resources_t *res = calloc (sizeof (qfile_resources_t), 1); + + PR_Resources_Register (pr, "Qfile", res, bi_qfile_clear); if (secure) { PR_AddBuiltin (pr, "Qrename", secured, -1); PR_AddBuiltin (pr, "Qremove", secured, -1); diff --git a/libs/gamecode/builtins/bi_qfs.c b/libs/gamecode/builtins/bi_qfs.c new file mode 100644 index 000000000..97b86193d --- /dev/null +++ b/libs/gamecode/builtins/bi_qfs.c @@ -0,0 +1,140 @@ +/* + bi_file.c + + CSQC file builtins + + Copyright (C) 1996-1997 Id Software, Inc. + + 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__ ((unused)) const char rcsid[] = + "$Id$"; + +#include +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#ifdef HAVE_FNMATCH_H +# define model_t sunmodel_t +# include +# undef model_t +#else +# ifdef WIN32 +# include "fnmatch.h" +# endif +#endif + +#ifndef HAVE_FNMATCH_PROTO +int fnmatch (const char *__pattern, const char *__string, int __flags); +#endif + +#include "QF/csqc.h" +#include "QF/progs.h" +#include "QF/quakefs.h" +#include "QF/va.h" +#include "QF/zone.h" + +static void +check_buffer (progs_t *pr, pr_type_t *buf, int count, const char *name) +{ + int len; + + len = (count + sizeof (pr_type_t) - 1) / sizeof (pr_type_t); + if (buf < pr->pr_globals || buf + len > pr->pr_globals + pr->globals_size) + PR_RunError (pr, "%s: bad buffer", name); +} + + +static void +bi_QFS_Rename (progs_t *pr) +{ + const char *old = P_STRING (pr, 0); + const char *new = P_STRING (pr, 1); + + R_INT (pr) = QFS_Rename (old, new); +} + +static void +bi_QFS_LoadFile (progs_t *pr) +{ + const char *filename = P_STRING (pr, 0); + QFile *file; + int size; + void *buffer; + + QFS_FOpenFile (filename, &file); + if (!file) { + RETURN_POINTER (pr, 0); + return; + } + size = Qfilesize (file); + buffer = PR_Zone_Malloc (pr, (size + 3) & ~3); + if (!buffer) { + Qclose (file); + RETURN_POINTER (pr, 0); + return; + } + Qread (file, buffer, size); + Qclose (file); + RETURN_POINTER (pr, buffer); +} + +static void +bi_QFS_OpenFile (progs_t *pr) +{ + qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); + QFile **file = QFile_AllocHandle (pr, res); + const char *filename = P_STRING (pr, 0); + + QFS_FOpenFile (filename, file); + if (!*file) { + RETURN_POINTER (pr, 0); + return; + } + R_INT (pr) = (file - res->handles) + 1; +} + +static void +bi_QFS_WriteFile (progs_t *pr) +{ + const char *filename = P_STRING (pr, 0); + pr_type_t *buf = P_POINTER (pr, 1); + int count = P_INT (pr, 2); + + check_buffer (pr, buf, count, "QFS_WriteFile"); + QFS_WriteFile (filename, buf, count); +} + +void +QFS_Progs_Init (progs_t *pr) +{ + PR_AddBuiltin (pr, "QFS_Rename", bi_QFS_Rename, -1); + PR_AddBuiltin (pr, "QFS_LoadFile", bi_QFS_LoadFile, -1); + PR_AddBuiltin (pr, "QFS_OpenFile", bi_QFS_OpenFile, -1); + PR_AddBuiltin (pr, "QFS_WriteFile", bi_QFS_WriteFile, -1); +}