1stMUD4.0/bin/
1stMUD4.0/doc/MPDocs/
1stMUD4.0/player/
1stMUD4.0/win32/
1stMUD4.0/win32/rom/
/**************************************************************************
*  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
*  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
*                                                                         *
*  Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael         *
*  Chastain, Michael Quan, and Mitchell Tse.                              *
*                                                                         *
*  In order to use any part of this Merc Diku Mud, you must comply with   *
*  both the original Diku license in 'license.doc' as well the Merc       *
*  license in 'license.txt'.  In particular, you may not remove either of *
*  these copyright notices.                                               *
*                                                                         *
*  Much time and thought has gone into this software and you are          *
*  benefiting.  We hope that you share your changes too.  What goes       *
*  around, comes around.                                                  *
***************************************************************************
*       ROM 2.4 is copyright 1993-1998 Russ Taylor                        *
*       ROM has been brought to you by the ROM consortium                 *
*           Russ Taylor (rtaylor@hypercube.org)                           *
*           Gabrielle Taylor (gtaylor@hypercube.org)                      *
*           Brian Moore (zump@rom.org)                                    *
*       By using this code, you have agreed to follow the terms of the    *
*       ROM license, in the file Rom24/doc/rom.license                    *
***************************************************************************
*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
*            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
***************************************************************************/
#if !defined(TABLESAVE_H)
#define TABLESAVE_H

typedef bool RW_FUNC(action_types type, void *temp, const char **arg);
#define RW_FUN(fun)	bool fun(action_types type, void *temp, const char **arg)
#define DECLARE_RW_FUN(fun) RW_FUNC fun

typedef void TABLESAVE(action_types type);
#define TABLESAVE(fun) void fun(action_types type)
#define DECLARE_TABLESAVE(fun)  TABLESAVE fun

struct savetable_type
{
	const char *field;
	int type_field;
	void *puntero_field;
	const void *argument;
	const void *array_arg;
};

#define FIELD_STRING			0
#define FIELD_FUNCTION_INT_TO_STR	1
#define FIELD_LONG_ARRAY        2
#define FIELD_FLAGSTRING		3
#define FIELD_INT			4
#define FIELD_FLAGVECTOR		5
#define FIELD_BOOL			6
#define FIELD_INT_ARRAY		7
#define FIELD_STRING_ARRAY		8
#define FIELD_INT_FLAGSTRING    9
#define FIELD_BOOL_ARRAY		10
#define FIELD_INUTIL			11
#define FIELD_INT_ALLOC_ARRAY   12
#define FIELD_LONG              13
#define FIELD_STRING_ARRAY_NULL 14
#define FIELD_RANK_DATA         15
#define FIELD_LONG_ALLOC_ARRAY  16
#define FIELD_STRING_SIZE       17
#define FIELD_CHAR              18
#define FIELD_INT_FUNCTION      19
#define FIELD_FLOAT             20
#define FIELD_DOUBLE            21
#define FIELD_TIME              22
#define FIELD_INT_FUNC_ARRAY    23
#define FIELD_CHARDATA          24
#define FIELD_SPEC_FUN			25
#define FIELD_MOBINDEX		    26
#define FIELD_RACE			    27
#define FIELD_DEITY		        28
#define FIELD_AREA  			29
#define FIELD_ROOM  			30
#define FIELD_CLAN              31
#define FIELD_OBJ               32
#define FIELD_PCDATA            33
#define FIELD_DESC              34
#define FIELD_SHOP              35
#define FIELD_EXDESC            36
#define FIELD_RESET_DATA        37
#define FIELD_EXIT_DATA         38
#define FIELD_PROG_LIST         39
#define FIELD_OBJINDEX          40
#define FIELD_AFFECT            41
#define FIELD_FUNCTION          42
#define FIELD_DICE              43

#define DATA_LIST       1
#define DATA_NAME       2
#define DATA_STAT       3

PROTOTYPE(void load_struct, (READ_DATA *, void *,
							 const struct savetable_type *, void *));
PROTOTYPE(void save_struct, (FILE *, void *,
							 const struct savetable_type *, void *));

struct data_save_type
{
	TABLESAVE *fun;
	const char *name;
};

EXTERN const struct data_save_type data_save_table[];
EXTERN const struct savetable_type socialsavetable[];
EXTERN const struct savetable_type cmdsavetable[];

DECLARE_TABLESAVE(rw_commands);
DECLARE_TABLESAVE(rw_skills);
DECLARE_TABLESAVE(rw_races);
DECLARE_TABLESAVE(rw_groups);
DECLARE_TABLESAVE(rw_classes);
DECLARE_TABLESAVE(rw_socials);
DECLARE_TABLESAVE(rw_clans);
DECLARE_TABLESAVE(rw_stats);
DECLARE_TABLESAVE(rw_bans);
DECLARE_TABLESAVE(rw_gquest_data);
DECLARE_TABLESAVE(rw_deities);
DECLARE_TABLESAVE(rw_webpasswds);
DECLARE_TABLESAVE(rw_members);
DECLARE_TABLESAVE(rw_war_data);
DECLARE_TABLESAVE(rw_channels);
DECLARE_TABLESAVE(rw_mud_data);
DECLARE_TABLESAVE(rw_music);

