Hi Jonathan, it's been a while because I was on vacation. I've forgotten about most of the intricacies of this patch (I think this was a good thing, read on below). Jonathan Tan <jonathantanmy@xxxxxxxxxx> writes: > "Linus Arver via GitGitGadget" <gitgitgadget@xxxxxxxxx> writes: >> From: Linus Arver <linusa@xxxxxxxxxx> >> >> Previously, trailer_info_get() computed the trailer block end position >> by >> >> (1) checking for the opts->no_divider flag and optionally calling >> find_patch_start() to find the "patch start" location (patch_start), and >> (2) calling find_trailer_end() to find the end of the trailer block >> using patch_start as a guide, saving the return value into >> "trailer_end". >> >> The logic in (1) was awkward because the variable "patch_start" is >> misleading if there is no patch in the input. The logic in (2) was >> misleading because it could be the case that no trailers are in the >> input (yet we are setting a "trailer_end" variable before even searching >> for trailers, which happens later in find_trailer_start()). The name >> "find_trailer_end" was misleading because that function did not look for >> any trailer block itself --- instead it just computed the end position >> of the log message in the input where the end of the trailer block (if >> it exists) would be (because trailer blocks must always come after the >> end of the log message). > > [...] > > As it is, the reader still needs to know that trailer_start is where > the trailer would start if it was present, and then I think it's quite > natural to have trailer_end be where the trailer would end if it was > present. > > I believe the code is simpler this way, because trailer absence now no > longer needs to be special-cased when we use these variables (or maybe > they sometimes do, but not as often, since code that writes to the end > of the trailers, for example, can now just write at trailer_end instead > of having to check whether trailers exist). Same comment for patch 4 > regarding using the special value 0 if no trailers are found (I think > the existing code makes more sense). I think the root cause of my confusion with this codebase is due to the variables being named as if the things they refer to exist, but without any guarantees that they indeed exist. This applies to "patch_start" (the patch part might not be present in the input), "trailer_{start,end}" (trailers block might not exist (yet)). IOW these variables are named as if the intent is to always add new trailers into the input, which may not be the case (we have "--parse", after all). Looking again at patch 4, I'm now leaning toward dropping it. Other than the reasons you cited, we also add a new struct field which by itself does not add new information (the information can already be deduced from the other fields). In the near future I want to simplify the data structures as much as possible, and adding a new field seems to go against this desire of mine. >> Combine the logic in (1) and (2) together into find_patch_start() by >> renaming it to find_end_of_log_message(). The end of the log message is >> the starting point which find_trailer_start() needs to start searching >> backward to parse individual trailers (if any). > > Having said that, if patch_start is too confusing for whatever reason, > this refactoring makes sense. (Avoid the confusing name by avoiding > needing to name it in the first place.) I think the existing code is confusing, and would prefer to keep this patch. >> -static size_t find_patch_start(const char *str) >> +static size_t find_end_of_log_message(const char *input, int no_divider) >> { >> + size_t end; >> + >> const char *s; >> >> - for (s = str; *s; s = next_line(s)) { >> + /* Assume the naive end of the input is already what we want. */ >> + end = strlen(input); >> + >> + /* Optionally skip over any patch part ("---" line and below). */ >> + for (s = input; *s; s = next_line(s)) { >> const char *v; >> >> - if (skip_prefix(s, "---", &v) && isspace(*v)) >> - return s - str; >> + if (!no_divider && skip_prefix(s, "---", &v) && isspace(*v)) { >> + end = s - input; >> + break; >> + } >> } >> >> - return s - str; >> + /* Skip over other ignorable bits. */ >> + return end - ignored_log_message_bytes(input, end); >> } > > This sometimes redundantly calls strlen and sometimes redundantly loops. > I think it's better to do as the code currently does - so, have a big > if/else at the beginning of this function that checks no_divider. Will update, thanks.