global.h 33.8 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
/* -*- mode:C++;compile-command: "g++-3.4 -I.. -g -c global.cc" -*- */

/* Global definition and constants (see also dispatch.h)
 *  Copyright (C) 2000,2014 B. Parisse, Institut Fourier, 38402 St Martin d'Heres
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef _GIAC_GLOBAL_H
#define _GIAC_GLOBAL_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "first.h"
#define GIAC_CONTEXT const context * contextptr
#define GIAC_CONTEXT0 const context * contextptr=0

#if !defined(HAVE_NO_SYS_TIMES_H) && !defined(BESTA_OS) && !defined(__MINGW_H) && !defined(NSPIRE)
#include <sys/times.h>
#else
#if defined VISUALC || defined BESTA_OS 
typedef long pid_t;
#else // VISUALC
#if !defined(__MINGW_H) && !defined(NSPIRE) && !defined(__ANDROID__) && !defined(NSPIRE_NEWLIB) && !defined(OSX) && !defined(IOS) && !defined(OSXIOS) && !defined(FIR_LINUX)
#include "wince_replacements.h"
#endif
#ifdef __MINGW_H
#include <sys/types.h>
#endif
#endif // VISUALC
#endif // HAVE_NO_SYS_TIMES_H
// #ifndef __APPLE__
#if defined VISUALC || defined BESTA_OS
#include <math.h>
#include <float.h>
#endif
#ifndef WIN32
#include <math.h>
//#define isnan __isnan
//#define isinf __isinf
#endif
// #endif

#ifdef SOFTMATH
#include "softmath.h"
#else
#include <cmath>
#endif

#ifdef _SOFTMATH_H
inline double giac_log(double d){
  return std::giac_gnuwince_log(d);
}
#else
inline double giac_log(double d){
  return std::log(d);
}
#endif


#ifdef HAVE_LIBPTHREAD
#include <semaphore.h>
#endif
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif

#include "vector.h"
#include <string>
#ifndef NSPIRE
#include <cstring>
#endif
#include <iostream>
#include <fstream>
#include <map>

#ifdef GNUWINCE
#define SIGINT 2
#else
#ifndef HAVE_NO_SIGNAL_H
#include <signal.h>
#endif
#endif // GNUWINCE

#include <stdexcept>
#include "help.h"
#if 1 // !defined(GIAC_HAS_STO_38) // && !defined(ConnectivityKit) && !defined(BESTA_OS)
#include "tinymt32.h"
#endif

#ifndef NO_NAMESPACE_GIAC
namespace giac {
#endif // ndef NO_NAMESPACE_GIAC
  void opaque_double_copy(void * source,void * target);
  double opaque_double_val(const void * source);

  double giac_floor(double d);
  double giac_ceil(double d);
  unsigned int utf82unicode(const char * line,wchar_t * wline,unsigned int n);
  unsigned int unicode2utf8(const wchar_t * wline,char * line,unsigned int n);
  wchar_t * utf82unicode(const char * idname);
  char * unicode2utf8(const wchar_t * idname);

/* ---------------------------------------------------------------------
    The following 4 definitions are compiler-specific.
    The C standard does not guarantee that wchar_t has at least
    16 bits, so wchar_t is no less portable than unsigned short!
    All should be unsigned values to avoid sign extension during
    bit mask & shift operations.
------------------------------------------------------------------------ */

#ifdef GIAC_HAS_STO_38
typedef unsigned long UTF32; /* at least 32 bits */
typedef wchar_t UTF16; /* at least 16 bits */
typedef unsigned char UTF8; /* typically 8 bits */
typedef unsigned char Boolean; /* 0 or 1 */
#else
typedef unsigned long UTF32; /* at least 32 bits */
typedef unsigned short UTF16; /* at least 16 bits */
typedef unsigned char UTF8; /* typically 8 bits */
typedef unsigned char Boolean; /* 0 or 1 */
#endif

  int system_no_deprecation(const char *command);

/* Some fundamental constants */
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
#define UNI_MAX_BMP (UTF32)0x0000FFFF
#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF

typedef enum {
    conversionOK = 0,   /* conversion successful */
    sourceExhausted = -1, /* partial character in source, but hit end */
    targetExhausted = -2, /* insuff. room in target for conversion */
    sourceIllegal = -3 /* source sequence is illegal/malformed */
} ConversionResult;

typedef enum {
    strictConversion = 0,
    lenientConversion
} ConversionFlags;

/* This is for C++ and does no harm in C */
#ifdef __cplusplus
extern "C" {
#endif

unsigned int ConvertUTF8toUTF16 (
        const UTF8* sourceStart, const UTF8* sourceEnd, 
        UTF16* targetStart, UTF16* targetEnd, ConversionFlags flags);

unsigned int ConvertUTF16toUTF8 (
        const UTF16* sourceStart, const UTF16* sourceEnd, 
        UTF8* targetStart, UTF8* targetEnd, ConversionFlags flags);

Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);

