/***
*
*          Copyright © 1992 SAS Institute, Inc.
*
* name             __main - process command line, open files, and call main()
*
* synopsis         __main(line);
*                  char *line;     ptr to command line that caused execution
*
* description      This function performs the standard pre-processing for
*                  the main module of a C program.  It accepts a command
*                  line of the form
*
*                       pgmname arg1 arg2 ...
*
*                  and builds a list of pointers to each argument.  The first
*                  pointer is to the program name.  For some environments, the
*                  standard I/O files are also opened, using file names that
*                  were set up by the OS interface module XCMAIN.
*
***/

#include <stdio.h>
#include <fcntl.h>
#include <ios1.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <workbench/startup.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <exec/execbase.h>

extern struct ExecBase *SysBase;

#define MAXARG 32
#define QUOTE       '"'
#define MAXWINDOW   40
#define ESCAPE '*'
#define ESC '\027'
#define NL '\n'

#define isspace(c)      ((c == ' ')||(c == '\t') || (c == '\n'))


#ifndef TINY
extern int __fmode;
#endif

extern char __stdiowin[];
extern char __stdiov37[];

extern struct WBStartup *_WBenchMsg;
int main(int, void *);

static int argc;                            /* arg count */
static char **targv, *argv[MAXARG+1];       /* arg pointers */




void __stdargs __main(line)
    char *line;
{
    char **pargv;
    char *argbuf;
    int ret;


#ifndef TINY
    int x;
    struct Process *process;
    struct FileHandle *handle;
    struct UFB  ufbs[3];
    static char window[MAXWINDOW+18];
#endif


/***
*     Build argument pointer list
***/
   while (argc < MAXARG)
   {
        while (isspace(*line))  line++;
        if (*line == '\0')      break;
        pargv = &argv[argc++];
        if (*line == QUOTE)
        {
            argbuf = *pargv = ++line;  /* ptr inside quoted string */
            while (*line != QUOTE && *line != 0)
            {
               if (*line == ESCAPE)
               {
                  line++;
                  switch (*line)
                  {
                     case '\0':
                        *argbuf = 0;
                        goto linedone;
                     case 'E':
                        *argbuf++ = ESC;
                        break;
                     case 'N':
                        *argbuf++ = NL;
                        break;
                     default:
                        *argbuf++ = *line;
                  }
                  line++;
               }
               else
               {
                 *argbuf++ = *line++;
               }
            }
            line++;
            *argbuf++ = '\0'; /* terminate arg */
        }
        else            /* non-quoted arg */
        {       
            *pargv = line;
            while ((*line != '\0') && (!isspace(*line))) line++;
            if (*line == '\0')  break;
            else                *line++ = '\0';  /* terminate arg */
        }
   }  /* while */

linedone:

    targv = (argc == 0) ? (char **) _WBenchMsg : (char **) &argv[0];


/***
*     Open standard files
***/

#ifndef TINY
    ufbs[0].ufbnxt = &ufbs[1];
    ufbs[1].ufbnxt = &ufbs[2];
    ufbs[2].ufbnxt = NULL;
    __ufbs = &ufbs[0];
    ufbs[0].ufbfn = NULL;
    ufbs[1].ufbfn = NULL;
    ufbs[2].ufbfn = NULL;
    ufbs[0].ufbflg = UFB_RA | O_RAW | UFB_NC;
    ufbs[1].ufbflg = UFB_WA | O_RAW | UFB_NC;
    ufbs[2].ufbflg = UFB_WA | O_RAW | UFB_NC | UFB_CLO;

    if (argc == 0) 
    {             /* running under workbench      */
        if (_WBenchMsg->sm_ToolWindow)
            ufbs[0].ufbfh = Open(_WBenchMsg->sm_ToolWindow, MODE_NEWFILE);
        else
        {
           strcpy(window, __stdiowin);
           strncat(window, _WBenchMsg->sm_ArgList->wa_Name, MAXWINDOW);
        
           if (SysBase->LibNode.lib_Version >= 36)
              strncat(window, __stdiov37, MAXWINDOW+18-strlen(window)-1); 
            
           ufbs[0].ufbfh = Open(window, MODE_NEWFILE);
        }
        
        ufbs[0].ufbflg |= UFB_CLO;
        handle = (struct FileHandle *) (ufbs[0].ufbfh << 2);
        process = (struct Process *) FindTask(0);
        process->pr_ConsoleTask = (APTR) handle->fh_Type;
        if ((ufbs[1].ufbfh = Open("*", MODE_OLDFILE)) == NULL)
             ufbs[1].ufbfh = Open("NIL:", MODE_OLDFILE);
        ufbs[2].ufbfh = ufbs[1].ufbfh;
    } 
    else 
    {                     /* running under CLI            */
        ufbs[0].ufbfh = Input();
        ufbs[1].ufbfh = Output();
        if ((ufbs[2].ufbfh = Open("*", MODE_OLDFILE)) == NULL)
             ufbs[2].ufbfh = Open("NIL:", MODE_OLDFILE);
    }


    __nufbs += 3;


    x = (__fmode) ? 0 : _IOXLAT;
    stdin->_file = 0;
    stdin->_flag = _IOREAD | x;
    stdout->_file = 1;
    stdout->_flag = _IOWRT | _IOLBF | x;
    stderr->_file = 2;
    stderr->_flag = _IOWRT | _IOLBF | x;

#endif


/***
*     Call user's main program
***/

    ret = main(argc, targv);                /* call main function */

#ifndef TINY
    exit(ret);
#else
    __exit(ret);
#endif
}
