⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unixprefs.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
        
        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: unixprefs.cpp,v 1.29 2000/09/20 11:03:51 ijr Exp $
____________________________________________________________________________*/

#include "config.h"

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif

#include <string>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "utility.h"
#include "unixprefs.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 = ".:~/."BRANDING_APP_NAME":"UNIX_LIBDIR"/"BRANDING_APP_NAME;
const char*  kDefaultUI = "freeamp.ui";
const char*  kDefaultTextUI = "freeampcmd.ui";
const char*  kDefaultPMO = "soundcard.pmo";
const char*  kDefaultALSADevice = "0:0";
const char*  kDefaultESOUNDHost = "localhost";


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;
        *destPtr = NULL;
    }
    strncpy(newStr + oldLen, src, length);
    newStr[newLen] = '\0';
    *destPtr = newStr;
}

UnixPrefEntry::
UnixPrefEntry()
{
    prefix = NULL;
    key = NULL;
    separator = NULL;
    value = NULL;
    suffix = NULL;
}

UnixPrefEntry::
~UnixPrefEntry()
{
    if (prefix)    delete [] prefix;
    if (key)       delete [] key;
    if (separator) delete [] separator;
    if (value)     delete [] value;
    if (suffix)    delete [] suffix;
}

static bool file_exists(char *s)
{
    struct stat st;
    if ((!s) || (!*s))
        return false;
    if (stat(s, &st) < 0)
        return false;
    return true;
}

UnixPrefs::
UnixPrefs()
     : m_prefsFilePath(0), m_errorLineNumber(0),
       m_saveEnable(true), m_changed(false)
{
    const char *old_suffix = "/.freeamp_prefs";
    char *old_prefsFilePath;
    const char *fadir = "/."BRANDING_APP_NAME;
    const char *suffix = "/preferences";
    char *homeDir = getenv("HOME"); 

    if (!homeDir)
    {
        m_saveEnable = false;
        return;
    }

    // Compute pathname of preferences file
    old_prefsFilePath = new char[strlen(homeDir) + strlen(old_suffix) + 1];
    strcpy(old_prefsFilePath, homeDir);
    strcat(old_prefsFilePath, old_suffix);

    m_prefsFilePath = new char[strlen(homeDir) + strlen(fadir) + strlen(suffix) 
                               + 1];
    strcpy(m_prefsFilePath, homeDir);
    strcat(m_prefsFilePath, fadir);
    if (!file_exists(m_prefsFilePath))
        mkdir(m_prefsFilePath, S_IRWXU);
    strcat(m_prefsFilePath, suffix);

    if (file_exists(old_prefsFilePath))
        rename(old_prefsFilePath, m_prefsFilePath);

    delete [] old_prefsFilePath;

    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)
    {
        UnixPrefEntry *entry = new UnixPrefEntry;
        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++;
            }

            if (p > buffer)
                AppendToString(&entry->prefix, buffer, p - buffer);

            if (*p)
            {
                char *end;
                // char *out;
                int32 length;
                
                entry->key = ReadQuotableString(p, (const char **)&end, ":#");
                if (entry->key && entry->key[0] == '/')
                    continue;
                else if (entry->key && (m_ht.find(entry->key) == m_ht.end()))
                    m_ht[entry->key] = entry;
                else if (!m_errorLineNumber)
                    m_errorLineNumber = lineNumber;
                p = end;
                
                while (*p && (*p == ' ' || *p == '\t'))
                    p++;
                if (*p == ':')
                    p++;
                else if (!m_errorLineNumber)
                    m_errorLineNumber = lineNumber;
                while (*p && (*p == ' ' || *p == '\t'))
                    p++;
                

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -