Move SettingsHandler to libshared
It's used by both Tracker and Codycam and others might find it useful. Change-Id: I585d3a1bdc7f8fce7d36bedf6867464cd541ba2e Reviewed-on: https://review.haiku-os.org/c/1637 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
d63cb7c8db
commit
194c483884
@@ -35,11 +35,12 @@ All rights reserved.
|
|||||||
#define _SETTINGS_FILE_H
|
#define _SETTINGS_FILE_H
|
||||||
|
|
||||||
|
|
||||||
#include <SupportDefs.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
class BFile;
|
class BFile;
|
||||||
@@ -111,7 +112,7 @@ public:
|
|||||||
|
|
||||||
void SaveSettings(Settings* settings, bool onlyIfNonDefault);
|
void SaveSettings(Settings* settings, bool onlyIfNonDefault);
|
||||||
|
|
||||||
const char* Name() const { return name; }
|
const char* Name() const { return fName; }
|
||||||
// name as it appears in the settings file
|
// name as it appears in the settings file
|
||||||
|
|
||||||
virtual const char* Handle(const char* const *argv) = 0;
|
virtual const char* Handle(const char* const *argv) = 0;
|
||||||
@@ -134,7 +135,7 @@ protected:
|
|||||||
// and does not need saving
|
// and does not need saving
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* name;
|
const char* fName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -9,9 +9,8 @@ Application CodyCam :
|
|||||||
FtpClient.cpp
|
FtpClient.cpp
|
||||||
SftpClient.cpp
|
SftpClient.cpp
|
||||||
Settings.cpp
|
Settings.cpp
|
||||||
SettingsHandler.cpp
|
|
||||||
VideoConsumer.cpp
|
VideoConsumer.cpp
|
||||||
: be localestub media translation $(TARGET_NETAPI_LIB)
|
: be localestub media shared translation $(TARGET_NETAPI_LIB)
|
||||||
[ TargetLibstdc++ ]
|
[ TargetLibstdc++ ]
|
||||||
: CodyCam.rdef
|
: CodyCam.rdef
|
||||||
;
|
;
|
||||||
@@ -22,7 +21,6 @@ DoCatalogs CodyCam :
|
|||||||
CodyCam.cpp
|
CodyCam.cpp
|
||||||
FtpClient.cpp
|
FtpClient.cpp
|
||||||
Settings.cpp
|
Settings.cpp
|
||||||
SettingsHandler.cpp
|
|
||||||
SftpClient.cpp
|
SftpClient.cpp
|
||||||
VideoConsumer.cpp
|
VideoConsumer.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -1,485 +0,0 @@
|
|||||||
#include "SettingsHandler.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <Catalog.h>
|
|
||||||
#include <Debug.h>
|
|
||||||
#include <Directory.h>
|
|
||||||
#include <Entry.h>
|
|
||||||
#include <File.h>
|
|
||||||
#include <FindDirectory.h>
|
|
||||||
#include <Locale.h>
|
|
||||||
#include <Path.h>
|
|
||||||
#include <StopWatch.h>
|
|
||||||
|
|
||||||
|
|
||||||
#undef B_TRANSLATION_CONTEXT
|
|
||||||
#define B_TRANSLATION_CONTEXT "SettingsHandler"
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int
|
|
||||||
Compare(const SettingsArgvDispatcher* p1, const SettingsArgvDispatcher* p2)
|
|
||||||
{
|
|
||||||
return strcmp(p1->Name(), p2->Name());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int
|
|
||||||
CompareByNameOne(const SettingsArgvDispatcher* item1,
|
|
||||||
const SettingsArgvDispatcher* item2)
|
|
||||||
{
|
|
||||||
return strcmp(item1->Name(), item2->Name());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*! \class ArgvParser
|
|
||||||
ArgvParser class opens a text file and passes the context in argv
|
|
||||||
format to a specified handler
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
ArgvParser::ArgvParser(const char* name)
|
|
||||||
:
|
|
||||||
fFile(0),
|
|
||||||
fBuffer(0),
|
|
||||||
fPos(-1),
|
|
||||||
fArgc(0),
|
|
||||||
fCurrentArgv(0),
|
|
||||||
fCurrentArgsPos(-1),
|
|
||||||
fSawBackslash(false),
|
|
||||||
fEatComment(false),
|
|
||||||
fInDoubleQuote(false),
|
|
||||||
fInSingleQuote(false),
|
|
||||||
fLineNo(0),
|
|
||||||
fFileName(name)
|
|
||||||
{
|
|
||||||
fFile = fopen(fFileName, "r");
|
|
||||||
if (!fFile) {
|
|
||||||
PRINT((B_TRANSLATE("Error opening %s\n"), fFileName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fBuffer = new char [kBufferSize];
|
|
||||||
fCurrentArgv = new char* [1024];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ArgvParser::~ArgvParser()
|
|
||||||
{
|
|
||||||
delete[] fBuffer;
|
|
||||||
|
|
||||||
MakeArgvEmpty();
|
|
||||||
delete [] fCurrentArgv;
|
|
||||||
|
|
||||||
if (fFile)
|
|
||||||
fclose(fFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ArgvParser::MakeArgvEmpty()
|
|
||||||
{
|
|
||||||
// done with current argv, free it up
|
|
||||||
for (int32 index = 0; index < fArgc; index++)
|
|
||||||
delete fCurrentArgv[index];
|
|
||||||
|
|
||||||
fArgc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
ArgvParser::SendArgv(ArgvHandler argvHandlerFunc, void* passThru)
|
|
||||||
{
|
|
||||||
if (fArgc) {
|
|
||||||
NextArgv();
|
|
||||||
fCurrentArgv[fArgc] = 0;
|
|
||||||
const char *result = (argvHandlerFunc)(fArgc, fCurrentArgv, passThru);
|
|
||||||
if (result)
|
|
||||||
printf(B_TRANSLATE("File %s; Line %ld # %s"), fFileName, fLineNo, result);
|
|
||||||
MakeArgvEmpty();
|
|
||||||
if (result)
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ArgvParser::NextArgv()
|
|
||||||
{
|
|
||||||
if (fSawBackslash) {
|
|
||||||
fCurrentArgs[++fCurrentArgsPos] = '\\';
|
|
||||||
fSawBackslash = false;
|
|
||||||
}
|
|
||||||
fCurrentArgs[++fCurrentArgsPos] = '\0';
|
|
||||||
// terminate current arg pos
|
|
||||||
|
|
||||||
// copy it as a string to the current argv slot
|
|
||||||
fCurrentArgv[fArgc] = new char [strlen(fCurrentArgs) + 1];
|
|
||||||
strcpy(fCurrentArgv[fArgc], fCurrentArgs);
|
|
||||||
fCurrentArgsPos = -1;
|
|
||||||
fArgc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ArgvParser::NextArgvIfNotEmpty()
|
|
||||||
{
|
|
||||||
if (!fSawBackslash && fCurrentArgsPos < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
NextArgv();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char
|
|
||||||
ArgvParser::GetCh()
|
|
||||||
{
|
|
||||||
if (fPos < 0 || fBuffer[fPos] == 0) {
|
|
||||||
if (fFile == 0)
|
|
||||||
return EOF;
|
|
||||||
if (fgets(fBuffer, kBufferSize, fFile) == 0)
|
|
||||||
return EOF;
|
|
||||||
fPos = 0;
|
|
||||||
}
|
|
||||||
return fBuffer[fPos++];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
ArgvParser::EachArgv(const char* name, ArgvHandler argvHandlerFunc,
|
|
||||||
void* passThru)
|
|
||||||
{
|
|
||||||
ArgvParser parser(name);
|
|
||||||
return parser.EachArgvPrivate(name, argvHandlerFunc, passThru);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
ArgvParser::EachArgvPrivate(const char* name, ArgvHandler argvHandlerFunc,
|
|
||||||
void* passThru)
|
|
||||||
{
|
|
||||||
status_t result;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
char ch = GetCh();
|
|
||||||
if (ch == EOF) {
|
|
||||||
// done with file
|
|
||||||
if (fInDoubleQuote || fInSingleQuote) {
|
|
||||||
printf(B_TRANSLATE("File %s # unterminated quote at end of "
|
|
||||||
"file\n"), name);
|
|
||||||
result = B_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = SendArgv(argvHandlerFunc, passThru);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch == '\n' || ch == '\r') {
|
|
||||||
// handle new line
|
|
||||||
fEatComment = false;
|
|
||||||
if (!fSawBackslash && (fInDoubleQuote || fInSingleQuote)) {
|
|
||||||
printf(B_TRANSLATE("File %s ; Line %ld # unterminated "
|
|
||||||
"quote\n"), name, fLineNo);
|
|
||||||
result = B_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fLineNo++;
|
|
||||||
if (fSawBackslash) {
|
|
||||||
fSawBackslash = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// end of line, flush all argv
|
|
||||||
result = SendArgv(argvHandlerFunc, passThru);
|
|
||||||
if (result != B_NO_ERROR)
|
|
||||||
break;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fEatComment)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!fSawBackslash) {
|
|
||||||
if (!fInDoubleQuote && !fInSingleQuote) {
|
|
||||||
if (ch == ';') {
|
|
||||||
// semicolon is a command separator, pass on the whole argv
|
|
||||||
result = SendArgv(argvHandlerFunc, passThru);
|
|
||||||
if (result != B_NO_ERROR)
|
|
||||||
break;
|
|
||||||
continue;
|
|
||||||
} else if (ch == '#') {
|
|
||||||
// ignore everything on this line after this character
|
|
||||||
fEatComment = true;
|
|
||||||
continue;
|
|
||||||
} else if (ch == ' ' || ch == '\t') {
|
|
||||||
// space or tab separates the individual arg strings
|
|
||||||
NextArgvIfNotEmpty();
|
|
||||||
continue;
|
|
||||||
} else if (!fSawBackslash && ch == '\\') {
|
|
||||||
// the next character is escaped
|
|
||||||
fSawBackslash = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!fInSingleQuote && ch == '"') {
|
|
||||||
// enter/exit double quote handling
|
|
||||||
fInDoubleQuote = !fInDoubleQuote;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!fInDoubleQuote && ch == '\'') {
|
|
||||||
// enter/exit single quote handling
|
|
||||||
fInSingleQuote = !fInSingleQuote;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// we just pass through the escape sequence as is
|
|
||||||
fCurrentArgs[++fCurrentArgsPos] = '\\';
|
|
||||||
fSawBackslash = false;
|
|
||||||
}
|
|
||||||
fCurrentArgs[++fCurrentArgsPos] = ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
SettingsArgvDispatcher::SettingsArgvDispatcher(const char* name)
|
|
||||||
:
|
|
||||||
fName(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SettingsArgvDispatcher::SaveSettings(Settings* settings, bool onlyIfNonDefault)
|
|
||||||
{
|
|
||||||
if (!onlyIfNonDefault || NeedsSaving()) {
|
|
||||||
settings->Write("%s ", Name());
|
|
||||||
SaveSettingValue(settings);
|
|
||||||
settings->Write("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
SettingsArgvDispatcher::HandleRectValue(BRect &result, const char* const *argv,
|
|
||||||
bool printError)
|
|
||||||
{
|
|
||||||
if (!*argv) {
|
|
||||||
if (printError)
|
|
||||||
printf("rect left expected");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
result.left = atoi(*argv);
|
|
||||||
if (!*++argv) {
|
|
||||||
if (printError)
|
|
||||||
printf("rect top expected");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
result.top = atoi(*argv);
|
|
||||||
if (!*++argv) {
|
|
||||||
if (printError)
|
|
||||||
printf("rect right expected");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
result.right = atoi(*argv);
|
|
||||||
if (!*++argv) {
|
|
||||||
if (printError)
|
|
||||||
printf("rect bottom expected");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
result.bottom = atoi(*argv);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SettingsArgvDispatcher::WriteRectValue(Settings* setting, BRect rect)
|
|
||||||
{
|
|
||||||
setting->Write("%d %d %d %d", (int32)rect.left, (int32)rect.top,
|
|
||||||
(int32)rect.right, (int32)rect.bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
/*! \class Settings
|
|
||||||
this class represents a list of all the settings handlers, reads and
|
|
||||||
saves the settings file
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
Settings::Settings(const char* filename, const char* settingsDirName)
|
|
||||||
:
|
|
||||||
fFileName(filename),
|
|
||||||
fSettingsDir(settingsDirName),
|
|
||||||
fList(0),
|
|
||||||
fCount(0),
|
|
||||||
fListSize(30),
|
|
||||||
fCurrentSettings(0)
|
|
||||||
{
|
|
||||||
#ifdef SINGLE_SETTING_FILE
|
|
||||||
settingsHandler = this;
|
|
||||||
#endif
|
|
||||||
fList = (SettingsArgvDispatcher**)calloc(fListSize, sizeof(SettingsArgvDispatcher *));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Settings::~Settings()
|
|
||||||
{
|
|
||||||
for (int32 index = 0; index < fCount; index++)
|
|
||||||
delete fList[index];
|
|
||||||
|
|
||||||
free(fList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char*
|
|
||||||
Settings::_ParseUserSettings(int, const char* const *argv, void* castToThis)
|
|
||||||
{
|
|
||||||
if (!*argv)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#ifdef SINGLE_SETTING_FILE
|
|
||||||
Settings* settings = settingsHandler;
|
|
||||||
#else
|
|
||||||
Settings* settings = (Settings*)castToThis;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SettingsArgvDispatcher* handler = settings->_Find(*argv);
|
|
||||||
if (!handler)
|
|
||||||
return B_TRANSLATE("unknown command");
|
|
||||||
return handler->Handle(argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns false if argv dispatcher with the same name already
|
|
||||||
registered
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
Settings::Add(SettingsArgvDispatcher* setting)
|
|
||||||
{
|
|
||||||
// check for uniqueness
|
|
||||||
if (_Find(setting->Name()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (fCount >= fListSize) {
|
|
||||||
fListSize += 30;
|
|
||||||
fList = (SettingsArgvDispatcher **)realloc(fList,
|
|
||||||
fListSize * sizeof(SettingsArgvDispatcher *));
|
|
||||||
}
|
|
||||||
fList[fCount++] = setting;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SettingsArgvDispatcher*
|
|
||||||
Settings::_Find(const char* name)
|
|
||||||
{
|
|
||||||
for (int32 index = 0; index < fCount; index++)
|
|
||||||
if (strcmp(name, fList[index]->Name()) == 0)
|
|
||||||
return fList[index];
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Settings::TryReadingSettings()
|
|
||||||
{
|
|
||||||
BPath prefsPath;
|
|
||||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &prefsPath, true) == B_OK) {
|
|
||||||
prefsPath.Append(fSettingsDir);
|
|
||||||
|
|
||||||
BPath path(prefsPath);
|
|
||||||
path.Append(fFileName);
|
|
||||||
ArgvParser::EachArgv(path.Path(), Settings::_ParseUserSettings, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Settings::SaveSettings(bool onlyIfNonDefault)
|
|
||||||
{
|
|
||||||
ASSERT(SettingsHandler());
|
|
||||||
SettingsHandler()->_SaveCurrentSettings(onlyIfNonDefault);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Settings::_MakeSettingsDirectory(BDirectory *resultingSettingsDir)
|
|
||||||
{
|
|
||||||
BPath path;
|
|
||||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, true) != B_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// make sure there is a directory
|
|
||||||
path.Append(fSettingsDir);
|
|
||||||
mkdir(path.Path(), 0777);
|
|
||||||
resultingSettingsDir->SetTo(path.Path());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Settings::_SaveCurrentSettings(bool onlyIfNonDefault)
|
|
||||||
{
|
|
||||||
BDirectory settingsDir;
|
|
||||||
_MakeSettingsDirectory(&settingsDir);
|
|
||||||
|
|
||||||
if (settingsDir.InitCheck() != B_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
printf("+++++++++++ Settings::_SaveCurrentSettings %s\n", fFileName);
|
|
||||||
// nuke old settings
|
|
||||||
BEntry entry(&settingsDir, fFileName);
|
|
||||||
entry.Remove();
|
|
||||||
|
|
||||||
BFile prefs(&entry, O_RDWR | O_CREAT);
|
|
||||||
if (prefs.InitCheck() != B_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fCurrentSettings = &prefs;
|
|
||||||
for (int32 index = 0; index < fCount; index++) {
|
|
||||||
fList[index]->SaveSettings(this, onlyIfNonDefault);
|
|
||||||
}
|
|
||||||
|
|
||||||
fCurrentSettings = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Settings::Write(const char* format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
va_start(args, format);
|
|
||||||
VSWrite(format, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Settings::VSWrite(const char* format, va_list arg)
|
|
||||||
{
|
|
||||||
char buffer[2048];
|
|
||||||
vsprintf(buffer, format, arg);
|
|
||||||
ASSERT(fCurrentSettings && fCurrentSettings->InitCheck() == B_OK);
|
|
||||||
fCurrentSettings->Write(buffer, strlen(buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef SINGLE_SETTING_FILE
|
|
||||||
Settings* Settings::settingsHandler = 0;
|
|
||||||
#endif
|
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
#ifndef SETTINGS_HANDLER_H
|
|
||||||
#define SETTINGS_HANDLER_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <SupportDefs.h>
|
|
||||||
|
|
||||||
|
|
||||||
class BFile;
|
|
||||||
class BDirectory;
|
|
||||||
class BRect;
|
|
||||||
class Settings;
|
|
||||||
|
|
||||||
|
|
||||||
typedef const char* (*ArgvHandler)(int argc, const char *const *argv, void *params);
|
|
||||||
// return 0 or error string if parsing failed
|
|
||||||
|
|
||||||
|
|
||||||
const int32 kBufferSize = 1024;
|
|
||||||
|
|
||||||
|
|
||||||
class ArgvParser {
|
|
||||||
public:
|
|
||||||
static status_t EachArgv(const char* name,
|
|
||||||
ArgvHandler argvHandlerFunc, void* passThru);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ArgvParser(const char* name);
|
|
||||||
~ArgvParser();
|
|
||||||
|
|
||||||
status_t EachArgvPrivate(const char* name,
|
|
||||||
ArgvHandler argvHandlerFunc, void* passThru);
|
|
||||||
char GetCh();
|
|
||||||
|
|
||||||
status_t SendArgv(ArgvHandler argvHandlerFunc, void* passThru);
|
|
||||||
// done with a whole line of argv, send it off and get ready
|
|
||||||
// to build a new one
|
|
||||||
|
|
||||||
void NextArgv();
|
|
||||||
// done with current string, get ready to start building next
|
|
||||||
void NextArgvIfNotEmpty();
|
|
||||||
// as above, don't commint current string if empty
|
|
||||||
|
|
||||||
void MakeArgvEmpty();
|
|
||||||
|
|
||||||
FILE* fFile;
|
|
||||||
char* fBuffer;
|
|
||||||
int32 fPos;
|
|
||||||
int32 fNumAvail;
|
|
||||||
|
|
||||||
int fArgc;
|
|
||||||
char** fCurrentArgv;
|
|
||||||
|
|
||||||
int32 fCurrentArgsPos;
|
|
||||||
char fCurrentArgs[1024];
|
|
||||||
|
|
||||||
bool fSawBackslash;
|
|
||||||
bool fEatComment;
|
|
||||||
bool fInDoubleQuote;
|
|
||||||
bool fInSingleQuote;
|
|
||||||
|
|
||||||
int32 fLineNo;
|
|
||||||
const char* fFileName;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class SettingsArgvDispatcher {
|
|
||||||
// base class for a single setting item
|
|
||||||
public:
|
|
||||||
SettingsArgvDispatcher(const char* name);
|
|
||||||
virtual ~SettingsArgvDispatcher() {};
|
|
||||||
|
|
||||||
void SaveSettings(Settings* settings, bool onlyIfNonDefault);
|
|
||||||
|
|
||||||
const char* Name() const
|
|
||||||
{
|
|
||||||
return fName;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const char* Handle(const char* const *argv) = 0;
|
|
||||||
// override this adding an argv parser that reads in the
|
|
||||||
// values in argv format for this setting
|
|
||||||
// return a pointer to an error message or null if parsed OK
|
|
||||||
|
|
||||||
bool HandleRectValue(BRect&, const char* const *argv,
|
|
||||||
bool printError = true);
|
|
||||||
|
|
||||||
// static bool HandleColorValue(rgb_color &, const char *const *argv, bool printError = true);
|
|
||||||
void WriteRectValue(Settings*, BRect);
|
|
||||||
// void WriteColorValue(BRect);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void SaveSettingValue(Settings* settings) = 0;
|
|
||||||
// override this to save the current value of this setting in a
|
|
||||||
// text format
|
|
||||||
|
|
||||||
virtual bool NeedsSaving() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// override to return false if current value is equal to the default
|
|
||||||
// and does not need saving
|
|
||||||
private:
|
|
||||||
const char* fName;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Settings {
|
|
||||||
public:
|
|
||||||
Settings(const char* filename, const char* settingsDirName);
|
|
||||||
~Settings();
|
|
||||||
void TryReadingSettings();
|
|
||||||
void SaveSettings(bool onlyIfNonDefault = true);
|
|
||||||
|
|
||||||
#ifdef SINGLE_SETTING_FILE
|
|
||||||
static Settings* SettingsHandler()
|
|
||||||
{
|
|
||||||
return settingsHandler;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
Settings* SettingsHandler()
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool Add(SettingsArgvDispatcher *);
|
|
||||||
|
|
||||||
void Write(const char* format, ...);
|
|
||||||
void VSWrite(const char*, va_list);
|
|
||||||
|
|
||||||
#ifdef SINGLE_SETTING_FILE
|
|
||||||
static Settings* settingsHandler;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
void _MakeSettingsDirectory(BDirectory*);
|
|
||||||
|
|
||||||
SettingsArgvDispatcher* _Find(const char*);
|
|
||||||
static const char* _ParseUserSettings(int, const char *const *argv, void*);
|
|
||||||
void _SaveCurrentSettings(bool onlyIfNonDefault);
|
|
||||||
|
|
||||||
const char* fFileName;
|
|
||||||
const char* fSettingsDir;
|
|
||||||
SettingsArgvDispatcher** fList;
|
|
||||||
int32 fCount;
|
|
||||||
int32 fListSize;
|
|
||||||
BFile* fCurrentSettings;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SETTINGS_HANDLER_H
|
|
||||||
@@ -54,6 +54,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
RegExp.cpp
|
RegExp.cpp
|
||||||
RWLocker.cpp
|
RWLocker.cpp
|
||||||
RWLockManager.cpp
|
RWLockManager.cpp
|
||||||
|
SettingsHandler.cpp
|
||||||
ShakeTrackingFilter.cpp
|
ShakeTrackingFilter.cpp
|
||||||
StringForRate.cpp
|
StringForRate.cpp
|
||||||
StringForSize.cpp
|
StringForSize.cpp
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ All rights reserved.
|
|||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <FindDirectory.h>
|
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <StopWatch.h>
|
#include <StopWatch.h>
|
||||||
|
|
||||||
@@ -53,6 +53,10 @@ All rights reserved.
|
|||||||
// #pragma mark - ArgvParser
|
// #pragma mark - ArgvParser
|
||||||
|
|
||||||
|
|
||||||
|
/*! \class ArgvParser
|
||||||
|
ArgvParser class opens a text file and passes the context in argv
|
||||||
|
format to a specified handler
|
||||||
|
*/
|
||||||
ArgvParser::ArgvParser(const char* name)
|
ArgvParser::ArgvParser(const char* name)
|
||||||
:
|
:
|
||||||
fFile(0),
|
fFile(0),
|
||||||
@@ -95,7 +99,7 @@ ArgvParser::MakeArgvEmpty()
|
|||||||
{
|
{
|
||||||
// done with current argv, free it up
|
// done with current argv, free it up
|
||||||
for (int32 index = 0; index < fArgc; index++)
|
for (int32 index = 0; index < fArgc; index++)
|
||||||
delete[] fCurrentArgv[index];
|
delete fCurrentArgv[index];
|
||||||
|
|
||||||
fArgc = 0;
|
fArgc = 0;
|
||||||
}
|
}
|
||||||
@@ -129,7 +133,7 @@ ArgvParser::NextArgv()
|
|||||||
fSawBackslash = false;
|
fSawBackslash = false;
|
||||||
}
|
}
|
||||||
fCurrentArgs[++fCurrentArgsPos] = '\0';
|
fCurrentArgs[++fCurrentArgsPos] = '\0';
|
||||||
// terminate current arg pos
|
// terminate current arg pos
|
||||||
|
|
||||||
// copy it as a string to the current argv slot
|
// copy it as a string to the current argv slot
|
||||||
fCurrentArgv[fArgc] = new char [strlen(fCurrentArgs) + 1];
|
fCurrentArgv[fArgc] = new char [strlen(fCurrentArgs) + 1];
|
||||||
@@ -268,7 +272,7 @@ ArgvParser::EachArgvPrivate(const char* name, ArgvHandler argvHandlerFunc,
|
|||||||
|
|
||||||
SettingsArgvDispatcher::SettingsArgvDispatcher(const char* name)
|
SettingsArgvDispatcher::SettingsArgvDispatcher(const char* name)
|
||||||
:
|
:
|
||||||
name(name)
|
fName(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,6 +333,10 @@ SettingsArgvDispatcher::WriteRectValue(Settings* setting, BRect rect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \class Settings
|
||||||
|
this class represents a list of all the settings handlers, reads and
|
||||||
|
saves the settings file
|
||||||
|
*/
|
||||||
Settings::Settings(const char* filename, const char* settingsDirName)
|
Settings::Settings(const char* filename, const char* settingsDirName)
|
||||||
:
|
:
|
||||||
fFileName(filename),
|
fFileName(filename),
|
||||||
@@ -366,6 +374,10 @@ Settings::ParseUserSettings(int, const char* const* argv, void* castToThis)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns false if argv dispatcher with the same name already
|
||||||
|
registered
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
Settings::Add(SettingsArgvDispatcher* setting)
|
Settings::Add(SettingsArgvDispatcher* setting)
|
||||||
{
|
{
|
||||||
@@ -481,8 +493,8 @@ Settings::Write(const char* format, ...)
|
|||||||
void
|
void
|
||||||
Settings::VSWrite(const char* format, va_list arg)
|
Settings::VSWrite(const char* format, va_list arg)
|
||||||
{
|
{
|
||||||
char fBuffer[2048];
|
char buffer[2048];
|
||||||
vsprintf(fBuffer, format, arg);
|
vsprintf(buffer, format, arg);
|
||||||
ASSERT(fCurrentSettings && fCurrentSettings->InitCheck() == B_OK);
|
ASSERT(fCurrentSettings && fCurrentSettings->InitCheck() == B_OK);
|
||||||
fCurrentSettings->Write(fBuffer, strlen(fBuffer));
|
fCurrentSettings->Write(buffer, strlen(buffer));
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,6 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
RegExp.cpp
|
RegExp.cpp
|
||||||
SelectionWindow.cpp
|
SelectionWindow.cpp
|
||||||
Settings.cpp
|
Settings.cpp
|
||||||
SettingsHandler.cpp
|
|
||||||
SettingsViews.cpp
|
SettingsViews.cpp
|
||||||
SlowContextPopup.cpp
|
SlowContextPopup.cpp
|
||||||
SlowMenu.cpp
|
SlowMenu.cpp
|
||||||
|
|||||||
Reference in New Issue
Block a user