1 //
2 // Copyright (c) 2010-2023 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using System.Collections.Generic;
10 using Antmicro.Renode.UserInterface.Tokenizer;
11 using AntShell.Commands;
12 using Antmicro.Renode.Core;
13 using System.Linq;
14 using Antmicro.Renode.Utilities;
15 
16 namespace Antmicro.Renode.UserInterface.Commands
17 {
18     public class MachCommand : Command
19     {
PrintHelp(ICommandInteraction writer)20         public override void PrintHelp(ICommandInteraction writer)
21         {
22             base.PrintHelp(writer);
23             writer.WriteLine();
24             var currentMachine = GetCurrentMachine();
25             if(currentMachine == null)
26             {
27                 writer.WriteError("No machine selected.");
28             }
29             else
30             {
31                 writer.WriteLine(string.Format("Current machine: {0}", EmulationManager.Instance.CurrentEmulation[currentMachine]));
32             }
33             if(EmulationManager.Instance.CurrentEmulation.MachinesCount > 0)
34             {
35                 writer.WriteLine("Available machines:");
36                 var emu = EmulationManager.Instance.CurrentEmulation;
37                 var longestNameLength = emu.Machines.Max(m => emu[m].Length);
38                 var i = 0;
39                 foreach(var machine in emu.Machines)
40                 {
41                     writer.WriteLine(string.Format("\t{2}: {0,-" + longestNameLength + "} {1}", emu[machine], machine.Platform != null ? string.Format("[{0}]", machine.Platform.Name) : string.Empty, i++));
42                 }
43             }
44             writer.WriteLine();
45             writer.WriteLine("You can use the following commands:");
46             writer.WriteLine("'mach set [\"name\"|number]'\tto enable the given machine");
47             writer.WriteLine("'mach add \"name\"'\tto create a new machine with the specified name");
48             writer.WriteLine("'mach rem \"name\"'\tto remove a machine");
49             writer.WriteLine("'mach create'\tto create a new machine with generic name and switch to it");
50             writer.WriteLine("'mach clear'\tto clear the current selection");
51         }
52 
53         [Runnable]
Run(ICommandInteraction writer, [Values(R)] LiteralToken action, DecimalIntegerToken number)54         public void Run(ICommandInteraction writer, [Values("set")] LiteralToken action, DecimalIntegerToken number)
55         {
56             var machines = EmulationManager.Instance.CurrentEmulation.Machines.ToArray();
57             if(machines.Length > number.Value && number.Value >= 0)
58             {
59                 SetCurrentMachine(machines[number.Value]);
60             }
61             else
62             {
63                 writer.WriteError("Wrong machine number. Type {0} to show a list of available machines.".FormatWith(Name));
64             }
65 
66         }
67 
68         [Runnable]
Run(ICommandInteraction writer, [Values(R, R, R, R)] LiteralToken action, StringToken name)69         public void Run(ICommandInteraction writer, [Values("set", "add", "rem", "create")] LiteralToken action, StringToken name)
70         {
71             IMachine machine;
72             switch(action.Value)
73             {
74             case "add":
75                 machine = new Machine();
76                 EmulationManager.Instance.CurrentEmulation.AddMachine(machine, name.Value);
77                 if(GetCurrentMachine() == null)
78                 {
79                     SetCurrentMachine(machine);
80                 }
81                 break;
82             case "set":
83                 if(!EmulationManager.Instance.CurrentEmulation.TryGetMachineByName(name.Value, out var machineToSet))
84                 {
85                     writer.WriteError(string.Format("Machine {0} not found.", name.Value));
86                     break;
87                 }
88                 SetCurrentMachine(machineToSet);
89                 break;
90             case "rem":
91                 if(!EmulationManager.Instance.CurrentEmulation.TryGetMachineByName(name.Value, out var machineToRemove))
92                 {
93                     writer.WriteError(string.Format("Machine {0} not found.", name.Value));
94                     break;
95                 }
96                 EmulationManager.Instance.CurrentEmulation.RemoveMachine(name.Value);
97                 if(GetCurrentMachine() == machineToRemove)
98                 {
99                     SetCurrentMachine(null);
100                 }
101                 break;
102             case "create":
103                 machine = new Machine();
104                 EmulationManager.Instance.CurrentEmulation.AddMachine(machine, name.Value);
105                 SetCurrentMachine(machine);
106                 break;
107             }
108         }
109 
110         [Runnable]
Run(ICommandInteraction writer, [Values(R, R)] LiteralToken action)111         public void Run(ICommandInteraction writer, [Values("create", "clear")] LiteralToken action)
112         {
113             switch(action.Value)
114             {
115             case "clear":
116                 SetCurrentMachine(null);
117                 break;
118             case "create":
119                 var machine = new Machine();
120                 EmulationManager.Instance.CurrentEmulation.AddMachine(machine);
121                 SetCurrentMachine(machine);
122                 break;
123             }
124         }
125 
126         private readonly Func<IMachine> GetCurrentMachine;
127         private readonly Action<IMachine> SetCurrentMachine;
128 
MachCommand(Monitor monitor, Func<IMachine> getCurrentMachine, Action<IMachine> setCurrentMachine)129         public MachCommand(Monitor monitor, Func<IMachine> getCurrentMachine, Action<IMachine> setCurrentMachine)
130             : base(monitor, "mach", "list and manipulate machines available in the environment.")
131         {
132             GetCurrentMachine = getCurrentMachine;
133             SetCurrentMachine = setCurrentMachine;
134         }
135     }
136 }
137 
138