PIPS
source_file.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "database.h"
#include "misc.h"
#include "properties.h"
#include "ri-util.h"
#include "pipsdbm.h"
#include "constants.h"
#include "resources.h"
#include "phases.h"
#include "property.h"
#include "preprocessor.h"
#include <regex.h>
+ Include dependency graph for source_file.c:

Go to the source code of this file.

Macros

#define skip_line_p(s)    ((*(s))=='\0' || (*(s))=='!' || (*(s))=='*' || (*(s))=='c' || (*(s))=='C')
 include "pipsmake.h" More...
 
#define IMPLICIT_NONE_RX   "^[ \t]*implicit[ \t]*none"
 
#define INCLUDE_FILE_RX   "^[ \t]*include[ \t]*['\"]\\‍([^'\"]*\\‍)['\"]"
 
#define CMPLX_RX   "^[^\t!*Cc].....[^\"']*[^a-zA-Z0-9_ \t][ \t]*\\‍((\\‍)[-+0-9eE\\. \t]*,[-+0-9eE\\. \t]*)"
 not recognized: print *, "i = ", (0.,1.) to avoid modifying a character constant... More...
 
#define CMPLX2_RX   "^[^\t!*Cc].....[ \t]*\\‍((\\‍)[-+0-9eE\\. \t]*,[-+0-9eE\\. \t]*)"
 
#define DCMPLX_RX
 
#define DCMPLX2_RX    "^[^\t!*Cc].....[ \t]*\\‍((\\‍)[-+0-9dDeE\\. \t]*,[-+0-9dDeE\\. \t]*)"
 
#define GOTO_RX   "g[ \t]*o[ \t]*t[ \t]*o[ \t]*"
 

Functions

void pips_get_workspace_list (gen_array_t array)
 Return a sorted arg list of workspace names. More...
 
void pips_get_fortran_list (gen_array_t array)
 Select the true file with names ending in ".[fF]" and return a sorted arg list: More...
 
string hpfc_generate_path_name_of_file_name (const char *file_name)
 Return the path of an HPFC file name relative to the current PIPS directory. More...
 
int hpfc_get_file_list (gen_array_t file_names, char **hpfc_directory_name)
 
string pips_change_directory (const char *dir)
 Change to the given directory if it exists and return a canonical name. More...
 
void pips_srcpath_set (string path)
 Set the PIPS source path. More...
 
string pips_srcpath_append (string pathtoadd)
 returns an allocated pointer to the old value More...
 
static string find_file (string name)
 tries several path for a file to include... More...
 
void init_processed_include_cache (void)
 
void close_processed_include_cache (void)
 
static string get_cached (string s)
 Returns the processed cached file name, or null if none. More...
 
static string get_new_tmp_file_name (void)
 return an allocated unique cache file name. More...
 
static bool handle_file (FILE *, FILE *)
 double recursion (handle_file/handle_file_name) => forwarded declaration. More...
 
static bool handle_file_name (FILE *out, char *file_name, bool included)
 
static bool handle_include_file (FILE *out, char *file_name)
 
static void init_rx (void)
 
static bool pips_process_file (string file_name, string new_name)
 
bool filter_file (string mod_name)
 
static bool zzz_file_p (string s)
 is the file name of the form .../zzz???.f More...
 
static void clean_file (string name)
 
static bool pips_split_file (string name, string tempfile)
 
string preprocessed_to_user_file (string preprocessed_user_file)
 Allocate a new string containing the user file name, before preprocessing. More...
 
bool dot_F_file_p (string name)
 Test if a name ends with .F. More...
 
bool dot_f_file_p (string name)
 Test if a name ends with .f. More...
 
bool dot_f90_file_p (string name)
 Test if a name ends with .f90. More...
 
bool dot_f95_file_p (string name)
 Test if a name ends with .f95. More...
 
bool dot_c_file_p (string name)
 Test if a name ends with .c. More...
 
language workspace_language (gen_array_t files)
 Choose a language if all filenames in "files" have the same C or Fortran extensions. More...
 
int find_eol_coding (string name)
 Returns the newly allocated name if preprocessing succeeds. More...
 
static string include_path_to_include_flags (string include_path)
 
static string process_thru_C_pp (string name)
 Process a file name.c through the C preprocessor to generate a name.cpp_processed.c file. More...
 
static string process_thru_fortran_pp (string name)
 Process a ratfor file name.F through the C preprocessor to generate a name.fpp_processed.f file. More...
 
static string process_thru_cpp (string name)
 Process a file through a C or Fortran preprocessor according to its type. More...
 
static bool pips_check_syntax (string env, string prop)
 Why return an int rather than a bool? More...
 
static bool pips_check_fortran (void)
 A Fortran compiler must be run or not before launching the PIPS Fortran parser, according to the environment variable PIPS_CHECK_FORTRAN firstly, and then according to property CHECK_FORTRAN_SYNTAX_BEFORE_RUNNING_PIPS. More...
 
static bool pips_check_c (void)
 A C compiler must be run or not before launching the PIPS C parser, according to the environment variable PIPS_CHECK_C firstly, and then according to property CHECK_C_SYNTAX_BEFORE_RUNNING_PIPS. More...
 
static bool check_input_file_syntax (string file_name, string compiler, string options, string language)
 Verify that the syntax of a program is correct by running a real compiler on it. More...
 
static bool check_fortran_syntax_before_pips (string file_name)
 Verify that the Fortran syntax of a source file is correct by compiling it. More...
 
static bool check_c_file_syntax (string file_name)
 Verify that the C syntax of a source file is correct by compiling it. More...
 
static char * extract_last_name (char *line)
 "foo bla fun ./e.database/foo.f" -> "./e.database/foo.f" More...
 
bool process_user_file (string file)
 
bool flag_as_stub (const string module_name)
 
bool bootstrap_stubs (const string module_name)
 

Variables

static string user_file_directory = NULL
 
static regex_t some_goto_rx
 
static regex_t implicit_none_rx
 
static regex_t include_file_rx
 
static regex_t complex_cst_rx
 
static regex_t complex_cst2_rx
 
static regex_t dcomplex_cst_rx
 
static regex_t dcomplex_cst2_rx
 
static hash_table processed_cache = hash_table_undefined
 cache of preprocessed includes More...
 
string preprocessor_current_split_file_name = string_undefined
 Split a C or Fortran file into as many files as modules. More...
 
string preprocessor_current_initial_file_name = string_undefined
 The digestion of a user file by PIPS begins here. More...
 

Macro Definition Documentation

◆ CMPLX2_RX

#define CMPLX2_RX   "^[^\t!*Cc].....[ \t]*\\‍((\\‍)[-+0-9eE\\. \t]*,[-+0-9eE\\. \t]*)"

Definition at line 233 of file source_file.c.

◆ CMPLX_RX

#define CMPLX_RX   "^[^\t!*Cc].....[^\"']*[^a-zA-Z0-9_ \t][ \t]*\\‍((\\‍)[-+0-9eE\\. \t]*,[-+0-9eE\\. \t]*)"

not recognized: print *, "i = ", (0.,1.) to avoid modifying a character constant...

this stuff should be done by hand in split... also the generated lines may be too long...

Well, the regex can be improved if necessary.

In particular, it does first columned tabbed lines.

Definition at line 230 of file source_file.c.

◆ DCMPLX2_RX

#define DCMPLX2_RX    "^[^\t!*Cc].....[ \t]*\\‍((\\‍)[-+0-9dDeE\\. \t]*,[-+0-9dDeE\\. \t]*)"

Definition at line 240 of file source_file.c.

◆ DCMPLX_RX

#define DCMPLX_RX
Value:
"^[^\t!*Cc].....[^\"']*[^a-zA-Z0-9_ \t][ \t]*" \
"\\((\\)[-+0-9dDeE\\. \t]*,[-+0-9dDeE\\. \t]*)"

Definition at line 236 of file source_file.c.

◆ GOTO_RX

#define GOTO_RX   "g[ \t]*o[ \t]*t[ \t]*o[ \t]*"

Definition at line 243 of file source_file.c.

◆ IMPLICIT_NONE_RX

#define IMPLICIT_NONE_RX   "^[ \t]*implicit[ \t]*none"

Definition at line 218 of file source_file.c.

◆ INCLUDE_FILE_RX

#define INCLUDE_FILE_RX   "^[ \t]*include[ \t]*['\"]\\‍([^'\"]*\\‍)['\"]"

Definition at line 219 of file source_file.c.

◆ skip_line_p

#define skip_line_p (   s)     ((*(s))=='\0' || (*(s))=='!' || (*(s))=='*' || (*(s))=='c' || (*(s))=='C')

include "pipsmake.h"

Definition at line 66 of file source_file.c.

Function Documentation

◆ bootstrap_stubs()

bool bootstrap_stubs ( const string  module_name)
Parameters
module_nameodule_name

Definition at line 1344 of file source_file.c.

1345 {
1346  if (db_resource_p(DBR_STUBS, ""))
1347  pips_internal_error("kernels already initialized for %s", module_name);
1348  callees stubs=make_callees(NIL);
1349  DB_PUT_MEMORY_RESOURCE(DBR_STUBS,"",stubs);
1350  return true;
1351 }
callees make_callees(list a)
Definition: ri.c:227
bool db_resource_p(const char *rname, const char *oname)
true if exists and in loaded or stored state.
Definition: database.c:524
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
#define pips_internal_error
Definition: misc-local.h:149

