Reading Gauche/Reading Gauche 0.9/main.c/main


Top / Reading Gauche / Reading Gauche 0.9 / main.c / main

main

概要

Gauche 0.9のmain関数。

ソースコード

/*-----------------------------------------------------------------
 * MAIN
 */
int main(int argc, char **argv)
{
    int argind;
    ScmObj cp;
    const char *scriptfile = NULL;
    ScmObj av = SCM_NIL;
    int exit_code = 0;
    ScmEvalPacket epak;
    ScmLoadPacket lpak;

#if defined(GAUCHE_WINDOWS)
    /* This saves so much trouble. */
    _setmode(_fileno(stdin),  _O_BINARY);
    _setmode(_fileno(stdout), _O_BINARY);
    _setmode(_fileno(stderr), _O_BINARY);
#endif /*GAUCHE_WINDOWS*/

    GC_INIT();
    Scm_Init(GAUCHE_SIGNATURE);
    sig_setup();

    argind = parse_options(argc, argv);

    /* If -ftest option is given and we seem to be in the source
       tree, adds build directories to the library path _before_
       loading init file.   This is to help development of Gauche
       itself; normal user should never need this. */
    if (test_mode) {
        /* The order of directories is important.  'lib' should
           be searched first (hence it should come latter), since some
           extension modules are built from the file in src then linked
           from lib, and we want to test the one in lib. */
        if (access("../src/stdlib.stub", R_OK) == 0
            && access("../libsrc/srfi-1.scm", R_OK) == 0
            && access("../lib/srfi-0.scm", R_OK) == 0) {
            Scm_AddLoadPath("../src", FALSE);
            Scm_AddLoadPath("../libsrc", FALSE);
            Scm_AddLoadPath("../lib", FALSE);
        } else if (access("../../src/stdlib.stub", R_OK) == 0
                   && access("../../libsrc/srfi-1.scm", R_OK) == 0
                   && access("../../lib/srfi-0.scm", R_OK) == 0) {
            Scm_AddLoadPath("../../src", FALSE);
            Scm_AddLoadPath("../../libsrc", FALSE);
            Scm_AddLoadPath("../../lib", FALSE);
        }
    }

    /* load init file */
    if (load_initfile) load_gauche_init();

    /* prepare *program-name* and *argv* */
    if (optind < argc) {
        /* We have a script file specified. */
        ScmObj at = SCM_NIL;
        int ac;
        struct stat statbuf;

        /* if the script name is given in relative pathname, see if
           it exists from the current directory.  if not, leave it
           to load() to search in the load paths */
        if (argv[optind][0] == '\0') Scm_Error("bad script name");
        if (argv[optind][0] == '/') {
            scriptfile = argv[optind];
#if defined(__CYGWIN__) || defined(GAUCHE_WINDOWS)
	} else if (isalpha(argv[optind][0]) && argv[optind][1] == ':') {
	    /* support of wicked legacy DOS drive letter */
	    scriptfile = argv[optind];
#endif /* __CYGWIN__ || GAUCHE_WINDOWS */
        } else {
            if (stat(argv[optind], &statbuf) == 0) {
                ScmDString ds;
                Scm_DStringInit(&ds);
                Scm_DStringPutz(&ds, "./", -1);
                Scm_DStringPutz(&ds, argv[optind], -1);
                scriptfile = Scm_DStringGetz(&ds);
            } else {
                scriptfile = argv[optind];
            }
        }

        /* sets up arguments. */
       for (ac = optind; ac < argc; ac++) {
            SCM_APPEND1(av, at, SCM_MAKE_STR_IMMUTABLE(argv[ac]));
        }
    } else {
        av = SCM_LIST1(SCM_MAKE_STR_IMMUTABLE(argv[0]));
    }
    SCM_DEFINE(Scm_UserModule(), "*argv*", SCM_CDR(av));
    SCM_DEFINE(Scm_UserModule(), "*program-name*", SCM_CAR(av));

    /* process pre-commands */
    SCM_FOR_EACH(cp, Scm_Reverse(pre_cmds)) {
        ScmObj p = SCM_CAR(cp);
        ScmObj v = SCM_CDR(p);
        
        switch (SCM_CHAR_VALUE(SCM_CAR(p))) {
        case 'I':
            Scm_AddLoadPath(Scm_GetStringConst(SCM_STRING(v)), FALSE);
            break;
        case 'A':
            Scm_AddLoadPath(Scm_GetStringConst(SCM_STRING(v)), TRUE);
            break;
        case 'l':
            if (Scm_Load(Scm_GetStringConst(SCM_STRING(v)), 0, &lpak) < 0)
                error_exit(lpak.exception);
            break;
        case 'L':
            if (Scm_Load(Scm_GetStringConst(SCM_STRING(v)), SCM_LOAD_QUIET_NOFILE, &lpak) < 0)
                error_exit(lpak.exception);
            break;
        case 'u':
            if (Scm_Require(Scm_StringJoin(Scm_StringSplitByChar(SCM_STRING(v), '.'),
                                           SCM_STRING(SCM_MAKE_STR("/")),
                                           SCM_STRING_JOIN_INFIX),
                            0, &lpak) < 0) {
                error_exit(lpak.exception);
            }
            Scm_ImportModule(SCM_CURRENT_MODULE(),  Scm_Intern(SCM_STRING(v)), SCM_FALSE, 0);
            break;
        case 'e':
            if (Scm_EvalCString(Scm_GetStringConst(SCM_STRING(v)),
                                SCM_OBJ(Scm_UserModule()),
                                &epak) < 0) {
                error_exit(epak.exception);
            }
            break;
        case 'E':
            v = Scm_StringAppend(SCM_LIST3(SCM_MAKE_STR("("),
                                           v,
                                           SCM_MAKE_STR(")")));

            if (Scm_EvalCString(Scm_GetStringConst(SCM_STRING(v)),
                                SCM_OBJ(Scm_UserModule()),
                                &epak) < 0) {
                error_exit(epak.exception);
            }   
            break;
        }
    }

    /* Set up instruments. */
    if (profiling_mode) {
        if (Scm_Require(SCM_MAKE_STR("gauche/vm/profiler"), 0, &lpak) < 0) {
            error_exit(lpak.exception);
        }
        Scm_ProfilerStart();
    }
    Scm_AddCleanupHandler(cleanup_main, NULL);

    /* Following is the main dish. */

    if (scriptfile != NULL) {
        /* If script file is specified, load it. */
        ScmObj mainproc;
        ScmEvalPacket epak;

        if (Scm_Load(scriptfile, 0, &lpak) < 0) {
            error_exit(lpak.exception);
        }

        /* if symbol 'main is bound to a procedure in the user module,
           call it.  (SRFI-22) */
        mainproc = Scm_SymbolValue(Scm_UserModule(),
                                   SCM_SYMBOL(SCM_INTERN("main")));
        if (SCM_PROCEDUREP(mainproc)) {
#if 0 /* Temporarily turned off due to the bug that loses stack traces. */
            int r = Scm_Apply(mainproc, SCM_LIST1(av), &epak);
            if (r > 0) {
                ScmObj res = epak.results[0];
                if (SCM_INTP(res)) exit_code = SCM_INT_VALUE(res);
                else exit_code = 70;  /* EX_SOFTWARE, see SRFI-22. */
            } else {
                Scm_ReportError(epak.exception);
                exit_code = 70;  /* EX_SOFTWARE, see SRFI-22. */
            }
#else
            ScmObj r = Scm_ApplyRec(mainproc, SCM_LIST1(av));
            if (SCM_INTP(r)) {
                exit_code = SCM_INT_VALUE(r);
            } else {
                exit_code = 70;
            }
#endif
        }
    } else {
        /* We're in interactive mode. (use gauche.interactive) */
        if (load_initfile) {
            if (Scm_Require(SCM_MAKE_STR("gauche/interactive"), 0, &lpak) < 0) {
                Scm_Warn("couldn't load gauche.interactive\n");
            } else {
                Scm_ImportModule(SCM_CURRENT_MODULE(),
                                 SCM_INTERN("gauche.interactive"),
                                 SCM_FALSE, 0);
            }
        }

        if (batch_mode || (!isatty(0) && !interactive_mode)) {
            Scm_LoadFromPort(SCM_PORT(Scm_Stdin()), SCM_LOAD_PROPAGATE_ERROR,
                            NULL);
        } else {
            Scm_Repl(SCM_FALSE, SCM_FALSE, SCM_FALSE, SCM_FALSE);
        }
    }

    /* All is done. */
    Scm_Exit(exit_code);
    return 0;
}

調べる項目

ScmObj
SCM_NIL
ScmEvalPacket
ScmLoadPacket

参照元

コメント

コメントはありません。 コメント/Reading Gauche/Reading Gauche 0.9/main.c/main?

お名前:

MENU

now: 5

リンク


最新の20件
2020-05-27 2020-05-22 2020-05-14 2020-05-12 2020-05-10 2020-04-27 2020-03-23
最新の20件
2010-02-01 2010-01-31 2010-01-30 2010-01-29 2010-01-16

Counter: 1649, today: 1, yesterday: 1

リロード   新規 編集 凍結 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS

Last-modified: 2009-12-23 (水) 23:44:14 (3810d);  Modified by mona
PukiWiki 1.4.6 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-ji
Powered by PHP 5.2.17
HTML convert time to 0.024 sec.