Blame dao/Settings.cc

Packit Service 3e823c
/*  cdrdao - write audio CD-Rs in disc-at-once mode
Packit Service 3e823c
 *
Packit Service 3e823c
 *  Copyright (C) 1998-2001 Andreas Mueller <andreas@daneb.de>
Packit Service 3e823c
 *
Packit Service 3e823c
 *  This program is free software; you can redistribute it and/or modify
Packit Service 3e823c
 *  it under the terms of the GNU General Public License as published by
Packit Service 3e823c
 *  the Free Software Foundation; either version 2 of the License, or
Packit Service 3e823c
 *  (at your option) any later version.
Packit Service 3e823c
 *
Packit Service 3e823c
 *  This program is distributed in the hope that it will be useful,
Packit Service 3e823c
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 3e823c
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 3e823c
 *  GNU General Public License for more details.
Packit Service 3e823c
 *
Packit Service 3e823c
 *  You should have received a copy of the GNU General Public License
Packit Service 3e823c
 *  along with this program; if not, write to the Free Software
Packit Service 3e823c
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Packit Service 3e823c
 */
Packit Service 3e823c
Packit Service 3e823c
#include <stdio.h>
Packit Service 3e823c
#include <stdlib.h>
Packit Service 3e823c
#include <ctype.h>
Packit Service 3e823c
#include <unistd.h>
Packit Service 3e823c
#include <errno.h>
Packit Service 3e823c
#include <string.h>
Packit Service 3e823c
#include <assert.h>
Packit Service 3e823c
Packit Service 3e823c
#include "Settings.h"
Packit Service 3e823c
Packit Service 3e823c
#include "util.h"
Packit Service 3e823c
#include "log.h"
Packit Service 3e823c
Packit Service 3e823c
Packit Service 3e823c
#ifdef UNIXWARE
Packit Service 3e823c
extern "C" {
Packit Service 3e823c
  extern int      strcasecmp(const char *, const char *);
Packit Service 3e823c
}
Packit Service 3e823c
#endif
Packit Service 3e823c
Packit Service 3e823c
  
