Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[C++] Counter of C/C++ code (Version 1.3.1)

9 views
Skip to first unread message

Alex Vinokur

unread,
Feb 5, 2004, 12:03:43 PM2/5/04
to
// ==============================================================
//
// Copyright (C) 2003-2004 Alex Vinokur.
//
// ------------------------------------------------------------
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// ------------------------------------------------------------
//
// mailto:ale...@connect.to
// http://up.to/alexv
//
// ==============================================================


// ##############################################################
//
// SOFTWARE : Print line and byte counts of C/C++ sources
// FILE : cncc.cpp
//
// DESCRIPTION :
// `cncc' counts the number of code, comment and empty
// lines and bytes of C/C++-sources
// which have been successfully compiled.
//
#define VERSION_No "1.3.1"
//
// ##############################################################

#include <cassert>
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
using namespace std;

// --------------
static string CurFilename_Static;

// --------------
typedef unsigned long ulong;

#define MAX_VALUE(x,y) ((x) > (y) ? (x) : (y))

#define ASSERTION(x) if (!(x)) \
{ \
cerr << "" \
<< "### "\
<< PROGRAM_NAME \
<< " : Version "\
<< VERSION_No \
<< " ###"\
<< endl; \
cerr << "" \
<< "[" \
<< __FILE__ \
<< ", #" \
<< __LINE__ \
<< "] " \
<< "There is some problem with file `" \
<< CurFilename_Static \
<< "'." \
<< endl; \
cerr << "" \
<< "Has `" \
<< CurFilename_Static \
<< "' been successfully compiled?" \
<< endl; \
exit(1); \
}

// --------------
enum ByteModeId
{
UNDEF_ByteModeId,
// ----------------
LIVING_SPACE_Id,
// ----------------
CPP_BRACKET_Id,
CL_BRACKET_Id,
CR_BRACKET_Id,
COMMENT_Id,
// ----------------
QL_BRACKET_Id,
QR_BRACKET_Id,
Q_STRING_Id,
// ----------------
LAST_ByteModeId
};

#define PROGRAM_NAME "cncc"


#define CPP_BRACKET "//"
#define CL_BRACKET "/*"
#define CR_BRACKET "*/"

#define SINGLE_QUOTE "\""
#define QL_BRACKET SINGLE_QUOTE
#define QR_BRACKET SINGLE_QUOTE

#define BRACKET_SIZE 2
#define QUOTE_SIZE 1

#define SPACE_VALUE ' '
#define TAB_VALUE '\t'

#define ONE_SLASH '\\'

#define PRE_OPTION_SIGN '-'

#define SUMMARY_OPTION 'a'
#define DETAILED_OPTION1_ROW 'b'
#define DETAILED_OPTION2_ROW 'c'
#define DETAILED_OPTION3_ROW_COL 'd'
#define HELP_OPTION 'h'
#define VERSION_OPTION 'v'

#define ROW_NO_SIZE 7
#define FIELD_NO_SIZE 7

#define LINES_TXT0 "Lines"
#define BYTES_TXT0 "Chars"

#define CODE_ONLY_TXT1 "Code Only"
#define CODE_COMMENT_TXT1 "Code+Comment"
#define COMMENT_ONLY_TXT1 "Comment Only"
#define EMPTY_TXT1 "Empty"
#define TOTAL_TXT1 "* Total"

#define TXT1_SIZE 13


#define CODE_TXT2 " code"
#define CODE_STRING_TXT2 " code (string)"
#define COMMENT_TXT2 " comment"
#define COMMENT_BLANK_TXT2 " comment (blank)"
#define EMPTY_TXT2 " blank"

#define TXT2_SIZE 10

#define DELIM1 "|"
#define DELIM2 ":"


#define PURIFIED_SUFFIX2 "i2"
#define PURIFIED_SUFFIX3 "i3"

#define PERCENT_FACTOR 100.0
#define PERCENT_SIGN " %"
#define PERCENT_100 "100"

#define NONE_TXT "None"


//=====================
template <typename T>
string to_str (const T& val_i)
{
ostringstream oss;
oss << val_i;
return oss.str();
}


//=====================
struct SimpleTable
{
const string title_;
const vector<ulong> col_size_;
const string prefix_;
vector<bool> align_;
const bool total_delim_line_flag_;
const string outside_delim_;
const string inside_delim_;
const ulong left_space_size_;
const ulong right_space_size_;

vector<string> header_str_;
vector<string> row_str_;

SimpleTable (
const string& title_i,
const vector<ulong>& col_size_i,
const string& prefix_i = "",
const vector<bool>& align_i = vector<bool>(),
bool total_delim_line_flag_i = false,
const string& outside_delim_i = "|",
const string& inside_delim_i = ":"
);

~SimpleTable ();


void build_header (const vector<vector<string> > header_i);
void build_row (const vector<string> row_i);
void build_empty_row ();

void print_table () const;
};


// ---------
SimpleTable::SimpleTable (
const string& title_i,
const vector<ulong>& col_size_i,
const string& prefix_i,
const vector<bool>& align_i,
bool total_delim_line_flag_i,
const string& outside_delim_i,
const string& inside_delim_i
)
:
title_ (title_i),
col_size_ (col_size_i),
prefix_ (prefix_i),
align_ (align_i),
total_delim_line_flag_ (total_delim_line_flag_i),
outside_delim_ (outside_delim_i),
inside_delim_ (inside_delim_i),
left_space_size_ (to_str(SPACE_VALUE).size()),
right_space_size_ (to_str(SPACE_VALUE).size())
{
assert (!col_size_.empty());

if (align_.empty()) align_.push_back(true);

for (ulong k = align_.size(); k < col_size_.size(); k++)
{
align_.push_back(false);
}

assert (col_size_.size() == align_.size());

}

// ---------
SimpleTable::~SimpleTable ()
{
print_table ();
}

// ---------
void SimpleTable::build_header (const vector<vector<string> > header_i)
{

for (ulong i = 0; i < header_i.size(); i++)
{
assert (header_i[i].size () == col_size_.size());

ostringstream oss;
oss << ""
<< outside_delim_;

for (ulong k = 0; k < header_i[i].size(); k++)
{
assert (header_i[i][k].size () <= col_size_[k]);
oss << ""
<< SPACE_VALUE
<< setw (col_size_[k])
<< (align_[k] ? left : right)
<< header_i[i][k]
<< SPACE_VALUE;
if (k < (header_i[i].size() - 1))
{
oss << inside_delim_;
}
else
{
oss << outside_delim_;
}
}
header_str_.push_back(oss.str());
}

}


// ---------
void SimpleTable::build_empty_row ()
{
ostringstream oss;
oss << ""
<< outside_delim_;
for (ulong k = 0; k < col_size_.size(); k++)
{
oss << ""
<< SPACE_VALUE
<< setw (col_size_[k])
<< ""
<< SPACE_VALUE;

if (k < (col_size_.size() - 1))
{
oss << inside_delim_;
}
else
{
oss << outside_delim_;
}
}
row_str_.push_back(oss.str());

}

