/* Copyright (C) 1993,1994 by the author(s).
 
 This software is published in the hope that it will be useful, but
 WITHOUT ANY WARRANTY for any part of this software to work correctly
 or as described in the manuals. See the ShapeTools Public License
 for details.

 Permission is granted to use, copy, modify, or distribute any part of
 this software but only under the conditions described in the ShapeTools 
 Public License. A copy of this license is supposed to have been given
 to you along with ShapeTools in a file named LICENSE. Among other
 things, this copyright notice and the Public License must be
 preserved on all copies.
*/
/*
 * ShapeTools/shape program - shape.h
 *
 * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de)
 *
 * $Header: shape.h[8.0] Tue May 24 15:21:21 1994 axel@cs.tu-berlin.de frozen $
 */

typedef int Bool;

#define TEST_ONLY 0
#define BIND_IT 1
#define ALL 0
#define SOURCE 1
#define BINARY 2
#define NONE 3

#define NIL ((char *) 0)
#define MYMAXNAMLEN 256

/* Restore Types */

#define REGULAR 0
#define VPATH 1
#define EXTERNAL 2

#include "atfs.h"
#include "atfstk.h"
#include "sttk.h"

#include "strbuf.h"

struct linked_list {
  char *string;
  struct linked_list *nextstring;
};


struct list
{
  int (*selfunc)();
  char *parn;
  char *parv;
  int i;
  struct list *cont;
};

struct cmds
{
  char *command;
  struct cmds *nextcmd;
};

#define ATTRNAME "__DerivationKey__"
#define DRV_TIME "__DTime__"

#define MAXDEPTH 64

#define MAXPATHLIST 256
#define MAXVPATH 16

#define MAXTARGS 128
#define MAXHERIT 32
#define MAXDEPS 256
#define MAXCMDS 32

struct rules
{
  char *name;
  struct rules *next;
  Af_set date;
  int done;
  Bool doublecolon;
  Bool saved;
  char *firstdep;                 /* possibly selection rule name */
  char *deplist;
  char *_deplist_buffer;
  char *heritage[MAXHERIT];
  char *targetlist[MAXHERIT];
  struct cmds *cmdlist;
  struct rules *nextrule;
};

typedef struct { 
  Bool bk_isdefined;
  Af_key bk_key;
} BKey;

typedef struct {
  int dependent_queue_initialized;
  Af_key *dependent_queue, *head, *tail;
  char keybuffer[AT_MAXATTRSIZE];
  int queued_dependents, current_max_dependents;
  int queue_changed;
} DepQ;

#define suffix(s) (strrchr (s, '.') ? strrchr (s, '.') : "")

#define STD_ATTRS 10

struct linkreg {
  char *fn;
  char *newfn;
  Bool busy_exist;
  struct linkreg *next;
};

#define MAXVARIANTS 32
#define MAXVMACROS 32 
#define MAXVCLASS 64
#define MAXVARDEFS 64
#define MAXCMDLINEVARS 32
#define MAXACTVAR 32

struct vardef {
  char *name;
  char *vmacros[MAXVMACROS];
  char *vflags;
  char *vpath;
};

struct varclass {
  char *name;
  int active;
  char *variants[MAXVARIANTS];
};

struct stringlist {		/* generic list of strings */
    char *string ;
    int freeable ;		/* if non-zero, string can be freed */
    struct stringlist *next ;
} ;

#define MAXPREDS 256

/*
 * Module interface section (Prototypes)
 */

/* error.c */
void	errexit		A((int err, char *mess));
void	warning		A((int err, char *mess));

/* files.c */
extern Af_attrs	buft;
extern char	*pathlist[MAXPATHLIST][2];
extern int	lastpath;
extern char	*curvpath[];
extern char	actpath[];
extern char	dollarplus[];
Bool	locate_object		A((char *name, int mode));
Bool	try_to_bind_version 	A((char *dep, char *bind_rule,
				   Bool try_or_bind, BKey *bind_result));
