public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PCH] driver, documentation
@ 2002-08-17 20:33 Geoffrey Keating
  2002-08-17 21:23 ` Daniel Jacobowitz
                   ` (6 more replies)
  0 siblings, 7 replies; 19+ messages in thread
From: Geoffrey Keating @ 2002-08-17 20:33 UTC (permalink / raw)
  To: gcc-patches


This patch starts PCH support.  It adds support in the driver for
compiling headers, and documents how the PCH support will work.

Bootstrapped & tested on x86-linux.

-- 
Geoff Keating <geoffk@redhat.com>

===File ~/patches/pchbranch-driver.patch====================
Index: ChangeLog
2002-08-17  Geoffrey Keating  <geoffk@redhat.com>

	* c-common.c: (pch_file): Define.
	* c-common.h (pch_file): Declare.
	* c-opts.c (COMMAND_LINE_OPTIONS): Add --output-pch=.
	(missing_arg): Require --output-pch= to have an argument.
	(c_common_decode_option): Handle --output-pch=.
	* gcc.c: Document new %V.
	(default_compilers): Handle compiling C header files.
	(do_spec_1): Implement %V.
	(main): Handle "gcc foo.h" without trying to run linker.
	* doc/invoke.texi (Invoking GCC): Add new menu item for PCH.
	(Overall Options): Document what the driver does with header files,
	document new -x option possibilities.
	(Invoking G++): More documentation for PCH.
	(Precompiled Headers): New.

Index: cp/ChangeLog
2002-08-17  Geoffrey Keating  <geoffk@redhat.com>

	* g++spec.c (lang_specific_driver): Treat .h files as C++ header
	files when using g++.
	* lang-specs.h: Handle compiling C++ header files.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.286.4.11
diff -p -u -p -r1.286.4.11 c-common.c
--- c-common.c	13 Aug 2002 17:56:13 -0000	1.286.4.11
+++ c-common.c	18 Aug 2002 00:21:06 -0000
@@ -197,6 +197,11 @@ tree c_global_trees[CTI_MAX];
 /* Nonzero if prepreprocessing only.  */
 int flag_preprocess_only;
 
+/* The filename to which we should write a precompiled header, or
+   NULL if no header will be written in this compile.  */
+
+const char *pch_file;
+
 /* Nonzero if an ISO standard was selected.  It rejects macros in the
    user's namespace.  */
 int flag_iso;
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.112.4.12
diff -p -u -p -r1.112.4.12 c-common.h
--- c-common.h	13 Aug 2002 17:56:13 -0000	1.112.4.12
+++ c-common.h	18 Aug 2002 00:21:06 -0000
@@ -373,6 +373,11 @@ extern c_language_kind c_language;
 /* Nonzero if prepreprocessing only.  */
 extern int flag_preprocess_only;
 
+/* The filename to which we should write a precompiled header, or
+   NULL if no header will be written in this compile.  */
+
+extern const char *pch_file;
+
 /* Nonzero if an ISO standard was selected.  It rejects macros in the
    user's namespace.  */
 extern int flag_iso;
