 /*
  * Khoros: $Id: poly_info.c,v 1.2 1991/12/18 09:48:53 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: poly_info.c,v 1.2 1991/12/18 09:48:53 dkhoros Exp $";
#endif

 /*
  * $Log: poly_info.c,v $
 * Revision 1.2  1991/12/18  09:48:53  dkhoros
 * HellPatch3
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.

 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *---------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "vinclude.h"	
#include "vpoly.h"

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: poly_info.c                            <<<<
   >>>>                                                       <<<<
   >>>>   description: contains poly_info()                   <<<<
   >>>>                                                       <<<<
   >>>>      routines: poly_info()			      <<<<
   >>>>                                                       <<<<
   >>>> modifications:					      <<<<
   >>>>                                                       <<<<
   >>>>          NOTE: this routine is not for public use!    <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


/***********************************************************************
*
*  Routine Name: poly_info.c
*
*          Date: Mon Dec 17 15:26:18 MST 1990
*        
*       Purpose: returns useful information to the calling routine  
*		 notes: if you pass in name and indep_var as NULL, then
*		 this routine will malloc them as necessary.  If you pass
*		 them is as something else, it will attempt to realloc them
*		 to meet the necessary requirements.  If the programmer
*		 passes in a garbage value (i.e. declared in calling 
*		 argument, but not allocated or specifically set to NULL,
*		 then this routine may puke.  This probably will not happen
*		 if compiled under ULTRIX because it zeros everything for
*		 security reasons.
*
*         Input: poly      - a polynomial whose information is to
*			     be returned
*
*        Output: ptype     - type of polynomial.  this is an attempt to
*			     characterize the polynomial according to such
*			     things as the independant variable, the nature
*			     of each of the terms, and its structure.  It will
*			     return one of POLY_NORM, indicating a normal 
*			     polynomial, POLY_DIFF, indicating a difference
*			     equation, or POLY_MIXED, indicating a mixture
*			     (usually illegal) of the two.
*
*		 max_exp   - maximum exponent found in the polynomial
*
*		 min_exp   - minimum exponent found in the polynomial
*
*		 name	   - the name of the function.  For example, if
*			     the function looks like "H(z) = ...", then
*			     name would be set to "H".
*
*		 indep_var - the independant variable of the function.
*			     In the above example, this function will return
*		 	     "z" in this variable.
*			     
*    Written By: Jeremy Worley  
*
* Modifications:
*
***********************************************************************/

int poly_info(poly,ptype,max_exp,min_exp,max_delay,min_delay,
    name,indep_var)
    struct poly_struct *poly;
    float  *max_exp,*min_exp;
    int    *max_delay,*min_delay,*ptype;
    char **name,**indep_var;
{
    char *program = "poly_info";
    int i,j,offset=0;

/*
** check to make sure that the programmer knows what he's doing
*/

    if(poly==0){
       fprintf(stderr,
         "%s:  Null polynomial found...you're code is obviously bug-ridden!\n",
         program);
       return(0);
    }

    if(max_exp==NULL || min_exp==NULL || name==NULL || indep_var==NULL){
       fprintf(stderr,"%s:  Null arguments found.  Don't do that!\n",program);
       return(0);
    }

/*
** now that we've got all that crap out of the way, let's extract some 
** information from that convoluted polynomial structure we all know and
** love...
*/

    i=strlen(poly->func_name) + 1;
    if((*name)==NULL){
       if(((*name) = (char *)kmalloc(i*sizeof(char)))==NULL){
          fprintf(stderr,"%s:  Attemped malloc of name argument failed.\n",
                  program);
          return(0);
       }
    }else{
       if(((char *)krealloc((*name),i*sizeof(char)))==NULL){
          fprintf(stderr,"%s:  Attempted realloc of name argument failed.\n",
                  program);
          return(0);
       }
    } /* end allocation of name */ 

    i=strlen(poly->indep_var) + 1;
    if((*indep_var)==NULL){
       if(((*indep_var) = (char *)kmalloc(i*sizeof(char)))==NULL){
          fprintf(stderr,"%s:  Attemped malloc of indep_var failed.\n",
                  program);
          return(0);
       }
    }else{
       if(((char *)krealloc((*indep_var),i*sizeof(char)))==NULL){
          fprintf(stderr,"%s: Attempted realloc of indep_var failed.\n",
                  program);
          return(0);
       }
    } /* end allocation of name */ 

    strcpy((*name),poly->func_name);
    strcpy((*indep_var),poly->indep_var);

/*
** now that the easy junk is out of the way, let's extract some more
** interesting information.
*/

    if(poly->stages==0)poly->stages = 1; /* this is just something that    */
					 /* readpoly() should take care of */

    (*max_exp) = (*min_exp) = poly->terms[0].expon;
    (*max_delay) = (*min_delay) = poly->terms[0].delay;

    (*ptype)   = poly->terms[0].type ? POLY_DIFF : POLY_NORM;

    for(i=0;i<poly->stages;i++){
        for(j=offset;j<offset+poly->nterms[2*i];j++){
            if(poly->terms[j].type==0&&(*ptype)==POLY_DIFF)(*ptype)=POLY_MIXED;
            if(poly->terms[j].type==1&&(*ptype)==POLY_NORM)(*ptype)=POLY_MIXED;

            if((*min_exp)>poly->terms[j].expon)(*min_exp)=poly->terms[j].expon;
            if((*max_exp)<poly->terms[j].expon)(*max_exp)=poly->terms[j].expon;

            if((*min_delay)<poly->terms[j].delay)
                (*min_delay)=poly->terms[j].delay;
            if((*max_delay)<poly->terms[j].delay)
                (*max_delay)=poly->terms[j].delay;
        }             
        offset +=poly->nterms[2*i];

        for(j=offset;j<offset+poly->nterms[2*i+1];j++){
            if(poly->terms[j].type==0&&(*ptype)==POLY_DIFF)(*ptype)=POLY_MIXED;
            if(poly->terms[j].type==1&&(*ptype)==POLY_NORM)(*ptype)=POLY_MIXED;

            if((*min_exp)>poly->terms[j].expon)(*min_exp)=poly->terms[j].expon;
            if((*max_exp)<poly->terms[j].expon)(*max_exp)=poly->terms[j].expon;

            if((*min_delay)<poly->terms[j].delay)
                (*min_delay)=poly->terms[j].delay;
            if((*max_delay)<poly->terms[j].delay)
                (*max_delay)=poly->terms[j].delay;
        }
        offset +=poly->nterms[2*i+1];
    } /* end for i */

/*
** now that were done with all that nonsense, lets get the hell outa here...
*/
 
    return(1);
}  