References DB_PUT_MEMORY_RESOURCE, db_resource_p(), make_callees(), module_name(), NIL, and pips_internal_error.

Referenced by generic_initializer().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_c_file_syntax()

static bool check_c_file_syntax ( string  file_name)
static

Verify that the C syntax of a source file is correct by compiling it.

Definition at line 1034 of file source_file.c.

1035 {
1036  string comp = getenv("PIPS_CC");
1037  string flags = getenv("PIPS_CPP_FLAGS");
1038  bool syntax_ok_p = true;
1039 
1040  comp = comp? comp: DEFAULT_PIPS_CC;
1041  flags = flags? flags: DEFAULT_PIPS_CC_FLAGS;
1042 
1043  syntax_ok_p = check_input_file_syntax(file_name, comp, flags, "C");
1044 
1045  return syntax_ok_p;
1046 }
#define DEFAULT_PIPS_CC_FLAGS
#define DEFAULT_PIPS_CC
See necessary definitions in pipsmake-rc.tex.
static bool check_input_file_syntax(string file_name, string compiler, string options, string language)
Verify that the syntax of a program is correct by running a real compiler on it.
Definition: source_file.c:981
static string file_name

References check_input_file_syntax(), DEFAULT_PIPS_CC, DEFAULT_PIPS_CC_FLAGS, and file_name.

Referenced by process_user_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_fortran_syntax_before_pips()

static bool check_fortran_syntax_before_pips ( string  file_name)
static

Verify that the Fortran syntax of a source file is correct by compiling it.

Definition at line 1020 of file source_file.c.

1021 {
1022  // get compiler & flags...
1023  string fortran = getenv("PIPS_FLINT");
1024  if (!fortran) fortran = getenv("PIPS_F77");
1025  if (!fortran) fortran = DEFAULT_PIPS_FLINT;
1026  // yes, cpp
1027  string flags = getenv("PIPS_CPP_FLAGS");
1028  flags = flags? flags: "";
1029  return check_input_file_syntax(file_name, fortran, flags, "Fortran");
1030 }
#define DEFAULT_PIPS_FLINT

References check_input_file_syntax(), DEFAULT_PIPS_FLINT, and file_name.

Referenced by process_user_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_input_file_syntax()

static bool check_input_file_syntax ( string  file_name,
string  compiler,
string  options,
string  language 
)
static

Verify that the syntax of a program is correct by running a real compiler on it.

string compiler may/must contain the necessary options, e.g. PIPS_CC_FLAGS

pips_user_warning("\n\n %s syntax errors in file \"s"!\007

",

language, file_name);

Hopefully, this new warning is more informative and easier to retrieve as last line in the Warnings file.

Definition at line 981 of file source_file.c.

983 {
984  bool syntax_ok_p = true;
985  // SRCPATH has already been used to locate the file and generate a
986  // full file name, file_name
987  string include_path = getenv(SRCPATH);
988  string includes = include_path_to_include_flags(include_path);
989 
990  user_log("Checking %s syntax of file \"%s\"\n", language, file_name);
991 
992  // SG: do not forget to protect file_name
993  char *pfile_name= strescape(file_name);
995  (concatenate(compiler, " ", options, includes, " ", pfile_name, " ",
996  // DO NOT USE A POSSIBLY SHARED FILE NAME!
997  // the same "file_name.o" can be used by several creates
998  // performed in parallel, for instance by the validation...
999  " -c -o /dev/null", NULL)))
1000  {
1001  // Note that TAB is avoided in warning to simplify validation.
1002  /* pips_user_warning("\n\n %s syntax errors in file \"%s\"!\007\n\n", */
1003  /* language, file_name); */
1004  /* Hopefully, this new warning is more informative and easier to
1005  * retrieve as last line in the Warnings file.
1006  */
1007  pips_user_warning("\n\%s syntax errors in source file \"%s\". "
1008  "Check source file and/or compilation and preprocessing flags.\n",
1009  language, file_name);
1010  syntax_ok_p = false;
1011  }
1012  free(pfile_name);
1013  free(includes);
1014  return syntax_ok_p;
1015 }
void user_log(const char *format,...)
Definition: message.c:234
char * strescape(const char *source)
protect a string, for example for use in a system call list of non escaped characters in the macro ab...
Definition: file.c:334
void free(void *)
#define pips_user_warning
Definition: misc-local.h:146
int safe_system_no_abort(string)
the command to be executed
Definition: system.c:47
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define SRCPATH
Preprocessing and splitting of Fortran and C files.
static string include_path_to_include_flags(string include_path)
Definition: source_file.c:751

References concatenate(), file_name, free(), include_path_to_include_flags(), pips_user_warning, safe_system_no_abort(), SRCPATH, strescape(), and user_log().

Referenced by check_c_file_syntax(), and check_fortran_syntax_before_pips().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ clean_file()

static void clean_file ( string  name)
static

drop zzz* files

resize lines[]

keep order for unsplit.

qsort(lines, i, sizeof(char*), cmp);

Definition at line 542 of file source_file.c.

543 {
544  FILE *f;
545  string line;
546  int i=0, size = 20;
547  char ** lines = (char**) malloc(sizeof(char*)*size);
548  pips_assert("malloc ok", lines);
549 
550  f=safe_fopen(name, "r");
551  while ((line=safe_readline(f)))
552  {
553  if (!zzz_file_p(line)) /* drop zzz* files */
554  {
555  if (i==size) { /* resize lines[] */
556  size*=2;
557  lines = (char**) realloc(lines, sizeof(char*)*size);
558  pips_assert("realloc ok", lines);
559  }
560  lines[i++]=line;
561  }
562  else
563  {
564  unlink(line);
565  free(line);
566  }
567  }
568  safe_fclose(f, name);
569 
570  /* keep order for unsplit. */
571  /* qsort(lines, i, sizeof(char*), cmp); */
572 
573  f=safe_fopen(name, "w");
574  while (i>0) {
575  fprintf(f, "%s\n", lines[--i]);
576  free(lines[i]);
577  }
578  free(lines);
579  safe_fclose(f, name);
580 }
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
char * safe_readline(FILE *file)
returns the allocated line read, whatever its length.
Definition: file.c:497
void * malloc(YYSIZE_T)
static GtkWidget * lines[HELP_LINES]
Definition: gtk_help.c:47
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
static int line
FLEX_SCANNER.
Definition: scanner.c:852
static bool zzz_file_p(string s)
is the file name of the form .../zzz???.f
Definition: source_file.c:535

References f(), fprintf(), free(), line, lines, malloc(), pips_assert, safe_fclose(), safe_fopen(), safe_readline(), and zzz_file_p().

Referenced by pips_split_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ close_processed_include_cache()

void close_processed_include_cache ( void  )

pips may call this without a prior call to init_processed_include_cache under some error conditions, such as a file not found in the initializer, or a failed cpp.

Definition at line 283 of file source_file.c.

284 {
285  //fprintf(stderr, "[close_processed_include_cache] Entering\n");
287  {
288  /* pips may call this without a prior call to
289  * init_processed_include_cache under some error conditions,
290  * such as a file not found in the initializer, or a failed cpp.
291  */
292  /*
293  Do not warn the user about PIPS internal architecture issues... :-/
294  pips_user_warning("no 'processed include cache' to close, "
295  "skipping...\n");
296  */
297  return;
298  }
300  HASH_MAP(k, v, { unlink(v); free(v); }, processed_cache);
303 }
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
#define hash_table_undefined_p(h)
Definition: newgen_hash.h:50
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49
static hash_table processed_cache
cache of preprocessed includes
Definition: source_file.c:271

References free(), HASH_MAP, hash_table_free(), hash_table_undefined, hash_table_undefined_p, pips_assert, and processed_cache.

Referenced by check_delete_workspace(), and close_workspace().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dot_c_file_p()

bool dot_c_file_p ( string  name)

Test if a name ends with .c.

Parameters
nameame

Definition at line 661 of file source_file.c.

661  {
662  return !!find_suffix(name, C_FILE_SUFFIX);
663 }
string find_suffix(const string, const string)
Find if a string s end with a suffix.
Definition: string.c:273

References find_suffix().

Referenced by get_new_user_file(), pips_split_file(), process_user_file(), and workspace_language().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dot_f90_file_p()

bool dot_f90_file_p ( string  name)

Test if a name ends with .f90.

Parameters
nameame

Definition at line 649 of file source_file.c.

649  {
650  return !!find_suffix( name, FORTRAN90_FILE_SUFFIX );
651 }

References find_suffix().

Referenced by create_workspace(), get_new_user_file(), pips_split_file(), process_user_file(), and workspace_language().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dot_f95_file_p()

bool dot_f95_file_p ( string  name)

Test if a name ends with .f95.

Parameters
nameame

Definition at line 655 of file source_file.c.

655  {
656  return !!find_suffix( name, FORTRAN95_FILE_SUFFIX );
657 }

References find_suffix().

Referenced by create_workspace(), get_new_user_file(), pips_split_file(), process_user_file(), and workspace_language().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dot_F_file_p()

bool dot_F_file_p ( string  name)

Test if a name ends with .F.

Parameters
nameame

Definition at line 637 of file source_file.c.

637  {
638  return !!find_suffix(name, RATFOR_FILE_SUFFIX);
639 }

References find_suffix().

Referenced by pips_split_file(), process_thru_cpp(), process_user_file(), and workspace_language().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dot_f_file_p()

bool dot_f_file_p ( string  name)

Test if a name ends with .f.

