/*
 * TimeCom - Time a command.
 *
 * Version 37.1 =TP= 16-Jan-92
 * Compile with SAS/C 5.10 and link without startup code:
 *      lc -cqfist -v -b0 -rr -O -ms TimeCom
 *      blink TimeCom.o to TimeCom sd sc
 *      protect TimeCom +p
 *
 * Copyright (c) 1992 Torsten Poulin
 *
 * Torsten Poulin
 * Banebrinken 99, 2, lejlighed 77
 * DK 2400  København NV
 * DENMARK
 */
/* section: User Environment Utilities */

/****** English:TIMECOM ***************************************************
*
*   FORMAT
*       TIMECOM [TO <log file> [APPEND]] [COMMAND] <command line>
*
*   TEMPLATE
*       TO/K,APPEND/S,COMMAND/F/A
*
*   PURPOSE
*       To time a command.
*
*   SPECIFICATION
*       The <command line> is executed; after it is complete, TimeCom
*       prints the elapsed time during the command.  The time is
*       reported in seconds.
*
*       The time is printed on CONSOLE: unless the TO option is used
*       to specify an output file.  The APPEND switch adds the output
*       to the end of the specified output file.  This is useful for
*       keeping a log of the execution times of several commands.
*
*   EXAMPLES
*           1> TIMECOM MyProgram
*           Elapsed time: 23 seconds.
*
*           1> TIMECOM TO timelog APPEND MyProgram
*           1> TYPE timelog
*           Elapsed time: 23 seconds. Command: MyProgram
*
*           1> ALIAS MyProgram "TIMECOM TO log APPEND MyProgram"
*           1> MyProgram
*
*   WARNING
*       The time value is not extremely accurate.
*
*   SEE ALSO
*       intuition.library/CurrentTime
*       in `ROM Kernel Reference Manual: Includes and Autodocs.'
*
***************************************************************************
*
*/
/****** dansk:TIMECOM *****************************************************
*
*   FORMAT
*       TIMECOM [TO <logfil> [APPEND]] [COMMAND] <kommandolinje>
*
*   SKABELON
*       TO/K,APPEND/S,COMMAND/F/A
*
*   FORMÅL
*       At tage tid på en kommando.
*
*   SPECIFIKATION
*       Argumentet <kommandolinje> udføres.  Når det er færdig
*       udskriver TimeCom den forløbne tid.  Tiden rapporteres i
*       sekunder.
*
*       Tiden udskrives på CONSOLE: medmindre argumentet TO bruges
*       til at angive en uddatafil.  Kontakten APPEND tilføjer
*       uddata til slutningen uddatafilen.  Dette er nyttigt til
*       at føre en logfil over kørselstiderne for flere
*       kommandoer.
*
*   EKSEMPLER
*           1> TIMECOM MitProgram
*           Elapsed time: 23 seconds.
*
*           1> TIMECOM TO tidslog APPEND MitProgram
*           1> TYPE tidslog
*           Elapsed time: 23 seconds. Command: MitProgram
*
*           1> ALIAS MitProgram "TIMECOM TO logfil APPEND MitProgram"
*           1> MitProgram
*
*   ADVARSEL
*       Tiderne er ikke ekstremt nøjagtige.
*
*   SE OGSÅ
*       intuition.library/CurrentTime
*       i `ROM Kernel Reference Manual: Includes and Autodocs.'
*
***************************************************************************
*
*/


#include <exec/types.h>
#include <libraries/dos.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>

#define OPT_TO      0
#define OPT_APPEND  1
#define OPT_COMMAND 2


static LONG MySystemTags(struct DosLibrary *DOSBase,
                         UBYTE *command, ULONG firsttag, ...);

char const *version = "\0$VER: TimeCom 37.1 (16.1.92) ©1992 Torsten Poulin";

int entrypoint(void)
{
    struct RDArgs        *args;

    struct IntuitionBase *IntuitionBase;
    struct DosLibrary    *DOSBase;
    struct Library       *SysBase;

    BPTR  out;
    ULONG secs1 = 0, secs2 = 0, not_used = 0;
    LONG  arg[3];
    LONG  rc = RETURN_OK;


    SysBase = *(struct Library **) 4L;
    if(!(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L)))
    {
        rc = RETURN_FAIL;
        goto exit1;
    }
    if(!(IntuitionBase = (struct IntuitionBase *)
                            OpenLibrary("intuition.library", 33L)))
    {
        rc = RETURN_FAIL;
        goto exit2;
    }

    arg[OPT_TO] = arg[OPT_APPEND] = arg[OPT_COMMAND] = 0L;
    
    if(args = ReadArgs("TO/K,APPEND/S,COMMAND/F/A", arg, NULL))
    {
        CurrentTime(&secs1, &not_used);
        rc = MySystemTags(DOSBase, (UBYTE *) arg[OPT_COMMAND],
                          SYS_UserShell, TRUE,
                          TAG_DONE);
        CurrentTime(&secs2, &not_used);
        if(rc == -1)
            rc = RETURN_ERROR;
        secs2 -= secs1;

        if(out = Open(arg[OPT_TO] ? (UBYTE *) arg[OPT_TO] : "CONSOLE:",
                 (BOOL) arg[OPT_APPEND] ? MODE_READWRITE : MODE_NEWFILE))
        {
            if((BOOL) arg[OPT_APPEND] && arg[OPT_TO])
                Seek(out, 0L, OFFSET_END);
            VFPrintf(out, "Elapsed time: %ld second", (LONG *) &secs2);
            FPuts(out, secs2 == 1 ? "." : "s.");
            if(arg[OPT_TO])
                VFPrintf(out, " Command: %s", (LONG *) &arg[OPT_COMMAND]);
            FPutC(out, '\n');
            Close(out);
        }
        else
        {
            LONG err = IoErr();
            PrintFault(err, "TimeCom");
            rc = RETURN_ERROR;
        }

        FreeArgs(args);
    }
    else
    {
        LONG err = IoErr();
        PrintFault(err, "TimeCom");
        rc = RETURN_ERROR;
    }

    CloseLibrary((struct Library *) IntuitionBase);
 exit2:
    CloseLibrary((struct Library *) DOSBase);
 exit1:
    return rc;
}


static LONG MySystemTags(struct DosLibrary *DOSBase,
                         UBYTE *command, ULONG firsttag, ...)
{
    return SystemTagList(command, (struct TagItem *) &firsttag);
}
