~ubuntu-branches/ubuntu/hardy/uim/hardy

« back to all changes in this revision

Viewing changes to sigscheme/src/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2007-04-21 03:46:09 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20070421034609-gpcurkutp8vaysqj
Tags: 1:1.4.1-3
* Switch to dh_gtkmodules for the gtk 2.10 transition (Closes:
  #419318)
  - debian/control: Add ${misc:Depends} and remove libgtk2.0-bin on
    uim-gtk2.0.
  - debian/uim-gtk2.0.post{inst,rm}: Removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*===========================================================================
 
2
 *  Filename : main.c
 
3
 *  About    : main function
 
4
 *
 
5
 *  Copyright (C) 2005      Kazuki Ohta <mover AT hct.zaq.ne.jp>
 
6
 *  Copyright (C) 2005      Jun Inoue <jun.lambda AT gmail.com>
 
7
 *  Copyright (C) 2005-2006 YAMAMOTO Kengo <yamaken AT bp.iij4u.or.jp>
 
8
 *  Copyright (c) 2007 SigScheme Project <uim AT freedesktop.org>
 
9
 *
 
10
 *  All rights reserved.
 
11
 *
 
12
 *  Redistribution and use in source and binary forms, with or without
 
13
 *  modification, are permitted provided that the following conditions
 
14
 *  are met:
 
15
 *
 
16
 *  1. Redistributions of source code must retain the above copyright
 
17
 *     notice, this list of conditions and the following disclaimer.
 
18
 *  2. Redistributions in binary form must reproduce the above copyright
 
19
 *     notice, this list of conditions and the following disclaimer in the
 
20
 *     documentation and/or other materials provided with the distribution.
 
21
 *  3. Neither the name of authors nor the names of its contributors
 
22
 *     may be used to endorse or promote products derived from this software
 
23
 *     without specific prior written permission.
 
24
 *
 
25
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
 
26
 *  IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
27
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
28
 *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
 
29
 *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
30
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
31
 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
32
 *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
33
 *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
34
 *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
35
 *  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
36
===========================================================================*/
 
37
 
 
38
#include <config.h>
 
39
 
 
40
#if BREW_MAJ_VER  /* FIXME: inappropriate detection method */
 
41
#include "sigscheme-combined.c"
 
42
#endif
 
43
 
 
44
#include <stdlib.h>
 
45
 
 
46
#include <unistd.h>
 
47
#include <sys/param.h>
 
48
 
 
49
#if BREW_MAJ_VER  /* FIXME: inappropriate detection method */
 
50
#include "AEEAppGen.h"
 
51
#include "AEEStdLib.h"
 
52
#endif
 
53
 
 
54
#include "sigscheme.h"
 
55
#include "sigschemeinternal.h"
 
56
#include "scmport-config.h"
 
57
#include "scmport.h"
 
58
 
 
59
/*=======================================
 
60
  File Local Macro Definitions
 
61
=======================================*/
 
62
#define PROMPT_STR "sscm> "
 
63
 
 
64
#if SCM_COMPAT_SIOD
 
65
#define FEATURE_ID_SIOD "siod"
 
66
#endif
 
67
 
 
68
/*=======================================
 
69
  File Local Type Definitions
 
70
=======================================*/
 
71
struct g_sscm {
 
72
#if SCM_COMPAT_SIOD
 
73
    ScmObj feature_id_siod;
 
74
#endif
 
75
    char lib_path[MAXPATHLEN + sizeof("")];
 
76
};
 
77
 
 
78
#if BREW_MAJ_VER  /* FIXME: inappropriate detection method */
 
79
/* experimental, broken and existing for technical example */
 
80
 
 
81
#define SCM_BREW_USER_APPLET_T CSSCMApplet
 
82
typedef struct _CSSCMApplet CSSCMApplet;
 
83
struct _CSSCMApplet {
 
84
    AEEApplet a;
 
85
    struct scm_g_aggregated m_scm_g_aggregated_instance;
 
86
 
 
87
    struct g_sscm m_sscm;
 
88
};
 
89
 
 
90
#define sscm (((CSSCMApplet *)GETAPPINSTANCE())->m_sscm)
 
91
#endif /* BREW_MAJ_VER */
 
92
 
 
93
/*=======================================
 
94
  Variable Definitions
 
95
=======================================*/
 
96
/* Don't use any global variable other than the 'sscm' */
 
97
#if !BREW_MAJ_VER  /* FIXME: inappropriate detection method */
 
98
static struct g_sscm sscm;
 
99
#endif /* !BREW_MAJ_VER */
 
100
 
 
101
/*=======================================
 
102
  File Local Function Declarations
 
103
=======================================*/
 
104
static void *repl(void *dummy);
 
105
static void repl_loop(void);
 
106
static scm_bool show_promptp(void);
 
107
 
 
108
/*=======================================
 
109
  Function Definitions
 
110
=======================================*/
 
111
static void *
 
112
repl(void *dummy)
 
113
{
 
114
    repl_loop();
 
115
    return NULL;
 
116
}
 
117
 
 
118
static void
 
119
repl_loop(void)
 
120
{
 
121
    ScmObj sexp, result;
 
122
#if SCM_USE_SRFI34
 
123
    ScmEvalState eval_state;
 
124
    ScmBaseCharPort *cport;
 
125
    ScmBytePort *bport;
 
126
    ScmObj sym_guard, cond_catch, proc_read, proc_eval, err;
 
127
 
 
128
    proc_read = scm_symbol_value(scm_intern("read"), SCM_INTERACTION_ENV);
 
129
    proc_eval = scm_symbol_value(scm_intern("eval"), SCM_INTERACTION_ENV);
 
130
    err = CONS(SCM_UNDEF, SCM_UNDEF); /* unique ID */
 
131
 
 
132
    /* prepare the constant part of the form to get the loop fast */
 
133
    sym_guard = scm_intern("guard");
 
134
    cond_catch = LIST_2(scm_intern("err"),
 
135
                        LIST_3(scm_intern("else"),
 
136
                               LIST_2(scm_intern("%%inspect-error"),
 
137
                                      scm_intern("err")),
 
138
                               LIST_2(SCM_SYM_QUOTE, err)));
 
139
#endif /* SCM_USE_SRFI34 */
 
140
 
 
141
    for (;;) {
 
142
        if (show_promptp())
 
143
            scm_port_puts(scm_out, PROMPT_STR);
 
144
 
 
145
#if SCM_USE_SRFI34
 
146
        /* error-proof read */
 
147
        SCM_EVAL_STATE_INIT1(eval_state, SCM_INTERACTION_ENV);
 
148
        sexp = scm_s_srfi34_guard(cond_catch,
 
149
                                  LIST_1(LIST_2(proc_read, scm_in)),
 
150
                                  &eval_state);
 
151
        sexp = SCM_FINISH_TAILREC_CALL(sexp, &eval_state);
 
152
        if (EOFP(sexp))
 
153
            break;
 
154
 
 
155
        /* parse error */
 
156
        if (EQ(sexp, err)) {
 
157
            cport = SCM_CHARPORT_DYNAMIC_CAST(ScmBaseCharPort,
 
158
                                              SCM_PORT_IMPL(scm_in));
 
159
            if (cport) {
 
160
                bport = cport->bport;
 
161
                /* discard all available input */
 
162
                while (SCM_BYTEPORT_BYTE_READYP(bport))
 
163
                    SCM_BYTEPORT_GET_BYTE(bport);
 
164
                continue;
 
165
            }
 
166
            PLAIN_ERR("unrecoverable parse error");
 
167
        }
 
168
 
 
169
        /*
 
170
         * Error-proof evaluation
 
171
         *
 
172
         * (guard (err
 
173
         *         (else
 
174
         *          (%%inspect-error err)
 
175
         *          #<err>))
 
176
         *   (eval (quote sexp) (interaction-environment)))
 
177
         *
 
178
         * To allow redefinition of 'guard' and '%%inspect-err', surely access
 
179
         * them via symbol instead of prepared syntax or procedure object.
 
180
         */
 
181
        SCM_EVAL_STATE_INIT1(eval_state, SCM_INTERACTION_ENV);
 
182
        result = scm_s_srfi34_guard(cond_catch,
 
183
                                    LIST_1(LIST_3(proc_eval,
 
184
                                                  LIST_2(SYM_QUOTE, sexp),
 
185
                                                  SCM_INTERACTION_ENV)),
 
186
                                    &eval_state);
 
187
        result = SCM_FINISH_TAILREC_CALL(result, &eval_state);
 
188
 
 
189
        if (!EQ(result, err)) {
 
190
            SCM_WRITE_SS(scm_out, result);
 
191
            scm_port_newline(scm_out);
 
192
        }
 
193
#else /* SCM_USE_SRFI34 */
 
194
        sexp = scm_read(scm_in);
 
195
        if (EOFP(sexp))
 
196
            break;
 
197
 
 
198
        result = EVAL(sexp, SCM_INTERACTION_ENV);
 
199
        SCM_WRITE_SS(scm_out, result);
 
200
        scm_port_newline(scm_out);
 
201
#endif /* SCM_USE_SRFI34 */
 
202
    }
 
203
}
 
204
 
 
205
static scm_bool
 
206
show_promptp(void)
 
207
{
 
208
#if SCM_COMPAT_SIOD
 
209
    return (FALSEP(scm_p_providedp(sscm.feature_id_siod))
 
210
            || scm_get_verbose_level() >= 2);
 
211
#else
 
212
    return scm_true;
 
213
#endif
 
214
}
 
215
 
 
216
int
 
217
main(int argc, char **argv)
 
218
{
 
219
    const char *filename;
 
220
    char **rest_argv;
 
221
 
 
222
    /* must be done before scm_initialize() */
 
223
    rest_argv = scm_interpret_argv(argv);
 
224
    filename = rest_argv[0];
 
225
 
 
226
    scm_initialize(NULL);
 
227
 
 
228
    /* Explicitly allow current directory-relative path. The sscm command is
 
229
     * supposed to neither setuid'ed nor setgid'ed. So the privilege escalation
 
230
     * problem for C plugins shall not occur. -- YamaKen 2006-03-25 */
 
231
    /*
 
232
     * FIXME:
 
233
     * - add multiple path capability to libsscm
 
234
     * - add library path specifying way for users
 
235
     * - support non-UNIX platforms
 
236
     */
 
237
    if (!getcwd(sscm.lib_path, MAXPATHLEN + sizeof("")))
 
238
        return EXIT_FAILURE;
 
239
    scm_set_lib_path(sscm.lib_path);
 
240
 
 
241
#if SCM_USE_SRFI34
 
242
    scm_use("srfi-34");
 
243
#endif
 
244
 
 
245
#if SCM_COMPAT_SIOD
 
246
    scm_gc_protect_with_init(&sscm.feature_id_siod,
 
247
                             CONST_STRING(FEATURE_ID_SIOD));
 
248
#endif
 
249
 
 
250
    if (filename) {
 
251
        scm_load(filename);
 
252
    } else {
 
253
        scm_call_with_gc_ready_stack(repl, NULL);
 
254
        /* ERR("usage: sscm <filename>"); */
 
255
    }
 
256
 
 
257
    scm_finalize();
 
258
    return EXIT_SUCCESS;
 
259
}