V8/usr/src/cmd/monk/cmd/monk/read_user.c

Compare this file to the similar file:
Show the results in this format:

#include	<stdio.h>
#include	<ctype.h>
#include	"search.h"
#include	"warn.h"
#include	"rd.h"

short	database_mode;

struct environment *
read_userfile(filename, database_path, env)
char	*filename, *database_path;
struct environment	*env;
{
	FILE	*userfile;

	/* do i really want to exit on fail, this routine called for
						inserted files */
	if (filename != (char *) 0) {
		if ((userfile = fopenncheck(filename, "r", NO_EXIT))
							== (FILE *) NULL)
			return(env);
	} else
		userfile = stdin;
#ifdef TIMING
	newtime("Start processing userfile %s:\t", filename);
#endif
	if (env == (struct environment *) 0)
		env = read_usertop(userfile, database_path);
	if (env != (struct environment *) 0)
		env = read_usertext(userfile, database_path, env);
	fclosencheck(userfile);
#ifdef TIMING
	newtime("Finished processing userfile %s:\t", filename);
#endif
	return(env);
}

struct environment *
read_usertop(userfile, database_path)
FILE	*userfile;
char	*database_path;
{
	ENTRY	*grabit;
	struct definition	*d;
	struct environment	*env, *newenv;
	int	command;
	int	c, close_delim;
	char	*key, *troff_string;

	if ((c = mygetc(userfile)) == EOF)
		return((struct environment *) 0);
	if (c != BEGIN_PRIMITIVE) {
		myungetc(c, userfile);
		read_databases(NULL, database_path);
		return(init_envir());
	}
	key = read_token(userfile, NO_SPACE);
	if ((command = isacommand(key)) != N_MAKE)
		if (command != N_INSERT) {
			read_databases(NULL, database_path);
			env = init_envir();
		}
	if (key == (char *) EOF || key == (char *) 0) {
		textputc(BEGIN_PRIMITIVE, userfile);
		return(env);
	}
	if ((close_delim = read_userdelim(userfile)) == (char) EOF)
		close_delim = (char) FALSE;
	if (command == NOT_ACOMMAND) {
		newenv = begin_envir(env, key, close_delim, USER_TEXT);
		/* To handle env wo delimiters, eg |paragraph */
		if (newenv != env) {
			env = newenv;
			/* Handle environ wo delimiters, eg |paragraph
					don't look at sub_def */
			if (close_delim != (char) FALSE) {
				if (env->def->sub_def != NULL)
					env = assoc_envir(userfile, env,
							env->def, close_delim,
							END_NOW, USER_TEXT);
			} else
				env = end_envir(env, TOP_LEVEL);
		}
		return(env);
	}
	/* could loop looking for make given a comment.... */
	if (command != N_COMMENT) {
		if (command != N_INSERT)
			key = read_token(userfile, OK_SPACE);
		else
			key = read_filename(userfile, OK_SPACE);
		if ((c = read_nonblank(userfile)) == close_delim)
				close_delim = 0;
		else
			if (c != ITEM_SEP) {
				wrong_delim(key, close_delim, c);
				/* put back any char for health?? */
				if (c == BEGIN_PRIMITIVE)
					myungetc(c, userfile);
			}
	}
	switch(command) {
		case N_INSERT:
			env = read_userfile(key, database_path, NULL);
			if (env == NULL) {
				read_databases(NULL, database_path);
				return(init_envir());
			}
			return(env);
		case N_MAKE:
			read_databases(key, database_path);
			return(begin_envir(init_envir(), DOC_TEXT,
							(char) 0, MONK_DB));
	}
	return(do_envcommands(command, key, database_path, userfile,
							env, close_delim));
}

struct environment *
read_usertext(userfile, database_path, env)
FILE	*userfile;
char	*database_path;
struct environment	*env;
{
	ENTRY	*grabit;
	struct definition	*d;
	struct environment	*newenv;
	int	command;
	int	c, close_delim;
	char	lastchar_in;
	char	*key;

	if ((c = mygetc(userfile)) != NEW_LINE)
		myungetc(c, userfile);
	while ((c = mygetc(userfile)) != EOF) {
		if (lastchar_in == '\\') {
			/* '\' special character only relative to '|' */
			if ((lastchar_in = c) != BEGIN_PRIMITIVE)
				textputc('\\', USER_TEXT);
			if ( c != '\\')
				textputc(c, USER_TEXT);
			continue;
		}
		if (c == '\\') {
			lastchar_in = c;
			continue;
		}
		if (c != BEGIN_PRIMITIVE) {
			if ( env->how_to_end != (char) 0 &&
					(char) c == env->how_to_end ) {
				env = end_envir(env, TOP_LEVEL);
				nl_nlgobble(lastchar_in, userfile);
			} else {
				textputc(c, USER_TEXT);
				lastchar_in = c;
			}
			continue;
		}
		if ((key = read_token(userfile, NO_SPACE)) == (char *) EOF)
			break;
		if (key == (char *) 0) {
			textputc(BEGIN_PRIMITIVE, USER_TEXT);
			lastchar_in = BEGIN_PRIMITIVE;
			continue;
		}
		/* gobbles white space looking for open_delimiter, returns
					matching close_delimiter */
		if ((close_delim = read_userdelim(userfile)) == EOF)
			close_delim = (char) FALSE;
		if ((command = isacommand(key)) == NOT_ACOMMAND) {
			/* short form of environment invocation */
			newenv = begin_envir(env, key, close_delim, USER_TEXT);
			if (newenv != env) {
				env = newenv;
				/* Handle environ wo delimiters, eg |paragraph
					don't look at sub_def */
				if (close_delim != (char) FALSE) {
					if (env->def->sub_def != NULL)
						env = assoc_envir(userfile,
							env, env->def,
							close_delim,
							END_NOW, USER_TEXT);
				} else
					env = end_envir(env, TOP_LEVEL);
			}
			nl_nlgobble(lastchar_in, userfile);
			continue;
		}
		if (command != N_COMMENT) {
			if (command != N_INSERT)
				key = read_token(userfile, OK_SPACE);
			else
				key = read_filename(userfile, OK_SPACE);
			if ((c = read_nonblank(userfile)) == close_delim)
				close_delim = 0;
			else
				if (c != ITEM_SEP) {
					wrong_delim(key, close_delim, c);
					/* put back any char for health?? */
					if (c == BEGIN_PRIMITIVE)
						myungetc(c, userfile);
				}
		}	
		env = do_envcommands(command, key, database_path, userfile,
							env, close_delim);
		nl_nlgobble(lastchar_in, userfile);
	}
	return(env);
}

