@@ -113,7 +113,7 @@ bool rename_file(const std::string& old_filename, const std::string& new_filenam
113113}
114114
115115static std::stringstream log_stream;
116- void write_log ();
116+ void write_log (bool );
117117
118118// / @todo make the filters non-global
119119IfcGeom::entity_filter entity_filter; // Entity filter is used always by default.
@@ -152,13 +152,16 @@ bool init_input_file(const std::string& filename, IfcParse::IfcFile& ifc_file, b
152152
153153int main (int argc, char ** argv)
154154{
155+ std::string log_format;
155156 po::options_description generic_options (" Command line options" );
156157 generic_options.add_options ()
157158 (" help,h" , " display usage information" )
158159 (" version" , " display version information" )
159- (" verbose,v" , " more verbose output" )
160- (" yes,y" , " answer 'yes' automatically to possible confirmation queries (e.g. overwriting an existing output file)" )
161- (" no-progress" , " Suppress possible progress bar type of prints that use carriage return." );
160+ (" verbose,v" , " more verbose log messages" )
161+ (" quiet,q" , " less status and progress output" )
162+ (" yes,y" , " answer 'yes' automatically to possible confirmation queries (e.g. overwriting an existing output file)" )
163+ (" no-progress" , " suppress possible progress bar type of prints that use carriage return" )
164+ (" log-format" , po::value<std::string>(&log_format), " log format: plain or json" );
162165
163166 po::options_description fileio_options;
164167 fileio_options.add_options ()
@@ -174,7 +177,7 @@ int main(int argc, char** argv)
174177 inclusion_traverse_filter include_traverse_filter;
175178 exclusion_filter exclude_filter;
176179 exclusion_traverse_filter exclude_traverse_filter;
177- std::string filter_filename;
180+ std::string filter_filename;
178181
179182 po::options_description geom_options (" Geometry options" );
180183 geom_options.add_options ()
@@ -336,22 +339,10 @@ int main(int argc, char** argv)
336339
337340 po::notify (vmap);
338341
339- print_version ();
340-
341- if (vmap.count (" version" )) {
342- return EXIT_SUCCESS;
343- } else if (vmap.count (" help" )) {
344- print_usage (false );
345- print_options (generic_options.add (geom_options).add (serializer_options));
346- return EXIT_SUCCESS;
347- } else if (!vmap.count (" input-file" )) {
348- std::cerr << " [Error] Input file not specified" << std::endl;
349- print_usage ();
350- return EXIT_FAILURE;
351- }
352342 const bool mmap = vmap.count (" mmap" ) != 0 ;
353343 const bool verbose = vmap.count (" verbose" ) != 0 ;
354344 const bool no_progress = vmap.count (" no-progress" ) != 0 ;
345+ const bool quiet = vmap.count (" quiet" ) != 0 ;
355346 const bool weld_vertices = vmap.count (" weld-vertices" ) != 0 ;
356347 const bool use_world_coords = vmap.count (" use-world-coords" ) != 0 ;
357348 const bool convert_back_units = vmap.count (" convert-back-units" ) != 0 ;
@@ -363,17 +354,33 @@ int main(int argc, char** argv)
363354 const bool include_plan = vmap.count (" plan" ) != 0 ;
364355 const bool include_model = vmap.count (" model" ) != 0 || (!include_plan);
365356 const bool enable_layerset_slicing = vmap.count (" enable-layerset-slicing" ) != 0 ;
366- const bool use_element_names = vmap.count (" use-element-names" ) != 0 ;
367- const bool use_element_guids = vmap.count (" use-element-guids" ) != 0 ;
368- const bool use_material_names = vmap.count (" use-material-names" ) != 0 ;
357+ const bool use_element_names = vmap.count (" use-element-names" ) != 0 ;
358+ const bool use_element_guids = vmap.count (" use-element-guids" ) != 0 ;
359+ const bool use_material_names = vmap.count (" use-material-names" ) != 0 ;
369360 const bool use_element_types = vmap.count (" use-element-types" ) != 0 ;
370361 const bool use_element_hierarchy = vmap.count (" use-element-hierarchy" ) != 0 ;
371- const bool no_normals = vmap.count (" no-normals" ) != 0 ;
372- const bool center_model = vmap.count (" center-model" ) != 0 ;
373- const bool model_offset = vmap.count (" model-offset" ) != 0 ;
374- const bool site_local_placement = vmap.count (" site-local-placement" ) != 0 ;
375- const bool building_local_placement = vmap.count (" building-local-placement" ) != 0 ;
376- const bool generate_uvs = vmap.count (" generate-uvs" ) != 0 ;
362+ const bool no_normals = vmap.count (" no-normals" ) != 0 ;
363+ const bool center_model = vmap.count (" center-model" ) != 0 ;
364+ const bool model_offset = vmap.count (" model-offset" ) != 0 ;
365+ const bool site_local_placement = vmap.count (" site-local-placement" ) != 0 ;
366+ const bool building_local_placement = vmap.count (" building-local-placement" ) != 0 ;
367+ const bool generate_uvs = vmap.count (" generate-uvs" ) != 0 ;
368+
369+ if (!quiet || vmap.count (" version" )) {
370+ print_version ();
371+ }
372+
373+ if (vmap.count (" version" )) {
374+ return EXIT_SUCCESS;
375+ } else if (vmap.count (" help" )) {
376+ print_usage (false );
377+ print_options (generic_options.add (geom_options).add (serializer_options));
378+ return EXIT_SUCCESS;
379+ } else if (!vmap.count (" input-file" )) {
380+ std::cerr << " [Error] Input file not specified" << std::endl;
381+ print_usage ();
382+ return EXIT_FAILURE;
383+ }
377384
378385#ifdef HAVE_ICU
379386 if (!unicode_mode.empty ()) {
@@ -438,12 +445,25 @@ int main(int argc, char** argv)
438445 Logger::SetOutput (&std::cout, &log_stream);
439446 Logger::Verbosity (verbose ? Logger::LOG_NOTICE : Logger::LOG_ERROR);
440447
448+ if (vmap.count (" log-format" ) == 1 ) {
449+ boost::to_lower (log_format);
450+ if (log_format == " plain" ) {
451+ Logger::OutputFormat (Logger::FMT_PLAIN);
452+ } else if (log_format == " json" ) {
453+ Logger::OutputFormat (Logger::FMT_JSON);
454+ } else {
455+ std::cerr << " [Error] --log-format should be either plain or json" << std::endl;
456+ print_usage ();
457+ return EXIT_FAILURE;
458+ }
459+ }
460+
441461 IfcParse::IfcFile ifc_file;
442462
443463 if (output_extension == " .xml" ) {
444464 int exit_code = EXIT_FAILURE;
445465 try {
446- if (init_input_file (input_filename, ifc_file, no_progress, mmap)) {
466+ if (init_input_file (input_filename, ifc_file, no_progress || quiet , mmap)) {
447467 XmlSerializer s (output_temp_filename);
448468 s.setFile (&ifc_file);
449469 Logger::Status (" Writing XML output..." );
@@ -455,7 +475,7 @@ int main(int argc, char** argv)
455475 } catch (const std::exception& e) {
456476 Logger::Error (e);
457477 }
458- write_log ();
478+ write_log (!quiet );
459479 return exit_code;
460480 }
461481
@@ -548,7 +568,7 @@ int main(int argc, char** argv)
548568 }
549569 } else {
550570 std::cerr << " [Error] Unknown output filename extension '" + output_extension + " '\n " ;
551- write_log ();
571+ write_log (!quiet );
552572 print_usage ();
553573 return EXIT_FAILURE;
554574 }
@@ -557,7 +577,7 @@ int main(int argc, char** argv)
557577
558578 if (use_element_hierarchy && output_extension != " .dae" ) {
559579 std::cerr << " [Error] --use-element-hierarchy can be used only with .dae output.\n " ;
560- write_log ();
580+ write_log (!quiet );
561581 print_usage ();
562582 delete serializer;
563583 std::remove (output_temp_filename.c_str ()); /* *< @todo Windows Unicode support */
@@ -582,14 +602,14 @@ int main(int argc, char** argv)
582602 if (!serializer->ready ()) {
583603 delete serializer;
584604 std::remove (output_temp_filename.c_str ()); /* *< @todo Windows Unicode support */
585- write_log ();
605+ write_log (!quiet );
586606 return EXIT_FAILURE;
587607 }
588608
589609 time_t start,end;
590610 time (&start);
591611
592- if (!init_input_file (input_filename, ifc_file, no_progress, mmap)) {
612+ if (!init_input_file (input_filename, ifc_file, no_progress || quiet , mmap)) {
593613 return EXIT_FAILURE;
594614 }
595615
@@ -600,7 +620,7 @@ int main(int argc, char** argv)
600620 Logger::Error (" No geometrical entities found" );
601621 delete serializer;
602622 std::remove (output_temp_filename.c_str ()); /* *< @todo Windows Unicode support */
603- write_log ();
623+ write_log (!quiet );
604624 return EXIT_FAILURE;
605625 }
606626
@@ -614,7 +634,7 @@ int main(int argc, char** argv)
614634
615635 serializer->writeHeader ();
616636
617- int old_progress = -1 ;
637+ int old_progress = quiet ? 0 : -1 ;
618638
619639 if (center_model || model_offset) {
620640 double * offset = serializer->settings ().offset ;
@@ -643,7 +663,9 @@ int main(int argc, char** argv)
643663 Logger::Notice (msg.str ());
644664 }
645665
646- Logger::Status (" Creating geometry..." );
666+ if (!quiet) {
667+ Logger::Status (" Creating geometry..." );
668+ }
647669
648670 // The functions IfcGeom::Iterator::get() and IfcGeom::Iterator::next()
649671 // wrap an iterator of all geometrical products in the Ifc file.
@@ -670,14 +692,28 @@ int main(int argc, char** argv)
670692 }
671693
672694 if (!no_progress) {
673- const int progress = context_iterator.progress () / 2 ;
674- if (old_progress != progress) Logger::ProgressBar (progress);
675- old_progress = progress;
695+ if (quiet) {
696+ const int progress = context_iterator.progress ();
697+ for (; old_progress < progress; ++old_progress) {
698+ std::cout << " ." ;
699+ }
700+ std::cout << std::flush;
701+ } else {
702+ const int progress = context_iterator.progress () / 2 ;
703+ if (old_progress != progress) Logger::ProgressBar (progress);
704+ old_progress = progress;
705+ }
676706 }
677707 } while (++num_created, context_iterator.next ());
678708
679- Logger::Status (" \r Done creating geometry (" + boost::lexical_cast<std::string>(num_created) +
680- " objects) " );
709+ if (!no_progress && quiet) {
710+ for (; old_progress < 100 ; ++old_progress) {
711+ std::cout << " ." ;
712+ }
713+ } else {
714+ Logger::Status (" \r Done creating geometry (" + boost::lexical_cast<std::string>(num_created) +
715+ " objects) " );
716+ }
681717
682718 serializer->finalize ();
683719 delete serializer;
@@ -690,34 +726,39 @@ int main(int argc, char** argv)
690726 output_temp_filename + " ' for the conversion result." );
691727 }
692728
693- write_log ();
729+ write_log (!quiet );
694730
695731 time (&end);
696732
697- int seconds = (int )difftime (end, start);
698- std::stringstream msg;
699- int minutes = seconds / 60 ;
700- seconds = seconds % 60 ;
701- msg << " \n Conversion took" ;
702- if (minutes > 0 ) {
703- msg << " " << minutes << " minute" ;
704- if (minutes > 1 ) {
733+ if (!quiet) {
734+ int seconds = (int )difftime (end, start);
735+ std::stringstream msg;
736+ int minutes = seconds / 60 ;
737+ seconds = seconds % 60 ;
738+ msg << " \n Conversion took" ;
739+ if (minutes > 0 ) {
740+ msg << " " << minutes << " minute" ;
741+ if (minutes > 1 ) {
742+ msg << " s" ;
743+ }
744+ }
745+ msg << " " << seconds << " second" ;
746+ if (seconds > 1 ) {
705747 msg << " s" ;
706748 }
749+ Logger::Status (msg.str ());
707750 }
708- msg << " " << seconds << " second" ;
709- if (seconds > 1 ) {
710- msg << " s" ;
711- }
712- Logger::Status (msg.str ());
713751
714752 return successful ? EXIT_SUCCESS : EXIT_FAILURE;
715753}
716754
717- void write_log () {
755+ void write_log (bool header ) {
718756 std::string log = log_stream.str ();
719757 if (!log.empty ()) {
720- std::cout << " \n Log:\n " << log << std::endl;
758+ if (header) {
759+ std::cout << " \n Log:\n " ;
760+ }
761+ std::cout << log << std::endl;
721762 }
722763}
723764
0 commit comments