Packit Service 3e823c
enum SettingType { SET_INTEGER, SET_STRING };
Packit Service 3e823c
Packit Service 3e823c
const char* Settings::setWriteSpeed       = "write_speed";
Packit Service 3e823c
const char* Settings::setWriteDriver      = "write_driver";
Packit Service 3e823c
const char* Settings::setWriteDevice      = "write_device";
Packit Service 3e823c
const char* Settings::setWriteBuffers     = "write_buffers";
Packit Service 3e823c
const char* Settings::setUserCapacity     = "user_capacity";
Packit Service 3e823c
const char* Settings::setFullBurn         = "full_burn";
Packit Service 3e823c
const char* Settings::setReadSpeed        = "read_speed";
Packit Service 3e823c
const char* Settings::setReadDriver       = "read_driver";
Packit Service 3e823c
const char* Settings::setReadDevice       = "read_device";
Packit Service 3e823c
const char* Settings::setReadParanoiaMode = "read_paranoia_mode";
Packit Service 3e823c
const char* Settings::setCddbServerList   = "cddb_server_list";
Packit Service 3e823c
const char* Settings::setCddbTimeout      = "cddb_timeout";
Packit Service 3e823c
const char* Settings::setCddbDbDir        = "cddb_directory";
Packit Service 3e823c
const char* Settings::setTmpFileDir       = "tmp_file_dir";
Packit Service 3e823c
Packit Service 3e823c
class SettingEntry {
Packit Service 3e823c
public:
Packit Service 3e823c
  SettingEntry(const char *, int);
Packit Service 3e823c
  SettingEntry(const char *, const char *);
Packit Service 3e823c
  ~SettingEntry();
Packit Service 3e823c
Packit Service 3e823c
  SettingType type_;
Packit Service 3e823c
Packit Service 3e823c
  char *name_;
Packit Service 3e823c
  union {
Packit Service 3e823c
    int integerValue_;
Packit Service 3e823c
    char *stringValue_;
Packit Service 3e823c
  } val_;
Packit Service 3e823c
Packit Service 3e823c
  SettingEntry *next_;
Packit Service 3e823c
};
Packit Service 3e823c
Packit Service 3e823c
class SettingsImpl {
Packit Service 3e823c
public:
Packit Service 3e823c
  SettingsImpl();
Packit Service 3e823c
  ~SettingsImpl();
Packit Service 3e823c
Packit Service 3e823c
  void addSetting(SettingEntry *);
Packit Service 3e823c
  SettingEntry *findSetting(const char *, SettingType);
Packit Service 3e823c
  void set(const char *, int);
Packit Service 3e823c
  void set(const char *, const char *);
Packit Service 3e823c
Packit Service 3e823c
  int read(FILE *);
Packit Service 3e823c
  
Packit Service 3e823c
  void parseAndSetValue(char *name, char *valStr);
Packit Service 3e823c
Packit Service 3e823c
  SettingEntry *settings_;
Packit Service 3e823c
};
Packit Service 3e823c
Packit Service 3e823c
SettingEntry::SettingEntry(const char *name, int val)
Packit Service 3e823c
{
Packit Service 3e823c
  type_ = SET_INTEGER;
Packit Service 3e823c
  name_ = strdupCC(name);
Packit Service 3e823c
  val_.integerValue_ = val;
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
SettingEntry::SettingEntry(const char *name, const char *val)
Packit Service 3e823c
{
Packit Service 3e823c
  type_ = SET_STRING;
Packit Service 3e823c
  name_ = strdupCC(name);
Packit Service 3e823c
  val_.stringValue_ = strdupCC(val);
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
SettingEntry::~SettingEntry()
Packit Service 3e823c
{
Packit Service 3e823c
  delete[] name_;
Packit Service 3e823c
  name_ = NULL;
Packit Service 3e823c
Packit Service 3e823c
  if (type_ == SET_STRING) {
Packit Service 3e823c
    delete[] val_.stringValue_;
Packit Service 3e823c
    val_.stringValue_ = NULL;
Packit Service 3e823c
  }
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
Packit Service 3e823c
SettingsImpl::SettingsImpl()
Packit Service 3e823c
{
Packit Service 3e823c
  settings_ = NULL;
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
SettingsImpl::~SettingsImpl()
Packit Service 3e823c
{
Packit Service 3e823c
  SettingEntry *next;
Packit Service 3e823c
Packit Service 3e823c
  while (settings_ != NULL) {
Packit Service 3e823c
    next = settings_->next_;
Packit Service 3e823c
    delete settings_;
Packit Service 3e823c
    settings_ = next;
Packit Service 3e823c
  }
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
void SettingsImpl::addSetting(SettingEntry *s)
Packit Service 3e823c
{
Packit Service 3e823c
  s->next_ = settings_;
Packit Service 3e823c
  settings_ = s;
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
Packit Service 3e823c
SettingEntry *SettingsImpl::findSetting(const char *name, SettingType type)
Packit Service 3e823c
{
Packit Service 3e823c
  SettingEntry *run;
Packit Service 3e823c
Packit Service 3e823c
  for (run = settings_; run != NULL; run = run->next_) {
Packit Service 3e823c
    if (run->type_ == type && strcasecmp(run->name_, name) == 0)
Packit Service 3e823c
      return run;
Packit Service 3e823c
  }
Packit Service 3e823c
Packit Service 3e823c
  return NULL;
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
void SettingsImpl::set(const char *name, int val)
Packit Service 3e823c
{
Packit Service 3e823c
  SettingEntry *s = findSetting(name, SET_INTEGER);
Packit Service 3e823c
Packit Service 3e823c
  if (s == NULL) {
Packit Service 3e823c
    addSetting(new SettingEntry(name, val));
Packit Service 3e823c
  }
Packit Service 3e823c
  else {
Packit Service 3e823c
    s->val_.integerValue_ = val;
Packit Service 3e823c
  }
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
void SettingsImpl::set(const char *name, const char *val)
Packit Service 3e823c
{
Packit Service 3e823c
  SettingEntry *s = findSetting(name, SET_STRING);
Packit Service 3e823c
Packit Service 3e823c
  if (s == NULL) {
Packit Service 3e823c
    addSetting(new SettingEntry(name, val));
Packit Service 3e823c
  }
Packit Service 3e823c
  else {
Packit Service 3e823c
    delete[] s->val_.stringValue_;
Packit Service 3e823c
    s->val_.stringValue_ = strdupCC(val);
Packit Service 3e823c
  }
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
#define MAX_LINE_LENGTH 1024
Packit Service 3e823c
int SettingsImpl::read(FILE *fp)
Packit Service 3e823c
{
Packit Service 3e823c
  char buf[MAX_LINE_LENGTH];
Packit Service 3e823c
  char *p, *p1;
Packit Service 3e823c
  char *name;
Packit Service 3e823c
  long n;
Packit Service 3e823c
Packit Service 3e823c
  while (fgets(buf, MAX_LINE_LENGTH, fp) != NULL) {
Packit Service 3e823c
    // handle comment
Packit Service 3e823c
    if ((p = strchr(buf, '#')) != NULL)
Packit Service 3e823c
      continue;
Packit Service 3e823c
Packit Service 3e823c
    if ((p = strchr(buf, ':')) != NULL) {
Packit Service 3e823c
      *p++ = 0;
Packit Service 3e823c
Packit Service 3e823c
      p1 = buf;
Packit Service 3e823c
      while (*p1 != 0 && isspace(*p1))
Packit Service 3e823c
        p1++;
Packit Service 3e823c
Packit Service 3e823c
      name = p1;
Packit Service 3e823c
Packit Service 3e823c
      while (*p1 != 0 && !isspace(*p1))
Packit Service 3e823c
        p1++;
Packit Service 3e823c
      *p1 = 0;
Packit Service 3e823c
Packit Service 3e823c
      while (*p != 0 && isspace(*p))
Packit Service 3e823c
        p++;
Packit Service 3e823c
Packit Service 3e823c
      // strip off trailing white space
Packit Service 3e823c
      if ((n = strlen(p)) > 0) {
Packit Service 3e823c
        for (p1 = p + n - 1; p1 >= p; p1--) {
Packit Service 3e823c
          if (isspace(*p1)) {
Packit Service 3e823c
            *p1 = 0;
Packit Service 3e823c
          }
Packit Service 3e823c
        }
Packit Service 3e823c
      }
Packit Service 3e823c
Packit Service 3e823c
      parseAndSetValue(name, p);
Packit Service 3e823c
    }
Packit Service 3e823c
  }
Packit Service 3e823c
Packit Service 3e823c
  return 0;
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
void SettingsImpl::parseAndSetValue(char *name, char *valStr)
Packit Service 3e823c
{
Packit Service 3e823c
  char *p;
Packit Service 3e823c
  char *val;
Packit Service 3e823c
  int intValue;
Packit Service 3e823c
Packit Service 3e823c
  if (name == NULL || *name == 0 || valStr == NULL || *valStr == 0)
Packit Service 3e823c
    return;
Packit Service 3e823c
Packit Service 3e823c
  if (*valStr == '"') {
Packit Service 3e823c
    val = valStr + 1;
Packit Service 3e823c
    p = val + strlen(val)-1;
Packit Service 3e823c
    if (*p != '"') {
Packit Service 3e823c
      fprintf(stderr,"Error in string constant '%s'\n", valStr);
Packit Service 3e823c
    } else {
Packit Service 3e823c
      *p=0;
Packit Service 3e823c
      set(name, val);
Packit Service 3e823c
    }
Packit Service 3e823c
    
Packit Service 3e823c
  } else {  /* valSTR is numeric? */
Packit Service 3e823c
    char * end = NULL;
Packit Service 3e823c
    errno=0;
Packit Service 3e823c
    intValue = strtol(valStr, &end, 0);
Packit Service 3e823c
    if(errno != 0 || !end || *end) {
Packit Service 3e823c
      fprintf(stderr,"Error parsing numeric option '%s' (missing quotes?)\n",
Packit Service 3e823c
              valStr);
Packit Service 3e823c
    } else
Packit Service 3e823c
      set(name, intValue);
Packit Service 3e823c
  }
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
Settings::Settings()
Packit Service 3e823c
{
Packit Service 3e823c
  impl_ = new SettingsImpl;
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
Settings::~Settings()
Packit Service 3e823c
{
Packit Service 3e823c
  delete impl_;
Packit Service 3e823c
  impl_ = NULL;
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
int Settings::read(const char *fname)
Packit Service 3e823c
{
Packit Service 3e823c
  FILE *fp;
Packit Service 3e823c
Packit Service 3e823c
  if ((fp = fopen(fname, "r")) == NULL)
Packit Service 3e823c
    return 1;
Packit Service 3e823c
Packit Service 3e823c
  impl_->read(fp);
Packit Service 3e823c
Packit Service 3e823c
  fclose(fp);
Packit Service 3e823c
Packit Service 3e823c
  return 0;
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
int Settings::write(const char *fname) const
Packit Service 3e823c
{
Packit Service 3e823c
  SettingEntry *run;
Packit Service 3e823c
  FILE *fp;
Packit Service 3e823c
  
Packit Service 3e823c
  if ((fp = fopen(fname, "w")) == NULL) {
Packit Service 3e823c
    log_message(-2, "Cannot open \"%s\" for writing: %s", fname, strerror(errno));
Packit Service 3e823c
    return 1;
Packit Service 3e823c
  }
Packit Service 3e823c
Packit Service 3e823c
  for (run = impl_->settings_; run != NULL; run = run->next_) {
Packit Service 3e823c
    switch (run->type_) {
Packit Service 3e823c
    case SET_INTEGER:
Packit Service 3e823c
      fprintf(fp, "%s: %d\n", run->name_, run->val_.integerValue_);
Packit Service 3e823c
      break;
Packit Service 3e823c
    case SET_STRING:
Packit Service 3e823c
      fprintf(fp, "%s: \"%s\"\n", run->name_, run->val_.stringValue_);
Packit Service 3e823c
      break;
Packit Service 3e823c
    }
Packit Service 3e823c
  }
Packit Service 3e823c
Packit Service 3e823c
  fclose(fp);
Packit Service 3e823c
Packit Service 3e823c
  return 0;
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
const int *Settings::getInteger(const char *name) const
Packit Service 3e823c
{
Packit Service 3e823c
  SettingEntry *s = impl_->findSetting(name, SET_INTEGER);
Packit Service 3e823c
Packit Service 3e823c
  if (s != NULL)
Packit Service 3e823c
    return &(s->val_.integerValue_);
Packit Service 3e823c
  else
Packit Service 3e823c
    return NULL;
Packit Service 3e823c
}
Packit Service 3e823c
  
Packit Service 3e823c
const char *Settings::getString(const char *name) const
Packit Service 3e823c
{
Packit Service 3e823c
  SettingEntry *s = impl_->findSetting(name, SET_STRING);
Packit Service 3e823c
Packit Service 3e823c
  if (s != NULL)
Packit Service 3e823c
    return s->val_.stringValue_;
Packit Service 3e823c
  else
Packit Service 3e823c
    return NULL;
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
void Settings::set(const char *name, int val)
Packit Service 3e823c
{
Packit Service 3e823c
  impl_->set(name, val);
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
void Settings::set(const char *name, const char *val)
Packit Service 3e823c
{
Packit Service 3e823c
  impl_->set(name, val);
Packit Service 3e823c
}