/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
- /*-*-c++-*-
- * $Id: cconfigmanager.cpp 1079 2004-10-22 19:59:34Z troyhebe $
- *
- * This file is part of qlcrash, a GUI for the dump-analysis tool lcrash.
- *
- * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *
- * Authors:
- * Michael Geselbracht (let@users.sourceforge.net)
- * Fritz Elfert (elfert@de.ibm.com)
- * Michael Holzheu (holzheu@de.ibm.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version. See the file COPYING for more
- * information.
- */
- #include "cconfigmanager.h"
- #include <stdio.h>
- #include <stdlib.h>
- #ifndef WIN32
- #include <regex.h>
- #include <unistd.h>
- #include <pwd.h>
- #else
- #include <qdir.h>
- #endif
- #include <assert.h>
- #include <sys/types.h>
- #include <iostream>
- using namespace std;
- /* Config file version */
- #define CFG_VERSION "0"
- CConfigManager::CConfigManager(QObject* parent, const char* name) : QObject(parent, name)
- {
- }
- CConfigManager::~CConfigManager()
- {
- clear();
- }
- void
- CConfigManager::clear()
- {
- // free allocated maps
- for (map<QString, map<QString, QString>*>::iterator it = oMap.begin(); it != oMap.end(); ++it) {
- delete (*it).second;
- }
- }
- QString
- CConfigManager::homeDir() const
- {
- #ifdef WIN32
- // On Windows, we use the Registry anyway ...
- return QDir::homeDirPath();
- #else
- uid_t uid = getuid();
- passwd* pwd = getpwuid(uid);
- return (pwd != 0) ? pwd->pw_dir : "";
- #endif
- }
- bool
- CConfigManager::setFile(const QString& fname)
- {
- bool retval = true;
- #ifdef WIN32
- HKEY kHandle;
- if (RegOpenKeyEx(MY_KEYROOT, MY_KEYHOME, 0, KEY_READ, &kHandle) != ERROR_SUCCESS)
- retval = false;
- else {
- QString category;
- unsigned char kValue[1024];
- unsigned long lValue = sizeof(kValue);
- unsigned long kType = REG_SZ;
- if ((RegQueryValueEx(kHandle, "Version", NULL, &kType, kValue, &lValue) ==
- ERROR_SUCCESS) && (kType == REG_SZ)) {
- if (::strcmp(CFG_VERSION, (const char *)kValue) == 0) {
- unsigned long kIndex = 0;
- unsigned char kName[1024];
- unsigned long lName = sizeof(kName);
- FILETIME tStamp;
- // Enumerate SubKeys (aka our "sections")
- while (RegEnumKeyEx(kHandle, kIndex++, (char *)kName, &lName,
- 0, 0, 0, &tStamp) == ERROR_SUCCESS) {
- category = (const char *)kName;
- HKEY subHandle;
- // Open a SubKey
- if (RegOpenKeyEx(kHandle, (const char *)kName, 0, KEY_READ,
- &subHandle) == ERROR_SUCCESS) {
- unsigned long subIndex = 0;
- unsigned char kSubName[1024];
- unsigned long lSubName = sizeof(kSubName);
- lValue = sizeof(kValue);
- kType = REG_SZ;
- // Enumerate values in the Subkey
- while (RegEnumValue(subHandle, subIndex++, (char *)kSubName, &lSubName, 0,
- &kType, kValue, &lValue) == ERROR_SUCCESS) {
- if (kType == REG_SZ) { // We only use keys of type String
- // When we got here, we have the key name in kSubName and
- // the corresponding value in kValue.
- map<QString, map<QString, QString>* >::iterator it = oMap.find(category);
- map<QString, QString>* mm = 0;
- if (it == oMap.end()) {
- mm = new map<QString, QString>;
- } else {
- mm = (*it).second;
- }
- (*mm)[QString((const char *)kSubName)] =
- QString((const char *)kValue);
- oMap[category] = mm;
- }
- lValue = sizeof(kValue);
- lSubName = sizeof(kSubName);
- kType = REG_SZ;
- }
- RegCloseKey(subHandle);
- }
- lName = sizeof(kName);
- }
- }
- }
- RegCloseKey(kHandle);
- }
- #else
- oFile = fname;
-
- FILE* fptr = fopen(fname.latin1(), "r");
- if (fptr != 0) {
- char* line = 0;
- size_t len;
- int i;
- QString category;
- regex_t reg;
- regmatch_t sub[3];
- const int subMax = 3;
- int count = 0; // line counter
-
- // retrieve version number
- int ret = regcomp(®, "VERSION\\([ \t]*([0-9]+)[ \t]*\\)", REG_EXTENDED);
- assert(ret == 0);
- while (getline(&line, &len, fptr) != -1) {
- count++;
- ret = regexec(®, line, subMax, sub, 0);
- if (ret == 0) {
- QString str(line);
- ret = strcmp(CFG_VERSION, str.mid(sub[1].rm_so, sub[1].rm_eo - sub[1].rm_so).latin1());
- break;
- }
- }
- regfree(®);
- if (ret != 0) { // don't read an incompatible file, but use it for writing
- fclose(fptr);
- return true;
- }
-
- ret = regcomp(®, "([a-zA-Z0-9_]+)[ \t]*=[ \t]*\"([^\"]+)\"", REG_EXTENDED);
- assert(ret == 0);
-
- while (getline(&line, &len, fptr) != -1) {
- count++;
- QString str(line);
- str = str.stripWhiteSpace();
- if (str.length() < 6) {
- continue;
- }
- if (str[0].latin1() == '[') { // new category
- category = "";
- int n = str.length();
- for (i = 1; i < n; i++) {
- if (str[i].latin1() == ']') {
- break;
- }
- category += str[i];
- }
- }
- else {
- if (category.length() == 0) {
- cerr << tr("Error in") << " " << fname << ": " << tr("Config item without category") << endl;
- continue;
- }
-
- ret = regexec(®, str.latin1(), subMax, sub, 0);
- if (ret != 0) {
- cerr << tr("Error in") << " " << fname << " " << tr("line") << ": " << count << endl;
- continue;
- }
-
- QString name = str.mid(sub[1].rm_so, sub[1].rm_eo - sub[1].rm_so);
- QString value = str.mid(sub[2].rm_so, sub[2].rm_eo - sub[2].rm_so);
-
- map<QString, map<QString, QString>* >::iterator it = oMap.find(category);
- map<QString, QString>* mm = 0;
- if (it == oMap.end()) {
- mm = new map<QString, QString>;
- }
- else {
- mm = (*it).second;
- }
- (*mm)[name] = value;
- oMap[category] = mm;
- }
- }
-
- free(line);
- regfree(®);
- fclose(fptr);
- }
- else {
- retval = false;
- }
- #endif
-
- return retval;
- }
- bool
- CConfigManager::saveConfig()
- {
- bool retval = true;
- #ifdef WIN32
- HKEY kHandle;
- if (RegCreateKey(MY_KEYROOT, MY_KEYHOME, &kHandle) != ERROR_SUCCESS)
- retval = false;
- else {
- if (RegSetValueEx(kHandle, "Version", 0, REG_SZ,
- (const unsigned char *)CFG_VERSION, strlen(CFG_VERSION)+1) ==
- ERROR_SUCCESS) {
- map<QString, map<QString, QString>* >::iterator dit = oMap.begin();
- int count = 1;
- while (retval && (dit != oMap.end())) {
- HKEY subHandle;
- map<QString, QString>* mm = (*dit).second;
- map<QString, QString>::iterator mit = mm->begin();
- count++;
-
- QString cat = (*dit).first;
- if (RegCreateKey(kHandle, cat.latin1(), &subHandle) != ERROR_SUCCESS) {
- retval = false;
- break;
- }
- while (mit != mm->end()) {
- const char *value = (*mit).second.latin1();
- if (!value)
- value = "";
- if (RegSetValueEx(subHandle, (*mit).first.latin1(), 0, REG_SZ,
- (const unsigned char *)value,
- strlen(value)+1) != ERROR_SUCCESS) {
- retval = false;
- break;
- }
- ++mit;
- }
- RegCloseKey(subHandle);
- ++dit;
- }
- } else
- retval = false;
- }
- RegCloseKey(kHandle);
- #else
- FILE* fptr = fopen(oFile.latin1(), "w");
-
- if (fptr != 0) {
- map<QString, map<QString, QString>* >::iterator dit = oMap.begin();
- int count = 1;
-
- // write version string
- fputs("VERSION(" CFG_VERSION ")\n\n", fptr);
-
- while (dit != oMap.end()) {
- map<QString, QString>* mm = (*dit).second;
- map<QString, QString>::iterator mit = mm->begin();
- count++;
-
- QString cat = (*dit).first;
- cat.prepend("[");
- if (count > 1) {
- cat.prepend("\n");
- }
- cat.append("]\n");
- fwrite(cat.latin1(), 1, cat.length(), fptr);
-
- while (mit != mm->end()) {
- cat = (*mit).first + " = \"" + (*mit).second + "\"\n";
- fwrite(cat.latin1(), 1, cat.length(), fptr);
- ++mit;
- }
- ++dit;
- }
-
- fclose(fptr);
- }
- else {
- retval = false;
- }
- #endif
- return retval;
- }
- void
- CConfigManager::setItem(const QString& category, const QString& name, const QString& value)
- {
- map<QString, map<QString, QString>*>::iterator it = oMap.find(category);
- map<QString, QString>* mm = 0;
-
- if (it == oMap.end()) {
- mm = new map<QString, QString>;
- }
- else {
- mm = (*it).second;
- }
- (*mm)[name] = value;
- oMap[category] = mm;
- }
- void
- CConfigManager::setItem(const QString& category, const QString& name, int value)
- {
- map<QString, map<QString, QString>*>::iterator it = oMap.find(category);
- map<QString, QString>* mm = 0;
-
- if (it == oMap.end()) {
- mm = new map<QString, QString>;
- }
- else {
- mm = (*it).second;
- }
- (*mm)[name] = QString::number(value);
- oMap[category] = mm;
- }
- QString
- CConfigManager::item(const QString& category, const QString& name, const QString& def) const
- {
- map<QString, map<QString, QString>*>::const_iterator it = oMap.find(category);
-
- if (it == oMap.end()) {
- return def;
- }
-
- if ((*it).second->find(name) != (*it).second->end()) {
- return (*(*it).second)[name];
- }
-
- return def;
- }
- // this is redundant...
- int
- CConfigManager::item(const QString& category, const QString& name, int def) const
- {
- map<QString, map<QString, QString>*>::const_iterator it = oMap.find(category);
-
- if (it == oMap.end()) {
- return def;
- }
-
- if ((*it).second->find(name) != (*it).second->end()) {
- return (*(*it).second)[name].toInt();
- }
-
- return def;
- }