Re: [PATCH 1/3] driver: Factor out environment variable path list parsing

Andrea Pinski <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <CALvbMcDiBnA5fE_iXsGkntK_WV-UaK7ncoXzsn_DBo0SfGHzOw@mail.gmail.com>
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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.