-
-
Notifications
You must be signed in to change notification settings - Fork 162
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
Implement printf %()T %.s %*s %.*s #668
Conversation
Thanks this is great! I pulled and ran the tests and they passed. And thanks for pointing out the bug. I think the existing code might not be behaving as much like a "parser" as I want it do -- I'm looking at why. Please separate the
( In addition I try to maintain different token types rather than looking at token values, see property #2 here: http://www.oilshell.org/blog/2019/02/07.html#three-nice-properties-of-a-parser So it would be nice if
These are defined in This is more of a style thing but I think it makes the code cleaner. If it causes complications let me know. One nice way to view the AST is to turn OK I'm looking at this a little more... I think it's good but I think the width parsing was already messed up as you noticed. |
Oh I see there are two problems:
https://github.com/oilshell/oil/blob/master/osh/builtin_printf.py#L48
Now I get this:
So I think it is important to update the grammar and then follow the code. But if you think that will mess things up let me know and I can try it. It's more important that it works at first than to follow a particular style. Long term I want to share the printf lexer and parser with a static variant:
This is analogous to Also another consequence of this is that I try to never synthesize |
Hm yeah I think the grammar should be something like:
instead of
Does that look right? No actually that's not right because you can combine width and precision with time:
Maybe add those test cases to make sure they work? |
So then I think the grammar is more like:
? |
Thank you for your review!
b695317 I added token IDs
27e435c Updated.
28c169f Changed so that
1c84df0 Added a test case and supported precision for Multiple flags?By the way, I noticed that the current implementation only accepts a single flag. Since Oil currently supports only |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parsing part looks great! Thank you. The Zero
is an improvement.
I don't know about multiple flags... I guess it's OK to parse more as long as nothing that exists is broken. We can recognize the full language and implement it later, as long as there is a decent error message about what's not implemented.
About the TZ
part -- this will have to be rewritten in C at some point, but it doesn't have to be done now (e.g. let's worry about the rest of #653 before that).
So the important part is really the tests. As long as the tests are covering the intended behavior and will catch bugs in future C code, it's good.
osh/builtin_printf.py
Outdated
@@ -252,14 +314,31 @@ def Run(self, cmd_val): | |||
s = '%x' % d | |||
elif typ == 'X': | |||
s = '%X' % d | |||
elif part.type.id == Id.Format_Time: | |||
# set timezone |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain this part in a high level comment? I don't know these APIs very well and eventually they will have to be translated to C.
(Actually if you prefer to write in C, then native/libc.c
has related functions and is fairly easy to modify.)
Does strftime
read os.environ['TZ']
? I'm not sure how it works exactly.
OK I looked over the docs a bit, I guess time.tzset()
reads os.environ['TZ']
. That's kind of confusing. Please add a comment about that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cb08494 Thank you! I added code comments. (edit: added a typofix)
osh/builtin_printf.py
Outdated
d = None | ||
elif d == -2: # shell start time | ||
d = shell_start_time | ||
s = time.strftime(typ[1:-2], time.localtime(d)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no semicolon needed
Also where does -2
come from? I'm having trouble following that. May need more comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the semicolon and added comments in cb08494. Also, I changed to explicitly set d = time.time()
(not relying on the default behavior of time.localtime(None)
). (edit: added a typo fix)
88360e5 I also added support of multiple flags. |
Great thank you! This is one of the biggest contributions ever to Oil. bash
:-) I made this change to accomodate how we strip down the CPython interpreter (will be obsolete after C++ translation, but it's closer to what C looks like) Also I adjusted this zsh output: Can you try building shells like this? At least 2 people have done it before and it takes 2-3 minutes. https://github.com/oilshell/oil/blob/master/test/spec-bin.sh That is the "golden version" of the shell we test. (Some of them are old but they are stable/known. The spec tests tickle lots of verison-specific behavior.) Thanks again! |
Thank you! FYI: I understand the motivation for using POSIX API and I'm not sure if it causes a real problem or not. but Python documentation recommends to call
Oh, I'm sorry. I actually noticed the results of test cases are sometimes different but didn't think about it seriously. Now I built the shells! Thank you! |
Minor updates: I removed a condition on TZ, and added some tests, see rationale here: Basically there is no equivalent of Also, I thought that TZ was like LANG. LANG is respected even if it's NOT exported. But that's not true of TZ. #527 I looked in I think the current behavior is fine but if you see any issues let me know. Right before I mentioned Then I realized you might not have pulled in the last 5 minutes. So if you have I did this for the Travis build which caches the |
Resolve #650
%()T
%6.s
(fix parsing of precision)%*.*s
#
flagNote on
%()T
In the implementation of
%()T
, I needed to reflect the exported shell variableTZ
in the real environment variableTZ
. This is the corresponding section. I'm not sure whether I did this in the right way. (Maybe a new method likeself.mem.GetExportedVar(name)
should be added toclass Mem
). Could you check and edit if necessary?Note on
%6.s
In the current master branch, the parsing of
%6.s
is broken to generate the following errors (s
is treated as a precision), so I added a check for the precision and treat missing precision as0
(as POSIX requirements).Note on
printf # flag
The tests for flag
#
in the current master branch doesn't fully describe the behavior, so I added and modified tests.