Skip to content

Commit

Permalink
Refactor: Relocated Unix system-level config to libdeng2
Browse files Browse the repository at this point in the history
Moved DD_Unix_GetConfigValue() into a proper class called
UnixInfo in libdeng2. The App instance will create one on
Unix platforms and host it for the lifetime of the application.
This fixes the issue of re-parsing the Info files every time
the config values were queried.
  • Loading branch information
skyjake committed Jul 22, 2012
1 parent e3283cd commit 582f19f
Show file tree
Hide file tree
Showing 14 changed files with 270 additions and 71 deletions.
2 changes: 1 addition & 1 deletion doomsday/engine/portable/src/library.c
Expand Up @@ -90,7 +90,7 @@ static void getBundlePath(char* path, size_t len)
# endif

// Check Unix-specific config files.
DD_Unix_GetConfigValue("paths", "libdir", path, len);
UnixInfo_GetConfigValue("paths", "libdir", path, len);
#endif
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion doomsday/engine/portable/src/sys_reslocator.c
Expand Up @@ -590,7 +590,7 @@ static void createPackagesResourceNamespace(void)
{
// Check the system-level config files.
filename_t fn;
if(DD_Unix_GetConfigValue("paths", "iwaddir", fn, FILENAME_T_MAXLEN))
if(UnixInfo_GetConfigValue("paths", "iwaddir", fn, FILENAME_T_MAXLEN))
{
doomWadDir = Str_Set(Str_New(), fn);
}
Expand Down
9 changes: 0 additions & 9 deletions doomsday/engine/unix/include/dd_uinit.h
Expand Up @@ -53,15 +53,6 @@ extern application_t app;
boolean DD_Unix_Init(int argc, char** argv);
void DD_Shutdown(void);

/**
* @note This implementation re-parses the entire config file on each call, so
* it is not useful for performance-critical or high volume usage.
*
* @return @c true, if the found config value was written to @a dest, otherwise
* @c false.
*/
boolean DD_Unix_GetConfigValue(const char* configFile, const char* key, char* dest, size_t destLen);

#ifdef __cplusplus
}
#endif
Expand Down
44 changes: 1 addition & 43 deletions doomsday/engine/unix/src/dd_uinit.c
Expand Up @@ -313,7 +313,7 @@ static void determineGlobalPaths(application_t* app)
strncpy(ddBasePath, DENG_BASE_DIR, FILENAME_T_MAXLEN);
#endif
// Also check the system config files.
DD_Unix_GetConfigValue("paths", "basedir", ddBasePath, FILENAME_T_MAXLEN);
UnixInfo_GetConfigValue("paths", "basedir", ddBasePath, FILENAME_T_MAXLEN);
}
Dir_CleanPath(ddBasePath, FILENAME_T_MAXLEN);
Dir_MakeAbsolutePath(ddBasePath, FILENAME_T_MAXLEN);
Expand Down Expand Up @@ -437,45 +437,3 @@ void DD_Shutdown(void)
Library_Shutdown();
DisplayMode_Shutdown();
}

boolean DD_Unix_GetConfigValue(const char* configFile, const char* key, char* dest, size_t destLen)
{
Info* info;
char buf[512];
ddstring_t* p;
boolean success = false;

// Maybe it is in the user's .doomsday dir.
p = Str_New();
Str_Appendf(p, "~/.doomsday/%s", configFile);
F_MakeAbsolute(p, p);
info = Info_NewFromFile(Str_Text(p));
if(info)
{
if(Info_FindValue(info, key, buf, sizeof(buf)))
{
strncpy(dest, buf, destLen);
success = true;
goto cleanup;
}
}

// Check for a config file for the library path.
Str_Clear(p);
Str_Appendf(p, "/etc/doomsday/%s", configFile);
info = Info_NewFromFile(Str_Text(p));
if(info)
{
if(Info_FindValue(info, key, buf, sizeof(buf)))
{
strncpy(dest, buf, destLen);
success = true;
goto cleanup;
}
}

cleanup:
Info_Delete(info);
Str_Delete(p);
return success;
}
1 change: 1 addition & 0 deletions doomsday/libdeng2/include/de/UnixInfo
@@ -0,0 +1 @@
#include "core/unixinfo.h"
5 changes: 5 additions & 0 deletions doomsday/libdeng2/include/de/c_wrapper.h
Expand Up @@ -128,6 +128,11 @@ DENG2_PUBLIC Info* Info_NewFromFile(const char* nativePath);
DENG2_PUBLIC void Info_Delete(Info* info);
DENG2_PUBLIC int Info_FindValue(Info* info, const char* path, char* buffer, size_t bufSize);

/*
* UnixInfo
*/
DENG2_PUBLIC int UnixInfo_GetConfigValue(const char* configFile, const char* key, char* dest, size_t destLen);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
8 changes: 8 additions & 0 deletions doomsday/libdeng2/include/de/core/app.h
Expand Up @@ -26,6 +26,7 @@
#include "../FS"
#include "../Module"
#include "../Config"
#include "../UnixInfo"
#include <QApplication>

/**
Expand Down Expand Up @@ -94,6 +95,11 @@ namespace de
*/
static Config& config();

/**
* Returns the Unix system-level configuration preferences.
*/
static UnixInfo& unixInfo();

