Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/shell/shell_command.cc @ 5190

Last change on this file since 5190 was 5190, checked in by bensch, 20 years ago

orxonox/trunk: construct for ShellCommandAlias… have to work some more on this :/

File size: 14.1 KB
RevLine 
[4744]1/*
[1853]2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
[1855]10
11   ### File Specific:
[5068]12   main-programmer: Benjamin Grauer
[1855]13   co-programmer: ...
[1853]14*/
15
[3955]16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
[1853]17
[5129]18#include "shell_command.h"
[1853]19
[5072]20#include "list.h"
[5129]21#include "debug.h"
[5113]22#include "class_list.h"
23
24#include "key_names.h"
[5075]25#include <stdarg.h>
26#include <stdio.h>
[5174]27#include <string.h>
[5075]28
[1856]29using namespace std;
[1853]30
[5166]31/**
[5170]32 * creates a new ShellCommandClass
33 * @param className the Name of the command-class to create
34 */
35ShellCommandClass::ShellCommandClass(const char* className)
36{
[5188]37  this->setClassID(CL_SHELL_COMMAND_CLASS, "ShellCommandClass");
38  this->setName(className);
39
[5170]40  this->className = className;
41  this->classID = CL_NULL;
42  this->commandList = new tList<ShellCommandBase>;
43
44  ShellCommandClass::commandClassList->add(this);
45}
46
47/**
48 * destructs the shellCommandClass again
49 */
50ShellCommandClass::~ShellCommandClass()
51{
52  tIterator<ShellCommandBase>* iterator = this->commandList->getIterator();
53  ShellCommandBase* elem = iterator->firstElement();
54  while(elem != NULL)
55  {
56    delete elem;
57    elem = iterator->nextElement();
58  }
59  delete iterator;
60  delete this->commandList;
61}
62
[5190]63bool ShellCommandClass::getCommandListOfClass(const char* className, tList<const char>* stringList)
[5189]64{
[5190]65  if (stringList == NULL)
66    return false;
67
[5189]68  tIterator<ShellCommandClass>* iterator = ShellCommandClass::commandClassList->getIterator();
69  ShellCommandClass* elem = iterator->firstElement();
70  while(elem != NULL)
71  {
72    if (!strcmp (elem->getName(), className))
73    {
74      tIterator<ShellCommandBase>* itFkt = elem->commandList->getIterator();
75      ShellCommandBase* command = itFkt->firstElement();
76      while (command != NULL)
77      {
[5190]78        stringList->add(command->getName());
[5189]79        command = itFkt->nextElement();
80      }
81      delete itFkt;
82    }
83
84    elem = iterator->nextElement();
85  }
86  delete iterator;
[5190]87  return true;
[5189]88}
89
[5171]90/**
91 * unregisters all Commands that exist
92 */
93void ShellCommandClass::unregisterAllCommands()
94{
95  tIterator<ShellCommandClass>* iterator = ShellCommandClass::commandClassList->getIterator();
96  ShellCommandClass* elem = iterator->firstElement();
97  while(elem != NULL)
98  {
99    delete elem;
100
101    elem = iterator->nextElement();
102  }
103  delete iterator;
104
105  delete ShellCommandClass::commandClassList;
106  ShellCommandClass::commandClassList = NULL;
107}
108
[5170]109const ShellCommandClass* ShellCommandClass::isRegistered(const char* className)
110{
111  if (ShellCommandClass::commandClassList == NULL)
112    initCommandClassList();
113
114  tIterator<ShellCommandClass>* iterator = ShellCommandClass::commandClassList->getIterator();
115  ShellCommandClass* elem = iterator->firstElement();
116  while(elem != NULL)
117  {
118    if (!strcmp(className, elem->className))
119    {
[5171]120      if (elem->classID == CL_NULL)
121        elem->classID = ClassList::StringToID(className);
122
[5170]123      delete iterator;
124      return elem;
125    }
126    elem = iterator->nextElement();
127  }
128  delete iterator;
129  return NULL;
130}
131
[5172]132/**
133 * searches for a CommandClass
134 * @param className the name of the CommandClass
135 * @returns the CommandClass if found, or a new CommandClass if not
136 */
[5170]137ShellCommandClass* ShellCommandClass::getCommandClass(const char* className)
138{
139  if (ShellCommandClass::commandClassList == NULL)
140    initCommandClassList();
141
142  tIterator<ShellCommandClass>* iterator = ShellCommandClass::commandClassList->getIterator();
143  ShellCommandClass* elem = iterator->firstElement();
144  while(elem != NULL)
145  {
146    if (!strcmp(className, elem->className))
147    {
148      delete iterator;
149      return elem;
150    }
151    elem = iterator->nextElement();
152  }
153  delete iterator;
154  return new ShellCommandClass(className);
155}
156
[5172]157/**
158 * initializes the CommandList (if it is NULL)
159 */
[5170]160void ShellCommandClass::initCommandClassList()
161{
162  if (ShellCommandClass::commandClassList == NULL)
163  {
164    ShellCommandClass::commandClassList = new tList<ShellCommandClass>;
165    ShellCommand<ShellCommandBase>::registerCommand("debug", "ShellCommand", &ShellCommandBase::debugDyn);
166  }
167}
168
169tList<ShellCommandClass>* ShellCommandClass::commandClassList = NULL;
170
171/**
[5166]172 * constructs and registers a new Command
173 * @param commandName the name of the Command
174 * @param className the name of the class to apply this command to
175 * @param paramCount the count of parameters this command takes
176 * @return self
177 */
[5161]178ShellCommandBase::ShellCommandBase(const char* commandName, const char* className, unsigned int paramCount, ...)
[3365]179{
[5141]180  this->setClassID(CL_SHELL_COMMAND, "ShellCommand");
181  this->setName(commandName);
[5164]182  this->description = NULL;
[5141]183
[5161]184//  this->classID = classID;
[5170]185  ShellCommandClass::getCommandClass(className)->commandList->add(this); //ClassList::IDToString(classID);
[5141]186
[5130]187  // handling parameters, and storing them:
[5142]188  if (paramCount > FUNCTOR_MAX_ARGUMENTS)
189    paramCount = FUNCTOR_MAX_ARGUMENTS;
[5130]190  this->paramCount = paramCount;
[5148]191  this->parameters = new unsigned int[paramCount];
[5130]192
[5148]193  va_list parameterList;
194  va_start(parameterList, paramCount);
195
[5130]196  for (unsigned int i = 0; i < paramCount; i++)
[5142]197  {
[5148]198    this->parameters[i] = va_arg(parameterList, int);
[5130]199
[5146]200    switch (this->parameters[i])
[5142]201    {
202      case ParameterBool:
[5148]203        this->defaultBools[i] = va_arg(parameterList, int);
[5142]204        break;
205      case ParameterChar:
206        this->defaultStrings[i] = new char[2];
[5148]207        sprintf(this->defaultStrings[0], "%c",  va_arg(parameterList, int));
[5142]208        break;
209      case ParameterString:
[5148]210        this->defaultStrings[i] = va_arg(parameterList, char*);
[5142]211        break;
212      case ParameterInt:
[5148]213        this->defaultInts[i] = va_arg(parameterList, int);
[5142]214        break;
215      case ParameterUInt:
[5148]216        this->defaultInts[i] = va_arg(parameterList, unsigned int);
[5142]217        break;
218      case ParameterFloat:
[5148]219        this->defaultFloats[i] = va_arg(parameterList, double);
[5142]220        break;
221      case ParameterLong:
[5148]222        this->defaultInts[i] = va_arg(parameterList, long);
[5142]223        break;
224      default:
225        break;
226    }
227  }
[5068]228}
[4320]229
[5166]230/**
231 * deconstructs a ShellCommand
232 * @return
233 */
[5130]234ShellCommandBase::~ShellCommandBase()
235{
236  delete[] this->parameters;
237}
[1853]238
[5166]239/**
240 * unregister an existing commandName
241 * @param className the name of the Class the command belongs to.
242 * @param commandName the name of the command itself
243 *
244 * @todo implement
245 */
246void ShellCommandBase::unregisterCommand(const char* commandName, const char* className)
[5165]247{
[5171]248  if (ShellCommandClass::commandClassList == NULL)
249    ShellCommandClass::initCommandClassList();
250
[5172]251 const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className);
[5171]252
[5172]253 if (checkClass != NULL)
[5171]254  {
255    tIterator<ShellCommandBase>* iterator = checkClass->commandList->getIterator();
256    ShellCommandBase* elem = iterator->firstElement();
257    while(elem != NULL)
258    {
259      if (!strcmp(commandName, elem->getName()))
260      {
261        checkClass->commandList->remove(elem);
262        delete elem;
263        break;
264      }
265      elem = iterator->nextElement();
266    }
267    delete iterator;
268
269    if (checkClass->commandList->getSize() == 0)
270    {
271      ShellCommandClass::commandClassList->remove(checkClass);
272      delete checkClass;
273    }
274  }
[5165]275}
276
[5166]277/**
278 * checks if a command has already been registered.
279 * @param commandName the name of the Command
280 * @param className the name of the Class the command should apply to.
281 * @param paramCount how many arguments the Command takes
282 * @returns true, if the command is registered/false otherwise
283 *
284 * This is used internally, to see, if we have multiple command subscriptions.
285 * This is checked in the registerCommand-function.
286 */
[5161]287bool ShellCommandBase::isRegistered(const char* commandName, const char* className, unsigned int paramCount, ...)
[5113]288{
[5170]289  if (ShellCommandClass::commandClassList == NULL)
[5072]290  {
[5170]291    ShellCommandClass::initCommandClassList();
[5113]292    return false;
293  }
[5105]294
[5170]295  const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className);
296  if (checkClass != NULL)
[5113]297  {
[5170]298    tIterator<ShellCommandBase>* iterator = checkClass->commandList->getIterator();
299    ShellCommandBase* elem = iterator->firstElement();
300    while(elem != NULL)
301   {
302     if (!strcmp(commandName, elem->getName()))
303     {
304       PRINTF(2)("Command already registered\n");
305       delete iterator;
306       return true;
307      }
308     elem = iterator->nextElement();
309   }
310   delete iterator;
311   return false;
[5113]312  }
[5170]313  else
314    return false;
[5113]315}
316
[5140]317
[5145]318/**
319 * executes commands
320 * @param executionString the string containing the following input
[5148]321 * ClassName [ObjectName] functionName [parameter1[,parameter2[,...]]]
[5145]322 * @return true on success, false otherwise.
323 */
[5135]324bool ShellCommandBase::execute(const char* executionString)
325{
[5170]326//   if (ShellCommandBase::commandList == NULL)
327//     return false;
328//
329//   tIterator<ShellCommandBase>* iterator = ShellCommandBase::commandList->getIterator();
330//   ShellCommandBase* elem = iterator->firstElement();
331//   while(elem != NULL)
332//   {
333//     printf("%s::%s\n", elem->className, elem->getName());
334//     if (!strncasecmp (executionString, elem->className, strlen(elem->className)) &&
335//          (*(executionString+strlen(elem->className)) == ' ' ||
336//           *(executionString+strlen(elem->className)) == ':' ))
337//     {
338//       const char* commandBegin = executionString + strlen(elem->className);
339//
340//       PRINTF(4)("Class %s matches\n", elem->className);
341//       BaseObject* objectPointer = NULL;
342//       if (ClassList::StringToID(elem->className) & CL_MASK_SINGLETON == CL_MASK_SINGLETON)
343//       {
344//         while(*commandBegin == ' ')
345//           commandBegin++;
346//         if (strncmp (commandBegin, elem->getName(), strlen(elem->getName())) ||
347//             *(commandBegin + strlen(elem->getName())) != ' ' &&
348//             *(commandBegin + strlen(elem->getName())) != '\0')
349//         {
350//           elem = iterator->nextElement();
351//           continue;
352//         }
353//         PRINTF(4)("Command %s matches\n", elem->getName());
354//         // getting singleton-reference
355//         tList<BaseObject>* list =  ClassList::getList(elem->className);
356//         if (list != NULL)
357//           objectPointer = list->firstElement();
358//       }
359//       else
360//       {
361//         // checking for the Object
362//         while(*commandBegin == ' ')
363//           commandBegin++;
364//         tList<BaseObject>* list = ClassList::getList(elem->className);
365//         if (list == NULL)
366//           break;
367//         tIterator<BaseObject>* iterBO = list->getIterator();
368//         BaseObject* enumBO = iterBO->firstElement();
369//         while(enumBO != NULL)
370//         {
371//           if(!strncmp(commandBegin, enumBO->getName(), strlen(enumBO->getName())))
372//           {
373//             PRINTF(4)("Object %s matches\n", enumBO->getName());
374//             objectPointer = enumBO;
375//             break;
376//           }
377//           enumBO = iterBO->nextElement();
378//         }
379//         delete iterBO;
380//
381//         // break on no object Found. We cannot operate on Classes, but on Objects
382//         if (objectPointer == NULL)
383//           break;
384//         commandBegin = commandBegin + strlen(objectPointer->getName());
385//         while(*commandBegin == ' ')
386//           commandBegin++;
387//         // checking for the requested function.
388//         if (strncmp (commandBegin, elem->getName(), strlen(elem->getName())))
389//         {
390//           elem = iterator->nextElement();
391//           continue;
392//         }
393//         PRINTF(4)("Function '%s' found\n", commandBegin);
394//       }
395//       const char* paramBegin = strchr(commandBegin, ' ');
396//       if (paramBegin == NULL)
397//         paramBegin = commandBegin + strlen(elem->getName());
398//       while (*paramBegin == ' ')
399//         paramBegin++;
400//
401//       PRINTF(3)("Parameters to Pass: %s\n", paramBegin);
402//       if (objectPointer != NULL && paramBegin != NULL)
403//       {
404//         elem->executeCommand(objectPointer, paramBegin);
405//         delete iterator;
406//         return true;
407//       }
408//     }
409//     elem = iterator->nextElement();
410//   }
411//   delete iterator;
412//   return true;
[5135]413}
[5148]414
[5166]415/**
416 * lets a command be described
417 * @param description the description of the Given command
418 */
[5164]419ShellCommandBase* ShellCommandBase::describe(const char* description)
420{
421  if (this == NULL)
422    return NULL;
[5165]423 else
424 {
425   this->description = description;
426   return this;
427 }
[5164]428}
429
[5166]430/**
431 * see ShellCommandBase::debug()
432 */
[5161]433void ShellCommandBase::debugDyn()
434{
435  this->debug();
436}
[5148]437
[5166]438/**
439 * prints out nice information about the Shells Commands
440 */
[5148]441void ShellCommandBase::debug()
442{
[5170]443  if (ShellCommandClass::commandClassList == NULL)
[5148]444  {
[5171]445    PRINT(0)("No Command registered.\n");
[5148]446    return;
447  }
448
[5170]449  tIterator<ShellCommandClass>* iteratorCL = ShellCommandClass::commandClassList->getIterator();
450  ShellCommandClass* elemCL = iteratorCL->firstElement();
451  while(elemCL != NULL)
[5148]452  {
[5171]453    PRINT(0)("Class:'%s' registered %d commands: \n", elemCL->className, elemCL->commandList->getSize());
[5170]454    tIterator<ShellCommandBase>* iterator = elemCL->commandList->getIterator();
455    const ShellCommandBase* elem = iterator->firstElement();
[5172]456    while(elem != NULL)
[5170]457    {
[5171]458      PRINT(0)("  command:'%s' : params:%d: ", elem->getName(), elem->paramCount);
[5170]459      for (unsigned int i = 0; i< elem->paramCount; i++)
460       printf("%s ", ShellCommandBase::paramToString(elem->parameters[i]));
461      if (elem->description != NULL)
462       printf("- %s", elem->description);
463      printf("\n");
[5148]464
[5170]465      elem = iterator->nextElement();
466    }
467    delete iterator;
468    elemCL = iteratorCL->nextElement();
[5148]469  }
[5170]470  delete iteratorCL;
[5148]471}
472
[5166]473/**
474 * converts a Parameter to a String
475 * @param parameter the Parameter we have.
476 * @returns the Name of the Parameter at Hand
477 */
[5148]478const char* ShellCommandBase::paramToString(long parameter)
479{
480  switch (parameter)
481  {
482    case ParameterBool:
483      return "BOOL";
484      break;
485    case ParameterChar:
486      return "CHAR";
487      break;
488    case ParameterString:
489      return "STRING";
490      break;
491    case ParameterInt:
492      return "INT";
493      break;
494    case ParameterUInt:
495      return "UINT";
496      break;
497    case ParameterFloat:
498      return "FLOAT";
499      break;
500    case ParameterLong:
501      return "LONG";
502      break;
503    default:
504      return "NULL";
505      break;
506  }
507}
Note: See TracBrowser for help on using the repository browser.