1 /***************************************************************************
2 rcommand.cpp - description
3 -------------------
4 begin : Mon Nov 11 2002
5 copyright : (C) 2002, 2006, 2007 by Thomas Friedrichsmeier
6 email : thomas.friedrichsmeier@kdemail.net
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "rcommand.h"
19 #include "rcommandreceiver.h"
20 #include "rkrinterface.h"
21 #include "../windows/rkcommandlog.h"
22 #include "rkrbackendprotocol_shared.h"
23 #include "../core/robject.h"
24
25 #include "../debug.h"
26 #include "../rkglobals.h"
27
toCommand()28 RCommand* RCommandChain::toCommand() {
29 return (is_command ? static_cast<RCommand*> (this) : 0);
30 }
31
32
RCommandNotifier()33 RCommandNotifier::RCommandNotifier () : QObject () {
34 RK_TRACE (RBACKEND);
35 }
36
~RCommandNotifier()37 RCommandNotifier::~RCommandNotifier () {
38 RK_TRACE (RBACKEND);
39 }
40
41 int RCommand::next_id = 0;
42
RCommand(const QString & command,int type,const QString & rk_equiv,RCommandReceiver * receiver,int flags)43 RCommand::RCommand(const QString &command, int type, const QString &rk_equiv, RCommandReceiver *receiver, int flags) : RData (), RCommandChain (false) {
44 RK_TRACE (RBACKEND);
45 _id = next_id++;
46 // if we ever submit enough commands to get a buffer overflow, use only positive numbers.
47 if (next_id < 0) {
48 next_id = 0;
49 }
50 _type = type;
51 _flags = flags;
52 if (type & Plugin) _command = command.trimmed ();
53 else _command = command;
54 if (_command.isEmpty ()) _type |= EmptyCommand;
55 status = 0;
56 has_been_run_up_to = 0;
57 _rk_equiv = rk_equiv;
58 _notifier = 0;
59 for (int i = 0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) receivers[i] = 0;
60 if (!(type & Internal)) {
61 addReceiver (receiver);
62 addReceiver (RKCommandLog::getLog ());
63 }
64 }
65
~RCommand()66 RCommand::~RCommand(){
67 RK_TRACE (RBACKEND);
68
69 for (QList<ROutput*>::const_iterator it = output_list.constBegin (); it != output_list.constEnd (); ++it) {
70 delete (*it);
71 }
72 // The output_list itself is cleared automatically
73
74 if (_notifier) delete _notifier;
75 }
76
notifier()77 RCommandNotifier* RCommand::notifier () {
78 if (!_notifier) {
79 RK_TRACE (RBACKEND);
80 _notifier = new RCommandNotifier ();
81 RK_ASSERT (_notifier);
82 }
83 return _notifier;
84 }
85
addReceiver(RCommandReceiver * receiver)86 void RCommand::addReceiver (RCommandReceiver *receiver) {
87 RK_TRACE (RBACKEND);
88
89 if (!receiver) return;
90
91 for (int i = 0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
92 if (receivers[i] == 0) {
93 receivers[i] = receiver;
94 receiver->addCommand (this);
95 return;
96 }
97 }
98
99 RK_DEBUG (RBACKEND, DL_ERROR, "Too many receivers for command");
100 }
101
removeReceiver(RCommandReceiver * receiver)102 void RCommand::removeReceiver (RCommandReceiver *receiver) {
103 RK_TRACE (RBACKEND);
104
105 if (!receiver) return;
106
107 for (int i = 0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
108 if (receivers[i] == receiver) {
109 receivers[i] = 0;
110 return;
111 }
112 }
113
114 RK_DEBUG (RBACKEND, DL_WARNING, "Was not a receiver in RCommand::removeReceiver: %p", receiver);
115 }
116
finished()117 void RCommand::finished () {
118 RK_TRACE (RBACKEND);
119
120 for (int i=0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
121 if (receivers[i] == 0) continue;
122 receivers[i]->delCommand (this);
123 receivers[i]->rCommandDone (this);
124 }
125 if (_notifier) _notifier->emitFinished (this);
126 }
127
newOutput(ROutput * output)128 void RCommand::newOutput (ROutput *output) {
129 RK_TRACE (RBACKEND);
130
131 for (int i=0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
132 if (receivers[i] == 0) continue;
133 receivers[i]->newOutput (this, output);
134 }
135 }
136
commandLineIn()137 void RCommand::commandLineIn () {
138 RK_TRACE (RBACKEND);
139 RK_ASSERT (_type & User);
140
141 for (int i=0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
142 if (receivers[i] == 0) continue;
143 receivers[i]->userCommandLineIn (this);
144 }
145 }
146
error() const147 QString RCommand::error () const {
148 RK_TRACE (RBACKEND);
149
150 QString ret;
151 for (ROutputList::const_iterator it = output_list.begin (); it != output_list.end (); ++it) {
152 if ((*it)->type == ROutput::Error) {
153 ret.append ((*it)->output);
154 }
155 }
156 return ret;
157 }
158
output() const159 QString RCommand::output () const {
160 RK_TRACE (RBACKEND);
161
162 QString ret;
163 for (ROutputList::const_iterator it = output_list.begin (); it != output_list.end (); ++it) {
164 if ((*it)->type == ROutput::Output) {
165 ret.append ((*it)->output);
166 }
167 }
168 return ret;
169 }
170
warnings() const171 QString RCommand::warnings () const {
172 RK_TRACE (RBACKEND);
173
174 QString ret;
175 for (ROutputList::const_iterator it = output_list.begin (); it != output_list.end (); ++it) {
176 if ((*it)->type == ROutput::Warning) {
177 ret.append ((*it)->output);
178 }
179 }
180 return ret;
181 }
182
fullOutput() const183 QString RCommand::fullOutput () const {
184 RK_TRACE (RBACKEND);
185
186 QString ret;
187 for (ROutputList::const_iterator it = output_list.begin (); it != output_list.end (); ++it) {
188 ret.append ((*it)->output);
189 }
190 return ret;
191 }
192
remainingCommand() const193 QString RCommand::remainingCommand () const {
194 RK_TRACE (RBACKEND);
195 RK_ASSERT (_type & User); // not a grave problem, if it's not, but not useful, either
196
197 return _command.mid (has_been_run_up_to);
198 }
199
mergeAndDeleteProxy(RCommandProxy * proxy)200 void RCommand::mergeAndDeleteProxy (RCommandProxy *proxy) {
201 RK_TRACE (RBACKEND);
202
203 RK_ASSERT (proxy);
204 RK_ASSERT (proxy->id == _id);
205 RK_ASSERT (proxy->type == _type);
206
207 status = proxy->status;
208 has_been_run_up_to = proxy->has_been_run_up_to;
209 swallowData (*proxy);
210 delete proxy;
211 }
212
makeProxy() const213 RCommandProxy* RCommand::makeProxy () const {
214 RK_TRACE (RBACKEND);
215 RK_ASSERT (status == 0); // Initialization from an already touched command is not a real problem, but certainly no expected usage
216 RK_ASSERT (has_been_run_up_to == 0);
217 RK_ASSERT (getDataType () == RData::NoData);
218
219 RCommandProxy *ret = new RCommandProxy (_command, _type);
220 ret->id = _id,
221 ret->status = status;
222 ret->has_been_run_up_to = has_been_run_up_to;
223 return ret;
224 }
225
rQuote(const QString & quoted)226 QString RCommand::rQuote (const QString "ed) {
227 return RObject::rQuote (quoted);
228 }
229
230