Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/shell/shell_completion.cc @ 5189

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

orxonox/trunk: only retrieve Classes, that actually have a Command associated with them

File size: 9.8 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: ...
13   co-programmer: ...
14*/
15
16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
17
18#include "shell_completion.h"
19
20#include "shell_input.h"
21
22#include "substring.h"
23#include "base_object.h"
24#include "class_list.h"
25#include "list.h"
26#include "debug.h"
27
28#include "stdlibincl.h"
29
30using namespace std;
31
32/**
33 * standard constructor
34 * @todo this constructor is not jet implemented - do it
35*/
36ShellCompletion::ShellCompletion(ShellInput* input)
37{
38  this->completionList = NULL;
39  this->input = input;
40}
41
42
43/**
44 * standard deconstructor
45*/
46ShellCompletion::~ShellCompletion ()
47{
48  // delete what has to be deleted here
49  if (this->completionList)
50  {
51    this->emptyCompletionList();
52    delete this->completionList;
53  }
54}
55
56
57
58/**
59 * autocompletes the Shell's inputLine
60 * @returns true, if a result was found, false otherwise
61 *
62 * @todo implement it!!
63 */
64bool ShellCompletion::autoComplete(ShellInput* input)
65{
66  const char* completionLine;
67
68  long classID;                    //< the classID retrieved from the Class.
69  tList<BaseObject>* objectList;   //< the list of Objects stored in classID
70  char* classBegin;                //< the beginn of the slass string
71  char* classEnd;                  //< the end of the class string
72  char* objectBegin;               //< the begin of the object string
73  char* objectEnd;                 //< the end of the object string
74  char* functionBegin;             //< the begin of the function string
75  char* functionEnd;               //< the end of the function string
76
77  PRINTF(4)("AutoComplete on input\n");
78  this->emptyCompletionList();
79
80  if (input != NULL)
81    this->input = input;
82  if (this->input == NULL)
83  {
84    PRINTF(2)("No ShellInput supplied\n");
85    return false;
86  }
87  if (this->input->getInput() == NULL)
88    return this->objectComplete("", CL_SHELL_COMMAND_CLASS);
89
90
91  completionLine = this->input->getInput() + strspn(this->input->getInput(), " \t\n");
92
93  SubString inputSplits(completionLine, true);
94
95
96  // CLASS COMPLETION
97  if (inputSplits.getCount() == 0)
98  {
99    PRINTF(5)("Listing all Classes\n");
100    this->objectComplete("", CL_SHELL_COMMAND_CLASS);
101    return false;
102  }
103  else if (inputSplits.getCount() == 1 && strlen(inputSplits.getString(0)) == strlen(completionLine))
104  {
105    printf("trying to complete a Class with '%s'\n", inputSplits.getString(0));
106    this->objectComplete(inputSplits.getString(0), CL_SHELL_COMMAND_CLASS);
107  }
108
109  // OBJECT COMPLETIONS
110  else if ( inputSplits.getCount() <= 2 && strlen(inputSplits.getString(0)) < strlen(completionLine))
111  {
112    classID = ClassList::StringToID(inputSplits.getString(0));
113    if (classID == CL_NULL)
114      return false;
115    if (inputSplits.getCount()==2)
116    {
117      if  (completionLine[strlen(completionLine)-1] != ' ')
118       this->objectComplete(inputSplits.getString(1), classID);
119    }
120    else
121      this->objectComplete("", classID);
122  }
123//  else if (inputSplits.getCount() <= 3 )
124
125/*  completionLine = new char[strlen(this->input->getText())+1];
126  strcpy(completionLine, this->input->getText());
127
128  char* commandBegin = strrchr(completionLine, ' ');
129  if (commandBegin == NULL)
130    commandBegin = completionLine;
131  else
132  {
133    if(commandBegin >= completionLine + strlen(completionLine))
134      commandBegin = completionLine + strlen(completionLine);
135    else
136      commandBegin++;
137  }
138
139  char* objectStart;
140  if (objectStart = strstr(commandBegin, "::"))
141  {
142    char* classIdentity = new char[objectStart - commandBegin +1];
143    strncpy(classIdentity, commandBegin, objectStart - commandBegin);
144    classIdentity[objectStart - commandBegin] = '\0';
145    this->objectComplete(objectStart+2, ClassList::StringToID(classIdentity));
146    delete[] classIdentity;
147  }
148  else
149    this->classComplete(commandBegin);
150
151  delete[] completionLine;*/
152}
153
154/**
155 * autocompletes a className
156 * @param classBegin the Beginning of a String to autoComplete
157 * @return true on success, false otherwise
158 */
159bool ShellCompletion::classComplete(const char* classBegin)
160{
161  if (unlikely(classBegin == NULL))
162    return false;
163  const tList<const char>* clList = ClassList::getClassList();
164  if (clList != NULL)
165  {
166    const tList<ShellC_Element>* classList = this->addToCompleteList(clList, classBegin);
167    if (classList != NULL)
168      this->generalComplete(classList, classBegin, "CL: %s ");
169    else
170      return false;
171  }
172  else
173    return false;
174  return true;
175}
176
177/**
178 * autocompletes an ObjectName
179 * @param objectBegin the beginning string of a Object
180 * @param classID the ID of the Class to search for.
181 * @return true on success, false otherwise
182 */
183bool ShellCompletion::objectComplete(const char* objectBegin, long classID)
184{
185  if (unlikely(objectBegin == NULL))
186    return false;
187  tList<BaseObject>* boList = ClassList::getList(classID);
188  if (boList != NULL)
189  {
190    //printf("%s\n", boList->firstElement()->getName());
191    const tList<ShellC_Element>* objectList = this->addToCompleteList(boList, objectBegin);
192    if (objectList != NULL)
193      this->generalComplete(objectList, objectBegin, "%s ");
194    else
195      return false;
196  }
197  else
198    return false;
199  return true;
200}
201
202/**
203 * completes a Function
204 * @param functionBegin the beginning of the function String
205 */
206bool ShellCompletion::functionComplete(const char* functionBegin)
207{
208}
209
210/**
211 * completes the inputline on grounds of an inputList
212 * @param stringList the List to parse through
213 * @param begin the String to search in the inputList, and to extend with it.
214 * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::"
215 * @param addBack what should be added at the end of the completion
216 * @param addFront what should be added to the front of one finished completion
217 * @return true if ok, false otherwise
218 */
219bool ShellCompletion::generalComplete(const tList<ShellC_Element>* stringList, const char* begin, const char* displayAs, const char* addBack, const char* addFront)
220{
221  if (stringList == NULL || this->input == NULL )
222    return false;
223  if (stringList->getSize() == 0)
224    return false;
225
226  ShellC_Element* addElem = stringList->firstElement();
227  const char* addString = addElem->name;
228  unsigned int addLength = 0;
229  unsigned int inputLenght = strlen(begin);
230
231  // Determin the longest Match
232  if (addString != NULL)
233    addLength = strlen(addString);
234  tIterator<ShellC_Element>* charIterator = stringList->getIterator();
235  ShellC_Element* charElem = charIterator->firstElement();
236  while (charElem != NULL)
237  {
238    PRINTF(0)(displayAs, charElem->name);
239    for (unsigned int i = inputLenght; i < addLength; i++)
240      if (addString[i] != charElem->name[i])
241      {
242       addLength = i;
243       break;
244      }
245    charElem = charIterator->nextElement();
246  }
247  delete charIterator;
248
249  if (addLength >= inputLenght)
250  {
251    char* adder = new char[addLength+1];
252    strncpy(adder, addString, addLength);
253    adder[addLength] = '\0';
254
255    if (this->input)
256    {
257     this->input->removeCharacters(inputLenght);
258     this->input->addCharacters(adder);
259
260      if (stringList->getSize() == 1)
261      {
262        if ( addBack != NULL )
263         this->input->addCharacters(addBack);
264        this->input->addCharacter(' ');
265      }
266     delete[] adder;
267    }
268  }
269  return true;
270}
271
272/**
273 * searches for classes, which beginn with completionBegin
274 * @param inputList the List to parse through
275 * @param completionBegin the beginning string
276 * !! The strings MUST NOT be deleted !!
277 */
278const tList<ShellC_Element>* ShellCompletion::addToCompleteList(const tList<const char>* inputList, const char* completionBegin)
279{
280  if (inputList == NULL || completionBegin == NULL)
281    return NULL;
282  unsigned int searchLength = strlen(completionBegin);
283
284  tIterator<const char>* iterator = inputList->getIterator();
285  const char* enumString = iterator->firstElement();
286  while (enumString != NULL)
287  {
288    if (strlen(enumString) >= searchLength &&
289        !strncasecmp(enumString, completionBegin, searchLength))
290    {
291      printf("%s\n", enumString);
292      ShellC_Element* newElem = new ShellC_Element;
293      newElem->name = enumString;
294      this->completionList->add(newElem);
295    }
296    enumString = iterator->nextElement();
297  }
298  delete iterator;
299
300  return this->completionList;
301}
302
303/**
304 * searches for classes, which beginn with completionBegin
305 * @param inputList the List to parse through
306 * @param completionBegin the beginning string
307 * !! The strings MUST NOT be deleted !!
308 */
309const tList<ShellC_Element>* ShellCompletion::addToCompleteList(const tList<BaseObject>* inputList, const char* completionBegin)
310{
311  if (inputList == NULL || completionBegin == NULL)
312    return NULL;
313  unsigned int searchLength = strlen(completionBegin);
314
315  tIterator<BaseObject>* iterator = inputList->getIterator();
316  BaseObject* enumBO = iterator->firstElement();
317  while (enumBO != NULL)
318  {
319    if (enumBO->getName() != NULL &&
320        strlen(enumBO->getName()) >= searchLength &&
321        !strncasecmp(enumBO->getName(), completionBegin, searchLength))
322    {
323      ShellC_Element* newElem = new ShellC_Element;
324      newElem->name = enumBO->getName();
325      this->completionList->add(newElem);
326      printf("%s\n",enumBO->getName());
327    }
328    enumBO = iterator->nextElement();
329  }
330  delete iterator;
331
332  return this->completionList;
333}
334
335void ShellCompletion::emptyCompletionList()
336{
337  if (this->completionList != NULL)
338  {
339    tIterator<ShellC_Element>* elemIT = this->completionList->getIterator();
340    ShellC_Element* elem = elemIT->firstElement();
341    while (elem != NULL)
342    {
343      delete elem;
344      elem = elemIT->nextElement();
345    }
346    delete this->completionList;
347  }
348  this->completionList = new tList<ShellC_Element>;
349}
Note: See TracBrowser for help on using the repository browser.