/* Agent Tcl
   Bob Gray
   10 January 1996

   tclParse.cc

   This file implements various parsing routines.

   Copyright (c) 1995-1996, Bob Gray, Dartmouth College

   See the file "agent.terms" for information on usage and redistribution
   of this file and for a DISCLAIMER OF ALL WARRANTIES.
*/

#ifndef NO_PRAGMAS
#pragma implementation
#endif

#include "platPorting.h"
#include "genUtility.h"
#include "tcl.h"
#include "tclParse.h"

/* parseShortTimeout

   Purpose: Parse the [-time seconds] portion of a command
*/

int parseShortTimeout (Tcl_Interp *interp, double &seconds, int argc, char **argv, int i)
{
    /* check for the -time option */

  if (strcmp (argv[i], "-time")) {
    Tcl_AppendResult (interp, "unknown option \"", argv[i], "\": should be \"-time\"", (char *) NULL);
    return -1;
  } 

    /* get the number of seconds */

  if (++i == argc) {
    Tcl_AppendResult (interp, "\"-time\" must be followed by number of seconds", (char *) NULL);
    return -1;
  } else if (Tcl_GetDouble (interp, argv[i], &seconds) != TCL_OK) { 
    Tcl_AppendResult (interp, ": seconds must be a real number", (char *) NULL);
    return -1;
  } else if (seconds < 0.0) {
    Tcl_AppendResult (interp, "seconds must be 0 or greater", (char *) NULL);
    return -1;
  }

    /* we got the number of seconds */

  return ++i;
}

#ifdef TCL8

int parseShortTimeoutObj (Tcl_Interp *interp, double &seconds, int objc, Tcl_Obj *const objv[], int i)
{
    char *arg;
    int argLen;

	// make sure that the flag is -time

    arg = Tcl_GetStringFromObj (objv[i], &argLen);

    if (!strcmp (arg, "-time")) {
        Tcl_AppendStringsToObj (Tcl_GetObjResult(interp), 
	    "unknown option \"", arg, "\": should be \"-time\"", (char *) NULL);
	return (-1);
    }

	// get the number of seconds

    char *errorMessage = (char *) NULL;

    if (++i == objc) {
	errorMessage = "\"-time\" must be followed by number of seconds";
    } else if (Tcl_GetDoubleFromObj (interp, objv[i], &seconds) != TCL_OK) {
	errorMessage = ": seconds must be a real number";
    } else if (seconds < 0.0) {
	errorMessage = "seconds must be 0.0 or greater";
    }

    if (errorMessage != (char *) NULL) {
	Tcl_AppendToObj (Tcl_GetObjResult(interp), errorMessage, -1);
	return (-1);
    }	

    return (++i);
}

#endif

/* parseTimeout

   Purpose: Parse the [-blocking | -time seconds | -nonblocking] section of a
	    command
*/

int parseTimeout (Tcl_Interp *interp, double &seconds, int argc, char **argv, int i)
{
   /* check for the -time option */

  if (!strcmp (argv[i], "-blocking")) {
    seconds = INFINITY;
  } else if (!strcmp (argv[i], "-nonblocking")) {
    seconds = 0.0; 
  } else if (!strcmp (argv[i], "-time")) {

      /* get the number of seconds */

    if (++i == argc) {
      Tcl_SetResult (interp, "-time must be followed by the number of seconds", TCL_STATIC);
      return -1;
    } else if (!strcmp(argv[i], "forever")) {
      seconds = INFINITY;
    } else if (Tcl_GetDouble (interp, argv[i], &seconds) != TCL_OK) { 
      Tcl_SetResult (interp, "-time must be followed by the number of seconds", TCL_STATIC);
      return -1;
    }

  } else {
    Tcl_SetResult (interp, "expected -time, -blocking or -nonblocking", TCL_STATIC);
    return -1;
  } 

    /* we got the number of seconds */

  return ++i;
} 

#ifdef TCL8

int parseTimeoutObj (Tcl_Interp *interp, double &seconds, int objc, Tcl_Obj *const objv[], int i)
{
    char *arg;
    int argLen;

	// get the flag

    arg = Tcl_GetStringFromObj (objv[i], &argLen);

	// check the flag and get the number of seconds

    if (!strcmp (arg, "-blocking")) {

	seconds = INFINITY;

    }  else if (!strcmp (arg, "-nonblocking")) {

	seconds = 0.0; 

    } else if (!strcmp (arg, "-time")) {

	if ((++i == objc) || (Tcl_GetDoubleFromObj (interp, objv[i], &seconds) != TCL_OK)) {
	    Tcl_AppendToObj (Tcl_GetObjResult(interp),
		": \"-time\" must be followed by the number of seconds", -1);
	    return (-1);
	}

    } else {

	Tcl_AppendToObj (Tcl_GetObjResult(interp), 
	    "expected -time, -blocking or -nonblocking", -1);
	return (-1);
    }
    
      // move past the timeout part of objv

    return ++i;
}

#endif
