--- ne-2.1/src/prefs.c.magic 2011-03-07 05:34:45.000000000 +0300 +++ ne-2.1/src/prefs.c 2011-03-07 14:02:12.525392992 +0300 @@ -22,8 +22,11 @@ #include "ne.h" +#ifdef HAVE_MAGIC +#include "mgc.h" +#endif /* These are the names of ne's autoprefs directory. */ #define PREFS_DIR ".ne" @@ -241,9 +244,24 @@ int load_syntax_by_name(buffer * const b } return NO_SYNTAX_FOR_EXT; } +#ifdef HAVE_MAGIC +int load_syntax_by_file(buffer * const b, char * const filename) { + struct high_syntax *syn; + char *s; + assert_buffer(b); + if ((s = (char *)file2syntax(filename)) == NULL) + return NO_SYNTAX_FOR_EXT; + if ((syn = load_syntax(s)) != NULL) { + b->syn = syn; + reset_syntax_states(b); + return OK; + } + return NO_SYNTAX_FOR_EXT; +} +#endif /* Performs an automatic preferences operation, which can be loading or saving, depending on the function pointed to by prefs_func. The extension given by ext is used in order to locate the appropriate file. If ext is NULL, the --- ne-2.1/src/makefile.magic 2011-03-07 05:34:46.165311304 +0300 +++ ne-2.1/src/makefile 2011-03-07 05:34:46.169334796 +0300 @@ -80,14 +80,17 @@ OBJS = actions.o \ TERMCAPOBJS = tparam.o \ info2cap.o \ termcap.o +MAGICOBJS = mgc.o + NE_POSIX= NE_TERMCAP= NE_ANSI= NE_NOWCHAR= NE_DEBUG= NE_TEST= +NE_MAGIC= ifeq ($(CC),gcc) NO_SIGN=-Wno-pointer-sign endif @@ -98,14 +101,15 @@ CFLAGS=$(OPTS) $(NO_SIGN) \ $(if $(NE_NOWCHAR), -DNOWCHAR,) \ $(if $(NE_TEST), -DNE_TEST,) \ $(if $(NE_DEBUG), -g,-O3 -DNDEBUG) \ $(if $(NE_TERMCAP), -DTERMCAP,) \ - $(if $(NE_ANSI), -DTERMCAP -DANSI,) + $(if $(NE_ANSI), -DTERMCAP -DANSI,) \ + $(if $(NE_MAGIC), -DHAVE_MAGIC,) -LIBS=$(if $(NE_TERMCAP)$(NE_ANSI),,-lcurses) +LIBS=-lm $(if $(NE_TERMCAP)$(NE_ANSI),,-lcurses) $(if $(NE_MAGIC),-lmagic,) -ne: $(OBJS) $(if $(NE_TERMCAP)$(NE_ANSI),$(TERMCAPOBJS),) - $(CC) $(OPTS) $(LDFLAGS) $^ $(LIBS) -lm -o $(PROGRAM) +ne: $(OBJS) $(if $(NE_TERMCAP)$(NE_ANSI),$(TERMCAPOBJS),) $(if $(NE_MAGIC),$(MAGICOBJS),) + $(CC) $(OPTS) $(LDFLAGS) $^ $(LIBS) -o $(PROGRAM) clean: rm -f *.o core @@ -191,4 +195,6 @@ tparam.o: termcap.h undo.o: ne.h keycodes.h names.h errors.h protos.h utf8.o: utf8.h + +mgc.o: mgc.h --- /dev/null 2011-03-05 16:11:26.664006066 +0300 +++ ne-2.1/src/mgc.c 2011-03-07 16:49:31.317390882 +0300 @@ -0,0 +1,142 @@ +/* Magic files support. + + Copyright (C) 2011 Alexey Gladkov + + This file is part of ne, the nice editor. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include +#include +#include +#include +#include +#include + +#include +#include "mgc.h" + +static magic_t cookie = NULL; + +struct m2s { + char *mgc; + char *syn; +}; + +static int magic_syntax_len = 0; +static struct m2s *magic_syntax = NULL; +static char magic_syntax_file[MAXPATHLEN]; + +static int read_magic_syntax(void) { + FILE *f; + int i; + char *global_dir, *mgc = NULL, *syn = NULL; + + if ((global_dir = (char *) get_global_dir()) == NULL) + return -1; + + snprintf(magic_syntax_file, MAXPATHLEN, "%s/magic.syntax", global_dir); + + if ((f = fopen(magic_syntax_file, "r")) == NULL) + return -1; + + errno = 0; + while (fscanf(f, "%as\t%as\n", &mgc, &syn) == 2) { + magic_syntax = (struct m2s *) realloc(magic_syntax, sizeof(struct m2s) * (magic_syntax_len + 1)); + if (magic_syntax == NULL) { + perror("realloc"); + exit(1); + } + + magic_syntax[magic_syntax_len].mgc = mgc; + magic_syntax[magic_syntax_len].syn = syn; + magic_syntax_len++; + } + + if (errno != 0) { + perror("scanf"); + fclose(f); + return -1; + } + + fclose(f); + return 0; +} + +void load_magic(void) { + if (read_magic_syntax() == -1) + return; + + if ((cookie = magic_open(MAGIC_SYMLINK|MAGIC_MIME_TYPE)) == NULL) + return; + + if (magic_load(cookie, NULL) == -1) + return; +} + +static void print_magic(void) { + int i; + for (i = 0; i < magic_syntax_len; i++) + fprintf(stderr, "[%s] = [%s]\n\r", magic_syntax[i].mgc, magic_syntax[i].syn); +} + +void unload_magic(void) { + int i; + if (magic_syntax) { + for (i = 0; i < magic_syntax_len; i++) { + free(magic_syntax[i].mgc); + free(magic_syntax[i].syn); + } + + free(magic_syntax); + + magic_syntax = NULL; + magic_syntax_len = 0; + } + + if (cookie) { + if (magic_check(cookie, NULL) == -1) + return; + + magic_close(cookie); + cookie = NULL; + } +} + +static char *find_magic(char * const fname) { + return (char *) magic_file(cookie, fname); +} + +static int magiccmp(struct m2s const *a, struct m2s const *b) { + return strncasecmp(a->mgc, b->mgc, strlen(b->mgc)); +} + +const char *file2syntax(char * const fn) { + struct m2s key, *t; + + if (!cookie) + return NULL; + + key.mgc = find_magic(fn); + key.syn = NULL; + + if (!key.mgc) + return NULL; + + t = bsearch(&key, magic_syntax, magic_syntax_len, sizeof(struct m2s), (int (*)(const void *, const void *))magiccmp); + + return t ? t->syn : NULL; +} --- ne-2.1/src/actions.c.magic 2011-03-07 05:34:45.000000000 +0300 +++ ne-2.1/src/actions.c 2011-03-07 16:48:51.077324772 +0300 @@ -23,8 +23,12 @@ #include "ne.h" #include "version.h" #include +#ifdef HAVE_MAGIC +#include "mgc.h" +#endif + /* ne's temporary file name template for the THROUGH command. */ #define NE_TMP "netmp.XXXXXX" @@ -100,8 +104,11 @@ int do_action(buffer *b, action a, int c print_error(CANT_SAVE_EXIT_SUSPENDED); return ERROR; } else { +#ifdef HAVE_MAGIC + unload_magic(); +#endif close_history(); unset_interactive_mode(); exit(0); } @@ -118,8 +125,11 @@ int do_action(buffer *b, action a, int c return stop ? STOPPED : error ; case QUIT_A: if (modified_buffers() && !request_response(b, info_msg[SOME_DOCUMENTS_ARE_NOT_SAVED], FALSE)) return ERROR; +#ifdef HAVE_MAGIC + unload_magic(); +#endif close_history(); unset_interactive_mode(); exit(0); @@ -758,8 +768,13 @@ int do_action(buffer *b, action a, int c /* 'c' -- flag meaning "Don't prompt if we've ever responded 'yes'." */ if (!dup || dup == b || (dprompt && !c ) || (dprompt = request_response(b, info_msg[SAME_NAME], FALSE))) { b->syn = NULL; /* So that autoprefs will load the right syntax. */ + if (!b->filename) b->filename = str_dup(tilde_expand(p)); +#ifdef HAVE_MAGIC + if (do_syntax) + load_syntax_by_file(b, b->filename); +#endif if (b->opt.auto_prefs && extension(p)) load_auto_prefs(b, extension(p)); error = load_file_in_buffer(b, p); if (error != FILE_IS_MIGRATED && error != FILE_IS_DIRECTORY) change_filename(b, p); print_error(error); @@ -1184,8 +1199,11 @@ int do_action(buffer *b, action a, int c case CLOSEDOC_A: if ((b->is_modified) && !request_response(b, info_msg[THIS_DOCUMENT_NOT_SAVED], FALSE)) return ERROR; if (!delete_buffer()) { +#ifdef HAVE_MAGIC + unload_magic(); +#endif close_history(); unset_interactive_mode(); exit(0); } --- ne-2.1/src/ne.c.magic 2011-03-07 05:34:45.000000000 +0300 +++ ne-2.1/src/ne.c 2011-03-07 05:34:46.173331527 +0300 @@ -24,8 +24,12 @@ #include "regex.h" #include "ne.h" +#ifdef HAVE_MAGIC +#include "mgc.h" +#endif + #include "version.h" #include "termchar.h" #include @@ -265,8 +269,13 @@ int main(int argc, char **argv) { if (!(cd = alloc_clip_desc(INT_MAX, 0))) exit(1); add_head(&clips, &cd->cd_node); +#ifdef HAVE_MAGIC + /* Initialize libmagic */ + load_magic(); +#endif + /* General terminfo and cursor motion initalization. From here onwards, we cannot exit() lightly. */ term_init(); --- /dev/null 2011-03-05 16:11:26.664006066 +0300 +++ ne-2.1/src/mgc.h 2011-03-07 05:34:46.173331527 +0300 @@ -0,0 +1,29 @@ +/* Magic typedefs and defines. + + Copyright (C) 2011 Alexey Gladkov + + This file is part of ne, the nice editor. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef MGC_H +#define MGC_H + +void load_magic(void); +void unload_magic(void); +const char *file2syntax(char * const fn); + +#endif /* MGC_H */ --- /dev/null 2011-03-05 16:11:26.664006066 +0300 +++ ne-2.1/src/magic.syntax 2011-03-07 05:34:46.173331527 +0300 @@ -0,0 +1,13 @@ +application/postscript ps +application/xml xml +text/html html +text/troff troff +text/x-c++ c +text/x-c c +text/x-diff diff +text/x-java java +text/x-makefile make +text/x-perl perl +text/x-php php +text/x-shellscript sh +text/x-texinfo tex