31 #ifdef CCCC_CONF_W32VC
34 #ifdef CCCC_CONF_W32BC
63 CCCC_Html_Stream main_html_stream(file.c_str(),
"Report on software metrics");
77 main_html_stream.Table_Of_Contents(report_mask,
false);
83 main_html_stream.Project_Summary();
88 main_html_stream.Procedural_Summary();
93 main_html_stream.Procedural_Detail();
98 main_html_stream.OO_Design();
103 main_html_stream.Structural_Summary();
108 main_html_stream.Structural_Detail();
113 main_html_stream.Separate_Modules();
118 main_html_stream.Other_Extents();
123 main_html_stream.Source_Listing();
129 main_html_stream.Put_Section_Heading(
"About CCCC",
"infocccc",1);
130 main_html_stream.fstr
131 <<
"<P>This report was generated by the program CCCC, which is FREELY "
132 <<
"REDISTRIBUTABLE but carries NO WARRANTY." << endl
133 <<
"<P>CCCC was developed by Tim Littlefair. " << endl
134 <<
"as part of a PhD research project. "
135 <<
"This project is now completed and descriptions of the "
136 <<
"findings can be accessed at "
137 <<
"<A HREF=http://www.chs.ecu.edu.au/~tlittlef>"
138 <<
"http://www.chs.ecu.edu.au/~tlittlef</A>. "
139 <<
"<P>User support for CCCC can be obtained by "
140 <<
"<A HREF=mailto:cccc-users@lists.sourceforge.net>"
141 <<
"mailing the list cccc-users@lists.sourceforge.net</A>."
142 <<
"<P>Please also visit the new CCCC development website at "
143 <<
"<A HREF=http://sarnold.github.io/cccc/>http://sarnold.github.io/cccc/</A>."
150 fstr <<
"</BODY></HTML>" << endl;
160 int number_of_report_parts=0;
161 int saved_stream_offset=
fstr.tellp();
163 fstr <<
"<TABLE BORDER WIDTH=100%>" << endl
164 <<
"<TR><TH COLSPAN=2>" << endl
165 <<
"CCCC Software Metrics Report";
174 if(showGenTime==
true)
176 time_t generationTime=time(NULL);
177 fstr <<
"<BR> generated " << ctime(&generationTime) << endl;
180 fstr <<
"</TR>" << endl;
185 "Project Summary",
"projsum",
186 "Summary table of high level measures summed "
187 "over all files processed in the current run.");
188 number_of_report_parts++;
194 "Procedural Metrics Summary",
"procsum",
195 "Table of procedural measures (i.e. lines of "
196 "code, lines of comment, McCabe's cyclomatic "
197 "complexity summed over each module.");
198 number_of_report_parts++;
204 "Procedural Metrics Detail",
"procdet",
205 "The same procedural metrics as in the procedural "
206 "metrics summary, reported for individual "
207 "functions, grouped by module.");
208 number_of_report_parts++;
214 "Object Oriented Design",
"oodesign",
215 "Table of four of the 6 metrics proposed by "
216 "Chidamber and Kemerer in their various papers on "
217 "'a metrics suite for object oriented design'.");
218 number_of_report_parts++;
224 "Structural Metrics Summary",
"structsum",
225 "Structural metrics based on the relationships of "
226 "each module with others. Includes fan-out (i.e. "
227 "number of other modules the current module "
228 "uses), fan-in (number of other modules which use "
229 "the current module), and the Information Flow "
230 "measure suggested by Henry and Kafura, which "
231 "combines these to give a measure of coupling for "
233 number_of_report_parts++;
239 "Structural Metrics Detail",
"structdet",
240 "The names of the modules included as clients and "
241 "suppliers in the counts for the Structural "
243 number_of_report_parts++;
249 "Other Extents",
"other",
250 "Lexical counts for parts of submitted source "
251 "files which the analyser was unable to assign to "
252 "a module. Each record in this table relates to "
253 "either a part of the code which triggered a "
254 "parse failure, or to the residual lexical counts "
255 "relating to parts of a file not associated with "
258 number_of_report_parts++;
264 "About CCCC",
"infocccc",
265 "A description of the CCCC program.");
266 number_of_report_parts++;
269 fstr <<
"</TR></TABLE>" << endl;
270 if(number_of_report_parts<2)
272 fstr.seekp(saved_stream_offset);
277 string heading_title,
281 fstr <<
"<H" << heading_level <<
">"
282 <<
"<A NAME=\"" << heading_tag <<
"\">"
284 <<
"</A></H" << heading_level
291 fstr <<
"This table shows measures over the project as a whole." << endl;
293 fstr <<
"<UL>" << endl;
295 "Number of non-trivial modules identified by the "
296 "analyser. Non-trivial modules include all classes, "
297 "and any other module for which member functions are "
300 "Number of non-blank, non-comment lines of source code "
301 "counted by the analyser.");
303 "Number of lines of comment identified by the analyser");
305 "A measure of the decision complexity of the functions "
306 "which make up the program."
307 "The strict definition of this measure is that it is "
308 "the number of linearly independent routes through "
309 "a directed acyclic graph which maps the flow of control "
310 "of a subprogram. The analyser counts this by recording "
311 "the number of distinct decision outcomes contained "
312 "within each function, which yields a good approximation "
313 "to the formally defined version of the measure.");
315 "Indicates density of comments with respect to textual "
318 "Indicates density of comments with respect to logical "
319 "complexity of program");
321 "Measure of information flow between modules suggested "
322 "by Henry and Kafura. The analyser makes an approximate "
323 "count of this by counting inter-module couplings "
324 "identified in the module interfaces.");
326 fstr <<
"</UL>" << endl
327 <<
"Two variants on the information flow measure IF4 are also "
328 <<
"presented, one (IF4v) calculated using only relationships in the "
329 <<
"visible part of the module interface, and the other (IF4c) "
330 <<
"calculated using only those relationships which imply that changes "
331 <<
"to the client must be recompiled of the supplier's definition "
345 fstr <<
"<TABLE BORDER WIDTH=100%>" << endl
351 fstr <<
"</TR>" << endl;
353 fstr <<
"<TR>" << endl;
358 fstr <<
"</TR>" << endl;
360 fstr <<
"<TR>" << endl;
365 fstr <<
"</TR>" << endl;
367 fstr <<
"<TR>" << endl;
372 fstr <<
"</TR>" << endl;
374 fstr <<
"<TR>" << endl;
379 fstr <<
"</TR>" << endl;
381 fstr <<
"<TR>" << endl;
386 fstr <<
"</TR>" << endl;
388 fstr <<
"<TR>" << endl;
393 fstr <<
"</TR>" << endl;
395 fstr <<
"<TR>" << endl;
400 fstr <<
"</TR>" << endl;
402 fstr <<
"<TR>" << endl;
407 fstr <<
"</TR>" << endl;
409 fstr <<
"<TR>" << endl;
414 fstr <<
"</TR>" << endl;
416 fstr <<
"<TR>" << endl;
421 fstr <<
"</TR>" << endl;
423 fstr <<
"</TABLE>" << endl;
429 fstr <<
"<UL>" << endl;
431 "The sum of a weighting function over the functions of "
432 "the module. Two different weighting functions are "
433 "applied: WMC1 uses the nominal weight of 1 for each "
434 "function, and hence measures the number of functions, "
435 "WMCv uses a weighting function which is 1 for functions "
436 "accessible to other modules, 0 for private functions.");
438 "The length of the longest path of inheritance ending at "
439 "the current module. The deeper the inheritance tree "
440 "for a module, the harder it may be to predict its "
441 "behaviour. On the other hand, increasing depth gives "
442 "the potential of greater reuse by the current module "
443 "of behaviour defined for ancestor classes.");
445 "The number of modules which inherit directly from the "
446 "current module. Moderate values of this measure "
447 "indicate scope for reuse, however high values may "
448 "indicate an inappropriate abstraction in the design.");
450 "The number of other modules which are coupled to the "
451 "current module either as a client or a supplier. "
452 "Excessive coupling indicates weakness of module "
453 "encapsulation and may inhibit reuse.");
454 fstr <<
"</UL>" << endl << endl;
456 fstr <<
"The label cell for each row in this table provides a link to "
457 <<
"the module summary table in the detailed report for the "
458 <<
"module in question" << endl;
461 fstr <<
"<TABLE BORDER WIDTH=100%>" << endl
470 fstr <<
"</TR>" << endl;
479 const char *metric_tags[5]={
"WMC1",
"WMCv",
"DIT",
"NOC",
"CBO"};
480 fstr <<
"<TR>" << endl;
482 string href=mod_ptr->
key()+
".html#summary";
495 fstr <<
"</TR>" << endl;
501 fstr <<
"</TABLE>" << endl;
508 fstr <<
"For descriptions of each of these metrics see the information "
509 <<
"preceding the project summary table."
512 fstr <<
"The label cell for each row in this table provides a link to "
513 <<
"the functions table in the detailed report for the "
514 <<
"module in question" << endl;
516 fstr <<
"<TABLE BORDER WIDTH=100%>" << endl
525 fstr <<
"</TR>" << endl;
534 fstr <<
"<TR>" << endl;
535 string href=mod_ptr->
key()+
".html#procdet";
552 fstr <<
"</TR>" << endl;
558 fstr <<
"</TABLE>" << endl;
566 fstr <<
"<UL>" << endl;
568 "The number of other modules which pass information "
569 "into the current module.");
571 "The number of other modules into which the current "
572 "module passes information");
574 "A composite measure of structural complexity, "
575 "calculated as the square of the product of the fan-in "
576 "and fan-out of a single module. Proposed by Henry and "
578 fstr <<
"</UL>" << endl;
580 fstr <<
"Note that the fan-in and fan-out are calculated by examining the "
581 <<
"interface of each module. As noted above, three variants of each "
582 <<
"each of these measures are presented: a count restricted to the "
583 <<
"part of the interface which is externally visible, a count which "
584 <<
"only includes relationships which imply the client module needs "
585 <<
"to be recompiled if the supplier's implementation changes, and an "
586 <<
"inclusive count" << endl << endl;
589 fstr <<
"The label cell for each row in this table provides a link to "
590 <<
"the relationships table in the detailed report for the "
591 <<
"module in question" << endl << endl;
593 fstr <<
"<TABLE BORDER WIDTH=100%>" << endl;
594 fstr <<
"<TR>" << endl
595 <<
"<TH BGCOLOR=AQUA ROWSPAN=2>Module Name</TH>" << endl
596 <<
"<TH BGCOLOR=AQUA COLSPAN=3>Fan-out</TH>" << endl
597 <<
"<TH BGCOLOR=AQUA COLSPAN=3>Fan-in</TH>" << endl
598 <<
"<TH BGCOLOR=AQUA COLSPAN=3>IF4</TH>" << endl
610 fstr <<
"</TR>" << endl;
613 while(module_ptr!=NULL)
617 fstr <<
"<TR>" << endl;
633 string href=module_ptr->
key()+
".html#structdet";
645 fstr <<
"</TR>" << endl;
649 fstr <<
"</TABLE>" << endl;
656 fstr <<
"<TD WIDTH=50%>" << endl;
660 <<
" (" << mod <<
")" << std::endl;
663 CCCC_Module::relationship_map_t::iterator iter;
674 if(relationship_map==NULL)
676 cerr <<
"unexpected relationship mask " << mask << endl;
681 iter=relationship_map->begin();
682 iter!=relationship_map->end();
710 fstr <<
"<BR>" << endl;
712 fstr <<
"<BR>" << endl;
717 fstr <<
" " << endl;
719 fstr <<
"</TD>" << endl;
726 fstr <<
"<TABLE BORDER WIDTH=100%>" << endl;
727 fstr <<
"<TR>" << endl;
731 fstr <<
"</TR>" << endl;
734 while(module_ptr!=NULL)
738 fstr <<
"<TR>" << endl;
741 fstr <<
"</TR>" << endl;
745 fstr <<
"</TABLE>" << endl;
752 fstr <<
"<TABLE BORDER WIDTH=100%>" << endl;
763 fstr <<
"<TR>" << endl;
765 "procdet",
"procsum",mod_ptr);
772 fstr <<
"</TR>" << endl;
777 fstr <<
"</TABLE>" << endl;
783 fstr <<
"<TABLE BORDER WIDTH=100%>" << endl;
784 fstr <<
"<TR>" << endl;
790 fstr <<
"</TR>" << endl;
794 fstr <<
"<TR><TD COLSPAN=5>"
796 <<
"</TD></TR>" << endl;
801 while(extent_ptr!=NULL)
809 fstr <<
"</TR>" << endl;
813 fstr <<
"</TABLE>" << endl;
818 string section_name,
string section_href,
819 string section_description)
821 fstr <<
"<TR>" << endl
822 <<
"<TH><H4><A HREF=\"#" << section_href <<
"\">"
823 << section_name <<
"</A></H4></TH>" << endl
825 << section_description << endl
831 fstr <<
"<TH BGCOLOR=\"AQUA\"";
834 fstr <<
" WIDTH=" << width <<
"%" ;
839 *
this << label.c_str();
852 string label,
int width,
853 string ref_name,
string ref_href,
859 fstr <<
" WIDTH=" << width <<
"%";
863 if(ref_name.size() > 0)
867 fstr <<
"<A NAME=\"" << ref_name <<
"\"></A>" << endl;
870 if(ref_href.size() > 0)
874 fstr <<
"<A HREF=\"" << ref_href <<
"\">" << endl;
880 *
this << label.c_str() ;
889 if(ref_href.size() > 0)
892 fstr <<
"</A>" << endl;
897 fstr <<
"<BR>" << endl;
906 int count,
string tag,
int width)
913 int num,
int denom,
string tag,
int width)
921 fstr <<
"<TD ALIGN=RIGHT";
925 fstr <<
" WIDTH=" << width <<
"%" ;
931 fstr <<
" BGCOLOR=\"YELLOW\"";
934 fstr <<
" BGCOLOR=\"RED\"";
952 string key=anchor.key();
953 source_anchor_map_t::value_type anchor_value(key, anchor);
956 anchor.Emit_HREF(
fstr);
966 fstr <<
" WIDTH=" << width <<
"%>";
977 fstr <<
"</TD>" << endl;
992 fstr <<
"<BR>" << endl;
1000 const char *cptr=stg.c_str();
1001 while(*cptr!=
'\000') {
1007 case '>': os.
fstr <<
">" ;
break;
1008 case '<': os.
fstr <<
"<" ;
break;
1009 case '&': os.
fstr <<
"&";
break;
1016 case ',': os.
fstr <<
", " ;
break;
1017 case '(': os.
fstr <<
"( " ;
break;
1018 case ')': os.
fstr <<
" )" ;
break;
1019 default : os.
fstr << c;
1028 const char *emphasis_prefix[]={
"",
"<EM>",
"<STRONG>"};
1029 const char *emphasis_suffix[]={
"",
"</EM>",
"</STRONG>"};
1045 while(mod_ptr!=NULL)
1048 if(trivial_module==FALSE)
1050 string info=
"Detailed report on module " + mod_ptr->
key();
1053 filename+=mod_ptr->
key()+
".html";
1058 module_html_str.Module_Summary(mod_ptr);
1060 module_html_str.Put_Section_Heading(
"Definitions and Declarations",
1062 module_html_str.fstr <<
"<TABLE BORDER WIDTH=100%><TR>" << endl;
1063 module_html_str.Put_Label_Cell(
"Description",50);
1064 module_html_str.Put_Header_Cell(
"LOC",10);
1065 module_html_str.Put_Header_Cell(
"MVG",10);
1066 module_html_str.Put_Header_Cell(
"COM",10);
1067 module_html_str.Put_Header_Cell(
"L_C",10);
1068 module_html_str.Put_Header_Cell(
"M_C",10);
1069 module_html_str.Module_Detail(mod_ptr);
1070 module_html_str.fstr <<
"</TR></TABLE>" << endl;
1072 module_html_str.Put_Section_Heading(
"Functions",
"proc",2);
1073 module_html_str.fstr <<
"<TABLE BORDER WIDTH=100%><TR>" << endl;
1074 module_html_str.Put_Label_Cell(
"Function prototype",50);
1075 module_html_str.Put_Header_Cell(
"LOC",10);
1076 module_html_str.Put_Header_Cell(
"MVG",10);
1077 module_html_str.Put_Header_Cell(
"COM",10);
1078 module_html_str.Put_Header_Cell(
"L_C",10);
1079 module_html_str.Put_Header_Cell(
"M_C",10);
1080 module_html_str.Procedural_Detail(mod_ptr);
1081 module_html_str.fstr <<
"</TR></TABLE>" << endl;
1083 module_html_str.Put_Section_Heading(
"Relationships",
"structdet",2);
1084 module_html_str.fstr
1085 <<
"<TABLE BORDER WIDTH=100%>" << endl
1086 <<
"<TR><TH WIDTH=50%>Clients</TH><TH WIDTH=50%>Suppliers</TH></TR>"
1089 module_html_str.Structural_Detail(mod_ptr);
1090 module_html_str.fstr <<
"</TR></TABLE>" << endl;
1098 <<
" is trivial" << endl;
1118 CCCC_Record::Extent_Table::iterator eIter = module_ptr->
extent_table.begin();
1121 fstr <<
"<TR><TD COLSPAN=6>"
1122 <<
"No module extents have been identified for this module"
1123 <<
"</TD></TR>" << endl;
1130 fstr <<
"<TR>" << endl;
1145 fstr <<
"</TR>" << endl;
1151 fstr <<
"<TR><TD HEIGHT=12 COLSPAN=6></TD></TR>" << endl;
1167 CCCC_Module::member_map_t::iterator iter = module_ptr->
member_map.begin();
1171 fstr <<
"<TR><TD COLSPAN=6>"
1172 <<
"No member functions have been identified for this module"
1173 <<
"</TD></TR>" << endl;
1180 fstr <<
"<TR>" << endl;
1196 fstr <<
"</TR>" << endl;
1201 fstr <<
"<TR><TD HEIGHT=12 COLSPAN=6></TD></TR>" << endl;
1205 string abbreviation,
1210 fstr <<
"<LI>" << abbreviation <<
" = " << name <<
"<BR>" << endl
1211 << description << endl;
1240 fstr <<
"<TABLE BORDER WIDTH=100%>" << endl
1246 fstr <<
"</TR>" << endl;
1248 fstr <<
"<TR>" << endl;
1253 fstr <<
"</TR>" << endl;
1255 fstr <<
"<TR>" << endl;
1260 fstr <<
"</TR>" << endl;
1262 fstr <<
"<TR>" << endl;
1267 fstr <<
"</TR>" << endl;
1269 fstr <<
"<TR>" << endl;
1274 fstr <<
"</TR>" << endl;
1276 fstr <<
"<TR>" << endl;
1281 fstr <<
"</TR>" << endl;
1283 fstr <<
"<TR>" << endl;
1284 Put_Label_Cell(
"Weighted Methods per Class (weighting = unity)");
1288 fstr <<
"</TR>" << endl;
1290 fstr <<
"<TR>" << endl;
1291 Put_Label_Cell(
"Weighted Methods per Class (weighting = visible)");
1295 fstr <<
"</TR>" << endl;
1297 fstr <<
"<TR>" << endl;
1302 fstr <<
"</TR>" << endl;
1304 fstr <<
"<TR>" << endl;
1309 fstr <<
"</TR>" << endl;
1311 fstr <<
"<TR>" << endl;
1316 fstr <<
"</TR>" << endl;
1318 fstr <<
"<TR>" << endl;
1323 fstr <<
"</TR>" << endl;
1325 fstr <<
"<TR>" << endl;
1330 fstr <<
"</TR>" << endl;
1332 fstr <<
"<TR>" << endl;
1337 fstr <<
"</TR>" << endl;
1339 fstr <<
"</TABLE>" << endl;
1346 fstr.open(fname.c_str());
1347 if(
fstr.good() != TRUE)
1349 cerr <<
"failed to open " << fname.c_str()
1350 <<
" for output in directory " <<
outdir.c_str() << endl;
1358 fstr <<
"<HTML><HEAD><TITLE>" << endl
1360 <<
"</TITLE>" << endl
1361 <<
"</HEAD>" << endl
1362 <<
"<BODY>" << endl;
1371 string key1=a1.
key(), key2=a2.
key();
1373 source_anchor_map_t::value_type v1(key1,a1);
1374 source_anchor_map_t::value_type v2(key2,a2);
1392 int next_anchor_required=0;
1393 ifstream *src_str=NULL;
1394 const char *style_open=
"<TT>", *style_close=
"</TT>";
1397 filename+=
"/cccc_src.html";
1400 source_html_str.
fstr << style_open << endl;
1407 if(current_filename!=nextAnchor.
get_file())
1409 current_filename=nextAnchor.
get_file();
1412 src_str=
new ifstream(current_filename.c_str(),std::ios::in);
1413 src_str->getline(linebuf,1023);
1414 source_html_str.fstr << style_close << endl;
1415 source_html_str.Put_Section_Heading(current_filename.c_str(),
"",1);
1416 source_html_str.fstr << style_open << endl;
1419 while(src_str->good())
1424 (current_filename==(*iter).second.get_file()) &&
1425 (current_line==(*iter).second.get_line())
1428 (*iter).second.Emit_NAME(source_html_str.fstr);
1433 (*iter).second.Emit_SPACE(source_html_str.fstr);
1435 source_html_str << linebuf;
1436 source_html_str.fstr <<
"<BR>" << endl;
1437 src_str->getline(linebuf,1023);
1445 (current_filename==(*iter).second.get_file())
1448 (*iter).second.Emit_NAME(source_html_str.fstr);
1450 source_html_str.fstr <<
"<BR>" << endl;
1459 source_html_str.fstr << style_close <<
" </BODY></HTML>" << endl;
1463 static string pad_string(
int target_width,
string the_string,
string padding)
1465 int spaces_required=target_width-the_string.size();
1467 while(spaces_required>0)
1469 pad_string+=padding;
1472 return pad_string+the_string;
1480 sprintf(linebuf,
"%d",
line_);
1488 string anchor_key=
key();
1490 fstr <<
"<CODE><A HREF=\"cccc_src.html#" << anchor_key.c_str() <<
"\">"
1497 string anchor_key=
key();
1499 sprintf(ln_buf,
"%d",
line_);
1500 string ln_string=
pad_string(8,ln_buf,
" ");
1501 string space_string=
pad_string(2,
"",
" ");
1502 fstr <<
"<A NAME=\"" << anchor_key.c_str() <<
"\">"
1503 << ln_string.c_str() << space_string.c_str() <<
"</A>";
1508 string space_string=
pad_string(10,
"",
" ");
1509 fstr << space_string.c_str();
CCCC_Html_Stream(const string &fname, const string &info)
CCCC_Table< CCCC_Module > module_table
int get_count(const char *count_tag)
void Put_Section_Heading(string section_name, string section_tag, int section_level)
void Table_Of_Contents(int report_mask, bool showGenTime)
virtual string key() const
void Structural_Summary()
void Put_Label_Cell(string label, int width=0, string ref_name="", string ref_href="", CCCC_Record *rec_ptr=0)
static CCCC_Project * prjptr
relationship_map_t client_map
void Put_Section_TOC_Entry(string section_name, string section_href, string section_description)
CCCC_Html_Stream & operator<<(CCCC_Html_Stream &os, const string &stg)
CCCC_Table< CCCC_Extent > rejected_extent_table
static void GenerateReports(CCCC_Project *project, int report_mask, const string &outfile, const string &outdir)
EmphasisLevel emphasis_level() const
void Emit_SPACE(ofstream &fstr)
string value_string() const
virtual int get_count(const char *count_tag)
virtual int get_count(const char *count_tag)
int get_count(const char *count_tag)
string name(int index) const
void Put_Extent_URL(const CCCC_Extent &extent)
string name(int level) const
void Put_Metric_Cell(const CCCC_Metric &metric, int width=0)
void Emit_HREF(ofstream &fstr)
Extent_Table extent_table
void Procedural_Summary()
void Put_Extent_List(CCCC_Record &record, bool withDescription=false)
AugmentedBool is_concrete() const
void Metric_Description(string abbreviation, string name, string description)
void Emit_NAME(ofstream &fstr)
string name(int name_level) const
string name(int index) const
relationship_map_t supplier_map
AugmentedBool is_visible() const
static string pad_string(int target_width, string the_string, string padding)
void Module_Detail(CCCC_Module *module_ptr)
void Put_Header_Cell(string label, int width=0)
int get_count(const char *count_tag)
int main(int argc, char **argv)
void Module_Summary(CCCC_Module *module_ptr)
std::map< string, CCCC_UseRelationship * > relationship_map_t
std::map< string, Source_Anchor > source_anchor_map_t
void Put_Structural_Details_Cell(CCCC_Module *mod, CCCC_Project *prj, int mask, UserelNameLevel nl)
string name(int index) const
source_anchor_map_t source_anchor_map
void Put_Extent_Cell(const CCCC_Extent &extent, int width=0, bool withDescription=false)