📄 beosprefs.cpp
字号:
/*____________________________________________________________________________
FreeAmp - The Free MP3 Player
Portions Copyright (C) 1998-1999 EMusic.com
Portions Copyright (C) 1999 Mark H. Weaver <mhw@netris.org>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: beosprefs.cpp,v 1.10 2000/07/10 04:19:06 hiro Exp $
____________________________________________________________________________*/
#include "config.h"
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <string>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <be/storage/FindDirectory.h>
#include <be/storage/Directory.h>
#include <be/storage/Path.h>
#include "utility.h"
#include "beosprefs.h"
#include "prefixprefs.h"
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
// THis module uses the strdup function to pass strings to the lists class
// (among others) which will in turn use delete to reclaim the memory.
// This is NOT VALID! A strdup()ed string must be free()ed, not deleted!
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
// default values
const char* kDefaultLibraryPath = "/boot/home/config/add-ons/freeamp";
const char* kDefaultUI = "freeamp.ui";
const char* kDefaultTextUI = "freeampcmd.ui";
const char* kDefaultPMO = "soundcard.pmo";
class LibDirFindHandle {
public:
vector <char *> *m_pLibDirs;
int32 m_current;
};
static
Error
ScanQuotableString(const char *in, const char **endPtr,
char *out, int32 *lengthPtr, const char *delim)
{
bool quoted = false;
int32 length = 0;
// In case of error, clear return fields now
if (endPtr)
*endPtr = 0;
if (lengthPtr)
*lengthPtr = 0;
if (*in == '"')
{
in++;
quoted = true;
}
while (*in)
{
if (*in == '"' && quoted)
{
in++;
break;
}
else if ((isspace(*in) || strchr(delim, *in)) && !quoted)
break;
else if (*in == '\\' && quoted)
{
char ch;
in++;
switch (*in)
{
case '\\': ch = '\\'; in++; break;
case '"': ch = '"'; in++; break;
case 'n': ch = '\n'; in++; break;
case 't': ch = '\t'; in++; break;
default:
if (in[0] < '0' || in[0] > '3' ||
in[1] < '0' || in[1] > '7' ||
in[2] < '0' || in[2] > '7')
{
*endPtr = in;
return kError_SyntaxError;
}
ch = (char)(((in[0] - '0') << 6) |
((in[1] - '0') << 3) |
(in[2] - '0'));
in += 3;
break;
}
if (out)
*out++ = ch;
length++;
}
else if (*in == '\n')
{
if (quoted)
{
*endPtr = in;
return kError_SyntaxError;
}
break;
}
else
{
if (out)
*out++ = *in;
length++;
in++;
}
}
if (out)
*out++ = '\0';
if (lengthPtr)
*lengthPtr = length;
if (endPtr)
*endPtr = in;
return kError_NoErr;
}
static
char *
ReadQuotableString(const char *in, const char **endPtr, const char *delim)
{
Error error;
int32 length;
error = ScanQuotableString(in, endPtr, 0, &length, delim);
if (IsError(error))
return 0;
char *out = new char[length + 1];
ScanQuotableString(in, 0, out, 0, delim);
return out;
}
static
void
PrepareQuotableString(const char *str, bool *needQuotes,
char *out, int32 *lengthPtr, const char *delim)
{
int32 unquotedLength = 0;
int32 quotedLength = 2;
bool quoted = *needQuotes;
if (out && quoted)
*out++ = '"';
if (*str == '"')
*needQuotes = true;
for (; *str; str++)
{
if (strchr(delim, *str) || *str == ' ')
{
*needQuotes = true;
quotedLength++;
if (out)
*out++ = *str;
}
else if (*str == '\\' || *str == '"')
{
quotedLength += 2;
unquotedLength++;
if (out)
{
if (quoted)
*out++ = '\\';
*out++ = *str;
}
}
else if (*str == '\n' || *str == '\t')
{
*needQuotes = true;
quotedLength += 2;
if (out)
{
*out++ = '\\';
*out++ = (*str == '\n') ? 'n' : 't';
}
}
else if (isspace(*str) || !isgraph(*str))
{
*needQuotes = true;
quotedLength += 4;
if (out)
{
unsigned char ch = *str;
*out++ = '\\';
*out++ = '0' + (ch >> 6);
*out++ = '0' + ((ch >> 3) & 7);
*out++ = '0' + (ch & 7);
}
}
else
{
unquotedLength++;
quotedLength++;
if (out)
*out++ = *str;
}
}
if (out)
{
if (quoted)
*out++ = '"';
*out++ = '\0';
}
if (lengthPtr)
*lengthPtr = *needQuotes ? quotedLength : unquotedLength;
}
static
char *
WriteQuotableString(const char *str, const char *delim)
{
int32 length;
bool needQuotes = false;
PrepareQuotableString(str, &needQuotes, 0, &length, delim);
char *out = new char[length + 1];
PrepareQuotableString(str, &needQuotes, out, 0, delim);
return out;
}
static
void
AppendToString(char **destPtr, const char *src, int32 length)
{
char *oldStr = *destPtr;
int32 oldLen = oldStr ? strlen(oldStr) : 0;
int32 newLen = oldLen + length;
char *newStr = new char[newLen + 1];
if (oldStr)
{
strncpy(newStr, oldStr, oldLen);
delete[] oldStr;
}
strncpy(newStr + oldLen, src, length);
newStr[newLen] = '\0';
*destPtr = newStr;
}
#if 0
static
void
Test(BeOSPrefs *prefs)
{
const char *delim = "#";
static const char *tests[] = {
"# \nfoo\tbar\r\017blah\371\321woz\\top\"dog",
"FooBar",
"Foo Bar",
" Foo Bar",
"\"Foo",
"Foo\"",
"Fo\"o",
"Fo\\o",
"#Foo",
"Fo#o",
":Foo",
"Fo:o",
"Fo\no",
"Fo\to",
"Fo\ro",
"Fo\017o",
"Fo\371o",
"Fo\123o",
"Foo",
0
};
prefs->SetPrefString(tests[0], tests[0]);
int i;
char quotedStr[256], recoveredStr[256];
bool needQuotes;
int len1, len2;
const char *end;
for (i = 0; tests[i]; i++)
{
needQuotes = false;
PrepareQuotableString(tests[i], &needQuotes, 0, &len1, delim);
PrepareQuotableString(tests[i], &needQuotes, quotedStr,
&len2, delim);
if (len1 != len2 || len1 != strlen(quotedStr))
printf("ERROR: len1: %d, len2: %d, len: %d\n", len1, len2,
strlen(quotedStr));
puts(quotedStr);
ScanQuotableString(quotedStr, &end, recoveredStr, &len2, delim);
if (len2 != strlen(recoveredStr) || strcmp(tests[i], recoveredStr))
printf("ERROR: len2: %d, len: %d\n", len2,
strlen(recoveredStr));
}
}
#endif
BeOSPrefEntry::
~BeOSPrefEntry()
{
if (prefix) delete[] prefix;
if (key) delete[] key;
if (separator) delete[] separator;
if (value) delete[] value;
if (suffix) delete[] suffix;
}
BeOSPrefs::
BeOSPrefs()
: m_prefsFilePath(0),
m_saveEnable(true),
m_changed(false),
m_errorLineNumber(0)
{
BPath prefPath( FreeampDir( NULL ) );
create_directory( prefPath.Path(), 0755 );
prefPath.Append( "preferences" );
// Compute pathname of preferences file
m_prefsFilePath = new char[ strlen( prefPath.Path() ) + 1 ];
strcpy( m_prefsFilePath, prefPath.Path() );
FILE *prefsFile = fopen(m_prefsFilePath, "r");
if (!prefsFile && errno != ENOENT)
{
m_saveEnable = false;
fprintf(stderr, "Error opening %s: %s\n",
m_prefsFilePath, strerror(errno));
}
if (prefsFile)
{
BeOSPrefEntry *entry = new BeOSPrefEntry;
char buffer[1024];
char *p;
int lineNumber = 0;
while (fgets(buffer, sizeof(buffer) - 1, prefsFile))
{
lineNumber++;
p = buffer;
while (*p && (*p == ' ' && *p == '\t'))
p++;
if (*p == '#')
{
// No data on this line, skip to the end of the comment
while (*p)
p++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -