Re: Support file-type guess using file/libmagic when source file does not have a suffix

Jun Sheng <[email protected]>
Newsgroups gmane.comp.gnu.global.bugs
Message-ID <CAAYzEVBZ68SnyhnvaqOjD4y=fVLso34f_KGT+jBYLm7TPaK_Hg@mail.gmail.com>
specifying the filetype in commandline is a good idea, but why not going
further, make gtags read file type when read file list ?

and I attached a patch, which will guess file type using libmagic

On Mon, Feb 20, 2017 at 3:16 PM Shigio YAMAGUCHI <[email protected]> wrote:

> Hi,
> > Hi,
> > There, what about adding file-type guessing when the source file does
> not have a suffix?
> >
> > Currently when the file doesnot have a suffix, gnu global wont parse it,
> > this is a problem when perl/python ... files. and gtags cant specify
> lang-type on command-line.
>
> You are right.
> Currently, we have a plan to do the following:
> http://lists.gnu.org/archive/html/bug-global/2016-10/msg00003.html
>
> Does this specification fulfill your requirements?
>
> Regards,
> Shigio
>
>
> 2017-02-20 15:45 GMT+09:00 Jun Sheng <[email protected]>:
>
> Hi,
> There, what about adding file-type guessing when the source file does not
> have a suffix?
>
> Currently when the file doesnot have a suffix, gnu global wont parse it,
> this is a problem when perl/python ... files. and gtags cant specify
> lang-type on command-line.
>
>
> _______________________________________________
> Bug-global mailing list
> [email protected]
> https://lists.gnu.org/mailman/listinfo/bug-global
>
>
>
>
> --
> Shigio YAMAGUCHI <[email protected]>
> PGP fingerprint: D1CB 0B89 B346 4AB6 5663  C4B6 3CA5 BBB3 57BE DDA3
>

_______________________________________________
Bug-global mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-global
add-magic-file.patch (text/x-patch, 5.8 KB)
diff -aur a/global-6.5.5/global/Makefile.in global-6.5.5/global/Makefile.in
--- a/global-6.5.5/global/Makefile.in	2016-09-21 12:54:30.000000000 +0800
+++ global-6.5.5/global/Makefile.in	2017-02-20 20:56:00.069969143 +0800
@@ -258,7 +258,7 @@
 LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
 LIBLTDL = @LIBLTDL@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = @LIBS@ -lmagic
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
diff -aur a/global-6.5.5/gozilla/Makefile.in global-6.5.5/gozilla/Makefile.in
--- a/global-6.5.5/gozilla/Makefile.in	2016-09-21 12:54:30.000000000 +0800
+++ global-6.5.5/gozilla/Makefile.in	2017-02-20 20:56:41.613301655 +0800
@@ -254,7 +254,7 @@
 LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
 LIBLTDL = @LIBLTDL@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = @LIBS@ -lmagic
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
diff -aur a/global-6.5.5/gtags/Makefile.in global-6.5.5/gtags/Makefile.in
--- a/global-6.5.5/gtags/Makefile.in	2016-09-21 12:54:30.000000000 +0800
+++ global-6.5.5/gtags/Makefile.in	2017-02-20 20:57:08.156634461 +0800
@@ -254,7 +254,7 @@
 LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
 LIBLTDL = @LIBLTDL@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = @LIBS@ -lmagic
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
diff -aur a/global-6.5.5/htags/Makefile.in global-6.5.5/htags/Makefile.in
--- a/global-6.5.5/htags/Makefile.in	2016-09-21 12:54:30.000000000 +0800
+++ global-6.5.5/htags/Makefile.in	2017-02-20 20:58:01.319966741 +0800
@@ -265,7 +265,7 @@
 LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
 LIBLTDL = @LIBLTDL@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = @LIBS@ -lmagic
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
diff -aur a/global-6.5.5/libparser/parser.c global-6.5.5/libparser/parser.c
--- a/global-6.5.5/libparser/parser.c	2016-09-21 12:54:13.000000000 +0800
+++ global-6.5.5/libparser/parser.c	2017-02-21 09:20:20.629995132 +0800
@@ -413,21 +413,16 @@
 	const struct lang_entry *ent;
 	struct parser_param param;
 
-	/* get suffix of the path. */
-	suffix = locatestring(path, ".", MATCH_LAST);
-	if (suffix == NULL)
-		return;
-	lang = decide_lang(suffix);
+	lang = guess_and_decide_lang(path, flags & PARSER_EXPLAIN);
 	if (lang == NULL)
 		return;
