amath  1.8.5
Simple command line calculator
language.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 "program.h"
33 #include "language.h"
34 #include "loc/help.h"
35 #include "loc/kword.h"
36 #include "loc/ident.h"
37 #include "loc/text.h"
38 #include "main/symbol.h"
39 #include "main/operatordefs.h"
40 #include "main/functionalias.h"
41 
42 static const texttag ansiTags[] = {
43  {"#HEADLINE#", "\x1B[1m"},
44 #if defined(UNIX)
45  {"#SYNTAXHIGHLIGHT#", "\x1B[3m\x1B[32m"},
46 #else
47  {"#SYNTAXHIGHLIGHT#", "\x1B[32m"},
48 #endif
49  {"#NORMALTEXT#", "\x1B[0m"},
50  {"#BOLD#", "\x1B[1m"},
51  {"#ITALICS#", "\x1B[3m"},
52  {"#UNDERLINE#", "\x1B[4m"},
53  {"#COLOR01#", "\x1B[31m"},
54  {"#COLOR02#", "\x1B[32m"},
55  {"#COLOR03#", "\x1B[33m"},
56  {"#SPACE#", SPACE},
57  {"#NEWLINE#", NEWLINE},
58  {"#STARTMSG#", TXTSTARTMSG}
59 };
60 
61 static const texttag emptyTags[] = {
62  {"#HEADLINE#", EMPTYSTRING},
63  {"#SYNTAXHIGHLIGHT#", EMPTYSTRING},
64  {"#NORMALTEXT#", EMPTYSTRING},
65  {"#BOLD#", EMPTYSTRING},
66  {"#ITALICS#", EMPTYSTRING},
67  {"#UNDERLINE#", EMPTYSTRING},
68  {"#COLOR01#", EMPTYSTRING},
69  {"#COLOR02#", EMPTYSTRING},
70  {"#COLOR03#", EMPTYSTRING},
71  {"#SPACE#", SPACE},
72  {"#NEWLINE#", NEWLINE},
73  {"#STARTMSG#", TXTSTARTMSG}
74 };
75 
77 {
78  lastText = nullptr;
79  keywordsloc = nullptr;
80  keywordcount = sizeof(keywords) / sizeof(keyworddef);
81  textcount = sizeof(textdefs) / sizeof(textdef);
82  identcount = sizeof(identtexts) / sizeof(identhelpdef);
83  helpcount = sizeof(helptexts) / sizeof(helptextdef);
84  aliascount = sizeof(identaliases) / sizeof(identalias);
85 }
86 
88 {
89  if (lastText != nullptr)
90  {
91  delete lastText;
92  }
93 
94  if (keywordsloc != nullptr)
95  {
96  delete [] keywordsloc;
97  }
98 }
99 
100 void Language::SetAnsiMode(bool value)
101 {
102  ansiMode = value;
103 }
104 
105 char* Language::FindAlias(const char* ident) const
106 {
107  for (unsigned int i = 0; i < aliascount; i++)
108  {
109  if (StrIsEqual(identaliases[i].ident, ident))
110  {
111  return const_cast<char*>(identaliases[i].alias);
112  }
113  }
114 
115  return const_cast<char*>(ident);
116 }
117 
118 Symbol Language::FindKeyword(const char* ident) const
119 {
120  for (unsigned int i = 0; i < keywordcount; i++)
121  {
122  if (Program->Language->StrIsEqualLoc(keywords[i].name, ident) ||
123  (keywordsloc != nullptr && Program->Language->StrIsEqualLoc(keywordsloc[i].name, ident)))
124  {
125  return keywords[i].symbol;
126  }
127  }
128 
129  return static_cast<Symbol>(0);
130 }
131 
132 char* Language::GetText(int id)
133 {
134  textdef* def = nullptr;
135  for (unsigned int i = 0; i < textcount; i++)
136  {
137  if (textdefs[i].id == id)
138  {
139  def = (textdef*)&textdefs[i];
140  break;
141  }
142  }
143 
144  if (def == nullptr)
145  {
146  return (char*)(HELPNOHELP);
147  }
148 
149  char* text = Translate(def);
150  char* untagged = UntagText(text);
151  return untagged;
152 }
153 
154 char* Language::GetHelpText(char* ident)
155 {
156  char* s = FindAlias(ident);
157  identhelpdef* def = nullptr;
158  for (unsigned int i = 0; i < identcount; i++)
159  {
161  {
162  def = (identhelpdef*)&identtexts[i];
163  break;
164  }
165  }
166 
167  if (def == nullptr)
168  {
169  return (char*)(HELPNOHELP);
170  }
171 
172  char* text = Translate(def);
173  char* untagged = UntagText(text);
174  return untagged;
175 }
176 
177 char* Language::GetHelpText(Symbol symbol)
178 {
179  helptextdef* def = nullptr;
180  for (unsigned int i = 0; i < helpcount; i++)
181  {
182  if (helptexts[i].symbol == symbol)
183  {
184  def = (helptextdef*)&helptexts[i];
185  break;
186  }
187  }
188 
189  if (def == nullptr)
190  {
191  return (char*)(HELPNOHELP);
192  }
193 
194  char* text = Translate(def);
195  char* untagged = UntagText(text);
196  return untagged;
197 }
198 
199 char* Language::UntagText(const char* text)
200 {
201  if (lastText != nullptr)
202  {
203  delete lastText;
204  lastText = nullptr;
205  }
206 
207  if (text == nullptr)
208  {
209  return nullptr;
210  }
211 
212  unsigned int count = sizeof(ansiTags) / sizeof(texttag);
213  char* untagged = new char[StrLen(text) * 2];
214  texttag* tags = ansiMode
215  ? (texttag*)ansiTags
216  : (texttag*)emptyTags;
217  Untag(untagged, text, tags, count);
218 
219  unsigned int len = StrLen(untagged) + 1;
220  lastText = new char[len];
221  MemCopy(lastText, untagged, len);
222  delete [] untagged;
223 
224  return lastText;
225 }
226 
227 bool Language::CharIsQuote(unsigned long character)
228 {
229  return (character == '"');
230 }
231 
232 bool Language::CharIsBlank(unsigned long character)
233 {
234 #if !defined(APPLE)
235  if (character == '\r')
236  {
237  return true;
238  }
239 #endif
240 
241  return (character == ' ' || character == '\t');
242 }
243 
244 bool Language::CharIsNewLine(unsigned long character)
245 {
246 #if defined(APPLE)
247  return (character == '\r');
248 #else
249  return (character == '\n');
250 #endif
251 }
252 
253 bool Language::CharIsOperator(unsigned long character)
254 {
255  static const unsigned int count = sizeof(operators) / sizeof(operatordef);
256  for (unsigned int i = 0; i < count; i++)
257  {
258  if (operators[i].chr == (char)character)
259  {
260  return true;
261  }
262  }
263 
264  return false;
265 }
char * UntagText(const char *text)
Definition: language.cpp:199
#define NEWLINE
Definition: amath.h:222
const char * name
Definition: kword.h:52
virtual char * Translate(identhelpdef *def)=0
virtual char * Translate(helptextdef *def)=0
virtual bool CharIsBlank(unsigned long character)
Definition: language.cpp:232
#define EMPTYSTRING
Definition: amath.h:213
Symbol FindKeyword(const char *ident) const
Definition: language.cpp:118
#define TXTSTARTMSG
Definition: amath.h:288
#define SPACE
Definition: amath.h:214
char * FindAlias(const char *ident) const
Definition: language.cpp:105
Character representation of keyword tied with its symbol.
Definition: kword.h:48
static const texttag ansiTags[]
Definition: language.cpp:42
char * GetHelpText(Symbol symbol)
Definition: language.cpp:177
char * GetText(int id)
Definition: language.cpp:132
virtual bool StrIsEqualLoc(const char *s1, const char *s2)=0
unsigned int helpcount
Definition: language.h:73
virtual bool CharIsQuote(unsigned long character)
Definition: language.cpp:227
Definition: amatht.h:33
static const keyworddef keywords[]
Definition: kword.h:55
static const texttag emptyTags[]
Definition: language.cpp:61
bool StrIsEqual(const char *s1, const char *s2)
Compare two null terminated strings to each other.
Definition: strcmp.c:50
unsigned int identcount
Definition: language.h:72
unsigned int textcount
Definition: language.h:71
virtual ~Language()
Definition: language.cpp:87
Symbol symbol
Definition: help.h:51
Language()
Definition: language.cpp:76
Symbol symbol
Definition: kword.h:51
char * lastText
Definition: language.h:79
static const identhelpdef identtexts[]
Definition: ident.h:45
keyworddef * keywordsloc
Definition: language.h:69
void Untag(char *destination, const char *source, texttag tags[], unsigned int tagcount)
Definition: untag.c:32
unsigned int aliascount
Definition: language.h:74
void SetAnsiMode(bool value)
Definition: language.cpp:100
virtual bool CharIsNewLine(unsigned long character)
Definition: language.cpp:244
static const identalias identaliases[]
Definition: functionalias.h:35
const char * alias
Definition: amatht.h:42
Character definition of operators.
Definition: operatordefs.h:45
const char * ident
Definition: amatht.h:48
unsigned int keywordcount
Definition: language.h:70
int StrLen(const char *string)
Get the length of a null terminated string.
Definition: strlen.c:34
char * GetHelpText(char *ident)
Definition: language.cpp:154
int id
Definition: amatht.h:35
virtual char * Translate(textdef *def)=0
const char * ident
Definition: amatht.h:41
static const helptextdef helptexts[]
Definition: help.h:55
static const operatordef operators[]
Character representation of operators tied with their symbols.
Definition: operatordefs.h:54
virtual bool CharIsOperator(unsigned long character)
Definition: language.cpp:253
void MemCopy(void *destination, const void *source, unsigned int length)
Copy a block of memory, handling overlap.
Definition: memcpy.c:75
#define HELPNOHELP
Definition: text.h:77
static const textdef textdefs[]
Definition: text.h:104
bool ansiMode
Definition: language.h:80