-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement request for preprocessors support #6
Comments
Very interesting. I'll look into it. Thanks for using my plugin! P.S. I was aware of the issue but I did not know it was even fixable. @Sei-Lisa is very knowledgeable 🥇 |
@XenHat Thank you very much! Your plugin is awesome! 🥇 |
In case it helps, I only see two possibilities around this. One is to invoke the preprocessor on a file and open the output in a dedicated window if that is possible with this editor, then run lslint on that (the The other is to make lslint's That second solution will require adding the file name to the output of lslint, which isn't currently there, so that when I may be missing some other solution. Perhaps there is some other language supported by this editor that already supports preprocessor, and it uses tricks that can be borrowed for this application. Ironically, I don't think C or C++ are among them; most compilers integrate the preprocessor pass internally. |
Wow! 👍 |
Having an issue with default parameters not working, will report back |
what should that regex do? catch |
Yeah, I was hoping to be able to "ignore" that specific error, but I was being tired, I think. |
Progress: DEBUG:: sanitized:
integer xlOwnerAttentive()
{
list landmasters = [llGetOwner(), "1d7465fc-27e4-4386-a965-ad92b670832c"];
integer lm_index = llGetListLength(landmasters) - 1;
integer mute = 1;
while (mute && lm_index > -1)
{
mute = llGetAgentInfo(llList2Key(landmasters, lm_index));
mute = mute && ((mute & AGENT_BUSY) || !(mute & AGENT_AWAY));
lm_index--;
}
return mute;
}
default
{
touch_start(integer total_number)dd
{
if(xlOwnerAttentive())
{
llSay(0, "Yes");
}
else
{
llSay(0, "No");
}
}
} |
Well, if you remove The trick here is to remember the For example, if this is the entire preprocessor output (with line numbers added):
then line 3 has a syntax error which will be reported as You have to replace 3 with 4+(3-2), where 4 is the line that the EDIT: The above explanation is off by one. The line number indicated in |
Yeah, I can't figure a way to make this happen with the facilities SublimeLinter provides. That might be better to leave this to lslint indeed. |
Hm, but the snapshot above suggests that you have access to the preprocessor output and to lslint's output. Can't you then filter lslint's output to make lines match as required, before giving them back to the editor? That sounds like basic piping to me. |
That is correct, and definitely possible, but beyond my mental gymnastic abilities right now. |
Would it help if I give you a Python function that takes two strings, one the preprocessor output and the other the lslint output, and gives you another string with the filtered lslint output? Perhaps in a different format, with file path information? |
I'm not sure... I'm pretty tired, I probably need to rest on this. String manipulation with offsets really isn't my part of the things I'm good at, and I don't think I've done something close enough to something like this to know what to do. |
I pushed what I have done so far, be aware that it breaks the linter due to mcpp forcefully inserting at least one |
This is my take on the process:
|
@Sei-Lisa is there a way to make EDIT3: After adding additional lines to my script, I see how lslint handles |
"stdin" is not a library. It has nothing to do with libraries (you may be confusing it with "stdio.h", a standard C library). "stdin" stands for "standard input" and it is the default pipe programs read from. When mcpp reads a file from standard input as opposed to a file you specify, the file parameter in |
Ah, right. I pretty much have to use standard input right now, because I can't figure how to "get" the file name without creating a new temporary one... Not something I feel like doing.
Python being so flexible was the problem 😳 I was using |
Yeah, so just replacing Edit: been there :) |
well, getting the file name is difficult, as mentioned. So whatever (currently hidden/unknown) functionality that relies on that will be broken until I find how.. |
@XenHat http://www.sublimetext.com/docs/3/api_reference.html#sublime.View and there |
Having absolutely no luck getting the API to return me file name, giving up for now. Plus, it works, so |
@winterwolf Could you please test the latest version (just update via package control) and see if this works for you? |
Yay! 👍 What can be done about an error in a different file? Can it notify the main linter module, in order to automatically open the right file where the error is and report it? I really hope so. If not, then I can only think of two alternatives. The ugliest is to just filter out the errors that correspond to a different file. The least bad is to try to guess where the Edit: Sorry that I was so stubborn. 😊 |
RE:edit: No worries. I was too. 😊 About complexity: I'm not afraid of complexity with logic, but I'm pretty trash at math. About the file thing... well, it would be easier if I could get the name of the file opened in the view, but no matter how I look at it, it seems impossible to get code that works fine in the editor's built-in console to behave properly in my linter plugin. I'm not sure why, either. However, we can probably treat "none" as "this file" and then do something with the lines coming from another file such as putting the marker at the position of the EDIT: if you would prefer to chat about this outside the bug tracker, you can hit me up in-world: https://my.secondlife.com/xenhat.liamano (or |
Well, if anything, to not spam Winterwolf with technical details. But since I didn't find you online... The question was not if you can access the filename. It's assumed that the main file is open in the editor, therefore you don't need to find its name in principle; you can assume that The question was if you can force the linter plugin to open a filename you give, in order to report errors in it. I presume that a C linter, for example, must be able to do exactly this, in order to report problems in the headers. Or any other language that supports includes, for the matter. If it doesn't support it, maybe you can file a feature request asking to implement that. But in case it's not supported, here's how I imagine the automatic detection of The basis of idea is that the preprocessor will insert a Then you replace the error line with L2, and do the same conversion math you're doing now using L1, and that's the line number that will appear in the final output. Example: top.lsl 1 | string s; // just to add something
2 | #include "level1.lsl"
3 | default{state_entry(){llOwnerSay(s);}} level1.lsl 1 | #include "level2.lsl" level2.lsl 1 | integer x; The goal is to report the unused identifier at line 2 of our file, which is the line with the include. The mcpp output is:
The error lines reported by lslint are 2 and 6. For line 2, the last For line 6, the last file was not If all goes well, the output should be:
|
Reading through
|
def remove_line_directives(my_string): | |
"""Not a good solution.""" | |
# return re.sub("^#line.*\n","",my_string) | |
return re.sub(r'(?m)^\#line.*\n?', '', my_string) |
currently not used
SublimeLinter-contrib-lslint/linter.py
Lines 150 to 152 in f01e33f
version_args = '-V' | |
version_re = r'(?P<version>\d+\.\d+\.\d+)' | |
version_requirement = '>= 1.0.4' |
You can require
v1.0.6
and use--version
now...
SublimeLinter-contrib-lslint/linter.py
Lines 189 to 191 in f01e33f
lslint_binary_path = fullpath(lslint_binary_name) | |
if lslint_binary_path is None: | |
lslint_binary_path = find_linter(lslint_binary_name) |
The preference here changed comparing to a few days ago. Maybe eventually it would make sense to compare the version for each and decide based upon that?
SublimeLinter-contrib-lslint/linter.py
Line 213 in f01e33f
OutputTuple = namedtuple('OutputTuple', 'mcpp_in_line\ SublimeLinter-contrib-lslint/linter.py
Line 215 in f01e33f
file')
SublimeLinter-contrib-lslint/linter.py
Line 55 in f01e33f
st_pf = sublime.platform().strip() |
no need to
.strip()
'...%s' % ...
or '...%s...%s' % (..., ...)
will format the output to string as well '...{}...{}'.format(..., ...)
. Haven't found a place where usages are compared in a way that would give a reason for either of these. Currently Sublime Text uses Python 3.3, would be nice to be able to use formatted string literals from Python 3.6.SublimeLinter-contrib-lslint/linter.py
Lines 253 to 255 in f01e33f
offset = getLastOffset(preproc_bank, number) # print("Offset: {0}".format(offset)) tokminoff = str(number - int(offset)) SublimeLinter-contrib-lslint/linter.py
Lines 115 to 128 in f01e33f
def getLastOffset(tuples_list, inlined_line): """Yeah.""" result = 0 # Fallback if there is no directives. for this_tuple in tuples_list: if int(this_tuple.mcpp_in_line) >= inlined_line - 1: # We reached a #line directive further than the one # we are looking for; Do not store this instance and # return the previous one instead. This assumes a few things. break # The offset ends up being negative in some cases, even if right. # Let's forcefully remove the negative part of the number. result = this_tuple.mcpp_in_line - this_tuple.orig_line + 2 # This will return 0 if there is no #line found return result
1-3: Fixed |
Here's one (lazy) idea for solving the appending of info: ...
# print("Offset: {0}".format(offset))
# tokminoff = str(number - int(offset))
tokminoff = str(number - int(offset))
# moved from below
# print("Token - offset: {0}".format(tokminoff))
new_line = re.sub(str(number), tokminoff, iter_line)
if result[1] != '"<stdin>"':
index = getLastStdin(preproc_bank, number)
# assert index != -1
new_number = preproc_bank[index + 1].mcpp_in_line + 1
offset = getLastOffset(preproc_bank, new_number)[0]
tokminoff = str(new_number - int(offset))
# the next line is best moved up to avoid calling p.match() twice
token_match = p.match(token)
new_line = '{0}:: ({1:>3}, 1): in file {2}: {3}'.format(token_match.group(1), tokminoff, result[1], new_line)
# print("New Line: {0}".format(new_line))
fixed_output_lines.append(new_line)
continue |
Sorry if I'm distracting, there is errors on linux again:
|
Looks like Linux treats the executable path correctly and my hack doesn't work there. My OS broke and I had to reinstall it, so I lost the Linux VM.. this might take a few days :( |
Or not ;) |
So, if everything goes right, the output of the top.lsl example should look like this:
(The lack of a space at the beginning of the second line is because the regex doesn't capture leading space, but that's only cosmetic.) This would create two warnings, one at line 1 and the other at line 2 of the main file (top.lsl). The first warning would look just as usual. The second warning would point to column 1 of the
which allows the user to go to level2.lsl and check line 1 column 8 manually. Lacking any support for file arguments in SublimeLinter, I think this is the best that can be done and we can declare this issue as fixed. |
@Sei-Lisa I'm only getting one warning.. :(
EDIT: Figured something |
My bad, apologies. I changed my top.lsl like this, and forgot to update the message:
Before that change, there was nothing wrong with line 1, so no warning was emitted for it. |
Nah, it was something else ^^ my top already looks like this, cleaning up and commiting |
Also doesn't have missing leading whitespace
Thanks @Sei-Lisa for spotting this one
Forgot to tag 9802e10 |
Implemented the best we could given SublimeLinter's limitations. |
@XenHat Thank you very much for your work! But I have a noob problem - don't know how to add parameters to lslint (I want to enable lazylists). Tried to edit linter settings like this:
it did not work. |
@winterwolf see #7 :) |
Here is issue that I've posted on lslint repo few days ago: Makopo/lslint#47.
My problem is that your plugin ignores files icluded by preprocessor and produces errors about undeclared variables.
The text was updated successfully, but these errors were encountered: