On Mon, Aug 10, 2026 at 12:03 AM John Ericson <[email protected]> wrote:
>
> The loop that splits a PATH_SEPARATOR separated environment variable and
> adds each directory as a prefix was written out three times, for
> COMPILER_PATH, LIBRARY_PATH and LPATH, differing only in which prefix
> list each directory is added to.
>
> Factor it out into for_each_env_path, a sibling of for_each_path that
> takes a callback the same way.  Handling a null value in the helper also
> lets the two startfile users share one 'cross_compile' test and one
> callback, rather than repeating both.
>
> No functional change.
>
> gcc/ChangeLog:
>
>         * gcc.cc (for_each_env_path): New function template.
>         (process_command): Use it for COMPILER_PATH, LIBRARY_PATH and
>         LPATH.
>
> Signed-off-by: John Ericson <[email protected]>
> ---
>  gcc/gcc.cc | 148 +++++++++++++++++++++--------------------------------
>  1 file changed, 57 insertions(+), 91 deletions(-)
>
> diff --git a/gcc/gcc.cc b/gcc/gcc.cc
> index 973a3402330..08a192ade76 100644
> --- a/gcc/gcc.cc
> +++ b/gcc/gcc.cc
> @@ -2983,6 +2983,51 @@ for_each_path (const struct path_prefix *paths,
>    return ret;
>  }
>
> +/* Call CALLBACK once per directory named in VALUE, a PATH_SEPARATOR
> +   separated list such as the value of COMPILER_PATH or PATH.  VALUE may be
> +   null, in which case CALLBACK is not called at all.
> +
> +   An empty element denotes the current directory.  Each directory is passed
> +   with a trailing directory separator, as add_prefix expects.  The buffer
> +   handed to CALLBACK is reused between iterations, so CALLBACK must copy
> +   anything it wants to keep -- add_prefix does.  */
> +
> +template<typename fun>
> +static void
> +for_each_env_path (const char *value, fun callback)

Do we have a callback that needs some other data passed to it?
If not then I would not make this a template and just make the
callback argument a function type `void (*)(const char*)`.

