/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/COPT.CPP   1.2.1.5   17 Apr 1997 15:43:36   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/COPT.CPP  $
** 
**    Rev 1.2.1.5   17 Apr 1997 15:43:36   ZJRD
** No change.
** 
**    Rev 1.2.1.4   16 Apr 1997 10:17:56   ZJRD
** No change.
** 
**    Rev 1.2.1.3   10 Apr 1997 15:29:22   ZJRD
** 2.09F
** 
**    Rev 1.2.1.1   03 Apr 1997 15:10:40   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:15:42   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:26:54   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:45:12   ZJRD
** Initial revision.
** 
**    Rev 1.3.1.0.1.2   09 Dec 1996 10:14:10   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.3.1.0.1.0   11 Nov 1996 12:57:26   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.3.1.4   09 Sep 1996 13:13:26   ZJRD
** No change.
** 
**    Rev 1.3.1.3   05 Sep 1996 11:24:58   ZJRD
** No change.
** 
**    Rev 1.3.1.2   02 Sep 1996 09:52:04   ZJRD
** EasyPack/SLD Version 1.9d
** 
**    Rev 1.3.1.0   12 Aug 1996 10:49:10   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.0   29 May 1996 09:35:36   ZJRD
** Initial revision.
** 
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
// copt.cpp
//
// Michael Long
//                                                                           
// 5/15/1996
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
//#include "afx.h"


#include "toolopt.h"    
#include "cc.h"
#include "ccoption.h"
#include "ca.h"
#include "caoption.h"
#include "cl.h"
#include "cloption.h"
#include "ce.h"
#include "ceoption.h"
#include "ctab.h"
#include "projopt.h"
#include "copt.h"   
#include "direct.h"
#include "io.h" 
#include "fcntl.h" 
#include "sys\stat.h"
extern char szAppPath[_MAX_PATH+1];

/////////////////////////////////////////////////////////////////////////////
// operations
void COption::SetOption(CWnd *pParent)
{
    CCTab dlg(&m_ccTool, &m_caTool, &m_clTool,&m_ceTool, pParent);
    dlg.DoModal();
}

BOOL COption::SaveOption(FILE * fp)
{                              
    ASSERT(fp);
    
    if(!m_ccTool.SaveOption(fp))
        return FALSE;
    if(!m_caTool.SaveOption(fp))
        return FALSE;
    if(!m_clTool.SaveOption(fp))
        return FALSE;
    if(!m_ceTool.SaveOption(fp))
        return FALSE;
  /*   if((_stricmp(m_ceTool.m_strPath," ")!=0)&&(_stricmp(m_ceTool.m_strProg,"c:\\ ")!=0))
       m_fValid=TRUE;
    else
       m_fValid=FALSE;*/   
    return TRUE;
}
                
BOOL COption::LoadOption(FILE * fp)
{                              
    ASSERT(fp);
    
    if(!m_ccTool.LoadOption(fp))
        return FALSE;
    if(!m_caTool.LoadOption(fp))
        return FALSE;
    if(!m_clTool.LoadOption(fp))
        return FALSE;
    if(!m_ceTool.LoadOption(fp))
        return FALSE;
    return TRUE;
}                
    
// return 0:c file, 1:asm file, 2:other file(library)    
int COption::GetFileType(LPCSTR lpcszFile) const
{              
    ASSERT(lpcszFile);

    char ext[_MAX_EXT];

    _splitpath(lpcszFile, NULL, NULL, NULL, ext);
    if(_stricmp(ext, ".c") == 0) {
        return 0;                
    } else if(_stricmp(ext, ".asm") == 0) {
        return 1;
    } else {
        return 2;
    }
}        