// ---------
void SimpleTable::build_row (const vector<string> row_i)
{
assert (row_i.size () == col_size_.size());

ostringstream oss;
oss << ""
<< outside_delim_;
for (ulong k = 0; k < row_i.size(); k++)
{
assert (row_i.size () <= col_size_[k]);

oss << ""
<< SPACE_VALUE
<< setw (col_size_[k])
<< (align_[k] ? left : right)
<< row_i[k]
<< SPACE_VALUE;
if (k < (row_i.size() - 1))
{
oss << inside_delim_;
}
else
{
oss << outside_delim_;
}
}

row_str_.push_back(oss.str());
}

// ---------
void SimpleTable::print_table () const
{

cout << prefix_ << "--- " << title_ << " ---" << endl;

assert (!header_str_.empty());

cout << prefix_ << string (header_str_.back().size(), '=') << endl;
for (ulong k = 0; k < header_str_.size(); k++)
{
cout << prefix_ << header_str_[k] << endl;
}
cout << prefix_ << outside_delim_ << string (header_str_.back().size() - 2, '-') << outside_delim_ << endl;

for (ulong k = 0; k < row_str_.size(); k++)
{
if (k == (row_str_.size() - 1))
{
if (total_delim_line_flag_)
{
cout << prefix_ << outside_delim_ << string (header_str_.back().size() - 2, '.') << outside_delim_ << endl;
}
}
cout << prefix_ << row_str_[k] << endl;
}

cout << prefix_ << string (header_str_.back().size(), '=') << endl;

}

//=====================
struct Couple
{
ulong row_no_;
ulong field_no_;

Couple (ulong row_no_i, ulong field_no_i)
:
row_no_ (row_no_i),
field_no_ (field_no_i)
{}

bool get_next(
const vector<string>& data_i,
ulong& row_no_o,
ulong& field_no_o
) const;

};

// ---------
bool Couple::get_next (
const vector<string>& data_i,
ulong& row_no_o,
ulong& field_no_o
) const
{
ASSERTION (row_no_ < data_i.size());

bool ret_bool = false;

if (field_no_ == (data_i[row_no_].size() - 1))
{
for (ulong k = (row_no_ + 1); k < data_i.size(); k++)
{
if (data_i[k].empty()) continue;

ret_bool = true;

row_no_o = k;
field_no_o = 0;

break;
}

}
else
{
ASSERTION (field_no_ < (data_i[row_no_].size() - 1));

ret_bool = true;

row_no_o = row_no_;
field_no_o = field_no_ + 1;
}

return ret_bool;
}

// ---------
bool operator< (const Couple& ins1_i, const Couple& ins2_i)
{
if (ins1_i.row_no_ < ins2_i.row_no_) return true;

if (
(ins1_i.row_no_ == ins2_i.row_no_)
&&
(ins1_i.field_no_ < ins2_i.field_no_)
)
{
return true;
}

return false;
}

// ---------
bool operator<= (const Couple& ins1_i, const Couple& ins2_i)
{
if (ins1_i < ins2_i) return true;
if ((ins1_i.row_no_ == ins2_i.row_no_) && (ins1_i.field_no_ == ins2_i.field_no_)) return true;

return false;
}

// ---------
bool operator== (const Couple& ins1_i, const Couple& ins2_i)
{
if (ins1_i.row_no_ != ins2_i.row_no_) return false;
if (ins1_i.field_no_ != ins2_i.field_no_) return false;

return true;
}


//=====================
struct Triple
{
vector<ulong> code_fields_;
vector<ulong> empty_fields_;
vector<ulong> comment_fields_;
};

//=====================
class CountCodeLines
{
private :
static string exe_full_name_s;
static string exe_basename_s;
static vector<string> filenames_s;
static ulong max_filenames_size_s;

static vector<string> actual_options_s;
static map<string, vector<string> > allowed_options_s;

ifstream fin_;
const string filename_;
const bool open_status_;

vector<string> rows_;
vector<string> modes_;
vector<Triple> triple_;

static ulong all_files_code_only_lines_s;
static ulong all_files_code_comment_lines_s;
static ulong all_files_comment_only_lines_s;
static ulong all_files_empty_lines_s;

static ulong all_files_code_fields_s;
static ulong all_files_comment_fields_s;
static ulong all_files_empty_fields_s;

bool open_file ();
void read_file ();

void assert_check () const;

void treatment ();

void init_modes ();
bool get_first_field (ulong& row_no_o, ulong& field_no_o);
void sign_modes (ulong row_no_i, ulong field_no_i);

void mask_modes (
ulong row1_i,
ulong field1_i,
ulong row2_i,
ulong field2_i,
ulong row3_i,
ulong field3_i,
ByteModeId mode_id_i
);

void mask2_modes (
ulong row_i,
ulong field_i
);


bool find_token (
const string& token_i,
ulong& row_no_o,
ulong& field_no_o,
ulong row_no_i,
ulong field_no_i,
bool deny_check_i = false
) const;


void prepare_reported_data ();

void show_report () const;

void show_summary_report (const string& prefix_i) const;
void show_detailed_report (const string& prefix_i) const;

void create_purified_code () const;


public :
CountCodeLines (const string& filename_i);
~CountCodeLines ();


bool get_open_status () const { return open_status_;}

static bool Set_Exe_Filename (const string& filename_i);
static void Init_Allowed_Options ();
static bool Set_Actual_Options (const string& str_i);
static void Set_Default_Option ();
static void Show_Help ();
static void Show_Summary_Report ();
static void Print_Summary_Report (
const string& center_title_i,
const string& left_title_i,
ulong lines_code_only_i,
ulong lines_code_comment_i,
ulong lines_comment_only_i,
ulong lines_empty_i,
ulong fields_code_i,
ulong fields_comment_i,
ulong fields_empty_i
);
static void Add_Filename (const string& filename_i);
static const vector<string>& Get_Filenames ();

};


// ---------
CountCodeLines::CountCodeLines (const string& filename_i)
:
filename_ (filename_i),
open_status_ (open_file())
{

assert_check ();

assert (!allowed_options_s.empty());

// ------------------
assert (!filename_.empty());

if (!open_status_) return;

// ------------------
assert (open_status_);

read_file ();

treatment ();

prepare_reported_data ();
show_report ();
}


// ---------
CountCodeLines::~CountCodeLines ()
{
if (fin_.is_open()) fin_.close();
assert (!fin_.is_open());
}

// ---------
const vector<string>& CountCodeLines::Get_Filenames ()
{
return filenames_s;
}

// ---------
void CountCodeLines::Add_Filename (const string& filename_i)
{
#define ADDITION_VAL 3
filenames_s.push_back (filename_i);
max_filenames_size_s = MAX_VALUE (max_filenames_size_s, filename_i.size() + ADDITION_VAL);
}


