summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/Setup.nt19
-rw-r--r--ext/Win32API/Win32API.c42
-rw-r--r--ext/Win32API/depend1
-rw-r--r--ext/curses/MANIFEST1
-rw-r--r--ext/curses/curses.c40
-rw-r--r--ext/curses/depend1
-rw-r--r--ext/dbm/extconf.rb7
-rw-r--r--ext/extmk.rb.in2
-rw-r--r--ext/kconv/kconv.c2017
-rw-r--r--ext/nkf/depend2
-rw-r--r--ext/nkf/nkf.c26
-rw-r--r--ext/pty/MANIFEST1
-rw-r--r--ext/pty/depend1
-rw-r--r--ext/pty/pty.c2
-rw-r--r--ext/readline/MANIFEST1
-rw-r--r--ext/readline/depend1
-rw-r--r--ext/sdbm/MANIFEST1
-rw-r--r--ext/sdbm/depend2
-rw-r--r--ext/socket/extconf.rb31
-rw-r--r--ext/socket/getaddrinfo.c17
-rw-r--r--ext/socket/getnameinfo.c11
-rw-r--r--ext/socket/socket.c52
-rw-r--r--ext/tcltklib/extconf.rb2
-rw-r--r--ext/tk/lib/tk.rb340
-rw-r--r--ext/tk/lib/tkcanvas.rb31
-rw-r--r--ext/tk/lib/tkentry.rb10
-rw-r--r--ext/tk/lib/tkfont.rb15
-rw-r--r--ext/tk/lib/tktext.rb65
28 files changed, 2451 insertions, 290 deletions
diff --git a/ext/Setup.nt b/ext/Setup.nt
deleted file mode 100644
index cd7969bb73..0000000000
--- a/ext/Setup.nt
+++ /dev/null
@@ -1,19 +0,0 @@
-#option nodynamic
-
-#GD
-Win32API
-#curses
-#dbm
-#etc
-fcntl
-#gdbm
-#gtk
-marshal
-md5
-nkf
-#pty
-#readline
-sdbm
-socket
-#tcltklib
-#tk
diff --git a/ext/Win32API/Win32API.c b/ext/Win32API/Win32API.c
index 9f75653132..433d13abeb 100644
--- a/ext/Win32API/Win32API.c
+++ b/ext/Win32API/Win32API.c
@@ -52,13 +52,10 @@ Win32API_initialize(self, dllname, proc, import, export)
int len;
int ex;
- hdll = GetModuleHandle(RSTRING(dllname)->ptr);
- if (!hdll) {
- hdll = LoadLibrary(RSTRING(dllname)->ptr);
- if (!hdll)
- rb_raise(rb_eRuntimeError, "LoadLibrary: %s\n", RSTRING(dllname)->ptr);
- Data_Wrap_Struct(self, 0, Win32API_FreeLibrary, hdll);
- }
+ hdll = LoadLibrary(RSTRING(dllname)->ptr);
+ if (!hdll)
+ rb_raise(rb_eRuntimeError, "LoadLibrary: %s\n", RSTRING(dllname)->ptr);
+ rb_iv_set(self, "__hdll__", Data_Wrap_Struct(self, 0, Win32API_FreeLibrary, hdll));
hproc = GetProcAddress(hdll, RSTRING(proc)->ptr);
if (!hproc) {
str = rb_str_new3(proc);
@@ -68,9 +65,9 @@ Win32API_initialize(self, dllname, proc, import, export)
rb_raise(rb_eRuntimeError, "GetProcAddress: %s or %s\n",
RSTRING(proc)->ptr, RSTRING(str)->ptr);
}
- rb_iv_set(self, "__dll__", INT2NUM((int)hdll));
+ rb_iv_set(self, "__dll__", UINT2NUM((unsigned long)hdll));
rb_iv_set(self, "__dllname__", dllname);
- rb_iv_set(self, "__proc__", INT2NUM((int)hproc));
+ rb_iv_set(self, "__proc__", UINT2NUM((unsigned long)hproc));
a_import = rb_ary_new();
ptr = RARRAY(import)->ptr;
@@ -124,7 +121,7 @@ Win32API_Call(argc, argv, obj)
ApiVoid *ApiFunctionVoid;
ApiInteger *ApiFunctionInteger;
- long lParam;
+ long lParam;
char *pParam;
VALUE Return;
@@ -140,11 +137,11 @@ Win32API_Call(argc, argv, obj)
obj_proc = rb_iv_get(obj, "__proc__");
- ApiFunction = (FARPROC)NUM2INT(obj_proc);
+ ApiFunction = (FARPROC)NUM2ULONG(obj_proc);
obj_import = rb_iv_get(obj, "__import__");
obj_export = rb_iv_get(obj, "__export__");
- nimport = RARRAY(obj_import)->len;
+ nimport = RARRAY(obj_import)->len;
texport = FIX2INT(obj_export);
if (items != nimport)
@@ -159,13 +156,13 @@ Win32API_Call(argc, argv, obj)
switch (timport) {
case _T_NUMBER:
case _T_INTEGER:
- lParam = NUM2INT(rb_ary_entry(args, i));
+ lParam = NUM2ULONG(rb_ary_entry(args, i));
#if defined(_MSC_VER) || defined(__LCC__)
_asm {
mov eax, lParam
push eax
}
-#elif defined(__CYGWIN32__) || defined(__MINGW32__)
+#elif defined(__CYGWIN__) || defined(__MINGW32__)
asm volatile ("pushl %0" :: "g" (lParam));
#else
#error
@@ -173,15 +170,21 @@ Win32API_Call(argc, argv, obj)
break;
case _T_POINTER:
str = rb_ary_entry(args, i);
- Check_Type(str, T_STRING);
- rb_str_modify(str);
- pParam = RSTRING(str)->ptr;
+ if (NIL_P(str)) {
+ pParam = 0;
+ } else if (FIXNUM_P(str)){
+ pParam = (char *)NUM2ULONG(str);
+ } else {
+ Check_Type(str, T_STRING);
+ rb_str_modify(str);
+ pParam = RSTRING(str)->ptr;
+ }
#if defined(_MSC_VER) || defined(__LCC__)
_asm {
- mov eax, dword ptr pParam
+ mov eax, pParam
push eax
}
-#elif defined(__CYGWIN32__) || defined(__MINGW32__)
+#elif defined(__CYGWIN__) || defined(__MINGW32__)
asm volatile ("pushl %0" :: "g" (pParam));
#else
#error
@@ -189,7 +192,6 @@ Win32API_Call(argc, argv, obj)
break;
}
}
-
}
switch (texport) {
diff --git a/ext/Win32API/depend b/ext/Win32API/depend
deleted file mode 100644
index b224bb66c9..0000000000
--- a/ext/Win32API/depend
+++ /dev/null
@@ -1 +0,0 @@
-Win32API.o : Win32API.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h
diff --git a/ext/curses/MANIFEST b/ext/curses/MANIFEST
index db5e54ffe8..e1a25d962d 100644
--- a/ext/curses/MANIFEST
+++ b/ext/curses/MANIFEST
@@ -1,5 +1,6 @@
MANIFEST
curses.c
+depend
extconf.rb
hello.rb
rain.rb
diff --git a/ext/curses/curses.c b/ext/curses/curses.c
index 202a0f9244..b0e2ef5bc7 100644
--- a/ext/curses/curses.c
+++ b/ext/curses/curses.c
@@ -407,50 +407,50 @@ curses_cols()
/*-------------------------- class Window --------------------------*/
-/* def new(lines, cols, top, left) */
+/* def new(h, w, top, left) */
static VALUE
-window_s_new(class, lines, cols, top, left)
+window_s_new(class, h, w, top, left)
VALUE class;
- VALUE lines;
- VALUE cols;
+ VALUE h;
+ VALUE w;
VALUE top;
VALUE left;
{
- VALUE w;
+ VALUE win;
WINDOW *window;
VALUE args[4];
- window = newwin(NUM2INT(lines), NUM2INT(cols), NUM2INT(top), NUM2INT(left));
+ window = newwin(NUM2INT(h), NUM2INT(w), NUM2INT(top), NUM2INT(left));
wclear(window);
- w = prep_window(class, window);
- args[0] = lines; args[1] = cols; args[2] = top; args[3] = left;
- rb_obj_call_init(w, 4, args);
+ win = prep_window(class, window);
+ args[0] = h; args[1] = w; args[2] = top; args[3] = left;
+ rb_obj_call_init(win, 4, args);
- return w;
+ return win;
}
-/* def subwin(lines, cols, top, left) */
+/* def subwin(h, w, top, left) */
static VALUE
-window_subwin(obj, lines, cols, top, left)
+window_subwin(obj, h, w, top, left)
VALUE obj;
- VALUE lines;
- VALUE cols;
+ VALUE h;
+ VALUE w;
VALUE top;
VALUE left;
{
struct windata *winp;
WINDOW *window;
- VALUE w;
+ VALUE win;
VALUE args[4];
GetWINDOW(obj, winp);
- window = subwin(winp->window, NUM2INT(lines), NUM2INT(cols),
+ window = subwin(winp->window, NUM2INT(h), NUM2INT(w),
NUM2INT(top), NUM2INT(left));
- w = prep_window(cWindow, window);
- args[0] = lines; args[1] = cols; args[2] = top; args[3] = left;
- rb_obj_call_init(w, 4, args);
+ win = prep_window(cWindow, window);
+ args[0] = h; args[1] = w; args[2] = top; args[3] = left;
+ rb_obj_call_init(win, 4, args);
- return w;
+ return win;
}
/* def close */
diff --git a/ext/curses/depend b/ext/curses/depend
new file mode 100644
index 0000000000..ecb79e512d
--- /dev/null
+++ b/ext/curses/depend
@@ -0,0 +1 @@
+curses.o: curses.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h
diff --git a/ext/dbm/extconf.rb b/ext/dbm/extconf.rb
index 55dadc2601..f47287c03e 100644
--- a/ext/dbm/extconf.rb
+++ b/ext/dbm/extconf.rb
@@ -1,9 +1,10 @@
require 'mkmf'
dir_config("dbm")
-if have_library("gdbm", "dbm_open")
- gdbm = true
-end
+#if have_library("gdbm", "dbm_open")
+# gdbm = true
+#end
+ gdbm = false
gdbm or have_library("db", "dbm_open") or have_library("dbm", "dbm_open")
have_header("cdefs.h")
if have_header("ndbm.h") and have_func("dbm_open")
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index 3e3ec3992e..20da2a4e47 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -500,7 +500,7 @@ def extmake(target)
$objs = nil
$local_flags = ""
case RUBY_PLATFORM
- when /cygwin|beos|openstep|nextstep|rhapsody/
+ when /cygwin|beos|openstep|nextstep|rhapsody|i386-os2_emx/
$libs = ""
when /mswin32/
$LIBEXT = "lib"
diff --git a/ext/kconv/kconv.c b/ext/kconv/kconv.c
new file mode 100644
index 0000000000..969c2cb504
--- /dev/null
+++ b/ext/kconv/kconv.c
@@ -0,0 +1,2017 @@
+/** Network Kanji Filter. (PDS Version)
+************************************************************************
+** Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)
+** 連絡先: (株)富士通研究所 ソフト3研 市川 至
+** (E-Mail Address: ichikawa@flab.fujitsu.co.jp)
+** Copyright (C) 1996
+** 連絡先: 琉球大学情報工学科 河野 真治 mine/X0208 support
+** (E-Mail Address: kono@ie.u-ryukyu.ac.jp)
+** 連絡先: COW for DOS & Win16 & Win32 & OS/2
+** (E-Mail Address: GHG00637@niftyserve.or.jp)
+** 営利を目的としない限り、このソースのいかなる
+** 複写,改変,修正も許諾します。その際には、この部分を残すこと。
+** このプログラムについては特に何の保証もしない、悪しからず。
+** Everyone is permitted to do anything on this program
+** including copying, modifying, improving
+** as long as you don't try to make money off it,
+** or pretend that you wrote it.
+** i.e., the above copyright notice has to appear in all copies.
+** THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+***********************************************************************/
+
+/***********************************************************************
+** 1996/03/10 modified for Kconv - by Ikuo Nakagawa
+***********************************************************************/
+/***********************************************************************
+** 1996/12/18 modified for kconv(ruby) - by matz@ruby.club.or.jp
+***********************************************************************/
+
+static char *CopyRight =
+ "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),1996 S. Kono, COW";
+static char *Version =
+ "1.62";
+static char *Patchlevel =
+ "5/9612/Shinji Kono, COW matz";
+
+#include "ruby.h"
+
+/*
+**
+**
+**
+** USAGE: nkf [flags] [file]
+**
+** Flags:
+** b Output is bufferred (DEFAULT)
+** u Output is unbufferred
+**
+** t no operation
+**
+** j Outout code is JIS 7 bit (DEFAULT SELECT)
+** s Output code is MS Kanji (DEFAULT SELECT)
+** e Output code is AT&T JIS (DEFAULT SELECT)
+** l Output code is JIS 7bit and ISO8859-1 Latin-1
+**
+** m MIME conversion for ISO-2022-JP
+** i_ Output sequence to designate JIS-kanji (DEFAULT_J)
+** o_ Output sequence to designate single-byte roman characters (DEFAULT_R)
+**
+** r {de/en}crypt ROT13/47
+**
+** v display Version
+**
+** T Text mode output (for MS-DOS)
+**
+** x Do not convert X0201 kana into X0208
+** Z Convert X0208 alphabet to ASCII
+**
+** f60 fold option
+**
+** m MIME decode
+** B try to fix broken JIS, missing Escape
+** B[1-9] broken level
+**
+** O Output to 'nkf.out' file
+** d Delete \r in line feed
+** c Add \r in line feed
+**/
+/******************************/
+/* デフォルトの出力コード選択 */
+/* Select DEFAULT_CODE */
+#define DEFAULT_CODE_JIS
+/* #define DEFAULT_CODE_SJIS */
+/* #define DEFAULT_CODE_EUC */
+/******************************/
+
+/* for Kconv: _AUTO, _EUC, _SJIS, _JIS */
+#define _AUTO 0
+#define _JIS 1
+#define _EUC 2
+#define _SJIS 3
+#define _BINARY 4
+#define _NOCONV 4
+#define _UNKNOWN _AUTO
+
+#if (defined(__TURBOC__) || defined(LSI_C)) && !defined(MSDOS)
+#define MSDOS
+#endif
+
+#include <stdio.h>
+
+#if defined(MSDOS) || defined(__OS2__)
+#include <stdlib.h>
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+#ifdef MSDOS
+#ifdef LSI_C
+#define setbinmode(fp) fsetbin(fp)
+#else /* Microsoft C, Turbo C */
+#define setbinmode(fp) setmode(fileno(fp), O_BINARY)
+#endif
+#else /* UNIX,OS/2 */
+#define setbinmode(fp)
+#endif
+
+#ifdef _IOFBF /* SysV and MSDOS */
+#define setvbuffer(fp, buf, size) setvbuf(fp, buf, _IOFBF, size)
+#else /* BSD */
+#define setvbuffer(fp, buf, size) setbuffer(fp, buf, size)
+#endif
+
+/*Borland C++ 4.5 EasyWin*/
+#if defined(__TURBOC__) && defined(_Windows) && !defined(__WIN32__) /*Easy Win */
+#define EASYWIN
+#include <windows.h>
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+/* state of output_mode and input_mode */
+
+#define ASCII 0
+#define X0208 1
+#define X0201 2
+#define NO_X0201 3
+#define JIS_INPUT 4
+#define SJIS_INPUT 5
+#define LATIN1_INPUT 6
+#define FIXED_MIME 7
+#define DOUBLE_SPACE -2
+
+#define NL 0x0a
+#define ESC 0x1b
+#define SP 0x20
+#define AT 0x40
+#define SSP 0xa0
+#define DEL 0x7f
+#define SI 0x0f
+#define SO 0x0e
+#define SSO 0x8e
+
+#define HOLD_SIZE 32
+#define IOBUF_SIZE 16384
+
+#define DEFAULT_J 'B'
+#define DEFAULT_R 'B'
+
+#define SJ0162 0x00e1 /* 01 - 62 ku offset */
+#define SJ6394 0x0161 /* 63 - 94 ku offset */
+
+
+/* MIME preprocessor */
+
+#define _GETC() (inlen-- ? (int)(*inptr++) : EOF)
+#define _UNGETC(c) (inlen++, *--inptr = (c))
+#define PUTCHAR(c) (outlen + 1 < outsiz ? \
+ ((outptr[outlen++] = (c)), (outptr[outlen] = '\0')) : EOF)
+#define GETC() ((!mime_mode)?_GETC():mime_getc())
+#define UNGETC(c) ((!mime_mode)?_UNGETC(c):mime_ungetc(c))
+
+#ifdef EASYWIN /*Easy Win */
+extern POINT _BufferSize;
+#endif
+
+/* buffers */
+
+static unsigned char hold_buf[HOLD_SIZE*2];
+static int hold_count;
+static unsigned char *inptr;
+static int inlen;
+static char *outptr;
+static int outsiz;
+static int outlen;
+
+/* MIME preprocessor fifo */
+
+#define MIME_BUF_SIZE (1024) /* 2^n ring buffer */
+#define MIME_BUF_MASK (MIME_BUF_SIZE-1)
+#define Fifo(n) mime_buf[(n)&MIME_BUF_MASK]
+static unsigned char mime_buf[MIME_BUF_SIZE];
+static unsigned int mime_top = 0;
+static unsigned int mime_last = 0; /* decoded */
+static unsigned int mime_input = 0; /* undecoded */
+
+/* flags */
+static int unbuf_f = FALSE;
+static int estab_f = FALSE;
+static int rot_f = FALSE; /* rot14/43 mode */
+static int input_f = FALSE; /* non fixed input code */
+static int alpha_f = FALSE; /* convert JIx0208 alphbet to ASCII */
+static int mime_f = FALSE; /* convert MIME B base64 or Q */
+static int mimebuf_f = FALSE; /* MIME buffered input */
+static int broken_f = FALSE; /* convert ESC-less broken JIS */
+static int iso8859_f = FALSE; /* ISO8859 through */
+#if defined(MSDOS) || defined(__OS2__)
+static int x0201_f = TRUE; /* Assume JISX0201 kana */
+#else
+static int x0201_f = NO_X0201; /* Assume NO JISX0201 */
+#endif
+
+/* X0208 -> ASCII converter */
+
+static int c1_return;
+
+/* fold parameter */
+static int line = 0; /* chars in line */
+static int prev = 0;
+static int fold_f = FALSE;
+static int fold_len = 0;
+
+/* options */
+static char kanji_intro = DEFAULT_J,
+ ascii_intro = DEFAULT_R;
+
+/* Folding */
+
+#define FOLD_MARGIN 10
+#define DEFAULT_FOLD 60
+
+/* Global states */
+static int output_mode = ASCII, /* output kanji mode */
+ input_mode = ASCII, /* input kanji mode */
+ shift_mode = FALSE; /* TRUE shift out, or X0201 */
+static int mime_mode = FALSE; /* MIME mode B base64, Q hex */
+
+/* X0208 -> ASCII translation table */
+/* X0201 / X0208 conversion tables */
+
+/* X0201 kana conversion table */
+/* 90-9F A0-DF */
+static unsigned char cv[]= {
+0x21,0x21,0x21,0x23,0x21,0x56,0x21,0x57,
+0x21,0x22,0x21,0x26,0x25,0x72,0x25,0x21,
+0x25,0x23,0x25,0x25,0x25,0x27,0x25,0x29,
+0x25,0x63,0x25,0x65,0x25,0x67,0x25,0x43,
+0x21,0x3c,0x25,0x22,0x25,0x24,0x25,0x26,
+0x25,0x28,0x25,0x2a,0x25,0x2b,0x25,0x2d,
+0x25,0x2f,0x25,0x31,0x25,0x33,0x25,0x35,
+0x25,0x37,0x25,0x39,0x25,0x3b,0x25,0x3d,
+0x25,0x3f,0x25,0x41,0x25,0x44,0x25,0x46,
+0x25,0x48,0x25,0x4a,0x25,0x4b,0x25,0x4c,
+0x25,0x4d,0x25,0x4e,0x25,0x4f,0x25,0x52,
+0x25,0x55,0x25,0x58,0x25,0x5b,0x25,0x5e,
+0x25,0x5f,0x25,0x60,0x25,0x61,0x25,0x62,
+0x25,0x64,0x25,0x66,0x25,0x68,0x25,0x69,
+0x25,0x6a,0x25,0x6b,0x25,0x6c,0x25,0x6d,
+0x25,0x6f,0x25,0x73,0x21,0x2b,0x21,0x2c,
+0x00,0x00};
+
+
+/* X0201 kana conversion table for daguten */
+/* 90-9F A0-DF */
+static unsigned char dv[]= {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x25,0x2c,0x25,0x2e,
+0x25,0x30,0x25,0x32,0x25,0x34,0x25,0x36,
+0x25,0x38,0x25,0x3a,0x25,0x3c,0x25,0x3e,
+0x25,0x40,0x25,0x42,0x25,0x45,0x25,0x47,
+0x25,0x49,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x25,0x50,0x25,0x53,
+0x25,0x56,0x25,0x59,0x25,0x5c,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00};
+
+/* X0201 kana conversion table for han-daguten */
+/* 90-9F A0-DF */
+static unsigned char ev[]= {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x25,0x51,0x25,0x54,
+0x25,0x57,0x25,0x5a,0x25,0x5d,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00};
+
+
+/* X0208 kigou conversion table */
+/* 0x8140 - 0x819e */
+static unsigned char fv[] = {
+0x00,0x00,0x00,0x00,0x2c,0x2e,0x00,0x3a,
+0x3b,0x3f,0x21,0x00,0x00,0x27,0x60,0x00,
+0x5e,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x2d,0x00,0x2f,
+0x5c,0x00,0x00,0x7c,0x00,0x00,0x60,0x27,
+0x22,0x22,0x28,0x29,0x00,0x00,0x5b,0x5d,
+0x7b,0x7d,0x3c,0x3e,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x2b,0x2d,0x00,0x00,
+0x00,0x3d,0x00,0x3c,0x3e,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x24,0x00,0x00,0x25,0x23,0x26,0x2a,0x40,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+} ;
+
+
+/* This converts =?ISO-2022-JP?B?HOGE HOGE?= */
+
+static unsigned char *mime_pattern[] = {
+ (unsigned char *)"\075?ISO-8859-1?Q?",
+ (unsigned char *)"\075?ISO-2022-JP?B?",
+ (unsigned char *)"\075?ISO-2022-JP?Q?",
+ NULL
+};
+
+static int mime_encode[] = {
+ 'Q', 'B', 'Q',
+ 0
+};
+
+static int add_cr = FALSE;
+static int del_cr = FALSE;
+
+static void (*iconv) _((register int c2,register int c1)); /* s_iconv or oconv */
+static void (*oconv) _((register int c2,register int c1)); /* [ejs]_oconv */
+static int do_kconv _((VALUE, VALUE, int out_code, int in_code));
+static void h_conv _((register int c2,register int c1));
+static int push_hold_buf _((int c2,int c1));
+static void s_iconv _((register int c2,register int c1));
+static void e_oconv _((register int c2,register int c1));
+static void s_oconv _((register int c2,register int c1));
+static void j_oconv _((register int c2,register int c1));
+static int fold _((register int c2,register int c1));
+static int pre_convert _((register int c1,register int c2));
+static int mime_begin _((void));
+static int mime_getc _((void));
+static int mime_ungetc _((unsigned int c));
+static int mime_integrity _((unsigned char *p));
+static int base64decode _((int c));
+
+#ifdef notdef
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ register FILE *fin;
+ register char *cp;
+
+#ifdef EASYWIN /*Easy Win */
+ _BufferSize.y = 400;/*Set Scroll Buffer Size*/
+#endif
+#ifdef DEFAULT_CODE_JIS
+ oconv = j_oconv; /* DEFAULT Code is JIS */
+#endif
+#ifdef DEFAULT_CODE_SJIS
+ oconv = s_oconv; /* DEFAULT Code is S-JIS */
+#endif
+#ifdef DEFAULT_CODE_EUC
+ oconv = e_oconv; /* DEFAULT Code is EUC */
+#endif
+
+ for (argc--,argv++; (argc > 0) && **argv == '-'; argc--, argv++) {
+ cp = *argv;
+ while (*cp) {
+ switch (*cp++) {
+ case 'b': /* buffered mode */
+ unbuf_f = FALSE;
+ continue;
+ case 'u': /* non bufferd mode */
+ unbuf_f = TRUE;
+ continue;
+ case 'j': /* JIS output */
+ case 'n':
+ oconv = j_oconv;
+ continue;
+ case 'e': /* AT&T EUC output */
+ oconv = e_oconv;
+ continue;
+ case 's': /* SJIS output */
+ oconv = s_oconv;
+ continue;
+ case 'l': /* ISO8859 Latin-1 support, no conversion */
+ iso8859_f = TRUE; /* Only compatible with ISO-2022-JP */
+ input_f = LATIN1_INPUT;
+ continue;
+ case 'i': /* Kanji IN ESC-$-@/B */
+ if(*cp=='@'||*cp=='B')
+ kanji_intro = *cp++;
+ continue;
+ case 'o': /* ASCII IN ESC-(-J/B */
+ if(*cp=='J'||*cp=='B'||*cp=='H')
+ ascii_intro = *cp++;
+ continue;
+ case 'r':
+ rot_f = TRUE;
+ continue;
+#if defined(MSDOS) || defined(__OS2__)
+ case 'T':
+ binmode_f = FALSE;
+ continue;
+#endif
+ case 'v':
+ usage();
+ exit(1);
+ break;
+ /* Input code assumption */
+ case 'J': /* JIS input */
+ case 'E': /* AT&T EUC input */
+ input_f = JIS_INPUT;
+ continue;
+ case 'S': /* MS Kanji input */
+ input_f = SJIS_INPUT;
+ if(x0201_f==NO_X0201) x0201_f=TRUE;
+ continue;
+ case 'Z': /* Convert X0208 alphabet to asii */
+ /* bit:0 Convert X0208
+ bit:1 Convert Kankaku to one space
+ bit:2 Convert Kankaku to two spaces
+ */
+ if('9'>= *cp && *cp>='0')
+ alpha_f |= 1<<(*cp++ -'0');
+ else
+ alpha_f |= TRUE;
+ continue;
+ case 'x': /* Convert X0201 kana to X0208 or X0201 Conversion */
+ x0201_f = FALSE; /* No X0201->X0208 conversion */
+ /* accept X0201
+ ESC-(-I in JIS, EUC, MS Kanji
+ SI/SO in JIS, EUC, MS Kanji
+ SSO in EUC, JIS, not in MS Kanji
+ MS Kanji (0xa0-0xdf)
+ output X0201
+ ESC-(-I in JIS (0x20-0x5f)
+ SSO in EUC (0xa0-0xdf)
+ 0xa0-0xd in MS Kanji (0xa0-0xdf)
+ */
+ continue;
+ case 'X': /* Assume X0201 kana */
+ /* Default value is NO_X0201 for EUC/MS-Kanji mix */
+ x0201_f = TRUE;
+ continue;
+ case 'f': /* folding -f60 or -f */
+ fold_f = TRUE;
+ fold_len = atoi(cp);
+ if(!(0<fold_len && fold_len<BUFSIZ))
+ fold_len = DEFAULT_FOLD;
+ while('0'<= *cp && *cp <='9') cp++;
+ continue;
+ case 'm': /* MIME support */
+ mime_f = TRUE;
+ if(*cp=='B'||*cp=='Q') {
+ mime_mode = *cp++;
+ mimebuf_f = FIXED_MIME;
+ }
+ continue;
+ case 'B': /* Broken JIS support */
+ /* bit:0 no ESC JIS
+ bit:1 allow any x on ESC-(-x or ESC-$-x
+ bit:2 reset to ascii on NL
+ */
+ if('9'>= *cp && *cp>='0')
+ broken_f |= 1<<(*cp++ -'0');
+ else
+ broken_f |= TRUE;
+ continue;
+ case 'O':/* for Output file */
+ file_out = TRUE;
+ continue;
+ case 'c':/* add cr code */
+ add_cr = TRUE;
+ continue;
+ case 'd':/* delete cr code */
+ del_cr = TRUE;
+ continue;
+ default:
+ /* bogus option but ignored */
+ continue;
+ }
+ }
+ }
+
+ if(iso8859_f && (oconv != j_oconv || !x0201_f )) {
+ fprintf(stderr,"Mixed ISO8859/JISX0201/SJIS/EUC output is not allowed.\n");
+ exit(1);
+ }
+
+ if(binmode_f == TRUE)
+#ifdef __OS2__
+ if(freopen("","wb",stdout) == NULL)
+ return (-1);
+#else
+ setbinmode(stdout);
+#endif
+
+ if(unbuf_f)
+ setbuf (stdout, (char *) NULL);
+ else
+ setvbuffer (stdout, stdobuf, IOBUF_SIZE);
+
+ if(argc == 0) {
+ if(binmode_f == TRUE)
+#ifdef __OS2__
+ if(freopen("","rb",stdin) == NULL) return (-1);
+#else
+ setbinmode(stdin);
+#endif
+ setvbuffer (stdin, stdibuf, IOBUF_SIZE);
+ convert (stdin);
+ } else {
+ while (argc--) {
+ if((fin = fopen (*argv++, "r")) == NULL) {
+ perror (*--argv);
+ return (-1);
+ } else {
+/* reopen file for stdout */
+ if(file_out == TRUE){
+ if(argc == 1 ) {
+ if(freopen(*argv++, "w", stdout) == NULL) {
+ perror (*--argv);
+ return (-1);
+ }
+ argc--;
+ } else {
+ if(freopen("nkf.out", "w", stdout) == NULL) {
+ perror (*--argv);
+ return (-1);
+ }
+ }
+ if(binmode_f == TRUE) {
+#ifdef __OS2__
+ if(freopen("","wb",stdout) == NULL)
+ return (-1);
+#else
+ setbinmode(stdout);
+#endif
+ }
+ }
+ if(binmode_f == TRUE)
+#ifdef __OS2__
+ if(freopen("","rb",fin) == NULL)
+ return (-1);
+#else
+ setbinmode(fin);
+#endif
+ setvbuffer (fin, stdibuf, IOBUF_SIZE);
+ convert (fin);
+ fclose (fin);
+ }
+ }
+ }
+#ifdef EASYWIN /*Easy Win */
+ if(file_out == FALSE)
+ scanf("%d",&end_check);
+ else
+ fclose(stdout);
+#else /* for Other OS */
+ if(file_out == TRUE)
+ fclose(stdout);
+#endif
+ return (0);
+}
+#endif /* notdef */
+
+static int
+do_kconv(in, out, out_code, in_code)
+ VALUE in, out;
+ int out_code, in_code;
+{
+ register int c1, c2;
+
+ c2 = 0;
+
+ inptr = (unsigned char *)RSTRING(in)->ptr; /* input buffer */
+ inlen = RSTRING(in)->len; /* input buffer size*/
+ outptr = RSTRING(out)->ptr; /* output buffer */
+ outsiz = RSTRING(out)->len; /* output buffer size */
+ outlen = 0; /* current length of output string */
+
+ if (inlen <= 0) {
+ return 0;
+ }
+ *outptr = '\0';
+
+ x0201_f = TRUE; /* don't assume JISX0201 kana */
+ rot_f = FALSE; /* rot14/43 mode */
+ input_f = FALSE; /* non fixed input code */
+ alpha_f = FALSE; /* convert JISX0208 alphbet to ASCII */
+ mime_f = TRUE; /* convert MIME base64 */
+ broken_f = FALSE; /* convert ESC-less broken JIS */
+
+ switch (out_code) {
+ case _SJIS:
+ oconv = s_oconv;
+ break;
+ case _EUC:
+ oconv = e_oconv;
+ break;
+ default:
+ oconv = j_oconv;
+ break;
+ }
+
+ switch (in_code) {
+ case _SJIS:
+ input_f = SJIS_INPUT;
+ x0201_f = TRUE;
+ break;
+ case _EUC:
+ case _JIS:
+ input_f = JIS_INPUT;
+ break;
+ default:
+ input_f = FALSE;
+ break;
+ }
+
+ if(input_f == JIS_INPUT || input_f == LATIN1_INPUT) {
+ estab_f = TRUE; iconv = oconv;
+ } else if(input_f == SJIS_INPUT) {
+ estab_f = TRUE; iconv = s_iconv;
+ } else {
+ estab_f = FALSE; iconv = oconv;
+ }
+ input_mode = ASCII;
+ output_mode = ASCII;
+ shift_mode = FALSE;
+ mime_mode = FALSE;
+
+#define NEXT continue /* no output, get next */
+#define SEND ; /* output c1 and c2, get next */
+#define LAST break /* end of loop, go closing */
+
+ while ((c1 = GETC()) != EOF) {
+ if(!c2 && !input_mode && c1<DEL && !mime_mode && !output_mode
+ && !shift_mode && !fold_f && !rot_f) {
+ /* plain ASCII tight loop, no conversion and no fold */
+ while(c1!='=' && c1!=SO && c1!=EOF &&
+ c1!=ESC && c1!='$' && c1<DEL && c1!='\r' && c1!='\n') {
+ PUTCHAR(c1);
+ c1 = _GETC();
+ }
+ if(c1==EOF) LAST;
+ }
+ if(c2) {
+ /* second byte */
+ if(c2 > DEL) {
+ /* in case of 8th bit is on */
+ if(!estab_f) {
+ /* in case of not established yet */
+ if(c1 > SSP) {
+ /* It is still ambiguious */
+ h_conv (c2, c1);
+ c2 = 0;
+ NEXT;
+ } else if(c1 < AT) {
+ /* ignore bogus code */
+ c2 = 0;
+ NEXT;
+ } else {
+ /* established */
+ /* it seems to be MS Kanji */
+ estab_f = TRUE;
+ iconv = s_iconv;
+ SEND;
+ }
+ } else
+ /* in case of already established */
+ if(c1 < AT) {
+ /* ignore bogus code */
+ c2 = 0;
+ NEXT;
+ } else
+ SEND;
+ } else
+ /* 7 bit code */
+ /* it might be kanji shitfted */
+ if((c1 == DEL) || (c1 <= SP)) {
+ /* ignore bogus first code */
+ c2 = 0;
+ NEXT;
+ } else
+ SEND;
+ } else {
+ /* first byte */
+ if(c1 > DEL) {
+ /* 8 bit code */
+ if(!estab_f && !iso8859_f) {
+ /* not established yet */
+ if(c1 < SSP) {
+ /* it seems to be MS Kanji */
+ estab_f = TRUE;
+ iconv = s_iconv;
+ } else if(c1 < 0xe0) {
+ /* it seems to be EUC */
+ estab_f = TRUE;
+ iconv = oconv;
+ } else {
+ /* still ambiguious */
+ }
+ c2 = c1;
+ NEXT;
+ } else { /* estab_f==TRUE */
+ if(iso8859_f) {
+ SEND;
+ } else if(SSP<=c1 && c1<0xe0 && iconv == s_iconv) {
+ /* SJIS X0201 Case... */
+ /* This is too arrogant, but ... */
+ if(x0201_f==NO_X0201) {
+ iconv = oconv;
+ c2 = c1;
+ NEXT;
+ } else
+ if(x0201_f) {
+ if(dv[(c1-SSP)*2]||ev[(c1-SSP)*2]) {
+ /* look ahead for X0201/X0208conversion */
+ if((c2 = GETC()) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ LAST;
+ } else if(c2==(0xde)) { /* 濁点 */
+ (*oconv)(dv[(c1-SSP)*2],dv[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else if(c2==(0xdf)&&ev[(c1-SSP)*2]) {
+ /* 半濁点 */
+ (*oconv)(ev[(c1-SSP)*2],ev[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ }
+ UNGETC(c2); c2 = 0;
+ }
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ NEXT;
+ } else
+ SEND;
+ } else if(c1==SSO && iconv != s_iconv) {
+ /* EUC X0201 Case */
+ /* This is too arrogant
+ if(x0201_f == NO_X0201) {
+ estab_f = FALSE;
+ c2 = 0;
+ NEXT;
+ } */
+ c1 = GETC(); /* skip SSO */
+ euc_1byte_check:
+ if(x0201_f && SSP<=c1 && c1<0xe0) {
+ if(dv[(c1-SSP)*2]||ev[(c1-SSP)*2]) {
+ if((c2 = GETC()) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ LAST;
+ }
+ /* forward lookup 濁点/半濁点 */
+ if(c2 != SSO) {
+ UNGETC(c2); c2 = 0;
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ NEXT;
+ } else if((c2 = GETC()) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ (*oconv)(0,SSO);
+ LAST;
+ } else if(c2==(0xde)) { /* 濁点 */
+ (*oconv)(dv[(c1-SSP)*2],dv[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else if(c2==(0xdf)&&ev[(c1-SSP)*2]) {
+ /* 半濁点 */
+ (*oconv)(ev[(c1-SSP)*2],ev[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ /* we have to check this c2 */
+ /* and no way to push back SSO */
+ c1 = c2; c2 = 0;
+ goto euc_1byte_check;
+ }
+ }
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ NEXT;
+ } else
+ SEND;
+ } else if(c1 < SSP && iconv != s_iconv) {
+ /* strange code in EUC */
+ iconv = s_iconv; /* try SJIS */
+ c2 = c1;
+ NEXT;
+ } else {
+ /* already established */
+ c2 = c1;
+ NEXT;
+ }
+ }
+ } else if((c1 > SP) && (c1 != DEL)) {
+ /* in case of Roman characters */
+ if(shift_mode) {
+ c1 |= 0x80;
+ /* output 1 shifted byte */
+ if(x0201_f && (!iso8859_f||input_mode==X0201) &&
+ SSP<=c1 && c1<0xe0 ) {
+ if(dv[(c1-SSP)*2]||ev[(c1-SSP)*2]) {
+ if((c2 = GETC()) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ LAST;
+ } else if(c2==(0xde&0x7f)) { /* 濁点 */
+ (*oconv)(dv[(c1-SSP)*2],dv[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else if(c2==(0xdf&0x7f)&&ev[(c1-SSP)*2]) {
+ /* 半濁点 */
+ (*oconv)(ev[(c1-SSP)*2],ev[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ }
+ UNGETC(c2); c2 = 0;
+ }
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ NEXT;
+ } else
+ SEND;
+ } else if(c1 == '(' && broken_f && input_mode == X0208
+ && !mime_mode ) {
+ /* Try to recover missing escape */
+ if((c1 = GETC()) == EOF) {
+ (*oconv) (0, '(');
+ LAST;
+ } else {
+ if(c1 == 'B' || c1 == 'J' || c1 == 'H') {
+ input_mode = ASCII; shift_mode = FALSE;
+ NEXT;
+ } else {
+ (*oconv) (0, '(');
+ /* do not modify various input_mode */
+ /* It can be vt100 sequence */
+ SEND;
+ }
+ }
+ } else if(input_mode == X0208) {
+ /* in case of Kanji shifted */
+ c2 = c1;
+ NEXT;
+ /* goto next_byte */
+ } else if(c1 == '=' && mime_f && !mime_mode ) {
+ if((c1 = _GETC()) == EOF) {
+ (*oconv) (0, '=');
+ LAST;
+ } else if(c1 == '?') {
+ /* =? is mime conversion start sequence */
+ if(mime_begin() == EOF) /* check in detail */
+ LAST;
+ else
+ NEXT;
+ } else {
+ (*oconv) (0, '=');
+ _UNGETC(c1);
+ NEXT;
+ }
+ } else if(c1 == '$' && broken_f && !mime_mode) {
+ /* try to recover missing escape */
+ if((c1 = GETC()) == EOF) {
+ (*oconv) (0, '$');
+ LAST;
+ } else if(c1 == '@'|| c1 == 'B') {
+ /* in case of Kanji in ESC sequence */
+ input_mode = X0208;
+ shift_mode = FALSE;
+ NEXT;
+ } else {
+ /* sorry */
+ (*oconv) (0, '$');
+ (*oconv) (0, c1);
+ NEXT;
+ }
+ } else
+ SEND;
+ } else if(c1 == SI) {
+ shift_mode = FALSE;
+ NEXT;
+ } else if(c1 == SO) {
+ shift_mode = TRUE;
+ NEXT;
+ } else if(c1 == ESC ) {
+ if((c1 = GETC()) == EOF) {
+ (*oconv) (0, ESC);
+ LAST;
+ } else if(c1 == '$') {
+ if((c1 = GETC()) == EOF) {
+ (*oconv) (0, ESC);
+ (*oconv) (0, '$');
+ LAST;
+ } else if(c1 == '@'|| c1 == 'B') {
+ /* This is kanji introduction */
+ input_mode = X0208;
+ shift_mode = FALSE;
+ NEXT;
+ } else if(broken_f&0x2) {
+ input_mode = X0208;
+ shift_mode = FALSE;
+ NEXT;
+ } else {
+ (*oconv) (0, ESC);
+ (*oconv) (0, '$');
+ (*oconv) (0, c1);
+ NEXT;
+ }
+ } else if(c1 == '(') {
+ if((c1 = GETC()) == EOF) {
+ (*oconv) (0, ESC);
+ (*oconv) (0, '(');
+ LAST;
+ } else {
+ if(c1 == 'I') {
+ /* This is X0201 kana introduction */
+ input_mode = X0201; shift_mode = X0201;
+ NEXT;
+ } else if(c1 == 'B' || c1 == 'J' || c1 == 'H') {
+ /* This is X0208 kanji introduction */
+ input_mode = ASCII; shift_mode = FALSE;
+ NEXT;
+ } else if(broken_f&0x2) {
+ input_mode = ASCII; shift_mode = FALSE;
+ NEXT;
+ } else {
+ (*oconv) (0, ESC);
+ (*oconv) (0, '(');
+ /* maintain various input_mode here */
+ SEND;
+ }
+ }
+ } else {
+ /* lonely ESC */
+ (*oconv) (0, ESC);
+ SEND;
+ }
+ } else if(c1 == NL && broken_f&4) {
+ input_mode = ASCII;
+ SEND;
+ } else
+ SEND;
+ }
+ /* send: */
+ if(input_mode == X0208)
+ (*oconv) (c2, c1); /* this is JIS, not SJIS/EUC case */
+ else
+ (*iconv) (c2, c1); /* can be EUC/SJIS */
+ c2 = 0;
+ continue;
+ /* goto next_word */
+ }
+
+ /* epilogue */
+ (*iconv) (EOF, 0);
+ return outlen;
+}
+
+
+static void
+h_conv (c2, c1)
+ register int c1,
+ c2;
+{
+ register int wc;
+
+
+ /** it must NOT be in the kanji shifte sequence */
+ /** it must NOT be written in JIS7 */
+ /** and it must be after 2 byte 8bit code */
+
+ hold_count = 0;
+ push_hold_buf (c2, c1);
+ c2 = 0;
+
+ while ((c1 = GETC()) != EOF) {
+ if(c2) {
+ /* second byte */
+ if(!estab_f) {
+ /* not established */
+ if(c1 > SSP) {
+ /* it is still ambiguious yet */
+ SEND;
+ } else if(c1 < AT) {
+ /* ignore bogus first byte */
+ c2 = 0;
+ SEND;
+ } else {
+ /* now established */
+ /* it seems to be MS Kanji */
+ estab_f = TRUE;
+ iconv = s_iconv;
+ SEND;
+ }
+ } else
+ SEND;
+ } else {
+ /* First byte */
+ if(c1 > DEL) {
+ /* 8th bit is on */
+ if(c1 < SSP) {
+ /* it seems to be MS Kanji */
+ estab_f = TRUE;
+ iconv = s_iconv;
+ } else if(c1 < 0xe0) {
+ /* it seems to be EUC */
+ estab_f = TRUE;
+ iconv = oconv;
+ } else {
+ /* still ambiguious */
+ }
+ c2 = c1;
+ NEXT;
+ } else
+ /* 7 bit code , then send without any process */
+ SEND;
+ }
+ /* send: */
+ if((push_hold_buf (c2, c1) == EOF) || estab_f)
+ break;
+ c2 = 0;
+ continue;
+ }
+
+ /** now,
+ ** 1) EOF is detected, or
+ ** 2) Code is established, or
+ ** 3) Buffer is FULL (but last word is pushed)
+ **
+ ** in 1) and 3) cases, we continue to use
+ ** Kanji codes by oconv and leave estab_f unchanged.
+ **/
+
+ for (wc = 0; wc < hold_count; wc += 2) {
+ c2 = hold_buf[wc];
+ c1 = hold_buf[wc+1];
+ (*iconv) (c2, c1);
+ }
+ return;
+}
+
+
+
+static int
+push_hold_buf (c2, c1)
+ int c2,
+ c1;
+{
+ if(hold_count >= HOLD_SIZE*2)
+ return (EOF);
+ hold_buf[hold_count++] = c2;
+ hold_buf[hold_count++] = c1;
+ return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count);
+}
+
+
+static void
+s_iconv (c2, c1)
+ register int c2,
+ c1;
+{
+ if((c2 == EOF) || (c2 == 0)) {
+ /* NOP */
+ } else {
+ c2 = c2 + c2 - ((c2 <= 0x9f) ? SJ0162 : SJ6394);
+ if(c1 < 0x9f)
+ c1 = c1 - ((c1 > DEL) ? SP : 0x1f);
+ else {
+ c1 = c1 - 0x7e;
+ c2++;
+ }
+ }
+ (*oconv) (c2, c1);
+}
+
+
+static void
+e_oconv (c2, c1)
+ register int c2,
+ c1;
+{
+ c2 = pre_convert(c1,c2); c1 = c1_return;
+ if(fold_f) {
+ switch(fold(c2,c1)) {
+ case '\n':
+ if(add_cr == TRUE) {
+ PUTCHAR('\r');
+ c1 = '\n';
+ }
+ PUTCHAR('\n');
+ break;
+ case 0: return;
+ case '\r':
+ c1 = '\n'; c2 = 0;
+ break;
+ case '\t':
+ case ' ':
+ c1 = ' '; c2 = 0;
+ break;
+ }
+ }
+ if(c2==DOUBLE_SPACE) {
+ PUTCHAR(' '); PUTCHAR(' ');
+ return;
+ }
+ if(c2 == EOF)
+ return;
+ else if(c2 == 0 && (c1&0x80)) {
+ PUTCHAR(SSO); PUTCHAR(c1);
+ } else if(c2 == 0) {
+ if(c1 == '\n' && add_cr == TRUE)
+ PUTCHAR('\r');
+ if(c1 != '\r')
+ PUTCHAR(c1);
+ else if(del_cr == FALSE)
+ PUTCHAR(c1);
+ } else {
+ if((c1<0x20 || 0x7e<c1) ||
+ (c2<0x20 || 0x7e<c2)) {
+ estab_f = FALSE;
+ return; /* too late to rescue this char */
+ }
+ PUTCHAR(c2 | 0x080);
+ PUTCHAR(c1 | 0x080);
+ }
+}
+
+
+static void
+s_oconv (c2, c1)
+ register int c2,
+ c1;
+{
+ c2 = pre_convert(c1,c2); c1 = c1_return;
+ if(fold_f) {
+ switch(fold(c2,c1)) {
+ case '\n':
+ if(add_cr == TRUE) {
+ PUTCHAR('\r');
+ c1 = '\n';
+ }
+ PUTCHAR('\n');
+ break;
+ case '\r':
+ c1 = '\n'; c2 = 0;
+ break;
+ case 0: return;
+ case '\t':
+ case ' ':
+ c1 = ' '; c2 = 0;
+ break;
+ }
+ }
+ if(c2==DOUBLE_SPACE) {
+ PUTCHAR(' '); PUTCHAR(' ');
+ return;
+ }
+ if(c2 == EOF)
+ return;
+ else if(c2 == 0) {
+ if(c1 == '\n' && add_cr == TRUE)
+ PUTCHAR('\r');
+ if(c1 != '\r')
+ PUTCHAR(c1);
+ else if(del_cr == FALSE)
+ PUTCHAR(c1);
+ } else {
+ if((c1<0x20 || 0x7e<c1) ||
+ (c2<0x20 || 0x7e<c2)) {
+ estab_f = FALSE;
+ return; /* too late to rescue this char */
+ }
+ PUTCHAR((((c2 - 1) >> 1) + ((c2 <= 0x5e) ? 0x71 : 0xb1)));
+ PUTCHAR((c1 + ((c2 & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e)));
+ }
+}
+
+static void
+j_oconv (c2, c1)
+ register int c2,
+ c1;
+{
+ c2 = pre_convert(c1,c2); c1 = c1_return;
+ if(fold_f) {
+ switch(fold(c2,c1)) {
+ case '\n':
+ if(output_mode) {
+ PUTCHAR(ESC);
+ PUTCHAR('(');
+ PUTCHAR(ascii_intro);
+ }
+ if(add_cr == TRUE) {
+ PUTCHAR('\r');
+ c1 = '\n';
+ }
+ PUTCHAR('\n');
+ output_mode = ASCII;
+ break;
+ case '\r':
+ c1 = '\n'; c2 = 0;
+ break;
+ case '\t':
+ case ' ':
+ c1 = ' '; c2 = 0;
+ break;
+ case 0: return;
+ }
+ }
+ if(c2 == EOF) {
+ if(output_mode) {
+ PUTCHAR(ESC);
+ PUTCHAR('(');
+ PUTCHAR(ascii_intro);
+ }
+ } else if(c2 == 0 && (c1 & 0x80)) {
+ if(input_mode==X0201 || !iso8859_f) {
+ if(output_mode!=X0201) {
+ PUTCHAR(ESC);
+ PUTCHAR('(');
+ PUTCHAR('I');
+ output_mode = X0201;
+ }
+ c1 &= 0x7f;
+ } else {
+ /* iso8859 introduction, or 8th bit on */
+ /* Can we convert in 7bit form using ESC-'-'-A ?
+ Is this popular? */
+ }
+ PUTCHAR(c1);
+ } else if(c2 == 0) {
+ if(output_mode) {
+ PUTCHAR(ESC);
+ PUTCHAR('(');
+ PUTCHAR(ascii_intro);
+ output_mode = ASCII;
+ }
+ if(c1 == '\n' && add_cr == TRUE)
+ PUTCHAR('\r');
+ if(c1 != '\r')
+ PUTCHAR(c1);
+ else if(del_cr == FALSE)
+ PUTCHAR(c1);
+ } else if(c2 == DOUBLE_SPACE) {
+ if(output_mode) {
+ PUTCHAR(ESC);
+ PUTCHAR('(');
+ PUTCHAR(ascii_intro);
+ output_mode = ASCII;
+ }
+ PUTCHAR(' ');
+ if(c1 == '\n' && add_cr == TRUE)
+ PUTCHAR('\r');
+ if(c1 != '\r')
+ PUTCHAR(c1);
+ else if(del_cr == FALSE)
+ PUTCHAR(c1);
+ } else {
+ if(output_mode != X0208) {
+ PUTCHAR(ESC);
+ PUTCHAR('$');
+ PUTCHAR(kanji_intro);
+ output_mode = X0208;
+ }
+ if(c1<0x20 || 0x7e<c1)
+ return;
+ if(c2<0x20 || 0x7e<c2)
+ return;
+ PUTCHAR(c2);
+ if(c1 == '\n' && add_cr == TRUE)
+ PUTCHAR('\r');
+ if(c1 != '\r')
+ PUTCHAR(c1);
+ else if(del_cr == FALSE)
+ PUTCHAR(c1);
+ }
+}
+
+
+#define rot13(c) ( \
+ ( c < 'A' ) ? c: \
+ (c <= 'M') ? (c + 13): \
+ (c <= 'Z') ? (c - 13): \
+ (c < 'a') ? (c): \
+ (c <= 'm') ? (c + 13): \
+ (c <= 'z') ? (c - 13): \
+ (c) \
+)
+
+#define rot47(c) ( \
+ ( c < '!' ) ? c: \
+ ( c <= 'O' ) ? (c + 47) : \
+ ( c <= '~' ) ? (c - 47) : \
+ c \
+)
+
+/*
+ Return value of fold()
+
+ \n add newline and output char
+ \r add newline and output nothing
+ ' ' space
+ 0 skip
+ 1 (or else) normal output
+
+ fold state in prev (previous character)
+
+ >0x80 Japanese (X0208/X0201)
+ <0x80 ASCII
+ \n new line
+ ' ' space
+
+ This fold algorthm does not preserve heading space in a line.
+ This is the main difference from fmt.
+*/
+
+static int
+fold(c2,c1)
+register int c2,c1;
+{
+ int prev0;
+ if(c1=='\r')
+ return 0; /* ignore cr */
+ if(c1== 8) {
+ if(line>0) line--;
+ return 1;
+ }
+ if(c2==EOF && line != 0) /* close open last line */
+ return '\n';
+ /* new line */
+ if(c1=='\n') {
+ if(prev == c1) { /* duplicate newline */
+ if(line) {
+ line = 0;
+ return '\n'; /* output two newline */
+ } else {
+ line = 0;
+ return 1;
+ }
+ } else {
+ if(prev&0x80) { /* Japanese? */
+ prev = c1;
+ return 0; /* ignore given single newline */
+ } else if(prev==' ') {
+ return 0;
+ } else {
+ prev = c1;
+ if(++line<=fold_len)
+ return ' ';
+ else {
+ line = 0;
+ return '\r'; /* fold and output nothing */
+ }
+ }
+ }
+ }
+ if(c1=='\f') {
+ prev = '\n';
+ if(line==0)
+ return 1;
+ line = 0;
+ return '\n'; /* output newline and clear */
+ }
+ /* X0208 kankaku or ascii space */
+ if( (c2==0&&c1==' ')||
+ (c2==0&&c1=='\t')||
+ (c2==DOUBLE_SPACE)||
+ (c2=='!'&& c1=='!')) {
+ if(prev == ' ') {
+ return 0; /* remove duplicate spaces */
+ }
+ prev = ' ';
+ if(++line<=fold_len)
+ return ' '; /* output ASCII space only */
+ else {
+ prev = ' '; line = 0;
+ return '\r'; /* fold and output nothing */
+ }
+ }
+ prev0 = prev; /* we still need this one... , but almost done */
+ prev = c1;
+ if(c2 || (SSP<=c1 && c1<=0xdf))
+ prev |= 0x80; /* this is Japanese */
+ line += (c2==0)?1:2;
+ if(line<=fold_len) { /* normal case */
+ return 1;
+ }
+ if(line>=fold_len+FOLD_MARGIN) { /* too many kinsou suspension */
+ line = (c2==0)?1:2;
+ return '\n'; /* We can't wait, do fold now */
+ }
+ /* simple kinsoku rules return 1 means no folding */
+ if(c2==0) {
+ if(c1==0xde) return 1; /* ゛*/
+ if(c1==0xdf) return 1; /* ゜*/
+ if(c1==0xa4) return 1; /* 。*/
+ if(c1==0xa3) return 1; /* ,*/
+ if(c1==0xa1) return 1; /* 」*/
+ if(c1==0xb0) return 1; /* - */
+ if(SSP<=c1 && c1<=0xdf) { /* X0201 */
+ line = 1;
+ return '\n';/* add one new line before this character */
+ }
+ /* fold point in ASCII { [ ( */
+ if(( c1!=')'&&
+ c1!=']'&&
+ c1!='}'&&
+ c1!='.'&&
+ c1!=','&&
+ c1!='!'&&
+ c1!='?'&&
+ c1!='/'&&
+ c1!=':'&&
+ c1!=';')&&
+ ((prev0=='\n')|| (prev0==' ')|| /* ignored new line */
+ (prev0&0x80)) /* X0208 - ASCII */
+ ) {
+ line = 1;
+ return '\n';/* add one new line before this character */
+ }
+ return 1; /* default no fold in ASCII */
+ } else {
+ if(c2=='!') {
+ if(c1=='"') return 1; /* 、 */
+ if(c1=='#') return 1; /* 。 */
+ if(c1=='$') return 1; /* , */
+ if(c1=='%') return 1; /* . */
+ if(c1=='\'') return 1; /* + */
+ if(c1=='(') return 1; /* ; */
+ if(c1==')') return 1; /* ? */
+ if(c1=='*') return 1; /* ! */
+ if(c1=='+') return 1; /* ゛ */
+ if(c1==',') return 1; /* ゜ */
+ }
+ line = 2;
+ return '\n'; /* add one new line before this character */
+ }
+}
+
+static int
+pre_convert(c1,c2)
+register int c1,c2;
+{
+ if(c2) c1 &= 0x7f;
+ c1_return = c1;
+ if(c2==EOF) return c2;
+ c2 &= 0x7f;
+ if(rot_f) {
+ if(c2) {
+ c1 = rot47(c1);
+ c2 = rot47(c2);
+ } else {
+ if(!(c1 & 0x80))
+ c1 = rot13(c1);
+ }
+ c1_return = c1;
+ }
+ /* JISX0208 Alphabet */
+ if(alpha_f && c2 == 0x23 ) return 0;
+ /* JISX0208 Kigou */
+ if(alpha_f && c2 == 0x21 ) {
+ if(0x21==c1) {
+ if(alpha_f&0x2) {
+ c1_return = ' ';
+ return 0;
+ } else if(alpha_f&0x4) {
+ c1_return = ' ';
+ return DOUBLE_SPACE;
+ } else {
+ return c2;
+ }
+ } else if(0x20<c1 && c1<0x7f && fv[c1-0x20]) {
+ c1_return = fv[c1-0x20];
+ return 0;
+ }
+ }
+ return c2;
+}
+
+
+static int iso8859_f_save;
+
+#define nkf_toupper(c) (('a'<=c && c<='z')?(c-('a'-'A')):c)
+/* I don't trust portablity of toupper */
+
+static int
+mime_begin()
+{
+ int c1;
+ int i,j,k;
+ unsigned char *p,*q;
+ int r[20]; /* recovery buffer, max mime pattern lenght */
+
+ mime_mode = FALSE;
+ /* =? has been checked */
+ j = 0;
+ p = mime_pattern[j];
+ r[0]='='; r[1]='?';
+
+ for(i=2;p[i]>' ';i++) { /* start at =? */
+ if( ((r[i] = c1 = _GETC())==EOF) || nkf_toupper(c1) != p[i] ) {
+ /* pattern fails, try next one */
+ q = p;
+ while (p = mime_pattern[++j]) {
+ for(k=2;k<i;k++) /* assume length(p) > i */
+ if(p[k]!=q[k]) break;
+ if(k==i && nkf_toupper(c1)==p[k]) break;
+ }
+ if(p) continue; /* found next one, continue */
+ /* all fails, output from recovery buffer */
+ _UNGETC(c1);
+ for(j=0;j<i;j++) {
+ (*oconv)(0,r[j]);
+ }
+ return c1;
+ }
+ }
+ iso8859_f_save = iso8859_f;
+ if(j==0) {
+ iso8859_f = TRUE;
+ }
+ mime_mode = mime_encode[j];
+ if(mime_mode=='B') {
+ mimebuf_f = unbuf_f;
+ if(!unbuf_f) {
+ /* do MIME integrity check */
+ return mime_integrity(mime_pattern[j]);
+ }
+ }
+ mimebuf_f = TRUE;
+ return c1;
+}
+
+#define mime_getc0() (mimebuf_f?_GETC():Fifo(mime_input++))
+#define mime_ungetc0(c) (mimebuf_f?_UNGETC(c):mime_input--)
+
+static int
+mime_getc()
+{
+ int c1, c2, c3, c4, cc;
+ int t1, t2, t3, t4, mode, exit_mode;
+
+ if(mime_top != mime_last) { /* Something is in FIFO */
+ return Fifo(mime_top++);
+ }
+
+ if(mimebuf_f == FIXED_MIME)
+ exit_mode = mime_mode;
+ else
+ exit_mode = FALSE;
+ if(mime_mode == 'Q') {
+ if((c1 = mime_getc0()) == EOF) return (EOF);
+ if(c1=='_') return ' ';
+ if(c1!='=' && c1!='?')
+ return c1;
+ mime_mode = exit_mode; /* prepare for quit */
+ if(c1<=' ') return c1;
+ if((c2 = mime_getc0()) == EOF) return (EOF);
+ if(c2<=' ') return c2;
+ if(c1=='?'&&c2=='=') {
+ /* end Q encoding */
+ input_mode = exit_mode;
+ iso8859_f = iso8859_f_save;
+ return _GETC();
+ }
+ if(c1=='?') {
+ mime_mode = 'Q'; /* still in MIME */
+ mime_ungetc0(c2);
+ return c1;
+ }
+ if((c3 = mime_getc0()) == EOF) return (EOF);
+ if(c2<=' ') return c2;
+ mime_mode = 'Q'; /* still in MIME */
+#define hex(c) (('0'<=c&&c<='9')?(c-'0'):\
+ ('A'<=c&&c<='F')?(c-'A'+10):('a'<=c&&c<='f')?(c-'a'+10):0)
+ return ((hex(c2)<<4) + hex(c3));
+ }
+
+ if(mime_mode != 'B') {
+ mime_mode = FALSE;
+ return _GETC();
+ }
+
+
+ /* Base64 encoding */
+ /*
+ MIME allows line break in the middle of
+ Base64, but we are very pessimistic in decoding
+ in unbuf mode because MIME encoded code may broken by
+ less or editor's control sequence (such as ESC-[-K in unbuffered
+ mode. ignore incomplete MIME.
+ */
+ mode = mime_mode;
+ mime_mode = exit_mode; /* prepare for quit */
+
+ while ((c1 = mime_getc0())<=' ') {
+ if(c1==EOF)
+ return (EOF);
+ }
+ if((c2 = mime_getc0())<=' ') {
+ if(c2==EOF)
+ return (EOF);
+ if(mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c2;
+ }
+ if((c1 == '?') && (c2 == '=')) {
+ input_mode = ASCII;
+ while((c1 = _GETC())==' ' /* || c1=='\n' || c1=='\r' */);
+ return c1;
+ }
+ if((c3 = mime_getc0())<=' ') {
+ if(c3==EOF)
+ return (EOF);
+ if(mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c3;
+ }
+ if((c4 = mime_getc0())<=' ') {
+ if(c4==EOF)
+ return (EOF);
+ if(mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c4;
+ }
+
+ mime_mode = mode; /* still in MIME sigh... */
+
+ /* BASE 64 decoding */
+
+ t1 = 0x3f & base64decode(c1);
+ t2 = 0x3f & base64decode(c2);
+ t3 = 0x3f & base64decode(c3);
+ t4 = 0x3f & base64decode(c4);
+ cc = ((t1 << 2) & 0x0fc) | ((t2 >> 4) & 0x03);
+ if(c2 != '=') {
+ Fifo(mime_last++) = cc;
+ cc = ((t2 << 4) & 0x0f0) | ((t3 >> 2) & 0x0f);
+ if(c3 != '=') {
+ Fifo(mime_last++) = cc;
+ cc = ((t3 << 6) & 0x0c0) | (t4 & 0x3f);
+ if(c4 != '=')
+ Fifo(mime_last++) = cc;
+ }
+ } else {
+ return c1;
+ }
+ return Fifo(mime_top++);
+}
+
+static int
+mime_ungetc(c)
+unsigned int c;
+{
+ Fifo(mime_last++) = c;
+ return c;
+}
+
+
+static int
+mime_integrity(p)
+unsigned char *p;
+{
+ int c,d;
+ unsigned int q;
+ /* In buffered mode, read until =? or NL or buffer full
+ */
+ mime_input = mime_top;
+ mime_last = mime_top;
+ while(*p) Fifo(mime_input++) = *p++;
+ d = 0;
+ q = mime_input;
+ while((c=_GETC())!=EOF) {
+ if(((mime_input-mime_top)&MIME_BUF_MASK)==0) break;
+ if(c=='=' && d=='?') {
+ /* checked. skip header, start decode */
+ Fifo(mime_input++) = c;
+ mime_input = q;
+ return 1;
+ }
+ if(!( (c=='+'||c=='/'|| c=='=' || c=='?' ||
+ ('a'<=c && c<='z')||('A'<= c && c<='Z')||('0'<=c && c<='9'))))
+ break;
+ /* Should we check length mod 4? */
+ Fifo(mime_input++) = c;
+ d=c;
+ }
+ /* In case of Incomplete MIME, no MIME decode */
+ Fifo(mime_input++) = c;
+ mime_last = mime_input; /* point undecoded buffer */
+ mime_mode = 1; /* no decode on Fifo last in mime_getc */
+ return 1;
+}
+
+static int
+base64decode(c)
+ int c;
+{
+ int i;
+ if(c > '@')
+ if(c < '[')
+ i = c - 'A'; /* A..Z 0-25 */
+ else
+ i = c - 'G' /* - 'a' + 26 */ ; /* a..z 26-51 */
+ else if(c > '/')
+ i = c - '0' + '4' /* - '0' + 52 */ ; /* 0..9 52-61 */
+ else if(c == '+')
+ i = '>' /* 62 */ ; /* + 62 */
+ else
+ i = '?' /* 63 */ ; /* / 63 */
+ return (i);
+}
+
+#ifdef notdef
+int
+usage()
+{
+ fprintf(stderr,"USAGE: nkf(nkf32,wnkf,nkf2) -[flags] [in file] .. [out file for -O flag]\n");
+ fprintf(stderr,"Flags:\n");
+ fprintf(stderr,"b,u Output is bufferred (DEFAULT),Output is unbufferred\n");
+#ifdef DEFAULT_CODE_SJIS
+ fprintf(stderr,"j,s,e Outout code is JIS 7 bit, Shift JIS (DEFAULT), AT&T JIS (EUC)\n");
+#endif
+#ifdef DEFAULT_CODE_JIS
+ fprintf(stderr,"j,s,e Outout code is JIS 7 bit (DEFAULT), Shift JIS, AT&T JIS (EUC)\n");
+#endif
+#ifdef DEFAULT_CODE_EUC
+ fprintf(stderr,"j,s,e Outout code is JIS 7 bit, Shift JIS, AT&T JIS (EUC) (DEFAULT)\n");
+#endif
+ fprintf(stderr,"J,S,E Input assumption is JIS 7 bit , Shift JIS, AT&T JIS (EUC)\n");
+ fprintf(stderr,"t no conversion\n");
+ fprintf(stderr,"i_ Output sequence to designate JIS-kanji (DEFAULT B)\n");
+ fprintf(stderr,"o_ Output sequence to designate ASCII (DEFAULT B)\n");
+ fprintf(stderr,"r {de/en}crypt ROT13/47\n");
+ fprintf(stderr,"v Show this usage\n");
+ fprintf(stderr,"m[BQ] MIME decode [B:base64 stream,Q:quoted stream]\n");
+ fprintf(stderr,"l ISO8859-1 (Latin-1) support\n");
+ fprintf(stderr,"f Folding: -f60 or -f\n");
+ fprintf(stderr,"Z[0-2] Convert X0208 alphabet to ASCII 1: Kankaku to space,2: 2 spaces\n");
+ fprintf(stderr,"X,x Assume X0201 kana in MS-Kanji, -x preserves X0201\n");
+ fprintf(stderr,"B[0-2] Broken input 0: missing ESC,1: any X on ESC-[($]-X,2: ASCII on NL\n");
+#ifdef MSDOS
+ fprintf(stderr,"T Text mode output\n");
+#endif
+ fprintf(stderr,"O Output to File (DEFAULT 'nkf.out')\n");
+ fprintf(stderr,"d,c Delete \\r in line feed, Add \\r in line feed\n");
+ fprintf(stderr,"Network Kanji Filter Version %s (%s) "
+#if defined(MSDOS) && !defined(_Windows)
+ "for DOS"
+#endif
+#if !defined(__WIN32__) && defined(_Windows)
+ "for Win16"
+#endif
+#if defined(__WIN32__) && defined(_Windows)
+ "for Win32"
+#endif
+#ifdef __OS2__
+ "for OS/2"
+#endif
+ ,Version,Patchlevel);
+ fprintf(stderr,"\n%s\n",CopyRight);
+ return 0;
+}
+#endif /* notdef */
+
+static VALUE
+kconv_kconv(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE src, dst;
+ VALUE in, out;
+ int in_code, out_code;
+ char *codename = 0;
+
+ rb_scan_args(argc, argv, "12", &src, &out, &in);
+ Check_Type(src, T_STRING);
+
+ if (NIL_P(out)) {
+ codename = rb_get_kcode();
+ goto codeselect;
+ }
+ else if (TYPE(out) == T_STRING) {
+ codename = RSTRING(out)->ptr;
+ codeselect:
+ switch (codename[0]) {
+ case 'E': case 'e':
+ out_code = _EUC;
+ break;
+ case 'S': case 's':
+ out_code = _SJIS;
+ break;
+ case 'J': case 'j':
+ default:
+ out_code = _JIS;
+ break;
+ }
+ }
+ else {
+ out_code = NUM2INT(out);
+ if (out_code == _NOCONV) return (VALUE)src;
+ }
+ if (NIL_P(in)) {
+ in_code = _AUTO;
+ }
+ else if (TYPE(in) == T_STRING) {
+ switch (RSTRING(in)->ptr[0]) {
+ case 'E': case 'e':
+ in_code = _EUC;
+ break;
+ case 'S': case 's':
+ in_code = _SJIS;
+ break;
+ case 'J': case 'j':
+ in_code = _JIS;
+ break;
+ default:
+ in_code = _AUTO;
+ break;
+ }
+ }
+ else {
+ in_code = NUM2INT(in);
+ if (in_code == _NOCONV) return (VALUE)src;
+ }
+
+ dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
+ RSTRING(dst)->len = do_kconv(src, dst, out_code, in_code);
+
+ return dst;
+}
+
+static VALUE
+kconv_tojis(obj, src)
+ VALUE obj, src;
+{
+ VALUE dst;
+
+ Check_Type(src, T_STRING);
+
+ dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
+ RSTRING(dst)->len = do_kconv(src, dst, _JIS, _AUTO);
+
+ return dst;
+}
+
+static VALUE
+kconv_toeuc(obj, src)
+ VALUE obj, src;
+{
+ VALUE dst;
+
+ Check_Type(src, T_STRING);
+
+ dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
+ RSTRING(dst)->len = do_kconv(src, dst, _EUC, _AUTO);
+
+ return (VALUE)dst;
+}
+
+static VALUE
+kconv_tosjis(obj, src)
+ VALUE obj, src;
+{
+ VALUE dst;
+
+ Check_Type(src, T_STRING);
+
+ dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
+ RSTRING(dst)->len = do_kconv(src, dst, _SJIS, _AUTO);
+
+ return dst;
+}
+
+/*
+ * Character code detection - Algorithm described in:
+ * Ken Lunde. `Understanding Japanese Information Processing'
+ * O'Reilly & Associates, Sebastopol, CA.
+ */
+
+static VALUE
+kconv_guess(obj, src)
+ VALUE obj, src;
+{
+ unsigned char *p;
+ unsigned char *pend;
+ int sequence_counter = 0;
+
+ Check_Type(src, T_STRING);
+
+ p = RSTRING(src)->ptr;
+ pend = p + RSTRING(src)->len;
+
+#define INCR do {\
+ p++;\
+ if (p==pend) return INT2FIX(_UNKNOWN);\
+ sequence_counter++;\
+ if (sequence_counter % 2 == 1 && *p != 0xa4)\
+ sequence_counter = 0;\
+ if (6 <= sequence_counter) {\
+ sequence_counter = 0;\
+ return INT2FIX(_EUC);\
+ }\
+} while (0)
+
+ if (*p == 0xa4)
+ sequence_counter = 1;
+
+ while (p<pend) {
+ if (*p == '\033') {
+ return INT2FIX(_JIS);
+ }
+ if ('\000' < *p && *p < '\006'
+ || *p == 0x7f
+ || *p == 0xdf) {
+ return INT2FIX(_BINARY);
+ }
+ if (0x81 <= *p && *p <= 0x8d) {
+ return INT2FIX(_SJIS);
+ }
+ if (0x8f <= *p && *p <= 0x9f) {
+ return INT2FIX(_SJIS);
+ }
+ if (*p == 0x8e) { /* SS2 */
+ INCR;
+ if ((0x40 <= *p && *p <= 0x7e) ||
+ (0x80 <= *p && *p <= 0xa0) ||
+ (0xe0 <= *p && *p <= 0xfc))
+ return INT2FIX(_SJIS);
+ }
+ else if (0xa1 <= *p && *p <= 0xdf) {
+ INCR;
+ if (0xf0 <= *p && *p <= 0xfe)
+ return INT2FIX(_EUC);
+ if (0xe0 <= *p && *p <= 0xef) {
+ while (p < pend && *p >= 0x40) {
+ if (*p >= 0x81) {
+ if (*p <= 0x8d || (0x8f <= *p && *p <= 0x9f)) {
+ return INT2FIX(_SJIS);
+ }
+ else if (0xfd <= *p && *p <= 0xfe) {
+ return INT2FIX(_EUC);
+ }
+ }
+ INCR;
+ }
+ }
+ else if (*p <= 0x9f) {
+ return INT2FIX(_SJIS);
+ }
+ }
+ else if (0xf0 <= *p && *p <= 0xfe) {
+ return INT2FIX(_EUC);
+ }
+ else if (0xe0 <= *p && *p <= 0xef) {
+ INCR;
+ if ((0x40 <= *p && *p <= 0x7e) ||
+ (0x80 <= *p && *p <= 0xa0)) {
+ return INT2FIX(_SJIS);
+ }
+ if (0xfd <= *p && *p <= 0xfe) {
+ return INT2FIX(_EUC);
+ }
+ }
+ INCR;
+ }
+ return INT2FIX(_UNKNOWN);
+}
+
+void
+Init_kconv()
+{
+ VALUE mKconv = rb_define_module("Kconv");
+
+ rb_define_module_function(mKconv, "kconv", kconv_kconv, -1);
+ rb_define_module_function(mKconv, "tojis", kconv_tojis, 1);
+ rb_define_module_function(mKconv, "toeuc", kconv_toeuc, 1);
+ rb_define_module_function(mKconv, "tosjis", kconv_tosjis, 1);
+ rb_define_module_function(mKconv, "guess", kconv_guess, 1);
+
+ rb_define_const(mKconv, "AUTO", INT2FIX(_AUTO));
+ rb_define_const(mKconv, "JIS", INT2FIX(_JIS));
+ rb_define_const(mKconv, "EUC", INT2FIX(_EUC));
+ rb_define_const(mKconv, "SJIS", INT2FIX(_SJIS));
+ rb_define_const(mKconv, "BINARY", INT2FIX(_BINARY));
+ rb_define_const(mKconv, "NOCONV", INT2FIX(_NOCONV));
+ rb_define_const(mKconv, "UNKNOWN", INT2FIX(_UNKNOWN));
+}
+
+/**
+ ** パッチ制作者
+ ** void@merope.pleiades.or.jp (Kusakabe Youichi)
+ ** NIDE Naoyuki <nide@ics.nara-wu.ac.jp>
+ ** ohta@src.ricoh.co.jp (Junn Ohta)
+ ** inouet@strl.nhk.or.jp (Tomoyuki Inoue)
+ ** kiri@pulser.win.or.jp (Tetsuaki Kiriyama)
+ ** Kimihiko Sato <sato@sail.t.u-tokyo.ac.jp>
+ ** a_kuroe@kuroe.aoba.yokohama.jp (Akihiko Kuroe)
+ ** kono@ie.u-ryukyu.ac.jp (Shinji Kono)
+ ** GHG00637@nifty-serve.or.jp (COW)
+ ** j_kuro@pluto.ai.kyutech.ac.jp (Jun Kuroda)
+ **
+ ** 最終更新日
+ ** 1996.12.18
+ **/
+
+/* end */
diff --git a/ext/nkf/depend b/ext/nkf/depend
index 645bc869c8..13e32e6074 100644
--- a/ext/nkf/depend
+++ b/ext/nkf/depend
@@ -1 +1 @@
-nkf.o : nkf.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h nkf1.7/nkf.c
+nkf.o : nkf.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h $(srcdir)/nkf1.7/nkf.c
diff --git a/ext/nkf/nkf.c b/ext/nkf/nkf.c
index 80d0d2e4be..b59688cb03 100644
--- a/ext/nkf/nkf.c
+++ b/ext/nkf/nkf.c
@@ -31,14 +31,12 @@ rb_nkf_putchar(c)
{
if (output_ctr >= o_len) {
o_len += incsize;
- rb_str_cat(dst, "", incsize);
+ rb_str_cat(dst, 0, incsize);
+ output = RSTRING(dst)->ptr;
incsize *= 2;
}
-
output[output_ctr++] = c;
-/*
-printf("[[%c][%c][%d]]\n", c, output[output_ctr - 1], output_ctr);
-*/
+
return c;
}
@@ -51,6 +49,7 @@ rb_nkf_kconv(obj, opt, src)
{
int i;
char *opt_ptr, *opt_end;
+ volatile VALUE v;
reinit();
opt_ptr = str2cstr(opt, &i);
@@ -66,7 +65,8 @@ rb_nkf_kconv(obj, opt, src)
input_ctr = 0;
input = str2cstr(src, &i_len);
- dst = rb_str_new(0, i_len*3 + 10); /* large enough? */
+ dst = rb_str_new(0, i_len*3 + 10);
+ v = dst;
output_ctr = 0;
output = RSTRING(dst)->ptr;
@@ -78,18 +78,8 @@ rb_nkf_kconv(obj, opt, src)
}
kanji_convert(NULL);
- if (output_ctr > 0) output_ctr--;
- if (output[output_ctr] == '\0') {
-/*
-printf("([%c][%d])\n", output[output_ctr], output_ctr);
-*/
- RSTRING(dst)->len = output_ctr;
- } else {
-/*
-printf("<[%c][%d]>\n", output[output_ctr], output_ctr);
-*/
- RSTRING(dst)->len = output_ctr + 1;
- }
+ RSTRING(dst)->ptr[output_ctr] = '\0';
+ RSTRING(dst)->len = output_ctr;
return dst;
}
diff --git a/ext/pty/MANIFEST b/ext/pty/MANIFEST
index 5e5af7dd6b..f46d611e5b 100644
--- a/ext/pty/MANIFEST
+++ b/ext/pty/MANIFEST
@@ -3,6 +3,7 @@ README
README.expect
README.expect.jp
README.jp
+depend
expect_sample.rb
extconf.rb
lib/expect.rb
diff --git a/ext/pty/depend b/ext/pty/depend
new file mode 100644
index 0000000000..888be6c301
--- /dev/null
+++ b/ext/pty/depend
@@ -0,0 +1 @@
+pty.o: pty.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index 98be9044b7..b8c4e9acae 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -282,7 +282,9 @@ establishShell(shellname, info)
dup2(slave,2);
close(slave);
+#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID)
seteuid(getuid());
+#endif
argc = 0;
for (i = 0; shellname[i];) {
diff --git a/ext/readline/MANIFEST b/ext/readline/MANIFEST
index f73a899abb..f8bfd1ea2c 100644
--- a/ext/readline/MANIFEST
+++ b/ext/readline/MANIFEST
@@ -1,4 +1,5 @@
MANIFEST
README
+depend
extconf.rb
readline.c
diff --git a/ext/readline/depend b/ext/readline/depend
new file mode 100644
index 0000000000..6570c5a036
--- /dev/null
+++ b/ext/readline/depend
@@ -0,0 +1 @@
+readline.o: readline.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h
diff --git a/ext/sdbm/MANIFEST b/ext/sdbm/MANIFEST
index d0ed99ba77..8888e69ad4 100644
--- a/ext/sdbm/MANIFEST
+++ b/ext/sdbm/MANIFEST
@@ -1,5 +1,6 @@
MANIFEST
_sdbm.c
+depend
extconf.rb
init.c
sdbm.h
diff --git a/ext/sdbm/depend b/ext/sdbm/depend
new file mode 100644
index 0000000000..1d8b13d13f
--- /dev/null
+++ b/ext/sdbm/depend
@@ -0,0 +1,2 @@
+_sdbm.o: _sdbm.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h
+init.o: init.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h
diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb
index 47addfeff8..6a2937bb3f 100644
--- a/ext/socket/extconf.rb
+++ b/ext/socket/extconf.rb
@@ -41,6 +41,7 @@ end
$ipv6type = nil
$ipv6lib = nil
$ipv6libdir = nil
+$ipv6trylibc = nil
if $ipv6
if egrep_cpp("yes", <<EOF)
#include <netinet/in.h>
@@ -59,6 +60,7 @@ EOF
$ipv6type = "kame"
$ipv6lib="inet6"
$ipv6libdir="/usr/local/v6/lib"
+ $ipv6trylibc=true
$CFLAGS="-DINET6 "+$CFLAGS
elsif File.directory? "/usr/inet6"
$ipv6type = "linux"
@@ -100,7 +102,7 @@ EOF
if $ipv6lib
if File.directory? $ipv6libdir and File.exist? "#{$ipv6libdir}/lib#{$ipv6lib}.a"
$LOCAL_LIBS = " -L#$ipv6libdir -l#$ipv6lib"
- else
+ elsif !$ipv6trylibc
print <<EOS
Fatal: no #$ipv6lib library found. cannot continue.
@@ -135,6 +137,23 @@ end
#include <netdb.h>
#include <string.h>
#include <sys/socket.h>
+int
+main()
+{
+ struct sockaddr_storage ss;
+
+ ss.ss_family;
+ return 0;
+}
+EOF
+ $CFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CFLAGS
+end
+
+ if try_link(<<EOF)
+#include <sys/types.h>
+#include <netdb.h>
+#include <string.h>
+#include <sys/socket.h>
#include <netinet/in.h>
int
main()
@@ -148,7 +167,6 @@ EOF
$CFLAGS="-DHAVE_SA_LEN "+$CFLAGS
end
-have_header("sys/sysctl.h")
have_header("netinet/tcp.h")
have_header("netinet/udp.h")
@@ -160,6 +178,10 @@ if try_run(<<EOF)
#include <sys/socket.h>
#include <netinet/in.h>
+#ifndef AF_LOCAL
+#define AF_LOCAL AF_UNIX
+#endif
+
main()
{
int passive, gaierr, inet4 = 0, inet6 = 0;
@@ -176,6 +198,7 @@ main()
goto bad;
}
for (ai = aitop; ai; ai = ai->ai_next) {
+ if (ai->ai_family == AF_LOCAL) continue;
if (ai->ai_addr == NULL ||
ai->ai_addrlen == 0 ||
getnameinfo(ai->ai_addr, ai->ai_addrlen,
@@ -221,7 +244,9 @@ main()
}
}
- if (inet6 != 2 || inet4 != 2)
+ if (!(inet4 == 0 || inet4 == 2))
+ goto bad;
+ if (!(inet6 == 0 || inet6 == 2))
goto bad;
if (aitop)
diff --git a/ext/socket/getaddrinfo.c b/ext/socket/getaddrinfo.c
index 501ebd5006..fbedac4cbb 100644
--- a/ext/socket/getaddrinfo.c
+++ b/ext/socket/getaddrinfo.c
@@ -38,14 +38,10 @@
* - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag.
*/
+#include "config.h"
#include <sys/types.h>
#ifndef NT
#include <sys/param.h>
-#endif
-#ifdef HAVE_SYSCTL_H
-#include <sys/sysctl.h>
-#endif
-#ifndef NT
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -71,7 +67,6 @@
#include <socks.h>
#endif
-#include "config.h"
#include "addrinfo.h"
#include "sockport.h"
@@ -135,6 +130,11 @@ static struct afd {
#define PTON_MAX 4
#endif
+#ifndef INET6
+#ifndef NT
+extern int h_errno;
+#endif
+#endif
static int get_name __P((const char *, struct afd *,
struct addrinfo **, char *, struct addrinfo *,
@@ -580,11 +580,6 @@ get_addr(hostname, af, res, pai, port0)
struct afd *afd;
int i, error = 0, h_error;
char *ap;
-#ifndef INET6
-#ifndef NT
- extern int h_errno;
-#endif
-#endif
top = NULL;
sentinel.ai_next = NULL;
diff --git a/ext/socket/getnameinfo.c b/ext/socket/getnameinfo.c
index cb65e4c070..774177c8c1 100644
--- a/ext/socket/getnameinfo.c
+++ b/ext/socket/getnameinfo.c
@@ -34,6 +34,7 @@
* but INRIA implementation returns EAI_xxx defined for getaddrinfo().
*/
+#include "config.h"
#include <sys/types.h>
#ifndef NT
#include <sys/socket.h>
@@ -60,10 +61,15 @@
#include <socks.h>
#endif
-#include "config.h"
#include "addrinfo.h"
#include "sockport.h"
+#ifndef INET6
+#ifndef NT
+extern int h_errno;
+#endif
+#endif
+
#define SUCCESS 0
#define ANY 0
#define YES 1
@@ -149,9 +155,6 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
int h_error;
char numserv[512];
char numaddr[512];
-#ifndef NT
- extern int h_errno;
-#endif
if (sa == NULL)
return ENI_NOSOCKET;
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index a1d707122e..43bde950f4 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -16,10 +16,10 @@
#ifndef NT
#include <sys/socket.h>
#include <netinet/in.h>
-#ifdef NETINET_TCP
+#ifdef HAVE_NETINET_TCP_H
# include <netinet/tcp.h>
#endif
-#ifdef NETINET_UDP
+#ifdef HAVE_NETINET_UDP_H
# include <netinet/udp.h>
#endif
#include <netdb.h>
@@ -81,10 +81,27 @@ int Rconnect();
#define INET_SERVER 1
#define INET_SOCKS 2
-#ifndef INET6
-# undef ss_family
-# define sockaddr_storage sockaddr
-# define ss_family sa_family
+#ifndef HAVE_SOCKADDR_STORAGE
+/*
+ * RFC 2553: protocol-independent placeholder for socket addresses
+ */
+#define _SS_MAXSIZE 128
+#define _SS_ALIGNSIZE (sizeof(double))
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) * 2)
+#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) * 2 - \
+ _SS_PAD1SIZE - _SS_ALIGNSIZE)
+
+struct sockaddr_storage {
+#ifdef HAVE_SA_LEN
+ unsigned char ss_len; /* address length */
+ unsigned char ss_family; /* address family */
+#else
+ unsigned short ss_family;
+#endif
+ char __ss_pad1[_SS_PAD1SIZE];
+ double __ss_align; /* force desired structure storage alignment */
+ char __ss_pad2[_SS_PAD2SIZE];
+};
#endif
#ifdef NT
@@ -93,16 +110,12 @@ sock_finalize(fptr)
OpenFile *fptr;
{
SOCKET s;
- extern int errno;
if (!fptr->f) return;
-
- myfdclose(fptr->f);
- if(fptr->f2) myfdclose(fptr->f);
-/*
- s = get_osfhandle(fileno(fptr->f));
+ s = get_osfhandle(fileno(fptr->f));
+ myfdclose(fptr->f);
+ if (fptr->f2) myfdclose(fptr->f2);
closesocket(s);
-*/
}
#endif
@@ -378,8 +391,8 @@ s_recv(sock, argc, argv, from)
GetOpenFile(sock, fptr);
fd = fileno(fptr->f);
rb_thread_wait_fd(fd);
- TRAP_BEG;
retry:
+ TRAP_BEG;
RSTRING(str)->len = recvfrom(fd, RSTRING(str)->ptr, RSTRING(str)->len, flags,
(struct sockaddr*)buf, &alen);
TRAP_END;
@@ -498,6 +511,7 @@ ip_addrsetup(host, port)
long i = NUM2LONG(host);
mkinetaddr(htonl(i), hbuf, sizeof(hbuf));
+ hostp = hbuf;
}
else {
char *name = STR2CSTR(host);
@@ -508,11 +522,14 @@ ip_addrsetup(host, port)
else if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
mkinetaddr(INADDR_BROADCAST, hbuf, sizeof(hbuf));
}
+ else if (strlen(name) > sizeof(hbuf)-1) {
+ rb_raise(rb_eSocket, "hostname too long (%d)", strlen(name));
+ }
else {
strcpy(hbuf, name);
}
+ hostp = hbuf;
}
- hostp = hbuf;
if (NIL_P(port)) {
portp = 0;
}
@@ -529,6 +546,9 @@ ip_addrsetup(host, port)
hints.ai_socktype = SOCK_DGRAM;
error = getaddrinfo(hostp, portp, &hints, &res);
if (error) {
+ if (hostp && hostp[strlen(hostp)-1] == '\n') {
+ rb_raise(rb_eSocket, "newline at the end of hostname");
+ }
rb_raise(rb_eSocket, "%s", gai_strerror(error));
}
@@ -890,7 +910,9 @@ tcp_s_gethostbyname(obj, host)
struct sockaddr_in6 sin6;
MEMZERO(&sin6, struct sockaddr_in6, 1);
sin6.sin6_family = AF_INET;
+#ifdef SIN6_LEN
sin6.sin6_len = sizeof(sin6);
+#endif
memcpy((char *) &sin6.sin6_addr, *pch, h->h_length);
h = gethostbyaddr((char *)&sin6.sin6_addr,
sizeof(sin6.sin6_addr),
diff --git a/ext/tcltklib/extconf.rb b/ext/tcltklib/extconf.rb
index e1086855ba..713cc811e5 100644
--- a/ext/tcltklib/extconf.rb
+++ b/ext/tcltklib/extconf.rb
@@ -21,6 +21,7 @@ def find_tcl(tcllib)
find_library(tcllib, func, *paths)
else
find_library("tcl", func, *paths) or
+ find_library("tcl8.2", func, *paths) or
find_library("tcl8.0", func, *paths) or
find_library("tcl7.6", func, *paths)
end
@@ -33,6 +34,7 @@ def find_tk(tklib)
find_library(tklib, func, *paths)
else
find_library("tk", func, *paths) or
+ find_library("tk8.2", func, *paths) or
find_library("tk8.0", func, *paths) or
find_library("tk4.2", func, *paths)
end
diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb
index f831dbc78a..c344a2bf8e 100644
--- a/ext/tk/lib/tk.rb
+++ b/ext/tk/lib/tk.rb
@@ -196,7 +196,9 @@ module TkComm
def _get_eval_string(str)
return nil if str == None
- if str.kind_of?(Hash)
+ if str.kind_of?(String)
+ # do nothing
+ elsif str.kind_of?(Hash)
str = hash_kv(str).join(" ")
elsif str.kind_of?(Array)
str = array2tk_list(str)
@@ -235,7 +237,7 @@ module TkComm
return format("rb_out %s", id);
end
def uninstall_cmd(id)
- id = $1 if /rb_out (c\d+)/
+ id = $1 if /rb_out (c\d+)/ =~ id
Tk_CMDTBL[id] = nil
end
private :install_cmd, :uninstall_cmd
@@ -347,15 +349,6 @@ module TkComm
def _bind_append(what, context, cmd, args=nil)
_bind_core('+', what, context, cmd, args)
end
- private :install_bind, :tk_event_sequence, :_bind_core, :_bind, :_bind_append
-
- def bind_all(context, cmd=Proc.new, args=nil)
- _bind(['bind', 'all'], context, cmd, args)
- end
-
- def bind_append_all(context, cmd=Proc.new, args=nil)
- _bind_append(['bind', 'all'], context, cmd, args)
- end
def _bindinfo(what, context=nil)
if context
@@ -372,11 +365,33 @@ module TkComm
}
end
end
+ private :install_bind, :tk_event_sequence,
+ :_bind_core, :_bind, :_bind_append, :_bindinfo
+
+ def bind(tagOrClass, context, cmd=Proc.new, args=nil)
+ _bind(["bind", tagOrClass], context, cmd, args)
+ end
+
+ def bind_append(tagOrClass, context, cmd=Proc.new, args=nil)
+ _bind_append(["bind", tagOrClass], context, cmd, args)
+ end
def bindinfo(tagOrClass, context=nil)
_bindinfo(['bind', tagOrClass], context)
end
+ def bind_all(context, cmd=Proc.new, args=nil)
+ _bind(['bind', 'all'], context, cmd, args)
+ end
+
+ def bind_append_all(context, cmd=Proc.new, args=nil)
+ _bind_append(['bind', 'all'], context, cmd, args)
+ end
+
+ def bindinfo_all(context=nil)
+ _bindinfo(['bind', 'all'], context)
+ end
+
def pack(*args)
TkPack.configure *args
end
@@ -401,14 +416,14 @@ module TkCore
INTERP = TclTkIp.new
- INTERP._invoke("proc", "rb_out", "args", "if {[set st [catch {ruby [format \"TkCore.callback %%Q!%s!\" $args]} ret]] != 0} {return -code $st $ret} {return $ret}")
+ INTERP._invoke("proc", "rb_out", "args", "if {[set st [catch {ruby [format \"TkCore.callback %%Q!%s!\" $args]} ret]] != 0} {if {[regsub -all {!} $args {\\!} newargs] == 0} {return -code $st $ret} {if {[set st [catch {ruby [format \"TkCore.callback %%Q!%s!\" $newargs]} ret]] != 0} {return -code $st $ret} {return $ret}}} {return $ret}")
def callback_break
- raise TkCallbackBreak, "Tk callback returns 'break' status"
+ fail TkCallbackBreak, "Tk callback returns 'break' status"
end
def callback_continue
- raise TkCallbackContinue, "Tk callback returns 'continue' status"
+ fail TkCallbackContinue, "Tk callback returns 'continue' status"
end
def after(ms, cmd=Proc.new)
@@ -514,8 +529,8 @@ module TkCore
args.unshift "unknown"
res = INTERP._invoke(*args)
rescue
- raise unless /^invalid command/ =~ $!
- raise err
+ fail unless /^invalid command/ =~ $!
+ fail err
end
end
if INTERP._return_value() != 0
@@ -570,13 +585,39 @@ module Tk
def yscrollcommand(cmd=Proc.new)
configure_cmd 'yscrollcommand', cmd
end
+ def xview(*index)
+ v = tk_send('xview', *index)
+ list(v) if index.size == 0
+ end
+ def yview(*index)
+ v = tk_send('yview', *index)
+ list(v) if index.size == 0
+ end
+ def xscrollbar(bar=nil)
+ if bar
+ @xscrollbar = bar
+ @xscrollbar.orient 'horizontal'
+ self.xscrollcommand {|arg| @xscrollbar.set *arg}
+ @xscrollbar.command {|arg| self.xview *arg}
+ end
+ @xscrollbar
+ end
+ def yscrollbar(bar=nil)
+ if bar
+ @yscrollbar = bar
+ @yscrollbar.orient 'vertical'
+ self.yscrollcommand {|arg| @yscrollbar.set *arg}
+ @yscrollbar.command {|arg| self.yview *arg}
+ end
+ @yscrollbar
+ end
end
module Wm
include TkComm
def aspect(*args)
- w = window(tk_call('wm', 'grid', path, *args))
- w.split.collect{|s|s.to_i} if args.length == 0
+ w = tk_call('wm', 'aspect', path, *args)
+ list(w) if args.length == 0
end
def client(name=None)
tk_call 'wm', 'client', path, name
@@ -594,17 +635,18 @@ module Tk
tk_call 'wm', 'focusmodel', path, *args
end
def frame
- tk_call 'wm', 'frame', path
+ tk_call('wm', 'frame', path)
end
def geometry(*args)
- list(tk_call('wm', 'geometry', path, *args))
+ tk_call('wm', 'geometry', path, *args)
end
def grid(*args)
w = tk_call('wm', 'grid', path, *args)
list(w) if args.size == 0
end
def group(*args)
- tk_call 'wm', 'group', path, *args
+ w = tk_call 'wm', 'group', path, *args
+ window(w) if args.size == 0
end
def iconbitmap(*args)
tk_call 'wm', 'iconbitmap', path, *args
@@ -628,7 +670,7 @@ module Tk
end
def maxsize(*args)
w = tk_call('wm', 'maxsize', path, *args)
- list(w) if not args.size == 0
+ list(w) if args.size == 0
end
def minsize(*args)
w = tk_call('wm', 'minsize', path, *args)
@@ -661,7 +703,7 @@ module Tk
end
end
def sizefrom(*args)
- list(tk_call('wm', 'sizefrom', path, *args))
+ tk_call('wm', 'sizefrom', path, *args)
end
def state
tk_call 'wm', 'state', path
@@ -670,7 +712,7 @@ module Tk
tk_call 'wm', 'title', path, *args
end
def transient(*args)
- tk_call 'wm', 'transient', path, *args
+ window(tk_call 'wm', 'transient', path, *args)
end
def withdraw
tk_call 'wm', 'withdraw', path
@@ -678,6 +720,46 @@ module Tk
end
end
+module TkBindCore
+ def bind(context, cmd=Proc.new, args=nil)
+ Tk.bind(to_eval, context, cmd, args)
+ end
+
+ def bind_append(context, cmd=Proc.new, args=nil)
+ Tk.bind_append(to_eval, context, cmd, args)
+ end
+
+ def bindinfo(context=nil)
+ Tk.bindinfo(to_eval, context)
+ end
+end
+
+class TkBindTag
+ include TkBindCore
+
+ BTagID_TBL = {}
+ Tk_BINDTAG_ID = ["btag00000"]
+
+ def TkBindTag.id2obj(id)
+ BTagID_TBL[id]? BTagID_TBL[id]: id
+ end
+
+ def initialize(*args)
+ @id = Tk_BINDTAG_ID[0]
+ Tk_BINDTAG_ID[0] = Tk_BINDTAG_ID[0].succ
+ BTagID_TBL[@id] = self
+ bind(*args) if args != []
+ end
+
+ def to_eval
+ @id
+ end
+
+ def inspect
+ format "#<TkBindTag: %s>", @id
+ end
+end
+
class TkVariable
include Tk
extend TkCore
@@ -730,7 +812,7 @@ class TkVariable
INTERP._eval(format('global %s; set %s', @id, @id))
rescue
if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1"
- raise
+ fail
else
Hash[*tk_split_simplelist(INTERP._eval(format('global %s; array get %s',
@id, @id)))]
@@ -744,7 +826,7 @@ class TkVariable
INTERP._eval(format('global %s; set %s %s', @id, @id, s))
rescue
if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1"
- raise
+ fail
else
if val == []
INTERP._eval(format('global %s; unset %s; set %s(0) 0; unset %s(0)',
@@ -761,7 +843,7 @@ class TkVariable
INTERP._eval(format('global %s; unset %s; array set %s %s',
@id, @id, @id, s))
else
- raise
+ fail
end
end
end
@@ -790,7 +872,7 @@ class TkVariable
end
def inspect
- format "<TkVariable: %s>", @id
+ format "#<TkVariable: %s>", @id
end
def ==(other)
@@ -1063,19 +1145,19 @@ module TkWinfo
include Tk
extend Tk
def TkWinfo.atom(name)
- tk_call 'winfo', name
+ number(tk_call 'winfo', 'atom', name)
end
def winfo_atom(name)
TkWinfo.atom name
end
def TkWinfo.atomname(id)
- tk_call 'winfo', id
+ tk_call 'winfo', 'atomname', id
end
def winfo_atomname(id)
TkWinfo.atomname id
end
def TkWinfo.cells(window)
- number(tk_call('winfo', window.path))
+ number(tk_call('winfo', 'cells', window.path))
end
def winfo_cells
TkWinfo.cells self
@@ -1093,6 +1175,12 @@ module TkWinfo
def winfo_classname
TkWinfo.classname self
end
+ def TkWinfo.colormapfull(window)
+ bool(tk_call('winfo', 'colormapfull', window.path))
+ end
+ def winfo_colormapfull
+ TkWinfo.colormapfull self
+ end
def TkWinfo.containing(rootX, rootY)
path = tk_call('winfo', 'containing', rootX, rootY)
window(path)
@@ -1119,7 +1207,7 @@ module TkWinfo
TkWinfo.fpixels self, number
end
def TkWinfo.geometry(window)
- list(tk_call('winfo', 'geometry', window.path))
+ tk_call('winfo', 'geometry', window.path)
end
def winfo_geometry
TkWinfo.geometry self
@@ -1131,15 +1219,15 @@ module TkWinfo
TkWinfo.height self
end
def TkWinfo.id(window)
- number(tk_call('winfo', 'id', window.path))
+ tk_call('winfo', 'id', window.path)
end
def winfo_id
TkWinfo.id self
end
def TkWinfo.interps(window=nil)
if window
- tk_split_simplelist(tk_call('winfo', '-displayof', window.path,
- 'interps'))
+ tk_split_simplelist(tk_call('winfo', 'interps',
+ '-displayof', window.path))
else
tk_split_simplelist(tk_call('winfo', 'interps'))
end
@@ -1153,8 +1241,14 @@ module TkWinfo
def winfo_mapped?
TkWinfo.mapped? self
end
+ def TkWinfo.manager(window)
+ tk_call('winfo', 'manager', window.path)
+ end
+ def winfo_manager
+ TkWinfo.manager self
+ end
def TkWinfo.appname(window)
- bool(tk_call('winfo', 'name', window.path))
+ tk_call('winfo', 'name', window.path)
end
def winfo_appname
TkWinfo.appname self
@@ -1255,6 +1349,12 @@ module TkWinfo
def winfo_screenwidth
TkWinfo.screenwidth self
end
+ def TkWinfo.server(window)
+ tk_call 'winfo', 'server', window.path
+ end
+ def winfo_server
+ TkWinfo.server self
+ end
def TkWinfo.toplevel(window)
window(tk_call('winfo', 'toplevel', window.path))
end
@@ -1267,7 +1367,24 @@ module TkWinfo
def winfo_visual
TkWinfo.visual self
end
- def TkWinfo.vrootheigh(window)
+ def TkWinfo.visualid(window)
+ tk_call 'winfo', 'visualid', window.path
+ end
+ def winfo_visualid
+ TkWinfo.visualid self
+ end
+ def TkWinfo.visualsavailable(window, includeids=false)
+ if includeids
+ v = tk_call('winfo', 'visualsavailable', window.path, "includeids")
+ else
+ v = tk_call('winfo', 'visualsavailable', window.path)
+ end
+ list(v)
+ end
+ def winfo_visualsavailable(includeids=false)
+ TkWinfo.visualsavailable self, includeids
+ end
+ def TkWinfo.vrootheight(window)
number(tk_call('winfo', 'vrootheight', window.path))
end
def winfo_vrootheight
@@ -1452,24 +1569,20 @@ module TkTreatFont
alias fontobj font_configinfo
def font_configure(slot)
- if (fnt = slot['font'])
- slot['font'] = nil
+ if (fnt = slot.delete('font'))
if fnt.kind_of? TkFont
return fnt.call_font_configure(self.path, self.path,'configure',slot)
else
latinfont_configure(fnt) if fnt
end
end
- if (ltn = slot['latinfont'])
- slot['latinfont'] = nil
+ if (ltn = slot.delete('latinfont'))
latinfont_configure(ltn) if ltn
end
- if (ltn = slot['asciifont'])
- slot['asciifont'] = nil
+ if (ltn = slot.delete('asciifont'))
latinfont_configure(ltn) if ltn
end
- if (knj = slot['kanjifont'])
- slot['kanjifont'] = nil
+ if (knj = slot.delete('kanjifont'))
kanjifont_configure(knj) if knj
end
@@ -1544,6 +1657,7 @@ end
class TkObject<TkKernel
include Tk
include TkTreatFont
+ include TkBindCore
def path
return @path
@@ -1640,18 +1754,6 @@ class TkObject<TkKernel
end
end
- def bind(context, cmd=Proc.new, args=nil)
- _bind(["bind", to_eval], context, cmd, args)
- end
-
- def bind_append(context, cmd=Proc.new, args=nil)
- _bind_append(["bind", to_eval], context, cmd, args)
- end
-
- def bindinfo(context=nil)
- _bindinfo(['bind', to_eval], context)
- end
-
def event_generate(context, keys=nil)
if keys
tk_call('event', 'generate', path,
@@ -1675,7 +1777,7 @@ class TkObject<TkKernel
end
class TkWindow<TkObject
-# extend TkClassBind
+ extend TkBindCore
def initialize(parent=nil, keys=nil)
install_win(if parent then parent.path end)
@@ -1823,11 +1925,15 @@ class TkWindow<TkObject
fail unless taglist.kind_of? Array
tk_call('bindtags', path, taglist)
else
- tk_split_list(tk_call('bindtags', path)).collect{|tag|
- if tag == nil
- '.'
- elsif tag.kind_of?(String) && (cls = WidgetClassNames[tag])
- cls
+ list(tk_call('bindtags', path)).collect{|tag|
+ if tag.kind_of?(String)
+ if cls = WidgetClassNames[tag]
+ cls
+ elsif btag = TkBindTag.id2obj(tag)
+ btag
+ else
+ tag
+ end
else
tag
end
@@ -1878,42 +1984,24 @@ class TkToplevel<TkWindow
@classname = classname
if keys.kind_of? Hash
keys = keys.dup
- if keys['classname']
- @classname = keys['classname']
- keys['classname'] = nil
- end
- if keys['colormap']
- @colormap = keys['colormap']
- keys['colormap'] = nil
- end
- if keys['container']
- @classname = keys['container']
- keys['classname'] = nil
- end
- if keys['screen']
- @screen = keys['screen']
- keys['screen'] = nil
- end
- if keys['use']
- @use = keys['use']
- keys['use'] = nil
- end
- if keys['visual']
- @screen = keys['visual']
- keys['visual'] = nil
- end
+ @classname = keys.delete('classname') if keys.key?('classname')
+ @colormap = keys.delete('colormap') if keys.key?('colormap')
+ @container = keys.delete('container') if keys.key?('container')
+ @screen = keys.delete('screen') if keys.key?('screen')
+ @use = keys.delete('use') if keys.key?('use')
+ @visual = keys.delete('visual') if keys.key?('visual')
end
super(parent, keys)
end
def create_self
s = []
- s.push << "-class" << @classname if @classname
- s.push << "-colormap" << @colormap if @colormap
- s.push << "-container" << @container if @container
- s.push << "-screen" << @screen if @screen
- s.push << "-use" << @use if @use
- s.push << "-visual" << @visual if @visual
+ s << "-class" << @classname if @classname
+ s << "-colormap" << @colormap if @colormap
+ s << "-container" << @container if @container
+ s << "-screen" << @screen if @screen
+ s << "-use" << @use if @use
+ s << "-visual" << @visual if @visual
tk_call 'toplevel', @path, *s
end
@@ -1932,32 +2020,20 @@ class TkFrame<TkWindow
def initialize(parent=nil, keys=nil)
if keys.kind_of? Hash
keys = keys.dup
- if keys['classname']
- @classname = keys['classname']
- keys['classname'] = nil
- end
- if keys['colormap']
- @colormap = keys['colormap']
- keys['colormap'] = nil
- end
- if keys['container']
- @classname = keys['container']
- keys['classname'] = nil
- end
- if keys['visual']
- @screen = keys['visual']
- keys['visual'] = nil
- end
+ @classname = keys.delete('classname') if keys.key?('classname')
+ @colormap = keys.delete('colormap') if keys.key?('colormap')
+ @container = keys.delete('container') if keys.key?('container')
+ @visual = keys.delete('visual') if keys.key?('visual')
end
super(parent, keys)
end
def create_self
s = []
- s.push << "-class" << @classname if @classname
- s.push << "-colormap" << @colormap if @colormap
- s.push << "-container" << @container if @container
- s.push << "-visual" << @visual if @visual
+ s << "-class" << @classname if @classname
+ s << "-colormap" << @colormap if @colormap
+ s << "-container" << @container if @container
+ s << "-visual" << @visual if @visual
tk_call 'frame', @path, *s
end
end
@@ -2101,7 +2177,7 @@ end
class TkTextWin<TkWindow
def create_self
- raise TypeError, "TkTextWin is abstract class"
+ fail TypeError, "TkTextWin is abstract class"
end
def bbox(index)
@@ -2131,6 +2207,8 @@ class TkTextWin<TkWindow
end
class TkListbox<TkTextWin
+ include Scrollable
+
WidgetClassNames['Listbox'] = self
def TkListbox.to_eval
'Listbox'
@@ -2145,10 +2223,18 @@ class TkListbox<TkTextWin
def curselection
list(tk_send('curselection'))
end
+ def get(*index)
+ v = tk_send('get', *index)
+ if index.size == 1
+ v
+ else
+ tk_split_simplelist(v)
+ end
+ end
def nearest(y)
tk_send('nearest', y).to_i
end
- def size(y)
+ def size
tk_send('size').to_i
end
def selection_anchor(index)
@@ -2157,20 +2243,12 @@ class TkListbox<TkTextWin
def selection_clear(first, last=None)
tk_send 'selection', 'clear', first, last
end
- def selection_includes
- bool(tk_send('selection', 'includes'))
+ def selection_includes(index)
+ bool(tk_send('selection', 'includes', index))
end
def selection_set(first, last=None)
tk_send 'selection', 'set', first, last
end
- def xview(cmd, *more)
- v = tk_send('xview', cmd, *more)
- v.to_i if more.size == 0
- end
- def yview(cmd, *more)
- v = tk_send('yview', cmd, *more)
- v.to_i if more.size == 0
- end
end
module TkTreatMenuEntryFont
@@ -2187,8 +2265,7 @@ module TkTreatMenuEntryFont
def tagfont_configure(index, slot)
pathname = self.path + ';' + index
- if (fnt = slot['font'])
- slot['font'] = nil
+ if (fnt = slot.delete('font'))
if fnt.kind_of? TkFont
return fnt.call_font_configure(pathname,
self.path,'entryconfigure',index,slot)
@@ -2196,16 +2273,13 @@ module TkTreatMenuEntryFont
latintagfont_configure(index, fnt) if fnt
end
end
- if (ltn = slot['latinfont'])
- slot['latinfont'] = nil
+ if (ltn = slot.delete('latinfont'))
latintagfont_configure(index, ltn) if ltn
end
- if (ltn = slot['asciifont'])
- slot['asciifont'] = nil
+ if (ltn = slot.delete('asciifont'))
latintagfont_configure(index, ltn) if ltn
end
- if (knj = slot['kanjifont'])
- slot['kanjifont'] = nil
+ if (knj = slot.delete('kanjifont'))
kanjitagfont_configure(index, knj) if knj
end
diff --git a/ext/tk/lib/tkcanvas.rb b/ext/tk/lib/tkcanvas.rb
index 40bfa54846..80c36f6ed8 100644
--- a/ext/tk/lib/tkcanvas.rb
+++ b/ext/tk/lib/tkcanvas.rb
@@ -30,8 +30,7 @@ module TkTreatCItemFont
else
pathname = self.path + ';' + tagOrId.to_s
end
- if (fnt = slot['font'])
- slot['font'] = nil
+ if (fnt = slot.delete('font'))
if fnt.kind_of? TkFont
return fnt.call_font_configure(pathname,
self.path,'itemconfigure',tagOrId,slot)
@@ -39,16 +38,13 @@ module TkTreatCItemFont
latintagfont_configure(tagOrId, fnt) if fnt
end
end
- if (ltn = slot['latinfont'])
- slot['latinfont'] = nil
+ if (ltn = slot.delete('latinfont'))
latintagfont_configure(tagOrId, ltn) if ltn
end
- if (ltn = slot['asciifont'])
- slot['asciifont'] = nil
+ if (ltn = slot.delete('asciifont'))
latintagfont_configure(tagOrId, ltn) if ltn
end
- if (knj = slot['kanjifont'])
- slot['kanjifont'] = nil
+ if (knj = slot.delete('kanjifont'))
kanjitagfont_configure(tagOrId, knj) if knj
end
@@ -129,6 +125,7 @@ end
class TkCanvas<TkWindow
include TkTreatCItemFont
+ include Scrollable
WidgetClassName = 'Canvas'.freeze
WidgetClassNames[WidgetClassName] = self
@@ -492,15 +489,15 @@ class TkcTag<TkObject
CTagID_TBL[id]? CTagID_TBL[id]: id
end
- $tk_canvas_tag = 'ctag0000'
+ Tk_CanvasTag_ID = ['ctag0000']
def initialize(parent, mode=nil, *args)
if not parent.kind_of?(TkCanvas)
fail format("%s need to be TkCanvas", parent.inspect)
end
@c = parent
- @path = @id = $tk_canvas_tag
+ @path = @id = Tk_CanvasTag_ID[0]
CTagID_TBL[@id] = self
- $tk_canvas_tag = $tk_canvas_tag.succ
+ Tk_CanvasTag_ID[0] = Tk_CanvasTag_ID[0].succ
if mode
tk_call @c.path, "addtag", @id, mode, *args
end
@@ -575,15 +572,15 @@ class TkcTagCurrent<TkcTag
end
class TkcGroup<TkcTag
- $tk_group_id = 'tkg00000'
+ Tk_cGroup_ID = ['tkcg00000']
def create_self(parent, *args)
if not parent.kind_of?(TkCanvas)
fail format("%s need to be TkCanvas", parent.inspect)
end
@c = parent
- @path = @id = $tk_group_id
+ @path = @id = Tk_cGroup_ID[0]
CTagID_TBL[@id] = self
- $tk_group_id = $tk_group_id.succ
+ Tk_cGroup_ID[0] = Tk_cGroup_ID[0].succ
add(*args) if args != []
end
@@ -705,10 +702,10 @@ class TkImage<TkObject
Tk_IMGTBL = {}
- $tk_image_id = 'i00000'
+ Tk_Image_ID = ['i00000']
def initialize(keys=nil)
- @path = $tk_image_id
- $tk_image_id = $tk_image_id.succ
+ @path = Tk_Image_ID[0]
+ Tk_Image_ID[0] = Tk_Image_ID[0].succ
tk_call 'image', 'create', @type, @path, *hash_kv(keys)
Tk_IMGTBL[@path] = self
end
diff --git a/ext/tk/lib/tkentry.rb b/ext/tk/lib/tkentry.rb
index 5822c00e53..f35d2eef00 100644
--- a/ext/tk/lib/tkentry.rb
+++ b/ext/tk/lib/tkentry.rb
@@ -6,6 +6,8 @@
require 'tk.rb'
class TkEntry<TkLabel
+ include Scrollable
+
WidgetClassName = 'Entry'.freeze
WidgetClassNames[WidgetClassName] = self
def self.to_eval
@@ -15,9 +17,6 @@ class TkEntry<TkLabel
def create_self
tk_call 'entry', @path
end
- def scrollcommand(cmd)
- configure 'scrollcommand', cmd
- end
def delete(s, e=None)
tk_send 'delete', s, e
@@ -45,7 +44,7 @@ class TkEntry<TkLabel
tk_send 'selection', 'adjust', index
end
def selection_clear
- tk_send 'selection', 'clear', 'end'
+ tk_send 'selection', 'clear'
end
def selection_from(index)
tk_send 'selection', 'from', index
@@ -59,9 +58,6 @@ class TkEntry<TkLabel
def selection_to(index)
tk_send 'selection', 'to', index
end
- def xview(*index)
- tk_send 'xview', *index
- end
def value
tk_send 'get'
diff --git a/ext/tk/lib/tkfont.rb b/ext/tk/lib/tkfont.rb
index c680d166e7..2683260d69 100644
--- a/ext/tk/lib/tkfont.rb
+++ b/ext/tk/lib/tkfont.rb
@@ -667,7 +667,20 @@ class TkFont
alias measure_core measure_core_tk8x
alias metrics_core metrics_core_tk8x
- when /^8\.1/
+ when /^8\.[12]/
+ alias create_latinfont create_latinfont_tk8x
+ alias create_kanjifont create_kanjifont_tk81
+ alias create_compoundfont create_compoundfont_tk81
+ alias actual_core actual_core_tk8x
+ alias configure_core configure_core_tk8x
+ alias configinfo_core configinfo_core_tk8x
+ alias delete_core delete_core_tk8x
+ alias latin_replace_core latin_replace_core_tk8x
+ alias kanji_replace_core kanji_replace_core_tk81
+ alias measure_core measure_core_tk8x
+ alias metrics_core metrics_core_tk8x
+
+ when /^8\.*/
alias create_latinfont create_latinfont_tk8x
alias create_kanjifont create_kanjifont_tk81
alias create_compoundfont create_compoundfont_tk81
diff --git a/ext/tk/lib/tktext.rb b/ext/tk/lib/tktext.rb
index 83999cb3e2..7872e6a078 100644
--- a/ext/tk/lib/tktext.rb
+++ b/ext/tk/lib/tktext.rb
@@ -28,8 +28,7 @@ module TkTreatTextTagFont
else
pathname = self.path + ';' + tag
end
- if (fnt = slot['font'])
- slot['font'] = nil
+ if (fnt = slot.delete('font'))
if fnt.kind_of? TkFont
return fnt.call_font_configure(pathname,
self.path,'tag','configure',tag,slot)
@@ -37,16 +36,13 @@ module TkTreatTextTagFont
latintagfont_configure(tag, fnt) if fnt
end
end
- if (ltn = slot['latinfont'])
- slot['latinfont'] = nil
+ if (ltn = slot.delete('latinfont'))
latintagfont_configure(tag, ltn) if ltn
end
- if (ltn = slot['asciifont'])
- slot['asciifont'] = nil
+ if (ltn = slot.delete('asciifont'))
latintagfont_configure(tag, ltn) if ltn
end
- if (knj = slot['kanjifont'])
- slot['kanjifont'] = nil
+ if (knj = slot.delete('kanjifont'))
kanjitagfont_configure(tag, knj) if knj
end
@@ -127,30 +123,48 @@ end
class TkText<TkTextWin
include TkTreatTextTagFont
+ include Scrollable
WidgetClassName = 'Text'.freeze
WidgetClassNames[WidgetClassName] = self
+
def self.to_eval
WidgetClassName
end
- include Scrollable
+
+ def self.new(*args)
+ obj = super(*args){}
+ obj.init_instance_variable
+ obj.instance_eval &block if defined? yield
+ obj
+ end
+
+ def init_instance_variable
+ @tags = {}
+ end
+
def create_self
tk_call 'text', @path
- @tags = {}
+ init_instance_variable
end
+
def index(index)
tk_send 'index', index
end
+
def value
tk_send 'get', "1.0", "end - 1 char"
end
+
def value= (val)
tk_send 'delete', "1.0", 'end'
tk_send 'insert', "1.0", val
end
+
def _addcmd(cmd)
@cmdtbl.push cmd
end
+
def _addtag(name, obj)
@tags[name] = obj
end
@@ -168,11 +182,19 @@ class TkText<TkTextWin
tagid2obj(elt)
}
end
+
+ def mark_names
+ tk_split_list(tk_send('mark', 'names')).collect{|elt|
+ tagid2obj(elt)
+ }
+ end
+
def window_names
tk_send('window', 'names').collect{|elt|
tagid2obj(elt)
}
end
+
def image_names
tk_send('image', 'names').collect{|elt|
tagid2obj(elt)
@@ -182,6 +204,7 @@ class TkText<TkTextWin
def set_insert(index)
tk_send 'mark', 'set', 'insert', index
end
+
def set_current(index)
tk_send 'mark', 'set', 'current', index
end
@@ -191,6 +214,7 @@ class TkText<TkTextWin
end
def destroy
+ @tags = {} unless @tags
@tags.each_value do |t|
t.destroy
end
@@ -408,14 +432,15 @@ end
class TkTextTag<TkObject
include TkTreatTagFont
- $tk_text_tag = 'tag0000'
+ Tk_TextTag_ID = ['tag0000']
+
def initialize(parent, *args)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@parent = @t = parent
- @path = @id = $tk_text_tag
- $tk_text_tag = $tk_text_tag.succ
+ @path = @id = Tk_TextTag_ID[0]
+ Tk_TextTag_ID[0] = Tk_TextTag_ID[0].succ
#tk_call @t.path, "tag", "configure", @id, *hash_kv(keys)
if args != [] then
keys = args.pop
@@ -541,14 +566,14 @@ class TkTextTagSel<TkTextTag
end
class TkTextMark<TkObject
- $tk_text_mark = 'mark0000'
+ Tk_TextMark_ID = ['mark0000']
def initialize(parent, index)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
- @path = @id = $tk_text_mark
- $tk_text_mark = $tk_text_mark.succ
+ @path = @id = Tk_TextMark_ID[0]
+ Tk_TextMark_ID[0] = Tk_TextMark_ID[0].succ
tk_call @t.path, 'mark', 'set', @id, index
@t._addtag id, self
end
@@ -572,6 +597,14 @@ class TkTextMark<TkObject
def gravity=(direction)
tk_call @t.path, 'mark', 'gravity', @id, direction
end
+
+ def next(index)
+ @t.tagid2obj(tk_call(@t.path, 'mark', 'next', index))
+ end
+
+ def previous(index)
+ @t.tagid2obj(tk_call(@t.path, 'mark', 'previous', index))
+ end
end
class TkTextMarkInsert<TkTextMark