Qore Programming Language  0.9.4.6
QoreLibIntern.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreLibIntern.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2020 Qore Technologies, s.r.o.
8 
9  Permission is hereby granted, free of charge, to any person obtaining a
10  copy of this software and associated documentation files (the "Software"),
11  to deal in the Software without restriction, including without limitation
12  the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  and/or sell copies of the Software, and to permit persons to whom the
14  Software is furnished to do so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in
17  all copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  DEALINGS IN THE SOFTWARE.
26 
27  Note that the Qore library is released under a choice of three open-source
28  licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29  information.
30 */
31 
32 #ifndef _QORE_QORELIBINTERN_H
33 
34 #define _QORE_QORELIBINTERN_H
35 
36 #include "qore/intern/config.h"
37 
38 #include <atomic>
39 #include <cstdarg>
40 #include <sys/types.h>
41 
42 #ifdef HAVE_SYS_STATVFS_H
43 #define Q_HAVE_STATVFS
44 #include <sys/statvfs.h>
45 #endif
46 #include <sys/stat.h>
47 #include <unistd.h>
48 #ifdef HAVE_EXECINFO_H
49 #include <execinfo.h>
50 #endif
51 #ifdef HAVE_ARPA_INET_H
52 #include <arpa/inet.h>
53 #endif
54 #ifdef HAVE_SYS_SOCKET_H
55 #include <sys/socket.h>
56 #endif
57 #ifdef HAVE_NETDB_H
58 #include <netdb.h>
59 #endif
60 #ifdef HAVE_NETINET_IN_H
61 #include <netinet/in.h>
62 #endif
63 #ifdef HAVE_ARPA_INET_H
64 #include <arpa/inet.h>
65 #endif
66 #ifdef HAVE_SYS_SOCKET_H
67 #include <sys/socket.h>
68 #endif
69 #ifdef HAVE_NETDB_H
70 #include <netdb.h>
71 #endif
72 #ifdef HAVE_ARPA_INET_H
73 #include <arpa/inet.h>
74 #endif
75 #ifdef HAVE_WINSOCK2_H
76 #include <winsock2.h>
77 #endif
78 #ifdef HAVE_WS2TCPIP_H
79 #include <ws2tcpip.h>
80 #endif
81 #ifdef HAVE_SYS_UN_H
82 #include <sys/un.h>
83 #endif
84 #ifdef HAVE_NETINET_TCP_H
85 #include <netinet/tcp.h>
86 #endif
87 
88 #ifdef HAVE_STDINT_H
89 #include <stdint.h>
90 #endif
91 #ifdef HAVE_INTTYPES_H
92 #include <cinttypes>
93 #endif
94 
95 #ifndef HAVE_STRCASESTR
96 extern char* strcasestr(const char* s1, const char* s2);
97 #endif
98 
99 // make sure that intmax support is available from mpfr
100 #define MPFR_USE_INTMAX_T 1
101 
102 // for arbitrary-precision numeric support
103 #include <mpfr.h>
104 
105 // printf format for size_t or qore_size_t integers
106 #if TARGET_BITS == 64
107 #define QSD QLLD
108 #else
109 #define QSD "%d"
110 #endif
111 
112 #include <set>
113 #include <list>
114 #include <map>
115 #include <vector>
116 
117 // here we define virtual types
118 #define NT_NONE -1
119 #define NT_ALL -2
120 #define NT_CODE -3
121 #define NT_SOFTINT -4
122 #define NT_SOFTFLOAT -5
123 #define NT_SOFTNUMBER -6
124 #define NT_SOFTBOOLEAN -7
125 #define NT_SOFTSTRING -8
126 #define NT_SOFTDATE -9
127 #define NT_SOFTLIST -10
128 #define NT_TIMEOUT -11
129 #define NT_INTORFLOAT -12
130 #define NT_INTFLOATORNUMBER -13
131 #define NT_FLOATORNUMBER -14
132 
133 #define NT_SOMETHING -101 // i.e. "not NOTHING"
134 #define NT_DATA -102 // either QoreStringNode or BinaryNode
135 
136 typedef std::set<QoreObject*> obj_set_t;
137 
138 // issue #3818: Qore SSL app-specific data index
139 DLLLOCAL extern int qore_ssl_data_index;
140 
142 enum q_setpub_t : unsigned char {
143  CSP_UNCHANGED = 0,
144  CSP_SETPRIV = 1,
145  CSP_SETPUB = 2,
146 };
147 
148 DLLLOCAL void parse_init_value(QoreValue& val, LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo);
149 
150 // returns true if the node needs to be scanned for recursive references or not
151 DLLLOCAL bool needs_scan(const AbstractQoreNode* n);
152 DLLLOCAL bool needs_scan(const QoreValue& v);
153 // increments or decrements the object count depending on the sign of the argument (cannot be 0)
154 DLLLOCAL void inc_container_obj(const AbstractQoreNode* n, int dt);
155 
156 DLLLOCAL AbstractQoreNode* missing_openssl_feature(const char* f, ExceptionSink* xsink);
157 
158 hashdecl ParseWarnOptions {
159  int64 parse_options;
160  int warn_mask;
161 
162  DLLLOCAL ParseWarnOptions() : parse_options(0), warn_mask(0) {
163  }
164 
165  DLLLOCAL ParseWarnOptions(int64 n_parse_options, int n_warn_mask = 0) : parse_options(n_parse_options), warn_mask(n_warn_mask) {
166  }
167 
168  DLLLOCAL void operator=(const ParseWarnOptions& pwo) {
169  parse_options = pwo.parse_options;
170  warn_mask = pwo.warn_mask;
171  }
172 
173  DLLLOCAL bool operator==(const ParseWarnOptions& pwo) const {
174  return parse_options == pwo.parse_options && warn_mask == pwo.warn_mask;
175  }
176 };
177 
178 hashdecl QoreProgramLineLocation {
179  int16_t start_line = -1,
180  end_line = -1;
181 
182  // if sline is 0 and eline is > 0 then set sline to 1
183  DLLLOCAL QoreProgramLineLocation(int sline, int eline) : start_line(sline ? sline : (eline ? 1 : 0)), end_line(eline) {
184  assert(sline <= 0xffff);
185  assert(eline <= 0xffff);
186  }
187 
188  DLLLOCAL QoreProgramLineLocation() {
189  }
190 
191  DLLLOCAL QoreProgramLineLocation(const QoreProgramLineLocation& old) = default;
192 
193  DLLLOCAL QoreProgramLineLocation(QoreProgramLineLocation&& old) = default;
194 };
195 
196 hashdecl QoreProgramLocation : public QoreProgramLineLocation {
197 public:
198  // "blank" constructor
199  DLLLOCAL QoreProgramLocation() {
200  }
201 
202  DLLLOCAL explicit QoreProgramLocation(const char* f, int sline, int eline, const char* source, int offset,
203  const char* lang = "Qore") :
204  QoreProgramLineLocation(sline, eline), file(f), source(source), lang(lang), offset(offset) {
205  assert(offset <= 0xffff);
206  }
207 
208  DLLLOCAL explicit QoreProgramLocation(const char* f, int sline = 0, int eline = 0) :
209  QoreProgramLineLocation(sline, eline), file(f) {
210  }
211 
212  // sets file position info from thread-local parse information
213  DLLLOCAL QoreProgramLocation(int sline, int eline);
214 
215  DLLLOCAL QoreProgramLocation(const QoreProgramLocation& old) = default;
216 
217  DLLLOCAL QoreProgramLocation(QoreProgramLocation&& old) = default;
218 
219  DLLLOCAL void clear() {
220  start_line = end_line = -1;
221  file = nullptr;
222  source = nullptr;
223  offset = 0;
224  }
225 
226  DLLLOCAL void toString(QoreString& str) const;
227 
228  DLLLOCAL const char* getFile() const {
229  return file;
230  }
231 
232  DLLLOCAL const char* getFileValue() const {
233  return file ? file : "";
234  }
235 
236  DLLLOCAL const char* getSource() const {
237  return source;
238  }
239 
240  DLLLOCAL const char* getSourceValue() const {
241  return source ? source : "";
242  }
243 
244  DLLLOCAL const char* getLanguage() const {
245  return lang;
246  }
247 
248  DLLLOCAL const char* getLanguageValue() const {
249  return lang ? lang : "";
250  }
251 
252  DLLLOCAL void setFile(const char* f) {
253  file = f;
254  }
255 
256  DLLLOCAL void setSource(const char* s) {
257  source = s;
258  }
259 
260  DLLLOCAL void setLanguage(const char* l) {
261  lang = l;
262  }
263 
264  DLLLOCAL bool operator<(const QoreProgramLocation& loc) const {
265  return start_line < loc.start_line
266  || end_line < loc.end_line
267  || file < loc.file
268  || source < loc.source
269  || offset < loc.offset
270  || lang < loc.lang;
271  }
272 
273  DLLLOCAL bool operator==(const QoreProgramLocation& loc) const {
274  return start_line == loc.start_line
275  && end_line == loc.end_line
276  && file == loc.file
277  && source == loc.source
278  && offset == loc.offset
279  && lang == loc.lang;
280  }
281 
282  DLLLOCAL bool operator!=(const QoreProgramLocation& loc) const {
283  return !(*this == loc);
284  }
285 
286 protected:
287  const char* file = nullptr;
288  const char* source = nullptr;
289  const char* lang = "Qore";
290 
291 public:
292  int16_t offset = 0;
293 };
294 
295 DLLLOCAL extern const QoreProgramLocation loc_builtin;
296 
297 hashdecl QoreCommandLineLocation : public QoreProgramLocation {
298  DLLLOCAL QoreCommandLineLocation() : QoreProgramLocation("<command-line>", 1, 1) {
299  }
300 };
301 
302 // parse location for objects parsed on the command-line
303 DLLLOCAL extern QoreCommandLineLocation qoreCommandLineLocation;
304 
305 // the following functions are implemented in support.cpp
306 DLLLOCAL void parse_error(const QoreProgramLocation& loc, const char* fmt, ...);
307 DLLLOCAL void parseException(const QoreProgramLocation& loc, const char* err, const char* fmt, ...);
308 DLLLOCAL void parseException(const QoreProgramLocation& loc, const char* err, QoreStringNode* desc);
309 
310 DLLLOCAL QoreString* findFileInPath(const char* file, const char* path);
311 DLLLOCAL QoreString* findFileInEnvPath(const char* file, const char* varname);
312 DLLLOCAL int qore_find_file_in_path(QoreString& str, const char* file, const char* path);
313 
314 DLLLOCAL const QoreTypeInfo* getBuiltinUserTypeInfo(const char* str);
315 DLLLOCAL const QoreTypeInfo* getBuiltinUserOrNothingTypeInfo(const char* str);
316 //DLLLOCAL qore_type_t getBuiltinType(const char* str);
317 DLLLOCAL const char* getBuiltinTypeName(qore_type_t type);
318 
319 // processes parameter information
320 DLLLOCAL void qore_process_params(unsigned num_params, type_vec_t& typeList, arg_vec_t& defaultArgList, va_list args);
321 DLLLOCAL void qore_process_params(unsigned num_params, type_vec_t& typeList, arg_vec_t& defaultArgList, name_vec_t& nameList, va_list args);
322 
323 // call to get a node with reference count 1 (copy on write)
324 void ensure_unique(AbstractQoreNode** v, ExceptionSink* xsink);
325 void ensure_unique(QoreValue& v, ExceptionSink* xsink);
326 
327 #ifndef HAVE_ATOLL
328 #ifdef HAVE_STRTOIMAX
329 static inline long long atoll(const char* str) {
330  return strtoimax(str, 0, 10);
331 }
332 #else
333 static inline long long atoll(const char* str) {
334  long long i;
335  sscanf(str, "%lld", &i);
336  return i;
337 }
338 #endif
339 #endif
340 
341 #if !defined(HAVE_STRTOLL) && defined(HAVE_STRTOIMAX)
342 #include <cinttypes>
343 #define strtoll strtoimax
344 #endif
345 
346 // use umem for memory allocation if available
347 #ifdef HAVE_UMEM_H
348 #include <umem.h>
349 #endif
350 
351 #ifdef HAVE_OPENSSL_CONST
352 #define OPENSSL_CONST const
353 #else
354 #define OPENSSL_CONST
355 #endif
356 
357 #ifdef HAVE_X509_GET0_SIGNATURE_CONST
358 #define OPENSSL_X509_GET0_SIGNATURE_CONST const
359 #else
360 #define OPENSSL_X509_GET0_SIGNATURE_CONST
361 #endif
362 
363 typedef std::set<const AbstractQoreNode*> const_node_set_t;
364 typedef std::set<LocalVar*> lvar_set_t;
365 
366 class LVarSet : public lvar_set_t {
367 protected:
368  // true if at least one variable in the set could contain an object or a closure (also through a container)
369  bool needs_scan;
370 
371 public:
372  // creates the object
373  DLLLOCAL LVarSet() : needs_scan(false) {
374  }
375 
376  // adds a local variable to the set
377  DLLLOCAL void add(LocalVar* var);
378 
379  // returns true if at least one variable in the set could contain an object or a closure (also through a container)
380  DLLLOCAL bool needsScan() const {
381  return needs_scan;
382  }
383 };
384 
385 enum obe_type_e { OBE_Unconditional, OBE_Success, OBE_Error };
386 
387 class StatementBlock;
388 typedef std::pair<enum obe_type_e, StatementBlock*> qore_conditional_block_exit_statement_t;
389 
390 typedef std::list<qore_conditional_block_exit_statement_t> block_list_t;
391 
392 // for maps of thread condition variables to TIDs
393 typedef std::map<QoreCondition*, int> cond_map_t;
394 
395 #if defined(HAVE_CHECK_STACK_POS)
396 #define QORE_MANAGE_STACK
397 #endif
398 
399 // Datasource Access Helper codes
400 #define DAH_NOCHANGE 0 // acquire lock temporarily
401 #define DAH_ACQUIRE 1 // acquire lock and hold
402 #define DAH_RELEASE 2 // release lock at end of action
403 #define DAH_NOCONN 3 // acquire lock temporarily and do not make a connection
404 
405 #define DAH_TEXT(d) (d == DAH_RELEASE ? "RELEASE" : (d == DAH_ACQUIRE ? "ACQUIRE" : "NOCHANGE"))
406 
407 DLLLOCAL int check_lvalue(QoreValue n, bool assign = true);
408 DLLLOCAL int check_lvalue(AbstractQoreNode* n, bool assign = true);
409 DLLLOCAL int check_lvalue_int(const QoreProgramLocation* loc, const QoreTypeInfo*& typeInfo, const char* name);
410 DLLLOCAL int check_lvalue_float(const QoreProgramLocation* loc, const QoreTypeInfo*& typeInfo, const char* name);
411 DLLLOCAL int check_lvalue_int_float_number(const QoreProgramLocation* loc, const QoreTypeInfo*& typeInfo, const char* name);
412 DLLLOCAL int check_lvalue_number(const QoreProgramLocation* loc, const QoreTypeInfo*& typeInfo, const char* name);
413 
414 DLLLOCAL extern QoreClass* QC_PSEUDOVALUE;
415 DLLLOCAL extern QoreClass* QC_PSEUDONOTHING;
416 
417 DLLLOCAL bool node_has_effect(const AbstractQoreNode* n);
418 
419 DLLLOCAL QoreString* q_fix_decimal(QoreString* str, size_t offset = 0);
420 DLLLOCAL QoreStringNode* q_fix_decimal(QoreStringNode* str, size_t offset = 0);
421 
422 #ifdef _Q_WINDOWS
423 // simulated block size for statvfs() on Windows
424 #define Q_SVF_BSIZE 4096
425 #define Q_HAVE_STATVFS
426 hashdecl statvfs {
427  unsigned long f_bsize; /* File system block size */
428  unsigned long f_frsize; /* Fundamental file system block size */
429  unsigned int f_blocks; /* Blocks on FS in units of f_frsize */
430  unsigned int f_bfree; /* Free blocks */
431  unsigned int f_bavail; /* Blocks available to non-root */
432  unsigned int f_files; /* Total inodes */
433  unsigned int f_ffree; /* Free inodes */
434  unsigned int f_favail; /* Free inodes for non-root */
435  unsigned long f_fsid; /* Filesystem ID */
436  unsigned long f_flag; /* Bit mask of values */
437  unsigned long f_namemax; /* Max file name length */
438 
439  DLLLOCAL void set(int64 avail, int64 total, int64 free) {
440  f_frsize = f_bsize = Q_SVF_BSIZE;
441  f_blocks = total / Q_SVF_BSIZE;
442  f_bfree = free / Q_SVF_BSIZE;
443  f_bavail = avail / Q_SVF_BSIZE;
444  // simulate inodes
445  f_files = f_blocks / 8;
446  f_ffree = f_bfree / 8;
447  f_favail = f_bavail / 8;
448  f_fsid = 0;
449  f_flag = 0;
450  f_namemax = 256;
451  }
452 };
453 DLLLOCAL int statvfs(const char* path, struct statvfs* buf);
454 DLLLOCAL int q_fstatvfs(const char* filepath, struct statvfs* buf);
455 #endif
456 
457 class QoreParseListNode;
458 
459 #include "qore/intern/NamedScope.h"
460 #include "qore/intern/QoreTypeInfo.h"
461 #include "qore/intern/ParseNode.h"
462 #include "qore/intern/QoreThreadList.h"
463 #include "qore/intern/lvalue_ref.h"
464 #include "qore/intern/qore_thread_intern.h"
465 #include "qore/intern/Function.h"
466 #include "qore/intern/CallReferenceCallNode.h"
467 #include "qore/intern/CallReferenceNode.h"
468 #include "qore/intern/BuiltinFunction.h"
469 #include "qore/intern/AbstractStatement.h"
470 #include "qore/intern/Variable.h"
471 #include "qore/intern/LocalVar.h"
472 #include "qore/intern/ScopedObjectCallNode.h"
473 #include "qore/intern/NewComplexTypeNode.h"
474 #include "qore/intern/ScopedRefNode.h"
475 #include "qore/intern/ClassRefNode.h"
476 #include "qore/intern/Context.h"
477 #include "qore/intern/BarewordNode.h"
478 #include "qore/intern/SelfVarrefNode.h"
479 #include "qore/intern/StaticClassVarRefNode.h"
480 #include "qore/intern/BackquoteNode.h"
481 #include "qore/intern/ContextrefNode.h"
482 #include "qore/intern/ContextRowNode.h"
483 #include "qore/intern/ComplexContextrefNode.h"
484 #include "qore/intern/FindNode.h"
485 #include "qore/intern/VRMutex.h"
486 #include "qore/intern/VLock.h"
487 #include "qore/intern/QoreException.h"
488 #include "qore/intern/StatementBlock.h"
489 #include "qore/intern/VarRefNode.h"
490 #include "qore/intern/QoreRegexSubst.h"
491 #include "qore/intern/QoreRegex.h"
492 #include "qore/intern/QoreTransliteration.h"
493 #include "qore/intern/ObjectMethodReferenceNode.h"
494 #include "qore/intern/QoreClosureParseNode.h"
495 #include "qore/intern/QoreClosureNode.h"
496 #include "qore/intern/QoreImplicitArgumentNode.h"
497 #include "qore/intern/QoreImplicitElementNode.h"
498 #include "qore/intern/QoreOperatorNode.h"
499 #include "qore/intern/QoreTimeZoneManager.h"
500 #include "qore/intern/ContextStatement.h"
501 #include "qore/intern/SwitchStatement.h"
502 #include "qore/intern/QorePseudoMethods.h"
503 #include "qore/intern/ParseReferenceNode.h"
504 #include "qore/intern/WeakReferenceNode.h"
505 
506 DLLLOCAL extern std::atomic<bool> qore_shutdown;
507 
508 DLLLOCAL extern int qore_library_options;
509 
510 #ifndef HAVE_GETHOSTBYADDR_R
511 DLLLOCAL extern QoreThreadLock lck_gethostbyaddr;
512 #endif
513 
514 DLLLOCAL extern qore_license_t qore_license;
515 
516 #ifndef NET_BUFSIZE
517 #define NET_BUFSIZE 1024
518 #endif
519 
520 #ifndef HOSTNAMEBUFSIZE
521 #define HOSTNAMEBUFSIZE 512
522 #endif
523 
524 #ifndef HAVE_LOCALTIME_R
525 DLLLOCAL extern QoreThreadLock lck_localtime;
526 #endif
527 
528 #ifndef HAVE_GMTIME_R
529 DLLLOCAL extern QoreThreadLock lck_gmtime;
530 #endif
531 
532 DLLLOCAL extern char table64[64];
533 
534 DLLLOCAL int get_nibble(char c, ExceptionSink* xsink);
535 DLLLOCAL BinaryNode* parseHex(const QoreProgramLocation* loc, const char* buf, int len);
536 DLLLOCAL void print_node(FILE* fp, const QoreValue qv);
537 DLLLOCAL void delete_global_variables();
538 DLLLOCAL void init_lib_intern(char* env[]);
539 DLLLOCAL QoreParseListNode* make_args(const QoreProgramLocation* loc, QoreValue arg);
540 
541 DLLLOCAL QoreValue copy_value_and_resolve_lvar_refs(const QoreValue& n, ExceptionSink* xsink);
542 
543 DLLLOCAL void init_qore_types();
544 DLLLOCAL void delete_qore_types();
545 
546 DLLLOCAL QoreListNode* stat_to_list(const struct stat& sbuf);
547 DLLLOCAL QoreHashNode* stat_to_hash(const struct stat& sbuf, const TypedHashDecl* hd = hashdeclStatInfo);
548 DLLLOCAL QoreHashNode* statvfs_to_hash(const struct statvfs& statvfs);
549 
550 // only called in stage 1 parsing: true means node requires run-time evaluation
551 //DLLLOCAL bool needsEval(AbstractQoreNode* n);
552 
553 DLLLOCAL const char* check_hash_key(const QoreHashNode* h, const char* key, const char* err, ExceptionSink* xsink);
554 
555 // class for master namespace of all builtin classes, constants, etc
556 class StaticSystemNamespace : public RootQoreNamespace {
557 public:
558  DLLLOCAL StaticSystemNamespace();
559 
560  DLLLOCAL ~StaticSystemNamespace();
561 };
562 
563 // master namespace of all builtin classes, constants, etc
564 DLLLOCAL extern StaticSystemNamespace* staticSystemNamespace;
565 
566 class QoreParseListNodeParseInitHelper {
567 private:
568  QoreParseListNode* l;
569  int pos = -1;
570  LocalVar* oflag;
571  int pflag;
572  int& lvids;
573 
574 public:
575  DLLLOCAL QoreParseListNodeParseInitHelper(QoreParseListNode* n_l, LocalVar* n_oflag, int n_pflag, int& n_lvids) :
576  l(n_l), oflag(n_oflag), pflag(n_pflag), lvids(n_lvids) {
577  }
578 
579  DLLLOCAL QoreValue parseInit(const QoreTypeInfo*& typeInfo) {
580  //printd(0, "QoreListNodeParseInitHelper::parseInit() this=%p %d/%d (l=%p)\n", this, index(), getList()->size(), getList());
581 
582  typeInfo = nullptr;
583  QoreValue& n = l->getReference(pos);
584  parse_init_value(n, oflag, pflag, lvids, typeInfo);
585  return n;
586  }
587 
588  DLLLOCAL bool next() {
589  ++pos;
590  if (pos == (int)l->size()) {
591  pos = -1;
592  return false;
593  }
594  return true;
595  }
596 
597  DLLLOCAL int index() {
598  return pos;
599  }
600 };
601 
602 class QorePossibleListNodeParseInitHelper {
603 private:
604  LocalVar* oflag;
605  int pflag;
606  int& lvids;
607  QoreListNode* l;
608  bool finished;
609  qore_size_t pos = -1;
610  const QoreTypeInfo* singleTypeInfo = nullptr;
611 
612 public:
613  DLLLOCAL QorePossibleListNodeParseInitHelper(QoreValue& n, LocalVar* n_oflag, int n_pflag, int& n_lvids) :
614  oflag(n_oflag),
615  pflag(n_pflag),
616  lvids(n_lvids),
617  l(n.getType() == NT_LIST ? n.get<QoreListNode>() : nullptr),
618  finished(!l) {
619  // if the expression is not a list, then initialize it now
620  // and save the return type
621  if (!l) {
622  parse_init_value(n, oflag, pflag, lvids, singleTypeInfo);
623  // set type info to 0 if the expression can return a list
624  // FIXME: set list element type here when list elements can have types
625  //printd(0, "singleTypeInfo=%s la=%d\n", QoreTypeInfo::getName(singleTypeInfo), QoreTypeInfo::parseAccepts(listTypeInfo, singleTypeInfo));
626  if (QoreTypeInfo::parseAccepts(listTypeInfo, singleTypeInfo))
627  singleTypeInfo = 0;
628  }
629  }
630 
631  DLLLOCAL bool noArgument() const {
632  return finished;
633  }
634 
635  DLLLOCAL bool next() {
636  ++pos;
637 
638  if (finished)
639  return false;
640 
641  if (pos == l->size()) {
642  finished = true;
643  return false;
644  }
645  return true;
646  }
647 
648  DLLLOCAL void parseInit(const QoreTypeInfo*& typeInfo);
649 };
650 
651 DLLLOCAL void raise_nonexistent_method_call_warning(const QoreProgramLocation* loc, const QoreClass* qc, const char* method);
652 
653 /*
654 class abstract_assignment_helper {
655 public:
656  DLLLOCAL virtual AbstractQoreNode* swapImpl(AbstractQoreNode* v, ExceptionSink* xsink) = 0;
657  DLLLOCAL virtual AbstractQoreNode* getValueImpl() const = 0;
658 };
659 */
660 
661 class qore_hash_private;
662 class qore_object_private;
663 class HashMember;
664 
665 class hash_assignment_priv {
666 public:
667  qore_hash_private& h;
668  HashMember* om;
669  qore_object_private* o = nullptr;
670 
671  DLLLOCAL hash_assignment_priv(qore_hash_private& n_h, HashMember* n_om) : h(n_h), om(n_om) {
672  }
673 
674  DLLLOCAL hash_assignment_priv(qore_hash_private& n_h, const char* key, bool must_already_exist = false, qore_object_private* obj = nullptr);
675 
676  DLLLOCAL hash_assignment_priv(QoreHashNode& n_h, const char* key, bool must_already_exist = false);
677 
678  DLLLOCAL hash_assignment_priv(QoreHashNode& n_h, const std::string &key, bool must_already_exist = false);
679 
680  DLLLOCAL hash_assignment_priv(ExceptionSink* xsink, QoreHashNode& n_h, const QoreString& key, bool must_already_exist = false);
681 
682  DLLLOCAL hash_assignment_priv(ExceptionSink* xsink, QoreHashNode& n_h, const QoreString* key, bool must_already_exist = false);
683 
684  DLLLOCAL void reassign(const char* key, bool must_already_exist = false);
685 
686  DLLLOCAL QoreValue swapImpl(QoreValue v);
687 
688  DLLLOCAL QoreValue getImpl() const;
689 
690  DLLLOCAL QoreValue operator*() const {
691  return getImpl();
692  }
693 
694  DLLLOCAL void assign(QoreValue v, ExceptionSink* xsink);
695 
696  DLLLOCAL QoreValue swap(QoreValue v) {
697  return swapImpl(v);
698  }
699 
700  DLLLOCAL static hash_assignment_priv* get(HashAssignmentHelper& h) {
701  return h.priv;
702  }
703 };
704 
705 DLLLOCAL void qore_machine_backtrace();
706 
707 #ifndef QORE_THREAD_STACK_BLOCK
708 #define QORE_THREAD_STACK_BLOCK 64
709 #endif
710 
711 template <typename T, int S1 = QORE_THREAD_STACK_BLOCK>
712 class ThreadBlock {
713 private:
714  DLLLOCAL ThreadBlock(const ThreadBlock&);
715 
716 public:
717  T var[S1];
718  int pos;
719  ThreadBlock<T, S1>* prev, * next;
720 
721  DLLLOCAL ThreadBlock(ThreadBlock* n_prev = 0) : pos(0), prev(n_prev), next(0) { }
722  DLLLOCAL ~ThreadBlock() { }
723  DLLLOCAL T& get(int p) {
724  return var[p];
725  }
726 
727  DLLLOCAL bool frameBoundary(int p);
728 };
729 
730 template <typename T, int S1 = QORE_THREAD_STACK_BLOCK>
731 class ThreadLocalDataIterator {
732  typedef ThreadLocalDataIterator<T, S1> self_t;
733 
734 public:
735  typedef ThreadBlock<T, S1> Block;
736 
737 protected:
738  Block* orig = nullptr, * curr = nullptr;
739  int pos = 0;
740 
741 public:
742  DLLLOCAL ThreadLocalDataIterator(Block* n_orig) : orig(n_orig && n_orig->pos ? n_orig : nullptr) {
743  }
744 
745  DLLLOCAL ThreadLocalDataIterator() {
746  }
747 
748  DLLLOCAL bool next() {
749  if (!orig) {
750  return false;
751  }
752 
753  do {
754  if (!curr) {
755  curr = orig;
756  pos = orig->pos - 1;
757  } else {
758  --pos;
759  if (pos < 0) {
760  if (!curr->prev) {
761  curr = 0;
762  pos = 0;
763  return false;
764  }
765  curr = curr->prev;
766  pos = curr->pos - 1;
767  }
768  }
769  } while (curr->frameBoundary(pos));
770 
771  return true;
772  }
773 
774  DLLLOCAL T& get() {
775  assert(curr);
776  return curr->get(pos);
777  }
778 };
779 
780 template <typename T, int S1 = QORE_THREAD_STACK_BLOCK>
781 class ThreadLocalData {
782 public:
783  typedef ThreadBlock<T, S1> Block;
784  typedef ThreadLocalDataIterator<T, S1> iterator;
785 
786  Block* curr;
787 
788  DLLLOCAL ThreadLocalData() {
789  curr = new Block;
790  //printf("this=%p: first curr=%p\n", this, curr);
791  }
792 
793  DLLLOCAL ~ThreadLocalData() {
794 #ifdef DEBUG
795  //if (curr->pos)
796  //printf("~ThreadLocalData::~~ThreadLocalData() this=%p: del curr=%p pos=%d next=%p prev=%p\n", this, curr, curr->pos, curr->next, curr->prev);
797 #endif
798  assert(!curr->prev);
799  assert(!curr->pos);
800  if (curr->next)
801  delete curr->next;
802  delete curr;
803  }
804 #ifdef DEBUG
805  DLLLOCAL bool empty() const {
806  return (!curr->pos && !curr->prev);
807  }
808 #endif
809 
810  DLLLOCAL int getFrameCount() const {
811  return frame_count;
812  }
813 
814 protected:
815  int frame_count = -1;
816 
817 private:
818  DLLLOCAL ThreadLocalData(const ThreadLocalData&);
819 };
820 
821 // maps from Q_AF_* to standard system AF_ constants
822 DLLLOCAL int q_get_af(int type);
823 // maps from AF_* to Q_AF_ constants
824 DLLLOCAL int q_get_raf(int type);
825 // maps from Q_SOCK_ to standard system SOCK_ constants
826 DLLLOCAL int q_get_sock_type(int t);
827 
828 class OptHashRefHelper {
829  const ReferenceNode* ref;
830  ExceptionSink* xsink;
832 
833 public:
834  DLLLOCAL OptHashRefHelper(QoreListNode* args, unsigned i, ExceptionSink* n_xsink) : ref(test_reference_param(args, i)), xsink(n_xsink), info(ref ? new QoreHashNode(autoTypeInfo) : 0, xsink) {
835  }
836  DLLLOCAL OptHashRefHelper(const ReferenceNode* n_ref, ExceptionSink* n_xsink) : ref(n_ref), xsink(n_xsink), info(ref ? new QoreHashNode(autoTypeInfo) : 0, xsink) {
837  }
838  DLLLOCAL ~OptHashRefHelper() {
839  if (!ref)
840  return;
841 
842  ExceptionSink xs;
843  QoreTypeSafeReferenceHelper rh(ref, &xs);
844  if (xs)
845  xsink->assimilate(xs);
846  if (!rh)
847  return;
848 
849  rh.assign(info.release());
850  if (xs)
851  xsink->assimilate(xs);
852  }
853  DLLLOCAL QoreHashNode* operator*() {
854  return *info;
855  }
856 };
857 
858 // pushes a marker on the local variable parse stack so that searches can skip to global thread-local variables when the search hits the marker
859 class VariableBlockHelper {
860 public:
861  DLLLOCAL VariableBlockHelper();
862  DLLLOCAL ~VariableBlockHelper();
863 };
864 
865 class ParseOptionMaps {
866 protected:
867  DLLLOCAL void doMap(int64 code, const char* desc, const char* dom = nullptr);
868 
869 public:
870  typedef std::map<int64, const char*> pomap_t;
871  typedef std::map<const char*, int64, ltstr> pormap_t;
872 
873  pomap_t pomap, dommap;
874  pormap_t pormap, domrmap;
875 
876  DLLLOCAL ParseOptionMaps();
877 
878  DLLLOCAL QoreHashNode* getCodeToStringMap() const;
879  DLLLOCAL QoreHashNode* getStringToCodeMap() const;
880 
881  DLLLOCAL QoreHashNode* getDomainToStringMap() const;
882  DLLLOCAL QoreHashNode* getStringToDomainMap() const;
883 };
884 
885 DLLLOCAL extern ParseOptionMaps pomaps;
886 
887 DLLLOCAL extern QoreString YamlNullString;
888 
889 DLLLOCAL extern bool q_disable_gc;
890 
891 DLLLOCAL QoreValue qore_parse_get_define_value(const QoreProgramLocation* loc, const char* str, QoreString& arg, bool& ok);
892 
893 #ifndef HAVE_INET_NTOP
894 DLLLOCAL const char* inet_ntop(int af, const void* src, char* dst, size_t size);
895 #endif
896 #ifndef HAVE_INET_PTON
897 DLLLOCAL int inet_pton(int af, const char* src, void* dst);
898 #endif
899 
900 DLLLOCAL AbstractQoreNode* missing_function_error(const char* func, ExceptionSink* xsink);
901 DLLLOCAL AbstractQoreNode* missing_function_error(const char* func, const char* opt, ExceptionSink* xsink);
902 DLLLOCAL AbstractQoreNode* missing_method_error(const char* meth, const char* opt, ExceptionSink* xsink);
903 
904 // checks for illegal $self assignments in an object context
905 DLLLOCAL void check_self_assignment(const QoreProgramLocation* loc, QoreValue n, LocalVar* selfid);
906 
907 DLLLOCAL void ignore_return_value(QoreSimpleValue& n);
908 
909 DLLLOCAL void qore_string_init();
910 
911 DLLLOCAL QoreListNode* split_intern(const char* pattern, qore_size_t pl, const char* str, qore_size_t sl, const QoreEncoding* enc, bool with_separator = false);
912 DLLLOCAL QoreStringNode* join_intern(const QoreStringNode* p0, const QoreListNode* l, int offset, ExceptionSink* xsink);
913 DLLLOCAL QoreListNode* split_with_quote(const QoreString* sep, const QoreString* str, const QoreString* quote, bool trim_unquoted, ExceptionSink* xsink);
914 DLLLOCAL bool inlist_intern(const QoreValue arg, const QoreListNode* l, ExceptionSink* xsink);
915 DLLLOCAL QoreStringNode* format_float_intern(const QoreString& fmt, double num, ExceptionSink* xsink);
916 DLLLOCAL QoreStringNode* format_float_intern(int prec, const QoreString& dsep, const QoreString& tsep, double num, ExceptionSink* xsink);
917 DLLLOCAL DateTimeNode* make_date_with_mask(const AbstractQoreZoneInfo* tz, const QoreString& dtstr, const QoreString& mask, ExceptionSink* xsink);
918 DLLLOCAL QoreHashNode* date_info(const DateTime& d);
919 DLLLOCAL void init_charmaps();
920 DLLLOCAL int do_unaccent(QoreString& str, const QoreString& src, ExceptionSink* xsink);
921 DLLLOCAL int do_unaccent(QoreString& str, const QoreString& src, ExceptionSink* xsink);
922 DLLLOCAL int do_tolower(QoreString& str, const QoreString& src, ExceptionSink* xsink);
923 DLLLOCAL int do_toupper(QoreString& str, const QoreString& src, ExceptionSink* xsink);
924 
925 DLLLOCAL int64 q_clock_getmillis();
926 DLLLOCAL int64 q_clock_getmicros();
927 DLLLOCAL int64 q_clock_getnanos();
928 
929 DLLLOCAL void qore_init_random_salt();
930 DLLLOCAL int qore_get_ptr_hash(QoreString& str, const void* ptr);
931 
932 // find the position of the first path separator in the string, or 0
933 DLLLOCAL const char* q_find_first_path_sep(const char* path);
934 // find the position of the last path separator in the string, or 0
935 DLLLOCAL const char* q_find_last_path_sep(const char* path);
936 
937 // reutrns the given file's mode or 0 if the stat() call fails
938 DLLLOCAL int q_get_mode(const QoreString& path);
940 
942 DLLLOCAL qore_offset_t q_UTF8_get_char_len(const char* p, qore_size_t valid_len);
943 
945 
947 DLLLOCAL qore_offset_t q_UTF16BE_get_char_len(const char* p, qore_size_t valid_len);
948 DLLLOCAL qore_offset_t q_UTF16LE_get_char_len(const char* p, qore_size_t len);
949 
950 DLLLOCAL int64 get_ms_zero(const QoreValue& v);
951 
952 DLLLOCAL AbstractQoreNode* copy_strip_complex_types(const AbstractQoreNode* n);
953 DLLLOCAL QoreValue copy_strip_complex_types(const QoreValue& n);
954 
955 // for IPv4/v6 only
956 DLLLOCAL void* qore_get_in_addr(struct sockaddr *sa);
957 // for IPv4/v6 only
958 DLLLOCAL size_t qore_get_in_len(struct sockaddr *sa);
959 
960 #ifdef QORE_MANAGE_STACK
961 DLLLOCAL size_t q_thread_get_stack_size();
962 DLLLOCAL size_t q_thread_set_stack_size(size_t size, ExceptionSink* xsink);
963 #endif
964 
965 DLLLOCAL QoreHashNode* get_source_location(const QoreProgramLocation* loc);
966 
967 DLLLOCAL void qore_delete_module_options();
968 
969 DLLLOCAL const QoreTypeInfo* qore_get_type_from_string_intern(const char* str);
970 
971 DLLLOCAL QoreValue get_call_reference_intern(QoreObject* self, const QoreStringNode* identifier, ExceptionSink* xsink);
972 
973 #endif
defines string encoding functions in Qore
Definition: QoreEncoding.h:83
This is the hash or associative list container type in Qore, dynamically allocated only...
Definition: QoreHashNode.h:50
use this class to make assignments to hash keys from a pointer to the key value
Definition: QoreHashNode.h:671
const qore_type_t NT_LIST
type value for QoreListNode
Definition: node_types.h:50
Holds absolute and relative date/time values in Qore with precision to the microsecond.
Definition: DateTime.h:93
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:54
size_t qore_size_t
used for sizes (same range as a pointer)
Definition: common.h:73
static const ReferenceNode * test_reference_param(const QoreListNode *n, qore_size_t i)
returns a ReferenceNode pointer for the argument position given or 0 if there is no argument there or...
Definition: params.h:65
DLLLOCAL T * release()
releases the pointer to the caller
Definition: ReferenceHolder.h:91
Qore&#39;s string type supported by the QoreEncoding class.
Definition: QoreString.h:81
Qore&#39;s string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
the root namespace of a QoreProgram object
Definition: QoreNamespace.h:286
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
Qore&#39;s parse tree/value type for date-time values, reference-counted, dynamically-allocated only...
Definition: DateTimeNode.h:45
DLLEXPORT size_t size() const
returns the number of elements in the list
defines a Qore-language class
Definition: QoreClass.h:239
parse type: reference to a lvalue expression
Definition: ReferenceNode.h:45
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:262
qore_license_t
qore library and module license type identifiers
Definition: common.h:85
the implementation of Qore&#39;s object data type, reference counted, dynamically-allocated only ...
Definition: QoreObject.h:61
static unsigned num_params(const QoreListNode *n)
returns the number of arguments passed to the function
Definition: params.h:54
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:46
std::vector< std::string > name_vec_t
vector of parameter names for parameter lists
Definition: common.h:257
helper class to manage variable references passed to functions and class methods, stack only...
Definition: QoreTypeSafeReferenceHelper.h:57
long long int64
64bit integer type, cannot use int64_t here since it breaks the API on some 64-bit systems due to equ...
Definition: common.h:260
std::vector< QoreValue > arg_vec_t
vector of value information for default argument lists
Definition: common.h:254
intptr_t qore_offset_t
used for offsets that could be negative
Definition: common.h:76
typed hash declaration
Definition: TypedHashDecl.h:44
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode) ...
Definition: common.h:70
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:47
std::vector< const QoreTypeInfo * > type_vec_t
vector of type information for parameter lists
Definition: common.h:251
DLLEXPORT BinaryNode * parseHex(const char *buf, int len, ExceptionSink *xsink)
parses a string of hex characters and returns a BinaryNode
DLLEXPORT void assimilate(ExceptionSink *xs)
assimilates all entries of the "xs" argument by appending them to the internal list and deletes the "...
holds arbitrary binary data
Definition: BinaryNode.h:41