/*		utils.h  Feb 2004					*/
/*	Stuff needed by utils.c (formerly defgb_utils.c).  This is a	*/
/*    subset of the old defgb.h						*/
/*		Sigh.  WJS						*/
#define UTILSH_VERSION "utils.h version 1.3 18 Oct 2008"
/*  18 Oct 08.  WJS							*/
/*	REMOTE_OBJECT_HOST_TERMINATOR_CHAR 				*/
/*  29 Feb 08.  WJS							*/
/*	REMOTE_OBJECT_PREFIX_x stuff					*/
/*	[Begin 1.3]							*/
/*  31 Dec 06.  WJS							*/
/*	Keyword pair parsing structures, defns, etc			*/
/*   3 Jun 05.  WJS							*/
/*	Needs jdb func defns						*/

#include "jdbfuncdefns.h"
#define FULL_UTILSH_VERSION UTILSH_VERSION"/"FULL_JDBFUNCDEFNSH_VERSION 

/*  Integer definitions are to allow the 4 separator strings to be	*/
/*  specified in an array						*/
#define BETWEEN_PAIRS 0		/*	z chars				*/
#define WITHIN_PAIRS 1		/*	y chars				*/
#define QUOTES 2
#define SPECIALS 3		/*	x chars				*/
#define PARSE_SEPARATOR_ARRAY_SIZE 4
/*  Static in next statement needed to avoid "double defn" errors	*/
/*  Presence of "=" makes next statement a definition rather than a	*/
/*    reference, and for some reason definitions outside of program	*/
/*    blocks have full image scope WITHOUT the use of "extern"		*/
/*  Harbison and Steele point out that if one DOES use "extern", there	*/
/*    can be cross-compiler difficulties.				*/
/*  In order to get rid of the implicit extern, one cannot use, say,	*/
/*    "local" - one instead uses a storage class specifier!		*/
static char *STANDARD_PARSE_SEPARATORS[PARSE_SEPARATOR_ARRAY_SIZE] =
			{ ";,/|" , "=:" , "\'\'" , ILLEGAL_VARNAME_CHARS};

/* USE_SPECIALS		    String that lengthen_str routine uses to	*/
/*			    avoid its normal table lookup (and there-	*/
/*			    for avoid table overflow)			*/
#define USE_SPECIALS "Use special entries"

/* ****								   **** */
/*	Next set of defns should be checked for disjointness		*/
/*	but isn't							*/

/* SOURCE_IS_DATA		Character in indirect file entry which	*/
/*			    indicates that what follows is a data 	*/
/*			    record (rather than a file containing that	*/
/*			    data)					*/
#define SOURCE_IS_DATA '\\'

/* EXEC_DELIM			Characters that surround a new level	*/
/* 			    data source indicating that the source	*/
/* 			    is output of a shell script (not a file)	*/
#define EXEC_DELIM "()"

/* OBJECT_DELIM			Characters that surround a new level	*/
/* 			    data source indicating that the source	*/
/* 			    is a JGOFS data object (not a file)		*/
#define OBJECT_DELIM "{}"

/* Remote object ID definitions						*/
/* REMOTE_OBJECT_PREFIX 	Characters which, if leading off an	*/
/*			    object spec, indicate object is "remote"	*/
/*			    (ie, will be accessed via http)		*/
/*	_NEW is necessary but not sufficient to ID a remote object	*/
/* REMOTE_OBJECT_HOST_TERMINATOR_CHAR Character delimiting the end	*/
/*			    of the host serving a remote object.	*/
/*			    Practically, this is the end of the node/	*/
/*			    port spec in an http://node:port/.  Don't	*/
/*			    know best way to parametrize this for	*/
/*			    remote object use				*/
#define REMOTE_OBJECT_PREFIX_OLD "//"
#define REMOTE_OBJECT_PREFIX_NEW "/"
#define REMOTE_OBJECT_PREFIX REMOTE_OBJECT_PREFIX_OLD
#define REMOTE_OBJECT_HOST_TERMINATOR_CHAR '/'

/* ****								   **** */

/************************************************************************/

  /*  Fundamental structure saving information about the various 	*/
  /*  sources of info that we tap into.  Not all fields are relevant to	*/
  /*  all sources of info.						*/

  /*	  Values for .source_type character				*/
  /*	COMMAND_FILE	    data is coming from a child process via a	*/
  /*	    via a shell command or user-written script.  See EXEC_DELIM	*/
  /*	    above (as well as doc)					*/
  /*	DATA_FILE	    data is coming from a disk file		*/
  /*	JGOFS_OBJECT	    data is coming from a JGOFS object.  See	*/
  /*	    OBJECT_DELIM (as well as doc)				*/
  /*	INDIRECT_FILE_LINE  data consists of one record.  The record	*/
  /*	    record is either part of a line in the indirect file 	*/
  /*	    (possibly redirected to an argument passed to the method	*/
  /*	    by the shell which, in turn, is a parameter in the		*/
  /*	    .objects file if the method is run by serv).  See		*/
  /*	    SOURCE_IS_DATA (as well as doc)				*/
  /*	CREATE_NULL_DATA    data not provided by user.  Supply line of	*/
  /*	    "missing data" tokens					*/
  /*	ILLEGAL_SOURCE	     not initialized, or not one of the above	*/