Parameters
nameame

Definition at line 643 of file source_file.c.

643  {
644  return !!find_suffix(name, FORTRAN_FILE_SUFFIX);
645 }

References find_suffix().

Referenced by get_new_user_file(), pips_split_file(), process_user_file(), and workspace_language().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ extract_last_name()

static char* extract_last_name ( char *  line)
static

"foo bla fun ./e.database/foo.f" -> "./e.database/foo.f"

look for the two past directory separators

then look for whitespace separated module names

Definition at line 1050 of file source_file.c.

1051 {
1052 #if 1
1053  /* look for the two past directory separators */
1054  char * iter = line + strlen(line);
1055  for(int i =2;i&&iter!=line;--iter) {
1056  if(*iter=='/') --i;
1057  }
1058  /* then look for whitespace separated module names */
1059  if(iter==line) {
1060  iter= strrchr(line,' ');
1061  if(iter) {
1062  iter[0]=0;
1063  iter=iter+1;
1064  }
1065  }
1066  else
1067  iter[-1]=0;
1068  if(!iter)
1069  iter=line;
1070 
1071  return iter;
1072 #else
1073  int l = strlen(line);
1074  do {
1075  while (l>=0 && line[l]!=' ') l--;
1076  if (l>=0 && line[l]==' ') line[l]='\0';
1077  } while (l>=0 && strlen(line+l+1)==0);
1078  return l>=-1? line+l+1: NULL;
1079 #endif
1080 
1081 }

References line.

Referenced by process_user_file().

+ Here is the caller graph for this function:

◆ filter_file()

bool filter_file ( string  mod_name)

directory is set for finding includes.

Parameters
mod_nameod_name

Definition at line 501 of file source_file.c.

502 {
503  string name, new_name, dir_name, abs_name, abs_new_name;
504  name = db_get_memory_resource(DBR_INITIAL_FILE, mod_name, true);
505 
506  /* directory is set for finding includes. */
508  pips_dirname(db_get_memory_resource(DBR_USER_FILE, mod_name, true));
509  new_name = db_build_file_resource_name
510  (DBR_SOURCE_FILE, mod_name, FORTRAN_FILE_SUFFIX);
511 
513  abs_name = strdup(concatenate(dir_name, "/", name, NULL));
514  abs_new_name = strdup(concatenate(dir_name, "/", new_name, NULL));
515  free(dir_name);
516 
517  if (!pips_process_file(abs_name, abs_new_name))
518  {
519  pips_user_warning("initial file filtering of %s failed\n", mod_name);
520  safe_unlink(abs_new_name);
521  free(abs_new_name); free(abs_name);
522  return false;
523  }
524  free(abs_new_name); free(abs_name);
526 
527  DB_PUT_NEW_FILE_RESOURCE(DBR_SOURCE_FILE, mod_name, new_name);
528  return true;
529 }
some path to file suffix some path to *char * pips_dirname(char *fullpath)
Definition: file.c:837
void safe_unlink(const char *file_name)
Delete the given file.
Definition: file.c:852
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_NEW_FILE_RESOURCE(res_name, own_name, res_val)
Put a new file resource into the current workspace database.
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
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
char * strdup()
static bool pips_process_file(string file_name, string new_name)
Definition: source_file.c:487
static string user_file_directory
Definition: source_file.c:194

References concatenate(), db_build_file_resource_name(), db_get_current_workspace_directory(), db_get_memory_resource(), DB_PUT_NEW_FILE_RESOURCE, free(), pips_dirname(), pips_process_file(), pips_user_warning, safe_unlink(), strdup(), and user_file_directory.

+ Here is the call graph for this function:

◆ find_eol_coding()

int find_eol_coding ( string  name)

Returns the newly allocated name if preprocessing succeeds.

Returns NULL if preprocessing fails.

Parameters
nameame

Definition at line 721 of file source_file.c.

722 {
723  FILE * f = safe_fopen(name, "r");
724  int state =0;
725  int eol_code = -1;
726  int c;
727 
728  while((c=getc(f))!=EOF) {
729  if(c=='\n') {
730  if(state==1)
731  eol_code = 1; // DOS
732  else
733  eol_code = 0; // UNIX
734  break;
735  }
736  else if(c=='\r')
737  state = 1;
738  else {
739  if(state==1) {
740  eol_code = 2; // ISO22
741  break;
742  }
743  }
744  }
745 
746  safe_fclose(f, name);
747 
748  return eol_code;
749 }

References f(), safe_fclose(), and safe_fopen().

Referenced by process_thru_C_pp().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ find_file()

static string find_file ( string  name)
static

tries several path for a file to include...

first rely on $PIPS_SRCPATH, then other directories.

Definition at line 257 of file source_file.c.

258 {
259  string srcpath = getenv(SRCPATH), result;
260  string path = strdup(concatenate(
261  srcpath? srcpath: "", ":",
263  NULL));
264  result = find_file_in_directories(name, path);
265  free(path);
266  return result;
267 }
char * find_file_in_directories(const char *file_name, const char *dir_path)
returns an allocated string pointing to the file, possibly with an additional path taken from colon-s...
Definition: file.c:399

References concatenate(), find_file_in_directories(), free(), SRCPATH, strdup(), and user_file_directory.

Referenced by handle_file_name().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flag_as_stub()

bool flag_as_stub ( const string  module_name)
Parameters
module_nameodule_name

Definition at line 1334 of file source_file.c.

1334  {
1335  if (!db_resource_p(DBR_STUBS, ""))
1336  pips_internal_error("stubs not initialized");
1337  callees stubs=(callees)db_get_memory_resource(DBR_STUBS,"",true);
1339  DB_PUT_MEMORY_RESOURCE(DBR_STUBS,"",stubs);
1340  return true;
1341 
1342 }
#define STRING(x)
Definition: genC.h:87
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define callees_callees(x)
Definition: ri.h:675

References callees_callees, CONS, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, db_resource_p(), module_name(), pips_internal_error, strdup(), and STRING.

Referenced by generic_initializer().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_cached()

static string get_cached ( string  s)
static

Returns the processed cached file name, or null if none.

Definition at line 307 of file source_file.c.

308 {
309  string res;
310  pips_assert("cache initialized", !hash_table_undefined_p(processed_cache));
311  res = hash_get(processed_cache, s);
312  //fprintf(stderr, "[close_processed_include_cache] Looking for %s : %s\n", s,
313  //res == HASH_UNDEFINED_VALUE ? "NULL" : res);
314 
315  return res == HASH_UNDEFINED_VALUE ? NULL : res;
316 }
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56

References hash_get(), hash_table_undefined_p, HASH_UNDEFINED_VALUE, pips_assert, and processed_cache.

Referenced by handle_include_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_new_tmp_file_name()

static string get_new_tmp_file_name ( void  )
static

return an allocated unique cache file name.

Definition at line 321 of file source_file.c.

322 {
323  static int unique = 0;
324  string dir_name, file_name;
325  unsigned int len;
327  len = strlen(dir_name)+20;
328  file_name = (char*) malloc(sizeof(char)*len);
329  if (!file_name) pips_internal_error("malloc failed");
330  sprintf(file_name, "%s/cached.%d", dir_name, unique++);
331  pips_assert("not too long", strlen(file_name)<len);
332  free(dir_name);
333  return file_name;
334 }
string db_get_directory_name_for_module(const char *name)
returns the allocated and mkdir'ed directory for module name
Definition: lowlevel.c:150
#define WORKSPACE_TMP_SPACE
Definition: pipsdbm-local.h:31

References db_get_directory_name_for_module(), file_name, free(), malloc(), pips_assert, pips_internal_error, and WORKSPACE_TMP_SPACE.

Referenced by handle_include_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ handle_file()

static bool handle_file ( FILE *  out,
FILE *  f 
)
static

double recursion (handle_file/handle_file_name) => forwarded declaration.

process f for includes and nones

matched strings

error?

FI: test for parser

handle_complex_constants(&line);

Definition at line 437 of file source_file.c.

438 {
439  string line;
440  regmatch_t matches[2]; /* matched strings */
441 
442  while ((line = safe_readline(f)))
443  {
444  if (!skip_line_p(line))
445  {
446  if (!regexec(&include_file_rx, line, 2, matches, 0))
447  {
448  char c = line[matches[1].rm_eo];
449  line[matches[1].rm_eo]='\0';
450 
451  if (!handle_include_file(out, &line[matches[1].rm_so]))
452  return false; /* error? */
453 
454  line[matches[1].rm_eo]=c;
455  fprintf(out, "! ");
456  }
457  else if (!regexec(&implicit_none_rx, line, 0, matches, 0))
458  fprintf(out,
459  "! MIL-STD-1753 Fortran extension not in PIPS\n! ");
460  else {
461  /* FI: test for parser */
462  /* handle_complex_constants(&line); */
463  ;
464  }
465  }
466  fprintf(out, "%s\n", line);
467  free(line);
468  }
469  return true;
470 }
static FILE * out
Definition: alias_check.c:128
static hash_table matches
Definition: simdizer.c:60
static regex_t implicit_none_rx
Definition: source_file.c:247
#define skip_line_p(s)
include "pipsmake.h"
Definition: source_file.c:66
static bool handle_include_file(FILE *out, char *file_name)
Definition: source_file.c:372
static regex_t include_file_rx
Definition: source_file.c:248

References f(), fprintf(), free(), handle_include_file(), implicit_none_rx, include_file_rx, line, matches, out, safe_readline(), and skip_line_p.

Referenced by handle_file_name().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ handle_file_name()

static bool handle_file_name ( FILE *  out,
char *  file_name,
bool  included 
)
static

Do not raise a user_error exception, because you are not in the right directory maybe this is not true anymore? FC 01/04/1998

Definition at line 341 of file source_file.c.

342 {
343  FILE * f;
344  string found = find_file(file_name);
345  bool ok = false;
346 
347  if (!found)
348  {
349  /* Do not raise a user_error exception,
350  because you are not in the right directory
351  maybe this is not true anymore? FC 01/04/1998
352  */
353  pips_user_warning("include file %s not found\n", file_name);
354  fprintf(out,
355  "!! ERROR - include \"%s\" was not found\n"
356  " include \"%s\"\n", file_name, file_name);
357  return false;
358  }
359 
360  pips_debug(2, "including file \"%s\"\n", found);
361  if (included) fprintf(out, "! include \"%s\"\n", file_name);
362 
363  f=safe_fopen(found, "r");
364  ok = handle_file(out, f);
365  safe_fclose(f, found);
366 
367  if (included) fprintf(out, "! end include \"%s\"\n", file_name);
368  free(found);
369  return ok;
370 }
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
static bool handle_file(FILE *, FILE *)
double recursion (handle_file/handle_file_name) => forwarded declaration.
Definition: source_file.c:437
static string find_file(string name)
tries several path for a file to include...
Definition: source_file.c:257
static bool ok

References f(), file_name, find_file(), fprintf(), free(), handle_file(), ok, out, pips_debug, pips_user_warning, safe_fclose(), and safe_fopen().

Referenced by handle_include_file(), and pips_process_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ handle_include_file()

static bool handle_include_file ( FILE *  out,
char *  file_name 
)
static

handle bang comments and hollerith with an additionnal processing...

if ok put in the cache, otherwise drop it.

Definition at line 372 of file source_file.c.

373 {
374  FILE * in;
375  bool ok = true;
376  string cached = get_cached(file_name);
377  char * error = NULL;
378 
379  if (!cached)
380  {
381  FILE * tmp_out;
382 
383  cached = get_new_tmp_file_name();
384  tmp_out = safe_fopen(cached, "w");
385  ok = handle_file_name(tmp_out, file_name, true);
386  safe_fclose(tmp_out, cached);
387 
388  /* handle bang comments and hollerith with an additionnal
389  * processing...
390  */
391  if (ok)
392  {
393  string filtered;
394  FILE * tmp_hbc, * tmp_in;
395 
396  filtered = get_new_tmp_file_name();
397  tmp_hbc = safe_fopen(filtered, "w");
398  tmp_in = safe_fopen(cached, "r");
399 
400  error = process_bang_comments_and_hollerith(tmp_in, tmp_hbc);
401  if (error) ok = false;
402 
403  safe_fclose(tmp_in, cached);
404  safe_fclose(tmp_hbc, filtered);
405 
406  safe_unlink(cached);
407  free(cached);
408  cached = filtered;
409  }
410 
411  /* if ok put in the cache, otherwise drop it. */
412  if (ok) {
413  //fprintf(stderr, "[handle_include_file] Adding in the cache %s for file %s\n",
414  //cached, file_name);
416  }
417  else {
418  safe_unlink(cached);
419  free(cached), cached = NULL;
420  }
421  }
422 
423  if (ok)
424  {
425  in = safe_fopen(cached, "r");
426  safe_cat(out, in);
427  safe_fclose(in, cached);
428  }
429 
430  if (error) pips_user_error("preprocessing error: %s\n", error);
431 
432  return ok;
433 }
#define error(fun, msg)
NewGen interface with C3 type Psysteme for PIPS project.
Definition: Psc.c:78
void safe_cat(FILE *out, FILE *in)
Definition: file.c:669
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
#define pips_user_error
Definition: misc-local.h:147
char * process_bang_comments_and_hollerith(FILE *, FILE *)
processing extracted for includes...
Definition: split_file.c:836
static bool handle_file_name(FILE *out, char *file_name, bool included)
Definition: source_file.c:341
static string get_new_tmp_file_name(void)
return an allocated unique cache file name.
Definition: source_file.c:321
static string get_cached(string s)
Returns the processed cached file name, or null if none.
Definition: source_file.c:307

References error, file_name, free(), get_cached(), get_new_tmp_file_name(), handle_file_name(), hash_put(), ok, out, pips_user_error, process_bang_comments_and_hollerith(), processed_cache, safe_cat(), safe_fclose(), safe_fopen(), and safe_unlink().

Referenced by handle_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hpfc_generate_path_name_of_file_name()

string hpfc_generate_path_name_of_file_name ( const char *  file_name)

Return the path of an HPFC file name relative to the current PIPS directory.

Can be freed by the caller.

Parameters
file_nameile_name

Definition at line 97 of file source_file.c.

98 {
99  string dir_name = db_get_current_workspace_directory(),
100  name = strdup(concatenate(
101  dir_name, "/", HPFC_COMPILED_FILE_DIR, "/", file_name, NULL));
102  free(dir_name);
103  return name;
104 }

References concatenate(), db_get_current_workspace_directory(), file_name, free(), and strdup().

Referenced by notify_hpfc_file_view().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hpfc_get_file_list()

int hpfc_get_file_list ( gen_array_t  file_names,
char **  hpfc_directory_name 
)

Where is the output of HPFC:

generated files start with upercases

Plain files only:

Parameters
file_namesile_names
hpfc_directory_namepfc_directory_name

Definition at line 106 of file source_file.c.

108 {
109  // some static but dynamic buffer.
110  static int hpfc_bsz = 0;
111  static char * hpfc_dir = NULL;
112 
113  int return_code, len;
115 
116  len = strlen(dir) + strlen(HPFC_COMPILED_FILE_DIR) + 5;
117 
118  if (hpfc_bsz<len) {
119  if (hpfc_dir) free(hpfc_dir), hpfc_dir=NULL;
120  hpfc_bsz = len;
121  hpfc_dir = (char*) malloc(hpfc_bsz);
122  message_assert("malloc succeeded", hpfc_dir);
123  }
124 
125  // Get the HPFC file name list:
126  sprintf(hpfc_dir, "%s/%s", dir, HPFC_COMPILED_FILE_DIR);
127 
128  return_code = safe_list_files_in_directory(
129  file_names,
130  hpfc_dir, /* Where is the output of HPFC: */
131  "^[A-Z].*\\.[fh]$", /* generated files start with upercases */
132  file_exists_p /* Plain files only: */);
133  *hpfc_directory_name = hpfc_dir;
134 
135  return return_code;
136 }
bool file_exists_p(const char *name)
Definition: file.c:321
int safe_list_files_in_directory(gen_array_t files, string dir, string re, bool(*file_name_predicate)(const char *))
returns a sorted arg list of files matching regular expression re in directory 'dir' and with file_na...
Definition: file.c:250
#define message_assert(msg, ex)
Definition: newgen_assert.h:47
#define build_pgmwd
string db_get_current_workspace_name(void)
the function is used to check that there is some current workspace...
Definition: workspace.c:82

References build_pgmwd, db_get_current_workspace_name(), file_exists_p(), free(), malloc(), message_assert, and safe_list_files_in_directory().

Referenced by generate_a_menu_with_HPF_output_files().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ include_path_to_include_flags()

static string include_path_to_include_flags ( string  include_path)
static

At least include files from the current directory:

Transform the include path p1:p2:... into -Ip1 -Ip2...

Definition at line 751 of file source_file.c.

752 {
753  /* At least include files from the current directory: */
754  string includes = strdup("");
755 
756  /* Transform the include path p1:p2:... into -Ip1 -Ip2...*/
757  for(int i = 0;; i++) {
758  // Get the path i:
759  string p = nth_path(include_path, i);
760  if (p == NULL)
761  // No more directory
762  break;
763  string old_includes = includes;
764  includes = strdup(concatenate(includes, " -I", p, NULL));
765  free(p);
766  free(old_includes);
767  }
768  return includes;
769 }
string nth_path(const char *path_list, int n)
Returns the allocated nth path from colon-separated path string.
Definition: file.c:362

References concatenate(), free(), nth_path(), and strdup().

Referenced by check_input_file_syntax(), and process_thru_C_pp().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_processed_include_cache()

void init_processed_include_cache ( void  )

Definition at line 272 of file source_file.c.

273 {
274  // Since these functions are called in different context, the
275  // conventional pips_debug() is not well suitable, so revert to plain
276  // old fprintf for debug...
277  //fprintf(stderr, "[init_processed_include_cache] Entering\n");
280 }
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
@ hash_string
Definition: newgen_hash.h:32

References hash_string, hash_table_make(), hash_table_undefined_p, pips_assert, and processed_cache.

Referenced by create_workspace(), and open_workspace().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_rx()

static void init_rx ( void  )
static

Definition at line 472 of file source_file.c.

