-
Notifications
You must be signed in to change notification settings - Fork 0
/
nameCollector.cpp
131 lines (115 loc) · 4.58 KB
/
nameCollector.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// SPDX-License-Identifier: GPL-3.0-only
/**
* @file nameCollector.cpp
*
* @copyright Copyright (C) 2023 srcML, LLC. (www.srcML.org)
*
* This file is part of the nameCollector application.
*/
/**
*
* Takes srcML input (with --position) of a source code file(s)
* Gets a vector<identifier> which contains name, category, and position
* of all the user defined identifiers in the file
*
* Works for srcML single unit or archives.
*
*
* Need to have installed: libxml2 and srcml
* Need to build and install srcSAX:
* In srcSAX folder:
* cmake CMakeLists.txt
* make
* sudo make install
*
* cmake finds/downloads CLI11.hpp
*/
#include <srcSAXController.hpp>
#include <iostream>
#include <fstream>
#include "CLI11.hpp"
#include "identifierName.hpp"
#include "nameCollectorHandler.hpp"
bool DEBUG = false; // Debug flag from CLI option
// Print out coma separated output (CSV) - no header
// identifier, type, category, filename, position
void printCSV(std::ostream& out, const std::vector<identifier>& identifiers) {
//out << "IDENTIFIER" << ", TYPE" << ", CATEGORY" << ", FILENAME" << ", POSITION" << ", LANGUAGE" << std::endl;
for (unsigned int i = 0; i < identifiers.size(); ++i)
out << identifiers[i] << std::endl;
}
//Print out simple report
void printReport(std::ostream& out, const std::vector<identifier>& identifiers) {
out << "The following " << identifiers.size() << " user defined identifiers occur: " << std::endl;
for (unsigned int i = 0; i<identifiers.size(); ++i) {
out << identifiers[i].getName()
<< " is a " << identifiers[i].getType()
<< (identifiers[i].getType() != "" ? " " : "") << identifiers[i].getCategory()
<< " in " << identifiers[i].getLanguage() << " file: " << identifiers[i].getFilename()
<< (identifiers[i].getPosition() != "" ? " at " : "") << identifiers[i].getPosition()
<< std::endl;
}
}
/**
* main
* @param argc number of arguments
* @param argv the provided arguments (array of C strings)
*
*/
int main(int argc, char * argv[]) {
std::string inputFile = "";
std::string outputFile = "";
std::string outputFormat = "";
bool outputCSV = false; //True is CSV, false is text
bool appendOutput = false;
CLI::App app{"nameCollector: Finds all user defined identifier names in a source code file. "};
app.add_option("-i, --input", inputFile, "Name of srcML file of source code with --position option");
app.add_option("-o, --output", outputFile, "Name of output file");
app.add_option("-f, --format", outputFormat, "The output format (text by default): csv, text"); //To support other output options
app.add_flag ("-a, --append", appendOutput, "Output will be appended to end of file");
app.add_flag ("-c, --csv", outputCSV, "Short for: --format csv");
app.add_flag ("-d, --debug", DEBUG, "Turn on debug mode (off by default)");
CLI11_PARSE(app, argc, argv);
try {
nameCollectorHandler handler;
// srcSAXController control(inputFile.c_str());
if (inputFile != "") {
srcSAXController control (inputFile.c_str());
control.parse(&handler);
}
else {
std::string input = "";
std::string line;
while (std::getline(std::cin, line)) {
input += line + '\n';
}
srcSAXController control (input);
control.parse(&handler);
}
//Results
std::vector<identifier> identifiers = handler.getIdentifiers();
//Output format is text by default: outputCSV == false
if (outputFormat == "text") outputCSV = false;
if (outputFormat == "csv") outputCSV = true;
if (outputFile != "") {
std::ofstream out;
if (appendOutput) out.open(outputFile, std::ios::app);
else out.open(outputFile);
if (!out.is_open())
throw std::string("Can not open file: " + outputFile + " for writing.");
if (outputCSV) printCSV(out, identifiers);
else printReport(out, identifiers);
out.close();
} else {
if (outputCSV) printCSV(std::cout, identifiers);
else printReport(std::cout, identifiers);
}
}
catch (std::string& error) {
std::cerr << "Error: " << error << std::endl;
}
catch (SAXError& error) {
std::cerr << "Error: " << error.message << " " << error.error_code << std::endl;
}
return 0;
}