Sophie

Sophie

distrib > * > 2008.0 > x86_64 > by-pkgid > c6d8198fd3a861c932152544cde921fd > files > 19

vile-9.5r-1mdv2008.0.src.rpm

# vile 9.5p
# patch by Thomas E. Dickey <dickey@invisible-island.net>
# created  Wed Apr 25 21:01:05 UTC 2007
# ------------------------------------------------------------------------------
# CHANGES              |   17 +++-
# MANIFEST             |    4 
# builtflt.c           |   30 +++++++
# estruct.h            |    4 
# filters/filters.h    |    3 
# filters/spellflt.l   |  177 ++++++++++++++++++++++++++++++++++++-------
# filters/txt-filt.l   |    7 +
# makefile.wnt         |   19 ++--
# ntwinio.c            |   64 ++++-----------
# patchlev.h           |    2 
# revlist              |   28 +++---
# vile-9.5.spec        |    9 +-
# vile-9.5p/makeargv.c |   90 +++++++++++++++++++++
# vile-9.5p/makeargv.h |   13 +++
# wvwrap.cpp           |  201 +++++++++++++++++++++++++++++++------------------
# 15 files changed, 488 insertions(+), 180 deletions(-)
# ------------------------------------------------------------------------------
Index: CHANGES
--- vile-9.5o+/CHANGES	2007-01-16 01:34:39.000000000 +0000
+++ vile-9.5p/CHANGES	2007-04-25 00:46:46.000000000 +0000
@@ -1,5 +1,20 @@
 Changes for vile 9.6 (released ??? ??? ?? ????)
 
+ 20070425 (p)
+	> Tom Dickey:
+	+ modify spell- and txt-filters to allow users to add words to their
+	  respective ".keywords" files to override the builtin highlighting.
+	+ correct check of return of ffread() in spellflt.l's workaround for
+	  platforms such as win32 which have no usable popen().  That made
+	  spelling checks require two ^X-i presses.
+	+ modify spellflt.l to chop words according to Camel-case, so
+	  tokens such as "ChopWords" are treated by the spell checker as
+	  multiple words.
+	+ fix a limit check in argc/argv[] parsing for winvile (report by
+	  Larry Gensch).
+	+ modify wvwrap.exe to work with pathnames containing "$", "&" and "'".
+	+ change OPT_MULTIBYTE definition to depend on OPT_LOCALE.
+
  20070115 (o)
 	> Tom Dickey:
 	+ change Inno Setup script to not put version numbers on the SendTo
@@ -912,7 +927,7 @@
 	  definitions, e.g., from .vile.keywords, as is done in a ".source"
 	  command.
 	+ add a ".brief" to filters parsing, which uses "?" to match zero or
-	  all of the following characters, in constrast to ".abbrev" which uses
+	  all of the following characters, in contrast to ".abbrev" which uses
 	  "*" to match zero or more of the following characters.
 	+ modify sql-filt.l to distinguish between SQL*PLUS and SQL, PL/SQL.
 	  The latter delimit statements with semicolons, while the former makes
Index: MANIFEST
--- vile-9.5o+/MANIFEST	2007-01-16 01:42:23.000000000 +0000
+++ vile-9.5p/MANIFEST	2007-04-25 21:00:15.000000000 +0000
@@ -1,4 +1,4 @@
-MANIFEST for vile, version v9_5o
+MANIFEST for vile, version v9_5p
 --------------------------------------------------------------------------------
 MANIFEST                        this file
 CHANGES                         Change-log for VILE
@@ -63,6 +63,8 @@
 lckfiles.c                      locked-files support
 line.c                          line-management functions
 main.c                          main program of VILE
+makeargv.c                      parse string to argc/argv[]
+makeargv.h                      interface of makeargv.c
 makefile.blc                    makefile for Win32 with Borland C++
 makefile.djg                    makefile for DJGCC
 makefile.icc                    makefile for C Set++ 2.x (OS/2)
Index: builtflt.c
Prereq:  1.47 
--- vile-9.5o+/builtflt.c	2005-02-13 01:03:19.000000000 +0000
+++ vile-9.5p/builtflt.c	2007-04-23 23:14:18.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Main program and I/O for external vile syntax/highlighter programs
  *
- * $Header: /usr/build/vile/vile/RCS/builtflt.c,v 1.47 2005/02/13 01:03:19 tom Exp $
+ * $Header: /usr/build/vile/vile/RCS/builtflt.c,v 1.48 2007/04/23 23:14:18 tom Exp $
  *
  */
 
@@ -510,6 +510,34 @@
     return FALSE;
 }
 
+/*
+ * The spelling filter uses this function, since it parses the buffer more
+ * than once, using the parsed data for a list of words to check.  So we
+ * do not wipe the symbol table.
+ */
+int
+flt_restart(char *name)
+{
+    TRACE(("flt_restart(%s)\n", name));
+    if (flt_lookup(name)
+#ifdef HAVE_LIBDL
+	&& (current_filter->loaded || load_filter(current_filter->filter_name))
+#endif
+	) {
+	need_separator = FALSE;
+	mark_in.l = lforw(buf_head(curbp));
+	mark_in.o = w_left_margin(curwp);
+	mark_out = mark_in;
+	tb_init(&gets_data, 0);
+
+	init_flt_error();
+	set_symbol_table(current_filter->filter_name);
+
+	return TRUE;
+    }
+    return FALSE;
+}
+
 static TBUFF *filter_list;
 
 int
