diff options
author | (no author) <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-04-14 14:35:50 +0000 |
---|---|---|
committer | (no author) <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-04-14 14:35:50 +0000 |
commit | ed131ebad88c2948d7b40f93ff6ce39f1eb8a2f7 (patch) | |
tree | 7bbf62c5e0d0bb8ff971637cf432c6f16824f8f6 /ext | |
parent | be1fea072cd0d22788ef8a931c0c6b64a2503b5d (diff) |
This commit was manufactured by cvs2svn to create tag 'v1_4_4'.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_4_4@668 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r-- | ext/Setup.nt | 19 | ||||
-rw-r--r-- | ext/Win32API/Win32API.c | 42 | ||||
-rw-r--r-- | ext/Win32API/depend | 1 | ||||
-rw-r--r-- | ext/curses/MANIFEST | 1 | ||||
-rw-r--r-- | ext/curses/curses.c | 40 | ||||
-rw-r--r-- | ext/curses/depend | 1 | ||||
-rw-r--r-- | ext/dbm/extconf.rb | 7 | ||||
-rw-r--r-- | ext/extmk.rb.in | 2 | ||||
-rw-r--r-- | ext/kconv/kconv.c | 2017 | ||||
-rw-r--r-- | ext/nkf/depend | 2 | ||||
-rw-r--r-- | ext/nkf/nkf.c | 26 | ||||
-rw-r--r-- | ext/pty/MANIFEST | 1 | ||||
-rw-r--r-- | ext/pty/depend | 1 | ||||
-rw-r--r-- | ext/pty/pty.c | 2 | ||||
-rw-r--r-- | ext/readline/MANIFEST | 1 | ||||
-rw-r--r-- | ext/readline/depend | 1 | ||||
-rw-r--r-- | ext/sdbm/MANIFEST | 1 | ||||
-rw-r--r-- | ext/sdbm/depend | 2 | ||||
-rw-r--r-- | ext/socket/extconf.rb | 31 | ||||
-rw-r--r-- | ext/socket/getaddrinfo.c | 17 | ||||
-rw-r--r-- | ext/socket/getnameinfo.c | 11 | ||||
-rw-r--r-- | ext/socket/socket.c | 52 | ||||
-rw-r--r-- | ext/tcltklib/extconf.rb | 2 | ||||
-rw-r--r-- | ext/tk/lib/tk.rb | 340 | ||||
-rw-r--r-- | ext/tk/lib/tkcanvas.rb | 31 | ||||
-rw-r--r-- | ext/tk/lib/tkentry.rb | 10 | ||||
-rw-r--r-- | ext/tk/lib/tkfont.rb | 15 | ||||
-rw-r--r-- | ext/tk/lib/tktext.rb | 65 |
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 |