#define COMMAND_FILE 'c'
#define DATA_FILE 'f'
#define JGOFS_OBJECT 'o'
#define INDIRECT_FILE_LINE 'i'
#define CREATE_NULL_DATA 'z'
#define ILLEGAL_SOURCE 'x'

struct fileinfo {
  FILE *stream;
  char *source;		/* Where does information of this type		*/
			/*  come from?  Can be file name, this buffer,	*/
			/*   object or script.  Additionally, may be	*/
			/*    asked to supply appropriate # of nds.	*/
			/*     source_type field tells which		*/
  char *descrip;	/* Keyword for an optional file type in the	*/
			/*  indirect file.  Also may be used in error	*/
			/*   messages to id optional file type.  This	*/
			/*    field filled in from constants in init_	*/
			/*     file_structs				*/
  char *item_separators;/* Chars, any string of which (or any one of	*/
			/*  which for datafiles; see significant_con-	*/
			/*   secutive_separators doc) separates items 	*/
			/*    in an entry				*/
  char *entry_separators; /* Chars that separate mult entries on a line	*/
			/* Should be the whitespace of item_separators	*/
			/*  plus one significant character.		*/
			/*   Set to '\0' if mult entries not allowed	*/
  char *comment_postfix; /* String inserted after comments from this	*/
			/*  file to distinguish them from other comments */
			/*  Presently = " {" + file.descrip + "}, so	*/
			/*  this field candidate for removal		*/
  char *buf;		/* Data buffer pointer for this structure.	*/
			/*  Logically an array, but wanted a pointer.	*/
			/*   Allocated in init_filestructs.		*/
			/* Not sure separate buffer per structure is	*/
			/*   necessary, but at one point it was.	*/
  int buf_size;		/* Size of buf (yes, including \0s, etc)	*/
  int nrecs;		/* Count of records read from this file		*/
  int print_lines;	/* Dump every 'print_lines'th input line	*/
  int dup_print_lines;	/* Dump every 'dup_print_lines'th input line	*/
			/*  to dup diag sink				*/
  int firstvar;		/* First variable in the permutation at a level	*/
			/*    For datafiles				*/
  int lastvar;		/* Upper bound for variables in the permutation	*/
			/*  at a level (actually, first variable of	*/
			/*      next level)				*/
			/*    For datafiles				*/
  int level;		/* Level within this object of this structure	*/
			/*    For datafiles				*/
  int objlevel;		/* JGOFS object level to which this file	*/
			/*  corresponds.  For datafiles.		*/
  int force_flag;	/* If non-zero, file is not optional.  +1=file	*/
			/*  required; -1=must NOT be present		*/
  int maxlenrec;	/* Maximum length of fixed field record. Sum of	*/
			/*  lens of fixed field variables present at	*/
			/*    this level.  Also serves as fixed/free	*/
			/*      flag					*/
  char item_alt_separators[2+1]; /* Delims which allow item_separators	*/
			/*  in an item; see alt_sep doc			*/
  char source_type;	/* See *source, above.  Vals: f, d, o, z, or s.	*/
		/*  Next bit filled in in get_files 			*/
  unsigned int pre_trans : 1;	/* Vars in this file need translation	*/
  unsigned int accepts_trans_prefix : 1;
		/*  Next 3 bits separate data hunks from actual "files"	*/
		/*  A fileinfo structure is processed until its eod bit	*/
		/*  is set.  The open bit says that the data stream	*/
		/*  associated with this file structure is open (and	*/
		/*  implies that there is a real stream as opposed to	*/
		/*  a simulated stream of some kind).  The eof bit says	*/
		/*  that an end-of-file has been encountered on the	*/
		/*  data stream associated with the file structure.	*/
		/*  Normally, open=FALSE causes an open, which sets	*/
		/*  open and resets eod and eof.  Processing continues	*/
		/*  until eod.  If end-of-file is encountered, eof is	*/
		/*  set.  USUALLY eod is set, too.  getrec_and_proc-	*/
		/*  comment manages the eof and eod bits. open_datafile	*/
		/*  and open_and_log_optfile do opens.  Closing things	*/
		/*  (and resetting open) is done "elsewhere"		*/
		/*  We generally assume that eof is only set for a	*/
		/*  data stream.					*/
  unsigned int eod : 1;
  unsigned int open : 1;
  unsigned int eof : 1;
};