#ifdef __cplusplus
}
#endif

  // convert position n in utf8-encoded line into the corresponding position
  // in the same string encoded with unicode
  unsigned int utf8pos2unicodepos(const char * line,unsigned int n,bool skip_added_spaces = true);
  unsigned int wstrlen(const char * line, unsigned int n = ~0u);
  unsigned int wstrlen(const wchar_t * wline);
  unsigned int utf8length(const wchar_t * wline);


#if defined VISUALC || defined BESTA_OS || defined FREERTOS
#ifndef R_OK
  extern int R_OK;
#endif
  int access(const char * ch,int mode);
  void usleep(int );
#endif
#ifdef NSPIRE_NEWLIB
  void usleep(int );
#endif

  double delta_tms(struct tms tmp1,struct tms tmp2);

#define GIAC_DATA_BEGIN   ((char) 2)
#define GIAC_DATA_END     ((char) 5)
#define GIAC_DATA_ESCAPE  ((char) 27)

  std::vector<aide> * & vector_aide_ptr();
  std::vector<std::string> * & vector_completions_ptr();
  extern void (*fl_widget_delete_function)(void *);
#ifndef NSPIRE
  extern std::ostream & (*fl_widget_archive_function)(std::ostream &,void *);
#endif
  extern bool secure_run; // true if used in a non-trusted environment
  extern bool center_history,in_texmacs,block_signal,synchronize_history;
  extern bool threads_allowed;
  extern bool mpzclass_allowed;
  enum { 
    smallint=256, // max small int to make modular oply operations with int
    max_series_expansion_order=64, // max auto order for series expansion
    max_texpand_expansion_order=64,
    max_numexp=100
  };
  extern const char cas_suffixe[];
  extern const int BUFFER_SIZE;
  extern int history_begin_level;

  extern int debug_infolevel; // ==0 normal value
  // >0 log some informations
  // <0 for internal use
  // ==-1:
  // ==-2: icas.cc reads aide_cas even if STATIC_BUILTIN_LEXER is defined
  //       write static_lexer.h, static_extern.h
  // ==-3:
  // ==-4: write static_lexer.h, static_lexer_.h and static_extern.h
  // ==-5: do not throw on errors
  extern int threads;
  extern unsigned short int GIAC_PADIC;

  extern bool CAN_USE_LAPACK;
  extern bool simplify_sincosexp_pi;
#ifndef RTOS_THREADX
  //#ifndef BESTA_OS
  extern int CALL_LAPACK; // lapack is used if dim of matrix is >= CALL_LAPACK
  // can be changed using shell variable GIAC_LAPACK in icas
  //#endif
#endif
  extern int FACTORIAL_SIZE_LIMIT;
  extern int GAMMA_LIMIT;
  extern int LIST_SIZE_LIMIT;
  extern int NEWTON_DEFAULT_ITERATION;
  extern int DEFAULT_EVAL_LEVEL;
  extern int PARENTHESIS_NWAIT;

  extern int TEST_PROBAB_PRIME; // probabilistic primality tests
  extern int GCDHEU_MAXTRY; // maximal number of retry for heuristic algorithms
  extern int GCDHEU_DEGREE; // max degree allowed inside gcdheu
  extern int MODFACTOR_PRIMES; // number of primes used for factorization
  extern int NTL_MODGCD; // lowest degree for NTL univariate modular GCD 
  extern int HENSEL_QUADRATIC_POWER; // above #steps do quadratic Hensel lift
  extern int KARAMUL_SIZE; // Use Karatsuba multiplication if degree is >
  extern int INT_KARAMUL_SIZE; // Use Karatsuba multiplication if degree is >
  extern int FFTMUL_SIZE; // minimal size for fft mult of poly
  extern int FFTMUL_INT_MAXBITS; // max number of bits for fft mult of int poly 
  // Should be lower for larger coeff
  extern int MAX_ALG_EXT_ORDER_SIZE; // x^1/d extension not algebraic if d>
  extern int MAX_COMMON_ALG_EXT_ORDER_SIZE;
  extern int TRY_FU_UPRIME;
  extern int SOLVER_MAX_ITERATE;
  extern int MAX_PRINTABLE_ZINT;
  extern int MAX_RECURSION_LEVEL;
  extern int GBASIS_DETERMINISTIC;
  extern int GBASISF4_MAX_TOTALDEG;
  extern int GBASISF4_MAXITER;
  // extern int GBASISF4_BUCHBERGER;
  extern int PROOT_FACTOR_MAXDEG;
  extern int ABS_NBITS_EVALF;
  extern volatile bool ctrl_c,interrupted;
  void ctrl_c_signal_handler(int signum);
#ifdef TIMEOUT
#ifndef EMCC
  double time(int );
#endif
  extern time_t caseval_begin,caseval_current;
  extern double caseval_maxtime;
  extern int caseval_n,caseval_mod,caseval_unitialized;
#endif
  extern double powlog2float;
  extern int MPZ_MAXLOG2;

#ifdef WITH_MYOSTREAM
  // replacement for std::cerr
  extern my_ostream my_cerr;
