diff --git a/include/rua_internal.h b/include/rua_internal.h index a134a49ad..d7482f530 100644 --- a/include/rua_internal.h +++ b/include/rua_internal.h @@ -54,7 +54,7 @@ void RUA_Script_Init (progs_t *pr, int secure); void RUA_String_Init (struct progs_s *pr, int secure); void RUA_QFile_Init (struct progs_s *pr, int secure); -QFile **QFile_AllocHandle (struct progs_s *pr, qfile_resources_t *res); +int QFile_AllocHandle (struct progs_s *pr, QFile *file); void RUA_QFS_Init (struct progs_s *pr, int secure); diff --git a/libs/ruamoko/rua_cbuf.c b/libs/ruamoko/rua_cbuf.c index 39570412b..dad70f71c 100644 --- a/libs/ruamoko/rua_cbuf.c +++ b/libs/ruamoko/rua_cbuf.c @@ -47,20 +47,13 @@ typedef struct { static cbuf_t * get_cbuf (progs_t *pr, int arg, const char *func) { - pr_type_t *handle; - cbuf_t *cbuf; + cbuf_t *cbuf = 0; if (arg == 0) { cbuf_resources_t *res = PR_Resources_Find (pr, "Cbuf"); cbuf = res->cbuf; } else { - if (arg <= ((pr_type_t *) pr->zone - pr->pr_globals) - || (size_t) arg >= (pr->zone_size / sizeof (pr_type_t))) - PR_RunError (pr, "%s: Invalid cbuf_t", func); - - handle = pr->pr_globals + arg; - - cbuf = *(cbuf_t **)handle; + PR_RunError (pr, "%s: Invalid cbuf_t", func); } if (!cbuf) PR_RunError (pr, "Invalid cbuf_t"); diff --git a/libs/ruamoko/rua_cmd.c b/libs/ruamoko/rua_cmd.c index be8a670ae..22dc43a55 100644 --- a/libs/ruamoko/rua_cmd.c +++ b/libs/ruamoko/rua_cmd.c @@ -159,7 +159,7 @@ static builtin_t builtins[] = { void RUA_Cmd_Init (progs_t *pr, int secure) { - cmd_resources_t *res = malloc (sizeof (cmd_resources_t)); + cmd_resources_t *res = calloc (1, sizeof (cmd_resources_t)); res->cmds = 0; PR_Resources_Register (pr, "Cmd", res, bi_cmd_clear); diff --git a/libs/ruamoko/rua_file.c b/libs/ruamoko/rua_file.c index 92322a6a9..f5b1af255 100644 --- a/libs/ruamoko/rua_file.c +++ b/libs/ruamoko/rua_file.c @@ -118,8 +118,7 @@ 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); + QFile *file; const char *pth = P_GSTRING (pr, 0); const char *mode = P_GSTRING (pr, 1); char *path; @@ -163,12 +162,13 @@ bi_File_Open (progs_t *pr) if (do_write && !file_writeable (path)) goto error; - *file = QFS_Open (va ("%s/%s", qfs_gamedir->dir.def, path), mode); - if (!*file) + file = QFS_Open (va ("%s/%s", qfs_gamedir->dir.def, path), mode); + if (!file) goto error; - R_INT (pr) = (file - res->handles) + 1; free (path); - return; + if ((R_INT (pr) = QFile_AllocHandle (pr, file))) + return; + Qclose (file); error: free (path); R_INT (pr) = 0; diff --git a/libs/ruamoko/rua_hash.c b/libs/ruamoko/rua_hash.c index 1f67085e6..21b65df30 100644 --- a/libs/ruamoko/rua_hash.c +++ b/libs/ruamoko/rua_hash.c @@ -60,9 +60,40 @@ typedef struct bi_hashtab_s { } bi_hashtab_t; typedef struct { + PR_RESMAP (bi_hashtab_t) table_map; bi_hashtab_t *tabs; } hash_resources_t; +static bi_hashtab_t * +table_new (hash_resources_t *res) +{ + PR_RESNEW (bi_hashtab_t, res->table_map); +} + +static void +table_free (hash_resources_t *res, bi_hashtab_t *table) +{ + PR_RESFREE (bi_hashtab_t, res->table_map, table); +} + +static void +table_reset (hash_resources_t *res) +{ + PR_RESRESET (bi_hashtab_t, res->table_map); +} + +static inline bi_hashtab_t * +table_get (hash_resources_t *res, int index) +{ + PR_RESGET(res->table_map, index); +} + +static inline int +table_index (hash_resources_t *res, bi_hashtab_t *table) +{ + PR_RESINDEX(res->table_map, table); +} + static const char * bi_get_key (void *key, void *_ht) { @@ -112,7 +143,7 @@ bi_Hash_NewTable (progs_t *pr) void (*f)(void*,void*); bi_hashtab_t *ht; - ht = PR_Zone_Malloc (pr, sizeof (bi_hashtab_t)); + ht = table_new (res); ht->pr = pr; ht->gk = P_FUNCTION (pr, 1); ht->f = P_FUNCTION (pr, 2); @@ -120,19 +151,31 @@ bi_Hash_NewTable (progs_t *pr) ht->next = res->tabs; ht->prev = &res->tabs; - if (ht->next) - ht->next->prev = &ht->next; + if (res->tabs) + res->tabs->prev = &ht->next; + res->tabs = ht; gk = ht->gk ? bi_get_key : 0; f = ht->f ? bi_free : 0; ht->tab = Hash_NewTable (tsize, gk, f, ht); - RETURN_POINTER (pr, ht); + R_INT (pr) = table_index (res, ht); +} + +static bi_hashtab_t * +get_table (progs_t *pr, const char *name, int index) +{ + hash_resources_t *res = PR_Resources_Find (pr, "Hash"); + bi_hashtab_t *ht = table_get (res, index); + + if (!ht) + PR_RunError (pr, "invalid hash table index passed to %s", name + 3); + return ht; } static void bi_Hash_SetHashCompare (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); unsigned long (*gh)(void*,void*); int (*cmp)(void*,void*,void*); @@ -146,17 +189,18 @@ bi_Hash_SetHashCompare (progs_t *pr) static void bi_Hash_DelTable (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + hash_resources_t *res = PR_Resources_Find (pr, "Hash"); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); Hash_DelTable (ht->tab); *ht->prev = ht->next; - PR_Zone_Free (pr, ht); + table_free (res, ht); } static void bi_Hash_FlushTable (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); Hash_FlushTable (ht->tab); } @@ -164,7 +208,7 @@ bi_Hash_FlushTable (progs_t *pr) static void bi_Hash_Add (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); R_INT (pr) = Hash_Add (ht->tab, (void *) (long) P_INT (pr, 1)); } @@ -172,7 +216,7 @@ bi_Hash_Add (progs_t *pr) static void bi_Hash_AddElement (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); R_INT (pr) = Hash_AddElement (ht->tab, (void *) (long) P_INT (pr, 1)); } @@ -180,7 +224,7 @@ bi_Hash_AddElement (progs_t *pr) static void bi_Hash_Find (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); R_INT (pr) = (long) Hash_Find (ht->tab, P_GSTRING (pr, 1)); } @@ -188,7 +232,7 @@ bi_Hash_Find (progs_t *pr) static void bi_Hash_FindElement (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); R_INT (pr) = (long) Hash_FindElement (ht->tab, (void *) (long) P_INT (pr, 1)); @@ -197,7 +241,7 @@ bi_Hash_FindElement (progs_t *pr) static void bi_Hash_FindList (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); void **list, **l; pr_type_t *pr_list; int count; @@ -206,6 +250,7 @@ bi_Hash_FindList (progs_t *pr) for (count = 1, l = list; *l; l++) count++; pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t)); + // the hash tables stores progs pointers... for (count = 0, l = list; *l; l++) pr_list[count++].integer_var = (long) *l; free (list); @@ -215,7 +260,7 @@ bi_Hash_FindList (progs_t *pr) static void bi_Hash_FindElementList (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); void **list, **l; pr_type_t *pr_list; int count; @@ -224,6 +269,7 @@ bi_Hash_FindElementList (progs_t *pr) for (count = 1, l = list; *l; l++) count++; pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t)); + // the hash tables stores progs pointers... for (count = 0, l = list; *l; l++) pr_list[count++].integer_var = (long) *l; free (list); @@ -233,7 +279,7 @@ bi_Hash_FindElementList (progs_t *pr) static void bi_Hash_Del (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); R_INT (pr) = (long) Hash_Del (ht->tab, P_GSTRING (pr, 1)); } @@ -241,7 +287,7 @@ bi_Hash_Del (progs_t *pr) static void bi_Hash_DelElement (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); R_INT (pr) = (long) Hash_DelElement (ht->tab, (void *) (long) P_INT (pr, 1)); @@ -250,7 +296,7 @@ bi_Hash_DelElement (progs_t *pr) static void bi_Hash_Free (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); Hash_Free (ht->tab, (void *) (long) P_INT (pr, 1)); } @@ -270,7 +316,7 @@ bi_Hash_Buffer (progs_t *pr) static void bi_Hash_GetList (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); void **list, **l; pr_type_t *pr_list; int count; @@ -279,6 +325,7 @@ bi_Hash_GetList (progs_t *pr) for (count = 1, l = list; *l; l++) count++; pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t)); + // the hash tables stores progs pointers... for (count = 0, l = list; *l; l++) pr_list[count++].integer_var = (long) *l; free (list); @@ -288,7 +335,7 @@ bi_Hash_GetList (progs_t *pr) static void bi_Hash_Stats (progs_t *pr) { - bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0); + bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0)); Hash_Stats (ht->tab); } @@ -302,6 +349,7 @@ bi_hash_clear (progs_t *pr, void *data) for (ht = res->tabs; ht; ht = ht->next) Hash_DelTable (ht->tab); res->tabs = 0; + table_reset (res); } static builtin_t builtins[] = { @@ -328,7 +376,7 @@ static builtin_t builtins[] = { void RUA_Hash_Init (progs_t *pr, int secure) { - hash_resources_t *res = malloc (sizeof (hash_resources_t)); + hash_resources_t *res = calloc (1, sizeof (hash_resources_t)); res->tabs = 0; PR_Resources_Register (pr, "Hash", res, bi_hash_clear); diff --git a/libs/ruamoko/rua_qfile.c b/libs/ruamoko/rua_qfile.c index 646c7f9a3..6512784b8 100644 --- a/libs/ruamoko/rua_qfile.c +++ b/libs/ruamoko/rua_qfile.c @@ -46,32 +46,82 @@ static __attribute__ ((unused)) const char rcsid[] = #include "rua_internal.h" +typedef struct qfile_s { + struct qfile_s *next; + struct qfile_s **prev; + QFile *file; +} qfile_t; + +typedef struct { + PR_RESMAP (qfile_t) handle_map; + qfile_t *handles; +} qfile_resources_t; + +static qfile_t * +handle_new (qfile_resources_t *res) +{ + PR_RESNEW (qfile_t, res->handle_map); +} + +static void +handle_free (qfile_resources_t *res, qfile_t *handle) +{ + PR_RESFREE (qfile_t, res->handle_map, handle); +} + +static void +handle_reset (qfile_resources_t *res) +{ + PR_RESRESET (qfile_t, res->handle_map); +} + +static inline qfile_t * +handle_get (qfile_resources_t *res, int index) +{ + PR_RESGET(res->handle_map, index); +} + +static inline int +handle_index (qfile_resources_t *res, qfile_t *handle) +{ + PR_RESINDEX(res->handle_map, handle); +} + 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; - } + qfile_t *handle; + + for (handle = res->handles; handle; handle = handle->next) + Qclose (handle->file); + res->handles = 0; + handle_reset (res); } -QFile ** -QFile_AllocHandle (struct progs_s *pr, qfile_resources_t *res) +static int +alloc_handle (qfile_resources_t *res, QFile *file) { - int h; + qfile_t *handle = handle_new (res); - for (h = 0; h < QFILE_MAX_HANDLES && res->handles[h]; h++) - ; - if (h == QFILE_MAX_HANDLES) - goto error; - res->handles[h] = (QFile *) 1; - return res->handles + h; -error: - return 0; + if (!handle) + return 0; + + handle->next = res->handles; + handle->prev = &res->handles; + if (res->handles) + res->handles->prev = &handle->next; + res->handles = handle; + handle->file = file; + return handle_index (res, handle); +} + +int +QFile_AllocHandle (progs_t *pr, QFile *file) +{ + qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); + + return alloc_handle (res, file); } static void @@ -103,44 +153,48 @@ bi_Qopen (progs_t *pr) qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); const char *path = P_GSTRING (pr, 0); const char *mode = P_GSTRING (pr, 1); - QFile **h = QFile_AllocHandle (pr, res); + QFile *file; - if (!h) { - R_INT (pr) = 0; + R_INT (pr) = 0; + if (!(file = Qopen (path, mode))) return; - } - *h = Qopen (path, mode); - R_INT (pr) = (h - res->handles) + 1; + if (!(R_INT (pr) = alloc_handle (res, file))) + Qclose (file); } -static QFile ** -get_qfile (progs_t *pr, int handle, const char *func) +static qfile_t * +get_handle (progs_t *pr, const char *name, int handle) { qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); + qfile_t *h = handle_get (res, handle); - if (handle < 1 || handle > QFILE_MAX_HANDLES || !res->handles[handle - 1]) - PR_RunError (pr, "%s: Invalid QFile", func); - return res->handles + handle - 1; + if (!h) + PR_RunError (pr, "invalid file handle passed to %s", name + 3); + return h; } static void bi_Qclose (progs_t *pr) { + qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qclose"); + qfile_t *h = handle_get (res, handle); - Qclose (*h); - *h = 0; + if (!h) + PR_RunError (pr, "invalid file handle pass to Qclose"); + Qclose (h->file); + *h->prev = h->next; + handle_free (res, h); } static void bi_Qgetline (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qgetline"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); const char *s; - s = Qgetline (*h); + s = Qgetline (h->file); if (s) RETURN_STRING (pr, s); else @@ -161,112 +215,112 @@ static void bi_Qread (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qread"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); pr_type_t *buf = P_GPOINTER (pr, 1); int count = P_INT (pr, 2); check_buffer (pr, buf, count, "Qread"); - R_INT (pr) = Qread (*h, buf, count); + R_INT (pr) = Qread (h->file, buf, count); } static void bi_Qwrite (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qwrite"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); pr_type_t *buf = P_GPOINTER (pr, 1); int count = P_INT (pr, 2); check_buffer (pr, buf, count, "Qwrite"); - R_INT (pr) = Qwrite (*h, buf, count); + R_INT (pr) = Qwrite (h->file, buf, count); } static void bi_Qputs (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qputs"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); const char *str = P_GSTRING (pr, 1); - R_INT (pr) = Qputs (*h, str); + R_INT (pr) = Qputs (h->file, str); } #if 0 static void bi_Qgets (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qgets"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); pr_type_t *buf = P_GPOINTER (pr, 1); int count = P_INT (pr, 2); check_buffer (pr, buf, count, "Qgets"); - R_INT (pr) = POINTER_TO_PROG (pr, Qgets (*h, (char *) buf, count)); + RETURN_POINTER (pr, Qgets (h->file, (char *) buf, count)); } #endif static void bi_Qgetc (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qgetc"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); - R_INT (pr) = Qgetc (*h); + R_INT (pr) = Qgetc (h->file); } static void bi_Qputc (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qputc"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); int c = P_INT (pr, 1); - R_INT (pr) = Qputc (*h, c); + R_INT (pr) = Qputc (h->file, c); } static void bi_Qseek (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qseek"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); int offset = P_INT (pr, 1); int whence = P_INT (pr, 2); - R_INT (pr) = Qseek (*h, offset, whence); + R_INT (pr) = Qseek (h->file, offset, whence); } static void bi_Qtell (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qtell"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); - R_INT (pr) = Qtell (*h); + R_INT (pr) = Qtell (h->file); } static void bi_Qflush (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qflush"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); - R_INT (pr) = Qflush (*h); + R_INT (pr) = Qflush (h->file); } static void bi_Qeof (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qeof"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); - R_INT (pr) = Qeof (*h); + R_INT (pr) = Qeof (h->file); } static void bi_Qfilesize (progs_t *pr) { int handle = P_INT (pr, 0); - QFile **h = get_qfile (pr, handle, "Qfilesize"); + qfile_t *h = get_handle (pr, __FUNCTION__, handle); - R_INT (pr) = Qfilesize (*h); + R_INT (pr) = Qfilesize (h->file); } static builtin_t secure_builtins[] = { diff --git a/libs/ruamoko/rua_qfs.c b/libs/ruamoko/rua_qfs.c index 681536552..c30b86ea7 100644 --- a/libs/ruamoko/rua_qfs.c +++ b/libs/ruamoko/rua_qfs.c @@ -99,16 +99,16 @@ bi_QFS_LoadFile (progs_t *pr) static void bi_QFS_OpenFile (progs_t *pr) { - qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); - QFile **file = QFile_AllocHandle (pr, res); + QFile *file; const char *filename = P_GSTRING (pr, 0); - QFS_FOpenFile (filename, file); - if (!*file) { - RETURN_POINTER (pr, 0); + QFS_FOpenFile (filename, &file); + if (!file) { + R_INT (pr) = 0; return; } - R_INT (pr) = (file - res->handles) + 1; + if (!(R_INT (pr) = QFile_AllocHandle (pr, file))) + Qclose (file); } static void @@ -136,9 +136,9 @@ bi_QFS_Filelist (progs_t *pr) list = PR_Zone_Malloc (pr, sizeof (list) + filelist->count * 4); list->count = filelist->count; strings = (string_t *) list + 1; - list->list = POINTER_TO_PROG (pr, strings); + list->list = PR_SetPointer (pr, strings); for (i = 0; i < filelist->count; i++) - strings[i] = PR_SetString (pr, filelist->list[i]); + strings[i] = PR_SetTempString (pr, filelist->list[i]); RETURN_POINTER (pr, list); }