BOOL COption::CreateLinkCmdFile(const CStringList &lst, LPCSTR lpcszProj)
{
    POSITION pos;
    CString str, str1, str2;
    FILE * fp,*fpold;
    int i, flag, bFlag = 0;
    const int ncnt=1 ;
    char ad[ncnt];
    fp = fopen(GetName(lpcszProj, ".lnk"), "wt");
    if(!fp)
        goto CMDFAIL;          
    char drive[_MAX_DRIVE], dir[_MAX_DIR];
    char fname[_MAX_FNAME],  ext[_MAX_EXT];
    char path[_MAX_PATH];
   
    str1 ="version : ";
    if(fwrite(str1.GetBuffer(str1.GetLength()), str1.GetLength(), 1, fp) != 1)
        goto CMDFAIL;
    else
        str1.ReleaseBuffer();

    if(fputc('\n', fp) == EOF)          
        goto CMDFAIL;
  
    str1 ="options : ";
    str = m_clTool.GetOption();
    str1 += str;

    if(fwrite(str1.GetBuffer(str1.GetLength()), str1.GetLength(), 1, fp) != 1)
        goto CMDFAIL;
    else
        str1.ReleaseBuffer();

    if(fputc('\n', fp) == EOF)          
        goto CMDFAIL;
     
    for(i = 0, pos = lst.GetHeadPosition(); pos != NULL; i ++) {
        str2 = lst.GetNext(pos);
         
        flag = GetFileType(str2);
        if(flag != 2) 
          { 
            if(flag==0) bFlag = 1;
            str1 = "input : ";
            str = GetName(str2, ".obj");         
          // for 2500ad compiler  
            _splitpath(str, drive, dir, fname, ext); 
            _makepath (path, NULL, NULL, fname, ext);
            str1 += path;
          }
        else
            str1 = str2;
            
        if(fwrite(str1.GetBuffer(str1.GetLength()), str1.GetLength(), 1, fp) 
            != 1)
            goto CMDFAIL;
        else
            str1.ReleaseBuffer();
            
        if(fputc('\n', fp) == EOF)          
            goto CMDFAIL;
    }
                      
    str1 = "output : ";
    str  = GetName(lpcszProj, " "); 
    _splitpath(str, drive, dir, fname, ext); 
    _makepath (path, NULL, NULL, fname, NULL);
    str1 += path ;              
    
    if(fwrite(str1.GetBuffer(str1.GetLength()), str1.GetLength(), 1, fp) != 1)
        goto CMDFAIL;
    else 
        str1.ReleaseBuffer();
        
    if(fputc('\n', fp) == EOF)          
        goto CMDFAIL;
   
    {
        CString strFile(::szAppPath);
        strFile += "ide25.lnk";
        fpold = fopen(strFile, "rt");
    }
    
    while(feof(fpold)==0){
	    fread(ad,1,ncnt,fpold);
	    fwrite(ad,1,ncnt,fp);
    }
         
    fclose(fpold); 
    fclose(fp);
    return TRUE;
                     
CMDFAIL:
    AfxMessageBox("Failed to create link command file!");                    
    if(fp)
        fclose(fp);
    return FALSE;
                     
}                                              

BOOL COption::WriteBatchFile(FILE * fp, LPCSTR lpcszText)
{
    ASSERT(fp);
    
    if(fwrite(lpcszText, lstrlen(lpcszText), 1, fp) != 1) 
        goto BATFAIL;
    if(fputc('\n', fp) == EOF)
        goto BATFAIL;
        
    return TRUE;

BATFAIL:    
    fclose(fp); 
    AfxMessageBox("Failed to create batch file!");
    return FALSE;
}


