-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Improvements and fixes for Stream library. #3337
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
Conversation
AbstractBeliefs
commented
Jun 15, 2015
👍
I've quickly glanced over the code, and it seems ok (haven't looked close enough to really check it, though).
Regarding the commit itself, I'd rather see this as two separate changes, since AFAICS they are separate both in function as well as in implementation? Care to split the commit in two? Regarding the commit message, it would be better to remove the "this patch" part, since the message describes a commit, not a patch. In general, a direct form is shorter and preferred, so "Improve the parsing capabilities..." (or if you split the patches, the message can be more specific: "Make parseFloat stop parsing at a second decimal separator" , or "Make parseFloat work without a leading zero", something like that.
AbstractBeliefs
commented
Jun 18, 2015
@matthijskooijman it does have to be said, this does exist as two separate changes that can be used (with a bit of TLC), however, they've both been left to rot.
I understand that many of the people who can pull these requests are volunteers (but the same can be said of other projects) and Arduino has a particular reputation of being... inconsistent in which pull requests are/aren't accepted and the quality of feedback in either case.
Why not just apply the original PRs, which have already been set up and reviewed?
@AbstractBeliefs, I can't comment on why / when PR's are (not) merged. I'm not in a position to make such decisions. I just try to give feedback on contributions, to get them in the best possible shape and make their merging as easy as possible for the people that do the merging. Also, there might be some discrepancy in my feedback and the de-facto requirements for a commit / PR, I'm known to have very high standards in terms of history tidyness :-)
@matthijskooijman, no worries, I will change it up a bit.
prefixed by an '.' character. Previously the preceeding zero must be present: '0.'
multiple decimals '.' in the stream. Only one can be accepted for valid decimal numbers.
125acd5
to
9f6c6ae
Compare
@matthijskooijman
I have re-based the initial commit, separating it into two specific changes.
@facchinm
You added the Stream::find(char);
to the AVR core only in ed1b8eb I have added the SAM version in: Chris--A@94007e2, (#847)
I have added in a modification which resolves #630 and I have also exposed some previously hidden functionality that can be quite useful. Checkout the original PR message for a revised overview of the commits.
PR looks better now. I had a closer look at the actual code too, and added some comments inline.
Regarding the commit messages, I still have one more request. The style commonly used is:
- A first, short (<60 chars preferably) line describing the essence of the commit. For brevity, this line shouldn't have extra fluff like "this commit makes" (instead just say "make"). This line should describe what is changed, not why it is changed, what bug number is fixed, etc. Also, this line shouldn't have a trailing period.
- An empty line.
- A more detailed commit message, describing the change in more details. This should include rationale for the change, any caveats, side-effects, etc. Using "This commit" in this part of the message is ok. Sentences should use trailing periods.
- If a bug is closed by the commit, it should have "Closes #000" in the commit message to allow github to automatically close the commit. If a commit is related to a bug but doesn't close it, just use the bugnumber in the commit message somewhere (e.g. "This commit prepares for fixing #000.").
These are not hard-and-fast rules, but ideally all commits follow these guidelines. We should probably put them up in some good place and have github reference them when creating a PR....
AbstractBeliefs
commented
Jun 19, 2015
As an additional comment about documentation, the functions exposing more controls (such as skipChar and skipMode) should have their documentation updated here. Currently there's no way for the general public to do that (sadly). How should we trigger this once the changes are pulled in?
Updating documentation is usually handled by opening up an issue, preferably already containing some suggested text for the documentation, so the Arduino team can copy that into the online docs.
94b91bd
to
6d2728c
Compare
I have finalized this PR and it now is ready for a final review. :)
I made a decision in the last commit to keep some overloads protected. This is to keep the public API simple. I would prefer these to be public, however I did what I thought would be better for newbies. What do you think?
Two more remarks:
- When adding the skipMode parameter to
peekNextDigit()
, why not add it as a second parameter with a default, to keep backward compatibility? AFAICS, this would make the commits a lot easier to read (I might be wrong, but especially the last commit is a bit big and I don't have a lot of time right now). - The commit adding comments should ideally be squashed into the previous commit where the constants were introduced. I can't see any reason for this to be two commits?
7d79114
to
8cead55
Compare
@matthijskooijman, I had an absolute nightmare removing the comments from the unrelated commit previously, so I left it as its own commit. However I have managed to rebase it today into the previous commit.
As for peekNextDigit()
the first parameter was added in this PR's first commit: Chris--A@2e12a79 so it will not break any existing code.
Ah, I see what you mean now and indeed, no existing code will be broken. However, the history is a bit messy and confusing by this. Ideally, the commits would be reordered such that the protected members are made public first, and then adds skipMode as a second parameter. AFAICS that would result in a much cleaner patch (which is good for reviewing and for the history). Does that sound reasonable to you?
Initially the user/public interface had a parseInt()
& parseFloat()
accepting no parameters. Only derived classes had access to parseInt(skipChar)
& parseFloat(skipChar)
. I intentionally introduced the skipMode enum as the first parameter to peekNextDigit()
as it reflects how it is used with the parsing functions (it was the only parameter in the public API), and this function is private so it is an internal change only.
Exposing the protected features to the public interface is unrelated to the addition of the skipMode functionality, and re-ordering would only impact the ordering of the parameters skipMode and skipChar, where it would have replaced skipChar as the first parameter.
The history may look slightly better if I did not remove the protected member and replace it later. However there is a comment why the function is protected: Chris--A@8cead55#diff-55eb81fc7b42d6d266a05aee3b593ed3R114
Having skipMode as the first parameter in parseInt
/parseFloat
(in my opinion) is keeping in tune with common orderings like coarse grained to fine grained/most used to least used. Of course the single parameter version of parseInt(skipChar)
& parseFloat(skipChar)
can co-exist in the public API (there is no ambiguity), I just left it protected to avoid confusion.
Hm, seems part of my confusion stems from the fact that 'skipChar' is erronously documented as a public interface, probably because it was actually public before 1.0.
Regarding the preferred ordering, I'm not so sure if either skipChar or skipMode is really differently grained and I can't really predict what would be more used, but I don't have a strong preference for the order either way, I think.
Of course the single parameter version of parseInt(skipChar) & parseFloat(skipChar) can co-exist in the public API (there is no ambiguity), I just left it protected to avoid confusion.
Right, that's probably the confusion that hit me too :-p An advantage of swapping the parameters is that there is no need for a separate single-parameter version, which I think is what I was aiming for.
Anyway, if we stick to the parameter order you suggest (as I said, I don't have a strong preference), then I think that the first commit (that introduces the parseX(skipMode)
public method, should not remove the protected parseX(skipChar)
method, but instead add a protected parseX(skipMode, skipChar)
alongside it, which is called by both single-parameter versions. This prevents the first commit from breaking the API, and will make the second commit significantly simpler - it will just make a protected method public as its commit messages promises. And, re-reading your comment, this is exactly what you meant saying "if I did not remove the protected member and replace it later.". I would agree that the history would look cleaner, though I can imagine you're tired of my nitpicking already :-p
On an unrelated note, thinking about the grained-ness of the parameters made me realize that one of them is about skipping stuff before the number and one of them is about skipping stuff inside the number. Would it make sense to change the parameter names to reflect this? If you have a brief look at the names now, you might think that skipChar
is a character to skip and skipMode
indicates in what way it should be skipped. Perhaps skipStartMode
and skipInsideChar
might be better?
I'll fix up the ordering a bit,
For the parameters, maybe: lookahead
& ignore
. I'll change the enum name to LookaheadMode
.
1474bbb
to
508b2c5
Compare
Ok, the breaking changes that were added and removed are now gone from the history. It can now be reverted to any commit without breaking backwards compatibility.
I have renamed the parameters and enum as discussed above 🌴
EDIT: if merged, I'll create a PR to update the zero core.
@buildbot, build this please.
Code looks good to me now!
Two more remarks about the commit messages:
-
The first commit has "This adds the capability to control the Stream::parseInt/float" as the summary line, which is an incomplete sentence (which continues in the rest of the commit description on subsequent lines). It is customary to make the first line self-contained, so something like "Allow controlling Stream::parseInt/Float lookahead" is probably better there, using the entire current commit message as the detailed description after the empty line.
Also, it would be good to mention the skipChar -> ignore rename in the commit message, that makes the patch easier to review.
-
The subject line of the last commit, "Enables public access to features previously marked private" is very general. I would propose changing it to e.g. "Make protected Stream::parseInt/Float overloads public".
The rest of the commit message is fine.
Its default is SKIP_ALL which reflects previous versions. However SKIP_NONE, and SKIP_WHITESPACE can refine this behaviour. A parameter used in the protected overloads of parseInt/Float has been changed from `skipChar` to `ignore`.
This is a feature added to the AVR core here: arduino@ed1b8eb It allows using the find method with a single char (arduino#847).
Stream::parseInt & Stream::parseFloat previously had protected overloads which allowed skipping a custom character. This commit brings this feature to the public interface. To keep the public API simpler, the single paramter overload remains protected. However its functionality is available in the public interface using the two parameter overload.
508b2c5
to
876e540
Compare
The commit messages have been edited.
Chris--A@004838a now mentions the changes skipChar
-> ignore
.
Anything holding this back from being merged?
As soon as this is approved (if), I will also do up a PR for the zero (and third party ESP8266) to keep a contiguous API.
I hope these improvements do not get lost in the abyss.
I can also rebase the commits if needed so it doesn't throw out the history.
+1 for merging this.
AbstractBeliefs
commented
Oct 7, 2015
I'd like to see this merged also.
BlackBrix
commented
Nov 21, 2015
why isn't this merged, it is needed ...
DaveAhrendt
commented
Nov 22, 2015
Same here. Please merge this.
Thanks @Chris--A! I've rebased your PR and pushed it to master. It will be available in the next hourly build: http://www.arduino.cc/en/Main/Software#hourly
@matthijskooijman, @AbstractBeliefs thank you for reviewing and providing feedback as well.
Also add Stream::find(char) API. Port of: arduino/Arduino#3337
This set of commits improves the parsing capabilities of
Stream::parseFloat()
andStream::parseInt()
.parseFloat
The function will now accept decimals starting with an
.
character not just0.
An error has been fixed where where 1.23.45 is parsed as 1.2345 rather than 1.23 and subsequent calls reading _0.45_ (after the fix mentioned above).
both parseInt/Float
The lookahead feature can be controlled using either
SKIP_NONE
,SKIP_ALL
, orSKIP_WHITESPACE
The hidden member
skipChar
has been exposed. This allows parsing of formatted decimals, not just shorthand like .12 but complex formatting like: -1,234.567 (parseFloat), 1,234 (parseInt). Rather than removing the hidden unused features, they could be quite beneficial.As the interface changes are implemented using optional parameters, the code is backwards compatible without change.
SAM
The
Stream::find(char);
method has been added to the SAM core making it equivalent to the AVR implementation.This resolves:
#1962
#2007
#630