
/* "VIEW", a data viewing program,
   Copyright (C) 1987, 1990 California Institute of Technology.
   Original authors: Dave Gillespie, port by Rick Koshi
   Unix Port Maintainer: John Lazzaro
   Maintainers's address: lazzaro@hobiecat.cs.caltech.edu;
                          CB 425/ CU Boulder/Boulder CO 91125. 


This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (Version 1, Feb 1989).

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.  If not, write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

/* Output from p2c, the Pascal-to-C translator */
/* From input file "viewcmds.text" */


/* The View program
   by Dave Gillespie
 */



/*caged_date='I{ Last edit by $U on $X $]'*/
/* Last edit by dave on Mar 3, 1988 6:29 pm */
/* Last edit by dave on Mar 3, 1988 5:46 pm */
/* Last edit by dave on Mar 3, 1988 5:33 pm */
/* Last edit by dave on Mar 3, 1988 5:27 pm */
/* Last edit by dave on Mar 2, 1988 4:46 pm */
/* Last edit by dave on Feb 15, 1988 3:08 pm */
/* Last edit by dave on Jan 20, 1988 11:20 pm */
/* Last edit by dave on Jan 14, 1988 5:26 pm */
/* Last edit by dave on Nov 27, 1987 6:15 pm */
/* Last edit by dave on Oct 20, 1987 10:59 pm */









#include "global.h"


#define VIEWCMDS_G
#include "viewcmds.h"




#ifndef NUMEX_H
#include <p2c/numex.h>
#endif

#ifndef REGEX_H
#include <p2c/regex.h>
#endif

#ifndef NEWASM_H
#include <p2c/newasm.h>
#endif

#ifndef SYSGLOBALS_H
#include <p2c/sysglobals.h>
#endif

/*homeless orphans*/

#ifndef MISC_H
#include <p2c/misc.h>
#endif

#ifndef SYSDEVS_H
#include <p2c/sysdevs.h>
#endif

#ifndef FILEPACK_H
#include <p2c/filepack.h>
#endif

#ifndef MATH_H
#include <p2c/math.h>
#endif

#ifndef MYLIB_H
#include <p2c/mylib.h>
#endif

#ifndef NEWCRT_H
#include <p2c/newcrt.h>
#endif

#ifndef NEWCI_H
#include <p2c/newci.h>
#endif

#ifndef VIEWMOD_H
#include "viewmod.h"
#endif

#ifndef VIEWCONF_H
#include "viewconf.h"
#endif


/*$if v_hasdebug$
   $debug$
$end$*/




Static Void dolet(buf_)
Char *buf_;
{
  Char buf[256], wrd[256];

  strcpy(buf, buf_);
  v_strword(buf, wrd);
  v_assignment(wrd, buf);
}


Local Void listbase(bp)
v_baserec *bp;
{
  v_curverec *cp;
  boolean first;

  first = true;
  cp = v_curvebase;
  while (cp != NULL) {
    if (cp->base == bp) {
      if (!first)
	printf(", ");
      fputs(cp->name, stdout);
      first = false;
    }
    cp = cp->next;
  }
  if (!first)
    putchar('\n');
}



Static Void dolist(buf_)
Char *buf_;
{
  Char buf[256];
  v_baserec *bp;
  v_curverec *cp;

  strcpy(buf, buf_);
  if (*buf == '\0') {
    bp = v_basebase;
    while (bp != NULL) {
      listbase(bp);
      bp = bp->next;
    }
    listbase(NULL);
    return;
  }
  v_ncurvelist(buf, &cp, v_clopt);
  v_checktoomany(buf);
  if (cp == NULL)
    v_logwriteln("[No matching names]");
  while (cp != NULL) {
    printf("%s (", cp->name);
    if (cp->expr != NULL)
      printf("== %s, ", cp->expr);
    bp = cp->base;
    if (bp == NULL && cp->sval != NULL)
      printf("string) = \"%s\"", cp->sval);
    else {
      if (*cp->units != '\0')
	printf("'%s'", cp->units);
      else
	printf("unitless");
      if (bp != NULL) {
	printf(" vs ");
	if (*bp->units != '\0')
	  printf("'%s'", bp->units);
	else
	  printf("unitless");
      }
      putchar(')');
      if (bp == NULL)
	printf(" = %g", cp->yval);
      else {
	printf("  %ld", bp->len);
	if (bp->sorted)
	  printf(" sorted");
	printf(" data points");
      }
    }
    putchar('\n');
    cp = cp->next2;
  }
}  /*dolist*/


