[uim-commit] r2250 - branches/r5rs/sigscheme

yamaken at freedesktop.org yamaken at freedesktop.org
Thu Nov 24 20:27:46 PST 2005


Author: yamaken
Date: 2005-11-24 20:27:43 -0800 (Thu, 24 Nov 2005)
New Revision: 2250

Modified:
   branches/r5rs/sigscheme/config.h
   branches/r5rs/sigscheme/encoding.c
   branches/r5rs/sigscheme/encoding.h
   branches/r5rs/sigscheme/error.c
   branches/r5rs/sigscheme/io.c
   branches/r5rs/sigscheme/main.c
   branches/r5rs/sigscheme/mbcport.c
   branches/r5rs/sigscheme/mbcport.h
   branches/r5rs/sigscheme/operations-siod.c
   branches/r5rs/sigscheme/operations-srfi6.c
   branches/r5rs/sigscheme/sbcport.c
   branches/r5rs/sigscheme/sigscheme.c
   branches/r5rs/sigscheme/sigschemeinternal.h
Log:
* This commit enables multibyte character port, SRFI-22, runtime
  encoding specification with optional argument to sscm, and automatic
  encoding switching on file loading using the optional argument
  written in UNIX script prelude of the file

* sigscheme/config.h
  - (SCM_USE_SRFI22): New macro
* sigscheme/sbcport.c
  - (ScmBaseCharPort_construct): Fix wrong vptr initialization
* sigscheme/mbcport.h
  - (ScmMultiByteCharPort_set_codec): New function decl
* sigscheme/mbcport.c
  - (ScmMultiByteCharPort_set_codec): New function
  - (mbcport_fill_rbuf): Fix partial char handling
* sigscheme/encoding.h
  - (SCM_CHARCODEC_ENCODING, SCM_CHARCODEC_SCAN_CHAR,
    SCM_CHARCODEC_STR2INT, SCM_CHARCODEC_INT2STR): Fix operator
    precedence
  - (Scm_mb_find_codec): New function decl
* sigscheme/encoding.c
  - (available_codecs): New static variable
  - (Scm_mb_find_codec): New function
* sigscheme/io.c
  - Include mbcport.c
  - (SCRIPT_PRELUDE_MAXLEN, SCRIPT_PRELUDE_DELIM): New macro
  - (interpret_script_prelude, parse_script_prelude): New static
    function
  - (Scm_NewCharPort): New function
  - (Scm_MakeSharedFilePort, ScmOp_open_input_file,
    ScmOp_open_output_file): Support multibyte char port
  - (SigScm_load_internal): Support SRFI-22, and automatic encoding
    switching using it
* sigscheme/sigscheme.c
  - (scm_initialized): New static variable
  - (SigScm_Initialize_internal):
    * Add initialization for multibyte char port
    * Add scm_initialized handling
  - (SigScm_Finalize): Add scm_initialized handling
  - (Scm_eval_c_string_internal): Support multibyte char port
  - (Scm_InterpretArgv, Scm_FreeArgv): New function
* sigscheme/main.c
  - (main): Replace argv processing with Scm_InterpretArgv()
* sigscheme/operations-srfi6.c
  - (ScmOp_SRFI6_open_input_string, ScmOp_SRFI6_open_output_string):
    Support multibyte char port
* sigscheme/operations-siod.c
  - (SigScm_Initialize_SIOD): Support multibyte char port
* sigscheme/sigschemeinternal.h
  - (SCM_ERR_HEADER): Moved from error.c
  - (Scm_NewCharPort, Scm_InterpretArgv, Scm_FreeArgv): New function
    decl
* sigscheme/error.c
  - (SCM_ERR_HEADER): Move to sigschemeinternal.h