// ---------
bool CountCodeLines::Set_Exe_Filename (const string& filename_i)
{
assert (exe_full_name_s.empty());
exe_full_name_s = filename_i;
exe_basename_s = exe_full_name_s;


string::size_type find_pos;

find_pos = exe_basename_s.find_last_of ("/\\");
if (find_pos != string::npos) exe_basename_s = exe_basename_s.substr (find_pos + 1);

find_pos = exe_basename_s.find_last_of (".");
if (find_pos != string::npos) exe_basename_s = exe_basename_s.substr (0, find_pos);


if (exe_basename_s != PROGRAM_NAME)
{
cerr << ""
<< endl
<< "ERROR : Executable basename must be "
<< "`"
<< PROGRAM_NAME
<< "'"

<< "; Actual basename is "
<< "`"
<< exe_basename_s
<< "'"

<< ", Actual full name is "
<< "`"
<< exe_full_name_s
<< "'"

<< "."
<< endl;

return false;
}

assert (exe_basename_s == PROGRAM_NAME);
return true;

}

// ---------
bool CountCodeLines::Set_Actual_Options (const string& str_i)
{
assert (str_i[0] == PRE_OPTION_SIGN);

if (str_i.size() == 1)
{
cerr << ""
<< endl
<< "WARNING : Option `"
<< str_i
<< "' is empty and will be ignored."
<< endl;
return false;
}

//assert (str_i.size() > 1);

for (ulong k = 1; k < str_i.size(); k++)
{
const string cur_option (to_str(str_i[k]));

if (allowed_options_s.count (cur_option) == 0)
{
cerr << ""
<< endl
<< "WARNING : Option `"
<< (PRE_OPTION_SIGN + cur_option)
<< "' is illegal and will be ignored."
<< endl;
continue;
}

if (count (actual_options_s.begin(), actual_options_s.end(), cur_option) == 0)
{
actual_options_s.push_back (cur_option);
}
}

if (count (actual_options_s.begin(), actual_options_s.end(), to_str(HELP_OPTION)))
{
Show_Help();
return true;
}

if (count (actual_options_s.begin(), actual_options_s.end(), to_str(VERSION_OPTION)))
{
cout << endl;
cout << PROGRAM_NAME << " : Version " << VERSION_No << endl;

cout << endl;
cout << "Copyright (C) 2003-2004 Alex Vinokur" << endl;

cout << "This is free software; see the source for copying conditions." << endl;
cout << "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." << endl;
cout << endl;

return true;
}


if (
(count (actual_options_s.begin(), actual_options_s.end(), to_str(DETAILED_OPTION2_ROW)))
&&
(count (actual_options_s.begin(), actual_options_s.end(), to_str(DETAILED_OPTION3_ROW_COL)))
)
{
cerr << ""
<< endl
<< "ERROR : Options "
<< "`"
<< PRE_OPTION_SIGN
<< DETAILED_OPTION2_ROW
<< "'"
<< " and "
<< "`"
<< PRE_OPTION_SIGN
<< DETAILED_OPTION3_ROW_COL
<< "'"
<< " are incompatible."
<< endl;

return true;

}

// -------------
return false;

}

// ---------
void CountCodeLines::Set_Default_Option ()
{
actual_options_s.push_back (to_str(SUMMARY_OPTION));
}

// ---------
void CountCodeLines::Init_Allowed_Options ()
{
allowed_options_s [to_str(SUMMARY_OPTION)].push_back ("Print code-line, empty-line and comment-line counts for each FILE.");
allowed_options_s [to_str(SUMMARY_OPTION)].push_back ("This option is DEFAULT.");

allowed_options_s [to_str(DETAILED_OPTION1_ROW)].push_back ("Print line-type for each LINE of each FILE.");

allowed_options_s [to_str(DETAILED_OPTION2_ROW)].push_back ("Print");
allowed_options_s [to_str(DETAILED_OPTION2_ROW)].push_back ("* line-type");
allowed_options_s [to_str(DETAILED_OPTION2_ROW)].push_back (" and");
allowed_options_s [to_str(DETAILED_OPTION2_ROW)].push_back ("* code-field, empty-field and comment-field counts");
allowed_options_s [to_str(DETAILED_OPTION2_ROW)].push_back ("for each line of each FILE.");
allowed_options_s [to_str(DETAILED_OPTION2_ROW)].push_back ("### Note. This option is incompatible with option `" +
to_str(PRE_OPTION_SIGN) + to_str(DETAILED_OPTION3_ROW_COL) + "'.");

allowed_options_s [to_str(DETAILED_OPTION3_ROW_COL)].push_back("Print field-type for each field of each line of each FILE.");
allowed_options_s [to_str(DETAILED_OPTION3_ROW_COL)].push_back ("### Note. This option is incompatible with option `" +
to_str(PRE_OPTION_SIGN) + to_str(DETAILED_OPTION2_ROW) + "'.");

allowed_options_s [to_str(HELP_OPTION)].push_back("Display this help and exit.");

allowed_options_s [to_str(VERSION_OPTION)].push_back("Print the version number and exit.");

}

// ---------
void CountCodeLines::Show_Help ()
{
#define PREFIX1 " "
#define PREFIX2 " "

cout << endl;
cout << endl;

assert (exe_basename_s == PROGRAM_NAME);

cout << ""
<< "NAME"
<< endl
<< PREFIX1
<< PROGRAM_NAME
<< " - "
<< "count C/C++ source lines and bytes"
<< endl;
cout << endl;

cout << ""
<< "SYNOPSIS"
<< endl
<< PREFIX1
<< PROGRAM_NAME
<< " [OPTIONS]... [FILE]..."
<< endl;
cout << endl;

cout << ""
<< "DESCRIPTION"
<< endl
<< PREFIX1
<< "Count code-lines, empty-lines, comment-lines, "
<< endl
<< PREFIX1
<< "code-fields, empty-fields, comment-fields of C/C++-sources "
<< endl
<< PREFIX1
<< "which have been successfully compiled."
<< endl;
cout << endl;


cout << PREFIX1 << "The program accepts the following options." << endl;
for (map<string, vector<string> >::const_iterator pos_iter = allowed_options_s.begin();
pos_iter != allowed_options_s.end();
pos_iter++
)
{
cout << ""
<< endl
<< PREFIX1
<< "`"
<< PRE_OPTION_SIGN
<< pos_iter->first
<< "'"
<< endl;

for (ulong k = 0; k < pos_iter->second.size(); k++)
{
cout << ""
<< PREFIX2
<< pos_iter->second [k]
<< endl;
}
}


}


// ---------
void CountCodeLines::assert_check () const
{
assert (string (CPP_BRACKET).size() == BRACKET_SIZE);
assert (string (CL_BRACKET).size() == BRACKET_SIZE);
assert (string (CR_BRACKET).size() == BRACKET_SIZE);

assert (string (LINES_TXT0).size() <= ROW_NO_SIZE);
assert (string (BYTES_TXT0).size() <= FIELD_NO_SIZE);

assert (string (CODE_ONLY_TXT1).size() < TXT1_SIZE);
assert (string (CODE_COMMENT_TXT1).size() < TXT1_SIZE);
assert (string (EMPTY_TXT1).size() < TXT1_SIZE);
assert (string (COMMENT_ONLY_TXT1).size() < TXT1_SIZE);
assert (string (TOTAL_TXT1).size() < TXT1_SIZE);

}

// ---------
void CountCodeLines::treatment ()
{

init_modes ();

ulong row_no;
ulong field_no;
if (get_first_field (row_no, field_no)) sign_modes(row_no, field_no);

}