473 {
474  static bool done=false;
475  if (done) return;
476  done=true;
477  if (regcomp(&some_goto_rx, GOTO_RX, REG_ICASE) ||
478  regcomp(&implicit_none_rx, IMPLICIT_NONE_RX, REG_ICASE) ||
479  regcomp(&include_file_rx, INCLUDE_FILE_RX, REG_ICASE) ||
480  regcomp(&complex_cst_rx, CMPLX_RX, REG_ICASE) ||
481  regcomp(&complex_cst2_rx, CMPLX2_RX, REG_ICASE) ||
482  regcomp(&dcomplex_cst_rx, DCMPLX_RX, REG_ICASE) ||
483  regcomp(&dcomplex_cst2_rx, DCMPLX2_RX, REG_ICASE))
484  pips_internal_error("invalid regular expression");
485 }
#define GOTO_RX
Definition: source_file.c:243
#define CMPLX2_RX
Definition: source_file.c:233
#define CMPLX_RX
not recognized: print *, "i = ", (0.,1.) to avoid modifying a character constant.....
Definition: source_file.c:230
static regex_t some_goto_rx
Definition: source_file.c:246
static regex_t dcomplex_cst_rx
Definition: source_file.c:251
#define INCLUDE_FILE_RX
Definition: source_file.c:219
static regex_t complex_cst2_rx
Definition: source_file.c:250
#define DCMPLX2_RX
Definition: source_file.c:240
#define DCMPLX_RX
Definition: source_file.c:236
#define IMPLICIT_NONE_RX
Definition: source_file.c:218
static regex_t dcomplex_cst2_rx
Definition: source_file.c:252
static regex_t complex_cst_rx
Definition: source_file.c:249

References CMPLX2_RX, CMPLX_RX, complex_cst2_rx, complex_cst_rx, DCMPLX2_RX, DCMPLX_RX, dcomplex_cst2_rx, dcomplex_cst_rx, GOTO_RX, IMPLICIT_NONE_RX, implicit_none_rx, INCLUDE_FILE_RX, include_file_rx, pips_internal_error, and some_goto_rx.

Referenced by pips_process_file().

+ Here is the caller graph for this function:

◆ pips_change_directory()

string pips_change_directory ( const char *  dir)

Change to the given directory if it exists and return a canonical name.

Return NULL if it does not exist, or fails

Parameters
dirir

Definition at line 142 of file source_file.c.

143 {
144  if (directory_exists_p(dir))
145  {
146  int status = chdir(dir);
147  if (status==-1)
148  {
149  perror("chdir");
150  return NULL;
151  }
152  // should check status...
153  return get_cwd();
154  }
155  return NULL;
156 }
char * get_cwd(void)
returns the current working directory name.
Definition: file.c:486
bool directory_exists_p(const char *name)
Definition: file.c:314

References directory_exists_p(), and get_cwd().

Referenced by end_directory_notify().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pips_check_c()

static bool pips_check_c ( void  )
static

A C compiler must be run or not before launching the PIPS C parser, according to the environment variable PIPS_CHECK_C firstly, and then according to property CHECK_C_SYNTAX_BEFORE_RUNNING_PIPS.

So the environment overrides the property.

Definition at line 968 of file source_file.c.

969 {
970  string env = "PIPS_CHECK_C";
971  string prop = "CHECK_C_SYNTAX_BEFORE_RUNNING_PIPS";
972  return pips_check_syntax(env, prop);
973 }
static jmp_buf env
Definition: genClib.c:2473
static bool pips_check_syntax(string env, string prop)
Why return an int rather than a bool?
Definition: source_file.c:932

References env, and pips_check_syntax().

Referenced by process_user_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pips_check_fortran()

static bool pips_check_fortran ( void  )
static

A Fortran compiler must be run or not before launching the PIPS Fortran parser, according to the environment variable PIPS_CHECK_FORTRAN firstly, and then according to property CHECK_FORTRAN_SYNTAX_BEFORE_RUNNING_PIPS.

So the environment overrides the property.

Definition at line 955 of file source_file.c.

956 {
957  string env = "PIPS_CHECK_FORTRAN";
958  string prop = "CHECK_FORTRAN_SYNTAX_BEFORE_RUNNING_PIPS";
959  return pips_check_syntax(env, prop);
960 }

References env, and pips_check_syntax().

Referenced by process_user_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pips_check_syntax()

static bool pips_check_syntax ( string  env,
string  prop 
)
static

Why return an int rather than a bool?

Definition at line 932 of file source_file.c.

933 {
934  // environment has the priority
935  string v = getenv(env);
936 
937  if (v && (*v=='o' || *v=='y' || *v=='t' || *v=='v' || *v=='1' ||
938  *v=='O' || *v=='Y' || *v=='T' || *v=='V'))
939  return true;
940 
941  if (v && (*v=='n' || *v=='f' || *v=='0' || *v=='N' || *v=='F' ))
942  return false;
943 
944  // else look for the property
945  return get_bool_property(prop);
946 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....

References env, and get_bool_property().

Referenced by pips_check_c(), and pips_check_fortran().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pips_get_fortran_list()

void pips_get_fortran_list ( gen_array_t  array)

Select the true file with names ending in ".[fF]" and return a sorted arg list:

Parameters
arrayrray

Definition at line 89 of file source_file.c.

90 {
91  list_files_in_directory(array, ".", "^.*\\.[fF]$", file_exists_p);
92 }
void list_files_in_directory(gen_array_t files, string dir, string re, bool(*file_name_predicate)(const char *))
The same as the previous safe_list_files_in_directory() but with no return code and a call to user er...
Definition: file.c:299
static entity array

References array, file_exists_p(), and list_files_in_directory().

Referenced by continue_create_workspace_notify().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pips_get_workspace_list()

void pips_get_workspace_list ( gen_array_t  array)

Return a sorted arg list of workspace names.

cproto-generated files

(For each name, there is a name.database directory in the current directory):

Parameters
arrayrray

Definition at line 74 of file source_file.c.

75 {
76  int i, n;
77  // Find all directories with name ending with ".database":
78  list_files_in_directory(array, ".", "^.*\\.database$", directory_exists_p);
80  // Remove the ".database":
81  for (i = 0; i < n; i++) {
82  *strchr(gen_array_item(array, i), '.') = '\0';
83  }
84 }
size_t gen_array_nitems(const gen_array_t a)
Definition: array.c:131
void * gen_array_item(const gen_array_t a, size_t i)
Definition: array.c:143

References array, directory_exists_p(), gen_array_item(), gen_array_nitems(), and list_files_in_directory().

Referenced by generate_workspace_menu(), open_or_create_workspace(), open_workspace_notify(), and start_delete_workspace_notify().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pips_process_file()

static bool pips_process_file ( string  file_name,
string  new_name 
)
static

Definition at line 487 of file source_file.c.

488 {
489  bool ok = false;
490  FILE * out;
491  pips_debug(2, "processing file %s\n", file_name);
492  init_rx();
493  out = safe_fopen(new_name, "w");
494  ok = handle_file_name(out, file_name, false);
495  safe_fclose(out, new_name);
496  return ok;
497 }
static void init_rx(void)
Definition: source_file.c:472

References file_name, handle_file_name(), init_rx(), ok, out, pips_debug, safe_fclose(), and safe_fopen().

Referenced by filter_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pips_split_file()

static bool pips_split_file ( string  name,
string  tempfile 
)
static

Definition at line 586 of file source_file.c.

587 {
588  char * err = NULL;
589  FILE * out = safe_fopen(tempfile, "w");
590  string dir = db_get_current_workspace_directory();
592 
593  if ( dot_c_file_p( name ) )
594  err = csplit( dir, name, out );
595  else if ( dot_f_file_p( name ) || dot_F_file_p( name ) )
596  err = fsplit( dir, name, out );
597  else if ( dot_f90_file_p( name ) || dot_f95_file_p( name ) )
598  err = f95split( dir, name, &out );
599  else
600  pips_user_error("unexpected file name for splitting: %s", name);
601 
602  free(dir);
604  safe_fclose(out, tempfile);
605  clean_file(tempfile);
606  if (err) {
607  fprintf(stderr, "split error while extracting %s from %s: %s\n",
608  tempfile, name, err);
609  }
610  return err != NULL;
611 }
string csplit(char *dir_name, char *file_name, FILE *out)
Definition: csplit_file.c:641
char * f95split(char *dir_name, char *file_name, FILE **out)
f95split_file.c
Definition: f95split_file.c:56
char * fsplit(char *, char *, FILE *)
Definition: split_file.c:474
static void clean_file(string name)
Definition: source_file.c:542
bool dot_c_file_p(string name)
Test if a name ends with .c.
Definition: source_file.c:661
bool dot_f_file_p(string name)
Test if a name ends with .f.
Definition: source_file.c:643
string preprocessor_current_split_file_name
Split a C or Fortran file into as many files as modules.
Definition: source_file.c:584
bool dot_f90_file_p(string name)
Test if a name ends with .f90.
Definition: source_file.c:649
bool dot_f95_file_p(string name)
Test if a name ends with .f95.
Definition: source_file.c:655
bool dot_F_file_p(string name)
Test if a name ends with .F.
Definition: source_file.c:637

References clean_file(), csplit(), db_get_current_workspace_directory(), dot_c_file_p(), dot_f90_file_p(), dot_f95_file_p(), dot_F_file_p(), dot_f_file_p(), f95split(), fprintf(), free(), fsplit(), out, pips_user_error, preprocessor_current_split_file_name, safe_fclose(), safe_fopen(), and strdup().

Referenced by process_user_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pips_srcpath_append()

string pips_srcpath_append ( string  pathtoadd)

returns an allocated pointer to the old value

Strdup the string since it is returned and use later in many other places

Parameters
pathtoaddathtoadd

Definition at line 177 of file source_file.c.

178 {
179  string old_path, new_path;
180  old_path = getenv(SRCPATH);
181  if (old_path)
182  /* Strdup the string since it is returned and use later in many other
183  places */
184  old_path = strdup(old_path);
185  new_path = concatenate(old_path? old_path: "", old_path? ":": "",
186  pathtoadd, NULL);
187  pips_srcpath_set(new_path);
188  return old_path;
189 }
void pips_srcpath_set(string path)
Set the PIPS source path.
Definition: source_file.c:167

References concatenate(), pips_srcpath_set(), SRCPATH, and strdup().

Referenced by parse_arguments(), and step_analyse_init().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pips_srcpath_set()

void pips_srcpath_set ( string  path)

Set the PIPS source path.

Parameters
pathis used to set the search path or to unset if path is NULL

Strangely this environment variable is set many times in PIPS to pass some information...

Parameters
pathath

Definition at line 167 of file source_file.c.

168 {
169  if (path)
170  setenv(SRCPATH, path, true);
171  else
172  unsetenv(SRCPATH);
173 }

References SRCPATH.

Referenced by parse_arguments(), pips_srcpath_append(), pop_path(), and safe_pop_path().

+ Here is the caller graph for this function:

◆ preprocessed_to_user_file()

string preprocessed_to_user_file ( string  preprocessed_user_file)

Allocate a new string containing the user file name, before preprocessing.

No preprocessing has occured

Parameters
preprocessed_user_filereprocessed_user_file

Definition at line 617 of file source_file.c.

618 {
619  string user_file = strdup(preprocessed_user_file);
620  string suffix = string_undefined;
621 
622  if ((suffix = find_suffix(user_file, PP_FORTRAN_ED)) != NULL) {
623  strcpy(suffix, FORTRAN_FILE_SUFFIX);
624  }
625  else if((suffix = find_suffix(user_file, PP_C_ED)) != NULL) {
626  strcpy(suffix, C_FILE_SUFFIX);
627  }
628  else {
629  /* No preprocessing has occured */
630  ;
631  }
632  return user_file;
633 }
static FILE * user_file
These functions implements the writing of objects.
Definition: genClib.c:1485
#define string_undefined
Definition: newgen_types.h:40

References find_suffix(), strdup(), string_undefined, and user_file.

Referenced by get_new_user_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ process_thru_C_pp()

static string process_thru_C_pp ( string  name)
static

Process a file name.c through the C preprocessor to generate a name.cpp_processed.c file.

Parameters
nameis the name of the file to process
Returns
the name of the produced file

check "test" could be performed before "cat" but not after, and the error file may be useful for the user. Why should we remove it so soon?

        " && test ! -s ", cpp_err,
        " && rm -f ", cpp_err, NULL)); 