Modified: branches/r5rs/sigscheme/config.h
===================================================================
--- branches/r5rs/sigscheme/config.h	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/config.h	2005-11-25 04:27:43 UTC (rev 2250)
@@ -44,6 +44,7 @@
 #define SCM_USE_SRFI2           1  /* use SRFI-2  'and-let*' */
 #define SCM_USE_SRFI6           1  /* use SRFI-6  basic string ports */
 #define SCM_USE_SRFI8           1  /* use SRFI-8  'receive' */
+#define SCM_USE_SRFI22          1  /* use SRFI-22 running scheme scripts on Unix */
 #define SCM_USE_SRFI23          1  /* use SRFI-23 'error' */
 #define SCM_USE_SRFI34          1  /* use SRFI-34 exception handling for programs */
 #define SCM_USE_SRFI38          1  /* use SRFI-38 'write-with-shared-structure' */

Modified: branches/r5rs/sigscheme/encoding.c
===================================================================
--- branches/r5rs/sigscheme/encoding.c	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/encoding.c	2005-11-25 04:27:43 UTC (rev 2250)
@@ -183,6 +183,26 @@
 };
 #define unibyte_codec (&unibyte_codec_vtbl)
 
+static ScmCharCodec *available_codecs[] = {
+#if SCM_USE_UTF8
+    utf8_codec,
+#endif
+#if SCM_USE_EUCJP
+    eucjp_codec,
+#endif
+#if SCM_USE_EUCCN
+    euccn_codec,
+#endif
+#if SCM_USE_EUCKR
+    euckr_codec,
+#endif
+#if SCM_USE_SJIS
+    sjis_codec,
+#endif
+    unibyte_codec,
+    NULL
+};
+
 /*=======================================
   Global Variables
 =======================================*/
@@ -275,7 +295,19 @@
     return ret;
 }
 
+/* TODO: support encoding name canonicalization */
+ScmCharCodec *Scm_mb_find_codec(const char *encoding)
+{
+    ScmCharCodec **codecp;
 
+    for (codecp = &available_codecs[0]; *codecp; codecp++) {
+        if (strcmp(SCM_CHARCODEC_ENCODING(*codecp), encoding) == 0)
+            return *codecp;
+    }
+
+    return NULL;
+}
+
 /*=======================================
   Encoding-specific functions
 =======================================*/

Modified: branches/r5rs/sigscheme/encoding.h
===================================================================
--- branches/r5rs/sigscheme/encoding.h	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/encoding.h	2005-11-25 04:27:43 UTC (rev 2250)
@@ -90,12 +90,12 @@
                       SCM_MBS_GET_SIZE(mbs) - SCM_MBCINFO_GET_SIZE(inf)),     \
      SCM_MBS_SET_STATE((mbs), SCM_MBCINFO_GET_STATE(inf)))
 
-#define SCM_CHARCODEC_ENCODING(codec)           ((*codec->encoding)())
-#define SCM_CHARCODEC_SCAN_CHAR(codec, mbs)     ((*codec->scan_char)(mbs))
+#define SCM_CHARCODEC_ENCODING(codec)           ((*(codec)->encoding)())
+#define SCM_CHARCODEC_SCAN_CHAR(codec, mbs)     ((*(codec)->scan_char)(mbs))
 #define SCM_CHARCODEC_STR2INT(codec, src, len, state)                        \
-    ((*codec->str2int)((src), (len), (state)))
+    ((*(codec)->str2int)((src), (len), (state)))
 #define SCM_CHARCODEC_INT2STR(codec, dst, ch, state)                         \
-    ((*codec->int2str)((dst), (ch), (state)))
+    ((*(codec)->int2str)((dst), (ch), (state)))
 
 /*=======================================
   Type Definitions
@@ -163,6 +163,7 @@
 int Scm_mb_bare_c_strlen(const char *str);
 ScmMultibyteString Scm_mb_substring(ScmMultibyteString str, int i, int len);
 #define Scm_mb_strref(str, i) (Scm_mb_substring((str), (i), 1))
+ScmCharCodec *Scm_mb_find_codec(const char *encoding);
 
 
 #endif /* __SCM_ENCODING_H */

