10
10
11
11
#include < util/c_types.h>
12
12
#include < util/config.h>
13
+ #include < util/run.h>
13
14
#include < util/suffix.h>
14
15
#include < util/tempfile.h>
15
16
#include < util/unicode.h>
@@ -379,25 +380,12 @@ bool c_preprocess_visual_studio(
379
380
temporary_filet tmpi (" tmp.cl" , " " );
380
381
381
382
std::string command = " CL @\" " + command_file_name () + " \" " ;
382
- command += " > \" " + tmpi () + " \" " ;
383
383
command += " 2> \" " + stderr_file () + " \" " ;
384
384
385
385
// _popen isn't very reliable on WIN32
386
- // that's why we use system()
387
- int result=system (command.c_str ());
388
-
389
- std::ifstream instream (tmpi ());
390
-
391
- if (!instream)
392
- {
393
- message.error () << " CL Preprocessing failed (open failed)"
394
- << messaget::eom;
395
- return true ;
396
- }
397
-
398
- outstream << instream.rdbuf (); // copy
399
-
400
- instream.close ();
386
+ // that's why we use run()
387
+ int result =
388
+ run (" cl" , {" cl" , " @" + command_file_name ()}, " " , outstream, stderr_file ());
401
389
402
390
// errors/warnings
403
391
std::ifstream stderr_stream (stderr_file ());
@@ -463,30 +451,30 @@ bool c_preprocess_codewarrior(
463
451
464
452
temporary_filet stderr_file (" tmp.stderr" , " " );
465
453
466
- std::string command;
467
-
468
- command=" mwcceppc -E -P -D__CPROVER__ -ppopt line -ppopt full" ;
454
+ std::vector<std::string> command = {
455
+ " mwcceppc" , " -E" , " -P" , " -D__CPROVER__" , " -ppopt" , " line" , " -ppopt full" };
469
456
470
457
for (const auto &define : config.ansi_c .defines )
471
- command+= " -D" + shell_quote ( define);
458
+ command. push_back ( " -D" + define);
472
459
473
460
for (const auto &include_path : config.ansi_c .include_paths )
474
- command+= " -I" + shell_quote ( include_path);
461
+ command. push_back ( " -I" + include_path);
475
462
476
463
for (const auto &include_file : config.ansi_c .include_files )
477
- command+=" -include " +shell_quote (include_file);
464
+ {
465
+ command.push_back (" -include" );
466
+ command.push_back (include_file);
467
+ }
478
468
479
469
for (const auto &opt : config.ansi_c .preprocessor_options )
480
- command+=" " +opt;
481
-
482
- int result;
470
+ command.push_back (opt);
483
471
484
472
temporary_filet tmpi (" tmp.cl" , " " );
485
- command+= " \" " + file+ " \" " ;
486
- command += " -o \" " + tmpi () + " \" " ;
487
- command += " 2> \" " + stderr_file () + " \" " ;
473
+ command. push_back ( file) ;
474
+ command. push_back ( " -o " ) ;
475
+ command. push_back ( tmpi ()) ;
488
476
489
- result= system (command. c_str ());
477
+ int result = run (command[ 0 ], command, " " , " " , stderr_file ());
490
478
491
479
std::ifstream stream_i (tmpi ());
492
480
@@ -532,62 +520,63 @@ bool c_preprocess_gcc_clang(
532
520
533
521
temporary_filet stderr_file (" tmp.stderr" , " " );
534
522
535
- std::string command ;
523
+ std::vector<std:: string> argv ;
536
524
537
525
if (preprocessor==configt::ansi_ct::preprocessort::CLANG)
538
- command= " clang" ;
526
+ argv. push_back ( " clang" ) ;
539
527
else
540
- command= " gcc" ;
528
+ argv. push_back ( " gcc" ) ;
541
529
542
- command += " -E -D__CPROVER__" ;
530
+ argv.push_back (" -E" );
531
+ argv.push_back (" -D__CPROVER__" );
543
532
544
533
const irep_idt &arch = config.ansi_c .arch ;
545
534
546
535
if (config.ansi_c .pointer_width == 16 )
547
536
{
548
537
if (arch == " i386" || arch == " x86_64" || arch == " x32" )
549
- command += " -m16" ;
538
+ argv. push_back ( " -m16" ) ;
550
539
else if (has_prefix (id2string (arch), " mips" ))
551
- command += " -mips16" ;
540
+ argv. push_back ( " -mips16" ) ;
552
541
}
553
542
else if (config.ansi_c .pointer_width == 32 )
554
543
{
555
544
if (arch == " i386" || arch == " x86_64" )
556
- command += " -m32" ;
545
+ argv. push_back ( " -m32" ) ;
557
546
else if (arch == " x32" )
558
- command += " -mx32" ;
547
+ argv. push_back ( " -mx32" ) ;
559
548
else if (has_prefix (id2string (arch), " mips" ))
560
- command += " -mabi=32" ;
549
+ argv. push_back ( " -mabi=32" ) ;
561
550
else if (arch == " powerpc" || arch == " ppc64" || arch == " ppc64le" )
562
- command += " -m32" ;
551
+ argv. push_back ( " -m32" ) ;
563
552
else if (arch == " s390" || arch == " s390x" )
564
- command += " -m31" ; // yes, 31, not 32!
553
+ argv. push_back ( " -m31" ) ; // yes, 31, not 32!
565
554
else if (arch == " sparc" || arch == " sparc64" )
566
- command += " -m32" ;
555
+ argv. push_back ( " -m32" ) ;
567
556
}
568
557
else if (config.ansi_c .pointer_width == 64 )
569
558
{
570
559
if (arch == " i386" || arch == " x86_64" || arch == " x32" )
571
- command += " -m64" ;
560
+ argv. push_back ( " -m64" ) ;
572
561
else if (has_prefix (id2string (arch), " mips" ))
573
- command += " -mabi=64" ;
562
+ argv. push_back ( " -mabi=64" ) ;
574
563
else if (arch == " powerpc" || arch == " ppc64" || arch == " ppc64le" )
575
- command += " -m64" ;
564
+ argv. push_back ( " -m64" ) ;
576
565
else if (arch == " s390" || arch == " s390x" )
577
- command += " -m64" ;
566
+ argv. push_back ( " -m64" ) ;
578
567
else if (arch == " sparc" || arch == " sparc64" )
579
- command += " -m64" ;
568
+ argv. push_back ( " -m64" ) ;
580
569
}
581
570
582
571
// The width of wchar_t depends on the OS!
583
572
if (config.ansi_c .wchar_t_width == config.ansi_c .short_int_width )
584
- command += " -fshort-wchar" ;
573
+ argv. push_back ( " -fshort-wchar" ) ;
585
574
586
575
if (config.ansi_c .char_is_unsigned )
587
- command += " -funsigned-char" ;
576
+ argv. push_back ( " -funsigned-char" ) ;
588
577
589
578
if (config.ansi_c .os == configt::ansi_ct::ost::NO_OS)
590
- command += " -nostdinc" ;
579
+ argv. push_back ( " -nostdinc" ) ;
591
580
592
581
// Set the standard
593
582
if (has_suffix (file, " .cpp" ) || has_suffix (file, " .CPP" ) ||
@@ -600,19 +589,19 @@ bool c_preprocess_gcc_clang(
600
589
switch (config.cpp .cpp_standard )
601
590
{
602
591
case configt::cppt::cpp_standardt::CPP98:
603
- command += " -std=gnu++98" ;
592
+ argv. push_back ( " -std=gnu++98" ) ;
604
593
break ;
605
594
606
595
case configt::cppt::cpp_standardt::CPP03:
607
- command += " -std=gnu++03" ;
596
+ argv. push_back ( " -std=gnu++03" ) ;
608
597
break ;
609
598
610
599
case configt::cppt::cpp_standardt::CPP11:
611
- command += " -std=gnu++11" ;
600
+ argv. push_back ( " -std=gnu++11" ) ;
612
601
break ;
613
602
614
603
case configt::cppt::cpp_standardt::CPP14:
615
- command += " -std=gnu++14" ;
604
+ argv. push_back ( " -std=gnu++14" ) ;
616
605
break ;
617
606
}
618
607
}
@@ -621,30 +610,33 @@ bool c_preprocess_gcc_clang(
621
610
switch (config.ansi_c .c_standard )
622
611
{
623
612
case configt::ansi_ct::c_standardt::C89:
624
- command += " -std=gnu++89" ;
613
+ argv. push_back ( " -std=gnu++89" ) ;
625
614
break ;
626
615
627
616
case configt::ansi_ct::c_standardt::C99:
628
- command += " -std=gnu99" ;
617
+ argv. push_back ( " -std=gnu99" ) ;
629
618
break ;
630
619
631
620
case configt::ansi_ct::c_standardt::C11:
632
- command += " -std=gnu11" ;
621
+ argv. push_back ( " -std=gnu11" ) ;
633
622
break ;
634
623
}
635
624
}
636
625
637
626
for (const auto &define : config.ansi_c .defines )
638
- command+= " -D" + shell_quote ( define);
627
+ argv. push_back ( " -D" + define);
639
628
640
629
for (const auto &include_path : config.ansi_c .include_paths )
641
- command+= " -I" + shell_quote ( include_path);
630
+ argv. push_back ( " -I" + include_path);
642
631
643
632
for (const auto &include_file : config.ansi_c .include_files )
644
- command+=" -include " +shell_quote (include_file);
633
+ {
634
+ argv.push_back (" -include" );
635
+ argv.push_back (include_file);
636
+ }
645
637
646
638
for (const auto &opt : config.ansi_c .preprocessor_options )
647
- command+= " " + opt;
639
+ argv. push_back ( opt) ;
648
640
649
641
int result;
650
642
@@ -660,35 +652,28 @@ bool c_preprocess_gcc_clang(
660
652
}
661
653
#endif
662
654
663
- #ifdef _WIN32
655
+ // the file that is to be preprocessed
656
+ argv.push_back (file);
657
+
658
+ #ifdef _WIN32
664
659
temporary_filet tmpi (" tmp.gcc" , " " );
665
- command+=" \" " +file+" \" " ;
666
- command += " -o \" " + tmpi () + " \" " ;
667
- command += " 2> \" " + stderr_file () + " \" " ;
660
+ argv.push_back (" -o" );
661
+ argv.push_back (tmpi ());
668
662
669
663
// _popen isn't very reliable on WIN32
670
- // that's why we use system() and a temporary file
671
- result=system (command.c_str ());
672
-
673
- std::ifstream instream (tmpi ());
664
+ // that's why we use run() and a temporary file
665
+ result = run (argv[0 ], argv, " " , outstream, stderr_file ());
674
666
675
667
// errors/warnings
676
668
std::ifstream stderr_stream (stderr_file ());
677
669
error_parse (stderr_stream, result==0 , message);
678
670
679
- if (instream)
680
- {
681
- outstream << instream.rdbuf ();
682
- instream.close ();
683
- }
684
- else
685
- {
686
- message.error () << " GCC preprocessing failed (open failed)"
687
- << messaget::eom;
688
- result=1 ;
689
- }
690
671
#else
691
- command+=" \" " +file+" \" " ;
672
+
673
+ std::string command;
674
+ for (const auto &arg : argv)
675
+ command += " " + shell_quote (arg);
676
+
692
677
command += " 2> \" " + stderr_file () + " \" " ;
693
678
694
679
FILE *stream=popen (command.c_str (), " r" );
@@ -738,66 +723,56 @@ bool c_preprocess_arm(
738
723
739
724
temporary_filet stderr_file (" tmp.stderr" , " " );
740
725
741
- std::string command ;
726
+ std::vector<std:: string> argv ;
742
727
743
- command=" armcc -E -D__CPROVER__" ;
728
+ argv.push_back (" armcc" );
729
+ argv.push_back (" -E" );
730
+ argv.push_back (" -D__CPROVER__" );
744
731
745
732
if (config.ansi_c .endianness == configt::ansi_ct::endiannesst::IS_BIG_ENDIAN)
746
- command += " --bigend" ;
733
+ argv. push_back ( " --bigend" ) ;
747
734
else
748
- command += " --littleend" ;
735
+ argv. push_back ( " --littleend" ) ;
749
736
750
737
if (config.ansi_c .char_is_unsigned )
751
- command += " --unsigned_chars" ;
738
+ argv. push_back ( " --unsigned_chars" ) ;
752
739
else
753
- command += " --signed_chars" ;
740
+ argv. push_back ( " --signed_chars" ) ;
754
741
755
742
// Set the standard
756
743
switch (config.ansi_c .c_standard )
757
744
{
758
745
case configt::ansi_ct::c_standardt::C89:
759
- command += " --c90" ;
746
+ argv. push_back ( " --c90" ) ;
760
747
break ;
761
748
762
749
case configt::ansi_ct::c_standardt::C99:
763
750
case configt::ansi_ct::c_standardt::C11:
764
- command += " --c99" ;
751
+ argv. push_back ( " --c99" ) ;
765
752
break ;
766
753
}
767
754
768
755
for (const auto &define : config.ansi_c .defines )
769
- command+= " " + shell_quote (" -D" + define);
756
+ argv. push_back (" -D" + define);
770
757
771
758
for (const auto &include_path : config.ansi_c .include_paths )
772
- command+=" " +shell_quote (" -I" +include_path);
759
+ argv.push_back (" -I" + include_path);
760
+
761
+ // the file that is to be preprocessed
762
+ argv.push_back (file);
773
763
774
764
int result;
775
765
776
766
#ifdef _WIN32
777
- temporary_filet tmpi (" tmp.cl" , " " );
778
- command+=" \" " +file+" \" " ;
779
- command += " > \" " + tmpi () + " \" " ;
780
- command += " 2> \" " + stderr_file () + " \" " ;
781
-
782
767
// _popen isn't very reliable on WIN32
783
- // that's why we use system () and a temporary file
784
- result= system (command. c_str ());
768
+ // that's why we use run () and a temporary file
769
+ result = run (argv[ 0 ], argv, " " , outstream, stderr_file ());
785
770
786
- std::ifstream instream (tmpi ());
771
+ #else
772
+ std::string command;
773
+ for (const auto &arg : argv)
774
+ command += " " + shell_quote (arg);
787
775
788
- if (!instream)
789
- {
790
- outstream << instream.rdbuf (); // copy
791
- instream.close ();
792
- }
793
- else
794
- {
795
- message.error () << " ARMCC preprocessing failed (fopen failed)"
796
- << messaget::eom;
797
- return true ;
798
- }
799
- #else
800
- command+=" \" " +file+" \" " ;
801
776
command += " 2> \" " + stderr_file () + " \" " ;
802
777
803
778
FILE *stream=popen (command.c_str (), " r" );
0 commit comments