Index: estruct.h
Prereq:  1.608 
--- vile-9.5o+/estruct.h	2007-01-15 23:27:36.000000000 +0000
+++ vile-9.5p/estruct.h	2007-02-11 17:34:33.000000000 +0000
@@ -12,7 +12,7 @@
 */
 
 /*
- * $Header: /usr/build/vile/vile/RCS/estruct.h,v 1.608 2007/01/15 23:27:36 tom Exp $
+ * $Header: /usr/build/vile/vile/RCS/estruct.h,v 1.609 2007/02/11 17:34:33 tom Exp $
  */
 
 #ifndef _estruct_h
@@ -621,7 +621,7 @@
 #define OPT_MACRO_ARGS	(!SMALLER && OPT_EVAL)	/* macro argument parsing */
 #define OPT_MLFORMAT    !SMALLER		/* modeline-format */
 #define OPT_MODELINE    !SMALLER		/* vi-style modeline-support */
-#define OPT_MULTIBYTE   !SMALLER		/* experimental multibyte support */
+#define OPT_MULTIBYTE   (!SMALLER && OPT_LOCALE) /* experimental multibyte support */
 #define OPT_NAMEBST     !SMALLER		/* name's stored in a bst */
 #define OPT_ONLINEHELP  !SMALLER		/* short per-command help */
 #define OPT_POPUPCHOICE !SMALLER		/* popup-choices mode */
Index: filters/filters.h
Prereq:  1.97 
--- vile-9.5o+/filters/filters.h	2006-10-03 00:12:43.000000000 +0000
+++ vile-9.5p/filters/filters.h	2007-04-23 22:44:14.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Header: /usr/build/vile/vile/filters/RCS/filters.h,v 1.97 2006/10/03 00:12:43 tom Exp $
+ * $Header: /usr/build/vile/vile/filters/RCS/filters.h,v 1.98 2007/04/23 22:44:14 tom Exp $
  */
 
 #ifndef FILTERS_H
@@ -231,6 +231,7 @@
 extern int flt_get_line(void);
 extern int flt_input(char *buffer, int max_size);
 extern int flt_lookup(char *name);
+extern int flt_restart(char *name);
 extern int flt_start(char *name);
 extern void flt_echo(const char *string, int length);
 extern void flt_error(const char *fmt, ...) VILE_PRINTF(1,2);
Index: filters/spellflt.l
Prereq:  1.25 
--- vile-9.5o+/filters/spellflt.l	2006-08-13 20:23:47.000000000 +0000
+++ vile-9.5p/filters/spellflt.l	2007-04-25 00:40:56.000000000 +0000
@@ -1,7 +1,7 @@
 %{
 
 /*
- * $Header: /usr/build/vile/vile/filters/RCS/spellflt.l,v 1.25 2006/08/13 20:23:47 tom Exp $
+ * $Header: /usr/build/vile/vile/filters/RCS/spellflt.l,v 1.33 2007/04/25 00:40:56 tom Exp $
  *
  * Filter to add vile "attribution" sequences to misspelled words.
  */
@@ -35,6 +35,9 @@
 
 #define SPELL_PIPE SPELL_PROG " " SPELL_OPTS
 
+static FILE *ChopFP;
+static void ChopWords(FILE *fp, char *text, int len);
+
 #ifdef HAVE_POPEN
 #define pipe_open(command)	popen(command, "r")
 #define	pipe_read(b,s)		fgets(b, sizeof(b), s)
@@ -42,6 +45,9 @@
 #else				/* platforms with no workable popen */
 #ifdef filter_def		/* built-in filter? */
 #define HAVE_POPEN		/* we can fake it */
+static char lastdata[BUFFER_SIZE];
+static int lastsize;
+
 static FILE *
 pipe_open(const char *command)
 {
@@ -52,15 +58,13 @@
     if (ffropen(buffer) == FIOSUC)
 	result = ffp;
 
+    lastsize = 0;
     return result;
 }
 
 static char *
 pipe_read(char *buffer, FILE *s)
 {
-    static char lastdata[BUFFER_SIZE];
-    static int lastsize;
-
     char *result = buffer;
     int len;
     int done = 0;
@@ -74,7 +78,7 @@
 		    lastdata[len - used] = lastdata[len];
 		} else {
 		    if ((buffer + 1 - result) >= BUFFER_SIZE
-		    	|| (*buffer++ = lastdata[len]) == '\n') {
+			|| (*buffer++ = lastdata[len]) == '\n') {
 			done = 1;
 		    }
 		    used = len + 1;
@@ -88,14 +92,15 @@
 	}
 
 	if (!done) {
-	    if (ffread(lastdata, sizeof(lastdata), &lastsize) <= 0)
+	    if (ffread(lastdata, sizeof(lastdata), &lastsize) < 0) {
 		done = 1;
+	    }
 	}
     } while (!done);
 
     *buffer = 0;
     if (buffer == result)
-    	result = 0;
+	result = 0;
 
     return result;
 }
@@ -116,7 +121,7 @@
 #ifdef HAVE_MKSTEMP
     int fd = mkstemp(strcpy(fname, "vileXXXXXX"));
     if (fd >= 0)
-    	fp = fdopen(fd, "w");
+	fp = fdopen(fd, "w");
 #else
     int oldmask = umask(0077);
     strcpy(fname, tmpnam((char *)0));
@@ -132,15 +137,89 @@
 
 %%
 
