Attached is a patch to enable the plug-in parser to work with Windows. It also
enables pygments_parser.py to work with both Python 2 & 3 (2.6 at a minimum,
for print_function). I've also removed sorted writing for Windows, since it's
slightly quicker without it.
--
Jason.
diff -urp global-6.3.2/libparser/parser.c global-6.3-2/libparser/parser.c
--- global-6.3.2/libparser/parser.c 2014-09-04 15:46:14 +1000
+++ global-6.3-2/libparser/parser.c 2014-11-08 23:07:46 +1000
@@ -31,6 +31,11 @@
#include <strings.h>
#endif
#include <ltdl.h>
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef SLIST_ENTRY
+#endif
#include "parser.h"
#include "internal.h"
@@ -171,6 +176,11 @@ load_plugin_parser(const char *pluginspe
if (p != NULL)
*p++ = '\0';
q = strchr(lt_dl_name, ':');
+#ifdef _WIN32
+ /* Assume a single-character name is a drive letter. */
+ if (q == lt_dl_name + 1)
+ q = strchr(q + 1, ':');
+#endif
if (q == NULL) {
parser_name = "parser";
} else {
@@ -179,11 +189,38 @@ load_plugin_parser(const char *pluginspe
die_with_code(2, "syntax error in pluginspec
'%s'.", pluginspec);
parser_name = q;
}
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* Bypass libtool and load the DLL directly, relative to us. */
+ pent->handle = (lt_dlhandle)LoadLibrary(lt_dl_name);
+ if (pent->handle == NULL) {
+ q = strrchr(lt_dl_name, '/');
+ if (q == NULL)
+ q = strrchr(lt_dl_name, '\\');
+ if (q != NULL)
+ lt_dl_name = q + 1;
+ q = strrchr(lt_dl_name, '.');
+ if (q != NULL && strcmp(q, ".la") == 0)
+ *q = '\0';
+ pent->handle = (lt_dlhandle)LoadLibrary(lt_dl_name);
+ if (pent->handle == NULL) {
+ char dll[MAX_PATH*2];
+ GetModuleFileName(NULL, dll, MAX_PATH);
+ q = strrchr(dll, '\\');
+ sprintf(q+1, "..\\lib\\gtags\\%s", lt_dl_name);
+ pent->handle = (lt_dlhandle)LoadLibrary(dll);
+ }
+ }
+ if (pent->handle == NULL)
+ die_with_code(2, "cannot open shared object '%s'.",
lt_dl_name);
+ pent->entry.lt_dl_name = lt_dl_name;
+ pent->entry.parser =
(PVOID)GetProcAddress((HINSTANCE)pent->handle, parser_name);
+#else
pent->handle = lt_dlopen(lt_dl_name);
if (pent->handle == NULL)
die_with_code(2, "cannot open shared object '%s'.",
lt_dl_name);
pent->entry.lt_dl_name = lt_dl_name;
pent->entry.parser = lt_dlsym(pent->handle, parser_name);
+#endif
if (pent->entry.parser == NULL)
die_with_code(2, "cannot find symbol '%s' in '%s'.",
parser_name, lt_dl_name);
pent->entry.parser_name = parser_name;
@@ -205,7 +242,11 @@ unload_plugin_parser(void)
return;
while (!STAILQ_EMPTY(&plugin_list)) {
pent = STAILQ_FIRST(&plugin_list);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ FreeLibrary((HMODULE)pent->handle);
+#else
lt_dlclose(pent->handle);
+#endif
STAILQ_REMOVE_HEAD(&plugin_list, next);
free(pent);
}
diff -urp global-6.3.2/libutil/conf.c global-6.3-2/libutil/conf.c
--- global-6.3.2/libutil/conf.c 2014-09-04 15:46:14 +1000
+++ global-6.3-2/libutil/conf.c 2014-11-08 13:02:39 +1000
@@ -32,6 +32,10 @@
#else
#include <strings.h>
#endif
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
#include "gparam.h"
#include "char.h"
@@ -398,10 +402,11 @@ getconfs(const char *name, STRBUF *sb)
if (test("d", DATADIR))
strbuf_puts(sb, DATADIR);
else {
- const char *name = strrchr(_pgmptr, '\\');
- if (name)
- strbuf_nputs(sb, _pgmptr, name+1 -
_pgmptr);
- strbuf_puts(sb, "..\\share");
+ char path[MAX_PATH], *name;
+ GetModuleFileName(NULL, path, MAX_PATH);
+ name = strrchr(path, '\\');
+ strcpy(name+1, "..\\share");
+ strbuf_puts(sb, path);
}
#else
strbuf_puts(sb, DATADIR);
diff -urp global-6.3.2/libutil/dbop.c global-6.3-2/libutil/dbop.c
--- global-6.3.2/libutil/dbop.c 2014-09-04 15:46:14 +1000
+++ global-6.3-2/libutil/dbop.c 2014-11-08 22:10:17 +1000
@@ -78,11 +78,12 @@ static void start_sort_process(DBOP *);
static void terminate_sort_process(DBOP *);
static char *sortnotfound = "POSIX sort program not found. If available, the
program will be speed up.\nPlease see ./configure --help.";
/*
- * 1. DJGPP
+ * 1. DJGPP/Windows
*/
-#if defined(__DJGPP__)
+#if defined(__DJGPP__) || defined(_WIN32)
/*
- * Just ignored. DJGPP version doesn't use sorted writing.
+ * Just ignored. DJGPP version doesn't use sorted writing; Windows (including
+ * Cygwin) is slightly quicker without it.
*/
static void
start_sort_process(DBOP *dbop) {
@@ -93,78 +94,7 @@ terminate_sort_process(DBOP *dbop) {
return;
}
/*
- * 2. WIN32
- */
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-/*
- * sort is included with the binary distribution
- */
-static char argv[] = "sort -k 1,1";
-static void
-start_sort_process(DBOP *dbop) {
- HANDLE opipe[2], ipipe[2];
- SECURITY_ATTRIBUTES sa;
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- const char* lc_all;
- char sort[MAX_PATH];
- char* path;
- static int informed;
-
- if (!strcmp(POSIX_SORT, "no"))
- return;
- if (informed)
- return;
- /*
- * force using sort in the same directory as the program, to avoid
- * using the Windows one
- */
- path = strrchr(_pgmptr, '\\');
- sprintf(sort, "%.*s\\sort.exe", path - _pgmptr, _pgmptr);
- if (!test("fx", sort)) {
- warning(sortnotfound);
- informed = 1;
- return;
- }
-
- sa.nLength = sizeof(sa);
- sa.bInheritHandle = TRUE;
- sa.lpSecurityDescriptor = NULL;
- if (!CreatePipe(&opipe[0], &opipe[1], &sa, 0) ||
- !CreatePipe(&ipipe[0], &ipipe[1], &sa, 0))
- die("CreatePipe failed.");
- SetHandleInformation(opipe[1], HANDLE_FLAG_INHERIT, 0);
- SetHandleInformation(ipipe[0], HANDLE_FLAG_INHERIT, 0);
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
- si.hStdInput = opipe[0];
- si.hStdOutput = ipipe[1];
- si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
- si.dwFlags = STARTF_USESTDHANDLES;
- lc_all = getenv("LC_ALL");
- if (lc_all == NULL)
- lc_all = "";
- set_env("LC_ALL", "C");
- CreateProcess(sort, argv, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
- set_env("LC_ALL", lc_all);
- CloseHandle(opipe[0]);
- CloseHandle(ipipe[1]);
- CloseHandle(pi.hThread);
- dbop->pid = pi.hProcess;
- dbop->sortout = fdopen(_open_osfhandle((long)opipe[1], _O_WRONLY), "w");
- dbop->sortin = fdopen(_open_osfhandle((long)ipipe[0], _O_RDONLY), "r");
- if (dbop->sortout == NULL || dbop->sortin == NULL)
- die("fdopen failed.");
-}
-static void
-terminate_sort_process(DBOP *dbop) {
- WaitForSingleObject(dbop->pid, INFINITE);
- CloseHandle(dbop->pid);
-}
-/*
- * 3. UNIX and CYGWIN
+ * 2. UNIX
*/
#else
#include <sys/wait.h>
diff -urp global-6.3.2/plugin-factory/exuberant-ctags.c
global-6.3-2/plugin-factory/exuberant-ctags.c
--- global-6.3.2/plugin-factory/exuberant-ctags.c 2014-09-04 15:46:15
+1000
+++ global-6.3-2/plugin-factory/exuberant-ctags.c 2014-11-08 18:12:14
+1000
@@ -22,9 +22,6 @@
#include <config.h>
#endif
#include <sys/types.h>
-#if !defined(_WIN32) || defined(__CYGWIN__)
-#include <sys/wait.h>
-#endif
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@@ -51,24 +48,15 @@
#define LANGMAP_OPTION "--langmap="
#define INITIAL_BUFSIZE 1024
-static char *argv[] = {
- EXUBERANT_CTAGS,
- NULL,
-#ifdef USE_TYPE_STRING
- "--gtags",
-#endif
- "-xu",
- "--filter",
- "--filter-terminator=" TERMINATOR "\n",
- "--format=1",
- NULL
-};
-static pid_t pid;
static FILE *ip, *op;
static char *linebuf;
static size_t bufsize;
static char *ctagsnotfound = "Exuberant Ctags not found. Please see
./configure --help.";
+#ifdef __GNUC__
+static void terminate_ctags(void) __attribute__((destructor));
+#endif
+
static void
copy_langmap_converting_cpp(char *dst, const char *src)
{
@@ -89,6 +77,84 @@ copy_langmap_converting_cpp(char *dst, c
strcpy(dst, src);
}
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <fcntl.h>
+static HANDLE pid;
+static char argv[] = "ctags "
+ "--gtags "
+ "-xu --filter --filter-terminator=" TERMINATOR "\n "
+ "--format=1 " LANGMAP_OPTION;
+static void
+start_ctags(const struct parser_param *param)
+{
+ HANDLE opipe[2], ipipe[2];
+ SECURITY_ATTRIBUTES sa;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ char* arg;
+
+ arg = malloc(sizeof(argv) + strlen(param->langmap));
+ if (arg == NULL)
+ param->die("short of memory.");
+ strcpy(arg, argv);
+ copy_langmap_converting_cpp(arg + sizeof(argv) - 1, param->langmap);
+
+ sa.nLength = sizeof(sa);
+ sa.bInheritHandle = TRUE;
+ sa.lpSecurityDescriptor = NULL;
+ if (!CreatePipe(&opipe[0], &opipe[1], &sa, 0) ||
+ !CreatePipe(&ipipe[0], &ipipe[1], &sa, 0))
+ param->die("CreatePipe failed.");
+ SetHandleInformation(opipe[1], HANDLE_FLAG_INHERIT, 0);
+ SetHandleInformation(ipipe[0], HANDLE_FLAG_INHERIT, 0);
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ si.hStdInput = opipe[0];
+ si.hStdOutput = ipipe[1];
+ si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ si.dwFlags = STARTF_USESTDHANDLES;
+ CreateProcess(NULL, arg, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
+ CloseHandle(opipe[0]);
+ CloseHandle(ipipe[1]);
+ CloseHandle(pi.hThread);
+ pid = pi.hProcess;
+ op = fdopen(_open_osfhandle((long)opipe[1], _O_WRONLY), "w");
+ ip = fdopen(_open_osfhandle((long)ipipe[0], _O_RDONLY), "r");
+ if (ip == NULL || op == NULL)
+ param->die("fdopen failed.");
+
+ bufsize = INITIAL_BUFSIZE;
+ linebuf = malloc(bufsize);
+ if (linebuf == NULL)
+ param->die("short of memory.");
+}
+static void
+terminate_ctags(void) {
+ if (op == NULL)
+ return;
+ free(linebuf);
+ fclose(op);
+ fclose(ip);
+ WaitForSingleObject(pid, INFINITE);
+ CloseHandle(pid);
+}
+#else
+#include <sys/wait.h>
+static pid_t pid;
+static char *argv[] = {
+ EXUBERANT_CTAGS,
+ NULL,
+#ifdef USE_TYPE_STRING
+ "--gtags",
+#endif
+ "-xu",
+ "--filter",
+ "--filter-terminator=" TERMINATOR "\n",
+ "--format=1",
+ NULL
+};
static void
start_ctags(const struct parser_param *param)
{
@@ -134,10 +200,6 @@ start_ctags(const struct parser_param *p
param->die("short of memory.");
}
-#ifdef __GNUC__
-static void terminate_ctags(void) __attribute__((destructor));
-#endif
-
static void
terminate_ctags(void)
{
@@ -149,6 +211,7 @@ terminate_ctags(void)
while (waitpid(pid, NULL, 0) < 0 && errno == EINTR)
;
}
+#endif
static char *
get_line(const struct parser_param *param)
diff -urp global-6.3.2/plugin-factory/pygments-parser.c
global-6.3-2/plugin-factory/pygments-parser.c
--- global-6.3.2/plugin-factory/pygments-parser.c 2014-09-04 15:46:15
+1000
+++ global-6.3-2/plugin-factory/pygments-parser.c 2014-11-10 21:26:24
+1000
@@ -22,9 +22,6 @@
#include <config.h>
#endif
#include <sys/types.h>
-#if !defined(_WIN32) || defined(__CYGWIN__)
-#include <sys/wait.h>
-#endif
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@@ -43,7 +40,12 @@
#include "parser.h"
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define PYTHON "python"
+#define PYGMENTS_PARSER "../share/gtags/script/pygments_parser.py"
+#else
#define PYGMENTS_PARSER (DATADIR "/gtags/script/pygments_parser.py")
+#endif
/*
* Function layer plugin parser sample
@@ -53,16 +55,14 @@
#define LANGMAP_OPTION "--langmap="
#define INITIAL_BUFSIZE 1024
-static char *argv[] = {
- PYGMENTS_PARSER,
- NULL,
- NULL
-};
-static pid_t pid;
static FILE *ip, *op;
static char *linebuf;
static size_t bufsize;
+#ifdef __GNUC__
+static void terminate_process(void) __attribute__((destructor));
+#endif
+
static void
copy_langmap_converting_cpp(char *dst, const char *src)
{
@@ -83,6 +83,80 @@ copy_langmap_converting_cpp(char *dst, c
strcpy(dst, src);
}
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <fcntl.h>
+static HANDLE pid;
+static void
+start_process(const struct parser_param *param)
+{
+ HANDLE opipe[2], ipipe[2];
+ SECURITY_ATTRIBUTES sa;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ char* arg;
+ char parser[MAX_PATH*2];
+ size_t len;
+
+ GetModuleFileName(NULL, parser, MAX_PATH);
+ arg = strrchr(parser, '\\');
+ strcpy(arg+1, PYGMENTS_PARSER);
+ arg = malloc(sizeof(PYTHON) + strlen(parser) + sizeof(LANGMAP_OPTION) +
strlen(param->langmap) + 1);
+ if (arg == NULL)
+ param->die("short of memory.");
+ len = sprintf(arg, "%s %s %s", PYTHON, parser, LANGMAP_OPTION);
+ copy_langmap_converting_cpp(arg + len, param->langmap);
+
+ sa.nLength = sizeof(sa);
+ sa.bInheritHandle = TRUE;
+ sa.lpSecurityDescriptor = NULL;
+ if (!CreatePipe(&opipe[0], &opipe[1], &sa, 0) ||
+ !CreatePipe(&ipipe[0], &ipipe[1], &sa, 0))
+ param->die("CreatePipe failed.");
+ SetHandleInformation(opipe[1], HANDLE_FLAG_INHERIT, 0);
+ SetHandleInformation(ipipe[0], HANDLE_FLAG_INHERIT, 0);
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ si.hStdInput = opipe[0];
+ si.hStdOutput = ipipe[1];
+ si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ si.dwFlags = STARTF_USESTDHANDLES;
+ if (!CreateProcess(NULL, arg, NULL, NULL, TRUE, 0, NULL, NULL, &si,
&pi))
+ param->die("no python");
+ CloseHandle(opipe[0]);
+ CloseHandle(ipipe[1]);
+ CloseHandle(pi.hThread);
+ pid = pi.hProcess;
+ op = fdopen(_open_osfhandle((long)opipe[1], _O_WRONLY), "w");
+ ip = fdopen(_open_osfhandle((long)ipipe[0], _O_RDONLY), "r");
+ if (ip == NULL || op == NULL)
+ param->die("fdopen failed.");
+
+ bufsize = INITIAL_BUFSIZE;
+ linebuf = malloc(bufsize);
+ if (linebuf == NULL)
+ param->die("short of memory.");
+}
+static void
+terminate_process(void) {
+ if (op == NULL)
+ return;
+ free(linebuf);
+ fclose(op);
+ fclose(ip);
+ WaitForSingleObject(pid, INFINITE);
+ CloseHandle(pid);
+}
+#else
+#include <sys/wait.h>
+static char *argv[] = {
+ PYGMENTS_PARSER,
+ NULL,
+ NULL
+};
+static pid_t pid;
+
static void
start_process(const struct parser_param *param)
{
@@ -126,10 +200,6 @@ start_process(const struct parser_param
param->die("short of memory.");
}
-#ifdef __GNUC__
-static void terminate_process(void) __attribute__((destructor));
-#endif
-
static void
terminate_process(void)
{
@@ -141,6 +211,7 @@ terminate_process(void)
while (waitpid(pid, NULL, 0) < 0 && errno == EINTR)
;
}
+#endif
static char *
get_line(const struct parser_param *param)
diff -urp global-6.3.2/plugin-factory/pygments_parser.py.in
global-6.3-2/plugin-factory/pygments_parser.py.in
--- global-6.3.2/plugin-factory/pygments_parser.py.in 2014-09-04 15:46:15
+1000
+++ global-6.3-2/plugin-factory/pygments_parser.py.in 2014-11-11 12:30:07
+1000
@@ -16,6 +16,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+from __future__ import print_function
+import io
import os
import subprocess
import sys
@@ -39,7 +41,12 @@ LANGUAGE_ALIASES = {
# All punctuation characters except some characters which are valid
# identifier characters in some languages
-PUNCTUATION_CHARACTERS = string.punctuation.translate(None, '-_.')
+if sys.version_info < (3,):
+ PUNCTUATION_CHARACTERS = string.punctuation.translate(None, '-_.')
+else:
+ PUNCTUATION_CHARACTERS = string.punctuation.translate(str.maketrans('',
'', '-_.'))
+
+CLOSEFDS = sys.platform != 'win32';
TERMINATOR = '###terminator###\n'
@@ -115,23 +122,33 @@ class PygmentsParser:
def read_file(self, path):
try:
- with open(path, 'r') as f:
- text = f.read()
- return text
+ if sys.version_info < (3,):
+ with open(path, 'r') as f:
+ text = f.read()
+ return text
+ else:
+ with open(path, 'r', encoding='latin1') as f:
+ text = f.read()
+ return text
except Exception as e:
- print >> sys.stderr, e
+ print(e, file=sys.stderr)
return None
class CtagsParser:
def __init__(self, ctags_command, options):
self.process = subprocess.Popen([ctags_command, '-xu', '--filter',
'--filter-terminator=' + TERMINATOR, '--format=1'], bufsize=-1,
- stdin=subprocess.PIPE,
stdout=subprocess.PIPE, close_fds=True)
- self.child_stdout = self.process.stdout
+ stdin=subprocess.PIPE,
stdout=subprocess.PIPE, close_fds=CLOSEFDS,
+ universal_newlines=True)
+ if sys.version_info < (3,):
+ self.child_stdout = self.process.stdout
+ else:
+ self.child_stdout = io.TextIOWrapper(self.process.stdout.buffer,
encoding='latin1')
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='latin1')
self.child_stdin = self.process.stdin
self.options = options
def parse(self, path):
- print >> self.child_stdin, path
+ print(path, file=self.child_stdin)
self.child_stdin.flush()
result = {}
while True:
@@ -173,6 +190,9 @@ def parse_langmap(string):
for ext in exts.split('.'):
if ext:
langmap['.' + ext] = lang
+ if sys.platform == 'win32':
+ langmap['.' + ext.upper()] = lang
+ langmap['.' + ext.lower()] = lang
return langmap
def handle_requests(langmap, options):
@@ -188,13 +208,13 @@ def handle_requests(langmap, options):
break
path = path.rstrip()
tags = parser.parse(path)
- for (isdef, tag, lnum),image in tags.iteritems():
+ for (isdef, tag, lnum),image in tags.items():
if isdef:
typ = 'D'
else:
typ = 'R'
- print typ, tag, lnum, path, image
- print TERMINATOR,
+ print(typ, tag, lnum, path, image)
+ print(TERMINATOR, end='')
sys.stdout.flush()
def get_parser_options_from_env(parser_options):
_______________________________________________
Bug-global mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-global