void	init_confid		A((char *name));
void    add_rule_to_confid      A((struct rules *rule));
void	finish_confid		A((void));
FILE	*cmfopen		A((char *filename, char *mode,
				   int major_version, int minor_version));
void 	restore_all_vers 	A((void));
char	*restored_object_id	A((char *unixname));
void	drop_restorelist	A((void));

/* main.c */
extern char rbfile[];
extern char prev_dir[];
extern int main_gen;
extern int main_rev;
extern char *suffs;
extern char shapeflags[];
extern struct linked_list *shapefiles;
extern char *cmdtargets[];
extern char *cmd_line_vars[MAXCMDLINEVARS];
extern int rec_do_depth;
extern char *newarg[];
extern int newargc;
extern Bool Oldsuffs;
extern Bool Newsuffs;
void	cleanup		A((void));
void	get_env_vals	A((void));

/* dkey.c */
DepQ	*new_DepQ		A((void));
void	drop_dependent_queue	A((DepQ *q));
void	append_dependent	A((Af_key *key, DepQ *q));
char	*make_derivation_key	A((struct rules *current_rule, DepQ *q));

/* produce.c */
extern Bool error_occ;
extern Bool no_comm_subst;
extern char rbrule[];
extern char rbtarg[];
extern char ruleset[];
extern Bool busy_done;
extern int depth;
struct rules	*get_target	 A((char *targ));
struct rules	*implicit_target A((char *targ));
void 		produce		 A((void));

/* pa.c */
int parse_file A((char *filename)) ;
extern int parse_errors ;	/* number of parse errors */
void parsing_error A((char *message, char *ptr, char *option)) ;
void parsing_warning A((char *message, char *ptr, char *option)) ;

/* utils.c */
/* exports from utils.c */
char *skip_over_blanks A((char *line)) ;
char *skip_over_whitespace A((char *line)) ;
char *skip_over_name A((char *line)) ;
char *get_name A((char **line)) ;
struct stringlist *push_stringlist A((char *str,
				      struct stringlist *list,
				      int freeable)) ;
int is_no_namecomponent A((long c)) ;
char *skip_over_name_with_stop A((char *p, char *stop)) ;
struct stringlist *revert_stringlist A((struct stringlist *strlp)) ;
char *unquote A((char *string)) ;
char *check_malloc A(( unsigned size ));
char *check_realloc A(( char *ptr, unsigned size ));
char *check_strdup A(( char *s ));
char *check_strndup A(( char *s, int n ));
void strncpy0 A(( char *s1, char *s2, int n ));
sb_ptr check_sbcat A(( sb_ptr sb, char *string ));
sb_ptr check_sbaddc A(( sb_ptr sb, int c ));
sb_ptr check_sbnew A(( int len ));
void free_stringlist A(( struct stringlist *strlist ));
void fatal A(( char *message, char *message2 ));

/* queues.c */
void queue_dependency_rule A((struct stringlist *targets,
			      struct stringlist *deps,   
			      struct stringlist *macros, 
			      struct stringlist *cmds)) ;
void queue_selection_rule A((char *name, char *body, char *src_filename, int src_lineno)) ;
void queue_variant_definition A((char *name, struct stringlist *macros)) ;
void queue_vclass_definition A((char *name, struct stringlist *elements)) ;

void commit_definitions A((void)) ;
void commit_selrule_definitions A((void)) ;
void commit_deprule_definitions A((void)) ;



/* macro.c: */
extern char *environment_vars;
extern FILE *temp;
extern Bool shape_command;
char	*get_next_item		A((char *string));
void	define_macro		A((char *name, char *value, int mtype));
char	*expandmacro		A((char *inpstring));
void	echo_macro		A((char *name));

