# 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))