DEADSOFTWARE

Patched for Linux
[mp3cc.git] / MPC.3.5.LINUX / main / main.c
1 /*
3 MIDletPascal-compiler 3.5.IDE (mp3CC.exe)
4 http://sourceforge.net/projects/midletpascal
6 MPC.2.0.2:
7 Niksa Orlic
9 MPC.3.0.003/009:
10 Artem (ironwoodcutter@bk.ru)
11 new lexer,
12 bytecode inline,
13 shl & shr operators,
14 smart string concatenation,
15 new max array size (up to 32767),
16 inclusion of {$R+/-} to enable/disable real numbers support,
17 and {$V+/-} to enable/disable internal bytecode preverification
19 MPC.3.0.IDE:
20 Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
21 ported to GNUCC (with coditional defines),
22 pascal-like errors messages and warnings,
23 new command-line parsing (C way),
24 disabled $R and $V directives (confusing overlapped functionality with the IDE),
25 and several other adjustments (wow64 WM_COPYDATA workaround, etc)
26 and bugfixes (real numbers parsing, shl & shr swapped operators, etc)
28 MPC.3.1.IDE:
29 Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
30 infinite-loop support (repeat/forever),
31 and bugfixes (complex-type bidimensional array initialization index out-of-bound, etc)
33 MPC.3.2.IDE:
34 Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
35 exit keyword support,
36 C-style multiline comments support
38 MPC.3.3.IDE:
39 Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
40 result keyword support,
41 C-style shift operators support (<< and >>),
42 and bugfixes (const assignment crash, etc)
44 MPC.3.4.IDE:
45 Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
46 Project Library Directory support via -p switch,
47 imported the "ASM BLOCK" from the Artem's MPC.3.0.011.SIMPLE parser.c,
48 bytecode keyword support,
49 and ushr/>>> shift operator support
51 MPC.3.5.IDE:
52 Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
53 C-like double quoted strings support,
54 negative integer constants support,
55 and bugfixes (consecutive same variable name declaration collision, etc)
57 */
59 // j-a-s-d: workaround for Wow64 using WM_COPYDATA
60 /*#ifndef LINUX
61 #define WOW64_WORKAROUND
62 #endif*/
64 #include "../util/strings.h"
65 #include "../util/error.h"
66 #include "../structures/type_list.h"
67 #include "../structures/string_list.h"
68 #include "../structures/type.h"
69 #include "../structures/identifier.h"
70 #include "../structures/name_table.h"
71 #include "../classgen/bytecode.h"
72 #include "../structures/block.h"
73 #include "../parser/parser.h"
74 #include "../util/memory.h"
75 #include <stdio.h>
76 #include <stdlib.h>
77 #include <string.h>
78 #include <getopt.h>
80 #ifdef WOW64_WORKAROUND
81 #include <windows.h>
83 int ParentNotifyHandle = INVALID_HANDLE_VALUE;
84 COPYDATASTRUCT COMPILERMESSAGE;
85 #endif
87 char msgstr[1024];
88 int canvasType;
89 int mathType;
90 int next_record_ID;
91 int detect_units_only;
92 int goverify;
94 extern FILE *yyin;
95 extern string *string_constant;
96 char *output_path;
97 char *source_file_name;
98 char *global_library_directory;
99 char *project_library_directory;
100 char *user_libraries = NULL;
101 char **units;
103 extern short int error_count;
104 extern short int warning_count;
106 extern int usesForms;
107 extern int usesSupport;
108 extern int usesFloat;
109 extern int usesRecordStore;
110 extern int usesHttp;
111 extern int usesPlayer;
112 extern int usesSMS;
114 extern int constant_pool_size;
115 extern long int last_error_linenum;
116 extern int inside_loop;
118 extern int linenum;
119 extern string *string_constant;
121 extern int next_record_ID;
123 void compileMSG()
125 #ifdef WOW64_WORKAROUND
126 if (ParentNotifyHandle != INVALID_HANDLE_VALUE) {
127 COMPILERMESSAGE.dwData = 1;
128 COMPILERMESSAGE.cbData = sizeof( msgstr );
129 COMPILERMESSAGE.lpData = &msgstr;
130 SendMessage(ParentNotifyHandle, WM_COPYDATA,
131 (WPARAM) 0, (LPARAM)(LPVOID) &COMPILERMESSAGE);
132 return;
134 #endif
135 printf(msgstr);
136 fflush(stdout);
139 void requires(int reqkind, char* req)
141 switch (reqkind)
143 case 0: // unit
144 sprintf(msgstr,"^0%s\n", req);
145 break;
146 case 1: // lib
147 sprintf(msgstr,"^1%s\n", req);
148 break;
149 case 2: // stub
150 sprintf(msgstr,"^2%s\n", req);
151 break;
152 case 3: // record
153 sprintf(msgstr,"^3%s\n", req);
154 break;
156 compileMSG();
159 int last_progress;
161 void compile_progress(int x)
163 if (x != last_progress)
165 last_progress = x;
166 sprintf(msgstr,"@%d\n", last_progress);
167 compileMSG();
171 void compile_terminate(){
172 mem_close();
173 fclose(yyin);
174 exit(1);
175 };
177 //////////
179 void initialize_compiler()
181 constant_pool_size = 0;
182 string_constant = NULL;
183 error_count = 0;
184 warning_count = 0;
185 last_error_linenum = -1;
186 linenum = 1;
187 inside_loop = 0;
188 goverify = 1;
189 usesFloat = 0;
190 usesForms = 0;
191 usesSupport = 0;
192 usesRecordStore = 0;
193 usesHttp = 0;
194 usesPlayer = 0;
195 usesSMS = 0;
196 user_libraries = NULL;
199 void ShowHelp()
201 sprintf(msgstr,
202 "-------------------------------------------------------------------------\n"
203 "MIDletPascal 3.5 Compiler\n"
204 "Version: MPC.3.5.IDE\n"
205 "Authors: Niksa Orlic (1.x-2.0), Artem (3.0), Javier Santo Domingo (3.x)\n"
206 "-------------------------------------------------------------------------\n"
207 "usage: mp3cc\n"
208 "\t-s\"<source_filename>\"\n"
209 "\t-o\"<output_path>\"\n"
210 "\t-l\"<global_library_path>\"\n"
211 "\t-p\"<project_library_path>\"\n"
212 "\t-m<math_type>\n"
213 "\t-c<canvas_type>\n"
214 "\t-r<next_record_ID>\n"
215 "\t[-d] // detect units only\n"
216 #ifdef WOW64_WORKAROUND
217 "\t[-n]<parent_notify_handle> // outputs using WMCOPYDATA\n"
218 #endif
219 "\n"
220 );
221 compileMSG();
222 exit(2);
225 void PrintFinalMessage ()
227 if (usesForms) {
228 requires(2,"FS.class");
230 if (usesSupport) {
231 requires(2,"S.class");
233 if (usesFloat == 1) {
234 if (mathType == 2) {
235 requires(2,"Real.class");
236 requires(2,"Real$NumberFormat.class");
237 } else {
238 requires(2,"F.class");
241 if (usesRecordStore == 1) {
242 requires(2,"RS.class");
244 if (usesHttp == 1) {
245 requires(2,"H.class");
247 if (usesPlayer == 1) {
248 requires(2,"P.class");
250 if (usesSMS == 1) {
251 requires(2,"SM.class");
253 sprintf(msgstr,"Done - %d error(s), %d warning(s)\n", error_count, warning_count);
256 int main(int argc, char **argv)
258 error_count = -1;
259 char *source_file = NULL;
260 char *output_directory = NULL;
262 int pos;
264 if (argc >= 2)
266 // -- parse command line arguments
267 detect_units_only = 0;
268 mathType = 1;
269 canvasType = NORMAL;
271 int c;
272 while ((c = getopt(argc, argv, "?:s:o:l:p:m:n:c:r:d")) != -1) {
273 switch(c) {
274 case 's':
275 source_file = optarg;
276 break;
277 case 'o':
278 output_directory = optarg;
279 break;
280 case 'l':
281 global_library_directory = optarg;
282 break;
283 case 'p':
284 project_library_directory = optarg;
285 break;
286 case 'm':
287 if (strcmp("2", optarg) == 0) {
288 mathType = 2; // REAL
290 break;
291 case 'n':
292 #ifdef WOW64_WORKAROUND
293 ParentNotifyHandle = atoi(optarg);
294 #endif
295 break;
296 case 'r':
297 next_record_ID = atoi(optarg);
298 break;
299 case 'c':
300 if (strcmp("2", optarg) == 0) {
301 canvasType = FULL_NOKIA; // FULL_NOKIA
302 } else if (strcmp("1", optarg) == 0) {
303 canvasType = FULL_MIDP20; // FULL_MIDP20
305 break;
306 case 'd':
307 detect_units_only++;
308 break;
309 case '?':
310 default:
311 ShowHelp();
315 if (project_library_directory == NULL) {
316 sprintf(msgstr,"mp3cc: no project library directory\n");
317 compileMSG();
318 ShowHelp();
320 if (global_library_directory == NULL) {
321 sprintf(msgstr,"mp3cc: no global library directory\n");
322 compileMSG();
323 ShowHelp();
325 if (output_directory == NULL) {
326 sprintf(msgstr,"mp3cc: no output directory\n");
327 compileMSG();
328 ShowHelp();
330 if (source_file == NULL) {
331 sprintf(msgstr,"mp3cc: no source file\n");
332 compileMSG();
333 ShowHelp();
336 // --
338 mem_init();
339 initialize_compiler();
340 units=malloc(8);
341 *units=malloc(8);
342 *units=NULL;
343 pos=strlen(source_file)-1;
344 while ((source_file[pos] == '\r') || (source_file[pos] == '\n')) pos --;
345 source_file[pos + 1] = '\0';
346 source_file_name = (char*) mem_alloc(pos + 1);
347 if (source_file_name == NULL) die(1);
348 //pos = len - 1;
349 #ifdef UNIX
350 while ((pos >= 0) && (source_file[pos] != '/')) pos --;
351 #endif
352 #ifdef WIN32
353 while ((pos >= 0) && (source_file[pos] != '\\')) pos --;
354 if (source_file[pos] != '\\') die(21);
355 #endif
356 //pos ++;
357 strcpy(source_file_name, source_file + pos + 1);
358 ////////////////////
359 pos = strlen(output_directory) - 1;
360 while ((output_directory[pos] == '\r')|| (output_directory[pos] == '\n')) pos --;
361 output_directory[pos + 1] = '\0';
362 //len = strlen(output_directory); output_path = (char*) mem_alloc(len + 1);
363 output_path = output_directory;
364 //library_directory=output_directory;
365 yyrestart(source_file);
366 if ((yyin != NULL) && (output_path != NULL))
368 if (detect_units_only) {
369 sprintf(msgstr,"Detecting units of \'%s\'...\n", source_file_name);
370 } else {
371 sprintf(msgstr,"Compiling \'%s\'...\n", source_file_name);
373 compileMSG();
374 strcpy(output_path, output_directory);
375 parser_start();
377 fclose(yyin);
378 mem_free(output_path);
379 mem_free(source_file_name);
383 if (string_constant != NULL)
384 string_destroy(string_constant);
386 if (!detect_units_only)
388 switch(error_count)
390 case -1:
391 ShowHelp();
392 case 0:
393 PrintFinalMessage();
394 default:
395 sprintf(msgstr,"");
397 compileMSG();
400 mem_close();
401 return error_count;