gcc config
[prop.git] / prop-src / process.cc
blob9cb5c9023ea4376516207026a1ec2d2a53b76cc9
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // ////////
4 // // // ////// ///// ///////
5 // //////// // // // // //
6 // // // // // ///////
7 // // // ///// //
8 // // Version 2.3.x
9 //
10 // Allen Leung (leunga@cs.nyu.edu)
11 ///////////////////////////////////////////////////////////////////////////////
13 // This is the driver routine for the translator
15 #include <iostream>
16 #include <fstream>
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <string.h>
21 #include "config.h"
22 #include "compiler.h"
23 #include "type.h"
24 #include "author.h"
25 #include "options.h"
27 ///////////////////////////////////////////////////////////////////////////////
29 // Various global data.
31 ///////////////////////////////////////////////////////////////////////////////
32 int errors = 0;
33 int warnings = 0;
34 std::istream * input_stream = 0;
35 std::ostream * output_stream = 0;
36 std::ostream * log_stream = 0;
37 Compiler * error_log = 0;
38 Decls program = 0;
40 ///////////////////////////////////////////////////////////////////////////////
42 // Memory pool and string pool
44 ///////////////////////////////////////////////////////////////////////////////
45 MemPool mem_pool(4096); // 4K page size
46 MemPool global_pool(4096); // 4K page size
47 MemPool * current_pool = &mem_pool;
48 StringPool str_pool(4096); // 4K page size
49 static int globals = 0;
50 void MEM::use_global_pools() { current_pool = &global_pool; globals++; }
51 void MEM::use_local_pools() { if (--globals == 0) current_pool = &mem_pool;}
52 void * MEM::operator new(size_t n) { return (*current_pool)[n]; }
54 ///////////////////////////////////////////////////////////////////////////////
56 // Current source location variables.
58 ///////////////////////////////////////////////////////////////////////////////
59 int line, first_line;
60 const char * file;
62 ///////////////////////////////////////////////////////////////////////////////
64 // Source location methods
66 ///////////////////////////////////////////////////////////////////////////////
67 Loc::Loc() { begin_line = first_line; end_line = line; file_name = file;
68 first_line = line; }
69 Loc::Loc(int a, int b)
70 { begin_line = a; end_line = b; file_name = file;
71 first_line = line; }
73 void Loc::set_loc() const { line = begin_line; file = file_name; }
75 const char * my_strrchr(const char * s, char c)
76 { register const char * p;
77 for (p = s + strlen(s) - 1; p != s; p--)
78 if (*p == c) return p;
79 return 0;
82 ///////////////////////////////////////////////////////////////////////////////
84 // Compute the output file name from the input file name
86 ///////////////////////////////////////////////////////////////////////////////
87 void PropOptions::compute_output_file_name ()
88 { // Locate the . in the file name and
89 // Cut out the directory prefix.
90 const char * dot = my_strrchr(input_file_name,'.');
91 const char * slash = my_strrchr(input_file_name,PATH_SEPARATOR);
92 if (dot == 0 || ! (dot[1] == 'p' || dot[1] == 'P')) {
93 std::cerr << '"' << input_file_name
94 << "\" is not a valid source file name. "
95 "It must be of the form \"*.p*\".\n";
96 exit(1);
98 if (slash == 0) slash = input_file_name-1;
99 memcpy(file_prefix, slash+1, dot - slash);
100 file_prefix[dot - slash] = '\0';
101 if (output_file_name[0] == '\0') {
102 strcpy(output_file_name,file_prefix);
103 strcat(output_file_name, dot+2);
105 encode_string(mangled_file_prefix,file_prefix);
106 encode_string(mangled_file_name,output_file_name);
109 ///////////////////////////////////////////////////////////////////////////////
111 // Function to emit the proper headers
113 ///////////////////////////////////////////////////////////////////////////////
114 static void emit_headers(Compiler& C)
116 C.pr
117 ("%^%/"
118 "%^// This file is generated automatically using Prop (version %s.%s),"
119 "%^// last updated on %s."
120 "%^// The original source file is \"%s\"."
121 "%^%/\n",
122 VERSION, PATCH_LEVEL, LAST_UPDATED, options.input_file_name
125 C.emit_header_text();
127 /////////////////////////////////////////////////////////////////////////
128 // Emit headers
129 /////////////////////////////////////////////////////////////////////////
130 Bool inc = false;
131 if (Used::rewriting) { C.pr ("#define PROP_REWRITING_USED\n"); inc = true; }
132 if (Used::infer) { C.pr ("#define PROP_INFERENCE_USED\n"); inc = true; }
133 if (Used::gc) { C.pr ("#define PROP_GARBAGE_COLLECTION_USED\n"); inc = true; }
134 if (Used::refcount) { C.pr ("#define PROP_REFCOUNT_USED\n"); inc = true; }
135 if (Used::printer) { C.pr ("#define PROP_PRINTER_USED\n"); inc = true; }
136 if (Used::persistence) { C.pr ("#define PROP_PERSISTENCE_USED\n"); inc = true; }
137 if (Used::objc) { C.pr ("#define PROP_OBJC_USED\n"); inc = true; }
138 if (Used::regexp) { C.pr ("#define PROP_REGEXP_MATCHING_USED\n"); inc = true; }
139 if (Used::string_match) { C.pr ("#define PROP_STRCMP_USED\n"); inc = true; }
140 if (Used::equality) { C.pr ("#define PROP_EQUALITY_USED\n"); inc = true; }
141 if (Used::unification) { C.pr ("#define PROP_UNIFICATION_USED\n"); inc = true; }
142 if (Used::vector) { C.pr ("#define PROP_VECTOR_USED\n"); inc = true; }
143 if (Used::parser) { C.pr ("#define PROP_PARSER_USED\n"); inc = true; }
144 if (Used::quark) { C.pr ("#define PROP_QUARK_USED\n"); inc = true; }
145 if (Used::bigint) { C.pr ("#define PROP_BIGINT_USED\n"); inc = true; }
146 if (Used::graph_type) { C.pr ("#define PROP_GRAPHTYPE_USED\n"); inc = true; }
147 if (options.trace) { C.pr ("#define PROP_TRACE_ON\n"); inc = true; }
148 for (int i = 2; i < MAX_TUPLE_ARITY; i++)
149 { if (Used::tuple[i])
150 { C.pr("#define PROP_TUPLE%i_USED\n", i);
151 inc = true;
154 if (inc) C.pr ("#include <propdefs.h>\n");
157 ///////////////////////////////////////////////////////////////////////////////
159 // The main program.
161 ///////////////////////////////////////////////////////////////////////////////
162 int process_input(PropOptions& options)
164 ////////////////////////////////////////////////////////////////////////////
165 // Open input file
166 ////////////////////////////////////////////////////////////////////////////
167 { input_stream = new std::ifstream(options.input_file_name);
168 if (! *input_stream) { perror(options.input_file_name); return 1; }
171 ////////////////////////////////////////////////////////////////////////////
172 // The compiler
173 ////////////////////////////////////////////////////////////////////////////
174 Compiler C(options.tagged_pointer ? OPTtaggedpointer : OPTnone,
175 options.max_embedded_tags);
177 ////////////////////////////////////////////////////////////////////////////
178 // Parse input
179 ////////////////////////////////////////////////////////////////////////////
180 initialize_types();
181 { extern void front_end(const char *, Compiler&);
182 front_end(options.input_file_name,C);
185 ////////////////////////////////////////////////////////////////////////////
186 // Open output file
187 ////////////////////////////////////////////////////////////////////////////
188 if (errors > 0) options.emit_code = false;
190 ////////////////////////////////////////////////////////////////////////////
191 // Setup output file
192 ////////////////////////////////////////////////////////////////////////////
193 Bool clean_up_file = false;
194 if (! options.gen_dependences)
195 { if (options.to_stdout) {
196 output_stream = &std::cout;
197 } else {
198 output_stream = options.emit_code ?
199 (new std::ofstream(options.output_file_name)) : (new std::ofstream);
200 if (! (*output_stream)) {
201 perror(options.output_file_name); return 1;
203 clean_up_file = true;
205 C.set_stream(*output_stream);
207 /////////////////////////////////////////////////////////////////////////
208 // Emit the headers.
209 /////////////////////////////////////////////////////////////////////////
210 emit_headers(C);
212 /////////////////////////////////////////////////////////////////////////
213 // Compile.
214 /////////////////////////////////////////////////////////////////////////
215 C.generate(program);
216 C.pr("/*\n");
217 C.print_report(*output_stream);
218 C.pr("*/\n");
220 /////////////////////////////////////////////////////////////////////////
221 // Cleanup
222 /////////////////////////////////////////////////////////////////////////
223 if (clean_up_file) delete output_stream;
224 if (errors > 0 && options.emit_code && options.output_file_name[0])
225 remove(options.output_file_name);
228 ////////////////////////////////////////////////////////////////////////////
229 // Postprocessing
230 ////////////////////////////////////////////////////////////////////////////
231 if (errors > 0) return 1;
232 if (options.gen_dependences) IncludeDependency::print_dependences();
233 else std::cerr << options.output_file_name << '\n';
234 return 0;
237 ///////////////////////////////////////////////////////////////////////////////
239 // Print messages on the console
241 ///////////////////////////////////////////////////////////////////////////////
242 std::ostream& pr_msg(const char * fmt, va_list arg)
243 { if (error_log == 0) error_log = new Compiler(0,0);
244 return error_log->outv(fmt,arg).flush();
247 ///////////////////////////////////////////////////////////////////////////////
249 // Print messages
251 ///////////////////////////////////////////////////////////////////////////////
252 std::ostream& msg (const char * fmt, ...)
253 { va_list arg;
254 va_start(arg,fmt);
255 std::ostream& f = pr_msg(fmt,arg);
256 va_end(arg);
257 return f;
260 ///////////////////////////////////////////////////////////////////////////////
262 // Print debugging messages
264 ///////////////////////////////////////////////////////////////////////////////
265 std::ostream& debug_msg (const char * fmt, ...)
266 { va_list arg;
267 va_start(arg,fmt);
268 if (options.debug) pr_msg(fmt,arg);
269 va_end(arg);
270 return std::cerr;
273 ///////////////////////////////////////////////////////////////////////////////
275 // Print error message
277 ///////////////////////////////////////////////////////////////////////////////
278 std::ostream& error (const char * fmt, ...)
279 { va_list arg;
280 va_start(arg,fmt);
281 std::ostream& f = pr_msg(fmt,arg);
282 errors++;
283 va_end(arg);
284 return f;
287 ///////////////////////////////////////////////////////////////////////////////
289 // Print bug message
291 ///////////////////////////////////////////////////////////////////////////////
292 void bug (const char * fmt, ...)
293 { va_list arg;
294 va_start(arg,fmt);
295 msg("%Lbug: ");
296 pr_msg(fmt,arg);
297 va_end(arg);
298 std::cerr << "\nPlease send bug report to " << EMAIL << '\n';
299 exit (1);
302 //////////////////////////////////////////////////////////////////////////////
304 // Routine to open a file for reading, using the search path as
305 // starting point. Returns NIL if none can be found.
307 //////////////////////////////////////////////////////////////////////////////
308 std::istream * PropOptions::open_input_file(const char file_name[])
310 register const char * p;
311 register char * q;
313 for (p = search_paths; *p != '\0' && *p != FILE_SEPARATOR; p++) {
314 for (q = current_file_path; *p != '\0' && *p != FILE_SEPARATOR; )
315 *q++ = *p++;
316 *q++ = PATH_SEPARATOR; *q = '\0';
317 strcat(current_file_path,file_name);
318 debug_msg("[Opening file %s]\n",current_file_path);
319 std::ifstream * f = new std::ifstream(current_file_path);
320 if (*f) return f;
321 delete f;
323 return 0;
326 //////////////////////////////////////////////////////////////////////////////
328 // Routine to open a file for write and returns the handle
330 //////////////////////////////////////////////////////////////////////////////
331 std::ostream * open_output_file(const char file_name[])
333 std::ofstream * F = new std::ofstream(file_name);
334 if (! *F) { perror(file_name); exit(1); }
335 return F;
338 //////////////////////////////////////////////////////////////////////////////
340 // Routine to open a log file and returns the handle.
342 //////////////////////////////////////////////////////////////////////////////
343 std::ostream& open_logfile()
344 { if (log_stream) return *log_stream;
345 if (! options.generate_report)
346 { log_stream = new std::ofstream;
347 return *log_stream;
348 } else
349 { char log_file_name[256];
350 strcpy(log_file_name,options.file_prefix);
351 strcat(log_file_name,"report");
352 log_stream = open_output_file(log_file_name);
353 return *log_stream;