intersci-n.c

Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #ifdef _MSC_VER
00003 #include <windows.h>
00004 #endif
00005 #include "intersci-n.h"
00006 #include "getrhs.h" 
00007 #include "crerhs.h" 
00008 
00009 #ifdef _MSC_VER
00010   #define __STDC__
00011 #endif
00012 
00013 /* global variables */
00014 
00015 int icre=1;     /* incremental counter for variable creation */
00016 int indent = 0; /* incremental counter for code indentation */
00017 int pass = 0 ;  /* flag for couting pass on code generation */
00018 char target = 'C'; /* langage for generation */
00019 
00020 VARPTR variables[MAXVAR]; /* array of VAR structures */
00021 int nVariable; /* number of variables */
00022 BASFUNPTR basfun; /* SCILAB function structure */
00023 FORSUBPTR forsub; /* FORTRAN subroutine structure */
00024 int nFun; /* total number of functions in "desc" file */
00025 char *funNames[MAXFUN]; /* array of function names */
00026 char str1[4*MAXNAM];
00027 char str2[4*MAXNAM];
00028 
00029 static void GenBuilder __PARAMS(( char *file,char *files,char *libs ));
00030 void CheckCreateOrder(void);
00031 /* local variables */
00032 
00033 int main( int argc,char ** argv)
00034 { 
00035   char *files,*libs;
00036   char *file;
00037   int SciLabinterface = 0 ;
00038   switch (argc) 
00039     {
00040     case 2:
00041       file = argv[1];
00042       target =  'C';
00043       SciLabinterface =  0; 
00044       files = NULL;
00045       libs = NULL;
00046       break;
00047     case 3:
00048       file = argv[1];
00049       target = 'C';
00050       SciLabinterface = 0; 
00051       files = argv[2];
00052       libs = NULL;
00053       break;
00054     case 4:
00055       file = argv[1];
00056       target = 'C';
00057       SciLabinterface = 0; 
00058       files = argv[2];
00059       libs = argv[3];
00060       break;
00061     default:
00062       printf("usage:  intersci <interface file> 'files' 'libs' \n");
00063       exit(1);
00064       break;
00065     }
00066   basfun = BasfunAlloc();
00067   if (basfun == 0) {
00068     printf("Running out of memory\n");
00069     exit(1);
00070   }
00071   forsub = ForsubAlloc();
00072   if (forsub == 0) {
00073     printf("Running out of memory\n");
00074     exit(1);
00075   }
00076   Generate(file);
00077   GenFundef(file,SciLabinterface);
00078   GenBuilder(file,files,libs);
00079   exit(0);
00080 }
00081 
00082 /***************************************************************
00083  * Produce the interface 
00084  ***************************************************************/
00085 
00086 void Generate(char *file)
00087 {
00088   int icrekp;
00089   FILE *fin, *fout, *foutv;
00090   char filout[MAXNAM];
00091   char filin[MAXNAM];
00092   sprintf(filin,"%s.desc",file);
00093   fin = fopen(filin,"r");
00094   if (fin == 0) {
00095     printf("interface file \"%s\" does not exist\n",filin);
00096     exit(1);
00097   }
00098   Copyright();
00099   strcpy(filout,file);
00100   strcat(filout,(target == 'F' ) ? ".f" : ".c" );
00101   fout = fopen(filout,"w");
00102   strcpy(filout,file);
00103   strcat(filout,".tmp");
00104   foutv = fopen(filout,"w");
00105   InitDeclare();
00106   nFun = 0;
00107   Fprintf(fout,indent,"#include \"stack-c.h\"\n");
00108   while(ReadFunction(fin)) {
00109     nFun++;
00110     if (nFun > MAXFUN) {
00111       printf("Too many SCILAB functions. The maximum is %d\n",MAXFUN);
00112       exit(1);
00113     }
00114     pass=0;
00116     FixStackPositions();
00117     icrekp=icre;
00118     FixForNames();
00119     ResetDeclare();
00121     /* first pass to collect declarations */
00122     WriteFunctionCode(foutv);
00123     /* cleaning added Fornames before pass 2 */
00124     ForNameClean();
00125     FixForNames();
00126     /* scond pass to produce code */
00127     pass=1;
00128     icre=icrekp;
00129     WriteFunctionCode(fout);
00131   }
00132   /* WriteMain(fout,file); */ 
00133   printf("C file \"%s.c\" has been created\n",file);
00134   /* WriteAddInter(file) ; */
00135   printf("Scilab file \"%s.sce\" has been created\n",file);
00136   fclose(fout);
00137   fclose(fin);
00138 }
00139 
00140 /***************************************************************
00141  * Interface function 
00142  ***************************************************************/
00143 
00144 void WriteMain(FILE *f,char *file)
00145 {
00146   int i;
00147   FCprintf(f,"\n/**********************\n");
00148   FCprintf(f," *  interface function \n");
00149   FCprintf(f," ********************/\n");
00150   Fprintf(f,indent++,"static TabF Tab[]={\n");
00151   for (i = 0; i < nFun; i++) {
00152     Fprintf(f,indent,"{ ints%s, \"%s\"},\n",funNames[i],funNames[i]);
00153   }
00154   Fprintf(f,--indent,"};\n\n");
00155   Fprintf(f,indent,"int C2F(%s)()\n",file);
00156   Fprintf(f,indent++,"{\n");
00157   Fprintf(f,indent,"Rhs=Max(0,Rhs);\n");
00158   Fprintf(f,indent,"(*(Tab[Fin-1].f))(Tab[Fin-1].name);\n");
00159   Fprintf(f,indent,"return 0;\n");
00160   Fprintf(f,--indent,"};\n");
00161 
00162 }
00163 
00164 /***************************************************************
00165  * Code for addinter 
00166  ***************************************************************/
00167 
00168 void WriteAddInter(char *file) 
00169 {
00170   FILE *fout;
00171   int i;
00172   char filout[MAXNAM];
00173   strcpy(filout,file);
00174   strcat(filout,".sce");
00175   fout = fopen(filout,"w");
00176   if ( fout != (FILE*) 0) 
00177     {
00178       fprintf(fout,"// Addinter for file %s\n",file);
00179       fprintf(fout,"// for hppa/sun-solaris/linux/dec\n");
00180       fprintf(fout,"//--------------------------------\n");
00181       fprintf(fout,"//Scilab functions \n");
00182       fprintf(fout,"%s_funs=[...\n",file);
00183       for (i = 0; i < nFun -1; i++) 
00184         fprintf(fout,"  '%s';\n",funNames[i]);
00185       fprintf(fout,"  '%s']\n",funNames[nFun-1]);
00186       fprintf(fout,"// interface file to link: ifile='%s.o' \n",file);
00187       fprintf(fout,"// user's files to link: ufiles=['file1.o','file2.o',....] \n");
00188       fprintf(fout,"addinter([files],'%s',%s_funs);\n",file,file);
00189       fclose(fout);
00190     }
00191   else
00192     fprintf(stderr,"Can't open file %s\n",file);
00193 }
00194  
00195 
00196 void Copyright()
00197 {
00198   printf("\nINTERSCI Version %s (%s)\n",VERSION,DATE);
00199   printf("    Copyright (C) INRIA/ENPC All rights reserved\n\n");
00200 }
00201 
00202 /***************************************************************
00203   Code generation 
00204 ***************************************************************/
00205 
00206 void WriteHeader(FILE *f, char *fname0,char *fname)
00207 {
00208   Fprintf(f,indent,"\nint %s%s(fname)\n",fname0,fname);
00209   Fprintf(f,indent+3,"char *fname;\n");
00210   Fprintf(f,indent,"{\n");indent++;
00211   WriteDeclaration(f);
00212 }
00213 
00214 void WriteFunctionCode(FILE *f)
00215 {
00216   int i;
00217   IVAR ivar;
00218   if ( pass == 1) 
00219     {
00220       printf("  generating C interface for function (%s) Scilab function\"%s\"\n",
00221              forsub->name,
00222              basfun->name);
00223     }
00224   FCprintf(f,"/******************************************\n");
00225   FCprintf(f," * SCILAB function : %s, fin = %d\n",basfun->name,nFun);
00226   FCprintf(f," ******************************************/\n");
00227 
00228   WriteHeader(f,"ints",basfun->name);
00229 
00230   /* optional arguments : new style */
00232   basfun->NewMaxOpt= basfun->maxOpt;
00233   if ( basfun->NewMaxOpt > 0 ) 
00234     {
00236       AddDeclare(DEC_INT,"nopt");
00237       AddDeclare(DEC_INT,"iopos");
00238       Fprintf(f,indent,"nopt=NumOpt();\n");
00239     }
00240 
00241   /* rhs argument number checking */
00242 
00243   if ( basfun->NewMaxOpt > 0 ) 
00244     Fprintf(f,indent,"CheckRhs(%d,%d+nopt);\n",basfun->nin - basfun->maxOpt,
00245             basfun->nin-basfun->maxOpt);
00246   else 
00247     Fprintf(f,indent,"CheckRhs(%d,%d);\n",basfun->nin - basfun->maxOpt,basfun->nin);
00248 
00249   
00250   /* lhs argument number checking */
00251   ivar = basfun->out;
00252   if ( ivar == 0) 
00253     {
00254       Fprintf(f,indent,"CheckLhs(0,1);\n");
00255     }
00256   else 
00257     {
00258       if ((variables[ivar-1]->length == 0) 
00259           || (variables[ivar-1]->type == LIST)
00260           || (variables[ivar-1]->type == TLIST))
00261         {
00262           Fprintf(f,indent,"CheckLhs(1,1);\n");
00263         }
00264       else 
00265         {
00266           Fprintf(f,indent,"CheckLhs(1,%d);\n",variables[ivar-1]->length);
00267         }
00268     }
00269   /* SCILAB argument checking */
00270   for (i = 0; i < basfun->nin - basfun->NewMaxOpt ; i++)
00271     {
00272       switch ( variables[i]->type ) 
00273         {
00274         case LIST : 
00275           WriteListAnalysis(f,i,"l");
00276           break;
00277         case TLIST:
00278           WriteListAnalysis(f,i,"t");
00279           break;
00280         case MLIST :
00281           WriteListAnalysis(f,i,"m");
00282           break;
00283         default:
00284           WriteArgCheck(f,i);
00285           break;
00286         }
00287     }
00288 
00289   if ( basfun->NewMaxOpt != 0) 
00290     {
00291       sprintf(str1,"rhs_opts opts[]={\n");
00292       for (i = basfun->nin -basfun->NewMaxOpt ; i < basfun->nin ; i++)
00293         {
00294           sprintf(str2,"\t{-1,\"%s\",\"%s\",0,0,0},\n",variables[i]->name,
00295                   SGetForTypeAbrev(variables[i]));
00296           strcat(str1,str2);
00297         }
00298       strcat(str1,"\t{-1,NULL,NULL,NULL,0,0}}");
00299       AddDeclare(DEC_DATA,str1); 
00300       Fprintf(f,indent,"iopos=Rhs;\n");
00301       Fprintf(f,indent,"if ( get_optionals(fname,opts) == 0) return 0;\n");
00302       for (i = basfun->nin -basfun->NewMaxOpt ; i < basfun->nin ; i++)
00303         {
00304           WriteOptArgPhase2(f,i);
00305         }
00306     }
00307   
00308   /* SCILAB cross checking */
00309   WriteCrossCheck(f);
00310 
00311   /* SCILAB equal output variable checking */
00312   WriteEqualCheck(f);
00313   
00314   /* FORTRAN call */
00315   WriteFortranCall(f);
00316   
00317   /* FORTRAN output to SCILAB */
00318   WriteOutput(f);
00319 }
00320 
00321 
00322 void WriteInfoCode(FILE *f)
00323 {
00324   int i,iout;
00325   IVAR ivar;
00326   VARPTR var,vout;
00327 
00328   iout = GetExistOutVar();
00329   vout = variables[iout -1];
00330 
00331   switch (vout->type) {
00332   case LIST:
00333   case TLIST:
00334     /* loop on output variables */
00335     printf("list(");
00336     for (i = 0; i < vout->length; i++) 
00337       {
00338         ivar = vout->el[i];
00339         var = variables[ivar-1];
00340         printf("%s",var->name);
00341         if ( i != vout->length -1 ) 
00342           printf(",");
00343         else
00344           printf(")");
00345       }
00346     break ;
00347   case SEQUENCE:
00348     /* loop on output variables */
00349     printf("[");
00350     for (i = 0; i < vout->length; i++) 
00351       {
00352         ivar = vout->el[i];
00353         var = variables[ivar-1];
00354         printf("%s",var->name);
00355         if ( i != vout->length -1 ) 
00356           printf(",");
00357         else
00358           printf("]");
00359       }
00360     break;
00361   case EMPTY:
00362     printf("[]\n");
00363     break;
00364   }
00365 
00366   printf("=%s(",basfun->name);
00367   for (i = 0; i < basfun->nin; i++)
00368     {
00369       printf("%s(%s)",variables[i]->name,SGetSciType(variables[i]->type));
00370       if ( i != basfun->nin -1 ) 
00371         printf(",");
00372     }
00373   printf(")\n");
00374 
00375 }
00376 
00377 /*************************************************************
00378  *  Ckecking and getting infos for datas coming from scilab calling 
00379  * sequence ( datas on the stack ) 
00380  ***********************************************************/
00381 
00382 void WriteArgCheck(FILE *f,int i)
00383 {
00384   int i1;
00385   VARPTR var = variables[basfun->in[i]-1];
00386 
00387   i1 = i + 1;
00388   
00389   Fprintf(f,indent,"/*  checking variable %s */\n",var->name);
00390   
00391   if (var->opt_type != 0) 
00392     {
00393       /* Optional Arguments */ 
00394       WriteOptArg(f,var);
00395     }
00396   else 
00397     {
00402       if (RHSTAB[var->type].type != var->type ) 
00403         {
00404           fprintf(stderr,"Bug in intersci : Something wrong in RHSTAB\n");
00405         }
00406       (*(RHSTAB[var->type].fonc))(f,var,0);
00407     }
00408 }
00409 
00410 
00411 
00412 /*************************************************************
00413  * cross checking dimensions 
00414  ***********************************************************/
00415 
00416 void WriteCrossCheck(FILE *f)
00417 {
00418   int i, j;
00419   VARPTR var;
00420   Fprintf(f,indent,"/* cross variable size checking */\n");
00421   for (i = 0; i < nVariable; i++) 
00422     {
00423       var = variables[i];
00424       if ( var->type == DIMFOREXT ) 
00425         {
00426           if ( var->nfor_name > 1) 
00427             {
00428               for ( j = 1 ; j < var->nfor_name ; j++) 
00429                 {
00431                   /* we do not check external values since they are not known here */
00432                   if ( (var->for_name_orig[j] != var->for_name_orig[j-1]) 
00433                        && ( var->for_name[j-1][1] != 'e' &&  var->for_name[j][1] != 'e' ))
00434                     {
00435                       Fprintf(f,indent,"CheckDimProp(%d,%d,%s != %s);\n",
00436                               var->for_name_orig[j-1], var->for_name_orig[j],
00437                               var->for_name[j-1],   var->for_name[j]);
00438                     }
00439                 }
00440             }
00441         }
00442       else if (var->type == SCALAR) 
00443         {
00445           if ( var->nfor_name > 1) 
00446             {
00447               for ( j = 1 ; j < var->nfor_name ; j++) 
00448                 {
00449                   int dim=2;
00450                   if ( var->for_name[j][0]=='m') dim=1;
00451                   if ( var->for_name[j][1] != 'e' )  /* do not check external variables */
00452                     {
00453                       if ( strncmp(var->for_name[0],"istk",4)==0) 
00454                         Fprintf(f,indent,"CheckOneDim(%d,%d,%s,*%s);\n",
00455                                 var->for_name_orig[j], dim ,  var->for_name[j],var->for_name[0]);
00456                       else
00457                         Fprintf(f,indent,"CheckOneDim(%d,%d,%s,%s);\n",
00458                                 var->for_name_orig[j], dim ,  var->for_name[j],var->for_name[0]);
00459                     }
00460                 }
00461             }
00462         }
00463     }
00464   /* 
00465      FCprintf(f,"/ *       cross formal parameter checking\n");
00466      FCprintf(f," *      not implemented yet * /\n");  */
00467 }
00468 
00469 
00470 
00471 
00472 void WriteEqualCheck(FILE *f)
00473 {
00474   /*Fprintf(f,indent,"/ * cross equal output variable checking\n");
00475     Fprintf(f,indent,"   not implemented yet* /\n"); */
00476 }
00477 
00478 /***************************************************************
00479  * Scilab argument of type list 
00480  ***************************************************************/
00481 
00482 void WriteListAnalysis(FILE *f,int i,char *list_type)
00483 {
00484   int k,i1;
00485   VARPTR var;
00486   i1=i+1;
00487 
00488   AddDeclare1(DEC_INT,"m%d",i1);
00489   AddDeclare1(DEC_INT,"n%d",i1);
00490   AddDeclare1(DEC_INT,"l%d",i1);
00491   Fprintf(f,indent,"GetRhsVar(%d,\"%s\",&m%d,&n%d,&l%d);\n",
00492           i1,list_type,i1,i1,i1);
00493   for (k = 0; k < nVariable ; k++) 
00494     {
00495       var = variables[k];
00496       if ((var->list_el != 0) &&
00497           (strcmp(var->list_name,variables[i]->name) == 0) &&
00498           var->present)
00499         {
00500           Fprintf(f,indent,"/* list element %d %s */\n",var->list_el,var->name);
00501           if (RHSTAB[var->type].type != var->type ) 
00502             {
00503               fprintf(stderr,"Bug in intersci : Something wrong in RHSTAB\n");
00504             }
00505           (*(RHSTAB[var->type].fonc))(f,var,0);
00506         }
00507     }
00508 }
00509 
00510 /***************************************************************
00511  * Create the code for stack creation of 
00512  * variables which are not Scilab argument 
00513  * and gather the code for C or Fortran call
00514  ***************************************************************/
00515 
00516 void CheckCreateOrder()
00517 {
00518   int ivar,min= 10000;
00519   int i,count=0;
00520   if ( forsub->narg == 0) return ;
00521   for (i = 0; i < forsub->narg; i++) 
00522     {
00523       ivar = forsub->arg[i];
00524       if (variables[ivar-1]->list_el == 0 
00525           &&  variables[ivar-1]->is_sciarg == 0 
00526           &&  variables[ivar-1]->for_type != EXTERNAL 
00527           &&  variables[ivar-1]->for_type != CSTRINGV ) 
00528         {
00529           count++;
00530           if ( min != 10000 && variables[ivar-1]->stack_position !=0 
00531                && variables[ivar-1]->stack_position < min) 
00532             {
00533               fprintf(stderr,"Error: declaration for local variables \n");
00534               fprintf(stderr,"\t must respect the order given in the calling sequence\n");
00535               fprintf(stderr,"\t declaration for %s must be moved downward\n",
00536                       variables[ivar-1]->name);
00537               exit(1);
00538             }
00539           if (  variables[ivar-1]->stack_position !=0 )
00540             min = variables[ivar-1]->stack_position;
00541         }
00542     }
00543 }
00544 
00545 
00546 void WriteFortranCall(FILE *f)
00547 {
00548   int i, ind;
00549   IVAR ivar, iivar;
00550   char call[MAXCALL];
00551 
00552   sprintf(call,"C2F(%s)(",forsub->name);
00553 
00554   CheckCreateOrder();
00555 
00556   /* loop on FORTRAN arguments */
00557 
00558   for (i = 0; i < forsub->narg; i++) 
00559     {
00560       ivar = forsub->arg[i];
00561       ind = 0;
00562       if (variables[ivar-1]->list_el != 0) 
00563         {
00564           /* FORTRAN argument is a list element */
00565           iivar = GetExistVar(variables[ivar-1]->list_name);
00566           if ( variables[iivar-1]->is_sciarg == 0) 
00567             {
00568               printf("list or tlist \"%s\" must be an argument of SCILAB function\n",
00569                      variables[ivar-1]->list_name);
00570               exit(1);      
00571             }
00572           strcat(call,variables[ivar-1]->for_name[0]);
00573           strcat(call,",");
00574         }
00575       else 
00576         {
00577 
00578           if ( variables[ivar-1]->is_sciarg == 1)
00579             {
00580                 #ifdef WIN32
00581                         _try
00582                         {
00583                                 if (target == 'C' && variables[ivar-1]->C_name[0] != NULL) 
00584                                 {
00585                                         strcat(call,"&");
00586                                         strcat(call,variables[ivar-1]->C_name[0]);
00587                                 }
00588                                 else strcat(call,variables[ivar-1]->for_name[0]);
00589                                 strcat(call,",");
00590                         }
00591 
00592                         _except (EXCEPTION_EXECUTE_HANDLER)
00593                         {
00594                           printf("Error EXCEPTION_EXECUTE_HANDLER %s %d\n",__FILE__,__LINE__);
00595                           exit(1);
00596                         }
00597                 #else
00598                         if (target == 'C' && variables[ivar-1]->C_name[0] != NULL) 
00599                         {
00600                                 strcat(call,"&");
00601                                 strcat(call,variables[ivar-1]->C_name[0]);
00602                         }
00603                         else strcat(call,variables[ivar-1]->for_name[0]);
00604                         strcat(call,",");
00605                 #endif
00606                   
00607                 }
00608 
00609 
00610               
00611           else 
00612             {
00613               /* FORTRAN argument is not a SCILAB argument */
00614               /* a new variable is created on the stack for each 
00615                  Fortran argument */
00616               (*(CRERHSTAB[variables[ivar-1]->type].fonc))(f,variables[ivar-1]);
00617                 #ifdef _MSC_VER
00618                   _try
00619                   {
00620               if (target == 'C' && variables[ivar-1]->C_name[0] != NULL) 
00621                         {
00622                                 strcat(call,"&");
00623                                 strcat(call,variables[ivar-1]->C_name[0]);
00624                         }
00625               else strcat(call,variables[ivar-1]->for_name[0]);
00626               strcat(call,",");
00627                   }
00628                   _except (EXCEPTION_EXECUTE_HANDLER)
00629                   {
00630                           printf("Error EXCEPTION_EXECUTE_HANDLER %s %d\n",__FILE__,__LINE__);
00631                           exit(1);
00632                   }
00633                 #else
00634                   if (target == 'C' && variables[ivar-1]->C_name[0] != NULL) 
00635                   {
00636                           strcat(call,"&");
00637                           strcat(call,variables[ivar-1]->C_name[0]);
00638                   }
00639                   else strcat(call,variables[ivar-1]->for_name[0]);
00640                   strcat(call,",");
00641                 #endif
00642             }
00643         }
00644     }
00645   if  (forsub->narg == 0) 
00646     strcat(call,")");
00647   else 
00648     call[strlen(call)-1] = ')';
00649 
00650   if (target == 'C' ) strcat(call,";\n");
00651   Fprintf(f,indent,call);
00652 
00653   for ( i=0 ; i < nVariable ; i++) 
00654     {
00655       if ( strcmp(variables[i]->name,"err")==0)
00656         {
00657           AddDeclare(DEC_INT,"err=0");
00658           Fprintf(f,indent++,"if (err >  0) {\n");  
00659           Fprintf(f,indent,"Scierror(999,\"%%s: Internal Error \\r\\n\",fname);\n");
00660           Fprintf(f,indent,"return 0;\n");
00661           Fprintf(f,--indent,"};\n");
00662           break;
00663         }
00664     }
00665 }
00666 
00667 /***************************************************
00668  * Write the interface code 
00669  * for lhs variables creation 
00670  *****************************************************/
00671 
00672 void WriteOutput(FILE *f)
00673 {
00674   IVAR iout,ivar;
00675   VARPTR var,vout;
00676   int i;
00677   
00678   iout = CheckOutVar();
00679   
00680   if ( iout == 0) 
00681     {
00682       Fprintf(f,indent,"LhsVar(1)=0;\n;return 0;\n");
00683     }
00684   else 
00685     {
00686       vout = variables[iout-1];
00687       switch (vout->type) 
00688         {
00689         case LIST:
00690         case TLIST:
00691         case MLIST:
00692           Fprintf(f,indent,"/* Creation of output %s of length %d*/\n",
00693                   SGetSciType(vout->type),vout->length);
00694           vout->stack_position = icre;
00695           icre++;
00696           Fprintf(f,indent,"Create%s(%d,%d);\n",
00697                   SGetSciType(vout->type),
00698                   vout->stack_position,
00699                   vout->length);
00700           /* loop on output variables */
00701           for (i = 0; i < vout->length; i++) 
00702             {
00703               ivar = vout->el[i];
00704               var = variables[ivar-1];
00705               Fprintf(f,indent,"/* Element %d: %s*/\n",i+1,var->name);
00706               WriteVariable(f,var,ivar,1,i+1);
00707             }
00708           Fprintf(f,indent,"LhsVar(1)= %d;\nreturn 0;",vout->stack_position);
00709           break;
00710         case SEQUENCE:
00711           /* loop on output variables */
00712           for (i = 0; i < vout->length; i++) 
00713             {
00714               ivar = vout->el[i];
00715               var = variables[ivar-1];
00716               WriteVariable(f,var,ivar,0,0);
00717             }
00718           Fprintf(f,indent,"return 0;\n");
00719           break;
00720         case EMPTY:
00721           Fprintf(f,indent,"LhsVar(1)=0;\n;return 0;\n");
00722           break;
00723         }
00724     }
00725   Fprintf(f,--indent,"}\n");
00726 }
00727 
00728 /***********************************************
00729  * Output of variable var 
00730  *   if variable is outputed inside a list 
00731  *   insidelist is set to true (1) and nel is the number 
00732  *   of the variable in the list 
00733  ***********************************************/
00734 
00735 void WriteVariable(FILE *f, VARPTR var,IVAR ivar,int insidelist,int nel)
00736 {
00737   IVAR ivar2, barg, farg;
00738   VARPTR var2;
00739   int j;
00740 
00741   /* get number of variable in SCILAB calling list */
00742 
00743   barg = GetNumberInScilabCall(ivar);
00744 
00745   /* get number of variable in FORTRAN calling list */
00746 
00747   farg = GetNumberInFortranCall(ivar);
00748   
00749   if (var->for_type == EXTERNAL) 
00750     {
00751       /* external type */
00752       if (barg != 0) 
00753         {
00754           printf("output variable with external type \"%s\" \n",var->name);
00755           printf("  cannot be an input argument of SCILAB function\n");
00756           exit(1);
00757         }
00758       if (var->equal != 0) 
00759         {
00760           printf("output variable with external type \"%s\"\n", var->name);
00761           printf("  cannot have a convertion\n");
00762           exit(1);
00763         }
00764       if (farg == 0) 
00765         {
00766           printf("output variable with external type \"%s\" must be\n", var->name);
00767           printf("  an argument of FORTRAN subroutine");
00768           exit(1);
00769         }
00770       WriteExternalVariableOutput(f,var,insidelist,nel);
00771     }
00772   else 
00773     {
00774       if ( insidelist == 0 && var->list_el == 0 )
00775         {
00776           if ( var->opt_type != 0) 
00777             {
00778               Fprintf(f,indent,"LhsVar(%d)= opts[%d].position /* %s */;\n",
00779                       var->out_position,
00780                       var->stack_position - basfun->NewMaxOpt+1,
00781                       var->name);
00782             }
00783           else
00784             {
00785 
00786               if ( var->for_type == CSTRINGV) 
00787                 /* variable is recreated fro output */
00788                 Fprintf(f,indent,"LhsVar(%d)= %d;\n",
00789                         var->out_position,icre);
00790               else 
00791                 Fprintf(f,indent,"LhsVar(%d)= %d;\n",
00792                         var->out_position,var->stack_position);
00793             }
00794         }
00795       if (var->equal != 0) 
00796         {
00797           /* SCILAB type convertion */
00798           if (barg !=0 || farg!= 0) 
00799             {
00800               printf("output variable with convertion \"%s\" must not be\n",var->name);
00801               printf("  an input variable of SCILAB function or an argument\n");
00802               printf("  of FORTRAN subroutine\n");
00803               exit(1);
00804             }
00805           ivar2 = var->equal;
00806           var2 = variables[ivar2-1];
00807           /* get number of equal variable in SCILAB calling list */
00808           barg = 0;
00809           for (j = 0; j < basfun->nin; j++) 
00810             {
00811               if (ivar2 == basfun->in[j]) 
00812                 {
00813                   barg = j + 1;
00814                   break;
00815                 }
00816             }
00817           if (barg == 0) 
00818             {
00819               printf("output variable with convertion \"%s\" must be\n",
00820                      var->name);
00821               printf("  an input variable of SCILAB function\n");
00822               exit(1);
00823             }
00824           /* get number of equal variable in FORTRAN calling list */
00825           farg = 0;
00826           for (j = 0; j < forsub->narg; j++) {
00827             if (ivar2 == forsub->arg[j]) {
00828               farg = j + 1;
00829               break;
00830             }
00831           }
00832           if (farg == 0) 
00833             {
00834               printf("output variable with convertion \"%s\" must be\n",
00835                      var->name);
00836               printf("  an argument FORTRAN subroutine");
00837               exit(1);
00838             }
00839           var->for_type = var2->for_type;
00840           WriteVariableOutput(f,var,1,insidelist,nel);
00841         }
00842       else 
00843         {
00844           /* no SCILAB type convertion */
00845           if ( var->type == LIST || var->type == TLIST )
00846             {
00849               WriteVariableOutput(f,var,0,insidelist,nel);
00850               return;
00851             }
00852           if (farg == 0 ) {
00853             printf("variable without convertion \"%s\" must be an argument\n",
00854                    var->name);
00855             printf("  of FORTRAN subroutine\n");
00856             exit(1);
00857           }
00858           
00859           WriteVariableOutput(f,var,0,insidelist,nel);
00860         }
00861     }
00862 }
00863 
00864 
00865 int GetNumberInScilabCall(int ivar)
00866 {
00867   int j;
00868   for (j = 0; j < basfun->nin; j++) 
00869     {
00870       if (ivar == basfun->in[j]) {
00871         return(j+1);
00872         break;
00873       }
00874     }
00875   return(0);
00876 }
00877 
00878 int GetNumberInFortranCall(int ivar)
00879 {
00880   int j;
00881   for (j = 0; j < forsub->narg; j++) 
00882     {
00883       if (ivar == forsub->arg[j]) 
00884         {
00885           return( j + 1);
00886           break;
00887         }
00888     }
00889   return(0);
00890 }
00891 
00892 /********************************************
00893  * changes string "str" to "int(str)" 
00894  * if str begins with stk or return str unchanged 
00895  ********************************************/
00896  
00897 char unknown[]="ukn";
00898 
00899 char *Forname2Int(VARPTR var,int i)
00900 {
00901   int l;
00902   char *p;
00903   if ( var->for_name[i] == (char *) 0) 
00904     {
00905       printf("Error in Forname2Int for variable %s \n",var->name);
00906       printf("Maybe an internal variable has a dimension\n");
00907       printf("which can't be evaluated\n");
00908       abort();
00909       return(unknown);
00910     }
00911   if ( var->C_name[i] != (char *) 0) 
00912     return var->C_name[i];
00913   if (strncmp(var->for_name[i],"stk",3) == 0) {
00914     l = strlen(var->for_name[i]);
00915     p = (char *)malloc((unsigned)(l + 6));
00916     sprintf(p,"int(%s)",var->for_name[i]);
00917     return p;
00918   }
00919   else return var->for_name[i];
00920 }
00921 
00922 void GenFundef(char *file,int interf)
00923 {
00924   FILE *fout;
00925   char filout[MAXNAM];
00926   int i,j;
00927   if (interf != 0 ) 
00928     {
00929       strcpy(filout,file);
00930       strcat(filout,".fundef");
00931       fout = fopen(filout,"w");
00932       fprintf(fout,"#define IN_%s %.2d\n",file,interf);
00933       for (i = 0; i < nFun; i++) {
00934         fprintf(fout,"{\"%s\",",funNames[i]);
00935         for (j = 0; j < 25 - (int)strlen(funNames[i]); j++) fprintf(fout," ");
00936         fprintf(fout,"\t\tIN_%s,\t%d,\t3},\n",file,i+1);
00937       }
00938       printf("\nfile \"%s\" has been created\n",filout);
00939       fclose(fout);
00940     }
00941 }
00942 
00943 static void GenBuilder(char *file,char *files,char *libs)
00944 {
00945   FILE *fout;
00946   char filout[MAXNAM];
00947   int i;
00948   strcpy(filout,file);
00949   strcat(filout,"_builder.sce");
00950   fout = fopen(filout,"w");
00951   fprintf(fout,"// generated with intersci \n");
00952   fprintf(fout,"ilib_name = 'lib%s'\t\t// interface library name\n",file);
00953 
00954   /* files = 'file1.o file2.o ....' delimiter = ' ' */
00955   while ( files != NULL)
00956     {
00957       static int first =1; 
00958       if ( first ==1 ) { fprintf(fout,"files =['%s.o';\n\t'",file);first ++;} 
00959       else { fprintf(fout,"\t'");}
00960       while ( *files != 0 && *files != ' ' ) { fprintf(fout,"%c",*files); files++;}
00961       while ( *files == ' ') files++;
00962       if ( *files == 0 ) { fprintf(fout,"'];\n"); break;}
00963       else {  fprintf(fout,"'\n");} ;
00964     }
00965 
00966   while ( libs != NULL)
00967     {
00968       static int first =1; 
00969       if ( first ==1 ) { fprintf(fout,"libs =['");first ++;} 
00970       else { fprintf(fout,"\t'");}
00971       while ( *libs != 0 && *libs != ' ' ) { fprintf(fout,"%c",*libs); libs++;}
00972       while ( *libs == ' ') libs++;
00973       if ( *libs == 0 ) { fprintf(fout,"'];\n"); break;}
00974       else {  fprintf(fout,"'\n");} ;
00975     }
00976 
00977   fprintf(fout,"\ntable =[");
00978   i=0;
00979   if ( nFun == 1) 
00980     fprintf(fout,"\"%s\",\"ints%s\"];\n",funNames[i],funNames[i]);
00981   else 
00982     {
00983       fprintf(fout,"\"%s\",\"ints%s\";\n",funNames[i],funNames[i]);
00984       for (i = 1; i < nFun-1; i++) {
00985         fprintf(fout,"\t\"%s\",\"ints%s\";\n",funNames[i],funNames[i]);
00986       }
00987       i=nFun-1;
00988       fprintf(fout,"\t\"%s\",\"ints%s\"];\n",funNames[i],funNames[i]);
00989     }
00990   fprintf(fout,"ilib_build(ilib_name,table,files,libs);\n");
00991   printf("\nfile \"%s\" has been created\n",filout);
00992   fclose(fout);
00993 }
00994 
00995 
00996 
00997 
00998 /**********************************************************
00999   Dealing With Fortran OutPut 
01000   taking into account indentation and line breaks after column 72
01001 ***********************************************************/
01002 
01003 
01004 #define MAXBUF 4096 
01005 char sbuf[MAXBUF];
01006 
01007 #ifdef __STDC__
01008 #include <stdarg.h>
01009 #else
01010 #include <varargs.h>
01011 #endif 
01012 
01013 void  Fprintf(FILE *f,int indent2,char *format,...) 
01014 {
01015   int i;
01016   static int count=0;
01017   va_list ap;
01018   va_start(ap,format);
01019 
01020   vsprintf(sbuf,format,ap);
01021 
01022   for ( i = 0 ; i < (int) strlen(sbuf); i++) 
01023     {
01024       if ( count == 0)  
01025         {
01026           white(f,indent2);
01027           count = indent2;
01028         }
01029       if ( count >= 100 && sbuf[i] != '\n' && (sbuf[i] == ' ' || sbuf[i]== ',' || sbuf[i] == ';' || sbuf[i] == '(' ) ) 
01030         { 
01031           fprintf(f,"\n");
01032           white(f,indent2);count=indent2;
01033         }
01034       if ( sbuf[i] == '\n') count = -1 ;
01035       fprintf(f,"%c",sbuf[i]);
01036       count++;
01037     }
01038   va_end(ap);
01039 }
01040 
01041 void white(FILE *f,int ind)
01042 {
01043   int i ;
01044   for (i =0 ; i < ind ; i++) fprintf(f," ");
01045 }
01046 
01047 
01048 void  FCprintf(FILE *f,char *format,...) 
01049 {
01050   va_list ap;
01051 #ifdef __STDC__
01052   va_start(ap,format);
01053 #else 
01054   FILE *f;
01055   char *format;
01056   va_start(ap);
01057   f = va_arg(ap, FILE *);
01058   format = va_arg(ap, char *);
01059 #endif
01060   vfprintf(f,format,ap);
01061   va_end(ap);
01062 }
01063 
01064 /******************************************
01065  *  memory allocators 
01066  ******************************************/
01067 
01068 VARPTR VarAlloc()
01069 {
01070   return((VARPTR) malloc(sizeof(VAR)));
01071 }
01072 
01073 BASFUNPTR BasfunAlloc()
01074 {
01075   return((BASFUNPTR) malloc(sizeof(BASFUN)));
01076 }
01077 
01078 FORSUBPTR ForsubAlloc()
01079 {
01080   return((FORSUBPTR) malloc(sizeof(FORSUB)));
01081 }

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