Modified: branches/r5rs/sigscheme/error.c
===================================================================
--- branches/r5rs/sigscheme/error.c	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/error.c	2005-11-25 04:27:43 UTC (rev 2250)
@@ -52,7 +52,6 @@
 /*=======================================
   File Local Macro Declarations
 =======================================*/
-#define SCM_ERR_HEADER "Error: "
 #define SCM_BACKTRACE_HEADER "**** BACKTRACE ****\n"
 
 #define ERRMSG_UNHANDLED_EXCEPTION "unhandled exception"

Modified: branches/r5rs/sigscheme/io.c
===================================================================
--- branches/r5rs/sigscheme/io.c	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/io.c	2005-11-25 04:27:43 UTC (rev 2250)
@@ -42,7 +42,11 @@
 =======================================*/
 #include "sigscheme.h"
 #include "sigschemeinternal.h"
+#if SCM_USE_MULTIBYTE_CHAR
+#include "mbcport.h"
+#else /* SCM_USE_MULTIBYTE_CHAR */
 #include "sbcport.h"
+#endif /* SCM_USE_MULTIBYTE_CHAR */
 #include "fileport.h"
 
 /*=======================================
@@ -52,6 +56,11 @@
 /*=======================================
   File Local Macro Declarations
 =======================================*/
+#if SCM_USE_SRFI22
+/* SRFI-22: The <script prelude> line may not be longer than 64 characters. */
+#define SCRIPT_PRELUDE_MAXLEN 64
+#define SCRIPT_PRELUDE_DELIM  " \t\n\r"
+#endif
 
 /*=======================================
   Variable Declarations
@@ -97,10 +106,23 @@
 static ScmObj SigScm_load_internal(const char *c_filename);
 static char*  create_valid_path(const char *c_filename);
 static int    file_existsp(const char *filepath);
+#if SCM_USE_SRFI22
+static void interpret_script_prelude(ScmObj port);
+static char **parse_script_prelude(ScmObj port);
+#endif
 
 /*=======================================
   Function Implementations
 =======================================*/
+ScmCharPort *Scm_NewCharPort(ScmBytePort *bport)
+{
+#if  SCM_USE_MULTIBYTE_CHAR
+    return ScmMultiByteCharPort_new(bport, Scm_current_char_codec);
+#else
+    return ScmSingleByteCharPort_new(bport);
+#endif
+}
+
 void SigScm_set_lib_path(const char *path)
 {
     scm_lib_path = path;
@@ -113,7 +135,7 @@
 
     /* GC safe */
     bport = ScmFilePort_new_shared(file, aux_info);
-    return Scm_NewPort(ScmSingleByteCharPort_new(bport), flag);
+    return Scm_NewPort(Scm_NewCharPort(bport), flag);
 }
 
 void SigScm_PortPrintf(ScmObj port, const char *fmt, ...)
@@ -279,7 +301,7 @@
     if (!bport)
         ERR_OBJ("cannot open file ", filepath);
 
-    return Scm_NewPort(ScmSingleByteCharPort_new(bport), SCM_PORTFLAG_INPUT);
+    return Scm_NewPort(Scm_NewCharPort(bport), SCM_PORTFLAG_INPUT);
 }
 
 ScmObj ScmOp_open_output_file(ScmObj filepath)
@@ -293,7 +315,7 @@
     if (!bport)
         ERR_OBJ("cannot open file ", filepath);
 
-    return Scm_NewPort(ScmSingleByteCharPort_new(bport), SCM_PORTFLAG_OUTPUT);
+    return Scm_NewPort(Scm_NewCharPort(bport), SCM_PORTFLAG_OUTPUT);
 }
 
 ScmObj ScmOp_close_input_port(ScmObj port)
@@ -478,6 +500,7 @@
     ScmObj port         = SCM_FALSE;
     ScmObj s_expression = SCM_FALSE;
     ScmObj filepath     = SCM_FALSE;
+    ScmCharCodec *saved_codec;
     char  *c_filepath   = create_valid_path(c_filename);
 
     CDBG((SCM_DBG_FILE, "loading %s", c_filename));
@@ -490,12 +513,19 @@
     filepath = Scm_NewImmutableString(c_filepath);
     port = ScmOp_open_input_file(filepath);
 
+    saved_codec = Scm_current_char_codec;
+#if SCM_USE_SRFI22
+    if (SCM_PORT_PEEK_CHAR(port) == '#')
+        interpret_script_prelude(port);
+#endif
+
     /* read & eval cycle */
     while (s_expression = SigScm_Read(port), !EOFP(s_expression)) {
         EVAL(s_expression, SCM_INTERACTION_ENV);
     }
 
     ScmOp_close_input_port(port);
+    Scm_current_char_codec = saved_codec;
 
     CDBG((SCM_DBG_FILE, "done."));
 
@@ -559,6 +589,71 @@
 #endif
 }
 
+#if SCM_USE_SRFI22
+static void interpret_script_prelude(ScmObj port)
+{
+    char **argv;
+
+    argv = parse_script_prelude(port);
+    Scm_InterpretArgv(argv);
+#if SCM_USE_MULTIBYTE_CHAR
+    if (SCM_CHARPORT_DYNAMIC_CAST(ScmMultiByteCharPort, SCM_PORT_IMPL(port))) {
+        ScmMultiByteCharPort_set_codec(SCM_PORT_IMPL(port),
+                                       Scm_current_char_codec);
+    }
+#endif
+    Scm_FreeArgv(argv);
+}
+
+static char **parse_script_prelude(ScmObj port)
+{
+    int argc, c, len;
+    char **argv, *arg, *p, line[SCRIPT_PRELUDE_MAXLEN];
+    DECLARE_INTERNAL_FUNCTION("parse_script_prelude");
+
+    for (p = line; p < &line[SCRIPT_PRELUDE_MAXLEN]; p++) {
+        c = SCM_PORT_GET_CHAR(port);
+        if (!isascii(c))
+            ERR("non-ASCII char appeared in UNIX script prelude");
+        if (c == SCM_NEWLINE_STR[0]) {
+            *p = '\0';
+            break;
+        }
+        *p = c;
+    }
+    if (*p)
+        ERR("too long UNIX script prelude (max 64)");
+
+    if (line[0] != '#' || line[1] != '!') {
+        ERR("Invalid UNIX script prelude");
+    }
+#if 1
+    /* strict check */
+    if (line[2] != ' ') {
+        ERR("Invalid UNIX script prelude: "
+            "SRFI-22 requires a space after hash-bang sequence");
+    }
+#endif
+
+    argv = malloc(sizeof(char *));
+    argc = 0;
+    for (p = &line[3]; p < &line[SCRIPT_PRELUDE_MAXLEN]; p += len + 1) {
+        p += strspn(p, SCRIPT_PRELUDE_DELIM);
+        len = strcspn(p, SCRIPT_PRELUDE_DELIM);
+        if (len) {
+            p[len] = '\0';
+            arg = strdup(p);
+            argv[argc] = arg;
+            argv = realloc(argv, sizeof(char *) * (++argc + 1));
+            argv[argc] = NULL;
+        }
+    }         
+    argv[argc] = NULL;
+
+    return argv;
+}
+#endif
+
 /* FIXME: link conditionally with autoconf */
 #include "sbcport.c"
 #if SCM_USE_MULTIBYTE_CHAR