#endif

  // void control_c();
  // note that ctrl_c=false was removed, should be done before calling eval
#if defined NSPIRE
  void control_c();
#elif defined FIR
#define control_c()
#else
#ifdef TIMEOUT
  void control_c();
#else
#if 0
#define control_c() if (ctrl_c) { interrupted = true; CERR << "Throwing exception for user interruption." << std::endl; throw(std::runtime_error("Stopped by user interruption.")); }
#else
#define control_c() if (ctrl_c) { \
interrupted = true; \
std::string source_path = __FILE__; \
std::string source_filename = source_path.substr(source_path.find_last_of("/\\") + 1); \
CERR << "Throwing exception for user interruption (" << source_filename << ":" << __LINE__ << ")" << std::endl; \
throw(std::runtime_error("Stopped by user interruption.")); \
}
#endif
#endif // TIMEOUT
#endif // !NSPIRE, !FIR

  typedef void ( * void_function )();
  // set to non-0 if you want to hook a function call inside control_c()

#ifdef IMMEDIATE_VECTOR
  template <class T> class dbgprint_vector: public std::imvector<T> {
  public:
    // inherited constructors
    dbgprint_vector() : std::imvector<T>::imvector() { };
    dbgprint_vector(const T * b,const T * e) : std::imvector<T>::imvector(b,e) { };
    dbgprint_vector(size_t i) : std::imvector<T>::imvector(i) { };
    dbgprint_vector(size_t i,const T & t) : std::imvector<T>::imvector(i,t) { };
    // ~dbgprint_vector() { };
    // inherited destructors
    void dbgprint() const { COUT << *this << std::endl; }
  };
#else // IMMEDIATE_VECTOR
  template <class T> class dbgprint_vector: public std::vector<T> {
  public:
    // inherited constructors
    dbgprint_vector() : std::vector<T>::vector() { };
#ifndef GIAC_VECTOR
    dbgprint_vector(const typename std::vector<T>::const_iterator & b,const typename std::vector<T>::const_iterator & e) : std::vector<T>::vector(b,e) { };
#endif
    dbgprint_vector(const T * b,const T * e) : std::vector<T>::vector(b,e) { };
    dbgprint_vector(size_t i) : std::vector<T>::vector(i) { };
    dbgprint_vector(size_t i,const T & t) : std::vector<T>::vector(i,t) { };
    // ~dbgprint_vector() { };
    // inherited destructors
    void dbgprint() const { COUT << *this << std::endl; }
  };
#endif // IMMEDIATE_VECTOR
  
  template <class T> class std_matrix: public std::vector< dbgprint_vector<T> > {
  public:
    // inherited constructors
    std_matrix() : std::vector< dbgprint_vector<T> >::vector() { };
    std_matrix(size_t i) : std::vector< dbgprint_vector<T> >::vector(i) { };
    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) : std::vector< dbgprint_vector<T> >::vector(i,dbgprint_vector<T>(j)) { };
    std_matrix(size_t i,size_t j,const T & t) : std::vector< dbgprint_vector<T> >::vector(i,dbgprint_vector<T>(j,t)) { };
    // ~dbgprint_vector() { };
    // inherited destructors
    std_matrix<T> transpose() const {
      if (std::vector< dbgprint_vector<T> >::empty())
	return *this;
      int n=int(std::vector< dbgprint_vector<T> >::size());
      int m=int(std::vector< dbgprint_vector<T> >::front().dbgprint_vector<T>::size());
      std_matrix<T> res(m,n);
      typename std_matrix<T>::const_iterator it=std::vector< dbgprint_vector<T> >::begin();
      for (int i=0;i<n;++i,++it){
	for (int j=0;j<m;++j)
	  res[j][i]=(*it)[j];
      }
      return res;
    }
    std_matrix<T> transconjugate() const {
      if (std::vector< dbgprint_vector<T> >::empty())
	return *this;
      int n=std::vector< dbgprint_vector<T> >::size();
      int m=std::vector< dbgprint_vector<T> >::front().dbgprint_vector<T>::size();
      std_matrix<T> res(m,n);
      typename std_matrix<T>::const_iterator it=std::vector< dbgprint_vector<T> >::begin();
      for (int i=0;i<n;++i,++it){
	for (int j=0;j<m;++j)
	  res[j][i]=conj((*it)[j],0);
      }
      return res;
    }
    void dbgprint() { COUT << *this << std::endl; }
  };

  struct user_function {
    std::string s;
    int parser_token;
    user_function():s(""),parser_token(-1) {};
    user_function(const std::string & mys,int i):s(mys),parser_token(i){};
  };

  class gen;
  // vecteurs and dense 1-d polynomilas

  typedef dbgprint_vector<gen> vecteur; // debugging support

  vecteur * keywords_vecteur_ptr(); // idnt assigned to a commandname for localization, like mediatrice for perpen_bissector

  class context;
  
  struct debug_struct {
    int indent_spaces;
    vecteur args_stack;
    vecteur debug_breakpoint; // alternate _IDNT and instruction number
    // count 1 for a normal instruction, 3 for ifte, 4 for a for loop
    // breakpoint(_IDNT,int) to set a breakpoint at _IDNT, instruction int
    // rmbreakpoint(int) removes breakpoint number int
    vecteur debug_watch; 
    // the value of each element of debug_watch is signaled
    // to the parent process each time the execution stops
    // watch(_IDNT) to add _IDNT to the watch
    // rmwatch(int) or rmwatch(_IDNT) removes _IDNT
    // halt inside a prog starts debug mode, debug(instruction) 
    // starts prog in SST mode
    // kill reset the protection level, instruction_stack and debug_mode to false
    bool debug_mode;
    bool sst_mode; // true to single step in this function
    bool sst_in_mode; // true to single step inside next instruction
    bool debug_allowed;
    std::vector<int> current_instruction_stack;
    int current_instruction;
    std::vector< std::vector<int> > sst_at_stack;
    std::vector<int> sst_at;
    gen * debug_info_ptr, * fast_debug_info_ptr,* debug_prog_name, * debug_localvars;
    bool debug_refresh;
    context * debug_contextptr;
    debug_struct();
    ~debug_struct();
    debug_struct & operator =(const debug_struct & dbg);
  };

  typedef void (* giac_callback)(const giac::gen & ,void * );

  struct thread_param {
    bool _kill_thread;
    int thread_eval_status;
    giac_callback f;
    void * f_param;
    giac::vecteur v;
#ifdef HAVE_LIBPTHREAD
    pthread_t eval_thread;
    pthread_attr_t attr;
    size_t stacksize;
    void * stackaddr;
#endif
    thread_param();
  };

#ifndef NSPIRE
  extern gen (*fl_widget_unarchive_function)(std::istream &);
#endif
  extern std::string (*fl_widget_texprint_function)(void * ptr);
  extern gen (*fl_widget_updatepict_function)(const gen & g);
  // name -> gen table
  struct ltstring
  {
    bool operator()(const std::string & s1, const std::string & s2) const
    {
      return strcmp(s1.c_str(), s2.c_str()) < 0;
    }
  };
  typedef std::map<std::string, gen,ltstring> sym_string_tab;
  struct ltstr
  {
    bool operator()(const char* s1, const char* s2) const
    {
      return strcmp(s1, s2) < 0;
    }
  };
  
  typedef std::map<const char *, gen,ltstr> map_charptr_gen;
  typedef map_charptr_gen sym_tab;

  struct parser_lexer {
    int _index_status_; // 0 if [ -> T_VECT_DISPATCH, 1 if [ -> T_INDEX_BEGIN
    int _opened_quote_; // 1 if we are inside a quote
    int _in_rpn_; // 1 inside RPN expression
    int _lexer_line_number_;
    int _lexer_column_number_;
    int _spread_formula_; // beginning = and meaning of :
    int _initialisation_done_;
    std::string _comment_s_;
    std::string _parser_filename_;
    std::string _parser_error_;
    int _first_error_line_;
    std::string _error_token_name_;
    int _i_sqrt_minus1_;
  };
  std::string gen2string(const gen & g);
  struct logo_turtle {
    double x,y;
    double theta; // theta is given in degrees or radians dep. on angle_mode
    bool visible; // true if turtle visible
    bool mark; // true if moving marks
    bool direct; // true if rond/disque is done in the trigonometric direction
    int color;
    int turtle_length;
    int radius; // 0 nothing, >0 -> draw a plain disk 
    // bit 0-8=radius, bit9-17 angle1, bit 18-26 angle2, bit 27=1 filled  or 0 
    // <0 fill a polygon from previous turtle positions
    std::string s;
    void * widget;
#ifdef IPAQ
    logo_turtle(): x(70),y(70),theta(0),visible(true),mark(true),direct(true),color(0),turtle_length(10),radius(0),widget(0) {}
#else
    logo_turtle(): x(100),y(100),theta(0),visible(true),mark(true),direct(true),color(0),turtle_length(10),radius(0),widget(0) {}
#endif
  };

  // a structure that should contain all global variables
  class global {
  public:
    int _xcas_mode_;
    int _calc_mode_;
    int _decimal_digits_;
    int _scientific_format_;
    int _integer_format_;
    int _latex_format_;
#ifdef BCD
    u32 _bcd_decpoint_;
    u32 _bcd_mantissa_;
    u32 _bcd_flags_;
    bool _bcd_printdouble_;
#endif
    bool _expand_re_im_;
    bool _do_lnabs_;
    bool _eval_abs_;
    bool _eval_equaltosto_;
    bool _integer_mode_;
    bool _complex_mode_;
    bool _escape_real_;
    bool _complex_variables_;
    bool _increasing_power_;
    bool _approx_mode_;
    bool _variables_are_files_;
    bool _local_eval_;
    bool _withsqrt_;
    bool _show_point_; // show 3-d point 
    bool _io_graph_; // show 2-d point in io
    bool _all_trig_sol_;
    bool _ntl_on_;
    bool _lexer_close_parenthesis_;
    bool _rpn_mode_;
    bool _try_parse_i_;
    bool _specialtexprint_double_;
    bool _atan_tan_no_floor_;
    bool _keep_acosh_asinh_;
    bool _keep_algext_;
    bool _python_compat_;
    int _angle_mode_;
    int _bounded_function_no_;
    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
    int _step_infolevel_; 
    int _default_color_;
    double _epsilon_;
    double _proba_epsilon_; // if not 0, probabilistic algo may be used
    // the proba should be less than proba_epsilon for giac to return an answer
    int _show_axes_;
    int _spread_Row_,_spread_Col_;
    int _printcell_current_row_,_printcell_current_col_;
#ifdef NSPIRE
    nio::console * _logptr_;
#else
#ifdef WITH_MYOSTREAM
    my_ostream * _logptr_;
#else
    std::ostream * _logptr_;
#endif
#endif
    debug_struct * _debug_ptr;
    gen * _parsed_genptr_;
    parser_lexer _pl;
    int _prog_eval_level_val ;
    int _eval_level;
#if 0 // defined(GIAC_HAS_STO_38) || defined(ConnectivityKit)
    unsigned int _rand_seed;
#else
    tinymt32_t _rand_seed;
#endif
    thread_param * _thread_param_ptr;
#ifdef HAVE_LIBPTHREAD
    pthread_mutex_t * _mutexptr,* _mutex_eval_status_ptr ;
#endif
    int _language_;
    std::vector<const char *> _last_evaled_function_name_;
    vecteur _last_evaled_arg_;
    int _max_sum_sqrt_;
    int _max_sum_add_;
    logo_turtle _turtle_;
    std::string _autoname_;
    std::string _format_double_;
    std::string _autosimplify_;
    std::vector<logo_turtle> _turtle_stack_; 
    double _total_time_;
    void * _evaled_table_;
    void * _extra_ptr_;
    char _series_variable_name_;
    unsigned short _series_default_order_;
    global();  
    ~global();
    global & operator = (const global & g);
  };

  // Context type to be used for evaluation without global variables
  // tabptr is the current evaluation context, 
  // it is a global context if globalcontextptr=0, local otherwise
  // previous is the upper local or global evaluation context
  // globalcontextptr points to the current global evaluation context
  // If globalcontextptr=0 and previous=0, we are at the top folder
  // The top level local context should have previous=globalcontextptr
  class context {
  public:
    sym_tab * tabptr ;
    context * globalcontextptr ;
    context * previous ;
    global * globalptr; 
    const context * parent;
    vecteur * quoted_global_vars, * rootofs;
    vecteur * history_in_ptr, * history_out_ptr;
    context();
    context(const context & c);
#ifndef RTOS_THREADX
#ifndef BESTA_OS
    context(const std::string & name);
#endif
#endif
    ~context();
    context * clone() const;
  };

  context * clone_context(const context *);
  void init_context(context * ptr);

  extern const context * context0;
  std::vector<context *> & context_list();
