Bug Summary

File:main.c
Location:line 154, column 31
Description:Array access (from variable 'old_strvec') results in a null pointer dereference

Annotated Source Code

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)
34int 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
)
135int pos;(unsigned short* **strvec, int pos, int nb_to_add, int free_old
)
136int 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;
1
Within the expansion of the macro '___UCS_2STRING':
a
'old_strvec' initialized here
142 ___UCS_2STRINGunsigned short* *new_strvec;
143
144 if (old_strvec != 0)
2
Assuming 'old_strvec' is equal to null
3
Taking false branch
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)
4
Assuming 'new_strvec' is not equal to null
5
Taking false branch
151 return 0;
152
153 for (i=pos; i<n; i++)
6
Assuming 'i' is < 'n'
7
Loop condition is true. Entering loop body
154 new_strvec[i+nb_to_add] = old_strvec[i];
8
Array access (from variable 'old_strvec') results in a null pointer dereference
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
170int ___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 (&current_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 (&current_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/*---------------------------------------------------------------------------*/