+	
 	/*
 	 * Select parser.
 	 * If lang == NULL then default parser is selected.
 	 */
 	ent = get_lang_entry(lang);
 	if (flags & PARSER_EXPLAIN) {
-		fprintf(stderr, " - File '%s' is handled as follows:\n", trimpath(path));
-		fprintf(stderr, "\tsuffix:   |%s|\n", suffix);
 		fprintf(stderr, "\tlanguage: |%s|\n", lang);
 		fprintf(stderr, "\tparser:   |%s|\n", ent->parser_name);
 		fprintf(stderr, "\tlibrary:  |%s|\n", ent->lt_dl_name ? ent->lt_dl_name : "builtin library");
diff -aur a/global-6.5.5/libutil/find.c global-6.5.5/libutil/find.c
--- a/global-6.5.5/libutil/find.c	2016-09-21 12:54:13.000000000 +0800
+++ global-6.5.5/libutil/find.c	2017-02-20 21:52:55.269901465 +0800
@@ -409,7 +409,7 @@
 	}
 	if (regexec(suff, path, 0, 0, 0) == 0)
 		return 1;
-	return 0;
+	return 1;
 }
 /**
  * skipthisfile: check whether or not we accept this file.
diff -aur a/global-6.5.5/libutil/langmap.c global-6.5.5/libutil/langmap.c
--- a/global-6.5.5/libutil/langmap.c	2016-09-21 12:54:14.000000000 +0800
+++ global-6.5.5/libutil/langmap.c	2017-02-21 09:24:52.793323072 +0800
@@ -30,6 +30,8 @@
 #include <strings.h>
 #endif
 
+#include <magic.h>
+
 #include "checkalloc.h"
 #include "die.h"
 #include "locatestring.h"
@@ -39,6 +41,8 @@
 #include "langmap.h"
 #include "varray.h"
 
+
+
 static void trim_suffix_list(STRBUF *, STRHASH *);
 static int match_suffix_list(const char *, const char *);
 
@@ -202,6 +206,57 @@
 	return strbuf_value(sb);
 }
 
+
+magic_t magic_cookie = NULL;
+
+static int
+init_libmagic() {
+  if (! magic_cookie) {
+    magic_cookie = magic_open(MAGIC_MIME_TYPE);
+  }
+  if (! magic_cookie)
+    return 0;
+  magic_load(magic_cookie, NULL);
+  return 1;
+};
+const char *
+guess_and_decide_lang(const char *path, int flags)
+{
+        const char* suffix, *lang;
+	char buf[32];
+	int can_guess = 0;
+	can_guess = init_libmagic();
+	if (flags)
+	  fprintf(stderr, " - File '%s' is handled as follows:\n", path);
+	
+	suffix = locatestring(path, ".", MATCH_LAST);
+	if ( locatestring(suffix + 1, "/", MATCH_FIRST))
+	  suffix = NULL;
+	if (suffix == NULL) {
+	  if (can_guess) {
+	    suffix = magic_file(magic_cookie, path);
+	    if (suffix){
+	      if (flags) {
+		fprintf(stderr, "\tmimetype: %s\n", suffix);
+	      }
+	      suffix = locatestring(suffix, "/", MATCH_LAST);
+	      strncpy(buf, suffix, 32);
+	      buf[0] = '.';
+	      suffix = buf;
+	    }
+	  }
+	}
+	if (! suffix)
+	  return NULL;
+	if(flags)
+	  fprintf(stderr, "\tsuffix:   |%s|\n", suffix);
+	lang = decide_lang(suffix);
+	if (lang == NULL)
+		return NULL;
+	return lang;
+}  
+
+
 /**
  * decide language of the suffix.
  *
diff -aur a/global-6.5.5/plugin-factory/pygments_parser.py.in global-6.5.5/plugin-factory/pygments_parser.py.in
--- a/global-6.5.5/plugin-factory/pygments_parser.py.in	2016-09-21 12:54:14.000000000 +0800
+++ global-6.5.5/plugin-factory/pygments_parser.py.in	2017-02-21 08:41:56.773260769 +0800
@@ -27,6 +27,8 @@
 import pygments.lexers
 from pygments.token import Token
 
+import magic
+
 EXUBERANT_CTAGS = "@EXUBERANT_CTAGS@"
 
 # In most cases, lexers can be looked up with lowercase form of formal
@@ -111,6 +113,9 @@
 
     def get_lexer_by_langmap(self, path):
         ext = os.path.splitext(path)[1]
+        if ext == "":
+            mm = magic.from_file(path, mime=True)
+            ext = "." + mm.split("/")[1]
         lang = self.langmap[ext]
         if lang:
             name = lang.lower()
--- a/global-6.5.5/libutil/langmap.h.in	2016-09-21 12:54:14.000000000 +0800
+++ global-6.5.5/libutil/langmap.h.in	2017-02-21 09:36:29.419975935 +0800
@@ -31,5 +31,5 @@
 const char *trim_langmap(const char *);
 const char *decide_lang(const char *);
 void make_suffixes(const char *, STRBUF *);
-
+const char *guess_and_decide_lang(const char *, int);
 #endif
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.