#ifdef HAVE_LIBPTHREAD
  extern pthread_mutex_t context_list_mutex;
#endif
  
#if !defined(RTOS_THREADX) && !defined(BESTA_OS) && !defined(NSPIRE)
  extern std::map<std::string,context *> * context_names ;
#endif

  std::vector<const char *> & last_evaled_function_name(GIAC_CONTEXT);
  vecteur & last_evaled_arg(GIAC_CONTEXT);

  bool make_thread(const giac::gen & g,int level,const giac_callback & f,void * f_param,const context * contextptr);

  std::string autoname(GIAC_CONTEXT);
  std::string autoname(const std::string & s,GIAC_CONTEXT);

  std::string autosimplify(GIAC_CONTEXT);
  std::string autosimplify(const std::string & s,GIAC_CONTEXT);

  bool csv_guess(const char * data,int count,char & sep,char & nl,char & decsep);
  std::string & format_double(GIAC_CONTEXT);

  int check_thread(context * contextptr);
  int check_threads(int i=0);

  void * & evaled_table(GIAC_CONTEXT);
  void * & extra_ptr(GIAC_CONTEXT);

  int & xcas_mode(GIAC_CONTEXT);
  void xcas_mode(int b,GIAC_CONTEXT);

  bool & python_compat(GIAC_CONTEXT);
  void python_compat(bool b,GIAC_CONTEXT);

  int & calc_mode(GIAC_CONTEXT);
  int abs_calc_mode(GIAC_CONTEXT);
  void calc_mode(int b,GIAC_CONTEXT);

  int & scientific_format(GIAC_CONTEXT);
  void scientific_format(int b,GIAC_CONTEXT);

  int & decimal_digits(GIAC_CONTEXT);
  void decimal_digits(int b,GIAC_CONTEXT);

  int & integer_format(GIAC_CONTEXT);
  void integer_format(int b,GIAC_CONTEXT);
  int & latex_format(GIAC_CONTEXT);
