cprover
c_preprocess.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "c_preprocess.h"
10 
11 #include <util/c_types.h>
12 #include <util/config.h>
13 #include <util/prefix.h>
14 #include <util/run.h>
15 #include <util/suffix.h>
16 #include <util/tempfile.h>
17 #include <util/unicode.h>
18 
19 #include <fstream>
20 
22 static std::string shell_quote(const std::string &src)
23 {
24  #ifdef _WIN32
25  // first check if quoting is needed at all
26 
27  if(src.find(' ')==std::string::npos &&
28  src.find('"')==std::string::npos &&
29  src.find('&')==std::string::npos &&
30  src.find('|')==std::string::npos &&
31  src.find('(')==std::string::npos &&
32  src.find(')')==std::string::npos &&
33  src.find('<')==std::string::npos &&
34  src.find('>')==std::string::npos &&
35  src.find('^')==std::string::npos)
36  {
37  // seems fine -- return as is
38  return src;
39  }
40 
41  std::string result;
42 
43  result+='"';
44 
45  for(const char ch : src)
46  {
47  if(ch=='"')
48  result+='"'; // quotes are doubled
49  result+=ch;
50  }
51 
52  result+='"';
53 
54  return result;
55 
56  #else
57 
58  // first check if quoting is needed at all
59 
60  if(src.find(' ')==std::string::npos &&
61  src.find('"')==std::string::npos &&
62  src.find('*')==std::string::npos &&
63  src.find('$')==std::string::npos &&
64  src.find('\\')==std::string::npos &&
65  src.find('?')==std::string::npos &&
66  src.find('&')==std::string::npos &&
67  src.find('|')==std::string::npos &&
68  src.find('>')==std::string::npos &&
69  src.find('<')==std::string::npos &&
70  src.find('^')==std::string::npos &&
71  src.find('\'')==std::string::npos)
72  {
73  // seems fine -- return as is
74  return src;
75  }
76 
77  std::string result;
78 
79  // the single quotes catch everything but themselves!
80  result+='\'';
81 
82  for(const char ch : src)
83  {
84  if(ch=='\'')
85  result+="'\\''";
86  result+=ch;
87  }
88 
89  result+='\'';
90 
91  return result;
92  #endif
93 }
94 
95 static void error_parse_line(
96  const std::string &line,
97  bool warning_only,
99 {
100  std::string error_msg=line;
101  source_locationt saved_error_location;
102 
103  if(has_prefix(line, "file "))
104  {
105  const char *tptr=line.c_str();
106  int state=0;
107  std::string file, line_no, column, _error_msg, function;
108 
109  tptr+=5;
110 
111  char previous=0;
112 
113  while(*tptr!=0)
114  {
115  if(has_prefix(tptr, " line ") && state != 4)
116  {
117  state=1;
118  tptr+=6;
119  continue;
120  }
121  else if(has_prefix(tptr, " column ") && state != 4)
122  {
123  state=2;
124  tptr+=8;
125  continue;
126  }
127  else if(has_prefix(tptr, " function ") && state != 4)
128  {
129  state=3;
130  tptr+=10;
131  continue;
132  }
133  else if(*tptr==':' && state!=4)
134  {
135  if(tptr[1]==' ' && previous!=':')
136  {
137  state=4;
138  tptr++;
139  while(*tptr==' ') tptr++;
140  continue;
141  }
142  }
143 
144  if(state==0) // file
145  file+=*tptr;
146  else if(state==1) // line number
147  line_no+=*tptr;
148  else if(state==2) // column
149  column+=*tptr;
150  else if(state==3) // function
151  function+=*tptr;
152  else if(state==4) // error message
153  _error_msg+=*tptr;
154 
155  previous=*tptr;
156 
157  tptr++;
158  }
159 
160  if(state==4)
161  {
162  saved_error_location.set_file(file);
163  saved_error_location.set_function(function);
164  saved_error_location.set_line(line_no);
165  saved_error_location.set_column(column);
166  error_msg=_error_msg;
167  }
168  }
169  else if(has_prefix(line, "In file included from "))
170  {
171  }
172  else
173  {
174  const char *tptr=line.c_str();
175  int state=0;
176  std::string file, line_no;
177 
178  while(*tptr!=0)
179  {
180  if(state==0)
181  {
182  if(*tptr==':')
183  state++;
184  else
185  file+=*tptr;
186  }
187  else if(state==1)
188  {
189  if(*tptr==':')
190  state++;
191  else if(isdigit(*tptr))
192  line_no+=*tptr;
193  else
194  state=3;
195  }
196 
197  tptr++;
198  }
199 
200  if(state==2)
201  {
202  saved_error_location.set_file(file);
203  saved_error_location.set_function(irep_idt());
204  saved_error_location.set_line(line_no);
205  saved_error_location.set_column(irep_idt());
206  }
207  }
208 
210  warning_only ? message.warning() : message.error();
211  m.source_location=saved_error_location;
212  m << error_msg << messaget::eom;
213 }
214 
215 static void error_parse(
216  std::istream &errors,
217  bool warning_only,
218  messaget &message)
219 {
220  std::string line;
221 
222  while(std::getline(errors, line))
223  error_parse_line(line, warning_only, message);
224 }
225 
228  std::istream &instream,
229  std::ostream &outstream,
230  message_handlert &message_handler)
231 {
232  temporary_filet tmp_file("tmp.stdin", ".c");
233 
234  std::ofstream tmp(tmp_file());
235 
236  if(!tmp)
237  {
238  messaget message(message_handler);
239  message.error() << "failed to open temporary file" << messaget::eom;
240  return true; // error
241  }
242 
243  tmp << instream.rdbuf(); // copy
244 
245  tmp.close(); // flush
246 
247  bool result=c_preprocess(tmp_file(), outstream, message_handler);
248 
249  return result;
250 }
251 
253 static bool is_dot_i_file(const std::string &path)
254 {
255  return has_suffix(path, ".i") || has_suffix(path, ".ii");
256 }
257 
260  const std::string &, std::ostream &, message_handlert &);
261 bool c_preprocess_arm(
262  const std::string &, std::ostream &, message_handlert &);
264  const std::string &,
265  std::ostream &,
268 bool c_preprocess_none(
269  const std::string &, std::ostream &, message_handlert &);
271  const std::string &, std::ostream &, message_handlert &);
272 
274  const std::string &path,
275  std::ostream &outstream,
276  message_handlert &message_handler)
277 {
278  switch(config.ansi_c.preprocessor)
279  {
281  return c_preprocess_codewarrior(path, outstream, message_handler);
282 
284  return
286  path, outstream, message_handler, config.ansi_c.preprocessor);
287 
289  return
291  path, outstream, message_handler, config.ansi_c.preprocessor);
292 
294  return c_preprocess_visual_studio(path, outstream, message_handler);
295 
297  return c_preprocess_arm(path, outstream, message_handler);
298 
300  return c_preprocess_none(path, outstream, message_handler);
301  }
302 
303  // not reached
304  return true;
305 }
306 
309  const std::string &file,
310  std::ostream &outstream,
311  message_handlert &message_handler)
312 {
313  // check extension
314  if(is_dot_i_file(file))
315  return c_preprocess_none(file, outstream, message_handler);
316 
317  messaget message(message_handler);
318 
319  // use Visual Studio's CL
320 
321  temporary_filet stderr_file("tmp.stderr", "");
322  temporary_filet command_file_name("tmp.cl-cmd", "");
323 
324  {
325  std::ofstream command_file(command_file_name());
326 
327  // This marks the command file as UTF-8, which Visual Studio
328  // understands.
329  command_file << char(0xef) << char(0xbb) << char(0xbf);
330 
331  command_file << "/nologo" << '\n';
332  command_file << "/E" << '\n';
333 
334  // This option will make CL produce utf-8 output, as
335  // opposed to 8-bit with some code page.
336  // It only works on Visual Studio 2015 or newer.
337  command_file << "/source-charset:utf-8" << '\n';
338 
339  command_file << "/D__CPROVER__" << "\n";
340  command_file << "/D__WORDSIZE=" << config.ansi_c.pointer_width << "\n";
341 
343  {
344  command_file << "\"/D__PTRDIFF_TYPE__=long long int\"" << "\n";
345  // yes, both _WIN32 and _WIN64 get defined
346  command_file << "/D_WIN64" << "\n";
347  }
348  else if(config.ansi_c.int_width == 16 && config.ansi_c.pointer_width == 32)
349  {
350  // 16-bit LP32 is an artificial architecture we simulate when using --16
353  "Pointer difference expected to be long int typed");
354  command_file << "/D__PTRDIFF_TYPE__=long" << '\n';
355  }
356  else
357  {
360  "Pointer difference expected to be int typed");
361  command_file << "/D__PTRDIFF_TYPE__=int" << "\n";
362  }
363 
365  command_file << "/J" << "\n"; // This causes _CHAR_UNSIGNED to be defined
366 
367  for(const auto &define : config.ansi_c.defines)
368  command_file << "/D" << shell_quote(define) << "\n";
369 
370  for(const auto &include_path : config.ansi_c.include_paths)
371  command_file << "/I" << shell_quote(include_path) << "\n";
372 
373  for(const auto &include_file : config.ansi_c.include_files)
374  command_file << "/FI" << shell_quote(include_file) << "\n";
375 
376  // Finally, the file to be preprocessed
377  // (this is already in UTF-8).
378  command_file << shell_quote(file) << "\n";
379  }
380 
381  temporary_filet tmpi("tmp.cl", "");
382 
383  std::string command = "CL @\"" + command_file_name() + "\"";
384  command += " 2> \"" + stderr_file() + "\"";
385 
386  // _popen isn't very reliable on WIN32
387  // that's why we use run()
388  int result =
389  run("cl", {"cl", "@" + command_file_name()}, "", outstream, stderr_file());
390 
391  // errors/warnings
392  std::ifstream stderr_stream(stderr_file());
393  error_parse(stderr_stream, result==0, message);
394 
395  if(result!=0)
396  {
397  message.error() << "CL Preprocessing failed" << messaget::eom;
398  return true;
399  }
400 
401  return false;
402 }
403 
406  std::istream &instream,
407  std::ostream &outstream)
408 {
409  // CodeWarrior prepends some header to the file,
410  // marked with '#' signs.
411  // We skip over it.
412  //
413  // CodeWarrior has an ugly way of marking lines, e.g.:
414  //
415  // /* #line 1 "__ppc_eabi_init.cpp" /* stack depth 0 */
416  //
417  // We remove the initial '/* ' prefix
418 
419  std::string line;
420 
421  while(instream)
422  {
423  std::getline(instream, line);
424 
425  if(line.size()>=2 &&
426  line[0]=='#' && (line[1]=='#' || line[1]==' ' || line[1]=='\t'))
427  {
428  // skip the line!
429  }
430  else if(line.size()>=3 &&
431  line[0]=='/' && line[1]=='*' && line[2]==' ')
432  {
433  outstream << line.c_str()+3 << "\n"; // strip the '/* '
434  }
435  else
436  outstream << line << "\n";
437  }
438 }
439 
442  const std::string &file,
443  std::ostream &outstream,
444  message_handlert &message_handler)
445 {
446  // check extension
447  if(is_dot_i_file(file))
448  return c_preprocess_none(file, outstream, message_handler);
449 
450  // preprocessing
451  messaget message(message_handler);
452 
453  temporary_filet stderr_file("tmp.stderr", "");
454 
455  std::vector<std::string> command = {
456  "mwcceppc", "-E", "-P", "-D__CPROVER__", "-ppopt", "line", "-ppopt full"};
457 
458  for(const auto &define : config.ansi_c.defines)
459  command.push_back(" -D" + define);
460 
461  for(const auto &include_path : config.ansi_c.include_paths)
462  command.push_back(" -I" + include_path);
463 
464  for(const auto &include_file : config.ansi_c.include_files)
465  {
466  command.push_back(" -include");
467  command.push_back(include_file);
468  }
469 
470  for(const auto &opt : config.ansi_c.preprocessor_options)
471  command.push_back(opt);
472 
473  temporary_filet tmpi("tmp.cl", "");
474  command.push_back(file);
475  command.push_back("-o");
476  command.push_back(tmpi());
477 
478  int result = run(command[0], command, "", "", stderr_file());
479 
480  std::ifstream stream_i(tmpi());
481 
482  if(stream_i)
483  {
484  postprocess_codewarrior(stream_i, outstream);
485 
486  stream_i.close();
487  }
488  else
489  {
490  message.error() << "Preprocessing failed (fopen failed)"
491  << messaget::eom;
492  return true;
493  }
494 
495  // errors/warnings
496  std::ifstream stderr_stream(stderr_file());
497  error_parse(stderr_stream, result==0, message);
498 
499  if(result!=0)
500  {
501  message.error() << "Preprocessing failed" << messaget::eom;
502  return true;
503  }
504 
505  return false;
506 }
507 
510  const std::string &file,
511  std::ostream &outstream,
512  message_handlert &message_handler,
513  configt::ansi_ct::preprocessort preprocessor)
514 {
515  // check extension
516  if(is_dot_i_file(file))
517  return c_preprocess_none(file, outstream, message_handler);
518 
519  // preprocessing
520  messaget message(message_handler);
521 
522  temporary_filet stderr_file("tmp.stderr", "");
523 
524  std::vector<std::string> argv;
525 
527  argv.push_back("clang");
528  else
529  argv.push_back("gcc");
530 
531  argv.push_back("-E");
532  argv.push_back("-D__CPROVER__");
533 
534  const irep_idt &arch = config.ansi_c.arch;
535 
536  if(config.ansi_c.pointer_width == 16)
537  {
538  if(arch == "i386" || arch == "x86_64" || arch == "x32")
539  argv.push_back("-m16");
540  else if(has_prefix(id2string(arch), "mips"))
541  argv.push_back("-mips16");
542  }
543  else if(config.ansi_c.pointer_width == 32)
544  {
545  if(arch == "i386" || arch == "x86_64")
546  argv.push_back("-m32");
547  else if(arch == "x32")
548  argv.push_back("-mx32");
549  else if(has_prefix(id2string(arch), "mips"))
550  argv.push_back("-mabi=32");
551  else if(arch == "powerpc" || arch == "ppc64" || arch == "ppc64le")
552  argv.push_back("-m32");
553  else if(arch == "s390" || arch == "s390x")
554  argv.push_back("-m31"); // yes, 31, not 32!
555  else if(arch == "sparc" || arch == "sparc64")
556  argv.push_back("-m32");
557  }
558  else if(config.ansi_c.pointer_width == 64)
559  {
560  if(arch == "i386" || arch == "x86_64" || arch == "x32")
561  argv.push_back("-m64");
562  else if(has_prefix(id2string(arch), "mips"))
563  argv.push_back("-mabi=64");
564  else if(arch == "powerpc" || arch == "ppc64" || arch == "ppc64le")
565  argv.push_back("-m64");
566  else if(arch == "s390" || arch == "s390x")
567  argv.push_back("-m64");
568  else if(arch == "sparc" || arch == "sparc64")
569  argv.push_back("-m64");
570  }
571 
572  // The width of wchar_t depends on the OS!
574  argv.push_back("-fshort-wchar");
575 
577  argv.push_back("-funsigned-char");
578 
580  argv.push_back("-nostdinc");
581 
582  // Set the standard
583  if(
584  has_suffix(file, ".cpp") || has_suffix(file, ".CPP") ||
585 #ifndef _WIN32
586  has_suffix(file, ".C") ||
587 #endif
588  has_suffix(file, ".c++") || has_suffix(file, ".C++") ||
589  has_suffix(file, ".cp") || has_suffix(file, ".CP") ||
590  has_suffix(file, ".cc") || has_suffix(file, ".cxx"))
591  {
592  switch(config.cpp.cpp_standard)
593  {
595 #if defined(__OpenBSD__)
596  if(preprocessor == configt::ansi_ct::preprocessort::CLANG)
597  argv.push_back("-std=c++98");
598  else
599 #endif
600  argv.push_back("-std=gnu++98");
601  break;
602 
604 #if defined(__OpenBSD__)
605  if(preprocessor == configt::ansi_ct::preprocessort::CLANG)
606  argv.push_back("-std=c++03");
607  else
608 #endif
609  argv.push_back("-std=gnu++03");
610  break;
611 
613 #if defined(__OpenBSD__)
614  if(preprocessor == configt::ansi_ct::preprocessort::CLANG)
615  argv.push_back("-std=c++11");
616  else
617 #endif
618  argv.push_back("-std=gnu++11");
619  break;
620 
622 #if defined(__OpenBSD__)
623  if(preprocessor == configt::ansi_ct::preprocessort::CLANG)
624  argv.push_back("-std=c++14");
625  else
626 #endif
627  argv.push_back("-std=gnu++14");
628  break;
629  }
630  }
631  else
632  {
633  switch(config.ansi_c.c_standard)
634  {
636 #if defined(__OpenBSD__)
637  if(preprocessor == configt::ansi_ct::preprocessort::CLANG)
638  argv.push_back("-std=c89");
639  else
640 #endif
641  argv.push_back("-std=gnu89");
642  break;
643 
645 #if defined(__OpenBSD__)
646  if(preprocessor == configt::ansi_ct::preprocessort::CLANG)
647  argv.push_back("-std=c99");
648  else
649 #endif
650  argv.push_back("-std=gnu99");
651  break;
652 
654 #if defined(__OpenBSD__)
655  if(preprocessor == configt::ansi_ct::preprocessort::CLANG)
656  argv.push_back("-std=c11");
657  else
658 #endif
659  argv.push_back("-std=gnu11");
660  break;
661  }
662  }
663 
664  for(const auto &define : config.ansi_c.defines)
665  argv.push_back("-D" + define);
666 
667  for(const auto &include_path : config.ansi_c.include_paths)
668  argv.push_back("-I" + include_path);
669 
670  for(const auto &include_file : config.ansi_c.include_files)
671  {
672  argv.push_back("-include");
673  argv.push_back(include_file);
674  }
675 
676  for(const auto &opt : config.ansi_c.preprocessor_options)
677  argv.push_back(opt);
678 
679  int result;
680 
681  #if 0
682  // the following forces the mode
683  switch(config.ansi_c.mode)
684  {
685  case configt::ansi_ct::flavourt::GCC_C: command+=" -x c"; break;
686  case configt::ansi_ct::flavourt::GCC_CPP: command+=" -x c++"; break;
687  default:
688  {
689  }
690  }
691  #endif
692 
693  // the file that is to be preprocessed
694  argv.push_back(file);
695 
696  // execute clang or gcc
697  result = run(argv[0], argv, "", outstream, stderr_file());
698 
699  // errors/warnings
700  std::ifstream stderr_stream(stderr_file());
701  error_parse(stderr_stream, result==0, message);
702 
703  if(result!=0)
704  {
705  message.error() << "GCC preprocessing failed" << messaget::eom;
706  return true;
707  }
708 
709  return false;
710 }
711 
714  const std::string &file,
715  std::ostream &outstream,
716  message_handlert &message_handler)
717 {
718  // check extension
719  if(is_dot_i_file(file))
720  return c_preprocess_none(file, outstream, message_handler);
721 
722  // preprocessing using armcc
723  messaget message(message_handler);
724 
725  temporary_filet stderr_file("tmp.stderr", "");
726 
727  std::vector<std::string> argv;
728 
729  argv.push_back("armcc");
730  argv.push_back("-E");
731  argv.push_back("-D__CPROVER__");
732 
734  argv.push_back("--bigend");
735  else
736  argv.push_back("--littleend");
737 
739  argv.push_back("--unsigned_chars");
740  else
741  argv.push_back("--signed_chars");
742 
743  // Set the standard
744  switch(config.ansi_c.c_standard)
745  {
747  argv.push_back("--c90");
748  break;
749 
752  argv.push_back("--c99");
753  break;
754  }
755 
756  for(const auto &define : config.ansi_c.defines)
757  argv.push_back("-D" + define);
758 
759  for(const auto &include_path : config.ansi_c.include_paths)
760  argv.push_back("-I" + include_path);
761 
762  // the file that is to be preprocessed
763  argv.push_back(file);
764 
765  int result;
766 
767  // execute armcc
768  result = run(argv[0], argv, "", outstream, stderr_file());
769 
770  // errors/warnings
771  std::ifstream stderr_stream(stderr_file());
772  error_parse(stderr_stream, result==0, message);
773 
774  if(result!=0)
775  {
776  message.error() << "ARMCC preprocessing failed" << messaget::eom;
777  return true;
778  }
779 
780  return false;
781 }
782 
785  const std::string &file,
786  std::ostream &outstream,
787  message_handlert &message_handler)
788 {
789  #ifdef _MSC_VER
790  std::ifstream infile(widen(file));
791  #else
792  std::ifstream infile(file);
793  #endif
794 
795  if(!infile)
796  {
797  messaget message(message_handler);
798  message.error() << "failed to open '" << file << "'" << messaget::eom;
799  return true;
800  }
801 
803  {
804  // special treatment for "/* #line"
805  postprocess_codewarrior(infile, outstream);
806  }
807  else
808  {
809  char ch;
810 
811  while(infile.read(&ch, 1))
812  outstream << ch;
813  }
814 
815  return false;
816 }
817 
819 const char c_test_program[]=
820  "#include <stdlib.h>\n"
821  "\n"
822  "int main() { }\n";
823 
824 bool test_c_preprocessor(message_handlert &message_handler)
825 {
826  std::ostringstream out;
827  std::istringstream in(c_test_program);
828 
829  return c_preprocess(in, out, message_handler);
830 }
messaget
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:155
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:37
configt::cppt::cpp_standardt::CPP98
@ CPP98
configt::ansi_ct::defines
std::list< std::string > defines
Definition: config.h:122
tempfile.h
source_locationt::set_function
void set_function(const irep_idt &function)
Definition: source_location.h:126
configt::ansi_ct::wchar_t_width
std::size_t wchar_t_width
Definition: config.h:41
signed_long_long_int_type
signedbv_typet signed_long_long_int_type()
Definition: c_types.cpp:87
configt::ansi_ct::preprocessort::CLANG
@ CLANG
configt::ansi_ct::include_paths
std::list< std::string > include_paths
Definition: config.h:125
configt::ansi_ct::flavourt::CODEWARRIOR
@ CODEWARRIOR
configt::ansi_ct::os
ost os
Definition: config.h:80
configt::cppt::cpp_standardt::CPP03
@ CPP03
configt::ansi_ct::preprocessort
preprocessort
Definition: config.h:118
prefix.h
file
Definition: kdev_t.h:19
error_parse
static void error_parse(std::istream &errors, bool warning_only, messaget &message)
Definition: c_preprocess.cpp:215
c_preprocess.h
run
int run(const std::string &what, const std::vector< std::string > &argv)
Definition: run.cpp:49
irep_idt
dstringt irep_idt
Definition: irep.h:32
messaget::eom
static eomt eom
Definition: message.h:297
configt::ansi_c
struct configt::ansi_ct ansi_c
run.h
has_suffix
bool has_suffix(const std::string &s, const std::string &suffix)
Definition: suffix.h:17
c_preprocess_visual_studio
bool c_preprocess_visual_studio(const std::string &, std::ostream &, message_handlert &)
ANSI-C preprocessing.
Definition: c_preprocess.cpp:308
source_locationt::set_column
void set_column(const irep_idt &column)
Definition: source_location.h:116
source_locationt::set_line
void set_line(const irep_idt &line)
Definition: source_location.h:106
message
static const char * message(const static_verifier_resultt::statust &status)
Makes a status message string from a status.
Definition: static_verifier.cpp:74
configt::ansi_ct::c_standardt::C89
@ C89
signed_int_type
signedbv_typet signed_int_type()
Definition: c_types.cpp:30
DATA_INVARIANT
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:511
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:44
configt::ansi_ct::preprocessor
preprocessort preprocessor
Definition: config.h:120
messaget::mstreamt::source_location
source_locationt source_location
Definition: message.h:247
source_locationt::set_file
void set_file(const irep_idt &file)
Definition: source_location.h:96
configt::ansi_ct::arch
irep_idt arch
Definition: config.h:85
message_handlert
Definition: message.h:28
widen
std::wstring widen(const char *s)
Definition: unicode.cpp:50
configt::ansi_ct::preprocessor_options
std::list< std::string > preprocessor_options
Definition: config.h:124
configt::ansi_ct::include_files
std::list< std::string > include_files
Definition: config.h:126
configt::ansi_ct::ost::NO_OS
@ NO_OS
configt::ansi_ct::preprocessort::GCC
@ GCC
config
configt config
Definition: config.cpp:24
c_preprocess_none
bool c_preprocess_none(const std::string &, std::ostream &, message_handlert &)
ANSI-C preprocessing.
Definition: c_preprocess.cpp:784
source_locationt
Definition: source_location.h:20
configt::ansi_ct::c_standardt::C99
@ C99
configt::ansi_ct::preprocessort::NONE
@ NONE
shell_quote
static std::string shell_quote(const std::string &src)
quote a string for bash and CMD
Definition: c_preprocess.cpp:22
configt::ansi_ct::mode
flavourt mode
Definition: config.h:116
configt::ansi_ct::c_standardt::C11
@ C11
configt::ansi_ct::preprocessort::VISUAL_STUDIO
@ VISUAL_STUDIO
configt::ansi_ct::endiannesst::IS_BIG_ENDIAN
@ IS_BIG_ENDIAN
suffix.h
is_dot_i_file
static bool is_dot_i_file(const std::string &path)
ANSI-C preprocessing.
Definition: c_preprocess.cpp:253
configt::ansi_ct::c_standard
enum configt::ansi_ct::c_standardt c_standard
c_preprocess_arm
bool c_preprocess_arm(const std::string &, std::ostream &, message_handlert &)
ANSI-C preprocessing.
Definition: c_preprocess.cpp:713
unicode.h
c_test_program
const char c_test_program[]
tests ANSI-C preprocessing
Definition: c_preprocess.cpp:819
configt::cppt::cpp_standardt::CPP14
@ CPP14
config.h
configt::ansi_ct::short_int_width
std::size_t short_int_width
Definition: config.h:35
signed_long_int_type
signedbv_typet signed_long_int_type()
Definition: c_types.cpp:80
configt::ansi_ct::char_is_unsigned
bool char_is_unsigned
Definition: config.h:44
messaget::mstreamt
Definition: message.h:224
has_prefix
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
configt::cppt::cpp_standardt::CPP11
@ CPP11
configt::ansi_ct::pointer_width
std::size_t pointer_width
Definition: config.h:37
configt::cpp
struct configt::cppt cpp
pointer_diff_type
signedbv_typet pointer_diff_type()
Definition: c_types.cpp:228
error_parse_line
static void error_parse_line(const std::string &line, bool warning_only, messaget &message)
Definition: c_preprocess.cpp:95
c_preprocess_gcc_clang
bool c_preprocess_gcc_clang(const std::string &, std::ostream &, message_handlert &, configt::ansi_ct::preprocessort)
ANSI-C preprocessing.
Definition: c_preprocess.cpp:509
c_preprocess
bool c_preprocess(std::istream &instream, std::ostream &outstream, message_handlert &message_handler)
ANSI-C preprocessing.
Definition: c_preprocess.cpp:227
c_preprocess_codewarrior
bool c_preprocess_codewarrior(const std::string &, std::ostream &, message_handlert &)
ANSI-C preprocessing.
Definition: c_preprocess.cpp:441
configt::ansi_ct::int_width
std::size_t int_width
Definition: config.h:31
c_types.h
postprocess_codewarrior
void postprocess_codewarrior(std::istream &instream, std::ostream &outstream)
post-processing specifically for CodeWarrior
Definition: c_preprocess.cpp:405
configt::ansi_ct::preprocessort::ARM
@ ARM
configt::ansi_ct::preprocessort::CODEWARRIOR
@ CODEWARRIOR
configt::ansi_ct::endianness
endiannesst endianness
Definition: config.h:77
temporary_filet
Definition: tempfile.h:24
configt::cppt::cpp_standard
enum configt::cppt::cpp_standardt cpp_standard
test_c_preprocessor
bool test_c_preprocessor(message_handlert &message_handler)
Definition: c_preprocess.cpp:824