PageRenderTime 64ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/lkcd-6.1.0/lkcdutils/qlcrash/qlcrash/cconfigmanager.cpp

#
C++ | 384 lines | 305 code | 50 blank | 29 comment | 85 complexity | aead1c8946f9744ebcf3089504ab327f MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.1, LGPL-2.0
  1. /*-*-c++-*-
  2. * $Id: cconfigmanager.cpp 1079 2004-10-22 19:59:34Z troyhebe $
  3. *
  4. * This file is part of qlcrash, a GUI for the dump-analysis tool lcrash.
  5. *
  6. * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
  7. *
  8. * Authors:
  9. * Michael Geselbracht (let@users.sourceforge.net)
  10. * Fritz Elfert (elfert@de.ibm.com)
  11. * Michael Holzheu (holzheu@de.ibm.com)
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU Lesser Public License as published by
  15. * the Free Software Foundation; either version 2.1 of the License, or
  16. * (at your option) any later version. See the file COPYING for more
  17. * information.
  18. */
  19. #include "cconfigmanager.h"
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #ifndef WIN32
  23. #include <regex.h>
  24. #include <unistd.h>
  25. #include <pwd.h>
  26. #else
  27. #include <qdir.h>
  28. #endif
  29. #include <assert.h>
  30. #include <sys/types.h>
  31. #include <iostream>
  32. using namespace std;
  33. /* Config file version */
  34. #define CFG_VERSION "0"
  35. CConfigManager::CConfigManager(QObject* parent, const char* name) : QObject(parent, name)
  36. {
  37. }
  38. CConfigManager::~CConfigManager()
  39. {
  40. clear();
  41. }
  42. void
  43. CConfigManager::clear()
  44. {
  45. // free allocated maps
  46. for (map<QString, map<QString, QString>*>::iterator it = oMap.begin(); it != oMap.end(); ++it) {
  47. delete (*it).second;
  48. }
  49. }
  50. QString
  51. CConfigManager::homeDir() const
  52. {
  53. #ifdef WIN32
  54. // On Windows, we use the Registry anyway ...
  55. return QDir::homeDirPath();
  56. #else
  57. uid_t uid = getuid();
  58. passwd* pwd = getpwuid(uid);
  59. return (pwd != 0) ? pwd->pw_dir : "";
  60. #endif
  61. }
  62. bool
  63. CConfigManager::setFile(const QString& fname)
  64. {
  65. bool retval = true;
  66. #ifdef WIN32
  67. HKEY kHandle;
  68. if (RegOpenKeyEx(MY_KEYROOT, MY_KEYHOME, 0, KEY_READ, &kHandle) != ERROR_SUCCESS)
  69. retval = false;
  70. else {
  71. QString category;
  72. unsigned char kValue[1024];
  73. unsigned long lValue = sizeof(kValue);
  74. unsigned long kType = REG_SZ;
  75. if ((RegQueryValueEx(kHandle, "Version", NULL, &kType, kValue, &lValue) ==
  76. ERROR_SUCCESS) && (kType == REG_SZ)) {
  77. if (::strcmp(CFG_VERSION, (const char *)kValue) == 0) {
  78. unsigned long kIndex = 0;
  79. unsigned char kName[1024];
  80. unsigned long lName = sizeof(kName);
  81. FILETIME tStamp;
  82. // Enumerate SubKeys (aka our "sections")
  83. while (RegEnumKeyEx(kHandle, kIndex++, (char *)kName, &lName,
  84. 0, 0, 0, &tStamp) == ERROR_SUCCESS) {
  85. category = (const char *)kName;
  86. HKEY subHandle;
  87. // Open a SubKey
  88. if (RegOpenKeyEx(kHandle, (const char *)kName, 0, KEY_READ,
  89. &subHandle) == ERROR_SUCCESS) {
  90. unsigned long subIndex = 0;
  91. unsigned char kSubName[1024];
  92. unsigned long lSubName = sizeof(kSubName);
  93. lValue = sizeof(kValue);
  94. kType = REG_SZ;
  95. // Enumerate values in the Subkey
  96. while (RegEnumValue(subHandle, subIndex++, (char *)kSubName, &lSubName, 0,
  97. &kType, kValue, &lValue) == ERROR_SUCCESS) {
  98. if (kType == REG_SZ) { // We only use keys of type String
  99. // When we got here, we have the key name in kSubName and
  100. // the corresponding value in kValue.
  101. map<QString, map<QString, QString>* >::iterator it = oMap.find(category);
  102. map<QString, QString>* mm = 0;
  103. if (it == oMap.end()) {
  104. mm = new map<QString, QString>;
  105. } else {
  106. mm = (*it).second;
  107. }
  108. (*mm)[QString((const char *)kSubName)] =
  109. QString((const char *)kValue);
  110. oMap[category] = mm;
  111. }
  112. lValue = sizeof(kValue);
  113. lSubName = sizeof(kSubName);
  114. kType = REG_SZ;
  115. }
  116. RegCloseKey(subHandle);
  117. }
  118. lName = sizeof(kName);
  119. }
  120. }
  121. }
  122. RegCloseKey(kHandle);
  123. }
  124. #else
  125. oFile = fname;
  126. FILE* fptr = fopen(fname.latin1(), "r");
  127. if (fptr != 0) {
  128. char* line = 0;
  129. size_t len;
  130. int i;
  131. QString category;
  132. regex_t reg;
  133. regmatch_t sub[3];
  134. const int subMax = 3;
  135. int count = 0; // line counter
  136. // retrieve version number
  137. int ret = regcomp(&reg, "VERSION\\([ \t]*([0-9]+)[ \t]*\\)", REG_EXTENDED);
  138. assert(ret == 0);
  139. while (getline(&line, &len, fptr) != -1) {
  140. count++;
  141. ret = regexec(&reg, line, subMax, sub, 0);
  142. if (ret == 0) {
  143. QString str(line);
  144. ret = strcmp(CFG_VERSION, str.mid(sub[1].rm_so, sub[1].rm_eo - sub[1].rm_so).latin1());
  145. break;
  146. }
  147. }
  148. regfree(&reg);
  149. if (ret != 0) { // don't read an incompatible file, but use it for writing
  150. fclose(fptr);
  151. return true;
  152. }
  153. ret = regcomp(&reg, "([a-zA-Z0-9_]+)[ \t]*=[ \t]*\"([^\"]+)\"", REG_EXTENDED);
  154. assert(ret == 0);
  155. while (getline(&line, &len, fptr) != -1) {
  156. count++;
  157. QString str(line);
  158. str = str.stripWhiteSpace();
  159. if (str.length() < 6) {
  160. continue;
  161. }
  162. if (str[0].latin1() == '[') { // new category
  163. category = "";
  164. int n = str.length();
  165. for (i = 1; i < n; i++) {
  166. if (str[i].latin1() == ']') {
  167. break;
  168. }
  169. category += str[i];
  170. }
  171. }
  172. else {
  173. if (category.length() == 0) {
  174. cerr << tr("Error in") << " " << fname << ": " << tr("Config item without category") << endl;
  175. continue;
  176. }
  177. ret = regexec(&reg, str.latin1(), subMax, sub, 0);
  178. if (ret != 0) {
  179. cerr << tr("Error in") << " " << fname << " " << tr("line") << ": " << count << endl;
  180. continue;
  181. }
  182. QString name = str.mid(sub[1].rm_so, sub[1].rm_eo - sub[1].rm_so);
  183. QString value = str.mid(sub[2].rm_so, sub[2].rm_eo - sub[2].rm_so);
  184. map<QString, map<QString, QString>* >::iterator it = oMap.find(category);
  185. map<QString, QString>* mm = 0;
  186. if (it == oMap.end()) {
  187. mm = new map<QString, QString>;
  188. }
  189. else {
  190. mm = (*it).second;
  191. }
  192. (*mm)[name] = value;
  193. oMap[category] = mm;
  194. }
  195. }
  196. free(line);
  197. regfree(&reg);
  198. fclose(fptr);
  199. }
  200. else {
  201. retval = false;
  202. }
  203. #endif
  204. return retval;
  205. }
  206. bool
  207. CConfigManager::saveConfig()
  208. {
  209. bool retval = true;
  210. #ifdef WIN32
  211. HKEY kHandle;
  212. if (RegCreateKey(MY_KEYROOT, MY_KEYHOME, &kHandle) != ERROR_SUCCESS)
  213. retval = false;
  214. else {
  215. if (RegSetValueEx(kHandle, "Version", 0, REG_SZ,
  216. (const unsigned char *)CFG_VERSION, strlen(CFG_VERSION)+1) ==
  217. ERROR_SUCCESS) {
  218. map<QString, map<QString, QString>* >::iterator dit = oMap.begin();
  219. int count = 1;
  220. while (retval && (dit != oMap.end())) {
  221. HKEY subHandle;
  222. map<QString, QString>* mm = (*dit).second;
  223. map<QString, QString>::iterator mit = mm->begin();
  224. count++;
  225. QString cat = (*dit).first;
  226. if (RegCreateKey(kHandle, cat.latin1(), &subHandle) != ERROR_SUCCESS) {
  227. retval = false;
  228. break;
  229. }
  230. while (mit != mm->end()) {
  231. const char *value = (*mit).second.latin1();
  232. if (!value)
  233. value = "";
  234. if (RegSetValueEx(subHandle, (*mit).first.latin1(), 0, REG_SZ,
  235. (const unsigned char *)value,
  236. strlen(value)+1) != ERROR_SUCCESS) {
  237. retval = false;
  238. break;
  239. }
  240. ++mit;
  241. }
  242. RegCloseKey(subHandle);
  243. ++dit;
  244. }
  245. } else
  246. retval = false;
  247. }
  248. RegCloseKey(kHandle);
  249. #else
  250. FILE* fptr = fopen(oFile.latin1(), "w");
  251. if (fptr != 0) {
  252. map<QString, map<QString, QString>* >::iterator dit = oMap.begin();
  253. int count = 1;
  254. // write version string
  255. fputs("VERSION(" CFG_VERSION ")\n\n", fptr);
  256. while (dit != oMap.end()) {
  257. map<QString, QString>* mm = (*dit).second;
  258. map<QString, QString>::iterator mit = mm->begin();
  259. count++;
  260. QString cat = (*dit).first;
  261. cat.prepend("[");
  262. if (count > 1) {
  263. cat.prepend("\n");
  264. }
  265. cat.append("]\n");
  266. fwrite(cat.latin1(), 1, cat.length(), fptr);
  267. while (mit != mm->end()) {
  268. cat = (*mit).first + " = \"" + (*mit).second + "\"\n";
  269. fwrite(cat.latin1(), 1, cat.length(), fptr);
  270. ++mit;
  271. }
  272. ++dit;
  273. }
  274. fclose(fptr);
  275. }
  276. else {
  277. retval = false;
  278. }
  279. #endif
  280. return retval;
  281. }
  282. void
  283. CConfigManager::setItem(const QString& category, const QString& name, const QString& value)
  284. {
  285. map<QString, map<QString, QString>*>::iterator it = oMap.find(category);
  286. map<QString, QString>* mm = 0;
  287. if (it == oMap.end()) {
  288. mm = new map<QString, QString>;
  289. }
  290. else {
  291. mm = (*it).second;
  292. }
  293. (*mm)[name] = value;
  294. oMap[category] = mm;
  295. }
  296. void
  297. CConfigManager::setItem(const QString& category, const QString& name, int value)
  298. {
  299. map<QString, map<QString, QString>*>::iterator it = oMap.find(category);
  300. map<QString, QString>* mm = 0;
  301. if (it == oMap.end()) {
  302. mm = new map<QString, QString>;
  303. }
  304. else {
  305. mm = (*it).second;
  306. }
  307. (*mm)[name] = QString::number(value);
  308. oMap[category] = mm;
  309. }
  310. QString
  311. CConfigManager::item(const QString& category, const QString& name, const QString& def) const
  312. {
  313. map<QString, map<QString, QString>*>::const_iterator it = oMap.find(category);
  314. if (it == oMap.end()) {
  315. return def;
  316. }
  317. if ((*it).second->find(name) != (*it).second->end()) {
  318. return (*(*it).second)[name];
  319. }
  320. return def;
  321. }
  322. // this is redundant...
  323. int
  324. CConfigManager::item(const QString& category, const QString& name, int def) const
  325. {
  326. map<QString, map<QString, QString>*>::const_iterator it = oMap.find(category);
  327. if (it == oMap.end()) {
  328. return def;
  329. }
  330. if ((*it).second->find(name) != (*it).second->end()) {
  331. return (*(*it).second)[name].toInt();
  332. }
  333. return def;
  334. }