-{WORD}		{ char *attr = keyword_attr(yytext);
-		  if (attr != 0)
-		      flt_error(yytext);
-		  WriteToken(attr);
-		}
+{WORD}		{ ChopWords(ChopFP, yytext, yyleng); }
+[\n\r]		|
+.		{ if (ChopFP == 0) flt_putc(*yytext); }
 
 %%
 
 static void
+ChopWords(FILE *fp, char *text, int len)
+{
+    char *base = text;
+    char *attr;
+    int next = len;
+    int save;
+
+    /*
+     * Write the whole "word", just in case the chopped flavor is not needed.
+     */
+    if (fp != 0) {
+	fwrite(text, sizeof(*text), len, fp);
+	fputc('\n', fp);
+    } else {
+	attr = keyword_attr(text);
+	if (attr == 0 || *attr == '\0') {
+	    flt_puts(text, next, attr);
+	    return;
+	}
+    }
+
+    while (len > 0) {
+	int ch = CharOf(text[0]);
+	int all_upper = isupper(ch);
+	int all_lower = islower(ch);
+	int n;
+
+	/*
+	 * Handle three cases:  all lowercase, all uppercase, or one leading
+	 * cap.  Don't check spelling of a single letter.
+	 */
+	next = len;
+	for (n = 0; n < len; ++n) {
+	    ch = CharOf(text[n]);
+	    if (isalpha(ch)) {
+		if (isupper(ch)) {
+		    if (all_lower) {
+			next = n;
+			break;
+		    }
+		} else if (all_upper) {
+		    if (n == 1) {
+			all_lower = 1;
+			all_upper = 0;
+		    } else {
+			next = n;
+			break;
+		    }
+		}
+	    }
+	}
+
+	if (fp != 0) {
+	    if (text != base || next != len) {
+		fwrite(text, sizeof(*text), next, fp);
+		fputc('\n', fp);
+	    }
+	} else {
+	    if (next > 1) {
+		save = text[next];
+		text[next] = '\0';
+		attr = keyword_attr(text);
+		if (attr != 0)
+		    flt_error(text);
+		text[next] = save;
+	    } else {
+		attr = "";
+	    }
+	    flt_puts(text, next, attr);
+	}
+	text += next;
+	len -= next;
+    }
+}
+
+static void
 init_filter(int before GCC_UNUSED)
 {
     (void) before;
@@ -153,9 +232,11 @@
 #ifdef filter_def
     LINE *lp;
 #else
+    FILE *FromFP;
+    char from[256];
     int ch;
 #endif
-    char name[256];
+    char chop[256];
     FILE *fp;
     char buffer[BUFFER_SIZE + 2];
     char *attr = class_attr(NAME_ERROR);
@@ -163,48 +244,86 @@
 
     (void) inputs;
 
-    if ((fp = open_tempfile(name)) == 0)
+    /*
+     * Create a temporary file which will hold the words to check spelling.
+     */
+    if ((ChopFP = open_tempfile(chop)) == 0)
 	return;
 
 #ifdef filter_def		/* built-in filter? */
-    ffp = fp;
+    ffp = ChopFP;
 #if OPT_ENCRYPT
     ffstatus = file_is_pipe;
 #endif
     for_each_line(lp, curbp) {
 	ffputline(lp->l_text, llength(lp), "\n");
     }
+    yylex();
 #else				/* external filter */
-    while ((ch = fgetc(inputs)) != EOF && !feof(inputs))
-	fputc(ch, fp);
+    if ((FromFP = open_tempfile(from)) == 0) {
+	fclose(ChopFP);
+	remove(chop);
+	return;
+    }
+    while ((ch = fgetc(inputs)) != EOF)
+	fputc(ch, FromFP);
+    fclose(FromFP);
+
+    yyin = fopen(from, "r");
+    yylex();
+    fclose(yyin);
+
+    yyin = fopen(from, "r");
 #endif
 
-    fclose(fp);
+    fclose(ChopFP);
+    ChopFP = 0;
 
 #ifdef filter_def		/* built-in filter? */
     ffstatus = file_is_closed;
     ffp = 0;
 #endif
 
+    /*
+     * Run the spelling checker, reading the misspelled words from the pipe.
+     * Record those in the keyword table.
+     */
     if ((prog = getenv("VILE_SPELL_FILT")) == 0)
-    	prog = SPELL_PIPE;
-    sprintf(buffer, "%s <%s", prog, name);
+	prog = SPELL_PIPE;
+    sprintf(buffer, "%s <%s", prog, chop);
     if ((fp = pipe_open(buffer)) != 0) {
 	while (pipe_read(buffer, fp)) {
 	    unsigned len  = strlen(buffer);
-	    while (len-- && isspace(CharOf(buffer[len])))
+	    while (len-- && isspace(CharOf(buffer[len]))) {
 		buffer[len] = 0;
-	    if (*buffer)
-		insert_keyword(buffer, attr, 0);
+	    }
+	    if (*buffer) {
+		/*
+		 * If user did not override with an entry in spell.keywords,
+		 * add the latest as a misspelled word to highlight.
+		 */
+		if (keyword_attr(buffer) == 0) {
+		    insert_keyword(buffer, attr, 0);
+		}
+	    }
 	}
 	pipe_close(fp);
     }
-    yyin = fopen(name, "r");
+    remove(chop);
 
-    while (yylex() > 0) {
-    }
+    /*
+     * Reparse the buffer, marking the misspelled words.
+     */
+#ifdef filter_def		/* built-in filter? */
+    flt_restart(filter_def.filter_name);
+#endif
+    BEGIN(INITIAL);
+    yylex();
+
+#ifndef filter_def		/* external filter? */
+    fclose(yyin);		/* yylex() may not close */
+    remove(from);
+#endif
 
-    fclose(yyin);
-    remove(name);
 #endif /* HAVE_POPEN */
 }
