public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Use for-each more in gdb
@ 2021-12-03 21:45 Tom Tromey
  2021-12-04  2:15 ` Simon Marchi
  0 siblings, 1 reply; 4+ messages in thread
From: Tom Tromey @ 2021-12-03 21:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

There are many loops in gdb that use ARRAY_SIZE (or a wordier
equivalent) to loop over a static array.  This patch changes some of
these to use foreach instead.  I didn't do every spot because many of
them are in tdep code; this is a subset that was relatively easy to
test.

Regression tested on x86-64 Fedora 34.
---
 gdb/ada-lang.c   | 22 ++++++++--------------
 gdb/bcache.c     |  8 ++++----
 gdb/c-exp.y      | 41 ++++++++++++++++++++---------------------
 gdb/cp-support.c |  4 ++--
 gdb/d-exp.y      | 25 ++++++++++++-------------
 gdb/f-exp.y      | 46 +++++++++++++++++++++++-----------------------
 gdb/go-exp.y     | 25 ++++++++++++-------------
 gdb/p-exp.y      | 20 ++++++++++----------
 gdb/rust-parse.c | 29 +++++++++++++----------------
 9 files changed, 104 insertions(+), 116 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index b84e10fd029..02e8fd5a1d8 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12203,7 +12203,6 @@ static std::string
 ada_exception_catchpoint_cond_string (const char *excep_string,
 				      enum ada_exception_catchpoint_kind ex)
 {
-  int i;
   bool is_standard_exc = false;
   std::string result;
 
@@ -12236,9 +12235,9 @@ ada_exception_catchpoint_cond_string (const char *excep_string,
      breakpoint condition is to use its fully-qualified named:
      e.g. my_package.constraint_error.  */
 
-  for (i = 0; i < sizeof (standard_exc) / sizeof (char *); i++)
+  for (const char *name : standard_exc)
     {
-      if (strcmp (standard_exc [i], excep_string) == 0)
+      if (strcmp (name, excep_string) == 0)
 	{
 	  is_standard_exc = true;
 	  break;
@@ -12468,13 +12467,11 @@ ada_is_exception_sym (struct symbol *sym)
 static int
 ada_is_non_standard_exception_sym (struct symbol *sym)
 {
-  int i;
-
   if (!ada_is_exception_sym (sym))
     return 0;
 
-  for (i = 0; i < ARRAY_SIZE (standard_exc); i++)
-    if (strcmp (sym->linkage_name (), standard_exc[i]) == 0)
+  for (const char *name : standard_exc)
+    if (strcmp (sym->linkage_name (), name) == 0)
       return 0;  /* A standard exception.  */
 
   /* Numeric_Error is also a standard exception, so exclude it.
@@ -12539,20 +12536,17 @@ static void
 ada_add_standard_exceptions (compiled_regex *preg,
 			     std::vector<ada_exc_info> *exceptions)
 {
-  int i;
-
-  for (i = 0; i < ARRAY_SIZE (standard_exc); i++)
+  for (const char *name : standard_exc)
     {
-      if (preg == NULL
-	  || preg->exec (standard_exc[i], 0, NULL, 0) == 0)
+      if (preg == NULL || preg->exec (name, 0, NULL, 0) == 0)
 	{
 	  struct bound_minimal_symbol msymbol
-	    = ada_lookup_simple_minsym (standard_exc[i]);
+	    = ada_lookup_simple_minsym (name);
 
 	  if (msymbol.minsym != NULL)
 	    {
 	      struct ada_exc_info info
-		= {standard_exc[i], BMSYMBOL_VALUE_ADDRESS (msymbol)};
+		= {name, BMSYMBOL_VALUE_ADDRESS (msymbol)};
 
 	      exceptions->push_back (info);
 	    }
diff --git a/gdb/bcache.c b/gdb/bcache.c
index b7be9676271..ae43853adaa 100644
--- a/gdb/bcache.c
+++ b/gdb/bcache.c
@@ -68,7 +68,7 @@ bcache::expand_hash_table ()
      so we roughly double the table size each time.  After we fall off 
      the end of this table, we just double.  Don't laugh --- there have
      been executables sighted with a gigabyte of debug info.  */
-  static unsigned long sizes[] = { 
+  static const unsigned long sizes[] = {
     1021, 2053, 4099, 8191, 16381, 32771,
     65537, 131071, 262144, 524287, 1048573, 2097143,
     4194301, 8388617, 16777213, 33554467, 67108859, 134217757,
@@ -85,10 +85,10 @@ bcache::expand_hash_table ()
 
   /* Find the next size.  */
   new_num_buckets = m_num_buckets * 2;
-  for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++)
-    if (sizes[i] > m_num_buckets)
+  for (unsigned long a_size : sizes)
+    if (a_size > m_num_buckets)
       {
-	new_num_buckets = sizes[i];
+	new_num_buckets = a_size;
 	break;
       }
 
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 9b4b88accfe..22cd50ab1e2 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -2644,7 +2644,6 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 {
   int c;
   int namelen;
-  unsigned int i;
   const char *tokstart;
   bool saw_structop = last_was_structop;
 
@@ -2667,33 +2666,33 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 
   tokstart = pstate->lexptr;
   /* See if it is a special token of length 3.  */
-  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
-    if (strncmp (tokstart, tokentab3[i].oper, 3) == 0)
+  for (const auto &token : tokentab3)
+    if (strncmp (tokstart, token.oper, 3) == 0)
       {
-	if ((tokentab3[i].flags & FLAG_CXX) != 0
+	if ((token.flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
-	gdb_assert ((tokentab3[i].flags & FLAG_C) == 0);
+	gdb_assert ((token.flags & FLAG_C) == 0);
 
 	pstate->lexptr += 3;
-	yylval.opcode = tokentab3[i].opcode;
-	return tokentab3[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   /* See if it is a special token of length 2.  */
-  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
-    if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
+  for (const auto &token : tokentab2)
+    if (strncmp (tokstart, token.oper, 2) == 0)
       {
-	if ((tokentab2[i].flags & FLAG_CXX) != 0
+	if ((token.flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
-	gdb_assert ((tokentab2[i].flags & FLAG_C) == 0);
+	gdb_assert ((token.flags & FLAG_C) == 0);
 
 	pstate->lexptr += 2;
-	yylval.opcode = tokentab2[i].opcode;
-	if (tokentab2[i].token == ARROW)
+	yylval.opcode = token.opcode;
+	if (token.token == ARROW)
 	  last_was_structop = 1;
-	return tokentab2[i].token;
+	return token.token;
       }
 
   switch (c = *tokstart)
@@ -2979,18 +2978,18 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 
   /* Catch specific keywords.  */
   std::string copy = copy_name (yylval.sval);
-  for (i = 0; i < sizeof ident_tokens / sizeof ident_tokens[0]; i++)
-    if (copy == ident_tokens[i].oper)
+  for (const auto &token : ident_tokens)
+    if (copy == token.oper)
       {
-	if ((ident_tokens[i].flags & FLAG_CXX) != 0
+	if ((token.flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
-	if ((ident_tokens[i].flags & FLAG_C) != 0
+	if ((token.flags & FLAG_C) != 0
 	    && par_state->language ()->la_language != language_c
 	    && par_state->language ()->la_language != language_objc)
 	  break;
 
-	if ((ident_tokens[i].flags & FLAG_SHADOW) != 0)
+	if ((token.flags & FLAG_SHADOW) != 0)
 	  {
 	    struct field_of_this_result is_a_field_of_this;
 
@@ -3009,8 +3008,8 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 
 	/* It is ok to always set this, even though we don't always
 	   strictly need to.  */
-	yylval.opcode = ident_tokens[i].opcode;
-	return ident_tokens[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   if (*tokstart == '$')
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 367fb6a20bb..0e506f5b46e 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -147,9 +147,9 @@ inspect_type (struct demangle_parse_info *info,
   name[ret_comp->u.s_name.len] = '\0';
 
   /* Ignore any typedefs that should not be substituted.  */
-  for (int i = 0; i < ARRAY_SIZE (ignore_typedefs); ++i)
+  for (const char *ignorable : ignore_typedefs)
     {
-      if (strcmp (name, ignore_typedefs[i]) == 0)
+      if (strcmp (name, ignorable) == 0)
 	return 0;
     }
 
diff --git a/gdb/d-exp.y b/gdb/d-exp.y
index 1d11d9f3569..637bc8cd7df 100644
--- a/gdb/d-exp.y
+++ b/gdb/d-exp.y
@@ -1027,7 +1027,6 @@ lex_one_token (struct parser_state *par_state)
 {
   int c;
   int namelen;
-  unsigned int i;
   const char *tokstart;
   int saw_structop = last_was_structop;
 
@@ -1039,21 +1038,21 @@ lex_one_token (struct parser_state *par_state)
 
   tokstart = pstate->lexptr;
   /* See if it is a special token of length 3.  */
-  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
-    if (strncmp (tokstart, tokentab3[i].oper, 3) == 0)
+  for (const auto &token : tokentab3)
+    if (strncmp (tokstart, token.oper, 3) == 0)
       {
 	pstate->lexptr += 3;
-	yylval.opcode = tokentab3[i].opcode;
-	return tokentab3[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   /* See if it is a special token of length 2.  */
-  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
-    if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
+  for (const auto &token : tokentab2)
+    if (strncmp (tokstart, token.oper, 2) == 0)
       {
 	pstate->lexptr += 2;
-	yylval.opcode = tokentab2[i].opcode;
-	return tokentab2[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   switch (c = *tokstart)
@@ -1274,13 +1273,13 @@ lex_one_token (struct parser_state *par_state)
 
   /* Catch specific keywords.  */
   std::string copy = copy_name (yylval.sval);
-  for (i = 0; i < sizeof ident_tokens / sizeof ident_tokens[0]; i++)
-    if (copy == ident_tokens[i].oper)
+  for (const auto &token : ident_tokens)
+    if (copy == token.oper)
       {
 	/* It is ok to always set this, even though we don't always
 	   strictly need to.  */
-	yylval.opcode = ident_tokens[i].opcode;
-	return ident_tokens[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   if (*tokstart == '$')
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 6608831a9a5..e0d576fe533 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -1269,27 +1269,27 @@ yylex (void)
 
   if (*pstate->lexptr == '.')
     {
-      for (int i = 0; i < ARRAY_SIZE (boolean_values); i++)
+      for (const auto &candidate : boolean_values)
 	{
-	  if (strncasecmp (tokstart, boolean_values[i].name,
-			   strlen (boolean_values[i].name)) == 0)
+	  if (strncasecmp (tokstart, candidate.name,
+			   strlen (candidate.name)) == 0)
 	    {
-	      pstate->lexptr += strlen (boolean_values[i].name);
-	      yylval.lval = boolean_values[i].value;
+	      pstate->lexptr += strlen (candidate.name);
+	      yylval.lval = candidate.value;
 	      return BOOLEAN_LITERAL;
 	    }
 	}
     }
 
   /* See if it is a Fortran operator.  */
-  for (int i = 0; i < ARRAY_SIZE (fortran_operators); i++)
-    if (strncasecmp (tokstart, fortran_operators[i].oper,
-		     strlen (fortran_operators[i].oper)) == 0)
+  for (const auto &candidate : fortran_operators)
+    if (strncasecmp (tokstart, candidate.oper,
+		     strlen (candidate.oper)) == 0)
       {
-	gdb_assert (!fortran_operators[i].case_sensitive);
-	pstate->lexptr += strlen (fortran_operators[i].oper);
-	yylval.opcode = fortran_operators[i].opcode;
-	return fortran_operators[i].token;
+	gdb_assert (!candidate.case_sensitive);
+	pstate->lexptr += strlen (candidate.oper);
+	yylval.opcode = candidate.opcode;
+	return candidate.token;
       }
 
   switch (c = *tokstart)
@@ -1452,15 +1452,15 @@ yylex (void)
   
   /* Catch specific keywords.  */
 
-  for (int i = 0; i < ARRAY_SIZE (f77_keywords); i++)
-    if (strlen (f77_keywords[i].oper) == namelen
-	&& ((!f77_keywords[i].case_sensitive
-	     && strncasecmp (tokstart, f77_keywords[i].oper, namelen) == 0)
-	    || (f77_keywords[i].case_sensitive
-		&& strncmp (tokstart, f77_keywords[i].oper, namelen) == 0)))
+  for (const auto &keyword : f77_keywords)
+    if (strlen (keyword.oper) == namelen
+	&& ((!keyword.case_sensitive
+	     && strncasecmp (tokstart, keyword.oper, namelen) == 0)
+	    || (keyword.case_sensitive
+		&& strncmp (tokstart, keyword.oper, namelen) == 0)))
       {
-	yylval.opcode = f77_keywords[i].opcode;
-	return f77_keywords[i].token;
+	yylval.opcode = keyword.opcode;
+	return keyword.token;
       }
 
   yylval.sval.ptr = tokstart;
@@ -1475,7 +1475,7 @@ yylex (void)
   {
     std::string tmp = copy_name (yylval.sval);
     struct block_symbol result;
-    enum domain_enum_tag lookup_domains[] =
+    const enum domain_enum_tag lookup_domains[] =
     {
       STRUCT_DOMAIN,
       VAR_DOMAIN,
@@ -1483,10 +1483,10 @@ yylex (void)
     };
     int hextype;
 
-    for (int i = 0; i < ARRAY_SIZE (lookup_domains); ++i)
+    for (const auto &domain : lookup_domains)
       {
 	result = lookup_symbol (tmp.c_str (), pstate->expression_context_block,
-				lookup_domains[i], NULL);
+				domain, NULL);
 	if (result.symbol && SYMBOL_CLASS (result.symbol) == LOC_TYPEDEF)
 	  {
 	    yylval.tsym.type = SYMBOL_TYPE (result.symbol);
diff --git a/gdb/go-exp.y b/gdb/go-exp.y
index aaa65170a03..209e0a756b3 100644
--- a/gdb/go-exp.y
+++ b/gdb/go-exp.y
@@ -1018,7 +1018,6 @@ lex_one_token (struct parser_state *par_state)
 {
   int c;
   int namelen;
-  unsigned int i;
   const char *tokstart;
   int saw_structop = last_was_structop;
 
@@ -1030,23 +1029,23 @@ lex_one_token (struct parser_state *par_state)
 
   tokstart = par_state->lexptr;
   /* See if it is a special token of length 3.  */
-  for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
-    if (strncmp (tokstart, tokentab3[i].oper, 3) == 0)
+  for (const auto &token : tokentab3)
+    if (strncmp (tokstart, token.oper, 3) == 0)
       {
 	par_state->lexptr += 3;
-	yylval.opcode = tokentab3[i].opcode;
-	return tokentab3[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   /* See if it is a special token of length 2.  */
-  for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
-    if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
+  for (const auto &token : tokentab2)
+    if (strncmp (tokstart, token.oper, 2) == 0)
       {
 	par_state->lexptr += 2;
-	yylval.opcode = tokentab2[i].opcode;
+	yylval.opcode = token.opcode;
 	/* NOTE: -> doesn't exist in Go, so we don't need to watch for
 	   setting last_was_structop here.  */
-	return tokentab2[i].token;
+	return token.token;
       }
 
   switch (c = *tokstart)
@@ -1270,13 +1269,13 @@ lex_one_token (struct parser_state *par_state)
 
   /* Catch specific keywords.  */
   std::string copy = copy_name (yylval.sval);
-  for (i = 0; i < sizeof (ident_tokens) / sizeof (ident_tokens[0]); i++)
-    if (copy == ident_tokens[i].oper)
+  for (const auto &token : ident_tokens)
+    if (copy == token.oper)
       {
 	/* It is ok to always set this, even though we don't always
 	   strictly need to.  */
-	yylval.opcode = ident_tokens[i].opcode;
-	return ident_tokens[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   if (*tokstart == '$')
diff --git a/gdb/p-exp.y b/gdb/p-exp.y
index f496ce2016e..e9ebf1fa614 100644
--- a/gdb/p-exp.y
+++ b/gdb/p-exp.y
@@ -1107,28 +1107,28 @@ yylex (void)
 
   /* See if it is a special token of length 3.  */
   if (explen > 2)
-    for (int i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
-      if (strncasecmp (tokstart, tokentab3[i].oper, 3) == 0
-	  && (!isalpha (tokentab3[i].oper[0]) || explen == 3
+    for (const auto &token : tokentab3)
+      if (strncasecmp (tokstart, token.oper, 3) == 0
+	  && (!isalpha (token.oper[0]) || explen == 3
 	      || (!isalpha (tokstart[3])
 		  && !isdigit (tokstart[3]) && tokstart[3] != '_')))
 	{
 	  pstate->lexptr += 3;
-	  yylval.opcode = tokentab3[i].opcode;
-	  return tokentab3[i].token;
+	  yylval.opcode = token.opcode;
+	  return token.token;
 	}
 
   /* See if it is a special token of length 2.  */
   if (explen > 1)
-  for (int i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
-      if (strncasecmp (tokstart, tokentab2[i].oper, 2) == 0
-	  && (!isalpha (tokentab2[i].oper[0]) || explen == 2
+    for (const auto &token : tokentab2)
+      if (strncasecmp (tokstart, token.oper, 2) == 0
+	  && (!isalpha (token.oper[0]) || explen == 2
 	      || (!isalpha (tokstart[2])
 		  && !isdigit (tokstart[2]) && tokstart[2] != '_')))
 	{
 	  pstate->lexptr += 2;
-	  yylval.opcode = tokentab2[i].opcode;
-	  return tokentab2[i].token;
+	  yylval.opcode = token.opcode;
+	  return token.token;
 	}
 
   switch (c = *tokstart)
diff --git a/gdb/rust-parse.c b/gdb/rust-parse.c
index e12bf29a71d..89bfdc6a4b3 100644
--- a/gdb/rust-parse.c
+++ b/gdb/rust-parse.c
@@ -787,12 +787,12 @@ rust_parser::lex_identifier ()
   token = NULL;
   if (!is_raw)
     {
-      for (i = 0; i < ARRAY_SIZE (identifier_tokens); ++i)
+      for (const auto &candidate : identifier_tokens)
 	{
-	  if (length == strlen (identifier_tokens[i].name)
-	      && strncmp (identifier_tokens[i].name, start, length) == 0)
+	  if (length == strlen (candidate.name)
+	      && strncmp (candidate.name, start, length) == 0)
 	    {
-	      token = &identifier_tokens[i];
+	      token = &candidate;
 	      break;
 	    }
 	}
@@ -845,15 +845,14 @@ int
 rust_parser::lex_operator ()
 {
   const struct token_info *token = NULL;
-  int i;
 
-  for (i = 0; i < ARRAY_SIZE (operator_tokens); ++i)
+  for (const auto &candidate : operator_tokens)
     {
-      if (strncmp (operator_tokens[i].name, pstate->lexptr,
-		   strlen (operator_tokens[i].name)) == 0)
+      if (strncmp (candidate.name, pstate->lexptr,
+		   strlen (candidate.name)) == 0)
 	{
-	  pstate->lexptr += strlen (operator_tokens[i].name);
-	  token = &operator_tokens[i];
+	  pstate->lexptr += strlen (candidate.name);
+	  token = &candidate;
 	  break;
 	}
     }
@@ -2342,13 +2341,11 @@ rust_lex_tests (void)
   rust_lex_stringish_test (&parser, "br####\"\\x73tring\"####", "\\x73tring",
 			   BYTESTRING);
 
-  for (i = 0; i < ARRAY_SIZE (identifier_tokens); ++i)
-    rust_lex_test_one (&parser, identifier_tokens[i].name,
-		       identifier_tokens[i].value);
+  for (const auto &candidate : identifier_tokens)
+    rust_lex_test_one (&parser, candidate.name, candidate.value);
 
-  for (i = 0; i < ARRAY_SIZE (operator_tokens); ++i)
-    rust_lex_test_one (&parser, operator_tokens[i].name,
-		       operator_tokens[i].value);
+  for (const auto &candidate : operator_tokens)
+    rust_lex_test_one (&parser, candidate.name, candidate.value);
 
   rust_lex_test_completion (&parser);
   rust_lex_test_push_back (&parser);
-- 
2.31.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Use for-each more in gdb
  2021-12-03 21:45 [PATCH] Use for-each more in gdb Tom Tromey
@ 2021-12-04  2:15 ` Simon Marchi
  2021-12-07  4:23   ` Tom Tromey
  0 siblings, 1 reply; 4+ messages in thread
From: Simon Marchi @ 2021-12-04  2:15 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches



On 2021-12-03 16:45, Tom Tromey wrote:
> There are many loops in gdb that use ARRAY_SIZE (or a wordier
> equivalent) to loop over a static array.  This patch changes some of
> these to use foreach instead.  I didn't do every spot because many of
> them are in tdep code; this is a subset that was relatively easy to
> test.
> 
> Regression tested on x86-64 Fedora 34.

Thanks, I think that looks good.  I think you could do the ones in the
tdep files if you'd like.  At least you can build-test it, and there is
a relatively low risk of breaking something.

Simon

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Use for-each more in gdb
  2021-12-04  2:15 ` Simon Marchi
@ 2021-12-07  4:23   ` Tom Tromey
  2021-12-07 15:32     ` Simon Marchi
  0 siblings, 1 reply; 4+ messages in thread
From: Tom Tromey @ 2021-12-07  4:23 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches

Simon> Thanks, I think that looks good.  I think you could do the ones in the
Simon> tdep files if you'd like.  At least you can build-test it, and there is
Simon> a relatively low risk of breaking something.

I looked and there aren't many worth doing, as it turns out.  I'm still
on the fence about it, it doesn't seem super important.  I did fine one
other non-tdep spot that could be changed, though.  What do you think of
the appended?

Tom

commit 6a10255f9816b038be5eeaefcc0b9a13464974b1
Author: Tom Tromey <tom@tromey.com>
Date:   Fri Dec 3 14:45:37 2021 -0700

    Use for-each more in gdb
    
    There are some loops in gdb that use ARRAY_SIZE (or a wordier
    equivalent) to loop over a static array.  This patch changes some of
    these to use foreach instead.
    
    Regression tested on x86-64 Fedora 34.

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index f8ba05b4276..1a6b5d81d45 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12200,7 +12200,6 @@ static std::string
 ada_exception_catchpoint_cond_string (const char *excep_string,
 				      enum ada_exception_catchpoint_kind ex)
 {
-  int i;
   bool is_standard_exc = false;
   std::string result;
 
@@ -12233,9 +12232,9 @@ ada_exception_catchpoint_cond_string (const char *excep_string,
      breakpoint condition is to use its fully-qualified named:
      e.g. my_package.constraint_error.  */
 
-  for (i = 0; i < sizeof (standard_exc) / sizeof (char *); i++)
+  for (const char *name : standard_exc)
     {
-      if (strcmp (standard_exc [i], excep_string) == 0)
+      if (strcmp (name, excep_string) == 0)
 	{
 	  is_standard_exc = true;
 	  break;
@@ -12465,13 +12464,11 @@ ada_is_exception_sym (struct symbol *sym)
 static int
 ada_is_non_standard_exception_sym (struct symbol *sym)
 {
-  int i;
-
   if (!ada_is_exception_sym (sym))
     return 0;
 
-  for (i = 0; i < ARRAY_SIZE (standard_exc); i++)
-    if (strcmp (sym->linkage_name (), standard_exc[i]) == 0)
+  for (const char *name : standard_exc)
+    if (strcmp (sym->linkage_name (), name) == 0)
       return 0;  /* A standard exception.  */
 
   /* Numeric_Error is also a standard exception, so exclude it.
@@ -12536,20 +12533,17 @@ static void
 ada_add_standard_exceptions (compiled_regex *preg,
 			     std::vector<ada_exc_info> *exceptions)
 {
-  int i;
-
-  for (i = 0; i < ARRAY_SIZE (standard_exc); i++)
+  for (const char *name : standard_exc)
     {
-      if (preg == NULL
-	  || preg->exec (standard_exc[i], 0, NULL, 0) == 0)
+      if (preg == NULL || preg->exec (name, 0, NULL, 0) == 0)
 	{
 	  struct bound_minimal_symbol msymbol
-	    = ada_lookup_simple_minsym (standard_exc[i]);
+	    = ada_lookup_simple_minsym (name);
 
 	  if (msymbol.minsym != NULL)
 	    {
 	      struct ada_exc_info info
-		= {standard_exc[i], BMSYMBOL_VALUE_ADDRESS (msymbol)};
+		= {name, BMSYMBOL_VALUE_ADDRESS (msymbol)};
 
 	      exceptions->push_back (info);
 	    }
diff --git a/gdb/bcache.c b/gdb/bcache.c
index b7be9676271..ae43853adaa 100644
--- a/gdb/bcache.c
+++ b/gdb/bcache.c
@@ -68,7 +68,7 @@ bcache::expand_hash_table ()
      so we roughly double the table size each time.  After we fall off 
      the end of this table, we just double.  Don't laugh --- there have
      been executables sighted with a gigabyte of debug info.  */
-  static unsigned long sizes[] = { 
+  static const unsigned long sizes[] = {
     1021, 2053, 4099, 8191, 16381, 32771,
     65537, 131071, 262144, 524287, 1048573, 2097143,
     4194301, 8388617, 16777213, 33554467, 67108859, 134217757,
@@ -85,10 +85,10 @@ bcache::expand_hash_table ()
 
   /* Find the next size.  */
   new_num_buckets = m_num_buckets * 2;
-  for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++)
-    if (sizes[i] > m_num_buckets)
+  for (unsigned long a_size : sizes)
+    if (a_size > m_num_buckets)
       {
-	new_num_buckets = sizes[i];
+	new_num_buckets = a_size;
 	break;
       }
 
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 9b4b88accfe..22cd50ab1e2 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -2644,7 +2644,6 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 {
   int c;
   int namelen;
-  unsigned int i;
   const char *tokstart;
   bool saw_structop = last_was_structop;
 
@@ -2667,33 +2666,33 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 
   tokstart = pstate->lexptr;
   /* See if it is a special token of length 3.  */
-  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
-    if (strncmp (tokstart, tokentab3[i].oper, 3) == 0)
+  for (const auto &token : tokentab3)
+    if (strncmp (tokstart, token.oper, 3) == 0)
       {
-	if ((tokentab3[i].flags & FLAG_CXX) != 0
+	if ((token.flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
-	gdb_assert ((tokentab3[i].flags & FLAG_C) == 0);
+	gdb_assert ((token.flags & FLAG_C) == 0);
 
 	pstate->lexptr += 3;
-	yylval.opcode = tokentab3[i].opcode;
-	return tokentab3[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   /* See if it is a special token of length 2.  */
-  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
-    if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
+  for (const auto &token : tokentab2)
+    if (strncmp (tokstart, token.oper, 2) == 0)
       {
-	if ((tokentab2[i].flags & FLAG_CXX) != 0
+	if ((token.flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
-	gdb_assert ((tokentab2[i].flags & FLAG_C) == 0);
+	gdb_assert ((token.flags & FLAG_C) == 0);
 
 	pstate->lexptr += 2;
-	yylval.opcode = tokentab2[i].opcode;
-	if (tokentab2[i].token == ARROW)
+	yylval.opcode = token.opcode;
+	if (token.token == ARROW)
 	  last_was_structop = 1;
-	return tokentab2[i].token;
+	return token.token;
       }
 
   switch (c = *tokstart)
@@ -2979,18 +2978,18 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 
   /* Catch specific keywords.  */
   std::string copy = copy_name (yylval.sval);
-  for (i = 0; i < sizeof ident_tokens / sizeof ident_tokens[0]; i++)
-    if (copy == ident_tokens[i].oper)
+  for (const auto &token : ident_tokens)
+    if (copy == token.oper)
       {
-	if ((ident_tokens[i].flags & FLAG_CXX) != 0
+	if ((token.flags & FLAG_CXX) != 0
 	    && par_state->language ()->la_language != language_cplus)
 	  break;
-	if ((ident_tokens[i].flags & FLAG_C) != 0
+	if ((token.flags & FLAG_C) != 0
 	    && par_state->language ()->la_language != language_c
 	    && par_state->language ()->la_language != language_objc)
 	  break;
 
-	if ((ident_tokens[i].flags & FLAG_SHADOW) != 0)
+	if ((token.flags & FLAG_SHADOW) != 0)
 	  {
 	    struct field_of_this_result is_a_field_of_this;
 
@@ -3009,8 +3008,8 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
 
 	/* It is ok to always set this, even though we don't always
 	   strictly need to.  */
-	yylval.opcode = ident_tokens[i].opcode;
-	return ident_tokens[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   if (*tokstart == '$')
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 367fb6a20bb..0e506f5b46e 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -147,9 +147,9 @@ inspect_type (struct demangle_parse_info *info,
   name[ret_comp->u.s_name.len] = '\0';
 
   /* Ignore any typedefs that should not be substituted.  */
-  for (int i = 0; i < ARRAY_SIZE (ignore_typedefs); ++i)
+  for (const char *ignorable : ignore_typedefs)
     {
-      if (strcmp (name, ignore_typedefs[i]) == 0)
+      if (strcmp (name, ignorable) == 0)
 	return 0;
     }
 
diff --git a/gdb/d-exp.y b/gdb/d-exp.y
index 1d11d9f3569..637bc8cd7df 100644
--- a/gdb/d-exp.y
+++ b/gdb/d-exp.y
@@ -1027,7 +1027,6 @@ lex_one_token (struct parser_state *par_state)
 {
   int c;
   int namelen;
-  unsigned int i;
   const char *tokstart;
   int saw_structop = last_was_structop;
 
@@ -1039,21 +1038,21 @@ lex_one_token (struct parser_state *par_state)
 
   tokstart = pstate->lexptr;
   /* See if it is a special token of length 3.  */
-  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
-    if (strncmp (tokstart, tokentab3[i].oper, 3) == 0)
+  for (const auto &token : tokentab3)
+    if (strncmp (tokstart, token.oper, 3) == 0)
       {
 	pstate->lexptr += 3;
-	yylval.opcode = tokentab3[i].opcode;
-	return tokentab3[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   /* See if it is a special token of length 2.  */
-  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
-    if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
+  for (const auto &token : tokentab2)
+    if (strncmp (tokstart, token.oper, 2) == 0)
       {
 	pstate->lexptr += 2;
-	yylval.opcode = tokentab2[i].opcode;
-	return tokentab2[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   switch (c = *tokstart)
@@ -1274,13 +1273,13 @@ lex_one_token (struct parser_state *par_state)
 
   /* Catch specific keywords.  */
   std::string copy = copy_name (yylval.sval);
-  for (i = 0; i < sizeof ident_tokens / sizeof ident_tokens[0]; i++)
-    if (copy == ident_tokens[i].oper)
+  for (const auto &token : ident_tokens)
+    if (copy == token.oper)
       {
 	/* It is ok to always set this, even though we don't always
 	   strictly need to.  */
-	yylval.opcode = ident_tokens[i].opcode;
-	return ident_tokens[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   if (*tokstart == '$')
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 6608831a9a5..e0d576fe533 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -1269,27 +1269,27 @@ yylex (void)
 
   if (*pstate->lexptr == '.')
     {
-      for (int i = 0; i < ARRAY_SIZE (boolean_values); i++)
+      for (const auto &candidate : boolean_values)
 	{
-	  if (strncasecmp (tokstart, boolean_values[i].name,
-			   strlen (boolean_values[i].name)) == 0)
+	  if (strncasecmp (tokstart, candidate.name,
+			   strlen (candidate.name)) == 0)
 	    {
-	      pstate->lexptr += strlen (boolean_values[i].name);
-	      yylval.lval = boolean_values[i].value;
+	      pstate->lexptr += strlen (candidate.name);
+	      yylval.lval = candidate.value;
 	      return BOOLEAN_LITERAL;
 	    }
 	}
     }
 
   /* See if it is a Fortran operator.  */
-  for (int i = 0; i < ARRAY_SIZE (fortran_operators); i++)
-    if (strncasecmp (tokstart, fortran_operators[i].oper,
-		     strlen (fortran_operators[i].oper)) == 0)
+  for (const auto &candidate : fortran_operators)
+    if (strncasecmp (tokstart, candidate.oper,
+		     strlen (candidate.oper)) == 0)
       {
-	gdb_assert (!fortran_operators[i].case_sensitive);
-	pstate->lexptr += strlen (fortran_operators[i].oper);
-	yylval.opcode = fortran_operators[i].opcode;
-	return fortran_operators[i].token;
+	gdb_assert (!candidate.case_sensitive);
+	pstate->lexptr += strlen (candidate.oper);
+	yylval.opcode = candidate.opcode;
+	return candidate.token;
       }
 
   switch (c = *tokstart)
@@ -1452,15 +1452,15 @@ yylex (void)
   
   /* Catch specific keywords.  */
 
-  for (int i = 0; i < ARRAY_SIZE (f77_keywords); i++)
-    if (strlen (f77_keywords[i].oper) == namelen
-	&& ((!f77_keywords[i].case_sensitive
-	     && strncasecmp (tokstart, f77_keywords[i].oper, namelen) == 0)
-	    || (f77_keywords[i].case_sensitive
-		&& strncmp (tokstart, f77_keywords[i].oper, namelen) == 0)))
+  for (const auto &keyword : f77_keywords)
+    if (strlen (keyword.oper) == namelen
+	&& ((!keyword.case_sensitive
+	     && strncasecmp (tokstart, keyword.oper, namelen) == 0)
+	    || (keyword.case_sensitive
+		&& strncmp (tokstart, keyword.oper, namelen) == 0)))
       {
-	yylval.opcode = f77_keywords[i].opcode;
-	return f77_keywords[i].token;
+	yylval.opcode = keyword.opcode;
+	return keyword.token;
       }
 
   yylval.sval.ptr = tokstart;
@@ -1475,7 +1475,7 @@ yylex (void)
   {
     std::string tmp = copy_name (yylval.sval);
     struct block_symbol result;
-    enum domain_enum_tag lookup_domains[] =
+    const enum domain_enum_tag lookup_domains[] =
     {
       STRUCT_DOMAIN,
       VAR_DOMAIN,
@@ -1483,10 +1483,10 @@ yylex (void)
     };
     int hextype;
 
-    for (int i = 0; i < ARRAY_SIZE (lookup_domains); ++i)
+    for (const auto &domain : lookup_domains)
       {
 	result = lookup_symbol (tmp.c_str (), pstate->expression_context_block,
-				lookup_domains[i], NULL);
+				domain, NULL);
 	if (result.symbol && SYMBOL_CLASS (result.symbol) == LOC_TYPEDEF)
 	  {
 	    yylval.tsym.type = SYMBOL_TYPE (result.symbol);
diff --git a/gdb/go-exp.y b/gdb/go-exp.y
index aaa65170a03..209e0a756b3 100644
--- a/gdb/go-exp.y
+++ b/gdb/go-exp.y
@@ -1018,7 +1018,6 @@ lex_one_token (struct parser_state *par_state)
 {
   int c;
   int namelen;
-  unsigned int i;
   const char *tokstart;
   int saw_structop = last_was_structop;
 
@@ -1030,23 +1029,23 @@ lex_one_token (struct parser_state *par_state)
 
   tokstart = par_state->lexptr;
   /* See if it is a special token of length 3.  */
-  for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
-    if (strncmp (tokstart, tokentab3[i].oper, 3) == 0)
+  for (const auto &token : tokentab3)
+    if (strncmp (tokstart, token.oper, 3) == 0)
       {
 	par_state->lexptr += 3;
-	yylval.opcode = tokentab3[i].opcode;
-	return tokentab3[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   /* See if it is a special token of length 2.  */
-  for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
-    if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
+  for (const auto &token : tokentab2)
+    if (strncmp (tokstart, token.oper, 2) == 0)
       {
 	par_state->lexptr += 2;
-	yylval.opcode = tokentab2[i].opcode;
+	yylval.opcode = token.opcode;
 	/* NOTE: -> doesn't exist in Go, so we don't need to watch for
 	   setting last_was_structop here.  */
-	return tokentab2[i].token;
+	return token.token;
       }
 
   switch (c = *tokstart)
@@ -1270,13 +1269,13 @@ lex_one_token (struct parser_state *par_state)
 
   /* Catch specific keywords.  */
   std::string copy = copy_name (yylval.sval);
-  for (i = 0; i < sizeof (ident_tokens) / sizeof (ident_tokens[0]); i++)
-    if (copy == ident_tokens[i].oper)
+  for (const auto &token : ident_tokens)
+    if (copy == token.oper)
       {
 	/* It is ok to always set this, even though we don't always
 	   strictly need to.  */
-	yylval.opcode = ident_tokens[i].opcode;
-	return ident_tokens[i].token;
+	yylval.opcode = token.opcode;
+	return token.token;
       }
 
   if (*tokstart == '$')
diff --git a/gdb/p-exp.y b/gdb/p-exp.y
index f496ce2016e..e9ebf1fa614 100644
--- a/gdb/p-exp.y
+++ b/gdb/p-exp.y
@@ -1107,28 +1107,28 @@ yylex (void)
 
   /* See if it is a special token of length 3.  */
   if (explen > 2)
-    for (int i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
-      if (strncasecmp (tokstart, tokentab3[i].oper, 3) == 0
-	  && (!isalpha (tokentab3[i].oper[0]) || explen == 3
+    for (const auto &token : tokentab3)
+      if (strncasecmp (tokstart, token.oper, 3) == 0
+	  && (!isalpha (token.oper[0]) || explen == 3
 	      || (!isalpha (tokstart[3])
 		  && !isdigit (tokstart[3]) && tokstart[3] != '_')))
 	{
 	  pstate->lexptr += 3;
-	  yylval.opcode = tokentab3[i].opcode;
-	  return tokentab3[i].token;
+	  yylval.opcode = token.opcode;
+	  return token.token;
 	}
 
   /* See if it is a special token of length 2.  */
   if (explen > 1)
-  for (int i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
-      if (strncasecmp (tokstart, tokentab2[i].oper, 2) == 0
-	  && (!isalpha (tokentab2[i].oper[0]) || explen == 2
+    for (const auto &token : tokentab2)
+      if (strncasecmp (tokstart, token.oper, 2) == 0
+	  && (!isalpha (token.oper[0]) || explen == 2
 	      || (!isalpha (tokstart[2])
 		  && !isdigit (tokstart[2]) && tokstart[2] != '_')))
 	{
 	  pstate->lexptr += 2;
-	  yylval.opcode = tokentab2[i].opcode;
-	  return tokentab2[i].token;
+	  yylval.opcode = token.opcode;
+	  return token.token;
 	}
 
   switch (c = *tokstart)
diff --git a/gdb/rust-parse.c b/gdb/rust-parse.c
index e12bf29a71d..82ee382c2e3 100644
--- a/gdb/rust-parse.c
+++ b/gdb/rust-parse.c
@@ -756,7 +756,6 @@ rust_parser::lex_identifier ()
 {
   unsigned int length;
   const struct token_info *token;
-  int i;
   int is_gdb_var = pstate->lexptr[0] == '$';
 
   bool is_raw = false;
@@ -787,12 +786,12 @@ rust_parser::lex_identifier ()
   token = NULL;
   if (!is_raw)
     {
-      for (i = 0; i < ARRAY_SIZE (identifier_tokens); ++i)
+      for (const auto &candidate : identifier_tokens)
 	{
-	  if (length == strlen (identifier_tokens[i].name)
-	      && strncmp (identifier_tokens[i].name, start, length) == 0)
+	  if (length == strlen (candidate.name)
+	      && strncmp (candidate.name, start, length) == 0)
 	    {
-	      token = &identifier_tokens[i];
+	      token = &candidate;
 	      break;
 	    }
 	}
@@ -845,15 +844,14 @@ int
 rust_parser::lex_operator ()
 {
   const struct token_info *token = NULL;
-  int i;
 
-  for (i = 0; i < ARRAY_SIZE (operator_tokens); ++i)
+  for (const auto &candidate : operator_tokens)
     {
-      if (strncmp (operator_tokens[i].name, pstate->lexptr,
-		   strlen (operator_tokens[i].name)) == 0)
+      if (strncmp (candidate.name, pstate->lexptr,
+		   strlen (candidate.name)) == 0)
 	{
-	  pstate->lexptr += strlen (operator_tokens[i].name);
-	  token = &operator_tokens[i];
+	  pstate->lexptr += strlen (candidate.name);
+	  token = &candidate;
 	  break;
 	}
     }
@@ -2246,8 +2244,6 @@ rust_lex_test_push_back (rust_parser *parser)
 static void
 rust_lex_tests (void)
 {
-  int i;
-
   /* Set up dummy "parser", so that rust_type works.  */
   struct parser_state ps (language_def (language_rust), target_gdbarch (),
 			  nullptr, 0, 0, nullptr, 0, nullptr, false);
@@ -2342,13 +2338,11 @@ rust_lex_tests (void)
   rust_lex_stringish_test (&parser, "br####\"\\x73tring\"####", "\\x73tring",
 			   BYTESTRING);
 
-  for (i = 0; i < ARRAY_SIZE (identifier_tokens); ++i)
-    rust_lex_test_one (&parser, identifier_tokens[i].name,
-		       identifier_tokens[i].value);
+  for (const auto &candidate : identifier_tokens)
+    rust_lex_test_one (&parser, candidate.name, candidate.value);
 
-  for (i = 0; i < ARRAY_SIZE (operator_tokens); ++i)
-    rust_lex_test_one (&parser, operator_tokens[i].name,
-		       operator_tokens[i].value);
+  for (const auto &candidate : operator_tokens)
+    rust_lex_test_one (&parser, candidate.name, candidate.value);
 
   rust_lex_test_completion (&parser);
   rust_lex_test_push_back (&parser);
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 3f2eb64a7c4..c0820caec29 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -6370,13 +6370,12 @@ producer_is_realview (const char *producer)
     "ARM/Thumb C/C++ Compiler, RVCT",
     "ARM C/C++ Compiler, RVCT"
   };
-  int i;
 
   if (producer == NULL)
     return false;
 
-  for (i = 0; i < ARRAY_SIZE (arm_idents); i++)
-    if (startswith (producer, arm_idents[i]))
+  for (const char *ident : arm_idents)
+    if (startswith (producer, ident))
       return true;
 
   return false;

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Use for-each more in gdb
  2021-12-07  4:23   ` Tom Tromey
@ 2021-12-07 15:32     ` Simon Marchi
  0 siblings, 0 replies; 4+ messages in thread
From: Simon Marchi @ 2021-12-07 15:32 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On 2021-12-06 11:23 p.m., Tom Tromey wrote:
> Simon> Thanks, I think that looks good.  I think you could do the ones in the
> Simon> tdep files if you'd like.  At least you can build-test it, and there is
> Simon> a relatively low risk of breaking something.
> 
> I looked and there aren't many worth doing, as it turns out.  I'm still
> on the fence about it, it doesn't seem super important.  I did fine one
> other non-tdep spot that could be changed, though.  What do you think of
> the appended?
> 
> Tom

Yes, thanks.

Simon


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-12-07 15:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-03 21:45 [PATCH] Use for-each more in gdb Tom Tromey
2021-12-04  2:15 ` Simon Marchi
2021-12-07  4:23   ` Tom Tromey
2021-12-07 15:32     ` Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).