/***
*
*          Copyright © 1989  Lattice, 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>


#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 struct WBStartup *WBenchMsg;
void main(int, void *);

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




void __stdargs _main(line)
    char *line;
{
    char **pargv;
    char *argbuf;


#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];

    if (argc == 0) {             /* running under workbench      */
        strcpy(window, "con:10/10/320/80/");
        strncat(window, WBenchMsg->sm_ArgList->wa_Name, MAXWINDOW);
        ufbs[0].ufbfh = Open(window, MODE_NEWFILE);
        ufbs[1].ufbfh = ufbs[0].ufbfh;
        ufbs[2].ufbfh = ufbs[0].ufbfh;
        handle = (struct FileHandle *) (ufbs[0].ufbfh << 2);
        process = (struct Process *) FindTask(0);
        process->pr_ConsoleTask = (APTR) handle->fh_Type;
    } 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);
    }

    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;

    __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

    __tzset();

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

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

#ifndef TINY
    exit(0);
#else
    _exit(0);
#endif
}
