PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/common/options/monet_options.c

https://bitbucket.org/msaecker/monetdb-opencl
C | 338 lines | 268 code | 31 blank | 39 comment | 62 complexity | d9a781fae494f5b598f5d8cb51bbfb25 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.0
  1. /*
  2. * The contents of this file are subject to the MonetDB Public License
  3. * Version 1.1 (the "License"); you may not use this file except in
  4. * compliance with the License. You may obtain a copy of the License at
  5. * http://www.monetdb.org/Legal/MonetDBLicense
  6. *
  7. * Software distributed under the License is distributed on an "AS IS"
  8. * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  9. * License for the specific language governing rights and limitations
  10. * under the License.
  11. *
  12. * The Original Code is the MonetDB Database System.
  13. *
  14. * The Initial Developer of the Original Code is CWI.
  15. * Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
  16. * Copyright August 2008-2014 MonetDB B.V.
  17. * All Rights Reserved.
  18. */
  19. /*
  20. * @f monet_options
  21. * @a N.J. Nes
  22. * @* A simple option handling library
  23. * @T
  24. * The monet server and clients make use of command line options and a (possibly)
  25. * shared config file. With this library a set (represented by set,setlen) of
  26. * options is created. An option is stored as name and value strings with a
  27. * special flag indicating the origin of the options, (builtin, system config
  28. * file, special config file or command line option).
  29. *
  30. */
  31. #include "monetdb_config.h"
  32. #include "monet_options.h"
  33. #ifndef HAVE_GETOPT_LONG
  34. # include "monet_getopt.h"
  35. #else
  36. # ifdef HAVE_GETOPT_H
  37. # include "getopt.h"
  38. # endif
  39. #endif
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include <ctype.h>
  43. #ifdef HAVE_UNISTD_H
  44. #include <unistd.h>
  45. #endif
  46. #ifndef HAVE_GETOPT_LONG
  47. # include "getopt.c"
  48. # include "getopt1.c"
  49. #endif
  50. #ifdef NATIVE_WIN32
  51. #define getpid _getpid
  52. #endif
  53. /* these two are used of the set parameter passed into functions is NULL */
  54. static int default_setlen = 0;
  55. static opt *default_set = NULL;
  56. static int
  57. mo_default_set(opt **Set, int setlen)
  58. {
  59. if (*Set == NULL) {
  60. if (default_set == NULL) {
  61. default_setlen = mo_builtin_settings(&default_set);
  62. default_setlen = mo_system_config(&default_set, default_setlen);
  63. }
  64. *Set = default_set;
  65. setlen = default_setlen;
  66. }
  67. return setlen;
  68. }
  69. void
  70. mo_print_options(opt *set, int setlen)
  71. {
  72. int i = 0;
  73. setlen = mo_default_set(&set, setlen);
  74. for (i = 0; i < setlen; i++) {
  75. if (set[i].kind == opt_builtin) {
  76. fprintf(stderr, "# builtin opt \t%s = %s\n", set[i].name, set[i].value);
  77. }
  78. }
  79. for (i = 0; i < setlen; i++) {
  80. if (set[i].kind == opt_config) {
  81. fprintf(stderr, "# config opt \t%s = %s\n", set[i].name, set[i].value);
  82. }
  83. }
  84. for (i = 0; i < setlen; i++) {
  85. if (set[i].kind == opt_cmdline) {
  86. fprintf(stderr, "# cmdline opt \t%s = %s\n", set[i].name, set[i].value);
  87. }
  88. }
  89. }
  90. char *
  91. mo_find_option(opt *set, int setlen, const char *name)
  92. {
  93. opt *o = NULL;
  94. int i;
  95. setlen = mo_default_set(&set, setlen);
  96. for (i = 0; i < setlen; i++) {
  97. if (strcmp(set[i].name, name) == 0)
  98. if (!o || o->kind < set[i].kind)
  99. o = set + i;
  100. }
  101. if (o)
  102. return o->value;
  103. return NULL;
  104. }
  105. static int
  106. mo_config_file(opt **Set, int setlen, char *file)
  107. {
  108. char buf[BUFSIZ];
  109. FILE *fd = NULL;
  110. opt *set;
  111. if (Set == NULL) {
  112. if (default_set == NULL) {
  113. set = NULL;
  114. setlen = mo_default_set(&set, 0);
  115. }
  116. Set = &default_set;
  117. setlen = default_setlen;
  118. }
  119. set = *Set;
  120. fd = fopen(file, "r");
  121. if (fd == NULL) {
  122. fprintf(stderr, "Could not open file %s\n", file);
  123. return setlen;
  124. }
  125. while (fgets(buf, BUFSIZ, fd) != NULL) {
  126. char *s, *t, *val;
  127. int quote;
  128. for (s = buf; *s && isspace((int) (unsigned char) *s); s++)
  129. ;
  130. if (*s == '#')
  131. continue; /* commentary */
  132. if (*s == 0)
  133. continue; /* empty line */
  134. val = strchr(s, '=');
  135. if (val == NULL) {
  136. fprintf(stderr, "mo_config_file: syntax error in %s at %s\n", file, s);
  137. fclose(fd);
  138. exit(1);
  139. }
  140. *val = 0;
  141. for (t = s; *t && !isspace((int) (unsigned char) *t); t++)
  142. ;
  143. *t = 0;
  144. /* skip any leading blanks in the value part */
  145. for (val++; *val && isspace((int) (unsigned char) *val); val++)
  146. ;
  147. /* search to unquoted # */
  148. quote = 0;
  149. for (t = val; *t; t++) {
  150. if (*t == '"')
  151. quote = !quote;
  152. else if (!quote && *t == '#')
  153. break;
  154. }
  155. if (quote) {
  156. fprintf(stderr, "mo_config_file: wrong number of quotes in %s at %s\n", file, val);
  157. fclose(fd);
  158. exit(1);
  159. }
  160. /* remove trailing white space */
  161. while (isspace((int) (unsigned char) t[-1]))
  162. t--;
  163. *t++ = 0;
  164. /* treat value as empty if it consists only of white space */
  165. if (t <= val)
  166. val = t - 1;
  167. set = (opt *) realloc(set, (setlen + 1) * sizeof(opt));
  168. set[setlen].kind = opt_config;
  169. set[setlen].name = strdup(s);
  170. set[setlen].value = malloc((size_t) (t - val));
  171. for (t = val, s = set[setlen].value; *t; t++)
  172. if (*t != '"')
  173. *s++ = *t;
  174. *s = 0;
  175. setlen++;
  176. }
  177. (void) fclose(fd);
  178. *Set = set;
  179. return setlen;
  180. }
  181. int
  182. mo_system_config(opt **Set, int setlen)
  183. {
  184. char *cfg;
  185. if (Set == NULL) {
  186. if (default_set == NULL) {
  187. opt *set = NULL;
  188. setlen = mo_default_set(&set, 0);
  189. }
  190. Set = &default_set;
  191. setlen = default_setlen;
  192. }
  193. cfg = mo_find_option(*Set, setlen, "config");
  194. if (!cfg)
  195. return setlen;
  196. setlen = mo_config_file(Set, setlen, cfg);
  197. free(cfg);
  198. return setlen;
  199. }
  200. int
  201. mo_builtin_settings(opt **Set)
  202. {
  203. int i = 0;
  204. opt *set;
  205. char buf[BUFSIZ];
  206. if (Set == NULL)
  207. return 0;
  208. #define N_OPTIONS 10 /*MUST MATCH # OPTIONS BELOW */
  209. set = malloc(sizeof(opt) * N_OPTIONS);
  210. if (set == NULL)
  211. return 0;
  212. set[i].kind = opt_builtin;
  213. set[i].name = strdup("gdk_dbpath");
  214. snprintf(buf, BUFSIZ, "%s%c%s%c%s%c%s",
  215. LOCALSTATEDIR, DIR_SEP, "monetdb5", DIR_SEP, "dbfarm",
  216. DIR_SEP, "demo");
  217. set[i].value = strdup(buf);
  218. i++;
  219. set[i].kind = opt_builtin;
  220. set[i].name = strdup("gdk_debug");
  221. set[i].value = strdup("0");
  222. i++;
  223. set[i].kind = opt_builtin;
  224. set[i].name = strdup("gdk_vmtrim");
  225. /* default for gdk_vmtrim is
  226. * "yes" on 32 bit architectures and
  227. * "no" on 64 bit architectures;
  228. * see also GDKinit() in gdk/gdk_utils.c */
  229. #if SIZEOF_VOID_P == 4
  230. /* 32 bit architecture */
  231. set[i].value = strdup("yes");
  232. #else
  233. /* 64 bit architecture */
  234. set[i].value = strdup("no");
  235. #endif
  236. i++;
  237. set[i].kind = opt_builtin;
  238. set[i].name = strdup("monet_prompt");
  239. set[i].value = strdup(">");
  240. i++;
  241. set[i].kind = opt_builtin;
  242. set[i].name = strdup("monet_daemon");
  243. set[i].value = strdup("no");
  244. i++;
  245. set[i].kind = opt_builtin;
  246. set[i].name = strdup("mapi_port");
  247. set[i].value = strdup("50000");
  248. i++;
  249. set[i].kind = opt_builtin;
  250. set[i].name = strdup("mapi_open");
  251. set[i].value = strdup("false");
  252. i++;
  253. set[i].kind = opt_builtin;
  254. set[i].name = strdup("mapi_autosense");
  255. set[i].value = strdup("false");
  256. i++;
  257. set[i].kind = opt_builtin;
  258. set[i].name = strdup("sql_optimizer");
  259. set[i].value = strdup("default_pipe");
  260. i++;
  261. set[i].kind = opt_builtin;
  262. set[i].name = strdup("sql_debug");
  263. set[i].value = strdup("0");
  264. i++;
  265. assert(i == N_OPTIONS);
  266. *Set = set;
  267. return i;
  268. }
  269. int
  270. mo_add_option(opt **Set, int setlen, opt_kind kind, const char *name, const char *value)
  271. {
  272. opt *set;
  273. if (Set == NULL) {
  274. if (default_set == NULL) {
  275. set = NULL;
  276. setlen = mo_default_set(&set, 0);
  277. }
  278. Set = &default_set;
  279. setlen = default_setlen;
  280. }
  281. set = (opt *) realloc(*Set, (setlen + 1) * sizeof(opt));
  282. set[setlen].kind = kind;
  283. set[setlen].name = strdup(name);
  284. set[setlen].value = strdup(value);
  285. *Set = set;
  286. return setlen + 1;
  287. }
  288. void
  289. mo_free_options(opt *set, int setlen)
  290. {
  291. int i;
  292. if (set == NULL) {
  293. set = default_set;
  294. setlen = default_setlen;
  295. default_set = NULL;
  296. default_setlen = 0;
  297. }
  298. for (i = 0; i < setlen; i++) {
  299. if (set[i].name)
  300. free(set[i].name);
  301. if (set[i].value)
  302. free(set[i].value);
  303. }
  304. free(set);
  305. }