File: | main.c |
Location: | line 154, column 31 |
Description: | Array access (from variable 'old_strvec') results in a null pointer dereference |
1 | /* File: "main.c" */ | |||||
2 | ||||||
3 | /* Copyright (c) 1994-2013 by Marc Feeley, All Rights Reserved. */ | |||||
4 | ||||||
5 | /* This is the driver of the Gambit-C system */ | |||||
6 | ||||||
7 | #define ___INCLUDED_FROM_MAIN | |||||
8 | #define ___VERSION407000 407000 | |||||
9 | #include "gambit.h" | |||||
10 | ||||||
11 | #include "os_base.h" | |||||
12 | #include "os_shell.h" | |||||
13 | #include "setup.h" | |||||
14 | ||||||
15 | ||||||
16 | /**********************************/ | |||||
17 | #ifdef ___DEBUG | |||||
18 | #ifdef ___DEBUG_ALLOC_MEM_TRACE | |||||
19 | #define ___alloc_mem(bytes) ___alloc_mem_debug(bytes,__LINE__19,__FILE__"main.c") | |||||
20 | #endif | |||||
21 | #endif | |||||
22 | ||||||
23 | ||||||
24 | /*---------------------------------------------------------------------------*/ | |||||
25 | ||||||
26 | ||||||
27 | ___HIDDENstatic ___UCS_2unsigned short gambcopt_env_name[] = | |||||
28 | { 'G', 'A', 'M', 'B', 'C', 'O', 'P', 'T', '\0' }; | |||||
29 | ||||||
30 | ||||||
31 | ___HIDDENstatic ___SCMOBJlong usage_err | |||||
32 | ___P((int debug_settings),(int debug_settings) | |||||
33 | (debug_settings)(int debug_settings) | |||||
34 | int debug_settings;)(int debug_settings) | |||||
35 | { | |||||
36 | ___setup_params.debug_settings = debug_settings; | |||||
37 | ||||||
38 | if (___DEBUG_SETTINGS_LEVEL(debug_settings)(((debug_settings) & 15) >> 0) != 0) | |||||
39 | { | |||||
40 | char *msgs[2]; | |||||
41 | msgs[0] = | |||||
42 | "Usage: program [-:OPTION,OPTION...] ...\n" | |||||
43 | "where OPTION is one of:\n" | |||||
44 | " mHEAPSIZE set minimum heap size in kilobytes\n" | |||||
45 | " hHEAPSIZE set maximum heap size in kilobytes\n" | |||||
46 | " lLIVEPERCENT set heap live ratio after GC in percent\n" | |||||
47 | " s|S set standard Scheme mode (on|off)\n" | |||||
48 | " d[OPT...] set debugging options; OPT is one of:\n" | |||||
49 | " p|a treat uncaught exceptions as errors\n" | |||||
50 | " (primordial-thread only|all threads)\n" | |||||
51 | " r|s|q error handling (create a new REPL|start in\n" | |||||
52 | " single-step mode|quit with error status)\n" | |||||
53 | " R|D|Q user interrupt handling (create a new REPL|\n" | |||||
54 | " defer handling|quit with error status)\n" | |||||
55 | " i|c|-|@[HOST][:PORT]\n" | |||||
56 | " select REPL interaction channel (ide|console|\n" | |||||
57 | " standard input and output|remote debugger\n" | |||||
58 | " (defaults: HOST=127.0.0.1, PORT=44555))\n" | |||||
59 | " 0..9 verbosity level\n" | |||||
60 | " @[INTF][:PORT] set main RPC server configuration; defaults: INTF=127.0.0.1,\n" | |||||
61 | " PORT=44556; when INTF=* all interfaces accept connections\n" | |||||
62 | " =DIRECTORY override central Gambit installation directory\n" | |||||
63 | " ~~DIR=DIRECTORY override Gambit installation directory ~~DIR (where DIR can\n" | |||||
64 | " be the special \"bin\" and \"lib\", or empty, or any identifier)\n" | |||||
65 | " +ARGUMENT add ARGUMENT to the command line before other arguments\n" | |||||
66 | " f[OPT...] set file options; see below for OPT\n" | |||||
67 | " t[OPT...] set terminal options; see below for OPT\n" | |||||
68 | " -[OPT...] set standard input and output options; see below for OPT\n" | |||||
69 | "where OPT is one of:\n" | |||||
70 | " A|1|2|4|6|8|U character encoding (ASCII|ISO-8859-1|UCS-2/4|UTF-16/8|UTF)\n" | |||||
71 | " l|c|cl end-of-line encoding (LF|CR|CR-LF)\n" | |||||
72 | " u|n|f buffering (unbuffered|newline buffered|fully buffered)\n" | |||||
73 | " r|R enable character encoding errors (on|off)\n" | |||||
74 | " e|E [for terminals only] enable line-editing (on|off)\n"; | |||||
75 | msgs[1] = 0; | |||||
76 | ___display_error (msgs); | |||||
77 | } | |||||
78 | ||||||
79 | return ___FIXADD(___FIX(___EXIT_CODE_USAGE),___FIX(1))((long)(((((long)(64))<<2))+((((long)(1))<<2)))); | |||||
80 | } | |||||
81 | ||||||
82 | ||||||
83 | ___HIDDENstatic ___UCS_2STRINGunsigned short* extract_string | |||||
84 | ___P((___UCS_2STRING *start),(unsigned short* *start) | |||||
85 | (start)(unsigned short* *start) | |||||
86 | ___UCS_2STRING *start;)(unsigned short* *start) | |||||
87 | { | |||||
88 | ___UCS_2unsigned short c; | |||||
89 | ___UCS_2STRINGunsigned short* p1 = *start; | |||||
90 | ___UCS_2STRINGunsigned short* p2; | |||||
91 | int n = 0; | |||||
92 | ___UCS_2STRINGunsigned short* result; | |||||
93 | ||||||
94 | while ((c = *p1) != '\0' && (c != ',' || p1[1] == ',')) | |||||
95 | { | |||||
96 | p1++; | |||||
97 | if (c == ',') | |||||
98 | p1++; | |||||
99 | n++; | |||||
100 | } | |||||
101 | ||||||
102 | p2 = *start; | |||||
103 | *start = p1; | |||||
104 | ||||||
105 | result = ___CAST(___UCS_2STRING,((unsigned short*)(___alloc_mem ((n+1) * sizeof (unsigned short )))) | |||||
106 | ___alloc_mem ((n+1) * sizeof (___UCS_2)))((unsigned short*)(___alloc_mem ((n+1) * sizeof (unsigned short )))); | |||||
107 | ||||||
108 | if (result != 0) | |||||
109 | { | |||||
110 | p1 = result; | |||||
111 | while ((c = *p2) != '\0' && (c != ',' || p2[1] == ',')) | |||||
112 | { | |||||
113 | p2++; | |||||
114 | if (c == ',') | |||||
115 | p2++; | |||||
116 | *p1++ = c; | |||||
117 | } | |||||
118 | *p1++ = '\0'; | |||||
119 | } | |||||
120 | ||||||
121 | return result; | |||||
122 | } | |||||
123 | ||||||
124 | ||||||
125 | ___HIDDENstatic ___BOOLint extend_strvec | |||||
126 | ___P((___UCS_2STRING **strvec,(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
127 | int pos,(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
128 | int nb_to_add,(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
129 | ___BOOL free_old),(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
130 | (strvec,(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
131 | pos,(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
132 | nb_to_add,(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
133 | free_old)(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
134 | ___UCS_2STRING **strvec;(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
135 | int pos;(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
136 | int nb_to_add;(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
137 | ___BOOL free_old;)(unsigned short* **strvec, int pos, int nb_to_add, int free_old ) | |||||
138 | { | |||||
139 | int i; | |||||
140 | int n = 0; | |||||
141 | ___UCS_2STRINGunsigned short* *old_strvec = *strvec; | |||||
| ||||||
142 | ___UCS_2STRINGunsigned short* *new_strvec; | |||||
143 | ||||||
144 | if (old_strvec != 0) | |||||
145 | while (old_strvec[n] != 0) n++; | |||||
146 | ||||||
147 | new_strvec = ___CAST(___UCS_2STRING*,((unsigned short**)(___alloc_mem ((n+nb_to_add+1) * sizeof (unsigned short*)))) | |||||
148 | ___alloc_mem ((n+nb_to_add+1) * sizeof (___UCS_2STRING)))((unsigned short**)(___alloc_mem ((n+nb_to_add+1) * sizeof (unsigned short*)))); | |||||
149 | ||||||
150 | if (new_strvec == 0) | |||||
151 | return 0; | |||||
152 | ||||||
153 | for (i=pos; i<n; i++) | |||||
154 | new_strvec[i+nb_to_add] = old_strvec[i]; | |||||
| ||||||
155 | ||||||
156 | for (i=0; i<pos; i++) | |||||
157 | new_strvec[i] = old_strvec[i]; | |||||
158 | ||||||
159 | new_strvec[n+nb_to_add] = 0; | |||||
160 | ||||||
161 | *strvec = new_strvec; | |||||
162 | ||||||
163 | if (free_old) | |||||
164 | ___free_mem (old_strvec); | |||||
165 | ||||||
166 | return 1; | |||||
167 | } | |||||
168 | ||||||
169 | ||||||
170 | int ___main | |||||
171 | ___P((___mod_or_lnk (*linker)(___global_state_struct*)),(___mod_or_lnk (*linker)(___global_state_struct*)) | |||||
172 | (linker)(___mod_or_lnk (*linker)(___global_state_struct*)) | |||||
173 | ___mod_or_lnk (*linker)();)(___mod_or_lnk (*linker)(___global_state_struct*)) | |||||
174 | { | |||||
175 | #define LARGEST_ULONG(unsigned long)(~((unsigned long)(0))) (unsigned long)(~___CAST(unsigned long,0)((unsigned long)(0))) | |||||
176 | ||||||
177 | ___UCS_2STRINGunsigned short* *argv; | |||||
178 | ___UCS_2STRINGunsigned short* *current_argv; | |||||
179 | ___UCS_2STRINGunsigned short* runtime_options; | |||||
180 | ___UCS_2STRINGunsigned short* script_line; | |||||
181 | int extra_arg_pos; | |||||
182 | int contract_argv; | |||||
183 | int options_source; | |||||
184 | int options_source_min; | |||||
185 | int options_source_max; | |||||
186 | ___UCS_2STRINGunsigned short* gambcdir; | |||||
187 | ___UCS_2STRINGunsigned short* *gambcdir_map; | |||||
188 | int gambcdir_map_len; | |||||
189 | ___UCS_2STRINGunsigned short* gambcopt; | |||||
190 | ___UCS_2STRINGunsigned short* remote_dbg_addr; | |||||
191 | ___UCS_2STRINGunsigned short* rpc_server_addr; | |||||
192 | unsigned long min_heap_len; | |||||
193 | unsigned long max_heap_len; | |||||
194 | int live_percent; | |||||
195 | int standard_level; | |||||
196 | int debug_settings; | |||||
197 | int file_settings; | |||||
198 | int terminal_settings; | |||||
199 | int stdio_settings; | |||||
200 | ___SCMOBJlong e; | |||||
201 | ___setup_params_struct setup_params; | |||||
202 | ||||||
203 | /* handle arguments to runtime */ | |||||
204 | ||||||
205 | argv = ___program_startup_info.argv; | |||||
206 | gambcdir = 0; | |||||
207 | gambcdir_map = 0; | |||||
208 | gambcdir_map_len = 0; | |||||
209 | gambcopt = 0; | |||||
210 | remote_dbg_addr = 0; | |||||
211 | rpc_server_addr = 0; | |||||
212 | min_heap_len = 0; | |||||
213 | max_heap_len = 0; | |||||
214 | live_percent = 0; | |||||
215 | standard_level = 0; | |||||
216 | debug_settings = ___DEBUG_SETTINGS_INITIAL((1 << 0) | (0 << 4) | (2 << 5) | (0 << 7) | (2 << 9)); | |||||
217 | file_settings = ___FILE_SETTINGS_INITIAL0; | |||||
218 | terminal_settings = ___TERMINAL_SETTINGS_INITIAL0; | |||||
219 | stdio_settings = ___STDIO_SETTINGS_INITIAL0; | |||||
220 | ||||||
221 | if (argv != 0 | |||||
222 | && (runtime_options = argv[1]) != 0 | |||||
223 | && runtime_options[0] == '-' | |||||
224 | && runtime_options[1] == ':') | |||||
225 | { | |||||
226 | runtime_options += 2; | |||||
227 | if (runtime_options[0] == ':') | |||||
228 | runtime_options++; | |||||
229 | } | |||||
230 | else | |||||
231 | runtime_options = 0; | |||||
232 | ||||||
233 | if ((script_line = ___program_startup_info.script_line) != 0) | |||||
234 | { | |||||
235 | for (;;) | |||||
236 | { | |||||
237 | if (*script_line == '\0') | |||||
238 | { | |||||
239 | script_line = 0; | |||||
240 | break; | |||||
241 | } | |||||
242 | if (script_line[0] == ' ' | |||||
243 | && script_line[1] == '-' | |||||
244 | && script_line[2] == ':') | |||||
245 | { | |||||
246 | script_line += 3; | |||||
247 | break; | |||||
248 | } | |||||
249 | script_line++; | |||||
250 | } | |||||
251 | } | |||||
252 | ||||||
253 | if (script_line != 0 && | |||||
254 | script_line[0] == ':') | |||||
255 | { | |||||
256 | script_line++; | |||||
257 | runtime_options = 0; | |||||
258 | options_source_min = 1; | |||||
259 | options_source_max = 1; | |||||
260 | } | |||||
261 | else | |||||
262 | { | |||||
263 | options_source_min = 0; | |||||
264 | options_source_max = 2; | |||||
265 | } | |||||
266 | ||||||
267 | current_argv = argv; | |||||
268 | extra_arg_pos = 1; | |||||
269 | contract_argv = (runtime_options != 0); | |||||
270 | ||||||
271 | for (options_source = options_source_min; | |||||
272 | options_source <= options_source_max; | |||||
273 | options_source++) | |||||
274 | { | |||||
275 | ___UCS_2STRINGunsigned short* arg; | |||||
276 | ||||||
277 | if (options_source == 0) | |||||
278 | { | |||||
279 | if ((e = ___getenv_UCS_2 (gambcopt_env_name, &gambcopt)) | |||||
280 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||||
281 | goto after_setup; | |||||
282 | arg = gambcopt; | |||||
283 | } | |||||
284 | else if (options_source == 1) | |||||
285 | arg = script_line; | |||||
286 | else | |||||
287 | arg = runtime_options; | |||||
288 | ||||||
289 | if (arg == 0) | |||||
290 | continue; | |||||
291 | ||||||
292 | do | |||||
293 | { | |||||
294 | ___UCS_2STRINGunsigned short* s = arg++; | |||||
295 | switch (*s) | |||||
296 | { | |||||
297 | case 'm': | |||||
298 | case 'h': | |||||
299 | case 'l': | |||||
300 | { | |||||
301 | unsigned long argval = 0; | |||||
302 | while (*arg >= '0' && *arg <= '9') | |||||
303 | { | |||||
304 | unsigned int n = *arg - '0'; | |||||
305 | if (argval > (LARGEST_ULONG(unsigned long)(~((unsigned long)(0)))>>10)/10 || | |||||
306 | (argval == (LARGEST_ULONG(unsigned long)(~((unsigned long)(0)))>>10)/10 && | |||||
307 | n > ((LARGEST_ULONG(unsigned long)(~((unsigned long)(0)))>>10)-argval*10))) | |||||
308 | { | |||||
309 | e = usage_err (debug_settings); | |||||
310 | goto after_setup; | |||||
311 | } | |||||
312 | argval = argval*10 + n; | |||||
313 | arg++; | |||||
314 | } | |||||
315 | if (arg == s+1) | |||||
316 | { | |||||
317 | e = usage_err (debug_settings); | |||||
318 | goto after_setup; | |||||
319 | } | |||||
320 | switch (*s) | |||||
321 | { | |||||
322 | case 'm': min_heap_len = argval<<10; | |||||
323 | break; | |||||
324 | case 'h': max_heap_len = argval<<10; | |||||
325 | break; | |||||
326 | case 'l': if (argval > 100) | |||||
327 | argval = 100; | |||||
328 | live_percent = argval; | |||||
329 | break; | |||||
330 | } | |||||
331 | break; | |||||
332 | } | |||||
333 | ||||||
334 | case 's': | |||||
335 | standard_level = 5; | |||||
336 | break; | |||||
337 | ||||||
338 | case 'S': | |||||
339 | standard_level = 1; | |||||
340 | break; | |||||
341 | ||||||
342 | case 'd': | |||||
343 | { | |||||
344 | if (*arg == '\0' || *arg == ' ' || *arg == ',') | |||||
345 | debug_settings = ___DEBUG_SETTINGS_DEFAULT((1 << 0) | (0 << 4) | (0 << 5) | (0 << 7) | (0 << 9)); | |||||
346 | else | |||||
347 | while (*arg != '\0' && *arg != ' ' && *arg != ',') | |||||
348 | { | |||||
349 | if (*arg >= '0' && *arg <= '9') | |||||
350 | { | |||||
351 | debug_settings = | |||||
352 | (debug_settings & ~___DEBUG_SETTINGS_LEVEL_MASK15) | |||||
353 | | ((*arg - '0') << ___DEBUG_SETTINGS_LEVEL_SHIFT0); | |||||
354 | arg++; | |||||
355 | } | |||||
356 | else | |||||
357 | switch (*arg++) | |||||
358 | { | |||||
359 | case 'p': debug_settings = | |||||
360 | (debug_settings | |||||
361 | & ~___DEBUG_SETTINGS_UNCAUGHT_MASK(1<<4)) | |||||
362 | | (___DEBUG_SETTINGS_UNCAUGHT_PRIMORDIAL0 | |||||
363 | << ___DEBUG_SETTINGS_UNCAUGHT_SHIFT4); | |||||
364 | break; | |||||
365 | case 'a': debug_settings = | |||||
366 | (debug_settings | |||||
367 | & ~___DEBUG_SETTINGS_UNCAUGHT_MASK(1<<4)) | |||||
368 | | (___DEBUG_SETTINGS_UNCAUGHT_ALL1 | |||||
369 | << ___DEBUG_SETTINGS_UNCAUGHT_SHIFT4); | |||||
370 | break; | |||||
371 | case 'r': debug_settings = | |||||
372 | (debug_settings | |||||
373 | & ~___DEBUG_SETTINGS_ERROR_MASK(3<<5)) | |||||
374 | | (___DEBUG_SETTINGS_ERROR_REPL0 | |||||
375 | << ___DEBUG_SETTINGS_ERROR_SHIFT5); | |||||
376 | break; | |||||
377 | case 's': debug_settings = | |||||
378 | (debug_settings | |||||
379 | & ~___DEBUG_SETTINGS_ERROR_MASK(3<<5)) | |||||
380 | | (___DEBUG_SETTINGS_ERROR_SINGLE_STEP1 | |||||
381 | << ___DEBUG_SETTINGS_ERROR_SHIFT5); | |||||
382 | break; | |||||
383 | case 'q': debug_settings = | |||||
384 | (debug_settings | |||||
385 | & ~___DEBUG_SETTINGS_ERROR_MASK(3<<5)) | |||||
386 | | (___DEBUG_SETTINGS_ERROR_QUIT2 | |||||
387 | << ___DEBUG_SETTINGS_ERROR_SHIFT5); | |||||
388 | break; | |||||
389 | case 'R': debug_settings = | |||||
390 | (debug_settings | |||||
391 | & ~___DEBUG_SETTINGS_USER_INTR_MASK(3<<9)) | |||||
392 | | (___DEBUG_SETTINGS_USER_INTR_REPL0 | |||||
393 | << ___DEBUG_SETTINGS_USER_INTR_SHIFT9); | |||||
394 | break; | |||||
395 | case 'D': debug_settings = | |||||
396 | (debug_settings | |||||
397 | & ~___DEBUG_SETTINGS_USER_INTR_MASK(3<<9)) | |||||
398 | | (___DEBUG_SETTINGS_USER_INTR_DEFER1 | |||||
399 | << ___DEBUG_SETTINGS_USER_INTR_SHIFT9); | |||||
400 | break; | |||||
401 | case 'Q': debug_settings = | |||||
402 | (debug_settings | |||||
403 | & ~___DEBUG_SETTINGS_USER_INTR_MASK(3<<9)) | |||||
404 | | (___DEBUG_SETTINGS_USER_INTR_QUIT2 | |||||
405 | << ___DEBUG_SETTINGS_USER_INTR_SHIFT9); | |||||
406 | break; | |||||
407 | case 'i': debug_settings = | |||||
408 | (debug_settings | |||||
409 | & ~___DEBUG_SETTINGS_REPL_MASK(3<<7)) | |||||
410 | | (___DEBUG_SETTINGS_REPL_IDE0 | |||||
411 | << ___DEBUG_SETTINGS_REPL_SHIFT7); | |||||
412 | break; | |||||
413 | case 'c': debug_settings = | |||||
414 | (debug_settings | |||||
415 | & ~___DEBUG_SETTINGS_REPL_MASK(3<<7)) | |||||
416 | | (___DEBUG_SETTINGS_REPL_CONSOLE1 | |||||
417 | << ___DEBUG_SETTINGS_REPL_SHIFT7); | |||||
418 | break; | |||||
419 | case '-': debug_settings = | |||||
420 | (debug_settings | |||||
421 | & ~___DEBUG_SETTINGS_REPL_MASK(3<<7)) | |||||
422 | | (___DEBUG_SETTINGS_REPL_STDIO2 | |||||
423 | << ___DEBUG_SETTINGS_REPL_SHIFT7); | |||||
424 | break; | |||||
425 | ||||||
426 | case '@': | |||||
427 | debug_settings = | |||||
428 | (debug_settings | |||||
429 | & ~___DEBUG_SETTINGS_REPL_MASK(3<<7)) | |||||
430 | | (___DEBUG_SETTINGS_REPL_REMOTE3 | |||||
431 | << ___DEBUG_SETTINGS_REPL_SHIFT7); | |||||
432 | ___free_UCS_2STRING (remote_dbg_addr); | |||||
433 | remote_dbg_addr = extract_string (&arg); | |||||
434 | if (remote_dbg_addr == 0) | |||||
435 | { | |||||
436 | e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||||
437 | goto after_setup; | |||||
438 | } | |||||
439 | break; | |||||
440 | ||||||
441 | default: | |||||
442 | e = usage_err (debug_settings); | |||||
443 | goto after_setup; | |||||
444 | } | |||||
445 | } | |||||
446 | break; | |||||
447 | } | |||||
448 | ||||||
449 | case '@': | |||||
450 | { | |||||
451 | ___free_UCS_2STRING (rpc_server_addr); | |||||
452 | rpc_server_addr = extract_string (&arg); | |||||
453 | if (rpc_server_addr == 0) | |||||
454 | { | |||||
455 | e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||||
456 | goto after_setup; | |||||
457 | } | |||||
458 | break; | |||||
459 | } | |||||
460 | ||||||
461 | case '=': | |||||
462 | { | |||||
463 | ___free_UCS_2STRING (gambcdir); | |||||
464 | gambcdir = extract_string (&arg); | |||||
465 | if (gambcdir == 0) | |||||
466 | { | |||||
467 | e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||||
468 | goto after_setup; | |||||
469 | } | |||||
470 | break; | |||||
471 | } | |||||
472 | ||||||
473 | case '~': | |||||
474 | { | |||||
475 | ___UCS_2STRINGunsigned short* dir; | |||||
476 | ___UCS_2unsigned short c; | |||||
477 | ||||||
478 | if (*arg++ != '~') | |||||
479 | { | |||||
480 | e = usage_err (debug_settings); | |||||
481 | goto after_setup; | |||||
482 | } | |||||
483 | ||||||
484 | s = arg; | |||||
485 | ||||||
486 | while ((c = *s++) != '=') | |||||
487 | if (!(((c >= 'a') && (c <= 'z')) || | |||||
488 | ((c >= 'A') && (c <= 'Z')))) | |||||
489 | { | |||||
490 | e = usage_err (debug_settings); | |||||
491 | goto after_setup; | |||||
492 | } | |||||
493 | ||||||
494 | if (!extend_strvec (&gambcdir_map, 0, 1, gambcdir_map != 0)) | |||||
495 | { | |||||
496 | e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||||
497 | goto after_setup; | |||||
498 | } | |||||
499 | ||||||
500 | if ((dir = extract_string (&arg)) == 0) | |||||
501 | { | |||||
502 | e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||||
503 | goto after_setup; | |||||
504 | } | |||||
505 | ||||||
506 | gambcdir_map[0] = dir; | |||||
507 | ||||||
508 | break; | |||||
509 | } | |||||
510 | ||||||
511 | case '+': | |||||
512 | { | |||||
513 | ___UCS_2STRINGunsigned short* extra_arg; | |||||
514 | ||||||
515 | if (!extend_strvec (¤t_argv, | |||||
516 | extra_arg_pos, | |||||
517 | 1 - contract_argv, | |||||
518 | current_argv != argv)) | |||||
519 | { | |||||
520 | e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||||
521 | goto after_setup; | |||||
522 | } | |||||
523 | ||||||
524 | contract_argv = 0; | |||||
525 | ||||||
526 | if ((extra_arg = extract_string (&arg)) == 0) | |||||
527 | { | |||||
528 | e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||||
529 | goto after_setup; | |||||
530 | } | |||||
531 | ||||||
532 | current_argv[extra_arg_pos++] = extra_arg; | |||||
533 | ||||||
534 | break; | |||||
535 | } | |||||
536 | ||||||
537 | case 't': | |||||
538 | case 'f': | |||||
539 | case '-': | |||||
540 | { | |||||
541 | int settings = 0; | |||||
542 | ||||||
543 | switch (*s) | |||||
544 | { | |||||
545 | case 'f': | |||||
546 | settings = file_settings; | |||||
547 | break; | |||||
548 | case 't': | |||||
549 | settings = terminal_settings; | |||||
550 | break; | |||||
551 | case '-': | |||||
552 | settings = stdio_settings; | |||||
553 | break; | |||||
554 | } | |||||
555 | ||||||
556 | while (*arg != '\0' && *arg != ' ' && *arg != ',') | |||||
557 | { | |||||
558 | switch (*arg++) | |||||
559 | { | |||||
560 | case 'A': settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
561 | |___CHAR_ENCODING_ASCII(1<<0); | |||||
562 | break; | |||||
563 | case '1': settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
564 | |___CHAR_ENCODING_ISO_8859_1(2<<0); | |||||
565 | break; | |||||
566 | case '2': settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
567 | |___CHAR_ENCODING_UCS_2(13<<0); | |||||
568 | break; | |||||
569 | case '4': settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
570 | |___CHAR_ENCODING_UCS_4(16<<0); | |||||
571 | break; | |||||
572 | case '6': settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
573 | |___CHAR_ENCODING_UTF_16(4<<0); | |||||
574 | break; | |||||
575 | case '8': settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
576 | |___CHAR_ENCODING_UTF_8(3<<0); | |||||
577 | break; | |||||
578 | case 'U': switch (*arg++) | |||||
579 | { | |||||
580 | case 'A': | |||||
581 | settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
582 | |___CHAR_ENCODING_UTF_FALLBACK_ASCII(7<<0); | |||||
583 | break; | |||||
584 | case '1': | |||||
585 | settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
586 | |___CHAR_ENCODING_UTF_FALLBACK_ISO_8859_1(8<<0); | |||||
587 | break; | |||||
588 | case '6': | |||||
589 | settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
590 | |___CHAR_ENCODING_UTF_FALLBACK_UTF_16(10<<0); | |||||
591 | break; | |||||
592 | case '8': | |||||
593 | settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
594 | |___CHAR_ENCODING_UTF_FALLBACK_UTF_8(9<<0); | |||||
595 | break; | |||||
596 | default: | |||||
597 | arg--; | |||||
598 | settings = ___CHAR_ENCODING_MASK(settings)((settings)&~(31<<0)) | |||||
599 | |___CHAR_ENCODING_UTF(9<<0); | |||||
600 | break; | |||||
601 | } | |||||
602 | break; | |||||
603 | case 'l': settings = ___EOL_ENCODING_MASK(settings)((settings)&~(3<<7)) | |||||
604 | |((___EOL_ENCODING(settings)((settings)&(3<<7)) | |||||
605 | ==___EOL_ENCODING_CR(2<<7)) | |||||
606 | ?___EOL_ENCODING_CRLF(3<<7) | |||||
607 | :___EOL_ENCODING_LF(1<<7)); | |||||
608 | break; | |||||
609 | case 'c': settings = ___EOL_ENCODING_MASK(settings)((settings)&~(3<<7)) | |||||
610 | |___EOL_ENCODING_CR(2<<7); | |||||
611 | break; | |||||
612 | case 'u': settings = ___BUFFERING_MASK(settings)((settings)&~(3<<9)) | |||||
613 | |___NO_BUFFERING(1<<9); | |||||
614 | break; | |||||
615 | case 'n': settings = ___BUFFERING_MASK(settings)((settings)&~(3<<9)) | |||||
616 | |___LINE_BUFFERING(2<<9); | |||||
617 | break; | |||||
618 | case 'f': settings = ___BUFFERING_MASK(settings)((settings)&~(3<<9)) | |||||
619 | |___FULL_BUFFERING(3<<9); | |||||
620 | break; | |||||
621 | case 'r': settings = ___CHAR_ENCODING_ERRORS_MASK(settings)((settings)&~(3<<5)) | |||||
622 | |___CHAR_ENCODING_ERRORS_ON(1<<5); | |||||
623 | break; | |||||
624 | case 'R': settings = ___CHAR_ENCODING_ERRORS_MASK(settings)((settings)&~(3<<5)) | |||||
625 | |___CHAR_ENCODING_ERRORS_OFF(2<<5); | |||||
626 | break; | |||||
627 | case 'e': | |||||
628 | case 'E': if (*s != 't') | |||||
629 | { | |||||
630 | e = usage_err (debug_settings); | |||||
631 | goto after_setup; | |||||
632 | } | |||||
633 | settings = | |||||
634 | ___TERMINAL_LINE_EDITING_MASK(settings)((settings)&~(3<<16)) | |||||
635 | |((arg[-1] == 'e') | |||||
636 | ?___TERMINAL_LINE_EDITING_ON(1<<16) | |||||
637 | :___TERMINAL_LINE_EDITING_OFF(2<<16)); | |||||
638 | break; | |||||
639 | default: | |||||
640 | e = usage_err (debug_settings); | |||||
641 | goto after_setup; | |||||
642 | } | |||||
643 | } | |||||
644 | ||||||
645 | switch (*s) | |||||
646 | { | |||||
647 | case 'f': | |||||
648 | file_settings = settings; | |||||
649 | break; | |||||
650 | case 't': | |||||
651 | terminal_settings = settings; | |||||
652 | break; | |||||
653 | case '-': | |||||
654 | stdio_settings = settings; | |||||
655 | break; | |||||
656 | } | |||||
657 | ||||||
658 | break; | |||||
659 | } | |||||
660 | ||||||
661 | default: | |||||
662 | { | |||||
663 | arg--; | |||||
664 | break; | |||||
665 | } | |||||
666 | } | |||||
667 | } while (*arg++ == ','); | |||||
668 | ||||||
669 | if (arg[-1] != '\0' && arg[-1] != ' ') | |||||
670 | { | |||||
671 | e = usage_err (debug_settings); | |||||
672 | goto after_setup; | |||||
673 | } | |||||
674 | } | |||||
675 | ||||||
676 | if (contract_argv != 0) | |||||
677 | { | |||||
678 | if (!extend_strvec (¤t_argv, | |||||
679 | extra_arg_pos, | |||||
680 | -1, | |||||
681 | 0)) /* we know that current_argv == argv */ | |||||
682 | { | |||||
683 | e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||||
684 | goto after_setup; | |||||
685 | } | |||||
686 | } | |||||
687 | ||||||
688 | #ifdef ___FORCE_MAX_HEAP | |||||
689 | if (max_heap_len == 0 || max_heap_len > (___FORCE_MAX_HEAP<<10)) | |||||
690 | max_heap_len = ___FORCE_MAX_HEAP<<10; | |||||
691 | #endif | |||||
692 | ||||||
693 | /* Setup program, run it and perform any cleanup necessary. */ | |||||
694 | ||||||
695 | ___setup_params_reset (&setup_params); | |||||
696 | ||||||
697 | setup_params.version = ___VERSION407000; | |||||
698 | setup_params.argv = current_argv; | |||||
699 | setup_params.min_heap = min_heap_len; | |||||
700 | setup_params.max_heap = max_heap_len; | |||||
701 | setup_params.live_percent = live_percent; | |||||
702 | setup_params.standard_level = standard_level; | |||||
703 | setup_params.debug_settings = debug_settings; | |||||
704 | setup_params.file_settings = file_settings; | |||||
705 | setup_params.terminal_settings = terminal_settings; | |||||
706 | setup_params.stdio_settings = stdio_settings; | |||||
707 | setup_params.gambcdir = gambcdir; | |||||
708 | setup_params.gambcdir_map = gambcdir_map; | |||||
709 | setup_params.remote_dbg_addr = remote_dbg_addr; | |||||
710 | setup_params.rpc_server_addr = rpc_server_addr; | |||||
711 | setup_params.linker = linker; | |||||
712 | ||||||
713 | e = ___setup (&setup_params); | |||||
714 | ||||||
715 | after_setup: | |||||
716 | ||||||
717 | while (extra_arg_pos > 1) | |||||
718 | ___free_UCS_2STRING (current_argv[--extra_arg_pos]); | |||||
719 | ||||||
720 | if (current_argv != argv) | |||||
721 | ___free_mem (current_argv); | |||||
722 | ||||||
723 | while (gambcdir_map_len > 0) | |||||
724 | ___free_UCS_2STRING (gambcdir_map[gambcdir_map_len--]); | |||||
725 | ||||||
726 | if (gambcdir_map != 0) | |||||
727 | ___free_mem (gambcdir_map); | |||||
728 | ||||||
729 | ___free_UCS_2STRING (gambcdir); | |||||
730 | ___free_UCS_2STRING (gambcopt); | |||||
731 | ___free_UCS_2STRING (remote_dbg_addr); | |||||
732 | ___free_UCS_2STRING (rpc_server_addr); | |||||
733 | ||||||
734 | if (e == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||||
735 | { | |||||
736 | ___cleanup (); | |||||
737 | e = ___FIX(___EXIT_CODE_OK)(((long)(0))<<2); | |||||
738 | } | |||||
739 | else if (e > ___FIX(___NO_ERR)(((long)(0))<<2)) | |||||
740 | e = ___FIXSUB(e,___FIX(1))((long)((e)-((((long)(1))<<2)))); | |||||
741 | else | |||||
742 | { | |||||
743 | #ifdef ___DEBUG | |||||
744 | ___printf ("___setup returned error code %d\n", ___INT(e)((e)>>2)); | |||||
745 | #endif | |||||
746 | e = ___FIX(___EXIT_CODE_OSERR)(((long)(71))<<2); | |||||
747 | } | |||||
748 | ||||||
749 | return ___INT(e)((e)>>2); | |||||
750 | } | |||||
751 | ||||||
752 | ||||||
753 | /*---------------------------------------------------------------------------*/ |