1 /* -*- mode:C++;compile-command: "g++-3.4 -I.. -g -c global.cc" -*- */
2 
3 /* Global definition and constants (see also dispatch.h)
4  *  Copyright (C) 2000,2014 B. Parisse, Institut Fourier, 38402 St Martin d'Heres
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 #ifndef _GIAC_GLOBAL_H
20 #define _GIAC_GLOBAL_H
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 #include "first.h"
25 #ifdef HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28 #define GIAC_CONTEXT const context * contextptr
29 #define GIAC_CONTEXT0 const context * contextptr=0
30 
31 #if !defined(HAVE_NO_SYS_TIMES_H) && !defined(BESTA_OS) && !defined(__MINGW_H) && !defined(NSPIRE) && !defined(FXCG)
32 #include <sys/times.h>
33 #else
34 #if defined VISUALC || defined BESTA_OS || defined FREERTOS
35 typedef long pid_t;
36 #else // VISUALC
37 #if !defined(__MINGW_H) && !defined(NSPIRE) && !defined(FXCG) && !defined(__ANDROID__) && !defined(NSPIRE_NEWLIB) && !defined(OSX) && !defined(IOS) && !defined(OSXIOS) && !defined(FIR_LINUX) && !defined(PRIMEWEBASM)
38 #include "wince_replacements.h"
39 #endif
40 #ifdef __MINGW_H
41 #include <sys/types.h>
42 #endif
43 #endif // VISUALC
44 #endif // HAVE_NO_SYS_TIMES_H
45 // #ifndef __APPLE__
46 #if defined VISUALC || defined BESTA_OS
47 #include <math.h>
48 #include <float.h>
49 #endif
50 #ifndef WIN32
51 #include <math.h>
52 //#define isnan __isnan
53 //#define isinf __isinf
54 #endif
55 // #endif
56 
57 #ifdef SOFTMATH
58 #include "softmath.h"
59 #else
60 #include <cmath>
61 #endif
62 
63 #ifdef _SOFTMATH_H
giac_log(double d)64 inline double giac_log(double d){
65   return std::giac_gnuwince_log(d);
66 }
67 #else
giac_log(double d)68 inline double giac_log(double d){
69   return std::log(d);
70 }
71 #endif
72 
73 
74 #ifdef HAVE_LIBPTHREAD
75 #include <semaphore.h>
76 #endif
77 #ifdef HAVE_PTHREAD_H
78 #include <pthread.h>
79 #endif
80 
81 #include "vector.h"
82 #include <string>
83 #if !defined( NSPIRE) && !defined(FXCG)
84 #include <cstring>
85 #endif
86 #include <iostream>
87 //#include <fstream>
88 #include <map>
89 
90 #ifdef GNUWINCE
91 #define SIGINT 2
92 #else
93 #ifndef HAVE_NO_SIGNAL_H
94 #include <signal.h>
95 #endif
96 #endif // GNUWINCE
97 
98 #include <stdexcept>
99 #include "help.h"
100 #if !defined(FXCG) // !defined(GIAC_HAS_STO_38) // && !defined(ConnectivityKit) && !defined(BESTA_OS)
101 #include "tinymt32.h"
102 #endif
103 
104 #ifndef NO_NAMESPACE_GIAC
105 namespace giac {
106 #endif // ndef NO_NAMESPACE_GIAC
107   void opaque_double_copy(void * source,void * target);
108   double opaque_double_val(const void * source);
109 
110   double giac_floor(double d);
111   double giac_ceil(double d);
112   unsigned int utf82unicode(const char * line,wchar_t * wline,unsigned int n);
113   unsigned int unicode2utf8(const wchar_t * wline,char * line,unsigned int n);
114   wchar_t * utf82unicode(const char * idname);
115   char * unicode2utf8(const wchar_t * idname);
116 
117 /* ---------------------------------------------------------------------
118     The following 4 definitions are compiler-specific.
119     The C standard does not guarantee that wchar_t has at least
120     16 bits, so wchar_t is no less portable than unsigned short!
121     All should be unsigned values to avoid sign extension during
122     bit mask & shift operations.
123 ------------------------------------------------------------------------ */
124 
125 #ifdef GIAC_HAS_STO_38
126 typedef unsigned long UTF32; /* at least 32 bits */
127 typedef wchar_t UTF16; /* at least 16 bits */
128 typedef unsigned char UTF8; /* typically 8 bits */
129 typedef unsigned char Boolean; /* 0 or 1 */
130 #else
131 typedef unsigned long UTF32; /* at least 32 bits */
132 typedef unsigned short UTF16; /* at least 16 bits */
133 typedef unsigned char UTF8; /* typically 8 bits */
134 typedef unsigned char Boolean; /* 0 or 1 */
135 #endif
136 
137   int system_no_deprecation(const char *command);
138 
139 /* Some fundamental constants */
140 #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
141 #define UNI_MAX_BMP (UTF32)0x0000FFFF
142 #define UNI_MAX_UTF16 (UTF32)0x0010FFFF
143 #define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
144 #define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
145 
146 typedef enum {
147     conversionOK = 0,   /* conversion successful */
148     sourceExhausted = -1, /* partial character in source, but hit end */
149     targetExhausted = -2, /* insuff. room in target for conversion */
150     sourceIllegal = -3 /* source sequence is illegal/malformed */
151 } ConversionResult;
152 
153 typedef enum {
154     strictConversion = 0,
155     lenientConversion
156 } ConversionFlags;
157 
158 /* This is for C++ and does no harm in C */
159 #ifdef __cplusplus
160 extern "C" {
161 #endif
162 
163 unsigned int ConvertUTF8toUTF16 (
164         const UTF8* sourceStart, const UTF8* sourceEnd,
165         UTF16* targetStart, UTF16* targetEnd, ConversionFlags flags);
166 
167 unsigned int ConvertUTF16toUTF8 (
168         const UTF16* sourceStart, const UTF16* sourceEnd,
169         UTF8* targetStart, UTF8* targetEnd, ConversionFlags flags);
170 
171 Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
172 
173 #ifdef __cplusplus
174 }
175 #endif
176 
177   // convert position n in utf8-encoded line into the corresponding position
178   // in the same string encoded with unicode
179   unsigned int utf8pos2unicodepos(const char * line,unsigned int n,bool skip_added_spaces = true);
180   unsigned int wstrlen(const char * line, unsigned int n = ~0u);
181   unsigned int wstrlen(const wchar_t * wline);
182   unsigned int utf8length(const wchar_t * wline);
183 
184 
185 #if defined VISUALC || defined BESTA_OS || defined FREERTOS
186 #ifndef R_OK
187   extern int R_OK;
188 #endif
189   int access(const char * ch,int mode);
190   void usleep(int );
191 #endif
192 #if defined NSPIRE_NEWLIB || defined KHICAS
193   void usleep(int );
194 #endif
195 
196   double delta_tms(struct tms tmp1,struct tms tmp2);
197 
198 #define GIAC_DATA_BEGIN   ((char) 2)
199 #define GIAC_DATA_END     ((char) 5)
200 #define GIAC_DATA_ESCAPE  ((char) 27)
201 
202   std::vector<aide> * & vector_aide_ptr();
203   std::vector<std::string> * & vector_completions_ptr();
204   extern void (*fl_widget_delete_function)(void *);
205 #if !defined( NSPIRE) && !defined(FXCG)
206   extern std::ostream & (*fl_widget_archive_function)(std::ostream &,void *);
207 #endif
208   extern bool secure_run; // true if used in a non-trusted environment
209   extern bool center_history,in_texmacs,block_signal,synchronize_history;
210   extern bool threads_allowed;
211   extern bool mpzclass_allowed;
212   enum {
213     smallint=256, // max small int to make modular oply operations with int
214     max_series_expansion_order=64, // max auto order for series expansion
215     max_texpand_expansion_order=64,
216     max_numexp=100
217   };
218   extern const char cas_suffixe[];
219   extern const int BUFFER_SIZE;
220   extern int history_begin_level;
221 
222   extern int debug_infolevel; // ==0 normal value
223   extern int printprog; // ==0 normal value, used to force program print at parse
224   // >0 log some informations
225   // <0 for internal use
226   // ==-1:
227   // ==-2: icas.cc reads aide_cas even if STATIC_BUILTIN_LEXER is defined
228   //       write static_lexer.h, static_extern.h
229   // ==-3:
230   // ==-4: write static_lexer.h, static_lexer_.h and static_extern.h
231   // ==-5: do not throw on errors
232   extern int threads;
233   extern unsigned short int GIAC_PADIC;
234 
235   extern bool CAN_USE_LAPACK;
236   extern bool simplify_sincosexp_pi;
237 #ifndef RTOS_THREADX
238   //#ifndef BESTA_OS
239   extern int CALL_LAPACK; // lapack is used if dim of matrix is >= CALL_LAPACK
240   // can be changed using shell variable GIAC_LAPACK in icas
241   //#endif
242 #endif
243   extern int FACTORIAL_SIZE_LIMIT;
244   extern int GAMMA_LIMIT;
245   extern int LIST_SIZE_LIMIT;
246   extern int NEWTON_DEFAULT_ITERATION;
247   extern int DEFAULT_EVAL_LEVEL;
248   extern int PARENTHESIS_NWAIT;
249 
250   extern int TEST_PROBAB_PRIME; // probabilistic primality tests
251   extern int GCDHEU_MAXTRY; // maximal number of retry for heuristic algorithms
252   extern int GCDHEU_DEGREE; // max degree allowed inside gcdheu
253   extern int MODFACTOR_PRIMES; // number of primes used for factorization
254   extern int NTL_MODGCD; // lowest degree for NTL univariate modular GCD
255   extern int NTL_RESULTANT; // lowest degree for NTL univariate resultant
256   extern int NTL_XGCD; // lowest degree for NTL univariate extended GCD over Z
257   extern int MODRESULTANT; // lowest degree for modular resultant
258   extern int HGCD; // lowest degree for half gcd call
259   extern int HENSEL_QUADRATIC_POWER; // above #steps do quadratic Hensel lift
260   extern int KARAMUL_SIZE; // Use Karatsuba multiplication if degree is >
261   extern int INT_KARAMUL_SIZE; // Use Karatsuba multiplication if degree is >
262   extern int FFTMUL_SIZE; // minimal size for fft mult of poly
263   extern int FFTMUL_INT_MAXBITS; // max number of bits for fft mult of int poly
264   // Should be lower for larger coeff
265   extern int MAX_ALG_EXT_ORDER_SIZE; // x^1/d extension not algebraic if d>
266   extern int MAX_COMMON_ALG_EXT_ORDER_SIZE;
267   extern int TRY_FU_UPRIME;
268   extern int SOLVER_MAX_ITERATE;
269   extern int MAX_PRINTABLE_ZINT;
270   extern int MAX_RECURSION_LEVEL;
271   extern int GBASIS_DETERMINISTIC;
272   extern int GBASISF4_MAX_TOTALDEG;
273   extern int GBASISF4_MAXITER;
274   // extern int GBASISF4_BUCHBERGER;
275   extern unsigned max_pairs_by_iteration;
276   extern unsigned simult_primes,simult_primes2,simult_primes_seuil2,simult_primes3,simult_primes_seuil3;
277   extern double gbasis_reinject_ratio;
278   extern double gbasis_reinject_speed_ratio;
279   extern int gbasis_logz_age_sort,gbasis_stop;
280   extern int PROOT_FACTOR_MAXDEG;
281   extern int ABS_NBITS_EVALF;
282   extern volatile bool ctrl_c,interrupted,kbd_interrupted;
283   void ctrl_c_signal_handler(int signum);
284 #ifdef TIMEOUT
285 #ifndef EMCC
286   double time(int );
287 #endif
288   extern time_t caseval_begin,caseval_current;
289   extern double caseval_maxtime;
290   extern int caseval_n,caseval_mod,caseval_unitialized;
291 #endif
292   extern double powlog2float;
293   extern int MPZ_MAXLOG2;
294 
295 #ifdef WITH_MYOSTREAM
296   // replacement for std::cerr
297   extern my_ostream my_cerr;
298 #endif
299 
300   // void control_c();
301   // note that ctrl_c=false was removed, should be done before calling eval
302 #if defined (NSPIRE) || defined(FXCG)
303   void control_c();
304 #elif defined FIR
305 #define control_c()
306 #else
307 #if defined TIMEOUT && !defined POCKETCAS
308   void control_c();
309 #else
310 #if 0
311 #define control_c() if (ctrl_c) { interrupted = true; CERR << "Throwing exception for user interruption." << '\n'; throw(std::runtime_error("Stopped by user interruption.")); }
312 #else
313 #define control_c() if (ctrl_c) { \
314 interrupted = true; \
315 std::string source_path = __FILE__; \
316 std::string source_filename = source_path.substr(source_path.find_last_of("/\\") + 1); \
317 CERR << "Throwing exception for user interruption (" << source_filename << ":" << __LINE__ << ")" << '\n'; \
318 throw(std::runtime_error("Stopped by user interruption.")); \
319 }
320 #endif
321 #endif // TIMEOUT
322 #endif // !NSPIRE, !FIR
323 
324   typedef void ( * void_function )();
325   // set to non-0 if you want to hook a function call inside control_c()
326 
327 #ifdef IMMEDIATE_VECTOR
328   template <class T> class dbgprint_vector: public std::imvector<T> {
329   public:
330     // inherited constructors
dbgprint_vector()331     dbgprint_vector() : std::imvector<T>::imvector() { };
dbgprint_vector(const T * b,const T * e)332     dbgprint_vector(const T * b,const T * e) : std::imvector<T>::imvector(b,e) { };
dbgprint_vector(size_t i)333     dbgprint_vector(size_t i) : std::imvector<T>::imvector(i) { };
dbgprint_vector(size_t i,const T & t)334     dbgprint_vector(size_t i,const T & t) : std::imvector<T>::imvector(i,t) { };
335     // ~dbgprint_vector() { };
336     // inherited destructors
dbgprint()337     void dbgprint() const { COUT << *this << '\n'; }
338   };
339 #else // IMMEDIATE_VECTOR
340   template <class T> class dbgprint_vector: public std::vector<T> {
341   public:
342     // inherited constructors
dbgprint_vector()343     dbgprint_vector() : std::vector<T>::vector() { };
344 #ifndef GIAC_VECTOR
dbgprint_vector(const typename std::vector<T>::const_iterator & b,const typename std::vector<T>::const_iterator & e)345     dbgprint_vector(const typename std::vector<T>::const_iterator & b,const typename std::vector<T>::const_iterator & e) : std::vector<T>::vector(b,e) { };
346 #endif
dbgprint_vector(const T * b,const T * e)347     dbgprint_vector(const T * b,const T * e) : std::vector<T>::vector(b,e) { };
dbgprint_vector(size_t i)348     dbgprint_vector(size_t i) : std::vector<T>::vector(i) { };
dbgprint_vector(size_t i,const T & t)349     dbgprint_vector(size_t i,const T & t) : std::vector<T>::vector(i,t) { };
350     // ~dbgprint_vector() { };
351     // inherited destructors
dbgprint()352     void dbgprint() const { COUT << *this << '\n'; }
353   };
354 #endif // IMMEDIATE_VECTOR
355 
356   template <class T> class std_matrix: public std::vector< dbgprint_vector<T> > {
357   public:
358     // inherited constructors
std_matrix()359     std_matrix() : std::vector< dbgprint_vector<T> >::vector() { };
std_matrix(size_t i)360     std_matrix(size_t i) : std::vector< dbgprint_vector<T> >::vector(i) { };
std_matrix(size_t i,const dbgprint_vector<T> & v)361     std_matrix(size_t i,const dbgprint_vector<T> & v) : std::vector< dbgprint_vector<T> >::vector(i,v) { };
std_matrix(size_t i,size_t j)362     std_matrix(size_t i,size_t j) : std::vector< dbgprint_vector<T> >::vector(i,dbgprint_vector<T>(j)) { };
std_matrix(size_t i,size_t j,const T & t)363     std_matrix(size_t i,size_t j,const T & t) : std::vector< dbgprint_vector<T> >::vector(i,dbgprint_vector<T>(j,t)) { };
364     // ~dbgprint_vector() { };
365     // inherited destructors
transpose()366     std_matrix<T> transpose() const {
367       if (std::vector< dbgprint_vector<T> >::empty())
368 	return *this;
369       int n=int(std::vector< dbgprint_vector<T> >::size());
370       int m=int(std::vector< dbgprint_vector<T> >::front().dbgprint_vector<T>::size());
371       std_matrix<T> res(m,n);
372       typename std_matrix<T>::const_iterator it=std::vector< dbgprint_vector<T> >::begin();
373       for (int i=0;i<n;++i,++it){
374 	for (int j=0;j<m;++j)
375 	  res[j][i]=(*it)[j];
376       }
377       return res;
378     }
transconjugate()379     std_matrix<T> transconjugate() const {
380       if (std::vector< dbgprint_vector<T> >::empty())
381 	return *this;
382       int n=std::vector< dbgprint_vector<T> >::size();
383       int m=std::vector< dbgprint_vector<T> >::front().dbgprint_vector<T>::size();
384       std_matrix<T> res(m,n);
385       typename std_matrix<T>::const_iterator it=std::vector< dbgprint_vector<T> >::begin();
386       for (int i=0;i<n;++i,++it){
387 	for (int j=0;j<m;++j)
388 	  res[j][i]=conj((*it)[j],0);
389       }
390       return res;
391     }
dbgprint()392     void dbgprint() { COUT << *this << '\n'; }
393   };
394 
395   struct user_function {
396     std::string s;
397     int parser_token;
user_functionuser_function398     user_function():s(""),parser_token(-1) {};
user_functionuser_function399     user_function(const std::string & mys,int i):s(mys),parser_token(i){};
400   };
401 
402   class gen;
403   // vecteurs and dense 1-d polynomilas
404 
405   typedef dbgprint_vector<gen> vecteur; // debugging support
406 
407   vecteur * keywords_vecteur_ptr(); // idnt assigned to a commandname for localization, like mediatrice for perpen_bissector
408 
409   class context;
410 
411   struct debug_struct {
412     int indent_spaces;
413     vecteur args_stack;
414     vecteur debug_breakpoint; // alternate _IDNT and instruction number
415     // count 1 for a normal instruction, 3 for ifte, 4 for a for loop
416     // breakpoint(_IDNT,int) to set a breakpoint at _IDNT, instruction int
417     // rmbreakpoint(int) removes breakpoint number int
418     vecteur debug_watch;
419     // the value of each element of debug_watch is signaled
420     // to the parent process each time the execution stops
421     // watch(_IDNT) to add _IDNT to the watch
422     // rmwatch(int) or rmwatch(_IDNT) removes _IDNT
423     // halt inside a prog starts debug mode, debug(instruction)
424     // starts prog in SST mode
425     // kill reset the protection level, instruction_stack and debug_mode to false
426     bool debug_mode;
427     bool sst_mode; // true to single step in this function
428     bool sst_in_mode; // true to single step inside next instruction
429     bool debug_allowed;
430     std::vector<int> current_instruction_stack;
431     int current_instruction;
432     std::vector< std::vector<int> > sst_at_stack;
433     std::vector<int> sst_at;
434     gen * debug_info_ptr, * fast_debug_info_ptr,* debug_prog_name, * debug_localvars;
435     bool debug_refresh;
436     context * debug_contextptr;
437     debug_struct();
438     ~debug_struct();
439     debug_struct & operator =(const debug_struct & dbg);
440   };
441 
442   typedef void (* giac_callback)(const giac::gen & ,void * );
443 
444   struct thread_param {
445     bool _kill_thread;
446     int thread_eval_status;
447     giac_callback f;
448     void * f_param;
449     giac::vecteur v;
450 #ifdef HAVE_LIBPTHREAD
451     pthread_t eval_thread;
452     pthread_attr_t attr;
453     size_t stacksize;
454     void * stackaddr;
455 #endif
456     thread_param();
457   };
458 
459 #if !defined( NSPIRE) && !defined(FXCG)
460   extern gen (*fl_widget_unarchive_function)(std::istream &);
461 #endif
462   extern std::string (*fl_widget_texprint_function)(void * ptr);
463   extern gen (*fl_widget_updatepict_function)(const gen & g);
464   // name -> gen table
465   struct ltstring
466   {
operatorltstring467     bool operator()(const std::string & s1, const std::string & s2) const
468     {
469       return strcmp(s1.c_str(), s2.c_str()) < 0;
470     }
471   };
472   typedef std::map<std::string, gen,ltstring> sym_string_tab;
473   struct ltstr
474   {
operatorltstr475     bool operator()(const char* s1, const char* s2) const
476     {
477       return strcmp(s1, s2) < 0;
478     }
479   };
480 
481   typedef std::map<const char *, gen,ltstr> map_charptr_gen;
482   typedef map_charptr_gen sym_tab;
483 
484   struct parser_lexer {
485     int _index_status_; // 0 if [ -> T_VECT_DISPATCH, 1 if [ -> T_INDEX_BEGIN
486     int _opened_quote_; // 1 if we are inside a quote
487     int _in_rpn_; // 1 inside RPN expression
488     int _lexer_line_number_;
489     int _lexer_column_number_;
490     int _spread_formula_; // beginning = and meaning of :
491     int _initialisation_done_;
492     std::string _comment_s_;
493     std::string _parser_filename_;
494     std::string _parser_error_;
495     int _first_error_line_;
496     std::string _error_token_name_;
497     int _i_sqrt_minus1_;
498   };
499   std::string gen2string(const gen & g);
500 #ifdef KHICAS
501   struct logo_turtle {
502     double x,y;
503     double theta; // theta is given in degrees or radians dep. on angle_mode
504     bool visible; // true if turtle visible
505     bool mark; // true if moving marks
506     bool direct; // true if rond/disque is done in the trigonometric direction
507     int color;
508     int turtle_length;
509     int radius; // 0 nothing, >0 -> draw a plain disk
510     // bit 0-8=radius, bit9-17 angle1, bit 18-26 angle2, bit 27=1 filled  or 0
511     // <0 fill a polygon from previous turtle positions
512     int s;//std::string s;
logo_turtlelogo_turtle513     logo_turtle(): x(100),y(100),theta(0),visible(true),mark(true),direct(true),color(0),turtle_length(10),radius(0) {}
514   };
515 #else // KHICAS
516   struct logo_turtle {
517     double x,y;
518     double theta; // theta is given in degrees or radians dep. on angle_mode
519     bool visible; // true if turtle visible
520     bool mark; // true if moving marks
521     bool direct; // true if rond/disque is done in the trigonometric direction
522     int color;
523     int turtle_length;
524     int radius; // 0 nothing, >0 -> draw a plain disk
525     // bit 0-8=radius, bit9-17 angle1, bit 18-26 angle2, bit 27=1 filled  or 0
526     // <0 fill a polygon from previous turtle positions
527     std::string s;
528     void * widget;
529 #ifdef IPAQ
logo_turtlelogo_turtle530     logo_turtle(): x(70),y(70),theta(0),visible(true),mark(true),direct(true),color(0),turtle_length(10),radius(0),widget(0) {}
531 #else
logo_turtlelogo_turtle532     logo_turtle(): x(100),y(100),theta(0),visible(true),mark(true),direct(true),color(0),turtle_length(10),radius(0),widget(0) {}
533 #endif
534   };
535 #endif // KHICAS
536 
537   // a structure that should contain all global variables
538   class global {
539   public:
540     int _xcas_mode_;
541     int _calc_mode_;
542     int _decimal_digits_;
543     int _minchar_for_quote_as_string_;
544     int _scientific_format_;
545     int _integer_format_;
546     int _latex_format_;
547 #ifdef BCD
548     u32 _bcd_decpoint_;
549     u32 _bcd_mantissa_;
550     u32 _bcd_flags_;
551     bool _bcd_printdouble_;
552 #endif
553     bool _expand_re_im_;
554     bool _do_lnabs_;
555     bool _eval_abs_;
556     bool _eval_equaltosto_;
557     bool _integer_mode_;
558     bool _complex_mode_;
559     bool _escape_real_;
560     bool _complex_variables_;
561     bool _increasing_power_;
562     bool _approx_mode_;
563     bool _variables_are_files_;
564     bool _local_eval_;
565     bool _withsqrt_;
566     bool _show_point_; // show 3-d point
567     bool _io_graph_; // show 2-d point in io
568     bool _all_trig_sol_;
569     bool _ntl_on_;
570     bool _lexer_close_parenthesis_;
571     bool _rpn_mode_;
572     bool _try_parse_i_;
573     bool _specialtexprint_double_;
574     bool _atan_tan_no_floor_;
575     bool _keep_acosh_asinh_;
576     bool _keep_algext_;
577     int _python_compat_;
578     int _angle_mode_;
579     int _bounded_function_no_;
580     int _series_flags_; // 1= full simplify, 2=1 for truncation, bit3=atan does not rewrite sin/cos to tan, bit4=no back conversion, bit5=write<<1,1>> with series_variable_name, bit 6=write O() instead of order_size, bit7= 1 diff in subst does not variable substitution
581     int _step_infolevel_;
582     int _default_color_;
583     double _epsilon_;
584     double _proba_epsilon_; // if not 0, probabilistic algo may be used
585     // the proba should be less than proba_epsilon for giac to return an answer
586     int _show_axes_;
587     int _spread_Row_,_spread_Col_;
588     int _printcell_current_row_,_printcell_current_col_;
589 #ifdef NSPIRE
590     nio::console * _logptr_;
591 #else
592 #if 1 // def WITH_MYOSTREAM
593     my_ostream * _logptr_;
594 #else
595     std::ostream * _logptr_;
596 #endif
597 #endif
598     debug_struct * _debug_ptr;
599     gen * _parsed_genptr_;
600     parser_lexer _pl;
601     int _prog_eval_level_val ;
602     int _eval_level;
603 #if defined(FXCG) // defined(GIAC_HAS_STO_38) || defined(ConnectivityKit)
604     unsigned int _rand_seed;
605 #else
606     tinymt32_t _rand_seed;
607 #endif
608     thread_param * _thread_param_ptr;
609 #ifdef HAVE_LIBPTHREAD
610     pthread_mutex_t * _mutexptr,* _mutex_eval_status_ptr ;
611 #endif
612     int _language_;
613     const char * _last_evaled_function_name_;
614     const gen * _last_evaled_argptr_;
615     int _max_sum_sqrt_;
616     int _max_sum_add_;
617     logo_turtle _turtle_;
618     std::string _autoname_;
619     std::string _format_double_;
620     std::string _autosimplify_;
621     std::string _lastprog_name_;
622     const char * _currently_scanned_;
623 #ifndef KHICAS
624     std::vector<logo_turtle> _turtle_stack_;
625 #endif
626     double _total_time_;
627     void * _evaled_table_;
628     void * _extra_ptr_;
629     char _series_variable_name_;
630     unsigned short _series_default_order_;
631     global();
632     ~global();
633     global & operator = (const global & g);
634   };
635 
636   // Context type to be used for evaluation without global variables
637   // tabptr is the current evaluation context,
638   // it is a global context if globalcontextptr=0, local otherwise
639   // previous is the upper local or global evaluation context
640   // globalcontextptr points to the current global evaluation context
641   // If globalcontextptr=0 and previous=0, we are at the top folder
642   // The top level local context should have previous=globalcontextptr
643   class context {
644   public:
645     sym_tab * tabptr ;
646     context * globalcontextptr ;
647     context * previous ;
648     global * globalptr;
649     const context * parent;
650     vecteur * quoted_global_vars, * rootofs;
651     vecteur * history_in_ptr, * history_out_ptr,*history_plot_ptr;
652     context();
653     context(const context & c);
654 #ifndef RTOS_THREADX
655 #ifndef BESTA_OS
656     context(const std::string & name);
657 #endif
658 #endif
659     ~context();
660     context * clone() const;
661   };
662 
663   context * clone_context(const context *);
664   void init_context(context * ptr);
665 
666   extern const context * context0;
667   std::vector<context *> & context_list();
668 #ifdef HAVE_LIBPTHREAD
669   extern pthread_mutex_t context_list_mutex;
670 #endif
671 
672 #if !defined(RTOS_THREADX) && !defined(BESTA_OS) && !defined(NSPIRE) && !defined(FXCG) && !defined KHICAS
673   extern std::map<std::string,context *> * context_names ;
674 #endif
675 
676   const char * & last_evaled_function_name(GIAC_CONTEXT);
677   const char * & currently_scanned(GIAC_CONTEXT);
678   const gen * & last_evaled_argptr(GIAC_CONTEXT);
679 
680   bool make_thread(const giac::gen & g,int level,const giac_callback & f,void * f_param,const context * contextptr);
681 
682   std::string autoname(GIAC_CONTEXT);
683   std::string autoname(const std::string & s,GIAC_CONTEXT);
684 
685   std::string autosimplify(GIAC_CONTEXT);
686   std::string autosimplify(const std::string & s,GIAC_CONTEXT);
687 
688   bool csv_guess(const char * data,int count,char & sep,char & nl,char & decsep);
689   std::string & format_double(GIAC_CONTEXT);
690 
691   int check_thread(context * contextptr);
692   int check_threads(int i=0);
693 
694   void * & evaled_table(GIAC_CONTEXT);
695   void * & extra_ptr(GIAC_CONTEXT);
696 
697   int & xcas_mode(GIAC_CONTEXT);
698   void xcas_mode(int b,GIAC_CONTEXT);
699 
700   int & python_compat(GIAC_CONTEXT);
701   void python_compat(int b,GIAC_CONTEXT);
702   int array_start(GIAC_CONTEXT);
703   extern bool python_color; // global variable for syntax highlighting
704   extern bool os_shell; // true if Numworks called from shell
705 
706   int & calc_mode(GIAC_CONTEXT);
707   int abs_calc_mode(GIAC_CONTEXT);
708   void calc_mode(int b,GIAC_CONTEXT);
709 
710   int & scientific_format(GIAC_CONTEXT);
711   void scientific_format(int b,GIAC_CONTEXT);
712 
713   int & decimal_digits(GIAC_CONTEXT);
714   void decimal_digits(int b,GIAC_CONTEXT);
715 
716   int & minchar_for_quote_as_string(GIAC_CONTEXT);
717   void minchar_for_quote_as_string(int b,GIAC_CONTEXT);
718 
719   int & integer_format(GIAC_CONTEXT);
720   void integer_format(int b,GIAC_CONTEXT);
721   int & latex_format(GIAC_CONTEXT);
722 #ifdef BCD
723   u32 & bcd_decpoint(GIAC_CONTEXT);
724   u32 & bcd_mantissa(GIAC_CONTEXT);
725   u32 & bcd_flags(GIAC_CONTEXT);
726   bool & bcd_printdouble(GIAC_CONTEXT);
727 #endif
728   bool & expand_re_im(GIAC_CONTEXT);
729   void expand_re_im(bool b,GIAC_CONTEXT);
730 
731   bool & integer_mode(GIAC_CONTEXT);
732   void integer_mode(bool b,GIAC_CONTEXT);
733 
734   bool & complex_mode(GIAC_CONTEXT);
735   void complex_mode(bool b,GIAC_CONTEXT);
736 
737   bool & escape_real(GIAC_CONTEXT); // default=true, if false sqrt(-1) errorsglo
738   void escape_real(bool b,GIAC_CONTEXT);
739 
740   bool & try_parse_i(GIAC_CONTEXT);
741   void try_parse_i(bool b,GIAC_CONTEXT);
742 
743   bool & specialtexprint_double(GIAC_CONTEXT);
744   void specialtexprint_double(bool b,GIAC_CONTEXT);
745 
746   bool & atan_tan_no_floor(GIAC_CONTEXT);
747   void atan_tan_no_floor(bool b,GIAC_CONTEXT);
748 
749   bool & keep_acosh_asinh(GIAC_CONTEXT);
750   void keep_acosh_asinh(bool b,GIAC_CONTEXT);
751 
752   bool & keep_algext(GIAC_CONTEXT);
753   void keep_algext(bool b,GIAC_CONTEXT);
754 
755   bool & do_lnabs(GIAC_CONTEXT);
756   void do_lnabs(bool b,GIAC_CONTEXT);
757 
758   bool & eval_abs(GIAC_CONTEXT);
759   void eval_abs(bool b,GIAC_CONTEXT);
760 
761   bool & eval_equaltosto(GIAC_CONTEXT);
762   void eval_equaltosto(bool b,GIAC_CONTEXT);
763 
764   bool & complex_variables(GIAC_CONTEXT);
765   void complex_variables(bool b,GIAC_CONTEXT);
766 
767   bool & increasing_power(GIAC_CONTEXT);
768   void increasing_power(bool b,GIAC_CONTEXT);
769 
770   bool & approx_mode(GIAC_CONTEXT);
771   void approx_mode(bool b,GIAC_CONTEXT);
772 
773   char & series_variable_name(GIAC_CONTEXT);
774   void series_variable_name(char b,GIAC_CONTEXT);
775 
776   unsigned short & series_default_order(GIAC_CONTEXT);
777   void series_default_order(unsigned short b,GIAC_CONTEXT);
778 
779   vecteur & history_in(GIAC_CONTEXT);
780   vecteur & history_out(GIAC_CONTEXT);
781   vecteur & history_plot(GIAC_CONTEXT);
782 
783   // True if we factor 2nd order polynomials using sqrt
784   bool & withsqrt(GIAC_CONTEXT);
785   void withsqrt(bool b,GIAC_CONTEXT);
786 
787   bool & all_trig_sol(GIAC_CONTEXT);
788   void all_trig_sol(bool b,GIAC_CONTEXT);
789 
790   bool & ntl_on(GIAC_CONTEXT);
791   void ntl_on(bool b,GIAC_CONTEXT);
792 
793   bool & lexer_close_parenthesis(GIAC_CONTEXT);
794   void lexer_close_parenthesis(bool b,GIAC_CONTEXT);
795 
796   bool & rpn_mode(GIAC_CONTEXT);
797   void rpn_mode(bool b,GIAC_CONTEXT);
798 
799   std::string lastprog_name(GIAC_CONTEXT);
800   std::string lastprog_name(const std::string & b,GIAC_CONTEXT);
801 
802 #ifdef KHICAS
803   logo_turtle & turtle();
804   std::vector<logo_turtle> & turtle_stack();
805 #else
806   logo_turtle & turtle(GIAC_CONTEXT);
807   std::vector<logo_turtle> & turtle_stack(GIAC_CONTEXT);
808 #endif
809 
810   int & angle_mode(GIAC_CONTEXT);
811   int get_mode_set_radian(GIAC_CONTEXT);
812   void angle_mode(int m,GIAC_CONTEXT);
813   bool angle_radian(GIAC_CONTEXT);
814   void angle_radian(bool b,GIAC_CONTEXT);
815   bool angle_degree(GIAC_CONTEXT);
816 
817   bool & show_point(GIAC_CONTEXT);
818   void show_point(bool b,GIAC_CONTEXT);
819 
820   int & show_axes(GIAC_CONTEXT);
821   void show_axes(int b,GIAC_CONTEXT);
822 
823   bool & io_graph(GIAC_CONTEXT);
824   void io_graph(bool b,GIAC_CONTEXT);
825 
826   bool & variables_are_files(GIAC_CONTEXT);
827   void variables_are_files(bool b,GIAC_CONTEXT);
828 
829   int & bounded_function_no(GIAC_CONTEXT);
830   void bounded_function_no(int b,GIAC_CONTEXT);
831 
832   int & series_flags(GIAC_CONTEXT);
833   void series_flags(int b,GIAC_CONTEXT);
834 
835   int & step_infolevel(GIAC_CONTEXT);
836   void step_infolevel(int b,GIAC_CONTEXT);
837 
838   bool & local_eval(GIAC_CONTEXT);
839   void local_eval(bool b,GIAC_CONTEXT);
840 
841   int & default_color(GIAC_CONTEXT);
842   void default_color(int c,GIAC_CONTEXT);
843 
844   int & spread_Row(GIAC_CONTEXT);
845   void spread_Row(int c,GIAC_CONTEXT);
846 
847   int & spread_Col(GIAC_CONTEXT);
848   void spread_Col(int c,GIAC_CONTEXT);
849 
850   int & printcell_current_row(GIAC_CONTEXT);
851   void printcell_current_row(int c,GIAC_CONTEXT);
852 
853   int & printcell_current_col(GIAC_CONTEXT);
854   void printcell_current_col(int c,GIAC_CONTEXT);
855 
856   double & total_time(GIAC_CONTEXT);
857   double & epsilon(GIAC_CONTEXT);
858   void epsilon(double c,GIAC_CONTEXT);
859   double & proba_epsilon(GIAC_CONTEXT);
860   extern double min_proba_time; // in seconds, minimal time for proba early termination
861 
862 #ifdef NSPIRE
863   nio::console * logptr(GIAC_CONTEXT);
864   void logptr(nio::console *,GIAC_CONTEXT);
865 #else
866   my_ostream * logptr(GIAC_CONTEXT);
867   void logptr(my_ostream *,GIAC_CONTEXT);
868 #endif
869 
870   int & eval_level(GIAC_CONTEXT);
871   // void eval_level(int b,GIAC_CONTEXT);
872   thread_param * thread_param_ptr(const context * contextptr);
873 
874 #if defined(FXCG) // defined(GIAC_HAS_STO_38) || defined(ConnectivityKit)
875   unsigned int & rand_seed(GIAC_CONTEXT);
876 #else
877   tinymt32_t * rand_seed(GIAC_CONTEXT);
878 #endif
879   void rand_seed(unsigned int b,GIAC_CONTEXT);
880   int giac_rand(GIAC_CONTEXT);
881   int std_rand(); // a congruential random generator without context
882 
883   int & prog_eval_level_val(GIAC_CONTEXT);
884   void prog_eval_level_val(int b,GIAC_CONTEXT);
885 
886   int & max_sum_sqrt(GIAC_CONTEXT);
887   void max_sum_sqrt(int b,GIAC_CONTEXT);
888 
889   int & max_sum_add(GIAC_CONTEXT);
890 
891   int & language(GIAC_CONTEXT);
892   void language(int b,GIAC_CONTEXT);
893 
894   int & lexer_line_number(GIAC_CONTEXT);
895   int & lexer_column_number(GIAC_CONTEXT);
896   void lexer_line_number(int b,GIAC_CONTEXT);
897   void increment_lexer_line_number(GIAC_CONTEXT);
898 
899   std::string parser_error(GIAC_CONTEXT);
900   void parser_error(const std::string & s,GIAC_CONTEXT);
901 
902   int & index_status(GIAC_CONTEXT);
903   void index_status(int b,GIAC_CONTEXT);
904 
905   int & i_sqrt_minus1(GIAC_CONTEXT);
906   void i_sqrt_minus1(int b,GIAC_CONTEXT);
907 
908   int & opened_quote(GIAC_CONTEXT);
909   void opened_quote(int b,GIAC_CONTEXT);
910 
911   int & in_rpn(GIAC_CONTEXT);
912   void in_rpn(int b,GIAC_CONTEXT);
913 
914   int & spread_formula(GIAC_CONTEXT);
915   void spread_formula(int b,GIAC_CONTEXT);
916 
917   int & initialisation_done(GIAC_CONTEXT);
918   void initialisation_done(int b,GIAC_CONTEXT);
919 
920   std::string comment_s(GIAC_CONTEXT);
921   void comment_s(const std::string & s,GIAC_CONTEXT);
922   void increment_comment_s(const std::string & s,GIAC_CONTEXT);
923   void increment_comment_s(char ch,GIAC_CONTEXT);
924 
925   std::string parser_filename(GIAC_CONTEXT);
926   void parser_filename(const std::string & s,GIAC_CONTEXT);
927 
928   int & first_error_line(GIAC_CONTEXT);
929   void first_error_line(int s,GIAC_CONTEXT);
930 
931   std::string error_token_name(GIAC_CONTEXT);
932   void error_token_name(const std::string & s,GIAC_CONTEXT);
933 
934   gen parsed_gen(GIAC_CONTEXT);
935   void parsed_gen(const gen & g,GIAC_CONTEXT);
936 
937   debug_struct * debug_ptr(GIAC_CONTEXT);
938 
939   // gen_op is the type of all functions taking 1 or more gen args
940   // and returning 1 arg of type gen
941   // gen argument has atomic type for an unary op,
942   // and vecteur type (compttr) otherwise
943   typedef gen ( * gen_op ) (const gen & arg);
944   typedef gen ( * gen_op_context ) (const gen & arg,const context * context_ptr);
945 
946   extern pid_t child_id;
947   extern pid_t parent_id;
948 #ifdef HAVE_SIGNAL_H_OLD
949   // all this stuff is obsolete, will be removed soon
950   void kill_and_wait_sigusr2(); // called by child for interm. data
951   // subprocess evaluation
952   // return true if entree has been sent to evalation by child process
953   bool child_eval(const std::string & entree,bool numeric,bool is_run_file);
954   bool child_reeval(int history_begin_level);
955   bool update_data(gen & entree,gen & sortie,GIAC_CONTEXT);
956   void updatePICT(const vecteur & args);
957   bool read_data(gen & entree,gen & sortie,std::string & message,GIAC_CONTEXT);
958 
959   gen wait_parent(); // wait a SIGUSR2 from parent process, return a gen
960 
961   pid_t make_child(); // forks and return child id
962   extern bool running_file;
963   extern volatile bool child_busy;
964   extern volatile bool data_ready;
965   extern volatile bool signal_plot_child;
966   extern volatile bool signal_plot_parent;
967   extern int run_modif_pos;
968   // end of obsolete section
969 #endif
970 
971   void read_config(const std::string & name,GIAC_CONTEXT,bool verbose=true);
972   void protected_read_config(GIAC_CONTEXT,bool verbose=true);
973   vecteur remove_multiples(vecteur & v); // sort v and return list without multiple occurences
974   int equalposcomp(const std::vector<int> v,int i);
975   int equalposcomp(const std::vector<short int> v,int i);
976   int equalposcomp(int tab[],int f);
977   // replace c1 by c2 in s
978   std::string replace(const std::string & s,char c1,char c2);
979   // attempt to convert Python-like programming structures to Xcas
980   std::string python2xcas(const std::string & s_orig,GIAC_CONTEXT);
981   std::string find_doc_prefix(int i);
982   std::string find_lang_prefix(int i);
983   int string2lang(const std::string & s); // convert "fr" to 1, "es" to 3 etc.
984   void update_completions();
985   void add_language(int i,GIAC_CONTEXT);
986   void remove_language(int i,GIAC_CONTEXT);
987   std::string set_language(int i,GIAC_CONTEXT);
988   std::string read_env(GIAC_CONTEXT,bool verbose=true); // return doc prefix
989   std::string home_directory();
990   std::string cas_entree_name();
991   std::string cas_sortie_name();
992   std::string cas_setup_string(GIAC_CONTEXT);
993   std::string geo_setup_string();
994   std::string giac_aide_dir(); // PATH to the directory of aide_cas
995   bool is_file_available(const char * ch);
996   bool file_not_available(const char * ch);
997   bool check_file_path(const std::string & s); // true if file is in path
998   std::string browser_command(const std::string & orig_file);
999   bool system_browser_command(const std::string & file);
1000   // convert doc name to an absolute path name
1001   std::string absolute_path(const std::string & orig_file);
1002   std::string & xcasrc();
1003   std::string & xcasroot();
1004   std::string add_extension(const std::string & s,const std::string & ext,const std::string & def);
1005   std::string remove_filename(const std::string & s);
1006   bool my_isnan(double d);
1007   bool my_isinf(double d);
1008 
1009   /* launch a new thread for evaluation only,
1010      no more readqueue, readqueue is done by the "parent" thread
1011      Ctrl-C will kill the "child" thread
1012      wait_001 is a function that should wait 0.001 s and update thinks
1013      for example it could remove idle callback of a GUI
1014      then call the wait function of the GUI and readd callbacks
1015   */
1016   giac::gen thread_eval(const giac::gen & g,int level,giac::context * contextptr,void (* wait_001)(giac::context *));
1017 #ifdef HAVE_LIBPTHREAD
1018   // pointer to the context mutex so that thread_eval can be locked
1019   // Check this in wait_001 function if you don't want the main thread to
1020   // be blocked by a call to thread_eval inside wait_001
1021   pthread_mutex_t * mutexptr(GIAC_CONTEXT);
1022   extern pthread_mutex_t interactive_mutex,turtle_mutex;
1023 
1024 #endif
1025   // Check if a thread_eval is active
1026   bool is_context_busy(GIAC_CONTEXT);
1027   // Check and set the kill thread flag
1028   bool kill_thread(GIAC_CONTEXT);
1029   void kill_thread(bool b,GIAC_CONTEXT);
1030   // Thread eval status = 0 finished, =1 eval, =2 debug_wait_main
1031   int thread_eval_status(GIAC_CONTEXT);
1032   void thread_eval_status(int c,GIAC_CONTEXT);
1033 
1034   void clear_prog_status(GIAC_CONTEXT);
1035   void cleanup_context(GIAC_CONTEXT);
1036 
1037   // count how many bytes are required to save g in a file
1038   unsigned archive_count(const gen & g,GIAC_CONTEXT);
1039   // save g in a opened file
1040   bool archive_save(void * f,const gen & g,size_t writefunc(void const* p, size_t nbBytes,size_t NbElements, void *file),GIAC_CONTEXT, bool noRecurse=false);
1041 
1042   bool archive_save(void * f,const gen & g,GIAC_CONTEXT);
1043   // restore a gen from an opened file
1044   gen archive_restore(void * f,size_t readfunc(void * p, size_t nbBytes,size_t NbElements, void *file),GIAC_CONTEXT);
1045   gen archive_restore(FILE * f,GIAC_CONTEXT);
1046   void init_geogebra(bool on,GIAC_CONTEXT);
1047   vecteur giac_current_status(bool save_history,GIAC_CONTEXT);
1048   bool unarchive_session(const gen & g,int level,const gen & replace,GIAC_CONTEXT,bool with_history=true);
1049 
1050   gen add_autosimplify(const gen & g,GIAC_CONTEXT);
1051 
1052   extern void (*my_gprintf)(unsigned special,const std::string & format,const vecteur & v,GIAC_CONTEXT);
1053   void gprintf(const std::string & format,const vecteur & v,GIAC_CONTEXT);
1054   void gprintf(const std::string & format,const vecteur & v,int step_info,GIAC_CONTEXT);
1055   void gprintf(unsigned special,const std::string & format,const vecteur & v,GIAC_CONTEXT);
1056   void gprintf(unsigned special,const std::string & format,const vecteur & v,int step_info,GIAC_CONTEXT);
1057   gen make_symbolic(const gen & op,const gen & args);
1058   // optional, call it just before exiting
1059   int release_globals();
1060 
1061 #ifndef NO_NAMESPACE_GIAC
1062 } // namespace giac
1063 #endif // ndef NO_NAMESPACE_GIAC
1064 
1065 
1066 #endif // _GIAC_GLOBAL_H
1067