Sed command to replace the second occurence of the formal parameter __x of the functions used twice on the same line by __y. Examples from math.h: extern long double fabsl (long double __x) ; extern long double __fabsl (long double __x); will be replace by extern long double fabsl (long double __x) ; extern long double __fabsl (long double __y);

check "test" could be performed before "cat" but not after, and the error file may be useful for the user. Why should we remove it so soon?

" && test ! -s ", cpp_err, " && rm -f ", cpp_err, NULL));

Definition at line 778 of file source_file.c.

778  {
779  string dir_name, new_name, simpler, cpp_options, cpp, cpp_err;
780  int status = 0;
781  string include_path = getenv(SRCPATH);
782  // To manage file encoding
783  int eol_code = -1;
784 
786  // FI: generates conflicts when several source files have the same name
787  //simpler = pips_basename(name, C_FILE_SUFFIX);
788  simpler = pips_initial_filename(name, C_FILE_SUFFIX);
789  new_name = strdup(concatenate(dir_name, "/", simpler, PP_C_ED, NULL));
790  cpp_err = strescape(concatenate(new_name, PP_ERR, NULL));
791  free(dir_name);
792  free(simpler);
793 
794  cpp = getenv(CPP_PIPS_ENV);
795  cpp_options = getenv(CPP_PIPS_OPTIONS_ENV);
796 
797  string includes = include_path_to_include_flags(include_path);
798 
799  pips_debug(1, "PIPS_SRCPATH=\"%s\"\n", include_path);
800  pips_debug(1, "INCLUDE=\"%s\"\n", includes);
801 
802  eol_code = find_eol_coding(name);
803  eol_code = 0;
804 
805  if (eol_code>0)
807  "EOL encoding for file \"%s\" is \"%s\" and not supported\n",
808  name, eol_code==1? "dos" : "iso22");
809 
811  (concatenate(cpp? cpp: CPP_CPP,
812  CPP_CPPFLAGS, cpp_options? cpp_options: "",
813  includes, " '",
814  name, "' > '", new_name, "' 2> ", cpp_err, NULL));
815 
816  free(includes);
817 
818  if(status) {
819  (void) safe_system_no_abort(concatenate("cat ", cpp_err, NULL));
820 
821  /* check "test" could be performed before "cat" but not after, and
822  the error file may be useful for the user. Why should we remove
823  it so soon?
824 
825  " && test ! -s ", cpp_err,
826  " && rm -f ", cpp_err, NULL)); */
827  free(new_name);
828  new_name = NULL;
829  }
830 /* Sed command to replace the second occurence of the formal parameter __x of the functions
831  used twice on the same line by __y.
832  Examples from math.h:
833  extern long double fabsl (long double __x) ; extern long double __fabsl (long double __x);
834  will be replace by
835  extern long double fabsl (long double __x) ; extern long double __fabsl (long double __y);
836  */
837  if (status==0) {
839  (concatenate("sed -i -e \"s/(long double __x) ;/(long double __y);/2g\" '",
840  new_name, "' 2> ", cpp_err, NULL));
841 
842  if(status) {
843  (void) safe_system_no_abort(concatenate("cat ", cpp_err, NULL));
844 
845  /* check "test" could be performed before "cat" but not after, and
846  the error file may be useful for the user. Why should we remove
847  it so soon?
848 
849  " && test ! -s ", cpp_err,
850  " && rm -f ", cpp_err, NULL)); */
851  free(new_name);
852  new_name = NULL;
853  }
854  }
855  free(cpp_err);
856 
857  return new_name;
858 }
char * pips_initial_filename(char *fullpath, char *suffix)
The source file name access path is shortened or not depending on the property.
Definition: file.c:829
#define CPP_CPP
default preprocessor and basic options -C: do not discard comments...
#define CPP_PIPS_ENV
pre-processor and added options from environment
#define CPP_PIPS_OPTIONS_ENV
#define CPP_CPPFLAGS
#define CPP_CPPFLAGS " -P -D__PIPS__ -D__HPFC__ "
int find_eol_coding(string name)
Returns the newly allocated name if preprocessing succeeds.
Definition: source_file.c:721

References concatenate(), CPP_CPP, CPP_CPPFLAGS, CPP_PIPS_ENV, CPP_PIPS_OPTIONS_ENV, db_get_directory_name_for_module(), find_eol_coding(), free(), include_path_to_include_flags(), pips_debug, pips_initial_filename(), pips_user_error, safe_system_no_abort(), SRCPATH, strdup(), strescape(), and WORKSPACE_TMP_SPACE.

Referenced by process_thru_cpp().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ process_thru_cpp()

static string process_thru_cpp ( string  name)
static

Process a file through a C or Fortran preprocessor according to its type.

Not much to share between .F and .c?

Definition at line 916 of file source_file.c.

917 {
918  /* Not much to share between .F and .c? */
919  string new_name = string_undefined;
920 
921  if(dot_F_file_p(name))
922  new_name = process_thru_fortran_pp(name);
923  else
924  new_name = process_thru_C_pp(name);
925 
926  return new_name;
927 }
static string process_thru_C_pp(string name)
Process a file name.c through the C preprocessor to generate a name.cpp_processed....
Definition: source_file.c:778
static string process_thru_fortran_pp(string name)
Process a ratfor file name.F through the C preprocessor to generate a name.fpp_processed....
Definition: source_file.c:863

References dot_F_file_p(), process_thru_C_pp(), process_thru_fortran_pp(), and string_undefined.

Referenced by process_user_file().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ process_thru_fortran_pp()

static string process_thru_fortran_pp ( string  name)
static

Process a ratfor file name.F through the C preprocessor to generate a name.fpp_processed.f file.

Note: the preprocessor used must know somehow about Fortran and its lexical and comment conventions. This is ok with gcc when g77 or gfortran is included. Otherwise, "'" appearing in Fortran comments results in errors to be reported. Well, the return code could be ignored maybe, but I prefer not to.

FI->FC: it should be a safe_system_no_abort(). Errors are supposedly displayed... but their display is skipped because of the return code of the first process and pips_internal_error is executed!. PIPS_SRCPATH is not used to find the include files. A pips_user_error is not caught at the process_user_file level.

See preprocessor/Validation/csplit09.tpips

fpp was wrong...

show errors

Definition at line 863 of file source_file.c.

