Fix Stdlib.Arg: do no repeat usage_msg thrice#999
Conversation
stdlib/arg.ml
Outdated
| end; | ||
| done | ||
|
|
||
| let parse_and_expand_argv_dynamic_aux allow_expand current argv speclist anonfun |
There was a problem hiding this comment.
Is this a shadowing definition? There are some many parse_ functions now that I think it would be best avoided for readability.
|
To me that seems to be more of a problem of ocamllex. The behavior is the same for 4.04 which has the old functions. |
I am sorry, I was unclear. The problem is in no way specific to ocamllex: ocamlc, ocamlopt, …, all programs using Arg are also affected: an example as simple as is enough to trigger the problem, which was already here in 4.04. |
|
You are right, I just did not see it for ocamlopt since there are so many options. The problem is now only if there exist some other ocaml tool relying on the old behavior (I can't image one). |
2856cfc to
6d3e942
Compare
|
I have updated the fix to avoid changing the behavior with error raised by user functions: the patch now simply avoids to convert internal Stop exception to external Bad/Help exception too early (which caused these exceptions to be recaught a second time as user function errors, which cumulated with the lack of buffer clearing resulted to the triple repetition of the usage message). |
There should not be one, since 4.02.3 does not have this issue, it's a regression in 4.03. |
|
Ah okay, I only tried it with 4.04 and since I was pretty sure that there were no changes from 4.03 to 4.04 I thought it was no regression. |
6d3e942 to
0890ae9
Compare
|
I believe d431b5b is the change that introduced the regression (I just bisected). |
|
Is this related to / does this affect MPR#7460? |
|
It sounds similar, but I would say no: MPR#7460 exception is raised from outside of Arg: https://github.com/ocaml/ocaml/blob/trunk/driver/main.ml#L132 |
|
But it could have the same origin. The main changes to |
|
@Octachron : would you add a test to the testsuite for the behavior fixed in your PR? I think the two regressions show that we need more testing there. |
|
I found the source of MPR#7460 and opened a PR #1011 for it. |
0890ae9 to
675bbfb
Compare
|
@gasche : Done, I added a test for all major variations on error message raised in |
gasche
left a comment
There was a problem hiding this comment.
I think your added tests are nice, but they only test one of the Arg.parse* functions and I'm not sure I fully trust that other will behave in the same way; I think it would be helpful (rather than trying to test all of these functions) to also have an integration test that directly invokes the ocamlc compiler from the command-line (since this is what most users will see, and where we should therefore be most careful about avoiding regressions).
stdlib/arg.ml
Outdated
| *or* add the program name as a prefix and the usage message as a suffix | ||
| to an user-raised Bad exception. | ||
| *) | ||
| let () = Buffer.clear b in |
There was a problem hiding this comment.
I think that declaring b to be local to this function, instead of carefully clearing it, would make the code simpler and more robust.
stdlib/arg.ml
Outdated
| match follow with | ||
| | None -> () | ||
| | Some arg -> stop (Wrong (s, arg, "no argument")) in | ||
| | Some arg -> raise (Stop (Wrong (s, arg, "no argument"))) in |
There was a problem hiding this comment.
When reading the patch (without having tried to understand the code first) I see no particular reason why this raise site would not use convert_error, while the one above does. I think that this code could be restructured to be easier to understand. In particular, I would like all raises that do (respectively, don't) need the convert_error wrapping should be close together, instead of both categories being interleaved with no clear scoping. It would be even better, ideally, if the types could make it more clear that double-handling is impossible (for example by having the inputs of convert_error use a different error-description type than its output).
There was a problem hiding this comment.
I have simplified the code by moving it around and fusionning the different try clause in the main while loop.
Conversion now happens only at one point.
There was a problem hiding this comment.
Thanks, the new code makes much more sense to me.
testsuite/tests/lib-arg/testerror.ml
Outdated
| let argv = Array.of_list ("testerror" :: argv) in | ||
| try Arg.parse_argv ~current:(ref 0) argv spec anon usage with | ||
| | Arg.Bad s-> Printf.printf "(%d/%d) Bad:%s\n" (i+1) total s | ||
| | Arg.Help s -> Printf.printf "(%d/%d) Help:%s\n" (i+1) total s |
There was a problem hiding this comment.
I think that Help:\n%s\n (and similarly for Bad) would make the reference file easier to read.
|
@gasche All the parse functions are currently defined in term of I have nothing against an integration test for ocaml ({,c,opt} etc…) argument but is such test really the object of this PR? |
|
Ok; I'm willing to merge as-is after we get CI returns. |
Fix Stdlib.Arg: do no repeat usage_msg thrice (GPR#999)
* refactor package urls, routes, and handlers * move package redirects to redirection.ml
* make package documentation link more obvious (ocaml#828) * make documentation link more obvious * minor style improvement Co-Authored-By: Sabine Schmaltz <[email protected]> * improve authors/maintainers display on package overview (ocaml#1001) * refactor package urls, routes, and handlers (ocaml#999) * refactor package urls, routes, and handlers * move package redirects to redirection.ml * Unify package overview and documentation layout (ocaml#1015) * unified package overview/docs layout Rearranges package overview and documentation such that: * package_layout.eml defines the two sidebars and the content area * there is a navigation element to switch between Overview (About) and Documentation (Docs) * there is a placeholder element for the upcoming in-package search (to remind us how important this feature is and to show users that we have a plan where it goes) Consequences: * package overview page now has a collapsing sidebar with a button to slide it in on small screens * package documentation now has a tablet (md) layout that shows the sidebar on-screen, instead of collapsed * add text-sm which was lost during unification * "Overview" instead of "About" since we have the space * Add support for sitemap.xml * Generate sitemap.xml by dream * Apply suggestions from @cuihtlauac code review Co-authored-by: Cuihtlauac Alvarado <[email protected]> * Convert lists of urls to sequences and change names of functions * Apply suggestions from @cuihtlauac code review 2 Co-authored-by: Cuihtlauac Alvarado <[email protected]> * Delete subdomains URLs and URLs returning status code other than 200 * Apply suggestions from @cuihtlauac code review 3 Co-authored-by: Cuihtlauac Alvarado <[email protected]> * Update PR * formating * do not touch playground asset * Apply suggestions from @cuihtlauac code review 4 * Apply suggestions from @cuihtlauac code review 5 * Apply suggestions from @cuihtlauac code review 6 * Apply suggestions from @cuihtlauac code review 7 * Apply suggestions from @cuihtlauac code review 8 --------- Co-authored-by: Sabine Schmaltz <[email protected]> Co-authored-by: sabine <[email protected]> Co-authored-by: Cuihtlauac Alvarado <[email protected]>
Currently, when reporting an error during the parsing of argument, the parsing functions in Arg repeat the usage_msg thrice (and the error message twice). For instance, invoking
ocamllex -oyieldsThis PR fixes this problem by avoiding long-ranged side-effect when constructing error messages in
Arg.parse_and_expand_argv_dynamic_aux. Similarly, this PR also suppresses the repetition of the program name by not prefixing already constructed error messages with the program name.when reporting error.