Index: filters/txt-filt.l
Prereq:  1.29 
--- vile-9.5o+/filters/txt-filt.l	2006-10-29 20:33:08.000000000 +0000
+++ vile-9.5p/filters/txt-filt.l	2007-04-25 00:26:21.000000000 +0000
@@ -5,7 +5,7 @@
 %{
 
 /*
- * $Header: /usr/build/vile/vile/filters/RCS/txt-filt.l,v 1.29 2006/10/29 20:33:08 tom Exp $
+ * $Header: /usr/build/vile/vile/filters/RCS/txt-filt.l,v 1.30 2007/04/25 00:26:21 tom Exp $
  *
  * Filter to add vile "attribution" sequences to an ordinary text file
  */
@@ -51,7 +51,10 @@
 <TEXT>^[[:blank:]]*"--"[[:blank:]]	{ PushQuote(NOTE, Comment_attr); }
 <TEXT>^[-]+$		|
 <TEXT>{DASHES}		{ WriteToken(Comment_attr); }
-<TEXT>{KEYWORD}		{ WriteToken(mixedcase(yytext) ? "" : Keyword_attr); }
+<TEXT>{KEYWORD}		{ char *attr = keyword_attr(yytext);
+			  if (attr == 0) attr = (mixedcase(yytext) ? "" : Keyword_attr);
+			  WriteToken(attr);
+			}
 <TEXT>{NUMBER}		{ WriteToken(Number_attr); }
 <TEXT>{EMAIL}		{ WriteToken(Ident2_attr); }
 <TEXT>{URL}		{ WriteToken(Ident2_attr); }
Index: makeargv.c
--- /dev/null	2007-04-25 20:06:27.384575000 +0000
+++ vile-9.5p/makeargv.c	2007-04-21 00:25:34.000000000 +0000
@@ -0,0 +1,90 @@
+/*
+ * makeargv.c:  parse string to argv[]
+ *
+ * $Header: /usr/build/vile/vile/RCS/makeargv.c,v 1.1 2007/04/21 00:25:34 tom Exp $
+ */
+
+#include "w32vile.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "vl_alloc.h"
+#include "makeargv.h"
+
+#define DQUOTE '"'
+#define SQUOTE '\''
+
+//--------------------------------------------------------------
+
+int
+make_argv(const char *program,
+	  const char *cmdline,
+	  char ***argvp,
+	  int *argcp)
+{
+
+    int maxargs = 2 + (strlen(cmdline) + 2) / 2;
+    char *blob;
+    char *ptr;
+    char **argv;
+    int argc = 0;
+
+    if ((blob = typeallocn(char, strlen(cmdline) + 1)) == 0)
+	  return -1;
+
+    if ((argv = typeallocn(char *, maxargs)) == 0) {
+	free(blob);
+	return -1;
+    }
+
+    strcpy(blob, cmdline);
+    if (program != 0)
+	argv[argc++] = (char *) program;
+
+    for (ptr = blob; *ptr != '\0';) {
+	char *dst;
+	char delim = ' ';
+
+	while (*ptr == ' ')
+	    ptr++;
+
+	if (*ptr == SQUOTE
+	    || *ptr == DQUOTE
+	    || *ptr == ' ') {
+	    delim = *ptr++;
+	}
+
+	argv[argc++] = dst = ptr;
+	if (argc + 1 >= maxargs) {
+	    break;
+	}
+
+	while (*ptr != delim && *ptr != '\0') {
+	    if (*ptr == '"') {
+		ptr++;
+		delim = (char) ((delim == ' ') ? '"' : ' ');
+	    } else {
+		*dst++ = *ptr++;
+	    }
+	}
+
+	if (*ptr == '"') {
+	    ++ptr;
+	}
+
+	if (dst != ptr) {
+	    *dst = '\0';
+	} else if (*ptr == ' ') {
+	    *ptr++ = '\0';
+	}
+
+    }
+
+    argv[argc] = 0;
+    *argvp = argv;
+    *argcp = argc;
+
+    return 0;
+
+}
Index: makeargv.h
--- /dev/null	2007-04-25 20:06:27.384575000 +0000
+++ vile-9.5p/makeargv.h	2007-04-20 21:47:44.000000000 +0000
@@ -0,0 +1,13 @@
+/*
+ * $Header: /usr/build/vile/vile/RCS/makeargv.h,v 1.1 2007/04/20 21:47:44 tom Exp $
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int make_argv(const char * /* program */, const char * /*cmdline */, char *** /*argvp */, int * /*argcp */);
+
+#ifdef __cplusplus
+}
+#endif
Index: makefile.wnt
Prereq:  1.92 
--- vile-9.5o+/makefile.wnt	2007-01-14 21:39:05.000000000 +0000
+++ vile-9.5p/makefile.wnt	2007-04-20 22:58:33.000000000 +0000
@@ -1,7 +1,7 @@
 #
 # makefile for vile on WIN32 using Microsoft Visual C++
 #
-# $Header: /usr/build/vile/vile/RCS/makefile.wnt,v 1.92 2007/01/14 21:39:05 tom Exp $
+# $Header: /usr/build/vile/vile/RCS/makefile.wnt,v 1.93 2007/04/20 22:58:33 tom Exp $
 #
 #
 !include <ntwin32.mak>
