summaryrefslogtreecommitdiff
path: root/2.3-1/macros/CCodeGeneration/C_Funcall.sci
diff options
context:
space:
mode:
Diffstat (limited to '2.3-1/macros/CCodeGeneration/C_Funcall.sci')
-rw-r--r--2.3-1/macros/CCodeGeneration/C_Funcall.sci467
1 files changed, 467 insertions, 0 deletions
diff --git a/2.3-1/macros/CCodeGeneration/C_Funcall.sci b/2.3-1/macros/CCodeGeneration/C_Funcall.sci
new file mode 100644
index 00000000..450ad088
--- /dev/null
+++ b/2.3-1/macros/CCodeGeneration/C_Funcall.sci
@@ -0,0 +1,467 @@
+function SharedInfo = C_Funcall(FunInfo,FileInfo,SharedInfo,FlagCall)
+// function SharedInfo = C_Funcall(FunInfo,FileInfo,SharedInfo,FlagCall)
+// -----------------------------------------------------------------
+// Get function for a generic SCI2C table.
+//
+// Input data:
+// //NUT: add description here
+//
+// Output data:
+// //NUT: add description here
+//
+// Status:
+// 27-Oct-2007 -- Raffaele Nutricato: Author.
+//
+// Copyright 2007 Raffaele Nutricato.
+// Contact: raffaele.nutricato@tiscali.it
+// -----------------------------------------------------------------
+
+// ------------------------------
+// --- Check input arguments. ---
+// ------------------------------
+SCI2CNInArgCheck(argn(2),4,4);
+
+// -----------------------
+// --- Initialization. ---
+// -----------------------
+nxtscifunname = SharedInfo.NextSCIFunName;
+nxtscifunnumber = SharedInfo.NextSCIFunNumber;
+
+ReportFileName = FileInfo.Funct(nxtscifunnumber).ReportFileName;
+CPass1FileName = FileInfo.Funct(nxtscifunnumber).CPass1FileName;
+CPass1FreeFileName = FileInfo.Funct(nxtscifunnumber).CPass1FreeFileName;
+HeaderFileName = FileInfo.Funct(nxtscifunnumber).Pass1HeaderFileName;
+CDeclarationFileName = FileInfo.Funct(nxtscifunnumber).CDeclarationFileName;
+CInitVarsFileName = FileInfo.Funct(nxtscifunnumber).CInitVarsFileName;
+IndentLevel = SharedInfo.NIndent;
+CCall = '';
+Target = SharedInfo.Target;
+// --- Extract Function Info. ---
+FunctionName = FunInfo.SCIFunctionName;
+CFunName = FunInfo.CFunctionName;
+InArg = FunInfo.InArg;
+NInArg = FunInfo.NInArg;
+OutArg = FunInfo.OutArg;
+NOutArg = FunInfo.NOutArg;
+PosFirstOutScalar = FunInfo.PosFirstOutScalar;
+
+// #RNU_RES_B
+PrintStringInfo(' ',ReportFileName,'file','y');
+PrintStringInfo('***Generating C code***',ReportFileName,'file','y');
+// #RNU_RES_E
+// ---------------------------
+// --- End Initialization. ---
+// ---------------------------
+
+
+// --------------------------------------------------
+// --- Manage anticipated exit from the function. ---
+// --------------------------------------------------
+if (SharedInfo.SkipNextFun > 0)
+ SharedInfo.SkipNextFun = SharedInfo.SkipNextFun - 1;
+ return;
+end
+
+// #RNU_RES_B
+// Exit if the function is a precision specifier and the corresponding flag is 1.
+// #RNU_RES_E
+if ((sum(mtlb_strcmp(FunctionName,SharedInfo.Annotations.DataPrec)) > 0) & ...
+ (SharedInfo.SkipNextPrec == 1))
+ // #RNU_RES_B
+ PrintStringInfo(' Skipping code generating because already generated in the previous function.',ReportFileName,'file','y');
+ // #RNU_RES_E
+ SharedInfo.SkipNextPrec = SharedInfo.SkipNextPrec - 1;
+ return;
+end
+
+// #RNU_RES_B
+// Exit if the function is OpEqual and the corresponding skip flag is enabled.
+// #RNU_RES_E
+if ((mtlb_strcmp(FunctionName,'OpEqual')) & ...
+ (SharedInfo.SkipNextEqual == 1))
+ // #RNU_RES_B
+ PrintStringInfo(' Skipping code generating because already generated in the previous function.',ReportFileName,'file','y');
+ // #RNU_RES_E
+ SharedInfo.SkipNextEqual = SharedInfo.SkipNextEqual - 1;
+ return;
+end
+
+// #BJ
+// size should be managed as other functions
+// otherwise size(4) will lead to a C variable __4Size reference
+// wich will never exists
+
+// #RNU_RES_B
+// Exit if the function is size.
+// #RNU_RES_E
+// if ((mtlb_strcmp(FunctionName,'size')))
+// // #RNU_RES_B
+// PrintStringInfo(' Anticipated exit for the size function.',ReportFileName,'file','y');
+// // #RNU_RES_E
+// CCall ='';
+// if (NInArg == 1)
+// if (NOutArg == 1)
+// CCall = CCall+OutArg(1).Name+'[0] = __'+InArg(1).Name+'Size[0];';
+// // #RNU_RES_B
+// PrintStringInfo(' '+CCall,ReportFileName,'file','y');
+// // #RNU_RES_E
+// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y');
+
+// CCall ='';
+// CCall = CCall+OutArg(1).Name+'[1] = __'+InArg(1).Name+'Size[1];';
+// // #RNU_RES_B
+// PrintStringInfo(' '+CCall,ReportFileName,'file','y');
+// // #RNU_RES_E
+// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y');
+// elseif (NOutArg == 2)
+// CCall = CCall+OutArg(1).Name+' = __'+InArg(1).Name+'Size[0];';
+// // #RNU_RES_B
+// PrintStringInfo(' '+CCall,ReportFileName,'file','y');
+// // #RNU_RES_E
+// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y');
+
+// CCall ='';
+// CCall = CCall+OutArg(2).Name+' = __'+InArg(1).Name+'Size[1];';
+// // #RNU_RES_B
+// PrintStringInfo(' '+CCall,ReportFileName,'file','y');
+// // #RNU_RES_E
+// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y');
+// else
+// SCI2Cerror('Don''t know how to manage size function with number of output args different from 1 and 2.');
+// end
+// elseif (NInArg == 2)
+// if (NOutArg == 1)
+// if (InArg(2).Value == 1)
+// CCall = CCall+OutArg(1).Name+' = __'+InArg(1).Name+'Size[0];';
+// // #RNU_RES_B
+// PrintStringInfo(' '+CCall,ReportFileName,'file','y');
+// // #RNU_RES_E
+// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y');
+// elseif (InArg(2).Value == 2)
+// CCall = CCall+OutArg(1).Name+' = __'+InArg(1).Name+'Size[1];';
+// // #RNU_RES_B
+// PrintStringInfo(' '+CCall,ReportFileName,'file','y');
+// // #RNU_RES_E
+// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y');
+// else
+// SCI2Cerror('Not known the value of the second input arg for the size function.');
+// end
+// else
+// SCI2Cerror('Don''t know how to manage size function with number of output args different from 1.');
+// end
+// else
+// SCI2Cerror('Don''t know how to manage size function with number of input args different from 1 and 2.');
+// end
+// return;
+// end
+// ------------------------------------------------------
+// --- End Manage anticipated exit from the function. ---
+// ------------------------------------------------------
+
+// #RNU_RES_B
+// ------------------------------------------------------------
+// --- Allocate memory and size array for output arguments. ---
+// ------------------------------------------------------------
+// #RNU_RES_E
+if (FlagCall == 1)
+// #RNU_RES_B
+//RNU qui va tolto tutto una volta sicuri che la memallocout puo' essere fatta dentro la st_insoutarg
+// C_MemAllocOutTempVars(OutArg,NOutArg,CPass1FileName,CPass1FreeFileName,IndentLevel,ReportFileName);
+// #RNU_RES_E
+end
+
+// ----------------------------
+// --- Generate the C call. ---
+// ----------------------------
+CCall ='';
+if(mtlb_strcmp(part(CFunName,1:9),'PI_thread') == %T)
+//Functions that are to be ru in separate thread in case of RPi target,
+//need to have specific name which is PI_THREAD(functionname)
+
+CCall = CCall + 'PI_THREAD('+CFunName+')'
+else
+
+ if (FunInfo.CFunctionName == SharedInfo.CMainFunName)
+ if (FlagCall == 1)
+ error(9999, 'main function called in a source code!');
+ else
+ CCall =CCall+'int ';
+ end
+ elseif ((mtlb_strcmp(part(CFunName,1:5),'odefn') == %T))
+ //Return type of function containing ODEs must be int.
+ CCall = CCall + 'int ';
+ else
+ if (PosFirstOutScalar >= 1)
+ if (FlagCall == 1)
+ CCall = CCall+OutArg(PosFirstOutScalar).Name+' = ';
+ else
+ CCall = CCall+C_Type(OutArg(PosFirstOutScalar).Type)+' ';
+ end
+ else
+ if (FlagCall == 0)
+ CCall = CCall+'void ';
+ end
+ end
+ end
+
+
+ // FIXME : Wrap library function call with prefixed name
+
+ //if CFunName == "main"
+ CCall = CCall + CFunName + "(";
+ //else
+ // CCall = CCall+"SCI2C("+CFunName+")(";
+ //end
+
+ // #RNU_RES_B
+ PrintStringInfo(' C call after output scalar args check: '+CCall,ReportFileName,'file','y');
+ // #RNU_RES_E
+ clear counterin
+ if(mtlb_strcmp(part(CFunName,1:5),'odefn') == %F)
+ for counterin = 1:NInArg
+
+ if (InArg(counterin).Type == 'g' & InArg(counterin).Scope == 'String')
+ TmpInArgName = '""'+InArg(counterin).Name+'""';
+ elseif (InArg(counterin).Type == 'z' & (InArg(counterin).Scope == 'Number'))
+ TmpInArgName = 'DoubleComplex('+SCI2Cstring(real(InArg(counterin).Value))+','+SCI2Cstring(imag(InArg(counterin).Value))+')';
+ elseif (InArg(counterin).Type == 'c' & (InArg(counterin).Scope == 'Number'))
+ TmpInArgName = 'FloatComplex('+SCI2Cstring(real(InArg(counterin).Value))+','+SCI2Cstring(imag(InArg(counterin).Value))+')';
+ else
+ TmpInArgName = InArg(counterin).Name;
+ end
+ TmpInArgType = C_Type(InArg(counterin).Type);
+
+ //if (FunctionName == 'OpEqual')
+ // TmpInArgSizeVar = '__'+OutArg(counterin).Name+'Size';
+ // else
+ TmpInArgSizeVar = '__'+InArg(counterin).Name+'Size';
+ //end
+
+ if (InArg(counterin).Dimension == 0)
+ if (FlagCall == 0)
+ CCall = CCall+TmpInArgType+' ';
+ end
+ CCall = CCall+TmpInArgName+',';
+ else
+ if (FlagCall == 0)
+ CCall = CCall+TmpInArgType+'* '+TmpInArgName+', int* __'+TmpInArgName+'Size,';
+ else
+ CCall = CCall+TmpInArgName+', '+TmpInArgSizeVar+',';
+ end
+ end
+ end
+ else
+ //If current function contains 'odefn' at the beginning, then it contains
+ //differnetial equations and its function call need to be differnt than
+ //other function call. GSL library being used for solving ODEs, requires
+ //function containing odes in specific format which is differnt than generated
+ //above.
+ for counterin = 1:NInArg
+
+ //if((NInArg == 4 & counterin <> 3) | (NInArg == 5 & counterin <> 4)) //Skip third argument
+ if (InArg(counterin).Type == 'g' & InArg(counterin).Scope == 'String')
+ TmpInArgName = '""'+InArg(counterin).Name+'""';
+ elseif (InArg(counterin).Type == 'z' & (InArg(counterin).Scope == 'Number'))
+ TmpInArgName = 'DoubleComplex('+SCI2Cstring(real(InArg(counterin).Value))+','+SCI2Cstring(imag(InArg(counterin).Value))+')';
+ elseif (InArg(counterin).Type == 'c' & (InArg(counterin).Scope == 'Number'))
+ TmpInArgName = 'FloatComplex('+SCI2Cstring(real(InArg(counterin).Value))+','+SCI2Cstring(imag(InArg(counterin).Value))+')';
+ else
+ TmpInArgName = InArg(counterin).Name;
+ end
+
+ TmpInArgType = C_Type(InArg(counterin).Type);
+
+ //if (FunctionName == 'OpEqual')
+ // TmpInArgSizeVar = '__'+OutArg(counterin).Name+'Size';
+ // else
+ TmpInArgSizeVar = '__'+InArg(counterin).Name+'Size';
+ //end
+
+ if (InArg(counterin).Dimension == 0)
+ if (FlagCall == 0)
+ CCall = CCall+TmpInArgType+' ';
+ end
+ CCall = CCall+TmpInArgName+',';
+ else
+ if (FlagCall == 0)
+ CCall = CCall+TmpInArgType+'* '+TmpInArgName+', ';//int* __'+TmpInArgName+'Size,';
+ else
+ CCall = CCall+TmpInArgName+', ';//+TmpInArgSizeVar+',';
+ end
+ end
+ //end
+ end
+
+ end
+
+ // #RNU_RES_B
+ PrintStringInfo(' C call after input args analysis: '+CCall,ReportFileName,'file','y');
+ // #RNU_RES_E
+ for counterout = 1:NOutArg
+ TmpOutArgName = OutArg(counterout).Name;
+ TmpOutArgType = C_Type(OutArg(counterout).Type);
+ if (counterout == PosFirstOutScalar)
+ if (FlagCall == 0)
+ // #RNU_RES_B
+ // --- Write in the declaration file the returned output scalar (if any). ---
+ // #RNU_RES_E
+ outscalardeclaration = TmpOutArgType+' '+TmpOutArgName+';';
+ // #RNU_RES_B
+ PrintStringInfo(outscalardeclaration,ReportFileName,'file','y');
+ // #RNU_RES_E
+ PrintStringInfo(C_IndentBlanks(1)+outscalardeclaration,CDeclarationFileName,'file','y');
+ PrintStringInfo(' ',CDeclarationFileName,'file','y');
+ end
+ else
+ if (OutArg(counterout).Dimension == 0)
+ if (FlagCall == 0)
+ // --- Write in the declaration file the returned output scalar (if any). ---
+ outscalardeclaration = TmpOutArgType+' '+TmpOutArgName+';';
+ PrintStringInfo(outscalardeclaration,ReportFileName,'file','y');
+ PrintStringInfo(C_IndentBlanks(1)+outscalardeclaration,CDeclarationFileName,'file','y');
+ PrintStringInfo(' ',CDeclarationFileName,'file','y');
+ CCall = CCall+TmpOutArgType+'* __ptr'+TmpOutArgName+', ';
+ else
+ CCall = CCall+'&'+TmpOutArgName+', ';//NUT: verifica se ci vuole l'&
+ end
+ else
+ if (FlagCall == 0)
+ CCall = CCall+TmpOutArgType+'* '+TmpOutArgName+',';
+ if (OutArg(counterout).FindLike == 1)
+ CCall = CCall+'int* __'+TmpOutArgName+'Size'+',';
+ end
+ // #RNU_RES_B
+ //NUT prova a sostituire le variabili strutture con variabili dichiarate all'inizio del codice.
+ // --- Declare the size of the output arguments. ---
+ // #RNU_RES_E
+ outscalardeclaration = 'int __'+TmpOutArgName+'Size[2];';
+ PrintStringInfo(outscalardeclaration,ReportFileName,'file','y');
+ PrintStringInfo(C_IndentBlanks(1)+outscalardeclaration,CDeclarationFileName,'file','y');
+ outscalardeclaration = '__'+TmpOutArgName+'Size[0] = '+(OutArg(counterout).Size(1))+';';
+ PrintStringInfo(outscalardeclaration,ReportFileName,'file','y');
+ PrintStringInfo(C_IndentBlanks(1)+outscalardeclaration,CInitVarsFileName,'file','y');
+ outscalardeclaration = '__'+TmpOutArgName+'Size[1] = '+(OutArg(counterout).Size(2))+';';
+ PrintStringInfo(outscalardeclaration,ReportFileName,'file','y');
+ PrintStringInfo(C_IndentBlanks(1)+outscalardeclaration,CInitVarsFileName,'file','y');
+ PrintStringInfo(' ',CInitVarsFileName,'file','y');
+ else
+ CCall = CCall+OutArg(counterout).Name+',';
+ if (OutArg(counterout).FindLike == 1)
+ CCall = CCall+'(int* ) __'+TmpOutArgName+'Size'+',';
+ end
+ end
+ end
+ end
+ end
+ PrintStringInfo(' C call after output args analysis: '+CCall,ReportFileName,'file','y');
+ // Remove the last " " and ","
+ if (part(CCall,length(CCall):length(CCall)) == ' ')
+ CCall = part(CCall,1:length(CCall)-1);
+ end
+ if (part(CCall,length(CCall):length(CCall)) == ',')
+ CCall = part(CCall,1:length(CCall)-1);
+ end
+
+ //__ysize is added to input arguments at last to comply with form required by GSL
+ if(mtlb_strcmp(part(CFunName,1:5),'odefn') == %T)
+ CCall = CCall + ', int* '+TmpInArgSizeVar;
+ end
+
+ CCall = CCall+')';
+ if (FlagCall == 1)
+ CCall = CCall+';';
+ end
+
+end
+//NUT: la parte di generazione della C call va inserita in una funzione a parte.
+//NUT: tale funzione deve avere anche uno switch che consenta di generare differenti versioni
+//NUT: delle chiamate C in accordo con la libreria disponibile, fermo restando che
+//NUT: e' sempre possibile fornire la lista delle macro.
+if mtlb_strcmp(FunctionName,'return')
+ // Here I introduce the pointer assignment for output scalar arguments.
+ for cntout = 1:SharedInfo.CurrentFunInfo.NOutArg
+ if (cntout ~= SharedInfo.CurrentFunInfo.PosFirstOutScalar & ...
+ SharedInfo.CurrentFunInfo.OutArg(cntout).Dimension == 0)
+ CCall = '';
+ CCall = CCall+'*__ptr'+SharedInfo.CurrentFunInfo.OutArg(cntout).Name+' = '+...
+ SharedInfo.CurrentFunInfo.OutArg(cntout).Name+';';
+ PrintStringInfo(' '+CCall,ReportFileName,'file','y');
+ PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y');
+ end
+ end
+ // --- Then I free the memory dinamically allocated. ---
+ // ----------------------------
+ // --- Handle Free section. ---
+ // ----------------------------
+ PrintStringInfo(C_IndentBlanks(1)+'/*',CPass1FreeFileName,'file','y');
+ PrintStringInfo(C_IndentBlanks(1)+'** ------------------------- ',CPass1FreeFileName,'file','y');
+ PrintStringInfo(C_IndentBlanks(1)+'** --- End Free Section. --- ',CPass1FreeFileName,'file','y');
+ PrintStringInfo(C_IndentBlanks(1)+'** ------------------------- ',CPass1FreeFileName,'file','y');
+ PrintStringInfo(C_IndentBlanks(1)+'*/',CPass1FreeFileName,'file','y');
+ PrintStringInfo(' ',CPass1FreeFileName,'file','y');
+ SCI2Ccopyfile(CPass1FreeFileName,...
+ CPass1FileName,'append');
+ // --------------------------------
+ // --- End Handle Free section. ---
+ // --------------------------------
+
+ // --- Then I introduce the return to the first scalar output arguments. ---
+ CCall = '';
+ // #RNU_RES_B
+ //NUT: non capisco questo skip a questo punto.
+ //NUT: perche' la return finale la sto gestendo nella AST_HandleEndProgram.
+ PrintStringInfo(' return function of the AST is skipped.',ReportFileName,'file','y');
+ //RN provo a non skippare e a mettere la return.
+ // #RNU_RES_E
+
+ if (SharedInfo.CurrentFunInfo.CFunctionName == SharedInfo.CMainFunName)
+ CCall = CCall+'return(0);';
+ elseif (mtlb_strcmp(part(SharedInfo.CurrentFunInfo.CFunctionName,1:5),'odefn') == %T)
+ //For GSL library, function containing ODEs must return GSL_SUCCESS
+ CCall = CCall + 'return GSL_SUCCESS;'
+ else
+ if (SharedInfo.CurrentFunInfo.PosFirstOutScalar > 0)
+ CCall = CCall+'return('+SharedInfo.CurrentFunInfo.OutArg(SharedInfo.CurrentFunInfo.PosFirstOutScalar).Name+');'
+ end
+ end
+ // #RNU_RES_B
+ PrintStringInfo(' '+CCall,ReportFileName,'file','y');
+ // #RNU_RES_E
+ PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y');
+else
+ // #RNU_RES_B
+ PrintStringInfo(' '+CCall,ReportFileName,'file','y');
+ // #RNU_RES_E
+ PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y');
+ if (FlagCall == 0)
+ // Add prototype to the header file
+
+ C_InitHeader(CCall+';',HeaderFileName,SharedInfo.Sci2CLibMainHeaderFName,Target,SharedInfo.OpenCVUsed);
+
+ // Add { at the beginning of the function.
+ PrintStringInfo(' {',ReportFileName,'file','y');
+ PrintStringInfo(C_IndentBlanks(IndentLevel)+'{',CPass1FileName,'file','y');
+
+ end
+end
+
+// #RNU_RES_B
+// Add in the C code the new size of the output argument when SCI2Cresize function is called.
+// #RNU_RES_E
+if (FunctionName == 'SCI2Cresize')
+ // #RNU_RES_B
+ PrintStringInfo(' Found SCI2Cresize -> Changing the size of the output argument.',ReportFileName,'file','y');
+ // #RNU_RES_E
+ OutArgName = OutArg(counterout).Name;
+ tmpcode = '__'+OutArgName+'Size[0]='+OutArg(counterout).Size(1)+';';
+ PrintStringInfo(C_IndentBlanks(IndentLevel)+tmpcode,CPass1FileName,'file','y');
+ // #RNU_RES_B
+ PrintStringInfo(' '+tmpcode,ReportFileName,'file','y');
+ // #RNU_RES_E
+ tmpcode = '__'+OutArgName+'Size[1]='+OutArg(counterout).Size(2)+';';
+ PrintStringInfo(C_IndentBlanks(IndentLevel)+tmpcode,CPass1FileName,'file','y');
+ // #RNU_RES_B
+ PrintStringInfo(' '+tmpcode,ReportFileName,'file','y');
+ // #RNU_RES_E
+end
+endfunction