* Made FunctionID abstract. There are now two implementing subclasses,

SourceFunctionID (where we know the souce location of the function) and
  ImageFunctionID (where we don't know the source location). Made the
  classes archivable.
* Added support to find functions by ID.
* Improved user breakpoint handling. We can now "install" a breakpoint before we
  even know the function instances in which to install it. Whenever image debug
  information become available, breakpoints are installed in the concerned
  function instances of the respective image.
* Always trigger loading image debug info as soon as we become aware of an
  image.
* Implemented a settings management mechanism. ATM only the breakpoint
  locations for debugged teams are persisted. This seriously improves the
  debugging fun, though. :-)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31728 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-07-24 02:35:30 +00:00
parent 79a9dc4460
commit 2bf55b39a5
27 changed files with 1480 additions and 67 deletions
@@ -0,0 +1,207 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "SettingsManager.h"
#include <new>
#include <Directory.h>
#include <File.h>
#include <FindDirectory.h>
#include <AutoDeleter.h>
#include <AutoLocker.h>
#include "TeamSettings.h"
static const char* const kSettingsDirPath = "Debugger";
static const char* const kGlobalSettingsName = "Global";
static const int32 kMaxRecentTeamSettings = 10;
SettingsManager::SettingsManager()
:
fLock("settings manager"),
fRecentTeamSettings(kMaxRecentTeamSettings, true)
{
}
SettingsManager::~SettingsManager()
{
_Unset();
}
status_t
SettingsManager::Init()
{
// check the lock
status_t error = fLock.InitCheck();
if (error != B_OK)
return error;
// get and create our settings directory
if (find_directory(B_USER_SETTINGS_DIRECTORY, &fSettingsPath, true) == B_OK
&& fSettingsPath.Append(kSettingsDirPath) == B_OK
&& create_directory(fSettingsPath.Path(), 0700) == B_OK
&& fSettingsPath.Append(kGlobalSettingsName) == B_OK) {
// load the settings
_LoadSettings();
} else {
// something went wrong -- clear the path
fSettingsPath.Unset();
}
return B_OK;
}
status_t
SettingsManager::LoadTeamSettings(const char* teamName, TeamSettings& settings)
{
AutoLocker<BLocker> locker(fLock);
int32 index = _TeamSettingsIndex(teamName);
if (index < 0)
return B_ENTRY_NOT_FOUND;
try {
settings = *fRecentTeamSettings.ItemAt(index);
return B_OK;
} catch (std::bad_alloc) {
return B_NO_MEMORY;
}
}
status_t
SettingsManager::SaveTeamSettings(const TeamSettings& _settings)
{
AutoLocker<BLocker> locker(fLock);
TeamSettings* settings;
int32 index = _TeamSettingsIndex(_settings.TeamName());
if (index >= 0) {
settings = fRecentTeamSettings.RemoveItemAt(index);
} else {
settings = new(std::nothrow) TeamSettings;
if (settings == NULL)
return B_NO_MEMORY;
// enforce recent limit
while (fRecentTeamSettings.CountItems() >= kMaxRecentTeamSettings)
delete fRecentTeamSettings.RemoveItemAt(0);
}
ObjectDeleter<TeamSettings> settingsDeleter(settings);
try {
*settings = _settings;
if (!fRecentTeamSettings.AddItem(settings))
return B_NO_MEMORY;
settingsDeleter.Detach();
return _SaveSettings();
} catch (std::bad_alloc) {
return B_NO_MEMORY;
}
}
void
SettingsManager::_Unset()
{
fRecentTeamSettings.MakeEmpty();
}
status_t
SettingsManager::_LoadSettings()
{
_Unset();
if (fSettingsPath.Path() == NULL)
return B_ENTRY_NOT_FOUND;
// read the settings file
BFile file;
status_t error = file.SetTo(fSettingsPath.Path(), B_READ_ONLY);
if (error != B_OK)
return error;
BMessage archive;
error = archive.Unflatten(&file);
if (error != B_OK)
return error;
// unarchive the recent team settings
BMessage childArchive;
for (int32 i = 0; archive.FindMessage("teamSettings", i, &childArchive)
== B_OK; i++) {
TeamSettings* settings = new(std::nothrow) TeamSettings;
if (settings == NULL)
return B_NO_MEMORY;
error = settings->SetTo(childArchive);
if (error != B_OK) {
delete settings;
continue;
}
if (!fRecentTeamSettings.AddItem(settings)) {
delete settings;
return B_NO_MEMORY;
}
}
return B_OK;
}
status_t
SettingsManager::_SaveSettings()
{
if (fSettingsPath.Path() == NULL)
return B_ENTRY_NOT_FOUND;
// archive the recent team settings
BMessage archive;
for (int32 i = 0; TeamSettings* settings = fRecentTeamSettings.ItemAt(i);
i++) {
BMessage childArchive;
status_t error = settings->WriteTo(childArchive);
if (error != B_OK)
return error;
error = archive.AddMessage("teamSettings", &childArchive);
if (error != B_OK)
return error;
}
// open the settings file
BFile file;
status_t error = file.SetTo(fSettingsPath.Path(),
B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if (error != B_OK)
return error;
return archive.Flatten(&file);
}
int32
SettingsManager::_TeamSettingsIndex(const char* teamName) const
{
for (int32 i = 0; TeamSettings* settings = fRecentTeamSettings.ItemAt(i);
i++) {
if (settings->TeamName() == teamName)
return i;
}
return -1;
}