00001
00002
00003
00004
00005
00006
00007
00008 #include "postgres_fe.h"
00009
00010 #include "common.h"
00011 #include "variables.h"
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 static bool
00022 valid_variable_name(const char *name)
00023 {
00024 const unsigned char *ptr = (const unsigned char *) name;
00025
00026
00027 if (*ptr == '\0')
00028 return false;
00029
00030 while (*ptr)
00031 {
00032 if (IS_HIGHBIT_SET(*ptr) ||
00033 strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
00034 "_0123456789", *ptr) != NULL)
00035 ptr++;
00036 else
00037 return false;
00038 }
00039
00040 return true;
00041 }
00042
00043
00044
00045
00046
00047 VariableSpace
00048 CreateVariableSpace(void)
00049 {
00050 struct _variable *ptr;
00051
00052 ptr = pg_malloc(sizeof *ptr);
00053 ptr->name = NULL;
00054 ptr->value = NULL;
00055 ptr->assign_hook = NULL;
00056 ptr->next = NULL;
00057
00058 return ptr;
00059 }
00060
00061 const char *
00062 GetVariable(VariableSpace space, const char *name)
00063 {
00064 struct _variable *current;
00065
00066 if (!space)
00067 return NULL;
00068
00069 for (current = space->next; current; current = current->next)
00070 {
00071 if (strcmp(current->name, name) == 0)
00072 {
00073
00074 return current->value;
00075 }
00076 }
00077
00078 return NULL;
00079 }
00080
00081
00082
00083
00084
00085 bool
00086 ParseVariableBool(const char *value)
00087 {
00088 size_t len;
00089
00090 if (value == NULL)
00091 return false;
00092
00093 len = strlen(value);
00094
00095 if (pg_strncasecmp(value, "true", len) == 0)
00096 return true;
00097 else if (pg_strncasecmp(value, "false", len) == 0)
00098 return false;
00099 else if (pg_strncasecmp(value, "yes", len) == 0)
00100 return true;
00101 else if (pg_strncasecmp(value, "no", len) == 0)
00102 return false;
00103
00104 else if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
00105 return true;
00106 else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
00107 return false;
00108 else if (pg_strcasecmp(value, "1") == 0)
00109 return true;
00110 else if (pg_strcasecmp(value, "0") == 0)
00111 return false;
00112 else
00113 {
00114
00115 psql_error("unrecognized Boolean value; assuming \"on\"\n");
00116 return true;
00117 }
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 int
00127 ParseVariableNum(const char *val,
00128 int defaultval,
00129 int faultval,
00130 bool allowtrail)
00131 {
00132 int result;
00133
00134 if (!val)
00135 result = defaultval;
00136 else if (!val[0])
00137 result = faultval;
00138 else
00139 {
00140 char *end;
00141
00142 result = strtol(val, &end, 0);
00143 if (!allowtrail && *end)
00144 result = faultval;
00145 }
00146
00147 return result;
00148 }
00149
00150 int
00151 GetVariableNum(VariableSpace space,
00152 const char *name,
00153 int defaultval,
00154 int faultval,
00155 bool allowtrail)
00156 {
00157 const char *val;
00158
00159 val = GetVariable(space, name);
00160 return ParseVariableNum(val, defaultval, faultval, allowtrail);
00161 }
00162
00163 void
00164 PrintVariables(VariableSpace space)
00165 {
00166 struct _variable *ptr;
00167
00168 if (!space)
00169 return;
00170
00171 for (ptr = space->next; ptr; ptr = ptr->next)
00172 {
00173 if (ptr->value)
00174 printf("%s = '%s'\n", ptr->name, ptr->value);
00175 if (cancel_pressed)
00176 break;
00177 }
00178 }
00179
00180 bool
00181 SetVariable(VariableSpace space, const char *name, const char *value)
00182 {
00183 struct _variable *current,
00184 *previous;
00185
00186 if (!space)
00187 return false;
00188
00189 if (!valid_variable_name(name))
00190 return false;
00191
00192 if (!value)
00193 return DeleteVariable(space, name);
00194
00195 for (previous = space, current = space->next;
00196 current;
00197 previous = current, current = current->next)
00198 {
00199 if (strcmp(current->name, name) == 0)
00200 {
00201
00202 if (current->value)
00203 free(current->value);
00204 current->value = pg_strdup(value);
00205 if (current->assign_hook)
00206 (*current->assign_hook) (current->value);
00207 return true;
00208 }
00209 }
00210
00211
00212 current = pg_malloc(sizeof *current);
00213 current->name = pg_strdup(name);
00214 current->value = pg_strdup(value);
00215 current->assign_hook = NULL;
00216 current->next = NULL;
00217 previous->next = current;
00218 return true;
00219 }
00220
00221
00222
00223
00224 bool
00225 SetVariableAssignHook(VariableSpace space, const char *name, VariableAssignHook hook)
00226 {
00227 struct _variable *current,
00228 *previous;
00229
00230 if (!space)
00231 return false;
00232
00233 if (!valid_variable_name(name))
00234 return false;
00235
00236 for (previous = space, current = space->next;
00237 current;
00238 previous = current, current = current->next)
00239 {
00240 if (strcmp(current->name, name) == 0)
00241 {
00242
00243 current->assign_hook = hook;
00244 (*hook) (current->value);
00245 return true;
00246 }
00247 }
00248
00249
00250 current = pg_malloc(sizeof *current);
00251 current->name = pg_strdup(name);
00252 current->value = NULL;
00253 current->assign_hook = hook;
00254 current->next = NULL;
00255 previous->next = current;
00256 (*hook) (NULL);
00257 return true;
00258 }
00259
00260 bool
00261 SetVariableBool(VariableSpace space, const char *name)
00262 {
00263 return SetVariable(space, name, "on");
00264 }
00265
00266 bool
00267 DeleteVariable(VariableSpace space, const char *name)
00268 {
00269 struct _variable *current,
00270 *previous;
00271
00272 if (!space)
00273 return false;
00274
00275 for (previous = space, current = space->next;
00276 current;
00277 previous = current, current = current->next)
00278 {
00279 if (strcmp(current->name, name) == 0)
00280 {
00281 if (current->value)
00282 free(current->value);
00283 current->value = NULL;
00284
00285 if (current->assign_hook)
00286 (*current->assign_hook) (NULL);
00287 else
00288 {
00289 previous->next = current->next;
00290 free(current->name);
00291 free(current);
00292 }
00293 return true;
00294 }
00295 }
00296
00297 return true;
00298 }