Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7408 was 7408, checked in by bensch, 18 years ago

orxonox/trunk: exist get functions

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: Benjamin Grauer
13   co-programmer: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
17
18#include "shell_completion.h"
19#include "shell_command_class.h"
20#include "shell_completion_plugin.h"
21
22#include "shell_command.h"
23
24#include "substring.h"
25#include "class_list.h"
26#include "debug.h"
27
28namespace OrxShell
29{
30
31  /**
32   * @brief standard constructor
33   */
34  ShellCompletion::ShellCompletion()
35  { }
36
37
38  /**
39   * @brief standard deconstructor
40   */
41  ShellCompletion::~ShellCompletion ()
42  { }
43
44
45
46  /**
47   * @brief autocompletes the Shell's inputLine
48   * @param input the input to complete, will most possibly be changed.
49   * @returns true, if a result was found, false otherwise
50   */
51  bool ShellCompletion::autoComplete(std::string& input)
52  {
53    long classID = CL_NULL;                          //< the classID retrieved from the Class.
54    const std::list<BaseObject*>* objectList = NULL; //< the list of Objects stored in classID's ClassList
55    bool emptyComplete = false;                      //< if the completion input is empty string. e.g ""
56    long completeType = NullCompletion;              //< the Type we'd like to complete.
57    std::string completeString = "";                 //< the string to complete.
58    unsigned int parameterBegin = 0;                 //< The SubString-entry, the Parameters begin.
59
60
61    PRINTF(5)("AutoComplete on input\n");
62    this->clearCompletionList();
63
64    // Check if we are in a input. eg. the supplied string "class " and now we complete either function or object
65    if (input.empty() || input[input.size()-1] == ' ')
66      emptyComplete = true;
67
68    // CREATE INPUTS
69    SubString inputSplits(input, SubString::WhiteSpacesWithComma);
70
71    // What String will be completed
72    if (!emptyComplete && inputSplits.size() >= 1)
73      completeString = inputSplits.getString(inputSplits.size()-1);
74
75    // CLASS/ALIAS COMPLETION (on first argument)
76    if (inputSplits.size() == 0 || (!emptyComplete && inputSplits.size() == 1))
77    {
78      completeType |= ClassCompletion;
79      completeType |= AliasCompletion;
80    }
81
82    // OBJECT/FUNCTION COMPLETIONS
83    else if ((emptyComplete && inputSplits.size() == 1) ||
84              (!emptyComplete && inputSplits.size() == 2))
85    {
86      classID = ClassList::StringToID(inputSplits.getString(0));
87      objectList = ClassList::getList((ClassID)classID);
88      if (classID != CL_NULL)
89        completeType |= ObjectCompletion;
90      completeType |= FunctionCompletion;
91    }
92    // Complete the last Function
93    else if ((emptyComplete && inputSplits.size() == 2 ) ||
94             (!emptyComplete && inputSplits.size() == 3))
95    {
96      if (ClassList::exists(inputSplits[0], inputSplits[1]))
97        completeType |= FunctionCompletion;
98    }
99
100    // Looking for ParameterCompletions.
101
102    if (completeType & ClassCompletion)
103      this->objectComplete(completeString, CL_SHELL_COMMAND_CLASS);
104    if (completeType & ObjectCompletion)
105      this->objectComplete(completeString, classID);
106    if (completeType & FunctionCompletion)
107      this->commandComplete(completeString, inputSplits.getString(0));
108    if (completeType & AliasCompletion)
109      this->aliasComplete(completeString);
110
111    if (completeType == NullCompletion)
112    {
113      printf("Completing a Parameter\n");
114//      ShellCommand::
115    }
116
117
118    this->generalComplete(input, completeString);
119    return true;
120  }
121
122  /**
123   * @brief autocompletes an ObjectName
124   * @param objectBegin the beginning string of a Object
125   * @param classID the ID of the Class to search for.
126   * @return true on success, false otherwise
127   */
128  bool ShellCompletion::objectComplete(const std::string& objectBegin, long classID)
129  {
130    const std::list<BaseObject*>* boList = ClassList::getList((ClassID)classID);
131    if (boList != NULL)
132    {
133      CompletionType type = ObjectCompletion;
134      if (classID == CL_SHELL_COMMAND_CLASS)
135        type = ClassCompletion;
136      if (!this->addToCompleteList(*boList, objectBegin, type))
137        return false;
138    }
139    else
140      return false;
141    return true;
142  }
143
144  /**
145   * @brief completes a Command
146   * @param commandBegin the beginning of the function String
147   * @param classID the class' ID to complete the function of
148   */
149  bool ShellCompletion::commandComplete(const std::string& commandBegin, const std::string& className)
150  {
151    std::list<std::string> fktList;
152    ShellCommandClass::getCommandListOfClass(className, fktList);
153    //printf("%s\n", boList->firstElement()->getName());
154    if (!this->addToCompleteList(fktList, commandBegin, FunctionCompletion))
155      return false;
156    return true;
157  }
158
159  /**
160   * @brief completes an Alias
161   * @param aliasBegin the beginning of the Alias-String to complete
162   * @returns true on succes, false if something went wrong
163   */
164  bool ShellCompletion::aliasComplete(const std::string& aliasBegin)
165  {
166    std::list<std::string> aliasList;
167    ShellCommandAlias::getCommandListOfAlias(aliasList);
168    //printf("%s\n", boList->firstElement()->getName());
169    if (!this->addToCompleteList(aliasList, aliasBegin, AliasCompletion))
170      return false;
171    return true;
172  }
173
174
175  /**
176   * @brief completes the inputline on grounds of an inputList
177   * @param input the Input to complete.
178   * @param begin the String to search in the inputList, and to extend with it.
179   * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::"
180   * @param addBack what should be added at the end of the completion
181   * @param addFront what should be added to the front of one finished completion
182   * @return true if ok, false otherwise
183   */
184  bool ShellCompletion::generalComplete(std::string& input,
185                                        const std::string& begin, const std::string& displayAs,
186                                        const std::string& addBack, const std::string& addFront)
187  {
188    if (completionList.size() == 0)
189      return false;
190
191    CompletionElement addElem = completionList.front();
192    const std::string& addString = addElem.name;
193    unsigned int addLength = 0;
194    unsigned int inputLenght = begin.size();
195
196    // Determin the longest Match
197    addLength = addString.size();
198
199    CompletionType changeType = NullCompletion;
200    std::vector<CompletionElement>::iterator charIT;
201    for (charIT = completionList.begin(); charIT != completionList.end(); charIT++)
202    {
203      if ((*charIT).type != changeType)
204      {
205        if (changeType != NullCompletion)
206          PRINT(0)("\n");
207        PRINT(0)("%s: ", ShellCompletion::typeToString((*charIT).type).c_str());
208        changeType = (*charIT).type;
209      }
210      PRINTF(0)("%s ", (*charIT).name.c_str());
211      for (unsigned int i = inputLenght; i < addLength; i++)
212        if (addString[i] != (*charIT).name[i])
213        {
214          addLength = i;
215          //       break;
216        }
217    }
218    PRINT(0)("\n");
219
220    if (addLength >= inputLenght)
221    {
222      std::string adder = addString;
223      adder.resize(addLength);
224
225      input.resize(input.size()-inputLenght);
226      input += adder;
227
228      if (completionList.size() == 1)
229      {
230        if ( addBack != "")
231          input += addBack;
232        input += ' ';
233      }
234    }
235    return true;
236  }
237
238  /**
239   * @brief searches for classes, which beginn with completionBegin
240   * @param inputList the List to parse through
241   * @param completionBegin the beginning string
242   * !! The strings MUST NOT be deleted !!
243   */
244  bool ShellCompletion::addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, CompletionType type)
245  {
246    unsigned int searchLength = completionBegin.size();
247
248    std::list<std::string>::const_iterator string;
249    for (string = inputList.begin(); string != inputList.end(); string++)
250    {
251      if ((*string).size() >= searchLength &&
252          !nocaseCmp(*string, completionBegin, searchLength))
253      {
254        CompletionElement newElem;
255        newElem.name = (*string);
256        newElem.type = type;
257        this->completionList.push_back(newElem);
258      }
259    }
260    return true;
261  }
262
263  /**
264   * @brief searches for classes, which beginn with completionBegin
265   * @param inputList the List to parse through
266   * @param completionBegin the beginning string
267   * !! The strings MUST NOT be deleted !!
268   */
269  bool ShellCompletion::addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, CompletionType type)
270  {
271    unsigned int searchLength = completionBegin.size();
272
273    std::list<BaseObject*>::const_iterator bo;
274    for(bo = inputList.begin(); bo != inputList.end(); bo++)
275    {
276      if ((*bo)->getName() != NULL &&
277          strlen((*bo)->getName()) >= searchLength &&
278          !nocaseCmp((*bo)->getName(), completionBegin, searchLength))
279      {
280        CompletionElement newElem;
281        newElem.name = (*bo)->getName();
282        newElem.type = type;
283        this->completionList.push_back(newElem);
284      }
285    }
286
287    return true;
288  }
289
290  /**
291   * @brief deletes the Completion List.
292   *
293   * This is done at the beginning of each completion-run
294   */
295  void ShellCompletion::clearCompletionList()
296  {
297    this->completionList.clear();
298  }
299
300  const std::string& ShellCompletion::typeToString(CompletionType type)
301  {
302    switch (type)
303    {
304      default:// SHELLC_NONE
305        return typeNames[0];
306      case  ClassCompletion:
307        return typeNames[1];
308      case ObjectCompletion:
309        return typeNames[2];
310      case FunctionCompletion:
311        return typeNames[3];
312      case AliasCompletion:
313        return typeNames[4];
314    }
315  }
316
317
318  const std::string ShellCompletion::typeNames[] =
319    {
320      "error",
321      "class",
322      "object",
323      "function",
324      "alias"
325    };
326
327}
Note: See TracBrowser for help on using the repository browser.