DECLARE_RW_FUN(clan_rw);

#define rw_table(action, file, type, iMax, header, typebase, save_table, table) \
do \
{ \
	int i = 0; \
	switch(action) \
	{ \
		case action_read: \
		{ \
			static bool Loaded = FALSE; \
			if(!Loaded) \
			{ \
				READ_DATA *fp; \
				const char *word; \
				static type zero; \
				fp = open_read(file); \
				if (!fp) \
				{ \
					bugf("Unable to open %s for reading.", file); \
					break; \
				} \
                iMax = read_number(fp); \
				alloc_mem(table, type, iMax + 1); \
				if (!table) \
				{ \
					bugf("Error! " #table " == NULL, " #iMax " : %d", iMax); \
					break; \
				} \
				for (;;) \
				{ \
					word = read_word(fp); \
					if (!str_cmp(word, "#!")) \
						break; \
					if (str_cmp(word, "#" header)) \
					{ \
						bugf("word doesn't exist (%s)", word); \
						break; \
					} \
					if (i >= iMax) \
					{ \
						bugf("%d greater than " #iMax " %d", i, iMax); \
						break; \
					} \
					table[i] = zero; \
					load_struct(fp, &typebase, save_table, &table[i++]); \
				} \
				close_read(fp); \
				Loaded = TRUE; \
			} \
		} \
		break; \
		case action_write: \
		{ \
			WRITE_DATA *fp; \
			int i; \
			fp = open_write(file); \
			if (!fp) \
			{ \
				log_error(file); \
				break; \
			} \
			fprintf(fp->stream, "%d\n\n", iMax); \
			for (i = 0; i < iMax; ++i) \
			{ \
				fprintf(fp->stream, "#%s\n", header); \
				save_struct(fp->stream, &typebase, save_table, &table[i]); \
				fprintf(fp->stream, "#END\n\n"); \
			} \
			fprintf(fp->stream, "#!\n"); \
			close_write(fp); \
		}\
		break;\
		default: \
		break; \
	} \
} while(0)

#define rw_list(action, file, type, first, last, next, prev, new_fun, header, typebase, save_table) \
do \
{ \
	switch(action)\
	{\
		case action_read: \
		{ \
			static bool Loaded = FALSE; \
			if(!Loaded) \
			{ \
				READ_DATA *fp; \
				type *data; \
				const char *word; \
				fp = open_read(file); \
				if (!fp) \
				{ \
					bugf("Unable to open %s for reading.", file); \
					break; \
				} \
				for (;;) \
				{ \
					word = read_word(fp); \
					if (!str_cmp(word, "#!")) \
						break; \
					if (str_cmp(word, "#" header)) \
					{ \
						bugf("word doesn't exist (%s)", word); \
						break; \
					} \
					if(new_fun != NULL) \
						data = new_fun(); \
					else \
						alloc_mem(data, type, 1); \
					load_struct(fp, &typebase, save_table, data); \
					if(save_table == socialsavetable) \
						add_social((SOCIAL_DATA *)data); \
					else if(save_table == cmdsavetable) \
						add_command((CMD_DATA *)data); \
					else \
						LINK(data, first, last, next, prev); \
				} \
				close_read(fp); \
				Loaded = TRUE; \
			} \
		} \
		break; \
		case action_write: \
		{ \
			WRITE_DATA *fp; \
			type *data; \
			fp = open_write(file); \
			if (!fp) \
			{ \
				log_error(file); \
				break; \
			} \
			for (data = first; data != NULL; data = data->next) \
			{ \
				fprintf(fp->stream, "#%s\n", header); \
				save_struct(fp->stream, &typebase, save_table, data); \
				fprintf(fp->stream, "#END\n\n"); \
			} \
			fprintf(fp->stream, "#!\n"); \
			close_write(fp); \
		} \
		break; \
		default: \
		break; \
	} \
} while(0)

#define rw_single(action, file, header, typebase, save_table, data) \
do \
{ \
	switch(action) \
	{ \
		case action_read: \
		{ \
			static bool Loaded = FALSE; \
			if(!Loaded) \
			{ \
				READ_DATA *fp; \
				const char *word; \
				fp = open_read(file); \
				if (!fp) \
				{ \
					bugf("Could not open file %s for reading.", file); \
					break; \
				} \
				for (;;) \
				{ \
					word = read_word(fp); \
					if (!str_cmp(word, "#!")) \
						break; \
					if (str_cmp(word, "#" header "")) \
					{ \
						bugf("word doesn't exist (%s)", word); \
						break; \
					} \
					load_struct(fp, &typebase, save_table, &data); \
				} \
				close_read(fp); \
				Loaded = TRUE; \
			} \
		}\
		break; \
		case action_write: \
		{ \
			WRITE_DATA *fp; \
			if (!(fp = open_write(file))) \
			{ \
				log_error(file); \
				break; \
			} \
			fprintf(fp->stream, "#%s\n", header); \
			save_struct(fp->stream, &typebase, save_table, &data); \
			fprintf(fp->stream, "#END\n"); \
			fprintf(fp->stream, "\n#!\n"); \
			close_write(fp); \
		} \
		break; \
		default: \
		break; \
	} \
} while(0)

#endif