Commit add932ee authored by Bruce Momjian's avatar Bruce Momjian

I'm continuing to work on cleaning up code in psql. As things appear

now, my changes seem to work.  Some possible minor bugs got squished
on the way but I can't be sure without more feedback from people who
really put the code to the test.

The new patch mostly simplifies variable handling and reduces code
duplication.  Changes in the command parser eliminate some redundant
variables (boolean state + depth counter), replaces some
"else if" constructs with switches, and so on.  It is meant to be
applied together with my previous patch, although I hope they don't
conflict; I went back to the CVS version for this one.

One more thing I thought should perhaps be changed: an IGNOREEOF
value of n will ignore only n-1 EOFs.  I didn't want to touch this
for fear of breaking existing applications, but it does seem a tad
illogical.

Jeroen T. Vermeulen
parent 1b3d4cef
......@@ -3,7 +3,7 @@
*
* Copyright 2000-2002 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.93 2003/03/19 22:49:43 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.94 2003/03/20 06:43:35 momjian Exp $
*/
#include "postgres_fe.h"
#include "command.h"
......@@ -669,15 +669,7 @@ exec_command(const char *cmd,
if (!opt0)
{
/* list all variables */
/*
* XXX This is in utter violation of the GetVariable
* abstraction, but I have not bothered to do it better.
*/
struct _variable *ptr;
for (ptr = pset.vars; ptr->next; ptr = ptr->next)
fprintf(stdout, "%s = '%s'\n", ptr->next->name, ptr->next->value);
PrintVariables(pset.vars);
success = true;
}
else
......@@ -1073,9 +1065,7 @@ scan_option(char **string, enum option_type type, char *quote, bool semicolon)
save_char = options_string[pos + token_end + 1];
options_string[pos + token_end + 1] = '\0';
value = GetVariable(pset.vars, options_string + pos + 1);
if (!value)
value = "";
return_val = xstrdup(value);
return_val = xstrdup(value ? value : "");
options_string[pos + token_end + 1] = save_char;
*string = &options_string[pos + token_end + 1];
/* XXX should we set *quote to ':' here? */
......@@ -1287,15 +1277,9 @@ unescape(const unsigned char *source, size_t len)
case '7':
case '8':
case '9':
{
long int l;
char *end;
l = strtol(p, &end, 0);
c = (char) l;
p = end - 1;
c = parse_char((char **)&p);
break;
}
default:
c = *p;
}
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.59 2003/03/20 06:00:12 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.60 2003/03/20 06:43:35 momjian Exp $
*/
#include "postgres_fe.h"
#include "common.h"
......@@ -368,7 +368,7 @@ PSQLexec(const char *query, bool ignore_command_ok)
{
PGresult *res = NULL;
PGresult *newres;
const char *var;
int echo_hidden;
ExecStatusType rstatus;
if (!pset.db)
......@@ -377,17 +377,17 @@ PSQLexec(const char *query, bool ignore_command_ok)
return NULL;
}
var = GetVariable(pset.vars, "ECHO_HIDDEN");
if (var)
echo_hidden = SwitchVariable(pset.vars, "ECHO_HIDDEN", "noexec", NULL);
if (echo_hidden != var_notset)
{
printf("********* QUERY **********\n"
"%s\n"
"**************************\n\n", query);
fflush(stdout);
}
if (var && strcmp(var, "noexec") == 0)
if (echo_hidden == 1)
return NULL;
}
/* discard any uneaten results of past queries */
while ((newres = PQgetResult(pset.db)) != NULL)
......@@ -579,13 +579,13 @@ SendQuery(const char *query)
bool OK;
if (!pset.db)
{
{
psql_error("You are currently not connected to a database.\n");
return false;
}
}
if (GetVariableBool(pset.vars, "SINGLESTEP"))
{
{
char buf[3];
printf(gettext("***(Single step mode: Verify query)*********************************************\n"
......@@ -596,14 +596,9 @@ SendQuery(const char *query)
if (fgets(buf, sizeof(buf), stdin) != NULL)
if (buf[0] == 'x')
return false;
}
else
{
const char *var = GetVariable(pset.vars, "ECHO");
if (var && strncmp(var, "queries", strlen(var)) == 0)
puts(query);
}
else if (VariableEquals(pset.vars, "ECHO", "queries"))
puts(query);
SetCancelConn();
......@@ -619,3 +614,15 @@ SendQuery(const char *query)
PrintNotifications();
return OK;
}
char parse_char(char **buf)
{
long l;
l = strtol(*buf, buf, 0);
(*buf)--;
return (char)l;
}
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.23 2003/03/20 06:00:12 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.24 2003/03/20 06:43:35 momjian Exp $
*/
#ifndef COMMON_H
#define COMMON_H
......@@ -42,6 +42,12 @@ extern bool SendQuery(const char *query);
/* sprompt.h */
extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
/* Parse a numeric character code from the string pointed at by *buf, e.g.
* one written as 0x0c (hexadecimal) or 015 (octal); advance *buf to the last
* character of the numeric character code.
*/
extern char parse_char(char **buf);
/* Used for all Win32 popen/pclose calls */
#ifdef WIN32
#define popen(x,y) _popen(x,y)
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.22 2003/03/20 06:00:12 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.23 2003/03/20 06:43:35 momjian Exp $
*/
#include "postgres_fe.h"
#include "input.h"
......@@ -233,10 +233,12 @@ finishInput(int exitstatus, void *arg)
strlen(PSQLHISTORY) + 1);
if (psql_history)
{
const char *var = GetVariable(pset.vars, "HISTSIZE");
int hist_size;
hist_size = GetVariableNum(pset.vars,"HISTSIZE",-1,-1,true);
if (hist_size >= 0)
stifle_history(hist_size);
if (var)
stifle_history(atoi(var));
sprintf(psql_history, "%s/%s", home, PSQLHISTORY);
write_history(psql_history);
free(psql_history);
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000-2002 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.23 2002/10/15 02:24:16 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.24 2003/03/20 06:43:35 momjian Exp $
*/
#include "postgres_fe.h"
#include "large_obj.h"
......@@ -40,15 +40,20 @@ _my_notice_handler(void *arg, const char *message)
static bool
handle_transaction(void)
{
const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
PGresult *res;
bool commit;
bool commit = false;
PQnoticeProcessor old_notice_hook;
if (var && strcmp(var, "nothing") == 0)
switch (SwitchVariable(pset.vars, "LO_TRANSACTION",
"nothing",
"commit",
NULL))
{
case 1:
return true;
commit = (var && strcmp(var, "commit") == 0);
case 2:
commit = true;
}
notice[0] = '\0';
old_notice_hook = PQsetNoticeProcessor(pset.db, _my_notice_handler, NULL);
......@@ -87,11 +92,9 @@ do_lo_export(const char *loid_arg, const char *filename_arg)
{
PGresult *res;
int status;
bool own_transaction = true;
const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
bool own_transaction;
if (var && strcmp(var, "nothing") == 0)
own_transaction = false;
own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing");
if (!pset.db)
{
......@@ -154,11 +157,9 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
Oid loid;
char oidbuf[32];
unsigned int i;
bool own_transaction = true;
const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
bool own_transaction;
if (var && strcmp(var, "nothing") == 0)
own_transaction = false;
own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing");
if (!pset.db)
{
......@@ -271,11 +272,10 @@ do_lo_unlink(const char *loid_arg)
int status;
Oid loid = atooid(loid_arg);
char buf[256];
bool own_transaction = true;
const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
if (var && strcmp(var, "nothing") == 0)
own_transaction = false;
bool own_transaction;
own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing");
if (!pset.db)
{
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.52 2003/03/20 06:00:12 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.53 2003/03/20 06:43:35 momjian Exp $
*/
#include "postgres_fe.h"
#include "mainloop.h"
......@@ -40,16 +40,14 @@ MainLoop(FILE *source)
char *line; /* current line of input */
int len; /* length of the line */
volatile int successResult = EXIT_SUCCESS;
volatile backslashResult slashCmdStatus;
volatile backslashResult slashCmdStatus = CMD_UNKNOWN;
bool success;
volatile char in_quote; /* == 0 for no in_quote */
volatile bool in_xcomment; /* in extended comment */
volatile int xcdepth;
volatile int paren_level;
volatile char in_quote = 0; /* == 0 for no in_quote */
volatile int in_xcomment = 0; /* in extended comment */
volatile int paren_level = 0;
unsigned int query_start;
volatile int count_eof = 0;
const char *var;
volatile unsigned int bslash_count = 0;
int i,
......@@ -81,16 +79,12 @@ MainLoop(FILE *source)
exit(EXIT_FAILURE);
}
in_xcomment = false;
in_quote = 0;
paren_level = 0;
slashCmdStatus = CMD_UNKNOWN; /* set default */
prev_lineno = pset.lineno;
pset.lineno = 0;
/* main loop to get queries and execute them */
while (1)
while (successResult == EXIT_SUCCESS)
{
/*
* Welcome code for Control-C
......@@ -109,6 +103,7 @@ MainLoop(FILE *source)
}
cancel_pressed = false;
fflush(stdout);
}
#ifndef WIN32
......@@ -118,15 +113,16 @@ MainLoop(FILE *source)
if (pset.cur_cmd_interactive)
{
fputc('\n', stdout);
putc('\n', stdout);
resetPQExpBuffer(query_buf);
/* reset parsing state */
in_xcomment = false;
in_xcomment = 0;
in_quote = 0;
paren_level = 0;
count_eof = 0;
slashCmdStatus = CMD_UNKNOWN;
fflush(stdout);
}
else
{
......@@ -151,23 +147,21 @@ MainLoop(FILE *source)
line = xstrdup(query_buf->data);
resetPQExpBuffer(query_buf);
/* reset parsing state since we are rescanning whole line */
in_xcomment = false;
in_xcomment = 0;
in_quote = 0;
paren_level = 0;
slashCmdStatus = CMD_UNKNOWN;
}
else
{
fflush(stdout);
/*
* otherwise, set interactive prompt if necessary and get
* another line
*/
if (pset.cur_cmd_interactive)
else if (pset.cur_cmd_interactive)
{
int prompt_status;
fflush(stdout);
if (in_quote && in_quote == '\'')
prompt_status = PROMPT_SINGLEQUOTE;
else if (in_quote && in_quote == '"')
......@@ -185,7 +179,6 @@ MainLoop(FILE *source)
}
else
line = gets_fromFile(source);
}
/* Setting this will not have effect until next line. */
......@@ -203,50 +196,21 @@ MainLoop(FILE *source)
{
if (pset.cur_cmd_interactive)
{
bool getout = true;
/* This tries to mimic bash's IGNOREEOF feature. */
const char *val = GetVariable(pset.vars, "IGNOREEOF");
if (val)
{
long int maxeof;
char *endptr;
if (*val == '\0')
maxeof = 10;
else
{
maxeof = strtol(val, &endptr, 0);
if (*endptr != '\0') /* string not valid as a
* number */
maxeof = 10;
}
if (count_eof++ != maxeof)
getout = false; /* not quite there yet */
}
count_eof++;
if (getout)
{
if (QUIET())
putc('\n', stdout);
else
puts("\\q");
break;
}
else
if (count_eof < GetVariableNum(pset.vars,"IGNOREEOF",0,10,false))
{
if (!QUIET())
printf(gettext("Use \"\\q\" to leave %s.\n"), pset.progname);
continue;
}
puts(QUIET() ? "" : "\\q");
}
else
/* not interactive */
break;
}
else
count_eof = 0;
pset.lineno++;
......@@ -259,8 +223,7 @@ MainLoop(FILE *source)
}
/* echo back if flag is set */
var = GetVariable(pset.vars, "ECHO");
if (!pset.cur_cmd_interactive && var && strcmp(var, "all") == 0)
if (!pset.cur_cmd_interactive && VariableEquals(pset.vars, "ECHO", "all"))
puts(line);
fflush(stdout);
......@@ -276,14 +239,13 @@ MainLoop(FILE *source)
#define ADVANCE_1 (prevlen = thislen, i += thislen, thislen = PQmblen(line+i, pset.encoding))
success = true;
for (i = 0, prevlen = 0, thislen = (len > 0) ? PQmblen(line, pset.encoding) : 0;
i < len;
ADVANCE_1)
prevlen = 0;
thislen = ((len > 0) ? PQmblen(line, pset.encoding) : 0);
for (i = 0; (i < len) && (success || !die_on_error); ADVANCE_1)
{
/* was the previous character a backslash? */
bool was_bslash = (i > 0 && line[i - prevlen] == '\\');
if (was_bslash)
if (i > 0 && line[i - prevlen] == '\\')
bslash_count++;
else
bslash_count = 0;
......@@ -308,30 +270,24 @@ MainLoop(FILE *source)
in_quote = 0;
}
/* in extended comment? */
else if (in_xcomment)
{
if (line[i] == '*' && line[i + thislen] == '/')
{
if (xcdepth > 0)
xcdepth--;
else
/* start of extended comment? */
else if (line[i] == '/' && line[i + thislen] == '*')
{
in_xcomment = false;
in_xcomment++;
if (in_xcomment == 1)
ADVANCE_1;
}
}
else if (line[i] == '/' && line[i + thislen] == '*')
xcdepth++;
}
/* start of extended comment? */
else if (line[i] == '/' && line[i + thislen] == '*')
/* end of extended comment? */
else if (line[i] == '*' && line[i + thislen] == '/')
{
xcdepth = 0;
in_xcomment = true;
in_xcomment--;
if (in_xcomment <= 0)
{
in_xcomment = 0;
ADVANCE_1;
}
}
/* start of quote? */
else if (line[i] == '\'' || line[i] == '"')
......@@ -353,7 +309,7 @@ MainLoop(FILE *source)
/* colon -> substitute variable */
/* we need to be on the watch for the '::' operator */
else if (line[i] == ':' && !was_bslash
else if (line[i] == ':' && !bslash_count
&& strspn(line + i + thislen, VALID_VARIABLE_CHARS) > 0
&& !(prevlen > 0 && line[i - prevlen] == ':')
)
......@@ -411,7 +367,7 @@ MainLoop(FILE *source)
}
/* semicolon? then send query */
else if (line[i] == ';' && !was_bslash && !paren_level)
else if (line[i] == ';' && !bslash_count && !paren_level)
{
line[i] = '\0';
/* is there anything else on the line? */
......@@ -442,7 +398,7 @@ MainLoop(FILE *source)
* if you have a burning need to send a semicolon or colon to
* the backend ...
*/
else if (was_bslash && (line[i] == ';' || line[i] == ':'))
else if (bslash_count && (line[i] == ';' || line[i] == ':'))
{
/* remove the backslash */
memmove(line + i - prevlen, line + i, len - i + 1);
......@@ -451,7 +407,7 @@ MainLoop(FILE *source)
}
/* backslash command */
else if (was_bslash)
else if (bslash_count)
{
const char *end_of_cmd = NULL;
......@@ -499,15 +455,9 @@ MainLoop(FILE *source)
paren_level = 0;
/* process anything left after the backslash command */
i += end_of_cmd - &line[i];
i = end_of_cmd - line;
query_start = i;
}
/* stop the script after error */
if (!success && die_on_error)
break;
} /* for (line) */
......@@ -533,25 +483,19 @@ MainLoop(FILE *source)
if (query_buf->data[0] != '\0' && GetVariableBool(pset.vars, "SINGLELINE"))
{
success = SendQuery(query_buf->data);
slashCmdStatus = success ? CMD_SEND : CMD_ERROR;
slashCmdStatus = (success ? CMD_SEND : CMD_ERROR);
resetPQExpBuffer(previous_buf);
appendPQExpBufferStr(previous_buf, query_buf->data);
resetPQExpBuffer(query_buf);
}
if (!success && die_on_error && !pset.cur_cmd_interactive)
if (!pset.cur_cmd_interactive)
{
if (!success && die_on_error)
successResult = EXIT_USER;
break;
}
/* Have we lost the db connection? */
if (pset.db == NULL && !pset.cur_cmd_interactive)
{
else if (!pset.db)
successResult = EXIT_BADCONN;
break;
}
} /* while !endoffile/session */
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.22 2001/10/25 05:49:54 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.23 2003/03/20 06:43:35 momjian Exp $
*/
#include "postgres_fe.h"
#include "prompt.h"
......@@ -69,17 +69,30 @@ get_prompt(promptStatus_t status)
char buf[MAX_PROMPT_SIZE + 1];
bool esc = false;
const char *p;
const char *prompt_string;
const char *prompt_string = "? ";
const char *prompt_name = NULL;
if (status == PROMPT_READY)
prompt_string = GetVariable(pset.vars, "PROMPT1");
else if (status == PROMPT_CONTINUE || status == PROMPT_SINGLEQUOTE || status == PROMPT_DOUBLEQUOTE || status == PROMPT_COMMENT || status == PROMPT_PAREN)
prompt_string = GetVariable(pset.vars, "PROMPT2");
else if (status == PROMPT_COPY)
prompt_string = GetVariable(pset.vars, "PROMPT3");
else
prompt_string = "? ";
switch (status)
{
case PROMPT_READY:
prompt_name = "PROMPT1";
break;
case PROMPT_CONTINUE:
case PROMPT_SINGLEQUOTE:
case PROMPT_DOUBLEQUOTE:
case PROMPT_COMMENT:
case PROMPT_PAREN:
prompt_name = "PROMPT2";
break;
case PROMPT_COPY:
prompt_name = "PROMPT3";
break;
}
if (prompt_name)
prompt_string = GetVariable(pset.vars, prompt_name);
destination[0] = '\0';
......@@ -92,21 +105,15 @@ get_prompt(promptStatus_t status)
{
switch (*p)
{
case '%':
strcpy(buf, "%");
break;
/* Current database */
case '/':
if (pset.db)
strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE);
break;
case '~':
{
const char *var;
if (pset.db)
{
const char *var;
if (strcmp(PQdb(pset.db), PQuser(pset.db)) == 0 ||
((var = getenv("PGDATABASE")) && strcmp(var, PQdb(pset.db)) == 0))
strcpy(buf, "~");
......@@ -114,7 +121,7 @@ get_prompt(promptStatus_t status)
strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE);
}
break;
}
/* DB server hostname (long/short) */
case 'M':
case 'm':
......@@ -164,15 +171,8 @@ get_prompt(promptStatus_t status)
case '7':
case '8':
case '9':
{
long int l;
char *end;
l = strtol(p, &end, 0);
sprintf(buf, "%c", (unsigned char) l);
p = end - 1;
*buf = parse_char(&p);
break;
}
case 'R':
switch (status)
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.71 2003/03/18 22:15:44 petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.72 2003/03/20 06:43:35 momjian Exp $
*/
#include "postgres_fe.h"
......@@ -253,10 +253,9 @@ main(int argc, char *argv[])
*/
else if (options.action == ACT_SINGLE_SLASH)
{
const char *value;
if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all") == 0)
if (VariableEquals(pset.vars, "ECHO", "all"))
puts(options.action_string);
successResult = HandleSlashCmds(options.action_string, NULL, NULL, NULL) != CMD_ERROR
? EXIT_SUCCESS : EXIT_FAILURE;
}
......@@ -266,10 +265,9 @@ main(int argc, char *argv[])
*/
else if (options.action == ACT_SINGLE_QUERY)
{
const char *value;
if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all") == 0)
if (VariableEquals(pset.vars, "ECHO", "all"))
puts(options.action_string);
successResult = SendQuery(options.action_string)
? EXIT_SUCCESS : EXIT_FAILURE;
}
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/variables.c,v 1.9 2001/02/10 02:31:28 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/variables.c,v 1.10 2003/03/20 06:43:35 momjian Exp $
*/
#include "postgres_fe.h"
#include "variables.h"
......@@ -68,6 +68,74 @@ GetVariableBool(VariableSpace space, const char *name)
}
bool
VariableEquals(VariableSpace space, const char name[], const char value[])
{
const char *var;
var = GetVariable(space, name);
return var && (strcmp(var, value) == 0);
}
int
GetVariableNum(VariableSpace space,
const char name[],
int defaultval,
int faultval,
bool allowtrail)
{
const char *var;
int result;
var = GetVariable(space, name);
if (!var)
result = defaultval;
else if (!var[0])
result = faultval;
else
{
char *end;
result = strtol(var, &end, 0);
if (!allowtrail && *end)
result = faultval;
}
return result;
}
int
SwitchVariable(VariableSpace space, const char name[], const char *opt, ...)
{
int result;
const char *var;
var = GetVariable(space, name);
if (var)
{
va_list args;
va_start(args, opt);
for (result=1; opt && (strcmp(var, opt) != 0); result++)
opt = va_arg(args,const char *);
if (!opt) result = var_notfound;
va_end(args);
}
else
result = var_notset;
return result;
}
void
PrintVariables(VariableSpace space)
{
struct _variable *ptr;
for (ptr = space->next; ptr; ptr = ptr->next)
printf("%s = '%s'\n", ptr->name, ptr->value);
}
bool
SetVariable(VariableSpace space, const char *name, const char *value)
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/variables.h,v 1.10 2001/11/05 17:46:31 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/variables.h,v 1.11 2003/03/20 06:43:35 momjian Exp $
*/
/*
......@@ -30,10 +30,33 @@ typedef struct _variable *VariableSpace;
VariableSpace CreateVariableSpace(void);
const char *GetVariable(VariableSpace space, const char *name);
bool GetVariableBool(VariableSpace space, const char *name);
bool SetVariable(VariableSpace space, const char *name, const char *value);
bool SetVariableBool(VariableSpace space, const char *name);
bool DeleteVariable(VariableSpace space, const char *name);
void DestroyVariableSpace(VariableSpace space);
bool GetVariableBool(VariableSpace space, const char *name);
bool VariableEquals(VariableSpace space, const char name[], const char *opt);
/* 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
* include the case where there are trailing characters after the number.
*/
int GetVariableNum(VariableSpace space,
const char name[],
int defaultval,
int faultval,
bool allowtrail);
/* Find value of variable <name> among NULL-terminated list of alternative
* options. Returns var_notset if the variable was not set, var_notfound if its
* value did not occur in the list of options, or the number of the matching
* option. The first option is 1, the second is 2 and so on.
*/
enum { var_notset = 0, var_notfound = -1 };
int SwitchVariable(VariableSpace space, const char name[], const char *opt,...);
void PrintVariables(VariableSpace space);
bool SetVariable(VariableSpace space, const char *name, const char *value);
bool SetVariableBool(VariableSpace space, const char *name);
bool DeleteVariable(VariableSpace space, const char *name);
void DestroyVariableSpace(VariableSpace space);
#endif /* VARIABLES_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment