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

Reply via email to