Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
11 andreas 1
/*
101 andreas 2
 * Copyright (C) 2020 to 2022 by Andreas Theofilu <andreas@theosys.at>
11 andreas 3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include "tamxcommands.h"
209 andreas 20
#include "tpagemanager.h"
11 andreas 21
#include "terror.h"
22
#include "tresources.h"
14 andreas 23
#include "tconfig.h"
78 andreas 24
#include "texpat++.h"
11 andreas 25
 
83 andreas 26
#include <string>
27
#include <vector>
28
 
186 andreas 29
#if __cplusplus < 201402L
30
#   error "This module requires at least C++14 standard!"
31
#else
32
#   if __cplusplus < 201703L
33
#       include <experimental/filesystem>
34
namespace fs = std::experimental::filesystem;
35
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
36
#   else
37
#       include <filesystem>
38
#       ifdef __ANDROID__
39
namespace fs = std::__fs::filesystem;
40
#       else
41
namespace fs = std::filesystem;
42
#       endif
43
#   endif
44
#endif
45
 
11 andreas 46
using std::string;
47
using std::vector;
78 andreas 48
using namespace Expat;
11 andreas 49
 
50
typedef struct CMD_DEFINATIONS
51
{
52
    string cmd;
53
    bool hasChannels{false};
54
    bool hasPars{false};
14 andreas 55
    char separator{0};
11 andreas 56
}CMD_DEFINATIONS;
57
 
58
CMD_DEFINATIONS cmdDefinations[] = {
14 andreas 59
    { "@WLD", false, true, ',' },
60
    { "@AFP", false, true, ',' },
127 andreas 61
    { "^AFP", false, true, ',' },
14 andreas 62
    { "@GCE", false, true, ',' },
127 andreas 63
    { "^GCE", false, true, ',' },
14 andreas 64
    { "@APG", false, true, ';' },
65
    { "@CPG", false, true, ',' },
66
    { "@DPG", false, true, ';' },
67
    { "@PDR", false, true, ';' },
68
    { "@PHE", false, true, ';' },
69
    { "@PHP", false, true, ';' },
70
    { "@PHT", false, true, ';' },
71
    { "@PPA", false, true, ',' },
104 andreas 72
    { "^PPA", false, true, ',' },
14 andreas 73
    { "@PPF", false, true, ';' },
104 andreas 74
    { "^PPF", false, true, ';' },
14 andreas 75
    { "@PPG", false, true, ';' },
104 andreas 76
    { "^PPG", false, true, ';' },
14 andreas 77
    { "@PPK", false, true, ',' },
104 andreas 78
    { "^PPK", false, true, ',' },
14 andreas 79
    { "@PPM", false, true, ';' },
104 andreas 80
    { "^PPM", false, true, ';' },
14 andreas 81
    { "@PPN", false, true, ';' },
104 andreas 82
    { "^PPN", false, true, ';' },
14 andreas 83
    { "@PPT", false, true, ';' },
104 andreas 84
    { "^PPT", false, true, ';' },
14 andreas 85
    { "@PPX", false, false, '\0' },
104 andreas 86
    { "^PPX", false, false, '\0' },
14 andreas 87
    { "@PSE", false, true, ';' },
88
    { "@PSP", false, true, ';' },
89
    { "@PST", false, true, ';' },
90
    { "PAGE", false, true, ',' },
104 andreas 91
    { "^PGE", false, true, ',' },
14 andreas 92
    { "PPOF", false, true, ';' },
93
    { "PPOG", false, true, ';' },
94
    { "PPON", false, true, ';' },
95
    { "^ANI", true, true, ',' },
96
    { "^APF", true, true, ',' },
97
    { "^BAT", true, true, ',' },
98
    { "^BAU", true, true, ',' },
99
    { "^BCB", true, true, ',' },
100
    { "?BCB", true, true, ',' },
101
    { "^BCF", true, true, ',' },
102
    { "?BCF", true, true, ',' },
103
    { "^BCT", true, true, ',' },
104
    { "?BCT", true, true, ',' },
105
    { "^BDO", true, true, ',' },
106
    { "^BFB", true, true, ',' },
107
    { "^BIM", true, true, ',' },
108
    { "^BLN", true, true, ',' },
109
    { "^BMC", true, true, ',' },
110
    { "^BMF", true, true, ',' },
111
    { "^BMI", true, true, ',' },
112
    { "^BML", true, true, ',' },
113
    { "^BMP", true, true, ',' },
114
    { "?BMP", true, true, ',' },
115
    { "^BNC", true, true, ',' },
116
    { "^BNN", true, true, ',' },
117
    { "^BNT", true, true, ',' },
118
    { "^BOP", true, true, ',' },
119
    { "?BOP", true, true, ',' },
120
    { "^BOR", true, true, ',' },
121
    { "^BOS", true, true, ',' },
122
    { "^BPP", true, true, ',' },
123
    { "^BRD", true, true, ',' },
124
    { "?BRD", true, true, ',' },
125
    { "^BSF", true, true, ',' },
126
    { "^BSP", true, true, ',' },
127
    { "^BSM", true, false, ',' },
128
    { "^BSO", true, true, ',' },
129
    { "^BVL", true, true, ',' },
130
    { "^BVN", false, true, ',' },
131
    { "^BVP", true, true, ',' },
132
    { "^BVT", true, true, ',' },
133
    { "^BWW", true, true, ',' },
134
    { "?BWW", true, true, ',' },
135
    { "^CPF", true, false, ',' },
136
    { "^DLD", false, false, ',' },
137
    { "^DPF", true, true, ',' },
138
    { "^ENA", true, true, ',' },
139
    { "^FON", true, true, ',' },
140
    { "?FON", true, true, ',' },
141
    { "^GDI", true, true, ',' },
142
    { "^GIV", true, true, ',' },
143
    { "^GLH", true, true, ',' },
144
    { "^GLL", true, true, ',' },
145
    { "^GRD", true, true, ',' },
146
    { "^GRU", true, true, ',' },
147
    { "^GSC", true, true, ',' },
148
    { "^GSN", true, true, ',' },
149
    { "^ICO", true, true, ',' },
150
    { "?ICO", true, true, ',' },
151
    { "^IRM", false, true, ',' },
152
    { "^JSB", true, true, ',' },
153
    { "?JSB", true, true, ',' },
154
    { "^JSI", true, true, ',' },
155
    { "?JSI", true, true, ',' },
156
    { "^JST", true, true, ',' },
157
    { "?JST", true, true, ',' },
158
    { "^MBT", false, false, ',' },
159
    { "^MDC", false, false, ',' },
160
    { "^SHO", true, true, ',' },
161
    { "^TEC", true, true, ',' },
162
    { "?TEC", true, true, ',' },
163
    { "^TEF", true, true, ',' },
164
    { "?TEF", true, true, ',' },
165
    { "^TOP", false, true, ',' },
166
    { "^TXT", true, true, ',' },
167
    { "?TXT", true, true, ',' },
168
    { "^UNI", true, true, ',' },
104 andreas 169
    { "^UTF", true, true, ',' },
14 andreas 170
    { "^LPC", false, true, ',' },
171
    { "^LPR", false, true, ',' },
172
    { "^LPS", false, true, ',' },
173
    { "ABEEP", false, false, ',' },
174
    { "ADBEEP", false, false, ',' },
175
    { "@AKB", false, true, ';' },
176
    { "AKEYB", false, true, ',' },
177
    { "AKEYP", false, true, ',' },
178
    { "AKEYR", false, true, ',' },
179
    { "@AKP", false, true, ';' },
180
    { "@AKR", false, false, ',' },
181
    { "BEEP", false, false, ',' },
104 andreas 182
    { "^ABP", false, false, ',' },
14 andreas 183
    { "BRIT", false, true, ',' },
184
    { "@BRT", false, true, ',' },
185
    { "DBEEP", false, false, ',' },
104 andreas 186
    { "^ADP", false, false, ',' },
14 andreas 187
    { "@EKP", false, true, ';' },
188
    { "PKEYP", false, true, ',' },
63 andreas 189
    { "@PKB", false, true, ';' },
104 andreas 190
    { "^PKB", false, true, ';' },
14 andreas 191
    { "@PKP", false, true, ';' },
104 andreas 192
    { "^PKP", false, true, ';' },
14 andreas 193
    { "SETUP", false, false, ',' },
104 andreas 194
    { "^STP", false, false, ',' },
14 andreas 195
    { "SHUTDOWN", false, false, ',' },
196
    { "SLEEP", false, false, ',' },
197
    { "@SOU", false, true, ',' },
104 andreas 198
    { "^SOU", false, true, ',' },
14 andreas 199
    { "@TKP", false, true, ';' },
104 andreas 200
    { "^TKP", false, true, ';' },
14 andreas 201
    { "TPAGEON", false, false, ',' },
202
    { "TPAGEOFF", false, false, ',' },
203
    { "@VKB", false, false, ',' },
104 andreas 204
    { "^VKB", false, false, ',' },
14 andreas 205
    { "WAKE", false, false, ',' },
206
    { "^CAL", false, false, ',' },
207
    { "^KPS", false, true, ',' },
208
    { "^VKS", false, true, ',' },
127 andreas 209
    { "^WCN?", false, true, ',' },
14 andreas 210
    { "@PWD", false, true, ',' },
211
    { "^PWD", false, true, ',' },
212
    { "^BBR", true, true, ',' },
213
    { "^RAF", false, true, ',' },
214
    { "^RFR", false, true, ',' },
215
    { "^RMF", false, true, ',' },
216
    { "^RSR", false, true, ',' },
217
    { "^MODEL?", false, false, ',' },
127 andreas 218
    { "^MOD", false, false, ',' },
219
    { "^VER?", false, false, ',' },
14 andreas 220
    { "^ICS", false, true, ',' },
221
    { "^ICE", false, false, ',' },
222
    { "^ICM", false, true, ',' },
223
    { "^PHN", false, true, ',' },
224
    { "?PHN", false, true, ',' },
233 andreas 225
    { "^LVC", false, true, ',' },
227 andreas 226
    { "^LVD", true, true, ',' },
227
    { "^LVE", true, true, ',' },
228
    { "^LVF", true, true, ',' },
233 andreas 229
    { "^LVL", true, true, ',' },
230
    { "^LVM", true, true, '|' },
231
    { "^LVN", true, true, ',' },
232
    { "^LVR", true, true, ',' },
233
    { "^LVS", true, true, ',' },
127 andreas 234
    { "GET ", false, false, ',' },
235
    { "SET ", false, false, ',' },
14 andreas 236
    { "LEVON", false, false, ',' },
318 andreas 237
    { "LEVOF", false, false, ',' },
14 andreas 238
    { "RXON", false, false, ',' },
239
    { "ON", false, true, ',' },
240
    { "OFF", false, true, ',' },
15 andreas 241
    { "LEVEL", false, true, ',' },
242
    { "BLINK", false, true, ',' },
23 andreas 243
    { "#FTR", false, true, ':' },
134 andreas 244
    { "TPCCMD", false, true, ',' },
245
    { "TPCACC", false, true, ',' },
153 andreas 246
    { "TPCSIP", false, true, ',' },
300 andreas 247
    { "^EPR", true, true, ',' },
248
    { "^SCE", true, true, ',' },
249
    { "^SDR", true, true, ',' },
318 andreas 250
    { "^SHA", true, false, ',' },
300 andreas 251
    { "^SHD", true, true, ',' },
252
    { "^SSH", true, true, ',' },
253
    { "^STG", true, true, ',' },
14 andreas 254
    { "", false, false, '\0' }
11 andreas 255
};
256
 
257
CMD_DEFINATIONS& findCmdDefines(const string& cmd)
258
{
259
    DECL_TRACER("findCmdDefines(const string& cmd)");
260
 
261
    int i = 0;
101 andreas 262
    string uCmd = cmd;
263
    uCmd = toUpper(uCmd);
11 andreas 264
 
265
    while (cmdDefinations[i].cmd.length() > 0)
266
    {
101 andreas 267
        if (cmdDefinations[i].cmd.compare(uCmd) == 0)
11 andreas 268
            return cmdDefinations[i];
269
 
270
        i++;
271
    }
272
 
273
    return cmdDefinations[i];
274
}
275
 
276
TAmxCommands::TAmxCommands()
277
{
278
    DECL_TRACER("TAmxCommands::TAmxCommands()");
279
}
280
 
281
TAmxCommands::~TAmxCommands()
282
{
283
    DECL_TRACER("TAmxCommands::~TAmxCommands()");
194 andreas 284
 
285
    if (mMap && mSystemMap && mMap != mSystemMap)
286
    {
287
        delete mMap;
288
        delete mSystemMap;
289
    }
290
    else if (mMap)
291
        delete mMap;
292
    else if (mSystemMap)
293
        delete mSystemMap;
11 andreas 294
}
295
 
14 andreas 296
bool TAmxCommands::readMap()
297
{
298
    DECL_TRACER("TAmxCommands::readMap()");
299
 
193 andreas 300
    bool err = false;
186 andreas 301
    string projectPath = TConfig::getProjectPath();
302
 
193 andreas 303
    if (fs::exists(projectPath + "/prj.xma"))
88 andreas 304
    {
194 andreas 305
        mMap = new TMap(projectPath);
193 andreas 306
        err = mMap->haveError();
88 andreas 307
    }
14 andreas 308
 
193 andreas 309
    projectPath += "/__system";
14 andreas 310
 
193 andreas 311
    if (fs::exists(projectPath + "/prj.xma"))
14 andreas 312
    {
194 andreas 313
        mSystemMap = new TMap(projectPath);
14 andreas 314
 
193 andreas 315
        if (!err)
194 andreas 316
            err = mSystemMap->haveError();
14 andreas 317
    }
318
 
194 andreas 319
    if (!mMap)
320
        mMap = mSystemMap;
321
 
193 andreas 322
    return !err;
14 andreas 323
}
324
 
325
vector<string> TAmxCommands::getFields(string& msg, char sep)
326
{
327
    DECL_TRACER("TAmxCommands::getFields(string& msg, char sep)");
328
 
329
    vector<string> flds;
330
    bool bStr = false;
331
    string part;
332
 
16 andreas 333
    for (size_t i = 0; i < msg.length(); i++)
14 andreas 334
    {
16 andreas 335
        if (msg.at(i) == sep && !bStr)
14 andreas 336
        {
337
            flds.push_back(part);
338
            part.clear();
339
            continue;
340
        }
16 andreas 341
        else if (msg.at(i) == '\'' && !bStr)
14 andreas 342
            bStr = true;
16 andreas 343
        else if (msg.at(i) == '\'' && bStr)
14 andreas 344
            bStr = false;
345
        else
16 andreas 346
            part.append(msg.substr(i, 1));
14 andreas 347
    }
348
 
349
    if (!part.empty())
350
        flds.push_back(part);
351
 
83 andreas 352
    if (flds.size() > 0 && TStreamError::checkFilter(HLOG_DEBUG))
14 andreas 353
    {
354
        MSG_DEBUG("Found fields:");
355
        vector<string>::iterator iter;
356
        int i = 1;
357
 
118 andreas 358
        for (iter = flds.begin(); iter != flds.end(); ++iter)
14 andreas 359
        {
360
            MSG_DEBUG("    " << i << ": " << *iter);
361
            i++;
362
        }
363
    }
364
 
365
    return flds;
366
}
367
 
193 andreas 368
vector<TMap::MAP_T> TAmxCommands::findButtons(int port, vector<int>& channels, TMap::MAP_TYPE mt)
14 andreas 369
{
193 andreas 370
    DECL_TRACER("TAmxCommands::findButtons(int port, vector<int>& channels, TMap::MAP_TYPE mt)");
14 andreas 371
 
193 andreas 372
    vector<TMap::MAP_T> map;
14 andreas 373
 
209 andreas 374
    if (gPageManager && gPageManager->isSetupActive())
375
        map = mSystemMap->findButtons(port, channels, mt);
376
    else
377
        map = mMap->findButtons(port, channels, mt);
19 andreas 378
 
14 andreas 379
    return map;
380
}
381
 
165 andreas 382
string TAmxCommands::findImage(int bt, int page, int instance)
383
{
384
    DECL_TRACER("TAmxCommands::findImage(int bt, int page, int instance)");
385
 
209 andreas 386
    if (page < SYSTEM_PAGE_START)
193 andreas 387
        return mMap->findImage(bt, page, instance);
165 andreas 388
 
193 andreas 389
    return mSystemMap->findImage(bt, page, instance);
165 andreas 390
}
391
 
392
string TAmxCommands::findImage(const string& name)
393
{
394
    DECL_TRACER("TAmxCommands::findImage(const string& name)");
395
 
193 andreas 396
    string str = mMap->findImage(name);
165 andreas 397
 
193 andreas 398
    if (str.empty())
399
        return mSystemMap->findImage(name);
165 andreas 400
 
193 andreas 401
    return str;
165 andreas 402
}
403
 
193 andreas 404
vector<TMap::MAP_T> TAmxCommands::findButtonByName(const string& name)
97 andreas 405
{
406
    DECL_TRACER("TAmxCommands::findButtonByName(const string& name)");
407
 
193 andreas 408
    vector<TMap::MAP_T> map = mMap->findButtonByName(name);
97 andreas 409
 
193 andreas 410
    if (map.empty())
411
        return mSystemMap->findButtonByName(name);
97 andreas 412
 
413
    return map;
414
}
415
 
193 andreas 416
vector<TMap::MAP_T> TAmxCommands::findBargraphs(int port, vector<int>& channels)
15 andreas 417
{
418
    DECL_TRACER("TAmxCommands::findBargraphs(int port, vector<int>& channels)");
419
 
193 andreas 420
    vector<TMap::MAP_T> map = mMap->findBargraphs(port, channels);
15 andreas 421
 
193 andreas 422
    if (map.empty())
423
        return mSystemMap->findBargraphs(port, channels);
83 andreas 424
 
15 andreas 425
    return map;
426
}
427
 
107 andreas 428
vector<string> TAmxCommands::findSounds()
429
{
430
    DECL_TRACER("TAmxCommands::findSounds()");
431
 
193 andreas 432
    return mMap->findSounds();      // This is enough because there are no sounds in the system settings
107 andreas 433
}
434
 
118 andreas 435
bool TAmxCommands::soundExist(const string& sname)
107 andreas 436
{
437
    DECL_TRACER("TAmxCommands::soundExist(const string sname)");
438
 
193 andreas 439
    return mMap->soundExist(sname);
107 andreas 440
}
441
 
11 andreas 442
bool TAmxCommands::parseCommand(int device, int port, const string& cmd)
443
{
444
    DECL_TRACER("TAmxCommands::parseCommand(int device, int port, const string& cmd)");
169 andreas 445
 
11 andreas 446
    vector<CMD_TABLE>::iterator iter;
16 andreas 447
    size_t pos = cmd.find_first_of("-");
127 andreas 448
    int system = TConfig::getSystem();
449
    string scmd = getCommand(cmd);
11 andreas 450
 
127 andreas 451
    MSG_TRACE("Parsing for device <" << device << ":" << port << ":" << system << "> the command: " << scmd);
13 andreas 452
 
11 andreas 453
    if (pos != string::npos)    // Command with parameters
454
    {
455
        string rest = cmd.substr(pos + 1);
456
 
118 andreas 457
        for (iter = mCmdTable.begin(); iter != mCmdTable.end(); ++iter)
11 andreas 458
        {
13 andreas 459
            iter->channels.clear();
460
            iter->pars.clear();
461
 
153 andreas 462
            if (iter->cmd.compare(scmd) == 0 && iter->command)
11 andreas 463
            {
153 andreas 464
                CMD_DEFINATIONS cdef = findCmdDefines(scmd);
11 andreas 465
 
466
                if (cdef.cmd.empty())
467
                {
153 andreas 468
                    MSG_WARNING("Command \"" << scmd << "\" not found in command table! Ignoring it.");
11 andreas 469
                    continue;
470
                }
471
 
472
                if (cdef.hasChannels || cdef.hasPars)
473
                {
14 andreas 474
                    vector<string> parts = getFields(rest, cdef.separator);
11 andreas 475
 
476
                    if (cdef.hasChannels)
13 andreas 477
                        extractChannels(parts[0], &iter->channels);
11 andreas 478
 
479
                    if (cdef.hasPars)
480
                    {
13 andreas 481
                        MSG_DEBUG("Command may have parameters. Found " << parts.size() << " parameters.");
11 andreas 482
 
13 andreas 483
                        if (parts.size() > 0)
11 andreas 484
                        {
13 andreas 485
                            vector<string>::iterator piter;
486
                            int cnt = 0;
487
 
118 andreas 488
                            for (piter = parts.begin(); piter != parts.end(); ++piter)
11 andreas 489
                            {
13 andreas 490
                                if (cdef.hasChannels && !cnt)
491
                                {
492
                                    cnt++;
493
                                    continue;
494
                                }
495
 
496
                                iter->pars.push_back(*piter);
11 andreas 497
                                cnt++;
498
                            }
499
                        }
13 andreas 500
                        else
501
                            iter->pars.push_back(rest);
11 andreas 502
                    }
503
                }
504
 
505
                iter->command(port, iter->channels, iter->pars);
506
                return true;
507
            }
508
        }
509
    }
510
    else        // Command without parameter
511
    {
118 andreas 512
        for (iter = mCmdTable.begin(); iter != mCmdTable.end(); ++iter)
11 andreas 513
        {
153 andreas 514
            if (iter->cmd.compare(scmd) == 0 && iter->command)
11 andreas 515
            {
516
                iter->command(port, iter->channels, iter->pars);
517
                return true;
518
            }
519
        }
520
    }
521
 
522
    MSG_WARNING("Command \"" << cmd << "\" currently not supported!");
523
    return false;
524
}
525
 
526
bool TAmxCommands::extractChannels(const string& schan, vector<int>* ch)
527
{
528
    DECL_TRACER("TAmxCommands::extractChannels(const string& schan, vector<int>* ch)");
529
 
530
    if (!ch || schan.empty())
531
        return false;
532
 
16 andreas 533
    if (schan.find("&") == string::npos && schan.find(".") == string::npos)
11 andreas 534
    {
535
        int c = atoi(schan.c_str());
536
        ch->push_back(c);
537
        return true;
538
    }
539
 
540
    if (schan.find("&") != string::npos)
541
    {
542
        vector<string> parts = StrSplit(schan, "&");
543
        vector<string>::iterator iter;
544
 
83 andreas 545
        if (parts.size() > 0)
11 andreas 546
        {
118 andreas 547
            for (iter = parts.begin(); iter != parts.end(); ++iter)
11 andreas 548
            {
83 andreas 549
                if (iter->find(".") != string::npos)
550
                {
551
                    vector<string> p2 = StrSplit(*iter, ".");
11 andreas 552
 
83 andreas 553
                    if (p2.size() >= 2)
554
                    {
555
                        for (int i = atoi(p2[0].c_str()); i <= atoi(p2[1].c_str()); i++)
556
                            ch->push_back(i);
557
                    }
558
                    else if (p2.size() > 0)
559
                        ch->push_back(atoi(p2[0].c_str()));
38 andreas 560
                }
83 andreas 561
                else
562
                    ch->push_back(atoi(iter->c_str()));
11 andreas 563
            }
564
        }
565
    }
566
    else
567
    {
568
        vector<string> parts = StrSplit(schan, ".");
569
 
38 andreas 570
        if (parts.size() >= 2)
571
        {
60 andreas 572
            for (int i = atoi(parts[0].c_str()); i <= atoi(parts[1].c_str()); i++)
38 andreas 573
                ch->push_back(i);
574
        }
575
        else if (parts.size() > 0)
576
            ch->push_back(atoi(parts[0].c_str()));
11 andreas 577
    }
578
 
579
    return true;
580
}
581
 
582
void TAmxCommands::registerCommand(std::function<void (int port, vector<int>& channels, vector<string>& pars)> command, const string& name)
583
{
584
    DECL_TRACER("TAmxCommands::registerCommand(std::function<void (vector<int>& channels, vector<string>& pars)> command, const string& name)");
585
 
586
    vector<CMD_TABLE>::iterator iter;
587
 
118 andreas 588
    for (iter = mCmdTable.begin(); iter != mCmdTable.end(); ++iter)
11 andreas 589
    {
590
        if (iter->cmd.compare(name) == 0)
591
        {
592
            iter->command = command;
593
            iter->channels.clear();
594
            iter->pars.clear();
595
            return;
596
        }
597
    }
598
 
599
    CMD_TABLE ctbl;
600
    ctbl.cmd = name;
601
    ctbl.command = command;
602
    mCmdTable.push_back(ctbl);
603
}