void
nl_nlgobble(lastchar_in, userfile)
char	lastchar_in;
FILE	*userfile;
{
	int	c;

	if (lastchar_in == NEW_LINE)
		if ((c = mygetc(userfile)) != EOF && (char) c != NEW_LINE)
			myungetc(c, userfile);
}

read_databases(doctype, database_path)
char	*doctype, *database_path;
{
	char	*temp = NULL;

	init_dbread();
#ifdef TIMING
	newtime("Starting to read databases:");
#endif
	if (database_mode == COMPRESSED) {
		if (doctype == NULL)
			read_dbfile(DB_COMPRESSED, database_path, COMPRESSED);
		else {
			temp = strconcat(doctype, DB_COMP_EXT);
			read_dbfile(temp, database_path, COMPRESSED);
		}
#ifdef TIMING
		newtime("Finished reading compressed database:");
#endif
	} else {
		read_dbfile(DB_ATTRIBUTES, database_path, STANDARD);
#ifdef TIMING
		newtime("Finished reading attribute database:");
#endif
		read_dbfile(DB_DEFINITIONS, database_path, STANDARD);
#ifdef TIMING
		newtime("Finished reading definition database:");
#endif
		read_dbfile(DB_MACROS, database_path, STANDARD);
#ifdef TIMING
		newtime("Finished reading macro database:");
#endif
		if (doctype != NULL) {
			temp = strconcat(doctype, DB_DOC_EXT);
			read_dbfile(temp, database_path, STANDARD);
#ifdef TIMING
			newtime("Finished reading document %s database:",
								doctype);
#endif
		}
	}
	if (temp != (char *) 0)
		myfree(temp, 12);
}

read_dbfile(datafilename, database_path, mode)
char	*datafilename, *database_path;
int	mode;
{
	FILE	*database;

	database = fopendb(datafilename, database_path, "r", EXIT_ON_FAIL);
	if (mode == STANDARD)
		read_entries(database, database_path);
	else if (mode == COMPRESSED)
		/* read buffers: reads compressed file and macro file */
		read_buffers(database, database_path);
	fclosencheck(database);
}

struct environment	*
do_envcommands(command, name, database_path, file, env, close_delim)
int	command;
char	*name, *database_path;
FILE	*file;
struct environment	*env;
int	close_delim;
{
	struct definition	*def;
	char	c;

							/* textwrite? */
	switch(command) {
		case N_BEGIN:
			def = get_envir(name, close_delim, USER_TEXT);
			if (def == (struct definition *) 0)
				break;
			if (def->sub_def != (struct definition *) 0
					&& close_delim != 0) {
				env = assoc_envir(file, env, def,
					close_delim, END_AT_END, USER_TEXT);
				if ((c = read_nonblank(file)) !=  close_delim) {
					wrong_delim(name, close_delim, c);
					myungetc(c, file);
				}
			}
			env = do_envir(env, def, TOP_LEVEL, (char)0, USER_TEXT);
			break;
		case N_END:
			/* if key doesn't match next expected ??? */
			if (env->how_to_end != (char) 0
					|| strcmp(name, env->def->name) != 0) {
				if (*env->def->name == COLON)
					warn_user(PR_FILENAME | PR_LINENUMBER,
					"Unexpected end for %s\n", name);
				else {
					warn_user(PR_FILENAME | PR_LINENUMBER,
					"Expecting end for %s begun at line %d",
					env->def->name, env->linenumber);
					warn_user(0,"; got end for %s\n", name);
				}
#ifdef HEALTH
				env_health(env, name);
#endif
			} else
				env = end_envir(env, TOP_LEVEL);
			break;
		case N_INSERT:
			env = read_userfile(name, database_path, env);
			break;
		case N_MAKE:
			make_doc(name, database_path);
			env = begin_envir(env, DOC_TEXT, (char)0, MONK_DB);
			break;
		default:
			do_commands(command, name, database_path, file,
								close_delim);	
	}
	return(env);
}

struct environment *
make_doc(doctype, database_path)
char	*doctype, *database_path;
{
	char	*temp;

	temp = strconcat(doctype, DB_DOC_EXT);
	read_dbfile(temp, database_path, STANDARD);
#ifdef TIMING
	newtime("Finished reading document %s database:", doctype);
#endif
}