[Date Prev][Date Next][Thread Prev][][Date Index][Thread Index]

Re: w3m.el with backend patch



Citation (with leading "> " of each line) from article:
  <20010321065128E.1000@pine.kuee.kyoto-u.ac.jp>
    by TSUCHIYA Masatoshi <tsuchiya@pine.kuee.kyoto-u.ac.jp> :
> inclremental search / romaji search を有効にしないと、コンパイルが通ら
> ないので、多分、このメールの末尾に添付した修正が必要なのではないでしょ
> うか。

はいそうです^^;。何ともお恥ずかしい限りです。

> それでお願いがあるのですが、w3m.el との相性を良くするため、以下のよう
> な変更をしていただけないでしょうか?
>
>   (1) get / post コマンドに -dump_source オプションを追加してほしい。
>   (2) head コマンドを追加してほしい。

追加してみました。

今の実装だと-dump_sourceオプションはw3mのコマンドラインで指定するもの
と同じ振舞いをする筈ですが、w3mmeeやw3m-m17n的とセットで使う場合は
vwSrcのように出力するほうが(少なくとも文字のencodingの処理に関しては)
usabilityが上がると思います。一方オリジナルのw3mとのセットの場合は今の
実装のままにして文字のencodingの解釈はemacs側に任せたほうがよいでしょ
うし、どうしたもんでしょうか。

> なお、form 対応用の w3m-form: を出力するコードは私が書いたものから変わっ
> ていないようですが、この実装は良くないなあ、と最近考えています。上位層
> ではヘッダと本文を切り離して処理すると、処理がやりやすくなって嬉しいの
> ですが、form の情報は本文と一緒に処理されなければならないので、本文末
> 尾に
>
>   <_form fid="1" action="foo.cgi">
>
> のように出力する方がいいのではないかと思っています。

<pre>
…
</pre><title>…</title><_formlist>
<_form …>
…
</_formlist>

という風に出力するようにしてみましたが如何でしょうか。「<_formlist>」
と「</_formlist>」で囲むのは冗長な気もしましたが、一応将来の拡張に備え
てということで。

-- 
須藤 清一 <suto@ks-and-ks.ne.jp>
http://pub.ks-and-ks.ne.jp/pgp-public-key.html
Index: ChangeLog
===================================================================
RCS file: /usr/site/cvsroot/w3m/Attic/ChangeLog,v
retrieving revision 1.1.4.167
retrieving revision 1.1.4.168
diff -u -b -r1.1.4.167 -r1.1.4.168
--- ChangeLog	2001/03/20 18:08:52	1.1.4.167
+++ ChangeLog	2001/03/21 10:53:04	1.1.4.168
@@ -1,3 +1,13 @@
+Wed Mar 21 19:46:11 2001  Kiyokazu SUTO  <suto@ks-and-ks.ne.jp>
+
+	* Improvements of backend mode after suggestion from TSUCHIYA
+ 	Masatoshi <tsuchiya@pine.kuee.kyoto-u.ac.jp>.
+
+Wed Mar 21 13:07:55 2001  TSUCHIYA Masatoshi  <tsuchiya@pine.kuee.kyoto-u.ac.jp>
+
+	* main.c (srch{for,bak}): Fix compilation failure when either
+ 	``INC_SEARCH'' or ``ROMAJI_SEARCH'' disabled.
+
 Wed Mar 21 00:11:57 2001  Kiyokazu SUTO  <suto@ks-and-ks.ne.jp>
 
 	* Make it possible to pass urgent messages to client in backend
Index: backend.c
===================================================================
RCS file: /usr/site/cvsroot/w3m/Attic/backend.c,v
retrieving revision 1.1.2.6
retrieving revision 1.1.2.7
diff -u -b -r1.1.2.6 -r1.1.2.7
--- backend.c	2001/03/20 18:08:52	1.1.2.6
+++ backend.c	2001/03/21 10:53:04	1.1.2.7
@@ -2,6 +2,9 @@
 #include <string.h>
 #include <sys/types.h>
 #include <ctype.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
 #include "fm.h"
 #include "gc.h"
 #include "terms.h"
@@ -17,6 +20,7 @@
 
 
 /* Prototype declaration of command functions */
