/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 *
 *	@(#)config.h	5.3 (Berkeley) 4/18/86
 */

/*
 * Config.
 */

#ident	"$Header: config.h 1.26 90/04/27 $"

#include "param.h"
#include <sys/types.h>
#include <sys/errno.h>
#include <fatal.h>
#include <string.h>

/*
 *  Debug masks and levels.
 *  The range of allowed levels is [0..31].
 */
#define	DEBUG_LEVEL(n)	((Debug_mask) & (1L << (n)) )

/*
 *  Boolean definitions.
 */
#define	FALSE	0
#define	TRUE	1
typedef	char	boolean;

/*
 *  Minimum number of files required before another lint group is to
 *  be formed.
 */
#define	LINT_GROUP_SIZE	50

/*
 * A simple singly linked list.
 * Used to accumulate lists of text.
 */
struct list {
	struct list *l_next;		/* next element in list */
	char l_text[sizeof(long)];	/* arbitrary sized string text */
};

/*
 * List head for a linked list of list elements.
 */
struct list_head {
	struct list *l_head;		/* first element in list */
	struct list *l_last;		/* last element in list */
};

/*
 * list of lists
 */
struct llist {
	struct list_head ll_list;
	struct llist	*ll_next;
	char		*ll_name;
};

/*
 * list of name pairs used in macro substitution.
 */
struct macro {
	struct	macro	*macro_next;
	char		*macro_name;
	char		*macro_value;
};

/*
 * Max length of a device name and prefix.
 */
#define	MAX_DEVNAMELEN	31
/*
 * This is the per device configured structure
 * They are initialy allocated from the xxx/config files.
 */
#define QUES	-1	/* -1 means '?' */
#define	UNKNOWN -2	/* -2 means not set yet */
#define	T_BLOCK		0x01	/* block device */
#define	T_CHAR		0x02	/* raw device */
#define	T_STREAMM	0x04	/* stream module */
#define	T_STREAMD	0x08	/* stream driver */
#define	T_BUS		0x10	/* bus type */
#define	T_PSEUDO	0x20	/* pseudo device */
#define	T_FS		0x40	/* file system type */
#define	T_BUSD		0x80	/* bus driver module*/

struct device {
	int	d_type;			/* T_BLOCK
					   T_CHAR
					   T_STREAMM
					   T_STREAMD
					   T_PSEUDO
					   T_BUS
					*/
	struct  device **d_on_bus;	/* list off buses */
	struct  device **d_bus;		/* list off buses */
	struct	device *d_bus_own;	/* owner device of this bus */
	struct	connect *d_conn;	/* what it is connected to */
	char		d_name[MAX_DEVNAMELEN+1];
					/* name of device (e.g. rk11) */
	char		d_prefix[MAX_DEVNAMELEN+1];
					/* prefix of device (e.g. rk11) */
	char		d_uprefix[MAX_DEVNAMELEN+1];
					/* prefix of device in upper case */
	struct list_head d_aliases;	/* alias names for streams module */
	int		d_busno;	/* bus number */
	int		d_maxunit;	/* maximum unit number */
	int		d_minunit;	/* minimum unit number */
	long		d_entry;	/* device driver entry point set */
					/* (see L_??? defns in devcon.c) */
	int		d_block;	/* block major */
	int		d_character;	/* character major */
	int		d_flags;	/* nlags for device init */
	int		d_numdev;	/* number of devices */
	int		d_segalign;
	int		d_segsize;
	int		d_nsegs;
	struct	device *d_next;		/* Next one in list */
};

/*
 * Formed from construct   d v on t v unit u
 * in system_file.
 * For echo device type there is a struct connect
 * headed by ctab and linked via c_next. Whithin each of these
 * any multiple connection for the same device are linked via
 * c_next_d.
 * For each "bus" there is also a struct connect headed by cbtab
 * and linked via c_busses.
 * Within each of these, devices that are connected to it are
 * found via c_on.
 */
struct	connect {
	struct	connect	*c_next;	/* list of connects (by driver)*/
	struct	connect	*c_busses;	/* list of autoconfig busses */

	char		*c_d_name;	/* name of device */
	int		c_d_val;	/* which one */
	struct	device	*c_ddev;
	char		*c_t_name;	/* name of bus */
	int		c_t_val;	/* which one */
	struct	device	*c_tdev;
	int		c_unit;		/* which unit this is */
	struct	connect	*c_on;		/* connected to bus */

	int		c_numdev;	/* number of devices */
	struct	connect	*c_next_d;	/* list of devices or busses */
	struct	connect	*c_tail_d;	/* end of list of devices */
	int		c_segalign;
	int		c_segsize;
	int		c_nsegs;
	int		c_busnum;	/* configured busses index */
};

/*
 *  Define information common to both a primary module structure
 *  (i.e. struct pmodule), and a sub-module structure (i.e.
 *  struct smodule).
 */
struct cmodule {			/* common module */
	char		*cmod_relpath;	/* relative path name of module */
	char		*cmod_name;	/* module name */
	struct	macro	*cmod_subo;	/* sub option list for module */
};

/*
 *  A primary module is allocated for each possible
 *  sub-module (e.g. symmetry/modules).
 *  The current module is always:  Pmodp.
 */
struct pmodule {
	boolean	pmod_configured;	/* set if module configured */
	boolean pmod_parsing;		/* true if parsing flag */
	boolean pmod_parsed;		/* true if parsed flag */
	boolean	pmod_internalmod;	/* set if module internal to pmodule */
	struct	pmodule *pmod_prev;	/* prev primary module */
	struct	pmodule *pmod_next;	/* next primary module */
	struct	smodule	*pmod_fsubm;	/* first sub-module for module */
	struct	smodule *pmod_lsubm;	/* last sub-module for module */
	void	*pmod_product;		/* product containing this module */
	struct	cmodule pmod_common;	/* relative path, name, and sub-opts */
};

/*
 *  When the module is configured, a source module (sub-module) is
 *  allocated for each listed module source file (e.g. "xxx.c" and
 *  "xxx.s" files, but no "xxx.h" files).
 *
 *  When the module is not configured (deconfigured), a stubs module
 *  (sub-module) is allocated for each listed stubs file (e.g.
 *  "xxx_stubs.c").
 *
 *  A pointer to the "smod_common" field of the current sub-module
 *  is always maintained in:  Lcmodp.
 */
struct smodule {
	char	smod_type;		/* module type: 'c' 's' */
	struct	smodule	*smod_next;	/* next sub-module */
	struct	cmodule smod_common;	/* relative path, name, and sub-opts */
};

/*
 * The hdc table is used in parsing the config files to accumulate
 * connect information.
 */

static struct	hdc {
	char	*dev_spec;
	int	dev_val;
	char	*type_spec;
	int	type_val;
	int	unit_spec;
	int	nsegs;
	int	segsize;
	int	segalign;
};

/* extern definitions follow */
extern struct	pmodule	*Pmodp;		/* current module information */
extern struct	cmodule	*Lcmodp;	/* current library module info */

extern struct	device 	*dtab;		/* list of all devices */
extern struct	connect *ctab;		/* list of all connects */

extern	char	*arch_type;		/* architecture type (e.g. "sb8000") */

/*
 * for yacc
 */
extern	int	yyline;
extern	void	yyless();

/*
 * Global file specifiers and flags.
 */
extern	long	Debug_mask;	/* diagnostic messages */
extern	int	Lflag;		/* produce file list (on by default) */
extern	int	Visibility;	/* parameter visibility level */
extern	boolean	Dflag;		/* produce dependency information */
extern	boolean	Config;		/* make configuration (on by default) */
extern	boolean	Trouble;	/* trouble (error) flag */
extern	boolean	Warning;	/* warnings issued flag */

extern	char	*machine_type;		/* machine architecture */
extern	char	*configuration_name;	/* configuration (e.g. "std") */

extern	int	Anchor_len;		/* strlen(Anchor_dir) */
extern	char	Anchor_dir[MAXPATH];	/* anchor directory (see SRC_ANCHOR) */
extern	char	Mach_dir[MAXPATH];	/* the machine architecture directory */
extern	char	Build_dir[MAXPATH];	/* build dir: <machine>.<config> */
extern	char	Module_dir[MAXPATH];	/* current module dir being parsed */
extern	char	T_dirl[MAXPATH];	/* current module dir (local form) */
extern	char	T_ddirl[MAXPATH];	/* current destination (local form) */
extern	char	Smk_file[MAXPATH];	/* source system makefile.skel */
extern	char	Mk_file[MAXPATH];	/* destination system makefile */
extern	char	Files_file[MAXPATH];
extern	char	Bfiles_file[MAXPATH];

extern int errno;

extern boolean device_spec;		/* was this a device ? */

extern struct	macro	*Subo;		/* system sub option list */
extern char	*Ffile;			/* current file (see fatal()) */
extern int	Max_bdev;
extern int	Max_cdev;
extern int	Max_cstr;
extern int	Max_bus;
extern int	Max_fs;
extern int	Max_syscall;

struct vers {
	int	version;		/* 100 * version + sub_version */
	int	flags;
};
extern	struct vers	Vers;

extern	char	*sname();
extern 	int	fatal();
extern	void	_fatal();
extern	void	perm_to_tail();
extern	void	print_cat();
extern  char	*ms();
extern	char	*depend();
extern	void	configure_module();
#define fatal	_fatal
#define	SET_FILE(p)	(Ffile = (p))	/* Define current file */