> +{
> +  if (!value)
> +    return;
> +
> +  char *nstore = (char *) alloca (strlen (value) + 3);
> +
> +  for (const char *startp = value, *endp = value; ; endp++)
> +    {
> +      if (*endp != PATH_SEPARATOR && *endp != 0)
> +       continue;
> +
> +      if (endp == startp)
> +       strcpy (nstore, concat (".", dir_separator_str, NULL));
> +      else
> +       {
> +         strncpy (nstore, startp, endp - startp);
> +         if (!IS_DIR_SEPARATOR (endp[-1]))
> +           {
> +             nstore[endp - startp] = DIR_SEPARATOR;
> +             nstore[endp - startp + 1] = 0;
> +           }
> +         else
> +           nstore[endp - startp] = 0;
> +       }
> +
> +      callback (nstore);
> +
> +      if (*endp == 0)
> +       break;
> +      startp = endp + 1;
> +    }
> +}
> +
>  /* Add or change the value of an environment variable, outputting the
>     change to standard error if in verbose mode.  */
>  static void
> @@ -4962,103 +5007,24 @@ process_command (unsigned int decoded_options_count,
>    /* COMPILER_PATH and LIBRARY_PATH have values
>       that are lists of directory names with colons.  */
>
> -  temp = env.get ("COMPILER_PATH");
> -  if (temp)
> +  for_each_env_path (env.get ("COMPILER_PATH"), [] (const char *dir)
>      {
> -      const char *startp, *endp;
> -      char *nstore = (char *) alloca (strlen (temp) + 3);
> -
> -      startp = endp = temp;
> -      while (1)
> -       {
> -         if (*endp == PATH_SEPARATOR || *endp == 0)
> -           {
> -             strncpy (nstore, startp, endp - startp);
> -             if (endp == startp)
> -               strcpy (nstore, concat (".", dir_separator_str, NULL));
> -             else if (!IS_DIR_SEPARATOR (endp[-1]))
> -               {
> -                 nstore[endp - startp] = DIR_SEPARATOR;
> -                 nstore[endp - startp + 1] = 0;
> -               }
> -             else
> -               nstore[endp - startp] = 0;
> -             add_prefix (&exec_prefixes, nstore, 0,
> -                         PREFIX_PRIORITY_LAST, 0, 0);
> -             add_prefix (&include_prefixes, nstore, 0,
> -                         PREFIX_PRIORITY_LAST, 0, 0);
> -             if (*endp == 0)
> -               break;
> -             endp = startp = endp + 1;
> -           }
> -         else
> -           endp++;
> -       }
> -    }
> +      add_prefix (&exec_prefixes, dir, 0, PREFIX_PRIORITY_LAST, 0, 0);
> +      add_prefix (&include_prefixes, dir, 0, PREFIX_PRIORITY_LAST, 0, 0);
> +    });
>
> -  temp = env.get (LIBRARY_PATH_ENV);
> -  if (temp && *cross_compile == '0')
> +  if (*cross_compile == '0')
>      {
> -      const char *startp, *endp;
> -      char *nstore = (char *) alloca (strlen (temp) + 3);
> -
> -      startp = endp = temp;
> -      while (1)
> +      auto add_startfile_prefix = [] (const char *dir)
>         {
> -         if (*endp == PATH_SEPARATOR || *endp == 0)
> -           {
> -             strncpy (nstore, startp, endp - startp);
> -             if (endp == startp)
> -               strcpy (nstore, concat (".", dir_separator_str, NULL));
> -             else if (!IS_DIR_SEPARATOR (endp[-1]))
> -               {
> -                 nstore[endp - startp] = DIR_SEPARATOR;
> -                 nstore[endp - startp + 1] = 0;
> -               }
> -             else
> -               nstore[endp - startp] = 0;
> -             add_prefix (&startfile_prefixes, nstore, NULL,
> -                         PREFIX_PRIORITY_LAST, 0, 1);
> -             if (*endp == 0)
> -               break;
> -             endp = startp = endp + 1;
> -           }
> -         else
> -           endp++;
> -       }
> -    }
> +         add_prefix (&startfile_prefixes, dir, NULL,
> +                     PREFIX_PRIORITY_LAST, 0, 1);
> +       };
>
> -  /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
> -  temp = env.get ("LPATH");
> -  if (temp && *cross_compile == '0')
> -    {
> -      const char *startp, *endp;
> -      char *nstore = (char *) alloca (strlen (temp) + 3);
> +      for_each_env_path (env.get (LIBRARY_PATH_ENV), add_startfile_prefix);
>
> -      startp = endp = temp;
> -      while (1)
> -       {
> -         if (*endp == PATH_SEPARATOR || *endp == 0)
> -           {
> -             strncpy (nstore, startp, endp - startp);
> -             if (endp == startp)
> -               strcpy (nstore, concat (".", dir_separator_str, NULL));
> -             else if (!IS_DIR_SEPARATOR (endp[-1]))
> -               {
> -                 nstore[endp - startp] = DIR_SEPARATOR;
> -                 nstore[endp - startp + 1] = 0;
> -               }
> -             else
> -               nstore[endp - startp] = 0;
> -             add_prefix (&startfile_prefixes, nstore, NULL,
> -                         PREFIX_PRIORITY_LAST, 0, 1);
> -             if (*endp == 0)
> -               break;
> -             endp = startp = endp + 1;
> -           }
> -         else
> -           endp++;
> -       }
> +      /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
> +      for_each_env_path (env.get ("LPATH"), add_startfile_prefix);
>      }
>
>    /* Process the options and store input files and switches in their
>
> base-commit: c31b7a09eea3c33bccca12bab4a7bb6b01da1ff6
> --
> 2.54.0
>

Reply via email to