#ifdef BCD
  u32 & bcd_decpoint(GIAC_CONTEXT);
  u32 & bcd_mantissa(GIAC_CONTEXT);
  u32 & bcd_flags(GIAC_CONTEXT);
  bool & bcd_printdouble(GIAC_CONTEXT);
#endif
  bool & expand_re_im(GIAC_CONTEXT);
  void expand_re_im(bool b,GIAC_CONTEXT);

  bool & integer_mode(GIAC_CONTEXT);
  void integer_mode(bool b,GIAC_CONTEXT);

  bool & complex_mode(GIAC_CONTEXT);
  void complex_mode(bool b,GIAC_CONTEXT);

  bool & escape_real(GIAC_CONTEXT); // default=true, if false sqrt(-1) errorsglo
  void escape_real(bool b,GIAC_CONTEXT);

  bool & try_parse_i(GIAC_CONTEXT);
  void try_parse_i(bool b,GIAC_CONTEXT);

  bool & specialtexprint_double(GIAC_CONTEXT);
  void specialtexprint_double(bool b,GIAC_CONTEXT);

  bool & atan_tan_no_floor(GIAC_CONTEXT);
  void atan_tan_no_floor(bool b,GIAC_CONTEXT);

  bool & keep_acosh_asinh(GIAC_CONTEXT);
  void keep_acosh_asinh(bool b,GIAC_CONTEXT);

  bool & keep_algext(GIAC_CONTEXT);
  void keep_algext(bool b,GIAC_CONTEXT);

  bool & do_lnabs(GIAC_CONTEXT);
  void do_lnabs(bool b,GIAC_CONTEXT);

  bool & eval_abs(GIAC_CONTEXT);
  void eval_abs(bool b,GIAC_CONTEXT);

  bool & eval_equaltosto(GIAC_CONTEXT);
  void eval_equaltosto(bool b,GIAC_CONTEXT);

  bool & complex_variables(GIAC_CONTEXT);
  void complex_variables(bool b,GIAC_CONTEXT);

  bool & increasing_power(GIAC_CONTEXT);
  void increasing_power(bool b,GIAC_CONTEXT);

  bool & approx_mode(GIAC_CONTEXT);
  void approx_mode(bool b,GIAC_CONTEXT);

  char & series_variable_name(GIAC_CONTEXT);
  void series_variable_name(char b,GIAC_CONTEXT);

  unsigned short & series_default_order(GIAC_CONTEXT);
  void series_default_order(unsigned short b,GIAC_CONTEXT);

  vecteur & history_in(GIAC_CONTEXT);
  vecteur & history_out(GIAC_CONTEXT);

  // True if we factor 2nd order polynomials using sqrt
  bool & withsqrt(GIAC_CONTEXT);
  void withsqrt(bool b,GIAC_CONTEXT);

  bool & all_trig_sol(GIAC_CONTEXT);
  void all_trig_sol(bool b,GIAC_CONTEXT);

  bool & ntl_on(GIAC_CONTEXT);
  void ntl_on(bool b,GIAC_CONTEXT);

  bool & lexer_close_parenthesis(GIAC_CONTEXT);
  void lexer_close_parenthesis(bool b,GIAC_CONTEXT);

  bool & rpn_mode(GIAC_CONTEXT);
  void rpn_mode(bool b,GIAC_CONTEXT);

  logo_turtle & turtle(GIAC_CONTEXT);
  std::vector<logo_turtle> & turtle_stack(GIAC_CONTEXT);

  int & angle_mode(GIAC_CONTEXT);
  int get_mode_set_radian(GIAC_CONTEXT);
  void angle_mode(int m,GIAC_CONTEXT);
  bool angle_radian(GIAC_CONTEXT);
  void angle_radian(bool b,GIAC_CONTEXT);
  bool angle_degree(GIAC_CONTEXT);

  bool & show_point(GIAC_CONTEXT);
  void show_point(bool b,GIAC_CONTEXT);

  int & show_axes(GIAC_CONTEXT);
  void show_axes(int b,GIAC_CONTEXT);

  bool & io_graph(GIAC_CONTEXT);
  void io_graph(bool b,GIAC_CONTEXT);

  bool & variables_are_files(GIAC_CONTEXT);
  void variables_are_files(bool b,GIAC_CONTEXT);

  int & bounded_function_no(GIAC_CONTEXT);
  void bounded_function_no(int b,GIAC_CONTEXT);

  int & series_flags(GIAC_CONTEXT);
  void series_flags(int b,GIAC_CONTEXT);

  int & step_infolevel(GIAC_CONTEXT);
  void step_infolevel(int b,GIAC_CONTEXT);

  bool & local_eval(GIAC_CONTEXT);
  void local_eval(bool b,GIAC_CONTEXT);

  int & default_color(GIAC_CONTEXT);
  void default_color(int c,GIAC_CONTEXT);

  int & spread_Row(GIAC_CONTEXT);
  void spread_Row(int c,GIAC_CONTEXT);

  int & spread_Col(GIAC_CONTEXT);
  void spread_Col(int c,GIAC_CONTEXT);

  int & printcell_current_row(GIAC_CONTEXT);
  void printcell_current_row(int c,GIAC_CONTEXT);

  int & printcell_current_col(GIAC_CONTEXT);
  void printcell_current_col(int c,GIAC_CONTEXT);

  double & total_time(GIAC_CONTEXT);
  double & epsilon(GIAC_CONTEXT);
  void epsilon(double c,GIAC_CONTEXT);
  double & proba_epsilon(GIAC_CONTEXT);
  extern double min_proba_time; // in seconds, minimal time for proba early termination

