Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5164 was 5164, checked in by bensch, 19 years ago

orxonox/trunk: ability to describe the presented options :)

File size: 8.0 KB
Line 
1/*
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.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
17
18#include "shell_command.h"
19
20#include "list.h"
21#include "debug.h"
22#include "class_list.h"
23
24#include "key_names.h"
25#include <stdarg.h>
26#include <stdio.h>
27
28using namespace std;
29
30ShellCommandBase::ShellCommandBase(const char* commandName, const char* className, unsigned int paramCount, ...)
31{
32  this->setClassID(CL_SHELL_COMMAND, "ShellCommand");
33  this->setName(commandName);
34  this->description = NULL;
35
36//  this->classID = classID;
37  this->className = className; //ClassList::IDToString(classID);
38
39  // handling parameters, and storing them:
40  if (paramCount > FUNCTOR_MAX_ARGUMENTS)
41    paramCount = FUNCTOR_MAX_ARGUMENTS;
42  this->paramCount = paramCount;
43  this->parameters = new unsigned int[paramCount];
44
45  va_list parameterList;
46  va_start(parameterList, paramCount);
47
48  for (unsigned int i = 0; i < paramCount; i++)
49  {
50    this->parameters[i] = va_arg(parameterList, int);
51
52    switch (this->parameters[i])
53    {
54      case ParameterBool:
55        this->defaultBools[i] = va_arg(parameterList, int);
56        break;
57      case ParameterChar:
58        this->defaultStrings[i] = new char[2];
59        sprintf(this->defaultStrings[0], "%c",  va_arg(parameterList, int));
60        break;
61      case ParameterString:
62        this->defaultStrings[i] = va_arg(parameterList, char*);
63        break;
64      case ParameterInt:
65        this->defaultInts[i] = va_arg(parameterList, int);
66        break;
67      case ParameterUInt:
68        this->defaultInts[i] = va_arg(parameterList, unsigned int);
69        break;
70      case ParameterFloat:
71        this->defaultFloats[i] = va_arg(parameterList, double);
72        break;
73      case ParameterLong:
74        this->defaultInts[i] = va_arg(parameterList, long);
75        break;
76      default:
77        break;
78    }
79  }
80
81  // adding this ShellCommand to the list of known Commands
82  ShellCommandBase::commandList->add(this);
83}
84
85ShellCommandBase::~ShellCommandBase()
86{
87  delete[] this->parameters;
88}
89
90tList<ShellCommandBase>* ShellCommandBase::commandList = NULL;
91
92
93
94bool ShellCommandBase::isRegistered(const char* commandName, const char* className, unsigned int paramCount, ...)
95{
96  va_list parameterList;
97  va_start(parameterList, paramCount);
98
99  if (ShellCommandBase::commandList == NULL)
100  {
101    ShellCommandBase::commandList = new tList<ShellCommandBase>;
102    ShellCommand<ShellCommandBase>::registerCommand("debug", "ShellCommand", &ShellCommandBase::debugDyn);
103    return false;
104  }
105
106  tIterator<ShellCommandBase>* iterator = ShellCommandBase::commandList->getIterator();
107  ShellCommandBase* elem = iterator->firstElement();
108  while(elem != NULL)
109  {
110    if (!strcmp(className, elem->className) && !strcmp(commandName, elem->getName()))
111    {
112      PRINTF(2)("Command already registered\n");
113      delete iterator;
114      return true;
115    }
116    elem = iterator->nextElement();
117  }
118  delete iterator;
119  return false;
120}
121
122
123/**
124 * executes commands
125 * @param executionString the string containing the following input
126 * ClassName [ObjectName] functionName [parameter1[,parameter2[,...]]]
127 * @return true on success, false otherwise.
128 */
129bool ShellCommandBase::execute(const char* executionString)
130{
131  if (ShellCommandBase::commandList == NULL)
132    return false;
133
134  tIterator<ShellCommandBase>* iterator = ShellCommandBase::commandList->getIterator();
135  ShellCommandBase* elem = iterator->firstElement();
136  while(elem != NULL)
137  {
138    printf("%s::%s\n", elem->className, elem->getName());
139    if (!strncasecmp (executionString, elem->className, strlen(elem->className)) &&
140         (*(executionString+strlen(elem->className)) == ' ' ||
141          *(executionString+strlen(elem->className)) == ':' ))
142    {
143      const char* commandBegin = executionString + strlen(elem->className);
144
145      PRINTF(4)("Class %s matches\n", elem->className);
146      BaseObject* objectPointer = NULL;
147      if (ClassList::StringToID(elem->className) & CL_MASK_SINGLETON == CL_MASK_SINGLETON)
148      {
149        while(*commandBegin == ' ')
150          commandBegin++;
151        if (strncmp (commandBegin, elem->getName(), strlen(elem->getName())) ||
152            *(commandBegin + strlen(elem->getName())) != ' ' &&
153            *(commandBegin + strlen(elem->getName())) != '\0')
154        {
155          elem = iterator->nextElement();
156          continue;
157        }
158        PRINTF(4)("Command %s matches\n", elem->getName());
159        // getting singleton-reference
160        tList<BaseObject>* list =  ClassList::getList(elem->className);
161        if (list != NULL)
162          objectPointer = list->firstElement();
163      }
164      else
165      {
166        // checking for the Object
167        while(*commandBegin == ' ')
168          commandBegin++;
169        tList<BaseObject>* list = ClassList::getList(elem->className);
170        if (list == NULL)
171          break;
172        tIterator<BaseObject>* iterBO = list->getIterator();
173        BaseObject* enumBO = iterBO->firstElement();
174        while(enumBO != NULL)
175        {
176          if(!strncmp(commandBegin, enumBO->getName(), strlen(enumBO->getName())))
177          {
178            PRINTF(4)("Object %s matches\n", enumBO->getName());
179            objectPointer = enumBO;
180            break;
181          }
182          enumBO = iterBO->nextElement();
183        }
184        delete iterBO;
185
186        // break on no object Found. We cannot operate on Classes, but on Objects
187        if (objectPointer == NULL)
188          break;
189        commandBegin = commandBegin + strlen(objectPointer->getName());
190        while(*commandBegin == ' ')
191          commandBegin++;
192        // checking for the requested function.
193        if (strncmp (commandBegin, elem->getName(), strlen(elem->getName())))
194        {
195          elem = iterator->nextElement();
196          continue;
197        }
198        PRINTF(4)("Function '%s' found\n", commandBegin);
199      }
200      const char* paramBegin = strchr(commandBegin, ' ');
201      if (paramBegin == NULL)
202        paramBegin = commandBegin + strlen(elem->getName());
203      while (*paramBegin == ' ')
204        paramBegin++;
205
206      PRINTF(3)("Parameters to Pass: %s\n", paramBegin);
207      if (objectPointer != NULL && paramBegin != NULL)
208      {
209        elem->executeCommand(objectPointer, paramBegin);
210        delete iterator;
211        return true;
212      }
213    }
214    elem = iterator->nextElement();
215  }
216  delete iterator;
217  return true;
218}
219
220
221ShellCommandBase* ShellCommandBase::describe(const char* description)
222{
223  if (this == NULL)
224    return NULL;
225
226  this->description = description;
227  return this;
228}
229
230
231void ShellCommandBase::debugDyn()
232{
233  this->debug();
234}
235
236void ShellCommandBase::debug()
237{
238  if (ShellCommandBase::commandList == NULL)
239  {
240    PRINT(0)("No Command registered so far\n");
241    return;
242  }
243
244  tIterator<ShellCommandBase>* iterator = ShellCommandBase::commandList->getIterator();
245  ShellCommandBase* elem = iterator->firstElement();
246  while(elem != NULL)
247  {
248    PRINT(0)("Class %s registered command %s with %d parameters: ", elem->className, elem->getName(), elem->paramCount);
249    for (unsigned int i = 0; i< elem->paramCount; i++)
250      printf("%s ", ShellCommandBase::paramToString(elem->parameters[i]));
251    if (elem->description != NULL)
252      printf("- %s", elem->description);
253    printf("\n");
254
255    elem = iterator->nextElement();
256  }
257  delete iterator;
258}
259
260
261
262const char* ShellCommandBase::paramToString(long parameter)
263{
264  switch (parameter)
265  {
266    case ParameterBool:
267      return "BOOL";
268      break;
269    case ParameterChar:
270      return "CHAR";
271      break;
272    case ParameterString:
273      return "STRING";
274      break;
275    case ParameterInt:
276      return "INT";
277      break;
278    case ParameterUInt:
279      return "UINT";
280      break;
281    case ParameterFloat:
282      return "FLOAT";
283      break;
284    case ParameterLong:
285      return "LONG";
286      break;
287    default:
288      return "NULL";
289      break;
290  }
291}
Note: See TracBrowser for help on using the repository browser.