/*
  キーワードをファイルから取り出す
  Satofumi KAMIMURA
  $Id: get_keyword.c 286 2008-10-20 09:40:22Z satofumi $

  クラスの private として宣言する場合、
  このソースを取り込むクラス宣言の前に、以下の宣言が必要となる
  
  #include <string.h>
  #include <stdlib.h>
  #include <ctype.h>

  \todo Cでコンパイルできるようにする
*/

#ifndef __cplusplus
#include "get_keyword.h"
#endif

int skipSpace(FILE *fd) {
  while (!feof(fd)) {
    int ch = fgetc(fd);
    if ((ch == '\r') || (ch == '\n')) {
      ungetc(ch, fd);
      return -1;
    }
    if (!isspace(ch)) {
      ungetc(ch, fd);
      return 0;
    }
  }
  return -1;
}


void skipToLF(FILE *fd) {
  while (!feof(fd)) {
    int ch = fgetc(fd);
    if ((ch == '\r') || (ch == '\n')) {
      return;
    }
  }
}


char *getString(FILE *fd) {
  enum { BUFFER_MAX = 255 };
  char buffer[BUFFER_MAX+1];
  int index = 0;

  while (!feof(fd)) {
    int ch = fgetc(fd);
    if (isgraph(ch) && (ch != '=')) {
      if (index < BUFFER_MAX) {
	buffer[index++] = ch;
      }
    } else {
      char *ret_str;
      ungetc(ch, fd);
      ret_str = (char *)malloc(index +1);
      strncpy(ret_str, buffer, index);
      ret_str[index] = '\0';
      return ret_str;
    }
  }
  return NULL;
}


char *get_keyword(const char *file, const char *key) {

  FILE *fd = fopen(file, "r");
  if (!fd) {
    return NULL;
  }

  while (!feof(fd)) {
    while (1) {
      char *keyword;
      char *value;

      if (skipSpace(fd) < 0) {		// 空白を読み飛ばす
	break;
      }

      // キーワードを取り出す
      keyword = getString(fd);
      if ((!keyword) || (keyword[0] == '#') || (strcmp(key, keyword))) {
	free(keyword);
	break;
      }
      free(keyword);
      if (skipSpace(fd) < 0) {		// 空白を読み飛ばす
	skipToLF(fd);
	value = (char *)malloc(sizeof(char));
	value[0] = '\0';
	return value;
      }

      // '=' を検出
      if (fgetc(fd) != '=') {
	break;
      }
      if (skipSpace(fd) < 0) {		// 空白を読み飛ばす
	break;
      }

      // キーワードを取り出す
      value = getString(fd);
      if (!value) {
	break;
      }
      return value;
    }
    skipToLF(fd);
  }
  return NULL;
}
