Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
hyperlink committed Apr 30, 2012
2 parents 58a017f + 7f72c88 commit 72adfd2
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 90 deletions.
20 changes: 20 additions & 0 deletions LICENSE
@@ -0,0 +1,20 @@
Copyright Germán M. Bravo, Aparajita Fishman, Jacob Swartwood, and other
contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
108 changes: 53 additions & 55 deletions README.rst → README.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion SublimeLinter.py
Expand Up @@ -52,12 +52,13 @@
'sublimelinter_gutter_marks',
'sublimelinter_wrap_find',
'sublimelinter_popup_errors_on_save',
'perl_linter',
'javascript_linter',
'jshint_options',
'jslint_options',
'csslint_options',
'gjslint_options',
'gjslint_ignore',
'csslint_options',
'pep8_ignore',
'pyflakes_ignore',
'pyflakes_ignore_import_*',
Expand Down
8 changes: 7 additions & 1 deletion SublimeLinter.sublime-settings
Expand Up @@ -69,7 +69,7 @@
"sublimelinter_popup_errors_on_save": false,

// Javascript linter: "gjslint" to use the closure javascript linter (if available),
// or "jshint" to use the built in jshint linter.
// or either "jshint" or "jslint" to use a built in linter.
"javascript_linter": "jshint",

// jshint: options for linting JavaScript. See http://jshint.com/#docs for more info.
Expand Down Expand Up @@ -167,6 +167,12 @@
*/
"pyflakes_ignore_import_*": true,

// Perl linter: "perl" to use the Perl language syntax check,
// or "perlcritic" to use Perl::Critic linting.
// Perl is now set to use "perlcritic" by default due to a vulnerability with blindly running `perl -c`
// on files with `BEGIN` or `CHECK` blocks (see issue #77: https://github.com/Kronuz/SublimeLinter/issues/77).
"perl_linter": "perlcritic",

// Objective-J: if true, non-ascii characters are flagged as an error.
"sublimelinter_objj_check_ascii": false,

Expand Down
19 changes: 19 additions & 0 deletions changelog.txt
Expand Up @@ -203,3 +203,22 @@ CHANGES/FIXES
- Added additional debugging output (in Sublime console) when
errors occur running linters written in Javascript.


SublimeLinter 1.6.2 changelog
=============================
CHANGES/FIXES

- Replaced the default perl linter with Perl::Critic. The standard Perl syntax checker
can still be invoked by switching the "perl_linter" setting to "perl".

- Added a LICENSE file to define appropriate usage of SublimeLinter and its source.

- Converted README back to markdown.


IMPORTANT

Due to a vulnerability (issue #77) with the Perl linter, Perl syntax checking is no longer
enabled by default. The default linter for Perl has been replaced by Perl::Critic.


3 changes: 2 additions & 1 deletion messages.json
Expand Up @@ -8,5 +8,6 @@
"1.5.6": "messages/1.5.6.txt",
"1.5.7": "messages/1.5.7.txt",
"1.6.0": "messages/1.6.0.txt",
"1.6.1": "messages/1.6.1.txt"
"1.6.1": "messages/1.6.1.txt",
"1.6.2": "messages/1.6.2.txt"
}
16 changes: 16 additions & 0 deletions messages/1.6.2.txt
@@ -0,0 +1,16 @@
SublimeLinter 1.6.2 changelog

CHANGES/FIXES

- Replaced the default perl linter with Perl::Critic. The standard Perl syntax checker
can still be invoked by switching the "perl_linter" setting to "perl".

- Added a LICENSE file to define appropriate usage of SublimeLinter and its source.

- Converted README back to markdown.


IMPORTANT

Due to a vulnerability (issue #77) with the Perl linter, Perl syntax checking is no longer
enabled by default. The default linter for Perl has been replaced by Perl::Critic.
4 changes: 2 additions & 2 deletions package_control.json
Expand Up @@ -10,8 +10,8 @@
"platforms": {
"*": [
{
"version": "1.6.1",
"url": "https://nodeload.github.com/Kronuz/SublimeLinter/zipball/v1.6.1"
"version": "1.6.2",
"url": "https://nodeload.github.com/Kronuz/SublimeLinter/zipball/v1.6.2"
}
]
}
Expand Down
9 changes: 9 additions & 0 deletions sublimelinter/modules/base_linter.py
Expand Up @@ -275,6 +275,15 @@ def underline_regex(self, view, lineno, regex, lines, underlines, wordmatch=None
for start, end in results:
self.underline_range(view, lineno, start + offset, underlines, end - start)

def underline_word(self, view, lineno, position, underlines):
# Assume lineno is one-based, ST2 wants zero-based line numbers
lineno -= 1
line = view.full_line(view.text_point(lineno, 0))
position += line.begin()

word = view.word(position)
underlines.append(word)

def run(self, view, code, filename=None):
self.filename = filename

Expand Down
35 changes: 13 additions & 22 deletions sublimelinter/modules/libs/capp_lint.py
Expand Up @@ -37,8 +37,6 @@
import re
import sys

import sublime


EXIT_CODE_SHOW_HTML = 205
EXIT_CODE_SHOW_TOOLTIP = 206
Expand Down Expand Up @@ -135,12 +133,21 @@ class LintChecker(object):
METHOD_RE = ur'[-+]\s*\([a-zA-Z_$]\w*\)\s*[a-zA-Z_$]\w*'
FUNCTION_RE = re.compile(ur'\s*function\s*(?P<name>[a-zA-Z_$]\w*)?\(.*\)\s*\{?')
STRING_LITERAL_RE = re.compile(ur'(?<!\\)(["\'])(.*?)(?<!\\)\1')
RE_RE = re.compile(ur'(?<!\\)/.*?[^\\]/[gims]*')
EMPTY_STRING_LITERAL_FUNCTION = lambda match: match.group(1) + (len(match.group(2)) * ' ') + match.group(1)
EMPTY_SELF_STRING_LITERAL_FUNCTION = lambda self, match: match.group(1) + (len(match.group(2)) * ' ') + match.group(1)

ERROR_TYPE_ILLEGAL = 1
ERROR_TYPE_WARNING = 2

# Replace the contents of comments, regex and string literals
# with spaces so we don't get false matches within them
STD_IGNORES = (
{'regex': STRIP_LINE_COMMENT_RE, 'replace': ''},
{'regex': STRING_LITERAL_RE, 'replace': EMPTY_STRING_LITERAL_FUNCTION},
{'regex': RE_RE, 'replace': '/ /'},
)

LINE_CHECKLIST = (
{
'id': 'tabs',
Expand Down Expand Up @@ -178,11 +185,7 @@ class LintChecker(object):
# Filter out @import statements, method declarations, method parameters, unary plus/minus/increment/decrement
'filter': {'regex': re.compile(ur'(^@import\b|^\s*' + METHOD_RE + '|^\s*[a-zA-Z_$]\w*:\s*\([a-zA-Z_$][\w<>]*\)\s*\w+|[a-zA-Z_$]\w*(\+\+|--)|([ -+*/%^&|<>!]=?|&&|\|\||<<|>>>|={1,3}|!==?)\s*[-+][\w(\[])'), 'pass': False},

# Replace the contents of literal strings with spaces so we don't get false matches within them
'preprocess': (
{'regex': STRIP_LINE_COMMENT_RE, 'replace': ''},
{'regex': STRING_LITERAL_RE, 'replace': EMPTY_STRING_LITERAL_FUNCTION},
),
'preprocess': STD_IGNORES,
'regex': re.compile(ur'(?<=[\w)\]"\']|([ ]))([-+*/%^]|&&?|\|\|?|<<|>>>?)(?=[\w({\["\']|(?(1)\b\b|[ ]))'),
'error': 'binary operator without surrounding spaces',
'showPositionForGroup': 2,
Expand All @@ -192,11 +195,7 @@ class LintChecker(object):
# Filter out @import statements, method declarations
'filter': {'regex': re.compile(ur'^(@import\b|\s*' + METHOD_RE + ')'), 'pass': False},

# Replace the contents of literal strings with spaces so we don't get false matches within them
'preprocess': (
{'regex': STRIP_LINE_COMMENT_RE, 'replace': ''},
{'regex': STRING_LITERAL_RE, 'replace': EMPTY_STRING_LITERAL_FUNCTION},
),
'preprocess': STD_IGNORES,
'regex': re.compile(ur'(?:[-*/%^&|<>!]=?|&&|\|\||<<|>>>|={1,3}|!==?)\s*(?<!\+)(\+)[\w(\[]'),
'error': 'useless unary + operator',
'showPositionForGroup': 1,
Expand All @@ -206,11 +205,7 @@ class LintChecker(object):
# Filter out possible = within @accessors
'filter': {'regex': re.compile(ur'^\s*(?:@outlet\s+)?[a-zA-Z_$]\w*\s+[a-zA-Z_$]\w*\s+@accessors\b'), 'pass': False},

# Replace the contents of literal strings with spaces so we don't get false matches within them
'preprocess': (
{'regex': STRIP_LINE_COMMENT_RE, 'replace': ''},
{'regex': STRING_LITERAL_RE, 'replace': EMPTY_STRING_LITERAL_FUNCTION},
),
'preprocess': STD_IGNORES,
'regex': re.compile(ur'(?<=[\w)\]"\']|([ ]))(=|[-+*/%^&|]=|<<=|>>>?=)(?=[\w({\["\']|(?(1)\b\b|[ ]))'),
'error': 'assignment operator without surrounding spaces',
'showPositionForGroup': 2,
Expand All @@ -220,11 +215,7 @@ class LintChecker(object):
# Filter out @import statements and @implementation/method declarations
'filter': {'regex': re.compile(ur'^(@import\b|@implementation\b|\s*' + METHOD_RE + ')'), 'pass': False},

# Replace the contents of literal strings with spaces so we don't get false matches within them
'preprocess': (
{'regex': STRIP_LINE_COMMENT_RE, 'replace': ''},
{'regex': STRING_LITERAL_RE, 'replace': EMPTY_STRING_LITERAL_FUNCTION},
),
'preprocess': STD_IGNORES,
'regex': re.compile(ur'(?<=[\w)\]"\']|([ ]))(===?|!==?|[<>]=?)(?=[\w({\["\']|(?(1)\b\b|[ ]))'),
'error': 'comparison operator without surrounding spaces',
'showPositionForGroup': 2,
Expand Down
52 changes: 44 additions & 8 deletions sublimelinter/modules/perl.py
Expand Up @@ -2,28 +2,64 @@
# perl.py - sublimelint package for checking perl files

import re
import subprocess

from base_linter import BaseLinter

CONFIG = {
'language': 'perl',
'executable': 'perl',
'lint_args': '-c'
'language': 'perl'
}


class Linter(BaseLinter):
PERLCRITIC_RE = re.compile(r'\[(?P<pbp>.+)\] (?P<error>.+?) at line (?P<line>\d+), column (?P<column>\d+).+?')
PERL_RE = re.compile(r'(?P<error>.+?) at .+? line (?P<line>\d+)(, near "(?P<near>.+?)")?')

def __init__(self, config):
super(Linter, self).__init__(config)
self.linter = None

def get_executable(self, view):
self.linter = view.settings().get('perl_linter', 'perlcritic')

if self.linter == 'perl':
linter_name = 'Perl'
else:
linter_name = 'Perl::Critic'

try:
path = self.get_mapped_executable(view, self.linter)
subprocess.call([path, '--version'], startupinfo=self.get_startupinfo())
return (True, path, 'using {0}'.format(linter_name))
except OSError:
return (False, '', '{0} is required'.format(linter_name))

def get_lint_args(self, view, code, filename):
if self.linter == 'perl':
return ['-c']
else:
return ['--verbose', '8']

def parse_errors(self, view, errors, lines, errorUnderlines, violationUnderlines, warningUnderlines, errorMessages, violationMessages, warningMessages):
for line in errors.splitlines():
match = re.match(r'(?P<error>.+?) at .+? line (?P<line>\d+)(, near "(?P<near>.+?)")?', line)
if self.linter == 'perl':
match = self.PERL_RE.match(line)
else:
match = self.PERLCRITIC_RE.match(line)

if match:
error, line = match.group('error'), match.group('line')
lineno = int(line)
near = match.group('near')

if near:
error = '{0}, near "{1}"'.format(error, near)
self.underline_regex(view, lineno, '(?P<underline>{0})'.format(re.escape(near)), lines, errorUnderlines)
if self.linter == 'perl':
near = match.group('near')

if near:
error = '{0}, near "{1}"'.format(error, near)
self.underline_regex(view, lineno, '(?P<underline>{0})'.format(re.escape(near)), lines, errorUnderlines)
else:
column = match.group('column')
column = int(column) - 1
self.underline_word(view, lineno, column, errorUnderlines)

self.add_message(lineno, lines, error, errorMessages)

0 comments on commit 72adfd2

Please sign in to comment.