// ---------
void CountCodeLines::create_purified_code () const
{
string basename (filename_);

string::size_type find_pos;
find_pos = basename.find_last_of ("/\\");
if (find_pos != string::npos) basename = basename.substr (find_pos + 1);

find_pos = basename.find_last_of (".");
if (find_pos != string::npos)
{
basename = basename.substr (0, find_pos + 2); // dot + first letter of the suffix
}
else
{
basename += ".";
}

const string purified_file_name2 (basename + PURIFIED_SUFFIX2);
const string purified_file_name3 (basename + PURIFIED_SUFFIX3);

remove (purified_file_name2.c_str());
remove (purified_file_name3.c_str());

ofstream ofs2 (purified_file_name2.c_str());
ofstream ofs3 (purified_file_name3.c_str());


if (!ofs2)
{
cerr << ""
<< endl
<< "ERROR : Unable to open output file "
<< purified_file_name2
<< endl;
return;
}
assert (ofs2);
assert (ofs2.is_open());


if (!ofs3)
{
cerr << ""
<< endl
<< "ERROR : Unable to open output file "
<< purified_file_name3
<< endl;
return;
}
assert (ofs3);
assert (ofs3.is_open());


ASSERTION (rows_.size() == modes_.size());
for (ulong row_no = 0; row_no < rows_.size(); row_no++)
{
ASSERTION (rows_[row_no].size() == modes_[row_no].size());
for (ulong field_no = 0; field_no < rows_[row_no].size(); field_no++)
{
ASSERTION (modes_[row_no][field_no] < LAST_ByteModeId);
switch (modes_[row_no][field_no])
{
case LIVING_SPACE_Id :
case QL_BRACKET_Id :
case QR_BRACKET_Id :
case Q_STRING_Id :
ofs2 << rows_[row_no][field_no];
ofs3 << rows_[row_no][field_no];
break;

case CPP_BRACKET_Id :
case CL_BRACKET_Id :
case CR_BRACKET_Id :
case COMMENT_Id :
ofs2 << ' ';
break;

default :
ASSERTION (0);
break; // unused
}

}
ofs2 << endl;
ofs3 << endl;
}


const string pref (max_filenames_size_s, ' ');
ostringstream oss;


oss << "Files purified from comments created";

cout << pref << string (oss.str().size(), '-') << endl;
cout << pref << oss.str() << endl;
cout << pref << "* " << purified_file_name2 << endl;
cout << pref << "* " << purified_file_name3 << endl;
cout << pref << string (oss.str().size(), '-') << endl;

cout << endl;

}


// ---------
bool CountCodeLines::get_first_field (ulong& row_no_o, ulong& field_no_o)
{
for (ulong k = 0; k < rows_.size(); k++)
{
if (!rows_[k].empty())
{
row_no_o = k;
field_no_o = 0;
return true;
}
}
return false;
}

// ---------
void CountCodeLines::sign_modes (ulong row_no_i, ulong field_no_i)
{
ASSERTION (row_no_i < rows_.size());
ASSERTION (field_no_i < rows_[row_no_i].size());

// -------------------------
ulong start_selected_row_no;
ulong start_selected_field_no;
ulong end_selected_row_no;
ulong end_selected_field_no;

ulong cpp_bracket_row_no;
ulong cpp_bracket_field_no;

ulong cl_bracket_row_no;
ulong cl_bracket_field_no;
ulong cr_bracket_row_no;
ulong cr_bracket_field_no;

ulong ql_row_no;
ulong ql_field_no;
ulong qr_row_no;
ulong qr_field_no;


const bool cpp_bracket_found = find_token (
CPP_BRACKET,
cpp_bracket_row_no,
cpp_bracket_field_no,
row_no_i,
field_no_i
);

const bool cl_bracket_found = find_token (
CL_BRACKET,
cl_bracket_row_no,
cl_bracket_field_no,
row_no_i,
field_no_i
);

const bool ql_found = find_token (
QL_BRACKET,
ql_row_no,
ql_field_no,
row_no_i,
field_no_i,
true
);


if (!cpp_bracket_found && !cl_bracket_found & !ql_found)
{
mask2_modes (row_no_i, field_no_i);
return;
}

// -----------------------
ASSERTION (cpp_bracket_found || cl_bracket_found || ql_found);

const Couple cpp_couple (Couple (cpp_bracket_row_no, cpp_bracket_field_no));
const Couple cl_couple (Couple (cl_bracket_row_no, cl_bracket_field_no));
const Couple ql_couple (Couple (ql_row_no, ql_field_no));

vector<Couple> found;

if (cpp_bracket_found) found.push_back(cpp_couple);
if (cl_bracket_found) found.push_back(cl_couple);
if (ql_found) found.push_back(ql_couple);

ASSERTION (!found.empty());

for (ulong i = 0; i < found.size(); i++)
{
for (ulong k = 0; k < found.size(); k++)
{
if (i == k) continue;
ASSERTION (!(found[i] == found[k]));
}
}

sort (found.begin(), found.end());

// -----------------------

ulong counter = 0;
ByteModeId mode_id = UNDEF_ByteModeId;

if (found.front() == cpp_couple)
{
counter++;
mode_id = CPP_BRACKET_Id;

ASSERTION (cpp_bracket_found);

start_selected_row_no = cpp_bracket_row_no;
start_selected_field_no = cpp_bracket_field_no;

end_selected_row_no = cpp_bracket_row_no;
end_selected_field_no = modes_[cpp_bracket_row_no].size() - 1;

} // if (found.front() == cpp_couple)


if (found.front() == cl_couple)
{
counter++;
mode_id = CL_BRACKET_Id;

ASSERTION (cl_bracket_found);

// -----------------
bool cr_bracket_found = find_token (
CR_BRACKET,
cr_bracket_row_no,
cr_bracket_field_no,
row_no_i,
field_no_i
);

ASSERTION (cr_bracket_found);
if (
(cl_bracket_row_no == cr_bracket_row_no)
&&
((cr_bracket_field_no - cl_bracket_field_no) < BRACKET_SIZE)
)
{
cr_bracket_found = find_token (
CR_BRACKET,
cr_bracket_row_no,
cr_bracket_field_no,
cl_bracket_row_no,
(cl_bracket_field_no + BRACKET_SIZE)
);
}
ASSERTION (cr_bracket_found);

ASSERTION ((cl_bracket_row_no < cr_bracket_row_no) || ((cl_bracket_row_no == cr_bracket_row_no) && (cl_bracket_field_no <
cr_bracket_field_no)));

start_selected_row_no = cl_bracket_row_no;
start_selected_field_no = cl_bracket_field_no;

end_selected_row_no = cr_bracket_row_no;
end_selected_field_no = cr_bracket_field_no + BRACKET_SIZE - 1;

} // if (found.front() == cl_couple)


if (found.front() == ql_couple)
{
counter++;
mode_id = QL_BRACKET_Id;


ASSERTION (ql_found);

// -----------------
bool qr_found = find_token (
QR_BRACKET,
qr_row_no,
qr_field_no,
ql_row_no,
ql_field_no + QUOTE_SIZE,
true
);

ASSERTION (qr_found);
ASSERTION (qr_row_no == ql_row_no);
ASSERTION (qr_field_no > ql_field_no);

start_selected_row_no = ql_row_no;
start_selected_field_no = ql_field_no;

end_selected_row_no = qr_row_no;
end_selected_field_no = qr_field_no + QUOTE_SIZE - 1;


} // if (found.front() == ql_couple)

ASSERTION (counter == 1);
ASSERTION (mode_id != UNDEF_ByteModeId);


mask_modes (
row_no_i,
field_no_i,
start_selected_row_no,
start_selected_field_no,
end_selected_row_no,
end_selected_field_no,
mode_id
);


ulong next_row_no;
ulong next_field_no;

const Couple couple (end_selected_row_no, end_selected_field_no);

if (!couple.get_next(modes_, next_row_no, next_field_no))
{
return;
}

return sign_modes (next_row_no, next_field_no);

}

