PIPS
initializer.c
Go to the documentation of this file.
1 /*
2 
3  $Id: initializer.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 #include <stdio.h>
28 #include <string.h>
29 
30 #include "genC.h"
31 #include "text.h"
32 #include "constants.h"
33 
34 #include "text-util.h"
35 #include "misc.h"
36 #include "properties.h"
37 #include "linear.h"
38 #include "ri.h"
39 #include "ri-util.h"
40 #include "prettyprint.h"
41 #include "pipsdbm.h"
42 
43 #include "pips-libs.h"
44 
45 #ifdef HAVE_PIPS_c_syntax_LIBRARY
46 #include "c_syntax.h" // for compilation_unit_parser()
47 #else // ! HAVE_PIPS_c_syntax_LIBRARY
48 void compilation_unit_parser(_UNUSED_ const string s) {
49  pips_internal_error("c_syntax library not available");
50 }
51 #endif // HAVE_PIPS_c_syntax_LIBRARY
52 
53 #include "pipsmake.h"
54 #include "preprocessor.h"
55 #include "syntheses.h"
56 
57 #define FILE_WARNING \
58  "!\n" \
59  "! This module was automatically generated by PIPS and should\n" \
60  "! be updated by the user with READ and WRITE effects on\n" \
61  "! formal parameters to be useful...\n" \
62  "!\n"
63 
64 #define C_FILE_WARNING_EFFECT \
65  "//\n" \
66  "// This module was automatically generated by PIPS and should\n" \
67  "// be updated by the user with READ and WRITE effects on\n" \
68  "// formal parameters to be useful...\n" \
69  "//\n"
70 
71 #define C_FILE_WARNING \
72  "//\n" \
73  "// This module was automatically generated by PIPS\n" \
74  "//\n"
75 
76 /* Generate a string as "f42" for the number 42 for example. */
77 static string
79  string number = int2a(n);
80  string formal_name = strdup(concatenate("f", number, NULL));
81  free(number);
82  return formal_name;
83 }
84 
85 
86 /* Generate an entry for one formal parameter of a stub declaration */
87 static sentence stub_var_decl(parameter p, int n, bool is_fortran)
88 {
89  sentence result;
90  type t = parameter_type(p);
91 
92  if(type_variable_p(t)) {
93  string name = nth_formal_name(n);
94 
96  string comment =
98  "! Unable to determine the type of parameter number ", name, "\n",
100  " ", name, "\n", NULL));
101  free(name);
103  }
104  else {
109  strdup(" "), name, strdup(is_fortran? "" : ";"), NULL)));
110  }
111  }
112  else if(type_void_p(t)) {
116  strdup("void"), NULL)));
117  }
118  else if(type_varargs_p(t)) {
122  strdup("..."), NULL)));
123  }
124  else {
125  pips_internal_error("Unexpected type tag %d.", type_tag(t));
126  // prior call is no return but compiler does not know.
127  result = sentence_undefined;
128  }
129  return result;
130 }
131 
132 
133 /* Generate the head of a stub source for a missing source. */
134 static sentence stub_head(entity f, bool is_fortran)
135 {
136  list ls = NIL;
137  type t = entity_type(f);
138  functional fu;
139  int number, n;
140 
141  pips_assert("type is functional", type_functional_p(t));
142 
143  fu = type_functional(t);
145 
146  /* is it a subroutine or a function? */
148  {
149  type tf = functional_result(fu);
150  pips_assert("result is a variable", type_variable_p(tf));
151  ls = CONS(STRING, strdup(is_fortran? " FUNCTION " : " "),
152  CONS(STRING,
154  NIL));
155  }
156  else
157  ls = CONS(STRING, strdup(is_fortran? "SUBROUTINE ":"void "), NIL);
158 
159  ls = CONS(STRING, strdup(module_local_name(f)), ls);
160 
161  if(is_fortran) {
162  /* generate the formal parameter list. */
163  for(number=1; number<=n; number++)
164  ls = CONS(STRING, nth_formal_name(number),
165  CONS(STRING, strdup(number==1? "(": ", "), ls));
166 
167  /* close if necessary. */
168  if (number>1) ls = CONS(STRING, strdup(")"), ls);
169  }
170  else {
171  if(n>=1) {
173  if(type_void_p(t)) {
174  ls = CONS(STRING, strdup("(void)"), ls);
175  }
176  else {
177  // Assume C and generate the formal parameter list with their types
178  for(number=1; number<=n; number++) {
179  ls = CONS(STRING, nth_formal_name(number),
180  CONS(STRING, strdup(number==1? "(": ", "), ls));
181  }
182  /* close */
183  ls = CONS(STRING, strdup(")"), ls);
184  }
185  }
186  else
187  ls = CONS(STRING, strdup("()"), ls);
188  }
191 }
192 
193 
194 /* Generate the text for a missing module.
195  */
196 static text stub_text(entity module, bool is_fortran)
197 {
198  sentence warning, head;
199  type t = entity_type(module);
200  int n=1;
201  list /* of sentence */ ls = NIL;
202  text st = text_undefined;
203 
204  ifdebug(8) {
205  if(!is_fortran) {
206  /* FI: The result should be good because pdl wil be set to
207  NIL and the types used for the parameter will simply be
208  declared but not defined */
210  print_text(stderr, txt);
211  }
212  }
213 
214  if (type_undefined_p(t))
215  pips_user_error("undefined type for %s\n", entity_name(module));
216 
217  if (!type_functional_p(t))
218  pips_user_error("non functional type for %s\n", entity_name(module));
219 
222  if(is_fortran) {
223  head = stub_head(module, is_fortran);
224 
226  type t = parameter_type(p);
227  if(!type_void_p(t))
228  ls = CONS(SENTENCE, stub_var_decl(p, n++, is_fortran), ls);
229  }
230 
231  ls = CONS(SENTENCE,
234  CONS(STRING, strdup("END"), NIL))), ls);
235 
236  ls = CONS(SENTENCE, warning, CONS(SENTENCE, head, gen_nreverse(ls)));
237 
238  st = make_text(ls);
239  }
240  else { /* assume is_C */
241  list body=CHAIN_SWORD(NIL,"{");
242  /* SG: this just a few samples to show the possibility of the system
243  * A better idea would be to analyse arguments to guess which part of the memory could be touched. For instance, use a variable to represent the ``foreign state'' of the generated functions, and deduce from the argument type the kind of effects e can safely assume */
244  if(get_bool_property("STUB_MEMORY_BARRIER"))
246  if(get_bool_property("STUB_IO_BARRIER"))
247  body = CHAIN_SWORD(body, PIPS_IO_BARRIER_OPERATOR_NAME "();");
248  body=CHAIN_SWORD(body,"}");
251  body));
252  const char* name = entity_user_name(module);
253  type t = entity_type(module);
254  /* FI: I do not know what to use to initialize pdl usefully */
256  list pc = generic_c_words_entity(t, CHAIN_SWORD(NIL,name), false, true, &pdl);
257  gen_free_list(pdl);
258 
259  // st = c_text_entity_simple(entity_undefined, module, 0);
260  st = make_text(NIL);
262  make_unformatted(NULL, 0, 0, pc)));
263  text_sentences(st) = gen_nconc(CONS(SENTENCE, warning, NIL),
264  text_sentences(st)) ;
266  CONS(SENTENCE, bs, NIL));
267  }
268 
269  ifdebug(8) {
270  if(!is_fortran) {
271  print_text(stderr, st);
272  }
273  }
274 
275  return st;
276 }
277 
278 
279 /* Generate the text of a compilation unit for a missing C module.
280  */
282 {
283  sentence warning = sentence_undefined;
284  type t = entity_type(module);
285  text md = text_undefined;
286  list sel = NIL; // supporting entity list
287  list nsel = NIL; // supporting entity list
288  list cse = list_undefined;
289  // The text output of the compilation unit:
290  text cut = make_text(NIL);
291  //entity e = entity_undefined;
292  list pdl = NIL; // Let's hope it works; else pdl should contain
293  // each type to declare except for the module
294 
295  pips_assert("We must be in a C prettyprinter environment",
297 
298  if (type_undefined_p(t))
299  pips_user_error("undefined type for %s\n", entity_name(module));
300 
301  if (!type_functional_p(t))
302  pips_user_error("non functional type for %s\n", entity_name(module));
303 
305  ADD_SENTENCE_TO_TEXT(cut, warning);
306 
308 
309  ifdebug(8) {
310  pips_debug(8, "Redundant list of supporting entities: ");
311  print_entities(sel);
312  fprintf(stderr, "\n");
313  }
314 
315  /* Eliminate multiple occurrences. The first one must be preserved
316  to preserve the dependencies. Might be more efficient to CONS
317  and then to reverse nsel, or even better to update sel. I keep
318  the most intuitive version. */
319  for(cse = sel; !ENDP(cse); POP(cse)) {
320  entity e = ENTITY(CAR(cse));
321  if(!gen_in_list_p(e,nsel))
322  nsel = gen_nconc(nsel, CONS(ENTITY,e, NIL));
323  }
324  gen_free_list(sel);
325  sel = list_undefined;
326 
327  ifdebug(8) {
328  pips_debug(8, "List of supporting entities: ");
329  print_entities(nsel);
330  fprintf(stderr, "\n\n");
331  }
332 
333  pips_assert("Each entity appears only once", gen_once_p(nsel));
334 
335  FOREACH(ENTITY, se, nsel) {
336  const char* n = entity_user_name(se);
337 
338  /* Do not declare dummy structures, unions and enumerations,
339  which must be part of another declaration, either a typedef
340  or a name structure, union or enumeration. */
341  if((strstr(n,DUMMY_ENUM_PREFIX)==NULL) &&
342  (strstr(n,DUMMY_STRUCT_PREFIX)==NULL) &&
343  (strstr(n,DUMMY_UNION_PREFIX)==NULL)) {
344  bool init_p = false;
345  text se_text = c_text_entity(module, se, 0, &pdl, init_p);
346 
347  ifdebug(8) {
348  pips_debug(8, "Add declaration of entity \"\%s\"\n", entity_name(se));
349  print_text(stderr, se_text);
350  }
351 
352  MERGE_TEXTS(cut, se_text);
353  }
354  //free(n);
355  }
356 
357  md = c_text_entity(cu, module, 0, &pdl, false);
358  MERGE_TEXTS(cut, md);
359 
360  gen_free_list(nsel);
361  gen_free_list(pdl);
362 
363  return cut;
364 }
365 
366 void
368  /* Add the compilation unit files */
369  pips_assert("The compilation unit name is defined", !string_undefined_p(compilation_unit_name));
370  user_log("Registering synthesized compilation unit %s\n", compilation_unit_name);
372  const char* res = is_fortran? DBR_INITIAL_FILE : DBR_C_SOURCE_FILE;
373  if(entity_undefined_p(cu))
375 
376  char *dir_name = db_get_current_workspace_directory();
377 
378  char *file_name;
379  char* cu_real = strdup(compilation_unit_name);
380  cu_real[strlen(cu_real)-1]=0;
381  asprintf(&file_name,"%s" PP_C_ED ,cu_real);
382  free(cu_real);
383 
384  char * src_name;
385  asprintf(&src_name,WORKSPACE_TMP_SPACE "/%s",file_name);
386  char *full_name;
387  asprintf(&full_name,"%s/%s",dir_name,src_name);
388  free(src_name);
389 
390  char *init_name = db_build_file_resource_name(res, compilation_unit_name, is_fortran? FORTRAN_INITIAL_FILE_SUFFIX : C_FILE_SUFFIX);
391  char *finit_name;
392  asprintf(&finit_name,"%s/%s", dir_name, init_name);
393  free(dir_name);
394 
395  /* Builds the compilation unit stub: it can be empty or include
396  module_name declaration as an extern function.
397  */
399 
400  /* Put it in the source file and link the initial file.
401  */
403  FILE *f = safe_fopen(finit_name, "w");
404  print_text(f, stub);
405  safe_fclose(f, finit_name);
406  free_text(stub);
407 
408  if(!file_exists_p(full_name)) {
409  FILE *fake = safe_fopen(full_name,"a");
410  safe_fclose(fake, full_name);
411  }
414  DB_PUT_FILE_RESOURCE(DBR_INPUT_FILE_NAME, compilation_unit_name, strdup(""));
415 }
416 
417 
418 /* Add the new resource files associated to a module with its more-or-less
419  correct code.
420 
421  The idea is to prettyprint the module to some file resources and to
422  parse it later in order to have a full-fledge module with all the PIPS
423  data structures up-to-date.
424 
425  Useful for code generation, out-lining, stub generation...
426 
427  Should be checked with different module with the same name... Maybe a
428  conflict in WORKSPACE_TMP_SPACE ?
429 */
430 bool
432  text code_text,
433  bool is_fortran,
434  const char* compilation_unit_name) {
435  bool success_p = true;
437  /* relative to the current directory */
438  FILE * f;
439  const char *res = is_fortran? DBR_INITIAL_FILE : DBR_C_SOURCE_FILE;
440 
441  /* For C only: compilation unit cu and compilation unit name cun */
442  char* cun = string_undefined;
444 
445  if(entity_undefined_p(m))
446  {
448  "No entity defined for module %s although it might"
449  " have been encountered at a call site\n", module_name);
450  return false;
451  }
452 
453  /* depending on output language, build compilation unit,
454  * select prettyprinter
455  * choose out file name
456  */
457  char *file_name;
458  if(is_fortran) {
460  asprintf(&file_name,"%s" FORTRAN_FILE_SUFFIX ,module_name );
461  }
462  else {
466  }
467  else {
470  cu = MakeCompilationUnitEntity(cun);
471  }
472 
473  // Build the corresponding compilation unit for C code
474  if(string_undefined_p(cun)) {
475  char * the_cu = NULL,*iter;
476  if((iter=strchr(module_name,FILE_SEP))) {
477  the_cu = strndup(module_name,iter-module_name);
478  }
479  else the_cu = strdup(module_name);
480  asprintf(&cun, "%s" FILE_SEP_STRING, the_cu);
481  cu = MakeCompilationUnitEntity(cun);
482  free(the_cu);
483  }
484 
485  /* pips' current directory is just above the workspace
486  */
487  string cu_real = strdup(cun);
488  cu_real[strlen(cu_real)-1]=0;
489  asprintf(&file_name,"%s" PP_C_ED ,cu_real);
490  free(cu_real);
491  }
492  char *dir_name = db_get_current_workspace_directory(), *src_name;
493  asprintf(&src_name,WORKSPACE_TMP_SPACE "/%s",file_name);
494  char *full_name;
495  asprintf(&full_name,"%s/%s",dir_name,src_name);
496  char *init_name =
497  db_build_file_resource_name(res, entity_local_name(m), is_fortran? FORTRAN_INITIAL_FILE_SUFFIX : C_FILE_SUFFIX);
498  char *finit_name;
499  asprintf(&finit_name,"%s/%s" ,dir_name,init_name);
500  free(dir_name);
501 
502  /* Put the code text in the temporary source file */
504  f = safe_fopen(finit_name, "w");
505  print_text(f, code_text);
506  safe_fclose(f, finit_name);
507  /* A PIPS database may be partly incoherent after a core dump but
508  still usable (Cathare 2, FI). So delete a previously finit_name
509  file. */
512  /* The initial file is linked to the newly generated temporary file: */
513  safe_link(full_name, finit_name);
514  free(finit_name);
515 
516  /* Add the new generated file as a file resource with its local
517  * name... should only put a new user file, I guess?
518  */
519  user_log("Registering synthesized file %s\n", file_name );
520  free(file_name);
521  DB_PUT_FILE_RESOURCE(res, module_name, init_name);
522  /* The user file dwells in the WORKSPACE_TMP_SPACE */
523  DB_PUT_FILE_RESOURCE(DBR_USER_FILE, module_name, full_name);
524  if(!is_fortran) {
525  // No input file for synthesized C code
526  DB_PUT_FILE_RESOURCE(DBR_INPUT_FILE_NAME, module_name, strdup(""));
527  }
528 
529  if( !entity_undefined_p(cu) ) { // C is assumed
530  add_new_compilation_unit(cun, is_fortran, m);
531  }
532  else if(!is_fortran) {
533  if(entity_undefined_p(cu)) cu = module_name_to_entity(cun);
534  }
535 
536  if(!string_undefined_p(cun)) free(cun);
537  return success_p;
538 }
539 
540 
541 /* Add the new resource files associated to a module with its more-or-less
542  correct code.
543 
544  The idea is to prettyprint the module to some file resources and to
545  parse it later in order to have a full-fledge module with all the PIPS
546  structured up-to-date.
547 
548  Useful for code generation, out-lining...
549 
550  There is still some redundancy with module_name, module and stat
551 */
552 bool
554  entity module,
555  statement stat,
556  bool is_fortran/*,
557  text heading*/) {
558  /* Get a text code for the new module */
559  text code_text = text_module(module, stat);
561  code_text,
562  is_fortran,
564  free_text(code_text);
565 
566  return ret;
567 }
568 
569 
570 /* Generate a source file for a module, if none available.
571  */
572 static bool missing_file_initializer(const char* module_name, bool is_fortran)
573 {
575  text stub = text_undefined;
576 
577  pips_user_warning("no source file for %s: synthetic code is generated\n",
578  module_name);
579 
580  if(entity_undefined_p(m)) {
581  pips_user_error("No occurence of function \"%s\" has been encountered. "
582  "Code synthesis is not possible\n", module_name);
583  }
584 
585  /* Builds a stub code text for the missing module */
586  if(is_fortran) {
588  } else {
590  }
591 
592  stub = stub_text(m, is_fortran);
594  stub,
595  is_fortran,
597  free_text(stub);
598  return ret;
599 }
600 
601 
602 /*
603  *
604  */
605 static bool module_in_user_file_p(const char* module, bool is_fortran) {
606  string res= is_fortran? DBR_INITIAL_FILE : DBR_C_SOURCE_FILE;
607  return db_resource_p(res, module);
608 }
609 
610 
611 static string (* internal_resolver)(const char *) = 0;
612 void set_internal_missing_module_resolver_handler(string(* _internal_resolver)(const char *)) {
613  internal_resolver = _internal_resolver;
614 }
615 
616 /*
617  */
619  bool is_fortran) {
620  bool module_found = false;
621 
622  // Sanity check
623  if(!internal_resolver) {
624  pips_user_error("An internal resolver has to be defined !\n");
625  return false;
626  }
627 
628  string file = (* internal_resolver)(module);
629  if(!file || *file=='\0') {
630  // No file found by the resolver for this module
631  pips_user_error("The resolver couldn't find a source file for module '%s'"
632  ", did you forgot a source file ? For external library you have to"
633  " provide a stub file.\n",module);
634  } else {
635  // We got a correct answer from the resolver, let's use it !
636  if(!process_user_file(file)) {
637  pips_user_error("We didn't manage to process file "
638  "given by the resolver : %s\n",
639  file);
640  } else {
641  // Check that the module was found in the given file as expected
642  module_found = module_in_user_file_p(module, is_fortran);
643  }
644  }
645 
646  return module_found;
647 }
648 /*
649 */
651  bool is_fortran) {
652  bool module_found = false;
653 
654  // User gave the resolver command in a property
655  const char* missing_file_generator =
656  get_string_property("PREPROCESSOR_MISSING_FILE_GENERATOR");
657 
658  // Full generator cmdline : append requested module name
659  string generator_cmd = NULL;
660  if(!empty_string_p(missing_file_generator)) {
661  asprintf(&generator_cmd, "%s %s", missing_file_generator, module);
662  }
663 
664  // Call resolver !
665  FILE* pout = popen(generator_cmd, "r");
666  if(!pout) {
667  pips_user_error("Failed to launch command %s\n",missing_file_generator);
668  } else {
669  // Read output from resolver
670  string file = strdup("");
671  char buffer[256];
672  while(fgets(&buffer[0], sizeof(buffer), pout)) {
673  char * tmp = file;
674  if(asprintf(&file, "%s%s", tmp, buffer)==-1) {
675  pips_internal_error("asprintf returned -1 !");
676  return false; // never reached
677  }
678  free(tmp);
679  }
680  *strchrnul(file, '\n') = 0;
681  int ret = pclose(pout);
682  if(ret != 0) {
683  // oh oh... we got an error...
684  pips_user_error("Command %s returned an error(%d)\n",generator_cmd,ret);
685  return false;
686  }
687 
688  if(!file || *file=='\0') {
689  // No file found by the resolver for this module
690  pips_user_error("The resolver couldn't find a source file for module '%s'"
691  ", did you forgot a source file ? For external library you have to"
692  " provide a stub file.\n",module);
693  return false;
694  }
695  // We got a correct answer from the resolver, let's use it !
696  if(!process_user_file(file)) {
697  pips_user_error("We didn't manage to process file "
698  "given by the resolver : %s\n",
699  file);
700  }
701 
702  // Check that the module was found in the given file as expected
703  module_found = module_in_user_file_p(module, is_fortran);
704  free(file);
705  free(generator_cmd);
706  }
707 
708  return module_found;
709 }
710 
711 
712 
713 
714 /* Generate a new module by asking some files to the user. Can also
715  generate a stub if replied as so by the user. */
716 static bool ask_a_missing_file(const char* module, bool is_fortran) {
717  string file = 0;
718  bool request_the_module = true;
719  bool module_found = false;
720 
721  /* Loop until we get the module, or the user abort (quit) */
722  while(request_the_module) {
723  file = user_request("Please enter a file for module %s\n or \"quit\" "
724  "to abort or \"generate\" to generate a stub\n", module);
725 
726  if(!file) {
727  pips_internal_error("user_request should never return NULL !\n");
728  }
729 
730  // We are optimistic and bet that we won't loop !
731  request_the_module = false;
732 
733  if(same_string_p(file, "generate")) {
734  // user requested to generate an empty stub
735  bool check = missing_file_initializer(module,is_fortran);
736  if(!check) {
737  pips_user_warning("Module \"%s\" wasn't generated :-(\n",module);
738  // Loop over and ask again the user what to do
739  request_the_module = true;
740  } else {
741  module_found = true;
742  }
743  } else if(!same_string_p(file, "quit")) {
744  // We got a file name ! Try to process it and get the missing module
745  bool check = process_user_file(file);
746 
747  if(!check) {
748  pips_user_warning("Error while processing file %s\n",file);
749  // Loop over and ask again the user what to do
750  request_the_module = true;
751  }
752  // Check that the module was found in the file
753  if(!module_in_user_file_p(module, is_fortran)) {
754  pips_user_warning("Module \"%s\" not found in \"%s\".\n"
755  "Please type \"quit\" or another file name.\n",
756  module, file);
757  // Loop over and ask again the user what to do
758  request_the_module = true;
759  } else {
760  module_found = true;
761  }
762  }
763  }
764 
765  // Cleaning if necessary
766  if(file)
767  free(file);
768 
769  return module_found;
770 }
771 
772 
773 /* There is no real rule to produce source or user files when there is no
774  * corresponding file; so the initializer was introduced by Remi Triolet
775  * to deal with source and user files as with any other kind of resources.
776  *
777  * According to the PREPROCESSOR_MISSING_FILE_HANDLING property :
778  * - an empty stub definition for the module can be automatically generated,
779  * - a list of file names can be asked to the user
780  * - an external command can be run to retrieve the file containing the module
781  * - an internal command can be run instead, it has to be registered first
782  */
783 static bool generic_initializer(const char* module_name, bool is_fortran)
784 {
785  bool success_p = false;
786  const char* missing = get_string_property("PREPROCESSOR_MISSING_FILE_HANDLING");
787 
788  if(same_string_p(missing, "error")) {
789  pips_user_error("no source file for %s (might be an ENTRY point)\n"
790  "set PREPROCESSOR_MISSING_FILE_HANDLING"
791  " to \"query\" or \"generate\"...\n", module_name);
792  } else if(same_string_p(missing, "generate")) {
793  success_p = missing_file_initializer(module_name, is_fortran);
794  } else if(same_string_p(missing, "query")) {
795  success_p = ask_a_missing_file(module_name, is_fortran);
796  } else if(same_string_p(missing, "internal_resolver")) {
798  is_fortran);
799  } else if(same_string_p(missing, "external_resolver")) {
801  is_fortran);
802  } else {
803  pips_user_error("invalid value of property "
804  "PREPROCESSOR_MISSING_FILE_HANDLING = \"%s\"",
805  missing);
806  }
807 
808 
809  if(success_p && !is_fortran) {
810  // Force building of compilation unit declarations
811  // Not really pipsmake friendly but no choice here ... :-(
813  }
814 
815 
816  if(success_p && get_bool_property("PREPROCESSOR_INITIALIZER_FLAG_AS_STUB")) {
817  bool flag_as_stub(string);
818  if (!db_resource_p(DBR_STUBS, "")) {
819  bool bootstrap_stubs(string);
820  bootstrap_stubs((string)module_name);
821  }
822  flag_as_stub((string)module_name);
823  }
824 
825  return success_p;
826 }
827 
828 
829 /* Create a module with its related file resources when there is no
830  Fortran source for it. */
832 {
833  return generic_initializer(module_name, true);
834 }
835 
836 
837 /* A phase that creates a module with its related file resources when
838  there is no Fortran source for it. */
839 bool initializer(const string module_name)
840 {
841  bool res = false;
842 
843  debug_on("INITIALIZER_DEBUG_LEVEL");
844  res = generic_initializer(module_name, true);
845  debug_off();
846 
847  return res;
848 }
849 
850 
851 /* A phase that creates a module with its related file resources when
852  there is no C source for it. */
853 bool c_initializer(const string module_name)
854 {
855  bool res = false;
856 
857  debug_on("INITIALIZER_DEBUG_LEVEL");
858  res = generic_initializer(module_name, false);
859  debug_off();
860 
861  return res;
862 }
863 
864 
void user_log(const char *format,...)
Definition: message.c:234
unformatted make_unformatted(string a1, intptr_t a2, intptr_t a3, list a4)
Definition: text.c:149
sentence make_sentence(enum sentence_utype tag, void *val)
Definition: text.c:59
text make_text(list a)
Definition: text.c:107
void free_text(text p)
Definition: text.c:74
bool db_resource_p(const char *rname, const char *oname)
true if exists and in loaded or stored state.
Definition: database.c:524
string compilation_unit_name
cproto-generated files
Definition: c_parser.c:49
string compilation_unit_of_module(const char *)
The output is undefined if the module is referenced but not defined in the workspace,...
Definition: module.c:350
#define ret(why, what)
true if not a remapping for old.
Definition: dynamic.c:986
bool empty_string_p(const char *s)
Definition: entity_names.c:239
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
bool file_exists_p(const char *name)
Definition: file.c:321
char * get_string_property(const char *)
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
void safe_link(const char *topath, const char *frompath)
Create a hard link to topath.
Definition: file.c:878
void safe_unlink(const char *file_name)
Delete the given file.
Definition: file.c:852
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
static void comment(string_buffer code, spoc_hardware_type hw, dagvtx v, int stage, int side, bool flip)
Definition: freia_spoc.c:52
@ string_domain
Definition: genC.h:170
#define STRING(x)
Definition: genC.h:87
void free(void *)
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_make_list(int domain,...)
Definition: list.c:851
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
bool gen_once_p(list l)
FC: ARGH...O(n^2)!
Definition: list.c:758
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define DB_PUT_FILE_RESOURCE
Put a file resource into the current workspace database.
Definition: pipsdbm-local.h:85
#define full_name(dir, name)
Definition: compile.c:414
bool fortran_initializer(const string module_name)
Create a module with its related file resources when there is no Fortran source for it.
Definition: initializer.c:831
static bool retrieve_a_missing_file_using_internal_resolver(const char *module, bool is_fortran)
Definition: initializer.c:618
static sentence stub_head(entity f, bool is_fortran)
Generate the head of a stub source for a missing source.
Definition: initializer.c:134
static bool missing_file_initializer(const char *module_name, bool is_fortran)
Generate a source file for a module, if none available.
Definition: initializer.c:572
static text compilation_unit_text(entity cu, entity module)
Generate the text of a compilation unit for a missing C module.
Definition: initializer.c:281
void set_internal_missing_module_resolver_handler(string(*_internal_resolver)(const char *))
Definition: initializer.c:612
static sentence stub_var_decl(parameter p, int n, bool is_fortran)
Generate an entry for one formal parameter of a stub declaration.
Definition: initializer.c:87
static bool module_in_user_file_p(const char *module, bool is_fortran)
Definition: initializer.c:605
#define C_FILE_WARNING
Definition: initializer.c:71
bool initializer(const string module_name)
A phase that creates a module with its related file resources when there is no Fortran source for it.
Definition: initializer.c:839
static string nth_formal_name(int n)
Generate a string as "f42" for the number 42 for example.
Definition: initializer.c:78
static bool retrieve_a_missing_file_using_external_resolver(const char *module, bool is_fortran)
Definition: initializer.c:650
static text stub_text(entity module, bool is_fortran)
Generate the text for a missing module.
Definition: initializer.c:196
static bool generic_initializer(const char *module_name, bool is_fortran)
There is no real rule to produce source or user files when there is no corresponding file; so the ini...
Definition: initializer.c:783
bool add_new_module(const char *module_name, entity module, statement stat, bool is_fortran)
Add the new resource files associated to a module with its more-or-less correct code.
Definition: initializer.c:553
void compilation_unit_parser(_UNUSED_ const string s)
Definition: initializer.c:48
void add_new_compilation_unit(const char *compilation_unit_name, bool is_fortran, entity module)
Warning! Do not modify this file that is automatically generated!
Definition: initializer.c:367
#define C_FILE_WARNING_EFFECT
Definition: initializer.c:64
bool add_new_module_from_text(const char *module_name, text code_text, bool is_fortran, const char *compilation_unit_name)
Add the new resource files associated to a module with its more-or-less correct code.
Definition: initializer.c:431
static string(* internal_resolver)(const char *)=0
Definition: initializer.c:611
bool c_initializer(const string module_name)
A phase that creates a module with its related file resources when there is no C source for it.
Definition: initializer.c:853
static bool ask_a_missing_file(const char *module, bool is_fortran)
Generate a new module by asking some files to the user.
Definition: initializer.c:716
#define FILE_WARNING
Definition: initializer.c:57
bool prettyprint_language_is_c_p()
Definition: language.c:91
void set_prettyprint_language_tag(enum language_utype lang)
set the prettyprint language from a language_utype argument
Definition: language.c:143
string db_build_file_resource_name(const char *rname, const char *oname, const char *suffix)
returns an allocated file name for a file resource.
Definition: lowlevel.c:169
#define debug_on(env)
Definition: misc-local.h:157
#define _UNUSED_
Definition: misc-local.h:232
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define asprintf
Definition: misc-local.h:225
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
#define pips_user_error
Definition: misc-local.h:147
string user_request(const char *,...)
#define DUMMY_STRUCT_PREFIX
Definition: naming-local.h:87
#define FILE_SEP_STRING
Definition: naming-local.h:41
#define DUMMY_ENUM_PREFIX
For enum and struct and union without names (see c_syntax/cyacc.y)
Definition: naming-local.h:86
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
#define FILE_SEP
Definition: naming-local.h:39
#define DUMMY_UNION_PREFIX
Definition: naming-local.h:88
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
#define string_undefined
Definition: newgen_types.h:40
char * string
STRING.
Definition: newgen_types.h:39
#define string_undefined_p(s)
Definition: newgen_types.h:41
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static char * module
Definition: pips.c:74
#define WORKSPACE_TMP_SPACE
Definition: pipsdbm-local.h:31
#define db_make_subdirectory(n)
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
bool flag_as_stub(const string)
Definition: source_file.c:1334
bool bootstrap_stubs(const string)
Definition: source_file.c:1344
bool process_user_file(string)
Definition: source_file.c:1090
list generic_c_words_entity(type t, list name, bool is_safe, bool add_dummy_parameter_name_p, list *ppdl)
This recursive function prints a C variable with its type.
Definition: declarations.c:980
text c_text_entity(entity module, entity e, int margin, list *ppdl, bool init_p)
Regeneration of declarations from the symbol table.
text c_text_entity_simple(entity module, entity e, int margin)
text text_module(entity, statement)
string basic_to_string(basic)
Definition: type.c:87
#define PIPS_IO_BARRIER_OPERATOR_NAME
#define PIPS_MEMORY_BARRIER_OPERATOR_NAME
special pips intrinsics with global effects
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
void print_entities(list l)
Definition: entity.c:167
entity MakeCompilationUnitEntity(const char *name)
This is useful for the C language only.
Definition: entity.c:1954
list functional_type_supporting_entities(list, functional)
Definition: type.c:4014
list type_supporting_entities(list, type)
Definition: type.c:4347
#define type_functional_p(x)
Definition: ri.h:2950
#define functional_result(x)
Definition: ri.h:1444
#define parameter_type(x)
Definition: ri.h:1819
#define type_tag(x)
Definition: ri.h:2940
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define type_functional(x)
Definition: ri.h:2952
#define type_variable(x)
Definition: ri.h:2949
#define basic_overloaded_p(x)
Definition: ri.h:623
#define type_undefined_p(x)
Definition: ri.h:2884
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#define type_void_p(x)
Definition: ri.h:2959
#define entity_name(x)
Definition: ri.h:2790
#define functional_parameters(x)
Definition: ri.h:1442
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define type_varargs_p(x)
Definition: ri.h:2953
#define entity_type(x)
Definition: ri.h:2792
#define type_variable_p(x)
Definition: ri.h:2947
@ is_language_fortran
Definition: ri.h:1566
@ is_language_c
Definition: ri.h:1567
#define variable_basic(x)
Definition: ri.h:3120
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
char * strchrnul(const char *s, int c_in)
Searching in a string.
Definition: strchrnul.c:24
static string buffer
Definition: string.c:113
char * strndup(char const *s, size_t n)
A replacement function, for systems that lack strndup.
Definition: strndup.c:26
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define CHAIN_SWORD(l, s)
#define MERGE_TEXTS(r, t)
#define ADD_SENTENCE_TO_TEXT(t, p)
void print_text(FILE *fd, text t)
Definition: print.c:195
char * int2a(int)
util.c
Definition: util.c:42
#define sentence_undefined
Definition: text.h:42
#define SENTENCE(x)
newgen_unformatted_domain_defined
Definition: text.h:36
#define text_undefined
Definition: text.h:91
#define text_sentences(x)
Definition: text.h:113
@ is_sentence_formatted
Definition: text.h:57
@ is_sentence_unformatted
Definition: text.h:58
static string file_name