+static void head( TextList* );
 static void get( TextList* );
 static void post( TextList* );
 static void set( TextList* );
@@ -32,17 +36,18 @@
     const char *help;
     void (*func)( TextList* );
 } command_table[] = {
-    { "get", "[-download_only] URL", "Retrieve URL.", get },
-    { "post", "[-download_only] [-target TARGET] [-charset CHARSET]"
+    { "get", "[-download_only] [-dump_source] URL", "Retrieve URL.", get },
+    { "head", "URL", "Retrieve URL and print headers.", head }, 
+    { "help", "", "Display help messages.", help },
+    { "post", "[-download_only] [-dump_source] [-target TARGET] [-charset CHARSET]"
       " [-enctype ENCTYPE] [-body BODY] [-boundary BOUNDARY] [-length LEN] URL",
       "Retrieve URL.", post },
+    { "quit", "", "Quit program.", quit },
     { "set", "VARIABLE VALUE", "Set VALUE to VARIABLE.", set },
     { "show", "VARIABLE", "Show value of VARIABLE.", show },
-    { "quit", "", "Quit program.", quit },
-    { "help", "", "Display help messages.", help },
-    { NULL, NULL, NULL, NULL },
 };
 
+#define NO_CMDS (sizeof(command_table) / sizeof(command_table[0]))
 
 /* Prototype declaration of functions to manipulate configuration variables */
 static void set_column( TextList* );
@@ -116,7 +121,7 @@
 {
   char *l;
 
-  printf("w3m-input-prompt: %s\nw3m-input-default: %s\n\n", prompt, def_str ? def_str : "");
+  printf("w3m-input-prompt: %s\nw3m-input-default: %s\n", prompt, def_str ? def_str : "");
 
   if ((l = readline("w3m> "))) {
     size_t n;
@@ -128,7 +133,7 @@
   return l;
 }
 
-static void print_headers( Buffer *buf, int len ){
+static void print_headers( Buffer *buf, int len, const char *real_type ){
     TextListItem *tp;
     Str id;
 
@@ -148,7 +153,7 @@
       if (n)
 	printf("w3m-message: %s\n", p);
     }
-    printf( "w3m-content-type: %s\n", buf->type );
+    printf( "w3m-content-type: %s\n", real_type ? real_type : buf->type );
 #ifdef MANY_CHARSET
     if (buf->document_encoding)
       printf("w3m-content-charset: %s\n", buf->document_encoding);
@@ -168,28 +173,34 @@
 }
 
 
-static void print_formlist( int fid, FormList *fp ){
-    Str s = Sprintf( "w3m-form: (formlist (fid %d) (action \"%s\") (method \"%s\")",
+static void cat_formlist( Str s, int fid, FormList *fp ){
+    three_quater_cat(s, Sprintf( "<_form fid=%d action=\"%s\" method=\"%s\"",
 		     fid,
 		     fp->action->ptr,
 		     ( fp->method == FORM_METHOD_POST )? "post"
-		     :( ( fp->method == FORM_METHOD_INTERNAL )? "internal" : "get" ) );
+				 :( ( fp->method == FORM_METHOD_INTERNAL )? "internal" : "get" ) ));
     if( fp->target )
-	Strcat( s, Sprintf( " (target \"%s\")", fp->target ) );
+	three_quater_cat( s, Sprintf( " target=\"%s\"", fp->target ) );
     if( fp->charset )
 #ifdef MANY_CHARSET
-	Strcat( s, Sprintf( " (charset '%s)", fp->charset) );
+	three_quater_cat( s, Sprintf( " charset=\"%s\"", fp->charset) );
 #else
-	Strcat( s, Sprintf( " (charset '%s)", get_mime_charset_name(fp->charset) ) );
+	three_quater_cat( s, Sprintf( " charset=\"%s\"", get_mime_charset_name(fp->charset) ) );
 #endif
     if( fp->enctype == FORM_ENCTYPE_MULTIPART )
-	Strcat_charp( s, " (enctype \"multipart/form-data\")" );
+	three_quater_cat_charp( s, " enctype=\"multipart/form-data\"" );
     if( fp->boundary )
-	Strcat( s, Sprintf( " (boundary \"%s\")", fp->boundary ) );
-    Strcat_charp( s, ")\n" );
-    Strfputs( s, stdout );
+	three_quater_cat( s, Sprintf( " boundary=\"%s\"", fp->boundary ) );
+    three_quater_cat_charp( s, ">\n" );
 }
 
+enum {
+  get_flag_halfdump,
+  get_flag_download,
+  get_flag_dumpsource,
+  get_flag_head,
+};
+
 #define KEYEQ(key, mem, len) (sizeof(key) - 1 == (len) && !strncasecmp(key, (mem), (len)))
 
 static void internal_get( char *url, int flag, FormList *request ){
@@ -268,23 +279,75 @@
       Currentbuf = save_cur;
     }
     else {
-      do_download = flag;
+      do_download = flag == get_flag_download;
       buf = loadGeneralFile( url, NULL, NO_REFERER, 0, request );
       do_download = FALSE;
     }
     if( buf != NULL && buf != NO_BUFFER ){
 	Currentbuf = buf;
-	if( !strcasecmp( buf->type, "text/html" ) ){
+	if (flag == get_flag_head)
+	    print_headers( buf, 0, NULL );
+	else if (flag == get_flag_dumpsource) {
+	  if (buf->sourcefile) {
+	    int fd;
+	    struct stat stat_buf;
+
+	    if ((fd = open(buf->sourcefile, O_RDONLY)) < 0 || fstat(fd, &stat_buf))
+	      print_headers( buf, 0, NULL );
+	    else {
+	      static char *iobuf;
+	      static size_t iosize;
+	      size_t osize;
+	      ssize_t isize;
+	      char *p;
+
+	      print_headers( buf, stat_buf.st_size, "text/plain" );
+	      putc('\n', stdout);
+
+	      if (!iobuf) {
+		iosize = stat_buf.st_blksize;
+		iobuf = GC_MALLOC_ATOMIC(iosize);
+	      }
+
+	      while ((isize = read(fd, iobuf, iosize))) {
+		if (isize < 0)
+		  switch (errno) {
+		  case EAGAIN:
+		  case EINTR:
+		    sleep(1);
+		    continue;
+		  default:
+		    goto dumpsource_failure;
+		  }
+
+		p = iobuf;
+		do {
+		  if (!(osize = fwrite(p, 1, isize, stdout)))
+		    goto dumpsource_failure;
+		} while ((p += osize), (isize -= osize) > 0);
+	      }
+	    dumpsource_failure:
+	      close(fd);
+	    }
+	  }
+	  else
+	    print_headers( buf, 0, NULL );
+	}
+	else if( !strcasecmp( buf->type, "text/html" ) ){
 	    three_quater_cat( backend_halfdump_str,
-			      Sprintf( "</pre><title>%s</title>\n", buf->buffername ) );
-	    print_headers( buf, backend_halfdump_str->length );
+			      Sprintf( "</pre><title>%s</title>", buf->buffername ) );
 	    if( buf->formlist ){
 		FormList *fp;
 		int fid = 0;
+		Strcat_charp(backend_halfdump_str, "<_formlist>\n");
 		for( fp = buf->formlist; fp; fp = fp->next ) fid++;
 		for( fp = buf->formlist; fp; fp = fp->next )
-		    print_formlist( --fid, fp );
+		    cat_formlist( backend_halfdump_str, --fid, fp );
+		Strcat_charp(backend_halfdump_str, "</_formlist>\n");
 	    }
+	    else
+		Strcat_char(backend_halfdump_str, '\n');
+	    print_headers( buf, backend_halfdump_str->length, NULL );
 	    printf( "\n" );
 	    Strfputs( backend_halfdump_str, stdout );
 	} else {
@@ -295,25 +358,38 @@
 		    len += lp->len;
 		    if( lp->lineBuf[lp->len-1] != '\n' ) len++;
 		}
-		print_headers( buf, len );
+		print_headers( buf, len, NULL );
 		printf( "\n" );
 		saveBuffer( buf, stdout );
 	    } else {
-		print_headers( buf, 0 );
+		print_headers( buf, 0, NULL );
 	    }
 	}
     }
 }
 
 