@@ -118,6 +118,7 @@
 SCREEN   = ntwinio
 LIBS     = $(LD_DEBUG) $(guilflags) $(guilibsmt) ole32.lib shell32.lib \
            $(VILE_PERL_LIB) $(OLELIBS)
+EXTRAOBJ = makeargv.obj
 EXTRA    = winvile.res
 !endif
 
@@ -136,8 +137,8 @@
 OLEOBJS  = w32ole.obj w32reg.obj w32ole.res
 OLESRCS  = w32ole.cpp w32reg.c
 WRAPUTIL = wvwrap.exe
-EXTRA    =
 OLELIBS  = uuid.lib oleaut32.lib comsupp.lib
+EXTRA    = 
 !endif
 
 !IF "$(CFG)" == "winvile-with-perl" || "$(CFG)" == "vile-with-perl"
@@ -228,7 +229,7 @@
 	tags.obj tbuff.obj termio.obj ucrypt.obj undo.obj \
 	version.obj window.obj word.obj wordmov.obj map.obj \
 	w32cbrd.obj w32cmd.obj w32misc.obj w32oo.obj w32pipe.obj $(PERLOBJS) \
-	$(OLEOBJS) $(DBGOBJS) $(EXTRA)
+	$(OLEOBJS) $(DBGOBJS) $(EXTRAOBJ) $(EXTRA)
 
 .c.obj:
 	$(cc) $(CFLAGS) -c $< -Fo$@
@@ -295,8 +296,8 @@
 vile-perl-api.doc: vile-perl-api.pod
 	perl -e "use Pod::Text; pod2text(\"$?\");" > $@
 
-wvwrap.exe: wvwrap.obj
- 	$(link) $(LDFLAGS) wvwrap.obj $(LIBS) -out:$(@)
+wvwrap.exe: wvwrap.obj makeargv.obj
+ 	$(link) $(LDFLAGS) wvwrap.obj makeargv.obj $(LIBS) -out:$(@)
 
 mktbls.exe:  mktbls.c
 	$(cc) $(CFLAGS) mktbls.c -Fomktbls -link $(CON_LDFLAGS)
@@ -392,9 +393,9 @@
 display.obj :	pscreen.h
 filec.obj :	dirstuff.h
 glob.obj :	dirstuff.h
-main.obj :	chgdfunc.h 
-modes.obj :	chgdfunc.h 
-ntwinio.obj :	winvile.h pscreen.h patchlev.h
+main.obj :	chgdfunc.h
+modes.obj :	chgdfunc.h
+ntwinio.obj :	winvile.h pscreen.h patchlev.h makeargv.h
 path.obj :	dirstuff.h
 perl.obj :	api.h
 random.obj :	dirstuff.h
@@ -405,4 +406,4 @@
 w32ole.obj :	w32ole.h winviletlb.h w32reg.h
 w32oo.obj :	dirstuff.h
 w32reg.obj :	w32reg.h
-wvwrap.obj :	w32reg.h w32ole.h winviletlb.h
+wvwrap.obj :	w32reg.h w32ole.h winviletlb.h makeargv.h
Index: ntwinio.c
Prereq:  1.160 
--- vile-9.5o+/ntwinio.c	2006-10-31 21:44:16.000000000 +0000
+++ vile-9.5p/ntwinio.c	2007-04-21 00:25:37.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Uses the Win32 screen API.
  *
- * $Header: /usr/build/vile/vile/RCS/ntwinio.c,v 1.160 2006/10/31 21:44:16 tom Exp $
+ * $Header: /usr/build/vile/vile/RCS/ntwinio.c,v 1.161 2007/04/21 00:25:37 tom Exp $
  * Written by T.E.Dickey for vile (october 1997).
  * -- improvements by Clark Morgan (see w32cbrd.c, w32pipe.c).
  */
@@ -21,6 +21,7 @@
 #include "nefsms.h"
 #include "nefunc.h"
 #include "chgdfunc.h"
+#include "makeargv.h"
 
 #define ABS(x) (((x) < 0) ? -(x) : (x))
 
@@ -3695,9 +3696,8 @@
 {
     int argc;
     int n;
-    size_t maxargs = strlen(lpCmdLine) + 1;
-    char **argv = typecallocn(char *, maxargs + 10);
-    char *ptr, *fontstr;
+    char **argv = 0;
+    char *fontstr;
 #ifdef VILE_OLE
     int oa_invoke, oa_reg;
 
@@ -3707,49 +3707,23 @@
 
     TRACE(("Starting ntvile, CmdLine:%s\n", lpCmdLine));
 
-    argv[argc = 0] = "VILE";
+    if (make_argv("VILE", lpCmdLine, &argv, &argc) < 0)
+	ExitProgram(BADEXIT);
 
-    if (ffaccess(lpCmdLine, FL_READABLE)) {
-	argv[++argc] = lpCmdLine;
-    } else {
-	char *dst;
-	for (ptr = lpCmdLine; *ptr != '\0';) {
-	    char delim = ' ';
-
-	    /* skip spaces before parameter */
-	    while (*ptr == ' ')
-		ptr++;
-
-	    if (*argv[argc]) {
-		TRACE(("argv[%d]:%s\n", argc, argv[argc]));
-		++argc;
-	    }
-	    if ((size_t) (argc + 1) >= maxargs) {
-		break;
-	    }
-	    argv[argc] = dst = ptr;
-	    while (*ptr != delim && *ptr != '\0') {
-		if (*ptr == '"') {
-		    ptr++;
-		    delim = (char) ((delim == ' ') ? '"' : ' ');
-		} else {
-		    *dst++ = *ptr++;
-		}
-	    }
-	    if (*ptr == '"') {
-		++ptr;
-	    }
-	    if (dst != ptr) {
-		*dst = '\0';
-	    } else if (*ptr == ' ') {
-		*ptr++ = '\0';
-	    }
-	}
-    }
-    if (*argv[argc]) {
-	TRACE(("argv[%d]:%s\n", argc, argv[argc]));
-	++argc;
+    /*
+     * If the command-line really specifies an existing file, override the argv-parser.
+     * This makes "Send To" work.
+     */
+    if (argc > 1 && ffaccess(lpCmdLine, FL_READABLE)) {
+	argc = 1;
+	argv[argc++] = lpCmdLine;
+	argv[argc] = 0;
     }
+#if OPT_TRACE
+    for (n = 0; n < argc; ++n)
+	TRACE(("argv[%d] %s\n", n, argv[n]));
+#endif
+
     fontstr = 0;
 
     /*
Index: patchlev.h
--- vile-9.5o+/patchlev.h	2007-01-14 20:07:08.000000000 +0000
+++ vile-9.5p/patchlev.h	2007-02-11 19:46:45.000000000 +0000
@@ -1,3 +1,3 @@
 #define VILE_RELEASE "9"
 #define VILE_VERSION "5"
-#define VILE_PATCHLEVEL "o"
+#define VILE_PATCHLEVEL "p"
Index: revlist
--- vile-9.5o+/revlist	2007-01-16 01:41:50.000000000 +0000
+++ vile-9.5p/revlist	2007-04-25 20:59:42.000000000 +0000
@@ -1,6 +1,6 @@
-revlist for vile, version v9_5o
+revlist for vile, version v9_5p
 --------------------------------------------------------------------------------
-CHANGES	1.978
+CHANGES	1.985
 CHANGES.R3	1.1
 CHANGES.R4	1.1
 CHANGES.R5	1.1
@@ -24,7 +24,7 @@
 btree.h	1.5
 buffer.c	1.314
 buglist	1.405
-builtflt.c	1.47
+builtflt.c	1.48
 charsets.c	1.8
 chgdfunc.h	1.21
 cmdtbl	1.245
@@ -41,7 +41,7 @@
 djhandl.c	1.6
 dumbterm.c	1.21
 edef.h	1.328
-estruct.h	1.608
+estruct.h	1.609
 eval.c	1.357
 exec.c	1.309
 externs.c	1.10
@@ -62,11 +62,13 @@
 lckfiles.c	1.11
 line.c	1.177
 main.c	1.590
+makeargv.c	1.1
+makeargv.h	1.1
 makefile.blc	1.20
 makefile.djg	1.35
 makefile.icc	1.16
 makefile.in	1.204
-makefile.wnt	1.92
+makefile.wnt	1.93
 map.c	1.111
 menu.c	1.49
 mkdirs.sh	1.6
@@ -77,14 +79,14 @@
 msgs.c	1.28
 npopen.c	1.94
 ntconio.c	1.87
-ntwinio.c	1.160
+ntwinio.c	1.161
 nullterm.c	1.3
 oneliner.c	1.109
 opers.c	1.92
 os2keys.h	1.2
 os2pipe.c	1.5
 os2vio.c	1.35
-patchlev.h	1.352
+patchlev.h	1.353
 path.c	1.153
 perl.xs	1.104
 plugin.c	1.1
@@ -95,7 +97,7 @@
 random.c	1.298
 regexp.c	1.136
 region.c	1.133
-revlist	v9_5o
+revlist	v9_5p
 search.c	1.143
 select.c	1.162
 sinstall.sh	1.1
@@ -112,7 +114,7 @@
 ucrypt.c	1.15
 undo.c	1.91
 version.c	1.61
-vile-9.5.spec	1.16
+vile-9.5.spec	1.17
 vile.1	1.37
 vile.hlp	1.627
 vile.wmconfig	1.1
@@ -141,7 +143,7 @@
 winvile.rc	1.11
 word.c	1.81
 wordmov.c	1.23
-wvwrap.cpp	1.10
+wvwrap.cpp	1.12
 x11.c	1.286
 x11menu.c	1.10
 xshell.sh	1.4
@@ -207,7 +209,7 @@
 filters/fdl.key	1.4
 filters/filterio.c	1.29
 filters/filters.c	1.99
-filters/filters.h	1.97
+filters/filters.h	1.98
 filters/filters.rc	1.205
 filters/flt_defs.h	1.3
 filters/fltstack.h	1.9
@@ -296,7 +298,7 @@
 filters/sml-filt.l	1.6
 filters/sml.key	1.1
 filters/spell.rc	1.6
-filters/spellflt.l	1.25
+filters/spellflt.l	1.33
 filters/sql-filt.l	1.31
 filters/sql.key	1.9
 filters/syntax.key	1.1
@@ -313,7 +315,7 @@
 filters/texifilt.l	1.6
 filters/ti-filt.l	1.21
 filters/ti.key	1.2
-filters/txt-filt.l	1.29
+filters/txt-filt.l	1.30
 filters/unfilter.c	1.9
 filters/unfilter.h	1.1
 filters/vb.key	1.7
Index: vile-9.5.spec
Prereq:  1.16 
--- vile-9.5o+/vile-9.5.spec	2007-01-14 20:06:59.000000000 +0000
+++ vile-9.5p/vile-9.5.spec	2007-02-11 19:46:45.000000000 +0000
@@ -1,7 +1,7 @@
 Summary: VILE VI Like Emacs editor
-# $Header: /usr/build/vile/vile/RCS/vile-9.5.spec,v 1.16 2007/01/14 20:06:59 tom Exp $
+# $Header: /usr/build/vile/vile/RCS/vile-9.5.spec,v 1.17 2007/02/11 19:46:45 tom Exp $
 Name: vile
-Version: 9.5o
+Version: 9.5p
 # each patch should update the version
 Release: 1
 Copyright: GPL
@@ -23,6 +23,7 @@
 Patch13: vile-9.5m.patch.gz
 Patch14: vile-9.5n.patch.gz
 Patch15: vile-9.5o.patch.gz
+Patch16: vile-9.5p.patch.gz
 # each patch should add itself to this list
 Packager: Thomas Dickey <dickey@invisible-island.net>
 BuildRoot: %{_tmppath}/%{name}-root
@@ -50,6 +51,7 @@
 %patch13 -p1
 %patch14 -p1
 %patch15 -p1
+%patch16 -p1
 # each patch should add itself to this list
 
 %build
@@ -102,6 +104,9 @@
 %changelog
 # each patch should add its ChangeLog entries here
 
+* Sun Feb 11 2007 Thomas Dickey
+- added patch for 9.5p
+
 * Sun Jan 14 2007 Thomas Dickey
 - added patch for 9.5o
 
Index: wvwrap.cpp
Prereq:  1.10 
--- vile-9.5o+/wvwrap.cpp	2006-01-04 22:53:39.000000000 +0000
+++ vile-9.5p/wvwrap.cpp	2007-04-22 23:35:12.000000000 +0000
@@ -1,4 +1,6 @@
 /*
+ * vile:notabinsert sw=4:
+ *
  * wvwrap.cpp:  A WinVile WRAPper .
  *
  * Originally written by Ed Henderson.
@@ -10,7 +12,7 @@
  * Note:  A great deal of the code included in this file is copied
  * (almost verbatim) from other vile modules.
  *
- * $Header: /usr/build/vile/vile/RCS/wvwrap.cpp,v 1.10 2006/01/04 22:53:39 cmorgan Exp $
+ * $Header: /usr/build/vile/vile/RCS/wvwrap.cpp,v 1.12 2007/04/22 23:35:12 tom Exp $
  */
 
 #include "w32vile.h"
@@ -21,17 +23,37 @@
 #include <ctype.h>
 
 #include <initguid.h>
+
 #include "w32reg.h"
 #include "w32ole.h"
+#include "vl_alloc.h"
+#include "makeargv.h"
 
-#define	typeallocn(cast,ntypes)		(cast *)malloc((ntypes)*sizeof(cast))
-#define	typereallocn(cast,ptr,ntypes)	(cast *)realloc((char *)(ptr),\
-							(ntypes)*sizeof(cast))
+#define DQUOTE '"'
+#define SQUOTE '\''
 
 static size_t   olebuf_len;    /* scaled in wchar_t */
 static OLECHAR  *olebuf;
-static char     **argv;
-static int      argc;
+
+#ifdef OPT_TRACE
+static void
+Trace(const char *fmt, ...)
+{
+    FILE *fp = fopen("c:\\temp\\wvwrap.log", "a");
+    if (fp != 0)
+    {
+        va_list ap;
+        va_start(ap, fmt);
+        vfprintf(fp, fmt, ap);
+        va_end(ap);
+        fclose(fp);
+    }
+}
+#define TRACE(params) Trace params
+#else
+#define OPT_TRACE 0
+#define TRACE(params) /* nothing */
+#endif
 
 //--------------------------------------------------------------
 
@@ -53,8 +75,6 @@
     return (*buf);
 }
 
-
-
 static int
 nomem(void)
 {
@@ -66,44 +86,6 @@
     return (1);
 }
 
-
-
-/* from ntwinio.c */
-static void
-make_argv(char *cmdline)
-{
-    int maxargs = (strlen(cmdline) + 1) / 2;
-    char *ptr;
-
-    argv = typeallocn(char *, maxargs);
-    if (! argv)
-        exit(nomem());
-
-    for (ptr = cmdline; *ptr != '\0';)
-    {
-        char delim = ' ';
-
-        while (*ptr == ' ')
-            ptr++;
-
-        if (*ptr == '\''
-         || *ptr == '"'
-         || *ptr == ' ') {
-            delim = *ptr++;
-        }
-        argv[argc++] = ptr;
-        if (argc+1 >= maxargs) {
-            break;
-        }
-        while (*ptr != delim && *ptr != '\0')
-            ptr++;
-        if (*ptr == delim)
-            *ptr++ = '\0';
-    }
-}
-
-
-
 #if (! defined(_UNICODE) || defined(UNICODE))
 /*
  * Quick & Dirty Unicode conversion routine.  Routine uses a
@@ -134,6 +116,69 @@
 }
 #endif
 
+/*
+ * vile's prompts for directory/filename do not expect to strip quotes; they
+ * use the strings exactly as given.  At the same time, the initial "cd" and
+ * "e" commands use the token parsing which stops on a blank.  That makes it
+ * not simple to use OLE to send characters to the server to specify filenames
+ * containing blanks.
+ *
+ * We work around the problem using the "eval" command, which forces a reparse
+ * of the whole line.  That uses an extra level of interpretation, so we have
+ * to double each single quote _twice_ to enter single quotes in the filename.
+ *
+ * Dollar-signs introduce another twist: vile attempts to expand the associated
+ * variables unless the $'s are escaped.  In the globbing, all of the backslashes
+ * count as escapes.
+ *
+ * Obscure, but it works.
+ */
+static char *
+escape_quotes(const char *src)
+{
+    size_t len = 4 * strlen(src) + 1;
+    char *result = typeallocn(char, len);
+
+    if (result == 0)
+        exit (nomem());
+
+    char *dst = result;
+    bool escape = (strchr(src, '$') != 0);
+    while (*src != '\0')
+    {
+        if (*src == SQUOTE)
+        {
+            *dst++ = SQUOTE;
+            *dst++ = SQUOTE;
+            *dst++ = SQUOTE;
+        }
+        else if (*src == '$')
+        {
+            *dst++ = '\\';
+        }
+        else if (*src == '\\' && escape)
+        {
+            *dst++ = '\\';
+        }
+        *dst++ = *src++;
+    }
+    *dst = '\0';
+
+    return result;
+}
+
+
+static void
+append(char *&buffer, size_t &length, char *value)
+{
+    size_t newsize = strlen(buffer) + strlen(value);
+    if ((newsize + 1) > length)
+    {
+        length = (newsize + 1) * 2;
+        buffer = (char *) realloc(buffer, length);
+    }
+    strcat(buffer, value);
+}
 
 
 int WINAPI
