/*
* psql - the PostgreSQL interactive terminal
*
- * Copyright (c) 2000-2007, PostgreSQL Global Development Group
+ * Copyright (c) 2000-2015, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/variables.c,v 1.27 2007/01/05 22:19:50 momjian Exp $
+ * src/bin/psql/variables.c
*/
#include "postgres_fe.h"
+
#include "common.h"
#include "variables.h"
+/*
+ * Check whether a variable's name is allowed.
+ *
+ * We allow any non-ASCII character, as well as ASCII letters, digits, and
+ * underscore. Keep this in sync with the definition of variable_char in
+ * psqlscan.l.
+ */
+static bool
+valid_variable_name(const char *name)
+{
+ const unsigned char *ptr = (const unsigned char *) name;
+
+ /* Mustn't be zero-length */
+ if (*ptr == '\0')
+ return false;
+
+ while (*ptr)
+ {
+ if (IS_HIGHBIT_SET(*ptr) ||
+ strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
+ "_0123456789", *ptr) != NULL)
+ ptr++;
+ else
+ return false;
+ }
+
+ return true;
+}
+
/*
* A "variable space" is represented by an otherwise-unused struct _variable
* that serves as list header.
return NULL;
}
+/*
+ * Try to interpret "value" as boolean value.
+ *
+ * Valid values are: true, false, yes, no, on, off, 1, 0; as well as unique
+ * prefixes thereof.
+ *
+ * "name" is the name of the variable we're assigning to, to use in error
+ * report if any. Pass name == NULL to suppress the error report.
+ */
bool
-ParseVariableBool(const char *val)
+ParseVariableBool(const char *value, const char *name)
{
- if (val == NULL)
+ size_t len;
+
+ if (value == NULL)
return false; /* not set -> assume "off" */
- if (pg_strcasecmp(val, "off") == 0)
- return false; /* accept "off" or "OFF" as true */
- /*
- * for backwards compatibility, anything except "off" or "OFF" is taken as
- * "true"
- */
- return true;
+ len = strlen(value);
+
+ if (pg_strncasecmp(value, "true", len) == 0)
+ return true;
+ else if (pg_strncasecmp(value, "false", len) == 0)
+ return false;
+ else if (pg_strncasecmp(value, "yes", len) == 0)
+ return true;
+ else if (pg_strncasecmp(value, "no", len) == 0)
+ return false;
+ /* 'o' is not unique enough */
+ else if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
+ return true;
+ else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
+ return false;
+ else if (pg_strcasecmp(value, "1") == 0)
+ return true;
+ else if (pg_strcasecmp(value, "0") == 0)
+ return false;
+ else
+ {
+ /* NULL is treated as false, so a non-matching value is 'true' */
+ if (name)
+ psql_error("unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n",
+ value, name, "on");
+ return true;
+ }
}
+
/*
* Read numeric variable, or defaultval if it is not set, or faultval if its
* value is not a valid numeric string. If allowtrail is false, this will
if (!space)
return false;
- if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name))
+ if (!valid_variable_name(name))
return false;
if (!value)
if (!space)
return false;
- if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name))
+ if (!valid_variable_name(name))
return false;
for (previous = space, current = space->next;