]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectPlatform.cpp
1 //===-- CommandObjectPlatform.cpp -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/lldb-python.h"
11
12 #include "CommandObjectPlatform.h"
13
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Core/DataExtractor.h"
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/Module.h"
21 #include "lldb/Core/PluginManager.h"
22 #include "lldb/Interpreter/Args.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Interpreter/CommandReturnObject.h"
25 #include "lldb/Interpreter/OptionGroupFile.h"
26 #include "lldb/Interpreter/OptionGroupPlatform.h"
27 #include "lldb/Target/ExecutionContext.h"
28 #include "lldb/Target/Platform.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Utility/Utils.h"
31
32 using namespace lldb;
33 using namespace lldb_private;
34
35 static mode_t
36 ParsePermissionString(const char* permissions)
37 {
38     if (strlen(permissions) != 9)
39         return (mode_t)(-1);
40     bool user_r,user_w,user_x,
41     group_r,group_w,group_x,
42     world_r,world_w,world_x;
43     
44     user_r = (permissions[0] == 'r');
45     user_w = (permissions[1] == 'w');
46     user_x = (permissions[2] == 'x');
47     
48     group_r = (permissions[3] == 'r');
49     group_w = (permissions[4] == 'w');
50     group_x = (permissions[5] == 'x');
51     
52     world_r = (permissions[6] == 'r');
53     world_w = (permissions[7] == 'w');
54     world_x = (permissions[8] == 'x');
55     
56     mode_t user,group,world;
57     user = (user_r ? 4 : 0) | (user_w ? 2 : 0) | (user_x ? 1 : 0);
58     group = (group_r ? 4 : 0) | (group_w ? 2 : 0) | (group_x ? 1 : 0);
59     world = (world_r ? 4 : 0) | (world_w ? 2 : 0) | (world_x ? 1 : 0);
60     
61     return user | group | world;
62 }
63
64 static OptionDefinition
65 g_permissions_options[] =
66 {
67     {   LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument,       NULL, 0, eArgTypePermissionsNumber         , "Give out the numeric value for permissions (e.g. 757)" },
68     {   LLDB_OPT_SET_ALL, false, "permissions-string",'s', OptionParser::eRequiredArgument, NULL, 0, eArgTypePermissionsString  , "Give out the string value for permissions (e.g. rwxr-xr--)." },
69     {   LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone         , "Allow user to read." },
70     {   LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone         , "Allow user to write." },
71     {   LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone         , "Allow user to execute." },
72
73     {   LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone         , "Allow group to read." },
74     {   LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone         , "Allow group to write." },
75     {   LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone         , "Allow group to execute." },
76
77     {   LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone         , "Allow world to read." },
78     {   LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone         , "Allow world to write." },
79     {   LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone         , "Allow world to execute." },
80
81 };
82
83 class OptionPermissions : public lldb_private::OptionGroup
84 {
85 public:
86     OptionPermissions ()
87     {
88     }
89     
90     virtual
91     ~OptionPermissions ()
92     {
93     }
94     
95     virtual lldb_private::Error
96     SetOptionValue (CommandInterpreter &interpreter,
97                     uint32_t option_idx,
98                     const char *option_arg)
99     {
100         Error error;
101         char short_option = (char) GetDefinitions()[option_idx].short_option;
102         switch (short_option)
103         {
104             case 'v':
105             {
106                 bool ok;
107                 uint32_t perms = Args::StringToUInt32(option_arg, 777, 8, &ok);
108                 if (!ok)
109                     error.SetErrorStringWithFormat("invalid value for permissions: %s", option_arg);
110                 else
111                     m_permissions = perms;
112             }
113                 break;
114             case 's':
115             {
116                 mode_t perms = ParsePermissionString(option_arg);
117                 if (perms == (mode_t)-1)
118                     error.SetErrorStringWithFormat("invalid value for permissions: %s", option_arg);
119                 else
120                     m_permissions = perms;
121             }
122             case 'r':
123                 m_permissions |= lldb::eFilePermissionsUserRead;
124                 break;
125             case 'w':
126                 m_permissions |= lldb::eFilePermissionsUserWrite;
127                 break;
128             case 'x':
129                 m_permissions |= lldb::eFilePermissionsUserExecute;
130                 break;
131             case 'R':
132                 m_permissions |= lldb::eFilePermissionsGroupRead;
133                 break;
134             case 'W':
135                 m_permissions |= lldb::eFilePermissionsGroupWrite;
136                 break;
137             case 'X':
138                 m_permissions |= lldb::eFilePermissionsGroupExecute;
139                 break;
140             case 'd':
141                 m_permissions |= lldb::eFilePermissionsWorldRead;
142                 break;
143             case 't':
144                 m_permissions |= lldb::eFilePermissionsWorldWrite;
145                 break;
146             case 'e':
147                 m_permissions |= lldb::eFilePermissionsWorldExecute;
148                 break;
149
150             default:
151                 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
152                 break;
153         }
154         
155         return error;
156     }
157     
158     void
159     OptionParsingStarting (CommandInterpreter &interpreter)
160     {
161         m_permissions = 0;
162     }
163     
164     virtual uint32_t
165     GetNumDefinitions ()
166     {
167         return llvm::array_lengthof(g_permissions_options);
168     }
169     
170     const lldb_private::OptionDefinition*
171     GetDefinitions ()
172     {
173         return g_permissions_options;
174     }
175         
176     // Instance variables to hold the values for command options.
177     
178     uint32_t m_permissions;
179 private:
180     DISALLOW_COPY_AND_ASSIGN(OptionPermissions);
181 };
182
183 //----------------------------------------------------------------------
184 // "platform select <platform-name>"
185 //----------------------------------------------------------------------
186 class CommandObjectPlatformSelect : public CommandObjectParsed
187 {
188 public:
189     CommandObjectPlatformSelect (CommandInterpreter &interpreter) :
190         CommandObjectParsed (interpreter, 
191                              "platform select",
192                              "Create a platform if needed and select it as the current platform.",
193                              "platform select <platform-name>",
194                              0),
195         m_option_group (interpreter),
196         m_platform_options (false) // Don't include the "--platform" option by passing false
197     {
198         m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, 1);
199         m_option_group.Finalize();
200     }
201
202     virtual
203     ~CommandObjectPlatformSelect ()
204     {
205     }
206
207     virtual int
208     HandleCompletion (Args &input,
209                       int &cursor_index,
210                       int &cursor_char_position,
211                       int match_start_point,
212                       int max_return_elements,
213                       bool &word_complete,
214                       StringList &matches)
215     {
216         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
217         completion_str.erase (cursor_char_position);
218         
219         CommandCompletions::PlatformPluginNames (m_interpreter, 
220                                                  completion_str.c_str(),
221                                                  match_start_point,
222                                                  max_return_elements,
223                                                  NULL,
224                                                  word_complete,
225                                                  matches);
226         return matches.GetSize();
227     }
228
229     virtual Options *
230     GetOptions ()
231     {
232         return &m_option_group;
233     }
234
235 protected:
236     virtual bool
237     DoExecute (Args& args, CommandReturnObject &result)
238     {
239         if (args.GetArgumentCount() == 1)
240         {
241             const char *platform_name = args.GetArgumentAtIndex (0);
242             if (platform_name && platform_name[0])
243             {
244                 const bool select = true;
245                 m_platform_options.SetPlatformName (platform_name);
246                 Error error;
247                 ArchSpec platform_arch;
248                 PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, ArchSpec(), select, error, platform_arch));
249                 if (platform_sp)
250                 {
251                     platform_sp->GetStatus (result.GetOutputStream());
252                     result.SetStatus (eReturnStatusSuccessFinishResult);
253                 }
254                 else
255                 {
256                     result.AppendError(error.AsCString());
257                     result.SetStatus (eReturnStatusFailed);
258                 }
259             }
260             else
261             {
262                 result.AppendError ("invalid platform name");
263                 result.SetStatus (eReturnStatusFailed);
264             }
265         }
266         else
267         {
268             result.AppendError ("platform create takes a platform name as an argument\n");
269             result.SetStatus (eReturnStatusFailed);
270         }
271         return result.Succeeded();
272     }
273
274     OptionGroupOptions m_option_group;
275     OptionGroupPlatform m_platform_options;
276 };
277
278 //----------------------------------------------------------------------
279 // "platform list"
280 //----------------------------------------------------------------------
281 class CommandObjectPlatformList : public CommandObjectParsed
282 {
283 public:
284     CommandObjectPlatformList (CommandInterpreter &interpreter) :
285         CommandObjectParsed (interpreter,
286                              "platform list",
287                              "List all platforms that are available.",
288                              NULL,
289                              0)
290     {
291     }
292
293     virtual
294     ~CommandObjectPlatformList ()
295     {
296     }
297
298 protected:
299     virtual bool
300     DoExecute (Args& args, CommandReturnObject &result)
301     {
302         Stream &ostrm = result.GetOutputStream();
303         ostrm.Printf("Available platforms:\n");
304         
305         PlatformSP host_platform_sp (Platform::GetDefaultPlatform());
306         ostrm.Printf ("%s: %s\n", 
307                       host_platform_sp->GetPluginName().GetCString(),
308                       host_platform_sp->GetDescription());
309
310         uint32_t idx;
311         for (idx = 0; 1; ++idx)
312         {
313             const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (idx);
314             if (plugin_name == NULL)
315                 break;
316             const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (idx);
317             if (plugin_desc == NULL)
318                 break;
319             ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
320         }
321         
322         if (idx == 0)
323         {
324             result.AppendError ("no platforms are available\n");
325             result.SetStatus (eReturnStatusFailed);
326         }
327         else
328             result.SetStatus (eReturnStatusSuccessFinishResult);
329         return result.Succeeded();
330     }
331 };
332
333 //----------------------------------------------------------------------
334 // "platform status"
335 //----------------------------------------------------------------------
336 class CommandObjectPlatformStatus : public CommandObjectParsed
337 {
338 public:
339     CommandObjectPlatformStatus (CommandInterpreter &interpreter) :
340         CommandObjectParsed (interpreter,
341                              "platform status",
342                              "Display status for the currently selected platform.",
343                              NULL,
344                              0)
345     {
346     }
347
348     virtual
349     ~CommandObjectPlatformStatus ()
350     {
351     }
352
353 protected:
354     virtual bool
355     DoExecute (Args& args, CommandReturnObject &result)
356     {
357         Stream &ostrm = result.GetOutputStream();      
358         
359         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
360         PlatformSP platform_sp;
361         if (target)
362         {
363             platform_sp = target->GetPlatform();
364         }
365         if (!platform_sp)
366         {
367             platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
368         }
369         if (platform_sp)
370         {
371             platform_sp->GetStatus (ostrm);
372             result.SetStatus (eReturnStatusSuccessFinishResult);            
373         }
374         else
375         {
376             result.AppendError ("no platform us currently selected\n");
377             result.SetStatus (eReturnStatusFailed);            
378         }
379         return result.Succeeded();
380     }
381 };
382
383 //----------------------------------------------------------------------
384 // "platform connect <connect-url>"
385 //----------------------------------------------------------------------
386 class CommandObjectPlatformConnect : public CommandObjectParsed
387 {
388 public:
389     CommandObjectPlatformConnect (CommandInterpreter &interpreter) :
390         CommandObjectParsed (interpreter, 
391                              "platform connect",
392                              "Connect a platform by name to be the currently selected platform.",
393                              "platform connect <connect-url>",
394                              0)
395     {
396     }
397
398     virtual
399     ~CommandObjectPlatformConnect ()
400     {
401     }
402
403 protected:
404     virtual bool
405     DoExecute (Args& args, CommandReturnObject &result)
406     {
407         Stream &ostrm = result.GetOutputStream();      
408         
409         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
410         if (platform_sp)
411         {
412             Error error (platform_sp->ConnectRemote (args));
413             if (error.Success())
414             {
415                 platform_sp->GetStatus (ostrm);
416                 result.SetStatus (eReturnStatusSuccessFinishResult);            
417             }
418             else
419             {
420                 result.AppendErrorWithFormat ("%s\n", error.AsCString());
421                 result.SetStatus (eReturnStatusFailed);            
422             }
423         }
424         else
425         {
426             result.AppendError ("no platform is currently selected\n");
427             result.SetStatus (eReturnStatusFailed);            
428         }
429         return result.Succeeded();
430     }
431     
432     virtual Options *
433     GetOptions ()
434     {
435         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
436         OptionGroupOptions* m_platform_options = NULL;
437         if (platform_sp)
438         {
439             m_platform_options = platform_sp->GetConnectionOptions(m_interpreter);
440             if (m_platform_options != NULL && !m_platform_options->m_did_finalize)
441                 m_platform_options->Finalize();
442         }
443         return m_platform_options;
444     }
445
446 };
447
448 //----------------------------------------------------------------------
449 // "platform disconnect"
450 //----------------------------------------------------------------------
451 class CommandObjectPlatformDisconnect : public CommandObjectParsed
452 {
453 public:
454     CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) :
455         CommandObjectParsed (interpreter, 
456                              "platform disconnect",
457                              "Disconnect a platform by name to be the currently selected platform.",
458                              "platform disconnect",
459                              0)
460     {
461     }
462
463     virtual
464     ~CommandObjectPlatformDisconnect ()
465     {
466     }
467
468 protected:
469     virtual bool
470     DoExecute (Args& args, CommandReturnObject &result)
471     {
472         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
473         if (platform_sp)
474         {
475             if (args.GetArgumentCount() == 0)
476             {
477                 Error error;
478                 
479                 if (platform_sp->IsConnected())
480                 {
481                     // Cache the instance name if there is one since we are 
482                     // about to disconnect and the name might go with it.
483                     const char *hostname_cstr = platform_sp->GetHostname();
484                     std::string hostname;
485                     if (hostname_cstr)
486                         hostname.assign (hostname_cstr);
487
488                     error = platform_sp->DisconnectRemote ();
489                     if (error.Success())
490                     {
491                         Stream &ostrm = result.GetOutputStream();      
492                         if (hostname.empty())
493                             ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetPluginName().GetCString());
494                         else
495                             ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str());
496                         result.SetStatus (eReturnStatusSuccessFinishResult);            
497                     }
498                     else
499                     {
500                         result.AppendErrorWithFormat ("%s", error.AsCString());
501                         result.SetStatus (eReturnStatusFailed);            
502                     }
503                 }
504                 else
505                 {
506                     // Not connected...
507                     result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetPluginName().GetCString());
508                     result.SetStatus (eReturnStatusFailed);            
509                 }
510             }
511             else
512             {
513                 // Bad args
514                 result.AppendError ("\"platform disconnect\" doesn't take any arguments");
515                 result.SetStatus (eReturnStatusFailed);            
516             }
517         }
518         else
519         {
520             result.AppendError ("no platform is currently selected");
521             result.SetStatus (eReturnStatusFailed);            
522         }
523         return result.Succeeded();
524     }
525 };
526
527 //----------------------------------------------------------------------
528 // "platform settings"
529 //----------------------------------------------------------------------
530 class CommandObjectPlatformSettings : public CommandObjectParsed
531 {
532 public:
533     CommandObjectPlatformSettings (CommandInterpreter &interpreter) :
534         CommandObjectParsed (interpreter,
535                              "platform settings",
536                              "Set settings for the current target's platform, or for a platform by name.",
537                              "platform settings",
538                              0),
539         m_options (interpreter),
540         m_option_working_dir (LLDB_OPT_SET_1, false, "working-dir", 'w', 0, eArgTypePath, "The working directory for the platform.")
541     {
542         m_options.Append (&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
543     }
544     
545     virtual
546     ~CommandObjectPlatformSettings ()
547     {
548     }
549     
550 protected:
551     virtual bool
552     DoExecute (Args& args, CommandReturnObject &result)
553     {
554         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
555         if (platform_sp)
556         {
557             if (m_option_working_dir.GetOptionValue().OptionWasSet())
558                 platform_sp->SetWorkingDirectory (ConstString(m_option_working_dir.GetOptionValue().GetCurrentValue().GetPath().c_str()));
559         }
560         else
561         {
562             result.AppendError ("no platform is currently selected");
563             result.SetStatus (eReturnStatusFailed);
564         }
565         return result.Succeeded();
566     }
567     
568     virtual Options *
569     GetOptions ()
570     {
571         if (m_options.DidFinalize() == false)
572         {
573             m_options.Append(new OptionPermissions());
574             m_options.Finalize();
575         }
576         return &m_options;
577     }
578 protected:
579     
580     OptionGroupOptions m_options;
581     OptionGroupFile m_option_working_dir;
582
583 };
584
585
586 //----------------------------------------------------------------------
587 // "platform mkdir"
588 //----------------------------------------------------------------------
589 class CommandObjectPlatformMkDir : public CommandObjectParsed
590 {
591 public:
592     CommandObjectPlatformMkDir (CommandInterpreter &interpreter) :
593     CommandObjectParsed (interpreter,
594                          "platform mkdir",
595                          "Make a new directory on the remote end.",
596                          NULL,
597                          0),
598     m_options(interpreter)
599     {
600     }
601     
602     virtual
603     ~CommandObjectPlatformMkDir ()
604     {
605     }
606     
607     virtual bool
608     DoExecute (Args& args, CommandReturnObject &result)
609     {
610         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
611         if (platform_sp)
612         {
613             std::string cmd_line;
614             args.GetCommandString(cmd_line);
615             uint32_t mode;
616             const OptionPermissions* options_permissions = (OptionPermissions*)m_options.GetGroupWithOption('r');
617             if (options_permissions)
618                 mode = options_permissions->m_permissions;
619             else
620                 mode = lldb::eFilePermissionsUserRWX | lldb::eFilePermissionsGroupRWX | lldb::eFilePermissionsWorldRX;
621             Error error = platform_sp->MakeDirectory(cmd_line.c_str(), mode);
622             if (error.Success())
623             {
624                 result.SetStatus (eReturnStatusSuccessFinishResult);
625             }
626             else
627             {
628                 result.AppendError(error.AsCString());
629                 result.SetStatus (eReturnStatusFailed);
630             }
631         }
632         else
633         {
634             result.AppendError ("no platform currently selected\n");
635             result.SetStatus (eReturnStatusFailed);
636         }
637         return result.Succeeded();
638     }
639     
640     virtual Options *
641     GetOptions ()
642     {
643         if (m_options.DidFinalize() == false)
644         {
645             m_options.Append(new OptionPermissions());
646             m_options.Finalize();
647         }
648         return &m_options;
649     }
650     OptionGroupOptions m_options;
651     
652 };
653
654 //----------------------------------------------------------------------
655 // "platform fopen"
656 //----------------------------------------------------------------------
657 class CommandObjectPlatformFOpen : public CommandObjectParsed
658 {
659 public:
660     CommandObjectPlatformFOpen (CommandInterpreter &interpreter) :
661     CommandObjectParsed (interpreter,
662                          "platform file open",
663                          "Open a file on the remote end.",
664                          NULL,
665                          0),
666     m_options(interpreter)
667     {
668     }
669     
670     virtual
671     ~CommandObjectPlatformFOpen ()
672     {
673     }
674     
675     virtual bool
676     DoExecute (Args& args, CommandReturnObject &result)
677     {
678         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
679         if (platform_sp)
680         {
681             Error error;
682             std::string cmd_line;
683             args.GetCommandString(cmd_line);
684             mode_t perms;
685             const OptionPermissions* options_permissions = (OptionPermissions*)m_options.GetGroupWithOption('r');
686             if (options_permissions)
687                 perms = options_permissions->m_permissions;
688             else
689                 perms = lldb::eFilePermissionsUserRW | lldb::eFilePermissionsGroupRW | lldb::eFilePermissionsWorldRead;
690             lldb::user_id_t fd = platform_sp->OpenFile(FileSpec(cmd_line.c_str(),false),
691                                                        File::eOpenOptionRead | File::eOpenOptionWrite |
692                                                        File::eOpenOptionAppend | File::eOpenOptionCanCreate,
693                                                        perms,
694                                                        error);
695             if (error.Success())
696             {
697                 result.AppendMessageWithFormat("File Descriptor = %" PRIu64 "\n",fd);
698                 result.SetStatus (eReturnStatusSuccessFinishResult);
699             }
700             else
701             {
702                 result.AppendError(error.AsCString());
703                 result.SetStatus (eReturnStatusFailed);
704             }
705         }
706         else
707         {
708             result.AppendError ("no platform currently selected\n");
709             result.SetStatus (eReturnStatusFailed);
710         }
711         return result.Succeeded();
712     }
713     virtual Options *
714     GetOptions ()
715     {
716         if (m_options.DidFinalize() == false)
717         {
718             m_options.Append(new OptionPermissions());
719             m_options.Finalize();
720         }
721         return &m_options;
722     }
723     OptionGroupOptions m_options;
724 };
725
726 //----------------------------------------------------------------------
727 // "platform fclose"
728 //----------------------------------------------------------------------
729 class CommandObjectPlatformFClose : public CommandObjectParsed
730 {
731 public:
732     CommandObjectPlatformFClose (CommandInterpreter &interpreter) :
733     CommandObjectParsed (interpreter,
734                          "platform file close",
735                          "Close a file on the remote end.",
736                          NULL,
737                          0)
738     {
739     }
740     
741     virtual
742     ~CommandObjectPlatformFClose ()
743     {
744     }
745     
746     virtual bool
747     DoExecute (Args& args, CommandReturnObject &result)
748     {
749         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
750         if (platform_sp)
751         {
752             std::string cmd_line;
753             args.GetCommandString(cmd_line);
754             const lldb::user_id_t fd = Args::StringToUInt64(cmd_line.c_str(), UINT64_MAX);
755             Error error;
756             bool success = platform_sp->CloseFile(fd, error);
757             if (success)
758             {
759                 result.AppendMessageWithFormat("file %" PRIu64 " closed.\n", fd);
760                 result.SetStatus (eReturnStatusSuccessFinishResult);
761             }
762             else
763             {
764                 result.AppendError(error.AsCString());
765                 result.SetStatus (eReturnStatusFailed);
766             }
767         }
768         else
769         {
770             result.AppendError ("no platform currently selected\n");
771             result.SetStatus (eReturnStatusFailed);
772         }
773         return result.Succeeded();
774     }
775 };
776
777 //----------------------------------------------------------------------
778 // "platform fread"
779 //----------------------------------------------------------------------
780 class CommandObjectPlatformFRead : public CommandObjectParsed
781 {
782 public:
783     CommandObjectPlatformFRead (CommandInterpreter &interpreter) :
784     CommandObjectParsed (interpreter,
785                          "platform file read",
786                          "Read data from a file on the remote end.",
787                          NULL,
788                          0),
789     m_options (interpreter)
790     {
791     }
792     
793     virtual
794     ~CommandObjectPlatformFRead ()
795     {
796     }
797     
798     virtual bool
799     DoExecute (Args& args, CommandReturnObject &result)
800     {
801         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
802         if (platform_sp)
803         {
804             std::string cmd_line;
805             args.GetCommandString(cmd_line);
806             const lldb::user_id_t fd = Args::StringToUInt64(cmd_line.c_str(), UINT64_MAX);
807             std::string buffer(m_options.m_count,0);
808             Error error;
809             uint32_t retcode = platform_sp->ReadFile(fd, m_options.m_offset, &buffer[0], m_options.m_count, error);
810             result.AppendMessageWithFormat("Return = %d\n",retcode);
811             result.AppendMessageWithFormat("Data = \"%s\"\n",buffer.c_str());
812             result.SetStatus (eReturnStatusSuccessFinishResult);
813         }
814         else
815         {
816             result.AppendError ("no platform currently selected\n");
817             result.SetStatus (eReturnStatusFailed);
818         }
819         return result.Succeeded();
820     }
821     virtual Options *
822     GetOptions ()
823     {
824         return &m_options;
825     }
826     
827 protected:
828     class CommandOptions : public Options
829     {
830     public:
831         
832         CommandOptions (CommandInterpreter &interpreter) :
833         Options (interpreter)
834         {
835         }
836         
837         virtual
838         ~CommandOptions ()
839         {
840         }
841         
842         virtual Error
843         SetOptionValue (uint32_t option_idx, const char *option_arg)
844         {
845             Error error;
846             char short_option = (char) m_getopt_table[option_idx].val;
847             bool success = false;
848             
849             switch (short_option)
850             {
851                 case 'o':
852                     m_offset = Args::StringToUInt32(option_arg, 0, 0, &success);
853                     if (!success)
854                         error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
855                     break;
856                 case 'c':
857                     m_count = Args::StringToUInt32(option_arg, 0, 0, &success);
858                     if (!success)
859                         error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
860                     break;
861
862                 default:
863                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
864                     break;
865             }
866             
867             return error;
868         }
869         
870         void
871         OptionParsingStarting ()
872         {
873             m_offset = 0;
874             m_count = 1;
875         }
876         
877         const OptionDefinition*
878         GetDefinitions ()
879         {
880             return g_option_table;
881         }
882         
883         // Options table: Required for subclasses of Options.
884         
885         static OptionDefinition g_option_table[];
886         
887         // Instance variables to hold the values for command options.
888         
889         uint32_t m_offset;
890         uint32_t m_count;
891     };
892     CommandOptions m_options;
893 };
894 OptionDefinition
895 CommandObjectPlatformFRead::CommandOptions::g_option_table[] =
896 {
897     {   LLDB_OPT_SET_1, false, "offset"           , 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeIndex        , "Offset into the file at which to start reading." },
898     {   LLDB_OPT_SET_1, false, "count"            , 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount        , "Number of bytes to read from the file." },
899     {  0              , false, NULL               ,  0 , 0                , NULL, 0, eArgTypeNone         , NULL }
900 };
901
902
903 //----------------------------------------------------------------------
904 // "platform fwrite"
905 //----------------------------------------------------------------------
906 class CommandObjectPlatformFWrite : public CommandObjectParsed
907 {
908 public:
909     CommandObjectPlatformFWrite (CommandInterpreter &interpreter) :
910     CommandObjectParsed (interpreter,
911                          "platform file write",
912                          "Write data to a file on the remote end.",
913                          NULL,
914                          0),
915     m_options (interpreter)
916     {
917     }
918     
919     virtual
920     ~CommandObjectPlatformFWrite ()
921     {
922     }
923     
924     virtual bool
925     DoExecute (Args& args, CommandReturnObject &result)
926     {
927         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
928         if (platform_sp)
929         {
930             std::string cmd_line;
931             args.GetCommandString(cmd_line);
932             Error error;
933             const lldb::user_id_t fd = Args::StringToUInt64(cmd_line.c_str(), UINT64_MAX);
934             uint32_t retcode = platform_sp->WriteFile (fd,
935                                                        m_options.m_offset,
936                                                        &m_options.m_data[0],
937                                                        m_options.m_data.size(),
938                                                        error);
939             result.AppendMessageWithFormat("Return = %d\n",retcode);
940             result.SetStatus (eReturnStatusSuccessFinishResult);
941         }
942         else
943         {
944             result.AppendError ("no platform currently selected\n");
945             result.SetStatus (eReturnStatusFailed);
946         }
947         return result.Succeeded();
948     }
949     virtual Options *
950     GetOptions ()
951     {
952         return &m_options;
953     }
954     
955 protected:
956     class CommandOptions : public Options
957     {
958     public:
959         
960         CommandOptions (CommandInterpreter &interpreter) :
961         Options (interpreter)
962         {
963         }
964         
965         virtual
966         ~CommandOptions ()
967         {
968         }
969         
970         virtual Error
971         SetOptionValue (uint32_t option_idx, const char *option_arg)
972         {
973             Error error;
974             char short_option = (char) m_getopt_table[option_idx].val;
975             bool success = false;
976             
977             switch (short_option)
978             {
979                 case 'o':
980                     m_offset = Args::StringToUInt32(option_arg, 0, 0, &success);
981                     if (!success)
982                         error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
983                     break;
984                 case 'd':
985                     m_data.assign(option_arg);
986                     break;
987                     
988                 default:
989                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
990                     break;
991             }
992             
993             return error;
994         }
995         
996         void
997         OptionParsingStarting ()
998         {
999             m_offset = 0;
1000             m_data.clear();
1001         }
1002         
1003         const OptionDefinition*
1004         GetDefinitions ()
1005         {
1006             return g_option_table;
1007         }
1008         
1009         // Options table: Required for subclasses of Options.
1010         
1011         static OptionDefinition g_option_table[];
1012         
1013         // Instance variables to hold the values for command options.
1014         
1015         uint32_t m_offset;
1016         std::string m_data;
1017     };
1018     CommandOptions m_options;
1019 };
1020 OptionDefinition
1021 CommandObjectPlatformFWrite::CommandOptions::g_option_table[] =
1022 {
1023     {   LLDB_OPT_SET_1, false, "offset"           , 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeIndex        , "Offset into the file at which to start reading." },
1024     {   LLDB_OPT_SET_1, false, "data"            , 'd', OptionParser::eRequiredArgument, NULL, 0, eArgTypeValue        , "Text to write to the file." },
1025     {  0              , false, NULL               ,  0 , 0                , NULL, 0, eArgTypeNone         , NULL }
1026 };
1027
1028 class CommandObjectPlatformFile : public CommandObjectMultiword
1029 {
1030 public:
1031     //------------------------------------------------------------------
1032     // Constructors and Destructors
1033     //------------------------------------------------------------------
1034     CommandObjectPlatformFile (CommandInterpreter &interpreter) :
1035     CommandObjectMultiword (interpreter,
1036                             "platform file",
1037                             "A set of commands to manage file access through a platform",
1038                             "platform file [open|close|read|write] ...")
1039     {
1040         LoadSubCommand ("open", CommandObjectSP (new CommandObjectPlatformFOpen  (interpreter)));
1041         LoadSubCommand ("close", CommandObjectSP (new CommandObjectPlatformFClose  (interpreter)));
1042         LoadSubCommand ("read", CommandObjectSP (new CommandObjectPlatformFRead  (interpreter)));
1043         LoadSubCommand ("write", CommandObjectSP (new CommandObjectPlatformFWrite  (interpreter)));
1044     }
1045     
1046     virtual
1047     ~CommandObjectPlatformFile ()
1048     {
1049     }
1050     
1051 private:
1052     //------------------------------------------------------------------
1053     // For CommandObjectPlatform only
1054     //------------------------------------------------------------------
1055     DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformFile);
1056 };
1057
1058 //----------------------------------------------------------------------
1059 // "platform get-file remote-file-path host-file-path"
1060 //----------------------------------------------------------------------
1061 class CommandObjectPlatformGetFile : public CommandObjectParsed
1062 {
1063 public:
1064     CommandObjectPlatformGetFile (CommandInterpreter &interpreter) :
1065     CommandObjectParsed (interpreter,
1066                          "platform get-file",
1067                          "Transfer a file from the remote end to the local host.",
1068                          "platform get-file <remote-file-spec> <local-file-spec>",
1069                          0)
1070     {
1071         SetHelpLong(
1072 "Examples: \n\
1073 \n\
1074     platform get-file /the/remote/file/path /the/local/file/path\n\
1075     # Transfer a file from the remote end with file path /the/remote/file/path to the local host.\n");
1076
1077         CommandArgumentEntry arg1, arg2;
1078         CommandArgumentData file_arg_remote, file_arg_host;
1079     
1080         // Define the first (and only) variant of this arg.
1081         file_arg_remote.arg_type = eArgTypeFilename;
1082         file_arg_remote.arg_repetition = eArgRepeatPlain;
1083         // There is only one variant this argument could be; put it into the argument entry.
1084         arg1.push_back (file_arg_remote);
1085         
1086         // Define the second (and only) variant of this arg.
1087         file_arg_host.arg_type = eArgTypeFilename;
1088         file_arg_host.arg_repetition = eArgRepeatPlain;
1089         // There is only one variant this argument could be; put it into the argument entry.
1090         arg2.push_back (file_arg_host);
1091
1092         // Push the data for the first and the second arguments into the m_arguments vector.
1093         m_arguments.push_back (arg1);
1094         m_arguments.push_back (arg2);
1095     }
1096     
1097     virtual
1098     ~CommandObjectPlatformGetFile ()
1099     {
1100     }
1101     
1102     virtual bool
1103     DoExecute (Args& args, CommandReturnObject &result)
1104     {
1105         // If the number of arguments is incorrect, issue an error message.
1106         if (args.GetArgumentCount() != 2)
1107         {
1108             result.GetErrorStream().Printf("error: required arguments missing; specify both the source and destination file paths\n");
1109             result.SetStatus(eReturnStatusFailed);
1110             return false;
1111         }
1112
1113         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
1114         if (platform_sp)
1115         {
1116             const char *remote_file_path = args.GetArgumentAtIndex(0);
1117             const char *local_file_path = args.GetArgumentAtIndex(1);
1118             Error error = platform_sp->GetFile(FileSpec(remote_file_path, false),
1119                                                FileSpec(local_file_path, false));
1120             if (error.Success())
1121             {
1122                 result.AppendMessageWithFormat("successfully get-file from %s (remote) to %s (host)\n",
1123                                                remote_file_path, local_file_path);
1124                 result.SetStatus (eReturnStatusSuccessFinishResult);
1125             }
1126             else
1127             {
1128                 result.AppendMessageWithFormat("get-file failed: %s\n", error.AsCString());
1129                 result.SetStatus (eReturnStatusFailed);
1130             }
1131         }
1132         else
1133         {
1134             result.AppendError ("no platform currently selected\n");
1135             result.SetStatus (eReturnStatusFailed);
1136         }
1137         return result.Succeeded();
1138     }
1139 };
1140
1141 //----------------------------------------------------------------------
1142 // "platform get-size remote-file-path"
1143 //----------------------------------------------------------------------
1144 class CommandObjectPlatformGetSize : public CommandObjectParsed
1145 {
1146 public:
1147     CommandObjectPlatformGetSize (CommandInterpreter &interpreter) :
1148     CommandObjectParsed (interpreter,
1149                          "platform get-size",
1150                          "Get the file size from the remote end.",
1151                          "platform get-size <remote-file-spec>",
1152                          0)
1153     {
1154         SetHelpLong(
1155 "Examples: \n\
1156 \n\
1157     platform get-size /the/remote/file/path\n\
1158     # Get the file size from the remote end with path /the/remote/file/path.\n");
1159
1160         CommandArgumentEntry arg1;
1161         CommandArgumentData file_arg_remote;
1162     
1163         // Define the first (and only) variant of this arg.
1164         file_arg_remote.arg_type = eArgTypeFilename;
1165         file_arg_remote.arg_repetition = eArgRepeatPlain;
1166         // There is only one variant this argument could be; put it into the argument entry.
1167         arg1.push_back (file_arg_remote);
1168         
1169         // Push the data for the first argument into the m_arguments vector.
1170         m_arguments.push_back (arg1);
1171     }
1172     
1173     virtual
1174     ~CommandObjectPlatformGetSize ()
1175     {
1176     }
1177     
1178     virtual bool
1179     DoExecute (Args& args, CommandReturnObject &result)
1180     {
1181         // If the number of arguments is incorrect, issue an error message.
1182         if (args.GetArgumentCount() != 1)
1183         {
1184             result.GetErrorStream().Printf("error: required argument missing; specify the source file path as the only argument\n");
1185             result.SetStatus(eReturnStatusFailed);
1186             return false;
1187         }
1188
1189         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
1190         if (platform_sp)
1191         {
1192             std::string remote_file_path(args.GetArgumentAtIndex(0));
1193             user_id_t size = platform_sp->GetFileSize(FileSpec(remote_file_path.c_str(), false));
1194             if (size != UINT64_MAX)
1195             {
1196                 result.AppendMessageWithFormat("File size of %s (remote): %" PRIu64 "\n", remote_file_path.c_str(), size);
1197                 result.SetStatus (eReturnStatusSuccessFinishResult);
1198             }
1199             else
1200             {
1201                 result.AppendMessageWithFormat("Eroor getting file size of %s (remote)\n", remote_file_path.c_str());
1202                 result.SetStatus (eReturnStatusFailed);
1203             }
1204         }
1205         else
1206         {
1207             result.AppendError ("no platform currently selected\n");
1208             result.SetStatus (eReturnStatusFailed);
1209         }
1210         return result.Succeeded();
1211     }
1212 };
1213
1214 //----------------------------------------------------------------------
1215 // "platform put-file"
1216 //----------------------------------------------------------------------
1217 class CommandObjectPlatformPutFile : public CommandObjectParsed
1218 {
1219 public:
1220     CommandObjectPlatformPutFile (CommandInterpreter &interpreter) :
1221     CommandObjectParsed (interpreter,
1222                          "platform put-file",
1223                          "Transfer a file from this system to the remote end.",
1224                          NULL,
1225                          0)
1226     {
1227     }
1228     
1229     virtual
1230     ~CommandObjectPlatformPutFile ()
1231     {
1232     }
1233     
1234     virtual bool
1235     DoExecute (Args& args, CommandReturnObject &result)
1236     {
1237         const char* src = args.GetArgumentAtIndex(0);
1238         const char* dst = args.GetArgumentAtIndex(1);
1239
1240         FileSpec src_fs(src, true);
1241         FileSpec dst_fs(dst, false);
1242         
1243         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
1244         if (platform_sp)
1245         {
1246             Error error (platform_sp->PutFile(src_fs, dst_fs));
1247             if (error.Success())
1248             {
1249                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1250             }
1251             else
1252             {
1253                 result.AppendError (error.AsCString());
1254                 result.SetStatus (eReturnStatusFailed);
1255             }
1256         }
1257         else
1258         {
1259             result.AppendError ("no platform currently selected\n");
1260             result.SetStatus (eReturnStatusFailed);
1261         }
1262         return result.Succeeded();
1263     }
1264 };
1265
1266 //----------------------------------------------------------------------
1267 // "platform process launch"
1268 //----------------------------------------------------------------------
1269 class CommandObjectPlatformProcessLaunch : public CommandObjectParsed
1270 {
1271 public:
1272     CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
1273         CommandObjectParsed (interpreter,
1274                              "platform process launch",
1275                              "Launch a new process on a remote platform.",
1276                              "platform process launch program",
1277                              eFlagRequiresTarget | eFlagTryTargetAPILock),
1278         m_options (interpreter)
1279     {
1280     }
1281     
1282     virtual
1283     ~CommandObjectPlatformProcessLaunch ()
1284     {
1285     }
1286     
1287     virtual Options *
1288     GetOptions ()
1289     {
1290         return &m_options;
1291     }
1292     
1293 protected:
1294     virtual bool
1295     DoExecute (Args& args, CommandReturnObject &result)
1296     {
1297         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1298         PlatformSP platform_sp;
1299         if (target)
1300         {   
1301             platform_sp = target->GetPlatform();
1302         }   
1303         if (!platform_sp)
1304         {
1305             platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
1306         }   
1307
1308         if (platform_sp)
1309         {
1310             Error error;
1311             const size_t argc = args.GetArgumentCount();
1312             Target *target = m_exe_ctx.GetTargetPtr();
1313             Module *exe_module = target->GetExecutableModulePointer();
1314             if (exe_module)
1315             {
1316                 m_options.launch_info.GetExecutableFile () = exe_module->GetFileSpec();
1317                 char exe_path[PATH_MAX];
1318                 if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
1319                     m_options.launch_info.GetArguments().AppendArgument (exe_path);
1320                 m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
1321             }
1322
1323             if (argc > 0)
1324             {
1325                 if (m_options.launch_info.GetExecutableFile ())
1326                 {
1327                     // We already have an executable file, so we will use this
1328                     // and all arguments to this function are extra arguments
1329                     m_options.launch_info.GetArguments().AppendArguments (args);
1330                 }
1331                 else
1332                 {
1333                     // We don't have any file yet, so the first argument is our
1334                     // executable, and the rest are program arguments
1335                     const bool first_arg_is_executable = true;
1336                     m_options.launch_info.SetArguments (args, first_arg_is_executable);
1337                 }
1338             }
1339             
1340             if (m_options.launch_info.GetExecutableFile ())
1341             {
1342                 Debugger &debugger = m_interpreter.GetDebugger();
1343
1344                 if (argc == 0)
1345                     target->GetRunArguments(m_options.launch_info.GetArguments());
1346
1347                 ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info, 
1348                                                                  debugger,
1349                                                                  target,
1350                                                                  debugger.GetListener(),
1351                                                                  error));
1352                 if (process_sp && process_sp->IsAlive())
1353                 {
1354                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1355                     return true;
1356                 }
1357                 
1358                 if (error.Success())
1359                     result.AppendError ("process launch failed");
1360                 else
1361                     result.AppendError (error.AsCString());
1362                 result.SetStatus (eReturnStatusFailed);
1363             }
1364             else
1365             {
1366                 result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
1367                 result.SetStatus (eReturnStatusFailed);
1368                 return false;
1369             }
1370         }
1371         else
1372         {
1373             result.AppendError ("no platform is selected\n");
1374         }
1375         return result.Succeeded();
1376     }
1377     
1378 protected:
1379     ProcessLaunchCommandOptions m_options;
1380 };
1381
1382
1383
1384 //----------------------------------------------------------------------
1385 // "platform process list"
1386 //----------------------------------------------------------------------
1387 class CommandObjectPlatformProcessList : public CommandObjectParsed
1388 {
1389 public:
1390     CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
1391         CommandObjectParsed (interpreter, 
1392                              "platform process list",
1393                              "List processes on a remote platform by name, pid, or many other matching attributes.",
1394                              "platform process list",
1395                              0),
1396         m_options (interpreter)
1397     {
1398     }
1399     
1400     virtual
1401     ~CommandObjectPlatformProcessList ()
1402     {
1403     }
1404     
1405     virtual Options *
1406     GetOptions ()
1407     {
1408         return &m_options;
1409     }
1410     
1411 protected:
1412     virtual bool
1413     DoExecute (Args& args, CommandReturnObject &result)
1414     {
1415         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1416         PlatformSP platform_sp;
1417         if (target)
1418         {   
1419             platform_sp = target->GetPlatform();
1420         }   
1421         if (!platform_sp)
1422         {
1423             platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
1424         }   
1425         
1426         if (platform_sp)
1427         {
1428             Error error;
1429             if (args.GetArgumentCount() == 0)
1430             {
1431                 
1432                 if (platform_sp)
1433                 {
1434                     Stream &ostrm = result.GetOutputStream();      
1435
1436                     lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
1437                     if (pid != LLDB_INVALID_PROCESS_ID)
1438                     {
1439                         ProcessInstanceInfo proc_info;
1440                         if (platform_sp->GetProcessInfo (pid, proc_info))
1441                         {
1442                             ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
1443                             proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
1444                             result.SetStatus (eReturnStatusSuccessFinishResult);
1445                         }
1446                         else
1447                         {
1448                             result.AppendErrorWithFormat ("no process found with pid = %" PRIu64 "\n", pid);
1449                             result.SetStatus (eReturnStatusFailed);
1450                         }
1451                     }
1452                     else
1453                     {
1454                         ProcessInstanceInfoList proc_infos;
1455                         const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
1456                         const char *match_desc = NULL;
1457                         const char *match_name = m_options.match_info.GetProcessInfo().GetName();
1458                         if (match_name && match_name[0])
1459                         {
1460                             switch (m_options.match_info.GetNameMatchType())
1461                             {
1462                                 case eNameMatchIgnore: break;
1463                                 case eNameMatchEquals: match_desc = "matched"; break;
1464                                 case eNameMatchContains: match_desc = "contained"; break;
1465                                 case eNameMatchStartsWith: match_desc = "started with"; break;
1466                                 case eNameMatchEndsWith: match_desc = "ended with"; break;
1467                                 case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
1468                             }
1469                         }
1470
1471                         if (matches == 0)
1472                         {
1473                             if (match_desc)
1474                                 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n", 
1475                                                               match_desc,
1476                                                               match_name,
1477                                                               platform_sp->GetPluginName().GetCString());
1478                             else
1479                                 result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetPluginName().GetCString());
1480                             result.SetStatus (eReturnStatusFailed);
1481                         }
1482                         else
1483                         {
1484                             result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"", 
1485                                                             matches,
1486                                                             matches > 1 ? "es were" : " was",
1487                                                             platform_sp->GetName().GetCString());
1488                             if (match_desc)
1489                                 result.AppendMessageWithFormat (" whose name %s \"%s\"", 
1490                                                                 match_desc,
1491                                                                 match_name);
1492                             result.AppendMessageWithFormat ("\n");
1493                             ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
1494                             for (uint32_t i=0; i<matches; ++i)
1495                             {
1496                                 proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
1497                             }
1498                         }
1499                     }
1500                 }
1501             }
1502             else
1503             {
1504                 result.AppendError ("invalid args: process list takes only options\n");
1505                 result.SetStatus (eReturnStatusFailed);
1506             }
1507         }
1508         else
1509         {
1510             result.AppendError ("no platform is selected\n");
1511             result.SetStatus (eReturnStatusFailed);
1512         }
1513         return result.Succeeded();
1514     }
1515     
1516     class CommandOptions : public Options
1517     {
1518     public:
1519         
1520         CommandOptions (CommandInterpreter &interpreter) :
1521             Options (interpreter),
1522             match_info ()
1523         {
1524         }
1525         
1526         virtual
1527         ~CommandOptions ()
1528         {
1529         }
1530         
1531         virtual Error
1532         SetOptionValue (uint32_t option_idx, const char *option_arg)
1533         {
1534             Error error;
1535             const int short_option = m_getopt_table[option_idx].val;
1536             bool success = false;
1537
1538             switch (short_option)
1539             {
1540                 case 'p':
1541                     match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
1542                     if (!success)
1543                         error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
1544                     break;
1545                 
1546                 case 'P':
1547                     match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
1548                     if (!success)
1549                         error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
1550                     break;
1551
1552                 case 'u':
1553                     match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
1554                     if (!success)
1555                         error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
1556                     break;
1557
1558                 case 'U':
1559                     match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
1560                     if (!success)
1561                         error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
1562                     break;
1563
1564                 case 'g':
1565                     match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
1566                     if (!success)
1567                         error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
1568                     break;
1569
1570                 case 'G':
1571                     match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
1572                     if (!success)
1573                         error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
1574                     break;
1575
1576                 case 'a':
1577                     match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
1578                     break;
1579
1580                 case 'n':
1581                     match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
1582                     match_info.SetNameMatchType (eNameMatchEquals);
1583                     break;
1584
1585                 case 'e':
1586                     match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
1587                     match_info.SetNameMatchType (eNameMatchEndsWith);
1588                     break;
1589
1590                 case 's':
1591                     match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
1592                     match_info.SetNameMatchType (eNameMatchStartsWith);
1593                     break;
1594                     
1595                 case 'c':
1596                     match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
1597                     match_info.SetNameMatchType (eNameMatchContains);
1598                     break;
1599                     
1600                 case 'r':
1601                     match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
1602                     match_info.SetNameMatchType (eNameMatchRegularExpression);
1603                     break;
1604
1605                 case 'A':
1606                     show_args = true;
1607                     break;
1608
1609                 case 'v':
1610                     verbose = true;
1611                     break;
1612
1613                 default:
1614                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1615                     break;
1616             }
1617             
1618             return error;
1619         }
1620         
1621         void
1622         OptionParsingStarting ()
1623         {
1624             match_info.Clear();
1625             show_args = false;
1626             verbose = false;
1627         }
1628         
1629         const OptionDefinition*
1630         GetDefinitions ()
1631         {
1632             return g_option_table;
1633         }
1634         
1635         // Options table: Required for subclasses of Options.
1636         
1637         static OptionDefinition g_option_table[];
1638         
1639         // Instance variables to hold the values for command options.
1640         
1641         ProcessInstanceInfoMatch match_info;
1642         bool show_args;
1643         bool verbose;
1644     };
1645     CommandOptions m_options;
1646 };
1647
1648 OptionDefinition
1649 CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
1650 {
1651 { LLDB_OPT_SET_1            , false, "pid"        , 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid              , "List the process info for a specific process ID." },
1652 { LLDB_OPT_SET_2            , true , "name"       , 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName      , "Find processes with executable basenames that match a string." },
1653 { LLDB_OPT_SET_3            , true , "ends-with"  , 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName      , "Find processes with executable basenames that end with a string." },
1654 { LLDB_OPT_SET_4            , true , "starts-with", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName      , "Find processes with executable basenames that start with a string." },
1655 { LLDB_OPT_SET_5            , true , "contains"   , 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName      , "Find processes with executable basenames that contain a string." },
1656 { LLDB_OPT_SET_6            , true , "regex"      , 'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." },
1657 { LLDB_OPT_SET_FROM_TO(2, 6), false, "parent"     , 'P', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid              , "Find processes that have a matching parent process ID." },
1658 { LLDB_OPT_SET_FROM_TO(2, 6), false, "uid"        , 'u', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger  , "Find processes that have a matching user ID." },
1659 { LLDB_OPT_SET_FROM_TO(2, 6), false, "euid"       , 'U', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger  , "Find processes that have a matching effective user ID." },
1660 { LLDB_OPT_SET_FROM_TO(2, 6), false, "gid"        , 'g', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger  , "Find processes that have a matching group ID." },
1661 { LLDB_OPT_SET_FROM_TO(2, 6), false, "egid"       , 'G', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger  , "Find processes that have a matching effective group ID." },
1662 { LLDB_OPT_SET_FROM_TO(2, 6), false, "arch"       , 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeArchitecture     , "Find processes that have a matching architecture." },
1663 { LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args"  , 'A', OptionParser::eNoArgument      , NULL, 0, eArgTypeNone             , "Show process arguments instead of the process executable basename." },
1664 { LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose"    , 'v', OptionParser::eNoArgument      , NULL, 0, eArgTypeNone             , "Enable verbose output." },
1665 { 0                         , false, NULL         ,  0 , 0                , NULL, 0, eArgTypeNone             , NULL }
1666 };
1667
1668 //----------------------------------------------------------------------
1669 // "platform process info"
1670 //----------------------------------------------------------------------
1671 class CommandObjectPlatformProcessInfo : public CommandObjectParsed
1672 {
1673 public:
1674     CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
1675     CommandObjectParsed (interpreter, 
1676                          "platform process info",
1677                          "Get detailed information for one or more process by process ID.",
1678                          "platform process info <pid> [<pid> <pid> ...]",
1679                          0)
1680     {
1681         CommandArgumentEntry arg;
1682         CommandArgumentData pid_args;
1683         
1684         // Define the first (and only) variant of this arg.
1685         pid_args.arg_type = eArgTypePid;
1686         pid_args.arg_repetition = eArgRepeatStar;
1687         
1688         // There is only one variant this argument could be; put it into the argument entry.
1689         arg.push_back (pid_args);
1690         
1691         // Push the data for the first argument into the m_arguments vector.
1692         m_arguments.push_back (arg);
1693     }
1694     
1695     virtual
1696     ~CommandObjectPlatformProcessInfo ()
1697     {
1698     }
1699     
1700 protected:
1701     virtual bool
1702     DoExecute (Args& args, CommandReturnObject &result)
1703     {
1704         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1705         PlatformSP platform_sp;
1706         if (target)
1707         {   
1708             platform_sp = target->GetPlatform();
1709         }   
1710         if (!platform_sp)
1711         {
1712             platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
1713         }   
1714
1715         if (platform_sp)
1716         {
1717             const size_t argc = args.GetArgumentCount();
1718             if (argc > 0)
1719             {
1720                 Error error;
1721                 
1722                 if (platform_sp->IsConnected())
1723                 {
1724                     Stream &ostrm = result.GetOutputStream();      
1725                     bool success;
1726                     for (size_t i=0; i<argc; ++ i)
1727                     {
1728                         const char *arg = args.GetArgumentAtIndex(i);
1729                         lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
1730                         if (success)
1731                         {
1732                             ProcessInstanceInfo proc_info;
1733                             if (platform_sp->GetProcessInfo (pid, proc_info))
1734                             {
1735                                 ostrm.Printf ("Process information for process %" PRIu64 ":\n", pid);
1736                                 proc_info.Dump (ostrm, platform_sp.get());
1737                             }
1738                             else
1739                             {
1740                                 ostrm.Printf ("error: no process information is available for process %" PRIu64 "\n", pid);
1741                             }
1742                             ostrm.EOL();
1743                         }
1744                         else
1745                         {
1746                             result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg);
1747                             result.SetStatus (eReturnStatusFailed);            
1748                             break;
1749                         }
1750                     }
1751                 }
1752                 else
1753                 {
1754                     // Not connected...
1755                     result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetPluginName().GetCString());
1756                     result.SetStatus (eReturnStatusFailed);            
1757                 }
1758             }
1759             else
1760             {
1761                 // No args
1762                 result.AppendError ("one or more process id(s) must be specified");
1763                 result.SetStatus (eReturnStatusFailed);            
1764             }
1765         }
1766         else
1767         {
1768             result.AppendError ("no platform is currently selected");
1769             result.SetStatus (eReturnStatusFailed);            
1770         }
1771         return result.Succeeded();
1772     }
1773 };
1774
1775 class CommandObjectPlatformProcessAttach : public CommandObjectParsed
1776 {
1777 public:
1778     
1779     class CommandOptions : public Options
1780     {
1781     public:
1782         
1783         CommandOptions (CommandInterpreter &interpreter) :
1784         Options(interpreter)
1785         {
1786             // Keep default values of all options in one place: OptionParsingStarting ()
1787             OptionParsingStarting ();
1788         }
1789         
1790         ~CommandOptions ()
1791         {
1792         }
1793         
1794         Error
1795         SetOptionValue (uint32_t option_idx, const char *option_arg)
1796         {
1797             Error error;
1798             char short_option = (char) m_getopt_table[option_idx].val;
1799             bool success = false;
1800             switch (short_option)
1801             {
1802                 case 'p':   
1803                 {
1804                     lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
1805                     if (!success || pid == LLDB_INVALID_PROCESS_ID)
1806                     {
1807                         error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
1808                     }
1809                     else
1810                     {
1811                         attach_info.SetProcessID (pid);
1812                     }
1813                 }
1814                     break;
1815                     
1816                 case 'P':
1817                     attach_info.SetProcessPluginName (option_arg);
1818                     break;
1819                     
1820                 case 'n': 
1821                     attach_info.GetExecutableFile().SetFile(option_arg, false);
1822                     break;
1823                     
1824                 case 'w':   
1825                     attach_info.SetWaitForLaunch(true);
1826                     break;
1827                     
1828                 default:
1829                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1830                     break;
1831             }
1832             return error;
1833         }
1834         
1835         void
1836         OptionParsingStarting ()
1837         {
1838             attach_info.Clear();
1839         }
1840         
1841         const OptionDefinition*
1842         GetDefinitions ()
1843         {
1844             return g_option_table;
1845         }
1846         
1847         virtual bool
1848         HandleOptionArgumentCompletion (Args &input,
1849                                         int cursor_index,
1850                                         int char_pos,
1851                                         OptionElementVector &opt_element_vector,
1852                                         int opt_element_index,
1853                                         int match_start_point,
1854                                         int max_return_elements,
1855                                         bool &word_complete,
1856                                         StringList &matches)
1857         {
1858             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
1859             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
1860             
1861             // We are only completing the name option for now...
1862             
1863             const OptionDefinition *opt_defs = GetDefinitions();
1864             if (opt_defs[opt_defs_index].short_option == 'n')
1865             {
1866                 // Are we in the name?
1867                 
1868                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
1869                 // use the default plugin.
1870                 
1871                 const char *partial_name = NULL;
1872                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
1873                 
1874                 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
1875                 if (platform_sp)
1876                 {
1877                     ProcessInstanceInfoList process_infos;
1878                     ProcessInstanceInfoMatch match_info;
1879                     if (partial_name)
1880                     {
1881                         match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
1882                         match_info.SetNameMatchType(eNameMatchStartsWith);
1883                     }
1884                     platform_sp->FindProcesses (match_info, process_infos);
1885                     const uint32_t num_matches = process_infos.GetSize();
1886                     if (num_matches > 0)
1887                     {
1888                         for (uint32_t i=0; i<num_matches; ++i)
1889                         {
1890                             matches.AppendString (process_infos.GetProcessNameAtIndex(i), 
1891                                                   process_infos.GetProcessNameLengthAtIndex(i));
1892                         }
1893                     }
1894                 }
1895             }
1896             
1897             return false;
1898         }
1899         
1900         // Options table: Required for subclasses of Options.
1901         
1902         static OptionDefinition g_option_table[];
1903         
1904         // Instance variables to hold the values for command options.
1905         
1906         ProcessAttachInfo attach_info;
1907     };
1908     
1909     CommandObjectPlatformProcessAttach (CommandInterpreter &interpreter) :
1910     CommandObjectParsed (interpreter,
1911                          "platform process attach",
1912                          "Attach to a process.",
1913                          "platform process attach <cmd-options>"),
1914     m_options (interpreter)
1915     {
1916     }
1917     
1918     ~CommandObjectPlatformProcessAttach ()
1919     {
1920     }
1921     
1922     bool
1923     DoExecute (Args& command,
1924              CommandReturnObject &result)
1925     {
1926         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
1927         if (platform_sp)
1928         {
1929             Error err;
1930             ProcessSP remote_process_sp =
1931             platform_sp->Attach(m_options.attach_info, m_interpreter.GetDebugger(), NULL, m_interpreter.GetDebugger().GetListener(), err);
1932             if (err.Fail())
1933             {
1934                 result.AppendError(err.AsCString());
1935                 result.SetStatus (eReturnStatusFailed);
1936             }
1937             else if (remote_process_sp.get() == NULL)
1938             {
1939                 result.AppendError("could not attach: unknown reason");
1940                 result.SetStatus (eReturnStatusFailed);
1941             }
1942             else
1943                 result.SetStatus (eReturnStatusSuccessFinishResult);
1944         }
1945         else
1946         {
1947             result.AppendError ("no platform is currently selected");
1948             result.SetStatus (eReturnStatusFailed);            
1949         }
1950         return result.Succeeded();
1951     }
1952     
1953     Options *
1954     GetOptions ()
1955     {
1956         return &m_options;
1957     }
1958     
1959 protected:
1960     
1961     CommandOptions m_options;
1962 };
1963
1964
1965 OptionDefinition
1966 CommandObjectPlatformProcessAttach::CommandOptions::g_option_table[] =
1967 {
1968     { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
1969     { LLDB_OPT_SET_1,   false, "pid",    'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid,           "The process ID of an existing process to attach to."},
1970     { LLDB_OPT_SET_2,   false, "name",   'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
1971     { LLDB_OPT_SET_2,   false, "waitfor",'w', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone,              "Wait for the the process with <process-name> to launch."},
1972     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1973 };
1974
1975
1976 class CommandObjectPlatformProcess : public CommandObjectMultiword
1977 {
1978 public:
1979     //------------------------------------------------------------------
1980     // Constructors and Destructors
1981     //------------------------------------------------------------------
1982      CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
1983         CommandObjectMultiword (interpreter,
1984                                 "platform process",
1985                                 "A set of commands to query, launch and attach to platform processes",
1986                                 "platform process [attach|launch|list] ...")
1987     {
1988         LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
1989         LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
1990         LoadSubCommand ("info"  , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
1991         LoadSubCommand ("list"  , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
1992
1993     }
1994     
1995     virtual
1996     ~CommandObjectPlatformProcess ()
1997     {
1998     }
1999     
2000 private:
2001     //------------------------------------------------------------------
2002     // For CommandObjectPlatform only
2003     //------------------------------------------------------------------
2004     DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
2005 };
2006
2007 //----------------------------------------------------------------------
2008 // "platform shell"
2009 //----------------------------------------------------------------------
2010 class CommandObjectPlatformShell : public CommandObjectRaw
2011 {
2012 public:
2013     
2014     class CommandOptions : public Options
2015     {
2016     public:
2017         
2018         CommandOptions (CommandInterpreter &interpreter) :
2019         Options(interpreter),
2020         timeout(10)
2021         {
2022         }
2023         
2024         virtual
2025         ~CommandOptions ()
2026         {
2027         }
2028         
2029         virtual uint32_t
2030         GetNumDefinitions ()
2031         {
2032             return 1;
2033         }
2034         
2035         virtual const OptionDefinition*
2036         GetDefinitions ()
2037         {
2038             return g_option_table;
2039         }
2040         
2041         virtual Error
2042         SetOptionValue (uint32_t option_idx,
2043                         const char *option_value)
2044         {
2045             Error error;
2046             
2047             const char short_option = (char) g_option_table[option_idx].short_option;
2048             
2049             switch (short_option)
2050             {
2051                 case 't':
2052                 {
2053                     bool success;
2054                     timeout = Args::StringToUInt32(option_value, 10, 10, &success);
2055                     if (!success)
2056                         error.SetErrorStringWithFormat("could not convert \"%s\" to a numeric value.", option_value);
2057                     break;
2058                 }
2059                 default:
2060                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2061                     break;
2062             }
2063             
2064             return error;
2065         }
2066         
2067         virtual void
2068         OptionParsingStarting ()
2069         {
2070         }
2071         
2072         // Options table: Required for subclasses of Options.
2073         
2074         static OptionDefinition g_option_table[];
2075         uint32_t timeout;
2076     };
2077     
2078     CommandObjectPlatformShell (CommandInterpreter &interpreter) :
2079     CommandObjectRaw (interpreter, 
2080                       "platform shell",
2081                       "Run a shell command on a the selected platform.",
2082                       "platform shell <shell-command>",
2083                       0),
2084     m_options(interpreter)
2085     {
2086     }
2087     
2088     virtual
2089     ~CommandObjectPlatformShell ()
2090     {
2091     }
2092     
2093     virtual
2094     Options *
2095     GetOptions ()
2096     {
2097         return &m_options;
2098     }
2099     
2100     virtual bool
2101     DoExecute (const char *raw_command_line, CommandReturnObject &result)
2102     {
2103         m_options.NotifyOptionParsingStarting();
2104         
2105         const char* expr = NULL;
2106
2107         // Print out an usage syntax on an empty command line.
2108         if (raw_command_line[0] == '\0')
2109         {
2110             result.GetOutputStream().Printf("%s\n", this->GetSyntax());
2111             return true;
2112         }
2113
2114         if (raw_command_line[0] == '-')
2115         {
2116             // We have some options and these options MUST end with --.
2117             const char *end_options = NULL;
2118             const char *s = raw_command_line;
2119             while (s && s[0])
2120             {
2121                 end_options = ::strstr (s, "--");
2122                 if (end_options)
2123                 {
2124                     end_options += 2; // Get past the "--"
2125                     if (::isspace (end_options[0]))
2126                     {
2127                         expr = end_options;
2128                         while (::isspace (*expr))
2129                             ++expr;
2130                         break;
2131                     }
2132                 }
2133                 s = end_options;
2134             }
2135             
2136             if (end_options)
2137             {
2138                 Args args (raw_command_line, end_options - raw_command_line);
2139                 if (!ParseOptions (args, result))
2140                     return false;
2141             }
2142         }
2143         
2144         if (expr == NULL)
2145             expr = raw_command_line;
2146         
2147         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
2148         Error error;
2149         if (platform_sp)
2150         {
2151             const char *working_dir = NULL;
2152             std::string output;
2153             int status = -1;
2154             int signo = -1;
2155             error = (platform_sp->RunShellCommand (expr, working_dir, &status, &signo, &output, m_options.timeout));
2156             if (!output.empty())
2157                 result.GetOutputStream().PutCString(output.c_str());
2158             if (status > 0)
2159             {
2160                 if (signo > 0)
2161                 {
2162                     const char *signo_cstr = Host::GetSignalAsCString(signo);
2163                     if (signo_cstr)
2164                         result.GetOutputStream().Printf("error: command returned with status %i and signal %s\n", status, signo_cstr);
2165                     else
2166                         result.GetOutputStream().Printf("error: command returned with status %i and signal %i\n", status, signo);
2167                 }
2168                 else
2169                     result.GetOutputStream().Printf("error: command returned with status %i\n", status);
2170             }
2171         }
2172         else
2173         {
2174             result.GetOutputStream().Printf("error: cannot run remote shell commands without a platform\n");
2175             error.SetErrorString("error: cannot run remote shell commands without a platform");
2176         }
2177
2178         if (error.Fail())
2179         {
2180             result.AppendError(error.AsCString());
2181             result.SetStatus (eReturnStatusFailed);
2182         }
2183         else
2184         {
2185             result.SetStatus (eReturnStatusSuccessFinishResult);
2186         }
2187         return true;
2188     }
2189     CommandOptions m_options;
2190 };
2191
2192 OptionDefinition
2193 CommandObjectPlatformShell::CommandOptions::g_option_table[] =
2194 {
2195     { LLDB_OPT_SET_ALL, false, "timeout",      't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeValue,    "Seconds to wait for the remote host to finish running the command."},
2196     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2197 };
2198
2199
2200 //----------------------------------------------------------------------
2201 // "platform install" - install a target to a remote end
2202 //----------------------------------------------------------------------
2203 class CommandObjectPlatformInstall : public CommandObjectParsed
2204 {
2205 public:
2206     CommandObjectPlatformInstall (CommandInterpreter &interpreter) :
2207     CommandObjectParsed (interpreter,
2208                          "platform target-install",
2209                          "Install a target (bundle or executable file) to the remote end.",
2210                          "platform target-install <local-thing> <remote-sandbox>",
2211                          0)
2212     {
2213     }
2214     
2215     virtual
2216     ~CommandObjectPlatformInstall ()
2217     {
2218     }
2219     
2220     virtual bool
2221     DoExecute (Args& args, CommandReturnObject &result)
2222     {
2223         if (args.GetArgumentCount() != 2)
2224         {
2225             result.AppendError("platform target-install takes two arguments");
2226             result.SetStatus(eReturnStatusFailed);
2227             return false;
2228         }
2229         // TODO: move the bulk of this code over to the platform itself
2230         FileSpec src(args.GetArgumentAtIndex(0), true);
2231         FileSpec dst(args.GetArgumentAtIndex(1), false);
2232         if (src.Exists() == false)
2233         {
2234             result.AppendError("source location does not exist or is not accessible");
2235             result.SetStatus(eReturnStatusFailed);
2236             return false;
2237         }
2238         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
2239         if (!platform_sp)
2240         {
2241             result.AppendError ("no platform currently selected");
2242             result.SetStatus (eReturnStatusFailed);
2243             return false;
2244         }
2245         
2246         Error error = platform_sp->Install(src, dst);
2247         if (error.Success())
2248         {
2249             result.SetStatus(eReturnStatusSuccessFinishNoResult);
2250         }
2251         else
2252         {
2253             result.AppendErrorWithFormat("install failed: %s", error.AsCString());
2254             result.SetStatus(eReturnStatusFailed);
2255         }
2256         return result.Succeeded();
2257     }
2258 private:
2259
2260 };
2261
2262 //----------------------------------------------------------------------
2263 // CommandObjectPlatform constructor
2264 //----------------------------------------------------------------------
2265 CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
2266     CommandObjectMultiword (interpreter,
2267                             "platform",
2268                             "A set of commands to manage and create platforms.",
2269                             "platform [connect|disconnect|info|list|status|select] ...")
2270 {
2271     LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
2272     LoadSubCommand ("list"  , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
2273     LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
2274     LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
2275     LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
2276     LoadSubCommand ("settings", CommandObjectSP (new CommandObjectPlatformSettings (interpreter)));
2277 #ifdef LLDB_CONFIGURATION_DEBUG
2278     LoadSubCommand ("mkdir", CommandObjectSP (new CommandObjectPlatformMkDir (interpreter)));
2279     LoadSubCommand ("file", CommandObjectSP (new CommandObjectPlatformFile (interpreter)));
2280     LoadSubCommand ("get-file", CommandObjectSP (new CommandObjectPlatformGetFile (interpreter)));
2281     LoadSubCommand ("get-size", CommandObjectSP (new CommandObjectPlatformGetSize (interpreter)));
2282     LoadSubCommand ("put-file", CommandObjectSP (new CommandObjectPlatformPutFile (interpreter)));
2283 #endif
2284     LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
2285     LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter)));
2286     LoadSubCommand ("target-install", CommandObjectSP (new CommandObjectPlatformInstall (interpreter)));
2287 }
2288
2289
2290 //----------------------------------------------------------------------
2291 // Destructor
2292 //----------------------------------------------------------------------
2293 CommandObjectPlatform::~CommandObjectPlatform()
2294 {
2295 }