KSeExpr  4.0.4.0
ExprFunc.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2019 Disney Enterprises, Inc.
2 // SPDX-License-Identifier: LicenseRef-Apache-2.0
3 // SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 
6 #include <cstdlib>
7 #include <iostream>
8 #include <map>
9 #include <mutex>
10 #include <string>
11 
12 #include "ExprBuiltins.h"
13 #include "ExprFunc.h"
14 #include "ExprNode.h"
15 #include "Expression.h"
16 
17 namespace
18 {
19 // FuncTable - table of pre-defined functions
20 class FuncTable
21 {
22 public:
23  void define(const char *name, const KSeExpr::ExprFunc &f, const char *docString = nullptr)
24  {
25  if (docString)
26  funcmap[name] = FuncMapItem(std::string(docString), f);
27  else
28  funcmap[name] = FuncMapItem(name, f);
29  }
30 
31  const KSeExpr::ExprFunc *lookup(const std::string &name)
32  {
33  const auto &i = funcmap.find(name);
34  if (i == funcmap.end())
35  return nullptr;
36  else
37  return &i->second.second;
38  }
39 
40  void getFunctionNames(std::vector<std::string> &names)
41  {
42  for (const auto &i : funcmap)
43  names.push_back(i.first);
44  }
45 
46  std::string getDocString(const char *functionName)
47  {
48  const auto &i = funcmap.find(functionName);
49  if (i == funcmap.end())
50  return "";
51  else
52  return i->second.first;
53  }
54 
55  size_t sizeInBytes() const
56  {
57  size_t totalSize = 0;
58  for (const auto &it : funcmap) {
59  totalSize += it.first.size() + sizeof(FuncMapItem);
60  const KSeExpr::ExprFunc &function = it.second.second;
61  if (const KSeExpr::ExprFuncX *funcx = function.funcx()) {
62  totalSize += funcx->sizeInBytes();
63  }
64  }
65  return totalSize;
66  }
67 
68  KSeExpr::Statistics statistics() const
69  {
70  KSeExpr::Statistics statisticsDump;
71  size_t totalSize = 0;
72  for (const auto &it : funcmap) {
73  totalSize += it.first.size() + sizeof(FuncMapItem);
74  const KSeExpr::ExprFunc &function = it.second.second;
75  if (const KSeExpr::ExprFuncX *funcx = function.funcx()) {
76  funcx->statistics(statisticsDump);
77  }
78  }
79  return statisticsDump;
80  }
81 
82 private:
83  using FuncMapItem = std::pair<std::string, KSeExpr::ExprFunc>;
84  using FuncMap = std::map<std::string, FuncMapItem>;
85  FuncMap funcmap;
86 };
87 
88 std::unique_ptr<FuncTable> Functions;
89 } // namespace
90 
91 // ExprType ExprFuncX::prep(ExprFuncNode* node, bool scalarWanted, ExprVarEnv & env) const
92 //{
93 // /* call base node prep by default:
94 // this passes wantVec to all the children and sets isVec true if any
95 // child is a vec */
96 // /* TODO: check that this is correct behavior */
97 // return node->ExprNode::prep(scalarWanted, env);
98 //}
99 
100 namespace KSeExpr
101 {
103 
105 {
106  std::lock_guard<std::mutex> locker(mutex);
107  initInternal();
108 }
109 
111 {
112  std::lock_guard<std::mutex> locker(mutex);
113  Functions = nullptr;
114 }
115 
116 const ExprFunc *ExprFunc::lookup(const std::string &name)
117 {
118  std::lock_guard<std::mutex> locker(mutex);
119  if (!Functions)
120  initInternal();
121  const ExprFunc *ret = Functions->lookup(name);
122  return ret;
123 }
124 
125 inline static void defineInternal(const char *name, const ExprFunc &f)
126 {
127  // THIS FUNCTION IS NOT THREAD SAFE, it assumes you have a mutex from callee
128  // ALSO YOU MUST BE VERY CAREFUL NOT TO CALL ANYTHING THAT TRIES TO REACQUIRE MUTEX!
129  Functions->define(name, f);
130 }
131 
132 inline static void defineInternal3(const char *name, const ExprFunc &f, const char *docString)
133 {
134  // THIS FUNCTION IS NOT THREAD SAFE, it assumes you have a mutex from callee
135  // ALSO YOU MUST BE VERY CAREFUL NOT TO CALL ANYTHING THAT TRIES TO REACQUIRE MUTEX!
136  Functions->define(name, f, docString);
137 }
138 
140 {
141  // THIS FUNCTION IS NOT THREAD SAFE, it assumes you have a mutex from callee
142  // ALSO YOU MUST BE VERY CAREFUL NOT TO CALL ANYTHING THAT TRIES TO REACQUIRE MUTEX!
143 
144  if (Functions)
145  return;
146  Functions = std::make_unique<FuncTable>();
148 }
149 
150 void ExprFunc::define(const char *name, const ExprFunc &f)
151 {
152  std::lock_guard<std::mutex> locker(mutex);
153  if (!Functions)
154  initInternal();
155  defineInternal(name, f);
156 }
157 
158 void ExprFunc::define(const char *name, const ExprFunc &f, const char *docString)
159 {
160  std::lock_guard<std::mutex> locker(mutex);
161  if (!Functions)
162  initInternal();
163  defineInternal3(name, f, docString);
164 }
165 
166 void ExprFunc::getFunctionNames(std::vector<std::string> &names)
167 {
168  std::lock_guard<std::mutex> locker(mutex);
169  if (!Functions)
170  initInternal();
171  Functions->getFunctionNames(names);
172 }
173 
174 std::string ExprFunc::getDocString(const char *functionName)
175 {
176  std::lock_guard<std::mutex> locker(mutex);
177  if (!Functions)
178  initInternal();
179  std::string ret = Functions->getDocString(functionName);
180  return ret;
181 }
182 
184 {
185  std::lock_guard<std::mutex> locker(mutex);
186  if (!Functions)
187  initInternal();
188  return Functions->sizeInBytes();
189 }
190 
192 {
193  std::lock_guard<std::mutex> locker(mutex);
194  if (!Functions)
195  initInternal();
196  return Functions->statistics();
197 }
198 } // namespace KSeExpr
Extension function spec, used for complicated argument custom functions.
Definition: ExprFuncX.h:23
Function Definition, used in parse tree and func table.
Definition: ExprFunc.h:35
static void getFunctionNames(std::vector< std::string > &names)
Get a list of registered builtin and DSO generated functions.
Definition: ExprFunc.cpp:166
static void define(const char *name, const ExprFunc &f, const char *docString)
Definition: ExprFunc.cpp:158
static size_t sizeInBytes()
Get the total size estimate of all plugins.
Definition: ExprFunc.cpp:183
static void init()
call to define built-in funcs
Definition: ExprFunc.cpp:104
static const ExprFunc * lookup(const std::string &name)
Lookup a builtin function by name.
Definition: ExprFunc.cpp:116
static void initInternal()
Definition: ExprFunc.cpp:139
static void cleanup()
cleanup all functions
Definition: ExprFunc.cpp:110
static std::string getDocString(const char *functionName)
Get doc string for a specific function.
Definition: ExprFunc.cpp:174
static Statistics statistics()
Dump statistics.
Definition: ExprFunc.cpp:191
static std::mutex mutex
Definition: ExprFunc.cpp:102
static void defineInternal(const char *name, const ExprFunc &f)
Definition: ExprFunc.cpp:125
std::map< std::string, double > Statistics
Definition: ExprFuncX.h:16
void defineBuiltins(ExprFunc::Define, ExprFunc::Define3 define3)
static void defineInternal3(const char *name, const ExprFunc &f, const char *docString)
Definition: ExprFunc.cpp:132