0032308: Configuration - make Xlib dependency optional
[occt.git] / src / Draw / Draw_MessageCommands.cxx
1 // Copyright (c) 2020 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <Draw.hxx>
15 #include <Draw_Printer.hxx>
16
17 #include <Message.hxx>
18 #include <Message_Messenger.hxx>
19 #include <Message_PrinterOStream.hxx>
20 #include <Message_PrinterSystemLog.hxx>
21 #include <Message_PrinterToReport.hxx>
22 #include <Message_Report.hxx>
23 #include <NCollection_Shared.hxx>
24 #include <Standard_Dump.hxx>
25
26 //==============================================================================
27 //function : printerType
28 //purpose  :
29 //==============================================================================
30 static Standard_Boolean printerType (const TCollection_AsciiString& theTypeName,
31                                      Handle(Standard_Type)& theType)
32 {
33   if (theTypeName == "ostream")
34   {
35     theType = STANDARD_TYPE(Message_PrinterOStream);
36     return Standard_True;
37   }
38   else if (theTypeName == "systemlog")
39   {
40     theType = STANDARD_TYPE(Message_PrinterSystemLog);
41     return Standard_True;
42   }
43   else if (theTypeName == "report")
44   {
45     theType = STANDARD_TYPE(Message_PrinterToReport);
46     return Standard_True;
47   }
48   else if (theTypeName == "draw")
49   {
50     theType = STANDARD_TYPE(Draw_Printer);
51     return Standard_True;
52   }
53
54   return Standard_False;
55 }
56
57 //==============================================================================
58 //function : createPrinter
59 //purpose  :
60 //==============================================================================
61 static Handle(Message_Printer) createPrinter (const Handle(Standard_Type)& theType, Draw_Interpretor& theDI)
62 {
63   const TCollection_AsciiString aTypeName (theType->Name());
64   if (aTypeName == STANDARD_TYPE(Message_PrinterOStream)->Name())
65   {
66     return new Message_PrinterOStream();
67   }
68   else if (aTypeName == STANDARD_TYPE(Message_PrinterSystemLog)->Name())
69   {
70     return new Message_PrinterSystemLog ("draw_messages");
71   }
72   else if (aTypeName == STANDARD_TYPE(Message_PrinterToReport)->Name())
73   {
74     Handle(Message_PrinterToReport) aMessagePrinter = new Message_PrinterToReport();
75     const Handle(Message_Report)& aReport = Message::DefaultReport (Standard_True);
76     aMessagePrinter->SetReport (aReport);
77     return aMessagePrinter;
78   }
79   else if (aTypeName == STANDARD_TYPE(Draw_Printer)->Name())
80   {
81     return new Draw_Printer (theDI);
82   }
83   return Handle(Message_Printer)();
84 }
85
86 //==============================================================================
87 //function : SendMessage
88 //purpose  :
89 //==============================================================================
90 static Standard_Integer SendMessage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
91 {
92   if (theArgNb < 2)
93   {
94     theDI << "Error: wrong number of arguments";
95     return 1;
96   }
97
98   const Handle(Message_Messenger)& aMessenger = Message::DefaultMessenger();
99   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
100   {
101     TCollection_AsciiString anArg (theArgVec[anArgIter]);
102     anArg.LowerCase();
103     aMessenger->Send (anArg);
104   }
105
106   return 0;
107 }
108
109 //==============================================================================
110 //function : PrintMessenger
111 //purpose  :
112 //==============================================================================
113 static Standard_Integer PrintMessenger (Draw_Interpretor& theDI, Standard_Integer, const char**)
114 {
115   const Handle(Message_Messenger)& aMessenger = Message::DefaultMessenger();
116
117   Standard_SStream aSStream;
118   aMessenger->DumpJson (aSStream);
119   theDI << aSStream;
120   std::cout << aSStream.str() << std::endl;
121
122   return 0;
123 }
124
125 //==============================================================================
126 //function : SetMessagePrinter
127 //purpose  :
128 //==============================================================================
129 static Standard_Integer SetMessagePrinter (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
130 {
131   if (theArgNb < 2)
132   {
133     theDI << "Error: wrong number of arguments";
134     return 1;
135   }
136
137   Standard_Boolean toAddPrinter = Standard_True;
138   NCollection_List<TCollection_AsciiString> aPrinterTypes;
139   const Handle(Message_Messenger)& aMessenger = Message::DefaultMessenger();
140   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
141   {
142     TCollection_AsciiString anArg (theArgVec[anArgIter]);
143     anArg.LowerCase();
144     if (anArg == "-state")
145     {
146       if (anArgIter + 1 < theArgNb
147        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toAddPrinter))
148       {
149         ++anArgIter;
150       }
151     }
152     else if (anArg == "-type"
153           && anArgIter + 1 < theArgNb)
154     {
155       TCollection_AsciiString aVal (theArgVec[++anArgIter]);
156       aPrinterTypes.Append (aVal);
157     }
158     else
159     {
160       theDI << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
161       return 1;
162     }
163   }
164
165   for (NCollection_List<TCollection_AsciiString>::Iterator anIterator (aPrinterTypes); anIterator.More(); anIterator.Next())
166   {
167     Handle(Standard_Type) aPrinterType;
168     if (!printerType (anIterator.Value(), aPrinterType))
169     {
170       theDI << "Syntax error: unknown printer type '" << anIterator.Value() << "'";
171       return 1;
172     }
173
174     if (toAddPrinter)
175     {
176       Handle(Message_Printer) aPrinter = createPrinter (aPrinterType, theDI);
177       aMessenger->AddPrinter (aPrinter);
178       if (!Handle(Message_PrinterToReport)::DownCast(aPrinter).IsNull())
179       {
180         Message::DefaultReport (Standard_False)->UpdateActiveInMessenger();
181       }
182     }
183     else
184     {
185       aMessenger->RemovePrinters (aPrinterType);
186     }
187   }
188   return 0;
189 }
190
191 //==============================================================================
192 //function : ClearReport
193 //purpose  :
194 //==============================================================================
195 static Standard_Integer ClearReport(Draw_Interpretor& theDI, Standard_Integer theArgNb, const char**)
196 {
197   if (theArgNb < 1)
198   {
199     theDI << "Error: wrong number of arguments";
200     return 1;
201   }
202
203   const Handle(Message_Report)& aReport = Message::DefaultReport (Standard_False);
204   if (aReport.IsNull())
205   {
206     theDI << "Error: report is no created";
207     return 1;
208   }
209
210   aReport->Clear();
211   return 0;
212 }
213
214 //==============================================================================
215 //function : SetReportMetric
216 //purpose  :
217 //==============================================================================
218 static Standard_Integer SetReportMetric(Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
219 {
220   if (theArgNb < 1)
221   {
222     theDI << "Error: wrong number of arguments";
223     return 1;
224   }
225
226   const Handle(Message_Report)& aReport = Message::DefaultReport (Standard_True);
227   if (aReport.IsNull())
228   {
229     return 1;
230   }
231
232   aReport->ClearMetrics();
233   for (int i = 1; i < theArgNb; i++)
234   {
235     Standard_Integer aMetricId = Draw::Atoi (theArgVec[i]);
236     if (aMetricId < Message_MetricType_ThreadCPUUserTime || aMetricId > Message_MetricType_MemHeapUsage)
237     {
238       theDI << "Error: unrecognized message metric: " << aMetricId;
239       return 1;
240     }
241     aReport->SetActiveMetric ((Message_MetricType)aMetricId, Standard_True);
242   }
243   return 0;
244 }
245
246 //==============================================================================
247 //function : CollectMetricMessages
248 //purpose  :
249 //==============================================================================
250 static Standard_Integer CollectMetricMessages(Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
251 {
252   static Handle(NCollection_Shared<Message_Level>) MyLevel;
253
254   if (theArgNb < 1)
255   {
256     theDI << "Error: wrong number of arguments";
257     return 1;
258   }
259
260   Standard_Boolean toActivate = Standard_False;
261   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
262   {
263     TCollection_AsciiString anArg (theArgVec[anArgIter]);
264     anArg.LowerCase();
265     if (anArg == "-activate")
266     {
267       if (anArgIter + 1 < theArgNb
268        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toActivate))
269       {
270         ++anArgIter;
271       }
272     }
273   }
274   if (toActivate)
275   {
276     if (!MyLevel.IsNull())
277     {
278       theDI << "Error: collecting already activated";
279       return 1;
280     }
281     MyLevel = new NCollection_Shared<Message_Level>("Level");
282   }
283   else
284   {
285     if (!MyLevel)
286     {
287       theDI << "Error: collecting was not activated";
288       return 1;
289     }
290     MyLevel.Nullify();
291     MyLevel = 0;
292   }
293   return 0;
294 }
295
296 //==============================================================================
297 //function : PrintReport
298 //purpose  :
299 //==============================================================================
300 static Standard_Integer PrintReport(Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
301 {
302   if (theArgNb < 1)
303   {
304     theDI << "Error: wrong number of arguments";
305     return 1;
306   }
307
308   const Handle(Message_Report)& aReport = Message::DefaultReport (Standard_False);
309   if (aReport.IsNull())
310   {
311     theDI << "Error: report is no created";
312     return 1;
313   }
314
315   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
316   {
317     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
318     anArgCase.LowerCase();
319     if (anArgCase == "-messenger")
320     {
321       aReport->SendMessages (Message::DefaultMessenger());
322     }
323     else if (anArgCase == "-dump"
324           || anArgCase == "-print")
325     {
326       Standard_SStream aSStream;
327       aReport->Dump (aSStream);
328       theDI << aSStream;
329     }
330     else if (anArgCase == "-dumpjson")
331     {
332       Standard_SStream aSStream;
333       aReport->DumpJson (aSStream);
334       theDI << aSStream;
335     }
336   }
337
338   return 0;
339 }
340
341 void Draw::MessageCommands(Draw_Interpretor& theCommands)
342 {
343   static Standard_Boolean Done = Standard_False;
344   if (Done) return;
345   Done = Standard_True;
346
347   const char* group = "DRAW Message Commands";
348
349   theCommands.Add("PrintMessenger",
350     "PrintMessenger"
351     "\n\t\t: Prints DumpJson information about messenger.",
352     __FILE__, PrintMessenger, group);
353
354   theCommands.Add("SetMessagePrinter",
355     "SetMessagePrinter [-type ostream|systemlog|report|draw] [-state {on|off}=on]"
356     "\n\t\t: Sets or removes the printer in messenger."
357     "\n\t\t: Option -type set type of printer. Printers are applied with And combination."
358     "\n\t\t: Option -state add or remove printer",
359     __FILE__, SetMessagePrinter, group);
360
361   theCommands.Add("SendMessage",
362     "SendMessage text [text ...]"
363     "\n Sends the text into the messenger.\n",
364     __FILE__, SendMessage, group);
365
366   theCommands.Add("ClearReport",
367     "Removes all alerts in default printer",
368     __FILE__, ClearReport, group);
369
370   theCommands.Add("SetReportMetric",
371     "SetReportMetric [metric ...] \n Activate report metrics, deactivate all if there are no parameters.\n"
372     "\n\t\t: metric is a value of Message_MetricType, e.g. 1 is Message_MetricType_UserTimeCPU" ,
373     __FILE__, SetReportMetric, group);
374
375   theCommands.Add("CollectMetricMessages",
376     "CollectMetricMessages [-activate {0|1}]"
377     "\n Start metric collection by 1, stop by 0. Result is placed in metric attributes of message report.\n",
378     __FILE__, CollectMetricMessages, group);
379   
380   theCommands.Add("PrintReport",
381     "PrintReport [-messenger] [-dump] [-dumpJson]"
382     "\n\t\t: Send report content to default messenger or stream"
383     "\n\t\t: Output options:"
384     "\n\t\t:   -messenger Prints the information about report into messenger."
385     "\n\t\t:   -dump      Prints Dump information about report."
386     "\n\t\t:   -dumpJson  Prints DumpJson information about report.",
387     __FILE__, PrintReport, group);
388 }