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