amath  1.8.5
Simple command line calculator
functionlist.cpp
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * Project homepage:
26  * https://amath.innolan.net
27  *
28  */
29 
30 #include "amath.h"
31 #include "amathc.h"
32 #include "functionlist.h"
33 #include "userfunction.h"
34 #include "functionalias.h"
35 #include "function/defs.h"
36 #include "function/user.h"
37 #include "loc/text.h"
38 
40 {
41  first = nullptr;
42  buf = new CharBuffer();
43 }
44 
46 {
47  if (first != nullptr)
48  {
49  delete first;
50  }
51 
52  delete buf;
53 }
54 
56 {
57  if (first != nullptr)
58  {
59  delete first;
60  first = nullptr;
61  }
62 
64 }
65 
66 bool FunctionList::Delete(const char* name, const char* argument)
67 {
68  if (first == nullptr)
69  {
70  return false;
71  }
72 
74  {
75  UserFunction* func = first;
77  func->chainDelete = false;
78  delete func;
79  return true;
80  }
81 
82  UserFunction* current = first->Next;
83  UserFunction* last = first;
84 
85  while (current != nullptr && !StrIsEqual(current->GetName(), name))
86  {
87  current = current->Next;
88  last = last->Next;
89  }
90 
91  if (current == nullptr)
92  {
93  return false;
94  }
95  else if (!StrIsEqual(current->GetVariable()->GetName(), argument))
96  {
97  return false;
98  }
99 
100  last->Next = current->Next;
101 
102  // Only delete this variable. Not the whole chain.
103  current->chainDelete = false;
104  delete current;
105 
106  return true;
107 }
108 
110 {
111  return first;
112 }
113 
115 {
116  // Search the list for function definition. If function not found then create a new definition.
117  if (first == nullptr)
118  {
119  first = new UserFunction(name);
120  return first;
121  }
122 
123  UserFunction* current = first;
124  UserFunction* last = nullptr;
125 
126  while (current != nullptr)
127  {
128  if (StrIsEqual(current->GetName(), name))
129  {
130  return current;
131  }
132 
133  last = current;
134  current = current->Next;
135  }
136 
137  current = new UserFunction(name);
138  last->Next = current;
139 
140  return current;
141 }
142 
143 UserFunction* FunctionList::GetFunctionDef(const char* name, const char* argument) const
144 {
145  UserFunction* current = first;
146 
147  while (current != nullptr)
148  {
149  if (StrIsEqual(current->GetName(), name) && StrIsEqual(current->GetVariable()->GetName(), argument))
150  {
151  return current;
152  }
153 
154  current = current->Next;
155  }
156 
157  return nullptr;
158 }
159 
160 FunctionNode* FunctionList::GetFunctionCall(const char* function, ExpressionNode* parameter) const
161 {
162  const functiondef* systemFunction = GetSystemFunction(function);
163  if (systemFunction != nullptr)
164  {
165  char* sysname = FindAlias(function);
166  return (systemFunction->create)(parameter, const_cast<char*>(function), sysname);
167  }
168 
169  UserFunction* current = first;
170  while (current != nullptr && !StrIsEqual(current->GetName(), function))
171  {
172  current = current->Next;
173  }
174 
175  if (current != nullptr)
176  {
177  return new UserFunctionNode(current, parameter);
178  }
179 
180  return nullptr;
181 }
182 
183 char* FunctionList::List() const
184 {
185  return ListContent(false);
186 }
187 
189 {
190  return ListContent(true);
191 }
192 
193 char* FunctionList::ListContent(bool cmdFormat) const
194 {
195  if (first == nullptr)
196  {
197  return static_cast<char*>(cmdFormat ? nullptr : HELPFUNCNDEF);
198  }
199 
200  int len = 0;
201  UserFunction* current = first;
202 
203  while (current != nullptr)
204  {
205  len += StrLen(current->GetName());
206  len += 1;
208  len += 2;
210  len += cmdFormat ? 2 : 1;
211  current = current->Next;
212  }
213 
214  buf->Empty();
216 
217  current = first;
218  while (current != nullptr)
219  {
221  buf->Append("(");
223  buf->Append(")=");
225 
226  if (cmdFormat)
227  {
228  buf->Append(';');
229  }
230 
232  current = current->Next;
233  }
234 
235  return buf->GetString();
236 }
237 
238 bool FunctionList::IsSystemFunction(const char* name)
239 {
240  return (GetSystemFunction(name) != nullptr);
241 }
242 
244 {
245  char* s = FindAlias(ident);
246  static const unsigned int count = sizeof(functiondefs) / sizeof(functiondef);
247  for (unsigned int i = 0; i < count; i++)
248  {
250  {
251  return const_cast<functiondef*>(&functiondefs[i]);
252  }
253  }
254 
255  return nullptr;
256 }
257 
258 char* FunctionList::FindAlias(const char* ident)
259 {
260  static const unsigned int count = sizeof(identaliases) / sizeof(identalias);
261  for (unsigned int i = 0; i < count; i++)
262  {
263  if (StrIsEqual(identaliases[i].ident, ident))
264  {
265  return const_cast<char*>(identaliases[i].alias);
266  }
267  }
268 
269  return const_cast<char*>(ident);
270 }
void Append(const char c)
Definition: charbuf.cpp:245
#define NEWLINE
Definition: amath.h:222
UserFunction * GetFunctionDef(const char *name, const char *argument) const
UserFunction * Next
Definition: userfunction.h:51
Represents a mathematical function in a syntax tree.
Definition: node.h:50
void Empty()
Definition: charbuf.cpp:218
ExpressionNode * GetExpression() const
char * GetString() const
Definition: charbuf.cpp:306
UserFunction(const char *name)
CharBuffer * buf
Definition: functionlist.h:61
#define HELPFUNCNDEF
Definition: text.h:92
UserFunction * GetFirstFunction() const
char * ListContent(bool cmdFormat) const
void ClearBuffer()
Release memory in buffer.
Definition: charbuf.cpp:65
void Append(const char *source)
Definition: charbuf.cpp:262
An expression node able to compute a function value.
Definition: user.h:40
CharBuffer()
Initialize without allocating memory.
Definition: charbuf.cpp:38
bool StrIsEqual(const char *s1, const char *s2)
Compare two null terminated strings to each other.
Definition: strcmp.c:50
char * GetName() const
Definition: values.cpp:69
Function definitions of known mathematical functions.
Definition: defs.h:103
FunctionNode * GetFunctionCall(const char *function, ExpressionNode *value) const
Variable * GetVariable() const
CreateFunctionNode create
Definition: defs.h:106
static const identalias identaliases[]
Definition: functionalias.h:35
const char * alias
Definition: amatht.h:42
char * GetName() const
int StrLen(const char *string)
Get the length of a null terminated string.
Definition: strlen.c:34
virtual char * GetText()=0
A user defined function.
Definition: userfunction.h:44
static const functiondef functiondefs[]
Definition: defs.h:109
static functiondef * GetSystemFunction(const char *ident)
Base class for all nodes related to mathematical expressions.
Definition: nodes.h:99
const char * ident
Definition: amatht.h:41
static char * FindAlias(const char *ident)
UserFunction * first
Definition: functionlist.h:62
A list of user defined functions.
Definition: functionlist.h:42
bool Delete(const char *name, const char *argument)
static bool IsSystemFunction(const char *name)
Encapsulate an character array which can be used as a string.
Definition: charbuf.h:44
const char * name
Definition: defs.h:105
bool chainDelete
Definition: userfunction.h:65
char * ListDefinitions() const
void EnsureSize(unsigned int size)
Ensure a memory block of specified size is allocated.
Definition: charbuf.cpp:114
UserFunctionNode(UserFunction *function, ExpressionNode *parameter)
Definition: user.cpp:33
UserFunction * GetFunctionDef(const char *name)
char * List() const