Static Void dodump(buf_)
Char *buf_;
{
  Char buf[256], wrd[256];
  v_curverec *cp;
  v_baserec *bp;
  long i, FORLIM;

  strcpy(buf, buf_);
  v_ncurvelist(buf, &cp, v_clopt);
  v_checktoomany(buf);
  if (cp == NULL)
    v_logwriteln("[No matching names]");
  while (cp != NULL) {
    putchar('\n');
    bp = cp->base;
    if (bp == NULL)
      strcpy(wrd, "constant");
    else if (*bp->units != '\0')
      sprintf(wrd, "(%s)", bp->units);
    else
      strcpy(wrd, "base");
    fputs(wrd, stdout);
    for (i = strlen(wrd); i <= 12; i++)
      putchar(' ');
    printf("  ");
    if (*cp->units != '\0')
      sprintf(wrd, "(%s)", cp->units);
    else if (bp == NULL)
      strcpy(wrd, "(unitless)");
    else
      strcpy(wrd, "value");
    fputs(wrd, stdout);
    for (i = strlen(wrd); i <= 12; i++)
      putchar(' ');
    printf("      %s", cp->name);
    if (cp->expr != NULL)
      printf(" == %s", cp->expr);
    putchar('\n');
    if (bp == NULL) {
      if (cp->sval != NULL)
	printf("\"%s\"\n", cp->sval);
      else
	printf("% .5E\n", cp->yval);
    } else {
      FORLIM = bp->len;
      for (i = 0; i < FORLIM; i++) {
	if (bp->vec[i] == v_badvalue)
	  printf("(none)      ");
	else
	  printf("% .5E", bp->vec[i]);
	printf("   ");
	if (cp->vec[i] == v_badvalue)
	  printf("(none)");
	else
	  printf("% .5E", cp->vec[i]);
	putchar('\n');
      }
    }
    cp = cp->next2;
  }
}  /*dodump*/



