sagb.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.5 */
/* sagb.c 1.5 of 5/13/85 */
#include "saghdr.h"
combine(p, pn)
struct p *p;
int pn;
{
int a, b, c;
int i;
int qi = 0;
float vala, valb;
struct array *ara, *arb, *arc;
struct array *popar();
char *strcpy();
ara = p->c[pn].dptr;
arb = p->c[pn+1].dptr;
arc = popar();
if(DEBUG){fprintf(stderr, "combine p->c[%d].name:%s & p->c[%d].name:%s\n",
pn, p->c[pn].name, pn+1, p->c[pn+1].name);
fprintf(stderr, " alias ara->hname:%s arb->hname:%s\n",
ara->hname, arb->hname);
}
for(a=b=c=0; a<NPTS && b<NPTS && c<NPTS; )
{
if((ara->ent[a].hr == 0) || (arb->ent[b].hr == 0))
{ /* End of file */
arc->ent[c].hr = 0;
break;
}
if((ara->ent[0].hr < 0) || (arb->ent[0].hr < 0))
{ /* One or both is a constant */
if((ara->ent[a].val <= -1000) || (arb->ent[b].val <= -1000))
arc->ent[c].val = -1000;
else
switch (p->c[pn].op)
{
case '+':
arc->ent[c].val = ara->ent[a].val + arb->ent[b].val;
break;
case '-':
arc->ent[c].val = ara->ent[a].val - arb->ent[b].val;
break;
case '*':
arc->ent[c].val = ara->ent[a].val * arb->ent[b].val;
break;
case '/':
if(arb->ent[b].val != 0)
arc->ent[c].val = ara->ent[a].val / arb->ent[b].val;
else
arc->ent[c].val = 0;
break;
default:
break;
}
if(ara->ent[0].hr >= 0)
{ /* a is variable */
strcpy(arc->ent[c].tm, ara->ent[a].tm);
strcpy(arc->ent[c].qfld, ara->ent[a].qfld);
arc->ent[c].hr = ara->ent[a].hr;
a++;
}
else if(arb->ent[0].hr >= 0)
{ /* b is variable */
strcpy(arc->ent[c].tm, arb->ent[b].tm);
strcpy(arc->ent[c].qfld, arb->ent[b].qfld);
arc->ent[c].hr = arb->ent[b].hr;
b++;
}
else
{ /* Both are constant */
strcpy(arc->ent[c].tm, ara->ent[a].tm);
strcpy(arc->ent[c].qfld, ara->ent[a].qfld);
arc->ent[c].hr = ara->ent[a].hr;
a++;
b++;
}
c++;
continue;
}
if(ara->ent[a].hr < arb->ent[b].hr)
{ /* b missing */
arc->ent[c].hr = ara->ent[a].hr;
strcpy(arc->ent[c].tm, ara->ent[a].tm);
strcpy(arc->ent[c].qfld, ara->ent[a].qfld);
vala = ara->ent[a].val;
valb = 0.;
a++;
}
else if(ara->ent[a].hr > arb->ent[b].hr)
{ /* a missing */
arc->ent[c].hr = arb->ent[b].hr;
strcpy(arc->ent[c].tm, arb->ent[b].tm);
strcpy(arc->ent[c].qfld, arb->ent[b].qfld);
valb = arb->ent[b].val;
vala = 0.;
b++;
}
else
{ /* a & b hrs equal */
arc->ent[c].hr = ara->ent[a].hr;
strcpy(arc->ent[c].tm, ara->ent[a].tm);
vala = ara->ent[a].val;
valb = arb->ent[b].val;
/*
** Test which index can be incremented without
** incurring a change in ..hr
*/
if((ara->ent[a+1].hr == ara->ent[a].hr)
&& (arb->ent[b+1].hr != arb->ent[b].hr))
{ /* a free, b constrained */
strcpy(arc->ent[c].qfld, ara->ent[a].qfld);
qi = 0;
a++;
}
else if((ara->ent[a+1].hr != ara->ent[a].hr)
&& (arb->ent[b+1].hr == arb->ent[b].hr))
{ /* a constrained, b free */
strcpy(arc->ent[c].qfld, arb->ent[b].qfld);
qi = 1;
b++;
}
else
{ /* Both free or both constrained */
if(qi == 1)
strcpy(arc->ent[c].qfld, arb->ent[b].qfld);
else
strcpy(arc->ent[c].qfld, ara->ent[a].qfld);
a++;
b++;
}
}
if((vala <= -1000) || (valb <= -1000))
arc->ent[c].val = -1000;
else
switch (p->c[pn].op)
{
case '+':
arc->ent[c].val = vala + valb;
break;
case '-':
arc->ent[c].val = vala - valb;
break;
case '*':
arc->ent[c].val = vala * valb;
break;
case '/':
if(valb != 0)
arc->ent[c].val = vala / valb;
else
arc->ent[c].val = 0;
break;
default:
break;
}
c++;
}
sprintf(arc->hname, "%s %c %s", ara->hname, p->c[pn].op, arb->hname);
if(DEBUG){printar(ara);
printar(arb);
printar(arc);
}
pushar(ara);
pushar(arb);
p->c[pn].op = p->c[pn+1].op;
p->c[pn].dptr = arc;
for(i=pn+1; i<4; i++)
{
strcpy(p->c[i].name, p->c[i+1].name);
p->c[i].op = p->c[i+1].op;
p->c[i].dptr = p->c[i+1].dptr;
}
}
/************************************************/
getdata(name, array)
char *name;
struct array *array;
/*
** Extracts data from sarc[] array and puts into
** array entries. Hunts for name string among column
** headers in sarc, and copies following data items
** from corresponding field up to next "Average" line.
** Special treatment when name string contains an integer
** or "time".
*/
{
extern char fld[NFLD][FLDCH];
extern FILE *sard;
extern long sardoff;
int fnum;
char nm[18], ql[8];
int nparts;
int i, j;
int timeflg;
int hr, min, sec;
int nmloc;
double atof();
float hour;
char *strcpy();
char *strtok();
char *tok;
if(DEBUG) fprintf(stderr, "getdata-> name:%s\n", name);
if(sscanf(name,"%f", &array->ent[0].val) == 1) /* name contains a constant */
{ /* no sar data is required */
strcpy(array->ent[0].tm, "***");
strcpy(array->hname, name);
array->ent[0].hr = -1;
array->ent[0].qfld[0] = '\0';
array->ent[1].hr = 0;
return(0);
}
if(strmatch("time", name) >= 0) /* Pick up time values from */
{ /* 1st sar group - %usr */
if(DEBUG) fprintf(stderr, "name matches time\n");
strcpy(nm, "%usr");
strcpy(ql, "");
nparts = 1;
timeflg = 1;
}
else
{
nparts = 0;
timeflg = 0;
if((tok = strtok(name, "[]")) != NULL)
{
nparts = 1;
strcpy(nm, tok);
}
if((tok = strtok(0, "[]")) != NULL)
{
nparts++;
strcpy(ql, tok);
}
else
strcpy(ql, "");
}
/* fprintf(stderr, "nparts:%d nm:%s ql:%s\n", nparts, nm, ql);
*/
fseek(sard, sardoff, 0); /* seek to line 2 of sard */
while((fnum = getfld()) != EOF)
{
for(i=0; i<fnum; i++)
if(strmatch(nm, fld[i]) >= 0)
{
if(timeflg == 1)
{
nmloc = 0;
strcpy(array->hname, "time");
}
else
{
nmloc = i ;
if(nparts < 2)
strcpy(array->hname, fld[i]);
else
sprintf(array->hname, "%s[%s]",
fld[i], ql);
}
goto readin;
}
}
fprintf(stderr, "\"%s\" data not found\n", nm);
return(-1);
readin:
for(i=0; i<NPTS; )
{
if(((fnum = getfld()) == EOF)
|| (strmatch(":", fld[0]) < 0))
{
array->ent[i].hr = 0;
return(0);
}
if(DEBUG>1) {
for (j=0; j<fnum; j++)
fprintf(stderr, " %s", fld[j]);
fputc('\n', stderr);
}
sscanf(fld[0], "%d:%d:%d", &hr, &min, &sec);
hour = (float)hr + (float)min/60 + (float)sec/3600;
if(timeflg == 1)
{
strcpy(array->ent[i].tm, fld[0]);
array->ent[i].hr = hour;
array->ent[i].val = hour;
strcpy(array->ent[i].qfld, "");
i++;
continue;
}
if(strmatch("unix", fld[1]) >= 0)
{
strcpy(array->ent[i].tm, fld[0]);
array->ent[i].hr = hour;
array->ent[i].val = -1000.;
strcpy(array->ent[i].qfld, "");
i++;
continue;
}
if((nparts > 1) && (strmatch(ql, fld[1]) < 0))
continue;
strcpy(array->ent[i].tm, fld[0]);
array->ent[i].hr = hour;
array->ent[i].val = atof(fld[nmloc]);
strcpy(array->ent[i].qfld, fld[1]);
if(DEBUG>1)
fprintf(stderr, " .val:%.3f\n", array->ent[i].val);
i++;
}
return(0);
}
/************************************************/
getfld()
/*
** Scans characters pointed to by cp;
** puts non-blank strings into fld[NFLD][FLDCH]
** up to first newline or EOF.
** Returns number of fld's filled (or EOF),
** with cp updated to next readable char.
*/
{
extern char fld[NFLD][FLDCH];
extern FILE *sard;
int fnum=0, i=0;
int c;
while((c = getc(sard)) != EOF)
switch((char)c){
case ' ':
fld[fnum][i] = '\0';
i = 0;
if(++fnum >= 9) return(fnum);
break;
case '\n':
fld[fnum][i] = '\0';
return(++fnum);
break;
default:
fld[fnum][i++] = c;
break;
}
fld[fnum][i] = '\0';
if((i == 0) && (fnum == 0)) return(EOF);
else return(++fnum);
}
/************************************************/
static struct array stack[10];
static struct array *sp[] = {
&stack[0],
&stack[1],
&stack[2],
&stack[3],
&stack[4],
&stack[5],
&stack[6],
&stack[7],
&stack[8],
&stack[9]};
static int spn = 10;
struct array *popar()
{
if(spn > 0)
return(sp[--spn]);
else
{
fprintf(stderr, "Stack empty\n");
exit();
}
}
pushar(par)
struct array *par;
{
if(spn < 10)
{
sp[spn++] = par;
return(1);
}
else
{
fprintf(stderr, "Stack full\n");
return(0);
}
}
/************************************************/
stribl(s)
char *s;
/*
** Strips leading and trailing blanks from string
** by moving string pointer to first non-blank character,
** and replacing trailing blanks with '\0'.
** Returns number of remaining characters.
*/
{
char *a, *b;
a = b = s;
while (*b == ' ') b++;
while ((*a++ = *b++) != '\0');
a--;
while (a-- > s)
if (*a != ' ') break;
else *a = '\0';
return (int)(a-s+1);
}
/************************************************/
int strmatch (pat, targ)
char *pat, *targ;
/*
** strmatch looks for an occurrence of string pat
** inside string targ. It returns the number of
** the first starting character position (zero is valid),
** or -1 for no match.
*/
{
int i, c, ifirst;
for (ifirst=0; ; ifirst++)
{
i=0;
do
{
if(pat[i] == '\0')
return(ifirst);
if (targ[ifirst + i] == '\0')
return(-1);
c=i++;
}
while (pat[c] == targ[ifirst + c]);
}
}
/************************************************/
float yrange(ff)
float ff;
{
static float ylimit[] = {1.0, 1.5, 2.5, 5.0, 10.0};
float div = 1;
int i = 0;
if (ff <= 0.) return(0);
while (ff/div > 10.) div *= 10.;
while (ff/div < 1.) div /= 10.;
while ((ff/div) > ylimit[i]) i++;
return (ylimit[i] * div);
}