/* shapeopt.c */
extern char cfname[];
extern char echomac[];
extern char *forcelist[];
extern FILE *cid;
extern Bool debugflg;
extern Bool D_flag;
extern Bool Var_flag;
extern Bool selectflg;
extern Bool notfoundflg;
extern Bool noretrvflg;
extern Bool instflg;
extern Bool restflg;
extern Bool envflg;
extern Bool fileflg;
extern Bool nostdfile;
extern Bool ignoreflg;
extern Bool goflg;
extern Bool noexflg;
extern Bool printflg;
extern Bool questflg;
extern Bool ruleflg;
extern Bool silentflg;
extern Bool touchflg;
extern Bool stdinflg;
extern Bool confid;
extern Bool rebuildflg;
extern Bool stopflg;
extern Bool tunixflg;
extern Bool logflg;
extern Bool expflg;
extern Bool noexpflg;
extern Bool echoflg;
extern Bool nomsgflg;
extern Bool novclassflg;
extern Bool bpoolflg;
extern Bool nobpoolflg;
extern Bool forceflg;
extern StOptDesc odesc[];

/* rule.c */
extern struct rules *ruletab[];
extern char *firsttarget;
void	ruledef		A((char *string));
void	rulecont	A((char *string));
void	ruleend		A((void));
void    dump_rule       A((FILE *dest, struct rules *rule, Bool dump_commands));
void	ruledump	A((FILE *fd));
void	adjust_stdrules	A((char *suffs));
void	init_ruletab	A((void));
void	reset_dep_list	A((struct rules *dep_rule));
char	*get_dep	A((struct rules *dep_rule, int nth));
void	add_defaults	A((char *targ, struct rules *rule));
Bool	is_special_target A((char *string));
Bool	is_pattern	A((char *string));
char	*stem		A((char *pattern, char *string));
char    *subst_char     A((char *template, char s_char, char *substitution));

/* std.c */
extern struct rules *stdruletab[];
extern int lastrule;    /* index of last std rule */
extern char *stdsuff;
extern char *shaperules;
extern int implicit_suffs[];
void	add_stdrules	A((void));

/* selrule.c */
void	selruledef_preds	A((char *string));
void	selruledef_name		A((char *string));
Bool	is_selrule_name		A((char *name));

/* inherit.c */
Bool	stk_matchuda		A((char *udas, char *attr));
void	save_targets		A((struct rules *dep_rule, char *primary_target_name,
				   DepQ *q, BKey *primary_target_key, time_t touch_time));
Bool	already_in_done_list	A((char *targetname, Af_key *done_key));
void    add_to_done_list A((char *targ_path, Af_key *done_key));

/* misc.c */
extern struct linkreg *link_reg;
extern char *states[];
int	get_attr_type	A((char *name));
void	register_link	A((char *fn, char *newfn, Bool busy_exist));
void	cleanup_links	A((struct linkreg *cur_link));
void	free_linklist	A((void));
Bool	is_in_forcelist	A((char *name));
int	D_debug		A((char *name, char* type, char *at));

/* varsec.c */
extern struct vardef variantDefs[];
extern char *curvar[];
extern int variants_active;
extern int activeVariants[];
extern struct varclass variantClasses[];
extern int lastVariantDef;
void	vardef_end	A((void));
void	vclassdef	A((char *name, struct stringlist *varnames));
Bool	check_vclass	A((char *varname));
void	reset_vclass	A((void));
Bool	is_varname	A((char *string));
int	activate_variant A((char *varname));
void	de_activate A((char *varname));
char    *active_variants A(());
void    print_variant_class A((FILE * dest, struct varclass * vcdef_p));
void    print_variant_names A((FILE * destination));
void    print_variant_definition A((FILE * dest, struct vardef * vardef_p));

/* hash.c */

#define DYNAMIC 01
#define APPEND 02
#define ONCE 04
#define FROM_CMDLINE 0100

int	hashval		A((char *name, int tabsize));
void	addHash		A((char *name, char *value, int  mode));
char	*getHash	A((char *name));
Bool	visitedHash	A((char *name));
void	clearHashVisited A((char *name));
void	dump		A((FILE *fd));

/* sighand.c */
void	catch_sigs	A((void));

/* version.c */
char	*version	A((void));