// ---------
void CountCodeLines::mask_modes (
ulong row1_i,
ulong field1_i,
ulong row2_i,
ulong field2_i,
ulong row3_i,
ulong field3_i,
ByteModeId mode_id_i
)
{

ulong delim_size = 0;

switch (mode_id_i)
{
case CPP_BRACKET_Id :
case CL_BRACKET_Id :
delim_size = BRACKET_SIZE;
break;

case QL_BRACKET_Id :
delim_size = QUOTE_SIZE;
break;

default :
ASSERTION (0);
break; // unused
}

ASSERTION (delim_size > 0);


// ------ 1 ------
bool break_flag = false;

for (ulong k = row1_i; k < modes_.size(); k++)
{
const ulong start_field = ((k == row1_i) ? field1_i : 0);
for (ulong field = start_field; field < modes_[k].size(); field++)
{
if (Couple (k, field) < Couple (row2_i, field2_i))
{
modes_[k][field] = LIVING_SPACE_Id;
}
else
{
break_flag = true;
break;
}
}
if (break_flag) break;
}

// ------ 2 ------
for (ulong s = 0; s < delim_size; s++)
{
ASSERTION ((field2_i + s) < modes_[row2_i].size());

char& the_item = modes_[row2_i][field2_i + s];

switch (mode_id_i)
{
case CPP_BRACKET_Id :
the_item = CPP_BRACKET_Id;
break;

case CL_BRACKET_Id :
the_item = CL_BRACKET_Id;
break;

case QL_BRACKET_Id :
the_item = QL_BRACKET_Id;
break;

default :
ASSERTION (0);
break; // unused
}

}


// ------ 3 ------
for (ulong t = row2_i; t < modes_.size(); t++)
{
const ulong start_field = ((t == row2_i) ? (field2_i + delim_size) : 0);
for (ulong field = start_field; field < modes_[t].size(); field++)
{
if (Couple (t, field) <= Couple (row3_i, field3_i))
{
switch (mode_id_i)
{
case CPP_BRACKET_Id :
case CL_BRACKET_Id :
modes_[t][field] = COMMENT_Id;
break;

case QL_BRACKET_Id :
modes_[t][field] = Q_STRING_Id;
break;

default :
ASSERTION (0);
break; // unused
}

}
else
{
break;
}
}
}


// ------ 4 ------

switch (mode_id_i)
{
case CPP_BRACKET_Id :
// Do nothing
break;

case CL_BRACKET_Id :
ASSERTION ((field3_i + 1) >= delim_size);
for (ulong field = (field3_i - delim_size + 1); field <= field3_i; field++)
{
modes_[row3_i][field] = CR_BRACKET_Id;
}
break;

case QL_BRACKET_Id :
ASSERTION (field3_i >= delim_size);
for (ulong field = (field3_i - delim_size + 1); field <= field3_i; field++)
{
modes_[row3_i][field] = QR_BRACKET_Id;
}
break;

default :
ASSERTION (0);
break; // unused
}

}


// ---------
void CountCodeLines::mask2_modes (
ulong row_i,
ulong field_i
)
{
for (ulong k = row_i; k < modes_.size(); k++)
{
const ulong start_field = ((k == row_i) ? field_i : 0);
for (ulong field = start_field; field < modes_[k].size(); field++)
{
ASSERTION (modes_[k][field] == UNDEF_ByteModeId);
modes_[k][field] = LIVING_SPACE_Id;
}
}

}

// ---------
void CountCodeLines::init_modes ()
{
for (ulong k = 0; k < rows_.size(); k++)
{
modes_.push_back(string (rows_[k].size(), UNDEF_ByteModeId));
}

ASSERTION (rows_.size() == modes_.size());
for (ulong k = 0; k < rows_.size(); k++)
{
ASSERTION (rows_[k].size() == modes_[k].size());
}


}


// ---------
bool CountCodeLines::find_token (
const string& token_i,
ulong& row_no_o,
ulong& field_no_o,
ulong row_no_i,
ulong field_no_i,
bool deny_check_i
) const
{
ASSERTION (row_no_i < rows_.size());
ASSERTION (field_no_i < rows_[row_no_i].size());


if (!deny_check_i)
{
for (ulong k = row_no_i; k < rows_.size(); k++)
{
const ulong start_field = ((k == row_no_i) ? field_no_i : 0);
if ((field_no_o = rows_[k].find (token_i, start_field)) != string::npos)
{
row_no_o = k;
return true;
}
}
}
else
{
for (ulong k = row_no_i; k < rows_.size(); k++)
{
ulong start_field = ((k == row_no_i) ? field_no_i : 0);

for ( ; start_field < rows_[k].size(); )
{
field_no_o = rows_[k].find (token_i, start_field);

if (field_no_o == string::npos) break;

ASSERTION (field_no_o != string::npos);

ulong slash_count = 0;
long pos = field_no_o - 1;
while ((pos >= 0) && (rows_[k][pos] == ONE_SLASH))
{
slash_count++;
pos--;
}

if (slash_count%2 == 0)
{
row_no_o = k;
return true;
}
else
{
start_field++;
}
}
}
}

row_no_o = ULONG_MAX;
field_no_o = ULONG_MAX;

return false;

}

// ---------
void CountCodeLines::prepare_reported_data ()
{

for (ulong i = 0; i < modes_.size(); i++)
{
triple_.push_back(Triple());
assert (rows_.size() == modes_.size());
for (ulong k = 0; k < modes_[i].size(); k++)
{
switch (modes_[i][k])
{
case LIVING_SPACE_Id :
if ((rows_[i][k] == SPACE_VALUE) || (rows_[i][k] == TAB_VALUE))
{
triple_.back().empty_fields_.push_back(k);
}
else
{
triple_.back().code_fields_.push_back(k);
}
break;

case CPP_BRACKET_Id :
case CL_BRACKET_Id :
case CR_BRACKET_Id :
case COMMENT_Id :
triple_.back().comment_fields_.push_back(k);
break;

case QL_BRACKET_Id :
case QR_BRACKET_Id :
case Q_STRING_Id :
triple_.back().code_fields_.push_back(k);
break;

default :
assert(0);
break; // unused
}

}
assert ((triple_.back().code_fields_.size() + triple_.back().empty_fields_.size() + triple_.back().comment_fields_.size()) ==
modes_[i].size());

all_files_code_fields_s += triple_.back().code_fields_.size();
all_files_empty_fields_s += triple_.back().empty_fields_.size();
all_files_comment_fields_s += triple_.back().comment_fields_.size();
}

}

