*
* Displays available options under grand unified configuration scheme
*
- * 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
- * -l : lists all currently defined groups and terminates
- * -G : no sort by groups (you get strict name order, instead)
- * -m : output the list in Machine friendly format, with a header row
- * -M : same as m, except no header
- * -h : help
- *
* Options whose flag bits are set to GUC_NO_SHOW_ALL, GUC_NOT_IN_SAMPLE,
* or GUC_DISALLOW_IN_FILE are not displayed, unless the user specifically
* requests that variable by name
*
- * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/help_config.c,v 1.4 2003/08/04 00:43:27 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/help_config.c,v 1.17 2006/07/14 14:52:25 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include <fcntl.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#include <errno.h>
#include <float.h>
#include <limits.h>
#include <unistd.h>
-#include "utils/guc.h"
#include "utils/guc_tables.h"
#include "utils/help_config.h"
-extern int optind;
-extern char *optarg;
-
-
-/*
- * The following char constructs provide the different formats the variables
- * can be outputted in.
- */
-enum outputFormat
-{
- HUMAN_OUTPUT,
- MACHINE_OUTPUT
-};
-
-static const char *const GENERIC_FORMAT[] = {
- gettext_noop("Name : %-20s \nContext : %-20s \nGroup : %-20s\n"),
- gettext_noop("%s\t%s\t%s\t")
-};
-static const char *const GENERIC_DESC[] = {
- gettext_noop("Description: %s\n%s\n"),
- gettext_noop("%s %s\n")
-};
-static const char *const BOOL_FORMAT[] = {
- gettext_noop("Type : BOOL\nReset Value: %-s \n"),
- gettext_noop("BOOL\t%s\t\t\t")
-};
-static const char *const INT_FORMAT[] = {
- gettext_noop("Type : INT\nReset Value: %-20d \nMin Value : %-20d \nMax Value : %-20d \n"),
- gettext_noop("INT\t%d\t%d\t%d\t")
-};
-static const char *const REAL_FORMAT[] = {
- gettext_noop("Type : REAL\nReset Value: %-20g \nMin Value : %-20g \nMax Value : %-20g \n"),
- gettext_noop("REAL\t%g\t%g\t%g\t")
-};
-static const char *const STRING_FORMAT[] = {
- gettext_noop("Type : STRING\nReset Value: %-s \n"),
- gettext_noop("STRING\t%s\t\t\t")
-};
-static const char *const COLUMN_HEADER[] = {
- "",
- gettext_noop("NAME\tCONTEXT\tGROUP\tTYPE\tRESET_VALUE\tMIN\tMAX\tSHORT_DESCRIPTION\tLONG_DESCRIPTION\n")
-};
-static const char *const ROW_SEPARATOR[] = {
- "------------------------------------------------------------\n",
- ""
-};
-
-/*
- * Variables loaded from the command line
- */
-static char *nameString = NULL; /* The var name pattern to match */
-static bool nameRegexBool = false; /* Match the name pattern as a
- * regex */
-static char *groupString = NULL; /* The var group pattern to match */
-static bool groupRegexBool = false; /* Match the group pattern as a
- * regex */
-static enum outputFormat outFormat = HUMAN_OUTPUT;
-static bool suppressAllHeaders = false; /* MACHINE_OUTPUT output, no
- * column headers */
-static bool groupResults = true; /* sort result list by groups */
-
/*
* This union allows us to mix the numerous different types of structs
struct config_real real;
struct config_int integer;
struct config_string string;
-} mixedStruct;
+} mixedStruct;
-/* function prototypes */
-static bool varMatches(mixedStruct * structToTest);
-static int compareMixedStructs(const void *, const void *);
-static mixedStruct **varsToDisplay(int *resultListSize);
-static const char *usageErrMsg(void);
-static void helpMessage(void);
-static void listAllGroups(void);
-static void printGenericHead(struct config_generic structToPrint);
-static void printGenericFoot(struct config_generic structToPrint);
-static void printMixedStruct(mixedStruct * structToPrint);
-static bool displayStruct(mixedStruct * structToDisplay);
+static void printMixedStruct(mixedStruct *structToPrint);
+static bool displayStruct(mixedStruct *structToDisplay);
-/*
- * Reads in the the command line options and sets the state of the program
- * accordingly. Initializes the result list and sorts it.
- */
int
-GucInfoMain(int argc, char *argv[])
-{
- mixedStruct **varList;
- int resultListSize;
- int c;
- int i;
-
- while ((c = getopt(argc, argv, "g:rGmMlh")) != -1)
- {
- switch (c)
- {
- case 'g':
- groupString = optarg;
- break;
- case 'r': /* not actually implemented yet */
- nameRegexBool = true;
- break;
- case 'G':
- groupResults = false;
- break;
- case 'm':
- outFormat = MACHINE_OUTPUT;
- break;
- case 'M':
- outFormat = MACHINE_OUTPUT;
- suppressAllHeaders = true;
- break;
- case 'l':
- listAllGroups();
- exit(0);
- case 'h':
- helpMessage();
- exit(0);
-
- default:
- fprintf(stderr, gettext("%s \n Try -h for further details\n"), usageErrMsg());
- exit(1);
- }
- }
-
- if (optind < argc)
- nameString = argv[optind];
-
- /* get the list of variables that match the user's specs. */
- varList = varsToDisplay(&resultListSize);
-
- /* sort them by group if desired */
- /* (without this, we get the original sort by name from guc.c) */
- if (groupResults)
- qsort(varList, resultListSize,
- sizeof(mixedStruct *), compareMixedStructs);
-
- /* output the results */
- if (!suppressAllHeaders)
- printf(gettext(COLUMN_HEADER[outFormat]));
-
- for (i = 0; varList[i] != NULL; i++)
- {
- printf(gettext(ROW_SEPARATOR[outFormat]));
- printMixedStruct(varList[i]);
- }
-
- return 0;
-}
-
-
-/*
- * This function is used to compare two mixedStruct types. It compares based
- * on the value of the 'group' field, and then the name of the variable.
- * Each void* is expected to be a pointer to a pointer to a struct.
- * (This is because it is used by qsort to sort an array of struct pointers)
- *
- * Returns an integer less than, equal to, or greater than zero if the first
- * argument (struct1) is considered to be respectively less than, equal to,
- * or greater than the second (struct2). The comparison is made frist on the
- * value of struct{1,2}.generic.group and then struct{1,2}.generic.name. The
- * groups will display in the order they are defined in enum config_group
- */
-static int
-compareMixedStructs(const void *struct1, const void *struct2)
+GucInfoMain(void)
{
- mixedStruct *structVar1 = *(mixedStruct **) struct1;
- mixedStruct *structVar2 = *(mixedStruct **) struct2;
-
- if (structVar1->generic.group > structVar2->generic.group)
- return 1;
- else if (structVar1->generic.group < structVar2->generic.group)
- return -1;
- else
- return strcmp(structVar1->generic.name, structVar2->generic.name);
-}
-
-
-/*
- * This function returns a complete list of all the variables to display,
- * according to what the user wants to see.
- */
-static mixedStruct **
-varsToDisplay(int *resultListSize)
-{
- mixedStruct **resultList;
- int arrayIndex;
- int i;
+ struct config_generic **guc_vars;
+ int numOpts,
+ i;
/* Initialize the guc_variables[] array */
build_guc_variables();
- /* Extract just the ones we want to display */
- resultList = malloc((num_guc_variables + 1) * sizeof(mixedStruct *));
- arrayIndex = 0;
+ guc_vars = get_guc_variables();
+ numOpts = GetNumConfigOptions();
- for (i = 0; i < num_guc_variables; i++)
+ for (i = 0; i < numOpts; i++)
{
- mixedStruct *var = (mixedStruct *) guc_variables[i];
+ mixedStruct *var = (mixedStruct *) guc_vars[i];
- if (varMatches(var))
- resultList[arrayIndex++] = var;
+ if (displayStruct(var))
+ printMixedStruct(var);
}
- /* add an end marker */
- resultList[arrayIndex] = NULL;
-
- *resultListSize = arrayIndex;
- return resultList;
+ return 0;
}
/*
* This function will return true if the struct passed to it
* should be displayed to the user.
- *
- * The criteria to determine if the struct should not be displayed is:
- * + It's flag bits are set to GUC_NO_SHOW_ALL
- * + It's flag bits are set to GUC_NOT_IN_SAMPLE
- * + It's flag bits are set to GUC_DISALLOW_IN_FILE
*/
static bool
-displayStruct(mixedStruct * structToDisplay)
+displayStruct(mixedStruct *structToDisplay)
{
- if (structToDisplay->generic.flags & (GUC_NO_SHOW_ALL |
- GUC_NOT_IN_SAMPLE |
- GUC_DISALLOW_IN_FILE))
- return false;
- else
- return true;
-}
-
-
-/*
- * Used to determine if a variable matches the user's specifications (stored in
- * global variables). Returns true if this particular variable information should
- * be returned to the user.
- */
-static bool
-varMatches(mixedStruct * structToTest)
-{
- bool matches = false;
- bool specificSearch = false; /* This is true if the user
- * searched for a variable in
- * particular. */
-
- if (nameString != NULL && !nameRegexBool)
- {
- if (strstr(structToTest->generic.name, nameString) != NULL)
- {
- matches = true;
- specificSearch = true;
- }
- }
-
- if (nameString != NULL && nameRegexBool)
- {
- /* We do not support this option yet */
- }
-
- if (groupString != NULL && !groupRegexBool)
- {
- if (strstr(config_group_names[structToTest->generic.group], groupString) != NULL)
- {
- if (nameString != NULL)
- matches = (matches && true);
- else
- matches = true;
- }
- else
- matches = false;
- }
-
- if (groupString != NULL && groupRegexBool)
- {
- /* We do not support this option yet */
- }
-
- /* return all variables */
- if (nameString == NULL && groupString == NULL)
- matches = true;
-
- if (specificSearch)
- return matches;
- else
- return matches && displayStruct(structToTest);
+ return !(structToDisplay->generic.flags & (GUC_NO_SHOW_ALL |
+ GUC_NOT_IN_SAMPLE |
+ GUC_DISALLOW_IN_FILE));
}
* a different format, depending on what the user wants to see.
*/
static void
-printMixedStruct(mixedStruct * structToPrint)
+printMixedStruct(mixedStruct *structToPrint)
{
- printGenericHead(structToPrint->generic);
+ printf("%s\t%s\t%s\t",
+ structToPrint->generic.name,
+ GucContext_Names[structToPrint->generic.context],
+ _(config_group_names[structToPrint->generic.group]));
switch (structToPrint->generic.vartype)
{
case PGC_BOOL:
- printf(gettext(BOOL_FORMAT[outFormat]),
+ printf("BOOLEAN\t%s\t\t\t",
(structToPrint->bool.reset_val == 0) ?
- gettext("FALSE") : gettext("TRUE"));
+ "FALSE" : "TRUE");
break;
case PGC_INT:
- printf(gettext(INT_FORMAT[outFormat]),
+ printf("INTEGER\t%d\t%d\t%d\t",
structToPrint->integer.reset_val,
structToPrint->integer.min,
structToPrint->integer.max);
break;
case PGC_REAL:
- printf(gettext(REAL_FORMAT[outFormat]),
+ printf("REAL\t%g\t%g\t%g\t",
structToPrint->real.reset_val,
structToPrint->real.min,
structToPrint->real.max);
break;
case PGC_STRING:
- printf(gettext(STRING_FORMAT[outFormat]),
+ printf("STRING\t%s\t\t\t",
structToPrint->string.boot_val);
break;
default:
- printf(gettext("Unrecognized variable type!\n"));
+ write_stderr("internal error: unrecognized run-time parameter type\n");
break;
}
- printGenericFoot(structToPrint->generic);
-}
-
-static void
-printGenericHead(struct config_generic structToPrint)
-{
- printf(gettext(GENERIC_FORMAT[outFormat]),
- structToPrint.name,
- GucContext_Names[structToPrint.context],
- gettext(config_group_names[structToPrint.group]));
-}
-
-static void
-printGenericFoot(struct config_generic sPrint)
-{
- printf(gettext(GENERIC_DESC[outFormat]),
- (sPrint.short_desc == NULL) ? "" : gettext(sPrint.short_desc),
- (sPrint.long_desc == NULL) ? "" : gettext(sPrint.long_desc));
-}
-
-static void
-listAllGroups(void)
-{
- int i;
-
- printf(gettext("All currently defined groups\n"));
- printf(gettext("----------------------------\n"));
- for (i = 0; config_group_names[i] != NULL; i++)
- printf(gettext("%s\n"), gettext(config_group_names[i]));
-}
-
-static const char *
-usageErrMsg(void)
-{
- return gettext("Usage for --help-config option: [-h] [-g <group>] [-l] [-G] [-m] [-M] [string]\n");
-}
-
-static void
-helpMessage(void)
-{
- printf(gettext("Description:\n"
- "--help-config displays all the runtime options available in PostgreSQL.\n"
- "It groups them by category and sorts them by name. If available, it will\n"
- "present a short description, default, max and min values as well as other\n"
- "information about each option.\n\n"
- "With no options specified, it will output all available runtime options\n"
- "in human friendly format, grouped by category and sorted by name.\n\n"
-
- "%s\n"
-
- "General Options:\n"
- " [string] All options with names that match this string\n"
- " -g GROUP All options in categories that match GROUP\n"
- " -l Prints list of all groups / subgroups\n"
- " -h Prints this help message\n"
- "\nOutput Options:\n"
- " -G Do not group by category\n"
- " -m Machine friendly format: tab separated fields\n"
- " -M Same as m, except header with column names is suppressed\n"),
- usageErrMsg()
- );
+ printf("%s\t%s\n",
+ (structToPrint->generic.short_desc == NULL) ? "" : _(structToPrint->generic.short_desc),
+ (structToPrint->generic.long_desc == NULL) ? "" : _(structToPrint->generic.long_desc));
}