Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: some restructure of the Completion. now one can supply a Type to each completion

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