Index: c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.10.2.1
diff -p -u -p -r1.10.2.1 c-opts.c
--- c-opts.c	13 Aug 2002 17:56:14 -0000	1.10.2.1
+++ c-opts.c	18 Aug 2002 00:21:07 -0000
@@ -79,6 +79,7 @@ static void handle_OPT_d PARAMS ((const 
 
 #define COMMAND_LINE_OPTIONS						     \
   OPT("-help",                  CL_ALL,   OPT__help)			     \
+  OPT("-output-pch=",		CL_ALL | CL_JOINED, OPT__output_pch)	     \
   OPT("C",                      CL_ALL,   OPT_C)			     \
   OPT("CC",                     CL_ALL,   OPT_CC)			     \
   OPT("E",			CL_ALL,   OPT_E)			     \
@@ -282,6 +283,7 @@ missing_arg (opt_index)
 {
   switch (opt_index)
     {
+    case OPT__output_pch:
     case OPT_Wformat_eq:
     case OPT_d:
     case OPT_fbuiltin_:
@@ -511,6 +513,10 @@ c_common_decode_option (argc, argv)
 
     case OPT__help:
       print_help ();
+      break;
+
+    case OPT__output_pch:
+      pch_file = xstrdup (arg + strlen ("--output-pch="));
       break;
 
     case OPT_C:
Index: gcc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
retrieving revision 1.285.4.7
diff -p -u -p -r1.285.4.7 gcc.c
--- gcc.c	13 Aug 2002 17:56:31 -0000	1.285.4.7
+++ gcc.c	18 Aug 2002 00:21:07 -0000
@@ -382,6 +382,7 @@ or with constant text in a single argume
  %w	marks the argument containing or following the %w as the
 	"output file" of this compilation.  This puts the argument
 	into the sequence of arguments that %o will substitute later.
+ %V	indicates that this compilation produces no "output file".
  %W{...}
 	like %{...} but mark last argument supplied within
 	as a file to be deleted on failure.
@@ -845,8 +846,10 @@ static const struct compiler default_com
     %(trad_capable_cpp) %{ansi:-std=c89} %(cpp_options)", 0},
   {".h", "@c-header", 0},
   {"@c-header",
-   "%{!E:%ecompilation of header file requested} \
-    %(trad_capable_cpp) %{ansi:-std=c89} %(cpp_options) %(cpp_debug_options)",
+   "%{E|M|MM:%(trad_capable_cpp) -lang-c %{ansi:-std=c89} %(cpp_options) \
+      %(cpp_debug_options)}\
+    %{!E:cc1 %{ansi:-std=c89} %(cpp_unique_options) %(cc1_options) \
+     -o %g.s %{!o*:--output-pch=%i.pch} %W{^o*:--output-pch=%*}%V} ",
    0},
   {".i", "@cpp-output", 0},
   {"@cpp-output",
@@ -4690,6 +4693,10 @@ do_spec_1 (spec, inswitch, soft_matched_
 	    this_is_library_file = 1;
 	    break;
 
+	  case 'V':
+	    outfiles[input_file_number] = NULL;
+	    break;
+
 	  case 'w':
 	    this_is_output_file = 1;
 	    break;
@@ -5765,6 +5772,7 @@ main (argc, argv)
   size_t i;
   int value;
   int linker_was_run = 0;
+  int num_linker_inputs = 0;
   char *explicit_link_files;
   char *specs_file;
   const char *p;
@@ -6188,9 +6196,15 @@ main (argc, argv)
 	error_count++;
     }
 
+  /* Determine if there are any linker input files.  */
+  num_linker_inputs = 0;
+  for (i = 0; (int) i < n_infiles; i++)
+    if (explicit_link_files[i] || outfiles[i] != NULL)
+      num_linker_inputs++;
+
   /* Run ld to link all the compiler output files.  */
 
-  if (error_count == 0)
+  if (num_linker_inputs > 0 && error_count == 0)
     {
       int tmp = execution_count;
 
Index: cp/g++spec.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/g++spec.c,v
retrieving revision 1.25.12.3
diff -p -u -p -r1.25.12.3 g++spec.c
--- cp/g++spec.c	13 Aug 2002 17:57:36 -0000	1.25.12.3
+++ cp/g++spec.c	18 Aug 2002 00:21:12 -0000
@@ -57,9 +57,11 @@ lang_specific_driver (in_argc, in_argv, 
   /* If non-zero, the user gave us the `-v' flag.  */ 
   int saw_verbose_flag = 0;
 
-  /* This will be 0 if we encounter a situation where we should not
-     link in libstdc++.  */
-  int library = 1;
+  /* This is a tristate:
+     -1 means we should not link in libstdc++
+     0  means we should link in libstdc++ if it is needed
+     1  means libstdc++ is needed and should be linked in.  */
+  int library = 0;
 
   /* The number of arguments being added to what's in argv, other than
      libraries.  We use this to track the number of times we've inserted
@@ -128,10 +130,10 @@ lang_specific_driver (in_argc, in_argv, 
 
       if (argv[i][0] == '-')
 	{
-	  if (library != 0 && (strcmp (argv[i], "-nostdlib") == 0
-			       || strcmp (argv[i], "-nodefaultlibs") == 0))
+	  if (strcmp (argv[i], "-nostdlib") == 0
+	      || strcmp (argv[i], "-nodefaultlibs") == 0)
 	    {
-	      library = 0;
+	      library = -1;
 	    }
 	  else if (strcmp (argv[i], "-lm") == 0
 		   || strcmp (argv[i], "-lmath") == 0
@@ -149,30 +151,37 @@ lang_specific_driver (in_argc, in_argv, 
 	  else if (strcmp (argv[i], "-pg") == 0 || strcmp (argv[i], "-p") == 0)
 	    saw_profile_flag++;
 	  else if (strcmp (argv[i], "-v") == 0)
+	    saw_verbose_flag = 1;
+	  else if (strncmp (argv[i], "-x", 2) == 0)
 	    {
-	      saw_verbose_flag = 1;
-	      if (argc == 2)
+	      if (library == 0)
 		{
-		  /* If they only gave us `-v', don't try to link
-		     in libg++.  */ 
-		  library = 0;
+		  const char * arg;
+		  if (argv[i][2] != '\0')
+		    arg = argv[i]+2;
+		  else if (argv[i+1] != NULL)
+		    arg = argv[i+1];
+		  else  /* Error condition, message will be printed later.  */
+		    arg = "";
+		  if (strcmp (arg, "c++") == 0
+		      || strcmp (arg, "c++-cpp-output") == 0)
+		    library = 1;
 		}
+	      saw_speclang = 1;
 	    }
-	  else if (strncmp (argv[i], "-x", 2) == 0)
-	    saw_speclang = 1;
 	  else if (((argv[i][2] == '\0'
 		     && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
 		    || strcmp (argv[i], "-Xlinker") == 0
 		    || strcmp (argv[i], "-Tdata") == 0))
 	    quote = argv[i];
-	  else if (library != 0 && ((argv[i][2] == '\0'
-		     && (char *) strchr ("cSEM", argv[i][1]) != NULL)
-		    || strcmp (argv[i], "-MM") == 0
-		    || strcmp (argv[i], "-fsyntax-only") == 0))
+	  else if ((argv[i][2] == '\0'
+		    && (char *) strchr ("cSEM", argv[i][1]) != NULL)
+		   || strcmp (argv[i], "-MM") == 0
+		   || strcmp (argv[i], "-fsyntax-only") == 0)
 	    {
 	      /* Don't specify libraries if we won't link, since that would
 		 cause a warning.  */
-	      library = 0;
+	      library = -1;
 	      added -= 2;
 	    }
 	  else if (strcmp (argv[i], "-static-libgcc") == 0 
@@ -192,16 +201,28 @@ lang_specific_driver (in_argc, in_argv, 
 	      continue;
 	    }
 
-	  /* If the filename ends in .c or .i, put options around it.
+	  /* If the filename ends in .[chi], put options around it.
 	     But not if a specified -x option is currently active.  */
 	  len = strlen (argv[i]);
 	  if (len > 2
-	      && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i')
+	      && (argv[i][len - 1] == 'c' 
+		  || argv[i][len - 1] == 'i'
+		  || argv[i][len - 1] == 'h')
 	      && argv[i][len - 2] == '.')
 	    {
 	      args[i] |= LANGSPEC;
 	      added += 2;
 	    }
+	  
+	  /* If we don't know that this is a header file, we might
+	     need to be linking in the libraries.  */
+	  if (library == 0)
+	    {
+	      if ((len <= 2 || strcmp (argv[i] + (len - 2), ".H") != 0)
+		  && (len <= 2 || strcmp (argv[i] + (len - 2), ".h") != 0)
+		  && (len <= 3 || strcmp (argv[i] + (len - 3), ".hh") != 0))
+		library = 1;
+	    }
 	}
     }
 
@@ -209,7 +230,7 @@ lang_specific_driver (in_argc, in_argv, 
     fatal ("argument to `%s' missing\n", quote);
 
   /* If we know we don't have to do anything, bail now.  */
-  if (! added && ! library)
+  if (! added && library <= 0)
     {
       free (args);
       return;
@@ -238,27 +259,37 @@ lang_specific_driver (in_argc, in_argv, 
 
       /* Make sure -lstdc++ is before the math library, since libstdc++
 	 itself uses those math routines.  */
-      if (!saw_math && (args[i] & MATHLIB) && library)
+      if (!saw_math && (args[i] & MATHLIB) && library > 0)
 	{
 	  --j;
 	  saw_math = argv[i];
 	}
 
-      if (!saw_libc && (args[i] & WITHLIBC) && library)
+      if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
 	{
 	  --j;
 	  saw_libc = argv[i];
 	}
 
-      /* Wrap foo.c and foo.i files in a language specification to
+      /* Wrap foo.[chi] files in a language specification to
 	 force the gcc compiler driver to run cc1plus on them.  */
       if (args[i] & LANGSPEC)
 	{
 	  int len = strlen (argv[i]);
-	  if (argv[i][len - 1] == 'i')
-	    arglist[j++] = "-xc++-cpp-output";
-	  else
-	    arglist[j++] = "-xc++";
+	  switch (argv[i][len - 1])
+	    {
+	    case 'c':
+	      arglist[j++] = "-xc++";
+	      break;
+	    case 'i':
+	      arglist[j++] = "-xc++-cpp-output";
+	      break;
+	    case 'h':
+	      arglist[j++] = "-xc++-header";
+	      break;
+	    default:
+	      abort ();
+	    }
 	  arglist[j++] = argv[i];
 	  arglist[j] = "-xnone";
 	}
@@ -268,7 +299,7 @@ lang_specific_driver (in_argc, in_argv, 
     }
 
   /* Add `-lstdc++' if we haven't already done so.  */
-  if (library)
+  if (library > 0)
     {
       arglist[j++] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX;
       added_libraries++;
@@ -282,7 +313,7 @@ lang_specific_driver (in_argc, in_argv, 
     }
   if (saw_math)
     arglist[j++] = saw_math;
-  else if (library && need_math)
+  else if (library > 0 && need_math)
     {
       arglist[j++] = saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY;
       added_libraries++;
Index: cp/lang-specs.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lang-specs.h,v
retrieving revision 1.45.14.6
diff -p -u -p -r1.45.14.6 lang-specs.h
--- cp/lang-specs.h	13 Aug 2002 17:57:36 -0000	1.45.14.6
+++ cp/lang-specs.h	18 Aug 2002 00:21:12 -0000
@@ -32,6 +32,21 @@ Boston, MA 02111-1307, USA.  */
   {".cpp", "@c++", 0},
   {".c++", "@c++", 0},
   {".C",   "@c++", 0},
+  {".H",   "@c++-header", 0},
+  {".hh",  "@c++-header", 0},
+  {"@c++-header",
+     /* We should convert -ansi to -std=c++98 even if -fpreprocessed,
+	to get dollars in identifiers correct.  */
+    "%{E|M|MM:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
+       %{ansi:-std=c++98} %(cpp_options) %2 %(cpp_debug_options)}\
+     %{!E:%{!M:%{!MM:\
+       %{save-temps:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
+		%{ansi:-std=c++98} %(cpp_options) %2 %b.ii \n}\
+      cc1plus %{save-temps:-fpreprocessed %b.ii}\
+	      %{!save-temps:%(cpp_unique_options) %{!no-gcc:-D__GNUG__=%v1}}\
+	%{ansi:-std=c++98} %(cc1_options) %2 %{+e1*}\
+        -o %g.s %{!o*:--output-pch=%i.pch} %W{^o*:--output-pch=%*}%V}}}",
+     CPLUSPLUS_CPP_SPEC},
   {"@c++",
      /* We should convert -ansi to -std=c++98 even if -fpreprocessed,
 	to get dollars in identifiers correct.  */
Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.107.2.7
diff -p -u -p -r1.107.2.7 invoke.texi
--- doc/invoke.texi	13 Aug 2002 17:57:42 -0000	1.107.2.7
+++ doc/invoke.texi	18 Aug 2002 00:21:13 -0000
@@ -141,6 +141,7 @@ only one of these two forms, whichever o
 * Code Gen Options::    Specifying conventions for function calls, data layout
                         and register usage.
 * Environment Variables:: Env vars that affect GCC.
+* Precompiled Headers:: Compiling a header once, and using it many times.
 * Running Protoize::    Automatically adding or removing function prototypes.
 @end menu
 
@@ -736,7 +737,7 @@ Objective-C source code.  Note that you 
 Objective-C source code which should not be preprocessed.
 
 @item @var{file}.h
-C header file (not to be compiled or linked).
+C or C++ header file to be turned into a precompiled header.
 
 @item @var{file}.cc
 @itemx @var{file}.cp
@@ -748,6 +749,10 @@ C++ source code which must be preprocess
 the last two letters must both be literally @samp{x}.  Likewise,
 @samp{.C} refers to a literal capital C@.
 
+@item @var{file}.hh
+@itemx @var{file}.H
+C++ header file to be turned into a precompiled header.
+
 @item @var{file}.f
 @itemx @var{file}.for
 @itemx @var{file}.FOR
@@ -811,7 +816,7 @@ name suffix).  This option applies to al
 the next @option{-x} option.  Possible values for @var{language} are:
 @example
 c  c-header  cpp-output
-c++  c++-cpp-output
+c++  c++-header  c++-cpp-output
 objective-c  objc-cpp-output
 assembler  assembler-with-cpp
 ada
@@ -929,22 +934,23 @@ line options for each tool.
 @cindex suffixes for C++ source
 @cindex C++ source file suffixes
 C++ source files conventionally use one of the suffixes @samp{.C},
-@samp{.cc}, @samp{.cpp}, @samp{.c++}, @samp{.cp}, or @samp{.cxx};
-preprocessed C++ files use the suffix @samp{.ii}.  GCC recognizes
-files with these names and compiles them as C++ programs even if you
-call the compiler the same way as for compiling C programs (usually with
-the name @command{gcc}).
+@samp{.cc}, @samp{.cpp}, @samp{.c++}, @samp{.cp}, or @samp{.cxx}; C++
+header files often use @samp{.hh} or @samp{.H}; and preprocessed C++
+files use the suffix @samp{.ii}.  GCC recognizes files with these names
+and compiles them as C++ programs even if you call the compiler the same
+way as for compiling C programs (usually with the name @command{gcc}).
 
 @findex g++
 @findex c++
 However, C++ programs often require class libraries as well as a
 compiler that understands the C++ language---and under some
-circumstances, you might want to compile programs from standard input,
-or otherwise without a suffix that flags them as C++ programs.
-@command{g++} is a program that calls GCC with the default language
-set to C++, and automatically specifies linking against the C++
-library.  On many systems, @command{g++} is also
-installed with the name @command{c++}.
+circumstances, you might want to compile programs or header files from
+standard input, or otherwise without a suffix that flags them as C++
+programs.  You might also like to precompile a C header file with a
+@samp{.h} extension to be used in C++ compilations.  @command{g++} is a
+program that calls GCC with the default language set to C++, and
+automatically specifies linking against the C++ library.  On many
+systems, @command{g++} is also installed with the name @command{c++}.
 
 @cindex invoking @command{g++}
 When you compile C++ programs, you may specify many of the same
@@ -10201,6 +10207,88 @@ preprocessor.
 @include cppenv.texi
 
 @c man end
+
+@node Precompiled Headers
+@section Using Precompiled Headers
+
+Often large projects have many header files that are included in every
+source file.  The time the compiler takes to process these header files
+over and over again can account for nearly all of the time required to
+build the project.  To make builds faster, GCC allows users to
+`precompile' a header file; then, if builds can use the precompiled
+header file they will be much faster.
+
+To create a precompiled header file, simply compile it as you would any
+other file, if necessary using the @option{-x} option to make the driver
+treat it as a C or C++ header file.  You will probably want to use a
+tool like @command{make} to keep the precompiled header up-to-date when
+the headers it contains change.
+
+A precompiled header file will be searched for when @code{#include} is
+seen in the compilation.  As it searches for the included file
+(@pxref{Search Path,,Search Path,cpp.info,The C Preprocessor}) the
+compiler looks for a precompiled header in each directory just before it
+looks for the include file in that directory.  The name searched for is
+the name specified in the @code{#include} with @samp{.pch} appended.  If
+the precompiled header file can't be used, it is ignored.
+
+For instance, if you have @code{#include "all.h"}, and you have
+@file{all.h.pch} in the same directory as @file{all.h}, then the
+precompiled header file will be used if possible, and the original
+header will be used otherwise.
+
+Alternatively, you might decide to put the precompiled header file in a
+directory and use @option{-I} to ensure that directory is searched
+before (or instead of) the directory containing the original header.
+Then, if you want to check that the precompiled header file is always
+used, you can put a file of the same name as the original header in this
+directory containing an @code{#error} command.
+
+This also works with @option{-include}.  So yet another way to use
+precompiled headers is to simply 
+
+There are many other possibilities, limited only by your imagination,
+good sense, and the constraints of your build system.
+
+A precompiled header file can be used only when these conditions apply:
+
+@itemize
+@item
+Only one precompiled header can be used in a particular compilation.
+@item
+A precompiled header can't be used once the first C token is seen.  You
+can have preprocessor directives before a precompiled header; you can
+even include a precompiled header from inside another header, so long as
+there are no C tokens before the @code{#include}.
+@item
+The precompiled header file must be produced for the same language as
+the current compilation.  You can't use a C precompiled header for a C++
+compilation.
+@item
+The precompiled header file must be produced by the same compiler
+version and configuration as the current compilation is using.
+The easiest way to guarantee this is to use the same compiler binary
+for creating and using precompiled headers.
+@item
+Any macros defined before the precompiled header (including with
+@option{-D}) must either be defined in the same way as when the
+precompiled header was generated, or must not affect the precompiled
+header, which usually means that the they don't appear in the
+precompiled header at all.
+@item
+Certain command-line options must be defined in the same way as when the
+precompiled header was generated.  At present, it's not clear which
+options are safe to change and which are not; the safest choice is to
+use exactly the same options when generating and using the precompiled
+header.
+@end itemize
+
+For all of these but the last, the compiler will automatically ignore
+the precompiled header if the conditions aren't met.  For the last item,
+some option changes will cause the precompiled header to be rejected,
+but not all incompatible option combinations have yet been found.  If
+you find a new incompatible combination, please consider filing a bug
+report, see @ref{Bugs}.
 
 @node Running Protoize
 @section Running Protoize
============================================================

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

end of thread, other threads:[~2002-08-20 17:47 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-17 20:33 [PCH] driver, documentation Geoffrey Keating
2002-08-17 21:23 ` Daniel Jacobowitz
2002-08-17 23:07 ` Neil Booth
2002-08-17 23:09 ` Neil Booth
2002-08-18  2:53 ` Joseph S. Myers
2002-08-19 10:27 ` Mike Stump
2002-08-19 11:00   ` Stan Shebs
2002-08-19 11:25     ` Geoff Keating
2002-08-19 12:14       ` Daniel Berlin
2002-08-19 12:15       ` Neil Booth
2002-08-20 10:47       ` Jason Merrill
2002-08-19 11:27     ` Neil Booth
2002-08-19 11:42     ` Joseph S. Myers
2002-08-19 13:17 ` Devang Patel
2002-08-19 14:17   ` Geoff Keating
2002-08-19 15:51     ` Devang Patel
2002-08-19 13:19 ` Devang Patel
2002-08-19 14:18   ` Geoff Keating
2002-08-19 15:50     ` Devang Patel

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).