#ifndef PG_GUC_H
#define PG_GUC_H 1

/*-------------------------------------------------------------------------
 *
 * pg_guc.h
 * Interface to the --long-help option of main.c 
 *
 * The purpose of this option is to list, sort, and make searchable, all
 * runtime options available to Postgresql, by their description and grouping.
 *
 * Valid command-line options to this program:
 *
 *  none        : All available variables are sorted by group and name
 *                and formatted nicely. ( for human consumption )
 *  <string>    : list all the variables whose name matches this string
 *  -g <string> : list all the variables whose group matches this string
 *  -m          : output the list in Machine friendly format, with a header row
 *  -M          : same as m, except no header either
 *  -G          : do not sort results
 *  -l			: lists all currently defined groups and terminates
 *  -h			: help
 * 
 * Options whose flag bits are set to GUC_NO_SHOW_ALL, NOT_IN_SAMPLE_CONF,
 * or DISALLOW_IN_CONF_FILE are not displayed, unless the user specifically
 * requests that variable by name
 * 
 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 *
 * $Id: $ 
 *
 *-------------------------------------------------------------------------
 */

#define translatable(x) (x)
/* 
 * This is the maximum number of runtime variables
 * that this program can handle
 */
#define MAX_NUM_VARS 1024

/*
 * The following char constructs provide the different formats the variables
 * can be outputted in.
 */
enum outputFormat {
	HUMAN,
	MACHINE
};


static char * GENERIC_FORMAT [] = { translatable("Name       : %-20s \nContext    : %-20s \nGroup      : %-20s\n"),
									translatable("%s\t%s\t%s\t")
								  };
static char * GENERIC_DESC []   = { translatable("Description: %s\n%s\n"),
									translatable("%s	%s\n")
								  };
static char * BOOL_FORMAT []    = { translatable("Type       : BOOL\nReset Value: %-s \n"),
									translatable("BOOL\t%s\t\t\t")
								  };
static char * INT_FORMAT []     = { translatable("Type       : INT\nReset Value: %-20d \nMin Value  : %-20d \nMax Value  : %-20d \n"),
									translatable("INT\t%d\t%d\t%d\t")
								  };
static char * REAL_FORMAT []    = { translatable("Type       : REAL\nReset Value: %-20g \nMin Value  : %-20g \nMax Value  : %-20g \n"),
									translatable("REAL\t%g\t%g\t%g\t")
								  };
static char * STRING_FORMAT []  = { translatable("Type       : STRING\nReset Value: %-s \n"),
									translatable("STRING\t%s\t\t\t")
								  };
static char * COLUMN_HEADER []  = { "",
									translatable("NAME\tCONTEXT\tGROUP\tTYPE\tRESET_VALUE\tMIN\tMAX\tSHORT_DESCRIPTION\tLONG_DESCRIPTION\n")
								  };
static char * ROW_SEPARATOR []  = { "------------------------------------------------------------\n",
									""
								  };

/*
 * Variables loaded from the command line
 */
char *nameString = NULL;             /* The var name pattern to match */
bool  nameRegexBool = false;         /* Match the name pattern as a regex */
char *groupString = NULL;            /* The var group pattern to match */
bool  groupRegexBool = false;        /* Match the group pattern as a regex */
enum  outputFormat outFormat = HUMAN;
bool  suppressAllHeaders = false;    /* MACHINE output, no column headers */
bool  groupResults = true;           /* sort result list */


/*
 * This union allows us to mix the numerous different types of structs
 * that we are organizing. To be used as an element in the mixedStruct
 */
typedef union {
	struct config_bool configBool;
	struct config_real configReal;
	struct config_int configInt;
	struct config_string configString;
} structVal;


/*
 * This struct type allows us to access many of the field common to the
 * numerous different kinds of config_structs ( bool, int, string, real )
 * without knowing what kind it is, or writting special code in each case
 */
typedef struct {
	enum config_type type;
	struct config_generic generic;
	structVal var;
} mixedStruct;


/* function prototypes */
int GucInfoMain ( int argc, char * argv [] );
static mixedStruct * resultList [MAX_NUM_VARS];
static int resultListSize;
static bool varMatches ( mixedStruct );
static int compareMixedStructs ( const void*, const void* );
static mixedStruct **varsToDisplay ( void );
static mixedStruct *buildMixedStruct ( enum config_type, void* );
static char * usageErrMsg ( void );
static void helpMessage ( void );
static void listAllGroups ( void );
static int printGenericHead ( struct config_generic structToPrint );
static int printGenericFoot ( struct config_generic structToPrint );
static void descriptionParser ( const char *preParsed, char **shortDes, char **longDes );
static int printMixedStruct ( mixedStruct );
static int displayStruct ( mixedStruct* structToDisplay );

#endif