@@ -144,7 +189,7 @@
   )
 {
     BSTR         bstr;
-    size_t       dynbuf_len, dynbuf_idx;
+    size_t       dynbuf_len;
     HRESULT      hr;
     HWND         hwnd;
     VARIANT_BOOL insert_mode, minimized;
@@ -152,12 +197,20 @@
     OLECHAR      *olestr;
     LPUNKNOWN    punk;
     IVileAuto    *pVileAuto;
+    char         **argv;
+    int          argc;
+
+    if (make_argv(0, lpCmdLine, &argv, &argc) < 0)
+        return (nomem());
 
-    make_argv(lpCmdLine);
+#if OPT_TRACE
+    Trace("cmdline:%s\n", lpCmdLine);
+    for (int n = 0; n < argc; ++n)
+        Trace("argv%d:%s\n", n, argv[n]);
+#endif
 
     olebuf_len = 4096;
     dynbuf_len = 4096;
-    dynbuf_idx = 0;
     olebuf     = typeallocn(OLECHAR, olebuf_len);
     dynbuf     = typeallocn(char, dynbuf_len);
     if (! (olebuf && dynbuf))
@@ -208,6 +261,8 @@
     {
         char *cp;
 
+        *dynbuf = '\0';
+
         /*
          * When wvwrap starts up (and subsequently launches winvile), the
          * editor's CWD is set to a path deep within the bowels of Windows.
@@ -217,15 +272,23 @@
         cp = strrchr(*argv, '\\');
         if (cp)
         {
-            int add_delim, offset = 0;
+            int add_delim;
+
+            if (insert_mode)
+                append(dynbuf, dynbuf_len, "\033");
+
+#if OPT_TRACE
+            /*
+             * Turn on tracing in the server, for debugging.
+             */
+            append(dynbuf, dynbuf_len, ":setv $debug=true\n");
+#endif
 
             *cp = '\0';
             if (cp == *argv)
             {
                 /* filename is of the form:  \<leaf> .  handle this. */
-
-                strcpy(dynbuf, (insert_mode) ? "\033" : "");
-                strcat(dynbuf, ":cd \\\n");
+                append(dynbuf, dynbuf_len, ":cd \\\n");
             }
             else
             {
@@ -247,11 +310,6 @@
                 else
                     fp = *argv;
 
-                if (insert_mode)
-                {
-                    dynbuf[0] = '\033';
-                    offset    = 1;
-                }
                 add_delim = (isalpha(fp[0]) && fp[1] == ':' && fp[2] == '\0');
 
                 /*
@@ -261,27 +319,24 @@
                  * cd'ing to <drive>:  on a DOS/WIN32 host has special
                  * semantics (which we don't want).
                  */
-                sprintf(dynbuf + offset,
-                        ":cd %s%s\n",
-                        fp,
+                char temp[4096];
+                sprintf(temp, ":eval cd '%s%s'\n",
+                        escape_quotes(fp),
                         (add_delim) ? "\\" : "");
+
+                append(dynbuf, dynbuf_len, temp);
             }
-            dynbuf_idx = strlen(dynbuf);
-            *cp        = '\\';
+            * cp = '\\';
         }
+
         while (argc--)
         {
-            size_t len = strlen(*argv);
-
-            if (dynbuf_idx + len + sizeof(":e \n") >= dynbuf_len)
-            {
-                dynbuf_len *= 2 + len + sizeof(":e \n");
-                dynbuf      = typereallocn(char, dynbuf, dynbuf_len);
-                if (! dynbuf)
-                    return (nomem());
-            }
-            dynbuf_idx += sprintf(dynbuf + dynbuf_idx, ":e %s\n", *argv++);
+            char temp[4096];
+            sprintf(temp, ":eval e '%s'\n", escape_quotes(*argv++));
+            append(dynbuf, dynbuf_len, temp);
         }
+
+        TRACE(("dynbuf:\n%s\n", dynbuf));
         olestr = TO_OLE_STRING(dynbuf);
         bstr   = SysAllocString(olestr);
         if (! (bstr && olestr))