Static Void dotable(buf_)
Char *buf_;
{
  Char buf[256];
  FILE *f, **fp;
  Char fn[256];
  v_curverec *cbase, *cp, *cp2;
  v_baserec *bp;
  long i, j, k, spc, curwidth, ncurves;
  boolean flag;
  na_long *wid, *prec;
  long bwid, bprec;
  Char STR2[256], STR3[256];
  FILE *TEMP;
  long FORLIM;

  strcpy(buf, buf_);
  f = NULL;
  i = strposc(buf, '>', 1L);
  if (i > 0) {
    strcpy(fn, strltrim(strcpy(STR2, buf + i)));
    newci_fixfname(fn, "text", "");
    printf("Writing to %s\n", fn);
    if (f != NULL)
      f = freopen(fn, "w", f);
    else
      f = fopen(fn, "w");
    if (f == NULL)
      _EscIO(FileNotFound);
    fp = &f;
    fprintf(*fp, "Table written by VIEW on %s\n\n", strdate(STR3, ""));
    sprintf(STR2, "%.*s", (int)(i - 1), buf);
    strcpy(buf, strrtrim(STR2));
    curwidth = 195;   /*caged line-length limit*/
  } else {
    *fn = '\0';
    TEMP = stdout;
    fp = &TEMP;
/* p2c: viewcmds.text, line 239:
 * Note: Taking address of stdout; consider setting VarFiles = 0 [144] */
    curwidth = nc_curWindow->width - 2;
  }
  if (*buf == '\0')
    strcpy(buf, "*");
  v_ncurvelist(buf, &cbase, v_clopt);
  v_checktoomany(buf);
  if (cbase == NULL)
    v_logwriteln("[No matching names]");
  ncurves = 0;
  cp = cbase;
  while (cp != NULL) {
    cp->flag2 = (cp->kind == v_ck_curve);
    cp = cp->next2;
    ncurves++;
  }
  na_alloc((Anyptr)&wid, ncurves * sizeof(na_long));
  na_alloc((Anyptr)&prec, ncurves * sizeof(na_long));
  cp = cbase;
  for (i = 0; i < ncurves; i++) {
    if (cp->flag2)
      v_measurevec(cp->vec, cp->base->len, (long)strlen(cp->name),
		   (long*)(&wid[i]), (long*)(&prec[i]));
    cp = cp->next2;
  }
  flag = false;
  i = 0;
  cp2 = cbase;
  while (cp2 != NULL) {
    if (cp2->flag2) {
      flag = true;
      bp = cp2->base;
      v_measurevec(bp->vec, bp->len, 4L, &bwid, &bprec);
      fprintf(*fp, "%*s", (int)bwid, "base");
      spc = 4;
      k = 0;
      cp = cp2;
      j = i;
      while (cp != NULL) {
	cp->flag2 = false;
	spc += (long)wid[j] + 1;
	k++;
	do {
	  cp = cp->next2;
	  j++;
	} while (cp != NULL && (cp->kind != v_ck_curve || cp->base != bp));
      }
      if (spc < curwidth - k * 2)
	spc = 3;
      else if (spc < curwidth - k)
	spc = 2;
      else
	spc = 1;
      cp = cp2;
      j = i;
      while (cp != NULL) {
	fprintf(*fp, "%*s", (int)((long)wid[j] + spc), cp->name);
	do {
	  cp = cp->next2;
	  j++;
	} while (cp != NULL && (cp->kind != v_ck_curve || cp->base != bp));
      }
      putc('\n', *fp);
      FORLIM = bp->len;
      for (k = 0; k < FORLIM; k++) {
	fputs(v_fmtreal(STR3, bp->vec[k], bwid, bprec), *fp);
	j = i;
	cp = cp2;
	while (cp != NULL) {
	  if (cp->kind == v_ck_curve && cp->base == bp)
	    fprintf(*fp, "%*s%s",
		    (int)spc, "",
		    v_fmtreal(STR2, cp->vec[k], (long)wid[j], (long)prec[j]));
	  j++;
	  cp = cp->next2;
	}
	putc('\n', *fp);
      }
      putc('\n', *fp);
    }
    i++;
    cp2 = cp2->next2;
  }
  cp2 = cbase;
  while (cp2 != NULL) {
    if (cp2->kind != v_ck_curve) {
      if (flag)
	putc('\n', *fp);
      flag = false;
      fprintf(*fp, "%-30s", cp2->name);
      if (cp2->kind == v_ck_string)
	fprintf(*fp, "\"%s\"\n", cp2->sval);
      else
	fprintf(*fp, "%g\n", cp2->yval);
    }
    cp2 = cp2->next2;
  }
  if (*fn != '\0') {
    if (f != NULL)
      fclose(f);
    f = NULL;
  }
  if (f != NULL)
    fclose(f);
  na_free((Anyptr)&wid);
  na_free((Anyptr)&prec);
}



Static Void dosetunits(buf_)
Char *buf_;
{
  Char buf[256], wrd[256];
  v_curverec *cp;

  strcpy(buf, buf_);
  v_exstrword(buf, wrd);
  v_curvelist(wrd, &cp, v_clopt);
  while (cp != NULL) {
    strchange(&cp->units, buf);
    v_change(cp);
    cp = cp->next2;
  }
}  /*dosetunits*/



Static Void doload(buf_)
Char *buf_;
{
  Char buf[256], fn[256];
  Char STR1[256];

  strcpy(buf, buf_);
  do {
    v_strword(buf, fn);
    if (*fn == '\0') {
      v_checktoomany(buf);
      v_halt();
    }
    switch (v_loadfile(fn)) {

    case 0:
      /* blank case */
      break;

    case 1:
      sprintf(STR1, "%s not found", fn);
      v_failmsg(STR1);
      break;

    case 2:
      sprintf(STR1, "Can't understand format of file %s", fn);
      v_failmsg(STR1);
      break;
    }
  } while (true);
}



Static Void doaload(buf)
Char *buf;
{
  doload(buf);   /*for compatibility*/
}



Static Void dosave(buf_)
Char *buf_;
{
  Char buf[256], fn[256];

  strcpy(buf, buf_);
  v_strword(buf, fn);
  v_savecurves(fn, buf);
}


Static Void doappend(buf_)
Char *buf_;
{
  Char buf[256], fn[256];

  strcpy(buf, buf_);
  v_strword(buf, fn);
  v_appendcurves(fn, buf);
}



