PIPS
|
#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"
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... | |
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.
greedy_spaces | is 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.
References current_input_line, and ifdebug.
Referenced by csplit_append_to_compilation_unit(), and csplit_copy().
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:
dir_name | ir_name |
file_name | ile_name |
out | ut |
Definition at line 641 of file csplit_file.c.
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().
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.
last_line | ast_line |
last_offset | ast_offset |
Definition at line 262 of file csplit_file.c.
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().
void csplit_close_compilation_unit | ( | void | ) |
Definition at line 183 of file csplit_file.c.
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().
void csplit_close_files | ( | string | file_name | ) |
No close, because this file descriptor is managed by the caller.
file_name | ile_name |
Definition at line 547 of file csplit_file.c.
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().
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()
module_name | odule_name |
signature | ignature |
first_line | irst_line |
last_line | ast_line |
first_offset | irst_offset |
last_offset | ast_offset |
user_first_line | ser_first_line |
is_static_p | s_static_p |
Definition at line 334 of file csplit_file.c.
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.
void csplit_error_handler | ( | void | ) |
Close open files and reset variables.
Reset keyword table
Definition at line 531 of file csplit_file.c.
References free_keyword_typedef_table(), reset_csplit_line_number(), and reset_current_input_line().
Referenced by csplit_parser_error().
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
input_file_name | nput_file_name |
Definition at line 116 of file csplit_file.c.
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().
void csplit_reset | ( | void | ) |
Reset keyword table
Definition at line 539 of file csplit_file.c.
References free_keyword_typedef_table(), reset_csplit_line_number(), and reset_current_input_line().
Referenced by csplit().
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.
References list_undefined_p, module_name_list, and reset_module_name_list().
string get_splitc_input_file_name | ( | void | ) |
Definition at line 84 of file csplit_file.c.
References splitc_input_file_name.
void init_module_name_list | ( | void | ) |
Definition at line 58 of file csplit_file.c.
References list_undefined_p, module_name_list, NIL, and pips_assert.
void keep_track_of_typedef | ( | string | type_name | ) |
type_name | ype_name |
Definition at line 517 of file csplit_file.c.
References concatenate(), get_preprocessor_current_scope(), hash_put(), keyword_typedef_table, pips_debug, same_string_p, strdup(), and TK_NAMED_TYPE.
|
static |
Definition at line 318 of file csplit_file.c.
Referenced by csplit_copy().
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.
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().
void reset_current_input_line | ( | void | ) |
In file just above.
Definition at line 93 of file csplit_file.c.
References current_input_line.
Referenced by csplit_error_handler(), and csplit_reset().
void reset_module_name_list | ( | void | ) |
Definition at line 65 of file csplit_file.c.
References gen_free_list(), list_undefined, list_undefined_p, module_name_list, and pips_assert.
Referenced by error_reset_module_name_list().
|
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().
|
static |
Definition at line 98 of file csplit_file.c.
Referenced by csplit_close_compilation_unit(), and csplit_open_compilation_unit().
|
static |
Definition at line 99 of file csplit_file.c.
Referenced by csplit_close_compilation_unit(), csplit_copy(), and csplit_open_compilation_unit().
string current_file_name = string_undefined |
Split a C file into one file per module (function or procedure) plus.
dir_name | the directory name where the input file is to pick |
file_name | the C input file name to split |
out | file opened to record module and compilation unit names |
Definition at line 640 of file csplit_file.c.
Referenced by csplit(), and csplit_parser_error().
char* current_file_path = NULL |
Definition at line 52 of file csplit_file.c.
Referenced by csplit(), and csplit_close_files().
char* current_include_file_path = NULL |
used to keep track of include level
Definition at line 51 of file csplit_file.c.
Referenced by csplit(), csplit_close_files(), and csplit_copy().
|
static |
Definition at line 91 of file csplit_file.c.
Referenced by copy_between_2_fd_up_to_offset(), csplit_append_to_compilation_unit(), csplit_copy(), and reset_current_input_line().
|
static |
Definition at line 104 of file csplit_file.c.
Referenced by csplit(), csplit_copy(), and csplit_open_compilation_unit().
|
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().
|
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().
|
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().
|
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().