| File: | main.c |
| Location: | line 157, column 21 |
| 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 | /*---------------------------------------------------------------------------*/ |