Static Void dodelete(buf_)
Char *buf_;
{
  Char buf[256];
  v_curverec *cp, *cp2;

  strcpy(buf, buf_);
  v_curvelist(buf, &cp, v_clopt);
  v_checktoomany(buf);
  while (cp != NULL) {
    cp2 = cp->next2;
    v_deletecurve(&cp);
    cp = cp2;
  }
}


Static Void docopy(buf_)
Char *buf_;
{
  Char buf[256];
  v_curverec *cp;
  v_baserec *bp;

  strcpy(buf, buf_);
  v_desteqsrc(buf, &cp, v_clsome);
  v_checktoomany(buf);
  while (cp != NULL) {
    if (cp->dest != NULL) {   /*in case of overlap*/
      if (cp->expr != NULL)
	v_addcurveexpr(cp->expr, cp->dest);
      else {
	bp = cp->base;
	if (bp != NULL)
	  v_addcurve(bp->len, bp->vec, cp->vec, bp->units, cp->units,
		     cp->dest);
	else if (cp->sval != NULL)
	  v_addcurvestr(cp->sval, cp->dest);
	else
	  v_addcurveconst(cp->yval, cp->units, cp->dest);
      }
    }
    cp = cp->next2;
  }
}


Static Void dorename(buf_)
Char *buf_;
{
  Char buf[256];
  v_curverec *cbase, *cp, *cp2;
  v_baserec *bp;
  Char STR2[256];

  strcpy(buf, buf_);
  v_desteqsrc(buf, &cbase, v_clsome);
  v_checktoomany(buf);
  cp = cbase;
  while (cp != NULL) {
    cp2 = v_findcurve(cp->dest);
    if (cp2 != NULL && cp2 != cp) {
      sprintf(STR2, "Curve name %s already exists", cp->dest);
      v_failmsg(STR2);
    }
    cp = cp->next2;
  }
  cp = cbase;
  while (cp != NULL)
  {  /*note: can't just change name^, that would mess up the tree*/
    if (cp->expr != NULL)
      v_addcurveexpr(cp->expr, cp->dest);
    else {
      bp = cp->base;
      if (bp != NULL)
	v_addcurve(bp->len, bp->vec, cp->vec, bp->units, cp->units, cp->dest);
      else if (cp->sval != NULL)
	v_addcurvestr(cp->sval, cp->dest);
      else
	v_addcurveconst(cp->yval, cp->units, cp->dest);
    }
    v_deletecurve(&cp);
    cp = cp->next2;
  }
}



Static Void dointerp(buf)
Char *buf;
{
  v_listinterps();
}





Static Void linearinterp(cp, x, user, val)
v_curverec *cp;
double x;
na_long user;
double *val;
{
  v_baserec *bp;
  double *vec, *bvec;
  double diff;
  long i, len;

  bp = cp->base;
  if (!bp->sorted)
    v_checksorted(bp);
  bvec = bp->vec;
  len = bp->len;
  i = 1;
  while (i <= len && bvec[i - 1] <= x)   /*this should be a binary search*/
    i++;
  vec = cp->vec;
  if (i == 1) {
    *val = v_badvalue;
    return;
  }
  diff = x - bvec[i - 2];
  if (diff == 0) {
    *val = vec[i - 2];
    return;
  }
  if (i > len)
    *val = v_badvalue;
  else
    *val = vec[i - 2] +
	   diff * (vec[i - 1] - vec[i - 2]) / (bvec[i - 1] - bvec[i - 2]);
}






