2011-02-12 Chris Allegretta <chrisa@asty.org>
* Initial libmagic implementation, adapted from Eitan Adler <eitanadlerlist@gmail.com>. New nanorc entry "magic" to enable this functionality, nanorc file and man page updates. git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4528 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Этот коммит содержится в:
родитель
637daa85c5
Коммит
b00d0b9c8c
@ -1,3 +1,7 @@
|
|||||||
|
2011-02-12 Chris Allegretta <chrisa@asty.org>
|
||||||
|
* Initial libmagic implementation, adapted from Eitan Adler <eitanadlerlist@gmail.com>.
|
||||||
|
New nanorc entry "magic" to enable this functionality, nanorc file and man page updates.
|
||||||
|
|
||||||
2011-02-06 Chris Allegretta <chrisa@asty.org>
|
2011-02-06 Chris Allegretta <chrisa@asty.org>
|
||||||
* src/*: Retire iso_me_harder_funcmap based on suggestion by <bernd.spaeth@gmx.net>
|
* src/*: Retire iso_me_harder_funcmap based on suggestion by <bernd.spaeth@gmx.net>
|
||||||
This does add 20KB to nano's executable size but it gets rid of a lot of indirection
|
This does add 20KB to nano's executable size but it gets rid of a lot of indirection
|
||||||
|
@ -50,7 +50,7 @@ AC_DEFINE_DIR([PKGDATADIR], [pkgdatadir], [Where data are placed to.])
|
|||||||
dnl Checks for header files.
|
dnl Checks for header files.
|
||||||
|
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_CHECK_HEADERS(getopt.h libintl.h limits.h regex.h sys/param.h wchar.h wctype.h stdarg.h)
|
AC_CHECK_HEADERS(getopt.h libintl.h limits.h regex.h sys/param.h wchar.h wctype.h stdarg.h magic.h)
|
||||||
|
|
||||||
dnl Checks for options.
|
dnl Checks for options.
|
||||||
|
|
||||||
@ -583,6 +583,7 @@ AC_MSG_RESULT(yes),
|
|||||||
AC_MSG_RESULT(no),
|
AC_MSG_RESULT(no),
|
||||||
AC_MSG_WARN([*** Can't check for macro redefinability when cross-compiling]))
|
AC_MSG_WARN([*** Can't check for macro redefinability when cross-compiling]))
|
||||||
|
|
||||||
|
AC_CHECK_LIB(magic, magic_open)
|
||||||
|
|
||||||
# Check for groff html support
|
# Check for groff html support
|
||||||
AC_MSG_CHECKING([for HTML support in groff])
|
AC_MSG_CHECKING([for HTML support in groff])
|
||||||
|
@ -239,6 +239,13 @@ the same as not having a syntax at all. The \fIdefault\fP syntax is
|
|||||||
special: it takes no \fIfileregex\fP, and applies to files that don't
|
special: it takes no \fIfileregex\fP, and applies to files that don't
|
||||||
match any other syntax's \fIfileregex\fP.
|
match any other syntax's \fIfileregex\fP.
|
||||||
.TP
|
.TP
|
||||||
|
.B magic ["\fIregex\fP" ... ]
|
||||||
|
For the currently defined syntax, add one or more regexes which
|
||||||
|
will be compared against the \fBmagic\fP database when attempting
|
||||||
|
to determine which highlighting rules to use for a given file. This
|
||||||
|
functionality only works when \fBlibmagic\fP is installed on the
|
||||||
|
system and will be silently ignored otherwise.
|
||||||
|
.TP
|
||||||
.B color \fIfgcolor\fP,\fIbgcolor\fP "\fIregex\fP" ...
|
.B color \fIfgcolor\fP,\fIbgcolor\fP "\fIregex\fP" ...
|
||||||
For the currently defined syntax, display all expressions matching
|
For the currently defined syntax, display all expressions matching
|
||||||
the extended regular expression \fIregex\fP with foreground color
|
the extended regular expression \fIregex\fP with foreground color
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
## Here is an example for assembler.
|
## Here is an example for assembler.
|
||||||
##
|
##
|
||||||
syntax "asm" "\.(S|s|asm)$"
|
syntax "asm" "\.(S|s|asm)$"
|
||||||
|
magic "[Aa]ssembl(y|er)"
|
||||||
color red "\<[A-Z_]{2,}\>"
|
color red "\<[A-Z_]{2,}\>"
|
||||||
color brightgreen "\.(data|subsection|text)"
|
color brightgreen "\.(data|subsection|text)"
|
||||||
color green "\.(align|file|globl|global|hidden|section|size|type|weak)"
|
color green "\.(align|file|globl|global|hidden|section|size|type|weak)"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
## Here is an example for awk.
|
## Here is an example for awk.
|
||||||
##
|
##
|
||||||
syntax "awk" "\.awk$"
|
syntax "awk" "\.awk$"
|
||||||
|
magic "awk.*script text"
|
||||||
## records
|
## records
|
||||||
icolor brightred "\$[0-9A-Z_!@#$*?-]+"
|
icolor brightred "\$[0-9A-Z_!@#$*?-]+"
|
||||||
## awk-set variables
|
## awk-set variables
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
## Here is an example for C/C++.
|
## Here is an example for C/C++.
|
||||||
##
|
##
|
||||||
syntax "c" "\.(c(c|pp|xx)?|C)$" "\.(h(h|pp|xx)?|H)$" "\.ii?$"
|
syntax "c" "\.(c(c|pp|xx)?|C)$" "\.(h(h|pp|xx)?|H)$" "\.ii?$"
|
||||||
|
magic "ASCII C(\+\+)? program text"
|
||||||
color brightred "\<[A-Z_][0-9A-Z_]+\>"
|
color brightred "\<[A-Z_][0-9A-Z_]+\>"
|
||||||
color green "\<(float|double|bool|char|int|short|long|sizeof|enum|void|static|const|struct|union|typedef|extern|(un)?signed|inline)\>"
|
color green "\<(float|double|bool|char|int|short|long|sizeof|enum|void|static|const|struct|union|typedef|extern|(un)?signed|inline)\>"
|
||||||
color green "\<((s?size)|((u_?)?int(8|16|32|64|ptr)))_t\>"
|
color green "\<((s?size)|((u_?)?int(8|16|32|64|ptr)))_t\>"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
## Here is a short example for HTML.
|
## Here is a short example for HTML.
|
||||||
##
|
##
|
||||||
syntax "html" "\.html$"
|
syntax "html" "\.html$"
|
||||||
|
magic "HTML document text"
|
||||||
color blue start="<" end=">"
|
color blue start="<" end=">"
|
||||||
color red "&[^;[[:space:]]]*;"
|
color red "&[^;[[:space:]]]*;"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
## Here is an example for Java.
|
## Here is an example for Java.
|
||||||
##
|
##
|
||||||
syntax "java" "\.java$"
|
syntax "java" "\.java$"
|
||||||
|
magic "Java "
|
||||||
color green "\<(boolean|byte|char|double|float|int|long|new|short|this|transient|void)\>"
|
color green "\<(boolean|byte|char|double|float|int|long|new|short|this|transient|void)\>"
|
||||||
color red "\<(break|case|catch|continue|default|do|else|finally|for|if|return|switch|throw|try|while)\>"
|
color red "\<(break|case|catch|continue|default|do|else|finally|for|if|return|switch|throw|try|while)\>"
|
||||||
color cyan "\<(abstract|class|extends|final|implements|import|instanceof|interface|native|package|private|protected|public|static|strictfp|super|synchronized|throws|volatile)\>"
|
color cyan "\<(abstract|class|extends|final|implements|import|instanceof|interface|native|package|private|protected|public|static|strictfp|super|synchronized|throws|volatile)\>"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
## Here is an example for manpages.
|
## Here is an example for manpages.
|
||||||
##
|
##
|
||||||
syntax "man" "\.[1-9]x?$"
|
syntax "man" "\.[1-9]x?$"
|
||||||
|
magic "troff or preprocessor input text"
|
||||||
color green "\.(S|T)H.*$"
|
color green "\.(S|T)H.*$"
|
||||||
color brightgreen "\.(S|T)H" "\.TP"
|
color brightgreen "\.(S|T)H" "\.TP"
|
||||||
color brightred "\.(BR?|I[PR]?).*$"
|
color brightred "\.(BR?|I[PR]?).*$"
|
||||||
|
@ -5,7 +5,7 @@ syntax "nanorc" "\.?nanorc$"
|
|||||||
icolor brightwhite "^[[:space:]]*((un)?set|include|syntax|i?color).*$"
|
icolor brightwhite "^[[:space:]]*((un)?set|include|syntax|i?color).*$"
|
||||||
## Keywords
|
## Keywords
|
||||||
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|autoindent|backup|backupdir|backwards|boldtext|brackets|casesensitive|const|cut|fill|historylog|matchbrackets|morespace|mouse|multibuffer|noconvert|nofollow|nohelp|nonewlines|nowrap|operatingdir|preserve|punct)\>" "^[[:space:]]*(set|unset)[[:space:]]+(quickblank|quotestr|rebinddelete|rebindkeypad|regexp|smarthome|smooth|softwrap|speller|suspend|suspendenable|tabsize|tabstospaces|tempfile|undo|view|whitespace|wordbounds)\>"
|
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|autoindent|backup|backupdir|backwards|boldtext|brackets|casesensitive|const|cut|fill|historylog|matchbrackets|morespace|mouse|multibuffer|noconvert|nofollow|nohelp|nonewlines|nowrap|operatingdir|preserve|punct)\>" "^[[:space:]]*(set|unset)[[:space:]]+(quickblank|quotestr|rebinddelete|rebindkeypad|regexp|smarthome|smooth|softwrap|speller|suspend|suspendenable|tabsize|tabstospaces|tempfile|undo|view|whitespace|wordbounds)\>"
|
||||||
icolor green "^[[:space:]]*(set|unset|include|syntax|header)\>"
|
icolor green "^[[:space:]]*(set|unset|include|syntax|header|magic)\>"
|
||||||
## Colors
|
## Colors
|
||||||
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
|
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
|
||||||
icolor magenta "^[[:space:]]*i?color\>" "\<(start|end)="
|
icolor magenta "^[[:space:]]*i?color\>" "\<(start|end)="
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
## Here is an example for patch files.
|
## Here is an example for patch files.
|
||||||
##
|
##
|
||||||
syntax "patch" "\.(patch|diff)$"
|
syntax "patch" "\.(patch|diff)$"
|
||||||
|
magic "diff output text"
|
||||||
color brightgreen "^\+.*"
|
color brightgreen "^\+.*"
|
||||||
color green "^\+\+\+.*"
|
color green "^\+\+\+.*"
|
||||||
color brightblue "^ .*"
|
color brightblue "^ .*"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
## Here is an example for Perl.
|
## Here is an example for Perl.
|
||||||
##
|
##
|
||||||
syntax "perl" "\.p[lm]$"
|
syntax "perl" "\.p[lm]$"
|
||||||
|
magic "perl.*script text"
|
||||||
header "^#!.*/perl[-0-9._]*"
|
header "^#!.*/perl[-0-9._]*"
|
||||||
color red "\<(accept|alarm|atan2|bin(d|mode)|c(aller|h(dir|mod|op|own|root)|lose(dir)?|onnect|os|rypt)|d(bm(close|open)|efined|elete|ie|o|ump)|e(ach|of|val|x(ec|ists|it|p))|f(cntl|ileno|lock|ork))\>" "\<(get(c|login|peername|pgrp|ppid|priority|pwnam|(host|net|proto|serv)byname|pwuid|grgid|(host|net)byaddr|protobynumber|servbyport)|([gs]et|end)(pw|gr|host|net|proto|serv)ent|getsock(name|opt)|gmtime|goto|grep|hex|index|int|ioctl|join)\>" "\<(keys|kill|last|length|link|listen|local(time)?|log|lstat|m|mkdir|msg(ctl|get|snd|rcv)|next|oct|open(dir)?|ord|pack|pipe|pop|printf?|push|q|qq|qx|rand|re(ad(dir|link)?|cv|do|name|quire|set|turn|verse|winddir)|rindex|rmdir|s|scalar|seek(dir)?)\>" "\<(se(lect|mctl|mget|mop|nd|tpgrp|tpriority|tsockopt)|shift|shm(ctl|get|read|write)|shutdown|sin|sleep|socket(pair)?|sort|spli(ce|t)|sprintf|sqrt|srand|stat|study|substr|symlink|sys(call|read|tem|write)|tell(dir)?|time|tr(y)?|truncate|umask)\>" "\<(un(def|link|pack|shift)|utime|values|vec|wait(pid)?|wantarray|warn|write)\>"
|
color red "\<(accept|alarm|atan2|bin(d|mode)|c(aller|h(dir|mod|op|own|root)|lose(dir)?|onnect|os|rypt)|d(bm(close|open)|efined|elete|ie|o|ump)|e(ach|of|val|x(ec|ists|it|p))|f(cntl|ileno|lock|ork))\>" "\<(get(c|login|peername|pgrp|ppid|priority|pwnam|(host|net|proto|serv)byname|pwuid|grgid|(host|net)byaddr|protobynumber|servbyport)|([gs]et|end)(pw|gr|host|net|proto|serv)ent|getsock(name|opt)|gmtime|goto|grep|hex|index|int|ioctl|join)\>" "\<(keys|kill|last|length|link|listen|local(time)?|log|lstat|m|mkdir|msg(ctl|get|snd|rcv)|next|oct|open(dir)?|ord|pack|pipe|pop|printf?|push|q|qq|qx|rand|re(ad(dir|link)?|cv|do|name|quire|set|turn|verse|winddir)|rindex|rmdir|s|scalar|seek(dir)?)\>" "\<(se(lect|mctl|mget|mop|nd|tpgrp|tpriority|tsockopt)|shift|shm(ctl|get|read|write)|shutdown|sin|sleep|socket(pair)?|sort|spli(ce|t)|sprintf|sqrt|srand|stat|study|substr|symlink|sys(call|read|tem|write)|tell(dir)?|time|tr(y)?|truncate|umask)\>" "\<(un(def|link|pack|shift)|utime|values|vec|wait(pid)?|wantarray|warn|write)\>"
|
||||||
color magenta "\<(continue|else|elsif|do|for|foreach|if|unless|until|while|eq|ne|lt|gt|le|ge|cmp|x|my|sub|use|package|can|isa)\>"
|
color magenta "\<(continue|else|elsif|do|for|foreach|if|unless|until|while|eq|ne|lt|gt|le|ge|cmp|x|my|sub|use|package|can|isa)\>"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
## Here is an example for PHP
|
## Here is an example for PHP
|
||||||
##
|
##
|
||||||
syntax "php" "\.php[2345s~]?$"
|
syntax "php" "\.php[2345s~]?$"
|
||||||
|
magic "PHP script text"
|
||||||
|
|
||||||
## php markings
|
## php markings
|
||||||
color brightgreen "(<\?(php)?|\?>)"
|
color brightgreen "(<\?(php)?|\?>)"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
## Here is an example for Bourne shell scripts.
|
## Here is an example for Bourne shell scripts.
|
||||||
##
|
##
|
||||||
syntax "sh" "\.sh$"
|
syntax "sh" "\.sh$"
|
||||||
|
magic "(POSIX|Bourne.*) shell script text"
|
||||||
header "^#!.*/(ba|k|pdk)?sh[-0-9_]*"
|
header "^#!.*/(ba|k|pdk)?sh[-0-9_]*"
|
||||||
icolor brightgreen "^[0-9A-Z_]+\(\)"
|
icolor brightgreen "^[0-9A-Z_]+\(\)"
|
||||||
color green "\<(case|do|done|elif|else|esac|exit|fi|for|function|if|in|local|read|return|select|shift|then|time|until|while)\>"
|
color green "\<(case|do|done|elif|else|esac|exit|fi|for|function|if|in|local|read|return|select|shift|then|time|until|while)\>"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
## Here is an example for xml files.
|
## Here is an example for xml files.
|
||||||
##
|
##
|
||||||
syntax "xml" "\.([jrs]html?|sgml?|xml|xslt?)$"
|
syntax "xml" "\.([jrs]html?|sgml?|xml|xslt?)$"
|
||||||
|
magic "XML.*document text"
|
||||||
color green start="<" end=">"
|
color green start="<" end=">"
|
||||||
color cyan "<[^> ]+"
|
color cyan "<[^> ]+"
|
||||||
color cyan ">"
|
color cyan ">"
|
||||||
|
103
src/color.c
103
src/color.c
@ -25,6 +25,11 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_MAGIC_H
|
||||||
|
#include <magic.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_COLOR
|
#ifdef ENABLE_COLOR
|
||||||
|
|
||||||
@ -102,12 +107,32 @@ void color_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cleanup a regex we previously compiled */
|
||||||
|
void nfreeregex(regex_t *r)
|
||||||
|
{
|
||||||
|
assert(r != NULL);
|
||||||
|
|
||||||
|
regfree(r);
|
||||||
|
free(r);
|
||||||
|
r = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Update the color information based on the current filename. */
|
/* Update the color information based on the current filename. */
|
||||||
void color_update(void)
|
void color_update(void)
|
||||||
{
|
{
|
||||||
syntaxtype *tmpsyntax;
|
syntaxtype *tmpsyntax;
|
||||||
syntaxtype *defsyntax = NULL;
|
syntaxtype *defsyntax = NULL;
|
||||||
colortype *tmpcolor, *defcolor = NULL;
|
colortype *tmpcolor, *defcolor = NULL;
|
||||||
|
exttype *e;
|
||||||
|
|
||||||
|
/* libmagic structures */
|
||||||
|
/* magicstring will be NULL if we fail to get magic result */
|
||||||
|
#ifdef HAVE_LIBMAGIC
|
||||||
|
const char *magicstring = NULL;
|
||||||
|
const char *magicerr = NULL;
|
||||||
|
magic_t m;
|
||||||
|
#endif /* HAVE_LIBMAGIC */
|
||||||
|
|
||||||
|
|
||||||
assert(openfile != NULL);
|
assert(openfile != NULL);
|
||||||
|
|
||||||
@ -133,13 +158,35 @@ void color_update(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBMAGIC
|
||||||
|
|
||||||
|
if (strcmp(openfile->filename,"")) {
|
||||||
|
m = magic_open(MAGIC_SYMLINK |
|
||||||
|
#ifdef DEBUG
|
||||||
|
MAGIC_DEBUG | MAGIC_CHECK |
|
||||||
|
#endif /* DEBUG */
|
||||||
|
MAGIC_ERROR);
|
||||||
|
if (m == NULL || magic_load(m, NULL) < 0)
|
||||||
|
fprintf(stderr, "something went wrong: %s [%s]\n", strerror(errno), openfile->filename);
|
||||||
|
else {
|
||||||
|
magicstring = magic_file(m,openfile->filename);
|
||||||
|
if (magicstring == NULL) {
|
||||||
|
magicerr = magic_error(m);
|
||||||
|
fprintf(stderr, "something went wrong: %s [%s]\n", magicerr, openfile->filename);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "magic string returned: %s\n", magicstring);
|
||||||
|
#endif /* DEBUG */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_LIBMAGIC */
|
||||||
|
|
||||||
/* If we didn't specify a syntax override string, or if we did and
|
/* If we didn't specify a syntax override string, or if we did and
|
||||||
* there was no syntax by that name, get the syntax based on the
|
* there was no syntax by that name, get the syntax based on the
|
||||||
* file extension, and then look in the header. */
|
* file extension, and then look in the header. */
|
||||||
if (openfile->colorstrings == NULL) {
|
if (openfile->colorstrings == NULL) {
|
||||||
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
||||||
tmpsyntax = tmpsyntax->next) {
|
tmpsyntax = tmpsyntax->next) {
|
||||||
exttype *e;
|
|
||||||
|
|
||||||
/* If this is the default syntax, it has no associated
|
/* If this is the default syntax, it has no associated
|
||||||
* extensions, which we've checked for elsewhere. Skip over
|
* extensions, which we've checked for elsewhere. Skip over
|
||||||
@ -163,24 +210,52 @@ void color_update(void)
|
|||||||
|
|
||||||
/* Set colorstrings if we matched the extension
|
/* Set colorstrings if we matched the extension
|
||||||
* regex. */
|
* regex. */
|
||||||
if (regexec(e->ext, openfile->filename, 0, NULL,
|
if (regexec(e->ext, openfile->filename, 0, NULL, 0) == 0) {
|
||||||
0) == 0) {
|
|
||||||
openfile->syntax = tmpsyntax;
|
openfile->syntax = tmpsyntax;
|
||||||
openfile->colorstrings = tmpsyntax->color;
|
openfile->colorstrings = tmpsyntax->color;
|
||||||
}
|
|
||||||
|
|
||||||
if (openfile->colorstrings != NULL)
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Decompile e->ext_regex's specified regex if we aren't
|
/* Decompile e->ext_regex's specified regex if we aren't
|
||||||
* going to use it. */
|
* going to use it. */
|
||||||
if (not_compiled) {
|
if (not_compiled)
|
||||||
regfree(e->ext);
|
nfreeregex(e->ext);
|
||||||
free(e->ext);
|
}
|
||||||
e->ext = NULL;
|
}
|
||||||
|
|
||||||
|
/* Check magic if we don't yet have an answer */
|
||||||
|
#ifdef HAVE_LIBMAGIC
|
||||||
|
if (openfile->colorstrings == NULL) {
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "No match using extension, trying libmagic...\n");
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
||||||
|
tmpsyntax = tmpsyntax->next) {
|
||||||
|
for (e = tmpsyntax->magics; e != NULL; e = e->next) {
|
||||||
|
bool not_compiled = (e->ext == NULL);
|
||||||
|
if (not_compiled) {
|
||||||
|
e->ext = (regex_t *)nmalloc(sizeof(regex_t));
|
||||||
|
regcomp(e->ext, fixbounds(e->ext_regex), REG_EXTENDED);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr,"Matching regex \"%s\" against \"%s\"\n",e->ext_regex, magicstring);
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
if (magicstring && regexec(e->ext, magicstring, 0, NULL, 0) == 0) {
|
||||||
|
fprintf(stderr,"We matched!\n");
|
||||||
|
openfile->syntax = tmpsyntax;
|
||||||
|
openfile->colorstrings = tmpsyntax->color;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not_compiled)
|
||||||
|
nfreeregex(e->ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_LIBMAGIC */
|
||||||
|
|
||||||
/* If we haven't matched anything yet, try the headers */
|
/* If we haven't matched anything yet, try the headers */
|
||||||
if (openfile->colorstrings == NULL) {
|
if (openfile->colorstrings == NULL) {
|
||||||
@ -189,7 +264,6 @@ void color_update(void)
|
|||||||
#endif
|
#endif
|
||||||
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
||||||
tmpsyntax = tmpsyntax->next) {
|
tmpsyntax = tmpsyntax->next) {
|
||||||
exttype *e;
|
|
||||||
|
|
||||||
for (e = tmpsyntax->headers; e != NULL; e = e->next) {
|
for (e = tmpsyntax->headers; e != NULL; e = e->next) {
|
||||||
bool not_compiled = (e->ext == NULL);
|
bool not_compiled = (e->ext == NULL);
|
||||||
@ -217,11 +291,8 @@ void color_update(void)
|
|||||||
|
|
||||||
/* Decompile e->ext_regex's specified regex if we aren't
|
/* Decompile e->ext_regex's specified regex if we aren't
|
||||||
* going to use it. */
|
* going to use it. */
|
||||||
if (not_compiled) {
|
if (not_compiled)
|
||||||
regfree(e->ext);
|
nfreeregex(e->ext);
|
||||||
free(e->ext);
|
|
||||||
e->ext = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,6 +232,8 @@ typedef struct syntaxtype {
|
|||||||
/* The list of extensions that this syntax applies to. */
|
/* The list of extensions that this syntax applies to. */
|
||||||
exttype *headers;
|
exttype *headers;
|
||||||
/* Regexes to match on the 'header' (1st line) of the file */
|
/* Regexes to match on the 'header' (1st line) of the file */
|
||||||
|
exttype *magics;
|
||||||
|
/* Regexes to match libmagic results */
|
||||||
colortype *color;
|
colortype *color;
|
||||||
/* The colors used in this syntax. */
|
/* The colors used in this syntax. */
|
||||||
int nmultis;
|
int nmultis;
|
||||||
|
@ -547,6 +547,7 @@ char *parse_argument(char *ptr);
|
|||||||
char *parse_next_regex(char *ptr);
|
char *parse_next_regex(char *ptr);
|
||||||
bool nregcomp(const char *regex, int eflags);
|
bool nregcomp(const char *regex, int eflags);
|
||||||
void parse_syntax(char *ptr);
|
void parse_syntax(char *ptr);
|
||||||
|
void parse_magic_syntax(char *ptr);
|
||||||
void parse_include(char *ptr);
|
void parse_include(char *ptr);
|
||||||
short color_to_short(const char *colorname, bool *bright);
|
short color_to_short(const char *colorname, bool *bright);
|
||||||
void parse_colors(char *ptr, bool icase);
|
void parse_colors(char *ptr, bool icase);
|
||||||
|
74
src/rcfile.c
74
src/rcfile.c
@ -303,6 +303,7 @@ void parse_syntax(char *ptr)
|
|||||||
endheader = NULL;
|
endheader = NULL;
|
||||||
endsyntax->extensions = NULL;
|
endsyntax->extensions = NULL;
|
||||||
endsyntax->headers = NULL;
|
endsyntax->headers = NULL;
|
||||||
|
endsyntax->magics = NULL;
|
||||||
endsyntax->next = NULL;
|
endsyntax->next = NULL;
|
||||||
endsyntax->nmultis = 0;
|
endsyntax->nmultis = 0;
|
||||||
|
|
||||||
@ -358,6 +359,76 @@ void parse_syntax(char *ptr)
|
|||||||
} else
|
} else
|
||||||
free(newext);
|
free(newext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse the next syntax string from the line at ptr, and add it to the
|
||||||
|
* global list of color syntaxes. */
|
||||||
|
void parse_magictype(char *ptr)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LIBMAGIC
|
||||||
|
const char *fileregptr = NULL;
|
||||||
|
exttype *endext = NULL;
|
||||||
|
|
||||||
|
assert(ptr != NULL);
|
||||||
|
|
||||||
|
if (syntaxes == NULL) {
|
||||||
|
rcfile_error(
|
||||||
|
N_("Cannot add a magic string regex without a syntax command"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ptr == '\0') {
|
||||||
|
rcfile_error(N_("Missing magic string name"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ptr != '"') {
|
||||||
|
rcfile_error(
|
||||||
|
N_("Regex strings must begin and end with a \" character"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "Starting a magic type: \"%s\"\n", ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Now load the extensions into their part of the struct. */
|
||||||
|
while (*ptr != '\0') {
|
||||||
|
exttype *newext;
|
||||||
|
/* The new extension structure. */
|
||||||
|
|
||||||
|
while (*ptr != '"' && *ptr != '\0')
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
if (*ptr == '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
fileregptr = ptr;
|
||||||
|
ptr = parse_next_regex(ptr);
|
||||||
|
if (ptr == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
newext = (exttype *)nmalloc(sizeof(exttype));
|
||||||
|
|
||||||
|
/* Save the regex if it's valid. */
|
||||||
|
if (nregcomp(fileregptr, REG_NOSUB)) {
|
||||||
|
newext->ext_regex = mallocstrcpy(NULL, fileregptr);
|
||||||
|
newext->ext = NULL;
|
||||||
|
|
||||||
|
if (endext == NULL)
|
||||||
|
endsyntax->magics = newext;
|
||||||
|
else
|
||||||
|
endext->next = newext;
|
||||||
|
endext = newext;
|
||||||
|
endext->next = NULL;
|
||||||
|
} else
|
||||||
|
free(newext);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_LIBMAGIC */
|
||||||
}
|
}
|
||||||
|
|
||||||
int check_bad_binding(sc *s)
|
int check_bad_binding(sc *s)
|
||||||
@ -951,6 +1022,9 @@ void parse_rcfile(FILE *rcstream
|
|||||||
rcfile_error(N_("Syntax \"%s\" has no color commands"),
|
rcfile_error(N_("Syntax \"%s\" has no color commands"),
|
||||||
endsyntax->desc);
|
endsyntax->desc);
|
||||||
parse_syntax(ptr);
|
parse_syntax(ptr);
|
||||||
|
}
|
||||||
|
else if (strcasecmp(keyword, "magic") == 0) {
|
||||||
|
parse_magictype(ptr);
|
||||||
} else if (strcasecmp(keyword, "header") == 0)
|
} else if (strcasecmp(keyword, "header") == 0)
|
||||||
parse_headers(ptr);
|
parse_headers(ptr);
|
||||||
else if (strcasecmp(keyword, "color") == 0)
|
else if (strcasecmp(keyword, "color") == 0)
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user