moved
This commit is contained in:
515
Sapfor/_src/ProjectManipulation/ConvertFiles.cpp
Normal file
515
Sapfor/_src/ProjectManipulation/ConvertFiles.cpp
Normal file
@@ -0,0 +1,515 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../Utils/errors.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../Utils/utils.h"
|
||||
|
||||
#include "../VerificationCode/verifications.h"
|
||||
|
||||
#include "ConvertFiles.h"
|
||||
#include "calls.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern int v_print;
|
||||
extern int warn_all;
|
||||
extern int unparse_functions;
|
||||
extern int opt_base;
|
||||
extern int opt_loop_range;
|
||||
|
||||
extern graph_node* cur_node;
|
||||
extern graph_node* node_list;
|
||||
|
||||
extern "C" int out_free_form;
|
||||
extern "C" int out_upper_case;
|
||||
extern "C" int out_line_unlimit;
|
||||
extern "C" int out_line_length;
|
||||
extern "C" PTR_SYMB last_file_symbol;
|
||||
|
||||
static int convertFile(int argc, char* argv[], const set<string>& filesInProj, const set<string>& moduleDeclsInFiles)
|
||||
{
|
||||
FILE* fout = NULL;
|
||||
FILE* fout_cuf = NULL, * fout_C_cu = NULL, * fout_info = NULL; /*ACC*/
|
||||
const char* fout_name = NULL;
|
||||
char* fout_name_cuf; /*ACC*/
|
||||
char* fout_name_C_cu; /*ACC*/
|
||||
char* fout_name_info_C; /*ACC*/
|
||||
|
||||
char* source_name;
|
||||
int level, hpf, openmp, isz, dvm_type_size;
|
||||
int a_mode = 0;
|
||||
|
||||
initialize();
|
||||
|
||||
openmp = hpf = 0; dvm_type_size = 0;
|
||||
|
||||
argv++;
|
||||
while ((argc > 1) && (*argv)[0] == '-')
|
||||
{
|
||||
if ((*argv)[1] == 'o' && ((*argv)[2] == '\0')) {
|
||||
if (filesInProj.size() == 1)
|
||||
fout_name = argv[1];
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-dc"))
|
||||
check_regim = 1;
|
||||
else if (!strcmp(argv[0], "-dbif1"))
|
||||
dbg_if_regim = 1;
|
||||
else if (!strcmp(argv[0], "-dbif2"))
|
||||
dbg_if_regim = 2;
|
||||
else if (!strcmp(argv[0], "-speedL0")) /* for dedugging ACROSS-scheme */
|
||||
options.setOn(SPEED_TEST_L0); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-speedL1")) /* for dedugging ACROSS-scheme */
|
||||
options.setOn(SPEED_TEST_L1); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-dmpi"))
|
||||
deb_mpi = 1;
|
||||
else if (!strcmp(argv[0], "-dnoind"))
|
||||
d_no_index = 1;
|
||||
else if (!strcmp(argv[0], "-dperf")) {
|
||||
debug_regim = 1;
|
||||
omp_debug = DPERF;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-dvmLoopAnalysisEC")) /*ACC*/
|
||||
{
|
||||
options.setOn(LOOP_ANALYSIS);
|
||||
options.setOn(OPT_EXP_COMP);
|
||||
}
|
||||
else if (!strcmp(argv[0], "-dvmIrregAnalysis")) /*ACC*/
|
||||
{
|
||||
options.setOn(LOOP_ANALYSIS);
|
||||
options.setOn(OPT_EXP_COMP);
|
||||
options.setOn(GPU_IRR_ACC);
|
||||
}
|
||||
else if (!strcmp(argv[0], "-dvmLoopAnalysis")) /*ACC*/
|
||||
options.setOn(LOOP_ANALYSIS);
|
||||
else if (!strcmp(argv[0], "-dvmPrivateAnalysis")) /*ACC*/
|
||||
options.setOn(PRIVATE_ANALYSIS);
|
||||
else if ((*argv)[1] == 'd') {
|
||||
switch ((*argv)[2]) {
|
||||
case '0': level = 0; break;
|
||||
case '1': level = 1; omp_debug = D1; /*OMP*/ break;
|
||||
case '2': level = 2; omp_debug = D2; /*OMP*/ break;
|
||||
case '3': level = 3; omp_debug = D3; /*OMP*/ break;
|
||||
case '4': level = 4; omp_debug = D4; /*OMP*/ break;
|
||||
case '5': level = 5; omp_debug = D5; /*OMP*/ break;
|
||||
/* case '5': level = -1; many_files=1; break;*/
|
||||
default: level = -1;
|
||||
}
|
||||
if (level > 0)
|
||||
debug_regim = 1;
|
||||
if ((*argv)[3] == '\0')
|
||||
AddToFragmentList(0, 0, level, -1);
|
||||
else if ((*argv)[3] == ':')
|
||||
FragmentList(*argv + 4, level, -1);
|
||||
}
|
||||
else if ((*argv)[1] == 'e') {
|
||||
switch ((*argv)[2]) {
|
||||
case '0': level = 0; break;
|
||||
case '1': level = 1; break;
|
||||
case '2': level = 2; break;
|
||||
case '3': level = 3; break;
|
||||
case '4': level = 4; break;
|
||||
case 'm': omp_perf = 1; break;
|
||||
default: level = -1;
|
||||
}
|
||||
if ((*argv)[3] == '\0')
|
||||
AddToFragmentList(0, 0, -1, level);
|
||||
else if ((*argv)[3] == ':')
|
||||
FragmentList(*argv + 4, -1, level);
|
||||
}
|
||||
else if (!strcmp(argv[0], "-spf"))
|
||||
{
|
||||
fprintf(stderr, "Illegal option -spf \n");
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-p")) {
|
||||
only_debug = 0; hpf = 0;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-s")) {
|
||||
only_debug = 1; hpf = 0;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-v"))
|
||||
v_print = 1;
|
||||
else if (!strcmp(argv[0], "-w"))
|
||||
warn_all = 1;
|
||||
else if (!strcmp(argv[0], "-bind0"))
|
||||
bind_ = 0;
|
||||
else if (!strcmp(argv[0], "-bind1"))
|
||||
bind_ = 1;
|
||||
else if (!strcmp(argv[0], "-t8"))
|
||||
dvm_type_size = 8;
|
||||
else if (!strcmp(argv[0], "-t4"))
|
||||
dvm_type_size = 4;
|
||||
else if (!strcmp(argv[0], "-r8"))
|
||||
default_real_size = 8;
|
||||
else if (!strcmp(argv[0], "-i8"))
|
||||
default_integer_size = 8;
|
||||
else if (!strcmp(argv[0], "-hpf") || !strcmp(argv[0], "-hpf1") || !strcmp(argv[0], "-hpf2"))
|
||||
hpf = 1;
|
||||
else if (!strcmp(argv[0], "-mp")) {
|
||||
OMP_program = 1; /*OMP*/
|
||||
openmp = 1;
|
||||
}
|
||||
//else if (!strcmp(argv[0],"-ta"))
|
||||
// ACC_program = 1;
|
||||
else if (!strcmp(argv[0], "-noH"))
|
||||
ACC_program = 0;
|
||||
else if (!strcmp(argv[0], "-noCudaType")) /*ACC*/
|
||||
undefined_Tcuda = 1;
|
||||
else if (!strcmp(argv[0], "-noCuda"))
|
||||
options.setOn(NO_CUDA); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-noPureFunc"))
|
||||
options.setOn(NO_PURE_FUNC); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-C_Cuda")) /*ACC*/
|
||||
options.setOn(C_CUDA);
|
||||
else if (!strcmp(argv[0], "-FTN_Cuda") || !strcmp(argv[0], "-F_Cuda")) /*ACC*/
|
||||
options.setOff(C_CUDA);
|
||||
else if (!strcmp(argv[0], "-no_blocks_info") || !strcmp(argv[0], "-noBI"))
|
||||
options.setOn(NO_BL_INFO); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-cacheIdx"))
|
||||
options.setOff(NO_BL_INFO); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-Ohost")) /*ACC*/
|
||||
options.setOn(O_HOST);
|
||||
else if (!strcmp(argv[0], "-noOhost")) /*ACC*/
|
||||
options.setOff(O_HOST);
|
||||
else if (!strcmp(argv[0], "-Opl2")) /*ACC*/
|
||||
{
|
||||
parloop_by_handler = 2;
|
||||
options.setOn(O_HOST);
|
||||
options.setOn(O_PL2);
|
||||
// options.setOn(NO_CUDA);
|
||||
}
|
||||
else if (!strcmp(argv[0], "-Opl")) /*ACC*/
|
||||
{
|
||||
parloop_by_handler = 1;
|
||||
options.setOn(O_PL);
|
||||
}
|
||||
else if (!strcmp(argv[0], "-oneThread")) /*ACC*/
|
||||
options.setOn(ONE_THREAD);
|
||||
else if (!strcmp(argv[0], "-noTfm")) /*ACC*/
|
||||
options.setOff(AUTO_TFM);
|
||||
else if (!strcmp(argv[0], "-autoTfm")) /*ACC*/
|
||||
options.setOn(AUTO_TFM);
|
||||
else if (!strcmp(argv[0], "-gpuO0")) /*ACC*/
|
||||
options.setOn(GPU_O0);
|
||||
else if (!strcmp(argv[0], "-gpuO1")) /*ACC*/
|
||||
options.setOn(GPU_O1);
|
||||
else if (!strcmp(argv[0], "-rtc")) /*ACC*/
|
||||
options.setOn(RTC); //for NVRTC compilation and execution
|
||||
else if (!strcmp(argv[0], "-ffo"))
|
||||
out_free_form = 1;
|
||||
else if (!strcmp(argv[0], "-upcase"))
|
||||
out_upper_case = 1;
|
||||
else if (!strcmp(argv[0], "-noLimitLine"))
|
||||
out_line_unlimit = 1;
|
||||
else if (!strcmp(argv[0], "-uniForm"))
|
||||
{
|
||||
out_free_form = 1;
|
||||
out_line_length = 72;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-noRemote"))
|
||||
options.setOn(NO_REMOTE);
|
||||
else if (!strcmp(argv[0], "-lgstd"))
|
||||
{
|
||||
(void)fprintf(stderr, "Illegal option -lgstd \n");
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-byFunUnparse"))
|
||||
unparse_functions = 1;
|
||||
else if (!strncmp(argv[0], "-bufio", 6)) {
|
||||
if ((*argv)[6] != '\0' && (isz = is_integer_value(*argv + 6)))
|
||||
IOBufSize = isz;
|
||||
}
|
||||
else if (!strncmp(argv[0], "-bufUnparser", 12)) {
|
||||
if ((*argv)[12] != '\0' && (isz = is_integer_value(*argv + 12)))
|
||||
UnparserBufSize = isz * 1024 * 1024;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-ioRTS"))
|
||||
options.setOn(IO_RTS);
|
||||
else if (!strcmp(argv[0], "-read_all"))
|
||||
options.setOn(READ_ALL);
|
||||
else if (!strcmp(argv[0], "-Obase"))
|
||||
opt_base = 1;
|
||||
else if (!strcmp(argv[0], "-Oloop_range"))
|
||||
opt_loop_range = 1;
|
||||
else if ((*argv)[1] == 'H') {
|
||||
if ((*argv)[2] == 's' && (*argv)[3] == 'h' && (*argv)[4] == 'w') {
|
||||
if ((*argv)[5] != '\0' && (all_sh_width = is_integer_value(*argv + 5)))
|
||||
;
|
||||
}
|
||||
else if (!strcmp(*argv + 2, "nora"))
|
||||
no_rma = 1;
|
||||
else if (!strcmp(*argv + 2, "oneq"))
|
||||
one_inquiry = 1;
|
||||
else if (!strcmp(*argv + 2, "onlyl"))
|
||||
only_local = 1;
|
||||
}
|
||||
else if (!strncmp(argv[0], "-collapse", 9))
|
||||
if ((*argv)[9] != '\0' && (collapse_loop_count = is_integer_value(*argv + 9)));
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
// Check options combinations
|
||||
options.checkCombinations();
|
||||
|
||||
// definition of DvmType size: len_DvmType
|
||||
// len_DvmType==0, if DvmType-size == default_integer_size == 4
|
||||
if (bind_ == 1)
|
||||
len_DvmType = 8; //sizeof(long) == 8
|
||||
if (dvm_type_size)
|
||||
len_DvmType = dvm_type_size;
|
||||
if (len_DvmType == 0 && default_integer_size == 8)
|
||||
len_DvmType = 4;
|
||||
|
||||
if (ACC_program && debug_regim && !only_debug)
|
||||
{
|
||||
fprintf(stderr, "Warning: -noH option is set to debug mode\n");
|
||||
ACC_program = 0;
|
||||
}
|
||||
if (parloop_by_handler > 0 && debug_regim)
|
||||
{
|
||||
fprintf(stderr, "Warning: -Opl/Opl2 option is ignored in debug mode\n");
|
||||
parloop_by_handler = 0;
|
||||
options.setOff(O_PL);
|
||||
options.setOff(O_PL2);
|
||||
}
|
||||
|
||||
if (openmp && ACC_program)
|
||||
{
|
||||
fprintf(stderr, "Warning: -noH option is set to -mp mode\n");
|
||||
ACC_program = 0;
|
||||
}
|
||||
if (parloop_by_handler == 2 && !options.isOn(O_HOST))
|
||||
{
|
||||
fprintf(stderr, "Warning: -Ohost option is set to -Opl2 mode\n");
|
||||
options.setOn(O_HOST);
|
||||
}
|
||||
if (out_free_form == 1 && out_line_length == 72 && out_line_unlimit == 1)
|
||||
{
|
||||
fprintf(stderr, "Warning: -noLimitLine and -uniForm options are incompatible; -noLimitLine option is ignored\n");
|
||||
out_line_unlimit = 0;
|
||||
}
|
||||
|
||||
if (v_print)
|
||||
(void)fprintf(stderr, "<<<<< Translating >>>>>\n");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
string proj_name = "fdvm__";
|
||||
static int id = 0;
|
||||
|
||||
vector<char*> filesList;
|
||||
for (auto& file : filesInProj)
|
||||
filesList.push_back((char*)file.c_str());
|
||||
|
||||
SgProject project((proj_name + to_string(id++)).c_str(), filesList.data(), filesList.size());
|
||||
|
||||
shiftLines(&project, false);
|
||||
for (int z = 0; z < project.numberOfFiles(); ++z) {
|
||||
vector<SgStatement*> tmp;
|
||||
removeExecutableFromModuleDeclaration(&(project.file(z)), filesInProj, tmp);
|
||||
}
|
||||
|
||||
SgFile* file = NULL;
|
||||
addNumberOfFileToAttribute(&project);
|
||||
|
||||
//----------------------------
|
||||
ProjectStructure(project);
|
||||
Private_Vars_Project_Analyzer();
|
||||
//----------------------------
|
||||
|
||||
initVariantNames(); //for project
|
||||
initIntrinsicFunctionNames(); //for project
|
||||
initSupportedVars(); // for project, acc_f2c.cpp
|
||||
initF2C_FunctionCalls(); // for project, acc_f2c.cpp
|
||||
for (int id = project.numberOfFiles() - 1; id >= 0; id--)
|
||||
{
|
||||
file = &(project.file(id));
|
||||
fin_name = new char[strlen(project.fileName(id)) + 2];
|
||||
sprintf(fin_name, "%s%s", project.fileName(id), " ");
|
||||
|
||||
if (fout_name == NULL)
|
||||
fout_name = doOutFileName(file->filename());
|
||||
|
||||
if (fout_name && source_name && !strcmp(source_name, fout_name))
|
||||
{
|
||||
fprintf(stderr, "Output file has the same name as source file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("convert %d to %s\n", id, fout_name);
|
||||
|
||||
fout_name_cuf = ChangeFtoCuf(fout_name); /*ACC*/
|
||||
fout_name_C_cu = ChangeFto_C_Cu(fout_name); /*ACC*/
|
||||
fout_name_info_C = ChangeFto_info_C(fout_name); /*ACC*/
|
||||
|
||||
//set the last symbol of file
|
||||
initLibNames(); //for every file
|
||||
InitDVM(file); //for every file
|
||||
current_file = file; // global variable (used in SgTypeComplex)
|
||||
max_lab = getLastLabelId();
|
||||
|
||||
if (dbg_if_regim)
|
||||
GetLabel();
|
||||
|
||||
TranslateFileDVM(file);
|
||||
|
||||
if (err_cnt) {
|
||||
fprintf(stderr, "%d error(s)\n", err_cnt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!fout_name) {
|
||||
file->unparsestdout();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//writing result of converting into file
|
||||
if ((fout = fopen(fout_name, "w")) == NULL) {
|
||||
fprintf(stderr, "Can't open file %s for write\n", fout_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GeneratedForCuda()) /*ACC*/
|
||||
{
|
||||
if ((fout_C_cu = fopen(fout_name_C_cu, "w")) == NULL) {
|
||||
fprintf(stderr, "Can't open file %s for write\n", fout_name_C_cu);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!options.isOn(C_CUDA)) {
|
||||
if ((fout_cuf = fopen(fout_name_cuf, "w")) == NULL) {
|
||||
fprintf(stderr, "Can't open file %s for write\n", fout_name_cuf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fout_info = fopen(fout_name_info_C, "w")) == NULL) {
|
||||
fprintf(stderr, "Can't open file %s for write\n", fout_name_info_C);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (v_print)
|
||||
fprintf(stderr, "<<<<< Unparsing %s >>>>>\n", fout_name);
|
||||
|
||||
if (mod_gpu) /*ACC*/
|
||||
UnparseTo_CufAndCu_Files(file, fout_cuf, fout_C_cu, fout_info);
|
||||
|
||||
const string fileN = file->filename();
|
||||
set<SgStatement*> toRemove;
|
||||
|
||||
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
|
||||
{
|
||||
if (st->fileName() != fileN)
|
||||
{
|
||||
if (st->variant() == MODULE_STMT && moduleDeclsInFiles.find(st->fileName()) != moduleDeclsInFiles.end())
|
||||
{
|
||||
toRemove.insert(st);
|
||||
st = st->lastNodeOfStmt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& toRem : toRemove)
|
||||
toRem->extractStmt();
|
||||
|
||||
if (unparse_functions)
|
||||
UnparseFunctionsOfFile(file, fout);
|
||||
else if (UnparserBufSize)
|
||||
file->unparseS(fout, UnparserBufSize);
|
||||
else
|
||||
file->unparse(fout);
|
||||
|
||||
if ((fclose(fout)) < 0) {
|
||||
fprintf(stderr, "Could not close %s\n", fout_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GeneratedForCuda()) {
|
||||
if ((fclose(fout_C_cu)) < 0) {
|
||||
fprintf(stderr, "Could not close %s\n", fout_name_C_cu);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!options.isOn(C_CUDA)) {
|
||||
if ((fclose(fout_cuf)) < 0) {
|
||||
fprintf(stderr, "Could not close %s\n", fout_name_cuf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fclose(fout_info)) < 0) {
|
||||
fprintf(stderr, "Could not close %s\n", fout_name_info_C);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
fout_name = NULL;
|
||||
}
|
||||
|
||||
if (v_print)
|
||||
fprintf(stderr, "\n***** Done *****\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void preprocess(const vector<string>& files, map<string, set<string>>& moduleUsesByFile, map<string, string>& moduleDecls)
|
||||
{
|
||||
vector<char*> filesList;
|
||||
for (int z = 0; z < files.size(); ++z)
|
||||
filesList.push_back((char*)files[z].c_str());
|
||||
|
||||
SgProject tmpProj("preproc", filesList.data(), files.size());
|
||||
|
||||
for (int z = 0; z < tmpProj.numberOfFiles(); ++z)
|
||||
{
|
||||
SgFile* file = &(tmpProj.file(z));
|
||||
fillModuleUse(file, moduleUsesByFile, moduleDecls);
|
||||
}
|
||||
|
||||
InitializeTable();
|
||||
}
|
||||
|
||||
void convertFiles(int argc, char* argv[], const char* proj_name)
|
||||
{
|
||||
vector<char*> args_v;
|
||||
for (int z = 0; z < argc; ++z)
|
||||
args_v.push_back(argv[z]);
|
||||
|
||||
const string fileText = readFileToStr(proj_name);
|
||||
vector<string> files;
|
||||
set<string> filesInSet;
|
||||
splitString(fileText, '\n', files);
|
||||
|
||||
for (auto& file : files)
|
||||
filesInSet.insert(file);
|
||||
|
||||
map<string, set<string>> moduleUsesByFile;
|
||||
map<string, string> moduleDecls;
|
||||
set<string> moduleDeclsInFiles;
|
||||
|
||||
preprocess(files, moduleUsesByFile, moduleDecls);
|
||||
for (auto& elem : moduleDecls)
|
||||
moduleDeclsInFiles.insert(elem.second);
|
||||
|
||||
int codes = 0;
|
||||
//for (auto& file : files)
|
||||
{
|
||||
codes += convertFile(args_v.size(), args_v.data(), filesInSet, moduleDeclsInFiles);
|
||||
|
||||
cur_node = node_list = NULL;
|
||||
InitializeTable();
|
||||
}
|
||||
|
||||
if (codes == 0)
|
||||
printf("Convertation was completed successfully\n");
|
||||
exit(0);
|
||||
}
|
||||
3
Sapfor/_src/ProjectManipulation/ConvertFiles.h
Normal file
3
Sapfor/_src/ProjectManipulation/ConvertFiles.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void convertFiles(int argc, char* argv[], const char* proj_name = "dvm.proj");
|
||||
105
Sapfor/_src/ProjectManipulation/FileInfo.cpp
Normal file
105
Sapfor/_src/ProjectManipulation/FileInfo.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "FileInfo.h"
|
||||
#include "../Utils/utils.h"
|
||||
#include "../Utils/errors.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static int tmp_id = 0;
|
||||
static string tmp_name = "tmp_conv_";
|
||||
|
||||
extern "C" int out_free_form;
|
||||
extern "C" int out_line_length;
|
||||
|
||||
//convert through unparce
|
||||
void FileInfo::convertToUniform()
|
||||
{
|
||||
int old_free = out_free_form;
|
||||
int old_line = out_line_length;
|
||||
|
||||
out_free_form = 1;
|
||||
out_line_length = 72;
|
||||
|
||||
__spf_print(1, "covnert to uniform %s file\n", fileName.c_str());
|
||||
|
||||
if (error != 0)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
if (outDepPath == "")
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
vector<char*> filesList;
|
||||
filesList.push_back((char*)outDepPath.c_str());
|
||||
|
||||
const string name = tmp_name + to_string(tmp_id++);
|
||||
SgProject* tmpProj = new SgProject(name.c_str(), filesList.data(), 1);
|
||||
|
||||
if (tmpProj == NULL)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
SgFile* currF = &tmpProj->file(0);
|
||||
|
||||
string text = string(currF->firstStatement()->unparse());
|
||||
writeFileFromStr(fileName, text);
|
||||
|
||||
out_free_form = old_free;
|
||||
out_line_length = old_line;
|
||||
|
||||
InitializeTable();
|
||||
}
|
||||
|
||||
string FileInfo::convertStyle(bool needRewrite)
|
||||
{
|
||||
string tmp_text = text;
|
||||
|
||||
vector<string> splited;
|
||||
splitString(tmp_text, '\n', splited);
|
||||
|
||||
tmp_text = "";
|
||||
int z = 0;
|
||||
for (auto& line : splited)
|
||||
{
|
||||
if (line[0] == 'c' || line[0] == 'C' || line[0] == 'd' || line[0] == 'D' || line[0] == '*')
|
||||
line[0] = '!';
|
||||
|
||||
bool needContinuation = false;
|
||||
if (line[0] != '!' && line.size() > 6)
|
||||
{
|
||||
if (line[5] != ' ' && !(line[5] > '0' && line[5] < '9')) // not label
|
||||
{
|
||||
line[5] = ' ';
|
||||
needContinuation = true;// line[5] = '&';
|
||||
}
|
||||
|
||||
int p = 73;
|
||||
if (style == 1)
|
||||
p = 133;
|
||||
if (line.size() > p)
|
||||
{
|
||||
while (line[p] != '\0' && line[p] != '\n' && line[p] != '!')
|
||||
{
|
||||
line[p] = ' ';
|
||||
p++;
|
||||
if (p >= line.size())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needContinuation)
|
||||
tmp_text += "&";
|
||||
tmp_text += (z != 0 ? "\n" : "") + line;
|
||||
++z;
|
||||
}
|
||||
|
||||
if (needRewrite)
|
||||
writeFileFromStr(fileName, tmp_text);
|
||||
|
||||
return tmp_text;
|
||||
}
|
||||
51
Sapfor/_src/ProjectManipulation/FileInfo.h
Normal file
51
Sapfor/_src/ProjectManipulation/FileInfo.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
struct FileInfo
|
||||
{
|
||||
FileInfo()
|
||||
{
|
||||
fileName = "";
|
||||
options = "";
|
||||
errPath = "";
|
||||
outPath = "";
|
||||
outDepPath = "";
|
||||
text = "";
|
||||
error = -1;
|
||||
includesAdded = 0;
|
||||
style = -1;
|
||||
lvl = 0;
|
||||
}
|
||||
|
||||
FileInfo(const std::string& _fileName, const std::string& _options, const std::string& _errPath, const std::string& _outPath,
|
||||
const std::string& _outDepPath, const std::string& _text, int errorInit = -1)
|
||||
{
|
||||
fileName = _fileName;
|
||||
options = _options;
|
||||
errPath = _errPath;
|
||||
outPath = _outPath;
|
||||
outDepPath = _outDepPath;
|
||||
text = _text;
|
||||
error = errorInit;
|
||||
includesAdded = 0;
|
||||
style = -1;
|
||||
lvl = 0;
|
||||
}
|
||||
|
||||
int error;
|
||||
std::string fileName;
|
||||
std::string options;
|
||||
std::string errPath;
|
||||
std::string outPath;
|
||||
std::string outDepPath;
|
||||
std::string text;
|
||||
int style; // -1 unk, 0 fixed, 1 fixed ext, 2 free, 3 uniform
|
||||
int includesAdded;
|
||||
std::set<std::string> includes;
|
||||
int lvl;
|
||||
|
||||
std::string convertStyle(bool needRewrite = true);
|
||||
void convertToUniform();
|
||||
};
|
||||
793
Sapfor/_src/ProjectManipulation/ParseFiles.cpp
Normal file
793
Sapfor/_src/ProjectManipulation/ParseFiles.cpp
Normal file
@@ -0,0 +1,793 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
#include <locale>
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
#include <stack>
|
||||
|
||||
#include "../Utils/errors.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../VisualizerCalls/get_information.h"
|
||||
#include "../VisualizerCalls/SendMessage.h"
|
||||
|
||||
#include "ParseFiles.h"
|
||||
#include "StdCapture.h"
|
||||
#include "FileInfo.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" int parse_file(int argc, char* argv[], char* proj_name);
|
||||
|
||||
static void findModuleDeclInProject(const string& name, const vector<string>& files, map<string, string>& modDecls)
|
||||
{
|
||||
vector<char*> filesList;
|
||||
for (int z = 0; z < files.size(); ++z)
|
||||
filesList.push_back((char*)files[z].c_str());
|
||||
|
||||
SgProject* tmpProj = new SgProject(name.c_str(), filesList.data(), files.size());
|
||||
|
||||
int numF = tmpProj->numberOfFiles();
|
||||
for (int z = 0; z < numF; ++z)
|
||||
{
|
||||
vector<SgStatement*> modules;
|
||||
SgFile* currF = &tmpProj->file(z);
|
||||
string fileName = currF->filename();
|
||||
convertToLower(fileName);
|
||||
|
||||
findModulesInFile(currF, modules);
|
||||
for (auto& elem : modules)
|
||||
{
|
||||
if (string(elem->fileName()) == currF->filename())
|
||||
{
|
||||
const string name = elem->symbol()->identifier();
|
||||
auto it = modDecls.find(name);
|
||||
if (it != modDecls.end() && it->second != currF->filename())
|
||||
{
|
||||
__spf_print(1, "found several module declaration of '%s' in files '%s' and '%s'\n", name.c_str(), it->second.c_str(), currF->filename());
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
else
|
||||
modDecls.insert(it, make_pair(name, currF->filename()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InitializeTable();
|
||||
}
|
||||
|
||||
static void createIncludeOrder(vector<string> &toIncl,
|
||||
const map<string, string>& moduleDelc,
|
||||
const map<string, set<string>>& modDirectOrder,
|
||||
set<string> &done,
|
||||
const string &curr)
|
||||
{
|
||||
if (done.find(curr) == done.end())
|
||||
{
|
||||
for (auto& elem : modDirectOrder.find(curr)->second)
|
||||
createIncludeOrder(toIncl, moduleDelc, modDirectOrder, done, elem);
|
||||
|
||||
if (done.find(curr) == done.end())
|
||||
{
|
||||
toIncl.push_back(moduleDelc.find(curr)->second);
|
||||
done.insert(curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static set<FileInfo*> applyModuleDeclsForFile(FileInfo *forFile, const map<string, FileInfo*> &mapFiles,
|
||||
const map<string, string>& moduleDelc,
|
||||
const map<string, set<string>>& mapModuleDeps,
|
||||
const map<string, set<string>>& modDirectOrder,
|
||||
vector<string> &optSplited,
|
||||
bool includeForInline = false)
|
||||
{
|
||||
set<FileInfo*> retFilesMod;
|
||||
|
||||
auto itF = mapModuleDeps.find(forFile->fileName);
|
||||
if (itF == mapModuleDeps.end() && !includeForInline)
|
||||
return retFilesMod;
|
||||
|
||||
vector<string> toIncl;
|
||||
set<string> done;
|
||||
if (itF != mapModuleDeps.end())
|
||||
{
|
||||
for (auto& mod : itF->second)
|
||||
if (moduleDelc.find(mod) != moduleDelc.end())
|
||||
createIncludeOrder(toIncl, moduleDelc, modDirectOrder, done, mod);
|
||||
}
|
||||
|
||||
//rewrite files to the next iter of parse
|
||||
set<FileInfo*> allFiles;
|
||||
for (auto& incl : toIncl)
|
||||
{
|
||||
if (mapFiles.find(incl) == mapFiles.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
allFiles.insert(mapFiles.find(incl)->second);
|
||||
}
|
||||
allFiles.insert(forFile);
|
||||
|
||||
set<FileInfo*> toConvert;
|
||||
int mainStyle = forFile->style;
|
||||
for (auto& file : allFiles)
|
||||
if (mainStyle != file->style && file->style != 3)
|
||||
toConvert.insert(file);
|
||||
|
||||
const string mainText = forFile->text;
|
||||
for (auto& file : toConvert)
|
||||
file->convertToUniform();
|
||||
|
||||
string include = "";
|
||||
int includeCount = 0;
|
||||
set<string> included;
|
||||
for (auto& incl : toIncl)
|
||||
{
|
||||
if (included.find(incl) == included.end())
|
||||
{
|
||||
include += " include '" + incl + "'\n";
|
||||
includeCount++;
|
||||
}
|
||||
included.insert(incl);
|
||||
}
|
||||
|
||||
vector<string> toInclEnds;
|
||||
string includeLast = "";
|
||||
|
||||
if (includeForInline)
|
||||
{
|
||||
//find needed modules first
|
||||
vector<string> filesWithModules;
|
||||
for (auto& elem : moduleDelc)
|
||||
filesWithModules.push_back(elem.second);
|
||||
for (auto& file : filesWithModules)
|
||||
{
|
||||
if (file != forFile->fileName && included.find(file) == included.end())
|
||||
{
|
||||
toInclEnds.push_back(file);
|
||||
included.insert(file);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& file : mapFiles)
|
||||
if (file.second != forFile && included.find(file.second->fileName) == included.end())
|
||||
toInclEnds.push_back(file.second->fileName);
|
||||
|
||||
if (toInclEnds.size())
|
||||
includeLast += "!SPF SHADOW FILES\n";
|
||||
|
||||
for (auto& incl : toInclEnds)
|
||||
includeLast += " include '" + incl + "'\n";
|
||||
}
|
||||
|
||||
if (includeCount)
|
||||
include = "!SPF NUM FILES " + std::to_string(includeCount) + "\n" + include;
|
||||
|
||||
const string data = include + mainText + includeLast;
|
||||
__spf_print(1, "include to file %s before\n", forFile->fileName.c_str());
|
||||
__spf_print(1, "%s", include.c_str());
|
||||
__spf_print(1, "include to file %s after\n", forFile->fileName.c_str());
|
||||
__spf_print(1, "%s", includeLast.c_str());
|
||||
|
||||
writeFileFromStr(forFile->fileName, data);
|
||||
|
||||
/*static string tmp = "tmp__";
|
||||
static int id = 0;
|
||||
writeFileFromStr(tmp + to_string(id++) + ".ftn", data);*/
|
||||
|
||||
forFile->includesAdded = included.size();
|
||||
forFile->includes = included;
|
||||
|
||||
retFilesMod.insert(forFile);
|
||||
return retFilesMod;
|
||||
}
|
||||
|
||||
static void restoreOriginalText(const vector<FileInfo>& listOfProject)
|
||||
{
|
||||
for (auto& elem : listOfProject)
|
||||
writeFileFromStr(elem.fileName, elem.text);
|
||||
fflush(NULL);
|
||||
}
|
||||
|
||||
static inline void restoreOriginalText(const FileInfo& file)
|
||||
{
|
||||
writeFileFromStr(file.fileName, file.text);
|
||||
}
|
||||
|
||||
static void checkRetCode(FileInfo& info, const string& errorMessage)
|
||||
{
|
||||
if (info.error != 0)
|
||||
info.lvl++;
|
||||
|
||||
if (errorMessage.find("Warning 308") != string::npos)
|
||||
if (info.error == 0)
|
||||
info.error = 1;
|
||||
}
|
||||
|
||||
static vector<string> parseList(vector<FileInfo>& listOfProject,
|
||||
bool needToInclude, bool needToIncludeForInline,
|
||||
const map<string, set<string>> &mapModuleDeps,
|
||||
const map<string, string> &moduleDelc,
|
||||
const map<string, set<string>> &modDirectOrder, bool isFromConsole = false)
|
||||
{
|
||||
map<string, FileInfo*> mapFiles;
|
||||
for (auto& elem : listOfProject)
|
||||
mapFiles[elem.fileName] = &elem;
|
||||
|
||||
vector<string> errors;
|
||||
int i = 1;
|
||||
int N = listOfProject.size();
|
||||
for (auto& elem : listOfProject)
|
||||
{
|
||||
sendMessage_progress(std::to_wstring((int)(((double)(i++) / N) * 100)));
|
||||
|
||||
string file = elem.fileName;
|
||||
string options = elem.options;
|
||||
vector<string> optSplited = splitAndArgvCreate(options);
|
||||
|
||||
char** toParse = new char* [optSplited.size() + 1];
|
||||
for (int z = 0; z < optSplited.size(); ++z)
|
||||
{
|
||||
toParse[z] = new char[optSplited[z].size() + 1];
|
||||
strcpy(toParse[z], optSplited[z].c_str());
|
||||
}
|
||||
toParse[optSplited.size()] = new char[file.size() + 1];
|
||||
strcpy(toParse[optSplited.size()], file.c_str());
|
||||
|
||||
if (options.find("-FI") != string::npos)
|
||||
elem.style = 0;
|
||||
else if (options.find("-extend_source") != string::npos)
|
||||
elem.style = 1;
|
||||
else if (options.find("-FR") != string::npos || options.find("-f90") != string::npos)
|
||||
elem.style = 2;
|
||||
else
|
||||
{ //fdv|f|ftn|for|f90|f95|f03
|
||||
static set<string> fixed_exts = { "for", "f", "ftn" };
|
||||
static set<string> free_exts = { "f90", "f95", "f03" };
|
||||
string ext = OnlyExt(file.c_str());
|
||||
|
||||
if (fixed_exts.find(ext) != fixed_exts.end())
|
||||
elem.style = 0;
|
||||
else if (free_exts.find(ext) != free_exts.end())
|
||||
elem.style = 2;
|
||||
}
|
||||
|
||||
for (int z = 0; z < optSplited.size(); ++z)
|
||||
{
|
||||
if (optSplited[z] == "-o")
|
||||
{
|
||||
if (z + 1 == optSplited.size())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
elem.outDepPath = optSplited[z + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FILE* depPath = fopen(elem.outDepPath.c_str(), "r");
|
||||
if (depPath && !isFromConsole && !needToIncludeForInline)
|
||||
{
|
||||
fclose(depPath);
|
||||
if (elem.error <= 0)
|
||||
{
|
||||
elem.error = 0;
|
||||
errors.push_back("");
|
||||
for (int z = 0; z <= optSplited.size(); ++z)
|
||||
delete toParse[z];
|
||||
delete[] toParse;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
sendMessage_2lvl(L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> '" + to_wstring(file) + L"'");
|
||||
#else
|
||||
sendMessage_2lvl(L" processing file '" + to_wstring(file) + L"'");
|
||||
#endif
|
||||
StdCapture::Init();
|
||||
string errorMessage = "";
|
||||
try
|
||||
{
|
||||
set<FileInfo*> filesModified;
|
||||
StdCapture::BeginCapture();
|
||||
if (needToInclude)
|
||||
filesModified = applyModuleDeclsForFile(&elem, mapFiles, moduleDelc, mapModuleDeps, modDirectOrder, optSplited, needToIncludeForInline);
|
||||
else if (needToIncludeForInline)
|
||||
filesModified = applyModuleDeclsForFile(&elem, mapFiles, moduleDelc, mapModuleDeps, modDirectOrder, optSplited, needToIncludeForInline);
|
||||
|
||||
int retCode = parse_file(optSplited.size(), toParse, "dvm.proj");
|
||||
if (needToInclude || needToIncludeForInline)
|
||||
{
|
||||
for (auto &elem : filesModified)
|
||||
restoreOriginalText(*elem);
|
||||
fflush(NULL);
|
||||
}
|
||||
|
||||
elem.error = retCode;
|
||||
StdCapture::EndCapture();
|
||||
errorMessage = StdCapture::GetCapture();
|
||||
checkRetCode(elem, errorMessage);
|
||||
}
|
||||
catch (int err)
|
||||
{
|
||||
StdCapture::EndCapture();
|
||||
errorMessage = StdCapture::GetCapture();
|
||||
|
||||
if (needToInclude || needToIncludeForInline)
|
||||
restoreOriginalText(listOfProject);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StdCapture::EndCapture();
|
||||
errorMessage = StdCapture::GetCapture();
|
||||
|
||||
if (needToInclude || needToIncludeForInline)
|
||||
restoreOriginalText(listOfProject);
|
||||
}
|
||||
errors.push_back(errorMessage);
|
||||
for (int z = 0; z <= optSplited.size(); ++z)
|
||||
delete toParse[z];
|
||||
delete[] toParse;
|
||||
|
||||
createNeededException();
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
static string shiftLines(const string &in, const map<string, const FileInfo*> &mapOfFiles, const FileInfo* currF)
|
||||
{
|
||||
int byNum = 0;
|
||||
|
||||
auto it = in.find("on line ");
|
||||
if (it != string::npos)
|
||||
it += strlen("on line ");
|
||||
|
||||
int d = 0;
|
||||
sscanf(in.c_str() + it, "%d", &d);
|
||||
|
||||
auto it1 = in.find("of", it + 1);
|
||||
if (it1 == string::npos)
|
||||
return in;
|
||||
it1 += 3;
|
||||
|
||||
string fileN = in.substr(it1, in.find(':', it1) - it1);
|
||||
auto itF = mapOfFiles.find(fileN);
|
||||
if (itF == mapOfFiles.end())
|
||||
return in;
|
||||
if (itF->second != currF)
|
||||
return in;
|
||||
|
||||
byNum = itF->second->includesAdded;
|
||||
if (byNum == 0)
|
||||
return in;
|
||||
|
||||
if (d - byNum <= 0)
|
||||
{
|
||||
//return in;
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
else
|
||||
d -= byNum;
|
||||
|
||||
string newStr = in.substr(0, it) + std::to_string(d) + in.substr(in.find(' ', it + 1));
|
||||
return newStr;
|
||||
}
|
||||
|
||||
static int dumpErrors(const vector<FileInfo>& listOfProject, const vector<string>& errors)
|
||||
{
|
||||
int errorsCount = 0;
|
||||
map<string, const FileInfo*> mapOfFiles;
|
||||
for (auto& elem : listOfProject)
|
||||
mapOfFiles[elem.fileName] = &elem;
|
||||
|
||||
int z = 0;
|
||||
for (auto& file : listOfProject)
|
||||
{
|
||||
if (errors[z] == "")
|
||||
{
|
||||
FILE* ferr = fopen(file.errPath.c_str(), "w");
|
||||
if (!ferr)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
fclose(ferr);
|
||||
++z;
|
||||
continue;
|
||||
}
|
||||
|
||||
FILE* ferr = fopen(file.errPath.c_str(), "w");
|
||||
FILE* fout = fopen(file.outPath.c_str(), "w");
|
||||
if (!ferr)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
if (!fout)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
string errS = "", outS = "";
|
||||
vector<string> splited;
|
||||
splitString(errors[z], '\n', splited);
|
||||
for (auto& elem : splited)
|
||||
{
|
||||
if (elem.find("Warning 308") != string::npos)
|
||||
outS += shiftLines(elem, mapOfFiles, &file) + "\n";
|
||||
else if (elem.find("Error") != string::npos)
|
||||
{
|
||||
errS += shiftLines(elem, mapOfFiles, &file) + "\n";
|
||||
errorsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fout, "%s", outS.c_str());
|
||||
fprintf(ferr, "%s", errS.c_str());
|
||||
|
||||
fflush(NULL);
|
||||
|
||||
fclose(fout);
|
||||
fclose(ferr);
|
||||
++z;
|
||||
}
|
||||
|
||||
return errorsCount;
|
||||
}
|
||||
|
||||
static int createMapOfUse(const vector<string>& errors, const vector<FileInfo>& listOfProject, map<string, set<string>> &mapModuleDeps)
|
||||
{
|
||||
int changed = 0;
|
||||
for (int z = 0; z < listOfProject.size(); ++z)
|
||||
{
|
||||
if (listOfProject[z].error >= 0)
|
||||
{
|
||||
vector<string> splited;
|
||||
splitString(errors[z], '\n', splited);
|
||||
for (auto& err : splited)
|
||||
{
|
||||
if (err.find("Warning 308") != string::npos && err.find(listOfProject[z].fileName) != string::npos)
|
||||
{
|
||||
auto pos = err.find("Unknown module");
|
||||
if (pos != string::npos)
|
||||
{
|
||||
pos += strlen("Unknown module") + 1;
|
||||
string substr = "";
|
||||
while (err[pos] != ' ' && pos != err.size())
|
||||
substr += err[pos++];
|
||||
mapModuleDeps[listOfProject[z].fileName].insert(substr);
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static map<string, set<string>> createModuleOrder(const map<string, string> &moduleDelc, const map<string, set<string>> &mapModuleDeps)
|
||||
{
|
||||
map<string, set<string>> modDirectOrder;
|
||||
for (auto& elem : moduleDelc)
|
||||
modDirectOrder[elem.first] = set<string>();
|
||||
|
||||
for (auto& elem : moduleDelc)
|
||||
{
|
||||
auto itF = mapModuleDeps.find(elem.second);
|
||||
if (itF != mapModuleDeps.end())
|
||||
{
|
||||
for (auto& inFile : itF->second)
|
||||
{
|
||||
if (moduleDelc.find(inFile) != moduleDelc.end())
|
||||
modDirectOrder[elem.first].insert(inFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modDirectOrder;
|
||||
}
|
||||
|
||||
static void printDebug(const map<string, set<string>>& mapModuleDeps, const map<string, set<string>>& modDirectOrder,
|
||||
const vector<FileInfo>& listOfProject, bool console = false)
|
||||
{
|
||||
string toPrint = "MODULE DEPS:\n";
|
||||
for (auto& elem : mapModuleDeps)
|
||||
{
|
||||
toPrint += elem.first + '\n';
|
||||
for (auto& setEl : elem.second)
|
||||
toPrint += " " + setEl + '\n';
|
||||
}
|
||||
toPrint += "MODULE DIRECT ORDER:\n";
|
||||
for (auto& elem : modDirectOrder)
|
||||
{
|
||||
toPrint += elem.first + '\n';
|
||||
for (auto& setEl : elem.second)
|
||||
toPrint += " " + setEl + '\n';
|
||||
}
|
||||
toPrint += "FILES LVL:\n";
|
||||
for (auto& elem : listOfProject)
|
||||
toPrint += elem.fileName + " " + elem.outDepPath + " lvl = " + std::to_string(elem.lvl) + '\n';
|
||||
if (console)
|
||||
printf("%s\n", toPrint.c_str());
|
||||
__spf_print(1, "%s\n", toPrint.c_str());
|
||||
}
|
||||
|
||||
static void parseFiles(int& iters, vector<string>& errors, vector<FileInfo>& listOfProject,
|
||||
map<string, set<string>>& mapModuleDeps, map<string, string>& moduleDelc, map<string, set<string>>& modDirectOrder,
|
||||
int parseForInlining, bool isFromConsole)
|
||||
{
|
||||
int changed = 0;
|
||||
int lastChanged = 0;
|
||||
const string projName = (parseForInlining == 0) ? "tmp" : "tmp_inl";
|
||||
|
||||
do
|
||||
{
|
||||
#ifdef _WIN32
|
||||
sendMessage_1lvl(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + std::to_wstring((iters + 1)) + L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
#else
|
||||
sendMessage_1lvl(L"running " + std::to_wstring((iters + 1)) + L" iteration of syntax analisys");
|
||||
#endif
|
||||
errors = parseList(listOfProject, iters != 0, parseForInlining, mapModuleDeps, moduleDelc, modDirectOrder, isFromConsole);
|
||||
changed = createMapOfUse(errors, listOfProject, mapModuleDeps);
|
||||
if (iters != 0)
|
||||
if (lastChanged <= changed)
|
||||
break;
|
||||
|
||||
createNeededException();
|
||||
|
||||
if (changed)
|
||||
{
|
||||
vector<string> files;
|
||||
for (auto& elem : listOfProject)
|
||||
if (elem.error == 0)
|
||||
files.push_back(elem.outDepPath);
|
||||
if (files.size() == 0)
|
||||
break;
|
||||
findModuleDeclInProject(projName + std::to_string(iters++), files, moduleDelc);
|
||||
modDirectOrder = createModuleOrder(moduleDelc, mapModuleDeps);
|
||||
}
|
||||
lastChanged = changed;
|
||||
//printDebug(mapModuleDeps, modDirectOrder, listOfProject);
|
||||
} while (changed);
|
||||
}
|
||||
|
||||
static vector<string> finalyzeParsing(const vector<FileInfo>& listOfProject,
|
||||
const map<string, set<string>> mapModuleDeps,
|
||||
const map<string, string> moduleDelc)
|
||||
{
|
||||
vector<string> filesCompilationOrder;
|
||||
int added = 0;
|
||||
int iter = 0;
|
||||
vector<string> files;
|
||||
|
||||
while (added != listOfProject.size())
|
||||
{
|
||||
for (auto& elem : listOfProject)
|
||||
{
|
||||
if (elem.lvl == iter)
|
||||
{
|
||||
files.push_back(elem.fileName);
|
||||
added++;
|
||||
}
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
map<string, set<string>> fileDeps;
|
||||
for (auto& file : files)
|
||||
{
|
||||
fileDeps[file] = set<string>();
|
||||
if (mapModuleDeps.find(file) == mapModuleDeps.end())
|
||||
continue;
|
||||
|
||||
for (auto& dep : mapModuleDeps.at(file))
|
||||
{
|
||||
if (moduleDelc.find(dep) == moduleDelc.end())
|
||||
continue;
|
||||
fileDeps[file].insert(moduleDelc.at(dep));
|
||||
}
|
||||
}
|
||||
|
||||
set<string> addedFiles;
|
||||
|
||||
added = 0;
|
||||
while (added != fileDeps.size())
|
||||
{
|
||||
for (auto& file : fileDeps)
|
||||
{
|
||||
bool depsAdded = true;
|
||||
for (auto& dep : file.second)
|
||||
if (addedFiles.find(dep) == addedFiles.end())
|
||||
depsAdded = false;
|
||||
|
||||
if (depsAdded && addedFiles.find(file.first) == addedFiles.end())
|
||||
{
|
||||
filesCompilationOrder.push_back(file.first);
|
||||
addedFiles.insert(file.first);
|
||||
added++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__spf_print(1, "files compilation order:\n");
|
||||
for (auto& file : filesCompilationOrder)
|
||||
__spf_print(1, " %s\n", file.c_str());
|
||||
|
||||
return filesCompilationOrder;
|
||||
}
|
||||
|
||||
static int parseFiles(vector<string>& errors, vector<FileInfo>& listOfProject, vector<string>& filesCompilationOrder,
|
||||
int parseForInlining, bool isFromConsole = false)
|
||||
{
|
||||
int rethrow = 0;
|
||||
int iters = 0;
|
||||
|
||||
map<string, set<string>> mapModuleDeps;
|
||||
map<string, string> moduleDelc;
|
||||
map<string, set<string>> modDirectOrder;
|
||||
|
||||
try
|
||||
{
|
||||
parseFiles(iters, errors, listOfProject, mapModuleDeps, moduleDelc, modDirectOrder, false, isFromConsole);
|
||||
filesCompilationOrder = finalyzeParsing(listOfProject, mapModuleDeps, moduleDelc);
|
||||
|
||||
if (parseForInlining)
|
||||
parseFiles(iters, errors, listOfProject, mapModuleDeps, moduleDelc, modDirectOrder, true, isFromConsole);
|
||||
}
|
||||
catch (int err)
|
||||
{
|
||||
rethrow = err;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
rethrow = -1;
|
||||
}
|
||||
return rethrow;
|
||||
}
|
||||
|
||||
int parseFiles(const char* proj, vector<string>& filesCompilationOrder, int parseForInlining)
|
||||
{
|
||||
FILE* list = fopen(proj, "r");
|
||||
if (!list)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
vector<string> pathSplit;
|
||||
if (string(proj).find('\\') != string::npos)
|
||||
splitString(proj, '\\', pathSplit);
|
||||
else
|
||||
splitString(proj, '/', pathSplit);
|
||||
|
||||
if (pathSplit.size() < 2)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
if (pathSplit[pathSplit.size() - 2] != "visualiser_data")
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
string fullPath = "";
|
||||
for (int z = 0; z < pathSplit.size() - 2; ++z)
|
||||
fullPath += pathSplit[z] + "/";
|
||||
if (fullPath == "")
|
||||
fullPath = "./";
|
||||
else
|
||||
{
|
||||
//change dir
|
||||
if (chdir(fullPath.c_str()) != 0)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
|
||||
vector<FileInfo> listOfProject;
|
||||
while (!feof(list))
|
||||
{
|
||||
char buf[1024];
|
||||
if (fgets(buf, 1024, list) == NULL)
|
||||
continue;
|
||||
|
||||
string toAdd = buf;
|
||||
if (toAdd[toAdd.size() - 1] == '\n')
|
||||
toAdd = toAdd.erase(toAdd.size() - 1);
|
||||
|
||||
string fileNameFixed = "";
|
||||
auto idx = toAdd.find(fullPath);
|
||||
if (idx != string::npos)
|
||||
fileNameFixed = toAdd.substr(idx + fullPath.size());
|
||||
else
|
||||
fileNameFixed = (toAdd.substr(0, 2) == "./") ? toAdd.substr(2) : toAdd;
|
||||
|
||||
const string optPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".opt";
|
||||
const string errPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".err";
|
||||
const string outPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".out";
|
||||
|
||||
const string fileText = readFileToStr(toAdd);
|
||||
|
||||
FILE* opt = fopen(optPath.c_str(), "r");
|
||||
if (!opt)
|
||||
{
|
||||
__spf_print(1, "can not open path %s\n", optPath.c_str());
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
fgets(buf, 1024, opt);
|
||||
string toAddOpt = buf;
|
||||
if (toAddOpt[toAddOpt.size() - 1] == '\n')
|
||||
toAddOpt = toAddOpt.erase(toAddOpt.size() - 1);
|
||||
|
||||
fclose(opt);
|
||||
listOfProject.push_back(FileInfo(fileNameFixed, toAddOpt, errPath, outPath, "", fileText));
|
||||
}
|
||||
|
||||
fclose(list);
|
||||
vector<string> errors;
|
||||
|
||||
int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, parseForInlining);
|
||||
int errCount = dumpErrors(listOfProject, errors);
|
||||
|
||||
if (rethrow != 0)
|
||||
throw rethrow;
|
||||
return -errCount;
|
||||
}
|
||||
|
||||
void parseFiles(int argc, char** argv)
|
||||
{
|
||||
bool isInline = false;
|
||||
auto result = splitCommandLineForParse(argv, argc, isInline);
|
||||
if (result.second.size() == 0)
|
||||
{
|
||||
printf("Nothing to parse\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int code = 0;
|
||||
|
||||
vector<string> errors;
|
||||
vector<FileInfo> listOfProject;
|
||||
|
||||
string toAddOpt = "";
|
||||
for (auto& opt : result.first)
|
||||
toAddOpt += opt + " ";
|
||||
|
||||
for (auto& file : result.second)
|
||||
{
|
||||
const string fileText = readFileToStr(file);
|
||||
listOfProject.push_back(FileInfo(file, toAddOpt + "-o " + file + ".dep", "", "", "", fileText, 0));
|
||||
}
|
||||
|
||||
vector<string> filesCompilationOrder;
|
||||
if (isInline)
|
||||
printf(" run parsing for inlining\n");
|
||||
|
||||
int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, isInline, true);
|
||||
if (rethrow == 0)
|
||||
{
|
||||
for (auto& err : errors)
|
||||
{
|
||||
vector<string> splited;
|
||||
splitString(err, '\n', splited);
|
||||
for (auto& elem : splited)
|
||||
{
|
||||
if (elem.find("Error") != string::npos)
|
||||
{
|
||||
printf("%s\n", elem.c_str());
|
||||
code++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (code == 0 && rethrow == 0)
|
||||
{
|
||||
FILE* proj = fopen("dvm.proj", "w");
|
||||
if (proj == NULL)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
for (auto& file : result.second)
|
||||
fprintf(proj, "%s.dep\n", file.c_str());
|
||||
printf("Parsing was completed successfully\n");
|
||||
}
|
||||
else
|
||||
printf("Parsing was completed with errors, throw code %d, errors count %d\n", rethrow, code);
|
||||
exit(0);
|
||||
}
|
||||
7
Sapfor/_src/ProjectManipulation/ParseFiles.h
Normal file
7
Sapfor/_src/ProjectManipulation/ParseFiles.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
int parseFiles(const char* proj, std::vector<std::string>& filesCompilationOrder, int parseForInlining);
|
||||
void parseFiles(int argc, char** argv);
|
||||
45
Sapfor/_src/ProjectManipulation/PerfAnalyzer.cpp
Normal file
45
Sapfor/_src/ProjectManipulation/PerfAnalyzer.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../Utils/errors.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
|
||||
#include "StdCapture.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern int pppa_analyzer(int argv, char** argc);
|
||||
|
||||
int pppaAnalyzer(const char* options)
|
||||
{
|
||||
string optionsS(options);
|
||||
vector<string> splited = splitAndArgvCreate(optionsS);
|
||||
|
||||
char** argv = new char* [splited.size()];
|
||||
for (int z = 0; z < splited.size(); ++z)
|
||||
argv[z] = (char*)splited[z].c_str();
|
||||
|
||||
StdCapture::Init();
|
||||
string errorMessage = "";
|
||||
int retCode = pppa_analyzer(splited.size(), argv);
|
||||
StdCapture::EndCapture();
|
||||
errorMessage = StdCapture::GetCapture();
|
||||
|
||||
delete []argv;
|
||||
return retCode;
|
||||
}
|
||||
|
||||
void pppaAnalyzer(int argc, char** argv)
|
||||
{
|
||||
int code = pppa_analyzer(argc, argv);
|
||||
if (code == 0)
|
||||
printf("PPPA was completed successfully\n");
|
||||
else
|
||||
printf("PPPA was completed with error code %d\n", code);
|
||||
exit(0);
|
||||
}
|
||||
4
Sapfor/_src/ProjectManipulation/PerfAnalyzer.h
Normal file
4
Sapfor/_src/ProjectManipulation/PerfAnalyzer.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
int pppaAnalyzer(const char* options);
|
||||
void pppaAnalyzer(int argc, char** argv);
|
||||
195
Sapfor/_src/ProjectManipulation/StdCapture.h
Normal file
195
Sapfor/_src/ProjectManipulation/StdCapture.h
Normal file
@@ -0,0 +1,195 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
|
||||
#define popen _popen
|
||||
#define pclose _pclose
|
||||
#define stat _stat
|
||||
#define dup _dup
|
||||
#define dup2 _dup2
|
||||
#define fileno _fileno
|
||||
#define close _close
|
||||
#define pipe _pipe
|
||||
#define read _read
|
||||
#define eof _eof
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef STD_OUT_FD
|
||||
#define STD_OUT_FD (fileno(stdout))
|
||||
#endif
|
||||
|
||||
#ifndef STD_ERR_FD
|
||||
#define STD_ERR_FD (fileno(stderr))
|
||||
#endif
|
||||
|
||||
static int m_pipe[2];
|
||||
static int m_oldStdOut;
|
||||
static int m_oldStdErr;
|
||||
static bool m_capturing;
|
||||
static std::mutex m_mutex;
|
||||
static std::string m_captured;
|
||||
|
||||
class StdCapture
|
||||
{
|
||||
enum PIPES { READ, WRITE };
|
||||
|
||||
static int secure_dup(int src)
|
||||
{
|
||||
int ret = -1;
|
||||
bool fd_blocked = false;
|
||||
do
|
||||
{
|
||||
ret = dup(src);
|
||||
fd_blocked = (errno == EINTR || errno == EBUSY);
|
||||
if (fd_blocked)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
} while (ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void secure_pipe(int* pipes)
|
||||
{
|
||||
int ret = -1;
|
||||
bool fd_blocked = false;
|
||||
do
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ret = pipe(pipes, 1024 * 1024 * 20, O_BINARY); // 20 MB
|
||||
#else
|
||||
ret = pipe(pipes) == -1;
|
||||
#ifdef __APPLE__
|
||||
fcntl(*pipes, F_PREALLOCATE, 1024 * 1024 * 20);
|
||||
#else
|
||||
fcntl(*pipes, F_SETPIPE_SZ, 1024 * 1024 * 20);
|
||||
#endif
|
||||
#endif
|
||||
fd_blocked = (errno == EINTR || errno == EBUSY);
|
||||
if (fd_blocked)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
} while (ret < 0);
|
||||
}
|
||||
|
||||
static void secure_dup2(int src, int dest)
|
||||
{
|
||||
int ret = -1;
|
||||
bool fd_blocked = false;
|
||||
do
|
||||
{
|
||||
ret = dup2(src, dest);
|
||||
fd_blocked = (errno == EINTR || errno == EBUSY);
|
||||
if (fd_blocked)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
} while (ret < 0);
|
||||
}
|
||||
|
||||
static void secure_close(int& fd)
|
||||
{
|
||||
int ret = -1;
|
||||
bool fd_blocked = false;
|
||||
do
|
||||
{
|
||||
ret = close(fd);
|
||||
fd_blocked = (errno == EINTR);
|
||||
if (fd_blocked)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
} while (ret < 0);
|
||||
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
public:
|
||||
static void Init()
|
||||
{
|
||||
// make stdout & stderr streams unbuffered
|
||||
// so that we don't need to flush the streams
|
||||
// before capture and after capture
|
||||
// (fflush can cause a deadlock if the stream is currently being
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
static void BeginCapture()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_capturing)
|
||||
return;
|
||||
|
||||
secure_pipe(m_pipe);
|
||||
m_oldStdOut = secure_dup(STD_OUT_FD);
|
||||
m_oldStdErr = secure_dup(STD_ERR_FD);
|
||||
secure_dup2(m_pipe[WRITE], STD_OUT_FD);
|
||||
secure_dup2(m_pipe[WRITE], STD_ERR_FD);
|
||||
m_capturing = true;
|
||||
#ifndef _WIN32
|
||||
secure_close(m_pipe[WRITE]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool IsCapturing()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_capturing;
|
||||
}
|
||||
|
||||
static void EndCapture()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (!m_capturing)
|
||||
return;
|
||||
|
||||
m_captured.clear();
|
||||
secure_dup2(m_oldStdOut, STD_OUT_FD);
|
||||
secure_dup2(m_oldStdErr, STD_ERR_FD);
|
||||
|
||||
const int bufSize = 1025;
|
||||
char buf[bufSize];
|
||||
int bytesRead = 0;
|
||||
bool fd_blocked(false);
|
||||
do
|
||||
{
|
||||
bytesRead = 0;
|
||||
fd_blocked = false;
|
||||
#ifdef _WIN32
|
||||
if (!eof(m_pipe[READ]))
|
||||
bytesRead = read(m_pipe[READ], buf, bufSize - 1);
|
||||
#else
|
||||
bytesRead = read(m_pipe[READ], buf, bufSize - 1);
|
||||
#endif
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
buf[bytesRead] = 0;
|
||||
m_captured += buf;
|
||||
}
|
||||
else if (bytesRead < 0)
|
||||
{
|
||||
fd_blocked = (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR);
|
||||
if (fd_blocked)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
} while (fd_blocked || bytesRead == (bufSize - 1));
|
||||
|
||||
secure_close(m_oldStdOut);
|
||||
secure_close(m_oldStdErr);
|
||||
secure_close(m_pipe[READ]);
|
||||
#ifdef _WIN32
|
||||
secure_close(m_pipe[WRITE]);
|
||||
#endif
|
||||
m_capturing = false;
|
||||
}
|
||||
|
||||
static std::string GetCapture()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_captured;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user