void COption::Build(const CStringList &lst, LPCSTR lpcszProj)
{
    POSITION pos;   
    CString str;
    CString strBuild;
    CString cstr;
    CString astr;
    CString lstr;
    cstr = m_ccTool.m_strPath;
    astr = m_caTool.m_strPath; 
    lstr = m_clTool.m_strPath;    
    
     if(_stricmp(m_caTool.m_incPath,m_ccTool.m_incPath)!=0)
    { 
     AfxMessageBox("Include Path of Compiler and Assemble should be same");
     return;
    }

    if(cstr[cstr.GetLength()-1]!='\\')
    cstr = cstr + "\\";
    if(astr[astr.GetLength()-1]!='\\')
    astr = astr + "\\";
    if(lstr[lstr.GetLength()-1]!='\\')
    lstr = lstr + "\\"; 
    int nType;                   
    FILE * fp;
    
    fp = fopen(GetName(lpcszProj, ".bat"), "wt");
    if(!fp) {
        AfxMessageBox("Failed to create batch file!");
        return;
    }
    
    if(!WriteBatchFile(fp, "Set INCLUDE="+m_ccTool.m_incPath))
        return;
    if(!WriteBatchFile(fp, "Set LIB="+m_clTool.m_libPath))
        return;
    
    CString strDir ;
    int     strDrive;
    
    char Directory[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR];
       
    _splitpath(lpcszProj, drive, dir, NULL, NULL);
    _makepath(Directory,drive, dir, NULL, NULL);
    
    strDrive = drive[0]-'a'+1;
    
    _chdrive(strDrive);
    //discard '\' in directory 
     
    for(int i=0;i<_MAX_DIR;i++)
     if(dir[i]=='\\' && dir[i+1]=='\0')
      dir[i] = '\0';
    _chdir(dir);    
   char asmpath[_MAX_PATH], asmfname[_MAX_FNAME],asmext[_MAX_EXT];
   char asmdirectory[_MAX_PATH];
  // char command[_MAX_PATH+_MAX_DIR+5];
    // compile or macro preprocess
    for(pos = lst.GetHeadPosition(); pos != NULL; ) {
        str = lst.GetNext(pos);
        nType = GetFileType(str);
        if(nType == 0) {    // c file  
            strBuild = cstr + "c8051.exe ";
            strBuild += str;
            strBuild +=" ";
            strBuild += m_ccTool.GetOption();
     //       strBuild +=" ";
     //       strBuild +="-o ";
     //       strBuild += GetName(lpcszProj,".obj");
      } else if(nType == 1) { // asm file 
            
            _splitpath(str,NULL,NULL,asmfname,asmext);
            _makepath(asmpath,NULL,NULL,asmfname,asmext);
            strcpy(asmdirectory,Directory); 
            strcat(asmdirectory,asmpath);
            if(CopyFile(str.GetBuffer(str.GetLength()),asmdirectory) == FALSE)
            {
             AfxMessageBox("Cann't find object file");
             str.ReleaseBuffer();
             return;
            }
            strBuild = astr + "x8051.exe ";
            strBuild += asmpath;            
            strBuild += " ";
            strBuild += m_caTool.GetOption(); 
            strBuild +=" "; 
            str.ReleaseBuffer();
             //     strBuild +="-o ";
       //     strBuild += GetName(lpcszProj,".obj");
        } else {
            continue;
        }            
                
        if(!WriteBatchFile(fp, strBuild))
            return;
        
    }                                   
    
    // link
    if(!CreateLinkCmdFile(lst, lpcszProj))
        return;
    strBuild = lstr + "link.exe ";
    strBuild += " "; 
    strBuild += GetName(lpcszProj, ".lnk");
    if(!WriteBatchFile(fp, strBuild))
        return;
    if(!WriteBatchFile(fp, "pause"))
        return;
    fclose(fp);
    
    
    
    WinExec(GetName(lpcszProj, ".bat"), SW_SHOW);
}

  static char BASED_CODE szFilter[] = 
    "Source file (*.cpp)|*.cpp|Source file (*.c)|*.c|Source file (*.asm)|*.asm|All Files (*.*)|*.*||";
            
 void COption::Editor(CWnd * pParent)
  {
   CString str;
   CString str1;
   CString filename;
                
    str1 = m_ceTool.m_strPath; 
    char drive[_MAX_DRIVE], dir[_MAX_DIR];
    char fname[_MAX_FNAME],  ext[_MAX_EXT];
   
    _splitpath(str1, drive, dir, fname, ext);
    if(!(_stricmp(ext,".exe")==0||_stricmp(ext,".com")==0))
    {
     AfxMessageBox("Editor command error!");
      return;
     }
   CFileDialog dlg(TRUE, NULL, "*.c", 
        OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter, pParent);
    
   dlg.m_ofn.lpstrTitle = "Open File ";
   if(dlg.DoModal() == IDOK) {
      filename = dlg.GetPathName();
      m_ceTool.m_strProg = filename;
    
      str = m_ceTool.m_strPath + " ";
      str += filename;
      WinExec(str, SW_SHOW);
   }
}
 

BOOL COption::CopyFile(char* pszSource, char* pszTarget)
{
    int hSource, hTarget;

    if ( -1 == (hSource = _open(pszSource, _O_BINARY|_O_RDONLY)) ) {
        return FALSE;
    }
        
    hTarget = _open(pszTarget, _O_BINARY | _O_WRONLY | _O_CREAT | _O_TRUNC,
                               _S_IREAD | _S_IWRITE);

    if ( -1 == hTarget ) {
        return FALSE;
    }
        
    unsigned nCount = 0xff00;
    if ( (unsigned)_filelength(hSource) < nCount ) {
        nCount = (int)_filelength(hSource);
    }

    char* p = new char[sizeof(char)*nCount];
    if ( !p ) {
        return FALSE;
    }
    
    while ( !_eof(hSource) ) {
        if ( -1 == (nCount = _read(hSource, p, nCount)) ) {
            return FALSE;
        }
        if ( -1 == (nCount = _write(hTarget, p, nCount )) ) {
            return FALSE;
        }
    }

    _close( hSource );
    _close( hTarget );
    
    delete []p;

    return TRUE;
}

                