/*
 $Id: cmdpars.cc,v 1.2 1996/10/11 16:15:27 roitzsch Exp $
 (C)opyright 1996 by Konrad-Zuse-Center, Berlin
 All rights reserved.
 Part of the Kaskade distribution
*/

#include "general.h"
#include "utils.h"
#include "cmdpars.h"

//-------------------------------------------------------------------------


void CmdPars::read (int argc, char** argv)
{
    int i, n;

    // -- 	       first read command files ...

    ReadCmdFile("kaskade.init");  	// default cmd-file kaskade.init
    // ReadCmdFile(argv[0]);  	// default cmd-file: programme name

    for (i=1; i<argc; ++i)  
    {
	if (strchr(argv[i], CommentFlag)) break;	// ignore rest of line
	char* pos = strchr(argv[i],'=');
	++pos;
	if (!strncmp(argv[i],"cmd",3)) ReadCmdFile(pos);
    } 


    // -- 	      ... then command line options:

    for (i=1; i<argc; ++i)  
    {
	if (strchr(argv[i], CommentFlag)) break;

	for (n=1; n<4; ++n) tolower(argv[i][n]); 
	if (strncmp(argv[i],"file",4)) strToLower(argv[i]);  // not the file name

	if (strncmp(argv[i],"cmd",3)) putToDict(argv[i]);
    } 

    // dict.ambiguityCheck();
    cout << "\n";
}
//-------------------------------------------------------------------------


int CmdPars::ReadCmdFile(const char *file)
{
    int  n;
    char str[256];

    sprintf(str, "%s", file);
    if (!strchr(str,'.')) strcat(str,".cmd");
    cout << "\n  Command File " << str << " read\n";

    Parser parser(str,"",CommentFlag);

    while (parser.getString(str) != parser.eof)
    {
	for (n=1; n<4; ++n) tolower(str[n]); 
	if (strncmp(str,"file",4)) strToLower(str);  // it's not the file name

	putToDict(str);
    }
    return 1;
}
//------------------------------------------------------------------------


void CmdPars:: putToDict(char* obj)
{
    char key[100], val[100], *pos;

    if (strchr(obj, CommentFlag)) return;

    if ((pos=strchr(obj,'=')))
    {
	*pos = '\0';
	strcpy(key, obj);
	strcpy(val, pos+1);
    }
    else			// boolean parameter, 'true' assumed
    {
	strcpy(key, obj);
	strcpy(val, "1");
    }

    if (dict.inDict(key)) dict.changeValue(key,val);
    else  		  dict.push(key,val);
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------


int CmdPars::isSet(const char* key, const char* name)	// look for pair (key,name)
{
    char value[100], s[100];

    strcpy(s,key);
    strToLower(s);

    if (!dict.getVal(s, value)) return 0;	// key not present
    else 
    {
	int n1, n2;

	strcpy(s,name);
	strToLower(s);
	n1 = strlen(value);
	n2 = strlen(s);

	n1 = (n1<n2) ? n1 : n2;			// minimal length
	if (!strncmp(value, s, n1))  return 1;  // pair found!
    }
    return 0;
}
//-------------------------------------------------------------------------

int CmdPars::isPresent(const char* name)	// search for a keyword
{
    char s[100]; 
    strcpy(s,name);
    strToLower(s);
    return  dict.inDict(s);
}
//-------------------------------------------------------------------------

int CmdPars::isTrue(const char* name)		// look for boolean keyword
{
    char value[100], s[100];

    strcpy(s,name);
    strToLower(s);

    if (!dict.getVal(s, value)) return 0;
    else 		      	return atoi(value);
}
//-------------------------------------------------------------------------

int CmdPars::get(const char* name, char* value)
{
    char s[100];
    strcpy(s,name);
    strToLower(s);
    return dict.getVal(s, value);
}

int CmdPars::get(const char* name, int* value)
{
    char s[100]; 
    strcpy(s,name);
    strToLower(s);
    return dict.getVal(s, value);
}

int CmdPars::get(const char* name, float* value)
{
    char s[100]; 
    strcpy(s,name);
    strToLower(s);
    return dict.getVal(s, value);
}

int CmdPars::get(const char* name, double* value)
{
    char s[100]; 
    strcpy(s,name);
    strToLower(s);
    return dict.getVal(s, value);
}
//-------------------------------------------------------------------------

ostream& operator<< (ostream& os, CmdPars& c)
{
    os << "\nCommand parameters:\n" << c.dict;
    return os;
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------


InfoFile:: InfoFile()
{
    fileName = new char[strlen("main.lis")+1];
    strcpy (fileName, "main.lis");

    if (fb.open(fileName, ios::out) == 0)
    { 
	cout << "\n*** InfoFile: output file " << fileName 
	     << " could not be opened\n"; 
	cout.flush(); abort(); 
    }
    os = new ostream(&fb);
}
//-------------------------------------------------------------------------

InfoFile:: ~InfoFile()
{
    fb.close();
    delete fileName;
    delete os;
}
//-------------------------------------------------------------------------

void InfoFile:: write(char* s)  { *os << s; }
void InfoFile:: write(int i)    { *os << i; }
void InfoFile:: write(float  x) { *os << x; }
void InfoFile:: write(double x) { *os << x; }