864 {
865  string dir_name, new_name, simpler, fpp_options, fpp, fpp_err;
866  int status;
867 
869  simpler = pips_basename(name, RATFOR_FILE_SUFFIX);
870  new_name = strdup(concatenate(dir_name, "/", simpler, PP_FORTRAN_ED, NULL));
871  fpp_err = strdup(concatenate(new_name, PP_ERR, NULL));
872  free(dir_name);
873  free(simpler);
874 
875  fpp = getenv(FPP_PIPS_ENV);
876  fpp_options = getenv(FPP_PIPS_OPTIONS_ENV);
877 
878  /* Note: the preprocessor used **must** know somehow about Fortran and
879  * its lexical and comment conventions. This is ok with gcc when g77
880  * or gfortran is included. Otherwise, "'" appearing in Fortran
881  * comments results in errors to be reported. Well, the return code
882  * could be ignored maybe, but I prefer not to.
883  */
884 
885  /* FI->FC: it should be a safe_system_no_abort(). Errors are
886  supposedly displayed... but their display is skipped because of the
887  return code of the first process and pips_internal_error is
888  executed!. PIPS_SRCPATH is not used to find the include files. A
889  pips_user_error is not caught at the process_user_file level.
890 
891  See preprocessor/Validation/csplit09.tpips */
892 
894  FPP_CPPFLAGS, fpp_options? fpp_options: "",
895  " ", name, " > ", new_name, " 2> ", fpp_err,
896  " && cat ", fpp_err,
897  " && test ! -s ", fpp_err,
898  " && rm -f ", fpp_err, NULL));
899 
900  /* fpp was wrong... */
901  if (status)
902  {
903  /* show errors */
904  (void) safe_system_no_abort(concatenate("cat ", fpp_err, NULL));
905  free(new_name);
906  new_name = NULL;
907  }
908 
909  free(fpp_err);
910  return new_name;
911 }
struct _newgen_struct_status_ * status
Definition: database.h:31
char * pips_basename(char *fullpath, char *suffix)
Definition: file.c:822
#define FPP_CPPFLAGS
The default preprocessor flags to use with Fortran files.
#define FPP_CPP
The preprocessor to use for Fortran files.
#define FPP_PIPS_OPTIONS_ENV
#define FPP_PIPS_ENV

References concatenate(), db_get_directory_name_for_module(), FPP_CPP, FPP_CPPFLAGS, FPP_PIPS_ENV, FPP_PIPS_OPTIONS_ENV, free(), pips_basename(), safe_system_no_abort(), strdup(), and WORKSPACE_TMP_SPACE.

Referenced by process_thru_cpp().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ process_user_file()

bool process_user_file ( string  file)

The file is looked for in the pips source path.

Do not check the syntax in the input file: quite dangerous in case it is wrong because PIPS is not designed to work on damaged source codes. But this may be useful is the input file is a validation file or if the input file has already been checked.

If two modules have the same name, the first splitted wins and the other one is hidden by the call since fsplit gives it a zzz00n.f name Let's hope no user module is called ###???.f

The newly created module files are registered in the database The file_list allows split to communicate with this function.

a_line: "MODULE1 ... MODULEn file_name"

The list modules comes from entries that might be included in the subroutine.

For each Fortran module in the line, put the initial_file and user_file resource. In C, line should have only one entry and a C source file and a user file resources are created.

hey, that's cleaning!

Seems to be recorded as a resource, causes problems later when closing the workspace...

unlink(nfile);

Parameters
fileile

Definition at line 1090 of file source_file.c.

1091 {
1092  bool success_p = false, cpp_processed_p;
1093  string dir_name = db_get_current_workspace_directory();
1094 
1095  // FC: hmmm this function is not very strict,
1096  // and sometime we need clean user errors...
1097  bool generate_user_error =
1098  get_bool_property("ABORT_ON_USER_ERROR") ||
1099  get_bool_property("CLOSE_WORKSPACE_AND_QUIT_ON_ERROR");
1100 
1101  static int number_of_files = 0;
1102  static int number_of_modules = 0;
1103  static int resource_name_conflicts = 0;
1104 
1105  number_of_files++;
1106  pips_debug(1, "file %s (number %d)\n", file, number_of_files);
1107 
1108  /* The file is looked for in the pips source path.
1109  */
1110  string nfile = find_file_in_directories(file, getenv(SRCPATH));
1111 
1112  if (!nfile)
1113  {
1114  pips_user_error("Cannot open file: \"%s\"", file);
1115  return false;
1116  }
1117 
1118  string initial_file = nfile;
1120 
1121  // The new file is registered (well, not really...) in the database.
1122  user_log("Registering file %s\n", file);
1123 
1124  bool syntax_ok_p = true;
1125  if ((dot_F_file_p(nfile) || dot_f_file_p(nfile)) && pips_check_fortran())
1126  {
1127  // Note: a Fortran compiler is required on the machine.
1128  syntax_ok_p = check_fortran_syntax_before_pips(nfile);
1129  }
1130  else if (dot_c_file_p(nfile) && pips_check_c()) {
1131  // Note: a C compiler is required on the machine. Run it.
1132  syntax_ok_p = check_c_file_syntax(nfile);
1133  }
1134  else
1135  {
1136  /* Do not check the syntax in the input file: quite dangerous in
1137  case it is wrong because PIPS is not designed to work on
1138  damaged source codes. But this may be useful is the input file
1139  is a validation file or if the input file has already been
1140  checked. */
1141  pips_debug(1, "No syntactic check on file \"%s\"\n", nfile);
1142  }
1143 
1144  if (!syntax_ok_p)
1145  {
1146  if (generate_user_error)
1147  pips_user_error("Syntax check failed on \"%s\"", nfile);
1148  // It is up to the caller to decide if the syntax must be checked
1149  // for other files as well
1150  return false;
1151  }
1152 
1153  // CPP if file extension is .F or .c
1154  // (assumes string_equal_p(nfile, initial_file))
1155  cpp_processed_p = dot_F_file_p(nfile) || dot_c_file_p(nfile);
1156 
1157  if (cpp_processed_p)
1158  {
1159  user_log("Preprocessing file %s\n", initial_file);
1160  nfile = process_thru_cpp(initial_file);
1161  if (nfile==NULL)
1162  {
1163  if (generate_user_error)
1164  pips_user_error("Cannot preprocess file \"%s\"", initial_file);
1165  else
1166  pips_user_warning("Cannot preprocess file: %s\n", initial_file);
1167  return false;
1168  }
1169  }
1170  else if ( !dot_f_file_p( nfile ) && !dot_f90_file_p( nfile )
1171  && !dot_f95_file_p( nfile ) ) {
1172  pips_user_error("Unexpected file extension\n");
1173  }
1174 
1175  /* If two modules have the same name, the first splitted wins
1176  * and the other one is hidden by the call since fsplit gives
1177  * it a zzz00n.f name
1178  * Let's hope no user module is called ###???.f
1179  */
1180  string file_list =
1181  strdup(concatenate(dir_name,
1182  dot_c_file_p(nfile)?
1183  "/.csplit_file_list" : "/.fsplit_file_list", NULL));
1184  unlink(file_list);
1185 
1186  user_log("Splitting file %s\n", nfile);
1187  if (pips_split_file(nfile, file_list))
1188  {
1189  if (generate_user_error)
1190  pips_user_error("error while splitting file \"%s\"", nfile);
1191  return false;
1192  }
1193 
1194  /* The newly created module files are registered in the database
1195  * The file_list allows split to communicate with this function.
1196  */
1197  FILE * fd = safe_fopen(file_list, "r");
1198  string a_line;
1199  while ((a_line = safe_readline(fd)) && resource_name_conflicts == 0)
1200  {
1201  string mod_name = NULL, res_name = NULL;
1202  list modules = NIL;
1203  bool renamed=false;
1204 
1205  /* a_line: "MODULE1 ... MODULEn file_name"
1206  *
1207  * The list modules comes from entries that might be included
1208  * in the subroutine.
1209  */
1210  string file_name = extract_last_name(a_line);
1211  success_p = true;
1212  number_of_modules++;
1213  pips_debug(2, "module %s (number %d)\n", file_name, number_of_modules);
1214 
1215  while (mod_name!=a_line && (mod_name = extract_last_name(a_line)))
1216  modules = CONS(STRING, mod_name, modules);
1217 
1218  /* For each Fortran module in the line, put the initial_file and
1219  user_file resource. In C, line should have only one entry and a C
1220  source file and a user file resources are created. */
1221  FOREACH(STRING, mod_name, modules)
1222  {
1223  user_log(" Module %s\n", mod_name);
1224 
1225  if (!renamed)
1226  {
1227  FILE * rf = NULL;
1228 
1229  if (dot_c_file_p(nfile)) {
1230  res_name = db_build_file_resource_name
1231  (DBR_C_SOURCE_FILE, mod_name, C_FILE_SUFFIX);
1232  }
1233  else {
1234  res_name = db_build_file_resource_name
1235  (DBR_INITIAL_FILE, mod_name, FORTRAN_INITIAL_FILE_SUFFIX);
1236  }
1237 
1238  string abs_res = strdup(concatenate(dir_name, "/", res_name, NULL));
1239 
1240  if ((rf = fopen(abs_res, "r"))!=NULL)
1241  { // Resource name conflict
1242  string ofile =
1243  db_get_memory_resource(DBR_USER_FILE, mod_name, true);
1244 
1245  fclose(rf);
1246  pips_user_warning("Duplicate module name \"%s\""
1247  " from files \"%s\" and \"%s\".\n",
1248  res_name, ofile, nfile);
1249  resource_name_conflicts++;
1250  break;
1251  }
1252 
1253  if (rename(file_name, abs_res))
1254  pips_internal_error("mv %s %s failed", file_name, res_name);
1255  renamed = true;
1256  free(abs_res);
1257  }
1258 
1259  if(dot_c_file_p(nfile)) {
1260  DB_PUT_NEW_FILE_RESOURCE(DBR_C_SOURCE_FILE, mod_name,
1261  strdup(res_name));
1262  DB_PUT_NEW_FILE_RESOURCE(DBR_INPUT_FILE_NAME, mod_name,
1263  strdup(initial_file));
1264  }
1265  else {
1266  DB_PUT_NEW_FILE_RESOURCE(DBR_INITIAL_FILE, mod_name,
1267  strdup(res_name));
1268  }
1269  // from which file the initial source was derived.
1270  // absolute path to the file so that db moves should be ok?
1271  DB_PUT_NEW_FILE_RESOURCE(DBR_USER_FILE, mod_name, strdup(nfile));
1272 
1273  if ( dot_f90_file_p( nfile ) || dot_f95_file_p( nfile ) )
1274  {
1275  char *parsedcode_filename =
1276  get_resource_file_name(DBR_PARSED_CODE, mod_name);
1277  FILE *parsedcode_file = safe_fopen( parsedcode_filename, "r" );
1278  DB_PUT_NEW_FILE_RESOURCE(DBR_PARSED_CODE, mod_name,
1279  gen_read( parsedcode_file ));
1280  safe_fclose( parsedcode_file, parsedcode_filename );
1281  char *callees_filename =
1282  get_resource_file_name( DBR_CALLEES, mod_name );
1283  FILE *callees_file = safe_fopen( callees_filename, "r" );
1284  DB_PUT_NEW_FILE_RESOURCE(DBR_CALLEES, mod_name,
1285  gen_read( callees_file ) );
1286  safe_fclose( callees_file, callees_filename );
1287  string source_file_name =
1288  strdup(concatenate(dir_name, "/", mod_name, "/", mod_name, ".f90",
1289  NULL));
1290  DB_PUT_NEW_FILE_RESOURCE( DBR_SOURCE_FILE, mod_name, source_file_name );
1291  }
1292  }
1293 
1294  gen_free_list(modules), modules=NIL;
1295 
1296  if (res_name) free(res_name), res_name = NULL;
1297  free(a_line);
1298  }
1299 
1300  safe_fclose(fd, file_list);
1301  unlink(file_list);
1302  free(file_list);
1303  free(dir_name);
1304 
1305  if (cpp_processed_p) {
1306  free(initial_file); /* hey, that's cleaning! */
1308  }
1309 
1310  if (!success_p)
1311  {
1312  // empty file... ???
1313  pips_user_warning("No module was found when splitting file %s.\n", nfile);
1314  }
1315 
1316  if (cpp_processed_p) {
1317  // nfile is not the initial file
1318  pips_debug(1, "Remove output of preprocessing: %s\n", nfile);
1319  /* Seems to be recorded as a resource, causes problems later when
1320  closing the workspace... */
1321  /* unlink(nfile); */
1322  }
1323  free(nfile);
1324 
1325  // well, returns ok whether modules were found or not,
1326  // but do not accept name conflicts.
1327  return resource_name_conflicts==0;
1328 }
gen_chunk * gen_read(FILE *file)
GEN_READ reads any object from the FILE stream.
Definition: genClib.c:2323
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#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
string get_resource_file_name(const char *rname, const char *oname)
allocate a full file name for the given resource.
Definition: lowlevel.c:187
static string process_thru_cpp(string name)
Process a file through a C or Fortran preprocessor according to its type.
Definition: source_file.c:916
static bool check_c_file_syntax(string file_name)
Verify that the C syntax of a source file is correct by compiling it.
Definition: source_file.c:1034
static char * extract_last_name(char *line)
"foo bla fun ./e.database/foo.f" -> "./e.database/foo.f"
Definition: source_file.c:1050
static bool check_fortran_syntax_before_pips(string file_name)
Verify that the Fortran syntax of a source file is correct by compiling it.
Definition: source_file.c:1020
string preprocessor_current_initial_file_name
The digestion of a user file by PIPS begins here.
Definition: source_file.c:1088
static bool pips_check_fortran(void)
A Fortran compiler must be run or not before launching the PIPS Fortran parser, according to the envi...
Definition: source_file.c:955
static bool pips_split_file(string name, string tempfile)
Definition: source_file.c:586
static bool pips_check_c(void)
A C compiler must be run or not before launching the PIPS C parser, according to the environment vari...
Definition: source_file.c:968
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References check_c_file_syntax(), check_fortran_syntax_before_pips(), concatenate(), CONS, db_build_file_resource_name(), db_get_current_workspace_directory(), db_get_memory_resource(), DB_PUT_NEW_FILE_RESOURCE, dot_c_file_p(), dot_f90_file_p(), dot_f95_file_p(), dot_F_file_p(), dot_f_file_p(), extract_last_name(), file_name, find_file_in_directories(), FOREACH, free(), gen_free_list(), gen_read(), get_bool_property(), get_resource_file_name(), NIL, pips_check_c(), pips_check_fortran(), pips_debug, pips_internal_error, pips_split_file(), pips_user_error, pips_user_warning, preprocessor_current_initial_file_name, process_thru_cpp(), safe_fclose(), safe_fopen(), safe_readline(), SRCPATH, strdup(), STRING, string_undefined, and user_log().

