Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Sergio Durigan Junior <sergiodj@redhat.com>
To: Simon Marchi <simon.marchi@polymtl.ca>
Cc: GDB Patches <gdb-patches@sourceware.org>
Subject: Re: [PATCH v2] C++ify gdb/common/environ.c
Date: Tue, 18 Apr 2017 02:49:00 -0000	[thread overview]
Message-ID: <87o9vuh1ld.fsf@redhat.com> (raw)
In-Reply-To: <0a8a772222a48b2c16929100d1263566@polymtl.ca> (Simon Marchi's	message of "Sat, 15 Apr 2017 17:22:11 -0400")

Thanks for the review, Simon.  I don't know why I didn't receive this
message on my INBOX, so it took a little bit until I saw it on
gdb-patches.

On Saturday, April 15 2017, Simon Marchi wrote:

> On 2017-04-15 14:50, Sergio Durigan Junior wrote:
>> diff --git a/gdb/charset.c b/gdb/charset.c
>> index f55e482..a5ab383 100644
>> --- a/gdb/charset.c
>> +++ b/gdb/charset.c
>> @@ -794,16 +794,14 @@ find_charset_names (void)
>>    int err, status;
>>    int fail = 1;
>>    int flags;
>> -  struct gdb_environ *iconv_env;
>> +  std::unique_ptr<gdb_environ> iconv_env (new gdb_environ);
>
> Can it be allocated on the stack?

Yeah, it can.  It's probably an overkill to use a unique_ptr here
because the object will be short-lived anyway.  I'll change that.

>>  void
>> -set_in_environ (struct gdb_environ *e, const char *var, const char
>> *value)
>> +gdb_environ::set_in_environ (const char *var, const char *value)
>>  {
>> -  int i;
>> -  int len = strlen (var);
>> -  char **vector = e->vector;
>> -  char *s;
>> +  std::unordered_map<std::string, std::string>::iterator el;
>> +  bool needs_update = true;
>>
>> -  for (i = 0; (s = vector[i]) != NULL; i++)
>> -    if (strncmp (s, var, len) == 0 && s[len] == '=')
>> -      break;
>> +  el = this->env.find (var);
>>
>> -  if (s == 0)
>> +  if (el != this->env.end ())
>>      {
>> -      if (i == e->allocated)
>> +      if (el->second.compare (value) == 0)
>
> I think operator== will do what you want.

Good catch, thanks.

> If you did a return here, you wouldn't need the needs_update variable.
> I don't mind though, some people prefer a single return point.

No, you're totally right, I overlooked this detail.  Changed to a
return.

>> diff --git a/gdb/common/environ.h b/gdb/common/environ.h
>> index 3ace69e..c630425 100644
>> --- a/gdb/common/environ.h
>> +++ b/gdb/common/environ.h
>> @@ -17,33 +17,55 @@
>>  #if !defined (ENVIRON_H)
>>  #define ENVIRON_H 1
>>
>> -/* We manipulate environments represented as these structures.  */
>> +#include <unordered_map>
>> +#include <vector>
>
> In the interface of gdb_environ, I think you could get rid of the
> "environ" in method names.  You can also remove the (void) for methods
> without parameters.

Indeed, the "environ" in the names doesn't make sense anymore.

As for removing (void)...  I personally like to make it explicit, but I
understand we're living in other times now (C++11 and all).  I'll
remove.

>>
>> -struct gdb_environ
>> -  {
>> -    /* Number of usable slots allocated in VECTOR.
>> -       VECTOR always has one slot not counted here,
>> -       to hold the terminating zero.  */
>> -    int allocated;
>> -    /* A vector of slots, ALLOCATED + 1 of them.
>> -       The first few slots contain strings "VAR=VALUE"
>> -       and the next one contains zero.
>> -       Then come some unused slots.  */
>> -    char **vector;
>> -  };
>> +/* Class that represents the environment variables as seeing by the
>
> s/as seeing/as seen/

Fixed.

>> +   inferior.  */
>>
>> -extern struct gdb_environ *make_environ (void);
>> +class gdb_environ
>> +{
>> +public:
>> +  /* Regular constructor and destructor.  */
>> +  gdb_environ ();
>> +  ~gdb_environ ();
>>
>> -extern void free_environ (struct gdb_environ *);
>> +  /* Reinitialize the environment stored.  This is used when the user
>> +     wants to delete all environment variables added by him/her.  */
>> +  void reinit_environ (void);
>>
>> -extern void init_environ (struct gdb_environ *);
>> +  /* Return the value in the environment for the variable VAR.  */
>> +  char *get_in_environ (const char *var) const;
>
> Looking at the users, I think that this could return const char *.  It
> would also be good to mention that the pointer is valid as long as the
> corresponding variable environment is not removed/replaced.

Fair enough.  I constified the return type of the 'get' method, and
changed the callers accordingly.  I've also added the 

> It could also return something based on std::string, but I don't know
> how good it would be:
>
> 1. returning const std::string &: can't return "NULL".
> 2. returning gdb::optional<std::string>: it works but makes a copy of
> the string, maybe it's ok since there isn't a ton of that.  It would
> however make the return value usable even after the corresponding
> variable is removed from the env.
> 3. returning gdb::optional<const std::string &>: I don't think it can
> be done.
> 4. returning gdb::optional<std::reference_wrapper<const std::string>>:
> it works, but it gets a bit ugly.

Ahm, I'm not sure.  I mean, I know the rationale here (you're trying to
make sure that the return value only exists for as long as the
environment variable is there), but I don't think it's necessary to
overcomplicate things for now.  IMHO, a 'const char *' + the updated
comment are enough.

> One thing is sure, since you are constructing some std::string inside
> the methods, you could change the parameters in the interface from
> const char * to const std::string &.  With the implicit string
> constructor from const char *, the users won't have to be changed, but
> it will be possible to pass an std::string directly.

I confess this hasn't even crossed my mind.  Thanks, I adopted the idea.

>>
>> -extern char *get_in_environ (const struct gdb_environ *, const char
>> *);
>> +  /* Store VAR=VALUE in the environment.  */
>> +  void set_in_environ (const char *var, const char *value);
>>
>> -extern void set_in_environ (struct gdb_environ *, const char *,
>> const char *);
>> +  /* Unset VAR in environment.  */
>> +  void unset_in_environ (const char *var);
>>
>> -extern void unset_in_environ (struct gdb_environ *, const char *);
>> +  /* Return the environment vector represented as a 'char **'.  */
>> +  char **get_environ_char_vector (void) const;
>>
>> -extern char **environ_vector (struct gdb_environ *);
>> +  /* Return the environment vector.  */
>> +  std::vector<char *> get_environ_vector (void) const;
>
> Return a const reference, and change the (sole) user of this method to
> get a reference too?

Heh, I had done that before I got to this part of the e-mail.  Thanks.

>> @@ -2159,11 +2160,12 @@ environment_info (char *var, int from_tty)
>>      }
>>    else
>>      {
>> -      char **vector = environ_vector (current_inferior
>> ()->environment);
>> +      std::vector<char *> vector =
>> +	current_inferior ()->environment->get_environ_vector ();
>>
>> -      while (*vector)
>> +      for (char *&elem : vector)
>
> Is there advantage of doing
>
>   for (char *&elem : vector)
>
> vs
>
>   for (char *elem : vector)
>
> ?

No, this is just a brain fart.  I wrote this code when I was also
dealing with the fork-inferior sharing stuff, and you can see the same
pattern there.  Fixed.

>> diff --git a/gdb/inferior.h b/gdb/inferior.h
>> index b5eb3d1..e48d5cb 100644
>> --- a/gdb/inferior.h
>> +++ b/gdb/inferior.h
>> @@ -42,6 +42,9 @@ struct continuation;
>>  /* For struct frame_id.  */
>>  #include "frame.h"
>>
>> +/* For gdb_environ.  */
>> +#include "environ.h"
>> +
>
> You can remove the "struct gdb_environ;" above this.

Fixed.

>
>>  #include "progspace.h"
>>  #include "registry.h"
>>
>> @@ -362,7 +365,7 @@ public:
>>
>>    /* Environment to use for running inferior,
>>       in format described in environ.h.  */
>> -  gdb_environ *environment = NULL;
>> +  std::unique_ptr<gdb_environ> environment;
>
> Can this be simply
>
>   gdb_environ environment;
>
> ?
>
>> @@ -270,7 +270,7 @@ mi_cmd_inferior_tty_show (const char *command,
>> char **argv, int argc)
>>  void
>>  _initialize_mi_cmd_env (void)
>>  {
>> -  struct gdb_environ *environment;
>> +  std::unique_ptr<gdb_environ> environment (new gdb_environ);
>
> Again, can it be allocated on the stack?

Yes, already done that.  Thanks.

I'll send v3 soon.

-- 
Sergio
GPG key ID: 237A 54B1 0287 28BF 00EF  31F4 D0EB 7628 65FC 5E36
Please send encrypted e-mail if possible
http://sergiodj.net/


  reply	other threads:[~2017-04-18  2:49 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-13  4:05 [PATCH] " Sergio Durigan Junior
2017-04-15 18:51 ` [PATCH v2] " Sergio Durigan Junior
2017-04-15 21:22   ` Simon Marchi
2017-04-18  2:49     ` Sergio Durigan Junior [this message]
2017-04-16  5:09   ` Simon Marchi
2017-04-16 17:32     ` Sergio Durigan Junior
2017-04-18  3:03 ` [PATCH v3] " Sergio Durigan Junior
2017-04-19  4:56   ` Simon Marchi
2017-04-19 16:30     ` Pedro Alves
2017-04-19 18:14   ` Pedro Alves
2017-05-01  2:22     ` Sergio Durigan Junior
2017-05-04 15:30       ` Pedro Alves
2017-06-14 19:22 ` [PATCH v4] " Sergio Durigan Junior
2017-06-16 15:45   ` Pedro Alves
2017-06-16 18:01     ` Sergio Durigan Junior
2017-06-16 18:23       ` Pedro Alves
2017-06-16 21:59         ` Sergio Durigan Junior
2017-06-16 22:23 ` [PATCH v5] " Sergio Durigan Junior
2017-06-17  8:54   ` Simon Marchi
2017-06-19  4:19     ` Sergio Durigan Junior
2017-06-19 13:40       ` Pedro Alves
2017-06-19 16:19         ` Sergio Durigan Junior
2017-06-19 12:13     ` Pedro Alves
2017-06-20 14:02       ` Pedro Alves
2017-06-19  4:36 ` [PATCH v6] " Sergio Durigan Junior
2017-06-19  4:51   ` Sergio Durigan Junior
2017-06-19  7:18     ` Simon Marchi
2017-06-19 14:26       ` Pedro Alves
2017-06-19 15:30         ` Simon Marchi
2017-06-19 15:44           ` Pedro Alves
2017-06-19 15:47             ` Pedro Alves
2017-06-19 16:26             ` Simon Marchi
2017-06-19 16:55               ` Pedro Alves
2017-06-19 17:59                 ` Sergio Durigan Junior
2017-06-19 18:09                   ` Pedro Alves
2017-06-19 18:23                     ` Sergio Durigan Junior
2017-06-19 18:36                       ` Pedro Alves
2017-06-19 18:38                         ` Pedro Alves
2017-06-19 14:26   ` Pedro Alves
2017-06-19 16:13     ` Sergio Durigan Junior
2017-06-19 16:38       ` Pedro Alves
2017-06-19 16:46         ` Sergio Durigan Junior
2017-06-19 18:27 ` [PATCH v7] " Sergio Durigan Junior
2017-06-20  3:27 ` [PATCH v8] " Sergio Durigan Junior
2017-06-20 12:13   ` Pedro Alves
2017-06-20 12:46   ` Simon Marchi
2017-06-20 13:00     ` Sergio Durigan Junior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o9vuh1ld.fsf@redhat.com \
    --to=sergiodj@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=simon.marchi@polymtl.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox