variables.c

Go to the documentation of this file.
00001 #include <stdlib.h>
00002 
00003 #include "intersci-n.h"
00004 
00005 /*********************************************************************
00006  * Dealing with the set of variables 
00007  *********************************************************************/
00008 
00009 int ShowVariables() 
00010 {
00011   int i;
00012   VARPTR var;
00013   for (i = 0; i < nVariable; i++) 
00014     {
00015       int j;
00016       var = variables[i];
00017       fprintf(stderr,"==============variable %d : name %s\n",i+1,var->name);
00018       fprintf(stderr,"type %s<->%s\n",SGetSciType(var->type),
00019               SGetForType(var->for_type));
00020       fprintf(stderr,"elts : [");
00021       for (j=0 ; j < var->length ; j++) 
00022         {
00023           fprintf(stderr,"{var %d:%s}",var->el[j],
00024                   variables[var->el[j]-1]->name);
00025         }
00026       fprintf(stderr,"]\n");
00027       /* fprintf(stderr," name of external function when type is  char *fexternal[MAXNAM]; 
00028          external 
00029       */
00030       fprintf(stderr," ?  equal %d\n",var->equal);
00031       fprintf(stderr,"for_names [");
00032       if ( var->nfor_name != 0) 
00033         {
00034           for (j=0 ; j < var->nfor_name ; j++) 
00035             {
00036               fprintf(stderr,"{%s:%d}",var->for_name[j],
00037                       var->for_name_orig[j]);
00038               if ( j != var->nfor_name-1) fprintf(stderr,",");
00039             }
00040         }
00041       fprintf(stderr,"]\n");
00042       fprintf(stderr," position in a list %d\n",var->list_el);
00043       if ( var->list_el > 0 )
00044         fprintf(stderr," List name %s\n",var->list_name);
00045       fprintf(stderr," type of optional variable %d\n",var->opt_type);
00046       if ( var->opt_type != 0)
00047         fprintf(stderr," name or value default for optional variable %s\n",
00048                 var->opt_name);
00049       fprintf(stderr," 1 if the variable is really present %d\n",var->present);
00050       fprintf(stderr,"sciarg %d, rhs %d, lhs %d\n",
00051               var->is_sciarg,
00052               var->stack_position,
00053               var->out_position);
00054     }
00055   return 0;
00056 }
00057 
00058 /*******************************************************
00059  * this function recomputes the stack_positions 
00060  * taking into account the fact that external 
00061  * variables are not allocated on the stack. 
00062  * We use the fact that after the readfunction 
00063  * the stack_position increases when i increases  in variables[i]
00064  * CSTRINGV variables which are not given as arguments 
00065  * must be treated the same way 
00066  *******************************************************/
00067 
00068 #define ISNONSTACK(var) ( (var)->for_type == EXTERNAL \
00069    || ( (var)->for_type == CSTRINGV && (var)->is_sciarg == 0  && (var)->list_el == 0 ))
00070 
00071 int FixStackPositions() 
00072 {
00073   int i;
00074   VARPTR var,var1;
00075   for (i = nVariable-1 ; i >= 0; i--) 
00076     {
00077       int j;
00078       var = variables[i];
00079       if ( ISNONSTACK(var) )
00080         {
00081           icre--;
00082           for ( j = 0 ; j < nVariable ; j++ ) 
00083             {
00084               var1 = variables[j];
00085               if ( var1->stack_position > var->stack_position 
00086                    && ! (ISNONSTACK(var1)))
00087                 var1->stack_position--;
00088             }
00089         }
00090     }
00091   return 0;
00092 }
00093 
00094 /********************************************************
00095  * return the variable number of variable name. if it does not already exist,
00096  *  it is created and "nVariable" is incremented
00097  * p corresponds to the present slot of var structure:
00098  *  - if the variable does not exist it is created with p value
00099  *  - if the variable exists it is created with (p or 0) value 
00100  *********************************************************/
00101 
00102 
00103 IVAR GetVar(name,p)
00104      char *name;
00105      int p;
00106 {
00107   int i;
00108   VARPTR var;
00109   if (strcmp(name,"out") == 0) {
00110     printf("the name of a variable which is not the output variable\n");
00111     printf("  of SCILAB function cannot be \"out\"\n");
00112     exit(1);
00113   }
00114   for (i = 0; i < nVariable; i++) {
00115     var = variables[i];
00116     if (strcmp(var->name,name) == 0) {
00117       var->present = var->present || p;
00118       return(i+1);
00119     }
00120   }
00121   if (nVariable == MAXVAR) {
00122     printf("too many variables\n");
00123     printf("  augment constant \"MAXVAR\" and recompile intersci\n");
00124     exit(1);
00125   }
00126   var = VarAlloc();
00127   if (var == 0) {
00128     printf("Running out of memory\n");
00129     exit(1);
00130   }
00131   var->name = (char *)malloc((unsigned)(strlen(name) + 1));
00132   strcpy(var->name,name);
00133   var->type = 0;
00134   var->length = 0;
00135   var->for_type = 0;
00136   var->equal = 0;
00137   var->nfor_name = 0;
00138   var->kp_state = -1;
00139   var->list_el = 0;
00140   var->opt_type = 0;
00141   var->present = p;
00142   var->out_position = 0;
00143   var->stack_position = 0;
00144   var->is_sciarg = 0;
00145   variables[nVariable++] = var;
00146   var->vpos = nVariable;
00147   return(nVariable);
00148 }
00149 
00150 /************************************************************************
00151  * return the variable number of variable name which must already  exist 
00152  ***********************************************************************/
00153 
00154 IVAR GetExistVar(name)
00155      char *name;
00156 {
00157   int i;
00158   VARPTR var;
00159   if (strcmp(name,"out") == 0) {
00160     printf("the name of a variable which is not the output variable\n");
00161     printf("  of SCILAB function cannot be \"out\"\n");
00162     exit(1);
00163   }
00164   for (i = 0; i < nVariable; i++) {
00165     var = variables[i];
00166     if (strcmp(var->name,name) == 0) {
00167       /* always present */
00168       var->present = 1;
00169       return(i+1);
00170     }
00171   }
00172   i=CreatePredefVar(name);
00173   if ( i != -1) return(i);
00174   printf("variable \"%s\" must exist\n",name);
00175   exit(1);
00176 }
00177 
00178 /******************************************************************
00179  * fname,rhs,lhs,err are predefined variables 
00180  * if someone want to add them in the Fortran or C Calling sequence 
00181  * it's done without aby checks 
00182  ******************************************************************/
00183 
00184 int CreatePredefVar(name)
00185      char *name;
00186 {
00187   VARPTR var;
00188   if (strcmp(name,"err")  == 0 
00189       || strcmp(name,"rhs") == 0 
00190       || strcmp(name,"lhs") == 0 
00191       || strcmp(name,"fname") == 0)
00192     {
00193       int num ;
00194       num=GetVar(name,1);
00195       var = variables[num-1];
00196       var->for_type = PREDEF;
00197       return(num);
00198     }
00199   return(-1);
00200 }
00201 
00202 /********************************************************
00203  * return the variable number of variable "out"
00204  * which is created and "nVariable" is incremented 
00205  ********************************************************/
00206 
00207 IVAR GetOutVar(name)
00208      char *name;
00209 {
00210   VARPTR var;
00211   if (strcmp(name,"out") != 0) {
00212     printf("the name of output variable of SCILAB function\n");
00213     printf("  must be \"out\"\n");
00214     exit(1);
00215   }
00216   if (nVariable == MAXVAR) {
00217     printf("too many variables\n");
00218     printf("  augmente constant \"MAXVAR\" and recompile intersci\n");
00219     exit(1);
00220   }
00221   var = VarAlloc();
00222   if (var == 0) {
00223     printf("Running out of memory\n");
00224     exit(1);
00225   }
00226   var->name = (char *)malloc((unsigned)(strlen(name) + 1));
00227   strcpy(var->name,name);
00228   var->type = 0;
00229   var->length = 0;
00230   var->for_type = 0;
00231   var->equal = 0;
00232   var->nfor_name = 0;
00233   var->kp_state = -1;
00234   var->list_el = 0;
00235   var->opt_type = 0;
00236   var->present = 0;
00237   var->out_position = 0;
00238   var->stack_position = 0;
00239   variables[nVariable++] = var;
00240   return(nVariable);
00241 }
00242 
00243 /* return the variable number of variable "out"
00244    which must exist */
00245 
00246 IVAR GetExistOutVar()
00247 {
00248   int i;
00249   char str[4];
00250   strcpy(str,"out");
00251   for (i = 0; i < nVariable; i++) {
00252     if (strcmp(variables[i]->name,str) == 0)
00253       return(i+1);
00254   }
00255   printf("variable \"out\" must exist\n");
00256   exit(1);
00257 }
00258 
00259 /* return the variable number of variable "out" or 0 */
00260 
00261 IVAR CheckOutVar()
00262 {
00263   int i;
00264   char str[4];
00265   strcpy(str,"out");
00266   for (i = 0; i < nVariable; i++) {
00267     if (strcmp(variables[i]->name,str) == 0)
00268       return(i+1);
00269   }
00270   return 0;
00271 }
00272 
00273 
00274 
00275 
00276 /************************************************
00277  * add name in the for_name array 
00278  * field of variable ivar 
00279  * and add the number ivar1 in the for_name_orig array 
00280  * field (ivar1 is a stack position) 
00281  * this is used for variables which code dimensions 
00282  * if for_name contains [m1,n2,m3] 
00283  * and for_name_orig contains [1,2,5] 
00284  * this means that stack variables 1,2,5 must have 
00285  * the same value for m1,n2,m3
00286  *************************************************/
00287 
00288 void AddForName(ivar,name,cname,ivar1)
00289      IVAR ivar;
00290      IVAR ivar1;
00291      char* name;
00292      char* cname;
00293 {
00294   VARPTR var;
00295   int l;
00296   var = variables[ivar-1];
00297   l = var->nfor_name;
00298   if (l == MAXARG) {
00299     printf("too many \"for_name\" for variable \"%s\"\n",var->name);
00300     printf("  augment constant \"MAXARG\" and recompile intersci\n");
00301     exit(1);
00302   }
00303   var->for_name[l] = (char *)malloc((unsigned)(strlen(name) + 1));
00304   if ( cname != NULL) 
00305     {
00306       var->C_name[l] = (char *)malloc((unsigned)(strlen(cname) + 1));
00307       strcpy(var->C_name[l],cname);
00308     }
00309   else 
00310     var->C_name[l] = NULL;
00311   var->for_name_orig[l] = ivar1;
00312   strcpy(var->for_name[l],name);
00313   var->nfor_name = l + 1;
00314 }
00315 
00316 /***************************
00317  * add name in the for_name array 
00318  * field of variable ivar 
00319  * this names are not cleared between 
00320  * the two passes 
00321  ***************************/
00322 
00323 void AddForName1(ivar,name,cname,ivar1)
00324      IVAR ivar;
00325      IVAR ivar1;
00326      char* name;
00327      char* cname;
00328 {
00329   VARPTR var;
00330   int l;
00331   var = variables[ivar-1];
00332   l = var->nfor_name;
00333   if ( pass == 0 && var->kp_state == -1 ) 
00334     {
00335       var->kp_state = var->nfor_name ;
00336     }
00337   if (l == MAXARG) {
00338     printf("too many \"for_name\" for variable \"%s\"\n",var->name);
00339     printf("  augment constant \"MAXARG\" and recompile intersci\n");
00340     exit(1);
00341   }
00342   var->for_name[l] = (char *)malloc((unsigned)(strlen(name) + 1));
00343   if ( cname != NULL) 
00344     {
00345       var->C_name[l] = (char *)malloc((unsigned)(strlen(cname) + 1));
00346       strcpy(var->C_name[l],cname);
00347     }
00348 
00349   else 
00350     var->C_name[l] = NULL;
00351   var->for_name_orig[l] = ivar1;
00352   strcpy(var->for_name[l],name);
00353   var->nfor_name = l + 1;
00354 }
00355 
00356 
00357 /********************************************************
00358  ** if kp_state is not -1 then kp_state is 0 and the for_names are cleaned
00359  *(in fact just forgotten the free call should be added 
00360  ********************************************************/
00361 
00362 void ForNameClean() 
00363 {
00364   VARPTR var;
00365   int i;
00366   for (i = 0; i < nVariable; i++) {
00367     var = variables[i];
00368     if ( var->kp_state != -1 ) 
00369       {
00370         var->nfor_name = var->kp_state ;
00371       }
00372   }
00373 }
00374 
00375 /***********************************************************
00376  * Changes the first for_name of variable number ivar to name 
00377  * or add the forname if necessary. 
00378  * if the forname is added, since we do not change the kp_state,
00379  * this value is kept between the two pass. 
00380  ************************************************************/
00381 
00382 #define FORNAME 128
00383 
00384 
00385 #ifdef __STDC__
00386 #include <stdarg.h>
00387 #else
00388 #include <varargs.h>
00389 #endif 
00390 
00391 #ifdef __STDC__ 
00392 void ChangeForName2(VARPTR varptr,char * format ,...)
00393 #else 
00394      /*VARARGS0*/
00395      void ChangeForName2(va_alist) va_dcl
00396 #endif
00397 {
00398   char forbuf[FORNAME];
00399   va_list ap;
00400 #ifdef __STDC__ 
00401   va_start(ap,format);
00402 #else 
00403   char *format;
00404   VARPTR varptr;
00405   va_start(ap);
00406   varptr = va_arg(ap, VARPTR );
00407   format = va_arg(ap, char *);
00408 #endif
00409   vsprintf(forbuf,format,ap);
00410   ChangeForName1(varptr,forbuf);
00411   va_end(ap);
00412 }
00413 
00414 void ChangeForName1(var,name)
00415      VARPTR var;
00416      char* name;
00417 {
00418   int l,pos=0;
00419   l = var->nfor_name;
00420   if ( l  != 0)
00421     { 
00422       int i;
00423       for ( i=0 ; i < l ; i++) 
00424         {
00425           if ( var->for_name_orig[i] == var->stack_position ) 
00426             { 
00427               pos = i ; break;
00428             }
00429         }
00430     }
00431   var->for_name[pos] = (char *)malloc((unsigned)(strlen(name) + 1));
00432   strcpy(var->for_name[pos],name);
00433   if ( pos != 0) 
00434     {
00435       int xx;
00436       char *loc = var->for_name[pos];
00437       var->for_name[pos] =       var->for_name[0];
00438       var->for_name[0] = loc;
00439       xx= var->for_name_orig[pos];
00440       var->for_name_orig[pos] =       var->for_name_orig[0];
00441       var->for_name_orig[0] = xx;
00442     }
00443   /* we keep the C name  var->C_name[0] = NULL; */
00445   if (l == 0) var->nfor_name = 1;
00446 }
00447 
00448 /***********************************************************
00449  * Function used to deal with types 
00450  * conversion from code <-> to string 
00451  ************************************************************/
00452 
00453 /* Attention tableau en ordre alphabetique */
00454 
00455 static struct btype { char *sname ;
00456   int  code ;}
00457 SType[] = {
00458   {"any",       ANY},
00459   {"bmatrix",    BMATRIX},
00460   {"bpointer",   SCIBPOINTER},
00461   {"column",    COLUMN},
00462   {"empty",     EMPTY},
00463   {"imatrix",    IMATRIX},
00464   {"list",      LIST},
00465   {"lpointer",  SCILPOINTER},
00466   {"matrix",    MATRIX},
00467   {"mpointer",  SCIMPOINTER},
00468   {"opointer",  SCIOPOINTER},
00469   {"polynom",   POLYNOM},
00470   {"row",       ROW},
00471   {"scalar",    SCALAR},
00472   {"sequence",  SEQUENCE},
00473   {"smpointer",  SCISMPOINTER},
00474   {"sparse",    SPARSE},
00475   {"string",    STRING},
00476   {"stringmat", STRINGMAT},
00477   {"tlist",     TLIST},
00478   {"mlist",     MLIST},
00479   {"vector",    VECTOR},
00480   {"work",      WORK},
00481   {(char *) 0 ,  -1}
00482 };
00483 
00484 /* Type Scilab:  renvoit un codage du type en nombre entier etant donne une chaine */
00485 
00486 int GetBasType(sname)
00487      char *sname;
00488 { 
00489   int i=0;
00490   while ( SType[i].sname != (char *) NULL)
00491     {
00492       int j ;
00493       j = strcmp(sname,SType[i].sname);
00494       if ( j == 0 ) 
00495         { 
00496           return(SType[i].code);
00497         }
00498       else 
00499         { 
00500           if ( j <= 0) 
00501             break;
00502           else i++;
00503         }
00504     }
00505   printf("the type of variable \"%s\" is unknown\n",sname);
00506   exit(1);
00507 }
00508 
00509 /**********************************************
00510  * This function returns the string description of 
00511  * a Scilab type given its code number 
00512  **********************************************/
00513 
00514 char *SGetSciType(type)
00515      int type;
00516 {
00517   int i=0;
00518   while ( SType[i].code  != -1 ) 
00519     {
00520       if ( SType[i].code == type ) 
00521         return(SType[i].sname);
00522       else 
00523         i++;
00524     }
00525   return("unknown");
00526 }
00527 
00528 /* Warning : Ftype is lexicographically sorted */
00529 
00530 static struct ftype { char *fname ; /* full fortran type name */
00531   int  code ; /* associated code */
00532   char *abrev; /* abbrev code : just for c d i r */
00533   char *st_name; /* stack to use :just for c d i r*/ 
00534   char *b_convert; /* converter for building lhs (for lists)*/
00535   int dec; /* declaration for the Fortran name */
00536   char *ctype; /* type in C */
00537 }
00538 FType[] = {
00539   {"Cstringv",CSTRINGV,"XX","XX","XX",-1,"XX"},
00540   {"boolean",BOOLEAN,"b","istk","icopy",DEC_INT,"int"},
00541   {"bpointer",BPOINTER,"XX","XX","XX",-1,"XX"},
00542   {"char",CHAR,"c","cstk","cvstr1",DEC_CHAR,"char"},
00543   {"double", DOUBLE,"d","stk","dcopy",DEC_DOUBLE,"double"},
00544   {"int",INT,"i","istk","int2db",DEC_INT,"int"},
00545   {"integer",INT,"i","istk","int2db",DEC_INT,"int"},
00546   {"lpointer",LPOINTER,"XX","XX","XX",-1,"XX"},
00547   {"mpointer",MPOINTER,"XX","XX","XX",-1,"XX"},
00548   {"opointer",OPOINTER,"XX","XX","XX",-1,"XX"},
00549   {"predef",PREDEF,"XX","XX","XX",-1,"XX"},
00550   {"real",REAL,"r","sstk","rea2db",DEC_REAL,"float"},
00551   {"smpointer",SMPOINTER,"XX","XX","XX",-1,"XX"},
00552   {(char *) 0 ,  -1}
00553 };
00554 
00555 /**********************************************
00556  * This function returns the code of a Fortran (or C) type 
00557  * given its full name 
00558  **********************************************/
00559 
00560 int GetForType(type)
00561      char *type;
00562 {
00563   int i=0;
00564   while ( FType[i].fname != (char *) NULL)
00565     {
00566       int j;
00567       j = strcmp(type,FType[i].fname);
00568       if ( j == 0 ) 
00569         { 
00570           return(FType[i].code);
00571         }
00572       else 
00573         { 
00574           if ( j <= 0) 
00575             break;
00576           else i++;
00577         }
00578     }
00579   return(EXTERNAL);
00580 }
00581 
00582 /**********************************************
00583  * This function returns the string description of 
00584  * a C or Fortran type given its code number 
00585  **********************************************/
00586 
00587 char *SGetForType(type)
00588      int type;
00589 {
00590   int i=0;
00591   while ( FType[i].code  != -1 ) 
00592     {
00593       if ( FType[i].code == type ) 
00594         return(FType[i].fname);
00595       else 
00596         i++;
00597     }
00598   return("External");
00599 }
00600 
00601 
00602 /**********************************************
00603  * This function returns an abbrev string 'c' 'd' 'i' 'r' 'b'
00604  * of a C or Fortran type given its code number 
00605  **********************************************/
00606 
00607 char *SGetForTypeAbrev(var)
00608      VARPTR var;
00609 {
00610   int i=0;
00611   while ( FType[i].code  != -1 ) 
00612     {
00613       if ( FType[i].code == var->for_type ) 
00614         return(FType[i].abrev);
00615       else 
00616         i++;
00617     }
00618   return("XX");
00619 }
00620 
00621 /**********************************************
00622  * This function returns the code for declaration 
00623  * of a C or Fortran type given its code number 
00624  **********************************************/
00625 
00626 int SGetForDec(type)
00627      int type;
00628 {
00629   int i=0;
00630   while ( FType[i].code  != -1 ) 
00631     {
00632       if ( FType[i].code == type ) 
00633         return(FType[i].dec);
00634       else 
00635         i++;
00636     }
00637   return(-1);
00638 }
00639 
00640 /**********************************************
00641  * This function returns the C string for declaration 
00642  * of a C or Fortran type given its code number 
00643  **********************************************/
00644 
00645 char* SGetCDec(type)
00646      int type;
00647 {
00648   int i=0;
00649   while ( FType[i].code  != -1 ) 
00650     {
00651       if ( FType[i].code == type ) 
00652         return(FType[i].ctype);
00653       else 
00654         i++;
00655     }
00656   return("XXX");
00657 }
00658 
00659 
00660 /**********************************************
00661  * given a variable and according to its C or Fortran type,
00662  * this function returns the stack name to use 
00663  **********************************************/
00664 
00665 char *SGetForTypeStack(var)
00666      VARPTR var;
00667 {
00668   int i=0;
00669   while ( FType[i].code  != -1 ) 
00670     {
00671       if ( FType[i].code == var->for_type ) 
00672         {
00673           if ( FType[i].st_name[0] == 'X' ) 
00674             {
00675               printf("incompatibility between Scilab and Fortran type for variable \"%s\"\n",
00676                      var->name);   
00677               exit(1);
00678             }
00679           return(FType[i].st_name);
00680         }
00681       else 
00682         i++;
00683     }
00684   printf("Unknown Fortran type for variable \"%s\"\n", var->name);   
00685   exit(1);
00686 }
00687 
00688 
00689 
00690 
00691 /**********************************************
00692  * given a variable and according to its C or Fortran type,
00693  * this function returns the name of the converter to use 
00694  * for back conversion 
00695  **********************************************/
00696 
00697 char *SGetForTypeBConvert(var)
00698      VARPTR var;
00699 {
00700   int i=0;
00701   while ( FType[i].code  != -1 ) 
00702     {
00703       if ( FType[i].code == var->for_type ) 
00704         {
00705           if ( FType[i].b_convert[0] == 'X' ) 
00706             {
00707               printf("incompatibility between Scilab and Fortran type for variable \"%s\"\n",
00708                      var->name);   
00709               exit(1);
00710             }
00711           return(FType[i].b_convert);
00712         }
00713       else 
00714         i++;
00715     }
00716   printf("Unknown Fortran type for variable \"%s\"\n", var->name);   
00717   exit(1);
00718 }
00719 
00720 
00721 
00722 /**********************************************
00723  * This function returns an abbrev string 'c' 'd' 'i' 'r' 'b'
00724  * of a C or Fortran type to use for back converting 
00725  * an external variable 
00726  * XXXXX : only for MATRIX et BMATRIX
00727  **********************************************/
00728 
00729 char *SGetExtForTypeAbrev(var)
00730      VARPTR var;
00731 {
00732   if ( var->type == BMATRIX ) 
00733     return("b");
00734   else 
00735     {
00736       if ( strcmp(var->fexternal,"cintf")==0) 
00737         return "i";
00738       else 
00739         return("d");
00740     }
00741 }
00742 
00743 
00744 /**********************************************
00745  * given a variable and according to its C or Fortran type,
00746  * this function returns the stack name to use 
00747  * for back conversion of external
00748  * XXXXX : idem 
00749  **********************************************/
00750 
00751 char *SGetExtForTypeStack(var)
00752      VARPTR var;
00753 {
00754   if ( var->type == BMATRIX ) 
00755     return(FType[1].st_name);
00756   else 
00757     return(FType[4].st_name);
00758 }
00759 

Generated on Sun Mar 4 15:03:57 2007 for Scilab [trunk] by  doxygen 1.5.1