tinymush-3.1p2/game/backups/
tinymush-3.1p2/game/bin/
tinymush-3.1p2/game/data/
tinymush-3.1p2/game/modules/
tinymush-3.1p2/game/modules/old/
tinymush-3.1p2/src/modules/comsys/
tinymush-3.1p2/src/modules/hello/
tinymush-3.1p2/src/modules/mail/
tinymush-3.1p2/src/tools/
/* mkindx.c - make help/news file indexes */
/* $Id: mkindx.c,v 1.10 2000/11/25 21:40:52 merlin Exp $ */
/*
*  mkindx now supports multiple tags for a single entry.
*  example:
*
*		& foo
*		& bar
*		This is foo and bar.
*		& baz
*		This is baz.
*	
*/
#include "copyright.h"
#include "autoconf.h"

#include  "help.h"

char line[LINE_SIZE + 1];

typedef struct _help_indx_list {
	help_indx               entry;
	struct _help_indx_list  *next;
} help_indx_list;

int dump_entries(FILE *wfp, long pos, help_indx_list *entries);

int main(argc, argv)
int argc;
char *argv[];
{
	long pos;
	int i, n, lineno, ntopics, actualdata;
	char *s, *topic;
	help_indx_list *entries, *ep;
	FILE *rfp, *wfp;

	if (argc < 2 || argc > 3) {
		printf("Usage:\tmkindx <file_to_be_indexed> <output_index_filename>\n");
		exit(-1);
	}
	if ((rfp = fopen(argv[1], "r")) == NULL) {
		fprintf(stderr, "can't open %s for reading\n", argv[1]);
		exit(-1);
	}
	if ((wfp = fopen(argv[2], "w")) == NULL) {
		fprintf(stderr, "can't open %s for writing\n", argv[2]);
		exit(-1);
	}

	pos = 0L;
	lineno = 0;
	ntopics = 0;
	actualdata = 0;

	/* create initial entry storage */
	entries = (help_indx_list *)malloc(sizeof(help_indx_list));
	memset(entries, 0, sizeof(help_indx_list));

	while (fgets(line, LINE_SIZE, rfp) != NULL) {
		++lineno;

		n = strlen(line);
		if (line[n - 1] != '\n') {
			fprintf(stderr, "line %d: line too long\n", lineno);
		}
		if (line[0] == '&') {
			++ntopics;

			if ( (ntopics > 1) && actualdata ) {
				/*
				*  we've hit the next topic, time to write the ones we've been
				*  building
				*/
				actualdata = 0;
				if (dump_entries(wfp, pos, entries)) {
					fprintf(stderr, "error writing %s\n", argv[2]);
					exit(-1);
				}
				memset(entries, 0, sizeof(help_indx_list));
			}

			if (entries->entry.pos) {
				/*
				*  we're already working on an entry... time to start nesting
				*/
				ep = entries;
				entries = (help_indx_list *)malloc(sizeof(help_indx_list));
				memset(entries, 0, sizeof(help_indx_list));
				entries->next = ep;
			}

			for (topic = &line[1];
			     (*topic == ' ' || *topic == '\t') && *topic != '\0';
			     topic++) ;
			for (i = -1, s = topic; *s != '\n' && *s != '\0'; s++) {
				if (i >= TOPIC_NAME_LEN - 1)
					break;
				if (*s != ' ' || entries->entry.topic[i] != ' ')
					entries->entry.topic[++i] = *s;
			}
			entries->entry.topic[++i] = '\0';
			entries->entry.pos = pos + (long)n;
		}
		else if (n > 1) {
			/*
			*  a non blank line.  we can flush entries to the .indx file the next
			*  time we run into a topic line...
			*/
			actualdata = 1;
		}
		pos += n;
	}
	if (dump_entries(wfp, pos, entries)) {
		fprintf(stderr, "error writing %s\n", argv[2]);
		exit(-1);
	}
	fclose(rfp);
	fclose(wfp);

	printf("%d topics indexed\n", ntopics);
	exit(0);
}



int dump_entries(FILE *wfp, long pos, help_indx_list *entries)
{
	int	truepos;
	int	truelen;
	int	depth;
	help_indx_list	*prev_ep, *ep;

	/*
	*  if we have more than one entry, the one on the top of the chain
	*  is going to have the actual pos we want to use to index with
	*/
	truepos = (long)entries->entry.pos;
	truelen = (int)(pos - entries->entry.pos);

	prev_ep = 0;
	depth = 0;

	for (ep = entries; ep; ep = ep->next) {
		ep->entry.pos = (long)truepos;
		ep->entry.len = truelen;
		if (fwrite(&ep->entry, sizeof(help_indx), 1, wfp) < 1)
			return(-1);

		if (prev_ep)
			free(prev_ep);

		if (depth++)	/* don't want to try to free the top of the chain */
			prev_ep = ep;
	}
	/*
	*  no attempt is made to free the last remaining struct as its actually the
	*  one on the top of the chain, ie. the statically allocated struct.
	*/

	return(0);
}