PIPS
csplit_file.c File Reference
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "genC.h"
#include "misc.h"
#include "constants.h"
#include "linear.h"
#include "ri.h"
#include "ri-util.h"
#include "pipsdbm.h"
#include "preprocessor.h"
#include "properties.h"
#include "splitc.h"
+ Include dependency graph for csplit_file.c:

Go to the source code of this file.

Functions

void init_module_name_list ()
 
void reset_module_name_list ()
 
void error_reset_module_name_list ()
 No checking, to be called from a (future) error handling module. More...
 
string get_splitc_input_file_name (void)
 
void reset_current_input_line (void)
 In file just above. More...
 
void csplit_open_compilation_unit (string input_file_name)
 Disambiguate the compilation unit base name (special character to avoid conflicts with function names and rank if same basename exists elsewhere in user files). More...
 
void csplit_close_compilation_unit ()
 
void copy_between_2_fd_up_to_offset (FILE *source, FILE *destination, unsigned long long up_to_offset, bool greedy_spaces __attribute__((__unused__)))
 Copy data from on file to another up to an offset. More...
 
void csplit_append_to_compilation_unit (int last_line, unsigned long long last_offset)
 Copy the input file to the compilation unit between the function declarations up to the current function definition. More...
 
static bool path_header_p (const char *filepath)
 
void csplit_copy (const char *module_name, string signature, int first_line, int last_line, size_t first_offset, size_t last_offset, int user_first_line, bool is_static_p)
 Create the module directory and file, copy the definition of the module and add the module name to the module name list. More...
 
void keep_track_of_typedef (string type_name)
 
void csplit_error_handler ()
 Close open files and reset variables. More...
 
void csplit_reset ()
 
void csplit_close_files (string file_name)
 
void preprocessor_init_keyword_typedef_table ()
 
string csplit (char *dir_name, char *file_name, FILE *out)
 

Variables

char * current_include_file_path = NULL
 used to keep track of include level
More...
 
char * current_file_path = NULL
 
static list module_name_list = list_undefined
 Kind of useless since a file is used to mimic fsplit. More...
 
static string splitc_input_file_name = string_undefined
 File management. More...
 
static FILE * splitc_in_append = NULL
 The FILE descriptor used to generate the compilation unit: More...
 
static int current_input_line = 0
 
static string current_compilation_unit_file_name = string_undefined
 
static string current_compilation_unit_name = string_undefined
 
static FILE * compilation_unit_file = NULL
 includes FILE_SEP_STRING as a suffix. More...
 
static FILE * module_list_file = NULL
 Compilation unit. More...
 
static string current_workspace_name = string_undefined
 
string current_file_name = string_undefined
 Split a C file into one file per module (function or procedure) plus. More...
 

Function Documentation

◆ copy_between_2_fd_up_to_offset()

void copy_between_2_fd_up_to_offset ( FILE *  source,
FILE *  destination,
unsigned long long  up_to_offset,
bool greedy_spaces   __attribute__(__unused__) 
)

Copy data from on file to another up to an offset.

The encountered newlines increase the value of global variable current_input_line.

If the character just after the "up_to_offset" one is a newline, it is output in the destination, since it is nicer to have line oriented source files.

Parameters
greedy_spacesis no longer used (used to be: if true, the copy is going on if encounter some spaces or comments on the same current line. The idea is to get a comment attached to the current statement but try to keep the comment for a function.

There is something to copy:

If the next character is a new line, we include it in the file:

Oops. It was not, "unread" it:

But if the last character was not a '
', end the file with one, that is cleaner:

Remove the greedy stuff since it should be dealt by the lexer... Well, not...

Definition at line 208 of file csplit_file.c.

211  {
212  int c = EOF;
213  int next_c = EOF;
214  while(((unsigned) ftell(source)) < up_to_offset) {
215  /* There is something to copy: */
216  c = fgetc(source);
217  if (c == EOF)
218  break;
219 
220  ifdebug(5)
221  putc(c, stderr);
222  fputc(c, destination);
223  if (c == '\n')
225  }
226  /* If the next character is a new line, we include it in the file: */
227  if ((next_c = fgetc(source)) == '\n') {
228  fputc(next_c, destination);
230  ifdebug(5)
231  putc(next_c, stderr);
232  }
233  else {
234  /* Oops. It was not, "unread" it: */
235  ungetc(next_c, source);
236  /* But if the last character was not a '\n', end the file with one,
237  that is cleaner: */
238  if (c != EOF && c != '\n') {
239  ifdebug(5)
240  putc('\n', stderr);
241  fputc('\n', destination);
242  }
243  }
244  /* Remove the greedy stuff since it should be dealt by the
245  lexer... Well, not... */
246 #if 0
247  while(isspace(c = fgetc(source))) {
248  ifdebug(5)
249  putc(c, stderr);
250  fputc(c, destination);
251  if (c == '\n')
253  }
254  /* Oops. It was not, "unread" it: */
255  ungetc(c, source);
256 #endif
257 }
static int current_input_line
Definition: csplit_file.c:91
if(!(yy_init))
Definition: genread_lex.c:1029
else
Definition: set.c:239
#define ifdebug(n)
Definition: sg.c:47

References current_input_line, and ifdebug.

Referenced by csplit_append_to_compilation_unit(), and csplit_copy().

+ Here is the caller graph for this function:

◆ csplit()

string csplit ( char *  dir_name,
char *  file_name,
FILE *  out 
)

In case a error occurs

The same file is opened twice for parsing, for copying the compilation unit and for copying the modules.

splitc_in_copy = safe_fopen(file_name, "r");

Do not forget to catch what could remain after the last function up to the end of file:

Parameters
dir_nameir_name
file_nameile_name
outut

Definition at line 641 of file csplit_file.c.

645 {
646  string error_message = string_undefined;
647  current_file_name = file_name; /* In case a error occurs*/
648 
649  debug_on("CSPLIT_DEBUG_LEVEL");
650 
651  pips_debug(1, "Begin in directory %s for file %s\n", dir_name, file_name);
652 
653  /* The same file is opened twice for parsing, for copying the
654  compilation unit and for copying the modules. */
655 
656  if ((splitc_in = fopen(file_name, "r")) == NULL) {
657  fprintf(stderr, "csplit: cannot open %s\n", file_name);
658  return "cannot open file";
659  }
661 
662  current_workspace_name = dir_name;
663 
665  /* splitc_in_copy = safe_fopen(file_name, "r"); */
666 
668 
674  current_file_path = NULL;
675 
677  error_message = "PIPS preprocessor parser error";
678  }
679  TRY {
680  splitc_parse();
681  error_message = NULL;
683  }
684 
685  if(error_message==NULL) {
686  /* Do not forget to catch what could remain after the last function up
687  to the end of file: */
688  csplit_append_to_compilation_unit(INT_MAX, ULLONG_MAX);
690 
691  csplit_reset();
692  }
693  debug_off();
694 
695  return error_message;
696 }
static FILE * out
Definition: alias_check.c:128
#define CATCH(what)
@ any_exception_error
catch all
#define UNCATCH(what)
#define TRY
char * current_file_path
Definition: csplit_file.c:52
static string splitc_input_file_name
File management.
Definition: csplit_file.c:82
string current_file_name
Split a C file into one file per module (function or procedure) plus.
Definition: csplit_file.c:640
static FILE * module_list_file
Compilation unit.
Definition: csplit_file.c:102
void csplit_open_compilation_unit(string input_file_name)
Disambiguate the compilation unit base name (special character to avoid conflicts with function names...
Definition: csplit_file.c:116
void csplit_reset()
Definition: csplit_file.c:539
static FILE * splitc_in_append
The FILE descriptor used to generate the compilation unit:
Definition: csplit_file.c:90
void preprocessor_init_keyword_typedef_table()
Definition: csplit_file.c:567
void csplit_close_files(string file_name)
Definition: csplit_file.c:547
static string current_workspace_name
Definition: csplit_file.c:104
char * current_include_file_path
used to keep track of include level
Definition: csplit_file.c:51
void csplit_append_to_compilation_unit(int last_line, unsigned long long last_offset)
Copy the input file to the compilation unit between the function declarations up to the current funct...
Definition: csplit_file.c:262
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define debug_off()
Definition: misc-local.h:160
#define string_undefined
Definition: newgen_types.h:40
FILE * splitc_in
Definition: preprocessor.h:174
void MakeTypedefStack()
Define some functions from the .l or .y since cproto cannot dig them out:
Definition: splitc.c:243
int splitc_parse()
void init_preprocessor_scope_stack(void)
Definition: splitc.c:274
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
static string file_name

References any_exception_error, CATCH, csplit_append_to_compilation_unit(), csplit_close_files(), csplit_open_compilation_unit(), csplit_reset(), current_file_name, current_file_path, current_include_file_path, current_workspace_name, debug_off, debug_on, file_name, fprintf(), init_preprocessor_scope_stack(), MakeTypedefStack(), module_list_file, out, pips_debug, preprocessor_init_keyword_typedef_table(), safe_fopen(), splitc_in, splitc_in_append, splitc_input_file_name, splitc_parse(), string_undefined, TRY, and UNCATCH.

Referenced by pips_split_file().

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

◆ csplit_append_to_compilation_unit()

void csplit_append_to_compilation_unit ( int  last_line,
unsigned long long  last_offset 
)

Copy the input file to the compilation unit between the function declarations up to the current function definition.

We are in the offset mode instead of line mode

Copy up to function begin

We are in the line-oreiented mode:

In some cases, e.g. two module definitions are contiguous, nothing has to be copied.

Parameters
last_lineast_line
last_offsetast_offset

Definition at line 262 of file csplit_file.c.

263  {
264  pips_debug(2, "append to compilation unit up-to line %d (from %d) or offset %llu\n",
265  last_line, current_input_line, last_offset);
266 
267  if (last_offset != 0) {
268  /* We are in the offset mode instead of line mode */
269  pips_debug(2, "copying to compilation unit file up to offset %llu, we are at currently at offset %lu\n",
270  last_offset, ftell(splitc_in_append));
273  last_offset,
274  true /* Copy up to function begin */);
275  }
276  else {
277  /* We are in the line-oreiented mode: */
278  pips_assert("last_line is positive", last_line >= 0);
279  pips_assert("if last_line is strictly less than current_input_line, then last_line is 0",
280  last_line >= current_input_line || last_line == 0);
281 
282  pips_assert("The compilation unit file is open", compilation_unit_file != NULL);
283 
284  if(last_line == 0)
285  current_input_line = 0;
286  else {
287  /* In some cases, e.g. two module definitions are contiguous, nothing
288  has to be copied. */
289  while(current_input_line < last_line) {
290  char c = fgetc(splitc_in_append);
291 
292  ifdebug(5)
293  putc(c, stderr);
294  fputc(c, compilation_unit_file);
295  if(c == '\n')
297  }
298  }
299  }
300 }
static FILE * compilation_unit_file
includes FILE_SEP_STRING as a suffix.
Definition: csplit_file.c:100
void copy_between_2_fd_up_to_offset(FILE *source, FILE *destination, unsigned long long up_to_offset, bool greedy_spaces __attribute__((__unused__)))
Copy data from on file to another up to an offset.
Definition: csplit_file.c:208
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172

References compilation_unit_file, copy_between_2_fd_up_to_offset(), current_input_line, ifdebug, pips_assert, pips_debug, and splitc_in_append.

Referenced by csplit(), and csplit_copy().

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

◆ csplit_close_compilation_unit()

void csplit_close_compilation_unit ( void  )

Definition at line 183 of file csplit_file.c.

184 {
191 }
static string current_compilation_unit_file_name
Definition: csplit_file.c:98
static string current_compilation_unit_name
Definition: csplit_file.c:99
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
void free(void *)
void reset_preprocessor_scope_stack(void)
Definition: splitc.c:280

References compilation_unit_file, current_compilation_unit_file_name, current_compilation_unit_name, free(), reset_preprocessor_scope_stack(), safe_fclose(), and string_undefined.

Referenced by csplit_close_files().

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

◆ csplit_close_files()

void csplit_close_files ( string  file_name)

No close, because this file descriptor is managed by the caller.

Parameters
file_nameile_name

Definition at line 547 of file csplit_file.c.

548 {
552  current_file_path=NULL;
555  splitc_in = NULL;
558  splitc_in_append = NULL;
559  /*
560  safe_fclose(splitc_in_copy, file_name);
561  splitc_in_copy = NULL;
562  */
563  /* No close, because this file descriptor is managed by the caller. */
564  module_list_file = NULL;
565 }
void csplit_close_compilation_unit()
Definition: csplit_file.c:183
void ForceResetTypedefStack(void)
Definition: splitc.c:259

References csplit_close_compilation_unit(), current_file_path, current_include_file_path, file_name, ForceResetTypedefStack(), free(), module_list_file, safe_fclose(), splitc_in, splitc_in_append, splitc_input_file_name, and string_undefined.

Referenced by csplit(), and csplit_parser_error().

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

◆ csplit_copy()

void csplit_copy ( const char *  module_name,
string  signature,
int  first_line,
int  last_line,
size_t  first_offset,
size_t  last_offset,
int  user_first_line,
bool  is_static_p 
)

Create the module directory and file, copy the definition of the module and add the module name to the module name list.

The compilation unit name used for static functions is retrieved from a global variable set by csplit_open_compilation_unit(), current_compilation_unit_name.

If first_offset and last_offset are not both 0, the module is found in the source file between these file offset instead of between lines first_line and int last_line.

Unambiguous, unless the user has given the same name to two functions.

MODULE_SEP_STRING,

string unambiguous_module_name = module_name;

Keep track of the existence of a C main function in the workspace

pips_assert("First line is strictly positive and lesser than last_line", first_line>0 && first_line<last_line);

Step 1: Define an unambiguous name and open the file if possible

Concatenate the unambigous compilation unit name and the module name

Note: the same static function may be declared twice in the compilation unit because the user is mistaken.

pips_internal_error("Not implemented yet.");

FILE_SEP_STRING,

The name should be unique in the workspace, but the user may have provided several module with the same name

Open the module code file for writing as the mfd FILE descriptor:

Such a module already exists

Possible access right problem?

Step 2: Copy the file source from the end of the last function definition up to the begin of the current one into the compilation unit to get variable and type declarations, etc.

Only bother in line-oriented mode

Step 3: Copy the function declaration in its module file, starting with its line number in the original file.

skip is up to the C preprocessor choice for local files: foo.c or ./foo.c.

It does not really matter because the ambiguity is taken care of by the PIPS C parser.

Begin and end are specified as line numbers:

Begin and end are specified as file offsets. First seek at the begin of the function:

Copy up to the function end:

Do not include trailing spaces

Step 4: Copy the function definition

Fabien: you could add here anything you might want to unsplit the file later. SG: what about inline static ? why add an extern qualifier ?

check for the static qualifier

or the extern qualifier

default to extern qualifier? Not mandatory, but expected by the C parser

Step 5: Keep track of the new module

SG hook: do not keep track of module declared inside a header not very reliable in the presence of used inline function in user header, so left apart as of now

Do not free unambiguous_module_name since it is already done in reset_csplit_current_beginning()

Parameters
module_nameodule_name
signatureignature
first_lineirst_line
last_lineast_line
first_offsetirst_offset
last_offsetast_offset
user_first_lineser_first_line
is_static_ps_static_p

Definition at line 334 of file csplit_file.c.

