SubLoopCreation.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /******************************************************************************/
  2. /* */
  3. /* CONV (converter) for Agrif (Adaptive Grid Refinement In Fortran) */
  4. /* */
  5. /* Copyright or or Copr. Laurent Debreu (Laurent.Debreu@imag.fr) */
  6. /* Cyril Mazauric (Cyril_Mazauric@yahoo.fr) */
  7. /* This software is governed by the CeCILL-C license under French law and */
  8. /* abiding by the rules of distribution of free software. You can use, */
  9. /* modify and/ or redistribute the software under the terms of the CeCILL-C */
  10. /* license as circulated by CEA, CNRS and INRIA at the following URL */
  11. /* "http://www.cecill.info". */
  12. /* */
  13. /* As a counterpart to the access to the source code and rights to copy, */
  14. /* modify and redistribute granted by the license, users are provided only */
  15. /* with a limited warranty and the software's author, the holder of the */
  16. /* economic rights, and the successive licensors have only limited */
  17. /* liability. */
  18. /* */
  19. /* In this respect, the user's attention is drawn to the risks associated */
  20. /* with loading, using, modifying and/or developing or reproducing the */
  21. /* software by the user in light of its specific status of free software, */
  22. /* that may mean that it is complicated to manipulate, and that also */
  23. /* therefore means that it is reserved for developers and experienced */
  24. /* professionals having in-depth computer knowledge. Users are therefore */
  25. /* encouraged to load and test the software's suitability as regards their */
  26. /* requirements in conditions enabling the security of their systems and/or */
  27. /* data to be ensured and, more generally, to use and operate it in the */
  28. /* same conditions as regards security. */
  29. /* */
  30. /* The fact that you are presently reading this means that you have had */
  31. /* knowledge of the CeCILL-C license and that you accept its terms. */
  32. /******************************************************************************/
  33. /* version 1.7 */
  34. /******************************************************************************/
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include "decl.h"
  39. /******************************************************************************/
  40. /* preparation and write of the argument list of a subroutine */
  41. /******************************************************************************/
  42. /******************************************************************************/
  43. /* WriteBeginof_SubLoop */
  44. /******************************************************************************/
  45. /* We should write the head of the subroutine sub_loop_<subroutinename> */
  46. /******************************************************************************/
  47. /* */
  48. /******************************************************************************/
  49. void WriteBeginof_SubLoop()
  50. {
  51. if (todebug == 1) printf("##\n## Enter in HEAD SUBLOOP for |%s|\n##\n", subroutinename);
  52. if ( IsTabvarsUseInArgument_0() == 1 )
  53. {
  54. if ( todebug == 1 ) printf("> enter in WriteBeginof_SubLoop : IsTabvarsUseInArgument_0() == 1\n");
  55. /* we should add the use agrif_uti l if it is necessary */
  56. WriteHeadofSubroutineLoop();
  57. WriteUsemoduleDeclaration(subroutinename);
  58. if ( ImplicitNoneInSubroutine() == 1 ) fprintf(fortran_out, " implicit none\n");
  59. WriteIncludeDeclaration(fortran_out);
  60. /* */
  61. /* We should write once the declaration of tables (extract */
  62. /* from pointer) in the new subroutine */
  63. if ( SubInList_ContainsSubroutine() == 0 ) WriteLocalParamDeclaration(fortran_out);
  64. writesub_loopdeclaration_scalar(List_UsedInSubroutine_Var,fortran_out);
  65. writesub_loopdeclaration_tab(List_UsedInSubroutine_Var,fortran_out);
  66. WriteArgumentDeclaration_Sort(fortran_out);
  67. WriteFunctionDeclaration(fortran_out, 1);
  68. }
  69. else
  70. {
  71. if ( todebug == 1 ) printf("> enter in WriteBeginof_SubLoop : IsTabvarsUseInArgument_0() == 0\n");
  72. AddUseAgrifUtil_0(fortran_out);
  73. WriteUsemoduleDeclaration(subroutinename);
  74. WriteIncludeDeclaration(fortran_out);
  75. if ( ImplicitNoneInSubroutine() == 1 ) fprintf(fortran_out, " implicit none\n");
  76. WriteLocalParamDeclaration(fortran_out);
  77. WriteArgumentDeclaration_beforecall();
  78. if ( functiondeclarationisdone == 0 ) WriteFunctionDeclaration(fortran_out, 1);
  79. /* writesub_loopdeclaration_scalar(List_SubroutineArgument_Var,fortran_out);
  80. writesub_loopdeclaration_tab(List_SubroutineArgument_Var,fortran_out);*/
  81. }
  82. if ( todebug == 1 ) printf("< out of WriteBeginof_SubLoop\n");
  83. if ( todebug == 1 ) printf("## EXIT HEAD SUBLOOP (%s)\n\n", subroutinename);
  84. }
  85. /******************************************************************************/
  86. /* WriteVariablelist_subloop */
  87. /******************************************************************************/
  88. /* This subroutine is used to write the list of the variable which */
  89. /* should be called by the sub_loop_<name> subroutine */
  90. /* The first part is composed by the list of the local variables */
  91. /******************************************************************************/
  92. /* */
  93. /* List_SubroutineDeclaration_Var a,b,c, & */
  94. /* d,e,f, & */
  95. /* a,b,c,d,e,f,g,h ========> g,h */
  96. /* */
  97. /******************************************************************************/
  98. void WriteVariablelist_subloop(char *ligne)
  99. {
  100. listvar *parcours;
  101. if ( todebug == 1 ) printf("> enter in WriteVariablelist_subloop\n");
  102. parcours = List_SubroutineArgument_Var;
  103. didvariableadded = 0;
  104. while ( parcours )
  105. {
  106. /* if the readed variable is a variable of the subroutine */
  107. /* subroutinename we should write the name of this variable */
  108. /* in the output file */
  109. if ( !strcasecmp(parcours->var->v_subroutinename,subroutinename) )
  110. {
  111. if ( didvariableadded == 1 ) strcat(ligne,",");
  112. strcat(ligne,parcours->var->v_nomvar);
  113. didvariableadded = 1;
  114. }
  115. parcours = parcours -> suiv;
  116. }
  117. parcours = List_FunctionType_Var;
  118. while ( parcours )
  119. {
  120. if ( !strcasecmp(parcours->var->v_subroutinename,subroutinename) )
  121. {
  122. if ( didvariableadded == 1 ) strcat(ligne,",");
  123. strcat(ligne,parcours->var->v_nomvar);
  124. didvariableadded = 1;
  125. }
  126. parcours = parcours -> suiv;
  127. }
  128. if ( todebug == 1 ) printf("< out of WriteVariablelist_subloop\n");
  129. }
  130. /******************************************************************************/
  131. /* WriteVariablelist_subloop_Call */
  132. /******************************************************************************/
  133. /* This subroutine is used to write the list of the variable which */
  134. /* should be called by the sub_loop_<name> subroutine into the called */
  135. /* The second part is composed by the list of the global table */
  136. /******************************************************************************/
  137. /* */
  138. /* List_UsedInSubroutine_Var SubloopScalar = 0 | SubloopScalar = 1 */
  139. /* a,b,c, & | a,b(1,1),c, & */
  140. /* a,b,c,d,e,f,g,h =====> d,e,f, & | d(1),e(1,1,1),f, & */
  141. /* g,h | g,h(1,1) */
  142. /* */
  143. /******************************************************************************/
  144. void WriteVariablelist_subloop_Call(char **ligne, size_t line_length)
  145. {
  146. listvar *parcours;
  147. char ligne2[LONG_M];
  148. int i;
  149. size_t cur_length;
  150. cur_length = line_length;
  151. if ( todebug == 1 ) printf("> enter in WriteVariablelist_subloop_Call\n");
  152. parcours = List_UsedInSubroutine_Var;
  153. while ( parcours )
  154. {
  155. /* if the readed variable is a variable of the subroutine */
  156. /* subroutinename we should write the name of this variable */
  157. /* in the output file */
  158. if ( !strcasecmp(parcours->var->v_subroutinename,subroutinename) &&
  159. (parcours->var->v_pointerdeclare == 0 || !strcasecmp(parcours->var->v_typevar,"type"))
  160. )
  161. {
  162. if ( didvariableadded == 1 ) strcat(*ligne,",");
  163. const char *vres = vargridcurgridtabvars(parcours->var, 0);
  164. if ( (strlen(*ligne)+strlen(vres)+100) > cur_length )
  165. {
  166. cur_length += LONG_M;
  167. *ligne = realloc( *ligne, cur_length*sizeof(char) );
  168. }
  169. strcat(*ligne, vres);
  170. /* if it is asked in the call of the conv we should give */
  171. /* scalar in argument, so we should put (1,1,1) after the */
  172. /* the name of the variable */
  173. if ( SubloopScalar != 0 &&
  174. (
  175. (parcours->var->v_pointerdeclare == 0 || !strcasecmp(parcours->var->v_typevar,"type"))) &&
  176. parcours->var->v_nbdim != 0 )
  177. {
  178. i = 1;
  179. while ( i <= parcours->var->v_nbdim )
  180. {
  181. if ( i == 1 ) strcat(*ligne,"( ");
  182. if ( SubloopScalar == 2 )
  183. {
  184. strcat(*ligne,":");
  185. if ( i != parcours->var->v_nbdim ) strcat(*ligne,",");
  186. }
  187. else
  188. {
  189. sprintf(ligne2,"lbound(%s,%d",vargridcurgridtabvars(parcours->var,0),i);
  190. strcat(*ligne,ligne2);
  191. if ( i != parcours->var->v_nbdim ) strcat(*ligne,"),");
  192. }
  193. if ( i == parcours->var->v_nbdim ) strcat(*ligne,"))");
  194. i++;
  195. }
  196. }
  197. didvariableadded = 1;
  198. }
  199. parcours = parcours -> suiv;
  200. }
  201. if ( todebug == 1 ) printf("< out of WriteVariablelist_subloop_Call\n");
  202. }
  203. /******************************************************************************/
  204. /* WriteVariablelist_subloop_Def */
  205. /******************************************************************************/
  206. /* This subroutine is used to write the list of the variable which */
  207. /* should be called by the sub_loop_<name> subroutine into the def */
  208. /* The second part is composed by the list of the global table */
  209. /* <name>_tmp */
  210. /******************************************************************************/
  211. /* */
  212. /* List_UsedInSubroutine_Var */
  213. /* a-tmp,b-tmp,c_tmp, & */
  214. /* a,b,c,d,e,f,g,h =====> d_tmp,e_tmp,f_tmp, & */
  215. /* g_tmp,h_tmp */
  216. /* */
  217. /******************************************************************************/
  218. void WriteVariablelist_subloop_Def(char *ligne)
  219. {
  220. listvar *parcours;
  221. if ( todebug == 1 ) printf("> enter in WriteVariablelist_subloop_Def\n");
  222. parcours = List_UsedInSubroutine_Var;
  223. while ( parcours )
  224. {
  225. /* if the readed variable is a variable of the subroutine */
  226. /* subrotinename we should write the name of this variable */
  227. /* in the output file */
  228. if ( !strcasecmp(parcours->var->v_subroutinename,subroutinename) &&
  229. (parcours->var->v_pointerdeclare == 0 || !strcasecmp(parcours->var->v_typevar,"type")) )
  230. {
  231. if ( didvariableadded == 1 ) strcat(ligne,",");
  232. strcat(ligne,parcours->var->v_nomvar);
  233. didvariableadded = 1;
  234. }
  235. parcours = parcours -> suiv;
  236. }
  237. Save_Length(ligne,41);
  238. if ( todebug == 1 ) printf("< out of WriteVariablelist_subloop_Def\n");
  239. }
  240. /******************************************************************************/
  241. /* WriteHeadofSubroutineLoop */
  242. /******************************************************************************/
  243. /* This subroutine is used to write the head of the subroutine */
  244. /* Sub_Loop_<name> */
  245. /******************************************************************************/
  246. /* Sub_loop_subroutine.h */
  247. /* */
  248. /* subroutine Sub_Loop_subroutine ( & */
  249. /* a,b,c, & */
  250. /* SubLoopScalar d,e(1,1),f(1,1,1), & */
  251. /* g,h & */
  252. /* ) */
  253. /******************************************************************************/
  254. void WriteHeadofSubroutineLoop()
  255. {
  256. char ligne[LONG_M];
  257. FILE * subloop;
  258. if ( todebug == 1 ) printf("> enter in WriteHeadofSubroutineLoop\n");
  259. tofich(fortran_out,"\n",1);
  260. /* Open this newfile */
  261. sprintf(ligne,"Sub_Loop_%s.h",subroutinename);
  262. subloop = open_for_write(ligne);
  263. /* */
  264. if (isrecursive) sprintf(ligne,"recursive subroutine Sub_Loop_%s(",subroutinename);
  265. else sprintf(ligne,"subroutine Sub_Loop_%s(",subroutinename);
  266. /* */
  267. WriteVariablelist_subloop(ligne);
  268. WriteVariablelist_subloop_Def(ligne);
  269. /* */
  270. strcat(ligne,")");
  271. tofich(subloop,ligne,1);
  272. /* if USE agrif_Uti l should be add */
  273. AddUseAgrifUtil_0(subloop);
  274. /* */
  275. oldfortran_out = fortran_out;
  276. fortran_out = subloop;
  277. if ( todebug == 1 ) printf("< out of WriteHeadofSubroutineLoop\n");
  278. }
  279. /******************************************************************************/
  280. /* closeandcallsubloopandincludeit_0 */
  281. /******************************************************************************/
  282. /* Firstpass 0 */
  283. /* We should close the sub_loop subroutine, call it and close the */
  284. /* function (suborfun = 0) */
  285. /* subroutine (suborfun = 1) */
  286. /* end (suborfun = 2) */
  287. /* end program (suborfun = 3) */
  288. /* and include the sub_loop subroutine after */
  289. /******************************************************************************/
  290. /* */
  291. /******************************************************************************/
  292. void closeandcallsubloopandincludeit_0(int suborfun)
  293. {
  294. char *ligne;
  295. if ( firstpass == 1 ) return;
  296. if ( todebug == 1 ) printf("> enter in closeandcallsubloopandincludeit_0\n");
  297. ligne = (char*) calloc(LONG_M, sizeof(char));
  298. if ( IsTabvarsUseInArgument_0() == 1 )
  299. {
  300. /* We should remove the key word end subroutine */
  301. RemoveWordCUR_0(fortran_out,setposcur()-pos_endsubroutine);
  302. /* We should close the loop subroutine */
  303. tofich(fortran_out,"\n",1);
  304. sprintf(ligne,"end subroutine Sub_Loop_%s\n",subroutinename);
  305. tofich(fortran_out,ligne,1);
  306. fclose(fortran_out);
  307. fortran_out = oldfortran_out;
  308. AddUseAgrifUtilBeforeCall_0(fortran_out);
  309. WriteArgumentDeclaration_beforecall();
  310. if ( functiondeclarationisdone == 0 ) WriteFunctionDeclaration(fortran_out, 0);
  311. if ( !strcasecmp(subofagrifinitgrids,subroutinename) )
  312. fprintf(fortran_out," call Agrif_Init_Grids()\n");
  313. /* Now we add the call af the new subroutine */
  314. tofich(fortran_out,"\n",1);
  315. sprintf(ligne," call Sub_Loop_%s(",subroutinename);
  316. /* Write the list of the local variables used in this new subroutine */
  317. WriteVariablelist_subloop(ligne);
  318. /* Write the list of the global tables used in this new subroutine */
  319. /* in doloop */
  320. WriteVariablelist_subloop_Call(&ligne, LONG_M);
  321. /* Close the parenthesis of the new subroutine called */
  322. strcat(ligne,")\n");
  323. tofich(fortran_out,ligne,1);
  324. /* we should include the above file in the original code */
  325. /* We should close the original subroutine */
  326. if ( suborfun == 3 ) fprintf(fortran_out, " end program %s\n" , subroutinename);
  327. if ( suborfun == 2 ) fprintf(fortran_out, " end\n");
  328. if ( suborfun == 1 ) fprintf(fortran_out, " end subroutine %s\n", subroutinename);
  329. if ( suborfun == 0 ) fprintf(fortran_out, " end function %s\n" , subroutinename);
  330. fprintf(fortran_out,"\n\n#include \"Sub_Loop_%s.h\"\n",subroutinename);
  331. }
  332. oldfortran_out = (FILE *)NULL;
  333. if ( todebug == 1 ) printf("< out of closeandcallsubloopandincludeit_0\n");
  334. }
  335. void closeandcallsubloop_contains_0()
  336. {
  337. char *ligne;
  338. if ( todebug == 1 ) printf("> enter in closeandcallsubloop_contains_0\n");
  339. if ( IsTabvarsUseInArgument_0() == 1 )
  340. {
  341. ligne = (char*) calloc(LONG_M, sizeof(char));
  342. RemoveWordCUR_0(fortran_out,9); // Remove word 'contains'
  343. tofich(fortran_out,"\n",1);
  344. sprintf(ligne,"end subroutine Sub_Loop_%s\n",subroutinename);
  345. tofich(fortran_out,ligne,1);
  346. fclose(fortran_out);
  347. fortran_out = oldfortran_out;
  348. AddUseAgrifUtilBeforeCall_0(fortran_out);
  349. if ( ImplicitNoneInSubroutine() == 1 ) fprintf(fortran_out, " implicit none\n");
  350. WriteLocalParamDeclaration(fortran_out);
  351. WriteArgumentDeclaration_beforecall();
  352. if ( functiondeclarationisdone == 0 ) WriteFunctionDeclaration(fortran_out, 0);
  353. /* WriteSubroutineDeclaration(0);*/
  354. if ( !strcasecmp(subofagrifinitgrids,subroutinename) )
  355. fprintf(fortran_out," call Agrif_Init_Grids()\n");
  356. /* Now we add the call af the new subroutine */
  357. tofich(fortran_out,"\n",1);
  358. sprintf(ligne," call Sub_Loop_%s(",subroutinename);
  359. /* Write the list of the local variables used in this new subroutine */
  360. WriteVariablelist_subloop(ligne);
  361. /* Write the list of the global tables used in this new subroutine */
  362. /* in doloop */
  363. WriteVariablelist_subloop_Call(&ligne, LONG_M);
  364. /* Close the parenthesis of the new subroutine called */
  365. strcat(ligne,")\n");
  366. tofich(fortran_out,ligne,1);
  367. /* We should close the original subroutine */
  368. fprintf(fortran_out, " contains\n");
  369. /* we should include the above file in the original code */
  370. fprintf(fortran_out,"#include \"Sub_Loop_%s.h\"\n",subroutinename);
  371. }
  372. oldfortran_out = (FILE *)NULL;
  373. if ( todebug == 1 ) printf("< out of closeandcallsubloop_contains_0\n");
  374. }