Modified: branches/r5rs/sigscheme/main.c
===================================================================
--- branches/r5rs/sigscheme/main.c	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/main.c	2005-11-25 04:27:43 UTC (rev 2250)
@@ -146,8 +146,13 @@
 
 int main(int argc, char **argv)
 {
-    char *filename = argv[1];
+    const char *filename = NULL;
+    char **rest_argv;
 
+    /* must be done before SigScm_Initialize() */
+    rest_argv = Scm_InterpretArgv(argv);
+    filename = rest_argv[0];
+
     SigScm_Initialize();
 
 #if SCM_USE_SRFI34
@@ -157,15 +162,15 @@
     SigScm_GC_Protect(&feature_id_siod);
     feature_id_siod = Scm_NewImmutableStringCopying(FEATURE_ID_SIOD);
 
-    if (argc < 2) {
+    if (filename) {
+        SigScm_load(filename);
+    } else {
 #if SCM_GCC4_READY_GC
         SCM_GC_PROTECTED_CALL_VOID(repl, ());
 #else
         repl();
 #endif
         /*        SigScm_Error("usage : sscm <filename>"); */
-    } else {
-        SigScm_load(filename);
     }
 
     SigScm_Finalize();

Modified: branches/r5rs/sigscheme/mbcport.c
===================================================================
--- branches/r5rs/sigscheme/mbcport.c	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/mbcport.c	2005-11-25 04:27:43 UTC (rev 2250)
@@ -145,6 +145,19 @@
     return (ScmCharPort *)cport;
 }
 
+void
+ScmMultiByteCharPort_set_codec(ScmCharPort *cport, ScmCharCodec *codec)
+{
+    ScmMultiByteCharPort *mbcport;
+
+    mbcport = SCM_BYTEPORT_DYNAMIC_CAST(ScmMultiByteCharPort, cport);
+    mbcport->codec = codec;
+    SCM_MBCPORT_CLEAR_STATE(mbcport);
+    /* only one byte can be preserved for new codec. otherwise cleared */
+    if (1 < strlen(mbcport->rbuf))
+        mbcport->rbuf[0] = '\0';
+}
+
 static ScmCharPort *
 mbcport_dyn_cast(ScmCharPort *cport, const ScmCharPortVTbl *dst_vptr)
 {
@@ -245,7 +258,7 @@
         
         if (SCM_MBCINFO_ERRORP(mbc))
             SCM_CHARPORT_ERROR(port, "ScmMultibyteCharPort: broken character");
-        if (!SCM_MBCINFO_INCOMPLETEP(mbc))
+        if (!SCM_MBCINFO_INCOMPLETEP(mbc) && SCM_MBCINFO_GET_SIZE(mbc))
             break;
         if (SCM_MBS_GET_SIZE(mbs) == SCM_MB_MAX_LEN)
             SCM_CHARPORT_ERROR(port, "ScmMultibyteCharPort: broken scanner");

Modified: branches/r5rs/sigscheme/mbcport.h
===================================================================
--- branches/r5rs/sigscheme/mbcport.h	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/mbcport.h	2005-11-25 04:27:43 UTC (rev 2250)
@@ -78,5 +78,6 @@
                                     ScmBytePort *bport, ScmCharCodec *codec);
 ScmCharPort *ScmMultiByteCharPort_new(ScmBytePort *bport, ScmCharCodec *codec);
 
+void ScmMultiByteCharPort_set_codec(ScmCharPort *cport, ScmCharCodec *codec);
 
 #endif /* __SCM_MBCPORT_H */

Modified: branches/r5rs/sigscheme/operations-siod.c
===================================================================
--- branches/r5rs/sigscheme/operations-siod.c	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/operations-siod.c	2005-11-25 04:27:43 UTC (rev 2250)
@@ -36,7 +36,6 @@
 =======================================*/
 #include "sigscheme.h"
 #include "sigschemeinternal.h"
-#include "sbcport.h"
 #include "nullport.h"
 
 /*=======================================
@@ -117,7 +116,7 @@
     SigScm_GC_Protect(&saved_error_port);
 
     Scm_nullport_init();
-    null_port = Scm_NewPort(ScmSingleByteCharPort_new(ScmNullPort_new()),
+    null_port = Scm_NewPort(Scm_NewCharPort(ScmNullPort_new()),
                             SCM_PORTFLAG_INPUT | SCM_PORTFLAG_OUTPUT);
 
     SigScm_SetVerboseLevel(2);

Modified: branches/r5rs/sigscheme/operations-srfi6.c
===================================================================
--- branches/r5rs/sigscheme/operations-srfi6.c	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/operations-srfi6.c	2005-11-25 04:27:43 UTC (rev 2250)
@@ -92,7 +92,7 @@
     hold_str = (ScmObj *)ScmInputStrPort_ref_opaque(bport);
     *hold_str = str;
     SigScm_GC_Protect(hold_str);
-    return Scm_NewPort(ScmSingleByteCharPort_new(bport), SCM_PORTFLAG_INPUT);
+    return Scm_NewPort(Scm_NewCharPort(bport), SCM_PORTFLAG_INPUT);
 }
 
 ScmObj ScmOp_SRFI6_open_output_string(void)
@@ -101,7 +101,7 @@
     DECLARE_FUNCTION("open-output-string", ProcedureFixed0);
 
     bport = ScmOutputStrPort_new(NULL);
-    return Scm_NewPort(ScmSingleByteCharPort_new(bport), SCM_PORTFLAG_OUTPUT);
+    return Scm_NewPort(Scm_NewCharPort(bport), SCM_PORTFLAG_OUTPUT);
 }
 
 ScmObj ScmOp_SRFI6_get_output_string(ScmObj port)

Modified: branches/r5rs/sigscheme/sbcport.c
===================================================================
--- branches/r5rs/sigscheme/sbcport.c	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/sbcport.c	2005-11-25 04:27:43 UTC (rev 2250)
@@ -114,7 +114,7 @@
 ScmBaseCharPort_construct(ScmBaseCharPort *port, const ScmCharPortVTbl *vptr,
                           ScmBytePort *bport)
 {
-    port->vptr = ScmSingleByteCharPort_vptr;
+    port->vptr = vptr;
     port->bport = bport;
 #if SCM_DEBUG
     port->linenum = 1;

Modified: branches/r5rs/sigscheme/sigscheme.c
===================================================================
--- branches/r5rs/sigscheme/sigscheme.c	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/sigscheme.c	2005-11-25 04:27:43 UTC (rev 2250)
@@ -34,6 +34,8 @@
 /*=======================================
   System Include
 =======================================*/
+#include <stdlib.h>
+#include <stdio.h>
 
 /*=======================================
   Local Include
@@ -41,9 +43,13 @@
 #include "sigscheme.h"
 #include "sigschemeinternal.h"
 #include "baseport.h"
-#include "sbcport.h"
 #include "fileport.h"
 #include "strport.h"
+#if SCM_USE_MULTIBYTE_CHAR
+#include "mbcport.h"
+#else /* SCM_USE_MULTIBYTE_CHAR */
+#include "sbcport.h"
+#endif /* SCM_USE_MULTIBYTE_CHAR */
 
 /*=======================================
   File Local Struct Declarations
@@ -64,6 +70,8 @@
 ScmObj Scm_sym_unquote, Scm_sym_unquote_splicing;
 ScmObj Scm_sym_else, Scm_sym_yields;
 
+static int scm_initialized;
+
 #if SCM_COMPAT_SIOD
 static ScmObj scm_return_value    = NULL;
 #endif
@@ -161,7 +169,11 @@
       Preallocated Ports
     =======================================================================*/
     Scm_fileport_init();
+#if SCM_USE_MULTIBYTE_CHAR
+    Scm_mbcport_init();
+#else
     Scm_sbcport_init();
+#endif
 
     scm_current_input_port  = Scm_MakeSharedFilePort(stdin, "stdin",
                                                      SCM_PORTFLAG_INPUT);
@@ -196,11 +208,13 @@
     =======================================================================*/
     /* to evaluate SigScheme-dependent codes conditionally */
     ScmOp_provide(Scm_NewImmutableStringCopying("sigscheme"));
+    scm_initialized = TRUE;
 }
 
 void SigScm_Finalize()
 {
     SigScm_FinalizeStorage();
+    scm_initialized = FALSE;
 }
 
 void Scm_DefineAlias(const char *newsym, const char *sym)