// ---------
void CountCodeLines::Print_Summary_Report (
const string& center_title_i,
const string& left_title_i,

ulong lines_code_only_i,
ulong lines_code_comment_i,
ulong lines_comment_only_i,
ulong lines_empty_i,

ulong fields_code_i,
ulong fields_comment_i,
ulong fields_empty_i
)
{
const ulong total_lines = lines_code_only_i
+ lines_code_comment_i
+ lines_comment_only_i
+ lines_empty_i;

const ulong total_fields = fields_code_i
+ fields_comment_i
+ fields_empty_i;


ostringstream oss;
if (!center_title_i.empty())
{
cout << endl;
cout << endl;

const string pref (string (max_filenames_size_s, ' '));

oss.str("");
oss << "##### " << center_title_i << " #####";

cout << string(pref.size(), ' ') << string (oss.str().size(), '=') << endl;
cout << string(pref.size(), ' ') << oss.str() << endl;
cout << string(pref.size(), ' ') << string (oss.str().size(), '=') << endl;
cout << endl;
}

// ----------------------
vector<ulong> col_size;
col_size.push_back(TXT1_SIZE);
col_size.push_back(ROW_NO_SIZE);
col_size.push_back(FIELD_NO_SIZE);

oss.str("");
oss << setw (max_filenames_size_s)
<< left
<< left_title_i;

const vector<bool> align;
vector<string> row;

vector<vector<string> > header;
header.push_back(vector<string>());

header.back().push_back("");
header.back().push_back(LINES_TXT0);
header.back().push_back(BYTES_TXT0);

// ------ table numbers ------
{
cout << endl;
SimpleTable table_numbers ("Summary Report (numbers)", col_size, oss.str(), align, true);

table_numbers.build_header (header);

row.clear();
row.push_back(CODE_ONLY_TXT1);
row.push_back(to_str(lines_code_only_i));
row.push_back(to_str(fields_code_i));
table_numbers.build_row (row);

row.clear();
row.push_back(CODE_COMMENT_TXT1);
row.push_back(to_str(lines_code_comment_i));
row.push_back("-");
table_numbers.build_row (row);


row.clear();
row.push_back(COMMENT_ONLY_TXT1);
row.push_back(to_str(lines_comment_only_i));
row.push_back(to_str(fields_comment_i));
table_numbers.build_row (row);


row.clear();
row.push_back(EMPTY_TXT1);
row.push_back(to_str(lines_empty_i));
row.push_back(to_str(fields_empty_i));
table_numbers.build_row (row);


row.clear();
row.push_back(TOTAL_TXT1);
row.push_back(to_str(total_lines));
row.push_back(to_str(total_fields));
table_numbers.build_row (row);
}


// ------ table percents ------
{
double cur_line_percent;
double cur_field_percent;
ostringstream tss;
tss.setf(ios::fixed, ios::floatfield);
tss.precision(1);

cout << endl;
SimpleTable table_percents ("Summary Report (percents)", col_size, oss.str(), align, true);

table_percents.build_header (header);

row.clear();
row.push_back(CODE_ONLY_TXT1);

cur_line_percent = (lines_code_only_i*PERCENT_FACTOR)/total_lines;
tss.str("");
tss << cur_line_percent;
tss << PERCENT_SIGN;
row.push_back(total_lines ? tss.str() : NONE_TXT);

cur_field_percent = (fields_code_i*PERCENT_FACTOR)/total_fields;
tss.str("");
tss << cur_field_percent;
tss << PERCENT_SIGN;
row.push_back(total_fields ? tss.str() : NONE_TXT);

table_percents.build_row (row);


row.clear();
row.push_back(CODE_COMMENT_TXT1);

cur_line_percent = (lines_code_comment_i*PERCENT_FACTOR)/total_lines;
tss.str("");
tss << cur_line_percent;
tss << PERCENT_SIGN;
row.push_back(total_lines ? tss.str() : NONE_TXT);

row.push_back("-");

table_percents.build_row (row);


row.clear();
row.push_back(COMMENT_ONLY_TXT1);

cur_line_percent = (lines_comment_only_i*PERCENT_FACTOR)/total_lines;
tss.str("");
tss << cur_line_percent;
tss << PERCENT_SIGN;
row.push_back(total_lines ? tss.str() : NONE_TXT);

cur_field_percent = (fields_comment_i*PERCENT_FACTOR)/total_fields;
tss.str("");
tss << cur_field_percent;
tss << PERCENT_SIGN;
row.push_back(total_fields ? tss.str() : NONE_TXT);

table_percents.build_row (row);


row.clear();
row.push_back(EMPTY_TXT1);

cur_line_percent = (lines_empty_i*PERCENT_FACTOR)/total_lines;
tss.str("");
tss << cur_line_percent;
tss << PERCENT_SIGN;
row.push_back(total_lines ? tss.str() : NONE_TXT);

cur_field_percent = (fields_empty_i*PERCENT_FACTOR)/total_fields;
tss.str("");
tss << cur_field_percent;
tss << PERCENT_SIGN;
row.push_back(total_fields ? tss.str() : NONE_TXT);

table_percents.build_row (row);

row.clear();
row.push_back(TOTAL_TXT1);

cur_line_percent = (total_lines*PERCENT_FACTOR)/total_lines;
tss.str("");
tss << setprecision (0);
tss << cur_line_percent;
tss << PERCENT_SIGN;
row.push_back(total_lines ? tss.str() : NONE_TXT);

cur_field_percent = (total_fields*PERCENT_FACTOR)/total_fields;
tss.str("");
tss << setprecision (0);
tss << cur_field_percent;
tss << PERCENT_SIGN;
row.push_back(total_fields ? tss.str() : NONE_TXT);

table_percents.build_row (row);

}

}


// ---------
void CountCodeLines::Show_Summary_Report ()
{
assert (!filenames_s.empty());
if (filenames_s.size() == 1) return;

ostringstream oss;
oss << "All " << filenames_s.size() << " files";
cout << endl;
cout << endl;
cout << endl;
cout << endl;
Print_Summary_Report (
oss.str(),
"All files",

all_files_code_only_lines_s,
all_files_code_comment_lines_s,
all_files_comment_only_lines_s,
all_files_empty_lines_s,

all_files_code_fields_s,
all_files_comment_fields_s,
all_files_empty_fields_s
);

}

// ---------
void CountCodeLines::show_summary_report (const string& prefix_i) const
{
ulong code_only_lines = 0;
ulong code_comment_lines = 0;
ulong comment_only_lines = 0;
ulong empty_lines = 0;
const ulong total_lines = rows_.size();

ulong code_fields = 0;
ulong comment_fields = 0;
ulong empty_fields = 0;
ulong total_fields = 0;


assert (triple_.size() == total_lines);
for (ulong k = 0; k < triple_.size(); k++)
{
total_fields += rows_[k].size();

code_fields += triple_[k].code_fields_.size();
comment_fields += triple_[k].comment_fields_.size();
empty_fields += triple_[k].empty_fields_.size();

// ----------------
if (!triple_[k].code_fields_.empty())
{
if (triple_[k].comment_fields_.empty())
{
code_only_lines++;
all_files_code_only_lines_s++;
}
else
{
code_comment_lines++;
all_files_code_comment_lines_s++;
}
continue;
}
assert (triple_[k].code_fields_.empty());


if (!triple_[k].comment_fields_.empty())
{
comment_only_lines++;
all_files_comment_only_lines_s++;
continue;
}
assert (triple_[k].comment_fields_.empty());

assert (triple_[k].empty_fields_.size() == rows_[k].size());

empty_lines++;
all_files_empty_lines_s++;

}
assert (total_lines == (code_only_lines + code_comment_lines + comment_only_lines + empty_lines));
assert (total_fields == (code_fields + comment_fields + empty_fields));


Print_Summary_Report (
"",
prefix_i,

code_only_lines,
code_comment_lines,
comment_only_lines,
empty_lines,

code_fields,
comment_fields,
empty_fields
);

}

// ---------
void CountCodeLines::show_detailed_report (const string& prefix_i) const
{
ostringstream oss;

const bool detailed_opt1 =
count (actual_options_s.begin(), actual_options_s.end(), to_str(DETAILED_OPTION1_ROW));

const bool detailed_opt2 =
count (actual_options_s.begin(), actual_options_s.end(), to_str(DETAILED_OPTION2_ROW));

const bool detailed_opt3 =
count (actual_options_s.begin(), actual_options_s.end(), to_str(DETAILED_OPTION3_ROW_COL));


const string line_txt1 ("Line#");
const string byte_txt1 ("* Char");
ulong col1_size = line_txt1.size() + ROW_NO_SIZE;
if (detailed_opt3)
{
col1_size = MAX_VALUE (col1_size, byte_txt1.size() + ROW_NO_SIZE + FIELD_NO_SIZE + 4);
}
const ulong col2_size = 16;
const ulong col3_size = 7;
const ulong col4_size = col3_size;
const ulong col5_size = col3_size;

assert (col2_size >= (string (CODE_ONLY_TXT1).size()));
assert (col2_size >= (string (CODE_COMMENT_TXT1).size()));
assert (col2_size >= (string (COMMENT_ONLY_TXT1).size()));
assert (col2_size >= (string (EMPTY_TXT1).size()));

assert (col2_size >= (string (CODE_TXT2).size()));
assert (col2_size >= (string (CODE_STRING_TXT2).size()));
assert (col2_size >= (string (COMMENT_TXT2).size()));
assert (col2_size >= (string (COMMENT_BLANK_TXT2).size()));
assert (col2_size >= (string (EMPTY_TXT2).size()));


const string pref ((ulong(count(prefix_i.begin(), prefix_i.end(), ' ')) == prefix_i.size()) ? "" : prefix_i);


cout << endl;

// ----------------------
vector<ulong> col_size;
col_size.push_back(col1_size);
col_size.push_back(col2_size);
if (detailed_opt2)
{
col_size.push_back(col3_size);
col_size.push_back(col4_size);
col_size.push_back(col5_size);
}


ostringstream tss, tss2;
tss << "Detailed Report (";
if (detailed_opt1) tss2 << "Line Info-1";
if (detailed_opt2)
{
tss2.str("");
tss2 << "Line Info-2";
}
if (detailed_opt3)
{
tss2.str("");
tss2 << "Line & Chars Info";
}
tss << tss2.str() << ")";

const vector<bool> align (2, true);
SimpleTable table (tss.str(), col_size, prefix_i, align);

vector<vector<string> > header;

header.push_back(vector<string>());

header.back().push_back("Line#");
header.back().push_back("Content");

if (detailed_opt2)
{
header.back().push_back("Code ");
header.back().push_back("Comment");
header.back().push_back("Blank");
}

if (detailed_opt2)
{
header.push_back(vector<string>());

header.back().push_back("");
header.back().push_back("");
header.back().push_back("Chars");
header.back().push_back("Chars ");
header.back().push_back("Chars");
}


table.build_header (header);


assert (triple_.size() == rows_.size());
assert (triple_.size() == modes_.size());
for (ulong k = 0; k < triple_.size(); k++)
{
// ----------------
ostringstream tss_col1_line;
ostringstream tss_col2;

// ----------------
if (k > 0)
{
if (detailed_opt3) table.build_empty_row();
}

tss_col1_line << line_txt1
<< setw (ROW_NO_SIZE)
<< right
<< (k + 1);

// ----------------
if (!triple_[k].code_fields_.empty())
{
if (!triple_[k].comment_fields_.empty())
{
tss_col2 << CODE_COMMENT_TXT1;
}
else
{
tss_col2 << CODE_ONLY_TXT1;
}
}
else
{
if (!triple_[k].comment_fields_.empty())
{
tss_col2 << COMMENT_ONLY_TXT1;
}
}

if (triple_[k].empty_fields_.size() == rows_[k].size())
{
tss_col2 << EMPTY_TXT1;
}

// ----------------
vector<string> row;

row.push_back(tss_col1_line.str());
row.push_back(tss_col2.str());

if (detailed_opt2)
{
row.push_back(to_str(triple_[k].code_fields_.size()));
row.push_back(to_str(triple_[k].comment_fields_.size()));
row.push_back(to_str(triple_[k].empty_fields_.size()));
}

table.build_row (row);

if (detailed_opt3)
{
for (ulong t = 0; t < modes_[k].size(); t++)
{
ostringstream tss_col1_byte;
tss_col1_byte << byte_txt1
<< "["
<< setw (ROW_NO_SIZE)
<< right
<< (k + 1)
<< "]"
<< "["
<< setw (FIELD_NO_SIZE)
<< right
<< (t + 1)
<< "]";

row.clear();
row.push_back(tss_col1_byte.str());


ASSERTION (modes_[k][t] < LAST_ByteModeId);
switch (modes_[k][t])
{
case LIVING_SPACE_Id :
if ((rows_[k][t] == SPACE_VALUE) || (rows_[k][t] == TAB_VALUE))
{
row.push_back(EMPTY_TXT2);
}
else
{
row.push_back(CODE_TXT2);
}
break;

case CPP_BRACKET_Id :
case CL_BRACKET_Id :
case CR_BRACKET_Id :
case COMMENT_Id :
if ((rows_[k][t] == SPACE_VALUE) || (rows_[k][t] == TAB_VALUE))
{
row.push_back(COMMENT_BLANK_TXT2);
}
else
{
row.push_back(COMMENT_TXT2);
}
break;

case QL_BRACKET_Id :
case QR_BRACKET_Id :
case Q_STRING_Id :
row.push_back(CODE_STRING_TXT2);
break;

default :
assert (0);
break; // unused
}

table.build_row (row);
}

}


}

}

