On 3/13/2023 6:31 AM, Phillip Wood wrote: > Hi Stolee > > On 10/03/2023 17:20, Derrick Stolee via GitGitGadget wrote: >> From: Derrick Stolee <derrickstolee@xxxxxxxxxx> >> >> When a user wishes to input a large list of patterns to 'git >> for-each-ref' (likely a long list of exact refs) there are frequently >> system limits on the number of command-line arguments. >> >> Add a new --stdin option to instead read the patterns from standard >> input. Add tests that check that any unrecognized arguments are >> considered an error when --stdin is provided. Also, an empty pattern >> list is interpreted as the complete ref set. >> >> When reading from stdin, we populate the filter.name_patterns array >> dynamically as opposed to pointing to the 'argv' array directly. This >> requires a careful cast while freeing the individual strings, >> conditioned on the --stdin option. > > I think what you've got here is fine, but if you wanted you could simplify it by using an strvec. Something like > > struct strvec vec = STRVEC_INIT; > > ... > > if (from_stdin) { > struct strbuf buf = STRBUF_INIT; > > if (argv[0]) > die(_("unknown arguments supplied with --stdin")); > > while (strbuf_getline(&line, stdin) != EOF) > strvec_push(&vec, buf.buf); > > filter.name_patters = vec.v; > } else { > filter.name_patterns = argv; > } > > ... > > strvec_clear(&vec); > > gets rid of the manual memory management with ALLOC_GROW() and the need to cast filter.name_patterns when free()ing. It is not immediately obvious from the name but struct strvec keeps the array NULL terminated. Thanks, Philip. I like your version a lot and will use it in the next version. -Stolee