PIPS
csplit_file.c
Go to the documentation of this file.
1 /*
2 
3  $Id: csplit_file.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /*
28  * Split one C file into one compilation module declaration file and one
29  * file for each C function found. The input C file is assumed
30  * preprocessed.
31  */
32 
33 #include <stdio.h>
34 #include <string.h>
35 #include <ctype.h>
36 
37 #include "genC.h"
38 #include "misc.h"
39 
40 #include "constants.h"
41 #include "linear.h"
42 #include "ri.h"
43 #include "ri-util.h" // make_keyword_typedef_table() & al.
44 #include "pipsdbm.h" // for constant MAIN_FILE_NAMES
45 #include "preprocessor.h"
46 #include "properties.h" // IGNORE_FUNCTION_IN_HEADER
47 
48 #include "splitc.h"
49 
50 /* used to keep track of include level */
52 char * current_file_path = NULL;
53 
54 ␌
55 /* Kind of useless since a file is used to mimic fsplit */
57 
59 {
60  pips_assert("module_name_list is undefined",
63 }
64 
66 {
67  pips_assert("module_name_list is not undefined",
71 }
72 
73 /* No checking, to be called from a (future) error handling module. */
75 {
78 }
79 ␌
80 /* File management*/
81 
83 
85 {
87 }
88 
89 /* The FILE descriptor used to generate the compilation unit: */
90 static FILE * splitc_in_append = NULL;
91 static int current_input_line = 0; /* In file just above */
92 
94 {
96 }
97 
99 static string current_compilation_unit_name = string_undefined; /* includes FILE_SEP_STRING as a suffix. */
100 static FILE * compilation_unit_file = NULL; /* Compilation unit*/
101 
102 static FILE * module_list_file = NULL;
103 
105 
106 /* Disambiguate the compilation unit base name (special character to avoid
107  * conflicts with function names and rank if same basename exists
108  * elsewhere in user files).
109  *
110  * Do not create the corresponding directory and within it the compilation unit file.
111  *
112  * Initialize compilation_unit_file by opening this last file.
113  *
114  * Set the current_compilation_unit_file_name.
115  * */
116 void csplit_open_compilation_unit(string input_file_name)
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 }
182 
184 {
191 }
192 
193 
194 /* Copy data from on file to another up to an offset.
195 
196  The encountered newlines increase the value of global variable
197  current_input_line.
198 
199  If the character just after the "up_to_offset" one is a newline, it is
200  output in the destination, since it is nicer to have line oriented
201  source files.
202 
203  @param greedy_spaces is no longer used (used to be: if true, the copy
204  is going on if encounter some spaces or comments on the same current
205  line. The idea is to get a comment attached to the current statement
206  but try to keep the comment for a function.
207 */
209  FILE * destination,
210  unsigned long long up_to_offset,
211  bool greedy_spaces __attribute__ ((__unused__))) {
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 }
258 
259 
260 /* Copy the input file to the compilation unit between the function
261  declarations up to the current function definition. */
263  unsigned long long last_offset) {
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 }
301 
302 
303 /*
304 static void csplit_skip(FILE * f, int lines)
305 {
306  int i = 0;
307 
308  pips_assert("the number of lines to be skipped is positive", lines>0);
309 
310  while(i<lines) {
311  char c = fgetc(f);
312 
313  if(c=='\n')
314  i++;
315  }
316 }
317 */
318 static bool path_header_p(const char * filepath) {
319  return filepath &&
320  filepath[strlen(filepath)-1] != 'c';
321 }
322 
323 /* Create the module directory and file, copy the definition of the module
324  and add the module name to the module name list.
325 
326  The compilation unit name used for static functions is retrieved from a
327  global variable set by csplit_open_compilation_unit(),
328  current_compilation_unit_name.
329 
330  If first_offset and last_offset are not both 0, the module is found in the
331  source file between these file offset instead of between lines
332  first_line and int last_line.
333  */
334 void csplit_copy(const char* module_name,
335  string signature,
336  int first_line,
337  int last_line,
338  size_t first_offset,
339  size_t last_offset,
340  int user_first_line, bool is_static_p)
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 }
516 
517 void keep_track_of_typedef(string type_name)
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 }
529 
530 /* Close open files and reset variables */
532 {
533  /* Reset keyword table */
537 }
538 
540 {
541  /* Reset keyword table */
545 }
546 
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 }
566 ␌
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 }
631 ␌
632 /** Split a C file into one file per module (function or procedure) plus
633 
634  @param dir_name the directory name where the input file is to pick
635  @param file_name the C input file name to split
636  @param out file opened to record module and compilation unit names
637 
638  @return an error message or NULL if no error has occurred.
639 */
641 string csplit(
642  char * dir_name,
643  char * file_name,
644  FILE * out)
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 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
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 list module_name_list
Kind of useless since a file is used to mimic fsplit.
Definition: csplit_file.c:56
void csplit_close_compilation_unit()
Definition: csplit_file.c:183
void init_module_name_list()
Definition: csplit_file.c:58
void csplit_error_handler()
Close open files and reset variables.
Definition: csplit_file.c:531
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 th...
Definition: csplit_file.c:334
static string splitc_input_file_name
File management.
Definition: csplit_file.c:82
void reset_current_input_line(void)
In file just above.
Definition: csplit_file.c:93
string current_file_name
Split a C file into one file per module (function or procedure) plus.
Definition: csplit_file.c:640
static string current_compilation_unit_file_name
Definition: csplit_file.c:98
static FILE * compilation_unit_file
includes FILE_SEP_STRING as a suffix.
Definition: csplit_file.c:100
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 reset_module_name_list()
Definition: csplit_file.c:65
void csplit_reset()
Definition: csplit_file.c:539
string csplit(char *dir_name, char *file_name, FILE *out)
Definition: csplit_file.c:641
static string current_compilation_unit_name
Definition: csplit_file.c:99
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
string get_splitc_input_file_name(void)
Definition: csplit_file.c:84
char * current_include_file_path
used to keep track of include level
Definition: csplit_file.c:51
void error_reset_module_name_list()
No checking, to be called from a (future) error handling module.
Definition: csplit_file.c:74
void keep_track_of_typedef(string type_name)
Definition: csplit_file.c:517
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
static bool path_header_p(const char *filepath)
Definition: csplit_file.c:318
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
static int current_input_line
Definition: csplit_file.c:91
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
char * pips_basename(char *fullpath, char *suffix)
Definition: file.c:822
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void free(void *)
#define list_undefined_p(c)
Return if a list is undefined.
Definition: newgen_list.h:75
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
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
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 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 pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160
#define abort()
Definition: misc-local.h:53
#define pips_user_error
Definition: misc-local.h:147
#define FILE_SEP_STRING
Definition: naming-local.h:41
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
#define string_undefined
Definition: newgen_types.h:40
#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
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 reset_csplit_line_number()
Reinitialise global position numbers for a new file.
Definition: lexer.c:1124
void ForceResetTypedefStack(void)
Definition: splitc.c:259
void reset_preprocessor_scope_stack(void)
Definition: splitc.c:280
string preprocessor_current_initial_file_name
The digestion of a user file by PIPS begins here.
Definition: source_file.c:1088
string get_preprocessor_current_scope(void)
Definition: splitc.c:327
void init_preprocessor_scope_stack(void)
Definition: splitc.c:274
void free_keyword_typedef_table(void)
Definition: static.c:275
hash_table make_keyword_typedef_table(int)
Definition: static.c:256
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
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
#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_NAMED_TYPE
Definition: splitc.c:760
#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
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
static string file_name