341 {
342  FILE * mfd = NULL;
343  /* Unambiguous, unless the user has given the same name to two functions. */
344  string unambiguous_module_file_name;
345  const char* unambiguous_module_name = is_static_p?
346  strdup(concatenate(current_compilation_unit_name, /* MODULE_SEP_STRING,*/ module_name, NULL)) :
347  module_name;
348  /* string unambiguous_module_name = module_name; */
349 
350  if(same_string_p(module_name, "main")) {
351  /* Keep track of the existence of a C main function in the workspace*/
352  // full_name() in split_file.c... but declared static
353  char * main_list = strdup(concatenate(current_workspace_name, "/", MAIN_FILE_NAMES, NULL));
354  FILE * fm = fopen(main_list, "a");
355  if (fm==NULL) {
356  fprintf(stderr, "fopen(\"%s\", ...) failed\n", main_list);
357  // FI: not user friendly...
358  abort();
359  }
360  fputs(module_name, fm);
361  putc('\n', fm);
362  fclose(fm);
363  free(main_list);
364  }
365 
366  /* pips_assert("First line is strictly positive and lesser than last_line",
367  first_line>0 && first_line<last_line); */
368  if(!(first_line > 0 && first_line <= last_line)) {
369  pips_user_error("Definition of function %s starts at line %d and ends a t line %d\n"
370  "PIPS assumes the function definition to start on a new line "
371  "after the function signature\n", module_name, first_line, last_line);
372  }
373  pips_assert("current_compilation_unit_name is defined",
375 
376  /* Step 1: Define an unambiguous name and open the file if possible */
377  if(is_static_p) {
378  /* Concatenate the unambigous compilation unit name and the module name */
379  /* Note: the same static function may be declared twice in the
380  compilation unit because the user is mistaken. */
381  /* pips_internal_error("Not implemented yet."); */
382  unambiguous_module_file_name
384  /* FILE_SEP_STRING, */ module_name, C_FILE_SUFFIX, NULL));
385  }
386  else {
387  /* The name should be unique in the workspace, but the user may have
388  provided several module with the same name */
389  unambiguous_module_file_name
390  = strdup(concatenate(current_workspace_name, "/", module_name, C_FILE_SUFFIX, NULL));
391  }
392 
393  /* Open the module code file for writing as the mfd FILE descriptor: */
394  pips_debug(1, "Begin for %s module \"%s\" from line %d to line %d (offset [%zd-%zd]) in compilation unit %s towards %s\n",
395  is_static_p? "static" : "global",
396  module_name,
397  first_line, last_line, first_offset, last_offset,
399  unambiguous_module_file_name);
400 
401  if((mfd=fopen(unambiguous_module_file_name, "r"))!=NULL) {
402  /* Such a module already exists */
403  pips_user_error("Duplicate function \"%s\".\n"
404  "Copy in file %s from input file %s is ignored\n"
405  "Check source code with a compiler or set property %s\n",
406  module_name,
407  unambiguous_module_file_name,
409  "PIPS_CHECK_FORTRAN");
410  }
411  else if((mfd=fopen(unambiguous_module_file_name, "w"))==NULL) {
412  /* Possible access right problem? */
413  pips_user_error("Access or creation right denied for %s\n",
414  unambiguous_module_file_name);
415  }
416 
417  pips_assert("The module file descriptor is defined", mfd!=NULL);
418 
419  /* Step 2: Copy the file source from the end of the last function
420  definition up to the begin of the current one into the compilation
421  unit to get variable and type declarations, etc. */
422  csplit_append_to_compilation_unit(first_line - 1, first_offset);
423 
424  pips_assert("Current position is OK", /* Only bother in line-oriented mode */
425  (first_offset != 0 || last_offset != 0) || current_input_line == first_line-1);
426 
427  /* Step 3: Copy the function declaration in its module file, starting
428  with its line number in the original file. */
429 
430  /* skip is up to the C preprocessor choice for local files: foo.c or
431  * ./foo.c.
432  *
433  * It does not really matter because the ambiguity is taken care of
434  * by the PIPS C parser.
435  */
436  int skip = 0;
437  char * p = (char *) preprocessor_current_initial_file_name;
438  if(*p=='.' && *(p+1)=='/')
439  skip = 2;
440  fprintf(mfd, "# %d \"%s\"\n", user_first_line,
442  //preprocessor_current_split_file_name);
443  if (first_offset == 0 && last_offset == 0) {
444  pips_debug(2, "copying to module file lines [%d-%d]\n",
445  current_input_line, last_line);
446  /* Begin and end are specified as line numbers: */
447  while(current_input_line<last_line) {
448  char c = fgetc(splitc_in_append);
449  ifdebug(5)
450  putc(c, stderr);
451  fputc(c, mfd);
452  if(c=='\n')
454  }
455  }
456  else {
457  pips_debug(2, "copying to module file offset [%zd-%zd]\n",
458  first_offset, last_offset);
459  /* Begin and end are specified as file offsets. First seek at the begin
460  of the function: */
461  //safe_fseek(splitc_in_append, first_offset, SEEK_SET, "splitc_in_append");
462  /* Copy up to the function end: */
464  mfd,
465  last_offset,
466  false /* Do not include trailing spaces */);
467  }
468 
469  /* Step 4: Copy the function definition */
470  /* Fabien: you could add here anything you might want to unsplit the
471  file later.
472  SG: what about inline static ? why add an extern qualifier ?
473  */
474  /* check for the static qualifier */
475  char * where;
476  if( (where = strstr(signature,"static") ) &&
477  isspace(where[sizeof("static")-1]) &&
478  ( where == signature || isspace(where[-1]) )
479  ) {
480  fprintf(compilation_unit_file, "# %d \"%s\"\n", user_first_line,
482  fprintf(compilation_unit_file, "%s;\n", signature);
483  }
484  /* or the extern qualifier */
485  else if ( (where = strstr(signature,"extern") ) &&
486  isspace(where[sizeof("extern")-1]) &&
487  ( where == signature || isspace(where[-1]) )
488  ){
489  fprintf(compilation_unit_file, "%s;\n", signature);
490  }
491  /* default to extern qualifier? Not mandatory, but expected by the C parser */
492  else {
493  fprintf(compilation_unit_file, "# %d \"%s\"\n", (int) user_first_line,
495  fprintf(compilation_unit_file, "extern %s;\n", signature);
496  // fprintf(compilation_unit_file, "%s;\n", signature);
497  }
498 
499  /* Step 5: Keep track of the new module */
500  /* SG hook: do not keep track of module declared inside a header
501  * not very reliable in the presence of used inline function in user header,
502  * so left apart as of now
503  */
504  if(true || !get_bool_property("IGNORE_FUNCTION_IN_HEADER")
506  fprintf(module_list_file, "%s %s\n", unambiguous_module_name, unambiguous_module_file_name);
507  }
508 
509 
510  safe_fclose(mfd, unambiguous_module_file_name);
511  free(unambiguous_module_file_name);
512  /* Do not free unambiguous_module_name since it is already done in
513  reset_csplit_current_beginning() */
514  //free(unambiguous_module_name);
515 }
static bool path_header_p(const char *filepath)
Definition: csplit_file.c:318
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define abort()
Definition: misc-local.h:53
#define pips_user_error
Definition: misc-local.h:147
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
#define string_undefined_p(s)
Definition: newgen_types.h:41
#define MAIN_FILE_NAMES
Name of the file containing the names of the main procedures.
Definition: pipsdbm-local.h:41
string preprocessor_current_initial_file_name
The digestion of a user file by PIPS begins here.
Definition: source_file.c:1088
char * strdup()

References abort, compilation_unit_file, concatenate(), copy_between_2_fd_up_to_offset(), csplit_append_to_compilation_unit(), current_compilation_unit_name, current_include_file_path, current_input_line, current_workspace_name, fprintf(), free(), get_bool_property(), ifdebug, MAIN_FILE_NAMES, module_list_file, module_name(), path_header_p(), pips_assert, pips_debug, pips_user_error, preprocessor_current_initial_file_name, safe_fclose(), same_string_p, splitc_in_append, splitc_input_file_name, strdup(), and string_undefined_p.

+ Here is the call graph for this function:

◆ csplit_error_handler()

void csplit_error_handler ( void  )

Close open files and reset variables.

Reset keyword table

Definition at line 531 of file csplit_file.c.

532 {
533  /* Reset keyword table */
537 }
void reset_current_input_line(void)
In file just above.
Definition: csplit_file.c:93
void reset_csplit_line_number()
Reinitialise global position numbers for a new file.
Definition: lexer.c:1124
void free_keyword_typedef_table(void)
Definition: static.c:275

References free_keyword_typedef_table(), reset_csplit_line_number(), and reset_current_input_line().

Referenced by csplit_parser_error().

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

◆ csplit_open_compilation_unit()

void csplit_open_compilation_unit ( string  input_file_name)

Disambiguate the compilation unit base name (special character to avoid conflicts with function names and rank if same basename exists elsewhere in user files).

Do not create the corresponding directory and within it the compilation unit file.

Initialize compilation_unit_file by opening this last file.

Set the current_compilation_unit_file_name.

string compilation_unit_name = string_undefined;

string compilation_unit_file_name = string_undefined;

Step 1: Define the compilation unit name from the input file name.

Loop with a counter until the open is OK. Two or more files with the same local names may be imported from different directories.

This does not work because this file is later moved in the proper directory.

Loop over counter not implemented.

Does this current compilation unit already exist?

Keep track of the new compilation unit as a "module" stored in a file

Parameters
input_file_namenput_file_name

Definition at line 116 of file csplit_file.c.

117 {
118  string unambiguous_file_name = string_undefined;
119  string simpler_file_name = pips_basename(input_file_name, PP_C_ED);
120  /* string compilation_unit_name = string_undefined; */
121  /* string compilation_unit_file_name = string_undefined; */
122 
123  pips_debug(1, "Open compilation unit \"%s\"\n", input_file_name);
124 
125  pips_assert("No current compilation unit",
127 
128  pips_assert("No current compilation unit",
130 
131  /* Step 1: Define the compilation unit name from the input file name. */
132  unambiguous_file_name = strdup(concatenate(current_workspace_name,
133  "/",
134  simpler_file_name,
136  C_FILE_SUFFIX,
137  NULL));
138 
139  /* Loop with a counter until the open is OK. Two or more files with the
140  same local names may be imported from different directories. */
141  /* This does not work because this file is later moved in the proper directory. */
142  /*
143  if(fopen(unambiguous_file_name, "r")!=NULL) {
144  pips_internal_error("Two source files (at least) with same name: \"%s\"",
145  simpler_file_name);
146  }
147  */
148  compilation_unit_file = safe_fopen(unambiguous_file_name, "w");
149 
150  /* Loop over counter not implemented. */
151 
152  pips_assert("compilation_unit_file is defined",
153  compilation_unit_file != NULL);
154 
155  current_compilation_unit_file_name = unambiguous_file_name;
157  = strdup(concatenate(simpler_file_name, FILE_SEP_STRING, NULL));
158 
159  /* Does this current compilation unit already exist? */
161  "/",
162  simpler_file_name,
164  "/",
165  simpler_file_name,
167  C_FILE_SUFFIX, NULL)
168  , "r")!=NULL) {
169  pips_user_error("Two source files (at least) with same name: \"%s"
170  C_FILE_SUFFIX "\".\n"
171  "Not supported yet.\n",
172  simpler_file_name);
173  }
174 
175  /* Keep track of the new compilation unit as a "module" stored in a file */
176 
177  fprintf(module_list_file, "%s %s\n",
180  free(simpler_file_name);
181 }
char * pips_basename(char *fullpath, char *suffix)
Definition: file.c:822
#define FILE_SEP_STRING
Definition: naming-local.h:41

References compilation_unit_file, concatenate(), current_compilation_unit_file_name, current_compilation_unit_name, current_workspace_name, FILE_SEP_STRING, fprintf(), free(), module_list_file, pips_assert, pips_basename(), pips_debug, pips_user_error, safe_fopen(), strdup(), string_undefined, and string_undefined_p.

Referenced by csplit().

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

◆ csplit_reset()

void csplit_reset ( void  )

Reset keyword table

Definition at line 539 of file csplit_file.c.

540 {
541  /* Reset keyword table */
545 }

References free_keyword_typedef_table(), reset_csplit_line_number(), and reset_current_input_line().

Referenced by csplit().

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

◆ error_reset_module_name_list()

void error_reset_module_name_list ( void  )

No checking, to be called from a (future) error handling module.

Definition at line 74 of file csplit_file.c.

75 {
78 }
static list module_name_list
Kind of useless since a file is used to mimic fsplit.
Definition: csplit_file.c:56
void reset_module_name_list()
Definition: csplit_file.c:65
#define list_undefined_p(c)
Return if a list is undefined.
Definition: newgen_list.h:75

References list_undefined_p, module_name_list, and reset_module_name_list().

+ Here is the call graph for this function:

◆ get_splitc_input_file_name()

string get_splitc_input_file_name ( void  )

Definition at line 84 of file csplit_file.c.

85 {
87 }

References splitc_input_file_name.

◆ init_module_name_list()

void init_module_name_list ( void  )

Definition at line 58 of file csplit_file.c.

59 {
60  pips_assert("module_name_list is undefined",
63 }
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47

References list_undefined_p, module_name_list, NIL, and pips_assert.

◆ keep_track_of_typedef()

void keep_track_of_typedef ( string  type_name)
Parameters
type_nameype_name

Definition at line 517 of file csplit_file.c.

518 {
519  string sn = get_preprocessor_current_scope();
520  string scoped_type_name = same_string_p(sn,"")? strdup(type_name)
521  : strdup(concatenate(type_name, "%", sn, NULL));
522  hash_put(keyword_typedef_table, scoped_type_name, (void *) TK_NAMED_TYPE);
523  pips_debug(2,"Add typedef name \"%s\" to hash table\n", scoped_type_name);
524  if(strcmp(type_name, "v1")==0) {
525  pips_debug(1, "v1 added as typedef\n");
526  }
527  // FI: should we free "name"?
528 }
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
string get_preprocessor_current_scope(void)
Definition: splitc.c:327
hash_table keyword_typedef_table
Because of typedefs, the C lexers need help to decide if a character string such as toto is a type na...
Definition: static.c:253
#define TK_NAMED_TYPE
Definition: splitc.c:760

References concatenate(), get_preprocessor_current_scope(), hash_put(), keyword_typedef_table, pips_debug, same_string_p, strdup(), and TK_NAMED_TYPE.

+ Here is the call graph for this function:

◆ path_header_p()

static bool path_header_p ( const char *  filepath)
static

Definition at line 318 of file csplit_file.c.

318  {
319  return filepath &&
320  filepath[strlen(filepath)-1] != 'c';
321 }

Referenced by csplit_copy().

+ Here is the caller graph for this function:

◆ preprocessor_init_keyword_typedef_table()

void preprocessor_init_keyword_typedef_table ( void  )

FI: keyword_typedef_table is also a global variable. I am trying to move towards some kind of functional wrapping around the global variable, which I would like to declare static in ri-util/static.c.

GNU predefined type(s), expecting no conflict with user named type

AM: en attendant mieux...

typedef names are added later when encoutered.

Definition at line 567 of file csplit_file.c.

568 {
569  /* FI: keyword_typedef_table is also a global variable. I am trying
570  * to move towards some kind of functional wrapping around the
571  * global variable, which I would like to declare static in
572  * ri-util/static.c.
573  */
575  hash_put(keyword_typedef_table,"auto", (char *) TK_AUTO);
576  hash_put(keyword_typedef_table,"break", (char *) TK_BREAK);
577  hash_put(keyword_typedef_table,"case", (char *) TK_CASE);
578  hash_put(keyword_typedef_table,"char", (char *) TK_CHAR);
579  hash_put(keyword_typedef_table,"const", (char *) TK_CONST);
580  hash_put(keyword_typedef_table,"__const", (char *) TK_CONST);
581  hash_put(keyword_typedef_table,"continue", (char *) TK_CONTINUE);
582  hash_put(keyword_typedef_table,"default", (char *) TK_DEFAULT);
583  hash_put(keyword_typedef_table,"do", (char *) TK_DO);
584  hash_put(keyword_typedef_table,"double", (char *) TK_DOUBLE);
585  hash_put(keyword_typedef_table,"else", (char *) TK_ELSE);
586  hash_put(keyword_typedef_table,"enum", (char *) TK_ENUM);
587  hash_put(keyword_typedef_table,"extern", (char *) TK_EXTERN);
588  hash_put(keyword_typedef_table,"float", (char *) TK_FLOAT);
589  hash_put(keyword_typedef_table,"for", (char *) TK_FOR);
590  hash_put(keyword_typedef_table,"goto", (char *) TK_GOTO);
591  hash_put(keyword_typedef_table,"if", (char *) TK_IF);
592  hash_put(keyword_typedef_table,"inline", (char *) TK_INLINE);
593  hash_put(keyword_typedef_table,"int", (char *) TK_INT);
594  hash_put(keyword_typedef_table,"__int128_t", (char *) TK_INT128);
595  hash_put(keyword_typedef_table,"__uint128_t", (char *) TK_UINT128);
596  hash_put(keyword_typedef_table,"_Complex", (char *) TK_COMPLEX);
597  hash_put(keyword_typedef_table,"long", (char *) TK_LONG);
598  hash_put(keyword_typedef_table,"register", (char *) TK_REGISTER);
599  hash_put(keyword_typedef_table,"restrict", (char *) TK_RESTRICT);
600  hash_put(keyword_typedef_table,"__restrict", (char *) TK_RESTRICT);
601  hash_put(keyword_typedef_table,"__restrict__", (char *) TK_RESTRICT);
602  hash_put(keyword_typedef_table,"return", (char *) TK_RETURN);
603  hash_put(keyword_typedef_table,"short", (char *) TK_SHORT);
604  hash_put(keyword_typedef_table,"signed", (char *) TK_SIGNED);
605  hash_put(keyword_typedef_table,"sizeof", (char *) TK_SIZEOF);
606  hash_put(keyword_typedef_table,"static", (char *) TK_STATIC);
607  hash_put(keyword_typedef_table,"struct", (char *) TK_STRUCT);
608  hash_put(keyword_typedef_table,"switch", (char *) TK_SWITCH);
609  hash_put(keyword_typedef_table,"__thread", (char *) TK_THREAD);
610  hash_put(keyword_typedef_table,"typedef", (char *) TK_TYPEDEF);
611  hash_put(keyword_typedef_table,"union", (char *) TK_UNION);
612  hash_put(keyword_typedef_table,"unsigned", (char *) TK_UNSIGNED);
613  hash_put(keyword_typedef_table,"void", (char *) TK_VOID);
614  hash_put(keyword_typedef_table,"volatile", (char *) TK_VOLATILE);
615  hash_put(keyword_typedef_table,"while", (char *) TK_WHILE);
616  hash_put(keyword_typedef_table,"__builtin_va_arg", (char *) TK_BUILTIN_VA_ARG);
617  hash_put(keyword_typedef_table,"asm", (char *) TK_ASM);
618  hash_put(keyword_typedef_table,"__asm__", (char *) TK_ASM);
619  hash_put(keyword_typedef_table,"__volatile__", (char *) TK_VOLATILE);
620 
621  /* GNU predefined type(s), expecting no conflict with user named type */
622 
623  hash_put(keyword_typedef_table,"__builtin_va_list", (char *) TK_NAMED_TYPE);
624  hash_put(keyword_typedef_table,"_Bool", (char *) TK_NAMED_TYPE);
625 
626  /* AM: en attendant mieux... */
627  hash_put(keyword_typedef_table,"STEP_ARG", (char *) TK_NAMED_TYPE);
628 
629  /* typedef names are added later when encoutered. */
630 }
hash_table make_keyword_typedef_table(int)
Definition: static.c:256
#define TK_STATIC
Definition: splitc.c:782
#define TK_BREAK
Definition: splitc.c:837
#define TK_SHORT
Definition: splitc.c:779
#define TK_WHILE
Definition: splitc.c:844
#define TK_RESTRICT
Definition: splitc.c:784
#define TK_INT128
Definition: splitc.c:766
#define TK_RETURN
Definition: splitc.c:840
#define TK_INLINE
Definition: splitc.c:850
#define TK_THREAD
Definition: splitc.c:787
#define TK_CASE
Definition: splitc.c:842
#define TK_REGISTER
Definition: splitc.c:786
#define TK_COMPLEX
Definition: splitc.c:771
#define TK_GOTO
Definition: splitc.c:839
#define TK_STRUCT
Definition: splitc.c:773
#define TK_SIZEOF
Definition: splitc.c:789
#define TK_CONST
Definition: splitc.c:783
#define TK_VOID
Definition: splitc.c:770
#define TK_UINT128
Definition: splitc.c:767
#define TK_INT
Definition: splitc.c:765
#define TK_LONG
Definition: splitc.c:778
#define TK_FOR
Definition: splitc.c:846
#define TK_FLOAT
Definition: splitc.c:769
#define TK_SIGNED
Definition: splitc.c:776
#define TK_BUILTIN_VA_ARG
Definition: splitc.c:856
#define TK_SWITCH
Definition: splitc.c:841
#define TK_VOLATILE
Definition: splitc.c:780
#define TK_CONTINUE
Definition: splitc.c:838
#define TK_ELSE
Definition: splitc.c:848
#define TK_EXTERN
Definition: splitc.c:781
#define TK_ENUM
Definition: splitc.c:772
#define TK_IF
Definition: splitc.c:847
#define TK_CHAR
Definition: splitc.c:764
#define TK_AUTO
Definition: splitc.c:785
#define TK_TYPEDEF
Definition: splitc.c:774
#define TK_DO
Definition: splitc.c:845
#define TK_DEFAULT
Definition: splitc.c:843
#define TK_DOUBLE
Definition: splitc.c:768
#define TK_UNSIGNED
Definition: splitc.c:777
#define TK_UNION
Definition: splitc.c:775
#define TK_ASM
Definition: splitc.c:851

References hash_put(), keyword_typedef_table, make_keyword_typedef_table(), TK_ASM, TK_AUTO, TK_BREAK, TK_BUILTIN_VA_ARG, TK_CASE, TK_CHAR, TK_COMPLEX, TK_CONST, TK_CONTINUE, TK_DEFAULT, TK_DO, TK_DOUBLE, TK_ELSE, TK_ENUM, TK_EXTERN, TK_FLOAT, TK_FOR, TK_GOTO, TK_IF, TK_INLINE, TK_INT, TK_INT128, TK_LONG, TK_NAMED_TYPE, TK_REGISTER, TK_RESTRICT, TK_RETURN, TK_SHORT, TK_SIGNED, TK_SIZEOF, TK_STATIC, TK_STRUCT, TK_SWITCH, TK_THREAD, TK_TYPEDEF, TK_UINT128, TK_UNION, TK_UNSIGNED, TK_VOID, TK_VOLATILE, and TK_WHILE.

Referenced by csplit().

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

◆ reset_current_input_line()

void reset_current_input_line ( void  )

In file just above.

Definition at line 93 of file csplit_file.c.

94 {
96 }

References current_input_line.

Referenced by csplit_error_handler(), and csplit_reset().

+ Here is the caller graph for this function:

◆ reset_module_name_list()

void reset_module_name_list ( void  )

Definition at line 65 of file csplit_file.c.

66 {
67  pips_assert("module_name_list is not undefined",
71 }
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69

References gen_free_list(), list_undefined, list_undefined_p, module_name_list, and pips_assert.

Referenced by error_reset_module_name_list().

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

Variable Documentation

◆ compilation_unit_file

FILE* compilation_unit_file = NULL
static

includes FILE_SEP_STRING as a suffix.

Definition at line 100 of file csplit_file.c.

Referenced by csplit_append_to_compilation_unit(), csplit_close_compilation_unit(), csplit_copy(), and csplit_open_compilation_unit().

◆ current_compilation_unit_file_name

string current_compilation_unit_file_name = string_undefined
static

Definition at line 98 of file csplit_file.c.

Referenced by csplit_close_compilation_unit(), and csplit_open_compilation_unit().

◆ current_compilation_unit_name

string current_compilation_unit_name = string_undefined
static

◆ current_file_name

string current_file_name = string_undefined

Split a C file into one file per module (function or procedure) plus.

Parameters
dir_namethe directory name where the input file is to pick
file_namethe C input file name to split
outfile opened to record module and compilation unit names
Returns
an error message or NULL if no error has occurred.

Definition at line 640 of file csplit_file.c.

Referenced by csplit(), and csplit_parser_error().

◆ current_file_path

char* current_file_path = NULL

Definition at line 52 of file csplit_file.c.

Referenced by csplit(), and csplit_close_files().

◆ current_include_file_path

char* current_include_file_path = NULL

used to keep track of include level

csplit_file.c

Definition at line 51 of file csplit_file.c.

Referenced by csplit(), csplit_close_files(), and csplit_copy().

◆ current_input_line

int current_input_line = 0
static

◆ current_workspace_name

string current_workspace_name = string_undefined
static

Definition at line 104 of file csplit_file.c.

Referenced by csplit(), csplit_copy(), and csplit_open_compilation_unit().

◆ module_list_file

FILE* module_list_file = NULL
static

Compilation unit.

Definition at line 102 of file csplit_file.c.

Referenced by csplit(), csplit_close_files(), csplit_copy(), and csplit_open_compilation_unit().

◆ module_name_list

list module_name_list = list_undefined
static

Kind of useless since a file is used to mimic fsplit.

Definition at line 56 of file csplit_file.c.

Referenced by error_reset_module_name_list(), init_module_name_list(), and reset_module_name_list().

◆ splitc_in_append

FILE* splitc_in_append = NULL
static

The FILE descriptor used to generate the compilation unit:

Definition at line 90 of file csplit_file.c.

Referenced by csplit(), csplit_append_to_compilation_unit(), csplit_close_files(), and csplit_copy().

◆ splitc_input_file_name

string splitc_input_file_name = string_undefined
static

File management.

Definition at line 82 of file csplit_file.c.

Referenced by csplit(), csplit_close_files(), csplit_copy(), and get_splitc_input_file_name().