/* Copyright (c) 1991-2002 Doshita Lab. Speech Group, Kyoto University */
/* Copyright (c) 2000-2002 Speech and Acoustics Processing Lab., NAIST */
/*   All rights reserved   */

/* m_jconf.c --- read in jconf file */

/* $Id: m_jconf.c,v 1.3 2002/09/11 22:02:33 ri Exp $ */

#include <julius.h>

#define ISTOKEN(A) (A == ' ' || A == '\t' || A == '\n')

/* get directory name of a file path, with trailing slash */
static void
get_dirname(char *path)
{
  char *p;
  /* /path/file -> /path/ */
  /* path/file  -> path/  */
  /* /file      -> / */
  /* file       ->  */
  /* ../file    -> ../ */
  p = path + strlen(path) - 1;
  while (*p != '/' && p != path) p--;
  if (p == path && *p != '/') *p = '\0';
  else *(p+1) = '\0';
}

/* read-in and parse jconf file and process those using m_options */
void
config_file_parse(char *conffile)
{
  int c_argc;
  char **c_argv;
  FILE *fp;
  int maxnum, step;
  char buf[512], *cpy;
  char *p, *dst, *dst_from;
  char *cdir;

  j_printerr("include config: %s\n", conffile);
  
  /* set the content of jconf file into argument list c_argv[1..c_argc-1] */
  /* c_argv[0] will be the original conffile name */
  /* inside jconf file, quoting by ", ' and escape by '\' is supported */
  if ((fp = fopen_readfile(conffile)) == NULL) {
    j_error("%s: failed to open jconf file: %s\n",EXECNAME, conffile);
  }
  step = 20;
  maxnum = step;
  c_argv = (char **)mymalloc(sizeof(char *) * maxnum);
  c_argv[0] = strcpy((char *)mymalloc(strlen(conffile)+1), conffile);
  c_argc = 1;
  while (getl(buf, 512, fp) != NULL) {
    cpy = (char *)mymalloc(strlen(buf)+1);
    p = buf; dst = cpy;
    while (1) {
      while (*p != '\0' && ISTOKEN(*p)) p++;
      if (*p == '\0') break;
      
      dst_from = dst;
      
      while (*p != '\0' && (!ISTOKEN(*p))) {
	if (*p == 92) {	/* escape by '\' */
	  if (*(++p) == '\0') break;
	  *(dst++) = *(p++);
	} else {
	  if (*p == 34) { /* quote by "" */
	    p++;
	    while (*p != '\0' && *p != 34) *(dst++) = *(p++);
	    if (*p == '\0') break;
	    p++;
	  } else if (*p == 39) { /* quote by '' */
	    p++;
	    while (*p != '\0' && *p != 39) *(dst++) = *(p++);
	    if (*p == '\0') break;
	    p++;
	  } else if (*p == 35) { /* comment out by '#' */
	    *p = '\0';
	    break;
	  } else {		/* other */
	    *(dst++) = *(p++);
	  }
	}
      }
      if (dst != dst_from) {
	*dst = '\0'; dst++;
	if (c_argc >= maxnum) {
	  maxnum += step;
	  c_argv = (char **)myrealloc(c_argv, sizeof(char *) * maxnum);
	}
	c_argv[c_argc++] = dst_from;
      }
    }
  }
  if (fclose_readfile(fp) == -1) {
    j_error("%s: jconf file cannot close\n", EXECNAME);
  }

  if (debug2_flag) {		/* for debug */
    int i;
    j_printf("\t");
    for (i=1;i<c_argc;i++) j_printf(" %s",c_argv[i]);
    j_printf("\n");
  }

  /* now that options are in c_argv[][], call opt_parse() to process them */
  /* relative paths in jconf file are relative to the jconf file (not current) */
  cdir = strcpy((char *)mymalloc(strlen(conffile)+1), conffile);
  get_dirname(cdir);
  opt_parse(c_argc, c_argv, (cdir[0] == '\0') ? NULL : cdir);
  free(cdir);
}

