home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / misc / b186_1 / Source / c / variable < prev    next >
Text File  |  1990-04-14  |  12KB  |  475 lines

  1. /*
  2.  
  3.        This file is part of the PDP software package.
  4.          
  5.        Copyright 1987 by James L. McClelland and David E. Rumelhart.
  6.        
  7.        Please refer to licensing information in the file license.txt,
  8.        which is in the same directory with this source file and is
  9.        included here by reference.
  10. */
  11.  
  12.  
  13. /* variable.c
  14.  
  15.     This module implements a way to keep track of global variables
  16.     in a C program and to access them interactively from their names.
  17.    
  18.     Note: this is essentialy just a symbol table.
  19.    
  20.     First version implemented by Elliot Jaffe.
  21.     
  22.     Date of last revision:  8-12-87/JLM.
  23. */
  24.  
  25. /*LINTLIBRARY*/
  26.  
  27. #include "general.h"
  28. #include "variable.h"
  29. #include "command.h"
  30. #include "patterns.h"
  31. #include "weights.h"
  32.  
  33. char **uname = NULL;
  34. int  nunames;
  35.  
  36. int    *first_weight_to;  /* these guys are used for variables to type PVweight */
  37. int    *num_weights_to;   /* they are generally installed in weights.c; 
  38.                  arrays of type PVweight use them, but in aa,
  39.                  weights are declared as PVfloat, so do not
  40.                  use these */
  41.  
  42. static struct Variable *varlist = 0;/* variable table: linked list */
  43.  
  44. struct Variable *lookup_var (s)    /* find s in the variable list */
  45. char   *s;
  46. {
  47.     struct Variable *sp;
  48.  
  49.     for (sp = varlist; sp != (struct Variable  *) NULL; sp = sp->next) {
  50.     if (strcmp(sp->name, s) == 0)
  51.         return sp;
  52.     }
  53.     return NULL;        /* 0 ==> not found */
  54. }
  55. /* we replace this:
  56. struct Variable *
  57.    with void to avoid the hassle of casting to void on each call 
  58.    abh - 2/15/88
  59. */
  60. void install_var (s, t, varptr, max_x, max_y, menutype)
  61. char   *s;
  62. int     t;
  63. int    *varptr;
  64. int     max_x,
  65.         max_y;  /* This represents the second dimension in matrices and */
  66.         /* the offset of the unit name in vectors  */
  67. int     menutype;
  68. {
  69.     struct Variable *sp;
  70.     char   *emalloc (), *strcpy ();
  71.     int     change_variable ();
  72.  
  73.     sp = (struct Variable  *) emalloc (sizeof (struct Variable));
  74.     sp->name = emalloc((unsigned)(strlen(s) + 1));
  75.  /* +1 for trailing NULL */
  76.     (void) strcpy(sp->name, s);
  77.     sp->type = t;
  78.     sp->max_x = max_x;
  79.     sp->max_y = max_y;
  80.     sp->varptr = varptr;
  81.     sp->next = varlist;
  82.  
  83.     if (menutype != NOMENU) {
  84.     (void) install_command(sp->name,change_variable,menutype,(int *)sp);
  85.     }
  86.  
  87.     varlist = sp;
  88. /*
  89.     return sp;
  90. */
  91. }
  92.  
  93.  
  94. /* this function changes the max_x and max_y parameters of an 
  95.    installed variable.  It returns TRUE if it succeeded, and
  96.    FALSE otherwise.
  97. */
  98.  
  99. change_variable_length(str,x,y)
  100. char *str;
  101. int x,y;
  102. {
  103.     struct Variable *vp;
  104.     
  105.     vp = lookup_var(str);
  106.     if(vp == NULL) return(FALSE);
  107.     vp->max_x = x;
  108.     vp->max_y = y;
  109.     return(TRUE);
  110. }    
  111.  
  112. /* this section of code changes all types of variables */
  113. # define WEIGHTS 1
  114. /* ARGSUSED */
  115. change_variable(str, var)
  116. char   *str;
  117. int    *var;
  118. {
  119.     struct Variable *vp;
  120.  
  121.     vp = (struct Variable  *) var;
  122.  
  123.     switch (vp->type) {
  124.     case Int: 
  125.         return(change_int_var(vp));
  126.     case Float: 
  127.         return(change_float_var(vp));
  128.     case String: 
  129.         return(change_string_var(vp));
  130.     case Vint: 
  131.         return(change_ivector_var(vp));
  132.     case Vfloat: 
  133.         return(change_fvector_var(vp));
  134.     case Vstring: 
  135.         return(change_svector_var(vp));
  136.     case PVfloat:
  137.         return(change_pfvector_var(vp,!WEIGHTS));
  138.     case PVweight:
  139.         return(change_pfvector_var(vp,WEIGHTS));
  140.     default: 
  141.         sprintf(err_string,"I don't know how to change %s", vp->name);
  142.         return(put_error(err_string));
  143.     }
  144. }
  145.  
  146.  
  147. change_int_var(vp)
  148. struct Variable *vp;
  149. {
  150.     char    string[40];
  151.     char   *str;
  152.  
  153.     (void) sprintf(string, "%s = %d, new value: ", vp->name, *vp->varptr);
  154.  
  155.     str = get_command(string);
  156.     if (str != NULL) {
  157.     if (!sscanf(str,"%d",vp->varptr)) {
  158.         return(var_error(vp->name,-1,-1));
  159.     }
  160.     }
  161.     return(CONTINUE);
  162. }
  163.  
  164.  
  165. change_float_var(vp)
  166. struct Variable *vp;
  167. {
  168.     char    string[40];
  169.     char   *str;
  170.     float  *fp;
  171.  
  172.     fp = (float *) vp->varptr;
  173.     (void) sprintf(string, "%s = %f, new value: ", vp->name, *fp);
  174.  
  175.     str = get_command(string);
  176.     if (str != NULL) {
  177.     if (!sscanf(str,"%f",fp)) {
  178.         return(var_error(vp->name,-1,-1));
  179.     }
  180.     }
  181.     return(CONTINUE);
  182. }
  183.  
  184. change_string_var(vp)
  185. struct Variable *vp;
  186. {
  187.     char    string[40];
  188.     char   *str;
  189.  
  190.     str = (char *) vp->varptr;
  191.     (void) sprintf(string, "%s = %s, new value: ", vp->name, str);
  192.  
  193.     str = get_command(string);
  194.     if (str != NULL) {
  195.     (void) strcpy((char *) vp->varptr, str);
  196.     }
  197.     return(CONTINUE);
  198. }
  199.  
  200.  
  201. change_ivector_var(vp)
  202. struct Variable *vp;
  203. {
  204.     char    string[BUFSIZ];
  205.     char    tempstring[BUFSIZ];
  206.     int    *iptr;
  207.     int     index,i;
  208.     char   *str;
  209.  
  210.     iptr = (int *) vp->varptr;
  211.     (void) sprintf(string, "%s[0..%d] index:(name or number) ", 
  212.                             vp->name, vp->max_x - 1);
  213.  
  214.     while ((str = get_command(string)) != NULL) {
  215.     if (sscanf(str,"%d",&index) == 0) {
  216.       for (index = vp->max_x,i = vp->max_y; i < nunames; i++) {
  217.         if (startsame(str, uname[i])) {
  218.              index = i - vp->max_y;
  219.              break;
  220.         }
  221.        }
  222.     }
  223.     if (index >= vp->max_x) {
  224.         if((index = get_pattern_number(str)) < 0) {
  225.                 if (ind_error(vp->name) == BREAK) return(BREAK);
  226.             goto again;
  227.         }
  228.     }
  229.     (void) sprintf(tempstring, "%s[%d] = %d, new value: ", 
  230.                     vp->name, index, *(iptr + index));
  231.     if ((str = get_command(tempstring)) != NULL) {
  232.         if (!sscanf(str,"%d",(iptr + index))) {
  233.             return(var_error(vp->name,index,-1));
  234.         }
  235.     }
  236.     return(CONTINUE);
  237. again:
  238.     (void) sprintf(string, "%s[0..%d] index:(name or number) ", 
  239.                     vp->name, vp->max_x - 1);
  240.     }
  241. }
  242.  
  243. change_fvector_var(vp)
  244. struct Variable *vp;
  245. {
  246.     char    string[BUFSIZ];
  247.     char    tempstring[BUFSIZ];
  248.     float  *fptr;
  249.     int     index,i;
  250.     char   *str;
  251.  
  252.     fptr = (float *) vp->varptr;
  253.     (void) sprintf(string, "%s[0..%d] index:(name or number) ", 
  254.                             vp->name, vp->max_x - 1);
  255.  
  256.     while ((str = get_command(string)) != NULL) {
  257.     if (sscanf(str,"%d",&index) == 0) {
  258.       for (index = vp->max_x,i = vp->max_y; i < nunames; i++) {
  259.         if (startsame(str, uname[i])) {
  260.              index = i - vp->max_y;
  261.              break;
  262.         }
  263.        }
  264.     }
  265.     if (index >= vp->max_x) {
  266.         if((index = get_pattern_number(str)) < 0) {
  267.                 if (ind_error(vp->name) == BREAK) return(BREAK);
  268.             goto again;
  269.         }
  270.     }
  271.     (void) sprintf(tempstring, "%s[%d] = %.3f, new value: ", 
  272.                     vp->name, index, *(fptr + index));
  273.     if ((str = get_command(tempstring)) != NULL) {
  274.         if (!sscanf(str,"%f",(fptr + index))) {
  275.             return(var_error(vp->name,index,-1));
  276.         }
  277.     }
  278.     return(CONTINUE);
  279. again:
  280.     (void) sprintf(string, "%s[0..%d] index:(name or number) ", 
  281.                         vp->name, vp->max_x - 1);
  282.     }
  283. }
  284.  
  285. change_svector_var(vp)
  286. struct Variable *vp;
  287. {
  288.     char    string[BUFSIZ];
  289.     int     index,i;
  290.     char   *str;
  291.     char  **sptr;
  292.     char   *emalloc ();
  293.  
  294.     sptr = (char **) vp->varptr;
  295.     (void) sprintf(string, "%s[0..%d] index:(name or number) ", 
  296.                         vp->name, vp->max_x - 1);
  297.  
  298.     while ((str = get_command(string)) != NULL) {
  299.      if (sscanf(str,"%d",&index) == 0) {
  300.        if((index = get_pattern_number(str)) < 0) {
  301.           for (index = vp->max_x,i = vp->max_y; i < nunames; i++) {
  302.             if (startsame(str, uname[i])) {
  303.                  index = i - vp->max_y;
  304.                  break;
  305.             }
  306.            }
  307.           if (index >= vp->max_x) {
  308.                   if (ind_error(vp->name) == BREAK) return(BREAK);
  309.             goto again;
  310.           }
  311.        }
  312.     }
  313.     if (sptr[index] != NULL) {
  314.         (void) sprintf(string, "%s[%d] = %s, new value: ", 
  315.                         vp->name, index, sptr[index]);
  316.     }
  317.     else {
  318.         (void) sprintf(string, "%s[%d] = empty, new value: ", 
  319.                                 vp->name, index);
  320.     }
  321.     if ((str = get_command(string)) != NULL) {
  322.         if (sptr[index] != NULL) free(sptr[index]);
  323.         sptr[index] = 
  324.           (char *) emalloc((unsigned)(sizeof(char) * (strlen(str) + 1)));
  325.         (void) strcpy(sptr[index], str);
  326.     }
  327.         return(CONTINUE);
  328. again:
  329.     (void) sprintf(string, "%s[0..%d] index:(name or number) ", 
  330.                         vp->name, vp->max_x - 1);
  331.     }
  332. }
  333.  
  334. change_pfvector_var(vp,iswv)
  335. struct Variable *vp;
  336. int iswv;  /* is it a weight vector */
  337. {
  338.     char    string[BUFSIZ];
  339.     float  **pfptr;
  340.     int     i,index1,index2,cmin,cmax,tindex2;
  341.     char   *str;
  342.     char    *name;
  343.  
  344.     pfptr = (float **) vp->varptr;
  345.     name = (char *) vp->name;
  346.  
  347.     (void) sprintf(string, "%s[0..%d][0..%d] row index:(name or number)  ",
  348.         vp->name, vp->max_x - 1, vp->max_y - 1);
  349.  
  350.     while ((str = get_command(string)) != NULL) {
  351.     if (sscanf(str,"%d",&index1) == 0) {
  352.       for (index1 = vp->max_x,i = 0; i < nunames; i++) {
  353.         if (startsame(str, uname[i])) {
  354.              index1 = i;
  355.              break;
  356.         }
  357.        }
  358.       if (index1 >= vp->max_x) {
  359.        for (index1 = vp->max_x,i = 0; i < npatterns; i++) {
  360.         if (startsame(str, pname[i])) {
  361.              index1 = i;
  362.              break;
  363.         }
  364.         }
  365.       }
  366.     }
  367.     if (index1 >= vp->max_x) {
  368.         if (ind_error(vp->name) == BREAK) return(BREAK);
  369.         goto again;
  370.     }
  371.     if (iswv) {
  372.         cmin = first_weight_to[index1];
  373.         cmax = cmin + num_weights_to[index1] -1;
  374.     }
  375.     else {
  376.         cmin = 0;
  377.         cmax = vp->max_y - 1;
  378.     }
  379.     (void) sprintf(string, "%s[%d][%d..%d] column index:(name or number)  ", 
  380.                vp->name, index1, cmin,cmax);
  381.     while ((str = get_command(string)) != NULL) {
  382.         if (sscanf(str,"%d",&index2) == 0) {
  383.           for (index2 = vp->max_y,i = 0; i < nunames; i++) {
  384.             if (startsame(str, uname[i])) {
  385.              index2 = i;
  386.          if (strcmp(name,"tpattern") == 0) 
  387.             index2 -= nunits - noutputs;
  388.              break;
  389.             }
  390.           }
  391.         }
  392.         if (iswv) tindex2 = index2 - first_weight_to[index1];
  393.         else tindex2 = index2;
  394.         if (index2 > cmax || index2 < cmin) {
  395.             if (ind_error(vp->name) == BREAK) return(BREAK);
  396.         goto i2_again;
  397.         }
  398.         (void) sprintf(string, "%s[%d][%d] = %.3f, new value: ", 
  399.                vp->name, index1, index2, 
  400.                pfptr[index1][tindex2]);
  401.         if ((str = get_command(string)) != NULL) {
  402.           if(!sscanf(str,"%f",&pfptr[index1][tindex2])) {
  403.               return(var_error(vp->name,index1,index2));
  404.           }
  405.         }
  406.         return(CONTINUE);
  407. i2_again:
  408.         (void) sprintf(string,"%s[%d][%d..%d] column index:(name or number)  ",
  409.                vp->name, index1,cmin,cmax );
  410.     }
  411. again:
  412.     (void)sprintf(string,"%s[0..%d][0..%d] row index:(name or number)  ",
  413.         vp->name, vp->max_x - 1, vp->max_y - 1);
  414.     }
  415. }
  416.  
  417. get_unames() {
  418.     int i;
  419.  
  420.     if (nunits == 0) {
  421.     return(put_error("Must define nunits before unames!"));
  422.     }
  423.  
  424.     if(uname == NULL) {
  425.         uname = (char **) emalloc((unsigned)(sizeof(char *) * nunits));
  426.     for (i = 0; i < nunits; i++)
  427.         uname[i] = NULL;
  428.         (void) install_var("uname",Vstring,(int *) uname, nunames, 0, 
  429.                                 SETCONFMENU);
  430.     }
  431.  
  432.     /* we do one extra to read the "end" at the end of the list */
  433.     for (nunames = 0; nunames < nunits+1; nunames++) {
  434.     if (getn(&uname[nunames]) == FALSE || nunames == nunits) {
  435.         break;
  436.     }
  437.     }
  438.     change_variable_length("uname",nunames,0);
  439.     return(CONTINUE);
  440. }
  441.  
  442. getn(nm) char **nm; {
  443.     char   *str;
  444.  
  445.     str = get_command("next name (terminate with end): ");
  446.     if (str == NULL)
  447.     return(FALSE);
  448.     if (strcmp(str, "end") == 0) {
  449.     return(FALSE);
  450.     }
  451.     *nm = strsave(str);
  452.     return(TRUE);
  453. }
  454.  
  455. var_error(vname,i1,i2) char *vname; int i1,i2; {
  456.     if (i1 < 0) {
  457.         sprintf(err_string,"illegal value given for %s.",vname);
  458.     }
  459.     else if (i2 < 0) {
  460.         sprintf(err_string,"illegal value given for %s[%d].",
  461.                             vname,i1);
  462.     }
  463.     else {
  464.         sprintf(err_string,"illegal value given for %s[%d][%d].",
  465.                             vname,i1,i2);
  466.     }
  467.     return(put_error(err_string));
  468. }
  469.  
  470. ind_error(vname) char *vname; {
  471.     sprintf(err_string,"illegal index encountered for %s.",vname);
  472.     return (put_error(err_string));
  473. }
  474.  
  475.