xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/common-inferior.cc (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
1 /* Functions to deal with the inferior being executed on GDB or
2    GDBserver.
3 
4    Copyright (C) 2019-2024 Free Software Foundation, Inc.
5 
6    This file is part of GDB.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 #include "gdbsupport/common-inferior.h"
22 
23 /* See common-inferior.h.  */
24 
25 bool startup_with_shell = true;
26 
27 /* See common-inferior.h.  */
28 
29 std::string
30 construct_inferior_arguments (gdb::array_view<char * const> argv)
31 {
32   std::string result;
33 
34   if (startup_with_shell)
35     {
36 #ifdef __MINGW32__
37       /* This holds all the characters considered special to the
38 	 Windows shells.  */
39       static const char special[] = "\"!&*|[]{}<>?`~^=;, \t\n";
40       static const char quote = '"';
41 #else
42       /* This holds all the characters considered special to the
43 	 typical Unix shells.  We include `^' because the SunOS
44 	 /bin/sh treats it as a synonym for `|'.  */
45       static const char special[] = "\"!#$&*()\\|[]{}<>?'`~^; \t\n";
46       static const char quote = '\'';
47 #endif
48       for (int i = 0; i < argv.size (); ++i)
49 	{
50 	  if (i > 0)
51 	    result += ' ';
52 
53 	  /* Need to handle empty arguments specially.  */
54 	  if (argv[i][0] == '\0')
55 	    {
56 	      result += quote;
57 	      result += quote;
58 	    }
59 	  else
60 	    {
61 #ifdef __MINGW32__
62 	      bool quoted = false;
63 
64 	      if (strpbrk (argv[i], special))
65 		{
66 		  quoted = true;
67 		  result += quote;
68 		}
69 #endif
70 	      for (char *cp = argv[i]; *cp; ++cp)
71 		{
72 		  if (*cp == '\n')
73 		    {
74 		      /* A newline cannot be quoted with a backslash (it
75 			 just disappears), only by putting it inside
76 			 quotes.  */
77 		      result += quote;
78 		      result += '\n';
79 		      result += quote;
80 		    }
81 		  else
82 		    {
83 #ifdef __MINGW32__
84 		      if (*cp == quote)
85 #else
86 		      if (strchr (special, *cp) != NULL)
87 #endif
88 			result += '\\';
89 		      result += *cp;
90 		    }
91 		}
92 #ifdef __MINGW32__
93 	      if (quoted)
94 		result += quote;
95 #endif
96 	    }
97 	}
98     }
99   else
100     {
101       /* In this case we can't handle arguments that contain spaces,
102 	 tabs, or newlines -- see breakup_args().  */
103       for (char *arg : argv)
104 	{
105 	  char *cp = strchr (arg, ' ');
106 	  if (cp == NULL)
107 	    cp = strchr (arg, '\t');
108 	  if (cp == NULL)
109 	    cp = strchr (arg, '\n');
110 	  if (cp != NULL)
111 	    error (_("can't handle command-line "
112 		     "argument containing whitespace"));
113 	}
114 
115       for (int i = 0; i < argv.size (); ++i)
116 	{
117 	  if (i > 0)
118 	    result += " ";
119 	  result += argv[i];
120 	}
121     }
122 
123   return result;
124 }
125