C++程序  |  98行  |  1.69 KB

/* conf.c - config file parser */

#include "config.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "src/conf.h"

void strip_char (char *line, char c)
{
  char *p = strchr (line, c);
  if (p)
    *p = '\0';
}

void strip_newlines (char *line)
{
  strip_char (line, '\n');
  strip_char (line, '\r');
}

char *eat_whitespace (char *line)
{
  while (isspace ((int)(unsigned char)*line))
    line++;
  return line;
}

int is_ignored_line (char *line)
{
  return !*line || *line == '#';
}

struct conf_entry *conf_parse (FILE *f)
{
  struct conf_entry *head = NULL;
  struct conf_entry *tail = NULL;
  char buf[CONF_MAX_LINE];

  while (fgets (buf, sizeof (buf), f))
    {
      struct conf_entry *e;
      char *start = buf;
      char *key;
      char *val;
      strip_newlines (start);
      start = eat_whitespace (start);
      if (is_ignored_line (start))
        continue;
      key = strtok (start, " \t");
      val = strtok (NULL, "");
      if (val)
        val = eat_whitespace (val);
      e = malloc (sizeof *e);
      if (!e)
        goto fail;
      e->next = NULL;
      e->key = strdup (key);
      e->value = val ? strdup (val) : NULL;
      if (!e->key || (val && !e->value))
        {
          free (e->key);
          free (e->value);
          goto fail;
        }
      if (!head)
        {
          head = e;
          tail = e;
        }
      else
        {
          tail->next = e;
          tail = e;
        }
    }

  return head;
fail:
  conf_free (head);
  return NULL;
}

void conf_free (struct conf_entry *e)
{
  struct conf_entry *n;
  while (e)
    {
      n = e->next;
      free (e->key);
      free (e->value);
      free (e);
      e = n;
    }
}