// ---------
void CountCodeLines::show_report () const
{

assert (!filenames_s.empty());

// -----------------------------
ostringstream oss;

oss << setw (max_filenames_size_s)
<< left
<< ((filenames_s.size() == 1) ? "" : filename_.c_str());

const string pref (oss.str());

cout << endl;
cout << endl;
cout << endl;
cout << endl;

oss.str("");
oss << "### File : " << filename_ << " ###";

cout << string(pref.size(), ' ') << string (oss.str().size(), '=') << endl;
cout << string(pref.size(), ' ') << oss.str() << endl;
cout << string(pref.size(), ' ') << string (oss.str().size(), '=') << endl;
cout << endl;

create_purified_code ();
assert (!actual_options_s.empty());

// ------- summary_report ------
if (count (actual_options_s.begin(), actual_options_s.end(), to_str(SUMMARY_OPTION)))
{
show_summary_report (pref);
}


// ------- detailed_report ------
if (
count (actual_options_s.begin(), actual_options_s.end(), to_str(DETAILED_OPTION1_ROW))
||
count (actual_options_s.begin(), actual_options_s.end(), to_str(DETAILED_OPTION2_ROW))
||
count (actual_options_s.begin(), actual_options_s.end(), to_str(DETAILED_OPTION3_ROW_COL))
)
{
show_detailed_report (pref);
}

}


// ---------
bool CountCodeLines::open_file ()
{
assert (!filename_.empty());

fin_.open (filename_.c_str());

if (!fin_)
{
cerr << ""
<< endl
<< "ERROR : Unable to open input file "
<< filename_
<< endl;
return false;
}

assert (fin_);
assert (fin_.is_open());
return true;
}

// ---------
void CountCodeLines::read_file ()
{
assert (fin_.is_open());
assert (rows_.empty());

string file_line;
while (getline (fin_, file_line)) rows_.push_back (file_line);
}

// --------------
string CountCodeLines::exe_basename_s;
string CountCodeLines::exe_full_name_s;
vector<string> CountCodeLines::filenames_s;
ulong CountCodeLines::max_filenames_size_s (0);
vector<string> CountCodeLines::actual_options_s;
map<string, vector<string> > CountCodeLines::allowed_options_s;

ulong CountCodeLines::all_files_code_only_lines_s (0);
ulong CountCodeLines::all_files_code_comment_lines_s (0);
ulong CountCodeLines::all_files_empty_lines_s (0);
ulong CountCodeLines::all_files_comment_only_lines_s (0);
ulong CountCodeLines::all_files_code_fields_s (0);
ulong CountCodeLines::all_files_empty_fields_s (0);
ulong CountCodeLines::all_files_comment_fields_s (0);

// --------------
int main (int argc, char** argv)
{
cout << endl;
cout << "\tYOUR COMMAND LINE : ";
for (int i = 0; i < argc; i++) cout << argv[i] << " ";
cout << endl;

if (!CountCodeLines::Set_Exe_Filename (argv[0])) return 1;
CountCodeLines::Init_Allowed_Options ();

// -------------------------
CountCodeLines::Set_Default_Option ();
for (int i = 1; i < argc; i++)
{
const string str (argv[i]);
if (str[0] != PRE_OPTION_SIGN)
{
CountCodeLines::Add_Filename (str);
continue;
}

if (CountCodeLines::Set_Actual_Options (str)) return 0;
}

const vector<string>& filenames = CountCodeLines::Get_Filenames ();

// -------------------------
for (ulong i = 0; i < filenames.size(); i++)
{
CurFilename_Static = filenames[i];
CountCodeLines counter(CurFilename_Static);
if (!counter.get_open_status()) continue;
}

if (CurFilename_Static.empty())
{
CountCodeLines::Show_Help ();
return 1;
}

CountCodeLines::Show_Summary_Report ();

return 0;
}

Alex Vinokur

unread,
Feb 5, 2004, 12:05:47 PM2/5/04
to


#define DEF1 301

#define DEF2 \
302 /* Comment C-01 */

#define DEF3 303 /* Comment C-02 */

#define DEF4 /* Comment C-03 * / 98/*7 /* Comment C-04 */ 304

#define DEF5 /* Comment C-05 */ 305 /* Comment C-06 */

#define DEF6 306 // Comment CPP-01

#define DEF7 "Hello, /* define */ !"

#define DEF8 "Hello, \"define\"!"

#define DEF9 "Hello, \"define\"!" // Comment CPP-02


int main()
{
int i = 0;
i = i + 100; // Comment CPP-03

i = i + 101;

i = i + DEF1;

i = i + DEF2;

i = i + DEF3;

i = i + DEF4;

i = i + DEF5;

i = i + DEF6;

// Comment CPP-04; i = i + 102;

i = i + 103;
i = i + // Comment CPP-05
104;

i = i +
// Comment CPP-06
105;


i = i + 200; /* Comment C-07 */

i = i + 201; /* Comment C-08 */ /* Comment C-09 */

i = i + 202;

/* Comment C-10 i = i + 203; */

/* Comment C-11; */ i = i + 204;

i = i + 205; /* Comment C-12; */

i = i + 206;

i = i + 207; /* Comment C-13; */ i = i + 208;

i = i /* Comment C-14 */ + 209;

i = i + /* Comment C-15 */
210;

i = i +
/* Comment C-16 */
211;

i = i + 212;
/*
Comment C-17
*/

i = i + 213; /*
Comment C-18
*/


i = i + /*
Comment C-19
*/
214;


i = i + /*
Comment C-20
*/ 215;


i = i + /*
// Comment C-21
*/ 216;


i = i + /*
// Comment C-22 */
217;

i = i + 106; //* Comment CPP-07 */

i = i + 107; // /* Comment CPP-08 */

i = i + 108; //* Comment CPP-09 */


i = i + 218;
/* Comment C-23

/*
Comment C-24
*/


i = i + 219; /* Comment C-25 /* Comment C-26 */

i = i + 220; /* Comment C-27 // Comment C-28 */

i = i + 221; /*/ Comment C-29 */
i = i + 222;

i = i + 223; /* Comment C-30 /*/

i = i + 224; /* Comment C-31 */

i = i + 225; /* Comment C-32 */ i = i + 224; // Comment CPP-10 /* Comment C-33 */


char a1[] = "Hel\"lo /* word */\n\"";

// Comment CPP-11 : char a2[] = "Hel\"lo /* word */\n\"";

/* Comment C-34 : char a3[] = "Hel\"lo /* word \n\""; */

char a4[] = /*"Hel\"lo /* word \n\""*/"Hi everybody";

char a5[] = "";

char a6[] = "\"";

char a7[] = "/* Comment C-35*/";


char a8[] = "\\";

char a9[] = "\\\\";
char a10[] = "\\\\\"\\\\\\";

char a11[] = "\\\\\"\\/* Comment C-36 */\\\\";
char a12[] = "\\\\\"\\/* Comment C-37 */\\\"";

char a13[]=
"";

char a14[]=
"\"";


char d1[] = DEF7;

char d2[] = DEF8;

char d3[] = DEF9;

char bye[] = "Bye";

return 0;

}


0 new messages