Commit 0e6652e6 authored by Bruce Momjian's avatar Bruce Momjian

psql cleanup

parent 2323b636
This diff is collapsed.
...@@ -11,39 +11,36 @@ ...@@ -11,39 +11,36 @@
typedef enum _backslashResult { typedef enum _backslashResult
CMD_UNKNOWN = 0, /* not done parsing yet (internal only) */ {
CMD_SEND, /* query complete; send off */ CMD_UNKNOWN = 0, /* not done parsing yet (internal only) */
CMD_SKIP_LINE, /* keep building query */ CMD_SEND, /* query complete; send off */
CMD_TERMINATE, /* quit program */ CMD_SKIP_LINE, /* keep building query */
CMD_NEWEDIT, /* query buffer was changed (e.g., via \e) */ CMD_TERMINATE, /* quit program */
CMD_ERROR /* the execution of the backslash command resulted CMD_NEWEDIT, /* query buffer was changed (e.g., via \e) */
in an error */ CMD_ERROR /* the execution of the backslash command
} backslashResult; * resulted in an error */
} backslashResult;
backslashResult
HandleSlashCmds(PsqlSettings *pset, backslashResult HandleSlashCmds(PsqlSettings *pset,
const char *line, const char *line,
PQExpBuffer query_buf, PQExpBuffer query_buf,
const char ** end_of_cmd); const char **end_of_cmd);
bool bool do_connect(const char *new_dbname,
do_connect(const char *new_dbname, const char *new_user,
const char *new_user, PsqlSettings *pset);
PsqlSettings *pset);
bool process_file(const char *filename,
bool PsqlSettings *pset);
process_file(const char *filename,
PsqlSettings *pset);
bool do_pset(const char *param,
const char *value,
bool printQueryOpt * popt,
do_pset(const char * param, bool quiet);
const char * value,
printQueryOpt * popt,
bool quiet);
#endif #endif
This diff is collapsed.
...@@ -5,21 +5,21 @@ ...@@ -5,21 +5,21 @@
#include "settings.h" #include "settings.h"
char * char *
xstrdup(const char * string); xstrdup(const char *string);
bool bool
setQFout(const char *fname, PsqlSettings *pset); setQFout(const char *fname, PsqlSettings *pset);
char * char *
simple_prompt(const char *prompt, int maxlen, bool echo); simple_prompt(const char *prompt, int maxlen, bool echo);
const char * const char *
interpolate_var(const char * name, PsqlSettings * pset); interpolate_var(const char *name, PsqlSettings *pset);
PGresult * PGresult *
PSQLexec(PsqlSettings *pset, const char *query); PSQLexec(PsqlSettings *pset, const char *query);
bool bool
SendQuery(PsqlSettings *pset, const char *query); SendQuery(PsqlSettings *pset, const char *query);
#endif /* COMMON_H */ #endif /* COMMON_H */
This diff is collapsed.
...@@ -8,15 +8,15 @@ ...@@ -8,15 +8,15 @@
/* handler for \copy */ /* handler for \copy */
bool bool
do_copy(const char *args, PsqlSettings *pset); do_copy(const char *args, PsqlSettings *pset);
/* lower level processors for copy in/out streams */ /* lower level processors for copy in/out streams */
bool bool
handleCopyOut(PGconn *conn, FILE *copystream); handleCopyOut(PGconn *conn, FILE *copystream);
bool bool
handleCopyIn(PGconn *conn, FILE *copystream, const char * prompt); handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt);
#endif #endif
This diff is collapsed.
...@@ -5,38 +5,38 @@ ...@@ -5,38 +5,38 @@
/* \da */ /* \da */
bool bool
describeAggregates(const char * name, PsqlSettings * pset); describeAggregates(const char *name, PsqlSettings *pset);
/* \df */ /* \df */
bool bool
describeFunctions(const char * name, PsqlSettings * pset); describeFunctions(const char *name, PsqlSettings *pset);
/* \dT */ /* \dT */
bool bool
describeTypes(const char * name, PsqlSettings * pset); describeTypes(const char *name, PsqlSettings *pset);
/* \do */ /* \do */
bool bool
describeOperators(const char * name, PsqlSettings * pset); describeOperators(const char *name, PsqlSettings *pset);
/* \dp (formerly \z) */ /* \dp (formerly \z) */
bool bool
permissionsList(const char * name, PsqlSettings *pset); permissionsList(const char *name, PsqlSettings *pset);
/* \dd */ /* \dd */
bool bool
objectDescription(const char * object, PsqlSettings *pset); objectDescription(const char *object, PsqlSettings *pset);
/* \d foo */ /* \d foo */
bool bool
describeTableDetails(const char * name, PsqlSettings * pset); describeTableDetails(const char *name, PsqlSettings *pset);
/* \l */ /* \l */
bool bool
listAllDbs(PsqlSettings *pset); listAllDbs(PsqlSettings *pset);
/* \dt, \di, \dS, etc. */ /* \dt, \di, \dS, etc. */
bool bool
listTables(const char * infotype, const char * name, PsqlSettings * pset); listTables(const char *infotype, const char *name, PsqlSettings *pset);
#endif /* DESCRIBE_H */ #endif /* DESCRIBE_H */
This diff is collapsed.
...@@ -3,14 +3,13 @@ ...@@ -3,14 +3,13 @@
#include "settings.h" #include "settings.h"
void usage(void); void usage(void);
void slashUsage(PsqlSettings *pset); void slashUsage(PsqlSettings *pset);
void helpSQL(const char *topic); void helpSQL(const char *topic);
void print_copyright(void); void print_copyright(void);
#endif #endif
...@@ -10,9 +10,11 @@ ...@@ -10,9 +10,11 @@
/* (of course there is no runtime command for doing that :) */ /* (of course there is no runtime command for doing that :) */
#ifdef USE_READLINE #ifdef USE_READLINE
static bool useReadline; static bool useReadline;
#endif #endif
#ifdef USE_HISTORY #ifdef USE_HISTORY
static bool useHistory; static bool useHistory;
#endif #endif
...@@ -25,29 +27,31 @@ static bool useHistory; ...@@ -25,29 +27,31 @@ static bool useHistory;
char * char *
gets_interactive(const char *prompt) gets_interactive(const char *prompt)
{ {
char * s; char *s;
#ifdef USE_READLINE #ifdef USE_READLINE
if (useReadline) { if (useReadline)
s = readline(prompt); {
fputc('\r', stdout); s = readline(prompt);
fflush(stdout); fputc('\r', stdout);
} fflush(stdout);
else { }
else
{
#endif #endif
fputs(prompt, stdout); fputs(prompt, stdout);
fflush(stdout); fflush(stdout);
s = gets_fromFile(stdin); s = gets_fromFile(stdin);
#ifdef USE_READLINE #ifdef USE_READLINE
} }
#endif #endif
#ifdef USE_HISTORY #ifdef USE_HISTORY
if (useHistory && s && s[0] != '\0') if (useHistory && s && s[0] != '\0')
add_history(s); add_history(s);
#endif #endif
return s; return s;
} }
...@@ -60,25 +64,27 @@ gets_interactive(const char *prompt) ...@@ -60,25 +64,27 @@ gets_interactive(const char *prompt)
char * char *
gets_fromFile(FILE *source) gets_fromFile(FILE *source)
{ {
PQExpBufferData buffer; PQExpBufferData buffer;
char line[1024]; char line[1024];
initPQExpBuffer(&buffer); initPQExpBuffer(&buffer);
while (fgets(line, 1024, source) != NULL) { while (fgets(line, 1024, source) != NULL)
appendPQExpBufferStr(&buffer, line); {
if (buffer.data[buffer.len-1] == '\n') { appendPQExpBufferStr(&buffer, line);
buffer.data[buffer.len-1] = '\0'; if (buffer.data[buffer.len - 1] == '\n')
return buffer.data; {
buffer.data[buffer.len - 1] = '\0';
return buffer.data;
}
} }
}
if (buffer.len > 0) if (buffer.len > 0)
return buffer.data; /* EOF after reading some bufferload(s) */ return buffer.data; /* EOF after reading some bufferload(s) */
/* EOF, so return null */ /* EOF, so return null */
termPQExpBuffer(&buffer); termPQExpBuffer(&buffer);
return NULL; return NULL;
} }
...@@ -93,28 +99,33 @@ void ...@@ -93,28 +99,33 @@ void
initializeInput(int flags) initializeInput(int flags)
{ {
#ifdef USE_READLINE #ifdef USE_READLINE
if (flags == 1) { if (flags == 1)
useReadline = true; {
rl_readline_name = "psql"; useReadline = true;
} rl_readline_name = "psql";
}
#endif #endif
#ifdef USE_HISTORY #ifdef USE_HISTORY
if (flags == 1) { if (flags == 1)
const char * home; {
const char *home;
useHistory = true;
using_history(); useHistory = true;
home = getenv("HOME"); using_history();
if (home) { home = getenv("HOME");
char * psql_history = (char *) malloc(strlen(home) + 20); if (home)
if (psql_history) { {
sprintf(psql_history, "%s/.psql_history", home); char *psql_history = (char *) malloc(strlen(home) + 20);
read_history(psql_history);
free(psql_history); if (psql_history)
} {
sprintf(psql_history, "%s/.psql_history", home);
read_history(psql_history);
free(psql_history);
}
}
} }
}
#endif #endif
} }
...@@ -124,17 +135,19 @@ bool ...@@ -124,17 +135,19 @@ bool
saveHistory(const char *fname) saveHistory(const char *fname)
{ {
#ifdef USE_HISTORY #ifdef USE_HISTORY
if (useHistory) { if (useHistory)
if (write_history(fname) != 0) { {
perror(fname); if (write_history(fname) != 0)
return false; {
perror(fname);
return false;
}
return true;
} }
return true; else
} return false;
else
return false;
#else #else
return false; return false;
#endif #endif
} }
...@@ -144,19 +157,22 @@ void ...@@ -144,19 +157,22 @@ void
finishInput(void) finishInput(void)
{ {
#ifdef USE_HISTORY #ifdef USE_HISTORY
if (useHistory) { if (useHistory)
char * home; {
char * psql_history; char *home;
char *psql_history;
home = getenv("HOME");
if (home) { home = getenv("HOME");
psql_history = (char *) malloc(strlen(home) + 20); if (home)
if (psql_history) { {
sprintf(psql_history, "%s/.psql_history", home); psql_history = (char *) malloc(strlen(home) + 20);
write_history(psql_history); if (psql_history)
free(psql_history); {
} sprintf(psql_history, "%s/.psql_history", home);
write_history(psql_history);
free(psql_history);
}
}
} }
}
#endif #endif
} }
...@@ -38,19 +38,19 @@ ...@@ -38,19 +38,19 @@
char * char *
gets_interactive(const char *prompt); gets_interactive(const char *prompt);
char * char *
gets_fromFile(FILE *source); gets_fromFile(FILE *source);
void void
initializeInput(int flags); initializeInput(int flags);
bool bool
saveHistory(const char *fname); saveHistory(const char *fname);
void void
finishInput(void); finishInput(void);
#endif #endif
This diff is collapsed.
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
#include "settings.h" #include "settings.h"
bool do_lo_export(PsqlSettings * pset, const char * loid_arg, const char * filename_arg); bool do_lo_export(PsqlSettings *pset, const char *loid_arg, const char *filename_arg);
bool do_lo_import(PsqlSettings * pset, const char * filename_arg, const char * comment_arg); bool do_lo_import(PsqlSettings *pset, const char *filename_arg, const char *comment_arg);
bool do_lo_unlink(PsqlSettings * pset, const char * loid_arg); bool do_lo_unlink(PsqlSettings *pset, const char *loid_arg);
bool do_lo_list(PsqlSettings * pset); bool do_lo_list(PsqlSettings *pset);
#endif /* LARGE_OBJ_H */ #endif /* LARGE_OBJ_H */
This diff is collapsed.
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
#include "settings.h" #include "settings.h"
int int
MainLoop(PsqlSettings *pset, FILE *source); MainLoop(PsqlSettings *pset, FILE *source);
#endif MAINLOOP_H #endif /* MAINLOOP_H */
This diff is collapsed.
...@@ -7,52 +7,58 @@ ...@@ -7,52 +7,58 @@
#include <stdio.h> #include <stdio.h>
#include <libpq-fe.h> #include <libpq-fe.h>
enum printFormat { enum printFormat
PRINT_NOTHING = 0, /* to make sure someone initializes this */ {
PRINT_UNALIGNED, PRINT_NOTHING = 0, /* to make sure someone initializes this */
PRINT_ALIGNED, PRINT_UNALIGNED,
PRINT_HTML, PRINT_ALIGNED,
PRINT_LATEX PRINT_HTML,
/* add your favourite output format here ... */ PRINT_LATEX
/* add your favourite output format here ... */
}; };
typedef struct _printTableOpt { typedef struct _printTableOpt
enum printFormat format; /* one of the above */ {
bool expanded; /* expanded/vertical output (if supported by output format) */ enum printFormat format; /* one of the above */
bool pager; /* use pager for output (if to stdout and stdout is a tty) */ bool expanded; /* expanded/vertical output (if supported
bool tuples_only; /* don't output headers, row counts, etc. */ * by output format) */
unsigned short int border; /* Print a border around the table. 0=none, 1=dividing lines, 2=full */ bool pager; /* use pager for output (if to stdout and
char *fieldSep; /* field separator for unaligned text mode */ * stdout is a tty) */
char *tableAttr; /* attributes for HTML <table ...> */ bool tuples_only; /* don't output headers, row counts, etc. */
} printTableOpt; unsigned short int border; /* Print a border around the table.
* 0=none, 1=dividing lines, 2=full */
char *fieldSep; /* field separator for unaligned text mode */
char *tableAttr; /* attributes for HTML <table ...> */
} printTableOpt;
/* /*
* Use this to print just any table in the supported formats. * Use this to print just any table in the supported formats.
* - title is just any string (NULL is fine) * - title is just any string (NULL is fine)
* - headers is the column headings (NULL ptr terminated). It must be given and * - headers is the column headings (NULL ptr terminated). It must be given and
* complete since the column count is generated from this. * complete since the column count is generated from this.
* - cells are the data cells to be printed. Now you know why the correct * - cells are the data cells to be printed. Now you know why the correct
* column count is important * column count is important
* - footers are lines to be printed below the table * - footers are lines to be printed below the table
* - align is an 'l' or an 'r' for every column, if the output format needs it. * - align is an 'l' or an 'r' for every column, if the output format needs it.
* (You must specify this long enough. Otherwise anything could happen.) * (You must specify this long enough. Otherwise anything could happen.)
*/ */
void void printTable(const char *title, char **headers, char **cells, char **footers,
printTable(const char * title, char ** headers, char ** cells, char ** footers, const char *align,
const char * align, const printTableOpt * opt, FILE *fout);
const printTableOpt * opt, FILE * fout);
typedef struct _printQueryOpt { typedef struct _printQueryOpt
printTableOpt topt; /* the options above */ {
char * nullPrint; /* how to print null entities */ printTableOpt topt; /* the options above */
bool quote; /* quote all values as much as possible */ char *nullPrint; /* how to print null entities */
char * title; /* override title */ bool quote; /* quote all values as much as possible */
char ** footers; /* override footer (default is "(xx rows)") */ char *title; /* override title */
} printQueryOpt; char **footers; /* override footer (default is "(xx
* rows)") */
} printQueryOpt;
/* /*
* Use this to print query results * Use this to print query results
...@@ -60,7 +66,7 @@ typedef struct _printQueryOpt { ...@@ -60,7 +66,7 @@ typedef struct _printQueryOpt {
* It calls the printTable above with all the things set straight. * It calls the printTable above with all the things set straight.
*/ */
void void
printQuery(PGresult * result, const printQueryOpt * opt, FILE * fout); printQuery(PGresult *result, const printQueryOpt * opt, FILE *fout);
#endif /* PRINT_H */ #endif /* PRINT_H */
This diff is collapsed.
...@@ -3,17 +3,18 @@ ...@@ -3,17 +3,18 @@
#include "settings.h" #include "settings.h"
typedef enum _promptStatus { typedef enum _promptStatus
PROMPT_READY, {
PROMPT_CONTINUE, PROMPT_READY,
PROMPT_COMMENT, PROMPT_CONTINUE,
PROMPT_SINGLEQUOTE, PROMPT_COMMENT,
PROMPT_DOUBLEQUOTE, PROMPT_SINGLEQUOTE,
PROMPT_COPY PROMPT_DOUBLEQUOTE,
} promptStatus_t; PROMPT_COPY
} promptStatus_t;
const char * const char *
get_prompt(PsqlSettings *pset, promptStatus_t status); get_prompt(PsqlSettings *pset, promptStatus_t status);
#endif /* PROMPT_H */ #endif /* PROMPT_H */
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: psqlHelp.h,v 1.80 1999/10/29 23:52:22 momjian Exp $ * $Id: psqlHelp.h,v 1.81 1999/11/04 23:14:29 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -384,5 +384,6 @@ TIMEZONE|XACTISOLEVEL|CLIENT_ENCODING|SERVER_ENCODING"}, ...@@ -384,5 +384,6 @@ TIMEZONE|XACTISOLEVEL|CLIENT_ENCODING|SERVER_ENCODING"},
\tVACUUM [VERBOSE] [ANALYZE] [table]\n\ \tVACUUM [VERBOSE] [ANALYZE] [table]\n\
\tor\n\ \tor\n\
\tVACUUM [VERBOSE] ANALYZE [table [(column_name1, ...column_nameN)]];"}, \tVACUUM [VERBOSE] ANALYZE [table [(column_name1, ...column_nameN)]];"},
{NULL, NULL, NULL} /* important to keep a NULL terminator here!*/ {NULL, NULL, NULL} /* important to keep a NULL terminator
* here! */
}; };
...@@ -20,24 +20,27 @@ ...@@ -20,24 +20,27 @@
typedef struct _psqlSettings typedef struct _psqlSettings
{ {
PGconn *db; /* connection to backend */ PGconn *db; /* connection to backend */
FILE *queryFout; /* where to send the query results */ FILE *queryFout; /* where to send the query results */
bool queryFoutPipe; /* queryFout is from a popen() */ bool queryFoutPipe; /* queryFout is from a popen() */
printQueryOpt popt; printQueryOpt popt;
VariableSpace vars; /* "shell variable" repository */ VariableSpace vars; /* "shell variable" repository */
char *gfname; /* one-shot file output argument for \g */ char *gfname; /* one-shot file output argument for \g */
bool notty; /* stdin or stdout is not a tty (as determined on startup) */ bool notty; /* stdin or stdout is not a tty (as
bool useReadline; /* use libreadline routines */ * determined on startup) */
bool useHistory; bool useReadline; /* use libreadline routines */
bool getPassword; /* prompt the user for a username and bool useHistory;
password */ bool getPassword; /* prompt the user for a username and
FILE * cur_cmd_source; /* describe the status of the current main loop */ * password */
bool cur_cmd_interactive; FILE *cur_cmd_source; /* describe the status of the current main
* loop */
bool has_client_encoding; /* was PGCLIENTENCODING set on startup? */ bool cur_cmd_interactive;
bool has_client_encoding; /* was PGCLIENTENCODING set on
* startup? */
} PsqlSettings; } PsqlSettings;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -3,12 +3,11 @@ ...@@ -3,12 +3,11 @@
/* The cooler version of strtok() which knows about quotes and doesn't /* The cooler version of strtok() which knows about quotes and doesn't
* overwrite your input */ * overwrite your input */
extern char * extern char *strtokx(const char *s,
strtokx(const char *s, const char *delim,
const char *delim, const char *quote,
const char *quote, char escape,
char escape, char *was_quoted,
char * was_quoted, unsigned int *token_pos);
unsigned int * token_pos);
#endif /* STRINGUTILS_H */ #endif /* STRINGUTILS_H */
...@@ -6,127 +6,145 @@ ...@@ -6,127 +6,145 @@
#include <assert.h> #include <assert.h>
VariableSpace CreateVariableSpace(void) VariableSpace
CreateVariableSpace(void)
{ {
struct _variable *ptr; struct _variable *ptr;
ptr = calloc(1, sizeof *ptr); ptr = calloc(1, sizeof *ptr);
if (!ptr) return NULL; if (!ptr)
return NULL;
ptr->name = strdup("@");
ptr->value = strdup("");
if (!ptr->name || !ptr->value)
{
free(ptr->name);
free(ptr->value);
free(ptr);
return NULL;
}
ptr->name = strdup("@"); return ptr;
ptr->value = strdup("");
if (!ptr->name || !ptr->value) {
free(ptr->name);
free(ptr->value);
free(ptr);
return NULL;
}
return ptr;
} }
const char * GetVariable(VariableSpace space, const char * name) const char *
GetVariable(VariableSpace space, const char *name)
{ {
struct _variable *current; struct _variable *current;
if (!space) if (!space)
return NULL; return NULL;
if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name)) return NULL; if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name))
return NULL;
for (current = space; current; current = current->next) { for (current = space; current; current = current->next)
{
#ifdef USE_ASSERT_CHECKING #ifdef USE_ASSERT_CHECKING
assert(current->name); assert(current->name);
assert(current->value); assert(current->value);
#endif #endif
if (strcmp(current->name, name)==0) if (strcmp(current->name, name) == 0)
return current->value; return current->value;
} }
return NULL; return NULL;
} }
bool GetVariableBool(VariableSpace space, const char * name) bool
GetVariableBool(VariableSpace space, const char *name)
{ {
return GetVariable(space, name)!=NULL ? true : false; return GetVariable(space, name) != NULL ? true : false;
} }
bool SetVariable(VariableSpace space, const char * name, const char * value) bool
SetVariable(VariableSpace space, const char *name, const char *value)
{ {
struct _variable *current, *previous; struct _variable *current,
*previous;
if (!space) if (!space)
return false; return false;
if (!value) if (!value)
return DeleteVariable(space, name); return DeleteVariable(space, name);
if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name)) return false; if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name))
return false;
for (current = space; current; previous = current, current = current->next) { for (current = space; current; previous = current, current = current->next)
{
#ifdef USE_ASSERT_CHECKING #ifdef USE_ASSERT_CHECKING
assert(current->name); assert(current->name);
assert(current->value); assert(current->value);
#endif #endif
if (strcmp(current->name, name)==0) { if (strcmp(current->name, name) == 0)
free (current->value); {
current->value = strdup(value); free(current->value);
return current->value ? true : false; current->value = strdup(value);
return current->value ? true : false;
}
} }
}
previous->next = calloc(1, sizeof *(previous->next));
previous->next = calloc(1, sizeof *(previous->next)); if (!previous->next)
if (!previous->next) return false;
return false; previous->next->name = strdup(name);
previous->next->name = strdup(name); if (!previous->next->name)
if (!previous->next->name) return false;
return false; previous->next->value = strdup(value);
previous->next->value = strdup(value); return previous->next->value ? true : false;
return previous->next->value ? true : false;
} }
bool DeleteVariable(VariableSpace space, const char * name) bool
DeleteVariable(VariableSpace space, const char *name)
{ {
struct _variable *current, *previous; struct _variable *current,
*previous;
if (!space) if (!space)
return false; return false;
if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name)) return false; if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name))
return false;
for (current = space, previous = NULL; current; previous = current, current = current->next) { for (current = space, previous = NULL; current; previous = current, current = current->next)
{
#ifdef USE_ASSERT_CHECKING #ifdef USE_ASSERT_CHECKING
assert(current->name); assert(current->name);
assert(current->value); assert(current->value);
#endif #endif
if (strcmp(current->name, name)==0) { if (strcmp(current->name, name) == 0)
free (current->name); {
free (current->value); free(current->name);
if (previous) free(current->value);
previous->next = current->next; if (previous)
free(current); previous->next = current->next;
return true; free(current);
return true;
}
} }
}
return true; return true;
} }
void DestroyVariableSpace(VariableSpace space) void
DestroyVariableSpace(VariableSpace space)
{ {
if (!space) if (!space)
return; return;
DestroyVariableSpace(space->next); DestroyVariableSpace(space->next);
free(space); free(space);
} }
...@@ -13,21 +13,22 @@ ...@@ -13,21 +13,22 @@
#define VALID_VARIABLE_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_" #define VALID_VARIABLE_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_"
struct _variable { struct _variable
char * name; {
char * value; char *name;
struct _variable * next; char *value;
struct _variable *next;
}; };
typedef struct _variable * VariableSpace; typedef struct _variable *VariableSpace;
VariableSpace CreateVariableSpace(void); VariableSpace CreateVariableSpace(void);
const char * GetVariable(VariableSpace space, const char * name); const char *GetVariable(VariableSpace space, const char *name);
bool GetVariableBool(VariableSpace space, const char * name); bool GetVariableBool(VariableSpace space, const char *name);
bool SetVariable(VariableSpace space, const char * name, const char * value); bool SetVariable(VariableSpace space, const char *name, const char *value);
bool DeleteVariable(VariableSpace space, const char * name); bool DeleteVariable(VariableSpace space, const char *name);
void DestroyVariableSpace(VariableSpace space); void DestroyVariableSpace(VariableSpace space);
#endif /* VARIABLES_H */ #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