@@ -279,11 +293,9 @@
     ScmObj str_port    = SCM_FALSE;
     ScmObj ret         = SCM_FALSE;
     ScmBytePort *bport;
-    ScmCharPort *cport;
 
     bport = ScmInputStrPort_new_const(exp, NULL);
-    cport = ScmSingleByteCharPort_new(bport);
-    str_port = Scm_NewPort(cport, SCM_PORTFLAG_INPUT);
+    str_port = Scm_NewPort(Scm_NewCharPort(bport), SCM_PORTFLAG_INPUT);
 
     ret = SigScm_Read(str_port);
     ret = EVAL(ret, SCM_INTERACTION_ENV);
@@ -302,6 +314,69 @@
 }
 #endif
 
+/* TODO: parse properly */
+/* don't access ScmObj if (!scm_initialized) */
+char **Scm_InterpretArgv(char **argv)
+{
+    char **argp, **rest;
+    const char *encoding;
+    ScmCharCodec *specified_codec;
+    ScmObj err_obj; /* dont' initialize */
+    DECLARE_INTERNAL_FUNCTION("Scm_InterpretArgv");
+
+    encoding = NULL;
+    argp = (strcmp(argv[0], "/usr/bin/env") == 0) ? &argv[2] : &argv[1];
+
+    for (; *argp; argp++) {
+        /* script name appeared */
+        if (*argp[0] != '-')
+            break;
+
+        /* character encoding */
+        if (strcmp(*argp, "-C") == 0) {
+            encoding = *++argp;
+            if (!*argp) {
+                if (scm_initialized) {
+                    ERR("no encoding name specified");
+                } else {
+                    fprintf(stderr, "%sno encoding name specified\n",
+                            SCM_ERR_HEADER);
+                    exit(EXIT_FAILURE);
+                }
+            }
+        }
+    }
+    rest = argp;
+
+    if (encoding) {
+        specified_codec = Scm_mb_find_codec(encoding);
+        if (!specified_codec) {
+            if (scm_initialized) {
+                err_obj = Scm_NewImmutableStringCopying(encoding);
+                Scm_FreeArgv(argv);
+                ERR_OBJ("unsupported encoding", err_obj);
+            } else {
+                fprintf(stderr, "%sunsupported encoding: %s\n",
+                        SCM_ERR_HEADER, encoding);
+                exit(EXIT_FAILURE);
+            }
+        }
+        Scm_current_char_codec = specified_codec;
+    }
+
+    return rest;
+}
+
+void Scm_FreeArgv(char **argv)
+{
+    char **argp;
+
+    for (argp = &argv[0]; *argp; argp++) {
+        free(*argp);
+    }
+    free(argv);
+}
+
 /*===========================================================================
   Scheme Function Export Related Functions
 ===========================================================================*/

Modified: branches/r5rs/sigscheme/sigschemeinternal.h
===================================================================
--- branches/r5rs/sigscheme/sigschemeinternal.h	2005-11-24 21:31:42 UTC (rev 2249)
+++ branches/r5rs/sigscheme/sigschemeinternal.h	2005-11-25 04:27:43 UTC (rev 2250)
@@ -306,6 +306,8 @@
 /* Symbol Name Hash Size */
 #define NAMEHASH_SIZE 1024
 
+#define SCM_ERR_HEADER "Error: "
+
 /*=======================================
    String Mutation Assertion
 =======================================*/
@@ -381,4 +383,11 @@
 /* operations.c */
 int ScmOp_c_length(ScmObj lst);
 
+/* io.c */
+ScmCharPort *Scm_NewCharPort(ScmBytePort *bport);
+
+/* sigscheme.c */
+char **Scm_InterpretArgv(char **argv);
+void Scm_FreeArgv(char **argv);
+
 #endif /* __SIGSCHEMEINTERNAL_H */



More information about the uim-commit mailing list