Skip to content

Fix Stdlib.Arg: do no repeat usage_msg thrice#999

Merged
gasche merged 4 commits intoocaml:trunkfrom
Octachron:arg_stuttering
Jan 15, 2017
Merged

Fix Stdlib.Arg: do no repeat usage_msg thrice#999
gasche merged 4 commits intoocaml:trunkfrom
Octachron:arg_stuttering

Conversation

@Octachron
Copy link
Member

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 -o yields

ocamllex: option '-o' needs an argument.
usage: ocamllex [options] sourcefile
  -ml  Output code that does not use the Lexing module built-in automata interpreter
  -o  <file>  Set output file name to <file>
  -q  Do not display informational messages
  -v  Print version and exit
  -version  Print version and exit
  -vnum  Print version number and exit
  -help  Display this list of options
  --help  Display this list of options
ocamllex: ocamllex: option '-o' needs an argument.
usage: ocamllex [options] sourcefile
  -ml  Output code that does not use the Lexing module built-in automata interpreter
  -o  <file>  Set output file name to <file>
  -q  Do not display informational messages
  -v  Print version and exit
  -version  Print version and exit
  -vnum  Print version number and exit
  -help  Display this list of options
  --help  Display this list of options
.
usage: ocamllex [options] sourcefile
  -ml  Output code that does not use the Lexing module built-in automata interpreter
  -o  <file>  Set output file name to <file>
  -q  Do not display informational messages
  -v  Print version and exit
  -version  Print version and exit
  -vnum  Print version number and exit
  -help  Display this list of options
  --help  Display this list of options

This 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.

stdlib/arg.ml Outdated
end;
done

let parse_and_expand_argv_dynamic_aux allow_expand current argv speclist anonfun
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a shadowing definition? There are some many parse_ functions now that I think it would be best avoided for readability.

@bschommer
Copy link
Contributor

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.

@Octachron
Copy link
Member Author

Octachron commented Jan 9, 2017

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

Arg.parse ["-arg", String (fun _ -> ()), "arg"] ignore "Message"

is enough to trigger the problem, which was already here in 4.04.

@bschommer
Copy link
Contributor

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).

@lefessan lefessan added the bug label Jan 9, 2017
@Octachron Octachron force-pushed the arg_stuttering branch 2 times, most recently from 2856cfc to 6d3e942 Compare January 9, 2017 10:27
@Octachron
Copy link
Member Author

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).

@Leonidas-from-XIV
Copy link

@bschommer

The problem is now only if there exist some other ocaml tool relying on the old behavior (I can't image one).

There should not be one, since 4.02.3 does not have this issue, it's a regression in 4.03.

@bschommer
Copy link
Contributor

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.

@gasche
Copy link
Member

gasche commented Jan 9, 2017

I believe d431b5b is the change that introduced the regression (I just bisected).

@Octachron
Copy link
Member Author

Octachron commented Jan 9, 2017

@gasche d431b5b does introduce an "exception type" error by raising a Bad exception in get_arg rather than a Stop exception. I have tried to rename few key functions in the last version of the PR to avoid future misunderstandings.

@gasche
Copy link
Member

gasche commented Jan 13, 2017

Is this related to / does this affect MPR#7460?

@Octachron
Copy link
Member Author

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

@bschommer
Copy link
Contributor

But it could have the same origin. The main changes to Arg were my adding of Expand and the PR which introduced this regression. Since both trunk and 4.04 are affected I think the other PR will be the culprit.

@gasche
Copy link
Member

gasche commented Jan 13, 2017

@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.

@bschommer
Copy link
Contributor

I found the source of MPR#7460 and opened a PR #1011 for it.

@Octachron
Copy link
Member Author

@gasche : Done, I added a test for all major variations on error message raised in arg.ml .

Copy link
Member

@gasche gasche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that declaring b to be local to this function, instead of carefully clearing it, would make the code simpler and more robust.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. Fixed.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the new code makes much more sense to me.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that Help:\n%s\n (and similarly for Bad) would make the reference file easier to read.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point.

@Octachron
Copy link
Member Author

@gasche All the parse functions are currently defined in term of parse_and_expand_argv_dynamic_aux, testing ocamlc would test just a different parameter.

I have nothing against an integration test for ocaml ({,c,opt} etc…) argument but is such test really the object of this PR?

@gasche
Copy link
Member

gasche commented Jan 13, 2017

Ok; I'm willing to merge as-is after we get CI returns.

camlspotter pushed a commit to camlspotter/ocaml that referenced this pull request Oct 17, 2017
Fix Stdlib.Arg: do no repeat usage_msg thrice (GPR#999)
EmileTrotignon pushed a commit to EmileTrotignon/ocaml that referenced this pull request Jan 12, 2024
* refactor package urls, routes, and handlers
* move package redirects to redirection.ml
EmileTrotignon pushed a commit to EmileTrotignon/ocaml that referenced this pull request Jan 12, 2024
* 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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants