2007-12-30 17:41:49 +01:00
|
|
|
/***************************************************************************
|
|
|
|
|
2011-12-31 03:39:20 +01:00
|
|
|
gbx.c
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2018-02-12 02:53:46 +01:00
|
|
|
(c) 2000-2017 Benoît Minisini <g4mba5@gmail.com>
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-12-31 03:39:20 +01:00
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
any later version.
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-12-31 03:39:20 +01:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-12-31 03:39:20 +01:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
|
|
MA 02110-1301, USA.
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
|
2013-05-25 15:23:39 +02:00
|
|
|
#define __GBX_C
|
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
#include "config.h"
|
2013-05-25 15:23:39 +02:00
|
|
|
#include "../trunk_version.h"
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-07-25 02:50:11 +02:00
|
|
|
//#define USE_PROFILE 1
|
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
#include "gb_common.h"
|
|
|
|
#include "gb_alloc.h"
|
|
|
|
#include "gb_error.h"
|
|
|
|
|
|
|
|
#include <dlfcn.h>
|
2010-02-03 16:48:37 +01:00
|
|
|
#include <stdarg.h>
|
2012-03-28 23:55:19 +02:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/resource.h>
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
#include "gbx_class.h"
|
|
|
|
#include "gbx_exec.h"
|
|
|
|
#include "gbx_stack.h"
|
|
|
|
#include "gbx_debug.h"
|
|
|
|
#include "gb_file.h"
|
|
|
|
#include "gbx_component.h"
|
|
|
|
#include "gbx_project.h"
|
|
|
|
#include "gbx_local.h"
|
|
|
|
#include "gbx_watch.h"
|
|
|
|
#include "gbx_event.h"
|
|
|
|
#include "gbx_extern.h"
|
|
|
|
#include "gbx_eval.h"
|
|
|
|
#include "gbx_subr.h"
|
|
|
|
#include "gbx_math.h"
|
|
|
|
#include "gb_common_buffer.h"
|
|
|
|
#include "gbx_api.h"
|
2012-05-08 17:32:33 +02:00
|
|
|
#include "gbx_signal.h"
|
2018-06-01 03:50:42 +02:00
|
|
|
#include "gbx_jit.h"
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-07-25 02:50:11 +02:00
|
|
|
#if USE_PROFILE
|
|
|
|
#include "gbx_profile.h"
|
|
|
|
#endif
|
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
#include "gbx_c_file.h"
|
|
|
|
#include "gbx_c_application.h"
|
2019-09-17 10:07:59 +02:00
|
|
|
#include "gbx.h"
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
extern void _exit(int) NORETURN;
|
2009-02-06 13:05:39 +01:00
|
|
|
FILE *log_file;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
static bool _welcome = FALSE;
|
2010-05-22 20:02:34 +02:00
|
|
|
static bool _quit_after_main = FALSE;
|
2014-05-30 03:25:46 +02:00
|
|
|
static bool _eval = FALSE;
|
2020-05-07 08:17:27 +02:00
|
|
|
static const char *_tests = NULL;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-02-03 16:48:37 +01:00
|
|
|
static void NORETURN my_exit(int ret)
|
2010-01-20 01:37:00 +01:00
|
|
|
{
|
2011-03-03 16:05:54 +01:00
|
|
|
LOCAL_exit();
|
|
|
|
COMPONENT_exit();
|
|
|
|
EXTERN_exit();
|
2010-01-20 01:37:00 +01:00
|
|
|
//fclose(log_file);
|
2011-03-03 16:05:54 +01:00
|
|
|
exit(ret);
|
2010-01-20 01:37:00 +01:00
|
|
|
}
|
|
|
|
|
2012-09-27 22:52:08 +02:00
|
|
|
static void init(const char *file, int argc, char **argv)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2011-03-03 16:05:54 +01:00
|
|
|
COMPONENT_init();
|
|
|
|
FILE_init();
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2011-03-03 16:05:54 +01:00
|
|
|
EXEC_init();
|
|
|
|
CLASS_init();
|
|
|
|
CFILE_init();
|
|
|
|
WATCH_init();
|
|
|
|
MATH_init();
|
2007-12-30 17:41:49 +01:00
|
|
|
PROJECT_init(file);
|
2011-03-03 16:05:54 +01:00
|
|
|
DEBUG_init();
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-09-26 03:46:48 +02:00
|
|
|
LOCAL_init();
|
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
if (file)
|
2010-01-20 01:37:00 +01:00
|
|
|
{
|
2013-01-29 01:53:21 +01:00
|
|
|
PROJECT_load();
|
2012-09-27 22:52:08 +02:00
|
|
|
|
2013-08-02 23:57:49 +02:00
|
|
|
if (PROJECT_run_httpd)
|
2012-09-27 22:52:08 +02:00
|
|
|
COMPONENT_exec("gb.httpd", argc, argv);
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2012-09-27 22:52:08 +02:00
|
|
|
PROJECT_load_finish();
|
2010-01-20 01:37:00 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
else
|
|
|
|
STACK_init();
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2009-08-18 00:36:54 +02:00
|
|
|
if (EXEC_debug)
|
|
|
|
{
|
|
|
|
DEBUG.Welcome();
|
|
|
|
DEBUG.Main(FALSE);
|
|
|
|
}
|
|
|
|
_welcome = TRUE;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-09-17 10:07:59 +02:00
|
|
|
void main_exit(bool silent)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2018-01-20 16:43:13 +01:00
|
|
|
silent |= EXEC_task;
|
|
|
|
|
2012-09-27 22:52:08 +02:00
|
|
|
// If the stack has not been initialized because the project could not be started, do it now
|
2010-01-20 01:37:00 +01:00
|
|
|
if (!SP)
|
|
|
|
STACK_init();
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2010-08-29 22:51:10 +02:00
|
|
|
TRY
|
|
|
|
{
|
2019-03-11 16:34:50 +01:00
|
|
|
JIT_abort();
|
2012-05-08 17:32:33 +02:00
|
|
|
SIGNAL_exit();
|
2010-08-29 22:51:10 +02:00
|
|
|
EXTERN_release();
|
|
|
|
STREAM_exit();
|
|
|
|
OBJECT_exit();
|
2014-12-20 16:24:00 +01:00
|
|
|
CFILE_exit();
|
2014-05-30 03:25:46 +02:00
|
|
|
|
2010-08-29 22:51:10 +02:00
|
|
|
CLASS_clean_up(silent);
|
2014-05-30 03:25:46 +02:00
|
|
|
|
2010-08-29 22:51:10 +02:00
|
|
|
SUBR_exit();
|
|
|
|
DEBUG_exit();
|
|
|
|
WATCH_exit();
|
2011-07-25 02:50:11 +02:00
|
|
|
#if USE_PROFILE
|
|
|
|
PROFILE_exit();
|
|
|
|
#endif
|
2010-08-29 22:51:10 +02:00
|
|
|
CLASS_exit();
|
|
|
|
COMPONENT_exit();
|
|
|
|
EXTERN_exit();
|
|
|
|
PROJECT_exit();
|
|
|
|
LOCAL_exit();
|
|
|
|
EVENT_exit();
|
|
|
|
FILE_exit();
|
|
|
|
STACK_exit();
|
2018-06-01 03:50:42 +02:00
|
|
|
JIT_exit();
|
2010-08-29 22:51:10 +02:00
|
|
|
ERROR_exit();
|
|
|
|
}
|
2014-05-30 03:25:46 +02:00
|
|
|
CATCH
|
|
|
|
{
|
|
|
|
if (!silent)
|
|
|
|
ERROR_print_at(stderr, _eval, TRUE);
|
|
|
|
_exit(1);
|
|
|
|
}
|
2010-08-29 22:51:10 +02:00
|
|
|
END_TRY
|
2014-05-30 20:39:40 +02:00
|
|
|
|
|
|
|
STRING_exit();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2019-09-17 10:07:59 +02:00
|
|
|
|
|
|
|
void MAIN_exit(bool silent, int ret)
|
|
|
|
{
|
|
|
|
main_exit(silent);
|
|
|
|
_exit(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-03 03:30:37 +01:00
|
|
|
static bool is_option(const char *arg, char option)
|
|
|
|
{
|
|
|
|
return (arg[0] == '-' && arg[1] == option && arg[2] == 0);
|
|
|
|
}
|
|
|
|
|
2020-05-07 08:17:27 +02:00
|
|
|
static bool is_long_option(const char *arg, char option, const char *long_option)
|
2012-06-10 16:58:45 +02:00
|
|
|
{
|
2020-05-07 08:17:27 +02:00
|
|
|
if (is_option(arg, option))
|
2012-06-10 16:58:45 +02:00
|
|
|
return TRUE;
|
|
|
|
else
|
2020-05-07 08:17:27 +02:00
|
|
|
return (arg[0] == '-' && arg[1] == '-' && !strcmp(&arg[2], long_option));
|
2012-06-10 16:58:45 +02:00
|
|
|
}
|
|
|
|
|
2020-05-07 08:17:27 +02:00
|
|
|
static bool is_option_arg(char **argv, int argc, int *i, char option, const char *long_option, const char **param)
|
2010-02-03 03:30:37 +01:00
|
|
|
{
|
2020-05-07 08:17:27 +02:00
|
|
|
if (long_option)
|
|
|
|
{
|
|
|
|
if (!is_long_option(argv[*i], option, long_option))
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-02-03 03:30:37 +01:00
|
|
|
else
|
2020-05-07 08:17:27 +02:00
|
|
|
{
|
|
|
|
if (!is_option(argv[*i], option))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-05-07 10:18:33 +02:00
|
|
|
if (*i < (argc - 1) && *argv[*i + 1] != '-')
|
2020-05-07 08:17:27 +02:00
|
|
|
{
|
|
|
|
*param = argv[*i + 1];
|
|
|
|
(*i)++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*param = NULL;
|
|
|
|
|
|
|
|
return TRUE;
|
2010-02-03 03:30:37 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2020-01-04 22:11:29 +01:00
|
|
|
static void print_version()
|
|
|
|
{
|
|
|
|
#ifdef TRUNK_VERSION
|
|
|
|
#ifdef TRUNK_VERSION_GIT
|
|
|
|
printf(VERSION " " TRUNK_VERSION "\n");
|
|
|
|
#else /* from svn */
|
|
|
|
printf(VERSION " r" TRUNK_VERSION "\n");
|
|
|
|
#endif
|
|
|
|
#else /* no TRUNK_VERSION */
|
|
|
|
printf(VERSION "\n");
|
|
|
|
#endif
|
|
|
|
}
|
2013-05-25 16:00:40 +02:00
|
|
|
|
2012-04-30 02:04:51 +02:00
|
|
|
int main(int argc, char *argv[])
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2011-03-03 16:05:54 +01:00
|
|
|
CLASS_DESC_METHOD *startup = NULL;
|
|
|
|
int i, n;
|
|
|
|
char *file = NULL;
|
2011-07-26 02:28:52 +02:00
|
|
|
int ret = 0;
|
2014-02-09 17:00:13 +01:00
|
|
|
const char *redirect_stderr = NULL;
|
|
|
|
|
2011-03-03 16:05:54 +01:00
|
|
|
//char log_path[256];
|
|
|
|
//sprintf(log_path, "/tmp/gambas-%d.log", getuid());
|
2009-02-06 13:05:39 +01:00
|
|
|
//log_file = freopen(log_path, "w+", stderr);
|
2011-03-03 16:05:54 +01:00
|
|
|
//fprintf(stderr, "Fichier log Gambas\n");
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2012-05-24 01:23:00 +02:00
|
|
|
/*struct rlimit rl = { 64000000, 64000000 };
|
2012-05-12 14:04:20 +02:00
|
|
|
if (setrlimit(RLIMIT_CORE, &rl))
|
|
|
|
perror(strerror(errno));*/
|
2009-02-06 13:05:39 +01:00
|
|
|
|
2011-03-03 16:05:54 +01:00
|
|
|
MEMORY_init();
|
|
|
|
COMMON_init();
|
|
|
|
//STRING_init();
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-05-10 13:20:47 +02:00
|
|
|
EXEC_arch = (strcmp(FILE_get_name(argv[0]), "gbr" GAMBAS_VERSION_STRING) == 0);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-02-01 13:17:38 +01:00
|
|
|
if (argc == 2)
|
|
|
|
{
|
2010-02-03 03:30:37 +01:00
|
|
|
if (is_long_option(argv[1], 'h', "help"))
|
2010-02-01 13:17:38 +01:00
|
|
|
{
|
|
|
|
if (EXEC_arch)
|
|
|
|
{
|
|
|
|
printf(
|
2012-08-21 03:03:52 +02:00
|
|
|
"\nExecute a Gambas executable.\n"
|
|
|
|
"\nUsage: gbr" GAMBAS_VERSION_STRING " [options] <executable file> [<arguments>]\n\n"
|
2010-02-01 13:17:38 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf(
|
2012-08-21 03:03:52 +02:00
|
|
|
"\nExecute a Gambas project or evaluate a Gambas expression (-e option).\n"
|
2020-01-04 22:11:29 +01:00
|
|
|
"\nUsage: gbx" GAMBAS_VERSION_STRING " [options] [<project directory>] [-- <arguments>]\n"
|
2010-02-01 13:17:38 +01:00
|
|
|
" gbx" GAMBAS_VERSION_STRING " -e <expression>\n\n"
|
2010-02-03 03:30:37 +01:00
|
|
|
);
|
|
|
|
}
|
2013-12-18 12:21:01 +01:00
|
|
|
|
2020-05-07 08:17:27 +02:00
|
|
|
printf("Options:\n");
|
|
|
|
|
2010-02-03 03:30:37 +01:00
|
|
|
if (!EXEC_arch)
|
2020-05-07 08:17:27 +02:00
|
|
|
printf(" -e evaluate an expression\n");
|
2013-12-18 12:21:01 +01:00
|
|
|
|
2012-08-21 03:03:52 +02:00
|
|
|
printf(
|
2020-11-02 22:09:35 +01:00
|
|
|
" -a <path> override application path\n"
|
2020-05-07 08:17:27 +02:00
|
|
|
" -g enter debugging mode\n"
|
|
|
|
" -h --help display this help\n"
|
|
|
|
" -H --httpd run through an embedded http server\n"
|
|
|
|
" -j disable just-in-time compiler\n"
|
|
|
|
" -k do not unload shared libraries\n"
|
|
|
|
" -L --license display license\n"
|
|
|
|
" -p <path> activate profiling and debugging mode\n"
|
|
|
|
" -r <path> redirect standard error output\n"
|
|
|
|
" -s <class> override startup class\n"
|
|
|
|
" -t --trace dump the position of each executed line of code\n"
|
2020-05-23 04:31:33 +02:00
|
|
|
" -T list all test modules\n"
|
2020-05-07 08:17:27 +02:00
|
|
|
" -T <tests> run the specified test modules\n"
|
|
|
|
" -V --version display version\n"
|
2012-08-21 03:03:52 +02:00
|
|
|
"\n"
|
|
|
|
);
|
2010-02-01 13:17:38 +01:00
|
|
|
|
|
|
|
my_exit(0);
|
|
|
|
}
|
2010-02-03 03:30:37 +01:00
|
|
|
else if (is_long_option(argv[1], 'V', "version"))
|
2010-02-01 13:17:38 +01:00
|
|
|
{
|
2020-01-04 22:11:29 +01:00
|
|
|
print_version();
|
2010-02-01 13:17:38 +01:00
|
|
|
my_exit(0);
|
|
|
|
}
|
2010-02-03 03:30:37 +01:00
|
|
|
else if (is_long_option(argv[1], 'L', "license"))
|
2010-02-01 13:17:38 +01:00
|
|
|
{
|
2020-01-04 22:11:29 +01:00
|
|
|
printf("\nGambas interpreter version ");
|
|
|
|
print_version();
|
|
|
|
printf(COPYRIGHT);
|
2010-02-01 13:17:38 +01:00
|
|
|
my_exit(0);
|
|
|
|
}
|
|
|
|
}
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2010-02-03 16:48:37 +01:00
|
|
|
if (!EXEC_arch && argc >= 2 && is_option(argv[1], 'e'))
|
2010-02-01 13:17:38 +01:00
|
|
|
{
|
2010-02-03 16:48:37 +01:00
|
|
|
if (argc < 3)
|
2012-12-15 03:27:42 +01:00
|
|
|
ERROR_fatal("-e option needs an expression.");
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2014-05-30 03:25:46 +02:00
|
|
|
_eval = TRUE;
|
|
|
|
|
2010-02-01 13:17:38 +01:00
|
|
|
TRY
|
|
|
|
{
|
2012-09-27 22:52:08 +02:00
|
|
|
init(NULL, argc, argv);
|
2010-02-01 13:17:38 +01:00
|
|
|
EVAL_string(argv[2]);
|
|
|
|
}
|
|
|
|
CATCH
|
|
|
|
{
|
|
|
|
if (ERROR_current->info.code && ERROR_current->info.code != E_ABORT)
|
|
|
|
ERROR_print_at(stderr, TRUE, TRUE);
|
2019-09-17 10:07:59 +02:00
|
|
|
MAIN_exit(TRUE, 1);
|
2010-02-01 13:17:38 +01:00
|
|
|
}
|
|
|
|
END_TRY
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2019-09-17 10:07:59 +02:00
|
|
|
MAIN_exit(FALSE, 0);
|
2010-02-01 13:17:38 +01:00
|
|
|
}
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2010-02-01 13:17:38 +01:00
|
|
|
for (i = 1; i < argc; i++)
|
|
|
|
{
|
2010-02-03 03:30:37 +01:00
|
|
|
if (is_option(argv[i], 'g'))
|
2010-02-01 13:17:38 +01:00
|
|
|
{
|
|
|
|
EXEC_debug = TRUE;
|
|
|
|
}
|
2020-05-07 08:17:27 +02:00
|
|
|
else if (is_option_arg(argv, argc, &i, 'p', NULL, &EXEC_profile_path))
|
2011-07-24 18:55:09 +02:00
|
|
|
{
|
2012-05-19 04:55:05 +02:00
|
|
|
EXEC_debug = TRUE;
|
2011-07-24 18:55:09 +02:00
|
|
|
EXEC_profile = TRUE;
|
|
|
|
}
|
2019-10-05 04:03:32 +02:00
|
|
|
else if (is_long_option(argv[i], 't', "trace"))
|
2019-09-28 16:53:48 +02:00
|
|
|
{
|
|
|
|
EXEC_trace = TRUE;
|
|
|
|
}
|
2020-05-07 08:17:27 +02:00
|
|
|
else if (is_option_arg(argv, argc, &i, 'f', NULL, &EXEC_fifo_name))
|
2010-02-01 13:17:38 +01:00
|
|
|
{
|
|
|
|
EXEC_fifo = TRUE;
|
|
|
|
}
|
2020-05-07 08:17:27 +02:00
|
|
|
else if (is_option_arg(argv, argc, &i, 's', NULL, &PROJECT_startup))
|
2014-02-12 23:26:02 +01:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2020-05-07 08:17:27 +02:00
|
|
|
else if (is_option_arg(argv, argc, &i, 'r', NULL, &redirect_stderr))
|
2014-02-09 17:00:13 +01:00
|
|
|
{
|
2014-11-23 19:19:57 +01:00
|
|
|
int fd = open(redirect_stderr, O_WRONLY | O_CLOEXEC);
|
2014-02-09 17:00:13 +01:00
|
|
|
if (fd < 0)
|
|
|
|
ERROR_fatal("cannot redirect stderr.");
|
|
|
|
dup2(fd, STDERR_FILENO);
|
|
|
|
}
|
2010-02-03 03:30:37 +01:00
|
|
|
else if (is_option(argv[i], 'k'))
|
2010-02-01 13:17:38 +01:00
|
|
|
{
|
|
|
|
EXEC_keep_library = TRUE;
|
|
|
|
}
|
2010-05-22 20:02:34 +02:00
|
|
|
else if (is_option(argv[i], 'q'))
|
|
|
|
{
|
|
|
|
_quit_after_main = TRUE;
|
|
|
|
}
|
2012-09-27 22:52:08 +02:00
|
|
|
else if (is_long_option(argv[i], 'H', "httpd"))
|
|
|
|
{
|
2013-08-02 23:57:49 +02:00
|
|
|
PROJECT_run_httpd = TRUE;
|
2012-09-27 22:52:08 +02:00
|
|
|
}
|
2018-08-11 07:53:02 +02:00
|
|
|
else if (is_option(argv[i], 'j'))
|
|
|
|
{
|
|
|
|
JIT_disabled = TRUE;
|
|
|
|
}
|
2020-05-07 08:17:27 +02:00
|
|
|
else if (is_option_arg(argv, argc, &i, 'T', "test", &_tests))
|
|
|
|
{
|
|
|
|
PROJECT_run_tests = TRUE;
|
|
|
|
}
|
2020-11-02 22:09:35 +01:00
|
|
|
else if (is_option_arg(argv, argc, &i, 'a', NULL, &PROJECT_override))
|
|
|
|
{
|
|
|
|
}
|
2010-02-03 16:48:37 +01:00
|
|
|
else if (is_option(argv[i], '-'))
|
2010-02-01 13:17:38 +01:00
|
|
|
{
|
2010-04-12 14:24:29 +02:00
|
|
|
i++;
|
2010-02-01 13:17:38 +01:00
|
|
|
break;
|
|
|
|
}
|
2010-02-03 16:48:37 +01:00
|
|
|
else
|
2010-02-01 13:17:38 +01:00
|
|
|
{
|
2010-02-03 16:48:37 +01:00
|
|
|
if (file)
|
2012-12-15 03:27:42 +01:00
|
|
|
ERROR_fatal("too many %s.", EXEC_arch ? "executable files" : "project directories");
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2010-02-03 16:48:37 +01:00
|
|
|
file = argv[i];
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2010-02-04 17:00:01 +01:00
|
|
|
if (EXEC_arch)
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
break;
|
|
|
|
}
|
2010-02-01 13:17:38 +01:00
|
|
|
}
|
|
|
|
}
|
2020-05-07 08:17:27 +02:00
|
|
|
|
2010-02-01 13:17:38 +01:00
|
|
|
n = i;
|
2010-02-03 16:48:37 +01:00
|
|
|
if (!file)
|
|
|
|
file = ".";
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-04-12 14:47:31 +02:00
|
|
|
if (EXEC_arch)
|
|
|
|
argv[0] = file;
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2010-02-01 13:17:38 +01:00
|
|
|
for (i = 1; i <= (argc - n); i++)
|
|
|
|
argv[i] = argv[i + n - 1];
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-02-01 13:17:38 +01:00
|
|
|
argc -= n - 1;
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2011-03-03 16:05:54 +01:00
|
|
|
TRY
|
|
|
|
{
|
2012-09-27 22:52:08 +02:00
|
|
|
init(file, argc, argv);
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2010-04-12 14:47:31 +02:00
|
|
|
if (!EXEC_arch)
|
|
|
|
argv[0] = PROJECT_name;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2012-04-30 02:04:51 +02:00
|
|
|
HOOK(main)(&argc, &argv);
|
2011-03-03 16:05:54 +01:00
|
|
|
EXEC_main_hook_done = TRUE;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
/* Startup class */
|
2020-05-07 08:17:27 +02:00
|
|
|
|
2011-03-03 16:05:54 +01:00
|
|
|
CLASS_load(PROJECT_class);
|
2020-05-25 21:24:28 +02:00
|
|
|
startup = (CLASS_DESC_METHOD *)CLASS_get_symbol_desc_kind(PROJECT_class, "main", CD_STATIC_METHOD, 0, T_ANY);
|
|
|
|
if (startup == NULL)
|
|
|
|
THROW(E_MAIN);
|
2011-03-03 16:05:54 +01:00
|
|
|
|
2011-04-04 02:40:32 +02:00
|
|
|
//CAPP_init(); /* needs startup class */
|
2011-03-03 16:05:54 +01:00
|
|
|
CFILE_init_watch();
|
|
|
|
|
|
|
|
PROJECT_argc = argc;
|
|
|
|
PROJECT_argv = argv;
|
|
|
|
}
|
|
|
|
CATCH
|
|
|
|
{
|
2013-05-25 16:00:40 +02:00
|
|
|
ERROR_hook();
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2013-12-18 12:21:01 +01:00
|
|
|
if (EXEC_debug && DEBUG_is_init())
|
2011-03-03 16:05:54 +01:00
|
|
|
{
|
|
|
|
if (!_welcome)
|
|
|
|
DEBUG.Main(TRUE);
|
|
|
|
DEBUG.Main(TRUE);
|
2019-09-17 10:07:59 +02:00
|
|
|
MAIN_exit(FALSE, 0);
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-03-03 16:05:54 +01:00
|
|
|
if (ERROR->info.code && ERROR->info.code != E_ABORT)
|
2019-09-17 10:07:59 +02:00
|
|
|
ERROR_print(FALSE);
|
|
|
|
MAIN_exit(TRUE, 1);
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
2011-03-03 16:05:54 +01:00
|
|
|
}
|
|
|
|
END_TRY
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-03-03 16:05:54 +01:00
|
|
|
TRY
|
|
|
|
{
|
2020-05-07 08:17:27 +02:00
|
|
|
if (PROJECT_run_tests)
|
|
|
|
{
|
2020-05-25 21:24:28 +02:00
|
|
|
GB_Push(1, T_STRING, _tests, -1);
|
|
|
|
EXEC_public_desc(PROJECT_class, NULL, startup, 1);
|
2020-05-07 08:17:27 +02:00
|
|
|
}
|
|
|
|
else
|
2020-05-22 16:02:48 +02:00
|
|
|
{
|
2020-05-07 08:17:27 +02:00
|
|
|
EXEC_public_desc(PROJECT_class, NULL, startup, 0);
|
2020-05-22 16:02:48 +02:00
|
|
|
}
|
2011-07-26 02:28:52 +02:00
|
|
|
|
2020-05-25 21:24:28 +02:00
|
|
|
if (TYPE_is_boolean(startup->type))
|
|
|
|
ret = RP->_boolean.value ? 1 : 0;
|
|
|
|
else if (TYPE_is_integer(startup->type))
|
|
|
|
ret = RP->_integer.value & 0xFF;
|
|
|
|
|
2010-01-01 15:55:13 +01:00
|
|
|
EXEC_release_return_value();
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2010-05-22 20:02:34 +02:00
|
|
|
if (_quit_after_main)
|
|
|
|
{
|
2019-09-17 10:07:59 +02:00
|
|
|
MAIN_exit(TRUE, 0);
|
2010-05-22 20:02:34 +02:00
|
|
|
}
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2011-07-26 02:28:52 +02:00
|
|
|
if (!ret)
|
|
|
|
{
|
2012-05-20 19:58:34 +02:00
|
|
|
DEBUG_enter_event_loop();
|
2011-07-26 02:28:52 +02:00
|
|
|
HOOK_DEFAULT(loop, WATCH_loop)();
|
2012-05-20 19:58:34 +02:00
|
|
|
DEBUG_leave_event_loop();
|
2011-07-26 02:28:52 +02:00
|
|
|
EVENT_check_post();
|
|
|
|
}
|
2011-03-03 16:05:54 +01:00
|
|
|
}
|
|
|
|
CATCH
|
|
|
|
{
|
|
|
|
if (ERROR->info.code && ERROR->info.code != E_ABORT)
|
|
|
|
{
|
2013-05-25 16:00:40 +02:00
|
|
|
ERROR_hook();
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
if (EXEC_debug)
|
|
|
|
{
|
|
|
|
DEBUG.Main(TRUE);
|
2019-09-17 10:07:59 +02:00
|
|
|
MAIN_exit(TRUE, 0);
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-17 10:07:59 +02:00
|
|
|
ERROR_print(FALSE);
|
|
|
|
MAIN_exit(TRUE, 1);
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
2011-03-03 16:05:54 +01:00
|
|
|
}
|
2016-02-01 03:18:49 +01:00
|
|
|
|
2012-10-19 23:00:35 +02:00
|
|
|
ret = EXEC_quit_value;
|
2011-03-03 16:05:54 +01:00
|
|
|
}
|
|
|
|
END_TRY
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-03-03 16:05:54 +01:00
|
|
|
main_exit(FALSE);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2018-01-20 16:43:13 +01:00
|
|
|
if (!EXEC_task)
|
|
|
|
MEMORY_exit();
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-03-03 16:05:54 +01:00
|
|
|
fflush(NULL);
|
2018-01-28 17:57:13 +01:00
|
|
|
|
2012-05-26 00:24:13 +02:00
|
|
|
return ret;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|