mirror of
https://github.com/neovim/neovim.git
synced 2024-12-29 14:41:06 -07:00
Remove runtime/tools/ #2426
This directory contains old (at least 10+ years) scripts that mainly filter output of other old programs to make them conformant with an 'errorformat' from 10+ years ago.
This commit is contained in:
parent
b47ea5fcde
commit
a86193d88e
@ -1,37 +0,0 @@
|
||||
Some tools that can be used with Vim:
|
||||
|
||||
blink.c: C program to make the cursor blink in an xterm.
|
||||
|
||||
ccfilter*: C program to filter the output of a few compilers to a common
|
||||
QuickFix format.
|
||||
|
||||
efm_filter.*: Perl script to filter compiler messages to QuickFix format.
|
||||
|
||||
efm_perl.pl: Perl script to filter error messages from the Perl interpreter
|
||||
for use with Vim quickfix mode.
|
||||
|
||||
mve.* Awk script to filter error messages to QuickFix format.
|
||||
|
||||
pltags.pl: Perl script to create a tags file from Perl scripts.
|
||||
|
||||
ref: Shell script for the K command.
|
||||
|
||||
shtags.*: Perl script to create a tags file from a shell script.
|
||||
|
||||
vim132: Shell script to edit in 132 column mode on vt100 compatible
|
||||
terminals.
|
||||
|
||||
vimm: Shell script to start Vim on a DEC terminal with mouse
|
||||
enabled.
|
||||
|
||||
vimspell.*: Shell script for highlighting spelling mistakes.
|
||||
|
||||
vim_vs_net.cmd: MS-Windows command file to use Vim with MS Visual Studio 7 and
|
||||
later.
|
||||
|
||||
xcmdsrv_client.c: Example for a client program that communicates with a Vim
|
||||
server through the X-Windows interface.
|
||||
|
||||
unicode.vim Vim script to generate tables for src/mbyte.c.
|
||||
|
||||
[xxd can be found in the src directory]
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* An extremely simple program to make the cursor blink in an xterm.
|
||||
* This is useful when the cursor is hard to spot in a highlighted file.
|
||||
* Start in the background: "blink&" Stop by killing it.
|
||||
* Bram Moolenaar 980109 (based on an idea from John Lange).
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
main()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
printf("\e[?25h");
|
||||
fflush(stdout);
|
||||
usleep(400000); /* on time */
|
||||
printf("\e[?25l");
|
||||
fflush(stdout);
|
||||
usleep(250000); /* off time */
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
.TH ccfilter 1 "01-Apr-97"
|
||||
.SH NAME
|
||||
ccfilter \- a compiler's output filter for vim quickfix
|
||||
.SH SYNOPSIS
|
||||
ccfilter [
|
||||
.B <options>
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
The ccfilter utility "filters" the output of several compilers
|
||||
and makers (make/gmake) from several platforms (see NOTES below)
|
||||
to a standardized format which easily fits in vim's quickfix
|
||||
feature. For further details, see in vim ":help quickfix".
|
||||
.PP
|
||||
ccfilter reads
|
||||
.B 'stdin'
|
||||
and outputs to
|
||||
.B 'stdout'
|
||||
\.
|
||||
.PP
|
||||
The need for ccfilter is clear, as some compilers have irregular
|
||||
and/or multiple line error messages (with the relevant information on
|
||||
line 2), which makes it impossible for the errorformat to correctly
|
||||
display them !
|
||||
|
||||
When working on different platforms, and with different compilers,
|
||||
ccfilter eases the utilization of quickfix, due to it's standardized
|
||||
output, allowing to have in .vimrc a plain
|
||||
.br
|
||||
.B \ \ \ \ :set\ errorformat=%f:%l:%c:%t:%m
|
||||
|
||||
.SH USAGE
|
||||
When using ccfilter, one would include the following lines in .vimrc:
|
||||
.br
|
||||
.B \ \ \ \ :set shellpipe=\\\\|&ccfilter\\\\>
|
||||
.br
|
||||
.B \ \ \ \ :set errorformat=%f:%l:%c:%t:%m
|
||||
|
||||
.SH OPTIONS
|
||||
.TP 16
|
||||
-c
|
||||
Decrement column by one. This may be needed, depending on
|
||||
the compiler being used.
|
||||
.TP
|
||||
-r
|
||||
Decrement row by one. This may be needed, depending on
|
||||
the compiler being used.
|
||||
.TP
|
||||
-v
|
||||
Verbose (Outputs also invalid lines).
|
||||
This option makes ccfilter output also the lines that
|
||||
couldn't be correctly parsed. This is used mostly for
|
||||
ccfilter debugging.
|
||||
.TP
|
||||
-o <COMPILER>
|
||||
Treat input as <COMPILER>'s output.
|
||||
Even when configuring ccfilter to assume a default
|
||||
COMPILER, sometimes it's helpful to be able to specify
|
||||
the COMPILER used to generate ccfilter's input.
|
||||
For example, when cross-compiling on a network from a
|
||||
single machine.
|
||||
.TP
|
||||
-h
|
||||
Shows a brief help, describing the configured default COMPILER
|
||||
and the valid parameters for COMPILER.
|
||||
|
||||
.SH NOTES
|
||||
Currently, ccfilter accepts output from several compilers, as
|
||||
described below:
|
||||
.TP 10
|
||||
GCC
|
||||
GCC compiler
|
||||
.TP
|
||||
AIX
|
||||
AIX's C compiler
|
||||
.TP
|
||||
ATT
|
||||
AT&T/NCR's High Performance C Compiler
|
||||
.TP
|
||||
IRIX
|
||||
IRIX's MIPS/MIPSpro C compiler
|
||||
.TP
|
||||
SOLARIS
|
||||
SOLARIS's SparcWorks C compiler
|
||||
.TP
|
||||
HPUX
|
||||
HPUX's C compiler
|
||||
|
||||
.SH AUTHOR
|
||||
.B ccfilter
|
||||
was developed by
|
||||
.B Pablo Ariel Kohan
|
||||
.BR
|
||||
.B mailto:pablo@memco.co.il
|
@ -1,326 +0,0 @@
|
||||
/* ======================================================================= */
|
||||
/* Project : VIM */
|
||||
/* Module : ccfilter Version: 02.01.01 */
|
||||
/* File : ccfilter.c */
|
||||
/* Purpose : Filter gmake/cc output into a standardized form */
|
||||
/* ======================================================================= */
|
||||
/* Created On: 12-Sep-95 20:32 */
|
||||
/* Last modification: 03-Feb-98 */
|
||||
/* -e option added by Bernd Feige */
|
||||
/* ======================================================================= */
|
||||
/* Copyright : */
|
||||
/* This source file is copyright (c) to Pablo Ariel Kohan */
|
||||
/* ======================================================================= */
|
||||
#define __CCFILTER_C__
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define LINELENGTH 2048
|
||||
|
||||
/* Collector(s) */
|
||||
char Line[LINELENGTH];
|
||||
char Line2[LINELENGTH];
|
||||
/* Components */
|
||||
char FileName[1024];
|
||||
char BasePath[1024];
|
||||
char CWD[1024];
|
||||
unsigned long Row;
|
||||
unsigned long Col;
|
||||
char Severity;
|
||||
char Reason[LINELENGTH];
|
||||
|
||||
#define COMPILER_UNKNOWN 0
|
||||
#define COMPILER_GCC 1
|
||||
#define COMPILER_AIX 2
|
||||
#define COMPILER_ATT 3
|
||||
#define COMPILER_IRIX 4
|
||||
#define COMPILER_SOLARIS 5
|
||||
#define COMPILER_HPUX 6
|
||||
|
||||
char *COMPILER_Names[][2] =
|
||||
{
|
||||
/* Name Description */
|
||||
{ "N/A", "" },
|
||||
{ "GCC", "GCC compiler" },
|
||||
{ "AIX", "AIX's C compiler" },
|
||||
{ "ATT", "AT&T/NCR's High Performance C Compiler" },
|
||||
{ "IRIX", "IRIX's MIPS/MIPSpro C compiler" },
|
||||
{ "SOLARIS", "SOLARIS's SparcWorks C compiler" },
|
||||
{ "HPUX", "HPUX's C compiler" }
|
||||
};
|
||||
#define COMPILER_QTY (sizeof(COMPILER_Names)/sizeof(COMPILER_Names[0]))
|
||||
|
||||
#if defined(_GCC)
|
||||
# define COMPILER_DEFAULT COMPILER_GCC
|
||||
#elif defined(_AIX)
|
||||
# define COMPILER_DEFAULT COMPILER_AIX
|
||||
#elif defined(_ATT)
|
||||
# define COMPILER_DEFAULT COMPILER_ATT
|
||||
#elif defined(_IRIX)
|
||||
# define COMPILER_DEFAULT COMPILER_IRIX
|
||||
#elif defined(_SOLARIS)
|
||||
# define COMPILER_DEFAULT COMPILER_SOLARIS
|
||||
#elif defined(_HPUX)
|
||||
# define COMPILER_DEFAULT COMPILER_HPUX
|
||||
#else
|
||||
# define COMPILER_DEFAULT COMPILER_UNKNOWN
|
||||
#endif
|
||||
|
||||
const char USAGE[] =
|
||||
"ccfilter v2.1 (c)1994-1997 by Pablo Ariel Kohan\n"
|
||||
"Filter Out compiler's output, and converts it to fit VIM\n\n"
|
||||
"Usage:\n"
|
||||
" ccfilter [<options>]\n"
|
||||
"Where: <options> is one or more of:\n"
|
||||
" -c Decrement column by one\n"
|
||||
" -r Decrement row by one\n"
|
||||
" -e Echo stdin to stderr\n"
|
||||
" -v Verbose (Outputs also invalid lines)\n"
|
||||
" -o <COMPILER> Treat input as <COMPILER>'s output\n"
|
||||
" Note: COMPILER may be preceded by an _\n"
|
||||
" -h This usage.\n";
|
||||
|
||||
|
||||
int ShowUsage( char *szError )
|
||||
{ int i;
|
||||
|
||||
fprintf( stderr, USAGE );
|
||||
|
||||
fprintf( stderr, "Current default <COMPILER>: %s\n",
|
||||
COMPILER_Names[COMPILER_DEFAULT][0] );
|
||||
|
||||
fprintf( stderr, "Acceptable parameters for <COMPILER> are:\n" );
|
||||
for (i=1; i < COMPILER_QTY; i++)
|
||||
fprintf( stderr, " %-15.15s %s\n",
|
||||
COMPILER_Names[i][0],
|
||||
COMPILER_Names[i][1] );
|
||||
fprintf(stderr, szError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *echogets(char *s, int echo) {
|
||||
char * const retval=fgets(s, LINELENGTH, stdin);
|
||||
if (echo!=0 && retval!=NULL) {
|
||||
fputs(retval, stderr);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{ int rv, i, j, ok;
|
||||
int stay;
|
||||
int prefetch;
|
||||
char *p;
|
||||
int dec_col = 0; /* Decrement column value by 1 */
|
||||
int dec_row = 0; /* Decrement row value by 1 */
|
||||
int echo = 0; /* Echo stdin to stderr */
|
||||
int verbose = 0; /* Include Bad Formatted Lines */
|
||||
int CWDlen;
|
||||
int COMPILER = COMPILER_DEFAULT;
|
||||
|
||||
getcwd( CWD, sizeof(CWD) );
|
||||
CWDlen = strlen(CWD);
|
||||
|
||||
for (i=1; i<argc; i++)
|
||||
{
|
||||
if (argv[i][0] != '-')
|
||||
return ShowUsage("");
|
||||
switch ( argv[i][1] )
|
||||
{
|
||||
case 'c':
|
||||
dec_col = 1;
|
||||
break;
|
||||
case 'r':
|
||||
dec_row = 1;
|
||||
break;
|
||||
case 'e':
|
||||
echo = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'o':
|
||||
{
|
||||
if (i+1 >= argc)
|
||||
return ShowUsage("Error: Missing parameter for -o\n");
|
||||
i++;
|
||||
COMPILER = -1;
|
||||
for (j=1; j<COMPILER_QTY; j++)
|
||||
if ( (strcmp(argv[i], COMPILER_Names[j][0]) == 0) ||
|
||||
( (argv[i][0] == '_') &&
|
||||
(strcmp(&argv[i][1], COMPILER_Names[j][0]) == 0) ) )
|
||||
COMPILER = j;
|
||||
if (COMPILER == -1)
|
||||
return ShowUsage("Error: Invalid COMPILER specified\n");
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
return ShowUsage("");
|
||||
default:
|
||||
return ShowUsage("Error: Invalid option\n");
|
||||
}
|
||||
}
|
||||
if (COMPILER == 0)
|
||||
return ShowUsage("Error: COMPILER must be specified in this system\n");
|
||||
|
||||
stay = ( echogets(Line, echo) != NULL );
|
||||
prefetch = 0;
|
||||
|
||||
while( stay )
|
||||
{
|
||||
*FileName = 0;
|
||||
Row = 0;
|
||||
Col = 0;
|
||||
Severity = ' ';
|
||||
*Reason = 0;
|
||||
ok = 0;
|
||||
switch (COMPILER)
|
||||
{
|
||||
case COMPILER_GCC:
|
||||
Severity = 'e';
|
||||
#ifdef GOTO_FROM_WHERE_INCLUDED
|
||||
rv = sscanf( Line, "In file included from %[^:]:%u:",
|
||||
FileName, &Row );
|
||||
if ( rv == 2 )
|
||||
{
|
||||
ok = (echogets(Reason, echo) != NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if ((rv = sscanf( Line, "%[^:]:%u: warning: %[^\n]",
|
||||
FileName, &Row, Reason ))==3) {
|
||||
Severity = 'w';
|
||||
} else {
|
||||
rv = sscanf( Line, "%[^:]:%u: %[^\n]",
|
||||
FileName, &Row, Reason );
|
||||
}
|
||||
ok = ( rv == 3 );
|
||||
}
|
||||
Col = (dec_col ? 1 : 0 );
|
||||
break;
|
||||
case COMPILER_AIX:
|
||||
rv = sscanf( Line, "\"%[^\"]\", line %u.%u: %*s (%c) %[^\n]",
|
||||
FileName, &Row, &Col, &Severity, Reason );
|
||||
ok = ( rv == 5 );
|
||||
break;
|
||||
case COMPILER_HPUX:
|
||||
rv = sscanf( Line, "cc: \"%[^\"]\", line %u: %c%*[^:]: %[^\n]",
|
||||
FileName, &Row, &Severity, Reason );
|
||||
ok = ( rv == 4 );
|
||||
Col = (dec_col ? 1 : 0 );
|
||||
break;
|
||||
case COMPILER_SOLARIS:
|
||||
rv = sscanf( Line, "\"%[^\"]\", line %u: warning: %[^\n]",
|
||||
FileName, &Row, Reason );
|
||||
Severity = 'w';
|
||||
ok = ( rv == 3 );
|
||||
if ( rv != 3 )
|
||||
{
|
||||
rv = sscanf( Line, "\"%[^\"]\", line %u: %[^\n]",
|
||||
FileName, &Row, Reason );
|
||||
Severity = 'e';
|
||||
ok = ( rv == 3 );
|
||||
}
|
||||
Col = (dec_col ? 1 : 0 );
|
||||
break;
|
||||
case COMPILER_ATT:
|
||||
rv = sscanf( Line, "%c \"%[^\"]\",L%u/C%u%*[^:]:%[^\n]",
|
||||
&Severity, FileName, &Row, &Col, Reason );
|
||||
ok = ( rv == 5 );
|
||||
|
||||
if (rv != 5)
|
||||
{ rv = sscanf( Line, "%c \"%[^\"]\",L%u/C%u: %[^\n]",
|
||||
&Severity, FileName, &Row, &Col, Reason );
|
||||
ok = ( rv == 5 );
|
||||
}
|
||||
|
||||
if (rv != 5)
|
||||
{ rv = sscanf( Line, "%c \"%[^\"]\",L%u: %[^\n]",
|
||||
&Severity, FileName, &Row, Reason );
|
||||
ok = ( rv == 4 );
|
||||
Col = (dec_col ? 1 : 0 );
|
||||
}
|
||||
|
||||
stay = (echogets(Line2, echo) != NULL);
|
||||
while ( stay && (Line2[0] == '|') )
|
||||
{ for (p=&Line2[2]; (*p) && (isspace(*p)); p++);
|
||||
strcat( Reason, ": " );
|
||||
strcat( Reason, p );
|
||||
Line2[0] = 0;
|
||||
stay = (echogets(Line2, echo) != NULL);
|
||||
}
|
||||
prefetch = 1;
|
||||
strcpy( Line, Line2 );
|
||||
break;
|
||||
case COMPILER_IRIX:
|
||||
Col = 1;
|
||||
prefetch = 0;
|
||||
rv = 0;
|
||||
ok = 0;
|
||||
if ( !strncmp(Line, "cfe: ", 5) )
|
||||
{ p = &Line[5];
|
||||
Severity = tolower(*p);
|
||||
p = strchr( &Line[5], ':' );
|
||||
if (p == NULL)
|
||||
{ ok = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = sscanf( p+2, "%[^:]: %u: %[^\n]",
|
||||
FileName, &Row, Reason );
|
||||
if (rv != 3)
|
||||
rv = sscanf( p+2, "%[^,], line %u: %[^\n]",
|
||||
FileName, &Row, Reason );
|
||||
ok = ( rv == 3 );
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{ prefetch = 1;
|
||||
stay = (echogets(Line, echo) != NULL);
|
||||
if (Line[0] == ' ')
|
||||
stay = (echogets(Line2, echo) != NULL);
|
||||
if ( (Line2[0] == ' ') &&
|
||||
( (Line2[1] == '-') || (Line2[1] == '^') ) )
|
||||
{ Col = strlen(Line2)-1;
|
||||
prefetch = 0;
|
||||
}
|
||||
else
|
||||
{ strcat( Line, "\n" );
|
||||
strcat( Line, Line2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (dec_col) Col--;
|
||||
if (dec_row) Row--;
|
||||
if (!ok)
|
||||
{
|
||||
if ( Line[0] == 'g' )
|
||||
p = &Line[1];
|
||||
else
|
||||
p = &Line[0];
|
||||
ok = sscanf( p, "make[%*d]: Entering directory `%[^']",
|
||||
BasePath );
|
||||
if (verbose)
|
||||
printf( "[%u]?%s\n", ok, Line );
|
||||
}
|
||||
else
|
||||
{
|
||||
for (p=Reason; (*p) && (isspace(*p)); p++);
|
||||
if ( BasePath[CWDlen] == 0 )
|
||||
printf( "%s:%u:%u:%c:%s\n", FileName, Row, Col, Severity, p );
|
||||
else
|
||||
{
|
||||
printf( "%s/%s:%u:%u:%c:%s\n", &BasePath[CWDlen+1], FileName, Row, Col, Severity, p );
|
||||
}
|
||||
}
|
||||
if (!prefetch)
|
||||
stay = ( echogets(Line, echo) != NULL );
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
COMPILING AND INSTALLING:
|
||||
=========================
|
||||
|
||||
To compile ccfilter, you can just do a plain:
|
||||
cc ccfilter.c -o ccfilter
|
||||
Though, it may be wise to have your default compiler defined,
|
||||
so you would normally compile it with one of the following:
|
||||
cc -D_GCC ccfilter.c -o ccfilter
|
||||
cc -D_AIX ccfilter.c -o ccfilter
|
||||
cc -D_ATT ccfilter.c -o ccfilter
|
||||
cc -D_IRIX ccfilter.c -o ccfilter
|
||||
cc -D_SOLARIS ccfilter.c -o ccfilter
|
||||
cc -D_HPUX ccfilter.c -o ccfilter
|
||||
You can then copy ccfilter to its target destination (i.e: /usr/local/bin).
|
||||
The man page ccfilter.1 has to be copied to somewhere in your MANPATH,
|
||||
under a man1 directory (i.e: /usr/local/man/man1).
|
||||
|
||||
|
||||
SUPPORTED COMPILERS/PORTING NOTES:
|
||||
==================================
|
||||
|
||||
The supported formats for the different compilers are described below:
|
||||
In this section, meta-names are used as place-holders in the line
|
||||
formats: <FILE> <ROW> <COL> <SEVERITY> <REASON> <>
|
||||
The <> denotes ignored text.
|
||||
Line formats are delimited by the ^ (caret) symbol.
|
||||
|
||||
0) Special case: "gmake directory change" lines:
|
||||
Lines with a format like:
|
||||
^gmake[<NUM>]: Entering directory `<DIR>'^
|
||||
are used to follow the directory changes during the make process,
|
||||
providing in the <FILE> part, a relative (if possible) directory
|
||||
path to the erroneous file.
|
||||
|
||||
|
||||
1) GCC:
|
||||
Recognized lines are of the format:
|
||||
- ^In file included from <FILE>:<ROW>:^
|
||||
Line following this one is used as <REASON>
|
||||
<SEVERITY> is always 'e' (error)
|
||||
<COL> is always '0'
|
||||
|
||||
- ^<FILE>:<ROW>:<REASON>^
|
||||
<SEVERITY> is always 'e' (error)
|
||||
<COL> is always '0'
|
||||
|
||||
|
||||
2) AIX:
|
||||
Recognized lines are of the format:
|
||||
- ^"<FILE>", line <ROW>.<COL>: <> (<SEVERITY>) <REASON>",
|
||||
|
||||
|
||||
3) HPUX:
|
||||
Recognized lines are of the format:
|
||||
- ^cc: "<FILE>", line <ROW>: <SEVERITY>: <REASON>^
|
||||
<COL> is always '0'
|
||||
|
||||
|
||||
4) SOLARIS:
|
||||
Recognized lines are of the format:
|
||||
- ^"<FILE>", line <ROW>: warning: <REASON>^
|
||||
This assumes <SEVERITY> is "W"
|
||||
<COL> is always '0'
|
||||
|
||||
- ^"<FILE>", line <ROW>: <REASON>^
|
||||
This assumes <SEVERITY> is "E"
|
||||
<COL> is always '0'
|
||||
|
||||
|
||||
5) ATT / NCR:
|
||||
Recognized lines are of the format:
|
||||
- ^<SEVERITY> "<FILE>",L<ROW>/C<COL><>:<REASON>^
|
||||
or
|
||||
- ^<SEVERITY> "<FILE>",L<ROW>/C<COL>:<REASON>^
|
||||
Following lines beginning with a pipe (|) are continuation
|
||||
lines, and are therefore appended to the <REASON>
|
||||
|
||||
- ^<SEVERITY> "<FILE>",L<ROW>:<REASON>^
|
||||
<COL> is '0'
|
||||
Following lines beginning with a pipe (|) are continuation
|
||||
lines, and are therefore appended to the <REASON>
|
||||
|
||||
|
||||
6) SGI-IRIX:
|
||||
Recognized lines are of the format:
|
||||
- ^cfe: <SEVERITY>: <FILE>: <ROW>: <REASON>^
|
||||
or
|
||||
^cfe: <SEVERITY>: <FILE>, line <ROW>: <REASON>^
|
||||
Following lines beginning with a dash (-) are "column-bar"
|
||||
that end with a caret in the column of the error. These lines
|
||||
are analyzed to generate the <COL>.
|
@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# This program works as a filter that reads from stdin, copies to
|
||||
# stdout *and* creates an error file that can be read by vim.
|
||||
#
|
||||
# This program has only been tested on SGI, Irix5.3.
|
||||
#
|
||||
# Written by Ives Aerts in 1996. This little program is not guaranteed
|
||||
# to do (or not do) anything at all and can be freely used for
|
||||
# whatever purpose you can think of.
|
||||
|
||||
$args = @ARGV;
|
||||
|
||||
unless ($args == 1) {
|
||||
die("Usage: vimccparse <output filename>\n");
|
||||
}
|
||||
|
||||
$filename = @ARGV[0];
|
||||
open (OUT, ">$filename") || die ("Can't open file: \"$filename\"");
|
||||
|
||||
while (<STDIN>) {
|
||||
print;
|
||||
if ( (/"(.*)", line (\d+): (e)rror\((\d+)\):/)
|
||||
|| (/"(.*)", line (\d+): (w)arning\((\d+)\):/) ) {
|
||||
$file=$1;
|
||||
$line=$2;
|
||||
$errortype="\u$3";
|
||||
$errornr=$4;
|
||||
chop($errormsg=<STDIN>);
|
||||
$errormsg =~ s/^\s*//;
|
||||
$sourceline=<STDIN>;
|
||||
$column=index(<STDIN>, "^") - 1;
|
||||
|
||||
print OUT "$file>$line:$column:$errortype:$errornr:$errormsg\n";
|
||||
}
|
||||
}
|
||||
|
||||
close(OUT);
|
||||
exit(0);
|
@ -1,31 +0,0 @@
|
||||
[adopted from a message that Ives posted in the Vim mailing list]
|
||||
|
||||
Some compilers produce an error message that cannot be handled with
|
||||
'errorformat' in Vim. Following is an example of a Perl script that
|
||||
translates one error message into something that Vim understands.
|
||||
|
||||
|
||||
The compiler that generates this kind of error messages (4 lines):
|
||||
|
||||
"/tmp_mnt/cm/src/apertos/MoU/MetaCore/MetaCore/common/src/MetaCoreImp_M.cc",
|
||||
line 50: error(3114):
|
||||
identifier "PRIMITIVE_M" is undefined
|
||||
return(ExecuteCore(PRIMITIVE_M,
|
||||
|
||||
You can find a small perl program at the end.
|
||||
The way I use it is:
|
||||
|
||||
:set errorformat=%f>%l:%c:%t:%n:%m
|
||||
:set makeprg=clearmake\ -C\ gnu
|
||||
:set shellpipe=2>&1\|\ vimccparse
|
||||
|
||||
If somebody thinks this is useful: feel free to do whatever you can think
|
||||
of with this code.
|
||||
|
||||
-Ives
|
||||
____________________________________________________________
|
||||
Ives Aerts (SW Developer) Sony Telecom Europe
|
||||
ives@sonytel.be St.Stevens Woluwestr. 55
|
||||
`Death could create most things, B-1130 Brussels, Belgium
|
||||
except for plumbing.' PHONE : +32 2 724 19 67
|
||||
(Soul Music - T.Pratchett) FAX : +32 2 726 26 86
|
@ -1,153 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# vimparse.pl - Reformats the error messages of the Perl interpreter for use
|
||||
# with the quickfix mode of Vim
|
||||
#
|
||||
# Copyright (c) 2001 by Joerg Ziefle <joerg.ziefle@gmx.de>
|
||||
# You may use and distribute this software under the same terms as Perl itself.
|
||||
#
|
||||
# Usage: put one of the two configurations below in your ~/.vimrc (without the
|
||||
# description and '# ') and enjoy (be sure to adjust the paths to vimparse.pl
|
||||
# before):
|
||||
#
|
||||
# Program is run interactively with 'perl -w':
|
||||
#
|
||||
# set makeprg=$HOME/bin/vimparse.pl\ %\ $*
|
||||
# set errorformat=%f:%l:%m
|
||||
#
|
||||
# Program is only compiled with 'perl -wc':
|
||||
#
|
||||
# set makeprg=$HOME/bin/vimparse.pl\ -c\ %\ $*
|
||||
# set errorformat=%f:%l:%m
|
||||
#
|
||||
# Usage:
|
||||
# vimparse.pl [-c] [-f <errorfile>] <programfile> [programargs]
|
||||
#
|
||||
# -c compile only, don't run (perl -wc)
|
||||
# -f write errors to <errorfile>
|
||||
#
|
||||
# Example usages:
|
||||
# * From the command line:
|
||||
# vimparse.pl program.pl
|
||||
#
|
||||
# vimparse.pl -c -f errorfile program.pl
|
||||
# Then run vim -q errorfile to edit the errors with Vim.
|
||||
#
|
||||
# * From Vim:
|
||||
# Edit in Vim (and save, if you don't have autowrite on), then
|
||||
# type ':mak' or ':mak args' (args being the program arguments)
|
||||
# to error check.
|
||||
#
|
||||
# Version history:
|
||||
# 0.2 (04/12/2001):
|
||||
# * First public version (sent to Bram)
|
||||
# * -c command line option for compiling only
|
||||
# * grammatical fix: 'There was 1 error.'
|
||||
# * bug fix for multiple arguments
|
||||
# * more error checks
|
||||
# * documentation (top of file, &usage)
|
||||
# * minor code clean ups
|
||||
# 0.1 (02/02/2001):
|
||||
# * Initial version
|
||||
# * Basic functionality
|
||||
#
|
||||
# Todo:
|
||||
# * test on more systems
|
||||
# * use portable way to determine the location of perl ('use Config')
|
||||
# * include option that shows perldiag messages for each error
|
||||
# * allow to pass in program by STDIN
|
||||
# * more intuitive behaviour if no error is found (show message)
|
||||
#
|
||||
# Tested under SunOS 5.7 with Perl 5.6.0. Let me know if it's not working for
|
||||
# you.
|
||||
|
||||
use strict;
|
||||
use Getopt::Std;
|
||||
|
||||
use vars qw/$opt_c $opt_f $opt_h/; # needed for Getopt in combination with use strict 'vars'
|
||||
|
||||
use constant VERSION => 0.2;
|
||||
|
||||
getopts('cf:h');
|
||||
|
||||
&usage if $opt_h; # not necessarily needed, but good for further extension
|
||||
|
||||
if (defined $opt_f) {
|
||||
|
||||
open FILE, "> $opt_f" or do {
|
||||
warn "Couldn't open $opt_f: $!. Using STDOUT instead.\n";
|
||||
undef $opt_f;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
my $handle = (defined $opt_f ? \*FILE : \*STDOUT);
|
||||
|
||||
(my $file = shift) or &usage; # display usage if no filename is supplied
|
||||
my $args = (@ARGV ? ' ' . join ' ', @ARGV : '');
|
||||
|
||||
my @lines = `perl @{[defined $opt_c ? '-c ' : '' ]} -w "$file$args" 2>&1`;
|
||||
|
||||
my $errors = 0;
|
||||
foreach my $line (@lines) {
|
||||
|
||||
chomp($line);
|
||||
my ($file, $lineno, $message, $rest);
|
||||
|
||||
if ($line =~ /^(.*)\sat\s(.*)\sline\s(\d+)(\.|,\snear\s\".*\")$/) {
|
||||
|
||||
($message, $file, $lineno, $rest) = ($1, $2, $3, $4);
|
||||
$errors++;
|
||||
$message .= $rest if ($rest =~ s/^,//);
|
||||
print $handle "$file:$lineno:$message\n";
|
||||
|
||||
} else { next };
|
||||
|
||||
}
|
||||
|
||||
if (defined $opt_f) {
|
||||
|
||||
my $msg;
|
||||
if ($errors == 1) {
|
||||
|
||||
$msg = "There was 1 error.\n";
|
||||
|
||||
} else {
|
||||
|
||||
$msg = "There were $errors errors.\n";
|
||||
|
||||
};
|
||||
|
||||
print STDOUT $msg;
|
||||
close FILE;
|
||||
unlink $opt_f unless $errors;
|
||||
|
||||
};
|
||||
|
||||
sub usage {
|
||||
|
||||
(local $0 = $0) =~ s/^.*\/([^\/]+)$/$1/; # remove path from name of program
|
||||
print<<EOT;
|
||||
Usage:
|
||||
$0 [-c] [-f <errorfile>] <programfile> [programargs]
|
||||
|
||||
-c compile only, don't run (executes 'perl -wc')
|
||||
-f write errors to <errorfile>
|
||||
|
||||
Examples:
|
||||
* At the command line:
|
||||
$0 program.pl
|
||||
Displays output on STDOUT.
|
||||
|
||||
$0 -c -f errorfile program.pl
|
||||
Then run 'vim -q errorfile' to edit the errors with Vim.
|
||||
|
||||
* In Vim:
|
||||
Edit in Vim (and save, if you don't have autowrite on), then
|
||||
type ':mak' or ':mak args' (args being the program arguments)
|
||||
to error check.
|
||||
EOT
|
||||
|
||||
exit 0;
|
||||
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
#!/usr/bin/nawk -f
|
||||
#
|
||||
# Change "nawk" to "awk" or "gawk" if you get errors.
|
||||
#
|
||||
# Make Vim Errors
|
||||
# Processes errors from cc for use by Vim's quick fix tools
|
||||
# specifically it translates the ---------^ notation to a
|
||||
# column number
|
||||
#
|
||||
BEGIN { FS="[:,]" }
|
||||
|
||||
/^cfe/ { file=$3
|
||||
msg=$5
|
||||
split($4,s," ")
|
||||
line=s[2]
|
||||
}
|
||||
|
||||
# You may have to substitute a tab character for the \t here:
|
||||
/^[\t-]*\^/ {
|
||||
p=match($0, ".*\\^" )
|
||||
col=RLENGTH-2
|
||||
printf("%s, line %d, col %d : %s\n", file,line,col,msg)
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
[ The mve awk script was posted on the vimdev mailing list ]
|
||||
|
||||
From: jimmer@barney.mdhc.mdc.com (J. McGlasson)
|
||||
Date: Mon, 31 Mar 1997 13:16:49 -0700 (Mar)
|
||||
|
||||
My compiler (SGI MIPSpro C compiler - IRIX 6.4) works like this.
|
||||
I have written a script mve (make vim errors), through which I pipe my make
|
||||
output, which translates output of the following form:
|
||||
|
||||
cfe: Error: syntax.c, line 4: Syntax Error
|
||||
int i[12;
|
||||
------------^
|
||||
|
||||
into:
|
||||
|
||||
cl.c, line 4, col 12 : Syntax Error
|
||||
|
||||
(in vim notation: %f, line %l, col %c : %m)
|
||||
|
||||
You might be able to tailor this for your compiler's output.
|
@ -1,300 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# pltags - create a tags file for Perl code, for use by vi(m)
|
||||
#
|
||||
# Distributed with Vim <http://www.vim.org/>, latest version always available
|
||||
# at <http://www.mscha.com/mscha.html?pltags#tools>
|
||||
#
|
||||
# Version 2.3, 28 February 2002
|
||||
#
|
||||
# Written by Michael Schaap <pltags@mscha.com>. Suggestions for improvement
|
||||
# are very welcome!
|
||||
#
|
||||
# This script will not work with Perl 4 or below!
|
||||
#
|
||||
# Revision history:
|
||||
# 1.0 1997? Original version, quickly hacked together
|
||||
# 2.0 1999? Completely rewritten, better structured and documented,
|
||||
# support for variables, packages, Exuberant Ctags extensions
|
||||
# 2.1 Jun 2000 Fixed critical bug (typo in comment) ;-)
|
||||
# Support multiple level packages (e.g. Archive::Zip::Member)
|
||||
# 2.2 Jul 2001 'Glob' wildcards - especially useful under Windows
|
||||
# (thanks to Serge Sivkov and Jason King)
|
||||
# Bug fix: reset package name for each file
|
||||
# 2.21 Jul 2001 Oops... bug in variable detection (/local../ -> /^local.../)
|
||||
# 2.3 Feb 2002 Support variables declared with "our"
|
||||
# (thanks to Lutz Mende)
|
||||
|
||||
# Complain about undeclared variables
|
||||
use strict;
|
||||
|
||||
# Used modules
|
||||
use Getopt::Long;
|
||||
|
||||
# Options with their defaults
|
||||
my $do_subs = 1; # --subs, --nosubs include subs in tags file?
|
||||
my $do_vars = 1; # --vars, --novars include variables in tags file?
|
||||
my $do_pkgs = 1; # --pkgs, --nopkgs include packages in tags file?
|
||||
my $do_exts = 1; # --extensions, --noextensions
|
||||
# include Exuberant Ctags extensions
|
||||
|
||||
# Global variables
|
||||
my $VERSION = "2.21"; # pltags version
|
||||
my $status = 0; # GetOptions return value
|
||||
my $file = ""; # File being processed
|
||||
my @tags = (); # List of produced tags
|
||||
my $is_pkg = 0; # Are we tagging a package?
|
||||
my $has_subs = 0; # Has this file any subs yet?
|
||||
my $package_name = ""; # Name of current package
|
||||
my $var_continues = 0; # Variable declaration continues on last line
|
||||
my $line = ""; # Current line in file
|
||||
my $stmt = ""; # Current Perl statement
|
||||
my @vars = (); # List of variables in declaration
|
||||
my $var = ""; # Variable in declaration
|
||||
my $tagline = ""; # Tag file line
|
||||
|
||||
# Create a tag file line and push it on the list of found tags
|
||||
sub MakeTag($$$$$)
|
||||
{
|
||||
my ($tag, # Tag name
|
||||
$type, # Type of tag
|
||||
$is_static, # Is this a static tag?
|
||||
$file, # File in which tag appears
|
||||
$line) = @_; # Line in which tag appears
|
||||
|
||||
my $tagline = ""; # Created tag line
|
||||
|
||||
# Only process tag if not empty
|
||||
if ($tag)
|
||||
{
|
||||
# Get rid of \n, and escape / and \ in line
|
||||
chomp $line;
|
||||
$line =~ s/\\/\\\\/g;
|
||||
$line =~ s/\//\\\//g;
|
||||
|
||||
# Create a tag line
|
||||
$tagline = "$tag\t$file\t/^$line\$/";
|
||||
|
||||
# If we're told to do so, add extensions
|
||||
if ($do_exts)
|
||||
{
|
||||
$tagline .= ";\"\t$type"
|
||||
. ($is_static ? "\tfile:" : "")
|
||||
. ($package_name ? "\tclass:$package_name" : "");
|
||||
}
|
||||
|
||||
# Push it on the stack
|
||||
push (@tags, $tagline);
|
||||
}
|
||||
}
|
||||
|
||||
# Parse package name from statement
|
||||
sub PackageName($)
|
||||
{
|
||||
my ($stmt) = @_; # Statement
|
||||
|
||||
# Look for the argument to "package". Return it if found, else return ""
|
||||
if ($stmt =~ /^package\s+([\w:]+)/)
|
||||
{
|
||||
my $pkgname = $1;
|
||||
|
||||
# Remove any parent package name(s)
|
||||
$pkgname =~ s/.*://;
|
||||
return $pkgname;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
# Parse sub name from statement
|
||||
sub SubName($)
|
||||
{
|
||||
my ($stmt) = @_; # Statement
|
||||
|
||||
# Look for the argument to "sub". Return it if found, else return ""
|
||||
if ($stmt =~ /^sub\s+([\w:]+)/)
|
||||
{
|
||||
my $subname = $1;
|
||||
|
||||
# Remove any parent package name(s)
|
||||
$subname =~ s/.*://;
|
||||
return $subname;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
# Parse all variable names from statement
|
||||
sub VarNames($)
|
||||
{
|
||||
my ($stmt) = @_;
|
||||
|
||||
# Remove my or local from statement, if present
|
||||
$stmt =~ s/^(my|our|local)\s+//;
|
||||
|
||||
# Remove any assignment piece
|
||||
$stmt =~ s/\s*=.*//;
|
||||
|
||||
# Now find all variable names, i.e. "words" preceded by $, @ or %
|
||||
@vars = ($stmt =~ /[\$\@\%]([\w:]+)\b/g);
|
||||
|
||||
# Remove any parent package name(s)
|
||||
map(s/.*://, @vars);
|
||||
|
||||
return (@vars);
|
||||
}
|
||||
|
||||
############### Start ###############
|
||||
|
||||
print "\npltags $VERSION by Michael Schaap <mscha\@mscha.com>\n\n";
|
||||
|
||||
# Get options
|
||||
$status = GetOptions("subs!" => \$do_subs,
|
||||
"vars!" => \$do_vars,
|
||||
"pkgs!" => \$do_pkgs,
|
||||
"extensions!" => \$do_exts);
|
||||
|
||||
# Usage if error in options or no arguments given
|
||||
unless ($status && @ARGV)
|
||||
{
|
||||
print "\n" unless ($status);
|
||||
print " Usage: $0 [options] filename ...\n\n";
|
||||
print " Where options can be:\n";
|
||||
print " --subs (--nosubs) (don't) include sub declarations in tag file\n";
|
||||
print " --vars (--novars) (don't) include variable declarations in tag file\n";
|
||||
print " --pkgs (--nopkgs) (don't) include package declarations in tag file\n";
|
||||
print " --extensions (--noextensions)\n";
|
||||
print " (don't) include Exuberant Ctags / Vim style\n";
|
||||
print " extensions in tag file\n\n";
|
||||
print " Default options: ";
|
||||
print ($do_subs ? "--subs " : "--nosubs ");
|
||||
print ($do_vars ? "--vars " : "--novars ");
|
||||
print ($do_pkgs ? "--pkgs " : "--nopkgs ");
|
||||
print ($do_exts ? "--extensions\n\n" : "--noextensions\n\n");
|
||||
print " Example: $0 *.pl *.pm ../shared/*.pm\n\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
# Loop through files on command line - 'glob' any wildcards, since Windows
|
||||
# doesn't do this for us
|
||||
foreach $file (map { glob } @ARGV)
|
||||
{
|
||||
# Skip if this is not a file we can open. Also skip tags files and backup
|
||||
# files
|
||||
next unless ((-f $file) && (-r $file) && ($file !~ /tags$/)
|
||||
&& ($file !~ /~$/));
|
||||
|
||||
print "Tagging file $file...\n";
|
||||
|
||||
$is_pkg = 0;
|
||||
$package_name = "";
|
||||
$has_subs = 0;
|
||||
$var_continues = 0;
|
||||
|
||||
open (IN, $file) or die "Can't open file '$file': $!";
|
||||
|
||||
# Loop through file
|
||||
foreach $line (<IN>)
|
||||
{
|
||||
# Statement is line with comments and whitespace trimmed
|
||||
($stmt = $line) =~ s/#.*//;
|
||||
$stmt =~ s/^\s*//;
|
||||
$stmt =~ s/\s*$//;
|
||||
|
||||
# Nothing left? Never mind.
|
||||
next unless ($stmt);
|
||||
|
||||
# This is a variable declaration if one was started on the previous
|
||||
# line, or if this line starts with my or local
|
||||
if ($var_continues or ($stmt =~/^my\b/)
|
||||
or ($stmt =~/^our\b/) or ($stmt =~/^local\b/))
|
||||
{
|
||||
# The declaration continues if the line does not end with ;
|
||||
$var_continues = ($stmt !~ /;$/);
|
||||
|
||||
# Loop through all variable names in the declaration
|
||||
foreach $var (VarNames($stmt))
|
||||
{
|
||||
# Make a tag for this variable unless we're told not to. We
|
||||
# assume that a variable is always static, unless it appears
|
||||
# in a package before any sub. (Not necessarily true, but
|
||||
# it's ok for most purposes and Vim works fine even if it is
|
||||
# incorrect)
|
||||
if ($do_vars)
|
||||
{
|
||||
MakeTag($var, "v", (!$is_pkg or $has_subs), $file, $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# This is a package declaration if the line starts with package
|
||||
elsif ($stmt =~/^package\b/)
|
||||
{
|
||||
# Get name of the package
|
||||
$package_name = PackageName($stmt);
|
||||
|
||||
if ($package_name)
|
||||
{
|
||||
# Remember that we're doing a package
|
||||
$is_pkg = 1;
|
||||
|
||||
# Make a tag for this package unless we're told not to. A
|
||||
# package is never static.
|
||||
if ($do_pkgs)
|
||||
{
|
||||
MakeTag($package_name, "p", 0, $file, $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# This is a sub declaration if the line starts with sub
|
||||
elsif ($stmt =~/^sub\b/)
|
||||
{
|
||||
# Remember that this file has subs
|
||||
$has_subs = 1;
|
||||
|
||||
# Make a tag for this sub unless we're told not to. We assume
|
||||
# that a sub is static, unless it appears in a package. (Not
|
||||
# necessarily true, but it's ok for most purposes and Vim works
|
||||
# fine even if it is incorrect)
|
||||
if ($do_subs)
|
||||
{
|
||||
MakeTag(SubName($stmt), "s", (!$is_pkg), $file, $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
close (IN);
|
||||
}
|
||||
|
||||
# Do we have any tags? If so, write them to the tags file
|
||||
if (@tags)
|
||||
{
|
||||
# Add some tag file extensions if we're told to
|
||||
if ($do_exts)
|
||||
{
|
||||
push (@tags, "!_TAG_FILE_FORMAT\t2\t/extended format/");
|
||||
push (@tags, "!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted/");
|
||||
push (@tags, "!_TAG_PROGRAM_AUTHOR\tMichael Schaap\t/mscha\@mscha.com/");
|
||||
push (@tags, "!_TAG_PROGRAM_NAME\tpltags\t//");
|
||||
push (@tags, "!_TAG_PROGRAM_VERSION\t$VERSION\t/supports multiple tags and extended format/");
|
||||
}
|
||||
|
||||
print "\nWriting tags file.\n";
|
||||
|
||||
open (OUT, ">tags") or die "Can't open tags file: $!";
|
||||
|
||||
foreach $tagline (sort @tags)
|
||||
{
|
||||
print OUT "$tagline\n";
|
||||
}
|
||||
|
||||
close (OUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
print "\nNo tags found.\n";
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# ref - Check spelling of the arguments
|
||||
#
|
||||
# Usage: ref word ..
|
||||
#
|
||||
# can be used for the K command of Vim
|
||||
#
|
||||
spell <<EOF
|
||||
$*
|
||||
EOF
|
@ -1,61 +0,0 @@
|
||||
.TH shtags 1 "local Utilities"
|
||||
.SH NAME
|
||||
shtags \- Create tags for shell scripts
|
||||
.SH SYNOPSIS
|
||||
.B shtags
|
||||
[\fI-mvw\fP] [\fI-t <file>\fP] [\fI-s <shell>\fP] <files>
|
||||
.SH DESCRIPTION
|
||||
\fBshtags\fP creates a \fBvi(1)\fP tags file for shell scripts - which
|
||||
essentially turns your code into a hypertext document. \fBshtags\fP
|
||||
attempts to create tags for all function and variable definitions,
|
||||
although this is a little difficult, because in most shell languages,
|
||||
variables don't need to be explicitly defined, and as such there is
|
||||
often no distinct "variable definition". If this is the case,
|
||||
\fBshtags\fP simply creates a tag for the first instance of a variable
|
||||
which is being set in a simple way, ie: \fIset x = 5\fP.
|
||||
.SH OPTIONS
|
||||
.IP "\fB-t <file>\fP"
|
||||
Name of tags file to create. (default is 'tags')
|
||||
.IP "\fB-s <shell>\fP"
|
||||
The name of the shell used by the script(s). By default,
|
||||
\fBshtags\fP tries to work out which is the appropriate shell for each
|
||||
file individually by looking at the first line of each file. This wont
|
||||
work however, if the script starts as a bourne shell script and tries
|
||||
to be clever about starting the shell it really wants.
|
||||
.b
|
||||
Currently supported shells are:
|
||||
.RS
|
||||
.IP \fBsh\fP
|
||||
Bourne Shell
|
||||
.IP \fBperl\fP
|
||||
Perl (versions 4 and 5)
|
||||
.IP \fBksh\fP
|
||||
Korn Shell
|
||||
.IP \fBtclsh\fP
|
||||
The TCL shell
|
||||
.IP \fBwish\fP
|
||||
The TK Windowing shell (same as tclsh)
|
||||
.RE
|
||||
|
||||
.IP \fB-v\fP
|
||||
Include variable definitions (variables mentioned at the start of a line)
|
||||
.IP \fB-V\fP
|
||||
Print version information.
|
||||
.IP \fB-w\fP
|
||||
Suppress "duplicate tag" warning messages.
|
||||
.IP \fB-x\fP
|
||||
Explicitly create a new tags file. Normally new tags are merged with
|
||||
the old tags file.
|
||||
.PP
|
||||
\fBshtags\fP scans the specified files for subroutines and possibly
|
||||
variable definitions, and creates a \fBvi\fP style tags file.
|
||||
.SH FILES
|
||||
.IP \fBtags\fP
|
||||
A tags file contains a sorted list of tags, one tag per line. The
|
||||
format is the same as that used by \fBvi\fP(1)
|
||||
.SH AUTHOR
|
||||
Stephen Riehm
|
||||
.br
|
||||
sr@pc-plus.de
|
||||
.SH "SEE ALSO"
|
||||
ctags(1), etags(1), perl(1), tclsh(1), wish(1), sh(1), ksh(1).
|
@ -1,144 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# shtags: create a tags file for perl scripts
|
||||
#
|
||||
# Author: Stephen Riehm
|
||||
# Last Changed: 96/11/27 19:46:06
|
||||
#
|
||||
# "@(#) shtags 1.1 by S. Riehm"
|
||||
#
|
||||
|
||||
# obvious... :-)
|
||||
sub usage
|
||||
{
|
||||
print <<_EOUSAGE_ ;
|
||||
USAGE: $program [-kvwVx] [-t <file>] <files>
|
||||
-t <file> Name of tags file to create. (default is 'tags')
|
||||
-s <shell> Name of the shell language in the script
|
||||
-v Include variable definitions.
|
||||
(variables mentioned at the start of a line)
|
||||
-V Print version information.
|
||||
-w Suppress "duplicate tag" warnings.
|
||||
-x Explicitly create a new tags file. Normally tags are merged.
|
||||
<files> List of files to scan for tags.
|
||||
_EOUSAGE_
|
||||
exit 0
|
||||
}
|
||||
|
||||
sub version
|
||||
{
|
||||
#
|
||||
# Version information
|
||||
#
|
||||
@id = split( ', ', 'scripts/bin/shtags, /usr/local/, LOCAL_SCRIPTS, 1.1, 96/11/27, 19:46:06' );
|
||||
$id[0] =~ s,.*/,,;
|
||||
print <<_EOVERS;
|
||||
$id[0]: $id[3]
|
||||
Last Modified: @id[4,5]
|
||||
Component: $id[1]
|
||||
Release: $id[2]
|
||||
_EOVERS
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
#
|
||||
# initialisations
|
||||
#
|
||||
($program = $0) =~ s,.*/,,;
|
||||
require 'getopts.pl';
|
||||
|
||||
#
|
||||
# parse command line
|
||||
#
|
||||
&Getopts( "t:s:vVwx" ) || &usage();
|
||||
$tags_file = $opt_t || 'tags';
|
||||
$explicit = $opt_x;
|
||||
$variable_tags = $opt_v;
|
||||
$allow_warnings = ! $opt_w;
|
||||
&version if $opt_V;
|
||||
&usage() unless @ARGV != 0;
|
||||
|
||||
# slurp up the existing tags. Some will be replaced, the ones that aren't
|
||||
# will be re-written exactly as they were read
|
||||
if( ! $explicit && open( TAGS, "< $tags_file" ) )
|
||||
{
|
||||
while( <TAGS> )
|
||||
{
|
||||
/^\S+/;
|
||||
$tags{$&} = $_;
|
||||
}
|
||||
close( TAGS );
|
||||
}
|
||||
|
||||
#
|
||||
# for each line of every file listed on the command line, look for a
|
||||
# 'sub' definition, or, if variables are wanted aswell, look for a
|
||||
# variable definition at the start of a line
|
||||
#
|
||||
while( <> )
|
||||
{
|
||||
&check_shell($_), ( $old_file = $ARGV ) if $ARGV ne $old_file;
|
||||
next unless $shell;
|
||||
if( $shell eq "sh" )
|
||||
{
|
||||
next unless /^\s*(((\w+)))\s*\(\s*\)/
|
||||
|| ( $variable_tags && /^(((\w+)=))/ );
|
||||
$match = $3;
|
||||
}
|
||||
if( $shell eq "ksh" )
|
||||
{
|
||||
# ksh
|
||||
next unless /^\s*function\s+(((\w+)))/
|
||||
|| ( $variable_tags && /^(((\w+)=))/ );
|
||||
$match = $3;
|
||||
}
|
||||
if( $shell eq "perl" )
|
||||
{
|
||||
# perl
|
||||
next unless /^\s*sub\s+(\w+('|::))?(\w+)/
|
||||
|| /^\s*(((\w+))):/
|
||||
|| ( $variable_tags && /^(([(\s]*[\$\@\%]{1}(\w+).*=))/ );
|
||||
$match = $3;
|
||||
}
|
||||
if( $shell eq "tcl" )
|
||||
{
|
||||
next unless /^\s*proc\s+(((\S+)))/
|
||||
|| ( $variable_tags && /^\s*set\s+(((\w+)\s))/ );
|
||||
$match = $3;
|
||||
}
|
||||
chop;
|
||||
warn "$match - duplicate ignored\n"
|
||||
if ( $new{$match}++
|
||||
|| !( $tags{$match} = sprintf( "%s\t%s\t?^%s\$?\n", $match, $ARGV, $_ ) ) )
|
||||
&& $allow_warnings;
|
||||
}
|
||||
|
||||
# write the new tags to the tags file - note that the whole file is rewritten
|
||||
open( TAGS, "> $tags_file" );
|
||||
foreach( sort( keys %tags ) )
|
||||
{
|
||||
print TAGS "$tags{$_}";
|
||||
}
|
||||
close( TAGS );
|
||||
|
||||
sub check_shell
|
||||
{
|
||||
local( $_ ) = @_;
|
||||
# read the first line of a script, and work out which shell it is,
|
||||
# unless a shell was specified on the command line
|
||||
#
|
||||
# This routine can't handle clever scripts which start sh and then
|
||||
# use sh to start the shell they really wanted.
|
||||
if( $opt_s )
|
||||
{
|
||||
$shell = $opt_s;
|
||||
}
|
||||
else
|
||||
{
|
||||
$shell = "sh" if /^:$/ || /^#!.*\/bin\/sh/;
|
||||
$shell = "ksh" if /^#!.*\/ksh/;
|
||||
$shell = "perl" if /^#!.*\/perl/;
|
||||
$shell = "tcl" if /^#!.*\/wish/;
|
||||
printf "Using $shell for $ARGV\n";
|
||||
}
|
||||
}
|
@ -1,290 +0,0 @@
|
||||
" Script to extract tables from Unicode .txt files, to be used in src/mbyte.c.
|
||||
" The format of the UnicodeData.txt file is explained here:
|
||||
" http://www.unicode.org/Public/5.1.0/ucd/UCD.html
|
||||
" For the other files see the header.
|
||||
"
|
||||
" Usage: Vim -S <this-file>
|
||||
"
|
||||
" Author: Bram Moolenaar
|
||||
" Last Update: 2010 Jan 12
|
||||
|
||||
" Parse lines of UnicodeData.txt. Creates a list of lists in s:dataprops.
|
||||
func! ParseDataToProps()
|
||||
let s:dataprops = []
|
||||
let lnum = 1
|
||||
while lnum <= line('$')
|
||||
let l = split(getline(lnum), '\s*;\s*', 1)
|
||||
if len(l) != 15
|
||||
echoerr 'Found ' . len(l) . ' items in line ' . lnum . ', expected 15'
|
||||
return
|
||||
endif
|
||||
call add(s:dataprops, l)
|
||||
let lnum += 1
|
||||
endwhile
|
||||
endfunc
|
||||
|
||||
" Parse lines of CaseFolding.txt. Creates a list of lists in s:foldprops.
|
||||
func! ParseFoldProps()
|
||||
let s:foldprops = []
|
||||
let lnum = 1
|
||||
while lnum <= line('$')
|
||||
let line = getline(lnum)
|
||||
if line !~ '^#' && line !~ '^\s*$'
|
||||
let l = split(line, '\s*;\s*', 1)
|
||||
if len(l) != 4
|
||||
echoerr 'Found ' . len(l) . ' items in line ' . lnum . ', expected 4'
|
||||
return
|
||||
endif
|
||||
call add(s:foldprops, l)
|
||||
endif
|
||||
let lnum += 1
|
||||
endwhile
|
||||
endfunc
|
||||
|
||||
" Parse lines of EastAsianWidth.txt. Creates a list of lists in s:widthprops.
|
||||
func! ParseWidthProps()
|
||||
let s:widthprops = []
|
||||
let lnum = 1
|
||||
while lnum <= line('$')
|
||||
let line = getline(lnum)
|
||||
if line !~ '^#' && line !~ '^\s*$'
|
||||
let l = split(line, '\s*;\s*', 1)
|
||||
if len(l) != 2
|
||||
echoerr 'Found ' . len(l) . ' items in line ' . lnum . ', expected 2'
|
||||
return
|
||||
endif
|
||||
call add(s:widthprops, l)
|
||||
endif
|
||||
let lnum += 1
|
||||
endwhile
|
||||
endfunc
|
||||
|
||||
" Build the toLower or toUpper table in a new buffer.
|
||||
" Uses s:dataprops.
|
||||
func! BuildCaseTable(name, index)
|
||||
let start = -1
|
||||
let end = -1
|
||||
let step = 0
|
||||
let add = -1
|
||||
let ranges = []
|
||||
for p in s:dataprops
|
||||
if p[a:index] != ''
|
||||
let n = ('0x' . p[0]) + 0
|
||||
let nl = ('0x' . p[a:index]) + 0
|
||||
if start >= 0 && add == nl - n && (step == 0 || n - end == step)
|
||||
" continue with same range.
|
||||
let step = n - end
|
||||
let end = n
|
||||
else
|
||||
if start >= 0
|
||||
" produce previous range
|
||||
call Range(ranges, start, end, step, add)
|
||||
endif
|
||||
let start = n
|
||||
let end = n
|
||||
let step = 0
|
||||
let add = nl - n
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
if start >= 0
|
||||
call Range(ranges, start, end, step, add)
|
||||
endif
|
||||
|
||||
" New buffer to put the result in.
|
||||
new
|
||||
exe "file to" . a:name
|
||||
call setline(1, "static convertStruct to" . a:name . "[] =")
|
||||
call setline(2, "{")
|
||||
call append('$', ranges)
|
||||
call setline('$', getline('$')[:-2]) " remove last comma
|
||||
call setline(line('$') + 1, "};")
|
||||
wincmd p
|
||||
endfunc
|
||||
|
||||
" Build the foldCase table in a new buffer.
|
||||
" Uses s:foldprops.
|
||||
func! BuildFoldTable()
|
||||
let start = -1
|
||||
let end = -1
|
||||
let step = 0
|
||||
let add = -1
|
||||
let ranges = []
|
||||
for p in s:foldprops
|
||||
if p[1] == 'C' || p[1] == 'S'
|
||||
let n = ('0x' . p[0]) + 0
|
||||
let nl = ('0x' . p[2]) + 0
|
||||
if start >= 0 && add == nl - n && (step == 0 || n - end == step)
|
||||
" continue with same range.
|
||||
let step = n - end
|
||||
let end = n
|
||||
else
|
||||
if start >= 0
|
||||
" produce previous range
|
||||
call Range(ranges, start, end, step, add)
|
||||
endif
|
||||
let start = n
|
||||
let end = n
|
||||
let step = 0
|
||||
let add = nl - n
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
if start >= 0
|
||||
call Range(ranges, start, end, step, add)
|
||||
endif
|
||||
|
||||
" New buffer to put the result in.
|
||||
new
|
||||
file foldCase
|
||||
call setline(1, "static convertStruct foldCase[] =")
|
||||
call setline(2, "{")
|
||||
call append('$', ranges)
|
||||
call setline('$', getline('$')[:-2]) " remove last comma
|
||||
call setline(line('$') + 1, "};")
|
||||
wincmd p
|
||||
endfunc
|
||||
|
||||
func! Range(ranges, start, end, step, add)
|
||||
let s = printf("\t{0x%x,0x%x,%d,%d},", a:start, a:end, a:step == 0 ? -1 : a:step, a:add)
|
||||
call add(a:ranges, s)
|
||||
endfunc
|
||||
|
||||
" Build the combining table.
|
||||
" Uses s:dataprops.
|
||||
func! BuildCombiningTable()
|
||||
let start = -1
|
||||
let end = -1
|
||||
let ranges = []
|
||||
for p in s:dataprops
|
||||
if p[2] == 'Mn' || p[2] == 'Mc' || p[2] == 'Me'
|
||||
let n = ('0x' . p[0]) + 0
|
||||
if start >= 0 && end + 1 == n
|
||||
" continue with same range.
|
||||
let end = n
|
||||
else
|
||||
if start >= 0
|
||||
" produce previous range
|
||||
call add(ranges, printf("\t{0x%04x, 0x%04x},", start, end))
|
||||
endif
|
||||
let start = n
|
||||
let end = n
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
if start >= 0
|
||||
call add(ranges, printf("\t{0x%04x, 0x%04x},", start, end))
|
||||
endif
|
||||
|
||||
" New buffer to put the result in.
|
||||
new
|
||||
file combining
|
||||
call setline(1, " static struct interval combining[] =")
|
||||
call setline(2, " {")
|
||||
call append('$', ranges)
|
||||
call setline('$', getline('$')[:-2]) " remove last comma
|
||||
call setline(line('$') + 1, " };")
|
||||
wincmd p
|
||||
endfunc
|
||||
|
||||
" Build the double width or ambiguous width table in a new buffer.
|
||||
" Uses s:widthprops and s:dataprops.
|
||||
func! BuildWidthTable(pattern, tableName)
|
||||
let start = -1
|
||||
let end = -1
|
||||
let ranges = []
|
||||
let dataidx = 0
|
||||
for p in s:widthprops
|
||||
if p[1][0] =~ a:pattern
|
||||
if p[0] =~ '\.\.'
|
||||
" It is a range. we don't check for composing char then.
|
||||
let rng = split(p[0], '\.\.')
|
||||
if len(rng) != 2
|
||||
echoerr "Cannot parse range: '" . p[0] . "' in width table"
|
||||
endif
|
||||
let n = ('0x' . rng[0]) + 0
|
||||
let n_last = ('0x' . rng[1]) + 0
|
||||
else
|
||||
let n = ('0x' . p[0]) + 0
|
||||
let n_last = n
|
||||
endif
|
||||
" Find this char in the data table.
|
||||
while 1
|
||||
let dn = ('0x' . s:dataprops[dataidx][0]) + 0
|
||||
if dn >= n
|
||||
break
|
||||
endif
|
||||
let dataidx += 1
|
||||
endwhile
|
||||
if dn != n && n_last == n
|
||||
echoerr "Cannot find character " . n . " in data table"
|
||||
endif
|
||||
" Only use the char when it's not a composing char.
|
||||
" But use all chars from a range.
|
||||
let dp = s:dataprops[dataidx]
|
||||
if n_last > n || (dp[2] != 'Mn' && dp[2] != 'Mc' && dp[2] != 'Me')
|
||||
if start >= 0 && end + 1 == n
|
||||
" continue with same range.
|
||||
else
|
||||
if start >= 0
|
||||
" produce previous range
|
||||
call add(ranges, printf("\t{0x%04x, 0x%04x},", start, end))
|
||||
endif
|
||||
let start = n
|
||||
endif
|
||||
let end = n_last
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
if start >= 0
|
||||
call add(ranges, printf("\t{0x%04x, 0x%04x},", start, end))
|
||||
endif
|
||||
|
||||
" New buffer to put the result in.
|
||||
new
|
||||
exe "file " . a:tableName
|
||||
call setline(1, " static struct interval " . a:tableName . "[] =")
|
||||
call setline(2, " {")
|
||||
call append('$', ranges)
|
||||
call setline('$', getline('$')[:-2]) " remove last comma
|
||||
call setline(line('$') + 1, " };")
|
||||
wincmd p
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
" Edit the Unicode text file. Requires the netrw plugin.
|
||||
edit http://unicode.org/Public/UNIDATA/UnicodeData.txt
|
||||
|
||||
" Parse each line, create a list of lists.
|
||||
call ParseDataToProps()
|
||||
|
||||
" Build the toLower table.
|
||||
call BuildCaseTable("Lower", 13)
|
||||
|
||||
" Build the toUpper table.
|
||||
call BuildCaseTable("Upper", 12)
|
||||
|
||||
" Build the ranges of composing chars.
|
||||
call BuildCombiningTable()
|
||||
|
||||
" Edit the case folding text file. Requires the netrw plugin.
|
||||
edit http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
|
||||
|
||||
" Parse each line, create a list of lists.
|
||||
call ParseFoldProps()
|
||||
|
||||
" Build the foldCase table.
|
||||
call BuildFoldTable()
|
||||
|
||||
" Edit the width text file. Requires the netrw plugin.
|
||||
edit http://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt
|
||||
|
||||
" Parse each line, create a list of lists.
|
||||
call ParseWidthProps()
|
||||
|
||||
" Build the double width table.
|
||||
call BuildWidthTable('[WF]', 'doublewidth')
|
||||
|
||||
" Build the ambiguous width table.
|
||||
call BuildWidthTable('A', 'ambiguous')
|
@ -1,13 +0,0 @@
|
||||
#!/bin/csh
|
||||
#
|
||||
# Shell script for use with UNIX
|
||||
# Starts up Vim with the terminal in 132 column mode
|
||||
# Only works on VT-100 terminals and lookalikes
|
||||
# You need to have a termcap entry "vt100-w". Same as vt100 but 132 columns.
|
||||
#
|
||||
set oldterm=$term
|
||||
echo "[?3h"
|
||||
setenv TERM vt100-w
|
||||
vim $*
|
||||
set term=$oldterm
|
||||
echo "[?3l"
|
@ -1,24 +0,0 @@
|
||||
@rem
|
||||
@rem To use this with Visual Studio .Net
|
||||
@rem Tools->External Tools...
|
||||
@rem Add
|
||||
@rem Title - Vim
|
||||
@rem Command - d:\files\util\vim_vs_net.cmd
|
||||
@rem Arguments - +$(CurLine) $(ItemPath)
|
||||
@rem Init Dir - Empty
|
||||
@rem
|
||||
@rem Courtesy of Brian Sturk
|
||||
@rem
|
||||
@rem --remote-silent +%1 is a command +954, move ahead 954 lines
|
||||
@rem --remote-silent %2 full path to file
|
||||
@rem In Vim
|
||||
@rem :h --remote-silent for more details
|
||||
@rem
|
||||
@rem --servername VS_NET
|
||||
@rem This will create a new instance of vim called VS_NET. So if you
|
||||
open
|
||||
@rem multiple files from VS, they will use the same instance of Vim.
|
||||
@rem This allows you to have multiple copies of Vim running, but you can
|
||||
@rem control which one has VS files in it.
|
||||
@rem
|
||||
start /b gvim.exe --servername VS_NET --remote-silent "%1" "%2"
|
@ -1,6 +0,0 @@
|
||||
#!/bin/sh
|
||||
# enable DEC locator input model on remote terminal
|
||||
printf "\033[1;2'z\033[1;3'{\c"
|
||||
vim "$@"
|
||||
# disable DEC locator input model on remote terminal
|
||||
printf "\033[2;4'{\033[0'z\c"
|
@ -1,55 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Spell a file & generate the syntax statements necessary to
|
||||
# highlight in vim. Based on a program from Krishna Gadepalli
|
||||
# <krishna@stdavids.picker.com>.
|
||||
#
|
||||
# I use the following mappings (in .vimrc):
|
||||
#
|
||||
# noremap <F8> :so `vimspell.sh %`<CR><CR>
|
||||
# noremap <F7> :syntax clear SpellErrors<CR>
|
||||
#
|
||||
# Neil Schemenauer <nascheme@ucalgary.ca>
|
||||
# March 1999
|
||||
# updated 2008 Jul 17 by Bram
|
||||
#
|
||||
# Safe method for the temp file by Javier Fernández-Sanguino_Peña
|
||||
|
||||
INFILE=$1
|
||||
tmp="${TMPDIR-/tmp}"
|
||||
OUTFILE=`mktemp -t vimspellXXXXXX || tempfile -p vimspell || echo none`
|
||||
# If the standard commands failed then create the file
|
||||
# since we cannot create a directory (we cannot remove it on exit)
|
||||
# create a file in the safest way possible.
|
||||
if test "$OUTFILE" = none; then
|
||||
OUTFILE=$tmp/vimspell$$
|
||||
[ -e $OUTFILE ] && { echo "Cannot use temporary file $OUTFILE, it already exists!"; exit 1 ; }
|
||||
(umask 077; touch $OUTFILE)
|
||||
fi
|
||||
# Note the copy of vimspell cannot be deleted on exit since it is
|
||||
# used by vim, otherwise it should do this:
|
||||
# trap "rm -f $OUTFILE" 0 1 2 3 9 11 13 15
|
||||
|
||||
|
||||
#
|
||||
# local spellings
|
||||
#
|
||||
LOCAL_DICT=${LOCAL_DICT-$HOME/local/lib/local_dict}
|
||||
|
||||
if [ -f $LOCAL_DICT ]
|
||||
then
|
||||
SPELL_ARGS="+$LOCAL_DICT"
|
||||
fi
|
||||
|
||||
spell $SPELL_ARGS $INFILE | sort -u |
|
||||
awk '
|
||||
{
|
||||
printf "syntax match SpellErrors \"\\<%s\\>\"\n", $0 ;
|
||||
}
|
||||
|
||||
END {
|
||||
printf "highlight link SpellErrors ErrorMsg\n\n" ;
|
||||
}
|
||||
' > $OUTFILE
|
||||
echo "!rm $OUTFILE" >> $OUTFILE
|
||||
echo $OUTFILE
|
@ -1,22 +0,0 @@
|
||||
vimspell.sh
|
||||
===========
|
||||
|
||||
This is a simple script to spell check a file and generate the syntax
|
||||
statements necessary to highlight the errors in vim. It is based on a
|
||||
similar program by Krishna Gadepalli <krishna@stdavids.picker.com>.
|
||||
|
||||
To use this script, first place it in a directory in your path. Next,
|
||||
you should add some convenient key mappings. I use the following (in
|
||||
.vimrc):
|
||||
|
||||
noremap <F8> :so `vimspell.sh %`<CR><CR>
|
||||
noremap <F7> :syntax clear SpellErrors<CR>
|
||||
|
||||
This program requires the old Unix "spell" command. On my Debian
|
||||
system, "spell" is a wrapper around "ispell". For better security,
|
||||
you should uncomment the line in the script that uses "tempfile" to
|
||||
create a temporary file. As all systems don't have "tempfile" the
|
||||
insecure "pid method" is used.
|
||||
|
||||
|
||||
Neil Schemenauer <nascheme@ucalgary.ca>
|
@ -1,584 +0,0 @@
|
||||
/* vi:set ts=8 sts=4 sw=4:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* X-Windows communication by Flemming Madsen
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*
|
||||
* Client for sending commands to an '+xcmdsrv' enabled vim.
|
||||
* This is mostly a de-Vimified version of if_xcmdsrv.c in vim.
|
||||
* See that file for a protocol specification.
|
||||
*
|
||||
* You can make a test program with a Makefile like:
|
||||
* xcmdsrv_client: xcmdsrv_client.c
|
||||
* cc -o $@ -g -DMAIN -I/usr/X11R6/include -L/usr/X11R6/lib $< -lX11
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_SELECT
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#define __ARGS(x) x
|
||||
|
||||
/* Client API */
|
||||
char * sendToVim __ARGS((Display *dpy, char *name, char *cmd, int asKeys, int *code));
|
||||
|
||||
#ifdef MAIN
|
||||
/* A sample program */
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *res;
|
||||
int code;
|
||||
|
||||
if (argc == 4)
|
||||
{
|
||||
if ((res = sendToVim(XOpenDisplay(NULL), argv[2], argv[3],
|
||||
argv[1][0] != 'e', &code)) != NULL)
|
||||
{
|
||||
if (code)
|
||||
printf("Error code returned: %d\n", code);
|
||||
puts(res);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Usage: %s {k|e} <server> <command>", argv[0]);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Maximum size property that can be read at one time by
|
||||
* this module:
|
||||
*/
|
||||
|
||||
#define MAX_PROP_WORDS 100000
|
||||
|
||||
/*
|
||||
* Forward declarations for procedures defined later in this file:
|
||||
*/
|
||||
|
||||
static int x_error_check __ARGS((Display *dpy, XErrorEvent *error_event));
|
||||
static int AppendPropCarefully __ARGS((Display *display,
|
||||
Window window, Atom property, char *value, int length));
|
||||
static Window LookupName __ARGS((Display *dpy, char *name,
|
||||
int delete, char **loose));
|
||||
static int SendInit __ARGS((Display *dpy));
|
||||
static char *SendEventProc __ARGS((Display *dpy, XEvent *eventPtr,
|
||||
int expect, int *code));
|
||||
static int IsSerialName __ARGS((char *name));
|
||||
|
||||
/* Private variables */
|
||||
static Atom registryProperty = None;
|
||||
static Atom commProperty = None;
|
||||
static Window commWindow = None;
|
||||
static int got_x_error = FALSE;
|
||||
|
||||
|
||||
/*
|
||||
* sendToVim --
|
||||
* Send to an instance of Vim via the X display.
|
||||
*
|
||||
* Results:
|
||||
* A string with the result or NULL. Caller must free if non-NULL
|
||||
*/
|
||||
|
||||
char *
|
||||
sendToVim(dpy, name, cmd, asKeys, code)
|
||||
Display *dpy; /* Where to send. */
|
||||
char *name; /* Where to send. */
|
||||
char *cmd; /* What to send. */
|
||||
int asKeys; /* Interpret as keystrokes or expr ? */
|
||||
int *code; /* Return code. 0 => OK */
|
||||
{
|
||||
Window w;
|
||||
Atom *plist;
|
||||
XErrorHandler old_handler;
|
||||
#define STATIC_SPACE 500
|
||||
char *property, staticSpace[STATIC_SPACE];
|
||||
int length;
|
||||
int res;
|
||||
static int serial = 0; /* Running count of sent commands.
|
||||
* Used to give each command a
|
||||
* different serial number. */
|
||||
XEvent event;
|
||||
XPropertyEvent *e = (XPropertyEvent *)&event;
|
||||
time_t start;
|
||||
char *result;
|
||||
char *loosename = NULL;
|
||||
|
||||
if (commProperty == None && dpy != NULL)
|
||||
{
|
||||
if (SendInit(dpy) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind the server name to a communication window.
|
||||
*
|
||||
* Find any survivor with a serialno attached to the name if the
|
||||
* original registrant of the wanted name is no longer present.
|
||||
*
|
||||
* Delete any lingering names from dead editors.
|
||||
*/
|
||||
|
||||
old_handler = XSetErrorHandler(x_error_check);
|
||||
while (TRUE)
|
||||
{
|
||||
got_x_error = FALSE;
|
||||
w = LookupName(dpy, name, 0, &loosename);
|
||||
/* Check that the window is hot */
|
||||
if (w != None)
|
||||
{
|
||||
plist = XListProperties(dpy, w, &res);
|
||||
XSync(dpy, False);
|
||||
if (plist != NULL)
|
||||
XFree(plist);
|
||||
if (got_x_error)
|
||||
{
|
||||
LookupName(dpy, loosename ? loosename : name,
|
||||
/*DELETE=*/TRUE, NULL);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (w == None)
|
||||
{
|
||||
fprintf(stderr, "no registered server named %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
else if (loosename != NULL)
|
||||
name = loosename;
|
||||
|
||||
/*
|
||||
* Send the command to target interpreter by appending it to the
|
||||
* comm window in the communication window.
|
||||
*/
|
||||
|
||||
length = strlen(name) + strlen(cmd) + 10;
|
||||
if (length <= STATIC_SPACE)
|
||||
property = staticSpace;
|
||||
else
|
||||
property = (char *) malloc((unsigned) length);
|
||||
|
||||
serial++;
|
||||
sprintf(property, "%c%c%c-n %s%c-s %s",
|
||||
0, asKeys ? 'k' : 'c', 0, name, 0, cmd);
|
||||
if (name == loosename)
|
||||
free(loosename);
|
||||
if (!asKeys)
|
||||
{
|
||||
/* Add a back reference to our comm window */
|
||||
sprintf(property + length, "%c-r %x %d", 0, (uint) commWindow, serial);
|
||||
length += strlen(property + length + 1) + 1;
|
||||
}
|
||||
|
||||
res = AppendPropCarefully(dpy, w, commProperty, property, length + 1);
|
||||
if (length > STATIC_SPACE)
|
||||
free(property);
|
||||
if (res < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to send command to the destination program\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (asKeys) /* There is no answer for this - Keys are sent async */
|
||||
return NULL;
|
||||
|
||||
|
||||
/*
|
||||
* Enter a loop processing X events & pooling chars until we see the result
|
||||
*/
|
||||
|
||||
#define SEND_MSEC_POLL 50
|
||||
|
||||
time(&start);
|
||||
while ((time((time_t *) 0) - start) < 60)
|
||||
{
|
||||
/* Look out for the answer */
|
||||
#ifndef HAVE_SELECT
|
||||
struct pollfd fds;
|
||||
|
||||
fds.fd = ConnectionNumber(dpy);
|
||||
fds.events = POLLIN;
|
||||
if (poll(&fds, 1, SEND_MSEC_POLL) < 0)
|
||||
break;
|
||||
#else
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = SEND_MSEC_POLL * 1000;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(ConnectionNumber(dpy), &fds);
|
||||
if (select(ConnectionNumber(dpy) + 1, &fds, NULL, NULL, &tv) < 0)
|
||||
break;
|
||||
#endif
|
||||
while (XEventsQueued(dpy, QueuedAfterReading) > 0)
|
||||
{
|
||||
XNextEvent(dpy, &event);
|
||||
if (event.type == PropertyNotify && e->window == commWindow)
|
||||
if ((result = SendEventProc(dpy, &event, serial, code)) != NULL)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SendInit --
|
||||
* This procedure is called to initialize the
|
||||
* communication channels for sending commands and
|
||||
* receiving results.
|
||||
*/
|
||||
|
||||
static int
|
||||
SendInit(dpy)
|
||||
Display *dpy;
|
||||
{
|
||||
XErrorHandler old_handler;
|
||||
|
||||
/*
|
||||
* Create the window used for communication, and set up an
|
||||
* event handler for it.
|
||||
*/
|
||||
old_handler = XSetErrorHandler(x_error_check);
|
||||
got_x_error = FALSE;
|
||||
|
||||
commProperty = XInternAtom(dpy, "Comm", False);
|
||||
/* Change this back to "InterpRegistry" to talk to tk processes */
|
||||
registryProperty = XInternAtom(dpy, "VimRegistry", False);
|
||||
|
||||
if (commWindow == None)
|
||||
{
|
||||
commWindow =
|
||||
XCreateSimpleWindow(dpy, XDefaultRootWindow(dpy),
|
||||
getpid(), 0, 10, 10, 0,
|
||||
WhitePixel(dpy, DefaultScreen(dpy)),
|
||||
WhitePixel(dpy, DefaultScreen(dpy)));
|
||||
XSelectInput(dpy, commWindow, PropertyChangeMask);
|
||||
}
|
||||
|
||||
XSync(dpy, False);
|
||||
(void) XSetErrorHandler(old_handler);
|
||||
|
||||
return got_x_error ? -1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* LookupName --
|
||||
* Given an interpreter name, see if the name exists in
|
||||
* the interpreter registry for a particular display.
|
||||
*
|
||||
* Results:
|
||||
* If the given name is registered, return the ID of
|
||||
* the window associated with the name. If the name
|
||||
* isn't registered, then return 0.
|
||||
*/
|
||||
|
||||
static Window
|
||||
LookupName(dpy, name, delete, loose)
|
||||
Display *dpy; /* Display whose registry to check. */
|
||||
char *name; /* Name of an interpreter. */
|
||||
int delete; /* If non-zero, delete info about name. */
|
||||
char **loose; /* Do another search matching -999 if not found
|
||||
Return result here if a match is found */
|
||||
{
|
||||
unsigned char *regProp, *entry;
|
||||
unsigned char *p;
|
||||
int result, actualFormat;
|
||||
unsigned long numItems, bytesAfter;
|
||||
Atom actualType;
|
||||
Window returnValue;
|
||||
|
||||
/*
|
||||
* Read the registry property.
|
||||
*/
|
||||
|
||||
regProp = NULL;
|
||||
result = XGetWindowProperty(dpy, RootWindow(dpy, 0), registryProperty, 0,
|
||||
MAX_PROP_WORDS, False, XA_STRING, &actualType,
|
||||
&actualFormat, &numItems, &bytesAfter,
|
||||
®Prop);
|
||||
|
||||
if (actualType == None)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If the property is improperly formed, then delete it.
|
||||
*/
|
||||
|
||||
if ((result != Success) || (actualFormat != 8) || (actualType != XA_STRING))
|
||||
{
|
||||
if (regProp != NULL)
|
||||
XFree(regProp);
|
||||
XDeleteProperty(dpy, RootWindow(dpy, 0), registryProperty);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the property for the desired name.
|
||||
*/
|
||||
|
||||
returnValue = None;
|
||||
entry = NULL; /* Not needed, but eliminates compiler warning. */
|
||||
for (p = regProp; (p - regProp) < numItems; )
|
||||
{
|
||||
entry = p;
|
||||
while ((*p != 0) && (!isspace(*p)))
|
||||
p++;
|
||||
if ((*p != 0) && (strcasecmp(name, p + 1) == 0))
|
||||
{
|
||||
sscanf(entry, "%x", (uint*) &returnValue);
|
||||
break;
|
||||
}
|
||||
while (*p != 0)
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (loose != NULL && returnValue == None && !IsSerialName(name))
|
||||
{
|
||||
for (p = regProp; (p - regProp) < numItems; )
|
||||
{
|
||||
entry = p;
|
||||
while ((*p != 0) && (!isspace(*p)))
|
||||
p++;
|
||||
if ((*p != 0) && IsSerialName(p + 1)
|
||||
&& (strncmp(name, p + 1, strlen(name)) == 0))
|
||||
{
|
||||
sscanf(entry, "%x", (uint*) &returnValue);
|
||||
*loose = strdup(p + 1);
|
||||
break;
|
||||
}
|
||||
while (*p != 0)
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete the property, if that is desired (copy down the
|
||||
* remainder of the registry property to overlay the deleted
|
||||
* info, then rewrite the property).
|
||||
*/
|
||||
|
||||
if ((delete) && (returnValue != None))
|
||||
{
|
||||
int count;
|
||||
|
||||
while (*p != 0)
|
||||
p++;
|
||||
p++;
|
||||
count = numItems - (p-regProp);
|
||||
if (count > 0)
|
||||
memcpy(entry, p, count);
|
||||
XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, XA_STRING,
|
||||
8, PropModeReplace, regProp,
|
||||
(int) (numItems - (p-entry)));
|
||||
XSync(dpy, False);
|
||||
}
|
||||
|
||||
XFree(regProp);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
static char *
|
||||
SendEventProc(dpy, eventPtr, expected, code)
|
||||
Display *dpy;
|
||||
XEvent *eventPtr; /* Information about event. */
|
||||
int expected; /* The one were waiting for */
|
||||
int *code; /* Return code. 0 => OK */
|
||||
{
|
||||
unsigned char *propInfo;
|
||||
unsigned char *p;
|
||||
int result, actualFormat;
|
||||
int retCode;
|
||||
unsigned long numItems, bytesAfter;
|
||||
Atom actualType;
|
||||
|
||||
if ((eventPtr->xproperty.atom != commProperty)
|
||||
|| (eventPtr->xproperty.state != PropertyNewValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the comm property and delete it.
|
||||
*/
|
||||
|
||||
propInfo = NULL;
|
||||
result = XGetWindowProperty(dpy, commWindow, commProperty, 0,
|
||||
MAX_PROP_WORDS, True, XA_STRING, &actualType,
|
||||
&actualFormat, &numItems, &bytesAfter,
|
||||
&propInfo);
|
||||
|
||||
/*
|
||||
* If the property doesn't exist or is improperly formed
|
||||
* then ignore it.
|
||||
*/
|
||||
|
||||
if ((result != Success) || (actualType != XA_STRING)
|
||||
|| (actualFormat != 8))
|
||||
{
|
||||
if (propInfo != NULL)
|
||||
{
|
||||
XFree(propInfo);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Several commands and results could arrive in the property at
|
||||
* one time; each iteration through the outer loop handles a
|
||||
* single command or result.
|
||||
*/
|
||||
|
||||
for (p = propInfo; (p - propInfo) < numItems; )
|
||||
{
|
||||
/*
|
||||
* Ignore leading NULs; each command or result starts with a
|
||||
* NUL so that no matter how badly formed a preceding command
|
||||
* is, we'll be able to tell that a new command/result is
|
||||
* starting.
|
||||
*/
|
||||
|
||||
if (*p == 0)
|
||||
{
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*p == 'r') && (p[1] == 0))
|
||||
{
|
||||
int serial, gotSerial;
|
||||
char *res;
|
||||
|
||||
/*
|
||||
* This is a reply to some command that we sent out. Iterate
|
||||
* over all of its options. Stop when we reach the end of the
|
||||
* property or something that doesn't look like an option.
|
||||
*/
|
||||
|
||||
p += 2;
|
||||
gotSerial = 0;
|
||||
res = "";
|
||||
retCode = 0;
|
||||
while (((p-propInfo) < numItems) && (*p == '-'))
|
||||
{
|
||||
switch (p[1])
|
||||
{
|
||||
case 'r':
|
||||
if (p[2] == ' ')
|
||||
res = p + 3;
|
||||
break;
|
||||
case 's':
|
||||
if (sscanf(p + 2, " %d", &serial) == 1)
|
||||
gotSerial = 1;
|
||||
break;
|
||||
case 'c':
|
||||
if (sscanf(p + 2, " %d", &retCode) != 1)
|
||||
retCode = 0;
|
||||
break;
|
||||
}
|
||||
while (*p != 0)
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (!gotSerial)
|
||||
continue;
|
||||
|
||||
if (code != NULL)
|
||||
*code = retCode;
|
||||
return serial == expected ? strdup(res) : NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Didn't recognize this thing. Just skip through the next
|
||||
* null character and try again.
|
||||
* Also, throw away commands that we cant process anyway.
|
||||
*/
|
||||
|
||||
while (*p != 0)
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
XFree(propInfo);
|
||||
}
|
||||
|
||||
/*
|
||||
* AppendPropCarefully --
|
||||
*
|
||||
* Append a given property to a given window, but set up
|
||||
* an X error handler so that if the append fails this
|
||||
* procedure can return an error code rather than having
|
||||
* Xlib panic.
|
||||
*
|
||||
* Return:
|
||||
* 0 on OK - -1 on error
|
||||
*--------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
AppendPropCarefully(dpy, window, property, value, length)
|
||||
Display *dpy; /* Display on which to operate. */
|
||||
Window window; /* Window whose property is to
|
||||
* be modified. */
|
||||
Atom property; /* Name of property. */
|
||||
char *value; /* Characters to append to property. */
|
||||
int length; /* How much to append */
|
||||
{
|
||||
XErrorHandler old_handler;
|
||||
|
||||
old_handler = XSetErrorHandler(x_error_check);
|
||||
got_x_error = FALSE;
|
||||
XChangeProperty(dpy, window, property, XA_STRING, 8,
|
||||
PropModeAppend, value, length);
|
||||
XSync(dpy, False);
|
||||
(void) XSetErrorHandler(old_handler);
|
||||
return got_x_error ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Another X Error handler, just used to check for errors.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
x_error_check(dpy, error_event)
|
||||
Display *dpy;
|
||||
XErrorEvent *error_event;
|
||||
{
|
||||
got_x_error = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if "str" looks like it had a serial number appended.
|
||||
* Actually just checks if the name ends in a digit.
|
||||
*/
|
||||
static int
|
||||
IsSerialName(str)
|
||||
char *str;
|
||||
{
|
||||
int len = strlen(str);
|
||||
|
||||
return (len > 1 && isdigit(str[len - 1]));
|
||||
}
|
Loading…
Reference in New Issue
Block a user