+/* Command: head */
+static void head( TextList *argv ){
+  char *url;
+
+  if ((url = popText(argv))) {
+    backend_argv = argv;
+    internal_get(url, get_flag_head, NULL);
+  }
+}
+
+
 /* Command: get */
 static void get( TextList *argv ){
     char *p, *url = NULL;
-    int flag = FALSE;
+    int flag = get_flag_halfdump;
 
     while(( p = popText( argv ) )){
 	if( !strcasecmp( p, "-download_only" ) )
-	    flag = TRUE;
+	    flag = get_flag_download;
+	if( !strcasecmp( p, "-dump_source" ) )
+	    flag = get_flag_dumpsource;
 	else {
 	    url = p;
 	    backend_argv = argv;
@@ -331,7 +407,7 @@
     FormList *request;
     char *p, *target = NULL, *charset = NULL,
 	*enctype = NULL, *body = NULL, *boundary = NULL, *url = NULL;
-    int flag = FALSE, length = 0;
+    int flag = get_flag_halfdump, length = 0;
 
     while(( p = popText( argv ) )){
 	if( !strcasecmp( p, "-download_only" ) )
@@ -439,8 +515,17 @@
     int i;
     TextList *argv = split( str );
     if( argv->nitem > 0 ){
-	for( i = 0; command_table[i].name; i++ ){
-	    if( !strcasecmp( command_table[i].name, argv->first->ptr ) ){
+      int b, e, cmp;
+      char *cmd;
+
+      for (cmd = argv->first->ptr, b = 0, e = NO_CMDS ; b < e ;) {
+	i = (b + e) / 2;
+
+	if ((cmp = strcasecmp(cmd, command_table[i].name)) < 0)
+	  e = i;
+	else if (cmp)
+	  b = i + 1;
+	else {
 		popText( argv );
 		if( command_table[i].func )
 		    command_table[i].func( argv );
Index: file.c
===================================================================
RCS file: /usr/site/cvsroot/w3m/file.c,v
retrieving revision 1.1.1.1.6.87
retrieving revision 1.1.1.1.6.88
diff -u -b -r1.1.1.1.6.87 -r1.1.1.1.6.88
--- file.c	2001/03/20 18:08:53	1.1.1.1.6.87
+++ file.c	2001/03/21 10:53:04	1.1.1.1.6.88
@@ -2028,6 +2028,7 @@
 flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, int force, int width)
 {
     TextLineList *buf = h_env->buf;
+    Str backend_buf = h_env->backend_buf;
     FILE *f = h_env->f;
     Str line = obuf->line, pass = NULL;
     char *hidden_anchor = NULL, *hidden_img = NULL, *hidden_bold = NULL,
@@ -2212,7 +2213,11 @@
 	    h_env->maxlimit = lbuf->pos;
 	if (buf) {
 	  pushTextLine(buf, lbuf);
+	  if (backend_buf) {
+	    three_quater_cat(backend_buf, lbuf->line);
+	    Strcat_char(backend_buf, '\n');
 	}
+	}
 	else if (f) {
 	  if (w3m_halfdump > 1) {
 	    three_quater_dump(lbuf->line, f
@@ -2226,10 +2231,6 @@
 	    fputc('\n', f);
 	  }
 	}
-	else if (w3m_backend) {
-	  three_quater_cat(backend_halfdump_str, lbuf->line);
-	  Strcat_char(backend_halfdump_str, '\n');
-	}
 	if (obuf->flag & RB_SPECIAL || obuf->flag & RB_NFLUSHED)
 	    h_env->blank_lines = 0;
 	else
@@ -2244,32 +2245,28 @@
 	do { \
 	  if (buf) { \
 	    appendTextLine(buf,(str),0); \
+	    if (backend_buf) \
+	      three_quater_cat(backend_buf, (str)); \
 	  } else if (f) { \
 	    if (w3m_halfdump > 1) \
 	      three_quater_dump((str), f, info); \
 	    else \
 	      Strfputs((str),f); \
 	  } \
-	  else if (w3m_backend) { \
-	    three_quater_cat(backend_halfdump_str, (str)); \
-	    Strcat_char(backend_halfdump_str, '\n'); \
-	  } \
 	} while (0)
 #else
 #define APPEND(str) \
 	do { \
 	  if (buf) { \
 	    appendTextLine(buf,(str),0); \
+	    if (w3m_backend) \
+	      three_quater_cat(backend_buf, (str)); \
 	  } else if (f) { \
 	    if (w3m_halfdump > 1) \
 	      three_quater_dump((str), f); \
 	    else \
 	      Strfputs((str),f); \
 	  } \
-	  else if (w3m_backend) { \
-	    three_quater_cat(backend_halfdump_str, (str)); \
-	    Strcat_char(backend_halfdump_str, '\n'); \
-	  } \
 	} while (0)
 #endif
 
@@ -2356,7 +2353,7 @@
 void
 do_blankline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, int indent_incr, int width)
 {
-    if (((h_env->buf || w3m_backend) && h_env->blank_lines == 0) || h_env->f)
+    if ((h_env->buf && h_env->blank_lines == 0) || h_env->f)
 	flushline(h_env, obuf, indent, 1, width);
 }
 
@@ -5357,6 +5354,7 @@
     set_breakpoint(obuf, 0);
 
     h_env->buf = buf;
+    h_env->backend_buf = NULL;
     h_env->f = NULL;
 #ifdef MANY_CHARSET
     h_env->f_info = NULL;
@@ -5464,8 +5462,11 @@
 
     if (w3m_halfdump)
 	htmlenv1.f = stdout;
-    else if (!w3m_backend)
+    else {
 	htmlenv1.buf = newTextLineList();
+	if (w3m_backend)
+	  htmlenv1.backend_buf = backend_halfdump_str;
+    }
 
 #ifdef MANY_CHARSET
     if (newBuf && newBuf->document_encoding)
@@ -5578,7 +5579,6 @@
 	return;
     }
     newBuf->trbyte = trbyte + linelen;
-    if (htmlenv1.buf)
       HTMLlineproc2(newBuf, htmlenv1.buf);
 #ifdef MANY_CHARSET
     newBuf->document_encoding = detector.setup.cs;
Index: fm.h
===================================================================
RCS file: /usr/site/cvsroot/w3m/fm.h,v
retrieving revision 1.1.1.1.6.43
retrieving revision 1.1.1.1.6.44
diff -u -b -r1.1.1.1.6.43 -r1.1.1.1.6.44
--- fm.h	2001/03/20 18:08:53	1.1.1.1.6.43
+++ fm.h	2001/03/21 10:53:04	1.1.1.1.6.44
@@ -551,6 +551,7 @@
 struct html_feed_environ {
     struct readbuffer *obuf;
     TextLineList *buf;
+    Str backend_buf;
     FILE *f;
 #ifdef MANY_CHARSET
     mb_info_t *f_info;
Index: main.c
===================================================================
RCS file: /usr/site/cvsroot/w3m/main.c,v
retrieving revision 1.1.1.1.6.50
retrieving revision 1.1.1.1.6.52
diff -u -b -r1.1.1.1.6.50 -r1.1.1.1.6.52
--- main.c	2001/03/20 18:08:53	1.1.1.1.6.50
+++ main.c	2001/03/21 11:22:56	1.1.1.1.6.52
@@ -1326,16 +1326,32 @@
 void
 srchfor(void)
 {
+#ifdef INC_SEARCH
    use_inc_search = FALSE;
-   srch(AcrossLines ? forwardSearchAcrossLines : forwardSearch, use_romaji_search ? "Forward (Romaji): " : "Forward: ");
+#endif /* INC_SEARCH */
+   srch(AcrossLines ? forwardSearchAcrossLines : forwardSearch,
+#ifdef ROMAJI_SEARCH
+	use_romaji_search ? "Forward (Romaji): " : "Forward: "
+#else
+	"Forward: "
+#endif /* ROMAJI_SEARCH */
+       );
 }
 
 /* Search regular expression backward */
 void
 srchbak(void)
 {
+#ifdef INC_SEARCH
    use_inc_search = FALSE;
-   srch(AcrossLines ? backwardSearchAcrossLines : backwardSearch, use_romaji_search ? "Forward (Romaji): " : "Backward: ");
+#endif /* INC_SEARCH */
+   srch(AcrossLines ? backwardSearchAcrossLines : backwardSearch,
+#ifdef ROMAJI_SEARCH
+	use_romaji_search ? "Backward (Romaji): " : "Backward: "
+#else
+	"Backward: "
+#endif /* ROMAJI_SEARCH */
+       );
 }
 
 #ifdef INC_SEARCH