#ifdef NSPIRE
  nio::console * logptr(GIAC_CONTEXT);
  void logptr(nio::console *,GIAC_CONTEXT);
#else
  my_ostream * logptr(GIAC_CONTEXT);
  void logptr(my_ostream *,GIAC_CONTEXT);
#endif

  int & eval_level(GIAC_CONTEXT);
  // void eval_level(int b,GIAC_CONTEXT);
  thread_param * thread_param_ptr(const context * contextptr);

#if 0 // defined(GIAC_HAS_STO_38) || defined(ConnectivityKit)
  unsigned int & rand_seed(GIAC_CONTEXT);
#else
  tinymt32_t * rand_seed(GIAC_CONTEXT);
#endif
  void rand_seed(unsigned int b,GIAC_CONTEXT);
  int giac_rand(GIAC_CONTEXT);
  int std_rand(); // a congruential random generator without context

  int & prog_eval_level_val(GIAC_CONTEXT);
  void prog_eval_level_val(int b,GIAC_CONTEXT);

  int & max_sum_sqrt(GIAC_CONTEXT);
  void max_sum_sqrt(int b,GIAC_CONTEXT);

  int & max_sum_add(GIAC_CONTEXT);

  int & language(GIAC_CONTEXT);
  void language(int b,GIAC_CONTEXT);

  int & lexer_line_number(GIAC_CONTEXT);
  int & lexer_column_number(GIAC_CONTEXT);
  void lexer_line_number(int b,GIAC_CONTEXT);
  void increment_lexer_line_number(GIAC_CONTEXT);

  std::string parser_error(GIAC_CONTEXT);
  void parser_error(const std::string & s,GIAC_CONTEXT);

  int & index_status(GIAC_CONTEXT);
  void index_status(int b,GIAC_CONTEXT);

  int & i_sqrt_minus1(GIAC_CONTEXT);
  void i_sqrt_minus1(int b,GIAC_CONTEXT);

  int & opened_quote(GIAC_CONTEXT);
  void opened_quote(int b,GIAC_CONTEXT);

  int & in_rpn(GIAC_CONTEXT);
  void in_rpn(int b,GIAC_CONTEXT);

  int & spread_formula(GIAC_CONTEXT);
  void spread_formula(int b,GIAC_CONTEXT);

  int & initialisation_done(GIAC_CONTEXT);
  void initialisation_done(int b,GIAC_CONTEXT);

  std::string comment_s(GIAC_CONTEXT);
  void comment_s(const std::string & s,GIAC_CONTEXT);
  void increment_comment_s(const std::string & s,GIAC_CONTEXT);
  void increment_comment_s(char ch,GIAC_CONTEXT);

  std::string parser_filename(GIAC_CONTEXT);
  void parser_filename(const std::string & s,GIAC_CONTEXT);

  int & first_error_line(GIAC_CONTEXT);
  void first_error_line(int s,GIAC_CONTEXT);

  std::string error_token_name(GIAC_CONTEXT);
  void error_token_name(const std::string & s,GIAC_CONTEXT);

  gen parsed_gen(GIAC_CONTEXT);
  void parsed_gen(const gen & g,GIAC_CONTEXT);

  debug_struct * debug_ptr(GIAC_CONTEXT);

  // gen_op is the type of all functions taking 1 or more gen args 
  // and returning 1 arg of type gen
  // gen argument has atomic type for an unary op, 
  // and vecteur type (compttr) otherwise
  typedef gen ( * gen_op ) (const gen & arg);
  typedef gen ( * gen_op_context ) (const gen & arg,const context * context_ptr);

  extern pid_t child_id;
  extern pid_t parent_id;
#ifdef HAVE_SIGNAL_H_OLD
  // all this stuff is obsolete, will be removed soon
  void kill_and_wait_sigusr2(); // called by child for interm. data
  // subprocess evaluation
  // return true if entree has been sent to evalation by child process
  bool child_eval(const std::string & entree,bool numeric,bool is_run_file);
  bool child_reeval(int history_begin_level);
  bool update_data(gen & entree,gen & sortie,GIAC_CONTEXT);
  void updatePICT(const vecteur & args);
  bool read_data(gen & entree,gen & sortie,std::string & message,GIAC_CONTEXT);

  gen wait_parent(); // wait a SIGUSR2 from parent process, return a gen

  pid_t make_child(); // forks and return child id
  extern bool running_file;
  extern volatile bool child_busy;
  extern volatile bool data_ready;
  extern volatile bool signal_plot_child;
  extern volatile bool signal_plot_parent; 
  extern int run_modif_pos;
  // end of obsolete section 
#endif

  void read_config(const std::string & name,GIAC_CONTEXT,bool verbose=true);
  void protected_read_config(GIAC_CONTEXT,bool verbose=true);
  vecteur remove_multiples(vecteur & v); // sort v and return list without multiple occurences
  int equalposcomp(const std::vector<int> v,int i);
  int equalposcomp(const std::vector<short int> v,int i);
  int equalposcomp(int tab[],int f);
  // attempt to convert Python-like programming structures to Xcas
  std::string python2xcas(const std::string & s_orig,GIAC_CONTEXT);
  std::string find_doc_prefix(int i);
  std::string find_lang_prefix(int i);
  int string2lang(const std::string & s); // convert "fr" to 1, "es" to 3 etc.
  void update_completions();
  void add_language(int i,GIAC_CONTEXT);
  void remove_language(int i,GIAC_CONTEXT);
  std::string set_language(int i,GIAC_CONTEXT);
  std::string read_env(GIAC_CONTEXT,bool verbose=true); // return doc prefix
  std::string home_directory();
  std::string cas_entree_name();
  std::string cas_sortie_name();
  std::string cas_setup_string(GIAC_CONTEXT);
  std::string geo_setup_string();
  std::string giac_aide_dir(); // PATH to the directory of aide_cas
  bool is_file_available(const char * ch);
  bool file_not_available(const char * ch);
  bool check_file_path(const std::string & s); // true if file is in path
  std::string browser_command(const std::string & orig_file);
  bool system_browser_command(const std::string & file);
  // convert doc name to an absolute path name
  std::string absolute_path(const std::string & orig_file);
  std::string & xcasrc();
  std::string & xcasroot();
  std::string add_extension(const std::string & s,const std::string & ext,const std::string & def);
  std::string remove_filename(const std::string & s);
  bool my_isnan(double d);
  bool my_isinf(double d);

  /* launch a new thread for evaluation only,
     no more readqueue, readqueue is done by the "parent" thread
     Ctrl-C will kill the "child" thread
     wait_001 is a function that should wait 0.001 s and update thinks
     for example it could remove idle callback of a GUI
     then call the wait function of the GUI and readd callbacks
  */
  giac::gen thread_eval(const giac::gen & g,int level,giac::context * contextptr,void (* wait_001)(giac::context *));
#ifdef HAVE_LIBPTHREAD
  // pointer to the context mutex so that thread_eval can be locked
  // Check this in wait_001 function if you don't want the main thread to
  // be blocked by a call to thread_eval inside wait_001
  pthread_mutex_t * mutexptr(GIAC_CONTEXT);
  extern pthread_mutex_t interactive_mutex,turtle_mutex;
  
#endif
  // Check if a thread_eval is active
  bool is_context_busy(GIAC_CONTEXT);
  // Check and set the kill thread flag
  bool kill_thread(GIAC_CONTEXT);
  void kill_thread(bool b,GIAC_CONTEXT);
  // Thread eval status = 0 finished, =1 eval, =2 debug_wait_main
  int thread_eval_status(GIAC_CONTEXT);
  void thread_eval_status(int c,GIAC_CONTEXT);

  void clear_prog_status(GIAC_CONTEXT);
  void cleanup_context(GIAC_CONTEXT);

  // count how many bytes are required to save g in a file
  unsigned archive_count(const gen & g,GIAC_CONTEXT);
  // save g in a opened file
  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);

  bool archive_save(void * f,const gen & g,GIAC_CONTEXT);
  // restore a gen from an opened file
  gen archive_restore(void * f,size_t readfunc(void * p, size_t nbBytes,size_t NbElements, void *file),GIAC_CONTEXT);
  gen archive_restore(FILE * f,GIAC_CONTEXT);
  void init_geogebra(bool on,GIAC_CONTEXT);
  vecteur giac_current_status(bool save_history,GIAC_CONTEXT);
  bool unarchive_session(const gen & g,int level,const gen & replace,GIAC_CONTEXT,bool with_history=true);

  gen add_autosimplify(const gen & g,GIAC_CONTEXT);

  extern void (*my_gprintf)(unsigned special,const std::string & format,const vecteur & v,GIAC_CONTEXT);
  void gprintf(const std::string & format,const vecteur & v,GIAC_CONTEXT);
  void gprintf(const std::string & format,const vecteur & v,int step_info,GIAC_CONTEXT);
  void gprintf(unsigned special,const std::string & format,const vecteur & v,GIAC_CONTEXT);
  void gprintf(unsigned special,const std::string & format,const vecteur & v,int step_info,GIAC_CONTEXT);
  gen make_symbolic(const gen & op,const gen & args);
  // optional, call it just before exiting
  int release_globals();
  
#ifndef NO_NAMESPACE_GIAC
} // namespace giac
#endif // ndef NO_NAMESPACE_GIAC


#endif // _GIAC_GLOBAL_H