/**
* Imports a script module that is located on the import path.
*
Expand All @@ -118,6 +124,8 @@ namespace de
/// The file system.
FS _fs;

UnixInfo _unixInfo;

/// The configuration.
Config* _config;

Expand Down
64 changes: 64 additions & 0 deletions doomsday/libdeng2/include/de/core/unixinfo.h
@@ -0,0 +1,64 @@
/**
* @file unixinfo.h
* Unix system-level configuration. @ingroup core
*
* @authors Copyright © 2012 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2012 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/

#ifndef LIBDENG2_UNIXINFO_H
#define LIBDENG2_UNIXINFO_H

#include "../String"

namespace de {

/**
* System-level configuration preferences for the Unix platform. These are used
* for setting specific directory locations, e.g., where shared libraries are
* expected to be found. The configuration has two levels: system-global
* configuration under <tt>/etc</tt> and user-specific configuration under
* <tt>~/.doomsday</tt>.
*/
class UnixInfo
{
public:
/**
* Loads the system-level Info files.
*/
UnixInfo();

~UnixInfo();

/**
* Returns a path preference.
*
* @param key Path identifier.
* @param value The value is returned here.
*
* @return Path.
*/
bool path(const String& key, String& value) const;

private:
struct Instance;
Instance* d;
};

} // namespace de

#endif // LIBDENG2_UNIXINFO_H
26 changes: 26 additions & 0 deletions doomsday/libdeng2/include/de/data/info.h
Expand Up @@ -193,6 +193,14 @@ class Info

public:
Info();

/**
* Parses a string of text as Info source.
*
* @param source Info source text.
*/
Info(const String& source);

~Info();

/**
Expand All @@ -202,10 +210,28 @@ class Info
*/
void parse(const String& infoSource);

/**
* Parses the Info contents from a native text file.
*
* @param nativePath Path of a native file containing the Info source.
*/
void parseNativeFile(const String& nativePath);

const BlockElement& root() const;

const Element* findByPath(const String& path) const;

/**
* Finds the value of a key.
*
* @param key Key to find.
* @param value The value is returned here.
*
* @return @c true, if the key was found and @a value is valid. If @c
* false, the key was not found and @a value is not changed.
*/
bool findValueForKey(const String& key, String& value) const;

private:
struct Instance;
Instance* d;
Expand Down
7 changes: 5 additions & 2 deletions doomsday/libdeng2/libdeng2.pro
Expand Up @@ -61,6 +61,7 @@ HEADERS += \
include/de/Library \
include/de/Log \
include/de/LogBuffer \
include/de/UnixInfo \
include/de/Vector

HEADERS += \
Expand All @@ -75,7 +76,8 @@ HEADERS += \
include/de/core/commandline.h \
include/de/core/library.h \
include/de/core/log.h \
include/de/core/logbuffer.h
include/de/core/logbuffer.h \
include/de/core/unixinfo.h

# Private headers.
HEADERS += \
Expand All @@ -90,7 +92,8 @@ SOURCES += \
src/core/callbacktimer.cpp \
src/core/library.cpp \
src/core/log.cpp \
src/core/logbuffer.cpp
src/core/logbuffer.cpp \
src/core/unixinfo.cpp

OTHER_FILES += \
config/deng.de
Expand Down
37 changes: 28 additions & 9 deletions doomsday/libdeng2/src/c_wrapper.cpp
Expand Up @@ -18,6 +18,8 @@
*/

#include "de/c_wrapper.h"
#include "de/Error"
#include "de/App"
#include "de/LegacyCore"
#include "de/LegacyNetwork"
#include "de/Address"
Expand Down Expand Up @@ -344,25 +346,28 @@ Info* Info_NewFromString(const char* utf8text)
{
try
{
QScopedPointer<de::Info> self(new de::Info);
self->parse(QString::fromUtf8(utf8text));
return reinterpret_cast<Info*>(self.take());
return reinterpret_cast<Info*>(new de::Info(QString::fromUtf8(utf8text)));
}
catch(de::Error& er)
catch(const de::Error& er)
{
LOG_WARNING(er.asText());
return 0;
}
return 0;
}

Info* Info_NewFromFile(const char* nativePath)
{
QFile file(nativePath);
if(file.open(QFile::ReadOnly | QFile::Text))
try
{
QScopedPointer<de::Info> info(new de::Info);
info->parseNativeFile(QString::fromUtf8(nativePath));
return reinterpret_cast<Info*>(info.take());
}
catch(const de::Error& er)
{
return Info_NewFromString(file.readAll().constData());
LOG_WARNING(er.asText());
return 0;
}
return 0;
}

void Info_Delete(Info* info)
Expand Down Expand Up @@ -393,3 +398,17 @@ int Info_FindValue(Info* info, const char* path, char* buffer, size_t bufSize)
return value.size();
}
}

int UnixInfo_GetConfigValue(const char* configFile, const char* key, char* dest, size_t destLen)
{
// "paths" is the only config file currently being used.
if(qstrcmp(configFile, "paths")) return false;

de::String foundValue;
if(de::App::unixInfo().path(key, foundValue))
{
qstrncpy(dest, foundValue.toUtf8().constData(), destLen);
return true;
}
return false;
}
13 changes: 9 additions & 4 deletions doomsday/libdeng2/src/core/app.cpp
Expand Up @@ -157,27 +157,32 @@ String App::executablePath()
return DENG2_APP->_appPath;
}

FS &App::fileSystem()
FS& App::fileSystem()
{
return DENG2_APP->_fs;
}

Folder &App::fileRoot()
Folder& App::fileRoot()
{
return fileSystem().root();
}

Folder &App::homeFolder()
Folder& App::homeFolder()
{
return fileRoot().locate<Folder>("/home");
}

Config &App::config()
Config& App::config()
{
DENG2_ASSERT(DENG2_APP->_config != 0);
return *DENG2_APP->_config;
}

UnixInfo& App::unixInfo()
{
return DENG2_APP->_unixInfo;
}

static int sortFilesByModifiedAt(const File* a, const File* b)
{
return cmp(a->status().modifiedAt, b->status().modifiedAt);
Expand Down

0 comments on commit 582f19f

Please sign in to comment.