Referenced by add_a_file(), ask_a_missing_file(), create_workspace(), retrieve_a_missing_file_using_external_resolver(), and retrieve_a_missing_file_using_internal_resolver().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ workspace_language()

language workspace_language ( gen_array_t  files)

Choose a language if all filenames in "files" have the same C or Fortran extensions.

Parameters
filesiles

Definition at line 667 of file source_file.c.

668 {
669  int i, argc = gen_array_nitems(files);
671  int n_fortran = 0;
672  int n_fortran95 = 0;
673  int n_c = 0;
674 
675  for (i = 0; i < argc; i++) {
676  string fn = gen_array_item(files, i);
677  if(dot_F_file_p(fn) || dot_f_file_p(fn))
678  n_fortran++;
679  else if(dot_c_file_p(fn))
680  n_c++;
681  else if(dot_f90_file_p(fn) || dot_f95_file_p(fn)){
682  n_fortran95++;
683  } else {
684  ;
685  }
686  }
687 
688  if(n_fortran>0 && n_fortran95==0 && n_c==0) {
689  l = make_language_fortran();
690  } else if(n_fortran==0 && n_fortran95>0 && n_c==0) {
692  } else if(n_fortran==0 && n_fortran95==0 && n_c>0) {
693  l = make_language_c();
694  } else {
695  l = make_language_unknown();
696  }
697 
698  return l;
699 }
language make_language_fortran95(void)
Definition: ri.c:1256
language make_language_fortran(void)
Definition: ri.c:1250
language make_language_unknown(void)
Definition: ri.c:1259
language make_language_c(void)
Definition: ri.c:1253
#define language_undefined
Definition: ri.h:1551

References dot_c_file_p(), dot_f90_file_p(), dot_f95_file_p(), dot_F_file_p(), dot_f_file_p(), gen_array_item(), gen_array_nitems(), language_undefined, make_language_c(), make_language_fortran(), make_language_fortran95(), and make_language_unknown().

Referenced by add_a_file(), and create_workspace().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ zzz_file_p()

static bool zzz_file_p ( string  s)
static

is the file name of the form .../zzz???.f

Definition at line 535 of file source_file.c.

536 {
537  int len = strlen(s)-1;
538  return len>=8 && s[len-8]=='/' && s[len-7]=='#' && s[len-6]=='#' &&
539  s[len-5]=='#' && s[len-1]=='.' && s[len]=='f';
540 }

Referenced by clean_file().

+ Here is the caller graph for this function:

Variable Documentation

◆ complex_cst2_rx

regex_t complex_cst2_rx
static

Definition at line 250 of file source_file.c.

Referenced by init_rx().

◆ complex_cst_rx

regex_t complex_cst_rx
static

Definition at line 249 of file source_file.c.

Referenced by init_rx().

◆ dcomplex_cst2_rx

regex_t dcomplex_cst2_rx
static

Definition at line 252 of file source_file.c.

Referenced by init_rx().

◆ dcomplex_cst_rx

regex_t dcomplex_cst_rx
static

Definition at line 251 of file source_file.c.

Referenced by init_rx().

◆ implicit_none_rx

regex_t implicit_none_rx
static

Definition at line 247 of file source_file.c.

Referenced by handle_file(), and init_rx().

◆ include_file_rx

regex_t include_file_rx
static

Definition at line 248 of file source_file.c.

Referenced by handle_file(), and init_rx().

◆ preprocessor_current_initial_file_name

string preprocessor_current_initial_file_name = string_undefined

The digestion of a user file by PIPS begins here.

The file is searched in the SRCPATH directories.

Definition at line 1088 of file source_file.c.

Referenced by csplit_copy(), csplit_parser_warning_alist(), and process_user_file().

◆ preprocessor_current_split_file_name

string preprocessor_current_split_file_name = string_undefined

Split a C or Fortran file into as many files as modules.

Definition at line 584 of file source_file.c.

Referenced by csplit_parser_warning_alist(), and pips_split_file().

◆ processed_cache

hash_table processed_cache = hash_table_undefined
static

cache of preprocessed includes

Definition at line 271 of file source_file.c.

Referenced by close_processed_include_cache(), get_cached(), handle_include_file(), and init_processed_include_cache().

◆ some_goto_rx

regex_t some_goto_rx
static

Definition at line 246 of file source_file.c.

Referenced by init_rx().

◆ user_file_directory

string user_file_directory = NULL
static

Definition at line 194 of file source_file.c.

Referenced by filter_file(), and find_file().