Void viewcmds_viewbuiltin()
{
  _PROCEDURE TEMP;

  v_addhelpline("<var> = <expression>", "Compute a new var or curve");
  v_addhelpline("<var> == <expression>", "Create a computed variable");
  TEMP.proc = (Anyptr)dolet;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("let", TEMP, "", "");
  v_addhelp("let <var> = <expr>");
  v_addhelp("<var> = <expr>");
  v_addhelp("let <var> == <expr>");
  v_addhelp("<var> == <expr>");
  v_addhelp("  Compute a new variable as a function of other variables.");
  v_addhelp("  If <expr> contains curves, <var> will be a curve whose");
  v_addhelp("  y-values are computed pointwise from the others' y-values.");
  v_addhelp("  Expression may include:");
  v_addhelp("      + -  * /  ^  ()");
  v_addhelp("      log ln exp abs sqr sqrt pi");
  v_addhelp("      sin cos tan arcsin arccos arctan arctan2(y,x)");
  v_addhelp("      sinh cosh tanh arcsinh arccosh arctanh");
  v_addhelp("      min max rand rand2(a,b)");
  v_addhelp("      if(c,then(a,b))  then(a,b)  param(\"x\")");
  v_addhelp("      <curve>  <curve>_x  <curve>_y  base");
  v_addhelp("  The == format creates a computed variable.  If any vars");
  v_addhelp("  in <expr> change, <var> is recomputed automatically.");
  TEMP.proc = (Anyptr)doload;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("load", TEMP, "load <file>", "Load curves from a file");
  v_addhelp("load <file> <file> <file>");
  v_addhelp("  Load curves from file(s).");
  TEMP.proc = (Anyptr)doaload;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("aload", TEMP, "", "");
  v_addhelp("aload <file> <file> <file>");
  v_addhelp("  Obsolete -- use LOAD.");
  TEMP.proc = (Anyptr)dosave;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("save", TEMP, "save <file> <curves>", "Save curves to a file");
  v_addhelp("save <file>");
  v_addhelp("save <file> <var> <var> <var>");
  v_addhelp("  Save one or several variables or curves in a file.");
  v_addhelp("  If no <var>s, saves all variables in memory.");
  TEMP.proc = (Anyptr)doappend;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("append", TEMP, "*", "");
  v_addhelp("append <file>");
  v_addhelp("append <file> <var> <var> <var>");
  v_addhelp("  Save one or several variables or curves in a file.");
  v_addhelp("  Same as the \"save\" command, except value are appended");
  v_addhelp("  to the file.");
  TEMP.proc = (Anyptr)dolist;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("list", TEMP, "list", "List all vars in memory");
  v_addhelp("list");
  v_addhelp("list <var> <var> <var>");
  v_addhelp("  List information about variables or curves, or give");
  v_addhelp("  a list of all variables and curves in memory.");
  v_addhelp("  Curves with compatible bases are listed together.");
  v_addalias("ls", "list");
  v_addhelpline("list <curve>", "Describe a curve");
  TEMP.proc = (Anyptr)dosetunits;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("setunits", TEMP, "*", "");
  v_addhelp("setunits <curves> <units>");
  v_addhelp("  Set the units on the Y axis of a curve or curves.");
  v_addhelp("  If <units> is omitted, sets curves to be unitless.");
  v_addhelp("  <curves> must be only one word, but it may contain wildcards.");
  v_addalias("su", "setunits");
  TEMP.proc = (Anyptr)dodelete;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("delete", TEMP, "delete <var>", "Delete vars from memory");
  v_addhelp("delete <var> <var> <var>");
  v_addhelp("  Delete variable(s) and curve(s) from memory.");
  v_addalias("rm", "delete");
  TEMP.proc = (Anyptr)docopy;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("copy", TEMP, "*", "");
  v_addhelp("copy <new> = <var>");
  v_addhelp("  Make a copy of a variable or curve.");
  v_addalias("cp", "copy");
  TEMP.proc = (Anyptr)dorename;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("rename", TEMP, "*", "");
  v_addhelp("rename <new> = <var>");
  v_addhelp("  Change the name of a variable or curve.");
  v_addalias("mv", "rename");
  TEMP.proc = (Anyptr)dodump;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("dump", TEMP, "dump <curve>", "Display curve values");
  v_addhelp("dump <curve> <curve> <curve>");
  v_addhelp("  Dump values for one or more curves.");
  v_addalias("cat", "dump");
  TEMP.proc = (Anyptr)dotable;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("table", TEMP, "*", "");
  v_addhelp("table <var> <var> ...");
  v_addhelp("table <var> <var> ... >outfile");
  v_addhelp("  Write variable and curve values in tabular form,");
  v_addhelp("  to screen or to a file.");
  TEMP.proc = (Anyptr)dointerp;
  TEMP.link = (Anyptr)NULL;
  v_addcmd("interp", TEMP, "", "");
  v_addhelp("interp");
  v_addhelp("  Print a list of all interpolators.  (See the \"map\" command.)");

  TEMP.proc = (Anyptr)linearinterp;
  TEMP.link = (Anyptr)NULL;
  v_addinterp("linear", TEMP, "linear interpolation");
}








/*viewcmds*/





/* End. */
