diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index e0cc32fd3..1e31a4f1d 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -15,6 +15,7 @@ jobs: with: submodules: true - run: make -C apps/KhiCAS cleanall + - run: make -C apps/KhiCAS src/lib/libmpfi.a - run: make KhiCAS_rebuild - run: ./tool/archive KhiCAS.tar KhiCAS - uses: actions/upload-artifact@master diff --git a/.gitignore b/.gitignore index dc0291eb3..ab9af520b 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,6 @@ apps/KhiCAS/src/gmp*/trialdivtab.h *.pc **/libtool **/aclocal.m4 +khiext/ +khiext.tgz +*~ diff --git a/apps/KhiCAS/README.md b/apps/KhiCAS/README.md index 39953d41d..a78722cf7 100644 --- a/apps/KhiCAS/README.md +++ b/apps/KhiCAS/README.md @@ -13,7 +13,7 @@ To update KhiCAS, you have some things to do: 3. Copy the contents of the folder `khiext/apps/KhiCAS` to the folder `apps/KhiCAS` 4. Now, you have the new version of KhiCAS, but you have to apply some changes to the code. 5. Replace `inline bool iskeydown(int key){ return getkey(key | 0x80000000); }` by `inline bool iskeydown(int key);` -6. Add this code in the file `apps/KhiCAS/main.cpp`: +6. Add this code in the file `apps/KhiCAS/src/main.cpp`: ```cpp bool iskeydown(int key) { diff --git a/apps/KhiCAS/app.elf b/apps/KhiCAS/app.elf index c78186864..424c11b5c 100644 Binary files a/apps/KhiCAS/app.elf and b/apps/KhiCAS/app.elf differ diff --git a/apps/KhiCAS/buildDeps~ b/apps/KhiCAS/buildDeps~ deleted file mode 100755 index 8e4cfc9cb..000000000 --- a/apps/KhiCAS/buildDeps~ +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash - -set -e - -function build { - ( - cd src/gmp-6.2.1 - ./configure --host=arm-none-eabi --disable-assembly CFLAGS="$2" - make -j $(nproc) - cp .libs/libgmp.a ../lib/ - cp gmp.h ../include/gmp.h - make distclean - ) - - ( - cd src/mpfr-4.1.0 - ./configure --with-gmp=../ --host=arm-none-eabi --disable-shared CFLAGS="$2" - make -j $(nproc) - cp src/.libs/libmpfr.a ../lib/ - cp src/mpfr.h ../include/mpfr.h - make distclean - ) - - ( - cd src/mpfi-1.5.4 - - # Quick and dirty hack for github pages to work - # Setup symlinks manually - # mkdir build-aux - # mkdir m4 - - # ln -s /usr/share/libtool/build-aux/ltmain.sh build-aux/ltmain.sh - # ln -s /usr/share/automake-1.16/missing build-aux/missing - # ln -s /usr/share/automake-1.16/config.sub build-aux/config.sub - # ln -s /usr/share/automake-1.16/compile build-aux/compile - # ln -s /usr/share/automake-1.16/config.guess build-aux/config.guess - # ln -s /usr/share/automake-1.16/test-driver build-aux/test-driver - # ln -s /usr/share/automake-1.16/install-sh build-aux/install-sh - # ln -s /usr/share/automake-1.16/ar-lib build-aux/ar-lib - # ln -s /usr/share/automake-1.16/depcomp build-aux/depcomp - # ln -s /usr/share/aclocal/ltoptions.m4 m4/ltoptions.m4 - # ln -s /usr/share/aclocal/ltsugar.m4 m4/ltsugar.m4 - # ln -s /usr/share/aclocal/libtool.m4 m4/libtool.m4 - # ln -s /usr/share/aclocal/lt~obsolete.m4 m4/lt~obsolete.m4 - # ln -s /usr/share/aclocal/ltversion.m4 m4/ltversion.m4 - - - ./configure --with-mpfr=$(pwd)/../ --with-gmp=$(pwd)/../ --host=arm-none-eabi CFLAGS="$2" - make -j $(nproc) - cp src/.libs/libmpfi.a ../lib/ - cp src/mpfi.h ../include/mpfi.h - make distclean - - rm -r build-aux - rm -r m4 - ) - - ( - cd src/micropython-1.12/numworks - ./mklib - ) -} - -# build n0100 "-Os -fdata-sections -ffunction-sections -DNDEBUG -mthumb -march=armv7e-m -mfloat-abi=hard -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -fno-strict-aliasing --specs=nosys.specs" -build n0110 "-Os -fdata-sections -ffunction-sections -DNDEBUG -mthumb -march=armv7e-m -mfloat-abi=hard -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -fno-strict-aliasing --specs=nosys.specs" diff --git a/apps/KhiCAS/buildGiac~ b/apps/KhiCAS/buildGiac~ deleted file mode 100755 index 94b2f282e..000000000 --- a/apps/KhiCAS/buildGiac~ +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -set -e - -function build { - ( - cd src/giac-1.6.0/src - rm -f *.o *.a - make -f Makefile.numworks.$1 -j $(nproc) - cp libgiac.a ../../lib/ - rm -f *.o *.a - ) -} - -#build n0100 -build n0110 -#build simulator diff --git a/apps/KhiCAS/examples/bac11.xw b/apps/KhiCAS/examples/bac11.xw old mode 100755 new mode 100644 diff --git a/apps/KhiCAS/examples/bac12.xw b/apps/KhiCAS/examples/bac12.xw old mode 100755 new mode 100644 diff --git a/apps/KhiCAS/src/giac-1.6.0/src/Makefile.numworks.n0110~ b/apps/KhiCAS/src/giac-1.6.0/src/Makefile.numworks.n0110~ deleted file mode 100755 index 78d04865f..000000000 --- a/apps/KhiCAS/src/giac-1.6.0/src/Makefile.numworks.n0110~ +++ /dev/null @@ -1,27 +0,0 @@ -PREFIX=arm-none-eabi- -GCC = $(PREFIX)gcc -CXX = $(PREFIX)g++ -LD = $(PREFIX)ld - -CXXFLAGS = -Os -I. -I../../include #-I../../libtommath-0.39 -CXXFLAGS += -fno-threadsafe-statics -mthumb -march=armv7e-m -mfloat-abi=hard -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -fdata-sections -ffunction-sections -fno-strict-aliasing -fno-exceptions # -fpermissive -#CXXFLAGS += -DNUMWORKS -DNSPIRE_NEWLIB -DHAVE_CONFIG_H -DIN_GIAC -DTIMEOUT -DNO_PHYSICAL_CONSTANTS -DNO_STDEXCEPT -DGIAC_BINARY_ARCHIVE -DNO_UNARY_FUNCTION_COMPOSE -DNO_TEMPLATE_MULTGCD -DNO_RTTI -DGIAC_GENERIC_CONSTANTS # -DGIAC_NO_OPTIMIZATIONS -DSTATIC_BUILTIN_LEXER_FUNCTIONS -CXXFLAGS += -DDEVICE -DNUMWORKS -DHAVE_CONFIG_H -DIN_GIAC -DTIMEOUT -DNO_STDEXCEPT -DGIAC_BINARY_ARCHIVE -DNO_UNARY_FUNCTION_COMPOSE -DNO_TEMPLATE_MULTGCD -DGIAC_NO_OPTIMIZATIONS -DSTATIC_BUILTIN_LEXER_FUNCTIONS -DTIMEOUT -DMICROPY_LIB - -OBJS = sym2poly.o gausspol.o threaded.o maple.o ti89.o mathml.o moyal.o misc.o permu.o desolve.o input_parser.o symbolic.o index.o modpoly.o modfactor.o ezgcd.o derive.o solve.o intg.o intgab.o risch.o lin.o series.o subst.o vecteur.o sparse.o csturm.o tex.o global.o ifactor.o alg_ext.o gauss.o isom.o help.o plot.o plot3d.o rpn.o prog.o pari.o cocoa.o unary.o usual.o identificateur.o gen.o input_lexer.o tinymt32.o first.o quater.o kdisplay.o kadd.o k_csdk.o - -all: libgiac.a - -.cc.o: - $(CXX) $(CXXFLAGS) -c $< - -.c.o: - $(CXX) $(CXXFLAGS) -c $< - -clean: - rm -f *.o - -libgiac.a: $(OBJS) - $(PREFIX)ar rcs libgiac.a $(OBJS) - $(PREFIX)ranlib libgiac.a - $(PREFIX)objcopy --redefine-sym mp_init=mp_tm_init $@ diff --git a/apps/KhiCAS/src/giac-1.6.0/src/alg_ext.cc b/apps/KhiCAS/src/giac-1.6.0/src/alg_ext.cc index b24a5fa6a..fccdc5cc3 100644 --- a/apps/KhiCAS/src/giac-1.6.0/src/alg_ext.cc +++ b/apps/KhiCAS/src/giac-1.6.0/src/alg_ext.cc @@ -728,10 +728,10 @@ namespace giac { if (!rootof_trylock()){ if (lvptr){ gen vexpr=r2e(v,vecteur(lvptr->begin()+1,lvptr->end()),contextptr); - symbolic_rootof_list()[vexpr]=gaa+k*gbb; + symbolic_rootof_list()[vexpr]=k*gaa+gbb; } else - symbolic_rootof_list()[v]=gaa+k*gbb; + symbolic_rootof_list()[v]=k*gaa+gbb; rootof_unlock(); } } diff --git a/apps/KhiCAS/src/giac-1.6.0/src/config.h b/apps/KhiCAS/src/giac-1.6.0/src/config.h index ea739610e..5188900a4 100755 --- a/apps/KhiCAS/src/giac-1.6.0/src/config.h +++ b/apps/KhiCAS/src/giac-1.6.0/src/config.h @@ -455,7 +455,7 @@ #define PACKAGE_NAME "giac" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "giac 1.7.0" +#define PACKAGE_STRING "giac 1.9.0" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "giac" @@ -464,7 +464,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.7.0" +#define PACKAGE_VERSION "1.9.0" /* Define if exists and defines unusable PRI* macros. */ /* #undef PRI_MACROS_BROKEN */ @@ -506,7 +506,7 @@ /* #undef USE_OPENGL32 */ /* Version number of package */ -#define VERSION "1.7.0" +#define VERSION "1.9.0" /* Define to 1 if the X Window System is missing or not being used. */ #define X_DISPLAY_MISSING 1 diff --git a/apps/KhiCAS/src/giac-1.6.0/src/derive.cc b/apps/KhiCAS/src/giac-1.6.0/src/derive.cc index ddddfda55..f982f70a7 100644 --- a/apps/KhiCAS/src/giac-1.6.0/src/derive.cc +++ b/apps/KhiCAS/src/giac-1.6.0/src/derive.cc @@ -808,6 +808,8 @@ namespace giac { step_infolevel(contextptr)=savestep; gprintf(step_extrema1,gettext("Derivative of %gen with respect to %gen is %gen\nSolving %gen with respect to %gen answer %gen"),makevecteur(arg,var,d,deq,var,s.type==_VECT?change_subtype(s,_SEQ__VECT):s),contextptr); calc_mode(c,contextptr); + if (c==1 && s.type==_VECT) + s.subtype=0; vecteur ls=lidnt(s); for (int i=0;i=1 && range.front().type==_VECT){ + range=*range.front()._VECTptr; + if (range.size()==2 && range[0]==minus_inf && range[1]==plus_inf){ + gen periode; + if (is_periodic(f,x,periode,contextptr)){ + gen hyp=symb_and(symbolic(at_superieur_egal,makesequence(x,0)),symbolic(at_inferieur_egal,makesequence(x,periode))); + *logptr(contextptr) << "Periodic function. Auto assume" << hyp << "\n"; + giac_assume(hyp,contextptr); + } + } + } + } gen _domain(const gen & args,GIAC_CONTEXT){ if (is_undef(args)) return args; - if (args.type!=_VECT || args.subtype!=_SEQ__VECT) - return domain(args,vx_var,0,contextptr); + if (args.type!=_VECT || args.subtype!=_SEQ__VECT){ + gen xval=assumeeval(vx_var,contextptr); + domain_auto_assume(args,vx_var,contextptr); + gen res=domain(args,vx_var,0,contextptr); + restorepurge(xval,vx_var,contextptr); + return res; + } vecteur v=*args._VECTptr; if (v.size()<2) return gensizeerr(contextptr); @@ -1123,7 +1145,11 @@ namespace giac { v.push_back(0); if (v[2].type!=_INT_) return gensizeerr(contextptr); - return domain(v[0],v[1],v[2].val,contextptr); + gen xval=assumeeval(vx_var,contextptr); + domain_auto_assume(v[0],v[1],contextptr); + gen res=domain(v[0],v[1],v[2].val,contextptr); + restorepurge(xval,vx_var,contextptr); + return res; } static const char _domain_s []="domain"; static define_unary_function_eval (__domain,&_domain,_domain_s); diff --git a/apps/KhiCAS/src/giac-1.6.0/src/dispatch.h b/apps/KhiCAS/src/giac-1.6.0/src/dispatch.h index 70f054a33..6b1f0bc76 100644 --- a/apps/KhiCAS/src/giac-1.6.0/src/dispatch.h +++ b/apps/KhiCAS/src/giac-1.6.0/src/dispatch.h @@ -476,10 +476,10 @@ namespace giac { }; enum color_values { -#ifdef KHICAS +#if defined KHICAS || defined GIAC_HAS_STO_38 _BLACK=0, _RED=0xf800, - _GREEN=0x0400, + _GREEN=0x07e0, _YELLOW=0xffe0, _BLUE=0x001f, _MAGENTA=0xf81f, @@ -488,18 +488,21 @@ namespace giac { #else // KHICAS #ifdef GIAC_HAS_STO_38 _WHITE=0, + _RED=0xff0000, + _GREEN=0xff00, + _YELLOW=0xffff00, + _BLUE=0xff, + _MAGENTA=0xff00ff, + _CYAN=0xffff, + _BLACK=7, #else _BLACK=0, -#endif _RED=1, _GREEN=2, _YELLOW=3, _BLUE=4, _MAGENTA=5, _CYAN=6, -#ifdef GIAC_HAS_STO_38 - _BLACK=7, -#else _WHITE=7, #endif #endif // KHICAS @@ -618,6 +621,18 @@ namespace giac { _GT_ACYCLIC = 159, // acyclic _KDE_BANDWIDTH = 160, // bandwidth _KDE_BINS = 161, // bins + _NLP_METHOD = 162, + _NLP_TOLERANCE = 163, + _NLP_VERBOSE = 164, + _ANN_HALF_MSE = 165, // MSE + _ANN_CROSS_ENTROPY = 166, // cross_entropy + _ANN_LOG_LOSS = 167, // log_loss + _ANN_BLOCK_SIZE = 168, // block_size + _ANN_MOMENTUM = 169, // momentum + _ANN_TOPOLOGY = 170, // topology + _ANN_LEARNING_RATE = 171, // learning_rate + _ANN_WEIGHT_DECAY = 172, // weight_decay + _ANN_RELU = 173, // ReLU }; enum mupad_operator { diff --git a/apps/KhiCAS/src/giac-1.6.0/src/gen.cc b/apps/KhiCAS/src/giac-1.6.0/src/gen.cc index c2318db91..e53d4200b 100755 --- a/apps/KhiCAS/src/giac-1.6.0/src/gen.cc +++ b/apps/KhiCAS/src/giac-1.6.0/src/gen.cc @@ -4669,7 +4669,7 @@ namespace giac { if (a.type==_INT_){ longlong tmp=((longlong) a.val+b.val); a.val=(int)tmp; - if (a.val==tmp) + if (a.val==tmp && tmp!=-2147483648) return a; return a=tmp; } @@ -5475,7 +5475,7 @@ namespace giac { if (a.type==_INT_){ longlong tmp=((longlong) a.val-b.val); a.val=(int)tmp; - if (a.val==tmp) + if (a.val==tmp && tmp!=-2147483648) return a; return a=tmp; } @@ -6025,7 +6025,7 @@ namespace giac { if (ab>>31) tmp=ab; #else - if (tmp.val!=ab) + if (tmp.val!=ab || tmp==-2147483648) tmp=ab; #endif return; @@ -9037,7 +9037,7 @@ namespace giac { #ifdef HAVE_LIBMPFR // FIXME?? try to avoid rounding error with more digits if (fabs(approx._DOUBLE_val)<1e-5 && (a-b).type!=_FRAC){ - gen tmp=accurate_evalf(eval(a-b,1,contextptr),1000); + gen tmp=accurate_evalf(eval(a-b,1,contextptr),1100); // 1100 bits exceeds double precision, if a and b are equal up to double precision, this will be rounded to 0.0 tmp=evalf_double(tmp,1,contextptr); if (tmp.type==_DOUBLE_) approx=tmp; @@ -14181,6 +14181,8 @@ void sprint_double(char * s,double d){ return "lp_heuristic"; case _NLP_PRESOLVE: return "nlp_presolve"; + case _NLP_METHOD: + return "nlp_method"; case _NLP_SAMPLES: return "nlp_samples"; case _NLP_INTEGER: @@ -14193,6 +14195,10 @@ void sprint_double(char * s,double d){ return "nlp_binaryvariables"; case _NLP_NONNEGINT: return "nlp_nonnegint"; + case _NLP_TOLERANCE: + return "nlp_tolerance"; + case _NLP_VERBOSE: + return "nlp_verbose"; case _NLP_FEAS_TOL: return "nlp_feasibilitytolerance"; case _NLP_INT_TOL: @@ -14231,6 +14237,24 @@ void sprint_double(char * s,double d){ return "bandwidth"; case _KDE_BINS: return "bins"; + case _ANN_LEARNING_RATE: + return "learning_rate"; + case _ANN_WEIGHT_DECAY: + return "weight_decay"; + case _ANN_RELU: + return "ReLU"; + case _ANN_HALF_MSE: + return "MSE"; + case _ANN_CROSS_ENTROPY: + return "cross_entropy"; + case _ANN_LOG_LOSS: + return "log_loss"; + case _ANN_BLOCK_SIZE: + return "block_size"; + case _ANN_MOMENTUM: + return "momentum"; + case _ANN_TOPOLOGY: + return "topology"; } } if (subtype==_INT_MUPADOPERATOR){ @@ -16797,7 +16821,7 @@ void sprint_double(char * s,double d){ if (is3d(last)){ int worker=0; worker=EM_ASM_INT_V({ - if (typeof(UI.disable3d) !== 'undefined' && UI.disable3d) + if (typeof(UI)!=="undefined" && typeof(UI.disable3d) !== 'undefined' && UI.disable3d) return UI.disable3d; if (Module.worker) return 1; else return 0; }); @@ -16836,7 +16860,7 @@ void sprint_double(char * s,double d){ #ifdef KHICAS // replace ],[ by ][ if (last.is_symb_of_sommet(at_pnt)){ if (os_shell || nspirelua) - xcas::displaygraph(g,&C); + xcas::displaygraph(g,gp,&C); S="Graphic_object"; } else { @@ -16878,12 +16902,12 @@ void sprint_double(char * s,double d){ #if !defined GIAC_GGB #if defined EMCC || defined EMCC2 double add_evalf=EM_ASM_DOUBLE_V({ - if (typeof(UI.add_evalf)!="undefined") + if (typeof(UI)!=="undefined" && typeof(UI.add_evalf)!="undefined") return UI.add_evalf*1.0; return 1.0; }), js_bigint=EM_ASM_DOUBLE_V({ - if (typeof(UI.js_bigint)!="undefined") + if (typeof(UI)!=="undefined" && typeof(UI.js_bigint)!="undefined") return UI.js_bigint*1.0; return 0.0; }); diff --git a/apps/KhiCAS/src/giac-1.6.0/src/gen.h b/apps/KhiCAS/src/giac-1.6.0/src/gen.h index b3345088b..95f7862ab 100644 --- a/apps/KhiCAS/src/giac-1.6.0/src/gen.h +++ b/apps/KhiCAS/src/giac-1.6.0/src/gen.h @@ -1275,6 +1275,7 @@ namespace giac { return s.c_str(); } virtual std::string texprint (GIAC_CONTEXT) const { return "Nothing_to_print_tex"; } + virtual gen giac_constructor (GIAC_CONTEXT) const { return *this; } virtual gen eval(int level,const context * contextptr) const {return *this;}; virtual gen evalf(int level,const context * contextptr) const {return *this;}; virtual gen makegen(int i) const { return string2gen("makegen not redefined"); } ; diff --git a/apps/KhiCAS/src/giac-1.6.0/src/global.cc b/apps/KhiCAS/src/giac-1.6.0/src/global.cc index 03c88839e..343d9d22e 100755 --- a/apps/KhiCAS/src/giac-1.6.0/src/global.cc +++ b/apps/KhiCAS/src/giac-1.6.0/src/global.cc @@ -52,7 +52,9 @@ using namespace std; #include #include #include -#include +#if !defined RTOS_THREADX +//#include +#endif #if !defined BESTA_OS && !defined FXCG #include #endif @@ -1577,7 +1579,7 @@ namespace giac { // 00 // type // record data - if (*ptr!=0xee0bddba) // ba dd 0b ee + if (*((unsigned *)ptr)!=0xee0bddba) // ba dd 0b ee return false; int pos=4; ptr+=4; for (;pos. - */ -#ifdef KHICAS - extern "C" double millis(); //extern int time_shift; -#endif - -using namespace std; -#ifdef HAVE_SSTREAM -#include -#else -#include -#endif -#if !defined GIAC_HAS_STO_38 && !defined NSPIRE && !defined FXCG -#include -#endif -#include "global.h" -// #include -#if !defined BESTA_OS && !defined FXCG -#include -#endif -#include -#ifndef WINDOWS -#include // for uintptr_t -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_PWD_H -#include -#endif -#include -#include -#include -#include -#if !defined BESTA_OS && !defined FXCG -#include -#endif -#include "gen.h" -#include "identificateur.h" -#include "symbolic.h" -#include "sym2poly.h" -#include "plot.h" -#include "rpn.h" -#include "prog.h" -#include "usual.h" -#include "tex.h" -#include "path.h" -#include "input_lexer.h" -#include "giacintl.h" -#ifdef HAVE_LOCALE_H -#include -#endif -#ifdef _HAS_LIMITS -#include -#endif -#ifndef BESTA_OS -#ifdef WIN32 -#ifndef VISUALC -#if !defined(GNUWINCE) && !defined(__MINGW_H) -#include -#endif -#if !defined(GNUWINCE) -#include -#endif // ndef gnuwince -#endif // ndef visualc -#endif // win32 -#endif // ndef bestaos - -#ifdef HAVE_LIBFLTK -#include -#endif - -#if defined VISUALC && !defined BESTA_OS && !defined RTOS_THREADX && !defined FREERTOS -#include -#endif - -#ifdef BESTA_OS -#include -#endif // besta_os - -#include -#include -#ifdef QUICKJS -#include "qjsgiac.h" -string js_vars; -void update_js_vars(){ - const char VARS[]="function update_js_vars(){let res=''; for(var b in globalThis) { let prop=globalThis[b]; if (globalThis.hasOwnProperty(b)) res+=b+' ';} return res;}; update_js_vars()"; - char * names=js_ck_eval(VARS,&global_js_context); - if (names){ - js_vars=names; - free(names); - } -} -int js_token(const char * buf){ - return js_token(js_vars.c_str(),buf); -} -#else // QUICKJS -void update_js_vars(){} -int js_token(const char * buf){ - return 0; -} -#endif -int js_token(const char * list,const char * buf){ - int bufl=strlen(buf); - for (const char * p=list;*p;){ - if (p[0]=='\'') - ++p; - if (strncmp(p,buf,bufl)==0 && - (p[bufl]==0 || p[bufl]==' ' || p[bufl]=='\'')){ - return (p[bufl]=='\'')?3:2; - } - // skip to next keyword in p - for (;*p;++p){ - if (*p==' '){ - ++p; break; - } - } - } - return 0; -} - -#ifdef HAVE_LIBMICROPYTHON -std::string & python_console(){ - static std::string * ptr=0; - if (!ptr) - ptr=new string; - return *ptr; -} -#endif -bool freezeturtle=false; - -#if defined(FIR) -extern "C" int firvsprintf(char*,const char*, va_list); -#endif - -#ifdef FXCG -extern "C" int KeyPressed( void ); -#endif - -#ifdef KHICAS -#include "kdisplay.h" -#endif - -#ifdef NSPIRE_NEWLIB -#include -#endif - -#if defined NUMWORKS && defined DEVICE -extern "C" const char * extapp_fileRead(const char * filename, size_t *len, int storage); -extern "C" bool extapp_erasesector(void *); -extern "C" bool extapp_writememory(unsigned char * dest,const unsigned char * data,size_t length); -#endif - -#ifdef NUMWORKS -size_t pythonjs_stack_size=30*1024,pythonjs_heap_size=40*1024; -#else - size_t pythonjs_stack_size=128*1024,pythonjs_heap_size=(2*1024-256-64)*1024; -#endif -void * bf_ctx_ptr=0; -size_t bf_global_prec=128; // global precision for BF - -int my_sprintf(char * s, const char * format, ...){ - int z; - va_list ap; - va_start(ap,format); -#if defined(FIR) && !defined(FIR_LINUX) - z = firvsprintf(s, format, ap); -#else - z = vsprintf(s, format, ap); -#endif - va_end(ap); - return z; -} - -int ctrl_c_interrupted(int exception){ - if (!giac::ctrl_c && !giac::interrupted) - return 0; - giac::ctrl_c=giac::interrupted=0; -#ifndef NO_STD_EXCEPT - if (exception) - giac::setsizeerr("Interrupted"); -#endif - return 1; -} - -void console_print(const char * s){ - *logptr(giac::python_contextptr) << s; -} - -const char * console_prompt(const char * s){ - static string S; - giac::gen g=giac::_input(giac::string2gen(s?s:"?",false),giac::python_contextptr); - S=g.print(giac::python_contextptr); - return S.c_str(); -} - -// support for tar archive in flash on the numworks -char * buf64k=0; // we only have 64k of RAM buffer on the Numworks -const size_t buflen=(1<<16); -int numworks_maxtarsize=0x600000-0x10000; -size_t tar_first_modified_offset=0; // set to non 0 if tar data comes from Numworks - - -// erase sector containing address if required -// returns true if erased, false otherwise -// if false is returned, it means that [address..end of sector] contains 0xff -// i.e. the remaining part of this sector is ready to write without erasing -void erase_sector(const char * buf){ -#if defined NUMWORKS && defined DEVICE - extapp_erasesector((void *)buf); -#else - char * nxt=(char *) ((((size_t) buf)/buflen +1)*buflen); - char * start=nxt-buflen; - for (int i=0;inxt-target) - delta=nxt-target; - // first copy current sector in buf64k before erasing - char * prev=(char *)nxt-buflen; - memcpy(buf64k,prev,buflen); - memcpy(buf64k+(target-prev),src,delta); - erase_sector(target); - WriteMemory(prev,buf64k,buflen); - length -= delta; - src += delta; - target += delta; - while (length>0){ - memcpy(buf64k,target,buflen); - delta=length; - if (delta>buflen) - delta=buflen; - memcpy(buf64k,src,delta); - erase_sector(target); - WriteMemory(target,buf64k,buflen); - length -= delta; - src += delta; - target += delta; - } -} -#endif - -// TAR: tar file format support -int tar_filesize(int s){ - int h=(s/512+1)*512; - if (s%512) - h +=512; - return h; -} - -// adapted from tarballjs https://github.com/ankitrohatgi/tarballjs -string giac_readString(const char * buffer,size_t str_offset, size_t size) { - int i = 0; - string rtnStr = ""; - while(i=128) break; - rtnStr += ch; - i++; - } - return rtnStr; -} -string giac_readFileName(const char * buffer,size_t header_offset) { - return giac_readString(buffer,header_offset, 100); -} -string giac_readFileType(const char * buffer,size_t header_offset) { - // offset: 156 - const char typeStr = buffer[header_offset+156]; - if (typeStr == '0') - return "file"; - if (typeStr == '5') - return "directory"; - return string(1,typeStr); -} -int giac_readFileSize(const char * buffer,size_t header_offset) { - // offset: 124 - const char * szView = buffer+ header_offset+124; - int res=0; - for (int i = 0; i < 11; i++) { - char tmp=szView[i]; - if (tmp<'0' || tmp>'9') return -1; // invalid file size - res *= 8; - res += (tmp-'0'); - } - return res; -} - -int giac_readMode(const char * buffer,size_t header_offset) { - // offset: 100 - const char * szView = buffer+ header_offset+100; - int res=0; - for (int i = 0; i < 7; i++) { - char tmp=szView[i]; - if (tmp==' ') - return res; - if (tmp<'0' || tmp>'9') - return -1; // invalid file size - res *= 10; - res += (tmp-'0'); - } - return res; -} - -void tar_clear(char * buffer){ - for (int i=0;i<1024;++i) - buffer[i]=0; -} - -std::vector tar_fileinfo(const char * buffer,size_t byteLength){ - vector fileInfo; - if (!buffer) return fileInfo; - size_t offset=0,file_size=0; - string file_name = ""; - string file_type = ""; - while (byteLength==0 || offset f=tar_fileinfo(buffer,byteLength); - if (f.empty()) return 0; - fileinfo_t i=f[f.size()-1]; - size_t offset=i.header_offset+tar_filesize(i.size); - return offset; -} - -std::string leftpad(const string & s,size_t targetLength) { - if (targetLength<=s.size()) - return s; - string add(targetLength-s.size(),'0'); - return add+s; -} - -void tar_writestring(char * buffer,const string & str, size_t offset, size_t size) { - for (size_t i = 0; i < size; i++) { - if (i < str.size()) - buffer[i+offset] = str[i]; - else - buffer[i+offset] = 0; - } -} - -std::string toString8(longlong chksum){ - if (chksum<0) - return "-"+toString8(-chksum); - if (chksum==0) - return "0"; - string res; - for (;chksum;chksum/=8){ - res = string(1,'0'+(chksum % 8))+res; - } - return res; -} - -ulonglong fromstring8(const char * ptr){ - ulonglong res=0; char ch; - for (;(ch=*ptr);++ptr){ - if (ch==' ') - return res; - if (ch<'0' || ch>'8') - return -1; - res *= 8; - res += ch-'0'; - } - return res; -} - -void tar_writechecksum(char * buffer,size_t header_offset) { - // offset: 148 - tar_writestring(buffer," ", header_offset+148, 8); // first fill with spaces - // add up header bytes - int chksum = 0; - for (int i = 0; i < 512; i++) { - chksum += buffer[header_offset+i]; - } - tar_writestring(buffer,leftpad(toString8(chksum),6), header_offset+148, 8); - tar_writestring(buffer," ",header_offset+155,1); // add space inside chksum field -} - -void tar_fillheader(char * buffer,size_t offset,int exec=0){ - int uid = 501; - int gid = 20; - string mode = exec?"755":"644"; -#if !defined HAVE_NO_SYS_TIMES_H && defined HAVE_SYS_TIME_H - struct timeval t; - gettimeofday(&t, NULL); - longlong mtime=t.tv_sec; -#else - longlong mtime=(2021LL-1970)*24*365.2425*3600; -#ifdef KHICAS - mtime = millis()/1000; -#endif -#endif - string user = "user"; - string group = "group"; - - tar_writestring(buffer,leftpad(mode,7)+" ", offset+100, 8); - tar_writestring(buffer,leftpad(toString8(uid),6)+" ",offset+108,8); - tar_writestring(buffer,leftpad(toString8(gid),6)+" ",offset+116,8); - tar_writestring(buffer,leftpad(toString8(mtime),11)+" ",offset+136,12); - - //UI.tar_writestring(buffer,"ustar", offset+257,6); // magic string - //UI.tar_writestring(buffer,"00", offset+263,2); // magic version - tar_writestring(buffer,"ustar ", offset+257,8); - - tar_writestring(buffer,user, offset+265,32); // user - tar_writestring(buffer,group, offset+297,32); //group - tar_writestring(buffer,"000000 ",offset+329,7); //devmajor - tar_writestring(buffer,"000000 ",offset+337,7); //devmajor - tar_writechecksum(buffer,offset); -} - -// flash version -int flash_adddata(const char * buffer_,const char * filename,const char * data,size_t datasize,int exec){ - vector finfo=tar_fileinfo(buffer_,numworks_maxtarsize); - size_t s=finfo.size(); - if (s==0) return 0; - fileinfo_t last=finfo[s-1]; - size_t offset=last.header_offset; - offset += tar_filesize(last.size); - if (offset+1024+datasize>numworks_maxtarsize) return 0; - buffer_ += offset; - char * nxt=(char *) ((((size_t) buffer_)/buflen +1)*buflen); - char * prev=nxt-buflen; - size_t pos=buffer_-prev; - for (int i=0;ibuflen-pos) - length=buflen-pos; - memcpy(buffer,data,length); - buffer += length; - for (;(size_t) buffer % 512;++buffer) - *buffer=0; - erase_sector(prev); - WriteMemory(prev,buf64k,buflen); - datasize -= length; - data += length; - prev += buflen; - while (datasize>0){ - // copy remaining data - length=datasize finfo=tar_fileinfo(buffer,buffersize); - size_t s=finfo.size(); - if (s==0) return 0; - fileinfo_t last=finfo[s-1]; - size_t offset=last.header_offset; - offset += tar_filesize(last.size); - buffersize=offset; - size_t newsize=offset+1024+datasize; - newsize=10240*((newsize+10239)/10240); - if (newsize>numworks_maxtarsize) return 0; - // console.log(buffer.byteLength,newsize); - // resize buffer - if (buffersize data; - FILE * f = fopen(filename,"rb"); - while (1){ - char ch=fgetc(f); - if (feof(f)) - break; - data.push_back(ch); - } - fclose(f); - int exec=1; - for (int i=0;filename[i];++i){ - if (filename[i]=='.') - exec=0; - } - string fname=filename; - for (int i=0;filename[i];++i){ - if (filename[i]=='/') - fname=filename+i+1; - } - return flash_adddata(buffer,fname.c_str(),&data.front(),data.size(),exec); -#endif -} - -// RAM version -int tar_addfile(char * & buffer,const char * filename,size_t * buffersizeptr){ - FILE * f = fopen(filename,"rb"); - vector data; - while (1){ - char ch=fgetc(f); - if (feof(f)) - break; - data.push_back(ch); - } - fclose(f); - int exec=1; - for (int i=0;filename[i];++i){ - if (filename[i]=='.') - exec=0; - } - string fname=giac::remove_path(filename); - return tar_adddata(buffer,buffersizeptr,fname.c_str(),&data.front(),data.size(),exec); -} - -int tar_savefile(char * buffer,const char * filename){ - vector finfo=tar_fileinfo(buffer,0); - int s=finfo.size(); - if (s==0) return 0; - fileinfo_t info; - for (int i=0;i finfo=tar_fileinfo(buffer,0); - int s=finfo.size(); - if (s==0) return 0; - fileinfo_t info; - for (int i=0;i finfo=tar_fileinfo(buffer,0); - int s=finfo.size(); - for (int i=0;i=fl) return false; - int i=fl-el,j=0; - for (;j finfo=tar_fileinfo(buf,0); - int s=finfo.size(); - if (s==0) return 0; - int j=0; - for (int i=0;i finfo=tar_fileinfo(buffer,0); - int s=finfo.size(); - if (s==0) return 0; - fileinfo_t info; - for (int i=0;i & finfo,int cur,fileinfo_t & f){ - int s=finfo.size(); - for (int i=cur;i & finfo,size_t * tar_first_modif_offsetptr){ - vector oinfo=tar_fileinfo(buffer,0); - int s=finfo.size(); - if (oinfo.size()!=finfo.size()) - return 0; - for (int i=0;if.header_offset) - *tar_first_modif_offsetptr=f.header_offset; - // copy current sector - size_t sector_begin=(f.header_offset/buflen)*buflen,sector_end=sector_begin+buflen; - memcpy(buf64k,buffer+sector_begin,buflen); - // modify all records in this sector - for (;i=buflen){ - break; - } - char * headbuf=buf64k+sector_pos; - strcpy(headbuf,f.filename.c_str()); - if ( (f.mode/100 & 4) ==0) - headbuf[104] = '0'+((headbuf[104]-'0') &3); - else - headbuf[104] = '0'+((headbuf[104]-'0') |4); - tar_writechecksum(headbuf,0); - } - erase_sector(buffer+sector_begin); - WriteMemory((char *)buffer+sector_begin,buf64k,buflen); - } - return 1; -} - -int flash_emptytrash(const char * buffer,const vector & finfo,size_t * tar_first_modif_offsetptr){ - size_t flash_end=0x90800000LL-buflen,flash_begin=0x90200000LL; - int s=finfo.size(); - if (s==0) return 0; - // find 1st offset marked non readable - int i; // record position - fileinfo_t f,fnxt; - for (i=0;if.header_offset) - *tar_first_modif_offsetptr=f.header_offset; - // find current sector - size_t sector_begin=(f.header_offset/buflen)*buflen,sector_end=sector_begin+buflen; - memcpy(buf64k,buffer+sector_begin,buflen); - size_t sector_pos=f.header_offset-sector_begin; // in [0,buflen[ - int nwrite=0; - for (;i0){ - size_t nbytes=length; - if (length>buflen-sector_pos) - nbytes=buflen-sector_pos; - memcpy(buf64k+sector_pos,buffer+src,nbytes); - sector_pos += nbytes; - for (int j=sector_pos;jflash_end-flash_begin) - return 1; - sector_end += buflen; - sector_pos = 0; - memcpy(buf64k,buffer+sector_begin,buflen); - } - } - i=nxti; - } - if (sector_pos>0){ - erase_sector((char *)buffer+sector_begin); - for (int j=sector_pos;j finfo=tar_fileinfo(buffer,0); - return flash_emptytrash(buffer,finfo,tar_first_modif_offsetptr); -} - -char * file_gettar(const char * filename){ - FILE * f=fopen(filename,"rb"); - if (!f) return 0; - vector res; - while (1){ - char ch=fgetc(f); - if (feof(f)) - break; - res.push_back(ch); - } - fclose(f); - size_t size=res.size(); - size_t bufsize=65536*((size+65535)/65536); - char * buffer=(char *)malloc(bufsize); - memcpy(buffer,&res.front(),size); - return buffer; -} - -char * file_gettar_aligned(const char * filename,char * & freeptr){ - size_t size=numworks_maxtarsize; - size_t bufsize=buflen*((size+(buflen-1))/buflen); - char * buffer=(char *)malloc(bufsize+2*buflen); - freeptr=buffer; - // align buffer - buffer=(char *) ((((size_t) buffer)/buflen +1)*buflen); - FILE * f=fopen(filename,"rb"); - if (!f){ - for (size_t i=0;i res; - while (1){ - char ch=fgetc(f); - if (feof(f)) - break; - res.push_back(ch); - } - fclose(f); - size=res.size(); - if (size ls; - std::vector v; - while (ss >> arg) - { - ls.push_back(arg); - v.push_back(const_cast(ls.back().c_str())); - } - v.push_back(0); // need terminating null pointer - int res=dfu_main(v.size()-1,&v[0]); - return res; -#else -#ifdef WIN32 - string s(s_); -#ifdef __MINGW_H - if (giac::is_file_available("c:\\xcaswin\\dfu-util.exe")) - s="c:\\xcaswin\\"+s; - // otherwise dfu-util should be in the path -#else - if (giac::is_file_available("/cygdrive/c/xcas64/dfu-util.exe")) - s="/cygdrive/c/xcas64/"+s; - else - s="./"+s; -#endif - return system(s.c_str()); -#else // WIN32 -#ifdef __APPLE__ - string s(s_); - s="/Applications/usr/bin/"+s; - if (giac::is_file_available(s.c_str())) - return giac::system_no_deprecation(s.c_str()); - s=s_; s="/usr/bin/"+s; - return giac::system_no_deprecation(s.c_str()); -#else - return system(s_); -#endif -#endif // WIN32 -#endif -} - -bool dfu_get_scriptstore_addr(size_t & start,size_t & taille){ - unlink("__platf"); - if (dfu_exec("dfu-util -i0 -a0 -s 0x90000000:0x20 -U __platf")) - return false; - FILE * f=fopen("__platf","r"); - if (!f){ return false; } - unsigned char r[32]; - int i=fread(r,1,32,f); - fclose(f); - unlink("__platf"); - // check for f0 0d c0 de at offset 8, 9, a, b - bool externalinfo=r[8]==0xf0 && r[9]==0x0d && r[10]==0xc0 && r[11]==0xde; - if (externalinfo){ - if (dfu_exec("dfu-util -i0 -a0 -s 0x90010000:0x20 -U __platf")) - return false; - } - else { - if (dfu_exec("dfu-util -i0 -a0 -s 0x080001c4:0x20 -U __platf")) - return false; - } - f=fopen("__platf","r"); - if (!f){ return false; } - i=fread(r,1,32,f); - if (externalinfo){ - start=((r[15]*256U+r[14])*256+r[13])*256+r[12]; - taille=((r[19]*256U+r[18])*256+r[17])*256+r[16]; - } - else { - start=((r[23]*256U+r[22])*256+r[21])*256+r[20]; - taille=((r[27]*256U+r[26])*256+r[25])*256+r[24]; - } - // taille=(taille/32768)*32768; // do not care of end of scriptstore - fclose(f); - return i==32; -} - -bool dfu_get_scriptstore(const char * fname){ - unlink(fname); - size_t start,taille; - if (!dfu_get_scriptstore_addr(start,taille)) return false; - string s="dfu-util -U "+string(fname)+" -i0 -a0 -s "+ giac::print_INT_(start)+":"+giac::print_INT_(taille)+":force"; - return !dfu_exec(s.c_str()); -} - -bool dfu_send_scriptstore(const char * fname){ - size_t start,taille; - if (!dfu_get_scriptstore_addr(start,taille)) return false; - string s="dfu-util -D "+string(fname)+" -i0 -a0 -s "+ giac::print_INT_(start)+":"+giac::print_INT_(taille)+":force"; - return !dfu_exec(s.c_str()); -} - -bool dfu_send_rescue(const char * fname){ - string s=string("dfu-util -i0 -a0 -s 0x20030000:force:leave -D ")+ fname; - return !dfu_exec(s.c_str()); -} - -bool dfu_send_firmware(const char * fname){ - string s=string("dfu-util -i0 -a0 -D ")+ fname; - return !dfu_exec(s.c_str()); -} - -bool dfu_send_apps(const char * fname){ - string s=string("dfu-util -i 0 -a 0 -s 0x90200000 -D ")+ fname; - return !dfu_exec(s.c_str()); -} - -bool dfu_get_epsilon_internal(const char * fname){ - unlink(fname); - string s=string("dfu-util -i 0 -a 0 -s 0x08000000:0x8000 -U ")+ fname; - return !dfu_exec(s.c_str()); -} - -bool dfu_get_epsilon(const char * fname){ - unlink(fname); - string s=string("dfu-util -i 0 -a 0 -s 0x90000000:0x120000 -U ")+ fname; - return !dfu_exec(s.c_str()); -} - -// check that we can really read/write on the Numworks at 0x90120000 -// and get the same -bool dfu_check_epsilon2(const char * fname){ - FILE * f=fopen(fname,"wb"); - int n=0xe0000; - char * ptr=(char *) malloc(n); - srand(time(NULL)); - int i; - for (i=0;i oldv=tar_fileinfo(oldbuffer,0),v=tar_fileinfo(buffer,0); - // add files from oldbuffer that are not in buffer - for (int i=0;i v=tar_fileinfo(buffer,buffersize); - if (v.empty()) - return false; - fileinfo_t info=v[v.size()-1]; - size_t end=info.header_offset+tar_filesize(info.size)+1024; - if (end>numworks_maxtarsize || end<=tar_first_modif_offset) return false; - for (size_t i=end-1024;i init - // tar(buf) -> list files - // tar(buf,0,"filename") -> remove filename - // tar(buf,1,"filename") -> add filename - // tar(buf,2,"filename") -> save filename - // tar(buf,"file.tar") -> write tar - // purge(buf) -> free buffer - gen _tar(const gen & g_,GIAC_CONTEXT){ - gen g(eval(g_,eval_level(contextptr),contextptr)); - if (g.type==_STRNG){ - char * buf=file_gettar(g._STRNGptr->c_str()); - if (!buf) return 0; - tar_first_modified_offset=0; - return gen((void *)buf,_BUFFER_POINTER); - } - if (g.type==_POINTER_ && g.subtype==_BUFFER_POINTER){ - char * buf= (char *) g._POINTER_val; - if (!buf) return 0; - vector v=tar_fileinfo(buf,0); - vecteur res1,res2,res3,res4; - for (int i=0;i=2 && v.front().type==_POINTER_){ - char * buf= (char *) v[0]._POINTER_val; - if (!buf) return 0; - if (s==2 && v[1].type==_STRNG) - return file_savetar(v[1]._STRNGptr->c_str(),buf,0); -#if !defined KHICAS && !defined USE_GMP_REPLACEMENTS && !defined GIAC_HAS_STO_38 - if (s==2 && v[1].type==_INT_){ - if (v[1].val==1) - return numworks_sendtar(buf,0,tar_first_modified_offset); - } -#endif - if (s==3 && v[1].type==_INT_ && v[2].type==_STRNG){ - int val=v[1].val; - if (val==0) - return tar_removefile(buf,v[2]._STRNGptr->c_str(),0); - if (val==1 && tar_addfile(buf,v[2]._STRNGptr->c_str(),0)){ - gen res=gen((void *)buf,_BUFFER_POINTER); - if (g_.type==_VECT && !g_._VECTptr->empty()) - return sto(res,g_._VECTptr->front(),contextptr); - return res; - } - if (val==2) - return tar_savefile(buf,v[2]._STRNGptr->c_str()); - } - } - } - return gensizeerr(contextptr); - } - static const char _tar_s []="tar"; - static define_unary_function_eval_quoted (__tar,&_tar,_tar_s); - define_unary_function_ptr5( at_tar ,alias_at_tar,&__tar,_QUOTE_ARGUMENTS,true); - - std::string dos2unix(const std::string & src){ - std::string unixsrc; // convert newlines to Unix - for (int i=0;i+1=nwstoresize1) - return false; - return true; - } - - bool map2scriptstore(const nws_map & m,const char * fname){ - unsigned char buf[nwstoresize1]; - for (int i=0;ifirst; - unsigned l1=s.size(); - unsigned l2=it->second.data.size(); - short unsigned L=2+l1+1+1+l2+1; - total += L; - if (total>=nwstoresize1) - return false; - *ptr=L % 256; ++ptr; *ptr=L/256; ++ptr; - memcpy(ptr,s.c_str(),l1+1); ptr += l1+1; - *ptr=it->second.type; ++ptr; - memcpy(ptr,&it->second.data[0],l2); ptr+=l2; - *ptr=0; ++ptr; - } - FILE * f=fopen(fname,"wb"); - if (!f) - return false; - fwrite(buf,1,nwstoresize1,f); - fclose(f); - return true; - } -#endif - - -#if !defined USE_GMP_REPLACEMENTS && !defined GIAC_HAS_STO_38 - - /********************************************************************* - * Filename: sha256.c/.h - * Author: Brad Conte (brad AT bradconte.com) - * Copyright: - * Disclaimer: This code is presented "as is" without any guarantees. - * Details: Implementation of the SHA-256 hashing algorithm. - SHA-256 is one of the three algorithms in the SHA2 - specification. The others, SHA-384 and SHA-512, are not - offered in this implementation. - Algorithm specification can be found here: - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf - This implementation uses little endian byte order. - *********************************************************************/ -#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest - - /**************************** DATA TYPES ****************************/ - typedef unsigned char BYTE; // 8-bit byte - typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines - - typedef struct { - BYTE data[64]; - WORD datalen; - unsigned long long bitlen; - WORD state[8]; - } SHA256_CTX; - - - /****************************** MACROS ******************************/ -#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) -#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) - -#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) -#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) -#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) -#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) -#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) -#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) - - /**************************** VARIABLES *****************************/ - static const WORD k[64] = { - 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, - 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, - 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, - 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, - 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, - 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, - 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, - 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 - }; - - /*********************** FUNCTION DEFINITIONS ***********************/ - void giac_sha256_transform(SHA256_CTX *ctx, const BYTE data[]) - { - WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; - - for (i = 0, j = 0; i < 16; ++i, j += 4) - m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); - for ( ; i < 64; ++i) - m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; - - a = ctx->state[0]; - b = ctx->state[1]; - c = ctx->state[2]; - d = ctx->state[3]; - e = ctx->state[4]; - f = ctx->state[5]; - g = ctx->state[6]; - h = ctx->state[7]; - - for (i = 0; i < 64; ++i) { - t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; - t2 = EP0(a) + MAJ(a,b,c); - h = g; - g = f; - f = e; - e = d + t1; - d = c; - c = b; - b = a; - a = t1 + t2; - } - - ctx->state[0] += a; - ctx->state[1] += b; - ctx->state[2] += c; - ctx->state[3] += d; - ctx->state[4] += e; - ctx->state[5] += f; - ctx->state[6] += g; - ctx->state[7] += h; - } - - void giac_sha256_init(SHA256_CTX *ctx) - { - ctx->datalen = 0; - ctx->bitlen = 0; - ctx->state[0] = 0x6a09e667; - ctx->state[1] = 0xbb67ae85; - ctx->state[2] = 0x3c6ef372; - ctx->state[3] = 0xa54ff53a; - ctx->state[4] = 0x510e527f; - ctx->state[5] = 0x9b05688c; - ctx->state[6] = 0x1f83d9ab; - ctx->state[7] = 0x5be0cd19; - } - - void giac_sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len) - { - WORD i; - - for (i = 0; i < len; ++i) { - ctx->data[ctx->datalen] = data[i]; - ctx->datalen++; - if (ctx->datalen == 64) { - giac_sha256_transform(ctx, ctx->data); - ctx->bitlen += 512; - ctx->datalen = 0; - } - } - } - - void giac_sha256_final(SHA256_CTX *ctx, BYTE hash[]) - { - WORD i; - - i = ctx->datalen; - - // Pad whatever data is left in the buffer. - if (ctx->datalen < 56) { - ctx->data[i++] = 0x80; - while (i < 56) - ctx->data[i++] = 0x00; - } - else { - ctx->data[i++] = 0x80; - while (i < 64) - ctx->data[i++] = 0x00; - giac_sha256_transform(ctx, ctx->data); - memset(ctx->data, 0, 56); - } - - // Append to the padding the total message's length in bits and transform. - ctx->bitlen += ctx->datalen * 8; - ctx->data[63] = ctx->bitlen; - ctx->data[62] = ctx->bitlen >> 8; - ctx->data[61] = ctx->bitlen >> 16; - ctx->data[60] = ctx->bitlen >> 24; - ctx->data[59] = ctx->bitlen >> 32; - ctx->data[58] = ctx->bitlen >> 40; - ctx->data[57] = ctx->bitlen >> 48; - ctx->data[56] = ctx->bitlen >> 56; - giac_sha256_transform(ctx, ctx->data); - - // Since this implementation uses little endian byte ordering and SHA uses big endian, - // reverse all the bytes when copying the final state to the output hash. - for (i = 0; i < 4; ++i) { - hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; - hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; - hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; - hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; - hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; - hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; - hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; - hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; - } - } - /* END OF SHA256 */ - - -#endif - -#if !defined KHICAS && !defined USE_GMP_REPLACEMENTS && !defined GIAC_HAS_STO_38 - const unsigned char rsa_n_tab[]= - { - 0xf2,0x0e,0xd4,0x9d,0x44,0x04,0xc4,0xc8,0x6a,0x5b,0xc6,0x9a,0xd6,0xdf, - 0x9c,0xf5,0x56,0xf2,0x0d,0xad,0x6c,0x34,0xb4,0x48,0xf7,0xa7,0xa8,0x27,0xa0, - 0xc8,0xbe,0x36,0xb1,0xc0,0x95,0xf8,0xc2,0x72,0xfb,0x78,0x0f,0x3f,0x15,0x22, - 0xaf,0x51,0x96,0xe3,0xdc,0x39,0xb4,0xc6,0x40,0x6d,0x58,0x56,0x1f,0xad,0x55, - 0x55,0x08,0xf1,0xde,0x5a,0xbc,0xd3,0xcc,0x16,0x3d,0x33,0xee,0x83,0x3f,0x32, - 0xa7,0xa7,0xb8,0x95,0x2f,0x35,0xeb,0xf6,0x32,0x4d,0x22,0xd9,0x60,0xb7,0x5e, - 0xbd,0xea,0xa5,0xcb,0x9c,0x69,0xeb,0xfd,0x9f,0x2b,0x5f,0x3d,0x38,0x5a,0xe1, - 0x2b,0x63,0xf8,0x92,0x35,0x91,0xea,0x77,0x07,0xcc,0x4b,0x7a,0xbc,0xe0,0xa0, - 0x8b,0x82,0x98,0xa2,0x87,0x10,0x2c,0xe2,0x23,0x53,0x2f,0x70,0x03,0xec,0x2d, - 0x22,0x34,0x72,0x57,0x4d,0x24,0x2e,0x97,0xc9,0xfb,0x23,0xb0,0x05,0xff,0x87, - 0x6e,0xbf,0x94,0x2d,0xf0,0x36,0xed,0xd7,0x9a,0xac,0x0c,0x21,0x94,0xa2,0x75, - 0xfc,0x39,0x9b,0xba,0xf2,0xc6,0xc9,0x34,0xa0,0xb2,0x66,0x5a,0xcc,0xc9,0x5c, - 0xc7,0xdb,0xce,0xfb,0x3a,0x10,0xee,0xc1,0x82,0x9a,0x43,0xef,0xed,0x87,0xbd, - 0x6c,0xe4,0xc1,0x36,0xd0,0x0a,0x85,0x6e,0xca,0xcd,0x13,0x29,0x65,0xb5,0xd4, - 0x13,0x4a,0x14,0xaa,0x65,0xac,0x0e,0x6f,0x19,0xb0,0x62,0x47,0x65,0x0e,0x40, - 0x82,0x37,0xd6,0xf0,0x17,0x48,0xaa,0x8c,0x7b,0xc4,0x5e,0x4a,0x72,0x26,0xa6, - 0x08,0x2e,0xff,0x2d,0x9d,0x0e,0x2e,0x19,0xe9,0x6a,0x4c,0x7c,0x3e,0xe9,0xbc, - 0x78,0x95 - }; - - int rsa_check(const char * sigfilename,int maxkeys,BYTE hash[][SHA256_BLOCK_SIZE],int * tailles,vector & fnames){ - gen rsa_n(tabunsignedchar2gen(rsa_n_tab,sizeof(rsa_n_tab))); - gen N=pow(gen(2),768),q; - // read by blocks of 2048 bits=256 bytes - FILE * f=fopen(sigfilename,"r"); - if (!f) - return 0; - char firmwarename[256]; - int i=0; - for (;i='0' && c<='9') - c=c-'0'; - else { - if (c>='a' && c<='f') - c=10+c-'a'; - else { - fclose(f); - return 0; - } - } - unsigned char d=fgetc(f); - if (feof(f)){ - fclose(f); - return 0; - } - if (d==' ' || d=='\n'){ - key = key/16+int(c); - break; - } - if (d>='0' && d<='9') - d=d-'0'; - else { - if (d>='a' && d<='f') - d=10+d-'a'; - else { - fclose(f); - return 0; - } - } - key += int(c)*16+int(d); - } - // public key decrypt and keep only 768 low bits - key=powmod(key,65537,rsa_n); - key=irem(key,N,q); - if (q!=12345){ - fclose(f); - return 0; - } - // check that key is valid and write in hash[i] - for (int j=0;j<32;++j){ - // divide 3 times by 256, remainder must be in '0'..'9' - int o=0; - int tab[]={1,10,100}; - for (int k=0;k<3;++k){ - gen r=irem(key,256,q); - key=q; - if (r.type!=_INT_ || r.val>'9' || r.val<'0'){ - fclose(f); - return 0; - } - o+=(r.val-'0')*tab[k]; - } - if (o<0 || o>255){ - fclose(f); - return 0; - } - if (i fnames; - int nkeys=rsa_check(sigfilename,MAXKEYS,hash,tailles,fnames); - if (nkeys==0) return false; - BYTE buf[SHA256_BLOCK_SIZE]; - SHA256_CTX ctx; - string text; - FILE * f=fopen(filename,"rb"); - if (!f) - return false; - int taille=0; - for (;;++taille){ - unsigned char c=fgetc(f); - if (feof(f)) - break; - text += c; - } - fclose(f); - unsigned char * ptr=(unsigned char *)text.c_str(); - for (int i=0;i0){ - ++caseval_n; - if (caseval_n >=caseval_mod){ - caseval_n=0; - caseval_current=time(0); -#if defined(EMCC) || defined(EMCC2) - if (difftime(caseval_current,caseval_begin)>caseval_maxtime) -#else - if (caseval_current>caseval_maxtime+caseval_begin) -#endif - { - CERR << "Timeout" << '\n'; ctrl_c=true; interrupted=true; - caseval_begin=caseval_current; - } - } - } -#endif // NSPIRE - } -#endif // POCKETCAS -#endif // TIMEOUT - -#if defined KHICAS - void usleep(int t){ - os_wait_1ms(t/1000); - } -#else -#ifdef NSPIRE_NEWLIB - void usleep(int t){ - msleep(t/1000); - } -#endif - -#endif - -#if defined VISUALC || defined BESTA_OS -#if !defined FREERTOS && !defined HAVE_LIBMPIR - int R_OK=4; -#endif - int access(const char *path, int mode ){ - // return _access(path, mode ); - return 0; - } -#ifdef RTOS_THREADX -extern "C" void Sleep(unsigned int miliSecond); -#endif - - void usleep(int t){ -#ifdef RTOS_THREADX - Sleep(t/1000); -#else - Sleep(int(t/1000.+.5)); -#endif - } -#endif - -#ifdef __APPLE__ - int PARENTHESIS_NWAIT=10; -#else - int PARENTHESIS_NWAIT=100; -#endif - - // FIXME: threads allowed curently disabled - // otherwise fermat_gcd_mod_2var crashes at puccini - bool threads_allowed=true,mpzclass_allowed=true; -#ifdef HAVE_LIBPTHREAD - pthread_mutex_t interactive_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif - - std::vector * & vector_aide_ptr (){ - static std::vector * ans = 0; - if (!ans) ans=new std::vector; - return ans; - } - std::vector * & vector_completions_ptr (){ - static std::vector * ans = 0; - if (!ans) ans=new std::vector; - return ans; - } -#ifdef NSPIRE_NEWLIB - const context * context0=new context; -#else - const context * context0=0; -#endif - // Global variable when context is 0 - void (*fl_widget_delete_function)(void *) =0; -#ifndef NSPIRE - ostream & (*fl_widget_archive_function)(ostream &,void *)=0; - gen (*fl_widget_unarchive_function)(istream &)=0; -#endif - gen (*fl_widget_updatepict_function)(const gen & g)=0; - std::string (*fl_widget_texprint_function)(void * ptr)=0; - - const char * _last_evaled_function_name_=0; - const char * & last_evaled_function_name(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_last_evaled_function_name_; - else - return _last_evaled_function_name_; - } - - const char * _currently_scanned=0; - const char * & currently_scanned(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_currently_scanned_; - else - return _currently_scanned; - } - - const gen * _last_evaled_argptr_=0; - const gen * & last_evaled_argptr(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_last_evaled_argptr_; - else - return _last_evaled_argptr_; - } - - static int _language_=0; - int & language(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_language_; - else - return _language_; - } - void language(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_language_=b; -#if !defined(EMCC) && !defined(EMCC2) - else -#endif - _language_=b; - } - - static int _max_sum_sqrt_=3; - int & max_sum_sqrt(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_max_sum_sqrt_; - else - return _max_sum_sqrt_; - } - void max_sum_sqrt(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_max_sum_sqrt_=b; - else - _max_sum_sqrt_=b; - } - -#ifdef GIAC_HAS_STO_38 // Prime sum(x^2,x,0,100000) crash on hardware - static int _max_sum_add_=10000; -#else - static int _max_sum_add_=100000; -#endif - int & max_sum_add(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_max_sum_add_; - else - return _max_sum_add_; - } - - static int _default_color_=FL_BLACK; - int & default_color(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_default_color_; - else - return _default_color_; - } - void default_color(int c,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr) - contextptr->globalptr->_default_color_=c; - else - _default_color_=c; - } - - static void * _evaled_table_=0; - void * & evaled_table(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_evaled_table_; - else - return _evaled_table_; - } - - static void * _extra_ptr_=0; - void * & extra_ptr(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_extra_ptr_; - else - return _extra_ptr_; - } - - static int _spread_Row_=0; - int & spread_Row(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_spread_Row_; - else - return _spread_Row_; - } - void spread_Row(int c,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr) - contextptr->globalptr->_spread_Row_=c; - else - _spread_Row_=c; - } - - static int _spread_Col_=0; - int & spread_Col(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_spread_Col_; - else - return _spread_Col_; - } - void spread_Col(int c,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr) - contextptr->globalptr->_spread_Col_=c; - else - _spread_Col_=c; - } - - static int _printcell_current_row_=0; - int & printcell_current_row(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_printcell_current_row_; - else - return _printcell_current_row_; - } - void printcell_current_row(int c,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr) - contextptr->globalptr->_printcell_current_row_=c; - else - _printcell_current_row_=c; - } - - static int _printcell_current_col_=0; - int & printcell_current_col(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_printcell_current_col_; - else - return _printcell_current_col_; - } - void printcell_current_col(int c,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr) - contextptr->globalptr->_printcell_current_col_=c; - else - _printcell_current_col_=c; - } - - static double _total_time_=0.0; - double & total_time(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_total_time_; - else - return _total_time_; - } - -#if 1 - static double _epsilon_=1e-12; -#else -#ifdef __SGI_CPP_LIMITS - static double _epsilon_=100*numeric_limits::epsilon(); -#else - static double _epsilon_=1e-12; -#endif -#endif - double & epsilon(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_epsilon_; - else - return _epsilon_; - } - void epsilon(double c,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr) - contextptr->globalptr->_epsilon_=c; - else - _epsilon_=c; - } - - static double _proba_epsilon_=1e-15; - double & proba_epsilon(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_proba_epsilon_; - else - return _proba_epsilon_; - } - - static bool _expand_re_im_=true; - bool & expand_re_im(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_expand_re_im_; - else - return _expand_re_im_; - } - void expand_re_im(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_expand_re_im_=b; - else - _expand_re_im_=b; - } - - static int _scientific_format_=0; - int & scientific_format(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_scientific_format_; - else - return _scientific_format_; - } - void scientific_format(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_scientific_format_=b; - else - _scientific_format_=b; - } - - static int _decimal_digits_=12; - - int & decimal_digits(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_decimal_digits_; - else - return _decimal_digits_; - } - void decimal_digits(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_decimal_digits_=b; - else - _decimal_digits_=b; - } - - static int _minchar_for_quote_as_string_=1; - - int & minchar_for_quote_as_string(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_minchar_for_quote_as_string_; - else - return _minchar_for_quote_as_string_; - } - void minchar_for_quote_as_string(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_minchar_for_quote_as_string_=b; - else - _minchar_for_quote_as_string_=b; - } - - static int _xcas_mode_=0; - int & xcas_mode(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_xcas_mode_; - else - return _xcas_mode_; - } - void xcas_mode(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_xcas_mode_=b; - else - _xcas_mode_=b; - } - - - static int _integer_format_=0; - int & integer_format(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_integer_format_; - else - return _integer_format_; - } - void integer_format(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_integer_format_=b; - else - _integer_format_=b; - } - static int _latex_format_=0; - int & latex_format(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_latex_format_; - else - return _latex_format_; - } -#ifdef BCD - static u32 _bcd_decpoint_='.'|('E'<<16)|(' '<<24); - u32 & bcd_decpoint(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_bcd_decpoint_; - else - return _bcd_decpoint_; - } - - static u32 _bcd_mantissa_=12+(15<<8); - u32 & bcd_mantissa(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_bcd_mantissa_; - else - return _bcd_mantissa_; - } - - static u32 _bcd_flags_=0; - u32 & bcd_flags(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_bcd_flags_; - else - return _bcd_flags_; - } - - static bool _bcd_printdouble_=false; - bool & bcd_printdouble(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_bcd_printdouble_; - else - return _bcd_printdouble_; - } - -#endif - - static bool _integer_mode_=true; - bool & integer_mode(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_integer_mode_; - else - return _integer_mode_; - } - - void integer_mode(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_integer_mode_=b; - else - _integer_mode_=b; - } - - bool python_color=false; -#ifdef NSPIRE_NEWLIB - bool os_shell=false; -#else - bool os_shell=true; -#endif - -#ifdef KHICAS - static int _python_compat_=true; -#else - static int _python_compat_=false; -#endif - int & python_compat(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_python_compat_; - else - return _python_compat_; - } - - void python_compat(int b,GIAC_CONTEXT){ - python_color=b; //cout << "python_color " << b << '\n'; - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_python_compat_=b; - else - _python_compat_=b; - } - - static bool _complex_mode_=false; - bool & complex_mode(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_complex_mode_; - else - return _complex_mode_; - } - - void complex_mode(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_complex_mode_=b; - else - _complex_mode_=b; - } - - static bool _escape_real_=true; - bool & escape_real(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_escape_real_; - else - return _escape_real_; - } - - void escape_real(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_escape_real_=b; - else - _escape_real_=b; - } - - static bool _do_lnabs_=true; - bool & do_lnabs(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_do_lnabs_; - else - return _do_lnabs_; - } - - void do_lnabs(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_do_lnabs_=b; - else - _do_lnabs_=b; - } - - static bool _eval_abs_=true; - bool & eval_abs(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_eval_abs_; - else - return _eval_abs_; - } - - void eval_abs(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_eval_abs_=b; - else - _eval_abs_=b; - } - - static bool _eval_equaltosto_=true; - bool & eval_equaltosto(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_eval_equaltosto_; - else - return _eval_equaltosto_; - } - - void eval_equaltosto(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_eval_equaltosto_=b; - else - _eval_equaltosto_=b; - } - - static bool _all_trig_sol_=false; - bool & all_trig_sol(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_all_trig_sol_; - else - return _all_trig_sol_; - } - - void all_trig_sol(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_all_trig_sol_=b; - else - _all_trig_sol_=b; - } - - static bool _try_parse_i_=true; - bool & try_parse_i(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_try_parse_i_; - else - return _try_parse_i_; - } - - void try_parse_i(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_try_parse_i_=b; - else - _try_parse_i_=b; - } - - static bool _specialtexprint_double_=false; - bool & specialtexprint_double(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_specialtexprint_double_; - else - return _specialtexprint_double_; - } - - void specialtexprint_double(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_specialtexprint_double_=b; - else - _specialtexprint_double_=b; - } - - static bool _atan_tan_no_floor_=false; - bool & atan_tan_no_floor(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_atan_tan_no_floor_; - else - return _atan_tan_no_floor_; - } - - void atan_tan_no_floor(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_atan_tan_no_floor_=b; - else - _atan_tan_no_floor_=b; - } - - static bool _keep_acosh_asinh_=false; - bool & keep_acosh_asinh(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_keep_acosh_asinh_; - else - return _keep_acosh_asinh_; - } - - void keep_acosh_asinh(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_keep_acosh_asinh_=b; - else - _keep_acosh_asinh_=b; - } - - static bool _keep_algext_=false; - bool & keep_algext(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_keep_algext_; - else - return _keep_algext_; - } - - void keep_algext(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_keep_algext_=b; - else - _keep_algext_=b; - } - - static bool _auto_assume_=false; - bool & auto_assume(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_auto_assume_; - else - return _auto_assume_; - } - - void auto_assume(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_auto_assume_=b; - else - _auto_assume_=b; - } - - static bool _parse_e_=false; - bool & parse_e(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_parse_e_; - else - return _parse_e_; - } - - void parse_e(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_parse_e_=b; - else - _parse_e_=b; - } - - static bool _convert_rootof_=true; - bool & convert_rootof(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_convert_rootof_; - else - return _convert_rootof_; - } - - void convert_rootof(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_convert_rootof_=b; - else - _convert_rootof_=b; - } - - static bool _lexer_close_parenthesis_=true; - bool & lexer_close_parenthesis(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_lexer_close_parenthesis_; - else - return _lexer_close_parenthesis_; - } - - void lexer_close_parenthesis(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_lexer_close_parenthesis_=b; - else - _lexer_close_parenthesis_=b; - } - - static bool _rpn_mode_=false; - bool & rpn_mode(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_rpn_mode_; - else - return _rpn_mode_; - } - - void rpn_mode(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_rpn_mode_=b; - else - _rpn_mode_=b; - } - -#ifdef __MINGW_H - static bool _ntl_on_=false; -#else - static bool _ntl_on_=true; -#endif - - bool & ntl_on(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_ntl_on_; - else - return _ntl_on_; - } - - void ntl_on(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_ntl_on_=b; - else - _ntl_on_=b; - } - - static bool _complex_variables_=false; - bool & complex_variables(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_complex_variables_; - else - return _complex_variables_; - } - - void complex_variables(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_complex_variables_=b; - else - _complex_variables_=b; - } - - static bool _increasing_power_=false; - bool & increasing_power(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_increasing_power_; - else - return _increasing_power_; - } - - void increasing_power(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_increasing_power_=b; - else - _increasing_power_=b; - } - - static vecteur & _history_in_(){ - static vecteur * ans = 0; - if (ans) - ans=new vecteur; - return *ans; - } - vecteur & history_in(GIAC_CONTEXT){ - if (contextptr) - return *contextptr->history_in_ptr; - else - return _history_in_(); - } - - static vecteur & _history_out_(){ - static vecteur * ans = 0; - if (!ans) - ans=new vecteur; - return *ans; - } - vecteur & history_out(GIAC_CONTEXT){ - if (contextptr) - return *contextptr->history_out_ptr; - else - return _history_out_(); - } - - static vecteur & _history_plot_(){ - static vecteur * ans = 0; - if (!ans) - ans=new vecteur; - return *ans; - } - vecteur & history_plot(GIAC_CONTEXT){ - if (contextptr) - return *contextptr->history_plot_ptr; - else - return _history_plot_(); - } - - static bool _approx_mode_=false; - bool & approx_mode(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_approx_mode_; - else - return _approx_mode_; - } - - void approx_mode(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_approx_mode_=b; - else - _approx_mode_=b; - } - - static char _series_variable_name_='h'; - char & series_variable_name(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_series_variable_name_; - else - return _series_variable_name_; - } - - void series_variable_name(char b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_series_variable_name_=b; - else - _series_variable_name_=b; - } - - static unsigned short _series_default_order_=5; - unsigned short & series_default_order(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_series_default_order_; - else - return _series_default_order_; - } - - void series_default_order(unsigned short b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_series_default_order_=b; - else - _series_default_order_=b; - } - - static int _angle_mode_=0; - bool angle_radian(GIAC_CONTEXT) - { - if(contextptr && contextptr->globalptr) - return contextptr->globalptr->_angle_mode_ == 0; - else - return _angle_mode_ == 0; - } - - void angle_radian(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_angle_mode_=(b?0:1); - else - _angle_mode_=(b?0:1); - } - - bool angle_degree(GIAC_CONTEXT) - { - if(contextptr && contextptr->globalptr) - return contextptr->globalptr->_angle_mode_ == 1; - else - return _angle_mode_ == 1; - } - - int get_mode_set_radian(GIAC_CONTEXT) - { - int mode; - if(contextptr && contextptr->globalptr) - { - mode = contextptr->globalptr->_angle_mode_; - contextptr->globalptr->_angle_mode_ = 0; - } - else - { - mode = _angle_mode_; - _angle_mode_ = 0; - } - return mode; - } - - void angle_mode(int b, GIAC_CONTEXT) - { - if(contextptr && contextptr->globalptr){ -#ifdef POCKETCAS - _angle_mode_ = b; -#endif - contextptr->globalptr->_angle_mode_ = b; - } - else - _angle_mode_ = b; - } - - int & angle_mode(GIAC_CONTEXT) - { - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_angle_mode_; - else - return _angle_mode_; - } - - static bool _show_point_=true; - bool & show_point(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_show_point_; - else - return _show_point_; - } - - void show_point(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_show_point_=b; - else - _show_point_=b; - } - - static int _show_axes_=1; - int & show_axes(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_show_axes_; - else - return _show_axes_; - } - - void show_axes(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_show_axes_=b; - else - _show_axes_=b; - } - - static bool _io_graph_=false; - // DO NOT SET TO true WITH non-zero contexts or fix symadd when points are added - bool & io_graph(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_io_graph_; - else - return _io_graph_; - } - - void io_graph(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_io_graph_=b; - else - _io_graph_=b; - } - - static bool _variables_are_files_=false; - bool & variables_are_files(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_variables_are_files_; - else - return _variables_are_files_; - } - - void variables_are_files(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_variables_are_files_=b; - else - _variables_are_files_=b; - } - - static int _bounded_function_no_=0; - int & bounded_function_no(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_bounded_function_no_; - else - return _bounded_function_no_; - } - - void bounded_function_no(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_bounded_function_no_=b; - else - _bounded_function_no_=b; - } - - static int _series_flags_=0x3; - int & series_flags(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_series_flags_; - else - return _series_flags_; - } - - void series_flags(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_series_flags_=b; - else - _series_flags_=b; - } - - static int _step_infolevel_=0; - int & step_infolevel(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_step_infolevel_; - else - return _step_infolevel_; - } - - void step_infolevel(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_step_infolevel_=b; - else - _step_infolevel_=b; - } - - static bool _local_eval_=true; - bool & local_eval(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_local_eval_; - else - return _local_eval_; - } - - void local_eval(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_local_eval_=b; - else - _local_eval_=b; - } - - static bool _withsqrt_=true; - bool & withsqrt(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_withsqrt_; - else - return _withsqrt_; - } - - void withsqrt(bool b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_withsqrt_=b; - else - _withsqrt_=b; - } - -#ifdef WITH_MYOSTREAM - my_ostream my_cerr (&CERR); - static my_ostream * _logptr_= &my_cerr; - - my_ostream * logptr(GIAC_CONTEXT){ - my_ostream * res; - if (contextptr && contextptr->globalptr ) - res=contextptr->globalptr->_logptr_; - else - res= _logptr_; - return res?res:&my_cerr; - } -#else -#ifdef NSPIRE - static nio::console * _logptr_=&CERR; - nio::console * logptr(GIAC_CONTEXT){ - return &CERR; - } -#else -#ifdef FXCG - static ostream * _logptr_=0; -#else -#ifdef KHICAS - stdostream os_cerr; - static my_ostream * _logptr_=&os_cerr; -#else - static my_ostream * _logptr_=&CERR; -#endif -#endif - my_ostream * logptr(GIAC_CONTEXT){ - my_ostream * res; - if (contextptr && contextptr->globalptr ) - res=contextptr->globalptr->_logptr_; - else - res= _logptr_; -#if defined(EMCC) || defined(EMCC2) - return res?res:&COUT; -#else -#ifdef FXCG - return 0; -#else -#ifdef KHICAS - return res?res:&os_cerr; -#else - return res?res:&CERR; -#endif -#endif -#endif - } -#endif -#endif - - void logptr(my_ostream * b,GIAC_CONTEXT){ -#ifdef NSPIRE -#else - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_logptr_=b; - else - _logptr_=b; -#endif - } - - thread_param::thread_param(): _kill_thread(false), thread_eval_status(-1), v(6) -#ifdef HAVE_LIBPTHREAD -#ifdef __MINGW_H - ,eval_thread(),stackaddr(0) -#else - ,eval_thread(0),stackaddr(0) -#endif -#endif - { - } - - thread_param * & context0_thread_param_ptr(){ - static thread_param * ans=0; - if (!ans) - ans=new thread_param(); - return ans; - } - -#if 0 - static thread_param & context0_thread_param(){ - return *context0_thread_param_ptr(); - } -#endif - - thread_param * thread_param_ptr(const context * contextptr){ - return (contextptr && contextptr->globalptr)?contextptr->globalptr->_thread_param_ptr:context0_thread_param_ptr(); - } - - bool kill_thread(GIAC_CONTEXT){ - thread_param * ptr= (contextptr && contextptr->globalptr )?contextptr->globalptr->_thread_param_ptr:0; - return ptr?ptr->_kill_thread:context0_thread_param_ptr()->_kill_thread; - } - - void kill_thread(bool b,GIAC_CONTEXT){ - thread_param * ptr= (contextptr && contextptr->globalptr )?contextptr->globalptr->_thread_param_ptr:0; - if (!ptr) - ptr=context0_thread_param_ptr(); - ptr->_kill_thread=b; - } - - -#ifdef HAVE_LIBPTHREAD - pthread_mutex_t _mutexptr = PTHREAD_MUTEX_INITIALIZER,_mutex_eval_status= PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_t * mutexptr(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr) - return contextptr->globalptr->_mutexptr; - return &_mutexptr; - } - - bool is_context_busy(GIAC_CONTEXT){ - int concurrent=pthread_mutex_trylock(mutexptr(contextptr)); - bool res=concurrent==EBUSY; - if (!res) - pthread_mutex_unlock(mutexptr(contextptr)); - return res; - } - - int thread_eval_status(GIAC_CONTEXT){ - int res; - if (contextptr && contextptr->globalptr){ - pthread_mutex_lock(contextptr->globalptr->_mutex_eval_status_ptr); - res=contextptr->globalptr->_thread_param_ptr->thread_eval_status; - pthread_mutex_unlock(contextptr->globalptr->_mutex_eval_status_ptr); - } - else { - pthread_mutex_lock(&_mutex_eval_status); - res=context0_thread_param_ptr()->thread_eval_status; - pthread_mutex_unlock(&_mutex_eval_status); - } - return res; - } - - void thread_eval_status(int val,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr){ - pthread_mutex_lock(contextptr->globalptr->_mutex_eval_status_ptr); - contextptr->globalptr->_thread_param_ptr->thread_eval_status=val; - pthread_mutex_unlock(contextptr->globalptr->_mutex_eval_status_ptr); - } - else { - pthread_mutex_lock(&_mutex_eval_status); - context0_thread_param_ptr()->thread_eval_status=val; - pthread_mutex_unlock(&_mutex_eval_status); - } - } - -#else - bool is_context_busy(GIAC_CONTEXT){ - return false; - } - - int thread_eval_status(GIAC_CONTEXT){ - return -1; - } - - void thread_eval_status(int val,GIAC_CONTEXT){ - } - -#endif - - static int _eval_level=DEFAULT_EVAL_LEVEL; - int & eval_level(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_eval_level; - else - return _eval_level; - } - - void eval_level(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_eval_level=b; - else - _eval_level=b; - } - -#ifdef FXCG // defined(GIAC_HAS_STO_38) || defined(ConnectivityKit) - static unsigned int _rand_seed=123457; -#else - static tinymt32_t _rand_seed; -#endif - -#ifdef FXCG // defined(GIAC_HAS_STO_38) || defined(ConnectivityKit) - unsigned int & rand_seed(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_rand_seed; - else - return _rand_seed; - } -#else - tinymt32_t * rand_seed(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return &contextptr->globalptr->_rand_seed; - else - return &_rand_seed; - } -#endif - - void rand_seed(unsigned int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_rand_seed=b; - else - _rand_seed=b; - } - - int std_rand(){ -#if 1 // def NSPIRE - static unsigned int r = 0; - r = unsigned ((1664525*ulonglong(r)+1013904223)%(ulonglong(1)<<31)); - return r; -#else - return std::rand(); -#endif - } - - int giac_rand(GIAC_CONTEXT){ -#ifdef FXCG // defined(GIAC_HAS_STO_38) || defined(ConnectivityKit) - unsigned int & r = rand_seed(contextptr); - // r = (2147483629*ulonglong(r)+ 2147483587)% 2147483647; - r = unsigned ((1664525*ulonglong(r)+1013904223)%(ulonglong(1)<<31)); - return r; -#else - for (;;){ - unsigned r=tinymt32_generate_uint32(rand_seed(contextptr)) >> 1; - if (!(r>>31)) - return r; - } -#endif // tinymt32 - } - - static int _prog_eval_level_val=1; - int & prog_eval_level_val(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_prog_eval_level_val; - else - return _prog_eval_level_val; - } - - void prog_eval_level_val(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_prog_eval_level_val=b; - else - _prog_eval_level_val=b; - } - - void cleanup_context(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ){ - contextptr->globalptr->_eval_level=DEFAULT_EVAL_LEVEL; - } - eval_level(contextptr)=DEFAULT_EVAL_LEVEL; - if (!contextptr) - protection_level=0; - local_eval(true,contextptr); - } - - - static parser_lexer & _pl(){ - static parser_lexer * ans = 0; - if (!ans) - ans=new parser_lexer(); - ans->_i_sqrt_minus1_=1; - return * ans; - } - int & lexer_column_number(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._lexer_column_number_; - else - return _pl()._lexer_column_number_; - } - int & lexer_line_number(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._lexer_line_number_; - else - return _pl()._lexer_line_number_; - } - void lexer_line_number(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._lexer_line_number_=b; - else - _pl()._lexer_line_number_=b; - } - void increment_lexer_line_number(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - ++contextptr->globalptr->_pl._lexer_line_number_; - else - ++_pl()._lexer_line_number_; - } - - int & index_status(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._index_status_; - else - return _pl()._index_status_; - } - void index_status(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._index_status_=b; - else - _pl()._index_status_=b; - } - - int & i_sqrt_minus1(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._i_sqrt_minus1_; - else - return _pl()._i_sqrt_minus1_; - } - void i_sqrt_minus1(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._i_sqrt_minus1_=b; - else - _pl()._i_sqrt_minus1_=b; - } - - int & opened_quote(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._opened_quote_; - else - return _pl()._opened_quote_; - } - void opened_quote(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._opened_quote_=b; - else - _pl()._opened_quote_=b; - } - - int & in_rpn(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._in_rpn_; - else - return _pl()._in_rpn_; - } - void in_rpn(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._in_rpn_=b; - else - _pl()._in_rpn_=b; - } - - int & spread_formula(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._spread_formula_; - else - return _pl()._spread_formula_; - } - void spread_formula(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._spread_formula_=b; - else - _pl()._spread_formula_=b; - } - - int & initialisation_done(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._initialisation_done_; - else - return _pl()._initialisation_done_; - } - void initialisation_done(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._initialisation_done_=b; - else - _pl()._initialisation_done_=b; - } - - static int _calc_mode_=0; - int & calc_mode(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_calc_mode_; - else - return _calc_mode_; - } - int abs_calc_mode(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return absint(contextptr->globalptr->_calc_mode_); - else - return absint(_calc_mode_); - } - static std::string & _autoname_(){ - static string * ans = 0; - if (!ans){ -#ifdef GIAC_HAS_STO_38 - ans= new string("GA"); -#else - ans = new string("A"); -#endif - } - return *ans; - } - void calc_mode(int b,GIAC_CONTEXT){ - if ( (b==38 || b==-38) && strcmp(_autoname_().c_str(),"GA")<0) - autoname("GA",contextptr); - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_calc_mode_=b; - else - _calc_mode_=b; - } - - int array_start(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr){ - bool hp38=absint(contextptr->globalptr->_calc_mode_)==38; - return (!contextptr->globalptr->_python_compat_ && (contextptr->globalptr->_xcas_mode_ || hp38))?1:0; - } - return (!_python_compat_ && (_xcas_mode_ || absint(_calc_mode_)==38))?1:0; - } - - std::string autoname(GIAC_CONTEXT){ - std::string res; - if (contextptr && contextptr->globalptr ) - res=contextptr->globalptr->_autoname_; - else - res=_autoname_(); - for (;;){ - gen tmp(res,contextptr); - if (tmp.type==_IDNT){ - gen tmp1=eval(tmp,1,contextptr); - if (tmp==tmp1) - break; - } - autoname_plus_plus(res); - } - return res; - } - std::string autoname(const std::string & s,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_autoname_=s; - else - _autoname_()=s; - return s; - } - - static std::string & _autosimplify_(){ - static string * ans = 0; - if (!ans) - ans=new string("regroup"); - return *ans; - } - std::string autosimplify(GIAC_CONTEXT){ - std::string res; - if (contextptr && contextptr->globalptr ) - res=contextptr->globalptr->_autosimplify_; - else - res=_autosimplify_(); - return res; - } - std::string autosimplify(const std::string & s,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_autosimplify_=s; - else - _autosimplify_()=s; - return s; - } - - static std::string & _lastprog_name_(){ - static string * ans = 0; - if (!ans) - ans=new string("lastprog"); - return *ans; - } - std::string lastprog_name(GIAC_CONTEXT){ - std::string res; - if (contextptr && contextptr->globalptr ) - res=contextptr->globalptr->_lastprog_name_; - else - res=_lastprog_name_(); - return res; - } - std::string lastprog_name(const std::string & s,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_lastprog_name_=s; - else - _lastprog_name_()=s; - return s; - } - - static std::string & _format_double_(){ - static string * ans = 0; - if (!ans) - ans=new string(""); - return * ans; - } - std::string & format_double(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_format_double_; - else - return _format_double_(); - } - - std::string comment_s(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._comment_s_; - else - return _pl()._comment_s_; - } - void comment_s(const std::string & b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._comment_s_=b; - else - _pl()._comment_s_=b; - } - - void increment_comment_s(const std::string & b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._comment_s_ += b; - else - _pl()._comment_s_ += b; - } - - void increment_comment_s(char b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._comment_s_ += b; - else - _pl()._comment_s_ += b; - } - - std::string parser_filename(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._parser_filename_; - else - return _pl()._parser_filename_; - } - void parser_filename(const std::string & b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._parser_filename_=b; - else - _pl()._parser_filename_=b; - } - - std::string parser_error(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._parser_error_; - else - return _pl()._parser_error_; - } - void parser_error(const std::string & b,GIAC_CONTEXT){ -#ifndef GIAC_HAS_STO_38 - if (!first_error_line(contextptr)) - alert(b,contextptr); - else - *logptr(contextptr) << b << '\n'; -#endif - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._parser_error_=b; - else - _pl()._parser_error_=b; - } - - std::string error_token_name(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._error_token_name_; - else - return _pl()._error_token_name_; - } - void error_token_name(const std::string & b0,GIAC_CONTEXT){ - string b(b0); - if (b0.size()==2 && b0[0]==-61 && b0[1]==-65) - b="end of input"; - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._error_token_name_=b; - else - _pl()._error_token_name_=b; - } - - int & first_error_line(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_pl._first_error_line_; - else - return _pl()._first_error_line_; - } - void first_error_line(int b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - contextptr->globalptr->_pl._first_error_line_=b; - else - _pl()._first_error_line_=b; - } - - static gen & _parsed_gen_(){ - static gen * ans = 0; - if (!ans) - ans=new gen; - return * ans; - } - gen parsed_gen(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return *contextptr->globalptr->_parsed_genptr_; - else - return _parsed_gen_(); - } - void parsed_gen(const gen & b,GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - *contextptr->globalptr->_parsed_genptr_=b; - else - _parsed_gen_()=b; - } - - static logo_turtle & _turtle_(){ - static logo_turtle * ans = 0; - if (!ans) - ans=new logo_turtle; - return *ans; - } - logo_turtle & turtle(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr ) - return contextptr->globalptr->_turtle_; - else - return _turtle_(); - } - -#ifndef KHICAS - // protect turtle access by a lock - // turtle changes are mutually exclusive even in different contexts -#ifdef HAVE_LIBPTHREAD - pthread_mutex_t turtle_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif - std::vector & _turtle_stack_(){ - static std::vector * ans = 0; - if (!ans) - ans=new std::vector(1,_turtle_()); -#ifdef HAVE_LIBPTHREAD - ans->reserve(20000); -#endif - return *ans; - } - std::vector & turtle_stack(GIAC_CONTEXT){ -#ifdef HAVE_LIBPTHREAD - pthread_mutex_lock(&turtle_mutex); -#endif - std::vector * ans=0; - if (contextptr && contextptr->globalptr ) - ans=&contextptr->globalptr->_turtle_stack_; - else - ans=&_turtle_stack_(); -#ifdef HAVE_LIBPTHREAD - pthread_mutex_unlock(&turtle_mutex); -#endif - return *ans; - } -#endif - - // Other global variables -#ifdef NSPIRE - bool secure_run=false; -#else - bool secure_run=true; -#endif - bool center_history=false; - bool in_texmacs=false; - bool block_signal=false; - bool CAN_USE_LAPACK = true; - bool simplify_sincosexp_pi=true; - int history_begin_level=0; - // variable used to avoid copying the whole history between processes -#ifdef WIN32 // Temporary - int debug_infolevel=0; -#else - int debug_infolevel=0; -#endif - int printprog=0; -#if defined __APPLE__ || defined VISUALC || defined __MINGW_H || defined BESTA_OS || defined NSPIRE || defined FXCG || defined NSPIRE_NEWLIB || defined KHICAS -#ifdef _WIN32 - int threads=atoi(getenv("NUMBER_OF_PROCESSORS")); -#else - int threads=1; -#endif -#else - int threads=sysconf (_SC_NPROCESSORS_ONLN); -#endif - unsigned max_pairs_by_iteration=32768; - // gbasis max number of pairs by F4 iteration - // setting to 2000 accelerates cyclic9mod but cyclic9 would be slower - // 32768 is enough for cyclic10mod without truncation and not too large for yang1 - unsigned simult_primes=16,simult_primes2=16,simult_primes3=16,simult_primes_seuil2=-1,simult_primes_seuil3=-1; - // gbasis modular algorithm on Q: simultaneous primes (more primes means more parallel threads but also more memory required) - double gbasis_reinject_ratio=0.2; - // gbasis modular algo on Q: if new basis element exceed this ratio, new elements are reinjected in the ideal generators for the remaining computations - double gbasis_reinject_speed_ratio=1/6.; - // gbasis modular algo on Q: new basis elements are reinjected if the 2nd run with learning CPU speed / 1st run without learning CPU speed is >= - int gbasis_logz_age_sort=0,gbasis_stop=0; - // rur_do_gbasis==-1 no gbasis Q recon for rur, ==0 always gbasis Q recon, >0 size limit in monomials of the gbasis for gbasis Q recon - // rur_do_certify==-1 do not certify, ==0 full certify, >0 certify equation if total degree is <= rur_do_certify. Beware of the 1 shift with the user command. - int rur_do_gbasis=-1,rur_do_certify=0,rur_certify_maxthreads=6; - bool rur_error_ifnot0dimensional=false; - unsigned short int GIAC_PADIC=50; - const char cas_suffixe[]=".cas"; - int MAX_PROD_EXPAND_SIZE=4096; -#if defined RTOS_THREADX || defined BESTA_OS || defined(KHICAS) -#ifdef BESTA_OS - int LIST_SIZE_LIMIT = 100000 ; - int FACTORIAL_SIZE_LIMIT = 1000 ; - int CALL_LAPACK = 1111; -#else - int LIST_SIZE_LIMIT = 1000 ; - int FACTORIAL_SIZE_LIMIT = 254 ; - int CALL_LAPACK = 1111; -#endif - int GAMMA_LIMIT = 100 ; - int NEWTON_DEFAULT_ITERATION=40; - int TEST_PROBAB_PRIME=25; - int GCDHEU_MAXTRY=5; - int GCDHEU_DEGREE=100; - int DEFAULT_EVAL_LEVEL=5; - int MODFACTOR_PRIMES =5; - int NTL_MODGCD=1<<30; // default: ntl gcd disabled - int NTL_RESULTANT=382; - int NTL_XGCD=50; - int HGCD=128;//16384; - int HENSEL_QUADRATIC_POWER=25; - int KARAMUL_SIZE=13; - int INT_KARAMUL_SIZE=300; - int FFTMUL_SIZE=100; - int FFTMUL_INT_MAXBITS=1024; - int MAX_ALG_EXT_ORDER_SIZE = 4; - int MAX_COMMON_ALG_EXT_ORDER_SIZE = 16; - int TRY_FU_UPRIME=5; - int SOLVER_MAX_ITERATE=25; - int MAX_PRINTABLE_ZINT=10000; - int MAX_RECURSION_LEVEL=9; - int GBASIS_DETERMINISTIC=20; - int GBASISF4_MAX_TOTALDEG=1024; - int GBASISF4_MAXITER=256; - // int GBASISF4_BUCHBERGER=5; - const int BUFFER_SIZE=512; -#else - int CALL_LAPACK=1111; -#if defined(EMCC) || defined(EMCC2) - int LIST_SIZE_LIMIT = 10000000 ; -#else - int LIST_SIZE_LIMIT = 500000000 ; -#endif -#ifdef USE_GMP_REPLACEMENTS - int FACTORIAL_SIZE_LIMIT = 10000 ; -#else - int FACTORIAL_SIZE_LIMIT = 10000000 ; -#endif - int GAMMA_LIMIT = 100 ; - int NEWTON_DEFAULT_ITERATION=60; - int TEST_PROBAB_PRIME=25; - int GCDHEU_MAXTRY=5; - int GCDHEU_DEGREE=100; - int DEFAULT_EVAL_LEVEL=25; - int MODFACTOR_PRIMES =5; - int NTL_MODGCD=1<<30; // default: ntl gcd disabled - int NTL_RESULTANT=382; - int NTL_XGCD=50; - int HGCD=128;//16384; - int HENSEL_QUADRATIC_POWER=25; - int KARAMUL_SIZE=13; - int INT_KARAMUL_SIZE=300; - int FFTMUL_SIZE=100; - int FFTMUL_INT_MAXBITS=1024; -#if 0 // def GIAC_GGB - int MAX_ALG_EXT_ORDER_SIZE = 3; -#else - int MAX_ALG_EXT_ORDER_SIZE = 6; -#endif -#if defined EMCC || defined NO_TEMPLATE_MULTGCD || defined GIAC_HAS_STO_38 - int MAX_COMMON_ALG_EXT_ORDER_SIZE = 16; -#else - int MAX_COMMON_ALG_EXT_ORDER_SIZE = 64; -#endif - int TRY_FU_UPRIME=5; - int SOLVER_MAX_ITERATE=25; - int MAX_PRINTABLE_ZINT=1000000; - int MAX_RECURSION_LEVEL=100; - int GBASIS_DETERMINISTIC=50; - int GBASISF4_MAX_TOTALDEG=16384; - int GBASISF4_MAXITER=1024; - // int GBASISF4_BUCHBERGER=5; - const int BUFFER_SIZE=16384; -#endif - volatile bool ctrl_c=false,interrupted=false,kbd_interrupted=false; -#ifdef GIAC_HAS_STO_38 - double powlog2float=1e4; - int MPZ_MAXLOG2=8600; // max 2^8600 about 1K -#else - double powlog2float=1e8; - int MPZ_MAXLOG2=80000000; // 100 millions bits -#endif -#ifdef HAVE_LIBNTL - int PROOT_FACTOR_MAXDEG=300; -#else - int PROOT_FACTOR_MAXDEG=30; -#endif - int MODRESULTANT=20; - int ABS_NBITS_EVALF=1000; - - // used by WIN32 for the path to the xcas directory - string & xcasroot(){ - static string * ans=0; - if (!ans) - ans=new string; - return * ans; - } - string & xcasrc(){ -#ifdef WIN32 - static string * ans=0; - if (!ans) ans=new string("xcas.rc"); -#else - static string * ans=0; - if (!ans) ans=new string(".xcasrc"); -#endif - return *ans; - } - -#if defined HAVE_SIGNAL_H && !defined HAVE_NO_SIGNAL_H - pid_t parent_id=getpid(); -#else - pid_t parent_id=0; -#endif - pid_t child_id=0; // child process (to replace by a vector of childs?) - - void ctrl_c_signal_handler(int signum){ - ctrl_c=true; -#if !defined KHICAS && !defined NSPIRE_NEWLIB && !defined WIN32 && !defined BESTA_OS && !defined NSPIRE && !defined FXCG && !defined POCKETCAS && !defined __MINGW_H - if (child_id) - kill(child_id,SIGINT); -#endif -#if defined HAVE_SIGNAL_H && !defined HAVE_NO_SIGNAL_H - cerr << "Ctrl-C pressed (pid " << getpid() << ")" << '\n'; -#endif - } -#if !defined NSPIRE && !defined FXCG - gen catch_err(const std::runtime_error & error){ - cerr << error.what() << '\n'; - debug_ptr(0)->sst_at_stack.clear(); - debug_ptr(0)->current_instruction_stack.clear(); - debug_ptr(0)->args_stack.clear(); - protection_level=0; - debug_ptr(0)->debug_mode=false; - return string2gen(string(error.what()),false); - } -#endif - -#if 0 - static vecteur subvect(const vecteur & v,int i){ - int s=v.size(); - if (i<0) - i=-i; - vecteur res(v); - for (;s(pid_t) 0) - return child_id; // exists - child_id=fork(); - if (child_id<(pid_t) 0) - throw(std::runtime_error("Make_child error: Unable to fork")); - if (!child_id){ // child process, redirect input/output - sigset_t mask, oldmask; - sigemptyset (&mask); - sigaddset (&mask, SIGUSR1); - signal(SIGUSR1,child_signal_handler); - signal(SIGUSR2,child_plot_done); - signal_child=false; - gen args; - /* Wait for a signal to arrive. */ - sigprocmask (SIG_BLOCK, &mask, &oldmask); - signal_child=false; - for (;;){ - // cerr << "Child ready" << '\n'; -#ifndef WIN32 - while (!signal_child) - sigsuspend (&oldmask); - sigprocmask (SIG_UNBLOCK, &mask, NULL); -#endif - // read and evaluate input - CLOCK_T start, end; - double elapsed; - start = CLOCK(); - messages_to_print=""; - ifstream child_in(cas_entree_name().c_str()); - // Unarchive step - try { - child_in >> rpn_mode(context0) >> global_window_ymin >> history_begin_level ; - // cerr << args << '\n'; - if (history_begin_level<0){ - child_in >> synchronize_history; - args=unarchive(child_in,context0); - if (!synchronize_history){ - // cerr << "No sync " << '\n'; - history_in(0)[-history_begin_level-1]=args; - history_out(0)=subvect(history_out(0),-history_begin_level-1); - } - else { - // cerr << " Sync " << '\n'; - history_in(0)=*args._VECTptr; - args=unarchive(child_in,context0); - history_out(0)=*args._VECTptr; - } - } - else { - args=unarchive(child_in,context0); - // cerr << "Lu1 " << args << '\n'; - if (history_begin_level>signed(history_in(context0).size())) - history_begin_level=history_in(context0).size(); - history_in(0)=mergevecteur(subvect(history_in(context0),history_begin_level),*args._VECTptr); - args=unarchive(child_in,context0); - // cerr << "Lu2 " << args << '\n'; - history_out(0)=mergevecteur(subvect(history_out(context0),history_begin_level),*args._VECTptr); - args=unarchive(child_in,context0); - // cerr << "Lu3 " << args << '\n'; - history_in(0).push_back(args); - } - } - catch (std::runtime_error & error ){ - last_evaled_argptr(contextptr)=NULL; - args = string2gen("Child unarchive error:"+string(error.what()),false); - } - child_in.close(); - // cerr << args << '\n'; - // output result of evaluation to child_out - gen args_evaled; - { // BEGIN of old try block - if (history_begin_level<0){ - history_begin_level=-history_begin_level-1; - int s=history_in(context0).size(); - block_signal=true; - for (int k=history_begin_level;kfeuille,eval_level(context0),context0)); - else - history_out(context0).push_back(eval(history_in(context0)[k],eval_level(context0),context0)); - } - catch (std::runtime_error & error){ - last_evaled_argptr(contextptr)=NULL; - history_out(context0).push_back(catch_err(error)); - } - } - args=vecteur(history_in(context0).begin()+history_begin_level,history_in(context0).end()); - args_evaled=vecteur(history_out(context0).begin()+history_begin_level,history_out(context0).end()); - } - else { - if ( (args.type!=_VECT) || (args.subtype!=_RUNFILE__VECT) ){ - if (debug_infolevel>10) - cerr << "Child eval " << args << '\n'; - try { - args_evaled=args.eval(1,context0); - } - catch (std::runtime_error & error){ - last_evaled_argptr(contextptr)=NULL; - args_evaled=catch_err(error); - } - history_out(context0).push_back(args_evaled); - if (debug_infolevel>10) - cerr << "Child result " << args_evaled << '\n'; - } - else { - vecteur v; - history_in(context0).pop_back(); - const_iterateur it=args._VECTptr->begin(),itend=args._VECTptr->end(); - for (;it!=itend;++it){ - if (it->is_symb_of_sommet(at_signal) ||it->is_symb_of_sommet(at_debug) ) - continue; - history_in(context0).push_back(*it); - try { - if (it->is_symb_of_sommet(at_debug)) - args_evaled=it->_SYMBptr->feuille.eval(1,context0); - else - args_evaled=it->eval(1,context0); - } - catch (std::runtime_error & error){ - last_evaled_argptr(contextptr)=NULL; - args_evaled=catch_err(error); - } - // cerr << args_evaled << '\n'; - history_out(context0).push_back(args_evaled); - v.push_back(args_evaled); - ofstream child_out(cas_sortie_name().c_str()); - archive(child_out,*it,context0); - archive(child_out,args_evaled,context0); - child_out << messages_to_print << "ÿ" ; - child_out.close(); - // cerr << "Signal reads " << res << '\n'; - kill_and_wait_sigusr2(); - } - // args_evaled=gen(v,args.subtype); - args=0; - args_evaled=0; - } - } - } // END of old try/catch block - block_signal=false; - end = CLOCK(); - elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; - ofstream child_out(cas_sortie_name().c_str()); - archive(child_out,args,context0) ; - archive(child_out,args_evaled,context0) ; - child_out << messages_to_print ; - int mm=messages_to_print.size(); - if (mm && (messages_to_print[mm-1]!='\n')) - child_out << '\n'; - child_out << "Time: " << elapsed << "ÿ" ; - child_out.close(); - // cerr << "Child sending signal to " << parent_id << '\n'; - /* Wait for a signal to arrive. */ - sigprocmask (SIG_BLOCK, &mask, &oldmask); - signal_child=false; -#ifndef WIN32 - kill(parent_id,SIGUSR1); -#endif - } - } - // cerr << "Forking " << parent_id << " " << child_id << '\n'; - return child_id; -#endif // HAVE_NO_SIGNAL_H - } - - static void archive_write_error(){ - cerr << "Archive error on " << cas_entree_name() << '\n'; - } - - // return true if entree has been sent to evalation by child process - static bool child_eval(const string & entree,bool numeric,bool is_run_file){ -#if defined(HAVE_NO_SIGNAL_H) || defined(DONT_FORK) - return false; -#else - if (is_run_file || rpn_mode(context0)) - history_begin_level=0; - // added signal re-mapping because PARI seems to mess signal on the ipaq - signal(SIGUSR1,data_signal_handler); - signal(SIGUSR2,plot_signal_handler); - if (!child_id) - child_id=make_child(); - if (child_busy || data_ready) - return false; - gen entr; - CLOCK_T start, end; - start = CLOCK(); - try { - ofstream parent_out(cas_entree_name().c_str()); - if (!signal_plot_parent){ - parent_out << rpn_mode(context0) << " " << global_window_ymin << " " << history_begin_level << '\n'; - archive(parent_out,vecteur(history_in(context0).begin()+history_begin_level,history_in(context0).end()),context0); - archive(parent_out,vecteur(history_out(context0).begin()+history_begin_level,history_out(context0).end()),context0); - } - if (is_run_file){ - ifstream infile(entree.c_str()); - char c; - string s; - while (!infile.eof()){ - infile.get(c); - s += c; - } - entr = gen(s,context0); - if (entr.type!=_VECT) - entr=gen(makevecteur(entr),_RUNFILE__VECT); - else - entr.subtype=_RUNFILE__VECT; - } - else { - entr = gen(entree,context0); - if (numeric) - entr = symbolic(at_evalf,gen(entree,context0)); - } - archive(parent_out,entr,context0); - if (!parent_out) - setsizeerr(); - parent_out.close(); - if (!parent_out) - setsizeerr(); - } catch (std::runtime_error & e){ - last_evaled_argptr(contextptr)=NULL; - archive_write_error(); - return false; - } - child_busy=true; - if (signal_plot_parent){ - // cerr << "child_eval: Sending SIGUSR2 to child" << '\n'; - signal_plot_parent=false; -#ifndef WIN32 - kill(child_id,SIGUSR2); -#endif - return true; - } - // cerr << "Sending SIGUSR1 to " << child_id << '\n'; -#ifndef WIN32 - kill(child_id,SIGUSR1); -#endif - running_file=is_run_file; - end = CLOCK(); - // cerr << "# Save time" << double(end-start)/CLOCKS_PER_SEC << '\n'; - return true; -#endif /// HAVE_NO_SIGNAL_H - } - - static bool child_reeval(int history_begin_level){ -#if defined(HAVE_NO_SIGNAL_H) || defined(DONT_FORK) - return false; -#else - signal(SIGUSR1,data_signal_handler); - signal(SIGUSR2,plot_signal_handler); - if (!child_id) - child_id=make_child(); - if (child_busy || data_ready) - return false; - messages_to_print=""; - try { - ofstream parent_out(cas_entree_name().c_str()); - parent_out << rpn_mode(context0) << " " << global_window_ymin << " " << -1-history_begin_level << " " << synchronize_history << '\n'; - if (synchronize_history){ - archive(parent_out,history_in(context0),context0); - archive(parent_out,vecteur(history_out(context0).begin(),history_out(context0).begin()+history_begin_level),context0); - } - else - archive(parent_out,history_in(context0)[history_begin_level],context0); - if (!parent_out) - setsizeerr(); - parent_out.close(); - if (!parent_out) - setsizeerr(); - } catch (std::runtime_error & e){ - last_evaled_argptr(contextptr)=NULL; - archive_write_error(); - return false; - } - child_busy=true; - running_file=true; - // erase the part of the history that we are computing again - if (run_modif_possommet)){ -#ifdef WITH_GNUPLOT - plot_instructions.push_back(sortie); -#endif - if ((sortie._SYMBptr->feuille.type==_VECT) && (sortie._SYMBptr->feuille._VECTptr->size()==3) && (sortie._SYMBptr->feuille._VECTptr->back().type==_STRNG) && ( ((*sortie._SYMBptr->feuille._VECTptr)[1].type==_VECT) || is_zero((*sortie._SYMBptr->feuille._VECTptr)[1])) ){ - string lab=*(sortie._SYMBptr->feuille._VECTptr->back()._STRNGptr); -#ifdef WITH_GNUPLOT - if (lab.size() && (lab>=PICTautoname)){ - PICTautoname=lab; - PICTautoname_plus_plus(); - } -#endif - } - } - else { - if ( ((sortie.type==_SYMB) && (sortie._SYMBptr->sommet==at_erase)) || - ((sortie.type==_FUNC) && (*sortie._FUNCptr==at_erase)) ){ -#ifdef WITH_GNUPLOT - plot_instructions.clear(); -#endif - } - else { - if ( (sortie.type==_VECT) && (sortie._VECTptr->size()) && (sortie._VECTptr->back().type==_SYMB) && (equalposcomp(plot_sommets,sortie._VECTptr->back()._SYMBptr->sommet))){ -#ifdef WITH_GNUPLOT - plot_instructions.push_back(sortie); -#endif - sortie=sortie._VECTptr->back(); - if ((sortie._SYMBptr->feuille.type==_VECT) && (sortie._SYMBptr->feuille._VECTptr->size()==3) && (sortie._SYMBptr->feuille._VECTptr->back().type==_STRNG) ){ - string lab=*(sortie._SYMBptr->feuille._VECTptr->back()._STRNGptr); -#ifdef WITH_GNUPLOT - if (lab.size() && (lab>=PICTautoname)){ - PICTautoname=lab; - PICTautoname_plus_plus(); - } -#endif - } - } - else { -#ifdef WITH_GNUPLOT - plot_instructions.push_back(zero); -#endif - } - } - } - } // end for (;it!=itend;++it) - } - - static void signal_child_ok(){ - child_busy=true; - data_ready=false; - signal_plot_parent=false; -#ifndef WIN32 - kill(child_id,SIGUSR2); -#endif // WIN32 - } - - static const unary_function_eval * parent_evalonly_sommets_alias[]={*(const unary_function_eval **) &at_widget_size,*(const unary_function_eval **) &at_keyboard,*(const unary_function_eval **) &at_current_sheet,*(const unary_function_eval **) &at_Row,*(const unary_function_eval **) &at_Col,0}; - static const unary_function_ptr & parent_evalonly_sommets=(const unary_function_ptr *) parent_evalonly_sommets_alias; - static bool update_data(gen & entree,gen & sortie,GIAC_CONTEXT){ - // if (entree.type==_IDNT) - // entree=symbolic(at_sto,makevecteur(sortie,entree)); - // discarded sto autoadd otherwise files with many definitions - // are overwritten - debug_ptr(contextptr)->debug_mode=false; - if (signal_plot_parent){ - // cerr << "Child signaled " << entree << " " << sortie << '\n'; - if ( entree.type==_SYMB ){ - if ( (entree._SYMBptr->sommet==at_click && entree._SYMBptr->feuille.type==_VECT && entree._SYMBptr->feuille._VECTptr->empty() ) - || (entree._SYMBptr->sommet==at_debug) - ) { - debug_ptr(contextptr)->debug_mode=(entree._SYMBptr->sommet==at_debug); - // cerr << "Child waiting" << '\n'; - data_ready=false; - *debug_ptr(contextptr)->debug_info_ptr=entree._SYMBptr->feuille; - debug_ptr(contextptr)->debug_refresh=true; - return true; - } - if ( entree._SYMBptr->sommet==at_click || entree._SYMBptr->sommet==at_inputform || entree._SYMBptr->sommet==at_interactive ){ - // cerr << entree << '\n'; - gen res=entree.eval(1,contextptr); - // cerr << res << '\n'; - ofstream parent_out(cas_entree_name().c_str()); - archive(parent_out,res,contextptr); - parent_out.close(); - signal_child_ok(); - return true; - } - // cerr << "Child signaled " << entree << " " << sortie << '\n'; - } - if (sortie.type==_SYMB){ - if (sortie._SYMBptr->sommet==at_SetFold){ - current_folder_name=sortie._SYMBptr->feuille; - signal_child_ok(); - return false; - } - if (sortie._SYMBptr->sommet==at_sto && sortie._SYMBptr->feuille.type==_VECT){ - vecteur & v=*sortie._SYMBptr->feuille._VECTptr; - // cerr << v << '\n'; - if ((v.size()==2) && (v[1].type==_IDNT)){ - if (v[1]._IDNTptr->value) - delete v[1]._IDNTptr->value; - v[1]._IDNTptr->value = new gen(v[0]); - } - signal_child_ok(); - return false; - } - if (sortie._SYMBptr->sommet==at_purge){ - gen & g=sortie._SYMBptr->feuille; - if ((g.type==_IDNT) && (g._IDNTptr->value) ){ - delete g._IDNTptr->value; - g._IDNTptr->value=0; - } - signal_child_ok(); - return false; - } - if ((sortie._SYMBptr->sommet==at_cd) && (sortie._SYMBptr->feuille.type==_STRNG)){ -#ifndef HAVE_NO_CWD - chdir(sortie._SYMBptr->feuille._STRNGptr->c_str()); -#endif - signal_child_ok(); - return false; - } - if ( sortie._SYMBptr->sommet==at_insmod || sortie._SYMBptr->sommet==at_rmmod || sortie._SYMBptr->sommet==at_user_operator ){ - protecteval(sortie,DEFAULT_EVAL_LEVEL,contextptr); - signal_child_ok(); - return false; - } - if (sortie._SYMBptr->sommet==at_xyztrange){ - gen f=sortie._SYMBptr->feuille; - if ( (f.type==_VECT) && (f._VECTptr->size()>=12)){ - protecteval(sortie,2,contextptr); - signal_child_ok(); - return false; - } - } - if (sortie._SYMBptr->sommet==at_cas_setup){ - gen f=sortie._SYMBptr->feuille; - if ( (f.type==_VECT) && (f._VECTptr->size()>=7)){ - vecteur v=*f._VECTptr; - cas_setup(v,contextptr); - signal_child_ok(); - return false; - } - } - } - if (entree.type==_SYMB && entree._SYMBptr->sommet==at_signal && sortie.type==_SYMB && equalposcomp(parent_evalonly_sommets,sortie._SYMBptr->sommet) ) { - gen res=sortie.eval(1,contextptr); - ofstream parent_out(cas_entree_name().c_str()); - archive(parent_out,res,contextptr); - parent_out.close(); - signal_child_ok(); - return false; - } - } // end signal_plot_parent - // cerr << "# Parse time" << double(end-start)/CLOCKS_PER_SEC << '\n'; - // see if it's a PICT update - vecteur args; - // update history - if (rpn_mode(contextptr)) { - if ((sortie.type==_VECT)&& (sortie.subtype==_RPN_STACK__VECT)){ - history_out(contextptr)=*sortie._VECTptr; - history_in(contextptr)=vecteur(history_out(contextptr).size(),undef); - int i=erase_pos(contextptr); - args=vecteur(history_out(contextptr).begin()+i,history_out(contextptr).end()); -#ifdef WITH_GNUPLOT - plot_instructions.clear(); -#endif - } - else { - if (entree.type==_FUNC){ - int s=min(max(entree.subtype,0),(int)history_out(contextptr).size()); - vecteur v(s); - for (int k=s-1;k>=0;--k){ - v[k]=history_out(contextptr).back(); - history_out(contextptr).pop_back(); - history_in(contextptr).pop_back(); - } - entree=symbolic(*entree._FUNCptr,v); - } - history_in(contextptr).push_back(entree); - history_out(contextptr).push_back(sortie); - int i=erase_pos(contextptr); - args=vecteur(history_out(contextptr).begin()+i,history_out(contextptr).end()); -#ifdef WITH_GNUPLOT - plot_instructions.clear(); -#endif - } - } - else { - bool fait=false; - if (running_file) { - if (entree.type==_VECT && sortie.type==_VECT) { - history_in(contextptr)=mergevecteur(history_in(contextptr),*entree._VECTptr); - history_out(contextptr)=mergevecteur(history_out(contextptr),*sortie._VECTptr); - fait=true; - } - if (is_zero(entree) && is_zero(sortie)) - fait=true; - } - if (!fait){ - if (in_texmacs){ - COUT << GIAC_DATA_BEGIN << "verbatim:"; - COUT << "ans(" << history_out(contextptr).size() << ") " << sortie << "\n"; - - COUT << GIAC_DATA_BEGIN << "latex:$$ " << gen2tex(entree,contextptr) << "\\quad = \\quad " << gen2tex(sortie,contextptr) << "$$" << GIAC_DATA_END; - COUT << "\n"; - COUT << GIAC_DATA_BEGIN << "channel:prompt" << GIAC_DATA_END; - COUT << "quest(" << history_out(contextptr).size()+1 << ") "; - COUT << GIAC_DATA_END; - fflush (stdout); - } - history_in(contextptr).push_back(entree); - history_out(contextptr).push_back(sortie); - // for PICT update - args=vecteur(1,sortie); - } - if (running_file){ - // for PICT update - int i=erase_pos(contextptr); - args=vecteur(history_out(contextptr).begin()+i,history_out(contextptr).end()); - // CERR << "PICT clear" << '\n'; -#ifdef WITH_GNUPLOT - plot_instructions.clear(); -#endif - //running_file=false; - } - // now do the update - } - updatePICT(args); - data_ready=false; - if (signal_plot_parent) - signal_child_ok(); - return true; - } - - static void archive_read_error(){ - CERR << "Read error on " << cas_sortie_name() << '\n'; - data_ready=false; -#ifndef WIN32 - if (child_id) - kill(child_id,SIGKILL); -#endif - child_id=0; - } - - static bool read_data(gen & entree,gen & sortie,string & message,GIAC_CONTEXT){ - if (!data_ready) - return false; - message=""; - try { - ifstream parent_in(cas_sortie_name().c_str()); - if (!parent_in) - setsizeerr(); - CLOCK_T start, end; - start = CLOCK(); - entree=unarchive(parent_in,contextptr); - sortie=unarchive(parent_in,contextptr); - end = CLOCK(); - parent_in.getline(buf,BUFFER_SIZE,'¿'); - if (buf[0]=='\n') - message += (buf+1); - else - message += buf; - if (!parent_in) - setsizeerr(); - } catch (std::runtime_error & ){ - last_evaled_argptr(contextptr)=NULL; - archive_read_error(); - return false; - } - return update_data(entree,sortie,contextptr); - } -#endif // HAVE_SIGNAL_H_OLD - - string home_directory(){ - string s("/"); -#ifdef FXCG - return s; -#else - if (getenv("GIAC_HOME")) - s=getenv("GIAC_HOME"); - else { - if (getenv("XCAS_HOME")) - s=getenv("XCAS_HOME"); - } - if (!s.empty() && s[s.size()-1]!='/') - s += '/'; - if (s.size()!=1) - return s; -#ifdef HAVE_NO_HOME_DIRECTORY - return s; -#else - if (access("/etc/passwd",R_OK)) - return ""; - uid_t u=getuid(); - passwd * p=getpwuid(u); - if (p) s=p->pw_dir; - return s+"/"; -#endif -#endif - } - -#ifndef FXCG - string cas_entree_name(){ - if (getenv("XCAS_TMP")) - return getenv("XCAS_TMP")+("/#cas_entree#"+print_INT_(parent_id)); -#ifdef IPAQ - return "/tmp/#cas_entree#"+print_INT_(parent_id); -#else - return home_directory()+"#cas_entree#"+print_INT_(parent_id); -#endif - } - - string cas_sortie_name(){ - if (getenv("XCAS_TMP")) - return getenv("XCAS_TMP")+("/#cas_sortie#"+print_INT_(parent_id)); -#ifdef IPAQ - return "/tmp/#cas_sortie#"+print_INT_(parent_id); -#else - return home_directory()+"#cas_sortie#"+print_INT_(parent_id); -#endif - } -#endif - - void read_config(const string & name,GIAC_CONTEXT,bool verbose){ -#if !defined NSPIRE && !defined FXCG && !defined GIAC_HAS_STO_38 -#if !defined __MINGW_H - if (access(name.c_str(),R_OK)) { - if (verbose) - CERR << "// Unable to find config file " << name << '\n'; - return; - } -#endif - ifstream inf(name.c_str()); - if (!inf) - return; - vecteur args; - if (verbose) - CERR << "// Reading config file " << name << '\n'; - readargs_from_stream(inf,args,contextptr); - gen g(args); - if (debug_infolevel || verbose) - CERR << g << '\n'; - g.eval(1,contextptr); - if (verbose){ - CERR << "// User configuration done" << '\n'; - CERR << "// Maximum number of parallel threads " << threads << '\n'; - CERR << "Threads allowed " << threads_allowed << '\n'; - } - if (debug_infolevel){ -#ifdef HASH_MAP_NAMESPACE - CERR << "Using hash_map_namespace"<< '\n'; -#endif - CERR << "Mpz_class allowed " << mpzclass_allowed << '\n'; - // CERR << "Heap multiplication " << heap_mult << '\n'; - } -#endif - } - - // Unix: configuration is read from xcas.rc in the giac_aide_location dir - // then from the user ~/.xcasrc - // Win: configuration from $XCAS_ROOT/xcas.rc then from home_dir()+xcasrc - // or if not available from current dir xcasrc - void protected_read_config(GIAC_CONTEXT,bool verbose){ -#ifndef NO_STDEXCEPT - try { -#endif - string s; -#ifdef WIN32 - s=home_directory(); -#ifdef GNUWINCE - s = xcasroot(); -#else - if (s.size()<2 && getenv("XCAS_ROOT")){ - s=getenv("XCAS_ROOT"); - if (debug_infolevel || verbose) - CERR << "Found XCAS_ROOT " << s << '\n'; - } -#endif // GNUWINCE -#else - s=giac_aide_location; - s=s.substr(0,s.size()-8); -#endif - if (s.size()) - read_config(s+"/xcas.rc",contextptr,verbose); - s=home_directory(); - if (s.size()<2) - s=""; - read_config(s+xcasrc(),contextptr,verbose); -#ifndef NO_STDEXCEPT - } - catch (std::runtime_error & e){ - last_evaled_argptr(contextptr)=NULL; - CERR << "Error in config file " << xcasrc() << " " << e.what() << '\n'; - } -#endif - } - - string giac_aide_dir(){ -#if defined NSPIRE || defined FXCG || defined MINGW32 - return xcasroot(); -#else - if (!access((xcasroot()+"aide_cas").c_str(),R_OK)){ - return xcasroot(); - } - if (getenv("XCAS_ROOT")){ - string s=getenv("XCAS_ROOT"); - return s; - } - if (xcasroot().size()>4 && xcasroot().substr(xcasroot().size()-4,4)=="bin/"){ - string s(xcasroot().substr(0,xcasroot().size()-4)); - s+="share/giac/"; - if (!access((s+"aide_cas").c_str(),R_OK)){ - return s; - } - } -#ifdef __APPLE__ - if (!access("/Applications/usr/share/giac/",R_OK)) - return "/Applications/usr/share/giac/"; - return "/Applications/usr/share/giac/"; -#endif -#if defined WIN32 && !defined MINGW - return "/cygdrive/c/xcas/"; -#endif - string s(giac_aide_location); // ".../aide_cas" - // test if aide_cas is there, if not test at xcasroot() return "" - if (!access(s.c_str(),R_OK)){ - s=s.substr(0,s.size()-8); - CERR << "// Giac share root-directory:" << s << '\n'; - return s; - } - return ""; -#endif // __MINGW_H - } - - std::string absolute_path(const std::string & orig_file){ -#ifdef BESTA_OS - // BP: FIXME - return orig_file; -#else -#if (!defined WIN32) || (defined VISUALC) - if (orig_file[0]=='/') - return orig_file; - else - return giac_aide_dir()+orig_file; -#else -#if !defined GNUWINCE && !defined __MINGW_H - string res=orig_file; - const char *_epath; - _epath = orig_file.c_str() ; - /* If we have a POSIX path list, convert to win32 path list */ - if (_epath != NULL && *_epath != 0 - && cygwin_posix_path_list_p (_epath)){ -#ifdef x86_64 - int s = cygwin_conv_path (CCP_POSIX_TO_WIN_A , _epath, NULL, 0); - char * _win32path = (char *) malloc(s); - cygwin_conv_path(CCP_POSIX_TO_WIN_A,_epath, _win32path,s); - s=strlen(_win32path); -#else - char * _win32path = (char *) malloc - (cygwin_posix_to_win32_path_list_buf_size (_epath)); - cygwin_posix_to_win32_path_list (_epath, _win32path); - int s=strlen(_win32path); -#endif - res.clear(); - for (int i=0;i0;--ss){ - if (s[ss]=='#' || s[ss]=='.' || s[ss]=='/' ) - break; - } - if (ss && s[ss]!='.') - s=s.substr(0,ss); - s=xcasroot()+"cygstart.exe '"+s+"' &"; - /* - if (with_firefox){ - s="'"+firefox+"' '"+s+"' &"; - } - else { - if (getenv("BROWSER")) - s=getenv("BROWSER")+(" '"+s+"' &"); - else - s="'/cygdrive/c/Program Files/Internet Explorer/IEXPLORE.EXE' '"+s+"' &"; - } - */ -#else - string browser; - if (getenv("BROWSER")) - browser=getenv("BROWSER"); - else { -#ifdef __APPLE__ - browser="open" ; // browser="/Applications/Safari.app/Contents/MacOS/Safari"; - // Remove file: that seems not supported by Safari - if (!url) - s = s.substr(5,s.size()-5); - // Remove # trailing part of URL - int ss=s.size(); - for (--ss;ss>0;--ss){ - if (s[ss]=='#' || s[ss]=='.' || s[ss]=='/' ) - break; - } - if (ss && s[ss]!='.') - s=s.substr(0,ss); -#else - browser="mozilla"; - if (!access("/usr/bin/dillo",R_OK)) - browser="dillo"; - if (!access("/usr/bin/chromium",R_OK)) - browser="chromium"; - if (!access("/usr/bin/firefox",R_OK)) - browser="firefox"; -#endif - } - // find binary name - int bs=browser.size(),i; - for (i=bs-1;i>=0;--i){ - if (browser[i]=='/') - break; - } - ++i; - string browsersub=browser.substr(i,bs-i); - if (s[0]!='\'') s='\''+s+'\''; - if (browsersub=="mozilla" || browsersub=="mozilla-bin" || browsersub=="firefox" || browsersub=="chromium"){ - s="if ! "+browser+" -remote \"openurl("+s+")\" ; then "+browser+" "+s+" & fi &"; - } - else - s=browser+" "+s+" &"; -#endif - //if (debug_infolevel) - CERR << "// Running command:"+ s<<'\n'; - return s; -#endif // __MINGW_H - } - - bool system_browser_command(const string & file){ -#if defined BESTA_OS || defined POCKETCAS - return false; -#else -#ifdef WIN32 - string res=file; - if (file.size()>4 && file.substr(0,4)!="http" && file.substr(0,4)!="file"){ - if (res[0]!='/') - res=giac_aide_dir()+res; - // Remove # trailing part of URL - int ss=int(res.size()); - for (--ss;ss>0;--ss){ - if (res[ss]=='#' || res[ss]=='.' || res[ss]=='/' ) - break; - } - if (ss && res[ss]!='.') - res=res.substr(0,ss); - CERR << res << '\n'; -#if !defined VISUALC && !defined __MINGW_H && !defined NSPIRE && !defined FXCG - /* If we have a POSIX path list, convert to win32 path list */ - const char *_epath; - _epath = res.c_str() ; - if (_epath != NULL && *_epath != 0 - && cygwin_posix_path_list_p (_epath)){ -#ifdef x86_64 - int s = cygwin_conv_path (CCP_POSIX_TO_WIN_A , _epath, NULL, 0); - char * _win32path = (char *) malloc(s); - cygwin_conv_path(CCP_POSIX_TO_WIN_A,_epath, _win32path,s); -#else - char * _win32path = (char *) malloc (cygwin_posix_to_win32_path_list_buf_size (_epath)); - cygwin_posix_to_win32_path_list (_epath, _win32path); -#endif - res = _win32path; - free(_win32path); - } -#endif - } - CERR << res << '\n'; -#if !defined VISUALC && !defined NSPIRE && !defined FXCG -#ifdef __MINGW_H - while (res.size()>=2 && res.substr(0,2)=="./") - res=res.substr(2,res.size()-2); - if (res.size()<4 || res.substr(0,4)!="http") - res = "file:///c:/xcaswin/"+res; - CERR << "running open on " << res << '\n'; - //ShellExecute(NULL,"open","file:///c:/xcaswin/doc/fr/cascmd_fr/index.html",\ -NULL,NULL,SW_SHOWNORMAL); - ShellExecute(NULL,"open",res.c_str(),NULL,NULL,SW_SHOWNORMAL); -#else - // FIXME: works under visualc but not using /UNICODE flag - // find correct flag - ShellExecute(NULL,NULL,res.c_str(),NULL,NULL,1); -#endif -#endif - return true; -#else -#ifdef BESTA_OS - return false; // return 1; -#else - return !system_no_deprecation(browser_command(file).c_str()); -#endif -#endif -#endif - } - - vecteur remove_multiples(vecteur & ww){ - vecteur w; - if (!ww.empty()){ - islesscomplexthanf_sort(ww.begin(),ww.end()); - gen prec=ww[0]; - for (unsigned i=1;i v,int i){ - vector::const_iterator it=v.begin(),itend=v.end(); - for (;it!=itend;++it) - if (*it==i) - return int(it-v.begin())+1; - return 0; - } - - int equalposcomp(const vector v,int i){ - vector::const_iterator it=v.begin(),itend=v.end(); - for (;it!=itend;++it) - if (*it==i) - return int(it-v.begin())+1; - return 0; - } - - int equalposcomp(int tab[],int f){ - for (int i=1;*tab!=0;++tab,++i){ - if (*tab==f) - return i; - } - return 0; - } - - std::string find_lang_prefix(int i){ - switch (i){ - case 1: - return "fr/"; - case 2: - return "en/"; - case 3: - return "es/"; - case 4: - return "el/"; - case 9: - return "pt/"; - case 6: - return "it/"; - /* - case 7: - return "tr/"; - break; - */ - case 8: - return "zh/"; - case 5: - return "de/"; - break; - default: - return "local/"; - } - } - - std::string find_doc_prefix(int i){ - switch (i){ - case 1: - return "doc/fr/"; - break; - case 2: - return "doc/en/"; - break; - case 3: - return "doc/es/"; - break; - case 4: - return "doc/el/"; - break; - case 9: - return "doc/pt/"; - break; - case 6: - return "doc/it/"; - break; - /* - case 7: - return "doc/tr/"; - break; - */ - case 8: - return "doc/zh/"; - break; - case 5: - return "doc/de/"; - break; - default: - return "doc/local/"; - } - } - - void update_completions(){ - if (vector_completions_ptr()){ - vector_completions_ptr()->clear(); - int n=int(vector_aide_ptr()->size()); - for (int k=0;k10) - CERR << "+ " << (*vector_aide_ptr())[k].cmd_name << '\n'; - vector_completions_ptr()->push_back((*vector_aide_ptr())[k].cmd_name); - } - } - } - - void add_language(int i,GIAC_CONTEXT){ -#ifdef FXCG - return; -#else - if (!equalposcomp(lexer_localization_vector(),i)){ - lexer_localization_vector().push_back(i); - update_lexer_localization(lexer_localization_vector(),lexer_localization_map(),back_lexer_localization_map(),contextptr); -#if !defined(EMCC) && !defined(EMCC2) - if (vector_aide_ptr()){ - // add locale command description - int count; - string filename=giac_aide_dir()+find_doc_prefix(i)+"aide_cas"; - readhelp(*vector_aide_ptr(),filename.c_str(),count,false); - // add synonyms - multimap::iterator it,backend=back_lexer_localization_map().end(),itend; - vector::iterator jt = vector_aide_ptr()->begin(),jtend=vector_aide_ptr()->end(); - for (;jt!=jtend;++jt){ - it=back_lexer_localization_map().find(jt->cmd_name); - itend=back_lexer_localization_map().upper_bound(jt->cmd_name); - if (it!=backend){ - for (;it!=itend;++it){ - if (it->second.language==i) - jt->synonymes.push_back(it->second); - } - } - } - int s = int(vector_aide_ptr()->size()); - for (int j=0;jsecond.language==i){ - a.cmd_name=it->second.chaine; - a.language=it->second.language; - vector_aide_ptr()->push_back(a); - } - } - } - } -#ifndef KHICAS - CERR << "Added " << vector_aide_ptr()->size()-s << " synonyms" << '\n'; -#endif - sort(vector_aide_ptr()->begin(),vector_aide_ptr()->end(),alpha_order); - update_completions(); - } -#endif - } -#endif // FXCG - } - - void remove_language(int i,GIAC_CONTEXT){ -#ifdef FXCG - return; -#else - if (int pos=equalposcomp(lexer_localization_vector(),i)){ - if (vector_aide_ptr()){ - vector nv; - int s=int(vector_aide_ptr()->size()); - for (int j=0;j::iterator jt = vector_aide_ptr()->begin(),jtend=vector_aide_ptr()->end(); - for (;jt!=jtend;++jt){ - vector syno; - vector::const_iterator kt=jt->synonymes.begin(),ktend=jt->synonymes.end(); - for (;kt!=ktend;++kt){ - if (kt->language!=i) - syno.push_back(*kt); - } - jt->synonymes=syno; - } - } - --pos; - lexer_localization_vector().erase(lexer_localization_vector().begin()+pos); - update_lexer_localization(lexer_localization_vector(), lexer_localization_map(), back_lexer_localization_map(), contextptr); - } -#endif - } - - int string2lang(const string & s){ - if (s=="fr") - return 1; - if (s=="en") - return 2; - if (s=="sp" || s=="es") - return 3; - if (s=="el") - return 4; - if (s=="pt") - return 9; - if (s=="it") - return 6; - if (s=="tr") - return 7; - if (s=="zh") - return 8; - if (s=="de") - return 5; - return 0; - } - - std::string set_language(int i,GIAC_CONTEXT){ -#if defined(EMCC) || defined(EMCC2) - if (language(contextptr)!=i){ - language(i,contextptr); - add_language(i,contextptr); - } -#else - language(i,contextptr); - add_language(i,contextptr); -#endif -#ifdef KHICAS - lang=i; -#endif - return find_doc_prefix(i); - } - - std::string read_env(GIAC_CONTEXT,bool verbose){ -#ifndef RTOS_THREADX -#ifndef BESTA_OS - if (getenv("GIAC_LAPACK")){ - CALL_LAPACK=atoi(getenv("GIAC_LAPACK")); - if (verbose) - CERR << "// Will call lapack if dimension is >=" << CALL_LAPACK << '\n'; - } - if (getenv("GIAC_PADIC")){ - GIAC_PADIC=atoi(getenv("GIAC_PADIC")); - if (verbose) - CERR << "// Will use p-adic algorithm if dimension is >=" << GIAC_PADIC << '\n'; - } -#endif -#endif - if (getenv("XCAS_RPN")){ - if (verbose) - CERR << "// Setting RPN mode" << '\n'; - rpn_mode(contextptr)=true; - } - if (getenv("GIAC_XCAS_MODE")){ - xcas_mode(contextptr)=atoi(getenv("GIAC_XCAS_MODE")); - if (verbose) - CERR << "// Setting maple mode " << xcas_mode(contextptr) << '\n'; - } - if (getenv("GIAC_C")){ - xcas_mode(contextptr)=0; - if (verbose) - CERR << "// Setting giac C mode" << '\n'; - } - if (getenv("GIAC_MAPLE")){ - xcas_mode(contextptr)=1; - if (verbose) - CERR << "// Setting giac maple mode" << '\n'; - } - if (getenv("GIAC_MUPAD")){ - xcas_mode(contextptr)=2; - if (verbose) - CERR << "// Setting giac mupad mode" << '\n'; - } - if (getenv("GIAC_TI")){ - xcas_mode(contextptr)=3; - if (verbose) - CERR << "// Setting giac TI mode" << '\n'; - } - if (getenv("GIAC_MONO")){ - if (verbose) - CERR << "// Threads polynomial * disabled" << '\n'; - threads_allowed=false; - } - if (getenv("GIAC_MPZCLASS")){ - if (verbose) - CERR << "// mpz_class enabled" << '\n'; - mpzclass_allowed=true; - } - if (getenv("GIAC_DEBUG")){ - debug_infolevel=atoi(getenv("GIAC_DEBUG")); - CERR << "// Setting debug_infolevel to " << debug_infolevel << '\n'; - } - if (getenv("GIAC_PRINTPROG")){ - // force print of prog at parse, 256 for python compat mode print - printprog=atoi(getenv("GIAC_PRINTPROG")); - CERR << "// Setting printprog to " << printprog << '\n'; - } - string s; - if (getenv("LANG")) - s=getenv("LANG"); - else { // __APPLE__ workaround -#if !defined VISUALC && !defined NSPIRE && !defined FXCG - if (!strcmp(gettext("File"),"Fich")){ - setenv("LANG","fr_FR.UTF8",1); - s="fr_FR.UTF8"; - } - else { - s="en_US.UTF8"; - setenv("LANG",s.c_str(),1); - } - if (!strcmp(gettext("File"),"Datei")){ - setenv("LANG","de_DE.UTF8",1); - s="de_DE.UTF8"; - } -#endif - } - if (s.size()>=2){ - s=s.substr(0,2); - int i=string2lang(s); - if (i){ - language(i,contextptr); - return find_doc_prefix(i); - } - } - language(0,contextptr); - return find_doc_prefix(0); - } - - string cas_setup_string(GIAC_CONTEXT){ - string s("cas_setup("); - s += print_VECT(cas_setup(contextptr),_SEQ__VECT,contextptr); - s += "),"; - s += "xcas_mode("; - s += print_INT_(xcas_mode(contextptr)+python_compat(contextptr)*256); - s += ")"; - return s; - } - - string geo_setup_string(){ - return xyztrange(gnuplot_xmin,gnuplot_xmax,gnuplot_ymin,gnuplot_ymax,gnuplot_zmin,gnuplot_zmax,gnuplot_tmin,gnuplot_tmax,global_window_xmin,global_window_xmax,global_window_ymin,global_window_ymax,_show_axes_,class_minimum,class_size, -#ifdef WITH_GNUPLOT - gnuplot_hidden3d,gnuplot_pm3d -#else - 1,1 -#endif - ).print(context0); - } - - string add_extension(const string & s,const string & ext,const string & def){ - if (s.empty()) - return def+"."+ext; - int i=int(s.size()); - for (--i;i>0;--i){ - if (s[i]=='.') - break; - } - if (i<=0) - return s+"."+ext; - return s.substr(0,i)+"."+ext; - } - -#ifdef HAVE_LIBPTHREAD - pthread_mutex_t context_list_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif - - vector & context_list(){ - static vector * ans=0; - if (!ans) ans=new vector(1,(context *) 0); - return *ans; - } - context::context() { - // CERR << "new context " << this << '\n'; - parent=0; - tabptr=new sym_tab; - globalcontextptr=this; previous=0; globalptr=new global; - quoted_global_vars=new vecteur; - rootofs=new vecteur; - history_in_ptr=new vecteur; - history_out_ptr=new vecteur; - history_plot_ptr=new vecteur; -#ifdef HAVE_LIBPTHREAD - pthread_mutex_lock(&context_list_mutex); -#endif - context_list().push_back(this); -#ifdef HAVE_LIBPTHREAD - pthread_mutex_unlock(&context_list_mutex); -#endif - } - -#ifndef RTOS_THREADX -#if !defined BESTA_OS && !defined NSPIRE && !defined FXCG && !defined(KHICAS) - std::map * context_names = new std::map ; - - context::context(const string & name) { - // CERR << "new context " << this << '\n'; - parent=0; - tabptr=new sym_tab; - globalcontextptr=this; previous=0; globalptr=new global; - quoted_global_vars=new vecteur; - rootofs=new vecteur; - history_in_ptr=new vecteur; - history_out_ptr=new vecteur; - history_plot_ptr=new vecteur; -#ifdef HAVE_LIBPTHREAD - pthread_mutex_lock(&context_list_mutex); -#endif - context_list().push_back(this); - if (context_names) - (*context_names)[name]=this; -#ifdef HAVE_LIBPTHREAD - pthread_mutex_unlock(&context_list_mutex); -#endif - } -#endif -#endif - - context::context(const context & c) { - *this = c; - } - - context * context::clone() const{ - context * ptr = new context; - *ptr->globalptr = *globalptr; - return ptr; - } - - void init_context(context * ptr){ - if (!ptr){ - CERR << "init_context on null context" << '\n'; - return; - } - ptr->globalptr->_xcas_mode_=_xcas_mode_; -#ifdef GIAC_HAS_STO_38 - ptr->globalptr->_calc_mode_=-38; -#else - ptr->globalptr->_calc_mode_=_calc_mode_; -#endif - ptr->globalptr->_decimal_digits_=_decimal_digits_; - ptr->globalptr->_minchar_for_quote_as_string_=_minchar_for_quote_as_string_; - ptr->globalptr->_scientific_format_=_scientific_format_; - ptr->globalptr->_integer_format_=_integer_format_; - ptr->globalptr->_integer_mode_=_integer_mode_; - ptr->globalptr->_latex_format_=_latex_format_; -#ifdef BCD - ptr->globalptr->_bcd_decpoint_=_bcd_decpoint_; - ptr->globalptr->_bcd_mantissa_=_bcd_mantissa_; - ptr->globalptr->_bcd_flags_=_bcd_flags_; - ptr->globalptr->_bcd_printdouble_=_bcd_printdouble_; -#endif - ptr->globalptr->_expand_re_im_=_expand_re_im_; - ptr->globalptr->_do_lnabs_=_do_lnabs_; - ptr->globalptr->_eval_abs_=_eval_abs_; - ptr->globalptr->_eval_equaltosto_=_eval_equaltosto_; - ptr->globalptr->_complex_mode_=_complex_mode_; - ptr->globalptr->_escape_real_=_escape_real_; - ptr->globalptr->_try_parse_i_=_try_parse_i_; - ptr->globalptr->_specialtexprint_double_=_specialtexprint_double_; - ptr->globalptr->_atan_tan_no_floor_=_atan_tan_no_floor_; - ptr->globalptr->_keep_acosh_asinh_=_keep_acosh_asinh_; - ptr->globalptr->_keep_algext_=_keep_algext_; - ptr->globalptr->_auto_assume_=_auto_assume_; - ptr->globalptr->_parse_e_=_parse_e_; - ptr->globalptr->_convert_rootof_=_convert_rootof_; - ptr->globalptr->_python_compat_=_python_compat_; - ptr->globalptr->_complex_variables_=_complex_variables_; - ptr->globalptr->_increasing_power_=_increasing_power_; - ptr->globalptr->_approx_mode_=_approx_mode_; - ptr->globalptr->_series_variable_name_=_series_variable_name_; - ptr->globalptr->_series_default_order_=_series_default_order_; - ptr->globalptr->_autosimplify_=_autosimplify_(); - ptr->globalptr->_lastprog_name_=_lastprog_name_(); - ptr->globalptr->_angle_mode_=_angle_mode_; - ptr->globalptr->_variables_are_files_=_variables_are_files_; - ptr->globalptr->_bounded_function_no_=_bounded_function_no_; - ptr->globalptr->_series_flags_=_series_flags_; // bit1= full simplify, bit2=1 for truncation - ptr->globalptr->_step_infolevel_=_step_infolevel_; // bit1= full simplify, bit2=1 for truncation - ptr->globalptr->_local_eval_=_local_eval_; - ptr->globalptr->_default_color_=_default_color_; - ptr->globalptr->_epsilon_=_epsilon_<=0?1e-12:_epsilon_; - ptr->globalptr->_proba_epsilon_=_proba_epsilon_; - ptr->globalptr->_withsqrt_=_withsqrt_; - ptr->globalptr->_show_point_=_show_point_; // show 3-d point - ptr->globalptr->_io_graph_=_io_graph_; // show 2-d point in io - ptr->globalptr->_show_axes_=_show_axes_; - ptr->globalptr->_spread_Row_=_spread_Row_; - ptr->globalptr->_spread_Col_=_spread_Col_; - ptr->globalptr->_printcell_current_row_=_printcell_current_row_; - ptr->globalptr->_printcell_current_col_=_printcell_current_col_; - ptr->globalptr->_all_trig_sol_=_all_trig_sol_; - ptr->globalptr->_lexer_close_parenthesis_=_lexer_close_parenthesis_; - ptr->globalptr->_rpn_mode_=_rpn_mode_; - ptr->globalptr->_ntl_on_=_ntl_on_; - ptr->globalptr->_prog_eval_level_val =_prog_eval_level_val ; - ptr->globalptr->_eval_level=_eval_level; - ptr->globalptr->_rand_seed=_rand_seed; - ptr->globalptr->_language_=_language_; - ptr->globalptr->_last_evaled_argptr_=_last_evaled_argptr_; - ptr->globalptr->_last_evaled_function_name_=_last_evaled_function_name_; - ptr->globalptr->_currently_scanned_=""; - ptr->globalptr->_max_sum_sqrt_=_max_sum_sqrt_; - ptr->globalptr->_max_sum_add_=_max_sum_add_; - - } - - context * clone_context(const context * contextptr) { - context * ptr = new context; - if (contextptr){ - *ptr->globalptr = *contextptr->globalptr; - *ptr->tabptr = *contextptr->tabptr; - } - else { - init_context(ptr); - } - return ptr; - } - - context::~context(){ - // CERR << "delete context " << this << '\n'; - if (!previous){ - if (history_in_ptr) - delete history_in_ptr; - if (history_out_ptr) - delete history_out_ptr; - if (history_plot_ptr) - delete history_plot_ptr; - if (quoted_global_vars) - delete quoted_global_vars; - if (rootofs) - delete rootofs; - if (globalptr) - delete globalptr; - if (tabptr) - delete tabptr; -#ifdef HAVE_LIBPTHREAD - pthread_mutex_lock(&context_list_mutex); -#endif - int s=int(context_list().size()); - for (int i=s-1;i>0;--i){ - if (context_list()[i]==this){ - context_list().erase(context_list().begin()+i); - break; - } - } -#ifndef RTOS_THREADX -#if !defined BESTA_OS && !defined NSPIRE && !defined FXCG && !defined(KHICAS) - if (context_names){ - map::iterator it=context_names->begin(),itend=context_names->end(); - for (;it!=itend;++it){ - if (it->second==this){ - context_names->erase(it); - break; - } - } - } -#endif -#endif -#ifdef HAVE_LIBPTHREAD - pthread_mutex_unlock(&context_list_mutex); -#endif - } - } - -#ifndef CLK_TCK -#define CLK_TCK 1 -#endif - -#ifndef HAVE_NO_SYS_TIMES_H - double delta_tms(struct tms tmp1,struct tms tmp2){ -#if defined(HAVE_SYSCONF) && !defined(EMCC) && !defined(EMCC2) - return double( tmp2.tms_utime+tmp2.tms_stime+tmp2.tms_cutime+tmp2.tms_cstime-(tmp1.tms_utime+tmp1.tms_stime+tmp1.tms_cutime+tmp1.tms_cstime) )/sysconf(_SC_CLK_TCK); -#else - return double( tmp2.tms_utime+tmp2.tms_stime+tmp2.tms_cutime+tmp2.tms_cstime-(tmp1.tms_utime+tmp1.tms_stime+tmp1.tms_cutime+tmp1.tms_cstime) )/CLK_TCK; -#endif - } -#elif defined(__MINGW_H) - double delta_tms(clock_t tmp1,clock_t tmp2) { - return (double)(tmp2-tmp1)/CLOCKS_PER_SEC; - } -#endif /// HAVE_NO_SYS_TIMES_H - - string remove_filename(const string & s){ - int l=int(s.size()); - for (;l;--l){ - if (s[l-1]=='/') - break; - } - return s.substr(0,l); - } - -#ifdef HAVE_LIBPTHREAD - static void * in_thread_eval(void * arg){ - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); - vecteur *v = (vecteur *) arg; - context * contextptr=(context *) (*v)[2]._POINTER_val; - thread_param * ptr =thread_param_ptr(contextptr); - pthread_attr_getstacksize(&ptr->attr,&ptr->stacksize); - ptr->stackaddr=(void *) ((uintptr_t) &ptr-ptr->stacksize); -#ifndef __MINGW_H - struct tms tmp1,tmp2; - times(&tmp1); -#else - int beg=CLOCK(); -#endif - gen g = (*v)[0]; - g = protecteval(g,(*v)[1].val,contextptr); -#ifndef NO_STDEXCEPT - try { -#endif -#ifndef __MINGW_H - times(&tmp2); - double dt=delta_tms(tmp1,tmp2); - total_time(contextptr) += dt; - (*v)[4]=dt; -#else - int end=CLOCK(); - (*v)[4]=end-beg; -#endif - (*v)[5]=g; -#ifndef NO_STDEXCEPT - } catch (std::runtime_error & e){ - last_evaled_argptr(contextptr)=NULL; - } -#endif - ptr->stackaddr=0; - thread_eval_status(0,contextptr); - pthread_exit(0); - return 0; - } - - // create a new thread for evaluation of g at level level in context - bool make_thread(const gen & g,int level,const giac_callback & f,void * f_param,const context * contextptr){ - if (is_context_busy(contextptr)) - return false; - thread_param * ptr =thread_param_ptr(contextptr); - if (!ptr || ptr->v.size()!=6) - return false; - pthread_mutex_lock(mutexptr(contextptr)); - ptr->v[0]=g; - ptr->v[1]=level; - ptr->v[2]=gen((void *)contextptr,_CONTEXT_POINTER); - ptr->f=f; - ptr->f_param=f_param; - thread_eval_status(1,contextptr); - pthread_attr_init(&ptr->attr); - int cres=pthread_create (&ptr->eval_thread, &ptr->attr, in_thread_eval,(void *)&ptr->v); - if (cres){ - thread_eval_status(0,contextptr); - pthread_mutex_unlock(mutexptr(contextptr)); - } - return !cres; - } - - // check if contextptr has a running evaluation thread - // if not returns -1 - // if evaluation is not finished return 1 - // if evaluation is finished, clear mutex lock and - // call the thread_param_ptr callback function with the evaluation value - // and returns 0 - // otherwise returns status, 2=debug, 3=wait click - int check_thread(context * contextptr){ - if (!is_context_busy(contextptr)) - return -1; - int status=thread_eval_status(contextptr); - if (status!=0 && !kill_thread(contextptr)) - return status; - thread_param tp = *thread_param_ptr(contextptr); - if (status==0){ - // unsigned thread_return_value=0; - // void * ptr_return=&thread_return_value; - // pthread_join(eval_thread,&ptr_return); - if ( -#ifdef __MINGW_H - 1 -#else - tp.eval_thread -#endif - ){ - giac_callback f=tp.f; - gen arg_callback=tp.v[5]; - void * param_callback=tp.f_param; - double tt=tp.v[4]._DOUBLE_val; - pthread_join(tp.eval_thread,0); - pthread_mutex_unlock(mutexptr(contextptr)); - // double tt=double(tp.v[4].val)/CLOCKS_PER_SEC; - if (tt>0.4) - (*logptr(contextptr)) << gettext("\nEvaluation time: ") << tt << '\n'; - if (f) - f(arg_callback,param_callback); - else - (*logptr(contextptr)) << arg_callback << '\n'; - return 0; - } - } - if (kill_thread(contextptr)){ - kill_thread(false,contextptr); - thread_eval_status(0,contextptr); - clear_prog_status(contextptr); - cleanup_context(contextptr); - if (tp.f) - tp.f(string2gen("Aborted",false),tp.f_param); -#if !defined __MINGW_H && !defined KHICAS - *logptr(contextptr) << gettext("Thread ") << tp.eval_thread << " has been cancelled" << '\n'; -#endif -#ifdef NO_STDEXCEPT - pthread_cancel(tp.eval_thread) ; -#else - try { - pthread_cancel(tp.eval_thread) ; - } catch (...){ - } -#endif - pthread_mutex_unlock(mutexptr(contextptr)); - return -1; - } - return status; - } - - // check contexts in context_list starting at index i, - // returns at first context with status >= 2 - // return value is -2 (invalid range), -1 (ok) or context number - int check_threads(int i){ - int s,ans=-1; - context * cptr; - if (// i>=s || - i<0) - return -2; - for (;;++i){ - pthread_mutex_lock(&context_list_mutex); - s=context_list().size(); - if (i=s) - break; - int res=check_thread(cptr); - if (res>1){ - ans=i; - break; - } - } - return ans; - } - - gen thread_eval(const gen & g_,int level,context * contextptr,void (* wait_0001)(context *) ){ - gen g=equaltosto(g_,contextptr); - /* 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 - */ - pthread_t eval_thread; - vecteur v(6); - v[0]=g; - v[1]=level; - v[2]=gen(contextptr,_CONTEXT_POINTER); - pthread_mutex_lock(mutexptr(contextptr)); - thread_eval_status(1,contextptr); - int cres=pthread_create (&eval_thread, (pthread_attr_t *) NULL, in_thread_eval,(void *)&v); - if (!cres){ - for (;;){ - int eval_status=thread_eval_status(contextptr); - if (!eval_status) - break; - wait_0001(contextptr); - if (kill_thread(contextptr)){ - kill_thread(false,contextptr); - clear_prog_status(contextptr); - cleanup_context(contextptr); -#if !defined __MINGW_H && !defined KHICAS - *logptr(contextptr) << gettext("Cancel thread ") << eval_thread << '\n'; -#endif -#ifdef NO_STDEXCEPT - pthread_cancel(eval_thread) ; -#else - try { - pthread_cancel(eval_thread) ; - } catch (...){ - } -#endif - pthread_mutex_unlock(mutexptr(contextptr)); - return undef; - } - } - // unsigned thread_return_value=0; - // void * ptr=&thread_return_value; - pthread_join(eval_thread,0); // pthread_join(eval_thread,&ptr); - // Restore pointers and return v[3] - pthread_mutex_unlock(mutexptr(contextptr)); - // double tt=double(v[4].val)/CLOCKS_PER_SEC; - double tt=v[4]._DOUBLE_val; - if (tt>0.1) - (*logptr(contextptr)) << gettext("Evaluation time: ") << tt << '\n'; - return v[5]; - } - pthread_mutex_unlock(mutexptr(contextptr)); - return protecteval(g,level,contextptr); - } -#else - - bool make_thread(const gen & g,int level,const giac_callback & f,void * f_param,context * contextptr){ - return false; - } - - int check_thread(context * contextptr){ - return -1; - } - - int check_threads(int i){ - return -1; - } - - gen thread_eval(const gen & g,int level,context * contextptr,void (* wait_001)(context * )){ - return protecteval(g,level,contextptr); - } -#endif // HAVE_LIBPTHREAD - - debug_struct::debug_struct():indent_spaces(0),debug_mode(false),sst_mode(false),sst_in_mode(false),debug_allowed(true),current_instruction(-1),debug_refresh(false){ - debug_info_ptr=new gen; - fast_debug_info_ptr=new gen; - debug_prog_name=new gen; - debug_localvars=new gen; - debug_contextptr=0; - } - - debug_struct::~debug_struct(){ - delete debug_info_ptr; - delete fast_debug_info_ptr; - delete debug_prog_name; - delete debug_localvars; - } - - debug_struct & debug_struct::operator =(const debug_struct & dbg){ - indent_spaces=dbg.indent_spaces; - args_stack=dbg.args_stack; - debug_breakpoint=dbg.debug_breakpoint; - debug_watch=dbg.debug_watch ; - debug_mode=dbg.debug_mode; - sst_mode=dbg.sst_mode ; - sst_in_mode=dbg.sst_in_mode ; - debug_allowed=dbg.debug_allowed; - current_instruction_stack=dbg.current_instruction_stack; - current_instruction=dbg.current_instruction; - sst_at_stack=dbg.sst_at_stack; - sst_at=dbg.sst_at; - if (debug_info_ptr) - delete debug_info_ptr; - debug_info_ptr=new gen(dbg.debug_info_ptr?*dbg.debug_info_ptr:0) ; - if (fast_debug_info_ptr) - delete fast_debug_info_ptr; - fast_debug_info_ptr= new gen(dbg.fast_debug_info_ptr?*dbg.fast_debug_info_ptr:0); - if (debug_prog_name) - delete debug_prog_name; - debug_prog_name=new gen(dbg.debug_prog_name?*dbg.debug_prog_name:0); - if (debug_localvars) - delete debug_localvars; - debug_localvars=new gen(dbg.debug_localvars?*dbg.debug_localvars:0); - debug_refresh=dbg.debug_refresh; - debug_contextptr=dbg.debug_contextptr; - return *this; - } - - static debug_struct & _debug_data(){ - static debug_struct * ans = 0; - if (!ans) ans=new debug_struct; - return *ans; - } - - debug_struct * debug_ptr(GIAC_CONTEXT){ - if (contextptr && contextptr->globalptr) - return contextptr->globalptr->_debug_ptr; - return &_debug_data(); - } - - void clear_prog_status(GIAC_CONTEXT){ - debug_struct * ptr=debug_ptr(contextptr); - if (ptr){ - ptr->args_stack.clear(); - ptr->debug_mode=false; - ptr->sst_at_stack.clear(); - if (!contextptr) - protection_level=0; - } - } - - - global::global() : _xcas_mode_(0), - _calc_mode_(0),_decimal_digits_(12),_minchar_for_quote_as_string_(1), - _scientific_format_(0), _integer_format_(0), _latex_format_(0), -#ifdef BCD - _bcd_decpoint_('.'|('E'<<16)|(' '<<24)),_bcd_mantissa_(12+(15<<8)), _bcd_flags_(0),_bcd_printdouble_(false), -#endif - _expand_re_im_(true), _do_lnabs_(true), _eval_abs_(true),_eval_equaltosto_(true),_integer_mode_(true),_complex_mode_(false), _escape_real_(true),_complex_variables_(false), _increasing_power_(false), _approx_mode_(false), _variables_are_files_(false), _local_eval_(true), - _withsqrt_(true), - _show_point_(true), _io_graph_(true), - _all_trig_sol_(false), -#ifdef __MINGW_H - _ntl_on_(false), -#else - _ntl_on_(true), -#endif -#ifdef WITH_MYOSTREAM - _lexer_close_parenthesis_(true),_rpn_mode_(false),_try_parse_i_(true),_specialtexprint_double_(false),_atan_tan_no_floor_(false),_keep_acosh_asinh_(false),_keep_algext_(false),_auto_assume_(false),_parse_e_(false),_convert_rootof_(true), -#ifdef KHICAS - _python_compat_(true), -#else - _python_compat_(false), -#endif - _angle_mode_(0), _bounded_function_no_(0), _series_flags_(0x3),_step_infolevel_(0),_default_color_(FL_BLACK), _epsilon_(1e-12), _proba_epsilon_(1e-15), _show_axes_(1),_spread_Row_ (-1), _spread_Col_ (-1),_logptr_(&my_CERR),_prog_eval_level_val(1), _eval_level(DEFAULT_EVAL_LEVEL), _rand_seed(123457),_last_evaled_function_name_(0),_currently_scanned_(""),_last_evaled_argptr_(0),_max_sum_sqrt_(3), -#ifdef GIAC_HAS_STO_38 // Prime sum(x^2,x,0,100000) crash on hardware - _max_sum_add_(10000), -#else - _max_sum_add_(100000), -#endif - _total_time_(0),_evaled_table_(0),_extra_ptr_(0),_series_variable_name_('h'),_series_default_order_(5), -#else - _lexer_close_parenthesis_(true),_rpn_mode_(false),_try_parse_i_(true),_specialtexprint_double_(false),_atan_tan_no_floor_(false),_keep_acosh_asinh_(false),_keep_algext_(false),_auto_assume_(false),_parse_e_(false),_convert_rootof_(true), -#ifdef KHICAS - _python_compat_(true), -#else - _python_compat_(false), -#endif - _angle_mode_(0), _bounded_function_no_(0), _series_flags_(0x3),_step_infolevel_(0),_default_color_(FL_BLACK), _epsilon_(1e-12), _proba_epsilon_(1e-15), _show_axes_(1),_spread_Row_ (-1), _spread_Col_ (-1), -#if defined(EMCC) || defined(EMCC2) - _logptr_(&COUT), -#else -#ifdef FXCG - _logptr_(0), -#else -#ifdef KHICAS - _logptr_(&os_cerr), -#else - _logptr_(&CERR), -#endif -#endif -#endif - _prog_eval_level_val(1), _eval_level(DEFAULT_EVAL_LEVEL), _rand_seed(123457),_last_evaled_function_name_(0),_currently_scanned_(""),_last_evaled_argptr_(0),_max_sum_sqrt_(3), -#ifdef GIAC_HAS_STO_38 // Prime sum(x^2,x,0,100000) crash on hardware - _max_sum_add_(10000), -#else - _max_sum_add_(100000), -#endif - _total_time_(0),_evaled_table_(0),_extra_ptr_(0),_series_variable_name_('h'),_series_default_order_(5) -#endif - { - _pl._i_sqrt_minus1_=1; -#ifndef KHICAS - _turtle_stack_.push_back(_turtle_); -#endif - _debug_ptr=new debug_struct; - _thread_param_ptr=new thread_param; - _parsed_genptr_=new gen; -#ifdef GIAC_HAS_STO_38 - _autoname_="GA"; -#else - _autoname_="A"; -#endif - _autosimplify_="regroup"; - _lastprog_name_="lastprog"; - _format_double_=""; -#ifdef HAVE_LIBPTHREAD - _mutexptr = new pthread_mutex_t; - pthread_mutex_init(_mutexptr,0); - _mutex_eval_status_ptr = new pthread_mutex_t; - pthread_mutex_init(_mutex_eval_status_ptr,0); -#endif - } - - global & global::operator = (const global & g){ - _xcas_mode_=g._xcas_mode_; - _calc_mode_=g._calc_mode_; - _decimal_digits_=g._decimal_digits_; - _minchar_for_quote_as_string_=g._minchar_for_quote_as_string_; - _scientific_format_=g._scientific_format_; - _integer_format_=g._integer_format_; - _integer_mode_=g._integer_mode_; - _latex_format_=g._latex_format_; -#ifdef BCD - _bcd_decpoint_=g._bcd_decpoint_; - _bcd_mantissa_=g._bcd_mantissa_; - _bcd_flags_=g._bcd_flags_; - _bcd_printdouble_=g._bcd_printdouble_; -#endif - _expand_re_im_=g._expand_re_im_; - _do_lnabs_=g._do_lnabs_; - _eval_abs_=g._eval_abs_; - _eval_equaltosto_=g._eval_equaltosto_; - _complex_mode_=g._complex_mode_; - _escape_real_=g._escape_real_; - _complex_variables_=g._complex_variables_; - _increasing_power_=g._increasing_power_; - _approx_mode_=g._approx_mode_; - _series_variable_name_=g._series_variable_name_; - _series_default_order_=g._series_default_order_; - _angle_mode_=g._angle_mode_; - _atan_tan_no_floor_=g._atan_tan_no_floor_; - _keep_acosh_asinh_=g._keep_acosh_asinh_; - _keep_algext_=g._keep_algext_; - _auto_assume_=g._auto_assume_; - _parse_e_=g._parse_e_; - _convert_rootof_=g._convert_rootof_; - _python_compat_=g._python_compat_; - _variables_are_files_=g._variables_are_files_; - _bounded_function_no_=g._bounded_function_no_; - _series_flags_=g._series_flags_; // bit1= full simplify, bit2=1 for truncation, bit3=?, bit4=1 do not convert back SPOL1 to symbolic expression - _step_infolevel_=g._step_infolevel_; // bit1= full simplify, bit2=1 for truncation - _local_eval_=g._local_eval_; - _default_color_=g._default_color_; - _epsilon_=g._epsilon_; - _proba_epsilon_=g._proba_epsilon_; - _withsqrt_=g._withsqrt_; - _show_point_=g._show_point_; // show 3-d point - _io_graph_=g._io_graph_; // show 2-d point in io - _show_axes_=g._show_axes_; - _spread_Row_=g._spread_Row_; - _spread_Col_=g._spread_Col_; - _printcell_current_row_=g._printcell_current_row_; - _printcell_current_col_=g._printcell_current_col_; - _all_trig_sol_=g._all_trig_sol_; - _ntl_on_=g._ntl_on_; - _prog_eval_level_val =g._prog_eval_level_val ; - _eval_level=g._eval_level; - _rand_seed=g._rand_seed; - _language_=g._language_; - _last_evaled_argptr_=g._last_evaled_argptr_; - _last_evaled_function_name_=g._last_evaled_function_name_; - _currently_scanned_=g._currently_scanned_; - _max_sum_sqrt_=g._max_sum_sqrt_; - _max_sum_add_=g._max_sum_add_; - _turtle_=g._turtle_; -#ifndef KHICAS - _turtle_stack_=g._turtle_stack_; -#endif - _autoname_=g._autoname_; - _format_double_=g._format_double_; - _extra_ptr_=g._extra_ptr_; - return *this; - } - - global::~global(){ - delete _parsed_genptr_; - delete _thread_param_ptr; - delete _debug_ptr; -#ifdef HAVE_LIBPTHREAD - pthread_mutex_destroy(_mutexptr); - delete _mutexptr; - pthread_mutex_destroy(_mutex_eval_status_ptr); - delete _mutex_eval_status_ptr; -#endif - } - -#ifdef FXCG - bool my_isinf(double d){ - return 1/d==0.0; - } - bool my_isnan(double d){ - return d==d+1 && !my_isinf(d); - } -#else // FXCG -#ifdef __APPLE__ - bool my_isnan(double d){ -#if 1 // TARGET_OS_IPHONE - return isnan(d); -#else - return __isnand(d); -#endif - } - - bool my_isinf(double d){ -#if 1 // TARGET_OS_IPHONE - return isinf(d); -#else - return __isinfd(d); -#endif - } - -#else // __APPLE__ - bool my_isnan(double d){ -#if defined VISUALC || defined BESTA_OS -#if !defined RTOS_THREADX && !defined FREERTOS - return _isnan(d)!=0; -#else - return isnan(d); -#endif -#else -#if defined(FIR_LINUX) || defined(FIR_ANDROID) - return std::isnan(d); -#else - return isnan(d); -#endif -#endif - } - - bool my_isinf(double d){ -#if defined VISUALC || defined BESTA_OS - double x=0.0; - return d==1.0/x || d==-1.0/x; -#else -#if defined(FIR_LINUX) || defined(FIR_ANDROID) - return std::isinf(d); -#else - return isinf(d); -#endif -#endif - } - -#endif // __APPLE__ -#endif // FXCG - - double giac_floor(double d){ - double maxdouble=longlong(1)<<30; - if (d>=maxdouble || d<=-maxdouble) - return std::floor(d); - if (d>0) - return int(d); - double k=int(d); - if (k==d) - return k; - else - return k-1; - } - double giac_ceil(double d){ - double maxdouble=longlong(1)<<54; - if (d>=maxdouble || d<=-maxdouble) - return d; - if (d<0) - return double(longlong(d)); - double k=double(longlong(d)); - if (k==d) - return k; - else - return k+1; - } - - - -/* --------------------------------------------------------------------- */ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -/* --------------------------------------------------------------------- - - Conversions between UTF-16 and UTF-8. Source code file. - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Sept 2001: fixed const & error conditions per - mods suggested by S. Parent & A. Lillich. - June 2002: Tim Dodd added detection and handling of incomplete - source sequences, enhanced error detection, added casts - to eliminate compiler warnings. - July 2003: slight mods to back out aggressive FFFE detection. - Jan 2004: updated switches in from-UTF8 conversions. - Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. - Jan 2013: Jean-Yves Avenard adapted to only calculate size if - destination pointer are null - ------------------------------------------------------------------------- */ - - -static const int halfShift = 10; /* used for shifting by 10 bits */ - -static const UTF32 halfBase = 0x0010000UL; -static const UTF32 halfMask = 0x3FFUL; - -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF - -/* --------------------------------------------------------------------- */ - -/* - * Index into the table below with the first byte of a UTF-8 sequence to - * get the number of trailing bytes that are supposed to follow it. - * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is - * left as-is for anyone who may want to do such conversion, which was - * allowed in earlier algorithms. - */ -static const char trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; - -/* - * Magic values subtracted from a buffer value during UTF8 conversion. - * This table contains as many values as there might be trailing bytes - * in a UTF-8 sequence. - */ -static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; - -/* - * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed - * into the first byte, depending on how many bytes follow. There are - * as many entries in this table as there are UTF-8 sequence types. - * (I.e., one byte sequence, two byte... etc.). Remember that sequencs - * for *legal* UTF-8 will be 4 or fewer bytes total. - */ -static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -/* --------------------------------------------------------------------- */ - -/* The interface converts a whole buffer to avoid function-call overhead. - * Constants have been gathered. Loops & conditionals have been removed as - * much as possible for efficiency, in favor of drop-through switches. - * (See "Note A" at the bottom of the file for equivalent code.) - * If your compiler supports it, the "isLegalUTF8" call can be turned - * into an inline function. - */ - -/* --------------------------------------------------------------------- */ - -unsigned int ConvertUTF16toUTF8 ( - const UTF16* sourceStart, const UTF16* sourceEnd, - UTF8* targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = sourceStart; - UTF8* target = targetStart; - UTF32 ch; - while ((source < sourceEnd) && (ch = *source)) { - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - UTF32 ch2; - if ((source < sourceEnd) && (ch2 = *source)) { - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* Figure out how many bytes the result will require */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - } - - target += bytesToWrite; - if ((uintptr_t)target > (uintptr_t)targetEnd) { - source = oldSource; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: target--; if (targetStart) { *target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; } - case 3: target--; if (targetStart) { *target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; } - case 2: target--; if (targetStart) { *target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; } - case 1: target--; if (targetStart) { *target = (UTF8)(ch | firstByteMark[bytesToWrite]); } - } - target += bytesToWrite; - } - - unsigned int length = int(target - targetStart); - return length; -} - -/* --------------------------------------------------------------------- */ - -/* - * Utility routine to tell whether a sequence of bytes is legal UTF-8. - * This must be called with the length pre-determined by the first byte. - * If not calling this from ConvertUTF8to*, then the length can be set by: - * length = trailingBytesForUTF8[*source]+1; - * and the sequence is illegal right away if there aren't that many bytes - * available. - * If presented with a length > 4, this returns false. The Unicode - * definition of UTF-8 goes up to 4-byte sequences. - */ - -static Boolean isLegalUTF8(const UTF8 *source, int length) { - UTF8 a; - const UTF8 *srcptr = source+length; - switch (length) { - default: return false; - /* Everything else falls through when "true"... */ - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 2: if ((a = (*--srcptr)) > 0xBF) return false; - - switch (*source) { - /* no fall-through in this inner switch */ - case 0xE0: if (a < 0xA0) return false; break; - case 0xED: if (a > 0x9F) return false; break; - case 0xF0: if (a < 0x90) return false; break; - case 0xF4: if (a > 0x8F) return false; break; - default: if (a < 0x80) return false; - } - - case 1: if (*source >= 0x80 && *source < 0xC2) return false; - } - if (*source > 0xF4) return false; - return true; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 sequence is legal or not. - * This is not used here; it's just exported. - */ -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { - int length = trailingBytesForUTF8[*source]+1; - if (source+length > sourceEnd) { - return false; - } - return isLegalUTF8(source, length); -} - -/* --------------------------------------------------------------------- */ - -unsigned int ConvertUTF8toUTF16 (const UTF8* sourceStart, const UTF8* sourceEnd, UTF16* targetStart, UTF16* targetEnd, ConversionFlags flags) -#if 0 //def GIAC_HAS_STO_38 -{ - wchar_t *d= targetStart; -#define read(a) if (sourceStart>=sourceEnd) break; a= *sourceStart++ - while (sourceStart= sourceEnd) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (! isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if ((uintptr_t)target >= (uintptr_t)targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - if (targetStart) - *target = UNI_REPLACEMENT_CHAR; - target++; - } - } else { - if (targetStart) - *target = (UTF16)ch; /* normal case */ - target++; - } - } else if (ch > UNI_MAX_UTF16) { - if (flags == strictConversion) { - result = sourceIllegal; - source -= (extraBytesToRead+1); /* return to the start */ - break; /* Bail out; shouldn't continue */ - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if ((uintptr_t)target + 1 >= (uintptr_t)targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - if (targetStart) - { - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - else - target += 2; - } - } - - unsigned int length = unsigned(target - targetStart); - return length; -} - - unsigned int utf82unicode(const char * line, wchar_t * wline, unsigned int n){ - if (!line){ - if (wline) wline[0]=0; - return 0; - } - - unsigned int j = ConvertUTF8toUTF16 ( - (const UTF8*) line,((line + n) < line) ? (const UTF8*)~0 : (const UTF8*)(line + n), - (UTF16*)wline, (UTF16*)~0, - lenientConversion); - - if (wline) wline[j] = 0; - - return j; - } - - // 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){ - if (!line) return 0; - unsigned int i=0,j=0,c; - for (;i=0x2000 && masked<0x2c00) - j -= 2; - } - continue; - } - if ( (c & 0xf8) == 0xf0) { // 4 char 11110/xxx/ 10/xxxxxx/ 10/xxxxxx/ 10/xxxxxx/ - i++; - c = (c & 0x07) << 6 | (line[i] & 0x3f); - i++; - c = c << 6 | (line[i] & 0x3f); - i++; - c = c << 6 | (line[i] & 0x3f); - j++; - continue; - } - // FIXME complete for 5 and 6 char - c = 0xfffd; - j++; - } - return j; - } - - unsigned int wstrlen(const char * line, unsigned int n){ - if (!line) return 0; - return utf82unicode(line, NULL, n); - } - - // convert UTF8 string to unicode, allocate memory with new - wchar_t * utf82unicode(const char * idname){ - if (!idname) - return 0; - int l=int(strlen(idname)); - wchar_t * wname=new wchar_t[l+1]; - utf82unicode(idname,wname,l); - return wname; - } - -#if defined NSPIRE || defined FXCG - unsigned wcslen(const wchar_t * c){ - unsigned i=0; - for (;*c;++i) - ++c; - return i; - } -#endif - - char * unicode2utf8(const wchar_t * idname){ - if (!idname) - return 0; - int l=int(wcslen(idname)); - char * name=new char[4*l+1]; - unicode2utf8(idname,name,l); - return name; - } - - unsigned int wstrlen(const wchar_t * wline){ - if (!wline) - return 0; - unsigned int i=0; - for (;*wline;wline++){ i++; } - return i; - } - - // return length required to translate from unicode to UTF8 - unsigned int utf8length(const wchar_t * wline){ - return unicode2utf8(wline,0,wstrlen(wline)); - } - - unsigned int unicode2utf8(const wchar_t * wline,char * line,unsigned int n){ - if (!wline){ - if (line) line[0]=0; - return 0; - } - - unsigned int j = ConvertUTF16toUTF8( - (UTF16*)wline, ((wline + n) < wline) ? (const UTF16*)~0 : (const UTF16*)(wline + n), - (UTF8*)line, (UTF8*)-1, - lenientConversion); - - if (line) line[j]=0; - - return j; - } - - // Binary archive format for a gen: - // 8 bytes=the gen itself (i.e. type, subtype, etc.) - // Additionnally for pointer types - // 4 bytes = total size of additionnal data - // _CPLX: both real and imaginary parts - // _FRAC: numerator and denominator - // _MOD: 2 gens - // _REAL, _ZINT: long int/real binary archive - // _VECT: 4 bytes = #rows #cols (#cols=0 if not a matrix) + list of elements - // _SYMB: feuille + sommet - // _FUNC: 2 bytes = -1 + string or index - // _IDNT or _STRNG: the name - // count number of bytes required to save g in a file - static size_t countfunction(void const* p, size_t nbBytes,size_t NbElements, void *file) - { - (*(unsigned *)file)+= unsigned(nbBytes*NbElements); - return nbBytes*NbElements; - } - unsigned archive_count(const gen & g,GIAC_CONTEXT){ - unsigned size= 0; - archive_save((void*)&size, g, countfunction, contextptr, true); - return size; - } - - /* - unsigned archive_count(const gen & g,GIAC_CONTEXT){ - if (g.type<=_DOUBLE_ || g.type==_FLOAT_) - return sizeof(gen); - if (g.type==_CPLX) - return sizeof(gen)+sizeof(unsigned)+archive_count(*g._CPLXptr,contextptr)+archive_count(*(g._CPLXptr+1),contextptr); - if (g.type==_REAL || g.type==_ZINT) - return sizeof(gen)+sizeof(unsigned)+g.print(contextptr).size(); - if (g.type==_FRAC) - return sizeof(gen)+sizeof(unsigned)+archive_count(g._FRACptr->num,contextptr)+archive_count(g._FRACptr->den,contextptr); - if (g.type==_MOD) - return sizeof(gen)+sizeof(unsigned)+archive_count(*g._MODptr,contextptr)+archive_count(*(g._MODptr+1),contextptr); - if (g.type==_VECT){ - unsigned res=sizeof(gen)+sizeof(unsigned)+4; - const_iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end(); - for (;it!=itend;++it) - res += archive_count(*it,contextptr); - return res; - } - if (g.type==_SYMB){ - if (archive_function_index(g._SYMBptr->sommet)) // ((equalposcomp(archive_function_tab(),g._SYMBptr->sommet)) - return sizeof(gen)+sizeof(unsigned)+sizeof(short)+archive_count(g._SYMBptr->feuille,contextptr); - return sizeof(gen)+sizeof(unsigned)+sizeof(short)+archive_count(g._SYMBptr->feuille,contextptr)+strlen(g._SYMBptr->sommet.ptr()->s); - } - if (g.type==_IDNT) - return sizeof(gen)+sizeof(unsigned)+strlen(g._IDNTptr->id_name); - if (g.type==_FUNC){ - if (archive_function_index(*g._FUNCptr)) // (equalposcomp(archive_function_tab(),*g._FUNCptr)) - return sizeof(gen)+sizeof(unsigned)+sizeof(short); - return sizeof(gen)+sizeof(unsigned)+sizeof(short)+strlen(g._FUNCptr->ptr()->s); - } - return sizeof(gen)+sizeof(unsigned)+strlen(g.print().c_str()); // not handled - } - */ - -#define DBG_ARCHIVE 0 - - 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){ - // write the gen first - writefunc(&g,sizeof(gen),1,f); - if (g.type<=_DOUBLE_ || g.type==_FLOAT_) - return true; - // heap allocated object, find size - unsigned size=0; - if (!noRecurse) size=archive_count(g,contextptr); - writefunc(&size,sizeof(unsigned),1,f); - if (g.type==_CPLX) - return archive_save(f,*g._CPLXptr,writefunc,contextptr,noRecurse) && archive_save(f,*(g._CPLXptr+1),writefunc,contextptr,noRecurse); - if (g.type==_MOD) - return archive_save(f,*g._MODptr,writefunc,contextptr,noRecurse) && archive_save(f,*(g._MODptr+1),writefunc,contextptr,noRecurse); - if (g.type==_FRAC) - return archive_save(f,g._FRACptr->num,writefunc,contextptr,noRecurse) && archive_save(f,g._FRACptr->den,writefunc,contextptr,noRecurse); - if (g.type==_VECT){ - unsigned short rows=g._VECTptr->size(),cols=0; - if (ckmatrix(g)) - cols=g._VECTptr->front()._VECTptr->size(); - writefunc(&rows,sizeof(short),1,f); - writefunc(&cols,sizeof(short),1,f); - const_iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end(); - for (;it!=itend;++it){ - if (!archive_save(f,*it,writefunc,contextptr,noRecurse)) - return false; - } - return true; - } - if (g.type==_IDNT){ -#if DBG_ARCHIVE - std::ofstream ofs; - ofs.open ("e:\\tmp\\logsave", std::ofstream::out | std::ofstream::app); - ofs << "IDNT " << g << '\n'; - ofs.close(); -#endif - // fprintf(f,"%s",g._IDNTptr->id_name); - writefunc(g._IDNTptr->id_name,1,strlen(g._IDNTptr->id_name),f); - return true; - } - if (g.type==_SYMB){ - if (!archive_save(f,g._SYMBptr->feuille,writefunc,contextptr,noRecurse)) - return false; -#if DBG_ARCHIVE - std::ofstream ofs; - ofs.open ("e:\\tmp\\logsave", std::ofstream::out | std::ofstream::app); - ofs << "SYMB " << g << '\n'; - ofs.close(); -#endif - short i=archive_function_index(g._SYMBptr->sommet); // equalposcomp(archive_function_tab(),g._SYMBptr->sommet); - writefunc(&i,sizeof(short),1,f); - if (i) - return true; - // fprintf(f,"%s",g._SYMBptr->sommet.ptr()->s); - writefunc(g._SYMBptr->sommet.ptr()->s,1,strlen(g._SYMBptr->sommet.ptr()->s),f); - return true; - } - if (g.type==_FUNC){ - short i=archive_function_index(*g._FUNCptr); // equalposcomp(archive_function_tab(),*g._FUNCptr); - writefunc(&i,sizeof(short),1,f); - if (!i){ - // fprintf(f,"%s",g._FUNCptr->ptr()->s); - writefunc(g._FUNCptr->ptr()->s,1,strlen(g._FUNCptr->ptr()->s),f); - } - return true; - } - string s; - if (g.type==_ZINT) - s=hexa_print_ZINT(*g._ZINTptr); - else - s=g.print(contextptr); - // fprintf(f,"%s",s.c_str()); - writefunc(s.c_str(),1,s.size(),f); - return true; - //return false; - } - - - bool archive_save(void * f,const gen & g,GIAC_CONTEXT){ - return archive_save(f,g,(size_t (*)(void const* p, size_t nbBytes,size_t NbElements, void *file))fwrite,contextptr); - } - -#ifdef GIAC_HAS_STO_38 - // return true/false to tell if s is recognized. return the appropriate gen if true - int lexerCompare(void const *a, void const *b) { - charptr_gen_unary const * ptr=(charptr_gen_unary const *)b; - const char * aptr=(const char *) a; - return strcmp(aptr, ptr->s); - } - - bool casbuiltin(const char *s, gen &g){ - // binary search in builtin_lexer_functions -#if 1 // def SMARTPTR64 - int n=builtin_lexer_functions_number; - charptr_gen_unary const * f = (charptr_gen_unary const *)bsearch(s, builtin_lexer_functions, n, sizeof(builtin_lexer_functions[0]), lexerCompare); - if (f != NULL) { - g = 0; - int pos = int(f - builtin_lexer_functions); - size_t val = builtin_lexer_functions_[pos]; - unary_function_ptr * at_val = (unary_function_ptr *)val; - g = at_val; - if (builtin_lexer_functions[pos]._FUNC_%2){ -#ifdef SMARTPTR64 - unary_function_ptr tmp=*at_val; - tmp._ptr+=1; - g=tmp; -#else - g._FUNC_ +=1; -#endif // SMARTPTR64 - } - return true; - } -#else - charptr_gen_unary const * f = (charptr_gen_unary const *)bsearch(s, builtin_lexer_functions, builtin_lexer_functions_number, sizeof(builtin_lexer_functions[0]), lexerCompare); - if (f != NULL) { - g = gen(0); - int pos=f - builtin_lexer_functions; - *(size_t *)(&g) = builtin_lexer_functions_[pos] + f->_FUNC_; - g = gen(*g._FUNCptr); - return true; - } -#endif - if (strlen(s)==1 && s[0]==':'){ - g=at_deuxpoints; - return true; - } - return false; - } - -#endif - - // 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 g; - if (!readfunc(&g,sizeof(gen),1,f)) - return undef; - if (g.type<=_DOUBLE_ || g.type==_FLOAT_) - return g; - unsigned char t=g.type; - signed char s=g.subtype; - g.type=0; // required to avoid destructor of g to mess up the pointer part - unsigned size; - if (!readfunc(&size,sizeof(unsigned),1,f)) - return undef; - if (t==_CPLX || t==_MOD || t==_FRAC){ - gen g1=archive_restore(f,readfunc,contextptr); - gen g2=archive_restore(f,readfunc,contextptr); - if (t==_CPLX) - return g1+cst_i*g2; - if (t==_FRAC) - return fraction(g1,g2); - if (t==_MOD) - return makemodquoted(g1,g2); - } - size -= sizeof(gen)+sizeof(unsigned); // adjust for gen size and length - if (t==_VECT){ - unsigned short rows,cols; - if (!readfunc(&rows,sizeof(unsigned short),1,f)) - return undef; - if (!readfunc(&cols,sizeof(unsigned short),1,f)) - return undef; -// if (!rows) return undef; - vecteur v(rows); - for (int i=0;isecond; - else { - res=identificateur(sch); - syms()[sch]=res; - } - unlock_syms_mutex(); -#if DBG_ARCHIVE - std::ofstream ofs; - ofs.open ("e:\\tmp\\logrestore", std::ofstream::out | std::ofstream::app); - ofs << "IDNT " << res << '\n'; - ofs.close(); -#endif - return res; - } - if (t==_SYMB){ - gen fe=archive_restore(f,readfunc,contextptr); - short index; - if (!readfunc(&index,sizeof(short),1,f)) - return undef; - if (index>0){ - const unary_function_ptr * aptr=archive_function_tab(); - if (index p=equal_range(builtin_lexer_functions_begin(),builtin_lexer_functions_end(),std::pair(ch,0),tri); - if (p.first!=p.second && p.first!=builtin_lexer_functions_end()){ - res = p.first->second; - res.subtype=1; - res=gen(int((*builtin_lexer_functions_())[p.first-builtin_lexer_functions_begin()]+p.first->second.val)); - res=gen(*res._FUNCptr); - } - } -#else - if (builtin_lexer_functions_){ -#ifdef GIAC_HAS_STO_38 - if (!casbuiltin(ch,res)){ -#if DBG_ARCHIVE - std::ofstream ofs; - ofs.open ("e:\\tmp\\logrestore", std::ofstream::out | std::ofstream::app); - ofs << "archive_restore error _SYMB " << ch << '\n'; - ofs.close(); -#endif - res=0; - } -#else - std::pair p=equal_range(builtin_lexer_functions_begin(),builtin_lexer_functions_end(),std::pair(ch,0),tri); - if (p.first!=p.second && p.first!=builtin_lexer_functions_end()){ - res = p.first->second; - res.subtype=1; - res=gen(int(builtin_lexer_functions_[p.first-builtin_lexer_functions_begin()]+p.first->second.val)); - res=gen(*res._FUNCptr); - } -#endif - } -#endif - } - if (is_zero(res)){ -#if DBG_ARCHIVE - std::ofstream ofs; - ofs.open ("e:\\tmp\\logrestore", std::ofstream::out | std::ofstream::app); - ofs << "archive_restore error _SYMB 0 " << ch << '\n'; - ofs.close(); -#endif - res=gen(ch,contextptr); - } - delete [] ch; - if (res.type!=_FUNC){ - return undef; - } - g=symbolic(*res._FUNCptr,fe); - } - g.subtype=s; -#if DBG_ARCHIVE - std::ofstream ofs; - ofs.open ("e:\\tmp\\logrestore", std::ofstream::out | std::ofstream::app); - ofs << "SYMB " << g << '\n'; - ofs.close(); -#endif - return g; - } - if (t==_FUNC){ - short index; - if (!readfunc(&index,sizeof(short),1,f)) - return undef; - if (index>0) - g = archive_function_tab()[index-1]; - else { - size -= sizeof(short); - char * ch=new char[size+1]; - ch[size]=0; - if (readfunc(ch,1,size,f)!=size){ - delete [] ch; - return undef; - } - g = gen(ch,contextptr); - delete [] ch; - if (g.type!=_FUNC) - return undef; - } - g.subtype=s; - return g; - } - char * ch=new char[size+1]; - ch[size]=0; - if (readfunc(ch,1,size,f)!=size){ - delete [] ch; - return undef; - } - gen res; - if (t==_STRNG) - res=string2gen(ch,true); - else - res=gen(ch,contextptr); - delete [] ch; - return res; - } - - gen archive_restore(FILE * f,GIAC_CONTEXT){ - return archive_restore(f,(size_t (*)(void * p, size_t nbBytes,size_t NbElements, void *file))fread,contextptr); - } - - void init_geogebra(bool on,GIAC_CONTEXT){ -#ifndef FXCG - setlocale(LC_NUMERIC,"POSIX"); -#endif - _decimal_digits_=on?13:12; - _all_trig_sol_=on; - _withsqrt_=!on; - _calc_mode_=on?1:0; - _eval_equaltosto_=on?0:1; - eval_equaltosto(on?0:1,contextptr); - decimal_digits(on?13:12,contextptr); - all_trig_sol(on,contextptr); - withsqrt(!on,contextptr); - calc_mode(on?1:0,contextptr); - powlog2float=3e4; - MPZ_MAXLOG2=33300; -#ifdef TIMEOUT - //caseval_maxtime=5; - caseval_n=0; - caseval_mod=10; -#endif - } - - vecteur giac_current_status(bool save_history,GIAC_CONTEXT){ - // cas and geo config - vecteur res; - if (abs_calc_mode(contextptr)==38) - res.push_back(cas_setup(contextptr)); - else - res.push_back(symbolic(at_cas_setup,cas_setup(contextptr))); - res.push_back(xyztrange(gnuplot_xmin,gnuplot_xmax,gnuplot_ymin,gnuplot_ymax,gnuplot_zmin,gnuplot_zmax,gnuplot_tmin,gnuplot_tmax,global_window_xmin,global_window_xmax,global_window_ymin,global_window_ymax,show_axes(contextptr),class_minimum,class_size, -#ifdef WITH_GNUPLOT - gnuplot_hidden3d,gnuplot_pm3d -#else - 1,1 -#endif - )); - if (abs_calc_mode(contextptr)==38) - res.back()=res.back()._SYMBptr->feuille; - // session - res.push_back(save_history?history_in(contextptr):vecteur(0)); - res.push_back(save_history?history_out(contextptr):vecteur(0)); - // user variables - if (contextptr && contextptr->tabptr){ - sym_tab::const_iterator jt=contextptr->tabptr->begin(),jtend=contextptr->tabptr->end(); - for (;jt!=jtend;++jt){ - gen a=jt->second; - gen b=identificateur(jt->first); - res.push_back(symb_sto(a,b)); - } - } - else { - lock_syms_mutex(); - sym_string_tab::const_iterator it=syms().begin(),itend=syms().end(); - for (;it!=itend;++it){ - gen id=it->second; - if (id.type==_IDNT && id._IDNTptr->value) - res.push_back(symb_sto(*id._IDNTptr->value,id)); - } - unlock_syms_mutex(); - } - int xc=xcas_mode(contextptr); - if (xc==0 && python_compat(contextptr)) - xc=256*python_compat(contextptr); - if (abs_calc_mode(contextptr)==38) - res.push_back(xc); - else - res.push_back(symbolic(at_xcas_mode,xc)); - return res; - } - - bool unarchive_session(const gen & g,int level,const gen & replace,GIAC_CONTEXT,bool with_history){ - int l; - if (g.type!=_VECT || (l=int(g._VECTptr->size()))<4) - return false; - vecteur v=*g._VECTptr; - if (v[2].type!=_VECT || v[3].type!=_VECT || (v[2]._VECTptr->size()!=v[3]._VECTptr->size() && v[2]._VECTptr->size()!=v[3]._VECTptr->size()+1)) - return false; - if (v[2]._VECTptr->size()==v[3]._VECTptr->size()+1) - v[2]._VECTptr->pop_back(); -#ifndef DONT_UNARCHIVE_HISTORY - history_in(contextptr)=*v[2]._VECTptr; - history_out(contextptr)=*v[3]._VECTptr; -#ifndef GNUWINCE - if (v[0].type==_VECT) - _cas_setup(v[0],contextptr); - else - protecteval(v[0],eval_level(contextptr),contextptr); - if (v[1].type==_VECT) - _xyztrange(v[1],contextptr); - else - protecteval(v[1],eval_level(contextptr),contextptr); -#endif -#endif - // restore variables - for (int i=4;i=0 - if (level<0 || level>=l){ - history_in(contextptr).push_back(replace); - history_out(contextptr).push_back(protecteval(replace,eval_level(contextptr),contextptr)); - } - else { - history_in(contextptr)[level]=replace; - for (int i=level;i= begin and < end - for (;;){ - cur=(beg+end)/2; - test=strcmp(s,tab[cur]); - if (!test) - return cur; - if (cur==beg) - return -1; - if (test>0) - beg=cur; - else - end=cur; - } - return -1; - } - - gen add_autosimplify(const gen & g,GIAC_CONTEXT){ - if (g.type==_VECT) - return apply(g,add_autosimplify,contextptr); - if (g.type==_SYMB){ - if (g._SYMBptr->sommet==at_program) - return g; -#ifdef GIAC_HAS_STO_38 - const char * c=g._SYMBptr->sommet.ptr()->s; -#else - string ss=g._SYMBptr->sommet.ptr()->s; - if (g._SYMBptr->sommet==at_sto && g._SYMBptr->feuille.type==_VECT){ - vecteur & v=*g._SYMBptr->feuille._VECTptr; - if (v.size()==2 && v.front().type==_SYMB) - ss=v.front()._SYMBptr->sommet.ptr()->s; - } - ss=unlocalize(ss); - const char * c=ss.c_str(); -#endif -#if 1 - if (dichotomic_search(do_not_autosimplify,sizeof(do_not_autosimplify)/sizeof(char*)-1,c)!=-1) - return g; -#else - const char ** ptr=do_not_autosimplify; - for (;*ptr;++ptr){ - if (!strcmp(*ptr,c)) - return g; - } -#endif - } - std::string s=autosimplify(contextptr); - if (s.size()<1 || s=="'nop'") - return g; - gen a(s,contextptr); - if (a.type==_FUNC) - return symbolic(*a._FUNCptr,g); - if (a.type>=_IDNT) - return symb_of(a,g); - return g; - } - - bool csv_guess(const char * data,int count,char & sep,char & nl,char & decsep){ - bool ans=true; - int nb[256],pointdecsep=0,commadecsep=0; - for (int i=0;i<256;++i) - nb[i]=0; - // count occurrence of each char - // and detect decimal separator between . or , - for (int i=1;i='0' && data[i-1]<='9' && data[i+1]>='0' && data[i+1]<='9'){ - if (data[i]=='.') - ++pointdecsep; - if (data[i]==',') - ++commadecsep; - } - } - decsep=commadecsep>pointdecsep?',':'.'; - // detect nl (ctrl-M or ctrl-J) - nl=nb[10]>nb[13]?10:13; - // find in control characters and : ; the most used (except 10/13) - int nbmax=0,imax=-1; - for (int i=0;i<60;++i){ - if (i==10 || i==13 || (i>=' ' && i<='9') ) - continue; - if (nb[i]>nbmax){ - imax=i; - nbmax=nb[i]; - } - } - // compare . with , (44) - if (nb[unsigned(',')] && nb[unsigned(',')]>=nbmax){ - imax=','; - nbmax=nb[unsigned(',')]; - } - if (nbmax && nbmax>=nb[unsigned(nl)] && imax!=decsep) - sep=imax; - else - sep=' '; - return ans; - } - - void (*my_gprintf)(unsigned special,const string & format,const vecteur & v,GIAC_CONTEXT)=0; - - -#if defined(EMCC) || defined(EMCC2) - static void newlinestobr(string &s,const string & add){ - int l=int(add.size()); - for (int i=0;i=int(format.size())) - break; - newlinestobr(s,format.substr(pos,p-pos)); -#if defined(EMCC) || defined(EMCC2) - gen tmp; - if (v[i].is_symb_of_sommet(at_pnt)) - tmp=_svg(v[i],contextptr); - else - tmp=_mathml(makesequence(v[i],1),contextptr); - s = s+((tmp.type==_STRNG)?(*tmp._STRNGptr):v[i].print(contextptr)); -#else - s += v[i].print(contextptr); -#endif - pos=p+4; - } - newlinestobr(s,format.substr(pos,format.size()-pos)); - *logptr(contextptr) << s << '\n'; -#if defined(EMCC) || defined(EMCC2) - *logptr(contextptr) << char(3) << '\n'; // end mixed text/mathml - *logptr(contextptr) << '\n'; -#endif - } - - void gprintf(const string & format,const vecteur & v,GIAC_CONTEXT){ - gprintf(step_nothing_special,format,v,contextptr); - } - - void gprintf(const string & format,const vecteur & v,int step_info,GIAC_CONTEXT){ - gprintf(step_nothing_special,format,v,step_info,contextptr); - } - - // moved from input_lexer.ll for easier debug - const char invalid_name[]="Invalid name"; - -#if defined USTL || defined GIAC_HAS_STO_38 || (defined KHICAS && !defined(SIMU)) -#if defined GIAC_HAS_STO_38 || defined KHICAS -void update_lexer_localization(const std::vector & v,std::map &lexer_map,std::multimap &back_lexer_map,GIAC_CONTEXT){} -#endif -#else - vecteur * keywords_vecteur_ptr(){ - static vecteur v; - return &v; - } - - static void in_update_lexer_localization(istream & f,int lang,const std::vector & v,std::map &lexer_map,std::multimap &back_lexer_map,GIAC_CONTEXT){ - char * line = (char *)malloc(1024); - std::string giac_kw,local_kw; - size_t l; - for (;;){ - f.getline(line,1023,'\n'); - l=strlen(line); - if (f.eof()){ - break; - } - if (l>3 && line[0]!='#'){ - if (line[l-1]=='\n') - --l; - // read giac keyword - size_t j; - giac_kw=""; - for (j=0;jpush_back(localgen); - sto(gen(giac_kw,contextptr),localgen,contextptr); -#else - lexer_map[local_kw]=giac_kw; - back_lexer_map.insert(pair(giac_kw,localized_string(lang,local_kw))); -#endif - } - local_kw=""; - } - else - local_kw += line[j]; - } - if (!local_kw.empty()){ -#if defined(EMCC) || defined(EMCC2) - gen localgen(gen(local_kw,contextptr)); - keywordsptr->push_back(localgen); - sto(gen(giac_kw,contextptr),localgen,contextptr); -#else - lexer_map[local_kw]=giac_kw; - back_lexer_map.insert(pair(giac_kw,localized_string(lang,local_kw))); -#endif - } - } - } - free(line); - } - - void update_lexer_localization(const std::vector & v,std::map &lexer_map,std::multimap &back_lexer_map,GIAC_CONTEXT){ - lexer_map.clear(); - back_lexer_map.clear(); - int s=int(v.size()); - for (int i=0;i=1 && lang<=4){ - std::string doc=find_doc_prefix(lang); - std::string file=giac_aide_dir()+doc+"keywords"; - //COUT << "keywords " << file << '\n'; - ifstream f(file.c_str()); - if (f.good()){ - in_update_lexer_localization(f,lang,v,lexer_map,back_lexer_map,contextptr); - // COUT << "// Using keyword file " << file << '\n'; - } // if (f) - else { - if (lang==1){ -#ifdef HAVE_SSTREAM - istringstream f( -#else - istrstream f( -#endif - "# enter couples\n# giac_keyword translation\n# for example, to define integration as a translation for integrate \nintegrate integration\neven est_pair\nodd est_impair\n# geometry\nbarycenter barycentre\nisobarycenter isobarycentre\nmidpoint milieu\nline_segments aretes\nmedian_line mediane\nhalf_line demi_droite\nparallel parallele\nperpendicular perpendiculaire\ncommon_perpendicular perpendiculaire_commune\nenvelope enveloppe\nequilateral_triangle triangle_equilateral\nisosceles_triangle triangle_isocele\nright_triangle triangle_rectangle\nlocus lieu\ncircle cercle\nconic conique\nreduced_conic conique_reduite\nquadric quadrique\nreduced_quadric quadrique_reduite\nhyperbola hyperbole\ncylinder cylindre\nhalf_cone demi_cone\nline droite\nplane plan\nparabola parabole\nrhombus losange\nsquare carre\nhexagon hexagone\npyramid pyramide\nquadrilateral quadrilatere\nparallelogram parallelogramme\northocenter orthocentre\nexbisector exbissectrice\nparallelepiped parallelepipede\npolyhedron polyedre\ntetrahedron tetraedre\ncentered_tetrahedron tetraedre_centre\ncentered_cube cube_centre\noctahedron octaedre\ndodecahedron dodecaedre\nicosahedron icosaedre\nbisector bissectrice\nperpen_bisector mediatrice\naffix affixe\naltitude hauteur\ncircumcircle circonscrit\nexcircle exinscrit\nincircle inscrit\nis_prime est_premier\nis_equilateral est_equilateral\nis_rectangle est_rectangle\nis_parallel est_parallele\nis_perpendicular est_perpendiculaire\nis_orthogonal est_orthogonal\nis_collinear est_aligne\nis_concyclic est_cocyclique\nis_element est_element\nis_included est_inclus\nis_coplanar est_coplanaire\nis_isosceles est_isocele\nis_square est_carre\nis_rhombus est_losange\nis_parallelogram est_parallelogramme\nis_conjugate est_conjugue\nis_harmonic_line_bundle est_faisceau_droite\nis_harmonic_circle_bundle est_faisceau_cercle\nis_inside est_dans\narea aire\nperimeter perimetre\ndistance longueur\ndistance2 longueur2\nareaat aireen\nslopeat penteen\nangleat angleen\nperimeterat perimetreen\ndistanceat distanceen\nareaatraw aireenbrut\nslopeatraw penteenbrut\nangleatraw angleenbrut\nperimeteratraw perimetreenbrut\ndistanceatraw distanceenbrut\nextract_measure extraire_mesure\ncoordinates coordonnees\nabscissa abscisse\nordinate ordonnee\ncenter centre\nradius rayon\npowerpc puissance\nvertices sommets\npolygon polygone\nisopolygon isopolygone\nopen_polygon polygone_ouvert\nhomothety homothetie\nsimilarity similitude\n# affinity affinite\nreflection symetrie\nreciprocation polaire_reciproque\nscalar_product produit_scalaire\n# solid_line ligne_trait_plein\n# dash_line ligne_tiret\n# dashdot_line ligne_tiret_point\n# dashdotdot_line ligne_tiret_pointpoint\n# cap_flat_line ligne_chapeau_plat\n# cap_round_line ligne_chapeau_rond\n# cap_square_line ligne_chapeau_carre\n# line_width_1 ligne_epaisseur_1\n# line_width_2 ligne_epaisseur_2\n# line_width_3 ligne_epaisseur_3\n# line_width_4 ligne_epaisseur_4\n# line_width_5 ligne_epaisseur_5\n# line_width_6 ligne_epaisseur_6\n# line_width_7 ligne_epaisseur_7\n# line_width_8 ligne_epaisseur_8\n# rhombus_point point_losange\n# plus_point point_plus\n# square_point point_carre\n# cross_point point_croix\n# triangle_point point_triangle\n# star_point point_etoile\n# invisible_point point_invisible\ncross_ratio birapport\nradical_axis axe_radical\npolar polaire\npolar_point point_polaire\npolar_coordinates coordonnees_polaires\nrectangular_coordinates coordonnees_rectangulaires\nharmonic_conjugate conj_harmonique\nharmonic_division div_harmonique\ndivision_point point_div\n# harmonic_division_point point_division_harmonique\ndisplay affichage\nvertices_abc sommets_abc\nvertices_abca sommets_abca\nline_inter inter_droite\nsingle_inter inter_unique\ncolor couleur\nlegend legende\nis_harmonic est_harmonique\nbar_plot diagramme_batons\nbarplot diagrammebatons\nhistogram histogramme\nprism prisme\nis_cospherical est_cospherique\ndot_paper papier_pointe\ngrid_paper papier_quadrille\nline_paper papier_ligne\ntriangle_paper papier_triangule\nvector vecteur\nplotarea tracer_aire\nplotproba graphe_probabiliste\nmult_c_conjugate mult_conjugue_C\nmult_conjugate mult_conjugue\ncanonical_form forme_canonique\nibpu integrer_par_parties_u\nibpdv integrer_par_parties_dv\nwhen quand\nslope pente\ntablefunc table_fonction\ntableseq table_suite\nfsolve resoudre_numerique\ninput saisir\nprint afficher\nassume supposons\nabout domaine\nbreakpoint point_arret\nwatch montrer\nrmwatch ne_plus_montrer\nrmbreakpoint suppr_point_arret\nrand alea\nInputStr saisir_chaine\nOx_2d_unit_vector vecteur_unitaire_Ox_2d\nOy_2d_unit_vector vecteur_unitaire_Oy_2d\nOx_3d_unit_vector vecteur_unitaire_Ox_3d\nOy_3d_unit_vector vecteur_unitaire_Oy_3d\nOz_3d_unit_vector vecteur_unitaire_Oz_3d\nframe_2d repere_2d\nframe_3d repere_3d\nrsolve resoudre_recurrence\nassume supposons\ncumulated_frequencies frequences_cumulees\nfrequencies frequences\nnormald loi_normale\nregroup regrouper\nosculating_circle cercle_osculateur\ncurvature courbure\nevolute developpee\nvector vecteur\n"); - in_update_lexer_localization(f,1,v,lexer_map,back_lexer_map,contextptr); - } - else - CERR << "// Unable to find keyword file " << file << '\n'; - } - } - } - } -#endif - -#if !defined NSPIRE - -#include "input_parser.h" - - bool has_special_syntax(const char * s){ -#ifdef USTL - ustl::pair p= - ustl::equal_range(builtin_lexer_functions_begin(),builtin_lexer_functions_end(), - std::pair(s,0), - tri); -#else - std::pair p= - equal_range(builtin_lexer_functions_begin(),builtin_lexer_functions_end(), - std::pair(s,0), - tri); -#endif - if (p.first!=p.second && p.first!=builtin_lexer_functions_end()) - return (p.first->second.subtype!=T_UNARY_OP-256); - map_charptr_gen::const_iterator i = lexer_functions().find(s); - if (i==lexer_functions().end()) - return false; - return (i->second.subtype!=T_UNARY_OP-256); - } - - bool lexer_functions_register(const unary_function_ptr & u,const char * s,int parser_token){ - map_charptr_gen::const_iterator i = lexer_functions().find(s); - if (i!=lexer_functions().end()) - return false; - if (doing_insmod){ - if (debug_infolevel) CERR << "insmod register " << s << '\n'; - registered_lexer_functions().push_back(user_function(s,parser_token)); - } - if (!builtin_lexer_functions_sorted){ -#ifndef STATIC_BUILTIN_LEXER_FUNCTIONS -#if defined NSPIRE_NEWLIB || defined KHICAS || defined NUMWORKS - builtin_lexer_functions_begin()[builtin_lexer_functions_number]=std::pair(s,gen(u)); -#else - builtin_lexer_functions_begin()[builtin_lexer_functions_number].first=s; - builtin_lexer_functions_begin()[builtin_lexer_functions_number].second.type=0; - builtin_lexer_functions_begin()[builtin_lexer_functions_number].second=gen(u); -#endif - if (parser_token==1) - builtin_lexer_functions_begin()[builtin_lexer_functions_number].second.subtype=T_UNARY_OP-256; - else - builtin_lexer_functions_begin()[builtin_lexer_functions_number].second.subtype=parser_token-256; - builtin_lexer_functions_number++; -#endif - if (debug_infolevel) CERR << "insmod register builtin " << s << '\n'; - } - else { - lexer_functions()[s] = gen(u); - if (parser_token==1) - lexer_functions()[s].subtype=T_UNARY_OP-256; - else - lexer_functions()[s].subtype=parser_token-256; - if (debug_infolevel) CERR << "insmod register lexer_functions " << s << '\n'; - } - // If s is a library function name (with ::), update the library - int ss=int(strlen(s)),j=0; - for (;j >::iterator it=library_functions().find(libname); -#else - std::map >::iterator it=library_functions().find(libname); -#endif - if (it!=library_functions().end()) - it->second.push_back(funcname); - else - library_functions()[libname]=vector(1,funcname); - } - return true; - } - - bool lexer_function_remove(const vector & v){ - vector::const_iterator it=v.begin(),itend=v.end(); - map_charptr_gen::const_iterator i,iend; - bool ok=true; - for (;it!=itend;++it){ - i = lexer_functions().find(it->s.c_str()); - iend=lexer_functions().end(); - if (i==iend) - ok=false; - else - lexer_functions().erase(it->s.c_str()); - } - return ok; - } - - int find_or_make_symbol(const string & s,gen & res,void * scanner,bool check38,GIAC_CONTEXT){ - int tmpo=opened_quote(contextptr); - if (tmpo & 2) - check38=false; - if (s.size()==1){ -#ifdef GIAC_HAS_STO_38 - if (0 && s[0]>='a' && s[0]<='z'){ - index_status(contextptr)=1; - res=*tab_one_letter_idnt[s[0]-'a']; - return T_SYMBOL; - } - if (check38 && s[0]>='a' && s[0]<='z' && calc_mode(contextptr)==38) - giac_yyerror(scanner,invalid_name); -#else - if (s[0]>='a' && s[0]<='z'){ - if (check38 && calc_mode(contextptr)==38) - giac_yyerror(scanner,invalid_name); - index_status(contextptr)=1; - res=*tab_one_letter_idnt[s[0]-'a']; - return T_SYMBOL; - } -#endif - switch (s[0]){ - case '+': - res=at_plus; - return T_UNARY_OP; - case '-': - res=at_neg; - return T_UNARY_OP; - case '*': - res=at_prod; - return T_UNARY_OP; - case '/': - res=at_division; - return T_UNARY_OP; - case '^': - res=at_pow; - return T_UNARY_OP; - } - } - string ts(s); -#ifdef USTL - ustl::map::const_iterator trans=lexer_localization_map().find(ts); - if (trans!=lexer_localization_map().end()) - ts=trans->second; - ustl::map >::const_iterator j=lexer_translator().find(ts); - if (j!=lexer_translator().end() && !j->second.empty()) - ts=j->second.back(); - ustl::pair p=ustl::equal_range(builtin_lexer_functions_begin(),builtin_lexer_functions_end(),std::pair(ts.c_str(),0),tri); -#else - std::map::const_iterator trans=lexer_localization_map().find(ts); - if (trans!=lexer_localization_map().end()) - ts=trans->second; - std::map >::const_iterator j=lexer_translator().find(ts); - if (j!=lexer_translator().end() && !j->second.empty()) - ts=j->second.back(); - std::pair p=equal_range(builtin_lexer_functions_begin(),builtin_lexer_functions_end(),std::pair(ts.c_str(),0),tri); -#endif - if (p.first!=p.second && p.first!=builtin_lexer_functions_end()){ - if (p.first->second.subtype==T_TO-256) - res=plus_one; - else - res = p.first->second; - res.subtype=1; - if (builtin_lexer_functions_){ -#ifdef NSPIRE - res=gen(int((*builtin_lexer_functions_())[p.first-builtin_lexer_functions_begin()]+p.first->second.val)); - res=gen(*res._FUNCptr); -#else -#if !defined NSPIRE_NEWLIB || defined KHICAS - res=0; - int pos=int(p.first-builtin_lexer_functions_begin()); -#if defined KHICAS && !defined x86_64 - const unary_function_ptr * at_val=*builtin_lexer_functions_[pos]; -#else - size_t val=builtin_lexer_functions_[pos]; - unary_function_ptr * at_val=(unary_function_ptr *)val; -#endif - res=at_val; -#if defined GIAC_HAS_STO_38 || (defined KHICAS && defined DEVICE) - if (builtin_lexer_functions[pos]._FUNC_%2){ -#ifdef SMARTPTR64 - unary_function_ptr tmp=*at_val; - tmp._ptr+=1; - res=tmp; -#else - res._FUNC_ +=1; -#endif // SMARTPTR64 - } -#endif // GIAC_HAS_STO_38 -#else // keep this code, required for the nspire otherwise evalf(pi)=reboot - res=gen(int(builtin_lexer_functions_[p.first-builtin_lexer_functions_begin()]+p.first->second.val)); - res=gen(*res._FUNCptr); -#endif -#endif - } - index_status(contextptr)=(p.first->second.subtype==T_UNARY_OP-256); - int token=p.first->second.subtype; - token += (token<0)?512:256 ; - return token; - } - lexer_tab_int_type tst={ts.c_str(),0,0,0,0}; -#ifdef USTL - ustl::pair pp = ustl::equal_range(lexer_tab_int_values,lexer_tab_int_values_end,tst,tri1); -#else - std::pair pp = equal_range(lexer_tab_int_values,lexer_tab_int_values_end,tst,tri1); -#endif - if (pp.first!=pp.second && pp.first!=lexer_tab_int_values_end){ - index_status(contextptr)=pp.first->status; - res=int(pp.first->value); - res.subtype=pp.first->subtype; - return pp.first->return_value; - } - // CERR << "lexer_functions search " << ts << '\n'; - map_charptr_gen::const_iterator i = lexer_functions().find(ts.c_str()); - if (i!=lexer_functions().end()){ - // CERR << "lexer_functions found " << ts << '\n'; - if (i->second.subtype==T_TO-256) - res=plus_one; - else - res = i->second; - res.subtype=1; - index_status(contextptr)=(i->second.subtype==T_UNARY_OP-256); - return i->second.subtype+256 ; - } - lock_syms_mutex(); - sym_string_tab::const_iterator i2 = syms().find(s),i2end=syms().end(); - if (i2 == i2end) { - unlock_syms_mutex(); - const char * S = s.c_str(); - // std::CERR << "lexer new" << s << '\n'; - if (check38 && calc_mode(contextptr)==38 && strcmp(S,string_pi) && strcmp(S,string_euler_gamma) && strcmp(S,string_infinity) && strcmp(S,string_undef) && S[0]!='G'&& (!is_known_name_38 || !is_known_name_38(0,S))){ - // detect invalid names and implicit multiplication - size_t ss=strlen(S); - vecteur args; - for (size_t i=0;i='E' && ch<='H') || ch=='L' || ch=='M' || ch=='R' - /* || ch=='S' */ - || ch=='U' || ch=='V' || (ch>='X' && ch<='Z') ){ - string name; - name += ch; - char c=0; - if (i='0' && c<='9'){ - name += c; - ++i; - } - res = identificateur(name); - lock_syms_mutex(); - syms()[name] = res; - unlock_syms_mutex(); - args.push_back(res); - } - else { - string coeff; - for (++i;i32 && isalpha(s[i])){ - --i; - break; - } - if (scanner && (s[i]<0 || s[i]>'z')){ - giac_yyerror(scanner,invalid_name); - res=undef; - return T_SYMBOL; - } - coeff += s[i]; - } - if (coeff.empty()) - res=1; - else - res=strtod(coeff.c_str(),0); - if (ch=='i') - res=res*cst_i; - else { - if (ch=='e') - res=std::exp(1.0)*res; - else { - // Invalid ident name, report error - if ( (ch>'Z' || ch<0) && scanner){ - giac_yyerror(scanner,invalid_name); - res=undef; - return T_SYMBOL; - } - coeff=string(1,ch); - gen tmp = identificateur(coeff); - // syms()[coeff.c_str()]=tmp; - res=res*tmp; - } - } - args.push_back(res); - } - } - if (args.size()==1) - res=args.front(); - else - res=_prod(args,contextptr); - lock_syms_mutex(); - syms()[s]=res; - unlock_syms_mutex(); - return T_SYMBOL; - } // end 38 compatibility mode - res = identificateur(s); - lock_syms_mutex(); - syms()[s] = res; - unlock_syms_mutex(); - return T_SYMBOL; - } // end if ==syms.end() - res = i2->second; - unlock_syms_mutex(); - return T_SYMBOL; - } - - // Add to the list of predefined symbols - void set_lexer_symbols(const vecteur & l,GIAC_CONTEXT){ - if (initialisation_done(contextptr)) - return; - initialisation_done(contextptr)=true; - const_iterateur it=l.begin(),itend=l.end(); - for (; it!=itend; ++it) { - if (it->type!=_IDNT) - continue; - lock_syms_mutex(); - sym_string_tab::const_iterator i = syms().find(it->_IDNTptr->id_name),iend=syms().end(); - if (i==iend) - syms()[it->_IDNTptr->name()] = *it; - unlock_syms_mutex(); - } - } - - string replace(const string & s,char c1,char c2){ - string res; - int l=s.size(); - res.reserve(l); - const char * ch=s.c_str(); - for (int i=0;i=int(res.size())) - break; - int pos2=res.find(pattern,pos1+3); - if (pos2<0 || pos2+3>=int(res.size())) - break; - if (rep) - res=res.substr(0,pos1)+'"'+replace(res.substr(pos1+3,pos2-pos1-3),'\n',' ')+'"'+res.substr(pos2+3,res.size()-pos2-3); - else - res=res.substr(0,pos1)+res.substr(pos2+3,res.size()-pos2-3); - } - return res; - } - - struct int_string { - int decal; - std::string endbloc; - int_string():decal(0){} - int_string(int i,string s):decal(i),endbloc(s){} - }; - - static bool instruction_at(const string & s,int pos,int shift){ - if (pos && isalphan(s[pos-1])) - return false; - if (pos+shift=0 && posif1) - cur[pos]='%'; - } - } - - string glue_lines_backslash(const string & s){ - int ss=s.size(); - int i=s.find('\\'); - if (i<0 || i>=ss) - return s; - string res,line; - for (i=0;i=0;--j){ - if (line[j]!=' ') - break; - } - if (line[j]!='\\' || (j && line[j-1]=='\\')){ - res += line+'\n'; - line =""; - } - else - line=line.substr(0,j); - } - return res+line; - } - - static void python_import(string & cur,int cs,int posturtle,int poscmath,int posmath,int posnumpy,int posmatplotlib,GIAC_CONTEXT){ - if (posmatplotlib>=0 && posmatplotlib=0 && posnumpy=0 && posturtle=0 && poscmath=0 && posmath - // int is the number of white spaces at the start of the next line - // def ... : -> function [ffunction] - // for ... : -> for ... do [od] - // while ... : -> while ... do [od] - // if ...: -> if ... then [fi] - // else: -> else [nothing in stack] - // elif ...: -> elif ... then [nothing in stack] - // try: ... except: ... - std::string python2xcas(const std::string & s_orig,GIAC_CONTEXT){ - if (xcas_mode(contextptr)>0 && abs_calc_mode(contextptr)!=38) - return s_orig; - // quick check for python-like syntax: search line ending with : - int first=0,sss=s_orig.size(); - first=s_orig.find("maple_mode"); - if (first>=0 && first=0 && first=sss){ - first=s_orig.find('\''); // derivative or Python string delimiter? - if (first>=0 && first=sss) - return s_orig; - } - } - bool pythoncompat=python_compat(contextptr); - bool pythonmode=false; - first=0; - if (sss>19 && s_orig.substr(first,17)=="add_autosimplify(") - first+=17; - if (s_orig[first]=='/' ) - return s_orig; - //if (sss>first+2 && s_orig[first]=='@' && s_orig[first+1]!='@') return s_orig.substr(first+1,sss-first-1); - if (sss>first+2 && s_orig.substr(first,2)=="@@"){ - pythonmode=true; - pythoncompat=true; - } - if (s_orig[first]=='#' || (s_orig[first]=='_' && !isalpha(s_orig[first+1])) || s_orig.substr(first,4)=="from" || s_orig.substr(first,7)=="import " || s_orig.substr(first,4)=="def "){ - pythonmode=true; - pythoncompat=true; - } - if (pythoncompat){ - int pos=s_orig.find("{"); - if (pos>=0 && pos=0 && pos=0 && pos=0 && pos=0 && pos=0 && pos=0 && pos=0 && pos=sss){ - first=s_orig.find(':',first); - if (first<0 || first>=sss){ - return s_orig; // not Python like - } - } - pos=s_orig.find("lambda"); - if (pos>=0 && pos=sss) - endl=sss; - ++first; - if (first18 && res.substr(0,17)=="add_autosimplify(" - && res[res.size()-1]==')' - ) - res=res.substr(17,res.size()-18); - if (res.size()>2 && res.substr(0,2)=="@@") - res=res.substr(2,res.size()-2); - res=remove_comment(res,"\"\"\"",true); - res=remove_comment(res,"'''",true); - res=glue_lines_backslash(res); - vector stack; - string s,cur; - s.reserve(res.capacity()); - if (pythoncompat) pythonmode=true; - for (;res.size();){ - int pos=-1; - bool cherche=true; - for (;cherche;){ - pos=res.find('\n',pos+1); - if (pos<0 || pos>=int(res.size())) - break; - cherche=false; - char ch=0; - // check if we should skip to next newline, look at previous non space - for (int pos2=0;pos2=0;--pos2){ - ch=res[pos2]; - if (ch!=' ' && ch!=9 && ch!='\r'){ - if (ch=='{' || ch=='[' || ch==',' || ch=='-' || ch=='+' || ch=='/'){ - if (pos2>0 && (ch=='+' || ch=='-') && ch==res[pos2-1]) - ; - else - cherche=true; - } - break; - } - } - for (size_t pos2=pos+1;pos2=int(res.size())){ - cur=res; res=""; - } - else { - cur=res.substr(0,pos); // without \n - res=res.substr(pos+1,res.size()-pos-1); - } - // detect comment (outside of a string) and lambda expr:expr - bool instring=false,chkfrom=true; - for (pos=0;pos0 && p'9') - str=true; - if (p-q>=minchar_for_quote_as_string(contextptr)) - str=true; - for (;!str && qpos+8 && (cur.substr(pos,8)=="# local " || cur.substr(pos,7)=="#local ")){ - cur.erase(cur.begin()+pos); - if (cur[pos]==' ') - cur.erase(cur.begin()+pos); - } - else - cur=cur.substr(0,pos); - pythonmode=true; - break; - } - // skip from * import * - if (chkfrom && ch=='f' && pos+15=int(cur.size())) - posi = cur.find(" import*"); - if (posi>pos+5 && posi=cur.size()) - posmatplotlib=cur.find("pylab"); - int cs=int(cur.size()); - pythonmode=true; -#ifdef KHICAS - if ( - (posturtle<0 || posturtle>=cs) && - (poscmath<0 || poscmath>=cs) && - (posmath<0 || posmath>=cs) && - (posnumpy<0 || posnumpy>=cs) && - (posmatplotlib<0 || posmatplotlib>=cs) - ){ - string filename=cur.substr(pos+5,posi-pos-5)+".py"; - // CERR << "import " << filename << endl; - const char * ptr=read_file(filename.c_str()); - if (ptr) - s += python2xcas(ptr,contextptr); // recursive call - cur =""; - // CERR << s << endl; - continue; - } - else -#endif - { - cur=cur.substr(0,pos); - python_import(cur,cs,posturtle,poscmath,posmath,posnumpy,posmatplotlib,contextptr); - } - break; - } - } - chkfrom=false; - // import * as ** -> **:=* - if (ch=='i' && pos+7=cur.size()) - posmatplotlib=cur.find("pylab"); - int cs=int(cur.size()); - int posi=cur.find(" as "); - int posp=cur.find('.'); - if (posp>=posi || posp<0) - posp=posi; - if (posi>pos+5 && posipos+7 && posdot"+cur.substr(posdot+1,cur.size()-posdot-1); - } - } - if (ch=='e' && pos+4=0;--pos){ - if (cur[pos]!=' ' && cur[pos]!=char(9) && cur[pos]!='\r') - break; - } - if (pos<0){ - s+='\n'; - continue; - } - if (cur[pos]!=':'){ // detect oneliner and function/fonction - int p; - for (p=0;p0;--p){ - if (instr){ - if (cur[p]=='"' && cur[p-1]!='\\') - instr=false; - continue; - } - if (cur[p]==':' && (cur[p+1]!=';' && cur[p+1]!='=')) - break; - if (cur[p]=='"' && cur[p-1]!='\\') - instr=true; - } - if (p==0){ - // = or return expr if cond else alt_expr => ifte(cond,expr,alt_expr) - int cs=int(cur.size()); - int elsepos=cur.find("else"); - if (elsepos>0 && elsepos0 && ifpos=cs){ - retpos=cur.find("="); - endretpos=retpos+1; - } - if (retpos>=0 && retpos0){ - int cs=int(cur.size()),q=4; - int progpos=cur.find("elif");; - if (progpos<0 || progpos>=cs){ - progpos=cur.find("if"); - q=2; - } - if (p>progpos && progpos>=0 && progposprogpos && progpos>=0 && progposprogpos && progpos>=0 && progposprogpos && progpos>=0 && progposprogpos && progpos>=0 && progpos=0 && progpos1){ - int indent=stack[stack.size()-1].decal; - if (ws1 && stack[stack.size()-1].decal>ws){ - s += ' '+stack.back().endbloc+';'; - stack.pop_back(); - } - if (nl) - s += '\n'; - } - } - s += cur.substr(0,pos)+"\n"; - continue; - } - progpos=cur.find("except"); - if (progpos>=0 && progpos1){ - int indent=stack[stack.size()-1].decal; - if (ws1 && stack[stack.size()-1].decal>ws){ - s += ' '+stack.back().endbloc+';'; - stack.pop_back(); - } - if (nl) - s += '\n'; - } - } - s += cur.substr(0,progpos)+"then\n"; - continue; - } - progpos=cur.find("elif"); - if (progpos>=0 && progpos1){ - int indent=stack[stack.size()-1].decal; - if (ws1 && stack[stack.size()-1].decal>ws){ - s += ' '+stack.back().endbloc+';'; - stack.pop_back(); - } - if (nl) - s += '\n'; - } - } - cur=cur.substr(0,pos); - convert_python(cur,contextptr); - s += cur+" then\n"; - continue; - } - } - if (!stack.empty()){ - int indent=stack.back().decal; - if (ws<=indent){ - // remove last \n and add explicit endbloc delimiters from stack - int ss=s.size(); - bool nl= ss && s[ss-1]=='\n'; - if (nl) - s=s.substr(0,ss-1); - while (!stack.empty() && stack.back().decal>=ws){ - int sb=stack.back().decal; - s += ' '+stack.back().endbloc+';'; - stack.pop_back(); - // indent must match one of the saved indent - if (sb!=ws && !stack.empty() && stack.back().decal=0 && progpos=0 && progpos=0 && progpos for x_ - cur=cur.substr(0,pos); - if (progpos+5=0 && progpos=0 && progpos ... and : - string entete=cur.substr(progpos+3,pos-progpos-3); - int posfleche=entete.find("->"); - if (posfleche>0 || posfleche=0 && curpos!=';' && curpos!=',' && curpos!='{' && curpos!='(' && curpos!='[' && curpos!=':' && curpos!='+' && curpos!='-' && curpos!='*' && curpos!='/' && curpos!='%') - cur = cur +';'; - if (pythonmode) - convert_python(cur,contextptr); - cur = cur +'\n'; - s = s+cur; - } - } - while (!stack.empty()){ - s += ' '+stack.back().endbloc+';'; - stack.pop_back(); - } - if (pythonmode){ - char ch; - while (s.size()>1 && - ( ((ch=s[s.size()-1])==';' && s[s.size()-2]!=':') || (ch=='\n')) - ) - s=s.substr(0,s.size()-1); - // replace ;) by ) - for (int i=s.size()-1;i>=2;--i){ - if (s[i]==')' && s[i-1]=='\n' && s[i-2]==';'){ - s.erase(s.begin()+i-2); - break; - } - } - if (s.size()>10 && s.substr(s.size()-9,9)=="ffunction") - s += ":;"; - else { - int pos=s.find('\n'); - if (pos>=0 && pos * builtin_lexer_functions_(){ - static vector * res=0; - if (res) return res; - res = new vector; - res->reserve(builtin_lexer_functions_number+1); -#include "static_lexer_at.h" - return res; - } -#else - // Array added because GH compiler stores builtin_lexer_functions in RAM -#if defined KHICAS || defined NSPIRE_NEWLIB - const unary_function_ptr * const * const builtin_lexer_functions_[]={ -#include "static_lexer__numworks.h" - }; -#else - const size_t builtin_lexer_functions_[]={ -#if defined(GIAC_HAS_STO_38) && defined(CAS38_DISABLED) -#include "static_lexer_38_.h" -#else -#include "static_lexer_.h" -#endif - }; -#endif // KHICAS -#endif // STATIC_BUILTIN - -#ifdef SMARTPTR64 - charptr_gen * builtin_lexer_functions64(){ - static charptr_gen * ans=0; - if (!ans){ - ans = new charptr_gen[builtin_lexer_functions_number]; - for (unsigned i=0;i> 16); -#endif - } -#endif - delete ®istered_lexer_functions(); - delete &lexer_functions(); - delete &library_functions(); - delete &lexer_translator(); - delete &back_lexer_localization_map(); - delete &lexer_localization_map(); - delete &lexer_localization_vector(); - delete &syms(); - delete &unit_conversion_map(); - delete &xcasrc(); - //delete &usual_units(); - if (vector_aide_ptr()) delete vector_aide_ptr(); - delete &symbolic_rootof_list(); - delete &proot_list(); - delete &galoisconj_list(); - delete &_autoname_(); - delete &_lastprog_name_(); - return 0; - } - -#ifndef NO_NAMESPACE_GIAC -} // namespace giac -#endif // ndef NO_NAMESPACE_GIAC diff --git a/apps/KhiCAS/src/giac-1.6.0/src/global.h b/apps/KhiCAS/src/giac-1.6.0/src/global.h index fdb6596e9..13a25689b 100755 --- a/apps/KhiCAS/src/giac-1.6.0/src/global.h +++ b/apps/KhiCAS/src/giac-1.6.0/src/global.h @@ -18,6 +18,7 @@ */ #ifndef _GIAC_GLOBAL_H #define _GIAC_GLOBAL_H +//#define USE_OBJET_BIDON #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -369,6 +370,7 @@ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); extern int GAMMA_LIMIT; extern int LIST_SIZE_LIMIT; extern int NEWTON_DEFAULT_ITERATION; + extern int NEWTON_MAX_RANDOM_RESTART; extern int DEFAULT_EVAL_LEVEL; extern int PARENTHESIS_NWAIT; extern int MAX_PROD_EXPAND_SIZE; diff --git a/apps/KhiCAS/src/giac-1.6.0/src/global.h~ b/apps/KhiCAS/src/giac-1.6.0/src/global.h~ deleted file mode 100755 index b2abf96c1..000000000 --- a/apps/KhiCAS/src/giac-1.6.0/src/global.h~ +++ /dev/null @@ -1,1186 +0,0 @@ -/* -*- 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 . - */ -#ifndef _GIAC_GLOBAL_H -#define _GIAC_GLOBAL_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "first.h" -#ifdef HAVE_UNISTD_H -#include -#endif -#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) && !defined(FXCG) -#include -#else -#if defined VISUALC || defined BESTA_OS || defined FREERTOS -typedef long pid_t; -#else // VISUALC -#if !defined(__MINGW_H) && !defined(NSPIRE) && !defined(FXCG) && !defined(__ANDROID__) && !defined(NSPIRE_NEWLIB) && !defined(OSX) && !defined(IOS) && !defined(OSXIOS) && !defined(FIR_LINUX) && !defined(PRIMEWEBASM) -#include "wince_replacements.h" -#endif -#ifdef __MINGW_H -#include -#endif -#endif // VISUALC -#endif // HAVE_NO_SYS_TIMES_H -// #ifndef __APPLE__ -#if defined VISUALC || defined BESTA_OS -#include -#include -#endif -#ifndef WIN32 -#include -//#define isnan __isnan -//#define isinf __isinf -#endif -// #endif - -#ifdef SOFTMATH -#include "softmath.h" -#else -#include -#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 -#endif -#ifdef HAVE_PTHREAD_H -#include -#endif - -#include "vector.h" -#include -#if !defined( NSPIRE) && !defined(FXCG) -#include -#endif -#include -//#include -#include - -#ifdef GNUWINCE -#define SIGINT 2 -#else -#ifndef HAVE_NO_SIGNAL_H -#include -#endif -#endif // GNUWINCE - -#include -#include "help.h" -#if !defined(FXCG) // !defined(GIAC_HAS_STO_38) // && !defined(ConnectivityKit) && !defined(BESTA_OS) -#include "tinymt32.h" -#endif - -#if defined(HAVE_NO_SYS_TIMES_H) && defined(__MINGW_H) -#include -#endif - -extern "C" int ctrl_c_interrupted(int exception); -extern "C" void console_print(const char * s); -extern "C" const char * console_prompt(const char * s); - -bool dfu_get_scriptstore_addr(size_t & start,size_t & taille); -bool dfu_get_scriptstore(const char * fname); -bool dfu_send_scriptstore(const char * fname); -bool dfu_send_rescue(const char * fname); -const int nwstoresize1=0x8000,nwstoresize2=0x8014; -bool dfu_send_firmware(const char * fname); -bool dfu_send_apps(const char * fname); -bool dfu_update_khicas(const char * fname); - -#if defined HAVE_LIBMICROPYTHON -#include -// giac interface to micropython modules -std::string & python_console(); -#endif -#ifdef QUICKJS -#include -extern std::string js_vars; -#endif -int js_token(const char * list,const char * buf); -int js_token(const char * buf); -void update_js_vars(); - -extern bool freezeturtle; -extern "C" size_t pythonjs_stack_size,pythonjs_heap_size; -extern "C" void * bf_ctx_ptr; -extern "C" size_t bf_global_prec; - -struct fileinfo_t { - std::string filename; - std::string type; - size_t size; - size_t header_offset; - int mode; -}; -size_t tar_totalsize(const char * buffer,size_t byteLength); -std::vector tar_fileinfo(const char * buffer,size_t byteLength); -// tar file format: operations on a malloc-ed char * buffer of size buffersize -// (malloc is assumed if buffer needs to be resized by tar_adddata) -extern char * buf64k; // a 64k buffer in RAM for flash sector copy -extern int numworks_maxtarsize; // max tar size on the Numworks -extern size_t tar_first_modified_offset; // will be used to truncate the file sent to the Numworks -int flash_adddata(const char * buffer_,const char * filename,const char * data,size_t datasize,int exec); -int tar_adddata(char * & buffer,size_t * buffersizeptr,const char * filename,const char * data,size_t datasize,int exec=0); // filename is only used to fill the header -int flash_addfile(const char * buffer,const char * filename); -int tar_addfile(char * & buffer,const char * filename,size_t * buffersizeptr); -const char * tar_loadfile(const char * buffer,const char * filename,size_t * len); -int tar_filebrowser(const char * buf,const char ** filenames,int maxrecords,const char * extension); -// by default removefile will mark the file as deleted (this requires 1 sector write) -// if mark_only==2, this will undelete the file -// int flash_removefile(const char * buffer,const char * filename,size_t * tar_first_modif_offsetptr,int mark_only=1); -// write all changes made in records (filename and readable attribut) -// returns 0 if there is a mismatch between buffer and finfo -int flash_synchronize(const char * buffer,const std::vector & finfo,size_t * tar_first_modif_offsetptr); -ulonglong fromstring8(const char * ptr); -std::string toString8(longlong chksum); - -// empty trash: files marked as non readable are really removed -// this will do 1 sector write from first sector where a file is marked to be removed to the end -int flash_emptytrash(const char * buffer,size_t * tar_first_modif_offsetptr); -int flash_emptytrash(const char * buffer,const std::vector & finfo,size_t * tar_first_modif_offsetptr); - -int tar_removefile(char * buffer,const char * filename,size_t * tar_first_modif_offsetptr); -int tar_savefile(char * buffer,const char * filename); -std::vector tar_fileinfo(const char * buffer,size_t byteLength); -char * file_gettar(const char * filename); -// same as file_gettar but returns an aligned pointer and sets freeptr to the address to be free-ed -char * file_gettar_aligned(const char * filename,char * & freeptr); -int file_savetar(const char * filename,char * buffer,size_t buffersize); -#if !defined KHICAS && !defined USE_GMP_REPLACEMENTS && !defined GIAC_HAS_STO_38// -// numworks_gettar return 0 or a buffer of size numworks_maxtarsize -// initialized with the calculator content -char * numworks_gettar(size_t & tar_first_modif_offset); -bool numworks_sendtar(char * buffer,size_t buffersize,size_t tar_first_modif_offset=0); -#endif - -#ifndef NO_NAMESPACE_GIAC -namespace giac { -#endif // ndef NO_NAMESPACE_GIAC - - // 3 or 1 if a list of space separated commandnames includes buf - int dichotomic_search(const char * const * tab,unsigned tab_size,const char * s); - 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 -#if defined NSPIRE_NEWLIB || defined KHICAS - void usleep(int ); -#endif - -#ifndef HAVE_NO_SYS_TIMES_H - double delta_tms(struct tms tmp1,struct tms tmp2); -#elif defined(__MINGW_H) - double delta_tms(clock_t tmp1,clock_t tmp2); -#endif - -#define GIAC_DATA_BEGIN ((char) 2) -#define GIAC_DATA_END ((char) 5) -#define GIAC_DATA_ESCAPE ((char) 27) - - std::vector * & vector_aide_ptr(); - std::vector * & vector_completions_ptr(); - extern void (*fl_widget_delete_function)(void *); -#if !defined( NSPIRE) && !defined(FXCG) - 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 - extern int printprog; // ==0 normal value, used to force program print at parse - // >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 MAX_PROD_EXPAND_SIZE; - - 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 NTL_RESULTANT; // lowest degree for NTL univariate resultant - extern int NTL_XGCD; // lowest degree for NTL univariate extended GCD over Z - extern int MODRESULTANT; // lowest degree for modular resultant - extern int HGCD; // lowest degree for half gcd call - 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 unsigned max_pairs_by_iteration; - extern unsigned simult_primes,simult_primes2,simult_primes_seuil2,simult_primes3,simult_primes_seuil3; - // see global.cc for explanations - extern double gbasis_reinject_ratio; - extern double gbasis_reinject_speed_ratio; - extern int gbasis_logz_age_sort,gbasis_stop,rur_do_gbasis,rur_do_certify,rur_certify_maxthreads; - extern bool rur_error_ifnot0dimensional; // error code or compute gbasis - - extern int PROOT_FACTOR_MAXDEG; - extern int ABS_NBITS_EVALF; - extern volatile bool ctrl_c,interrupted,kbd_interrupted; - void ctrl_c_signal_handler(int signum); -#ifdef TIMEOUT -#if !defined(EMCC) && !defined(EMCC2) - 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) || defined(FXCG) - void control_c(); -#elif defined FIR -#define control_c() -#else -#if defined TIMEOUT && !defined POCKETCAS - void control_c(); -#else -#if 0 -#define control_c() if (ctrl_c) { interrupted = true; CERR << "Throwing exception for user interruption." << '\n'; 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__ << ")" << '\n'; \ -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 dbgprint_vector: public std::imvector { - public: - // inherited constructors - dbgprint_vector() : std::imvector::imvector() { }; - dbgprint_vector(const T * b,const T * e) : std::imvector::imvector(b,e) { }; - dbgprint_vector(size_t i) : std::imvector::imvector(i) { }; - dbgprint_vector(size_t i,const T & t) : std::imvector::imvector(i,t) { }; - // ~dbgprint_vector() { }; - // inherited destructors - void dbgprint() const { COUT << *this << '\n'; } - }; -#else // IMMEDIATE_VECTOR - template class dbgprint_vector: public std::vector { - public: - // inherited constructors - dbgprint_vector() : std::vector::vector() { }; -#ifndef GIAC_VECTOR - dbgprint_vector(const typename std::vector::const_iterator & b,const typename std::vector::const_iterator & e) : std::vector::vector(b,e) { }; -#endif - dbgprint_vector(const T * b,const T * e) : std::vector::vector(b,e) { }; - dbgprint_vector(size_t i) : std::vector::vector(i) { }; - dbgprint_vector(size_t i,const T & t) : std::vector::vector(i,t) { }; - // ~dbgprint_vector() { }; - // inherited destructors - void dbgprint() const { COUT << *this << '\n'; } - }; -#endif // IMMEDIATE_VECTOR - - template class std_matrix: public std::vector< dbgprint_vector > { - public: - // inherited constructors - std_matrix() : std::vector< dbgprint_vector >::vector() { }; - std_matrix(size_t i) : std::vector< dbgprint_vector >::vector(i) { }; - std_matrix(size_t i,const dbgprint_vector & v) : std::vector< dbgprint_vector >::vector(i,v) { }; - std_matrix(size_t i,size_t j) : std::vector< dbgprint_vector >::vector(i,dbgprint_vector(j)) { }; - std_matrix(size_t i,size_t j,const T & t) : std::vector< dbgprint_vector >::vector(i,dbgprint_vector(j,t)) { }; - // ~dbgprint_vector() { }; - // inherited destructors - std_matrix transpose() const { - if (std::vector< dbgprint_vector >::empty()) - return *this; - int n=int(std::vector< dbgprint_vector >::size()); - int m=int(std::vector< dbgprint_vector >::front().dbgprint_vector::size()); - std_matrix res(m,n); - typename std_matrix::const_iterator it=std::vector< dbgprint_vector >::begin(); - for (int i=0;i transconjugate() const { - if (std::vector< dbgprint_vector >::empty()) - return *this; - int n=std::vector< dbgprint_vector >::size(); - int m=std::vector< dbgprint_vector >::front().dbgprint_vector::size(); - std_matrix res(m,n); - typename std_matrix::const_iterator it=std::vector< dbgprint_vector >::begin(); - for (int i=0;i vecteur; // debugging support - - vecteur * keywords_vecteur_ptr(); // idnt assigned to a commandname for localization, like mediatrice for perpen_bissector - - class context; - extern const giac::context * python_contextptr; - - 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 current_instruction_stack; - int current_instruction; - std::vector< std::vector > sst_at_stack; - std::vector 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(); - }; - -#if !defined( NSPIRE) && !defined(FXCG) - 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 sym_string_tab; - struct ltstr - { - bool operator()(const char* s1, const char* s2) const - { - return strcmp(s1, s2) < 0; - } - }; - - typedef std::map map_charptr_gen; - typedef map_charptr_gen sym_tab; - - struct nwsrec { - unsigned char type; - std::vector data; - }; - typedef std::map nws_map; - std::string dos2unix(const std::string & res); - bool scriptstore2map(const char * fname,nws_map & m); - bool map2scriptstore(const nws_map & m,const char * fname); - // check that filename content matches a file content signed in sigfilename - bool sha256_check(const char * sigfilename,const char * filename); - bool nws_certify_firmware(bool with_overwrite,GIAC_CONTEXT); // Numworks certification - - 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); - const int turtle_length=10; -#ifdef KHICAS - 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 - char turtle_width; - short int s;//std::string s; - int color; - 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 - logo_turtle(): x(100),y(100),theta(0),visible(true),mark(true),direct(true),color(0),turtle_width(1),radius(0) {} - }; -#else // KHICAS - 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_width; - 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_width(1),radius(0),widget(0) {} -#else - logo_turtle(): x(100),y(100),theta(0),visible(true),mark(true),direct(true),color(0),turtle_width(1),radius(0),widget(0) {} -#endif - }; -#endif // KHICAS - - // a structure that should contain all global variables - class global { - public: - int _xcas_mode_; - int _calc_mode_; - int _decimal_digits_; - int _minchar_for_quote_as_string_; - 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 _auto_assume_; - bool _parse_e_; - bool _convert_rootof_; - int _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 -#if 1 // def 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 defined(FXCG) // 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_; - const char * _last_evaled_function_name_; - const gen * _last_evaled_argptr_; - int _max_sum_sqrt_; - int _max_sum_add_; - logo_turtle _turtle_; - std::string _autoname_; - std::string _format_double_; - std::string _autosimplify_; - std::string _lastprog_name_; - const char * _currently_scanned_; -#ifndef KHICAS - std::vector _turtle_stack_; -#endif - 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,*history_plot_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_list(); -#ifdef HAVE_LIBPTHREAD - extern pthread_mutex_t context_list_mutex; -#endif - -#if !defined(RTOS_THREADX) && !defined(BESTA_OS) && !defined(NSPIRE) && !defined(FXCG) && !defined KHICAS - extern std::map * context_names ; -#endif - - const char * & last_evaled_function_name(GIAC_CONTEXT); - const char * & currently_scanned(GIAC_CONTEXT); - const gen * & last_evaled_argptr(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); - - int & python_compat(GIAC_CONTEXT); - void python_compat(int b,GIAC_CONTEXT); - int array_start(GIAC_CONTEXT); - extern bool python_color; // global variable for syntax highlighting - extern bool os_shell; // true if Numworks called from shell - - 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 & minchar_for_quote_as_string(GIAC_CONTEXT); - void minchar_for_quote_as_string(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 & auto_assume(GIAC_CONTEXT); - void auto_assume(bool b,GIAC_CONTEXT); - - bool & parse_e(GIAC_CONTEXT); - void parse_e(bool b,GIAC_CONTEXT); - - bool & convert_rootof(GIAC_CONTEXT); - void convert_rootof(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); - vecteur & history_plot(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); - - std::string lastprog_name(GIAC_CONTEXT); - std::string lastprog_name(const std::string & b,GIAC_CONTEXT); - -#ifdef KHICAS - logo_turtle & turtle(); - std::vector & turtle_stack(); -#else - logo_turtle & turtle(GIAC_CONTEXT); - std::vector & turtle_stack(GIAC_CONTEXT); -#endif - - 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 defined(FXCG) // 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 occurrences - int equalposcomp(const std::vector v,int i); - int equalposcomp(const std::vector v,int i); - int equalposcomp(int tab[],int f); - // replace c1 by c2 in s - std::string replace(const std::string & s,char c1,char c2); - // 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 diff --git a/apps/KhiCAS/src/giac-1.6.0/src/ifactor.cc b/apps/KhiCAS/src/giac-1.6.0/src/ifactor.cc index 89c74f691..2db1a7cad 100644 --- a/apps/KhiCAS/src/giac-1.6.0/src/ifactor.cc +++ b/apps/KhiCAS/src/giac-1.6.0/src/ifactor.cc @@ -4163,7 +4163,7 @@ namespace giac { return g; return _matrix(makesequence(g._VECTptr->size()/2,2,g),contextptr); } -#ifndef EMCC +#if !defined EMCC && defined HAVE_LIBPARI if (b.type==_SYMB){ gen res; // b is assumed to be a minimal polynomial check if g is a norm @@ -4774,7 +4774,7 @@ namespace giac { else { // is q a power of a prime? double d=evalf_double(q,1,contextptr)._DOUBLE_val; - int maxpow=int(std::ceil(std::log(d)/std::log(3))); + int maxpow=int(std::ceil(std::log(d)/std::log(3.0))); for (int i=2;i<=maxpow;++i){ if ( (i>2 && i%2==0) || (i>3 && i%3==0) || diff --git a/apps/KhiCAS/src/giac-1.6.0/src/input_lexer.ll b/apps/KhiCAS/src/giac-1.6.0/src/input_lexer.ll index d71ff8289..d61f74c77 100644 --- a/apps/KhiCAS/src/giac-1.6.0/src/input_lexer.ll +++ b/apps/KhiCAS/src/giac-1.6.0/src/input_lexer.ll @@ -1039,11 +1039,18 @@ AN [0-9a-zA-Z_~ ?\200-\355\357-\376] } } bool instring=false; - // stupid match of bracket then parenthesis - int l=s.size(),nb=0,np=0; + // stupid match of bracket then parenthesis then quotes + int l=s.size(),nb=0,np=0,nq=0; int i=0; if (lexer_close_parenthesis(contextptr)){ for (;i2 && s[i-2]=='\'' && s[i-1]=='='){ + s.insert(s.begin()+i-1,' '); + ++l; + } + } if (!instring && i && s[i]=='/' && s[i-1]=='/'){ // skip comment until end of line for (;ifeuille,a,b; + if (is_linear_wrt(vf,gen_x,a,b,contextptr) && (a==1||a==-1)){ + if (b==0) break; // + gen e1=complex_subst(e,gen_x,a*(gen_x-b),contextptr); + gen E1=integrate_id_rem(e1,gen_x,remains_to_integrate,contextptr,intmode); + remains_to_integrate=complex_subst(remains_to_integrate,gen_x,a*gen_x+b,contextptr); + E1=complex_subst(E1,gen_x,a*gen_x+b,contextptr); + return a*E1/curgcd; + } + } + } if (!allsame && curgcd!=0 && curgcd!=1){ gen e1=complex_subst(e,gen_x,inv(curgcd,contextptr)*gen_x,contextptr); v=vecteur(1,gen_x); @@ -2790,7 +2808,7 @@ namespace giac { for (int i=1;ifeuille,contextptr); + gen vf=expand(ratnormal(v[i]._SYMBptr->feuille,contextptr),contextptr); vrep[i]=symbolic(v[i]._SYMBptr->sommet,vf); } if (v!=vrep) e1=complex_subst(e1,v,vrep,contextptr); @@ -5855,7 +5873,7 @@ namespace giac { gen af=evalf_double(v[2],1,contextptr),bf=evalf_double(v[3],1,contextptr); if (v[1].type==_IDNT && (is_inf(af) || af.type==_DOUBLE_) && (is_inf(bf) || bf.type==_DOUBLE_)){ vecteur w; -#ifndef NSPIRE +#if !defined FXCG && !defined NSPIRE my_ostream * ptr=logptr(contextptr); logptr(0,contextptr); #endif @@ -5878,7 +5896,7 @@ namespace giac { v0=v[0]; } #endif -#ifndef NSPIRE +#if !defined FXCG && !defined NSPIRE logptr(ptr,contextptr); #endif for (unsigned i=0;i=0){ char buf[2]={c,0}; @@ -497,7 +502,7 @@ int khicas_addins_menu(GIAC_CONTEXT){ } break; } - if (smallmenu.selection==6){ + if (smallmenu.selection==7){ // Exemple simple d'application tierce: la suite de Syracuse // on entre la valeur de u0 double d; int i; @@ -518,16 +523,16 @@ int khicas_addins_menu(GIAC_CONTEXT){ v.push_back(i); } // representation graphique de la liste en appelant la commande Xcas listplot - displaygraph(_listplot(v,contextptr),contextptr); + displaygraph(_listplot(v,contextptr),symbolic(at_listplot,v),contextptr); // copie vers presse-papier en l'affichant copy_clipboard(gen(v).print(contextptr),true); continue; // on entre la liste en ligne de commande et on quitte return Console_Input(gen(v).print(contextptr).c_str()); } - if (smallmenu.selection==7) // mastermind, on ne quitte pas + if (smallmenu.selection==8) // mastermind, on ne quitte pas mastermind(contextptr); - if (smallmenu.selection==8) + if (smallmenu.selection==9) fractale(contextptr); } // end sres==menu_selection Console_Disp(1,contextptr); @@ -1158,7 +1163,7 @@ void sheet_graph(tableur &t,GIAC_CONTEXT){ vecteur v; sheet_pnt(t.m,v); gen g(v); - check_do_graph(g,2,contextptr); + check_do_graph(g,0,2,contextptr); } int sheet_menu_menu(tableur & t,GIAC_CONTEXT){ @@ -1443,6 +1448,8 @@ giac::gen sheet(GIAC_CONTEXT){ if (!sheetptr) sheetptr=new_tableur(contextptr); tableur & t=*sheetptr; + sheet_eval(t,contextptr,true); + t.changed=false; bool status_freeze=false; t.keytooltip=false; for (;;){ @@ -1786,5 +1793,55 @@ giac::gen sheet(GIAC_CONTEXT){ } } - +int geoapp(GIAC_CONTEXT){ + int res=newgeo(contextptr); + if (res<0) return res; + // load a figure? + textArea * text=geoptr->hp; + vector fign,figs; + vecteur V(gen2vecteur(giac::_VARS(0,contextptr))); + for (int i=0;isize()==2 && val._VECTptr->front()==at_pnt){ + vecteur & v=*val._VECTptr; + if (v[1].type==_STRNG){ + fign.push_back(tmp.print(contextptr)); + figs.push_back(*v[1]._STRNGptr); + } + } + } + if (1 || !figs.empty()){ + if (0 && figs.size()==1){ + text->elements.clear(); + add(text,figs[0]); + text->filename=fign[0]; + } + else { + const char * tab[figs.size()+3]={0}; + for (int i=0;i=0 && selements.clear(); + if (sfilename=fign[s]+".py"; + geoparse(text,contextptr); + } + else { + geoptr->plot_instructions.clear(); + geoptr->symbolic_instructions.clear(); + geoptr->is3d=(s==figs.size()+1); + geoptr->orthonormalize(); + text->filename="figure"+print_INT_(figs.size()+1)+".py"; + } + } + else return -3; + } + } + return geoloop(geoptr); +} #endif diff --git a/apps/KhiCAS/src/giac-1.6.0/src/kadd.cc~ b/apps/KhiCAS/src/giac-1.6.0/src/kadd.cc~ deleted file mode 100755 index 81c54e768..000000000 --- a/apps/KhiCAS/src/giac-1.6.0/src/kadd.cc~ +++ /dev/null @@ -1,1770 +0,0 @@ -#include "config.h" -#include "giacPCH.h" -#ifdef KHICAS -#include "kdisplay.h" -#include -#include -#include -#include -#include -#define HAVE_TIME_H -#include - -#ifndef NO_NAMESPACE_GIAC -namespace giac { -#endif // ndef NO_NAMESPACE_GIAC - xcas::tableur * new_tableur(GIAC_CONTEXT){ - xcas::tableur * sheetptr=new xcas::tableur; -#ifdef NUMWORKS - sheetptr->nrows=14; sheetptr->ncols=4; -#else - sheetptr->nrows=20; sheetptr->ncols=5; -#endif - gen g=vecteur(sheetptr->ncols); - sheetptr->m=makefreematrice(vecteur(sheetptr->nrows,g)); - makespreadsheetmatrice(sheetptr->m,contextptr); - sheetptr->cur_row=sheetptr->cur_col=sheetptr->disp_row_begin=sheetptr->disp_col_begin=0; - sheetptr->sel_row_begin=sheetptr->sel_col_begin=-1; - sheetptr->cmd_pos=sheetptr->cmd_row=sheetptr->cmd_col=-1; - sheetptr->changed=false; - sheetptr->recompute=true; - sheetptr->matrix_fill_cells=true; - sheetptr->movedown=true; - sheetptr->filename="session"; - return sheetptr; - } - gen current_sheet(const gen & g,GIAC_CONTEXT){ - if (!xcas::sheetptr) - xcas::sheetptr=new_tableur(contextptr); - xcas::tableur & t=*xcas::sheetptr; - if (ckmatrix(g,true)){ - t.m=*g._VECTptr; - makespreadsheetmatrice(t.m,contextptr); - t.cur_row=t.cur_col=0; - t.nrows=t.m.size(); - t.ncols=t.m.front()._VECTptr->size(); - t.sel_row_begin=-1; - t.cmd_row=t.cmd_pos=-1; - return 1; - } - int r,c; - if (iscell(g,c,r,contextptr)){ - if (r>=t.nrows||c>=t.ncols) - return undef; - gen tmp=t.m[r]; - tmp=tmp[c]; - return tmp[1]; - } - if (g.type==_VECT && g.subtype==0 && g._VECTptr->empty()) - return gen(extractmatricefromsheet(t.m,false),_SPREAD__VECT); - gen m(extractmatricefromsheet(t.m),_MATRIX__VECT); - if (g.type==_VECT && g._VECTptr->empty()) - return m; - return m[g]; - } - static const char _current_sheet_s []="current_sheet"; - static define_unary_function_eval(__current_sheet,¤t_sheet,_current_sheet_s); - define_unary_function_ptr5( at_current_sheet ,alias_at_current_sheet,&__current_sheet,_QUOTE_ARGUMENTS,true); - -#ifndef NO_NAMESPACE_GIAC -} -#endif // ndef NO_NAMESPACE_GIAC - - -using namespace std; -using namespace giac; -using namespace xcas; - -#if 0 -int ext_main(){ - while (1){ - statuslinemsg("Numworks loader"); - drawRectangle(0,0,LCD_WITH_PX,LCD_HEIGHT_PX,_BLACK); - os_draw_string(0,20,_WHITE,_BLACK,"1. Khicas shell"); - os_draw_string(0,40,_WHITE,_BLACK,"2. Epsilon (Numworks HOME)"); - int k=getkey(1); - if (k=='1' ) run_epsilon(); - if (k=='2') caseval("*"); - } -} -#else -int ext_main(){ - caseval("*"); - return 0; -} -#endif - -void handle_flash(GIAC_CONTEXT); - -unsigned short mmind_col[]={COLOR_BLUE,COLOR_RED,COLOR_MAGENTA,COLOR_GREEN,COLOR_CYAN,COLOR_YELLOW}; - -void mastermind_disp(const vector & solution,const vector< vector > & essais,const vector & essai,bool fulldisp,GIAC_CONTEXT){ - int x0=30,y0=30; - if (fulldisp) - drawRectangle(0,0,LCD_WIDTH_PX,LCD_HEIGHT_PX,_WHITE); - else - drawRectangle(0,y0+6*20,LCD_WIDTH_PX,LCD_HEIGHT_PX-(y0+4*20),_WHITE); - if (fulldisp){ - // grille - for (int i=y0;i<=y0+4*20;i+=20) - draw_line(x0,i,x0+12*20,i,_BLACK); - for (int j=x0;j<=x0+12*20;j+=20) - draw_line(j,y0,j,y0+4*20,_BLACK); - // affichage des coups precedents et resultats - for (int c=0;c & essai=essais[c]; - for (int i=0;i<4;++i){ - draw_filled_circle(x0+20*c+10,y0+20*i+10,10,mmind_col[essai[i]],true,true,contextptr); - } - // resultats - vector S(solution),E(essai); - // bien places - int bien=0; - for (int i=0;i=S.size() || e>=E.size()) - break; - if (S[s]==E[e]){ - ++mal; - ++s; ++e; - continue; - } - if (S[s] solution(4),essai; - vector< vector > essais; - const int nbcouleurs=6; - const int nbessais=12; - for (int i=0;i<4;++i) - solution[i]=giac_rand(contextptr) % nbcouleurs; - int i=0,j=0; - bool fulldisp=true; - for (;;){ - mastermind_disp(solution,essais,essai,fulldisp,contextptr); - // saisie du prochain coup - int key=getkey(1); - if (key==KEY_SHUTDOWN) - return key; - fulldisp=false; - if (key==KEY_CTRL_MENU) - return key; - if (key==KEY_PRGM_ACON){ - fulldisp=true; - continue; - } - if (key>='0' && key<='5'){ - if (essai.size()==4) - continue; - essai.push_back(key-'0'); - } - if (key==KEY_CTRL_EXE || key==KEY_CTRL_OK){ - if (essai.size()==4){ - if (essai==solution){ - char buf[16]; sprint_int(buf,essais.size()); - confirm("Vous avez trouve. Essais:",buf); - return i; - } - fulldisp=true; - essais.push_back(essai); - essai.clear(); - if (essais.size()==nbessais){ - mastermind_disp(solution,essais,essai,true,contextptr); - for (int i=0;i=1 && d<=20) - Nmax=d; - double w=2.7/X; - double h=-1.87/Y; - for (int y=0;y<=Y/2;++y){ - complex c(-2.1,h*y+0.935); - for (int x=0;x z(0); - int j; - for (j=0;j2) - break; - } - int color=126*j+2079; - os_set_pixel(x,y,color); - os_set_pixel(x,(Y-y),color); - c = c+w; - } - sync_screen(); - } - statuslinemsg("Ecran fige. Taper EXIT"); - getkey(1); - return 0; -} - -int finance(int mode,GIAC_CONTEXT){ // mode==-1 pret, 1 placement - static double pv=(-mode)*10000; - static double fv=0; - static double ir=3; // % annual - static double irpy=12; // per year - static double pm=100; // mensualite - static double nb=10; // nombre d'annuites - double * tabd[6]={&pv,&fv,&ir,&irpy,&pm,&nb}; - static bool solved=false; - Menu smallmenu; - smallmenu.numitems=7; - // and uncomment first smallmenuitems[app_number].text="Reserved" - // replace by your application name - // and add if (smallmenu.selection==app_number-1){ call your code } - MenuItem smallmenuitems[smallmenu.numitems]; - smallmenu.items=smallmenuitems; - smallmenu.height=11; - smallmenu.scrollbar=1; - smallmenu.scrollout=1; - smallmenu.title = (char *) "Pret bancaire"; - smallmenu.type = MENUTYPE_FKEYS; - while(1) { - drawRectangle(0,0,LCD_WIDTH_PX,LCD_HEIGHT_PX,_WHITE); - string pvs,fvs,pms; - if (mode==-1){ - pvs=((lang==1)?"Somme due actuelle ":"Present due amount "); - fvs=((lang==1)?"Somme due future ":"Future due amount "); - pms=((lang==1)?"Mensualite ":"Payment "); - } else { - pvs=((lang==1)?"Epargne actuelle ":"Present amount "); - fvs=((lang==1)?"Epargne future ":"Future amount "); - pms=((lang==1)?"Versement mensuel ":"Payment "); - } - string irs=((lang==1)?"Taux d'interet annuel ":"Annual interest rate "); - string irpys=((lang==1)?"Paiements par an ":"Payments per year "); - string nbs=((lang==1)?"Nombre d'annees ":"Number of years "); - string pvs1=pvs+giac::print_DOUBLE_((-mode)*pv,contextptr), - fvs1=fvs+giac::print_DOUBLE_((-mode)*fv,contextptr), - irs1=irs+giac::print_DOUBLE_(ir,contextptr)+"%", - irpys1=irpys+giac::print_DOUBLE_(irpy,contextptr), - pms1=pms+giac::print_DOUBLE_(pm,contextptr), - nbs1=nbs+giac::print_DOUBLE_(nb,contextptr); - char * tab[6]={(char*)pvs1.c_str(),(char*)fvs1.c_str(), (char*)irs1.c_str(),(char*)irpys1.c_str(), (char*)pms1.c_str(),(char*)nbs1.c_str()}; - for (int i=0;i<6;i++) - smallmenuitems[i].text = tab[i]; - smallmenuitems[6].text = (char*)((lang==1)?"Quitter ":"Quit "); - os_draw_string(0,200,solved?giac::_GREEN:giac::_MAGENTA,_WHITE,"Ans solve|EXE change|Tool help"); - int sres = doMenu(&smallmenu); - if (sres==MENU_RETURN_EXIT) - break; - int choix=smallmenu.selection-1; - if (sres == KEY_CTRL_CATALOG || sres==KEY_BOOK) { // Help - xcas::textArea text; - text.editable=false; - text.clipline=-1; - text.title = (char*)((lang==1)?"Calcul d'un pret":"Finance help"); - text.allowF1=true; - text.python=python_compat(contextptr); - std::vector & elem=text.elements; - elem = std::vector (2); - elem[0].s = (lang==1)?"Deplacez le curseur sur une ligne, tapez EXE/OK pour entrer une nouvelle valeur ou tapez sur Ans pour resoudre.":"Move cursor on a line, type EXE/OK to enter a new value or type Ans to solve"; - elem[0].newLine = 0; - if (mode==-1) - elem[1].s = (lang==1)?"Par exemple entrez le montant de l'emprunt en 1, 0 en 2, le taux d'interet, le nombre d'annees puis placez le curseur en 5 et tapez Ans.":"For example, enter due amount in 1, 0 in 2, interest rate, number of years then move cursor on 5 and type Ans"; - else - elem[1].s = (lang==1)?"Pour calculer l'evolution d'un placement, entrer le montant place au debut, le taux d'interet, le nombre d'annees, 0 en 5 (paiement) puis deplacez le curseur en 2 et tapez Ans":""; - elem[1].newLine = 1; - sres=doTextArea(&text,contextptr); - continue; - } - if (sres == KEY_CHAR_ANS){ - if (choix==3) - continue; - double t1=std::pow(1+ir/100,1./irpy); - double t=t1-1; - double & u0=pv; - double & un=fv; - double & r=pm; - double C=r/t; - double n=nb*irpy; - // un=(1+t)^n*(u0-r/t)+r/t - if (choix==0){ // solve for u0=(1+t)^(-n)*(un-r/t)+r/t - u0=pow(t1,-n)*(un-C)+C; - } - if (choix==1){ - un=pow(t1,n)*(u0-C)+C; - } - if (choix==2){ // solve for T - giac::gen sol=un-pow(1+vx_var,n,contextptr)*(u0-gen(r)/vx_var)-gen(r)/vx_var; - sol=giac::_fsolve(makesequence(sol,vx_var,t),contextptr); - if (sol.type==_DOUBLE_){ - t=sol._DOUBLE_val; - ir=100*(std::pow(1+t,irpy)-1); - } - else continue; - } - if (choix==4){ // solve for r=t*(u0*(t+1)**n-un)/((t+1)**n-1) - double tmp=pow(t+1,n); - r=t*(u0*tmp-un)/(tmp-1); - } - if (choix==5){ // solve for n=(-ln(t*u0-r)+ln(t*un-r))/ln(t+1) - double n=std::log((t*un-r)/(t*u0-r))/std::log(t+1); - nb=n/irpy; - } - solved=true; - } - if (sres==KEY_CTRL_EXE || sres == MENU_RETURN_SELECTION || sres == KEY_CTRL_OK) { - if (smallmenu.selection==7) // quit - break; - double d=*tabd[choix]; - if (choix<2 && mode==1) d=-d; - if (!inputdouble(tab[choix],d,contextptr)) - continue; - if (choix<2 && mode==1) d=-d; - if (choix==3){ - if (d<1) - d=1; - if (d>365) - d=365; - } - if (choix==5){ - if (d<=0) - d=1; - if (d>365) - d=365; - } - *tabd[choix]=d; - solved=false; - } - } - return 0; -} - -int khicas_addins_menu(GIAC_CONTEXT){ - Menu smallmenu; -#ifdef NUMWORKS - smallmenu.numitems=10; // INCREMENT IF YOU ADD AN APPLICATION -#else - smallmenu.numitems=9; // INCREMENT IF YOU ADD AN APPLICATION -#endif - // and uncomment first smallmenuitems[app_number].text="Reserved" - // replace by your application name - // and add if (smallmenu.selection==app_number-1){ call your code } - MenuItem smallmenuitems[smallmenu.numitems]; - smallmenu.items=smallmenuitems; - smallmenu.height=12; - smallmenu.scrollbar=1; - smallmenu.scrollout=1; - smallmenuitems[0].text = (char*)((lang==1)?"Tableur":"Spreadsheet"); - smallmenuitems[1].text = (char*)((lang==1)?"Table periodique":"Periodic table"); - smallmenuitems[2].text = (char*)((lang==1)?"Pret":"Mortgage"); - smallmenuitems[3].text = (char*)((lang==1)?"Epargne":"TVM"); - smallmenuitems[4].text = (char*)((lang==1)?"Exemple simple: Syracuse":"Simple example; Syracuse"); - smallmenuitems[5].text = (char*)((lang==1)?"Exemple de jeu: Mastermind":"Game example: Mastermind"); - smallmenuitems[6].text = (char*)((lang==1)?"Fractale de Mandelbrot":"Mandelbrot fractal"); - // smallmenuitems[5].text = (char*)"Mon application"; // adjust numitem ! - // smallmenuitems[6].text = (char*)"Autre application"; - // smallmenuitems[7].text = (char*)"Encore une autre"; - // smallmenuitems[8].text = (char*)"Une avant-derniere"; - // smallmenuitems[9].text = (char*)"Une derniere"; -#ifdef NUMWORKS - smallmenuitems[smallmenu.numitems-3].text = (char*)((lang==1)?"Personnaliser la flash":"Customize flash"); -#endif - smallmenuitems[smallmenu.numitems-2].text = (char*)((lang==1)?"Quitter le menu":"Leave menu"); - smallmenuitems[smallmenu.numitems-1].text = (char*)((lang==1)?"Quitter KhiCAS":"Leave KhiCAS"); - while(1) { - int sres = doMenu(&smallmenu); - if(sres == MENU_RETURN_SELECTION || sres==KEY_CTRL_EXE) { - if (smallmenu.selection==smallmenu.numitems){ - return KEY_CTRL_MENU; - } -#ifdef NUMWORKS - if (smallmenu.selection==smallmenu.numitems-2) - handle_flash(contextptr); -#endif - // Attention les entrees sont decalees de 1 - if (smallmenu.selection==1) // tableur - sheet(contextptr); - if (smallmenu.selection==2){ // table periodique - const char * name,*symbol; - char protons[32],nucleons[32],mass[32],electroneg[32]; - int res=periodic_table(name,symbol,protons,nucleons,mass,electroneg); - if (!res) - continue; - char console_buf[64]={0}; - char * ptr=console_buf; - if (res & 1) - ptr=strcpy(ptr,name)+strlen(ptr); - if (res & 2){ - if (res & 1) - ptr=strcpy(ptr,",")+strlen(ptr); - ptr=strcpy(ptr,symbol)+strlen(ptr); - } - if (res & 4){ - if (res&3) - ptr=strcpy(ptr,",")+strlen(ptr); - ptr=strcpy(ptr,protons)+strlen(ptr); - } - if (res & 8){ - if (res&7) - ptr=strcpy(ptr,",")+strlen(ptr); - ptr=strcpy(ptr,nucleons)+strlen(ptr); - } - if (res & 16){ - if (res&15) - ptr=strcpy(ptr,",")+strlen(ptr); - ptr=strcpy(ptr,mass+2)+strlen(ptr); - ptr=strcpy(ptr,"_(g/mol)")+8; - } - if (res & 32){ - if (res&31) - ptr=strcpy(ptr,",")+strlen(ptr); - ptr=strcpy(ptr,electroneg+4)+strlen(ptr); - } - return Console_Input(console_buf); - } - if (smallmenu.selection==3){ - finance(-1,contextptr); - continue; - } - if (smallmenu.selection==4){ - finance(1,contextptr); - continue; - } - if (smallmenu.selection==5){ - // Exemple simple d'application tierce: la suite de Syracuse - // on entre la valeur de u0 - double d; int i; - for (;;){ - inputdouble(gettext("Suite de Syracuse. u0?"),d,contextptr); - i=(d); - if (i==d) - break; - confirm(gettext("u0 doit etre entier!"),gettext("Recommencez")); - } - i=max(i,1); - vecteur v(1,i); // initialise une liste avec u0 - while (i!=1){ - if (i%2) - i=3*i+1; - else - i=i/2; - v.push_back(i); - } - // representation graphique de la liste en appelant la commande Xcas listplot - displaygraph(_listplot(v,contextptr),contextptr); - // on entre la liste en ligne de commande et on quitte - return Console_Input(gen(v).print(contextptr).c_str()); - } - if (smallmenu.selection==6) // mastermind, on ne quitte pas - mastermind(contextptr); - if (smallmenu.selection==7) - fractale(contextptr); - } // end sres==menu_selection - Console_Disp(1,contextptr); - break; - } // end endless while - return CONSOLE_SUCCEEDED; -} - -/* ******************* - * FLASH * - ********************* */ -#ifdef NUMWORKS - -void flash_info(const char * buf,std::vector &v,size_t & first_modif,bool modif,int initpos,GIAC_CONTEXT){ - Menu smallmenu; - smallmenu.numitems=v.size(); - MenuItem smallmenuitems[smallmenu.numitems]; - smallmenu.items=smallmenuitems; - smallmenu.height=modif?11:12; - smallmenu.scrollbar=1; - smallmenu.scrollout=1; - smallmenu.title = (char*)(lang==1?"Info Flash":"Flash Files"); - smallmenu.type = MENUTYPE_FKEYS; - smallmenu.selection=initpos; - if (modif){ - smallmenu.title = (char*)(lang==1?"Modifier fichiers":"Modify files"); - } - vector vs(v.size()); - for (int i=0;i=0 && i10){ - smallmenuitems[i].value=!smallmenuitems[i].value; - int m=v[i].mode; - if (smallmenuitems[i].value) - m = ((m/100) | 4)*100+(m%100); - else - m = ((m/100) & 3)*100+(m%100); - v[i].mode=m; - if (smallmenuitems[i].value){ - // uncheck all files having the same filename - const string & filename=v[i].filename; - for (int j=0;j v=tar_fileinfo(buf,0); - int initpos=1; - if (modif) - initpos=v.size(); - flash_info(buf,v,first_modif,modif,initpos,contextptr); -} - -// copy text file from ram scriptstore -int flash_from_ram(const char * buf,size_t & first_modif,GIAC_CONTEXT){ - char filename[MAX_FILENAME_SIZE+1]; - int n=giac_filebrowser(filename,"py",(lang==1?"Choisir fichier a copier":"Select file to copy"),0); - if (n==0) return 0; - const char * data=read_file(filename); - n=flash_adddata(buf,filename,data,strlen(data),0); - return n; -} - -void handle_flash(GIAC_CONTEXT){ - const char flash_fr[]="Cette application, disponible hors mode examen, permet de sauvegarder et gerer des scripts en memoire flash. Elle a besoin de 70K de memoire RAM, lancez-la tout de suite apres avoir ouvert KhiCAS.\nPour eviter une usure trop rapide de la flash, il est conseille de l'utiliser le moins souvent possible et de ne pas vider la corbeille avant que cela ne soit necessaire (ainsi les nouveaux fichiers s'ecriront sur d'autres secteurs).\nL'auteur decline toute responsabilite en cas d'usure prematuree de votre memoire flash."; - const char flash_en[]="This app (not available if exam mode is on) lets you save and handle scripts in flash memory. It requires 70K of free RAM, you should run it immediatly after launching KhiCAS.\nIn order to avoid premature wear of your flash, run this app only when required. Don't empty the trash unless it's necessary (that way new files will be written in other sectors).\nThe author declines all responsability in the event of premature wear of your flash memory."; - textArea text; - text.editable=false; - text.clipline=-1; - text.title =(lang==1)?"EXIT: annuler, EXE: ok":"EXIT: cancel, EXE: run"; - add(&text,(lang==1)?flash_fr:flash_en); - int key=doTextArea(&text,contextptr); - if (key!=1 -#ifdef DEVICE - || inexammode() -#endif - ) - return; - text.elements.clear(); - buf64k=(char *)malloc(1<<16); - if (buf64k==0){ - confirm(lang==1?"Pas assez de memoire RAM.":"RAM Memory full",lang==1?"Purgez et relancez KhiCAS":"Purge and restart KhiCAS"); - return; - } -#ifndef NUMWORKS - char * freeptr=0; - const char * flash_buf=file_gettar_aligned("apps.tar",freeptr); -#endif - Menu smallmenu; - smallmenu.numitems=5; - MenuItem smallmenuitems[smallmenu.numitems]; - smallmenu.items=smallmenuitems; - smallmenu.height=12; - smallmenu.scrollbar=1; - smallmenu.scrollout=1; - smallmenuitems[0].text = (char*)(lang==1?"Informations flash":"Flash informations"); - smallmenuitems[1].text = (char*)(lang==1?"Copier RAM->flash":"Copy RAM->flash"); - smallmenuitems[2].text = (char*)(lang==1?"Modifier infos fichiers":"Modify file infos"); - smallmenuitems[3].text = (char*)(lang==1?"Vider la corbeille":"Empty trash"); - smallmenuitems[4].text = (char*)(lang==1?"Quitter":"Leave"); - while (1){ - size_t first_modif=tar_totalsize(flash_buf,numworks_maxtarsize); - string title=(lang==1?"Flash libre ":"Free flash "); - title += print_INT_(numworks_maxtarsize-first_modif); - smallmenu.title = (char*)title.c_str(); - smallmenu.selection = 1; - int sres = doMenu(&smallmenu); - if (sres==MENU_RETURN_EXIT){ - break; - } - if (sres == MENU_RETURN_SELECTION || sres==KEY_CTRL_EXE) { - if (smallmenu.selection == smallmenu.numitems) - break; - if (smallmenu.selection == 1){ - flash_info(flash_buf,first_modif,false,contextptr); // info only, no erase - continue; - } - if (smallmenu.selection == 2){ - if (flash_from_ram(flash_buf,first_modif,contextptr)){ - // uncheck files having the same filename - std::vector v=tar_fileinfo(flash_buf,0); - int n=v.size(); - if (n){ - --n; - string & filename=v[n].filename; - int modif=0; - for (int j=0;j65536 && do_confirm(lang==1?"Il reste de la place, etes-vous sur?":"There's still room, are you sure?")) - flash_emptytrash(flash_buf,&first_modif); - } - } - } - free(buf64k); -#ifndef DEVICE - //free(freeptr); -#endif -} -#else -void handle_flash(GIAC_CONTEXT){ - -} -#endif - -/* ************************** - * SPREADSHEET CODE * - ************************** */ -const int row_height=20; -const int col_width=60; -string printcell(int i,int j){ - string s=""; - s+=('A'+j); - s+=print_INT_(i); - return s; -} -string printsel(int r,int c,int R,int C){ - return printcell(r,c)+":"+printcell(R,C); -} - -void change_undo(tableur & t){ - t.undo=t.m; - t.changed=true; -} - -void save_sheet(tableur & t,GIAC_CONTEXT){ -#if 1 - string s=print_tableur(t,contextptr); -#else - string s=gen(extractmatricefromsheet(t.m,false),_SPREAD__VECT).print(contextptr); -#endif - string filename(remove_path(remove_extension(t.filename))); - filename+=".tab"; -#ifdef NSPIRE_NEWLIB - filename+=".tns"; -#endif - write_file(filename.c_str(),s.c_str(),s.size()); -} -void sheet_status(tableur & t,GIAC_CONTEXT){ - string st; - if (python_compat(contextptr)) - st="tabl Py "; - else - st="tabl Xcas "; - if (t.var.type==_IDNT) - st += t.var.print(contextptr); - else - st += "<>"; - st += ' '; - st += t.filename ; - st += " R"; - st += print_INT_(t.nrows); - st += " C"; - st += print_INT_(t.ncols); - if (t.changed) - st += " *"; - else - st += " -"; - if (t.sel_row_begin>=0) - st += (lang==1)?" esc: annule selection":" esc: cancel selection"; - else { - if (t.cmd_row>=0) - st += (lang==1)?" esc: annule ligne cmd":" esc: cancel cmdline"; - } - statuslinemsg(st.c_str()); -} -bool sheet_display(tableur &t,GIAC_CONTEXT){ - int disp_rows=LCD_HEIGHT_PX/row_height-3; - int disp_cols=LCD_WIDTH_PX/(col_width+4)-1; - if (t.disp_row_begin>t.cur_row) - t.disp_row_begin=t.cur_row; - if (t.disp_row_begint.cur_col) - t.disp_col_begin=t.cur_col; - if (t.disp_col_begin=0 && t.sel_row_beginsel_R) - swapint(sel_r,sel_R); - if (sel_c>sel_C) - swapint(sel_c,sel_C); - bool has_cmd=t.cmd_row>=0 && t.cmd_row=26){ // if we accept more than 26 cols - colname[0] += j/26; - colname[1] = 'A'+(j%26); - colname[2]=0; - } - else - colname[0] += (j % 26); - os_draw_string(x+col_width/2-4,2,_BLACK,_WHITE,colname); - x+=col_width+4; - } - int waitn=2; - for (int i=t.disp_row_begin;isize()==3){ - bool iscur=i==t.cur_row && j==t.cur_col; - string s; - if (iscur){ - if (!has_cmd) - t.cmdline=(*vj._VECTptr)[0].print(contextptr); - } - bool rev=has_sel?(sel_r<=i && i<=sel_R && sel_c<=j && j<=sel_C):iscur; - if (rev) - drawRectangle(x+1,y,col_width+4,row_height,color_gris); - s=(*vj._VECTptr)[1].print(contextptr); - int dx=os_draw_string(0,0,0,0,s.c_str(),true); // find width - if (dx=LCD_WIDTH_PX-50; - int sheety=LCD_HEIGHT_PX-2*row_height,xtooltip=0; - if (t.cmd_row>=0 && t.cmd_pos>=0 && t.cmd_pos<=s.size()){ - xend=os_draw_string(xend,sheety,_BLUE,_WHITE,printcell(t.cmd_row,t.cmd_col).c_str())+5; - string s1=s.substr(0,t.cmd_pos); -#if 1 - xtooltip=xend=print_color(xend,sheety,s1.c_str(),_BLACK,false,small,contextptr); -#else - if (small) - xend=os_draw_string_small(xend,sheety,_BLACK,_WHITE,s1.c_str(),false); - else - xend=os_draw_string(xend,sheety,_BLACK,_WHITE,s1.c_str(),false); -#endif - drawRectangle(xend+1,sheety+2,2,small?10:13,_BLACK); - xend+=4; - s=s.substr(t.cmd_pos,s.size()-t.cmd_pos); - if (has_sel){ - s1=printsel(sel_r,sel_c,sel_R,sel_C); - xend=os_draw_string_small(xend,sheety,_BLACK,color_gris,s1.c_str(),false); - } - else { - if (t.cmd_row!=t.cur_row || t.cmd_col!=t.cur_col) - xend=os_draw_string_small(xend,sheety,_BLACK,color_gris,printcell(t.cur_row,t.cur_col).c_str(),false); - } - } // end cmdline active - else - xend=os_draw_string(xend,sheety,_BLACK,_WHITE,printcell(t.cur_row,t.cur_col).c_str())+5; - int bg=t.cmd_row>=0?_WHITE:57051; -#if 1 - xend=print_color(xend,sheety,s.c_str(),_BLACK,false,small,contextptr); -#else - if (small) - xend=os_draw_string_small(xend,sheety,_BLACK,bg,s.c_str(),false); - else - xend=os_draw_string(xend,sheety,_BLACK,bg,s.c_str(),false); -#endif - if (t.keytooltip) - t.keytooltip=tooltip(xtooltip,sheety,t.cmd_pos,t.cmdline.c_str(),contextptr); - python_compat(p,contextptr); xcas_python_eval=xpe; - // fast menus - string menu("shift-1 stat1d|2 2d|3 seq|4 edit|5 view|6 graph|7 R|8 list| "); - bg=65039;// bg=52832; - drawRectangle(0,205,LCD_WIDTH_PX,17,bg); - os_draw_string_small(0,205,_BLACK,bg,menu.c_str()); - return true; -} - -void activate_cmdline(tableur & t){ - if (t.cmd_row==-1){ - t.cmd_row=t.cur_row; - t.cmd_col=t.cur_col; - t.cmd_pos=t.cmdline.size(); - } -} - -bool sheet_eval(tableur & t,GIAC_CONTEXT,bool ckrecompute=true){ - t.changed=true; - if (!ckrecompute || t.recompute) - spread_eval(t.m,contextptr); - return true; -} - -void copy_right(tableur & t,GIAC_CONTEXT){ - int R=t.cur_row,C=t.cur_col,c=t.ncols; - vecteur v=*t.m[R]._VECTptr; - gen g=v[C]; - for (int i=C+1;iR) - dr=R-r; - if (dr && ckmatrix(m,true)){ - dc=m.front()._VECTptr->size(); - if (c+dc>C) - dc=C-c; - if (dc){ - for (int i=0;isize(),nr=t.nrows,nc=t.ncols; - if (nr!=cur_r || nc!=cur_c){ - if (do_confirm(((lang==1?"Redimensionner ":"Resize ")+print_INT_(cur_r)+"x"+print_INT_(cur_c)+"->"+print_INT_(nr)+"x"+print_INT_(nc)).c_str())){ - vecteur fill(3,0); - if (nr0){ - decimal_digits(d,contextptr); - } - continue; - } - if (smallmenu.selection == 2){ - double d=t.nrows; - if (inputdouble((lang==1?"Nombre de lignes?":"Rows?"),d,contextptr) && d==int(d) && d>0){ - t.nrows=d; - } - continue; - } - if (smallmenu.selection == 3){ - double d=t.ncols; - if (inputdouble((lang==1?"Nombre de colonnes?":"Colonnes?"),d,contextptr) && d==int(d) && d>0){ - t.ncols=d; - } - continue; - } - if (smallmenu.selection == 4){ - t.recompute=!t.recompute; - continue; - } - if (smallmenu.selection==5){ - t.matrix_fill_cells=!t.matrix_fill_cells; - continue; - } - if (smallmenu.selection == 6){ - t.movedown=!t.movedown; - continue; - } - if (smallmenu.selection == smallmenu.numitems){ - change_undo(t); - resizesheet(t); - break; - } - } - } // end endless while -} - -void sheet_graph(tableur &t,GIAC_CONTEXT){ - vecteur v; - sheet_pnt(t.m,v); - gen g(v); - check_do_graph(g,2,contextptr); -} - -int sheet_menu_menu(tableur & t,GIAC_CONTEXT){ - t.cmd_row=-1; t.cmd_pos=-1; t.sel_row_begin=-1; - Menu smallmenu; - smallmenu.numitems=14; - MenuItem smallmenuitems[smallmenu.numitems]; - smallmenu.items=smallmenuitems; - smallmenu.height=12; - //smallmenu.width=24; - smallmenu.scrollbar=1; - smallmenu.scrollout=1; -#ifdef NUMWORKS - smallmenu.title = (char*)(lang==1?"Back: annule menu tableur":"Back: cancel sheet menu"); -#else - smallmenu.title = (char*)(lang==1?"Esc: annule menu tableur":"Esc: cancel sheet menu"); -#endif - smallmenuitems[0].text = (char *)(lang==1?"Sauvegarde tableur (shift sto)":"Save sheet (shift sto)"); - smallmenuitems[1].text = (char *)(lang==1?"Sauvegarder tableur comme":"Save sheet as"); - if (nspire_exam_mode==2) smallmenuitems[1].text=smallmenuitems[0].text = (char*)(lang==1?"Sauvegarde desactivee":"Saving disabled"); - smallmenuitems[2].text = (char*)(lang==1?"Charger":"Load"); - string cell=(lang==1?"Editer cellule ":"Edit cell ")+printcell(t.cur_row,t.cur_col); - smallmenuitems[3].text = (char*)cell.c_str(); - smallmenuitems[4].text = (char*)(lang==1?"Voir graphique (shift 6)":"View graph (shift 4)"); -#ifdef NUMWORKS - smallmenuitems[5].text = (char*)(lang==1?"Copie vers le bas (shift 4)":"Copy down (shift 7)"); - smallmenuitems[6].text = (char*)(lang==1?"Copie vers droite (shift 4)":"Copy right (shift 7)"); -#else - smallmenuitems[5].text = (char*)(lang==1?"Copier vers le bas (ctrl D)":"Copy down (ctrl D)"); - smallmenuitems[6].text = (char*)(lang==1?"Copier vers la droite (ctrl R)":"Copy right (ctrl R)"); -#endif - smallmenuitems[7].text = (char*)(lang==1?"Inserer une ligne":"Insert row"); - smallmenuitems[8].text = (char*)(lang==1?"Inserer une colonne":"Insert column"); - smallmenuitems[9].text = (char*)(lang==1?"Effacer ligne courante":"Remove current row"); - smallmenuitems[10].text = (char*)(lang==1?"Effacer colonne courante":"Remove current column"); - smallmenuitems[11].text = (char*)(lang==1?"Remplir le tableau de 0":"Fill sheet with 0"); - smallmenuitems[smallmenu.numitems-2].text = (char*) "Config"; - smallmenuitems[smallmenu.numitems-1].text = (char*) (lang==1?"Quitter tableur":"Leave sheet"); - while(1) { - int sres = doMenu(&smallmenu); - if (sres==MENU_RETURN_EXIT) - return -1; - if (sres == MENU_RETURN_SELECTION || sres==KEY_CTRL_EXE) { - if (smallmenu.selection == 1){ - // save - save_sheet(t,contextptr); - return -1; - } - if (smallmenu.selection == 2 ){ - // save - char buf[270]; - if (get_filename(buf,".tab")){ - t.filename=remove_path(remove_extension(buf)); - save_sheet(t,contextptr); - return -1; - } - } - if (smallmenu.selection== 3 && !exam_mode) { - char filename[128]; - if (giac_filebrowser(filename,"tab",(lang==1?"Fichiers tableurs":"Sheet files"),2)){ - if (t.changed && do_confirm(lang==1?"Sauvegarder le tableur actuel?":"Save current sheet?")) - save_sheet(t,contextptr); - const char * s=read_file(filename); - if (s){ - gen g(s,contextptr); - g=eval(g,1,contextptr); - if (ckmatrix(g,true)){ - t.filename=filename; - t.m=*g._VECTptr; - t.nrows=t.m.size(); - t.ncols=t.m.front()._VECTptr->size(); - t.cur_col=t.cur_row=0; - t.sel_row_begin=t.cmd_row=-1; - fix_sheet(t,contextptr); - } - else - s=0; - } - if (!s) - do_confirm(lang==1?"Erreur de lecture du fichier":"Error reading file"); - } - return -1; - } // end load - if (smallmenu.selection==4){ - activate_cmdline(t); - t.cmd_pos=t.cmdline.size(); - return -1; - } - if (smallmenu.selection==5){ - sheet_graph(t,contextptr); - return -1; - } - if (smallmenu.selection==6){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - copy_down(t,contextptr); - return -1; - } - if (smallmenu.selection==7){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - copy_right(t,contextptr); - return -1; - } - if (smallmenu.selection==8){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - change_undo(t); - t.m=matrice_insert(t.m,t.cur_row,t.cur_col,1,0,makevecteur(0,0,2),contextptr); - t.nrows++; - return -1; - } - if (smallmenu.selection==9){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - change_undo(t); - t.m=matrice_insert(t.m,t.cur_row,t.cur_col,0,1,makevecteur(0,0,2),contextptr); - t.ncols++; - return -1; - } - if (smallmenu.selection==10 && t.nrows>=2){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - change_undo(t); - t.m=matrice_erase(t.m,t.cur_row,t.cur_col,1,0,contextptr); - --t.nrows; - return -1; - } - if (smallmenu.selection==11 && t.ncols>=2){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - change_undo(t); - t.m=matrice_erase(t.m,t.cur_row,t.cur_col,0,1,contextptr); - --t.ncols; - return -1; - } - if (smallmenu.selection==12){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - change_undo(t); - gen g=vecteur(t.ncols); - t.m=makefreematrice(vecteur(t.nrows,g)); - makespreadsheetmatrice(t.m,contextptr); - return -1; - } - if (smallmenu.selection == smallmenu.numitems-1){ - sheet_menu_setup(t,contextptr); - continue; - } - if (smallmenu.selection == smallmenu.numitems){ - return 0; - } - } - } // end endless while - return 1; -} - -bool is_empty_cell(const gen & g){ - if (g.type==_VECT) return is_zero(g[0]); - return is_zero(g); -} - -void sheet_cmd(tableur & t,const char * ans){ - string s=ans; - if (t.sel_row_begin>=0){ - t.cmdline=""; - s="="+s+"matrix("+print_INT_(absint(t.sel_row_begin-t.cur_row)+1)+","+print_INT_(absint(t.sel_col_begin-t.cur_col)+1)+","+printsel(t.sel_row_begin,t.sel_col_begin,t.cur_row,t.cur_col)+")"; - if (t.cur_row=0 && t.cmd_colsize()){ - vecteur w=*v._VECTptr; - g=spread_convert(g,t.cur_row,t.cur_col,contextptr); - w[t.cmd_col]=makevecteur(g,g,0); - t.m[t.cmd_row]=w; - sheet_eval(t,contextptr,true); - } - } - } - t.cur_row=t.cmd_row; - t.cur_col=t.cmd_col; - t.cmd_row=-1; - t.cmd_pos=-1; - if (t.movedown){ - ++t.cur_row; - if (t.cur_row>=t.nrows){ - t.cur_row=0; - ++t.cur_col; - if (t.cur_col>=t.ncols) - t.cur_col=0; - } - } - else { - ++t.cur_col; - if (t.cur_col>=t.ncols){ - t.cur_col=0; - ++t.cur_row; - if (t.cur_row>=t.nrows){ - t.cur_row=0; - } - } - } -} - -void sheet_help_insert(tableur & t,int exec,GIAC_CONTEXT){ - int back; - string adds=help_insert(t.cmdline.substr(0,t.cmd_pos).c_str(),back,exec,contextptr); - if (back>=t.cmd_pos){ - t.cmdline=t.cmdline.substr(0,t.cmd_pos-back)+t.cmdline.substr(t.cmd_pos,t.cmdline.size()-t.cmd_pos); - t.cmd_pos-=back; - } - if (!adds.empty()) - sheet_cmd(t,adds.c_str()); -} - -giac::gen sheet(GIAC_CONTEXT){ - if (!sheetptr) - sheetptr=new_tableur(contextptr); - tableur & t=*sheetptr; - bool status_freeze=false; - t.keytooltip=false; - for (;;){ - int R=t.cur_row,C=t.cur_col; - if (t.cmd_row>=0){ - R=t.cmd_row; - C=t.cmd_col; - } - printcell_current_row(contextptr)=R; - printcell_current_col(contextptr)=C; - if (!status_freeze) - sheet_status(t,contextptr); - sheet_display(t,contextptr); - int key=getkey(1); - if (key==KEY_SHUTDOWN) - return key; - if (t.keytooltip){ - t.keytooltip=false; - if (key==KEY_CTRL_EXIT) - continue; - if (key==KEY_CTRL_RIGHT && t.cmd_pos==t.cmdline.size()) - key=KEY_CTRL_OK; - if (key==KEY_CTRL_DOWN || key==KEY_CTRL_VARS) - key=KEY_BOOK; - if (key==KEY_CTRL_OK || key==KEY_CHAR_ANS){ - sheet_help_insert(t,key,contextptr); - continue; - } - } - status_freeze=false; - if (key==KEY_CTRL_SETUP){ - sheet_menu_setup(t,contextptr); - continue; - } - if (key==KEY_CHAR_STORE && t.cmd_row<0){ - save_sheet(t,contextptr); - continue; - } - if (key==KEY_CTRL_MENU){ - if (sheet_menu_menu(t,contextptr)==0) - return 0; - } - if (key==KEY_CTRL_EXIT){ - if (t.sel_row_begin>=0){ - t.sel_row_begin=-1; - continue; - } - if (t.cmd_row>=0){ - bool b= t.cmd_row==t.cur_row && t.cmd_col==t.cur_col; - t.cur_row=t.cmd_row; - t.cur_col=t.cmd_col; - if (b) - t.cmd_row=-1; - continue; - } - if (!t.changed || do_confirm("Quit?")) - return 0; - } - switch (key){ - case KEY_CTRL_UNDO: - std::swap(t.m,t.undo); - sheet_eval(t,contextptr); - continue; - case KEY_CTRL_CLIP: - if (t.sel_row_begin<0){ - t.sel_row_begin=t.cur_row; - t.sel_col_begin=t.cur_col; - } - else { - int r=t.cur_row,R=t.sel_row_begin,c=t.cur_col,C=t.sel_col_begin; - if (r>R) - swapint(r,R); - if (c>C) - swapint(c,C); - t.clip=matrice_extract(t.m,r,c,R-r+1,C-c+1); - copy_clipboard(gen(extractmatricefromsheet(t.clip)).print(contextptr).c_str(),true); - t.sel_row_begin=-1; - } - continue; - case KEY_CTRL_PASTE: - paste(t,contextptr); - status_freeze=true; - continue; - case KEY_SELECT_RIGHT: - if (t.sel_row_begin<0){ - t.sel_row_begin=t.cur_row; - t.sel_col_begin=t.cur_col; - } - case KEY_CTRL_RIGHT: - if (t.cmd_pos>=0 && t.cmd_row==t.cur_row && t.cmd_col==t.cur_col && t.sel_row_begin==-1){ - ++t.cmd_pos; - if (t.cmd_pos>t.cmdline.size()) - t.cmd_pos=t.cmdline.size(); - } - else { - ++t.cur_col; - if (t.cur_col>=t.ncols) - t.cur_col=0; - } - continue; - case KEY_SHIFT_RIGHT: - if (t.cmd_pos>=0 && t.cmd_row==t.cur_row && t.cmd_col==t.cur_col && t.sel_row_begin==-1){ - t.cmd_pos=t.cmdline.size(); - } - else - t.cur_col=t.ncols-1; - break; - case KEY_SELECT_LEFT: - if (t.sel_row_begin<0){ - t.sel_row_begin=t.cur_row; - t.sel_col_begin=t.cur_col; - } - case KEY_CTRL_LEFT: - if (t.cmd_pos>=0 && t.cmd_row==t.cur_row && t.cmd_col==t.cur_col && t.sel_row_begin==-1){ - if (t.cmd_pos>0) - --t.cmd_pos; - } - else { - --t.cur_col; - if (t.cur_col<0) - t.cur_col=t.ncols-1; - } - continue; - case KEY_SHIFT_LEFT: - if (t.cmd_pos>=0 && t.cmd_row==t.cur_row && t.cmd_col==t.cur_col && t.sel_row_begin==-1){ - t.cmd_pos=0; - } - else { - t.cur_col=0; - } - break; - case KEY_SELECT_UP: - if (t.sel_row_begin<0){ - t.sel_row_begin=t.cur_row; - t.sel_col_begin=t.cur_col; - } - case KEY_CTRL_UP: - --t.cur_row; - if (t.cur_row<0) - t.cur_row=t.nrows-1; - continue; - case KEY_SELECT_DOWN: - if (t.sel_row_begin<0){ - t.sel_row_begin=t.cur_row; - t.sel_col_begin=t.cur_col; - } - case KEY_CTRL_DOWN: - ++t.cur_row; - if (t.cur_row>=t.nrows) - t.cur_row=0; - continue; - case KEY_CTRL_DEL: - if (t.cmd_row>=0){ - if (t.cmd_pos>0){ - t.cmdline.erase(t.cmdline.begin()+t.cmd_pos-1); - --t.cmd_pos; - t.keytooltip=true; - } - } - else { - t.cmdline=""; - t.cmd_row=t.cur_row; - t.cmd_col=t.cur_col; - t.cmd_pos=0; - } - continue; - case KEY_CTRL_EXE: -#if 1 - if (t.cmd_row<0){ - sheet_eval(t,contextptr); - continue; - } -#else - if (t.cmd_row<0){ - int r=t.sel_row_begin; - if (r<0) - return extractmatricefromsheet(t.m); - int R=t.cur_row,c=t.sel_col_begin,C=t.cur_col; - if (r>R) - swapint(r,R); - if (c>C) - swapint(c,C); - return extractmatricefromsheet(matrice_extract(t.m,r,c,R-r+1,C-c+1)); - } -#endif - case KEY_CTRL_OK: - if (t.cmd_row>=0){ - string s; - if (t.sel_row_begin>=0){ - s=printsel(t.sel_row_begin,t.sel_col_begin,t.cur_row,t.cur_col); - t.cur_row=t.cmd_row; - t.cur_col=t.cmd_col; - t.sel_row_begin=-1; - } - if (t.cmd_row!=t.cur_row || t.cmd_col!=t.cur_col){ - s=printcell(t.cur_row,t.cur_col); - t.cur_row=t.cmd_row; - t.cur_col=t.cmd_col; - } - if (s.empty()) - sheet_cmdline(t,contextptr); - else { - insert(t.cmdline,t.cmd_pos,s.c_str()); - t.cmd_pos+=s.size(); - } - } // if t.cmd_row>=0 - else { - t.cmd_row=t.cur_row; - t.cmd_col=t.cur_col; - t.cmd_pos=t.cmdline.size(); - } - continue; - case KEY_CTRL_F5: // view - { - string value((*t.m[t.cur_row]._VECTptr)[t.cur_col][1].print(contextptr)); - char buf[1024]; - strcpy(buf,value.substr(0,1024-1).c_str()); - textedit(buf,1024-1,contextptr ); - } - continue; - case KEY_CTRL_F6: // view graph - sheet_graph(t,contextptr); - continue; - case KEY_CTRL_D: // copy down - copy_down(t,contextptr); - continue; -#ifndef NUMWORKS - case KEY_CTRL_R: - copy_right(t,contextptr); - continue; -#endif - case KEY_CTRL_CATALOG: case KEY_BOOK: case '\t': - { - if (t.cmd_pos>=0) - sheet_help_insert(t,0,contextptr); - } - continue; - } // end switch - if ( (key >= KEY_CTRL_F1 && key <= KEY_CTRL_F6) || - (key >= KEY_CTRL_F7 && key <= KEY_CTRL_F14) - ){ - const char tmenu[]= "F1 stat1d\nsum(\nmean(\nstddev(\nmedian(\nhistogram(\nbarplot(\nboxwhisker(\nF2 stat2d\nlinear_regression_plot(\nlogarithmic_regression_plot(\nexponential_regression_plot(\npower_regression_plot(\npolynomial_regression_plot(\nsin_regression_plot(\nscatterplot(\npolygonscatterplot(\nF3 seq\nrange(\nseq(\ntableseq(\nplotseq(\ntablefunc(\nrandvector(\nrandmatrix(\nF4 edt\nedit_cell\nundo\ncopy_down\ncopy_right\ninsert_row\ninsert_col\nerase_row\nerase_col\nF6 graph\nreserved\nF= poly\nproot(\npcoeff(\nquo(\nrem(\ngcd(\negcd(\nresultant(\nGF(\nF: arit\n mod \nirem(\nifactor(\ngcd(\nisprime(\nnextprime(\npowmod(\niegcd(\nF8 list\nmakelist(\nrange(\nseq(\nlen(\nappend(\nranv(\nsort(\napply(\nF; plot\nplot(\nplotseq(\nplotlist(\nplotparam(\nplotpolar(\nplotfield(\nhistogram(\nbarplot(\nF7 real\nexact(\napprox(\nfloor(\nceil(\nround(\nsign(\nmax(\nmin(\nF< prog\n:\n&\n#\nhexprint(\nbinprint(\nf(x):=\ndebug(\npython(\nF> cplx\nabs(\narg(\nre(\nim(\nconj(\ncsolve(\ncfactor(\ncpartfrac(\nF= misc\n!\nrand(\nbinomial(\nnormald(\nexponentiald(\n\\\n % \n\n"; - const char * s=console_menu(key,(char *)tmenu,0); - if (s && strlen(s)){ - if (strcmp(s,"undo")==0){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - std::swap(t.m,t.undo); - sheet_eval(t,contextptr); - continue; - } - if (strcmp(s,"copy_down")==0){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - copy_down(t,contextptr); - continue; - } - if (strcmp(s,"copy_right")==0){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - copy_right(t,contextptr); - continue; - } - if (strcmp(s,"insert_row")==0){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - change_undo(t); - t.m=matrice_insert(t.m,t.cur_row,t.cur_col,1,0,makevecteur(0,0,2),contextptr); - t.nrows++; - continue; - } - if (strcmp(s,"insert_col")==0){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - change_undo(t); - t.m=matrice_insert(t.m,t.cur_row,t.cur_col,0,1,makevecteur(0,0,2),contextptr); - t.ncols++; - continue; - } - if (strcmp(s,"erase_row")==0 && t.nrows>=2){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - change_undo(t); - t.m=matrice_erase(t.m,t.cur_row,t.cur_col,1,0,contextptr); - --t.nrows; - continue; - } - if (strcmp(s,"erase_col")==0 && t.ncols>=2){ - t.cmd_pos=t.cmd_row=t.sel_row_begin=-1; - change_undo(t); - t.m=matrice_erase(t.m,t.cur_row,t.cur_col,0,1,contextptr); - --t.ncols; - continue; - } - if (strcmp(s,"edit_cell")==0){ - if (t.cmd_row<0 && t.sel_row_begin<0){ - char buf[1024]; - strcpy(buf,t.cmdline.substr(0,1024-1).c_str()); - if (textedit(buf,1024-1,contextptr )){ - t.cmdline=buf; - t.cmd_row=t.cur_row; t.cmd_col=t.cur_col; - sheet_cmdline(t,contextptr); - } - } - continue; - } - if (t.cmd_row<0) - t.cmdline=""; - sheet_cmd(t,s); - } - continue; - } - if (key==KEY_CHAR_CROCHETS || key==KEY_CHAR_ACCOLADES){ - if (t.cmd_row<0) - t.cmdline=""; - activate_cmdline(t); - t.cmdline.insert(t.cmdline.begin()+t.cmd_pos,key==KEY_CHAR_CROCHETS?'[':'{'); - ++t.cmd_pos; - t.cmdline.insert(t.cmdline.begin()+t.cmd_pos,key==KEY_CHAR_CROCHETS?']':'}'); - continue; - } - if (key>=32 && key<128){ - if (t.cmd_row<0) - t.cmdline=""; - activate_cmdline(t); - t.cmdline.insert(t.cmdline.begin()+t.cmd_pos,char(key)); - ++t.cmd_pos; - t.keytooltip=true; - continue; - } - if (const char * ans=keytostring(key,0,false,contextptr)){ - if (ans && strlen(ans)){ - if (t.cmd_row<0) - t.cmdline=""; - sheet_cmd(t,ans); - } - continue; - } - if (key==KEY_CTRL_AC && t.cmd_row>=0){ - if (t.cmdline=="") - t.cmd_row=-1; - t.cmdline=""; - t.cmd_pos=0; - continue; - } - - } -} - - -#endif diff --git a/apps/KhiCAS/src/giac-1.6.0/src/kdisplay.cc b/apps/KhiCAS/src/giac-1.6.0/src/kdisplay.cc index 17349dfa6..4781d359e 100755 --- a/apps/KhiCAS/src/giac-1.6.0/src/kdisplay.cc +++ b/apps/KhiCAS/src/giac-1.6.0/src/kdisplay.cc @@ -222,7 +222,7 @@ namespace giac { s += char(cur); s += " "; s += print_INT_(cur); - s += " 0x"; + s += " "; s += hexa_print_INT_(cur); os_draw_string(0,160,_BLACK,_WHITE,s.c_str()); os_draw_string(0,180,_BLACK,_WHITE,lang==1?"EXE: copier caractere":"EXE: copy char"); @@ -462,17 +462,15 @@ namespace giac { menuitem[0]='0'+cur; menuitem[1]=' '; menuitem[2]=0; - strcpy(menuitem+2,menu->items[curitem].text); } else { menuitem[0]=cur>=10?('0'+(cur/10)):' '; menuitem[1]='0'+(cur%10); menuitem[2]=' '; menuitem[3]=0; - strcpy(menuitem+3,menu->items[curitem].text); } } - //strncat(menuitem, menu->items[curitem].text, 68); + strncat(menuitem, menu->items[curitem].text, 250); if(menu->items[curitem].type != MENUITEM_SEPARATOR) { //make sure we have a string big enough to have background when item is selected: // MB_ElementCount is used instead of strlen because multibyte chars count as two with strlen, while graphically they are just one char, making fillerRequired become wrong @@ -983,6 +981,7 @@ namespace giac { {"csolve(equation,x)", 0, "Resolution exacte dans C d'une equation en x (ou d'un systeme polynomial).","x^2+x+1=0", 0, CAT_CATEGORY_SOLVE | (CAT_CATEGORY_COMPLEXNUM << 8) | XCAS_ONLY}, {"cube(A,B,C)", 0, "Cube d'arete AB avec une face dans le plan ABC", "[0,0,0],[1,0,0],[0,1,0]","[0,0,0],[0,2,sqrt(5)/2+3/2],[0,0,1]", CAT_CATEGORY_3D}, {"curl(u,vars)", 0, "Rotationnel du vecteur u.", "[2*x*y,x*z,y*z],[x,y,z]", 0, CAT_CATEGORY_LINALG | XCAS_ONLY}, + {"curvature([x(t),y(t)],t,t0)", 0, "Courbure de la courbe parametree [x(t),y(t)] en t0", "[t,t^2],t,1", "[t,t^2],t", CAT_CATEGORY_CALCULUS | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, {"cyan", "cyan", "Option d'affichage", "#display=cyan", 0, CAT_CATEGORY_PROGCMD}, {"cylinder(A,v,r,[h])", 0, "Cylindre d'axe A,v de rayon r et de hauteur optionnelle h", "[0,0,0],[0,1,0],2", "[0,0,0],[0,1,0],2,3", CAT_CATEGORY_3D}, {"debug(f(args))", 0, "Execute la fonction f en mode pas a pas.", 0, 0, CAT_CATEGORY_PROG | XCAS_ONLY}, @@ -1029,6 +1028,7 @@ namespace giac { {"float(x)", 0, "Convertit x en nombre approche (flottant).", "pi", 0, CAT_CATEGORY_REAL}, {"floor(x)", 0, "Partie entiere de x", "pi", 0, CAT_CATEGORY_REAL}, {"fonction f(x)", "fonction", "Definition de fonction (Xcas). Par exemple\nfonction f(x)\n local y;\ny:=x*x;\nreturn y;\nffonction", 0, 0, CAT_CATEGORY_PROG | XCAS_ONLY}, + {"frenet([x(t),y(t)],t,t0)", 0, "Courbure, centre de courbure et repere de Frenet de la courbe parametree [x(t),y(t)] en t0", "[t,t^2],t,1", "[t,t^2],t", CAT_CATEGORY_CALCULUS | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, {"from arit import *", "from arit import *", "Instruction pour utiliser les fonctions d'arithmetique entiere en Python", "#from arit import *", "#import arit", CAT_CATEGORY_ARIT}, {"from cas import *", "from cas import *", "Permet d'utiliser le calcul formel depuis Python", "#from cas import *", "#import cas", CAT_CATEGORY_ALGEBRA|(CAT_CATEGORY_CALCULUS<<8)}, {"from cmath import *", "from cmath import *", "Instruction pour utiliser les fonctions de maths sur les complexes (trigo, exponentielle, log, ...) en Python", "#from cmath import *;i=1j", "#import cmath", CAT_CATEGORY_COMPLEXNUM}, @@ -1072,6 +1072,11 @@ namespace giac { {"iquo(a,b)", 0, "Quotient euclidien de deux entiers.", "23,13", 0, CAT_CATEGORY_ARIT | XCAS_ONLY}, {"irem(a,b)", 0,"Reste euclidien de deux entiers", "23,13", 0, CAT_CATEGORY_ARIT | XCAS_ONLY}, {"isprime(n)", 0, "Renvoie 1 si n est premier, 0 sinon.", "11", "10", CAT_CATEGORY_ARIT}, + {"is_collinear(A,B,C)", 0, "Renvoie 1 ou 2 si A, B, C sont alignes, 0 sinon.", "1,i,-1", "i,0,-i", CAT_CATEGORY_2D | XCAS_ONLY }, + {"is_concyclic(A,B,C,D)", 0, "Renvoie 1 si A, B, C, D sont cocyliques, 0 sinon.", "1,i,-1,-i", "1,i,0,-i", CAT_CATEGORY_2D | XCAS_ONLY }, + {"is_element(A,G)", 0, "Renvoie 1 si A appartient a G, 0 sinon.", "point(0),circle(0,1)", "point(i),square(0,1)", CAT_CATEGORY_2D | XCAS_ONLY }, + {"is_parallel(D,E)", 0, "Renvoie 1 si D et E sont paralleles, 0 sinon.", "line(y=x),line(y=-x)", "line(y=x),line(y=x+1)", CAT_CATEGORY_2D | XCAS_ONLY }, + {"is_perpendicular(D,E)", 0, "Renvoie 1 si D et E sont perpendiculaires, 0 sinon.", "line(y=x),line(y=-x)", "line(y=x),line(y=x+1)", CAT_CATEGORY_2D | XCAS_ONLY }, {"jordan(A)", 0, "Forme normale de Jordan de la matrice A, renvoie P et D tels que P^-1*A*P=D", "[[1,2],[3,4]]", "[[1,1,-1,2,-1],[2,0,1,-4,-1],[0,1,1,1,1],[0,1,2,0,1],[0,0,-3,3,-1]]", CAT_CATEGORY_MATRIX | XCAS_ONLY}, {"laguerre(n,a,x)", 0, "n-ieme polynome de Laguerre (a=0 par defaut).", "10", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, {"laplace(f,x,s)", 0, "Transformee de Laplace de f","sin(x),x,s", 0, CAT_CATEGORY_CALCULUS | XCAS_ONLY}, @@ -1110,6 +1115,7 @@ namespace giac { {"numer(x)", 0, "Numerateur de x.", "3/4", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, {"octahedron(A,B,C)", 0, "Octaedre d'arete AB avec une face dans le plan ABC", "[0,0,0],[3,0,0],[0,1,0]", 0, CAT_CATEGORY_3D}, {"odesolve(f(t,y),[t,y],[t0,y0],t1)", 0, "Solution approchee d'equation differentielle y'=f(t,y) et y(t0)=y0, valeur en t1 (ajouter curve pour les valeurs intermediaires de y)", "sin(t*y),[t,y],[0,1],2", "0..pi,(t,v)->{[-v[1],v[0]]},[0,1]", CAT_CATEGORY_SOLVE | XCAS_ONLY}, + {"osculating_circle([x(t),y(t)],t,t0)", 0, "Cercle osculateur de la courbe parametree [x(t),y(t)] en t0", "[t,t^2],t,1", "[t,t^2],t", CAT_CATEGORY_CALCULUS | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, {"parabole(F,A)", 0, "Parabole donnee par foyer et sommet", "-2-i,2+i", 0, CAT_CATEGORY_2D}, {"parameq(objet)", 0, "Equations parametriques. Utiliser equation pour une equation cartesienne", "circle(0,1)", "ellipse(-1,1,3)", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, {"partfrac(p,x)", 0, "Decomposition en elements simples. Raccourci p=>+", "1/(x^4-1)", 0, CAT_CATEGORY_ALGEBRA | XCAS_ONLY}, @@ -1461,6 +1467,11 @@ const catalogFunc completeCaten[] = { // list of all functions (including some n {"iquo(a,b)", 0, "Integer quotient of a and b.", "23,13", 0, CAT_CATEGORY_ARIT}, {"irem(a,b)", 0,"Integer remainder of a and b.", "23,13", 0, CAT_CATEGORY_ARIT}, {"isprime(n)", 0, "Returns 1 if n is prime, 0 otherwise.", "11", "10", CAT_CATEGORY_ARIT}, + {"is_collinear(A,B,C)", 0, "Returns 1 if A, B, C are collinear, 0 otherwise", "1,i,-1", "i,0,-i", CAT_CATEGORY_2D | XCAS_ONLY }, + {"is_concyclic(A,B,C,D)", 0, "Returns 1 if A, B, C, D are concyclic, 0 otherwise", "1,i,-1,-i", "1,i,0,-i", CAT_CATEGORY_2D | XCAS_ONLY }, + {"is_element(A,G)", 0, "Returns 1 if A belongs to G, 0 otherwise.", "point(0),circle(0,1)", "point(i),square(0,1)", CAT_CATEGORY_2D | XCAS_ONLY }, + {"is_parallel(D,E)", 0, "Returns 1 if D and E are parallel, 0 otherwise", "line(y=x),line(y=-x)", "line(y=x),line(y=x+1)", CAT_CATEGORY_2D | XCAS_ONLY }, + {"is_perpendicular(D,E)", 0, "Returns 1 if D and E are perpendicular, 0 otherwise", "line(y=x),line(y=-x)", "line(y=x),line(y=x+1)", CAT_CATEGORY_2D | XCAS_ONLY }, {"jordan(A)", 0, "Jordan normal form of matrix A, returns P and D such that P^-1*A*P=D", "[[1,2],[3,4]]", "[[1,1,-1,2,-1],[2,0,1,-4,-1],[0,1,1,1,1],[0,1,2,0,1],[0,0,-3,3,-1]]", CAT_CATEGORY_MATRIX}, {"laguerre(n,a,x)", 0, "n-ieme Laguerre polynomial (default a=0).", "10", 0, CAT_CATEGORY_POLYNOMIAL}, {"laplace(f,x,s)", 0, "Laplace transform of f","sin(x),x,s", 0, CAT_CATEGORY_CALCULUS}, @@ -2267,6 +2278,109 @@ const catalogFunc completeCaten[] = { // list of all functions (including some n return i; } + // geo_print / geoprint + std::string _pnt2string(const giac::gen & g,const giac::context * contextptr){ + unsigned ta=taille(g,100); + if (ta>100) + return "Done"; + if (g.is_symb_of_sommet(giac::at_pnt)){ + giac::gen & f=g._SYMBptr->feuille; + giac::gen fp=remove_at_pnt(g); + if (fp.is_symb_of_sommet(giac::at_hyperplan)){ + return gettext("plan")+string("(")+_equation(g,contextptr).print(contextptr)+string(")"); + } + if (f.type==giac::_VECT && !f._VECTptr->empty()){ + giac::gen f0=f._VECTptr->front(); + if (f0.is_symb_of_sommet(giac::at_legende)){ + return g.print(contextptr); + } + if (f0.is_symb_of_sommet(giac::at_curve)){ + giac::gen f1=f[0]._SYMBptr->feuille; + if (f1.type==giac::_VECT && !f1._VECTptr->empty() ){ + giac::gen f1f=f1._VECTptr->front(); + if (f1f.type==giac::_VECT && f1f._VECTptr->size()>=4){ + giac::vecteur f1v=*f1f._VECTptr; + return "plotparam("+_pnt2string(f1v[0],contextptr)+","+f1v[1].print(contextptr)+"="+f1v[2].print(contextptr)+".."+f1v[3].print(contextptr)+")"; + } + } + } + if (f0.is_symb_of_sommet(giac::at_cercle) && f0._SYMBptr->feuille.type==giac::_VECT){ + if (f0._SYMBptr->feuille._VECTptr->size()==3 && ((*f0._SYMBptr->feuille._VECTptr)[2]!=giac::cst_two_pi || (*f0._SYMBptr->feuille._VECTptr)[1]!=0)) + return f0.print(contextptr); + giac::gen centre,rayon; + if (!giac::centre_rayon(f0,centre,rayon,true,0)) + return "cercle_error"; + if (!complex_mode(contextptr) && (centre.typebegin(),itend=f0._VECTptr->end(); + if ( itend-it==2){ + switch(f0.subtype){ + case giac::_LINE__VECT: + s=gettext("line")+string("("); + break; + case giac::_HALFLINE__VECT: + s=gettext("half_line")+string("("); + break; + case giac::_GROUP__VECT: + s=gettext("segment")+string("("); + break; + } + if (f0.subtype==giac::_LINE__VECT && it->type!=giac::_VECT){ // 2-d line + s += _equation(g,contextptr).print(contextptr) + ")"; + return s; + } + } + for (;it!=itend;){ + s += "point("; + if (!complex_mode(contextptr) && (it->typetype==giac::_FRAC) ) + s += giac::re(*it,contextptr).print(contextptr)+","+giac::im(*it,contextptr).print(contextptr); + else { + gen f=*it; + if (f.type==_VECT && f.subtype==_POINT__VECT) + f.subtype=_SEQ__VECT; + s += f.print(contextptr); + } + s+=")"; + ++it; + s += it==itend?")":","; + } + return s; + } + if ( (f0.type!=giac::_FRAC && f0.type>=giac::_IDNT) || is3d(g) || complex_mode(contextptr)){ + if (f0.type==_VECT && f0.subtype==_POINT__VECT) + f0.subtype=_SEQ__VECT; + return "point("+f0.print(contextptr)+")"; + } + else + return "point("+giac::re(f0,contextptr).print(contextptr)+","+giac::im(f0,contextptr).print(contextptr)+")"; + } + } + if (g.type==giac::_VECT && !g._VECTptr->empty() && g._VECTptr->back().is_symb_of_sommet(giac::at_pnt)){ + std::string s = "["; + giac::const_iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end(); + for (;it!=itend;){ + s += _pnt2string(*it,contextptr); + ++it; + s += it==itend?"]":","; + } + return s; + } + return g.print(contextptr); + } + + std::string pnt2string(const giac::gen & g,const giac::context * contextptr){ + int p=python_compat(contextptr); + python_compat(0,contextptr); + string s=_pnt2string(g,contextptr); + python_compat(p,contextptr); + return s; + } + gen select_var(GIAC_CONTEXT){ kbd_interrupted=giac::ctrl_c=giac::interrupted=false; #ifdef QUICKJS @@ -2340,8 +2454,8 @@ const catalogFunc completeCaten[] = { // list of all functions (including some n vector vi(9); tailles(w,vi); total += vi[8]; - if (vi[8]<400) - vs[i]+=":="+w.print(contextptr); + if (vi[8]=0){ argcolor=0; return d; } + argcolor=M_PI; return -d; + } + double x=g._CPLXptr->_DOUBLE_val,y=(g._CPLXptr+1)->_DOUBLE_val; + argcolor=std::atan2(x,y); + double n=std::sqrt(x*x+y*y); // will be encoded in a float, no overflow care + return n; + } + // hpersurface encoded as a matrix // with lines containing 3 coordinates per point bool Graph2d::glsurface(int w,int h,int lcdz,GIAC_CONTEXT, @@ -6078,6 +6340,7 @@ namespace xcas { double hyperxymax=-1e307,hyperxymin=1e307; double3 tri[4]; for (int k=0;k >::const_iterator sbeg=hypv[k],send=hypv[k+1],sprec,scur; vector::const_iterator itprec,itcur,itprecend; for (sprec=sbeg,scur=sprec+1;scura; + z1 = ((float2 *)&z1)->f; + a2 = ((float2 *)&z2)->a; + z2 = ((float2 *)&z2)->f; + a3 = ((float2 *)&z3)->a; + z3 = ((float2 *)&z3)->f; + a4 = ((float2 *)&z4)->a; + z4 = ((float2 *)&z4)->f; + } yx1=y1-x1; yx2=y2-x2; yx3=y3-x3; yx4=y4-x4; #ifdef HYPERQUAD tri[0]=double3(x1,y1,z1); @@ -6146,7 +6420,16 @@ namespace xcas { if (xy123>hyperxymax) hyperxymax=xy123; do_transform(invtransform,x123,y123,z123,X,Y,Z); if (Z>=window_zmin && Z<=window_zmax && X>=window_xmin && X<=window_xmax && Y>=window_ymin && Y<=window_ymax ){ - hypertriangle_t res; res.colorptr=&hyp_color[k]; + hypertriangle_t res; + if (cplx){ + int idx=(a1+M_PI)*sizeof(tabcolorcplx)/(sizeof(int4)*2*M_PI); + if (idx<0 || idx >=sizeof(tabcolorcplx)/(sizeof(int4))) + idx = 0; + //CERR << idx << " "; + res.colorptr=&tabcolorcplx[idx]; + } + else + res.colorptr=&hyp_color[k]; compute(yx,tri,res); hypertriangles.push_back(res); } @@ -6237,7 +6520,7 @@ namespace xcas { if (plan_filled[k]){ only_hypertri=false; break; } } if (only_hypertri){ - if (hypertriangles.empty()) continue; + if (hypertriangles.empty()) goto suite3d; int effjmax=(hyperxymax-xc-yc)/yscale/2.0,effjmin=(hyperxymin-xc-yc)/yscale/2.0; if (effjmax+1 & selected,bool is3d){ + vecteur w(v); + vector s(selected); sort(s.begin(),s.end()); + int pos=0; + for (int i=0;i=s.size()) + break; + if (i==s[pos]){ + ++pos; + gen g=w[i]; + if (g.is_symb_of_sommet(at_pnt)){ + g=g._SYMBptr->feuille; + if (g.type==_VECT && g._VECTptr->size()>=2){ + vecteur gv(*g._VECTptr); + gv[1]=is3d?_CYAN:_BLUE; + g=gen(gv,g.subtype); + w[i]=symbolic(at_pnt,g); + } + } + } + } + return w; + } + + vecteur Graph2d::selected_names(bool allobjects,bool withdef) const { + vector::const_iterator it=selected.begin(),itend=selected.end(); + vecteur res; + for (;it!=itend;++it){ + gen g=symbolic_instructions[*it]; + if (g.is_symb_of_sommet(at_sto)){ + gen tmp=g._SYMBptr->feuille[0]; + if (allobjects || tmp.is_symb_of_sommet(at_point) || tmp.is_symb_of_sommet(at_element)) + res.push_back(withdef?g:g._SYMBptr->feuille[1]); + } + } + return res; + } + + void Graph2d::adjust_cursor_point_type(){ + if (hp){ + double newx,newy,newz; + find_xyz(current_i,current_j,current_depth,newx,newy,newz); + int pos=-1; + gen orig; + gen res=geometry_round(newx,newy,newz,find_eps(),orig,pos); + if (mode==0){ + if (pos>=0) + selected=vector(1,pos); + else + selected.clear(); + } + cursor_point_type=pos>=0?6:3; + } + } + + void Graph2d::update_g(){ + if (hp){ + adjust_cursor_point_type(); + find_title_plot(title_tmp,plot_tmp); + vecteur v(mergevecteur(get_current_animation(),trace_instructions)); + if (!is_undef(plot_tmp)) v.push_back(plot_tmp); + // geometry: update g from plot_instructions + g=mergevecteur(selected.empty()?plot_instructions:mark_selected(plot_instructions,selected,is3d),v); + if (is3d) + update_rotation(); + } + } + void Graph2d::update(){ + update_g(); update_scales(); - if (is3d) update_rotation(); + update_rotation(); } void mult4(double * c,double k,double * res){ @@ -7054,6 +7410,12 @@ namespace xcas { j=LCD_HEIGHT_PX/2-Z*lcdz+(Y+X)/9.6*LCD_WIDTH_PX; } + void Graph2d::xyz2ij(const double3 &d,double &i,double &j,double3 & d3) const { + do_transform(transform,d.x,d.y,d.z,d3.x,d3.y,d3.z); + i=LCD_WIDTH_PX/2+(d3.y-d3.x)/4.8*LCD_WIDTH_PX; + j=LCD_HEIGHT_PX/2-d3.z*lcdz+(d3.y+d3.x)/9.6*LCD_WIDTH_PX; + } + void Graph2d::XYZ2ij(const double3 &d,int &i,int &j) const { double X=d.x,Y=d.y,Z=d.z; i=LCD_WIDTH_PX/2+(Y-X)/4.8*LCD_WIDTH_PX; @@ -7061,6 +7423,8 @@ namespace xcas { } void Graph2d::update_rotation(){ + if (!is3d) + return; solid3d=false; double rx,ry,rz,theta; get_axis_angle_deg(q,rx,ry,rz,theta); @@ -7154,31 +7518,33 @@ namespace xcas { continue; } bool line=G.subtype==_LINE__VECT,halfline=G.subtype==_HALFLINE__VECT,segment= G.subtype==_GROUP__VECT; - if (G.type==_VECT && G._VECTptr->size()==2 && (line || halfline || segment)){ - gen a=evalf_double(G._VECTptr->front(),1,contextptr),b=evalf_double(G._VECTptr->back(),1,contextptr); - if (a.type==_VECT && b.type==_VECT && a._VECTptr->size()==3 && b._VECTptr->size()==3){ - vecteur & A=*a._VECTptr; - vecteur & B=*b._VECTptr; - if (A[0].type==_DOUBLE_ && A[1].type==_DOUBLE_ && A[2].type==_DOUBLE_ && B[0].type==_DOUBLE_ && B[1].type==_DOUBLE_ && B[2].type==_DOUBLE_ ){ - lines.push_back(ptr); - double x=A[0]._DOUBLE_val,y=A[1]._DOUBLE_val,z=A[2]._DOUBLE_val; + if (G.type==_VECT && G._VECTptr->size()>=2 && (line || halfline || segment)){ + for (int n=1;nsize();++n){ + gen a=evalf_double((*G._VECTptr)[n-1],1,contextptr),b=evalf_double((*G._VECTptr)[n],1,contextptr); + if (a.type==_VECT && b.type==_VECT && a._VECTptr->size()==3 && b._VECTptr->size()==3){ + vecteur & A=*a._VECTptr; + vecteur & B=*b._VECTptr; + if (A[0].type==_DOUBLE_ && A[1].type==_DOUBLE_ && A[2].type==_DOUBLE_ && B[0].type==_DOUBLE_ && B[1].type==_DOUBLE_ && B[2].type==_DOUBLE_ ){ + lines.push_back(ptr); + double x=A[0]._DOUBLE_val,y=A[1]._DOUBLE_val,z=A[2]._DOUBLE_val; #if 0 // ndef OLD_LINE_RENDERING - double3 prev(x,y,z); - linev.push_back(prev); + double3 prev(x,y,z); + linev.push_back(prev); #endif - double X,Y,Z; - do_transform(transform,x,y,z,X,Y,Z); - double3 M(X,Y,Z); - x=B[0]._DOUBLE_val;y=B[1]._DOUBLE_val;z=B[2]._DOUBLE_val; + double X,Y,Z; + do_transform(transform,x,y,z,X,Y,Z); + double3 M(X,Y,Z); + x=B[0]._DOUBLE_val;y=B[1]._DOUBLE_val;z=B[2]._DOUBLE_val; #if 0 // ndef OLD_LINE_RENDERING - linev.push_back(double3(x-prev.x,y-prev.y,z-prev.z)); -#endif - do_transform(transform,x,y,z,X,Y,Z); - double3 N(X,Y,Z); - double3 v(N.x-M.x,N.y-M.y,N.z-M.z); - linev.push_back(M); linev.push_back(v); - linetypev.push_back(G.subtype); - line_color.push_back(int4(u,d,du,dd)); + linev.push_back(double3(x-prev.x,y-prev.y,z-prev.z)); +#endif + do_transform(transform,x,y,z,X,Y,Z); + double3 N(X,Y,Z); + double3 v(N.x-M.x,N.y-M.y,N.z-M.z); + linev.push_back(M); linev.push_back(v); + linetypev.push_back(G.subtype); + line_color.push_back(int4(u,d,du,dd)); + } } } continue; @@ -7242,24 +7608,37 @@ namespace xcas { if (h.type==_VECT && h.subtype==_POLYEDRE__VECT) G=h; else if (ckmatrix(h,true)){ + bool cplx=has_i(h); // 4d hypersurface, encode color in a float+int + double argcplx; surfacev.push_back(vector< vector >(0)); vector< vector > & S=surfacev.back(); const vecteur & V=*h._VECTptr; S.reserve(V.size()); for (int j=0;j(0)); vector &S_=S.back(); S_.reserve(vj.size()); for (int k=0;kf = Z; + fptr->a = argcplx; + S_.push_back(Z); + } + else + S_.push_back(Z); } } - hyp_color.push_back(int4(u,d,du,dd)); + hyp_color.push_back(cplx?int4(0,0,0,0):int4(u,d,du,dd)); continue; } // end quad hypersurface } // end hypersurface @@ -7555,7 +7934,40 @@ namespace xcas { int mxw=LCD_WIDTH_PX,myw=LCD_HEIGHT_PX-STATUS_AREA_PX; double i0,j0,i0save,j0save,i1,j1; int fs=f.size(); - if ((fs==4) && (s==at_parameter)){ + if (fs>=4 && s==at_parameter && f[0].type==_IDNT){ + // display parameter from the left upper, f[0] name and f[3] value + char ch[128]; + strcpy(ch,f[0]._IDNTptr->id_name); + int pos=strlen(ch); + ch[pos]='='; + ++pos; + ch[pos]=0; + gen g=evalf_double(f[3],1,contextptr); + if (g.type==_DOUBLE_) + strcpy(ch+pos,g.print(contextptr).c_str()); + else { + ch[pos]='?'; + ++pos; + ch[pos]=0; + } + ++Mon_image.nparams; + int dw=fl_width(ch); + int fheight=14; + int ypos=(fheight+1)*Mon_image.nparams+fheight; + drawRectangle(1,ypos,dw,fheight-1,Mon_image.is3d?_BLACK:_WHITE); + os_draw_string_small_(1,ypos-fheight,ch); + if (Mon_image.pushed && Mon_image.moving_param){ + drawLine(64,ypos-2,192,ypos-2,Mon_image.is3d?_WHITE:_BLACK); + drawLine(64,ypos,64,ypos-fheight,Mon_image.is3d?_WHITE:_BLACK); + drawLine(192,ypos,192,ypos-fheight,Mon_image.is3d?_WHITE:_BLACK); + os_draw_string_small_(65,ypos-fheight-2,f[1].print(contextptr).c_str()); + os_draw_string_small_(193,ypos-fheight-2,f[2].print(contextptr).c_str()); + gen gxpos=64+128*(g-f[1])/(f[2]-f[1]); + if (gxpos.type==_DOUBLE_){ + int xpos=gxpos._DOUBLE_val; + drawLine(xpos,ypos,xpos,ypos-fheight,_RED); + } + } return ; } string the_legend; @@ -7656,7 +8068,7 @@ namespace xcas { return; } } // end circle -#if 0 +#if 1 if (point._SYMBptr->sommet==at_legende){ gen & f=point._SYMBptr->feuille; if (f.type==_VECT && f._VECTptr->size()==3){ @@ -7889,6 +8301,20 @@ namespace xcas { x/=n; y/=n; } + void Graph2d::adddepth(vector & polyg,const double3 &A,const double3 &B,int2 & IJmin) const { + if ((A.z-current_depth)*(B.z-current_depth)>0) + return; + double t=(current_depth-A.z)/(B.z-A.z); + double x=A.x+t*(B.x-A.x); + double y=A.y+t*(B.y-A.y); + int I,J; + XYZ2ij(double3(x,y,current_depth),I,J); + int2 IJ(I,J); + polyg.push_back(IJ); + if (IJ & polyg,double x,double y,double z,int2 & IJmin) const { int I,J; xyz2ij(double3(x,y,z),I,J); @@ -7898,7 +8324,184 @@ namespace xcas { IJmin=IJ; } + int roundint (double r) { + int tmp = static_cast (r); + tmp += (r-tmp>=.5) - (r-tmp<=-.5); + return tmp; + } + + bool Graph2d::find_dxdy(double & dx, double & dy) const { + double xmin=window_xmin,xmax=window_xmax; + int hp=LCD_WIDTH_PX-1; + dx=(xmax-xmin)/hp; + double ymin=window_ymin,ymax=window_ymax; + int vp=LCD_HEIGHT_PX-1; + dy=(ymax-ymin)/vp; + return abs(dx-dy) < 0.000001; + } + + void Graph2d::find_xy(double i,double j,double & x,double & y) const { + double xmin=window_xmin,xmax=window_xmax; + x=xmin+i*(xmax-xmin)/LCD_WIDTH_PX; + double ymin=window_ymin,ymax=window_ymax; + y=ymax-j*(ymax-ymin)/LCD_HEIGHT_PX; + } + + void Graph2d::round_xy(double & x, double & y) const { + double dx,dy; + find_dxdy(dx,dy); + double range = pow(10,log10(1.0/dx)); + x = roundint(x * range) / range; + y = roundint(y * range) / range; + } + + void round3(double & x,double xmin,double xmax){ + double dx=std::abs(xmax-xmin); + double logdx=std::log10(dx); + int ndec=int(logdx)-3; + double xpow=std::pow(10.0,ndec); + int newx=x>=0?int(x/xpow+0.5):int(x/xpow-0.5); + x=newx*xpow; + } + + vecteur Graph2d::param(double d) const { + const_iterateur it=plot_instructions.begin(),itend=plot_instructions.end(); + vecteur res; + double pos=0.5; + for (int i=0 ;it!=itend;++i,++it){ + gen tmp=*it; + if (tmp.is_symb_of_sommet(at_parameter)){ + tmp=tmp._SYMBptr->feuille; + if (tmp.type==_VECT && tmp._VECTptr->size()>=4){ + if (std::abs(d-pos)<0.50001){ + res.push_back(tmp); + res.push_back(i); + } + ++pos; + } + } + } + return res; + } + + void Graph2d::draw_decorations(const gen & title_tmp){ + if (args_tmp.empty()){ // add selected names + char s[256]; strcpy(s,modestr.c_str()); + int pos=0,modestrsize=modestr.size(); + pos += modestrsize; + s[pos++]=' '; + if (mode!=0 && drag_name.type==_IDNT){ + strcpy(s+pos,drag_name._IDNTptr->id_name); + pos += strlen(drag_name._IDNTptr->id_name); + } + else { + if (1 || mode==0 || mode==255){ // print selected names + vecteur v; + if (mode!=255) v=selected_names(true,false); + if (v.empty() && current_i<=192 && current_j<14*nparams+21){ + double d=current_j/14.-1; + v=param(d); + if (v.size()!=2) + v.clear(); + else + v=vecteur(1,v.front()[0]); + } + int vs=v.size(); + if (!vs){ // print current coordinates + double i=current_i,j=current_j,x,y,z; + if (is3d){ + find_xyz(i,j,current_depth,x,y,z); + round_xy(x,y); round3(z,window_zmin,window_zmax); + sprintf(s+pos," %.3g,%.3g,%.3g",x,y,z); + } + else { + find_xy(i,j,x,y); + // round to maximum pixel range + round_xy(x,y); + sprintf(s+pos," %.3g,%.3g",x,y); + } + pos=strlen(s); + } + for (int i=0;iid_name); + pos += strlen(v[i]._IDNTptr->id_name); + if (iptr()->s+('('+title_tmp.print(contextptr)+')'); // gen(symbolic(*function_final._FUNCptr,title_tmp)).print(contextptr); + } + else + mytitle=title; + if (!mytitle.empty()){ + int dt=int(fl_width(mytitle.c_str())); + if (dt>LCD_WIDTH_PX) + dt=LCD_WIDTH_PX; + os_draw_string_small_((LCD_WIDTH_PX-dt)/2,LCD_HEIGHT_PX-14,mytitle.c_str()); + } + } + if (hp){ // draw cursor at current_i,current_j + int taille=mode==255?2:5; + fl_line(current_i-taille,current_j,current_i+taille,current_j,is3d?_CYAN:_BLUE); + fl_line(current_i,current_j-taille,current_i,current_j+taille,is3d?_CYAN:_BLUE); + if (cursor_point_type==6){ + fl_line(current_i-2,current_j+2,current_i+2,current_j+2,_RED); + fl_line(current_i-2,current_j+2,current_i+2,current_j+2,_RED); + fl_line(current_i-2,current_j-2,current_i-2,current_j+2,_RED); + fl_line(current_i+2,current_j-2,current_i+2,current_j+2,_RED); + } + } + } + + void displaypolyg(const vector & polyg,const int2 & IJmin,int color,int & Px,int & Py,GIAC_CONTEXT){ + if (polyg.empty()) + return; + // sort list of arguments + vector p; + for (int k=0;k > P; + for (int k=0;k vi(2); + vi[0]=p[k].i; + vi[1]=p[k].j; + P.push_back(vi); + } + draw_polygon(P,color + // | 0x400000 + ,contextptr); + Px=P[0][0]; + Py=P[0][1]; + } + void Graph2d::draw(){ + waitforvblank(); + nparams=0; // reset number of parameters (shown from left upper) + if (hp) history_plot(contextptr).clear(); if (is3d){ if (lang==1) statuslinemsg("Toolbox: aide"); @@ -7912,16 +8515,21 @@ namespace xcas { F(window_xmin,window_ymax,window_zmax), G(window_xmax,window_ymax,window_zmin), H(window_xmax,window_ymax,window_zmax); - xyz2ij(A,Ai,Aj); - xyz2ij(B,Bi,Bj); - xyz2ij(C,Ci,Cj); - xyz2ij(D,Di,Dj); - xyz2ij(E,Ei,Ej); - xyz2ij(F,Fi,Fj); - xyz2ij(G,Gi,Gj); - xyz2ij(H,Hi,Hj); + double3 A3,B3,C3,D3,E3,F3,G3,H3; + xyz2ij(A,Ai,Aj,A3); + xyz2ij(B,Bi,Bj,B3); + xyz2ij(C,Ci,Cj,C3); + xyz2ij(D,Di,Dj,D3); + xyz2ij(E,Ei,Ej,E3); + xyz2ij(F,Fi,Fj,F3); + xyz2ij(G,Gi,Gj,G3); + xyz2ij(H,Hi,Hj,H3); set_abort(); + int prec=precision; + if (mode==0 && precision<3) + precision += 2; glsurface(precision,precision,lcdz,contextptr,default_upcolor,default_downcolor,default_downupcolor,default_downdowncolor); + precision=prec; clear_abort(); if (show_edges){ // polyhedrons @@ -8049,10 +8657,31 @@ namespace xcas { drawLine(Ci,Cj,Gi,Gj,COLOR_GREEN | 0x800000); drawLine(Di,Dj,Hi,Hj,COLOR_GREEN | 0x800000); // Z - drawLine(Ai,Aj,Bi,Bj,12345 | 0x800000); - drawLine(Ci,Cj,Di,Dj,12345 | 0x800000); - drawLine(Ei,Ej,Fi,Fj,12345 | 0x800000); - drawLine(Gi,Gj,Hi,Hj,12345 | 0x800000); + drawLine(Ai,Aj,Bi,Bj,COLOR_CYAN | 0x800000); + drawLine(Ci,Cj,Di,Dj,COLOR_CYAN | 0x800000); + drawLine(Ei,Ej,Fi,Fj,COLOR_CYAN | 0x800000); + drawLine(Gi,Gj,Hi,Hj,COLOR_CYAN | 0x800000); + // current_depth + if (hp){ + vector polyg; int2 IJmin={RAND_MAX,RAND_MAX}; + // x: A3-C3, B3-D3; E3-G3,F3-H3 + adddepth(polyg,A3,C3,IJmin); + adddepth(polyg,B3,D3,IJmin); + adddepth(polyg,E3,G3,IJmin); + adddepth(polyg,F3,H3,IJmin); + // y: A3-E3; B3-F3; C3-G3, D3-H3 + adddepth(polyg,A3,E3,IJmin); + adddepth(polyg,B3,F3,IJmin); + adddepth(polyg,C3,G3,IJmin); + adddepth(polyg,D3,H3,IJmin); + // z: A3-B3, C3-D3, E3-F3, G3-H3 + adddepth(polyg,A3,B3,IJmin); + adddepth(polyg,C3,D3,IJmin); + adddepth(polyg,E3,F3,IJmin); + adddepth(polyg,G3,H3,IJmin); + int Px,Py; + displaypolyg(polyg,IJmin,COLOR_YELLOW | 0x400000,Px,Py,contextptr); + } // planes vecteur attrv(gen2vecteur(g)); for (int i=0;i=window_zmin && z<=window_zmax) addpolyg(polyg,window_xmax,window_ymax,z,IJmin); } - // sort list of arguments - vector p; - for (int k=0;k > P; - for (int k=0;k vi(2); - vi[0]=p[k].i; - vi[1]=p[k].j; - P.push_back(vi); - } - draw_polygon(P,upcolor - // | 0x400000 - ,contextptr); + int Px,Py; + displaypolyg(polyg,IJmin,upcolor,Px,Py,contextptr); if (nameptr){ int x=os_draw_string_small(0,0,0,upcolor,nameptr,true); - os_draw_string_small(P[0][0]-x,P[0][1],upcolor,0,nameptr); + os_draw_string_small(Px-x,Py,upcolor,0,nameptr); } } } // frame double xi=Ci-Ai,xj=Cj-Aj; normalize(xi,xj); - drawLine(20,20,20+20*xi,20+20*xj,COLOR_RED); - os_draw_string_small(20+20*xi,20+20*xj,COLOR_RED,COLOR_BLACK,"x"); + int decal=180; + drawLine(20,decal,20+20*xi,decal+20*xj,COLOR_RED); + os_draw_string_small(20+20*xi,decal+20*xj,COLOR_RED,COLOR_BLACK,"x"); double yi=Ei-Ai,yj=Ej-Aj; normalize(yi,yj); - drawLine(20,20,20+20*yi,20+20*yj,COLOR_GREEN); - os_draw_string_small(20+20*yi,20+20*yj,COLOR_GREEN,COLOR_BLACK,"y"); + drawLine(20,decal,20+20*yi,decal+20*yj,COLOR_GREEN); + os_draw_string_small(20+20*yi,decal+20*yj,COLOR_GREEN,COLOR_BLACK,"y"); double zi=Bi-Ai,zj=Bj-Aj; normalize(zi,zj); - drawLine(20,20,20+20*zi,20+20*zj,12345); - os_draw_string_small(20+20*zi,20+20*zj,12345,COLOR_BLACK,"z"); + drawLine(20,decal,20+20*zi,decal+20*zj,COLOR_CYAN); + os_draw_string_small(20+20*zi,decal+20*zj,COLOR_CYAN,COLOR_BLACK,"z"); } // end show_axes // now handle legend([x,y],string) vecteur V(gen2vecteur(g)); for (int i=0;ifeuille.type==_VECT){ + vecteur f=*attr._SYMBptr->feuille._VECTptr; + int fs=f.size(); + if (fs>=4 && f[0].type==_IDNT){ + // display parameter from the left upper, f[0] name and f[3] value + char ch[128]; + strcpy(ch,f[0]._IDNTptr->id_name); + int pos=strlen(ch); + ch[pos]='='; + ++pos; + ch[pos]=0; + gen g=evalf_double(f[3],1,contextptr); + if (g.type==_DOUBLE_) + strcpy(ch+pos,g.print(contextptr).c_str()); + else { + ch[pos]='?'; + ++pos; + ch[pos]=0; + } + ++nparams; + int dw=fl_width(ch); + int fheight=14; + int ypos=(fheight+1)*nparams+fheight; + drawRectangle(1,ypos-fheight,dw,fheight-1,_WHITE); + os_draw_string_small_(1,ypos-fheight,ch); + if (pushed && moving_param){ + drawLine(64,ypos-2,192,ypos-2,is3d?_WHITE:_BLACK); + drawLine(64,ypos,64,ypos-fheight,is3d?_WHITE:_BLACK); + drawLine(192,ypos,192,ypos-fheight,is3d?_WHITE:_BLACK); + os_draw_string_small_(65,ypos-fheight-2,f[1].print(contextptr).c_str()); + os_draw_string_small_(193,ypos-fheight-2,f[2].print(contextptr).c_str()); + gen gxpos=64+128*(g-f[1])/(f[2]-f[1]); + if (gxpos.type==_DOUBLE_){ + int xpos=gxpos._DOUBLE_val; + drawLine(xpos,ypos,xpos,ypos-fheight,_RED); + } + } + } + } // end parameter if (attr.is_symb_of_sommet(at_pnt)){ attr=attr._SYMBptr->feuille; if (attr.type==_VECT && attr._VECTptr->size()>1){ @@ -8205,6 +8851,8 @@ namespace xcas { DefineStatusMessage((char*)"+-: zoom, pad: move, EXIT: quit", 1, 0, 0); #endif DisplayStatusArea(); + if (hp) + draw_decorations(title_tmp); return; } int save_clip_ymin=clip_ymin; @@ -8301,6 +8949,8 @@ namespace xcas { // draw fltk_draw(*this,g,x_scale,y_scale,clip_x,clip_y,clip_w,clip_h,contextptr); clip_ymin=save_clip_ymin; + if (hp) + draw_decorations(title_tmp); } void Graph2d::left(double d){ @@ -8581,11 +9231,11 @@ namespace xcas { } // End logo mode } - - int displaygraph(const giac::gen & ge,GIAC_CONTEXT){ + int displaygraph(const giac::gen & ge,const gen & gs,GIAC_CONTEXT){ // graph display //if (aborttimer > 0) { Timer_Stop(aborttimer); Timer_Deinstall(aborttimer);} xcas::Graph2d gr(ge,contextptr); + if (gs!=0) gr.symbolic_instructions=gen2vecteur(gs); gr.show_axes=global_show_axes; // initial setting for x and y if (ge.type==_VECT){ @@ -8627,110 +9277,1487 @@ namespace xcas { } } } - // UI -#ifdef NSPIRE_NEWLIB - DefineStatusMessage((char*)"+-: zoom, pad: move, esc: quit", 1, 0, 0); + return gr.ui(); + } + + vecteur Graph2d::get_current_animation() const { + if (animation_instructions_pos>=0 && animation_instructions_pos=2){ + gen function=(mode==int(args_tmp.size()))?function_final:function_tmp; + if (function.type==_FUNC){ + bool dim2=!is3d; + vecteur args2=args_tmp; + if ( *function._FUNCptr==(dim2?at_cercle:at_sphere)){ + gen argv1; +#ifdef NO_STDEXCEPT + argv1=evalf(args_tmp.back(),1,contextptr); + argv1=evalf_double(argv1,1,contextptr); #else - DefineStatusMessage((char*)"+-: zoom, pad: move, EXIT: quit", 1, 0, 0); + try { + argv1=evalf(args_tmp.back(),1,contextptr); + argv1=evalf_double(argv1,1,contextptr); + } + catch (std::runtime_error & e){ + argv1=undef; + } #endif - DisplayStatusArea(); - int saveprecision=gr.precision; - gr.precision += 2; // fast draw first - gr.draw(); - gr.precision=saveprecision; - bool redraw=true; - for (;;){ - int saveprec=gr.precision; - if (gr.doprecise){ - gr.doprecise=false; - gr.precision=1;//gr.precision-=2; - } - if (redraw) - gr.draw(); - redraw=true; - gr.precision=saveprec; - DisplayStatusArea(); + if (argv1.is_symb_of_sommet(at_pnt) ||argv1.type==_IDNT){ + argv1=remove_at_pnt(argv1); + if ( (argv1.type==_VECT && argv1.subtype==_POINT__VECT) || argv1.type==_CPLX || argv1.type==_IDNT) + args2.back()=args_tmp.back()-args_tmp.front(); + } + } + if (function==at_ellipse) + ; + title_tmp=gen(args2,_SEQ__VECT); + bool b=approx_mode(contextptr); + if (!b) + approx_mode(true,contextptr); + plot_tmp=symbolic(*function._FUNCptr,title_tmp); + if (!lidnt(title_tmp).empty()) + ; // cerr << plot_tmp << '\n'; + bool bb=io_graph(contextptr); + int locked=0; + if (bb){ +#ifdef HAVE_LIBPTHREAD + // cerr << "plot title lock" << '\n'; + locked=pthread_mutex_trylock(&interactive_mutex); +#endif + if (!locked) + io_graph(false,contextptr); + } + plot_tmp=protecteval(plot_tmp,1,contextptr); + if (bb && !locked){ + io_graph(bb,contextptr); +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&interactive_mutex); + // cerr << "plot title unlock" << '\n'; +#endif + } + if (!b) + approx_mode(false,contextptr); + } // end function.type==_FUNC + else + title_tmp=gen(args_tmp,_SEQ__VECT); + } // end size()>=2 + else + title_tmp=args_tmp; + } + } + + void Graph2d::eval(int start){ + plot_instructions.resize(symbolic_instructions.size()); + if (plot_instructions.empty()) return; + int level=prog_eval_level_val(contextptr); + for (size_t i=start;ifeuille); + f=protecteval(f,1,contextptr); #ifdef NUMWORKS - os_draw_string(0,LCD_HEIGHT_PX-STATUS_AREA_PX-17,COLOR_BLACK,COLOR_WHITE,"toolbox: cfg"); + const int maxtrace=128; #else - os_draw_string(0,LCD_HEIGHT_PX-STATUS_AREA_PX-17,COLOR_BLACK,COLOR_WHITE,"menu: cfg"); + const int maxtrace=512; #endif - int key=-1; - GetKey(&key); - if (key==KEY_SHUTDOWN) - return key; -#if 1 - if (key==KEY_CTRL_CATALOG || key==KEY_BOOK ){ - char menu_xmin[32],menu_xmax[32],menu_ymin[32],menu_ymax[32],menu_zmin[32],menu_zmax[32]; - for (;;){ - string s; - s="xmin "+print_DOUBLE_(gr.window_xmin,contextptr); - strcpy(menu_xmin,s.c_str()); - s="xmax "+print_DOUBLE_(gr.window_xmax,contextptr); - strcpy(menu_xmax,s.c_str()); - s="ymin "+print_DOUBLE_(gr.window_ymin,contextptr); - strcpy(menu_ymin,s.c_str()); - s="ymax "+print_DOUBLE_(gr.window_ymax,contextptr); - strcpy(menu_ymax,s.c_str()); - s="zmin "+print_DOUBLE_(gr.window_zmin,contextptr); - strcpy(menu_zmin,s.c_str()); - s="zmax "+print_DOUBLE_(gr.window_zmax,contextptr); - strcpy(menu_zmax,s.c_str()); - Menu smallmenu; - smallmenu.numitems=15; - MenuItem smallmenuitems[smallmenu.numitems]; - smallmenu.items=smallmenuitems; - smallmenu.height=12; - //smallmenu.title = "KhiCAS"; - smallmenuitems[0].text = (char *) menu_xmin; - smallmenuitems[1].text = (char *) menu_xmax; - smallmenuitems[2].text = (char *) menu_ymin; - smallmenuitems[3].text = (char *) menu_ymax; - smallmenuitems[4].text = (char *) menu_zmin; - smallmenuitems[5].text = (char *) menu_zmax; - smallmenuitems[6].text = (char*) "Orthonormalize /"; - smallmenuitems[7].text = (char*) "Autoscale *"; - smallmenuitems[8].text = (char *) ("Zoom in +"); - smallmenuitems[9].text = (char *) ("Zoom out -"); - smallmenuitems[10].text = (char *) ("Y-Zoom out (-)"); - smallmenuitems[11].text = (char *) ((lang==1)?"raccourcis clavier":"3d shortcuts"); - smallmenuitems[12].text = (char*) ((lang==1)?"Voir axes":"Show axes"); - smallmenuitems[13].text = (char*) ((lang==1)?"Cacher axes":"Hide axes"); - smallmenuitems[14].text = (char*)((lang==1)?"Quitter":"Quit"); - drawRectangle(0,180,LCD_WIDTH_PX,60,_BLACK); - int sres = doMenu(&smallmenu); - if (sres == MENU_RETURN_EXIT) - break; - if (sres == MENU_RETURN_SELECTION || sres==KEY_CTRL_EXE) { - const char * ptr=0; - string s1; double d; - if (smallmenu.selection==1){ - d=gr.window_xmin; - if (inputdouble(menu_xmin,d,200,contextptr)){ - gr.window_xmin=d; - gr.update(); - } - } - if (smallmenu.selection==2){ - d=gr.window_xmax; - if (inputdouble(menu_xmax,d,200,contextptr)){ - gr.window_xmax=d; - gr.update(); - } - } - if (smallmenu.selection==3){ - d=gr.window_ymin; - if (inputdouble(menu_ymin,d,200,contextptr)){ - gr.window_ymin=d; - gr.update(); - } - } - if (smallmenu.selection==4){ - d=gr.window_ymax; - if (inputdouble(menu_ymax,d,200,contextptr)){ - gr.window_ymax=d; - gr.update(); - } + if (trace_instructions.size()>=maxtrace) + trace_instructions.erase(trace_instructions.begin(),trace_instructions.begin()+maxtrace/2); + trace_instructions.push_back(f); + } + } + is3d=false; + for (size_t i=0;idy && dz >dx){ + eps=npixels*dz/L; + eps *= 2; + } + return eps; + } + + void Graph2d::set_gen_value(int n,const giac::gen & g,bool exec){ + // set n-th entry value, if n==-1 add a level + if (!hp) return; + if (n==-1 || n>=symbolic_instructions.size()){ + symbolic_instructions.push_back(g); + n=symbolic_instructions.size()-1; + } else symbolic_instructions[n]=g; + hp->set_string_value(n,g.print(contextptr)); + if (exec) + eval(n); + } + + void Graph2d::find_xyz(double i,double j,double k,double & x,double & y,double & z) const { + if (is3d){ // FIXME + int horiz=LCD_WIDTH_PX/2,vert=horiz/2;//LCD_HEIGHT_PX/2; + double lcdz= LCD_HEIGHT_PX/4; + double xmin=-1,ymin=-1,xmax=1,ymax=1,xscale=0.6*(xmax-xmin)/horiz,yscale=0.6*(ymax-ymin)/vert; + double Z=current_depth; // -1..1 + double I=i-horiz; + double J=j-LCD_HEIGHT_PX/2+lcdz*Z; + double X=yscale*J-xscale*I; + double Y=yscale*J+xscale*I; + do_transform(invtransform,X,Y,Z,x,y,z); + } + else { + z=k; + x=window_xmin+i*(window_xmax-window_xmin)/LCD_WIDTH_PX; + y=window_ymax-j*(window_ymax-window_ymin)/LCD_HEIGHT_PX; + } + } + + gen geometry_round_numeric(double x,double y,double eps,bool approx){ + return approx?gen(x,y):exact_double(x,eps)+cst_i*exact_double(y,eps); + } + + gen geometry_round_numeric(double x,double y,double z,double eps,bool approx){ + return gen(approx?makevecteur(x,y,z):makevecteur(exact_double(x,eps),exact_double(y,eps),exact_double(z,eps)),_POINT__VECT); + } + + gen int2color(int couleur_){ + gen col; + if (couleur_){ + gen tmp; + int val; + vecteur colv; + if ( (val=(couleur_ & 0x0000ffff))){ + tmp=val; + tmp.subtype=_INT_COLOR; + colv.push_back(tmp); + } + if ((val =(couleur_ & 0x00070000))){ + tmp=val; + tmp.subtype=_INT_COLOR; + colv.push_back(tmp); + } + if ((val =(couleur_ & 0x00380000))){ + tmp=val; + tmp.subtype=_INT_COLOR; + colv.push_back(tmp); + } + if ((val =(couleur_ & 0x01c00000))){ + tmp=val; + tmp.subtype=_INT_COLOR; + colv.push_back(tmp); + } + if ((val =(couleur_ & 0x0e000000))){ + tmp=val; + tmp.subtype=_INT_COLOR; + colv.push_back(tmp); + } + if ((val =(couleur_ & 0x30000000))){ + tmp=val; + tmp.subtype=_INT_COLOR; + colv.push_back(tmp); + } + if ((val =(couleur_ & 0x40000000))){ + tmp=val; + tmp.subtype=_INT_COLOR; + colv.push_back(tmp); + } + if ((val =(couleur_ & 0x80000000))){ + tmp=val; + tmp.subtype=_INT_COLOR; + colv.push_back(tmp); + } + if (colv.size()==1) + col=colv.front(); + else + col=symbolic(at_plus,gen(colv,_SEQ__VECT)); + } + return col; + } + + std::string print_color(int couleur){ + return int2color(couleur).print(context0); + } + + giac::gen add_attributs(const giac::gen & g,int couleur_,GIAC_CONTEXT) { + if (g.type!=_SYMB) + return g; + gen & f=g._SYMBptr->feuille; + if (g._SYMBptr->sommet==at_couleur && f.type==_VECT && !f._VECTptr->empty()){ + gen col=couleur_; + col.subtype=_INT_COLOR; + vecteur v(*f._VECTptr); + v.back()=col; + return symbolic(at_couleur,gen(v,_SEQ__VECT)); + } + if (couleur_==default_color(contextptr)) + return g; + if (g._SYMBptr->sommet==at_of){ + gen col=couleur_; + col.subtype=_INT_COLOR; + return symbolic(at_couleur,gen(makevecteur(g,col),_SEQ__VECT)); + } + vecteur v =gen2vecteur(f); + gen col=int2color(couleur_); + v.push_back(symbolic(at_equal,gen(makevecteur(at_display,col),_SEQ__VECT))); + return symbolic(g._SYMBptr->sommet,(v.size()==1 && f.type!=_VECT)?f:gen(v,f.type==_VECT?f.subtype:_SEQ__VECT)); + } + + void Graph2d::do_handle(const gen & g){ + if (hp){ + set_gen_value(hp_pos,g,true); + } + } + + void Graph2d::set_mode(const giac::gen & f_tmp,const giac::gen & f_final,int m,const string & help){ + approx=true; + mode=m; + selected.clear(); + redraw(); + args_help.clear(); + if (mode!=0 && mode!=255){ + int oldmode=calc_mode(contextptr); + calc_mode(0,contextptr); + gen g(help,contextptr); + calc_mode(oldmode,contextptr); + if (g.type==_VECT){ + const_iterateur it = g._VECTptr->begin(),itend=g._VECTptr->end(); + for (;it!=itend;++it) + args_help.push_back(it->print(contextptr)); + } + else + args_help.push_back(g.print(contextptr)); + } + if (mode==255) + modestr=gettext("Frame"); + else + modestr=mode?gen2string(f_final):gettext("Pointer"); + if (mode>=-1){ + pushed=false; + moving_param=moving=moving_frame=false; + // history_pos=-1; + mode=m; + function_final=f_final; + function_tmp=f_tmp; + args_tmp.clear(); + geo_handle(FL_MOVE,0); + update_g(); + } + } + + vecteur Graph2d::selection2vecteur(const vector & v){ + int n=v.size(); + vecteur res(n); + for (int i=0;i=hp->elements.size()) + selected.pop_back(); + } + + gen Graph2d::geometry_round(double x,double y,double z,double eps,gen & original,int & pos,bool selectfirstlevel,bool setscroller) { + if (!hp) + return undef; + gen tmp; + pos=-1; + geometry_round(x,y,z,eps,tmp,contextptr); + if (selected.empty()) + return tmp; + if (function_final==at_areaatraw || function_final==at_areaat || function_final==at_perimeteratraw || function_final==at_perimeterat){ + int p=findfirstclosedcurve(selection2vecteur(selected)); + if (p>0){ + pos=p; + } + } + if (pos==-1){ + if (selectfirstlevel){ + sort(selected.begin(),selected.end()); + // patch so that we move element and not the curve + int p=findfirstpoint(selection2vecteur(selected)); + if (p>0){ + pos=p; + } + } + else + pos=findfirstpoint(selection2vecteur(selected)); + } + gen g=symbolic_instructions[ (pos<0)?(pos=selected.front()):(pos=selected[pos]) ]; + if (pos>=0 && poselements.size()){ + // hp->_sel_begin=hp->_sel_end=pos; + // if (setscroller) hp->line=pos; + } + if (g.is_symb_of_sommet(at_plus) && g._SYMBptr->feuille.type==_VECT && !g._SYMBptr->feuille._VECTptr->empty()) + g=g._SYMBptr->feuille._VECTptr->front(); + if (g.is_symb_of_sommet(at_sto) && g._SYMBptr->feuille.type==_VECT ){ + vecteur & v = *g._SYMBptr->feuille._VECTptr; + if (v.size()==2){ + original = v[0]; + tmp = v[1]; + if (tmp.type==_IDNT){ + gen valeur=protecteval(original,1,contextptr); + if (valeur.is_symb_of_sommet(at_pnt)){ + gen & valf = valeur._SYMBptr->feuille; + if (valf.type==_VECT){ + vecteur & valv = *valf._VECTptr; + int s=v.size(); + if (s>1){ + gen valv1=valv[1]; + if (valv1.type==_VECT && valv1._VECTptr->size()>2){ + tmp=symbolic(at_extract_measure,v[1]); + } + } + } + } + } + } + } + return tmp; + } + + void Graph2d::autoname_plus_plus(){ + if (hp){ + string s=autoname(contextptr); + giac::autoname_plus_plus(s); + autoname(s,contextptr); + } + } + + int Graph2d::geo_handle(int event,int key){ + double eps=find_eps(); + int pos; + gen tmp,tmp2,decal; + if (event==FL_PUSH) + moving_param=false; + if ( pushed && !moving && !moving_frame && mode ==0 && in_area && event==FL_DRAG){ + // FIXME? redraw(); + return 1; + } + if (mode>=2 && event==FL_MOVE && args_tmp.size()>mode) + event=FL_RELEASE; + if ( in_area && ((mode!=1 && event==FL_DRAG) || event==FL_PUSH || event==FL_RELEASE || (mode>=2 && event==FL_MOVE)) ){ + double newx,newy,newz; + find_xyz(current_i,current_j,current_depth,newx,newy,newz); + round3(newx,window_xmin,window_xmax); + round3(newy,window_ymin,window_ymax); + if (is3d) + round3(newz,window_zmin,window_zmax); + tmp=geometry_round(newx,newy,newz,eps,tmp2,pos,mode==0 || (args_tmp.size()==mode && function_final.type==_FUNC && equalposcomp(transformation_functions,*function_final._FUNCptr)),event==FL_RELEASE); + if (tmp.type!=_IDNT && !tmp.is_symb_of_sommet(at_extract_measure)){ + bool done=false; + if (mode==0 && event==FL_PUSH && current_i<192 && current_j<14*nparams+21){ + double d=current_j/14.-1; + vecteur vp=param(d); + if (vp.size()==2){ + tmp=vp[0][0]; + tmp2=vp[0]; + pos=vp[1].val; + done=moving_param=true; + param_min=evalf_double(tmp2[1],1,contextptr)._DOUBLE_val; + param_max=evalf_double(tmp2[2],1,contextptr)._DOUBLE_val; + param_step=evalf_double(tmp2[4],1,contextptr)._DOUBLE_val; + param_orig=param_value=evalf_double(tmp2[3],1,contextptr)._DOUBLE_val; + } + } + if (!done){ + if (tmp.type==_VECT && tmp._VECTptr->size()==3){ + tmp.subtype=_SEQ__VECT; + tmp=symbolic(at_point,tmp); + } + else + tmp=symbolic(at_point,makevecteur(re(tmp,contextptr),im(tmp,contextptr))); + } + } + } + double newx,newy,newz; + if (is3d){ + double x1,y1,z1,x2,y2,z2; + find_xyz(current_i,current_j,current_depth,x1,y1,z1); + find_xyz(push_i,push_j,push_depth,x2,y2,z2); + newx=x1-x2; newy=y1-y2; newz=z1-z2; + } else { + int dw=LCD_WIDTH_PX,dh=LCD_HEIGHT_PX; + double dx=window_xmax-window_xmin; + double dy=window_ymax-window_ymin; + double x_scale=dx/dw,y_scale=dy/dh; + newx=(current_i-push_i)*x_scale; + newy=(push_j-current_j)*y_scale; + newz=0; + } + round3(newx,window_xmin,window_xmax); + round3(newy,window_ymin,window_ymax); + if (is3d){ + round3(newz,window_zmin,window_zmax); + decal=in_area?geometry_round_numeric(newx,newy,newz,eps,approx):0; + if (decal.type==_VECT && decal.subtype==_POINT__VECT) + decal.subtype=0; + } + else + decal=in_area?geometry_round_numeric(newx,newy,eps,approx):0; + // cerr << in_area << " " << decal << '\n'; + if (mode==0 || mode==255) { + if (event==FL_PUSH){ + // select object && flag to move it + if (mode==0 && pos>=0){ + if (tmp.type==_IDNT){ + drag_original_value=tmp2; + drag_name=tmp; + } + else { + drag_original_value=symbolic_instructions[pos]; + drag_name=0; + } + hp_pos=pos; + moving = true; + } + else { // nothing selected, move frame + if (!(display_mode & 0x80)) // disabled by default in 3-d + moving_frame=true; + } + return 1; + } + if (moving_frame && (event==FL_DRAG || event==FL_RELEASE) ){ + window_xmin -= newx; + window_xmax -= newx; + window_ymin -= newy; + window_ymax -= newy; + window_zmin -= newz; + window_zmax -= newz; + push_i = current_i; + push_j = current_j; + push_depth = current_depth; + redraw(); + if (event==FL_RELEASE) + moving_frame=false; + return 1; + } + if (mode==255) + return 0; + if (moving_param && (event==FL_DRAG || event==FL_RELEASE) ){ + // key -> + if (key==KEY_CTRL_EXIT) + param_value=param_orig; + double ps=param_step; + if (ps<=0) + ps=(param_max-param_min)/100; + if (key==KEY_CTRL_LEFT) + param_value -= ps; + if (key==KEY_SHIFT_LEFT) + param_value -= 10*ps; + if (key==KEY_CTRL_RIGHT) + param_value += ps; + if (key==KEY_SHIFT_RIGHT) + param_value += 10*ps; + if (param_valueparam_max) + param_value=param_max; + current_i=64+128*(param_value-param_min)/(param_max-param_min); + if (param_step<=0) + do_handle(symbolic(at_assume,symb_equal(drag_name,param_value))); + else { + gen newval=symbolic(at_element,makesequence(symb_interval(param_min,param_max),param_value)); + do_handle(symbolic(at_sto,makevecteur(newval,drag_name))); + } + if (event==FL_RELEASE){ + moving_param=moving=false; + } + return 1; + } + if (moving && (event==FL_DRAG || event==FL_RELEASE) ){ + // cerr << current_i << " " << current_j << '\n'; + // avoid point()+complex+complex+complex + gen newval=drag_original_value; + if (in_area && key!=KEY_CTRL_EXIT){ + if (drag_original_value.is_symb_of_sommet(at_plus) && drag_original_value._SYMBptr->feuille.type==_VECT && drag_original_value._SYMBptr->feuille._VECTptr->size()>=2){ + vecteur v=*drag_original_value._SYMBptr->feuille._VECTptr; + if (v[1].is_symb_of_sommet(at_nop)) + v[1]=v[1]._SYMBptr->feuille; + newval=symbolic(at_plus,makevecteur(v[0],symbolic(at_nop,ratnormal(_plus(vecteur(v.begin()+1,v.end()),contextptr)+decal)))); + } + else { + newval=is_zero(decal)?drag_original_value:symbolic(at_plus,makevecteur(drag_original_value,symbolic(at_nop,decal))); + } + } + int dclick = 0 || drag_original_value.type==_VECT; + if (!dclick){ + if (drag_name.type==_IDNT) + do_handle(symbolic(at_sto,makevecteur(newval,drag_name))); + else + do_handle(newval); + } + if (event==FL_RELEASE) + moving=false; + selected.clear(); + redraw(); + return 1; + } + return 0; + } + selected.clear(); + if (mode==1){ + if (function_final!=at_point){ + if (event==FL_RELEASE){ + string args=autoname(contextptr)+":="; + if (function_final.type==_FUNC) + args += function_final._FUNCptr->ptr()->s; + args +="("; + if (function_final==at_plotode) + args += fcnfield + "," + fcnvars + "," +tmp.print(contextptr) + ",plan)"; + else + args += tmp.print(contextptr) + ")"; + autoname_plus_plus(); + set_gen_value(-1,gen(args,contextptr),true); + } + if (event==FL_PUSH || event==FL_DRAG || event==FL_RELEASE) + return 1; + return 0; + } + // point|segment mode + if (event==FL_RELEASE){ + hp_pos=-1; + if (hp && !args_tmp.empty() && (std::abs(push_i-current_i)>npixels || std::abs(push_j-current_j)>npixels || (is3d && std::abs(push_depth-current_depth) >0)) ){ + // make a segment + gen val1,val2; + if (in_area && args_tmp.front().is_symb_of_sommet(at_point)){ + val1=gen(autoname(contextptr),contextptr); + // put in last history pack level + set_gen_value(-1,symbolic(at_sto,makevecteur(add_attributs(args_tmp.front(),couleur,contextptr),val1)),false); + hp_pos=hp->elements.size()-1; + autoname_plus_plus(); + } + else + val1=args_tmp.front(); + if (in_area && tmp.is_symb_of_sommet(at_point)){ + val2=gen(autoname(contextptr),contextptr); + gen tmp3=symbolic(at_sto,makevecteur(add_attributs(tmp,couleur,contextptr),val2)); + set_gen_value(-1,tmp3,false); + if (hp_pos<0) hp_pos=hp->elements.size()-1; + autoname_plus_plus(); + } + else + val2=tmp; + if (in_area){ + gen tmp3=add_attributs(symbolic(at_segment,makevecteur(val1,val2)),couleur,contextptr); + string v1v2=val1.print(contextptr)+val2.print(contextptr); + gen g1g2(v1v2,contextptr); + if (g1g2.type!=_IDNT) + g1g2=gen(v1v2+"_",contextptr); + tmp3=symbolic(at_sto,makevecteur(tmp3,g1g2)); + set_gen_value(-1,tmp3,false); + if (hp_pos<0) hp_pos=hp->elements.size()-1; + eval(hp_pos); + } + return 1; + } + if (in_area && tmp.type!=_IDNT) + do_handle(symbolic(at_sto,makevecteur(add_attributs(tmp,couleur,contextptr),gen(autoname(contextptr),contextptr)))); + // element + if (tmp.type==_IDNT && tmp2.type==_SYMB && !equalposcomp(point_sommet_tab_op,tmp2._SYMBptr->sommet)){ + // tmp2 is the geo object, find parameter value + double newx,newy,newz; + find_xyz(current_i,current_j,current_depth,newx,newy,newz); + round3(newx,window_xmin,window_xmax); + round3(newy,window_ymin,window_ymax); + gen t=projection(evalf(tmp2,1,contextptr),gen(newx,newy),contextptr); + if (is_undef(t)) + return 0; + gen tmp3=symbolic(at_element,( (t.type<_IDNT || t.type==_VECT)?gen(makevecteur(tmp,t),_SEQ__VECT):tmp)); + tmp3=symbolic(at_sto,makevecteur(add_attributs(tmp3,couleur,contextptr),gen(autoname(contextptr),contextptr))); + set_gen_value(-1,tmp3,false); + if (hp_pos<0) hp_pos=hp->elements.size()-1; + eval(hp_pos); + } + return 1; + } + if (event==FL_PUSH){ + args_tmp=vecteur(1,tmp); + return 1; + } + if (event==FL_DRAG){ + redraw(); + return 1; + } + return 0; + } + gen tmpval=remove_at_pnt(tmp.eval(1,contextptr)); + gen somm=symbolic(at_sommets,tmp); + int npoints=1; + if (!equalposcomp(nosplit_polygon_function,*function_final._FUNCptr)){ + if (tmpval.type==_VECT && tmpval.subtype==_GROUP__VECT) + npoints=tmpval._VECTptr->size(); + if (tmpval.is_symb_of_sommet(at_cercle)) + npoints=is3d?3:2; + } + unsigned args_size=args_tmp.size(); + // mode>=2 + if (event==FL_MOVE || event==FL_DRAG || event==FL_RELEASE || event==FL_PUSH){ + if (args_sizesize()==2){ + gen tmpa=remove_at_pnt(evalf(args_tmp[0],1,contextptr)); + gen tmpb=new_args_size==2?remove_at_pnt(evalf(args_tmp[1],1,contextptr)):undef; + if (npoints==2 && tmpa==tmp2._VECTptr->front() && tmpb!=tmp2._VECTptr->back()){ + tmp=symbolic(at_at,gen(makevecteur(somm,1),_SEQ__VECT)); + npoints=1; + } + if (npoints==2 && tmpa==tmp2._VECTptr->back() && tmpb!=tmp2._VECTptr->front()){ + tmp=symbolic(at_at,gen(makevecteur(somm,0),_SEQ__VECT)); + npoints=1; + } + if (npoints==2 && tmpb==tmp2._VECTptr->front() && tmpa!=tmp2._VECTptr->back() ){ + swapargs=true; + tmp=symbolic(at_at,gen(makevecteur(somm,1),_SEQ__VECT)); + npoints=1; + } + if (npoints==2 && tmpb==tmp2._VECTptr->back() && tmpa!=tmp2._VECTptr->front()){ + swapargs=true; + tmp=symbolic(at_at,gen(makevecteur(somm,0),_SEQ__VECT)); + npoints=1; + } + } + } + if (npoints+args_tmp.size()>mode) + npoints=1; + if (event==FL_MOVE || event==FL_DRAG || event==FL_RELEASE){ + if (args_size && args_tmp_push_size && args_push!=tmp_push){ + // replace by current mouse position + if (npoints==1) + args_tmp.push_back(tmp); + else { + gen somm=symbolic(at_sommets,tmp); + for (int i=0;i1 && s>=mode){ + if (s>mode){ + args_tmp=vecteur(args_tmp.begin(),args_tmp.begin()+mode); + s=mode; + } + gen tmp_plot; + if (in_area && function_final.type==_FUNC) { + gen res,objname=gen(autoname(contextptr),contextptr); + hp_pos=hp->elements.size(); + if (hp_pos && hp->elements[hp_pos-1].s.empty()) + --hp_pos; + // hp->update_pos=hp_pos; + int pos0=hp_pos; + unary_function_ptr * ptr=function_final._FUNCptr; + int ifinal=mode; + if (equalposcomp(measure_functions,*ptr)) + ifinal--; + // first replace points in args_tmp by assignations + for (int i=0;isize())>2){ + vecteur l; + if (res._VECTptr->back()==res._VECTptr->front()) + --ns; + if (function_final.type==_FUNC && equalposcomp(transformation_functions,*function_final._FUNCptr)){ + vecteur argv; + gen objn,som=symbolic(at_sommets,objname); + for (int i=1;i<=ns;++i){ + tmp_plot=symbolic(at_at,gen(makevecteur(som,i-1),_SEQ__VECT)); + objn=gen(autoname(contextptr)+print_INT_(i),contextptr); + argv.push_back(objn); + set_gen_value(hp_pos,symbolic(at_sto,gen(makevecteur(tmp_plot,objn),_SEQ__VECT)),false); + add_entry(hp_pos+1); + ++hp_pos; + } + for (int i=1;i<=ns;++i){ + tmp_plot=symbolic(at_segment,makevecteur(argv[i-1],argv[i%ns])); + set_gen_value(hp_pos,symbolic(at_sto,makevecteur(add_attributs(tmp_plot,couleur,contextptr),gen(autoname(contextptr)+print_INT_(ns+i),contextptr))),false); + add_entry(hp_pos+1); + ++hp_pos; + } + } + else { + for (int i=mode;iundo_position=save_undo_position; + eval(pos0); + } + args_tmp.clear(); + args_tmp_push_size=0; + } + redraw(); + return 1; + } + return 0; + } + + void geosave(textArea * text,GIAC_CONTEXT){ + string s=remove_extension(text->filename); + gen tmp(s,contextptr); + if (tmp.type==_IDNT){ + sto(makevecteur(at_pnt,string2gen(merge_area(text->elements),false)),tmp,contextptr); + return; + } + else { + for (int i=0;i<10;++i){ + string s1=s+print_INT_(i); + tmp=gen(s1,contextptr); + if (tmp.type==_IDNT){ + confirm(lang==1?"Nom de sauvegarde reserve":"Unable to use reserved name",((lang==1?"Nom utilise ":"Name used ")+s1).c_str()); + sto(makevecteur(at_pnt,string2gen(merge_area(text->elements),false)),tmp,contextptr); + return; + } + } + } + confirm(lang==1?"Nom de sauvegarde reserve":"Unable to use reserved name",lang==1?"Sauvegarde impossible":"Unable to save"); + } + + void geohelp(GIAC_CONTEXT){ + textArea text; + text.editable=false; + text.clipline=-1; + text.title = (char*)((lang==1)?"Aide":"Help"); + text.allowF1=false; + text.python=false; + add(&text,lang==1? + "haut/bas/droit/gauche: change point de vue\ny^x ou e^x: trace 3d precis\nEsc/Back: quitte ou interrompt le trace 3d en cours\n( et ): modifie le rendu des surfaces raides 3d\n0: surfaces cachees 3d ON/OFF\n.: remplissage surface 3d raide ON/OFF\n5 reset 3d view\n7,8,9,1,2,3: deplacement 3d\n\nGeometrie\nF4: change le mode\nLe mode repere (shift 7) permet de changer le point de vue\nLe mode pointeur (shift 8) permet de bouger un objet et les objets dependants avec enter/OK et les touches de deplacement\nLes autres modes permettent de creer des objets\nEsc/Back: permet de passer en vue symbolique et de creer/modifier des objets par des commandes, taper enter/OK pour revenir en vue graphique\n4,6: modifie la profondeur du clic": + "up/down/right/left: modify viewpoint\nEsc/Back: leave or interrupt 3d rendering\ny^x or e^x: precise 3d\n( and ): modify stiff surfaces 3d rendering\n0: hidden 3d surfaces ON/OFF\n.: fill stiff 3d surfacesON/OFF\n5 reset 3d view\n7,8,9,1,2,3: move 3d view\n\nGeometry\nF4: change geometry mode\nFrame mode (shift F1): modify viewpoint\nPointer mode (shift F2): select an object and move it with enter/OK and cursor keys\nOther modes: create an object\nEsc/Back: go to symbolic view where you can create/modify objects with commands, press enter/OK to go back to graphic view"); + int exec=doTextArea(&text,contextptr); + } + + string inputparam(char curname,int symbolic,GIAC_CONTEXT){ + Menu paramenu; + paramenu.numitems=7; + MenuItem paramenuitems[paramenu.numitems]; + paramenu.items=paramenuitems; + paramenu.height=8; + paramenu.title = (char *)"Parameter"; + char menu_xcur[32],menu_xmin[32],menu_xmax[32],menu_xstep[32],menu_name[16]="name a"; + menu_name[5]=curname; + double pcur=0,pmin=-5,pmax=5,pstep=0.1; + std::string s; + bool doit; + for (;;){ + s="cur "+giac::print_DOUBLE_(pcur,contextptr); + strcpy(menu_xcur,s.c_str()); + s="min "+giac::print_DOUBLE_(pmin,contextptr); + strcpy(menu_xmin,s.c_str()); + s="max "+giac::print_DOUBLE_(pmax,contextptr); + strcpy(menu_xmax,s.c_str()); + s="step "+giac::print_DOUBLE_(pstep,contextptr); + strcpy(menu_xstep,s.c_str()); + paramenuitems[0].text = (char *) "OK"; + paramenuitems[1].text = (char *) menu_name; + paramenuitems[2].text = (char *) menu_xcur; + paramenuitems[3].text = (char *) menu_xmin; + paramenuitems[4].text = (char *) menu_xmax; + paramenuitems[5].text = (char *) menu_xstep; + paramenuitems[6].text = (char *) "Symbolic"; + paramenuitems[6].type = MENUITEM_CHECKBOX; + paramenuitems[6].value = symbolic; + int sres = doMenu(¶menu); + doit = sres==MENU_RETURN_SELECTION || sres==KEY_CTRL_EXE; + if (doit) { + std::string s1; double d; + if (paramenu.selection==2){ + handle_f5(); + if (inputline(menu_name,(lang==1)?"Nouvelle valeur?":"New value?",s1,false)==KEY_CTRL_EXE && s1.size()>0 && isalpha(s1[0])){ + if (s1.size()>10) + s1=s1.substr(0,10); + strcpy(menu_name,("name "+s1).c_str()); + } + continue; + } + if (paramenu.selection==3){ + inputdouble(menu_xcur,pcur,contextptr); + continue; + } + if (paramenu.selection==4){ + inputdouble(menu_xmin,pmin,contextptr); + continue; + } + if (paramenu.selection==5){ + inputdouble(menu_xmax,pmax,contextptr); + continue; + } + if (paramenu.selection==6){ + inputdouble(menu_xstep,pstep,contextptr); + pstep=fabs(pstep); + continue; + } + if (paramenu.selection==7){ + symbolic=1-symbolic; + continue; + } + // if (paramenu.selection==6) break; + } // end menu + break; + } // end for (;;) + if (doit && pmin0){ + if (symbolic){ + s="assume("; + s += (menu_name+5); + s += "=["; + s += (menu_xcur+4); + s += ','; + s += (menu_xmin+4); + s += ','; + s += (menu_xmax+4); + s += ','; + s += (menu_xstep+5); + s += "])"; + } + else { + s=(menu_name+5); + s += ":=element("; + s += (menu_xmin+4); + s += ".."; + s += (menu_xmax+4); + s += ','; + s += (menu_xcur+4); + s += ")"; + } + } else s=""; + return s; + } + + int Graph2d::ui(){ + Graph2d & gr=*this; + // UI + int saveprecision=gr.precision; + gr.precision += 2; // fast draw first + gr.draw(); + gr.precision=saveprecision; + gr.must_redraw=true; +#ifdef NSPIRE_NEWLIB + const char * msg="+-: zoom, pad: move, esc: quit"; +#else + const char * msg="+-: zoom, pad: move, EXIT: quit"; +#endif + DefineStatusMessage((char *)msg,1,0,0); + DisplayStatusArea(); + for (;;){ + int saveprec=gr.precision; + if (gr.doprecise){ + gr.doprecise=false; + gr.precision=1;//gr.precision-=2; + } + if (gr.must_redraw) + gr.draw(); + if (hp){ + string msg=hp->filename+":"+(mode==255?" Frame. Shift-1: help":modestr); + // help + int help_pos=args_tmp.empty()?0:args_tmp.size()-1; + if (help_pos='a' && key<='z'){ + bool found=false; + char ch=key; + gen tmp=gen(string("")+ch,contextptr); + if (tmp.type==_IDNT){ + int pos=0; + for (int i=0;ifeuille[0]; + ++pos; + if (name==tmp){ + current_j=7+14*pos; + found=true; + break; + } + } + } + } + if (found) + continue; + key -= 'a'-'A'; + } + if (key>='A' && key<='Z'){ + char ch=key; + gen tmp=gen(string("")+ch,contextptr); + if (tmp.type==_IDNT){ + tmp=evalf(tmp,1,contextptr); + if (tmp.is_symb_of_sommet(at_pnt)){ + tmp=remove_at_pnt(tmp); + if (tmp.is_symb_of_sommet(at_cercle)) + tmp=(tmp._SYMBptr->feuille[0]+tmp._SYMBptr->feuille[1])/2; + if (tmp.type==_SYMB) + tmp=tmp._SYMBptr->feuille; + if (tmp.type==_VECT && tmp.subtype!=_POINT__VECT && !tmp._VECTptr->empty()) + tmp=tmp._VECTptr->front(); + if (is3d && tmp.type==_VECT && tmp._VECTptr->size()==3 && tmp.subtype==_POINT__VECT){ + const vecteur & tv=*tmp._VECTptr; + gen x=tv[0],y=tv[1],z=tv[2]; + x=evalf_double(x,1,contextptr); + y=evalf_double(y,1,contextptr); + z=evalf_double(z,1,contextptr); + if (x.type==_DOUBLE_ && y.type==_DOUBLE_ && z.type==_DOUBLE_){ + double i,j; double3 d3; + xyz2ij(double3(x._DOUBLE_val,y._DOUBLE_val,z._DOUBLE_val),i,j,d3); + current_i=i; current_j=j; current_depth=d3.z; + } + } + if (!is3d && (tmp.type==_DOUBLE_ || tmp.type==_CPLX)){ + double x_scale=LCD_WIDTH_PX/(window_xmax-window_xmin); + double y_scale=LCD_HEIGHT_PX/(window_ymax-window_ymin); + double i,j; + findij(tmp,x_scale,y_scale,i,j,contextptr); + current_i=int(i+.5); + current_j=int(j+.5); + adjust_cursor_point_type(); + geo_handle(moving?FL_DRAG:FL_MOVE,key); + continue; + } + } + } + } + } + if (hp && (key==KEY_CTRL_CATALOG || key==KEY_BOOK )){ + const char * + tab[]={ + lang==1?"Mode repere":"Frame mode", // 0 + lang==1?"Pointeur":"Pointer", + lang==1?"Point":"Point", // 2 + is3d?"Sphere":"Circle", + lang==1?"Triangle":"Triangle", // 4 + lang==1?"Points":"Points", + lang==1?"Droites, plans":"Lines, planes", // 6 + lang==1?"Polygone, polyedre":"Polygon, polyhedron", + lang==1?"Cercle, conique, sphere":"Circle, conic, sphere", // 8 + lang==1?"Courbe, surface":"Curve, surface", // 9 + lang==1?"Curseur":"Cursor", // 10 + lang==1?"Transformations":"Transforms", + lang==1?"Mesures":"Mesures", // 12 + lang==1?"Effacer trace":"Clear trace", // -1 + 0}; + const int s=sizeof(tab)/sizeof(char *); + int choix=select_item(tab,"Mode",true); + if (choix<0 || choix>s) + continue; + if (choix==s-1){ + trace_instructions.clear(); + update_g(); + continue; + } + if (choix<=4){ + gen ftmp[]={0,0,at_point,at_segment,at_segment}; + gen ffinal[]={0,0,at_point,is3d?at_sphere:at_cercle,at_triangle}; + int mode[]={255,0,1,2,3}; + const char * help[]={"","","Point","Center,Point","Point1,Point2,Point3"}; + set_mode(ftmp[choix],ffinal[choix],mode[choix],help[choix]); + continue; + } + draw(); // for small choosebox, we must clean up previous choosebox + if (choix==5){ // Points + const char * + tab[]={ + lang==1?"Point":"Point", + lang==1?"Milieu":"Middle point", + lang==1?"Centre":"Center", + lang==1?"Intersection unique":"Single intersection", + lang==1?"Liste d'intersections":"List of intersections", + lang==1?"Element":"Element", + 0}; + const int s=sizeof(tab)/sizeof(char *); + int choix=select_item(tab,"Points",true); + if (choix<0 || choix>s) + continue; + gen ftmp[]={at_point,at_segment,at_centre,at_inter_unique,at_inter,at_element}; + gen ffinal[]={at_point,at_milieu,at_centre,at_inter_unique,at_inter,at_element}; + int mode[]={1,2,1,2,2,1}; + const char * help[]={ + "Point", + "Point1,Point2", + "Circle", + "Line1,Line2", + "Curve1,Curve2", + "Curve", + }; + set_mode(ftmp[choix],ffinal[choix],mode[choix],help[choix]); + continue; + } + if (choix==6){ // Droites + const char * + tab[]={ + lang==1?"Segment":"Segment", + lang==1?"Vecteur":"Vector", + lang==1?"Demi-droite":"Halfline", + lang==1?"Droite":"Line", + lang==1?"Plan":"Plane", + lang==1?"Parallele":"Parallel", + lang==1?"Perpendiculaire":"Perpendicular", + lang==1?"Mediatrice":"Perpen_bisector", + lang==1?"Bissectrice":"Bisector", + lang==1?"Mediane":"Median line", + lang==1?"Tangente":"Tangent", + 0}; + const int s=sizeof(tab)/sizeof(char *); + int choix=select_item(tab,"Droites, segments...",true); + if (choix<0 || choix>s) + continue; + gen ftmp[]={at_segment,at_vector,at_demi_droite,at_droite,at_segment,at_parallele,at_perpendiculaire,at_mediatrice,at_segment,at_segment,at_segment}; + gen ffinal[]={at_segment,at_vector,at_demi_droite,at_droite,at_plan,at_parallele,at_perpendiculaire,at_mediatrice,at_bissectrice,at_mediane,at_tangent}; + int mode[]={2,2,2,2,2,3,2,2,3,3,2}; + const char * help[]={ + "Point1,Point2", + "Point1,Point2", + "Point1,Point2", + "Point1,Point2", + "Point1,Point2,Point3", + "Point,Line", + "Point,Line", + "Point1,Point2", + "Sommet_angle,Point2,Point3", + "Sommet_angle,Point2,Point3", + "Curve,Point" + }; + set_mode(ftmp[choix],ffinal[choix],mode[choix],help[choix]); + continue; + } + if (choix==7){ // Polygons + const char * + tab[]={ + lang==1?"Triangle":"Triangle", + lang==1?"Triangle equilateral":"Equilateral triangle", + lang==1?"Carre":"Square", + lang==1?"Quadrilatere":"Quadrilateral", + lang==1?"Polygone":"Polygon", + lang==1?"Tetraedre (pyramide)":"Tetrahedron (Pyramid)", + lang==1?"Tetraedre regulier":"Regular tetrahedron", + lang==1?"Cube":"Cube", + lang==1?"Octaedre":"Octahedron", + lang==1?"Dodecaedre":"Dodecahedron", + lang==1?"Icosaedre":"Icosahedron", + 0}; + const int s=sizeof(tab)/sizeof(char *); + int choix=select_item(tab,"Droites, segments...",true); + if (choix<0 || choix>s) + continue; + gen ftmp[]={at_polygone_ouvert,at_segment,at_segment,at_polygone_ouvert,at_polygone_ouvert,at_polygone_ouvert,at_polygone_ouvert,at_polygone_ouvert,at_polygone_ouvert,at_polygone_ouvert,at_polygone_ouvert}; + gen ffinal[]={at_triangle,at_triangle_equilateral,at_carre,at_quadrilatere,at_polygone,at_tetraedre,at_tetraedre,at_cube,at_octaedre,at_dodecaedre,at_icosaedre}; + int mode[]={3,2,2,4,5,4,3,3,3,3,3}; + int m=mode[choix]; + if (choix==4){ + double d=5; + if (inputdouble(lang==1?"Nombre de sommets?":"Number of vertices?",d,contextptr) && d==int(d) && d>=3 && d<20){ + m=d; + } + else continue; + } + const char * help[]={ + "Point1,Point2,Point3", + "Point1,Point2", + "Point1,Point2", + "Point1,Point2,Point3,Point4", + "Point1,Point2,Point3,Point4,Point5", + "Point1,Point2,Point3,Point4", + "Point1,Point2,Point3", + "Point1,Point2,Point3", + "Point1,Point2,Point3", + "Point1,Point2,Point3", + "Point1,Point2,Point3", + }; + set_mode(ftmp[choix],ffinal[choix],m,help[choix]); + continue; + } + if (choix==8){ // Conics + const char * + tab[]={ + lang==1?"cercle":"circle", + lang==1?"circonscrit":"circumcircle", + lang==1?"inscrit":"incircle", + lang==1?"ellipse":"ellipse", + lang==1?"hyperbole":"hyperbola", + lang==1?"parabole":"parabola", + lang==1?"sphere":"sphere", + 0}; + const int s=sizeof(tab)/sizeof(char *); + int choix=select_item(tab,"Conic",true); + if (choix<0 || choix>s) + continue; + gen ftmp[]={at_segment,at_segment,at_segment,at_segment,at_segment,at_segment,at_segment}; + gen ffinal[]={at_cercle,at_circonscrit,at_inscrit,at_ellipse,at_hyperbole,at_parabole,at_sphere}; + int mode[]={2,3,3,3,3,2,2}; + const char * help[]={ + "Center,Point", + "Point1,Point2,Point3", + "Point1,Point2,Point3", + "Focus1,Focus2,Point_on_ellipse", + "Focus1,Focus2,Point_on_hyperbola", + "Focus,Point_or_line", + "Center,Point", + }; + set_mode(ftmp[choix],ffinal[choix],mode[choix],help[choix]); + continue; + } + if (choix==9){ // Curves + const char * + tab[]={ + lang==1?"Fonction plot(sin(x))":"Function plot(sin(x))", + lang==1?"Param. plotparam([x^2,x^3])":"Param. plotparam([x^2,x^3])", + lang==1?"Polaire plotpolar(x)":"Polar plotpolar(x)", + lang==1?"Implicit plot(x^2+y^4=6)":"Implicit plot(x^2+y^4=6)", + lang==1?"Champ des tangentes":"Plotfield", + lang==1?"Solution equa. diff.":"Diff. equa. solution", + 0}; + const int s=sizeof(tab)/sizeof(char *); + int choix=select_item(tab,"Courbe",true); + if (choix<0 || choix>s) + continue; + const char * cmd[]={"plot()","plotparam()","plotpolar()","plot()","plotfield()","plotode()"}; + hp->line=hp->add_entry(-1); + string mycmd=autoname(contextptr)+":="+cmd[choix]; + autoname_plus_plus(); + hp->set_string_value(hp->line,mycmd); + hp->pos=mycmd.size()-1; + return KEY_CTRL_OK; + } + if (choix==10){ + gen param=0; + for (char ch='a';ch<='z';++ch){ + gen tmp(string("")+ch,contextptr); + if (tmp.type!=_IDNT) continue; + param=tmp.eval(1,contextptr); + if (param==tmp) + break; + } + if (param==0){ + confirm(lang==1?"Plus de variables libres.":"No more free variable available",lang==1?"Essayez purge(a) ou purge(b) ou ...":"Try purge(a) or purge(b) or ..."); + continue; + } + string mycmd=inputparam(param.print()[0],0,contextptr); + if (!mycmd.empty()){ + hp->line=hp->add_entry(-1); + // string mycmd=param.print()+":=element(0..1,0.5)"; + // autoname_plus_plus(); + hp->set_string_value(hp->line,mycmd); + hp->pos=mycmd.size()-1; + } + return KEY_CTRL_OK; + } + if (choix==11){ // Transforms + const char * + tab[]={ + lang==1?"symetrie":"reflexion", + lang==1?"rotation":"rotation", + lang==1?"translation":"translation", + lang==1?"projection":"projection", + lang==1?"homothetie":"homothety", + lang==1?"similitude":"similarity", + // lang==1?"":"", + // lang==1?"":"", + 0}; + const int s=sizeof(tab)/sizeof(char *); + int choix=select_item(tab,"Transform",true); + if (choix<0 || choix>s) + continue; + gen ftmp[]={at_segment,at_polygone_ouvert,at_segment,at_segment,at_segment,at_polygone_ouvert}; + gen ffinal[]={at_symetrie,at_rotation,at_translation,at_projection,at_homothetie,at_similitude}; + int mode[]={2,3,2,2,2,3}; + const char * help[]={ + "Symmetry_center_axis,Object", + "Center,Angle,Object", + "Vector,Object", + "Curve,Object", + "Center,Ratio,Object", + "Center,Ratio,Angle,Object" + }; + set_mode(ftmp[choix],ffinal[choix],mode[choix],help[choix]); + continue; + } + if (choix==12){ // Mesures + const char * + tab[]={ + lang==1?"distance":"distance", + lang==1?"angle":"angle", + lang==1?"aire":"area", + lang==1?"perimetre":"perimeter", + lang==1?"pente":"slope", + lang==1?"distance seule":"distance raw", + lang==1?"angle seul":"angle raw", + lang==1?"aire seule":"area raw", + lang==1?"perimetre seul":"perimeter raw", + lang==1?"pente seule":"slope raw", + 0}; + const int s=sizeof(tab)/sizeof(char *); + int choix=select_item(tab,"Mesures",true); + if (choix<0 || choix>s) + continue; + gen ftmp[]={at_segment,at_triangle,at_areaat,at_perimeterat,at_slopeat,at_segment,at_triangle,at_areaatraw,at_perimeteratraw,at_slopeatraw}; + gen ffinal[]={at_distanceat,at_angleat,at_areaat,at_perimeterat,at_slopeat,at_distanceatraw,at_angleatraw,at_areaatraw,at_perimeteratraw,at_slopeatraw}; + int mode[]={3,4,2,2,2,3,4,2,2,2}; + const char * help[]={ + "Object1,Object2,Position", + "Angle_vertex,Direction1,Direction2,Position", + "Object,Position", + "Object,Position", + "Object,Position", + "Object1,Object2,Position", + "Angle_vertex,Direction1,Direction2,Position", + "Object,Position", + "Object,Position", + "Object,Position", + }; + set_mode(ftmp[choix],ffinal[choix],mode[choix],help[choix]); + continue; + } + continue; + } + + if (key==KEY_CTRL_MENU || key==KEY_CTRL_F6){ + char menu_xmin[32],menu_xmax[32],menu_ymin[32],menu_ymax[32],menu_zmin[32],menu_zmax[32],menu_depth[32]; + for (;;){ + string s; + s="xmin "+print_DOUBLE_(gr.window_xmin,contextptr); + strcpy(menu_xmin,s.c_str()); + s="xmax "+print_DOUBLE_(gr.window_xmax,contextptr); + strcpy(menu_xmax,s.c_str()); + s="ymin "+print_DOUBLE_(gr.window_ymin,contextptr); + strcpy(menu_ymin,s.c_str()); + s="ymax "+print_DOUBLE_(gr.window_ymax,contextptr); + strcpy(menu_ymax,s.c_str()); + s="zmin 3d "+print_DOUBLE_(gr.window_zmin,contextptr); + strcpy(menu_zmin,s.c_str()); + s="zmax 3d "+print_DOUBLE_(gr.window_zmax,contextptr); + strcpy(menu_zmax,s.c_str()); + s="depth 3d "+print_DOUBLE_(gr.current_depth,contextptr); + strcpy(menu_depth,s.c_str()); + Menu smallmenu; + smallmenu.numitems=19; + MenuItem smallmenuitems[smallmenu.numitems]; + smallmenu.items=smallmenuitems; + smallmenu.height=12; + //smallmenu.title = "KhiCAS"; + smallmenuitems[0].text = (char *) menu_xmin; + smallmenuitems[1].text = (char *) menu_xmax; + smallmenuitems[2].text = (char *) menu_ymin; + smallmenuitems[3].text = (char *) menu_ymax; + smallmenuitems[4].text = (char *) menu_zmin; + smallmenuitems[5].text = (char *) menu_zmax; + smallmenuitems[6].text = (char *) menu_depth; + smallmenuitems[7].text = (char *) ((lang==1)?"Aide":"Help"); + smallmenuitems[8].text = (char*) (lang==1?"Sauvegarder figure":"Save figure"); + smallmenuitems[9].text = (char*) (lang==1?"Sauvegarder comme":"Save as"); + smallmenuitems[10].text = (char*)((lang==1)?"Quitter":"Quit"); + smallmenuitems[11].text = (char*) "Orthonormalize /"; + smallmenuitems[12].text = (char*) "Autoscale *"; + smallmenuitems[13].text = (char *) ("Zoom in +"); + smallmenuitems[14].text = (char *) ("Zoom out -"); + smallmenuitems[15].text = (char *) ("Y-Zoom out (-)"); + smallmenuitems[16].text = (char*) ((lang==1)?"Voir axes":"Show axes"); + smallmenuitems[17].text = (char*) ((lang==1)?"Cacher axes":"Hide axes"); + smallmenuitems[18].text = (char*) ((lang==1)?"Effacer trace":"Clear trace"); + drawRectangle(0,180,LCD_WIDTH_PX,60,_BLACK); + int sres = doMenu(&smallmenu); + if (sres == MENU_RETURN_EXIT) + break; + if (sres == MENU_RETURN_SELECTION || sres==KEY_CTRL_EXE) { + const char * ptr=0; + string s1; double d; + if (smallmenu.selection==1){ + d=gr.window_xmin; + if (inputdouble(menu_xmin,d,200,contextptr)){ + gr.window_xmin=d; + gr.update(); + } + } + if (smallmenu.selection==2){ + d=gr.window_xmax; + if (inputdouble(menu_xmax,d,200,contextptr)){ + gr.window_xmax=d; + gr.update(); + } + } + if (smallmenu.selection==3){ + d=gr.window_ymin; + if (inputdouble(menu_ymin,d,200,contextptr)){ + gr.window_ymin=d; + gr.update(); + } + } + if (smallmenu.selection==4){ + d=gr.window_ymax; + if (inputdouble(menu_ymax,d,200,contextptr)){ + gr.window_ymax=d; + gr.update(); + } } if (smallmenu.selection==5){ d=gr.window_zmin; @@ -8746,40 +10773,105 @@ namespace xcas { gr.update(); } } - if (smallmenu.selection==7) + if (smallmenu.selection==7){ + d=gr.current_depth; + if (inputdouble(menu_depth,d,200,contextptr)){ + if (d<-1) d=-1; + if (d>1) d=1; + gr.current_depth=d; + gr.update(); + } + } + if (smallmenu.selection==8){ + geohelp(contextptr); continue; + // gr.q=quaternion_double(0,0,0); gr.update(); + } + if (hp && smallmenu.selection==9){ + // save + geosave(hp,contextptr); + continue; + } + if (smallmenu.selection==9 || smallmenu.selection==10){ + // save as + char filename[MAX_FILENAME_SIZE+1]; + if (get_filename(filename,".py") && newgeo(contextptr)==0){ + geoptr->hp->filename=filename; + if (geoptr!=this && !symbolic_instructions.empty()){ + geoptr->symbolic_instructions=symbolic_instructions; + geoptr->hp->elements.clear(); + for (int i=0;ihp->set_string_value(i,symbolic_instructions[i].print(contextptr)); + } + geoloop(geoptr); + return 0; + } + } + } + if (smallmenu.selection==11) + return -4; + if (smallmenu.selection==12) gr.orthonormalize(); - if (smallmenu.selection==8) + if (smallmenu.selection==13) gr.autoscale(); - if (smallmenu.selection==9) + if (smallmenu.selection==14) gr.zoom(0.7); - if (smallmenu.selection==10) + if (smallmenu.selection==15) gr.zoom(1/0.7); - if (smallmenu.selection==11) + if (smallmenu.selection==16) gr.zoomy(1/0.7); - if (smallmenu.selection==12){ - xcas::textArea text; - text.editable=false; - text.clipline=-1; - text.title = (char*)((lang==1)?"Raccourcis clavier 3d":"3d Keyboard shortcuts"); - text.allowF1=false; - text.python=false; - add(&text,lang==1?"haut/bas/droit/gauche: change point de vue\ny^x ou e^x: trace precis\nON/Back: interrompt le trace en cours\n( et ): modifie le rendu des surfaces raides\n0: surfaces cachees ON/OFF\n.: remplissage surface raide ON/OFF\n5 reset view\n7,8,9,1,2,3: deplacement":"up/down/right/left: modify viewpoint\nON/Back: interrupt\ny^x or e^x: precise\n( and ): modify stiff surfaces rendering\n0: hidden surfaces ON/OFF\n.: fill stiff surfacesON/OFF\n5 reset view\n7,8,9,1,2,3: move view"); - int exec=doTextArea(&text,contextptr); - // gr.q=quaternion_double(0,0,0); gr.update(); - } - if (smallmenu.selection==13) + if (smallmenu.selection==17) gr.show_axes=true; - if (smallmenu.selection==14) + if (smallmenu.selection==18) gr.show_axes=false; - if (smallmenu.selection==15) - break; + if (smallmenu.selection==19){ + gr.trace_instructions.clear(); + update_g(); + } } } + gr.draw(); + gr.must_redraw=false; + continue; + } + + if (hp && key==KEY_CTRL_OK){ + if (mode==255) + return key; + if (!moving){ + pushed=true; + push_i=current_i; + push_j=current_j; + push_depth = current_depth; + geo_handle(FL_PUSH,KEY_CTRL_OK); + if (moving){ + update_g(); + continue; + } + } + int res=geo_handle(FL_RELEASE,KEY_CTRL_OK); + pushed=false; + update_g(); + continue; + } + if (hp && key==KEY_CTRL_EXIT && mode!=255){ + if (mode==0){ // restore original value and reeval + geo_handle(FL_RELEASE,KEY_CTRL_EXIT); + // do_handle(symbolic(at_sto,makevecteur(drag_original_value,drag_name))); + if (!pushed) + set_mode(0,0,255,""); + } + else + if (args_tmp.empty()) + set_mode(0,0,255,""); + pushed=false; + moving=moving_frame=false; + args_tmp.clear(); + update_g(); + continue; } -#endif if (key==KEY_CTRL_EXIT || key==KEY_CTRL_OK){ os_hide_graph(); - break; + return key; } if (key==KEY_CHAR_NORMAL || key=='>'){ // shift-+ if (gr.is3d && gr.precision<9) @@ -8790,6 +10882,16 @@ namespace xcas { gr.precision--; } if (key==KEY_CTRL_UP){ + if (hp && mode!=255){ + --current_j; + if (current_j<0){ + gr.up((gr.window_ymax-gr.window_ymin)/5); + current_j += LCD_HEIGHT_PX/5; + } + geo_handle(moving?FL_DRAG:FL_MOVE,key); + update_g(); + continue; + } if (gr.is3d){ int curprec=gr.precision; gr.precision += 2; @@ -8803,7 +10905,7 @@ namespace xcas { gr.q=rotation_2_quaternion_double(0.707,0.707,0,15)*gr.q;// quaternion_double(15,0,0)*gr.q; gr.update_rotation(); gr.draw(); - redraw=gr.solid3d; + gr.must_redraw=gr.solid3d; #ifndef SIMU if (!iskeydown(KEY_CTRL_UP)) break; @@ -8814,12 +10916,32 @@ namespace xcas { gr.precision=curprec; continue; } - gr.up((gr.window_ymax-gr.window_ymin)/5); + gr.up((gr.window_ymax-gr.window_ymin)/16); } if (key==KEY_CTRL_PAGEUP) { - gr.up((gr.window_ymax-gr.window_ymin)/2); + if (hp && mode!=255){ + current_j-=LCD_HEIGHT_PX/5;; + if (current_j<0){ + gr.up((gr.window_ymax-gr.window_ymin)/2); + current_j += LCD_HEIGHT_PX/2; + } + geo_handle(moving?FL_DRAG:FL_MOVE,key); + update_g(); + continue; + } + gr.up((gr.window_ymax-gr.window_ymin)/4); } if (key==KEY_CTRL_DOWN) { + if (hp && mode!=255){ + ++current_j; + if (current_j>=LCD_HEIGHT_PX-24){ + gr.down((gr.window_ymax-gr.window_ymin)/5); + current_j -= LCD_HEIGHT_PX/5; + } + geo_handle(moving?FL_DRAG:FL_MOVE,key); + update_g(); + continue; + } if (gr.is3d){ int curprec=gr.precision; gr.precision += 2; @@ -8833,7 +10955,7 @@ namespace xcas { gr.q=rotation_2_quaternion_double(0.707,0.707,0,-15)*gr.q; // quaternion_double(-15,0,0)*gr.q; gr.update_rotation(); gr.draw(); - redraw=gr.solid3d; + gr.must_redraw=gr.solid3d; #ifndef SIMU if (!iskeydown(KEY_CTRL_DOWN)) break; @@ -8844,12 +10966,32 @@ namespace xcas { gr.precision=curprec; continue; } - gr.down((gr.window_ymax-gr.window_ymin)/5); + gr.down((gr.window_ymax-gr.window_ymin)/16); } if (key==KEY_CTRL_PAGEDOWN) { - gr.down((gr.window_ymax-gr.window_ymin)/2); + if (hp && mode!=255){ + current_j += LCD_HEIGHT_PX/5; + if (current_j>=LCD_HEIGHT_PX-24){ + gr.down((gr.window_ymax-gr.window_ymin)/2); + current_j -= LCD_HEIGHT_PX/2; + } + geo_handle(moving?FL_DRAG:FL_MOVE,key); + update_g(); + continue; + } + gr.down((gr.window_ymax-gr.window_ymin)/4); } if (key==KEY_CTRL_LEFT) { + if (hp && mode!=255){ + --current_i; + if (current_i<0){ + gr.left((gr.window_xmax-gr.window_xmin)/5); + current_i += LCD_WIDTH_PX/5; + } + geo_handle(moving?FL_DRAG:FL_MOVE,key); + update_g(); + continue; + } if (gr.is3d){ int curprec=gr.precision; gr.precision += 2; @@ -8858,7 +11000,7 @@ namespace xcas { gr.q=quaternion_double(0,15,0)*gr.q; gr.update_rotation(); gr.draw(); - redraw=gr.solid3d; + gr.must_redraw=gr.solid3d; #ifndef SIMU if (!iskeydown(KEY_CTRL_LEFT)) break; @@ -8869,10 +11011,32 @@ namespace xcas { gr.precision=curprec; continue; } - gr.left((gr.window_xmax-gr.window_xmin)/5); + gr.left((gr.window_xmax-gr.window_xmin)/16); + } + if (key==KEY_SHIFT_LEFT) { + if (hp && mode!=255){ + current_i -= LCD_WIDTH_PX/5; + if (current_i<0){ + gr.left((gr.window_xmax-gr.window_xmin)/2); + current_i += LCD_WIDTH_PX/2; + } + geo_handle(moving?FL_DRAG:FL_MOVE,key); + update_g(); + continue; + } + gr.left((gr.window_xmax-gr.window_xmin)/4); } - if (key==KEY_SHIFT_LEFT) { gr.left((gr.window_xmax-gr.window_xmin)/2); } if (key==KEY_CTRL_RIGHT) { + if (hp && mode!=255){ + ++current_i; + if (current_i>=LCD_WIDTH_PX){ + gr.right((gr.window_xmax-gr.window_xmin)/5); + current_i -= LCD_WIDTH_PX/5; + } + geo_handle(moving?FL_DRAG:FL_MOVE,key); + update_g(); + continue; + } if (gr.is3d){ int curprec=gr.precision; gr.precision += 2; @@ -8881,7 +11045,7 @@ namespace xcas { gr.q=quaternion_double(0,-15,0)*gr.q; gr.update_rotation(); gr.draw(); - redraw=gr.solid3d; + gr.must_redraw=gr.solid3d; #ifndef SIMU if (!iskeydown(KEY_CTRL_RIGHT)) break; @@ -8892,9 +11056,21 @@ namespace xcas { gr.precision=curprec; continue; } - gr.right((gr.window_xmax-gr.window_xmin)/5); + gr.right((gr.window_xmax-gr.window_xmin)/16); + } + if (key==KEY_SHIFT_RIGHT) { + if (hp && mode!=255){ + current_i += LCD_WIDTH_PX/5; + if (current_i>=LCD_WIDTH_PX){ + gr.right((gr.window_xmax-gr.window_xmin)/2); + current_i -= LCD_WIDTH_PX/2; + } + geo_handle(moving?FL_DRAG:FL_MOVE,key); + update_g(); + continue; + } + gr.right((gr.window_xmax-gr.window_xmin)/4); } - if (key==KEY_SHIFT_RIGHT) { gr.right((gr.window_xmax-gr.window_xmin)/5); } if (key==KEY_CHAR_PLUS) { gr.zoom(0.7); } @@ -8920,6 +11096,14 @@ namespace xcas { if (key==KEY_CHAR_ANS){ gr.show_edges=!gr.show_edges; } + if (key==KEY_CHAR_4){ + if (current_depth>-1) + current_depth-=0.1; + } + if (key==KEY_CHAR_6){ + if (current_depth<1) + current_depth+=0.1; + } if (key==KEY_CHAR_5){ gr.q=quaternion_double(0,0,0); gr.update(); @@ -8955,8 +11139,17 @@ namespace xcas { if (key==KEY_CHAR_RPAR && gr.diffusionz>2) gr.diffusionz--; } - if (key==KEY_CTRL_VARS) { + if (key==KEY_CHAR_SIN) { gr.show_axes=!gr.show_axes; + gr.update(); + gr.draw(); + gr.must_redraw=false; + } + if (key==KEY_CTRL_VARS){ + select_var(contextptr); + gr.update(); + gr.draw(); + gr.must_redraw=false; } } // aborttimer = Timer_Install(0, check_execution_abort, 100); if (aborttimer > 0) { Timer_Start(aborttimer); } @@ -10208,7 +12401,7 @@ namespace xcas { return 0; } if (ispnt(ge)){ - if (displaygraph(ge,contextptr)==KEY_SHUTDOWN) + if (displaygraph(ge,g,contextptr)==KEY_SHUTDOWN) return KEY_SHUTDOWN; // aborttimer = Timer_Install(0, check_execution_abort, 100); if (aborttimer > 0) { Timer_Start(aborttimer); } return 0; @@ -10306,7 +12499,7 @@ namespace xcas { } } - int check_do_graph(giac::gen & ge,int do_logo_graph_eqw,GIAC_CONTEXT) { + int check_do_graph(giac::gen & ge,const gen & gs,int do_logo_graph_eqw,GIAC_CONTEXT) { if (ge.type==giac::_SYMB || (ge.type==giac::_VECT && !ge._VECTptr->empty() && !is_numericv(*ge._VECTptr)) ){ if (islogo(ge)){ if (do_logo_graph_eqw & 4){ @@ -10317,7 +12510,7 @@ namespace xcas { } if (ispnt(ge)){ if (do_logo_graph_eqw & 2){ - if (displaygraph(ge,contextptr)==KEY_SHUTDOWN) + if (displaygraph(ge,gs,contextptr)==KEY_SHUTDOWN) return KEY_SHUTDOWN; } // aborttimer = Timer_Install(0, check_execution_abort, 100); if (aborttimer > 0) { Timer_Start(aborttimer); } @@ -10472,12 +12665,13 @@ namespace xcas { } else { set_abort(); + gen gs=g; g=protecteval(g,1,contextptr); clear_abort(); giac::ctrl_c=false; kbd_interrupted=giac::interrupted=false; // define the function - if (check_do_graph(g,7,contextptr)==KEY_SHUTDOWN) + if (check_do_graph(g,gs,7,contextptr)==KEY_SHUTDOWN) return KEY_SHUTDOWN; DefineStatusMessage((char *)((lang==1)?"Syntaxe correcte":"Parse OK"),1,0,0); } @@ -10566,6 +12760,50 @@ namespace xcas { fix_newlines(edptr); } + void textArea::set_string_value(int n,const string & s){ + if (n==-1 || n>=elements.size()){ + textElement t; t.s=s; + if (!elements.empty()) + t.newLine=1; + elements.push_back(t); + } + else { + elements[n].s=s; + if (n) + elements[n].newLine=1; + } + changed=true; + } + + int textArea::add_entry(int n){ + textElement t; + if (n==-1 || n>=elements.size()){ + if (elements.empty()) + elements.push_back(t); + else { + t.newLine=1; + if (!elements.back().s.empty()) + elements.push_back(t); + } + n=elements.size()-1; + } + else { + if (n) t.newLine=1; + elements.insert(elements.begin()+n,t); + } + return n; + } + + void Graph2d::add_entry(int n){ + if (!hp) + return; + if (n==-1 || n>=symbolic_instructions.size()){ + symbolic_instructions.push_back(0); + n=symbolic_instructions.size(); + } + hp->add_entry(n); + } + int find_indentation(const std::string & s){ size_t indent=0; for (;indenteditable; int showtitle = !editable && (text->title != NULL); std::vector & v=text->elements; + if (v.empty()) v.push_back(textElement()); //drawRectangle(text->x, text->y+24, text->width, LCD_HEIGHT_PX-24, COLOR_WHITE); // insure cursor is visible if (editable && !isFirstDraw){ @@ -11178,6 +13417,11 @@ namespace xcas { deltax=27; } } + if (v.empty()){ + textElement cur; + cur.s=""; + v.push_back(cur); + } int & clipline=text->clipline; int & clippos=text->clippos; int & textline=text->line; @@ -11484,7 +13728,10 @@ namespace xcas { if (editable){ waitforvblank(); drawRectangle(0,205,LCD_WIDTH_PX,17,44444); - PrintMiniMini(0,205,text->python>0?"shift-1 test|2 loop|3 undo|4 misc|5 +-|6 logo|7 lin|8 list|9arit":"shift-1 test|2 loop|3 undo|4 misc|5 +-|6 logo|7 matr|8 cplx",4,44444,giac::_BLACK); + if (text->gr) + PrintMiniMini(0,205,"shift-1 pnts|2 lines|3 undo|4 disp|5 +-|6 curves|7 triangle|8 polygon|9 solid",4,giac::_CYAN,giac::_BLACK); + else + PrintMiniMini(0,205,text->python>0?"shift-1 test|2 loop|3 undo|4 misc|5 +-|6 logo|7 lin|8 list|9arit":"shift-1 test|2 loop|3 undo|4 misc|5 +-|6 logo|7 matr|8 cplx",4,44444,giac::_BLACK); //draw_menu(1); } #ifdef SCROLLBAR @@ -12059,12 +14306,16 @@ namespace xcas { (key >= KEY_CTRL_F6 && key <= KEY_CTRL_F16) ){ string le_menu; - if (xcas_python_eval==1)//text->python? - le_menu="F1 test\nif \nelse \n<\n>\n==\n!=\n&&\n||\nF2 loop\nfor \nfor in\nrange(\nwhile \nbreak\ndef\nreturn \n#\nF4 misc\n:\n;\n_\n!\n%\nfrom import *\nprint(\ninput(\nF6 tortue\nforward(\nbackward(\nleft(\nright(\npencolor(\ncircle(\nreset()\nfrom turtle import *\nF: plot\nplot(\ntext(\narrow(\nlinear_regression_plot(\nscatter(\naxis(\nbar(\nfrom matplotl import *\nF7 linalg\nadd(\nsub(\nmul(\ninv(\ndet(\nrref(\ntranspose(\nfrom linalg import *\nF< color\nred\nblue\ngreen\ncyan\nyellow\nmagenta\nblack\nwhite\nF; draw\nset_pixel(\ndraw_line(\ndraw_rectangle(\nfill_rect(\ndraw_polygon(\ndraw_circle(\ndraw_string(\nfrom graphic import *\nF8 numpy\narray(\nreshape(\narange(\nlinspace(\nsolve(\neig(\ninv(\nfrom numpy import *\nF9 arit\npow(\nisprime(\nnextprime(\nifactor(\ngcd(\nlcm(\niegcd(\nfrom arit import *\n"; - if (xcas_python_eval<=0) - le_menu="F1 test\nif \nelse \n<\n>\n==\n!=\nand\nor\nF2 loop\nfor \nfor in\nrange(\nwhile \nbreak\nf(x):=\nreturn \nvar\nF4 misc\n;\n:\n_\n!\n%\n&\nprint(\ninput(\nF6 tortue\navance\nrecule\ntourne_gauche\ntourne_droite\nrond\ndisque\nrepete\nefface\nF7 lin\nmatrix(\ndet(\nmatpow(\nranm(\nrref(\ntran(\negvl(\negv(\nF9 arit\n mod \nirem(\nifactor(\ngcd(\nisprime(\nnextprime(\npowmod(\niegcd(\nF< plot\nplot(\nplotseq(\nplotlist(\nplotparam(\nplotpolar(\nplotfield(\nhistogram(\nbarplot(\nF: misc\n<\n>\n_\n!\n % \nrand(\nbinomial(\nnormald(\nF8 cplx\nabs(\narg(\nre(\nim(\nconj(\ncsolve(\ncfactor(\ncpartfrac(\n"; - if (xcas_python_eval>=0) - le_menu += "F= list\nmakelist(\nrange(\nseq(\nlen(\nappend(\nranv(\nsort(\napply(\nF; real\nexact(\napprox(\nfloor(\nceil(\nround(\nsign(\nmax(\nmin(\nF> prog\n;\n:\n\\\n&\n?\n!\ndebug(\npython(\nF? geo\npoint(\nline(\nsegment(\ncircle(\ntriangle(\nplane(\nsphere(\nsingle_inter(\nF@ color\ncolor=\nred\ncyan\ngreen\nblue\nmagenta\nyellow\nlegend("; + if (text->gr) { // geometry menu + le_menu="F1 points\npoint(\nmidpoint(\ncenter(\nelement(\nsingle_inter(\ninter(\nlegende(\ntrace(\nF2 lines\nsegment(\nline(\nhalf_line(\nvector(\nparallel(\nperpendicular(\ntangent(\nplane(\ncircle(\nF4 disp\ndisplay=\nfilled\nred\nblue\ngreen\ncyan\nmagenta\nyellow\nF6 curves\ncircle(\nellipse(\nhyperbola(\nparabola(\nplot(\nplotparam(\nplotpolar(\nplotode(\nF7 triangle\ntriangle(\nequilateral_triangle(\nmedian(\nperpen_bisector(\nbisector(\nisobarycenter(\nF8 polygon\nsquare(\nrectangle(\nquadrilateral(\nhexagon(\npolygon(\nisopolygon(\nvertices(\nF9 3d\nplane(\ncube(\ntetrahedron(\nsphere(\ncone(\nhalf_cone(\ncylinder(\nplot3d(\nF: transf\nprojection(\nreflection(\ntranslation(\nrotation(\nhomothety(\nsimilarity(\nF; geodiff\ntangent(\nosculating_circle(\nevolute(\ncurvature(\nfrenet(\noctahedron(\ndodecahedron(\nicosahedron(\nF< mesures\ndistance(\ndistance2(\nradius(\naire(\nperimetre(\npente(\nangle(\nF= test\nis_collinear(\nis_concyclic(\nis_coplanar(\nis_cospherical(\nis_element(\nis_parallel(\nis_perpendicular(\nF> analyt\ncoordonnees(\nequation(\nparameq(\nabscisse(\nordonnee(\naffixe(\narg(\n"; + } else { + if (xcas_python_eval==1)//text->python? + le_menu="F1 test\nif \nelse \n<\n>\n==\n!=\n&&\n||\nF2 loop\nfor \nfor in\nrange(\nwhile \nbreak\ndef\nreturn \n#\nF4 misc\n:\n;\n_\n!\n%\nfrom import *\nprint(\ninput(\nF6 tortue\nforward(\nbackward(\nleft(\nright(\npencolor(\ncircle(\nreset()\nfrom turtle import *\nF: plot\nplot(\ntext(\narrow(\nlinear_regression_plot(\nscatter(\naxis(\nbar(\nfrom matplotl import *\nF7 linalg\nadd(\nsub(\nmul(\ninv(\ndet(\nrref(\ntranspose(\nfrom linalg import *\nF< color\nred\nblue\ngreen\ncyan\nyellow\nmagenta\nblack\nwhite\nF; draw\nset_pixel(\ndraw_line(\ndraw_rectangle(\nfill_rect(\ndraw_polygon(\ndraw_circle(\ndraw_string(\nfrom graphic import *\nF8 numpy\narray(\nreshape(\narange(\nlinspace(\nsolve(\neig(\ninv(\nfrom numpy import *\nF9 arit\npow(\nisprime(\nnextprime(\nifactor(\ngcd(\nlcm(\niegcd(\nfrom arit import *\n"; + if (xcas_python_eval<=0) + le_menu="F1 test\nif \nelse \n<\n>\n==\n!=\nand\nor\nF2 loop\nfor \nfor in\nrange(\nwhile \nbreak\nf(x):=\nreturn \nvar\nF4 misc\n;\n:\n_\n!\n%\n&\nprint(\ninput(\nF6 tortue\navance\nrecule\ntourne_gauche\ntourne_droite\nrond\ndisque\nrepete\nefface\nF7 lin\nmatrix(\ndet(\nmatpow(\nranm(\nrref(\ntran(\negvl(\negv(\nF9 arit\n mod \nirem(\nifactor(\ngcd(\nisprime(\nnextprime(\npowmod(\niegcd(\nF< plot\nplot(\nplotseq(\nplotlist(\nplotparam(\nplotpolar(\nplotfield(\nhistogram(\nbarplot(\nF: misc\n<\n>\n_\n!\n % \nrand(\nbinomial(\nnormald(\nF8 cplx\nabs(\narg(\nre(\nim(\nconj(\ncsolve(\ncfactor(\ncpartfrac(\n"; + if (xcas_python_eval>=0) + le_menu += "F= list\nmakelist(\nrange(\nseq(\nlen(\nappend(\nranv(\nsort(\napply(\nF; real\nexact(\napprox(\nfloor(\nceil(\nround(\nsign(\nmax(\nmin(\nF> prog\n;\n:\n\\\n&\n?\n!\ndebug(\npython(\nF? geo\npoint(\nline(\nsegment(\ncircle(\ntriangle(\nplane(\nsphere(\nsingle_inter(\nF@ color\ncolor=\nred\ncyan\ngreen\nblue\nmagenta\nyellow\nlegend("; + } // else not geometry const char * ptr=console_menu(key,(char*)(le_menu.c_str()),2); if (!ptr){ show_status(text,search,replace); @@ -12190,7 +14441,7 @@ namespace xcas { } continue; case KEY_CTRL_OK: - if (text->allowEXE || !text->editable) return TEXTAREA_RETURN_EXE; + if (text->gr || text->allowEXE || !text->editable) return TEXTAREA_RETURN_EXE; if (search.size()){ for (;;){ if (!move_to_word(text,search,replace,isFirstDraw,totalTextY,scroll,textY,contextptr)) @@ -13397,7 +15648,7 @@ namespace xcas { vout.erase(vout.begin()); vout.push_back(ge); } - if (check_do_graph(ge,do_logo_graph_eqw,contextptr)==KEY_SHUTDOWN) + if (check_do_graph(ge,g,do_logo_graph_eqw,contextptr)==KEY_SHUTDOWN) return KEY_SHUTDOWN; string s_; if (ge.type==giac::_STRNG) @@ -14564,7 +16815,7 @@ namespace xcas { numworks_certify_internal(); Bdisp_AllClr_VRAM(); int x=0,y=0; - PrintMini(x,y,"KhiCAS 1.7 (c) 2022 B. Parisse",TEXT_MODE_NORMAL, COLOR_BLACK, COLOR_WHITE); + PrintMini(x,y,"KhiCAS 1.9 (c) 2022 B. Parisse",TEXT_MODE_NORMAL, COLOR_BLACK, COLOR_WHITE); y +=18; PrintMini(x,y,"et al, License GPL 2",TEXT_MODE_NORMAL,COLOR_BLACK, COLOR_WHITE); y += 18; @@ -15350,80 +17601,10 @@ namespace xcas { break; } if (smallmenu.selection == 15){ - Menu paramenu; - paramenu.numitems=6; - MenuItem paramenuitems[paramenu.numitems]; - paramenu.items=paramenuitems; - paramenu.height=12; - paramenu.title = (char *)"Parameter"; - char menu_xcur[32],menu_xmin[32],menu_xmax[32],menu_xstep[32],menu_name[16]="name a"; static char curname='a'; - menu_name[5]=curname; - ++curname; - double pcur=0,pmin=-5,pmax=5,pstep=0.1; - std::string s; - bool doit; - for (;;){ - s="cur "+giac::print_DOUBLE_(pcur,contextptr); - strcpy(menu_xcur,s.c_str()); - s="min "+giac::print_DOUBLE_(pmin,contextptr); - strcpy(menu_xmin,s.c_str()); - s="max "+giac::print_DOUBLE_(pmax,contextptr); - strcpy(menu_xmax,s.c_str()); - s="step "+giac::print_DOUBLE_(pstep,contextptr); - strcpy(menu_xstep,s.c_str()); - paramenuitems[0].text = (char *) "OK"; - paramenuitems[1].text = (char *) menu_name; - paramenuitems[2].text = (char *) menu_xcur; - paramenuitems[3].text = (char *) menu_xmin; - paramenuitems[4].text = (char *) menu_xmax; - paramenuitems[5].text = (char *) menu_xstep; - int sres = doMenu(¶menu); - doit = sres==MENU_RETURN_SELECTION || sres==KEY_CTRL_EXE; - if (doit) { - std::string s1; double d; - if (paramenu.selection==2){ - handle_f5(); - if (inputline(menu_name,(lang==1)?"Nouvelle valeur?":"New value?",s1,false)==KEY_CTRL_EXE && s1.size()>0 && isalpha(s1[0])){ - if (s1.size()>10) - s1=s1.substr(0,10); - strcpy(menu_name,("name "+s1).c_str()); - } - continue; - } - if (paramenu.selection==3){ - inputdouble(menu_xcur,pcur,contextptr); - continue; - } - if (paramenu.selection==4){ - inputdouble(menu_xmin,pmin,contextptr); - continue; - } - if (paramenu.selection==5){ - inputdouble(menu_xmax,pmax,contextptr); - continue; - } - if (paramenu.selection==6){ - inputdouble(menu_xstep,pstep,contextptr); - pstep=fabs(pstep); - continue; - } - // if (paramenu.selection==6) break; - } // end menu - break; - } // end for (;;) - if (doit && pmin0){ - s="assume("; - s += (menu_name+5); - s += "=["; - s += (menu_xcur+4); - s += ','; - s += (menu_xmin+4); - s += ','; - s += (menu_xmax+4); - s += ','; - s += (menu_xstep+5); - s += "])"; + string s=inputparam(curname,1,contextptr); + if (!s.empty()){ + ++curname; return Console_Input((const char *)s.c_str()); } continue; @@ -16360,6 +18541,123 @@ namespace xcas { } #endif + Graph2d * geoptr=0; + + // return true if there is a syntax error and user asked to correct + bool geoparse(textArea *text,GIAC_CONTEXT){ + Graph2d * geoptr=text->gr; + if (!geoptr) + return false; + std::vector & v=text->elements; + geoptr->symbolic_instructions.resize(v.size()); + int pos=-1,i=0; + for (;isymbolic_instructions[i]=g; + if (lineerr){ + std::string tok=giac::error_token_name(contextptr); + if (lineerr==1){ + pos=v[i].s.find(tok); + const std::string & err=v[i].s; + if (pos>=err.size()) + pos=-1; + } + else { + tok=(lang==1)?"la fin":"end"; + pos=0; + } + if (pos>=0) + sprintf(status,(lang==1)?"Erreur ligne %i a %s":"Error line %i at %s",i+1,tok.c_str()); + else + sprintf(status,(lang==1)?"Erreur ligne %i %s":"Error line %i %s",i+1,(pos==-2?((lang==1)?", : manquant ?":", missing :?"):"")); + if (confirm(status,(lang==1)?"OK: corrige, back: continue":"OK: fix",1)==KEY_CTRL_F1){ + text->line=i; + if (pos>=0 && pospos=pos; + return true; + } + } + } // loop on lines + return false; + } + + int geoloop(Graph2d * geoptr){ + if (!geoptr || !geoptr->hp) return -1; + const context * contextptr=geoptr->contextptr; + textArea * text=geoptr->hp; + // main loop: alternate between plot and symb view + // start in plot view + // end plot view with EXIT or OK -> symb view editor + // end with OK or EXIT: OK will modify, EXIT will leave geo app + // (press twice EXIT to leave geo app from plot view) + for (;;){ + geoptr->eval(); + geoptr->update(); + if (geoptr->is3d) + geoptr->update_rotation(); + int key=geoptr->ui(); + if (key==KEY_SHUTDOWN){ + geosave(text,contextptr); + return key; + } + // symb view editor + for (;;){ + key=doTextArea(text,contextptr); + if (key== TEXTAREA_RETURN_EXIT || key==KEY_SHUTDOWN){ + geosave(text,contextptr); + return key; + } + // key was OK, parse step: synchronize symbolic_instructions from text + bool corrige=geoparse(text,contextptr); + if (!corrige) + break; + } // end edition loop + } // end plot/symb view infinite loop + } + + void cleargeo(){ + if (!geoptr) + return; + if (geoptr->hp) + delete geoptr->hp; + delete geoptr; + geoptr=0; + } + + int newgeo(GIAC_CONTEXT){ + if (!geoptr){ + geoptr=new Graph2d(0,contextptr); + geoptr->window_xmin=-5; + geoptr->window_ymin=-5; + geoptr->window_zmin=-5; + geoptr->window_xmax=5; + geoptr->window_ymax=5; + geoptr->window_zmax=5; + geoptr->orthonormalize(); + } + if (!geoptr) + return -1; + if (!geoptr->hp){ + geoptr->hp=new textArea; + geoptr->hp->filename="figure0.py"; + geoptr->hp->python=0; + } + if (!geoptr->hp) + return -2; + textArea * text=geoptr->hp; + text->editable=true; + text->clipline=-1; + text->gr=geoptr; + geoptr->set_mode(0,0,255,""); // start in frame mode + return 0; + } + tableur * sheetptr=0; string print_tableur(const tableur & t,GIAC_CONTEXT){ @@ -16372,6 +18670,11 @@ namespace xcas { vecteur & v=*g._VECTptr; for (int j=0;jsize()==3){ + vecteur vjv=*vj._VECTptr; + vjv[1]=0; + vj=gen(vjv,vj.subtype); + } printcell_current_col(contextptr)=j; s += vj.print(contextptr); if (j==t.ncols-1) @@ -17001,7 +19304,7 @@ int select_item(const char ** ptr,const char * title,bool askfor1){ Menu smallmenu; smallmenu.numitems=nitems; smallmenu.items=smallmenuitems; - smallmenu.height=12; + smallmenu.height=nitems<12?nitems+1:12; smallmenu.scrollbar=1; smallmenu.scrollout=1; smallmenu.title = (char*) title; diff --git a/apps/KhiCAS/src/giac-1.6.0/src/kdisplay.cc~ b/apps/KhiCAS/src/giac-1.6.0/src/kdisplay.cc~ deleted file mode 100755 index 1c8701bcd..000000000 --- a/apps/KhiCAS/src/giac-1.6.0/src/kdisplay.cc~ +++ /dev/null @@ -1,17378 +0,0 @@ -// -*- mode:C++ ; compile-command: "g++-3.4 -I. -I.. -g -c Equation.cc -DHAVE_CONFIG_H -DIN_GIAC -Wall" -*- -/* - * Copyright (C) 2005,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 . - */ -#include "config.h" -#include "giacPCH.h" -#if defined HAVE_UNISTD_H && !defined NUMWORKS -#include -#endif -#ifdef NSPIRE_NEWLIB -#include -#include -#include -#include -#include -#include -#include "sha256.h" -#endif -#ifndef is_cx2 -#define is_cx2 false -#endif - - - -#ifdef KHICAS - -#ifdef NUMWORKS -char * freeptr=0; -#ifndef DEVICE -const char * flash_buf=file_gettar_aligned("apps.tar",freeptr); -extern "C" const char * flash_read(const char * filename){ - return tar_loadfile(flash_buf,filename,0); -} -extern "C" int flash_filebrowser(const char ** filenames,int maxrecords,const char * extension){ - return tar_filebrowser(flash_buf,filenames,maxrecords,extension); -} -#else -const char * flash_buf=(const char *)0x90200000; -#endif -#endif - -#if defined NUMWORKS && !defined DEVICE //ndef NSPIRE_NEWLIB -extern "C" { - short int nspire_exam_mode=0; -} -#endif -#define XWASPY 1 // save .xw file as _xw.py (to be recognized by Numworks workshop) -const int xwaspy_shift=33; // must be between 32 and 63, reflect in xcas.js and History.cc -#include "kdisplay.h" -#include -#include -#include -#include -#include -#include "input_lexer.h" -#include "input_parser.h" -#if defined NUMWORKS && defined DEVICE - void py_ck_ctrl_c(){ - if (giac::ctrl_c || giac::interrupted) - raisememerr(); - } -#else - void py_ck_ctrl_c(){} -#endif -//giac::context * contextptr=0; -int clip_ymin=0; -int lang=1; -short int nspirelua=0; -bool warn_nr=true; -bool xthetat=false; -//bool freezeturtle=false; -bool global_show_axes=true; -int esc_flag=0; -int xcas_python_eval=0; -char * python_heap=0; - -#ifdef QUICKJS -#include "qjsgiac.h" -#endif - -#ifdef MICROPY_LIB -extern "C" int mp_token(const char * line); - -void python_free(){ - if (!python_heap) return; - mp_deinit(); free(python_heap); python_heap=0; -} - -int python_init(int stack_size,int heap_size){ -#if 1 // defined NUMWORKS - python_free(); - python_heap=micropy_init(stack_size,heap_size); - if (!python_heap) - return 0; -#endif - return 1; -} - -int micropy_ck_eval(const char *line){ -#if 1 // def NUMWORKS - giac::ctrl_c=giac::interrupted=false; - if (python_heap && line[0]==0) - return 1; - if (!python_heap){ - python_init(pythonjs_stack_size,pythonjs_heap_size); - } - if (!python_heap){ - console_output("Memory full",11); - return RAND_MAX; - } -#endif - return micropy_eval(line); - // if MP_PARSE_SINGLE_INPUT is used, split input if newline not followed by a space, return shift - int shift=0,nl=0; - const char * ptr=line; - for (;;++ptr){ - if (*ptr=='\n') - ++nl; - if (*ptr==0 || (*ptr=='\n' && *(ptr+1)!=' ')){ - int n=ptr-line; - char buf[n+1]; - strncpy(buf,line,n); - buf[n]=0; - micropy_eval(buf); - if (parser_errorline) - return shift; - if (*ptr==0) - return 0; - line=ptr+1; - shift=nl; - } - } - return 0; -} -#endif - -using namespace std; -using namespace giac; -const int LCD_WIDTH_PX=320; -const int LCD_HEIGHT_PX=222; -char* fmenu_cfg=0; -int khicas_addins_menu(GIAC_CONTEXT); // in kadd.cc -#ifdef MICROPY_LIB -extern "C" const char * const * mp_vars(); -#endif -#if defined NUMWORKS && defined DEVICE -extern "C" void extapp_clipboardStore(const char *text); -extern "C" const char * extapp_clipboardText(); -#endif - -// Numworks Logo commands -#ifndef NO_NAMESPACE_GIAC -namespace giac { -#endif // ndef NO_NAMESPACE_GIAC - void Bdisp_PutDisp_DD(){ - sync_screen(); - } - void Bdisp_AllClr_VRAM(){ - waitforvblank(); - drawRectangle(0,0,LCD_WIDTH_PX,LCD_HEIGHT_PX,_WHITE); - } - void drawLine(int x1,int y1,int x2,int y2,int c){ - draw_line(x1,y1,x2,y2,c,context0); - } - void stroke_rectangle(int x,int y,int w,int h,int c){ - drawLine(x,y,x+w,y,c); - drawLine(x,y+h,x+w,y+h,c); - drawLine(x,y,x,y+h,c); - drawLine(x+w,y,x+w,y+h,c); - } - void DefineStatusMessage(const char * s,int a,int b,int c){ - statuslinemsg(s); - } - - void DisplayStatusArea(){ - sync_screen(); - } - - void set_xcas_status(){ - statusline(1+2*xcas_python_eval); - } - int GetSetupSetting(int mode){ - return 0; - } - - void SetSetupSetting(int mode,int){ - } - - void handle_f5(){ - lock_alpha(); - } - - void delete_clipboard(){} - - bool clip_pasted=true; - - string * clipboard(){ - static string * ptr=0; - if (!ptr) - ptr=new string; - return ptr; - } - - void copy_clipboard(const string & s,bool status){ -#if defined NUMWORKS && defined DEVICE - extapp_clipboardStore(s.c_str()); -#else - if (1 || clip_pasted) // adding to clipboard is sometimes annoying - *clipboard()=s; - else - *clipboard()+=s; -#endif - clip_pasted=false; - if (status){ - DefineStatusMessage((char*)((lang==1)?"Selection copiee vers presse-papiers.":"Selection copied to clipboard"), 1, 0, 0); - DisplayStatusArea(); - } - } - - const char * paste_clipboard(){ - clip_pasted=true; -#if defined NUMWORKS && defined DEVICE - return extapp_clipboardText(); -#endif - return clipboard()->c_str(); - } - - int print_msg12(const char * msg1,const char * msg2,int textY=40){ - drawRectangle(0, textY+10, LCD_WIDTH_PX, 44, COLOR_WHITE); - drawRectangle(3,textY+10,316,3, COLOR_BLACK); - drawRectangle(3,textY+10,3,44, COLOR_BLACK); - drawRectangle(316,textY+10,3,44, COLOR_BLACK); - drawRectangle(3,textY+54,316,3, COLOR_BLACK); - int textX=30; - if (msg1){ - if (strlen(msg1)>=30) - os_draw_string_small_(textX,textY+15,msg1); - else - os_draw_string_(textX,textY+15,msg1); - } - textX=10; - textY+=33; - if (msg2){ - if (strlen(msg2)>=30) - os_draw_string_small_(textX,textY,msg2); - else - textX=os_draw_string_(textX,textY,msg2); - } - return textX; - } - - void insert(string & s,int pos,const char * add){ - if (pos>s.size()) - pos=s.size(); - if (pos<0) - pos=0; - s=s.substr(0,pos)+add+s.substr(pos,s.size()-pos); - } - - bool do_confirm(const char * s){ -#ifdef NSPIRE_NEWLIB - return confirm(s,((lang==1)?"enter: oui, esc:annuler":"enter: yes, esc: cancel"))==KEY_CTRL_F1; -#else - return confirm(s,((lang==1)?"OK: oui, Back:annuler":"OK: yes, Back: cancel"))==KEY_CTRL_F1; -#endif - } - - int confirm(const char * msg1,const char * msg2,bool acexit,int y){ - int key=0; - print_msg12(msg1,msg2,y); - while (key!=KEY_CTRL_F1 && key!=KEY_CTRL_F6){ - GetKey(&key); - if (key==KEY_SHUTDOWN) - return key; - if (key==KEY_CTRL_EXE || key==KEY_CTRL_OK) - key=KEY_CTRL_F1; - if (key==KEY_CTRL_AC || key==KEY_CTRL_EXIT || key==KEY_CTRL_MENU){ - if (acexit) return -1; - key=KEY_CTRL_F6; - } - set_xcas_status(); - } - return key; - } - - bool confirm_overwrite(){ -#ifdef NSPIRE_NEWLIB - return do_confirm((lang==1)?"enter: oui, esc:annuler":"enter: yes, esc: cancel")==KEY_CTRL_F1; -#else - return do_confirm((lang==1)?"OK: oui, Back:annuler":"OK: yes, Back: cancel")==KEY_CTRL_F1; -#endif - } - - void invalid_varname(){ - confirm((lang==1)?"Nom de variable incorrect":"Invalid variable name", -#ifdef NSPIRE_NEWLIB - (lang==1)?"enter: ok":"enter: ok" -#else - (lang==1)?"OK: ok":"OK: ok" -#endif - ); - } - - -#ifdef SCROLLBAR - typedef scrollbar TScrollbar; -#endif - -#define C24 18 // 24 on 90 -#define C18 18 // 18 -#define C10 10 // 18 -#define C6 6 // 6 - - int MB_ElementCount(const char * s){ - return strlen(s); // FIXME for UTF8 - } - - void PrintXY(int x,int y,const char * s,int mode,int c=giac::_BLACK,int bg=giac::_WHITE){ - if (mode==TEXT_MODE_NORMAL) - os_draw_string(x,y,c,bg,s); - else { - if (c==giac::_BLACK && bg==giac::_WHITE) - os_draw_string(x,y,c,color_gris,s); - else - os_draw_string(x,y,bg,c,s); - } - } - - int PrintMiniMini(int x,int y,const char * s,int mode,int c=giac::_BLACK,int bg=giac::_WHITE,bool fake=false){ - if (mode==TEXT_MODE_NORMAL) - return os_draw_string_small(x,y,c,bg,s,fake); - else { - if (c==giac::_BLACK && bg==giac::_WHITE) - return os_draw_string_small(x,y,c,color_gris,s,fake); - else - return os_draw_string_small(x,y,bg,c,s,fake); - } - } - - int PrintMini(int x,int y,const char * s,int mode,int c=giac::_BLACK,int bg=giac::_WHITE,bool fake=false){ - if (mode==TEXT_MODE_NORMAL) - return os_draw_string(x,y,c,bg,s,fake); - else { - if (c==giac::_BLACK && bg==giac::_WHITE) - return os_draw_string(x,y,c,color_gris,s,fake); - else - return os_draw_string(x,y,bg,c,s,fake); - } - } - - void printCentered(const char* text, int y) { - int len = strlen(text); - int x = LCD_WIDTH_PX/2-(len*6)/2; - PrintXY(x,y,text,0); - } - - int doMenu(Menu* menu, MenuItemIcon* icontable) { // returns code telling what user did. selection is on menu->selection. menu->selection starts at 1! - int itemsStartY=menu->startY; // char Y where to start drawing the menu items. Having a title increases this by one - int itemsHeight=menu->height; - int showtitle = menu->title != NULL; - if (showtitle) { - itemsStartY++; - itemsHeight--; - } - char keyword[5]; - keyword[0]=0; - if(menu->selection > menu->scroll+(menu->numitems>itemsHeight ? itemsHeight : menu->numitems)) - menu->scroll = menu->selection -(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); - if(menu->selection-1 < menu->scroll) - menu->scroll = menu->selection -1; - - while(1) { - // Cursor_SetFlashOff(); - if (menu->selection <=1) - menu->selection=1; - if (menu->selection > menu->scroll+(menu->numitems>itemsHeight ? itemsHeight : menu->numitems)) - menu->scroll = menu->selection -(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); - if (menu->selection-1 < menu->scroll) - menu->scroll = menu->selection -1; - if(menu->statusText != NULL) DefineStatusMessage(menu->statusText, 1, 0, 0); - // Clear the area of the screen we are going to draw on - if(0 == menu->pBaRtR) { - int x=C10*menu->startX-1, - y=C24*(menu->miniMiniTitle ? itemsStartY:menu->startY)-1, - w=2+C10*menu->width /* + ((menu->scrollbar && menu->scrollout)?C10:0) */, - h=2+C24*menu->height-(menu->miniMiniTitle ? C24:0); - // drawRectangle(x, y, w, h, COLOR_WHITE); - draw_line(x,y,x+w,y,COLOR_BLACK,context0); - draw_line(x,y+h,x+w,y+h,COLOR_BLACK,context0); - draw_line(x,y,x,y+h,COLOR_BLACK,context0); - draw_line(x+w,y,x+w,y+h,COLOR_BLACK,context0); - } - if (menu->numitems>0) { - for(int curitem=0; curitem < menu->numitems; curitem++) { - // print the menu item only when appropriate - if(menu->scroll <= curitem && menu->scroll > curitem-itemsHeight) { - if ((curitem-menu->scroll) % 6==0) - waitforvblank(); - char menuitem[256] = ""; - if(menu->numitems>=100 || menu->type == MENUTYPE_MULTISELECT){ - strcpy(menuitem, " "); //allow for the folder and selection icons on MULTISELECT menus (e.g. file browser) - strcpy(menuitem+2,menu->items[curitem].text); - } - else if (menu->type==MENUTYPE_NO_NUMBER) - strcpy(menuitem,menu->items[curitem].text); - else { - int cur=curitem+1; - if (menu->numitems<10){ - menuitem[0]='0'+cur; - menuitem[1]=' '; - menuitem[2]=0; - strcpy(menuitem+2,menu->items[curitem].text); - } - else { - menuitem[0]=cur>=10?('0'+(cur/10)):' '; - menuitem[1]='0'+(cur%10); - menuitem[2]=' '; - menuitem[3]=0; - strcpy(menuitem+3,menu->items[curitem].text); - } - } - //strncat(menuitem, menu->items[curitem].text, 68); - if(menu->items[curitem].type != MENUITEM_SEPARATOR) { - //make sure we have a string big enough to have background when item is selected: - // MB_ElementCount is used instead of strlen because multibyte chars count as two with strlen, while graphically they are just one char, making fillerRequired become wrong - int fillerRequired = menu->width - MB_ElementCount(menu->items[curitem].text) - (menu->type == MENUTYPE_MULTISELECT ? 2 : 3); - for(int i = 0; i < fillerRequired; i++) - strcat(menuitem, " "); - drawRectangle(C10*menu->startX,C18*(curitem+itemsStartY-menu->scroll),C10*menu->width,C24,(menu->selection == curitem+1 ? color_gris : _WHITE)); - PrintXY(C10*menu->startX,C18*(curitem+itemsStartY-menu->scroll),menuitem, (menu->selection == curitem+1 ? TEXT_MODE_INVERT : TEXT_MODE_NORMAL)); - } else { - /*int textX = (menu->startX-1) * C18; - int textY = curitem*C24+itemsStartY*C24-menu->scroll*C24-C24+C10; - clearLine(menu->startX, curitem+itemsStartY-menu->scroll, (menu->selection == curitem+1 ? textColorToFullColor(menu->items[curitem].color) : COLOR_WHITE)); - drawLine(textX, textY+C24-4, LCD_WIDTH_PX-2, textY+C24-4, COLOR_GRAY); - PrintMini(&textX, &textY, (unsigned char*)menuitem, 0, 0xFFFFFFFF, 0, 0, (menu->selection == curitem+1 ? COLOR_WHITE : textColorToFullColor(menu->items[curitem].color)), (menu->selection == curitem+1 ? textColorToFullColor(menu->items[curitem].color) : COLOR_WHITE), 1, 0);*/ - } - // deal with menu items of type MENUITEM_CHECKBOX - if(menu->items[curitem].type == MENUITEM_CHECKBOX) { - PrintXY(C10*(menu->startX+menu->width-4),C18*(curitem+itemsStartY-menu->scroll), - (menu->items[curitem].value == MENUITEM_VALUE_CHECKED ? " [+]" : " [-]"), - (menu->selection == curitem+1 ? TEXT_MODE_INVERT : (menu->pBaRtR == 1? TEXT_MODE_NORMAL : TEXT_MODE_NORMAL))); - } - // deal with multiselect menus - if(menu->type == MENUTYPE_MULTISELECT) { - if((curitem+itemsStartY-menu->scroll)>=itemsStartY && - (curitem+itemsStartY-menu->scroll)<=(itemsStartY+itemsHeight) && - icontable != NULL - ) { -#if 0 - if (menu->items[curitem].isfolder == 1) { - // assumes first icon in icontable is the folder icon - CopySpriteMasked(icontable[0].data, (menu->startX)*C18, (curitem+itemsStartY-menu->scroll)*C24, 0x12, 0x18, 0xf81f ); - } else { - if(menu->items[curitem].icon >= 0) CopySpriteMasked(icontable[menu->items[curitem].icon].data, (menu->startX)*C18, (curitem+itemsStartY-menu->scroll)*C24, 0x12, 0x18, 0xf81f ); - } -#endif - } - if (menu->items[curitem].isselected) { - if (menu->selection == curitem+1) { - PrintXY(C10*menu->startX,C18*(curitem+itemsStartY-menu->scroll),"\xe6\x9b", TEXT_MODE_NORMAL); - } else { - PrintXY(C10*menu->startX,C18*(curitem+itemsStartY-menu->scroll),"\xe6\x9b", TEXT_MODE_NORMAL); - } - } - } - } - } // end for curitemnumitem - int dh=menu->height-menu->numitems-(showtitle?1:0); - if (dh>0) - drawRectangle(C10*menu->startX,C24*(menu->numitems+(showtitle?1:0)),C10*menu->width,C24*dh,_WHITE); - if (menu->scrollbar) { -#ifdef SCROLLBAR - TScrollbar sb; - sb.I1 = 0; - sb.I5 = 0; - sb.indicatormaximum = menu->numitems; - sb.indicatorheight = itemsHeight; - sb.indicatorpos = menu->scroll; - sb.barheight = itemsHeight*C24; - sb.bartop = (itemsStartY-1)*C24; - sb.barleft = menu->startX*C18+menu->width*C18 - C18 - (menu->scrollout ? 0 : 5); - sb.barwidth = C10; - Scrollbar(&sb); -#endif - } - //if(menu->type==MENUTYPE_MULTISELECT && menu->fkeypage == 0) drawFkeyLabels(0x0037); // SELECT (white) - } else { - giac::printCentered(menu->nodatamsg, (itemsStartY*C24)+(itemsHeight*C24)/2-12); - } - if(showtitle) { - int textX = C10*menu->startX, textY=menu->startY*C24; - drawRectangle(textX,textY,C10*menu->width,C24,_WHITE); - if (menu->miniMiniTitle) - PrintMini( textX, textY, menu->title, 0 ); - else - PrintXY(textX, textY, menu->title, TEXT_MODE_NORMAL); - if(menu->subtitle != NULL) { - int textX=(MB_ElementCount(menu->title)+menu->startX-1)*C18+C10, textY=C10; - PrintMini(textX, textY, menu->subtitle, 0); - } - PrintXY(textX+C10*(menu->width-5), 1, "____", 0); - PrintXY(textX+C10*(menu->width-5), 1, keyword, 0); - } - /*if(menu->darken) { - DrawFrame(COLOR_BLACK); - VRAMInvertArea(menu->startX*C18-C18, menu->startY*C24, menu->width*C18-(menu->scrollout || !menu->scrollbar ? 0 : 5), menu->height*C24); - }*/ - if(menu->type == MENUTYPE_NO_KEY_HANDLING) return MENU_RETURN_INSTANT; // we don't want to handle keys - int key; - GetKey(&key); - if (key==KEY_SHUTDOWN) - return key; - if (key==KEY_CTRL_MENU){ - menu->selection=menu->numitems; - return MENU_RETURN_SELECTION; - } - if (key<256 && isalpha(key)){ - key=tolower(key); - int pos=strlen(keyword); - if (pos>=4) - pos=0; - keyword[pos]=key; - keyword[pos+1]=0; - int cur=0; - for (;curnumitems;++cur){ -#if 1 - if (strcmp(menu->items[cur].text,keyword)>=0) - break; -#else - char c=menu->items[cur].text[0]; - if (key<=c) - break; -#endif - } - if (curnumitems){ - menu->selection=cur+1; - if(menu->selection > menu->scroll+(menu->numitems>itemsHeight ? itemsHeight : menu->numitems)) - menu->scroll = menu->selection -(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); - if(menu->selection-1 < menu->scroll) - menu->scroll = menu->selection -1; - } - continue; - } - switch(key) { - case KEY_CTRL_PAGEDOWN: - menu->selection+=6; - if (menu->selection >= menu->numitems) - menu->selection=menu->numitems; - if(menu->selection > menu->scroll+(menu->numitems>itemsHeight ? itemsHeight : menu->numitems)) - menu->scroll = menu->selection -(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); - break; - case KEY_CTRL_DOWN: - if(menu->selection == menu->numitems) - { - if(menu->returnOnInfiniteScrolling) { - return MENU_RETURN_SCROLLING; - } else { - menu->selection = 1; - menu->scroll = 0; - } - } - else - { - menu->selection++; - if(menu->selection > menu->scroll+(menu->numitems>itemsHeight ? itemsHeight : menu->numitems)) - menu->scroll = menu->selection -(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); - } - if(menu->pBaRtR==1) return MENU_RETURN_INSTANT; - break; - case KEY_CTRL_PAGEUP: - menu->selection-=6; - if (menu->selection <=1) - menu->selection=1; - if(menu->selection-1 < menu->scroll) - menu->scroll = menu->selection -1; - break; - case KEY_CTRL_UP: - if(menu->selection == 1) - { - if(menu->returnOnInfiniteScrolling) { - return MENU_RETURN_SCROLLING; - } else { - menu->selection = menu->numitems; - menu->scroll = menu->selection-(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); - } - } - else - { - menu->selection--; - if(menu->selection-1 < menu->scroll) - menu->scroll = menu->selection -1; - } - if(menu->pBaRtR==1) return MENU_RETURN_INSTANT; - break; - case KEY_CTRL_F1: - if(menu->type==MENUTYPE_MULTISELECT && menu->fkeypage == 0 && menu->numitems > 0) { - /*if(menu->items[menu->selection-1].isselected) { - menu->items[menu->selection-1].isselected=0; - menu->numselitems = menu->numselitems-1; - } else { - menu->items[menu->selection-1].isselected=1; - menu->numselitems = menu->numselitems+1; - } - return key; //return on F1 too so that parent subroutines have a chance to e.g. redraw fkeys*/ - } else if (menu->type == MENUTYPE_FKEYS || menu->type==MENUTYPE_NO_NUMBER) { - return key; - } - break; - case KEY_CTRL_F2: - case KEY_CTRL_F3: - case KEY_CTRL_F4: - case KEY_CTRL_F5: - case KEY_CTRL_F6: case KEY_CTRL_CATALOG: case KEY_BOOK: case '\t': - case KEY_CHAR_ANS: - if (menu->type == MENUTYPE_FKEYS || menu->type==MENUTYPE_NO_NUMBER || menu->type==MENUTYPE_MULTISELECT) return key; // MULTISELECT also returns on Fkeys - break; - case KEY_CTRL_PASTE: - if (menu->type==MENUTYPE_MULTISELECT) return key; // MULTISELECT also returns on paste - case KEY_CTRL_OPTN: - if (menu->type==MENUTYPE_FKEYS || menu->type==MENUTYPE_MULTISELECT) return key; - break; - case KEY_CTRL_FORMAT: - if (menu->type==MENUTYPE_FKEYS) return key; // return on the Format key so that event lists can prompt to change event category - break; - case KEY_CTRL_RIGHT: - if(menu->type != MENUTYPE_MULTISELECT) return KEY_BOOK; // break; - // else fallthrough - case KEY_CTRL_EXE: case KEY_CTRL_OK: - if(menu->numitems>0) return key==KEY_CTRL_OK?MENU_RETURN_SELECTION:key; - break; - case KEY_CTRL_LEFT: - if(menu->type != MENUTYPE_MULTISELECT) break; - // else fallthrough - case KEY_CTRL_DEL: - if (strlen(keyword)) - keyword[strlen(keyword)-1]=0; - else { - if (strcmp(menu->title,"Variables")==0) - return key; - } - break; - case KEY_CTRL_AC: - if (strlen(keyword)){ - keyword[0]=0; - lock_alpha();//SetSetupSetting( (unsigned int)0x14, 0x88); - //DisplayStatusArea(); - break; - } - case KEY_CTRL_EXIT: - return MENU_RETURN_EXIT; - break; - case KEY_CHAR_1: - case KEY_CHAR_2: - case KEY_CHAR_3: - case KEY_CHAR_4: - case KEY_CHAR_5: - case KEY_CHAR_6: - case KEY_CHAR_7: - case KEY_CHAR_8: - case KEY_CHAR_9: - if (menu->type==MENUTYPE_NO_NUMBER) - return key; - if(menu->numitems>=(key-0x30)) { - menu->selection = (key-0x30); - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_0: - if (menu->type==MENUTYPE_NO_NUMBER) - return key; - if(menu->numitems>=10) { - menu->selection = 10; - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_EXPN: - if(menu->numitems>=11) { - menu->selection = 11; - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_LN: - if(menu->numitems>=12) { - menu->selection = 12; - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_LOG: - if(menu->numitems>=13) { - menu->selection = 13; - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_IMGNRY: - if(menu->numitems>=14) { - menu->selection = 14; - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_COMMA: - if(menu->numitems>=15) { - menu->selection = 15; - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_POW: - if(menu->numitems>=16) { - menu->selection = 16; - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_SIN: - case KEY_CHAR_COS: - case KEY_CHAR_TAN: - if(menu->numitems>=(key-112)) { - menu->selection = (key-112); - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_PI: - if(menu->numitems>=20) { - menu->selection = 20; - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_ROOT: - if(menu->numitems>=21) { - menu->selection = 21; - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_SQUARE: - if(menu->numitems>=22) { - menu->selection = 22; - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - case KEY_CHAR_LPAR: - case KEY_CHAR_RPAR: - if(menu->numitems>=(key-17)) { - menu->selection = (key-17); - if (menu->type != MENUTYPE_FKEYS) return MENU_RETURN_SELECTION; - } - break; - } - } - return MENU_RETURN_EXIT; - } - -#define CAT_CATEGORY_ALL 0 -#define CAT_CATEGORY_ALGEBRA 1 -#define CAT_CATEGORY_LINALG 2 -#define CAT_CATEGORY_CALCULUS 3 -#define CAT_CATEGORY_ARIT 4 -#define CAT_CATEGORY_COMPLEXNUM 5 -#define CAT_CATEGORY_PLOT 6 -#define CAT_CATEGORY_POLYNOMIAL 7 -#define CAT_CATEGORY_PROBA 8 -#define CAT_CATEGORY_PROGCMD 9 -#define CAT_CATEGORY_REAL 10 -#define CAT_CATEGORY_SOLVE 11 -#define CAT_CATEGORY_STATS 12 -#define CAT_CATEGORY_TRIG 13 -#define CAT_CATEGORY_OPTIONS 14 -#define CAT_CATEGORY_LIST 15 -#define CAT_CATEGORY_MATRIX 16 -#define CAT_CATEGORY_PROG 17 -#define CAT_CATEGORY_SOFUS 18 -#define CAT_CATEGORY_PHYS 19 -#define CAT_CATEGORY_UNIT 20 -#define CAT_CATEGORY_2D 21 -#define CAT_CATEGORY_3D 22 -#define CAT_CATEGORY_LOGO 23 // should be the last one -#define XCAS_ONLY 0x80000000 - void init_locale(){ - lang=1; - } - - const catalogFunc completeCatfr[] = { // list of all functions (including some not in any category) - // {"cosh(x)", 0, "Hyperbolic cosine of x.", 0, 0, CAT_CATEGORY_TRIG}, - // {"exp(x)", 0, "Renvoie e^x.", "1.2", 0, CAT_CATEGORY_REAL}, - // {"log(x)", 0, "Logarithme naturel de x.", 0, 0, CAT_CATEGORY_REAL}, - // {"sinh(x)", 0, "Hyperbolic sine of x.", 0, 0, CAT_CATEGORY_TRIG}, - // {"tanh(x)", 0, "Hyperbolic tangent of x.", 0, 0, CAT_CATEGORY_TRIG}, - {" boucle for (pour)", "for ", "Boucle definie pour un indice variant entre 2 valeurs fixees", "#\nfor ", 0, CAT_CATEGORY_PROG}, - {" boucle liste", "for in", "Boucle sur tous les elements d'une liste.", "#\nfor in", 0, CAT_CATEGORY_PROG}, - {" boucle while (tantque)", "while ", "Boucle indefinie tantque.", "#\nwhile ", 0, CAT_CATEGORY_PROG}, - {" test si alors", "if ", "Test", "#\nif ", 0, CAT_CATEGORY_PROG}, - {" test sinon", "else ", "Clause fausse du test", 0, 0, CAT_CATEGORY_PROG}, - {" fonction def.", "f(x):=", "Definition de fonction.", "#\nf(x):=", 0, CAT_CATEGORY_PROG}, - {" local j,k;", "local ", "Declaration de variables locales Xcas", 0, 0, CAT_CATEGORY_PROG | XCAS_ONLY}, - {" range(a,b)", "in range(", "Dans l'intervalle [a,b[ (a inclus, b exclus)", "# in range(1,10)", 0, CAT_CATEGORY_PROG}, - {" return res;", "return ", "return ou retourne quitte la fonction et renvoie le resultat res", 0, 0, CAT_CATEGORY_PROG}, - //{" edit list ", "list(", "Assistant creation de liste.", 0, 0, CAT_CATEGORY_LIST}, - //{" edit matrix ", "matrix(", "Assistant creation de matrice.", 0, 0, CAT_CATEGORY_MATRIX }, - {" mksa(x)", 0, "Conversion en unites MKSA", 0, 0, CAT_CATEGORY_PHYS | (CAT_CATEGORY_UNIT << 8) | XCAS_ONLY}, - {" ufactor(a,b)", 0, "Factorise l'unite b dans a", "100_J,1_kW", 0, CAT_CATEGORY_PHYS | (CAT_CATEGORY_UNIT << 8) | XCAS_ONLY}, - {" usimplify(a)", 0, "Simplifie l'unite dans a", "100_l/10_cm^2", 0, CAT_CATEGORY_PHYS | (CAT_CATEGORY_UNIT << 8) | XCAS_ONLY}, - //{"fonction def Xcas", "fonction f(x) local y; ffonction:;", "Definition de fonction.", "#fonction f(x) local y; y:=x^2; return y; ffonction:;", 0, CAT_CATEGORY_PROG}, - {"!", "!", "Non logique (prefixe) ou factorielle de n (suffixe).", "#7!", "#!b", CAT_CATEGORY_PROGCMD}, - {"#", "#", "Commentaire Python, en Xcas taper //.", 0, 0, CAT_CATEGORY_PROG}, - {"%", "%", "a % b signifie a modulo b", 0, 0, CAT_CATEGORY_ARIT | (CAT_CATEGORY_PROGCMD << 8)}, - {"&", "&", "Et logique ou +", "#1&2", 0, CAT_CATEGORY_PROGCMD}, - {":=", ":=", "Affectation vers la gauche (inverse de =>).", "#a:=3", 0, CAT_CATEGORY_PROGCMD|(CAT_CATEGORY_SOFUS<<8)|XCAS_ONLY}, - {"<", "<", "Inferieur strict. Raccourci SHIFT F2", 0, 0, CAT_CATEGORY_PROGCMD}, - {"=>", "=>", "Affectation vers la droite ou conversion en (touche ->). Par exemple 5=>a ou x^4-1=>* ou (x+1)^2=>+ ou sin(x)^2=>cos.", "#5=>a", "#15_m=>_cm", CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_PHYS <<8) | (CAT_CATEGORY_UNIT << 16) | XCAS_ONLY}, - {">", ">", "Superieur strict. Raccourci F2.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"\\", "\\", "Caractere \\", 0, 0, CAT_CATEGORY_PROGCMD}, - {"_", "_", "Caractere _. Prefixe d'unites.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"_(km/h)", "_(km/h)", "Vitesse en kilometre/heure", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_(m/s)", "_(m/s)", "Vitesse en metre/seconde", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_(m/s^2)", "_(m/s^2)", "Acceleration en metre par seconde au carre", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_(m^2/s)", "_(m^2/s)", "Viscosite", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_A", 0, "Intensite electrique en Ampere", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Bq", 0, "Radioactivite: Becquerel", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_C", 0, "Charge electrique en Coulomb", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Ci", 0, "Radioactivite: Curie", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_F", 0, "Farad", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_F_", 0, "constante de Faraday (charge globale d'une mole de charges élémentaires).", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_G_", 0, "constante de gravitation universelle. Force=_G_*m1*m2/r^2", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_H", 0, "Henry", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Hz", 0, "Hertz", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_J", 0, "Energie en Joule=kg*m^2/s^2", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_K", 0, "Temperature en Kelvin", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Kcal", 0, "Energie en kilo-calorier", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_MeV", 0, "Energie en mega-electron-Volt", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_N", 0, "Force en Newton=kg*m/s^2", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_NA_", 0, "Avogadro", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_Ohm", 0, "Resistance electrique en Ohm", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_PSun_", 0, "puissance du Soleil", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_Pa", 0, "Pression en Pascal=kg/m/s^2", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_REarth_", 0, "Rayon de la Terre", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_RSun_", 0, "rayon du Soleil", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_R_", 0, "constante des gaz (de Boltzmann par mole)", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_S", 0, "", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_StdP_", 0, "Pression standard (au niveau de la mer)", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_StdT_", 0, "temperature standard (0 degre Celsius exprimes en Kelvins)", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_Sv", 0, "Radioactivite: Sievert", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_T", 0, "Tesla", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_V", 0, "Tension electrique en Volt", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Vm_", 0, "Volume molaire", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_W", 0, "Puissance en Watt=kg*m^2/s^3", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Wb", 0, "Weber", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_alpha_", 0, "constante de structure fine", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_c_", 0, "vitesse de la lumiere", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_cd", 0, "Luminosite en candela", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_cdf", "_cdf", "Suffixe pour obtenir une distribution cumulee. Taper F2 pour la distribution cumulee inverse.", "#_icdf", 0, CAT_CATEGORY_PROBA|XCAS_ONLY}, - {"_d", 0, "Temps: jour", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_deg", 0, "Angle en degres", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_eV", 0, "Energie en electron-Volt", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_epsilon0_", 0, "permittivite du vide", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_ft", 0, "Longueur en pieds", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_g_", 0, "gravite au sol", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_grad", 0, "Angle en grades", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_h", 0, "Heure", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_h_", 0, "constante de Planck", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_ha", 0, "Aire en hectare", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_hbar_", 0, "constante de Planck/(2*pi)", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_inch", 0, "Longueur en pouces", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_kWh", 0, "Energie en kWh", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_k_", 0, "constante de Boltzmann", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_kg", 0, "Masse en kilogramme", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_l", 0, "Volume en litre", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_m", 0, "Longueur en metre", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_mEarth_", 0, "masse de la Terre", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_m^2", 0, "Aire en m^2", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_m^3", 0, "Volume en m^3", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_me_", 0, "masse electron", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_miUS", 0, "Longueur en miles US", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_mn", 0, "Temps: minute", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_mp_", 0, "masse proton", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_mpme_", 0, "ratio de masse proton/electron", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_mu0_", 0, "permeabilite du vide", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_phi_", 0, "quantum flux magnetique", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_plot", "_plot", "Suffixe pour obtenir le graphe d'une regression.", "#X,Y:=[1,2,3,4,5],[0,1,3,4,4];polynomial_regression_plot(X,Y,2);scatterplot(X,Y)", 0, CAT_CATEGORY_STATS| XCAS_ONLY}, - {"_qe_", 0, "charge de l'electron", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_qme_", 0, "_q_/_me_", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_rad", 0, "Angle en radians", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_rem", 0, "Radioactivite: rem", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_s", 0, "Temps: seconde", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_sd_", 0, "Jour sideral", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_syr_", 0, "Annee siderale", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_tr", 0, "Angle en tours", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_yd", 0, "Longueur en yards", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"a and b", " and ", "Et logique", 0, 0, CAT_CATEGORY_PROGCMD}, - {"a or b", " or ", "Ou logique", 0, 0, CAT_CATEGORY_PROGCMD}, - {"abcuv(a,b,c)", 0, "Cherche 2 polynomes u,v tels que a*u+b*v=c","x+1,x^2-2,x", 0, CAT_CATEGORY_POLYNOMIAL| XCAS_ONLY}, - {"abs(x)", 0, "Valeur absolue, module ou norme de x", "-3", "[1,2,3]", CAT_CATEGORY_COMPLEXNUM | (CAT_CATEGORY_REAL<<8)}, - {"add(u,v)", 0, "En Python, additionne des listes ou listes de listes u et v comme des vecteurs ou matrices.","[1,2,3],[0,1,3]", "[[1,2]],[[3,4]]", CAT_CATEGORY_LINALG}, - {"append", 0, "Ajoute un element en fin de liste l","#l.append(x)", 0, CAT_CATEGORY_LIST}, - {"approx(x)", 0, "Valeur approchee de x. Raccourci S-D", "pi", 0, CAT_CATEGORY_REAL| XCAS_ONLY}, - {"aire(objet)", 0, "Aire algebrique", "cercle(0,1)", "triangle(-1,1+i,3)", CAT_CATEGORY_2D }, - {"arg(z)", 0, "Argument du complexe z.", "1+i", 0, CAT_CATEGORY_COMPLEXNUM | XCAS_ONLY}, - {"asc(string)", 0, "Liste des codes ASCII d'une chaine", "\"Bonjour\"", 0, CAT_CATEGORY_ARIT}, - {"assume(hyp)", 0, "Hypothese sur une variable.", "x>1", "x>-1 and x<1", CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_SOFUS<<8) | XCAS_ONLY}, - {"avance n", "avance ", "La tortue avance de n pas, par defaut n=10", "#avance 40", 0, CAT_CATEGORY_LOGO}, - {"axes", "axes", "Axes visibles ou non axes=1 ou 0", "#axes=0", "#axes=1", CAT_CATEGORY_PROGCMD << 8|XCAS_ONLY}, - {"baisse_crayon ", "baisse_crayon ", "La tortue se deplace en marquant son passage.", 0, 0, CAT_CATEGORY_LOGO}, - {"barplot(list)", 0, "Diagramme en batons d'une serie statistique 1d.", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS | (CAT_CATEGORY_PLOT<<8)}, - {"barycentre([pnt,coeff],...)", 0, "Barycentre d'une sequnence de [points,coefficients]. Utiliser isobarycenter si tous les coefficients sont egaux.", "[1,1],[i,1],[2,3]", 0, CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"binomial(n,p,k)", 0, "binomial(n,p,k) probabilite de k succes avec n essais ou p est la proba de succes d'un essai. binomial_cdf(n,p,k) est la probabilite d'obtenir au plus k succes avec n essais. binomial_icdf(n,p,t) renvoie le plus petit k tel que binomial_cdf(n,p,k)>=t", "10,.5,4", 0, CAT_CATEGORY_PROBA | XCAS_ONLY}, - {"bissectrice(A,B,C)", 0, "Bissectrice de l'angle AB,AC", "1,i,2+i", 0,CAT_CATEGORY_2D}, - {"bitxor", "bitxor", "Ou exclusif", "#bitxor(1,2)", 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"black", "black", "Option d'affichage", "#display=black", 0, CAT_CATEGORY_PROGCMD}, - {"blue", "blue", "Option d'affichage", "#display=blue", 0, CAT_CATEGORY_PROGCMD}, - {"caseval", "caseval", "Evalue une chaine de caractere en appelant le CAS.", "caseval(\"limit(sin(x)/x,x=0)\")", "caseval(\"factor(x^10-1)\")", CAT_CATEGORY_ALGEBRA | (CAT_CATEGORY_CALCULUS <<8)}, - {"cache_tortue ", "cache_tortue ", "Cache la tortue apres avoir trace le dessin.", 0, 0, CAT_CATEGORY_LOGO}, - {"camembert(list)", 0, "Diagramme en camembert d'une serie statistique 1d.", "[[\"France\",6],[\"Allemagne\",12],[\"Suisse\",5]]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"ceil(x)", 0, "Partie entiere superieure", "1.2", 0, CAT_CATEGORY_REAL}, - {"centre(objet)", 0, "Centre d'un cercle ou d'une sphere. Pour une conique a centre, renvoie le centre, un foyer et un point de la conique. Pour une parabole, renvoie le foyer et le sommet.", "cercle(0,1)", "sphere([0,0,0],[1,1,1])", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"cercle(centre,rayon)", 0, "Cercle donne par centre et rayon ou par un diametre", "2+i,3", "1-i,1+i", CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"circonscrit(A,B,C)", 0, "Cercle circonscrit", "-1,2+i,3", 0, CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"cfactor(p)", 0, "Factorisation sur C.", "x^4-1", 0, CAT_CATEGORY_ALGEBRA | (CAT_CATEGORY_COMPLEXNUM << 8) | XCAS_ONLY}, - {"char(liste)", 0, "Chaine donnee par une liste de code ASCII", "[97,98,99]", 0, CAT_CATEGORY_ARIT}, - {"charpoly(M,x)", 0, "Polynome caracteristique de la matrice M en la variable x.", "[[1,2],[3,4]],x", 0, CAT_CATEGORY_MATRIX | XCAS_ONLY}, - {"clearscreen()", "clearscreen()", "Efface l'ecran.", 0, 0, CAT_CATEGORY_PROGCMD|XCAS_ONLY}, - {"coeff(p,x,n)", 0, "Coefficient de x^n dans le polynome p.", "(1+x)^6,x,3", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"comb(n,k)", 0, "Renvoie k parmi n.", "10,4", 0, CAT_CATEGORY_PROBA | XCAS_ONLY}, - {"cond(A,[1,2,inf])", 0, "Nombre de condition d'une matrice par rapport a la norme specifiee (par defaut 1)", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX | XCAS_ONLY}, - {"cone(A,v,theta,[h])", 0, "Cone de sommet A, axe v, angle theta, hauteur h optionnelle", "[0,0,0],[0,0,1],pi/6", "[0,0,0],[0,0,1],pi/6,4", CAT_CATEGORY_3D}, - {"conique(expression)", 0, "Conique donnee par une equation polynomiale de degre 2 ou passant par 5 points", "x^2+x*y+y^2=5", "1,i,2+i,3-i,4+2i", CAT_CATEGORY_2D}, - {"coordonnees(object)", 0, "Coordonnees (cartesiennes)", "point(1,2)", "point(1,2,3)", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"conj(z)", 0, "Conjugue complexe de z.", "1+i", 0, CAT_CATEGORY_COMPLEXNUM}, - {"correlation(l1,l2)", 0, "Correlation listes l1 et l2", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"covariance(l1,l2)", 0, "Covariance listes l1 et l2", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"cpartfrac(p,x)", 0, "Decomposition en elements simples sur C.", "1/(x^4-1)", 0, CAT_CATEGORY_ALGEBRA | (CAT_CATEGORY_COMPLEXNUM << 8) | XCAS_ONLY}, - {"crayon ", "crayon ", "Couleur de trace de la tortue", "#crayon rouge", 0, CAT_CATEGORY_LOGO}, - {"cross(u,v)", 0, "Produit vectoriel de u et v.","[1,2,3],[0,1,3]", 0, CAT_CATEGORY_LINALG | (CAT_CATEGORY_2D << 8)}, - {"csolve(equation,x)", 0, "Resolution exacte dans C d'une equation en x (ou d'un systeme polynomial).","x^2+x+1=0", 0, CAT_CATEGORY_SOLVE | (CAT_CATEGORY_COMPLEXNUM << 8) | XCAS_ONLY}, - {"cube(A,B,C)", 0, "Cube d'arete AB avec une face dans le plan ABC", "[0,0,0],[1,0,0],[0,1,0]","[0,0,0],[0,2,sqrt(5)/2+3/2],[0,0,1]", CAT_CATEGORY_3D}, - {"curl(u,vars)", 0, "Rotationnel du vecteur u.", "[2*x*y,x*z,y*z],[x,y,z]", 0, CAT_CATEGORY_LINALG | XCAS_ONLY}, - {"cyan", "cyan", "Option d'affichage", "#display=cyan", 0, CAT_CATEGORY_PROGCMD}, - {"cylinder(A,v,r,[h])", 0, "Cylindre d'axe A,v de rayon r et de hauteur optionnelle h", "[0,0,0],[0,1,0],2", "[0,0,0],[0,1,0],2,3", CAT_CATEGORY_3D}, - {"debug(f(args))", 0, "Execute la fonction f en mode pas a pas.", 0, 0, CAT_CATEGORY_PROG | XCAS_ONLY}, - {"degree(p,x)", 0, "Degre du polynome p en x.", "x^4-1", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"denom(x)", 0, "Denominateur de l'expression x.", "3/4", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"desolve(equation,t,y)", 0, "Resolution exacte d'equation differentielle ou de systeme differentiel lineaire a coefficients constants.", "[y'+y=exp(x),y(0)=1]", "[y'=[[1,2],[2,1]]*y+[x,x+1],y(0)=[1,2]]", CAT_CATEGORY_SOLVE | (CAT_CATEGORY_CALCULUS << 8) | XCAS_ONLY}, - {"det(A)", 0, "Determinant de la matrice A.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX | XCAS_ONLY}, - {"diff(f,var,[n])", 0, "Derivee de l'expression f par rapport a var (a l'ordre n, n=1 par defaut), par exemple diff(sin(x),x) ou diff(x^3,x,2). Pour deriver f par rapport a x, utiliser f' (raccourci F3). Pour le gradient de f, var est la liste des variables.", "sin(x),x", "sin(x^2),x,3", CAT_CATEGORY_CALCULUS | XCAS_ONLY}, - {"display", "display", "Option d'affichage", "#display=red", 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"disque n", "disque ", "Cercle rempli tangent a la tortue, de rayon n. Utiliser disque n,theta pour remplir un morceau de camembert ou disque n,theta,segment pour remplir un segment de disque", "#disque 30", "#disque(30,90)", CAT_CATEGORY_LOGO}, - {"distance(A,B)", 0, "Distance de 2 objets geometriques", "point(1,2,3),point(4,1,2)", 0, CAT_CATEGORY_3D | (CAT_CATEGORY_2D << 8) }, - {"dot(a,b)", 0, "Produit scalaire de 2 vecteurs. Raccourci: *", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_LINALG | (CAT_CATEGORY_2D << 8)}, - {"dodecahedron(A,B,C)", 0, "Dodecaedre d'arete AB avec une face dans le plan ABC", "[0,0,0],[0,2,sqrt(5)/2+3/2],[0,0,1]", 0, CAT_CATEGORY_3D}, - {"draw_arc(x1,y1,rx,ry,theta1,theta2,c)", 0, "Arc d'ellipse pixelise.", "100,100,60,80,0,pi,magenta", 0, CAT_CATEGORY_PROGCMD}, - {"draw_circle(x1,y1,r,c)", 0, "Cercle pixelise. Option filled pour le remplir.", "100,100,60,cyan+filled", 0, CAT_CATEGORY_PROGCMD}, - {"draw_line(x1,y1,x2,y2,c)", 0, "Droite pixelisee.", "100,50,300,200,blue", 0, CAT_CATEGORY_PROGCMD}, - {"draw_pixel(x,y,color)", 0, "Colorie le pixel x,y. Faire draw_pixel() pour synchroniser l'ecran.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"draw_polygon([[x1,y1],...],c)", 0, "Polygone pixelise.", "[[100,50],[30,20],[60,70]],red+filled", 0, CAT_CATEGORY_PROGCMD}, - {"draw_rectangle(x,y,w,h,c)", 0, "Rectangle pixelise.", "100,50,30,20,red+filled", 0, CAT_CATEGORY_PROGCMD}, - {"draw_string(s,x,y,c)", 0, "Affiche la chaine s en x,y", "\"Bonjour\",80,60", 0, CAT_CATEGORY_PROGCMD}, - {"droite(equation)", 0, "Droite donnee par une equation ou 2 points", "y=2x+1", "1+i,2-i", CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8) | (CAT_CATEGORY_2D << 16) | XCAS_ONLY}, - {"ecris ", "ecris ", "Ecrire a la position de la tortue", "#ecris \"coucou\"", 0, CAT_CATEGORY_LOGO}, - {"efface", "efface", "Remise a zero de la tortue", 0, 0, CAT_CATEGORY_LOGO | XCAS_ONLY}, - {"egcd(A,B)", 0, "Cherche des polynomes U,V,D tels que A*U+B*V=D=gcd(A,B)","x^2+3x+1,x^2-5x-1", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"eigenvals(A)", 0, "Valeurs propres de la matrice A.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX | XCAS_ONLY}, - {"eigenvects(A)", 0, "Vecteurs propres de la matrice A.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"elif (test)", "elif", "Tests en cascade", 0, 0, CAT_CATEGORY_PROG | XCAS_ONLY}, - //{"end", "end", "Fin de bloc", 0, 0, CAT_CATEGORY_PROG}, - {"ellipse(F1,F2,M)", 0, "Ellipse donnee par les 2 foyers et un point", "-1,1,2", 0, CAT_CATEGORY_2D}, - {"equation(objet)", 0, "Equation cartesienne. Utiliser parameq pour parametrique.", "circle(0,1)", "ellipse(-1,1,3)", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"erf(x)", 0, "Fonction erreur en x.", "1.2", 0, CAT_CATEGORY_PROBA}, - {"erfc(x)", 0, "Fonction erreur complementaire en x.", "1.2", 0, CAT_CATEGORY_PROBA}, - {"euler(n)",0,"Indicatrice d'Euler: nombre d'entiers < n premiers avec n","25",0,CAT_CATEGORY_ARIT}, - {"eval(f)", 0, "Evalue f.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"evalc(z)", 0, "Ecrit z=x+i*y.", "1/(1+i*sqrt(3))", 0, CAT_CATEGORY_COMPLEXNUM | XCAS_ONLY}, - {"exact(x)", 0, "Convertit x en rationnel. Raccourci shift S-D", "1.2", 0, CAT_CATEGORY_REAL | XCAS_ONLY}, - {"exp2trig(expr)", 0, "Conversion d'exponentielles complexes en sin/cos", "exp(i*x)", 0, CAT_CATEGORY_TRIG | XCAS_ONLY}, - {"exponential_regression(Xlist,Ylist)", 0, "Regression exponentielle.", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"exponential_regression_plot(Xlist,Ylist)", 0, "Graphe d'une regression exponentielle.", "#X,Y:=[1,2,3,4,5],[1,3,4,6,8];exponential_regression_plot(X,Y);", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"exponentiald(lambda,x)", 0, "Loi exponentielle de parametre lambda. exponentiald_cdf(lambda,x) probabilite que \"loi exponentielle <=x\" par ex. exponentiald_cdf(2,3). exponentiald_icdf(lambda,t) renvoie x tel que \"loi exponentielle <=x\" vaut t, par ex. exponentiald_icdf(2,0.95) ", "5.1,3.4", 0, CAT_CATEGORY_PROBA | XCAS_ONLY}, - {"extend", 0, "Concatene 2 listes. Attention en Xcas, ne pas utiliser + qui effectue l'addition de 2 vecteurs.","#l1.extend(l2)", 0, CAT_CATEGORY_LIST}, - {"factor(p,[x])", 0, "Factorisation du polynome p (utiliser ifactor pour un entier). Raccourci: p=>*", "x^4-1", "x^6+1,sqrt(3)", CAT_CATEGORY_ALGEBRA | (CAT_CATEGORY_POLYNOMIAL << 8) | XCAS_ONLY}, - {"filled", "filled", "Option d'affichage", 0, 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"float(x)", 0, "Convertit x en nombre approche (flottant).", "pi", 0, CAT_CATEGORY_REAL}, - {"floor(x)", 0, "Partie entiere de x", "pi", 0, CAT_CATEGORY_REAL}, - {"fonction f(x)", "fonction", "Definition de fonction (Xcas). Par exemple\nfonction f(x)\n local y;\ny:=x*x;\nreturn y;\nffonction", 0, 0, CAT_CATEGORY_PROG | XCAS_ONLY}, - {"from arit import *", "from arit import *", "Instruction pour utiliser les fonctions d'arithmetique entiere en Python", "#from arit import *", "#import arit", CAT_CATEGORY_ARIT}, - {"from cas import *", "from cas import *", "Permet d'utiliser le calcul formel depuis Python", "#from cas import *", "#import cas", CAT_CATEGORY_ALGEBRA|(CAT_CATEGORY_CALCULUS<<8)}, - {"from cmath import *", "from cmath import *", "Instruction pour utiliser les fonctions de maths sur les complexes (trigo, exponentielle, log, ...) en Python", "#from cmath import *;i=1j", "#import cmath", CAT_CATEGORY_COMPLEXNUM}, - {"from linalg import *", "from linalg import *", "Instruction pour utiliser les fonctions d'algebre lineaire en Python", "#from linalg import *;i=1j", "#import linalg", CAT_CATEGORY_LINALG | (CAT_CATEGORY_MATRIX<<8) | (CAT_CATEGORY_POLYNOMIAL<<16)}, - {"from numpy import *", "from numpy import *", "Instruction pour utiliser les fonctions sur les matrice en Python", "#from numpy import *;i=1j", "#import numpy", CAT_CATEGORY_LINALG | (CAT_CATEGORY_MATRIX <<8) | (CAT_CATEGORY_COMPLEXNUM << 16)}, - {"from math import *", "from math import *", "Instruction pour utiliser les fonctions de maths (trigo, exponentielle, log, ...) en Python", "#from math import *", "#import math", CAT_CATEGORY_REAL}, - {"from matplotl import *", "from matplotl import *", "Instruction pour utiliser les fonctions de trace en Python", "#from matplotl import *", "#import matplotl", CAT_CATEGORY_PROBA|(CAT_CATEGORY_PLOT <<8)|(CAT_CATEGORY_STATS<<16)}, - {"from random import *", "from random import *", "Instruction pour utiliser les fonctions aleatoires en Python", "#from random import *", "#import random", CAT_CATEGORY_PROBA}, - {"from turtle import *", "from turtle import *", "Instruction pour utiliser la tortue en Python", "#from turtle import *", "#import turtle", CAT_CATEGORY_LOGO}, - {"fsolve(equation,x=a[..b])", 0, "Resolution approchee de equation pour x dans l'intervalle a..b ou en partant de x=a.","cos(x)=x,x=0..1", "cos(x)-x,x=0.0", CAT_CATEGORY_SOLVE | XCAS_ONLY}, - {"gauss(q)", 0, "Reduction de Gauss d'une forme quadratique q", "x^2+x*y+x*z,[x,y,z]", "x^2+4*x*y,[]", CAT_CATEGORY_LINALG | XCAS_ONLY }, - {"gcd(a,b,...)", 0, "Plus grand commun diviseur. En Python ne fonctionne qu'avec des entiers. Voir iegcd ou egcd pour Bezout.", "23,13", "x^2-1,x^3-1", CAT_CATEGORY_ARIT | (CAT_CATEGORY_POLYNOMIAL << 8)}, - {"gl_x", "gl_x", "Reglage graphique X gl_x=xmin..xmax", "#gl_x=0..2", 0, CAT_CATEGORY_PROGCMD << 8 | XCAS_ONLY}, - {"gl_y", "gl_y", "Reglage graphique Y gl_y=ymin..ymax", "#gl_y=-1..1", 0, CAT_CATEGORY_PROGCMD << 8 | XCAS_ONLY}, - {"green", "green", "Option d'affichage", "#display=green", 0, CAT_CATEGORY_PROGCMD}, - {"halftan(expr)", 0, "Exprime cos, sin, tan avec tan(angle/2).","cos(x)", 0, CAT_CATEGORY_TRIG | XCAS_ONLY}, - {"hauteur(A,B,C)", 0, "Hauteur du triangle ABC issue de A", "1,i,2+i", 0,CAT_CATEGORY_2D}, - {"hermite(n)", 0, "n-ieme polynome de Hermite", "10", "10,t", CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"hilbert(n)", 0, "Matrice de Hilbert de taille n.", "4", 0, CAT_CATEGORY_MATRIX | XCAS_ONLY}, - {"histogram(list,min,size)", 0, "Histogramme d'une liste de donneees, classes commencant a min de taille size.","ranv(100,uniformd,0,1),0,0.1", 0, CAT_CATEGORY_STATS | (CAT_CATEGORY_PLOT<<8)}, - {"homothetie(centre,rapport,objet)", 0, "Image de l'objet par homothetie de rapport", "0,2,circle(1,1)", 0, CAT_CATEGORY_2D }, - {"hyperbole(F1,F2,M)", 0, "Hyperbole donnee par 2 foyers et un point", "-2-i,2+i,1", 0, CAT_CATEGORY_2D}, - {"iabcuv(a,b,c)", 0, "Cherche 2 entiers u,v tels que a*u+b*v=c","23,13,15", 0, CAT_CATEGORY_ARIT | XCAS_ONLY}, - {"ichinrem([a,m],[b,n])", 0,"Restes chinois entiers de a mod m et b mod n.", "[3,13],[2,7]", 0, CAT_CATEGORY_ARIT | XCAS_ONLY}, - {"icosahedron(A,B,C)", 0, "Icosaedre de centre A, de sommet B où le plan ABC contient le sommet le plus proche (parmi les 5) de B", "[0,0,0],[sqrt(5),0,0],[1,2,0]", 0, CAT_CATEGORY_3D}, - {"idivis(n)", 0, "Liste des diviseurs d'un entier n.", "10", 0, CAT_CATEGORY_ARIT}, - {"idn(n)", 0, "matrice identite n * n", "4", 0, CAT_CATEGORY_MATRIX}, - {"iegcd(a,b)", 0, "Determine les entiers u,v,d tels que a*u+b*v=d=gcd(a,b)","23,13", 0, CAT_CATEGORY_ARIT}, - {"ifactor(n)", 0, "Factorisation d'un entier (pas trop grand!). Raccourci n=>*", "1234", 0, CAT_CATEGORY_ARIT}, - {"ilaplace(f,s,x)", 0, "Transformee inverse de Laplace de f", "s/(s^2+1),s,x", 0, CAT_CATEGORY_CALCULUS | XCAS_ONLY}, - {"im(z)", 0, "Partie imaginaire (z.im en Python)", "1+i", 0, CAT_CATEGORY_COMPLEXNUM}, - {"inscrit(A,B,C)", 0, "Cercle inscrit", "-1,2+i,3", 0, CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"inf", "inf", "Plus l'infini. Utiliser -inf pour moins l'infini ou infinity pour l'infini complexe. Raccourci shift INS.", "-inf", "infinity", CAT_CATEGORY_CALCULUS | XCAS_ONLY}, - {"input()", "input()", "Lire une chaine au clavier", "\"Valeur ?\"", 0, CAT_CATEGORY_PROG}, - {"integrate(f,x,[,a,b])", 0, "Primitive de f par rapport a la variable x, par ex. integrate(x*sin(x),x). Pour calculer une integrale definie, entrer les arguments optionnels a et b, par ex. integrate(x*sin(x),x,0,pi). Raccourci SHIFT F3.", "x*sin(x),x", "cos(x)/(1+x^4),x,0,inf", CAT_CATEGORY_CALCULUS | XCAS_ONLY}, - {"interp(X,Y[,interp])", 0, "Interpolation de Lagrange aux points (xi,yi) avec X la liste des xi et Y des yi. Renvoie la liste des differences divisees si interp est passe en parametre.", "[1,2,3,4,5],[0,1,3,4,4]", "[1,2,3,4,5],[0,1,3,4,4],interp", CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"inter(A,B)", 0, "Liste des intersections. Utiliser single_inter si l'intersection est unique.", "line(y=x),circle(0,1)", 0, CAT_CATEGORY_3D | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"inter_unique(A,B)", 0, "Premiere intersection. Utiliser inter pour une liste d'intersections.", "line(y=x),line(x+y=3)", 0, CAT_CATEGORY_3D | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"inv(A)", 0, "Inverse de A.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX|(CAT_CATEGORY_LINALG<<8)}, - {"inverser(v)", "inverser ", "La variable v est remplacee par son inverse", "#v:=3; inverser v", 0, CAT_CATEGORY_SOFUS | XCAS_ONLY}, - {"iquo(a,b)", 0, "Quotient euclidien de deux entiers.", "23,13", 0, CAT_CATEGORY_ARIT | XCAS_ONLY}, - {"irem(a,b)", 0,"Reste euclidien de deux entiers", "23,13", 0, CAT_CATEGORY_ARIT | XCAS_ONLY}, - {"isprime(n)", 0, "Renvoie 1 si n est premier, 0 sinon.", "11", "10", CAT_CATEGORY_ARIT}, - {"jordan(A)", 0, "Forme normale de Jordan de la matrice A, renvoie P et D tels que P^-1*A*P=D", "[[1,2],[3,4]]", "[[1,1,-1,2,-1],[2,0,1,-4,-1],[0,1,1,1,1],[0,1,2,0,1],[0,0,-3,3,-1]]", CAT_CATEGORY_MATRIX | XCAS_ONLY}, - {"laguerre(n,a,x)", 0, "n-ieme polynome de Laguerre (a=0 par defaut).", "10", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"laplace(f,x,s)", 0, "Transformee de Laplace de f","sin(x),x,s", 0, CAT_CATEGORY_CALCULUS | XCAS_ONLY}, - {"lcm(a,b,...)", 0, "Plus petit commun multiple.", "23,13", "x^2-1,x^3-1", CAT_CATEGORY_ARIT | (CAT_CATEGORY_POLYNOMIAL << 8) | XCAS_ONLY}, - {"lcoeff(p,x)", 0, "Coefficient dominant du polynome p.", "x^4-1", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"legendre(n)", 0, "n-ieme polynome de Legendre.", "10", "10,t", CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, -#ifdef RELEASE - {"len(l)", 0, "Taille d'une liste.", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_LIST}, -#endif - {"leve_crayon ", "leve_crayon ", "La tortue se deplace sans marquer son passage", 0, 0, CAT_CATEGORY_LOGO}, - {"limit(f,x=a)", 0, "Limite de f en x = a. Ajouter 1 ou -1 pour une limite a droite ou a gauche, limit(sin(x)/x,x=0) ou limit(abs(x)/x,x=0,1). Raccourci: SHIFT MIXEDFRAC", "sin(x)/x,x=0", "exp(-1/x),x=0,1", CAT_CATEGORY_CALCULUS | XCAS_ONLY}, - {"droite(A,B)", 0, "Droite donnee par equation ou 2 points", "y=x-1", "[0,0,0],[1,-2,3]", CAT_CATEGORY_2D | XCAS_ONLY}, - {"line_width_", "line_width_", "Prefixe d'epaisseur (2 a 8)", 0, 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"linear_regression(Xlist,Ylist)", 0, "Regression lineaire.", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"linear_regression_plot(Xlist,Ylist)", 0, "Graphe d'une regression lineaire.", "#X,Y:=[1,2,3,4,5],[0,1,3,4,4];linear_regression_plot(X,Y);", 0, CAT_CATEGORY_STATS | (CAT_CATEGORY_PLOT<<8)}, - {"linetan(expr,x,x0)", 0, "Tangente au graphe en x=x0.", "sin(x),x,pi/2", 0, CAT_CATEGORY_PLOT | XCAS_ONLY}, - {"linsolve([eq1,eq2,..],[x,y,..])", 0, "Resolution de systeme lineaire. Peut utiliser le resultat de lu pour resolution en O(n^2).","[x+y=1,x-y=2],[x,y]", "#p,l,u:=lu([[1,2],[3,4]]); linsolve(p,l,u,[5,6])", CAT_CATEGORY_SOLVE | (CAT_CATEGORY_LINALG <<8) | (CAT_CATEGORY_MATRIX << 16) | XCAS_ONLY}, - {"logarithmic_regression(Xlist,Ylist)", 0, "Regression logarithmique.", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"logarithmic_regression_plot(Xlist,Ylist)", 0, "Graphe d'une regression logarithmique.", "#X,Y:=[1,2,3,4,5],[0,1,3,4,4];logarithmic_regression_plot(X,Y);", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"lu(A)", 0, "decomposition LU de la matrice A, P*A=L*U, renvoie P permutation, L et U triangulaires inferieure et superieure", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX | XCAS_ONLY}, - {"magenta", "magenta", "Option d'affichage", "#display=magenta", 0, CAT_CATEGORY_PROGCMD}, - {"map(f,l)", 0, "Applique f aux elements de la liste l.","lambda x:x*x,[1,2,3]", 0, CAT_CATEGORY_LIST}, - {"matpow(A,n)", 0, "Renvoie A^n, la matrice A la puissance n", "[[1,2],[3,4]],n","#assume(n>=1);matpow([[0,2],[0,4]],n)", CAT_CATEGORY_MATRIX | XCAS_ONLY}, - {"matrix(l,c,func)", 0, "Matrice de terme general donne.", "2,3,(j,k)->j^k", 0, CAT_CATEGORY_MATRIX}, - {"mean(l)", 0, "Moyenne arithmetique liste l", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"median(l)", 0, "Mediane", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"mediane(A,B,C)", 0, "Mediane du triangle ABC issue de A", "1,i,2+i", 0,CAT_CATEGORY_2D}, - {"mediatrice(A,B)", 0, "Mediatrice du segment AB", "1,i", 0,CAT_CATEGORY_2D}, - {"milieu(A,B)", 0, "Milieu de AB", "1,i", 0,CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8)}, - {"montre_tortue ", "montre_tortue ", "Affiche la tortue", 0, 0, CAT_CATEGORY_LOGO}, - {"mul(A,B)", 0, "En Python, multiplie des listes de listes u et v comme des matrices.","[[1,2],[3,4]],[5,6]", "[[1,2],[3,4]].[[5,6],[7,8]]", CAT_CATEGORY_LINALG}, - {"mult_c_conjugate", 0, "Multiplier par le conjugue complexe.", "1+2*i", 0, (CAT_CATEGORY_COMPLEXNUM << 8) | XCAS_ONLY}, - {"mult_conjugate", 0, "Multiplier par le conjugue (sqrt).", "sqrt(2)-sqrt(3)", 0, CAT_CATEGORY_ALGEBRA | XCAS_ONLY}, - {"normald([mu,sigma],x)", 0, "Loi normale, par defaut mu=0 et sigma=1. normald_cdf([mu,sigma],x) probabilite que \"loi normale <=x\" par ex. normald_cdf(1.96). normald_icdf([mu,sigma],t) renvoie x tel que \"loi normale <=x\" vaut t, par ex. normald_icdf(0.975) ", "1.2", 0, CAT_CATEGORY_PROBA | XCAS_ONLY}, - {"not(x)", 0, "Non logique.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"numer(x)", 0, "Numerateur de x.", "3/4", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"octahedron(A,B,C)", 0, "Octaedre d'arete AB avec une face dans le plan ABC", "[0,0,0],[3,0,0],[0,1,0]", 0, CAT_CATEGORY_3D}, - {"odesolve(f(t,y),[t,y],[t0,y0],t1)", 0, "Solution approchee d'equation differentielle y'=f(t,y) et y(t0)=y0, valeur en t1 (ajouter curve pour les valeurs intermediaires de y)", "sin(t*y),[t,y],[0,1],2", "0..pi,(t,v)->{[-v[1],v[0]]},[0,1]", CAT_CATEGORY_SOLVE | XCAS_ONLY}, - {"parabole(F,A)", 0, "Parabole donnee par foyer et sommet", "-2-i,2+i", 0, CAT_CATEGORY_2D}, - {"parameq(objet)", 0, "Equations parametriques. Utiliser equation pour une equation cartesienne", "circle(0,1)", "ellipse(-1,1,3)", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"partfrac(p,x)", 0, "Decomposition en elements simples. Raccourci p=>+", "1/(x^4-1)", 0, CAT_CATEGORY_ALGEBRA | XCAS_ONLY}, - {"pas_de_cote n", "pas_de_cote ", "Saut lateral de la tortue, par defaut n=10", "#pas_de_cote 30", 0, CAT_CATEGORY_LOGO}, - {"plan(equation)", 0, "Plan donne par equation ou 3 points", "z=x+y-1", "[0,0,0],[1,0,0],[0,1,0]", CAT_CATEGORY_3D | XCAS_ONLY}, - {"plot(expr,x)", 0, "Xcas: graphe de fonction, par exemple plot(sin(x)), plot(ln(x),x.0,5), plot(x^2-y^2), plot(x^2-y^2<1), plot(x^2-y^2=1). Python et Xcas: plot(Xlist,Ylist) ligne polygonale", "[1,2,3,4,5,6],[2,3,5,2,1,4]","ln(x),x=0..5,xstep=0.1", CAT_CATEGORY_PLOT }, - {"plotfunc(expr,[x,y])", 0, "Xcas: graphe de fonction 3d", "x^2-y^2,[x,y]","x^2-y^2,[x=-2..2,y=-2..2],nstep=700", CAT_CATEGORY_PLOT | (CAT_CATEGORY_3D << 8) | XCAS_ONLY }, - {"plotarea(expr,x=a..b,[n,meth])", 0, "Aire sous la courbe selon une methode d'integration.", "1/x,x=1..5,4,rectangle_gauche", 0, CAT_CATEGORY_PLOT | XCAS_ONLY}, - {"plotcontour(expr,[x=xm..xM,y=ym..yM],niveaux)", 0, "Lignes de niveau de expr.", "x^2+2y^2, [x=-2..2,y=-2..2],[1,2]", 0, CAT_CATEGORY_PLOT | XCAS_ONLY}, - {"plotdensity(expr,[x=xm..xM,y=ym..yM])", 0, "Representation en niveaux de couleurs d'une expression de 2 variables.", "x^2-y^2,[x=-3..3,y=-2..2]", 0, CAT_CATEGORY_PLOT | XCAS_ONLY}, - {"plotfield(f(t,y), [t=tmin..tmax,y=ymin..ymax])", 0, "Champ des tangentes de y'=f(t,y), optionnellement graphe avec plotode=[t0,y0]", "sin(t*y), [t=-3..3,y=-3..3],plotode=[0,1]", "5*[-y,x], [x=-1..1,y=-1..1]", CAT_CATEGORY_PLOT | XCAS_ONLY}, - {"plotlist(list)", 0, "Graphe d'une liste", "[3/2,2,1,1/2,3,2,3/2]", "[1,13],[2,10],[3,15],[4,16]", CAT_CATEGORY_PLOT | XCAS_ONLY}, - {"plotode(f(t,y), [t=tmin..tmax,y],[t0,y0])", 0, "Graphe de solution d'equation differentielle y'=f(t,y), y(t0)=y0.", "sin(t*y),[t=-3..3,y],[0,1]", 0, CAT_CATEGORY_PLOT | XCAS_ONLY}, - {"plotparam([x,y],t)", 0, "Graphe en parametriques. Par exemple plotparam([sin(3t),cos(2t)],t,0,pi) ou plotparam(exp(i*t),t,0,pi)", "[sin(3t),cos(2t)],t,0,pi", "[t^2,t^3],t=-1..1,tstep=0.1", CAT_CATEGORY_PLOT | (CAT_CATEGORY_3D << 8) | XCAS_ONLY}, - {"plotpolar(r,theta)", 0, "Graphe en polaire.","cos(3*x),x,0,pi", "1/(1+cos(x)),x=0..pi,xstep=0.05", CAT_CATEGORY_PLOT | XCAS_ONLY}, - {"plotseq(f(x),x=[u0,m,M],n)", 0, "Trace f(x) sur [m,M] et n termes de la suite recurrente u_{n+1}=f(u_n) de 1er terme u0.","sqrt(2+x),x=[6,0,7],5", 0, CAT_CATEGORY_PLOT | XCAS_ONLY}, - {"plus_point", "plus_point", "Option d'affichage", "#display=blue+plus_point", 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"point(x,y[,z])", 0, "Point", "1,2", "1,2,3", CAT_CATEGORY_PLOT | (CAT_CATEGORY_2D << 8) | (CAT_CATEGORY_3D << 16) | XCAS_ONLY}, - {"polygone(list)", 0, "Polygone ferme donne par la liste de ses sommets.", "1-i,2+i,3,3-2i", 0, CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"polygonscatterplot(Xlist,Ylist)", 0, "Nuage de points relies.", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"polyhedron(A,B,C,D,...)", 0, "Polyedre convexe dont les sommets sont parmi A,B,C,D,...", "[0,0,0],[0,5,0],[0,0,5],[1,2,6]", 0, CAT_CATEGORY_3D}, - {"polynomial_regression(Xlist,Ylist,n)", 0, "Regression polynomiale de degre <= n.", "[1,2,3,4,5],[0,1,3,4,4],2", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"polynomial_regression_plot(Xlist,Ylist,n)", 0, "Graphe d'une regression polynomiale de degre <= n.", "#X,Y:=[1,2,3,4,5],[0,1,3,4,4];polynomial_regression_plot(X,Y,2);scatterplot(X,Y);", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"pour (boucle Xcas)", "pour de to faire fpour;", "Boucle definie.","#pour j de 1 to 10 faire print(j,j^2); fpour;", 0, CAT_CATEGORY_PROG | XCAS_ONLY}, - {"power_regression(Xlist,Ylist,n)", 0, "Regression puissance.", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"power_regression_plot(Xlist,Ylist,n)", 0, "Graphe d'une regression puissance.", "#X,Y:=[1,2,3,4,5],[1,1,3,4,4];power_regression_plot(X,Y);", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"pow(a,n,p)", 0, "Renvoie a^n mod p","123,456,789", 0, CAT_CATEGORY_ARIT}, - {"powmod(a,n,p[,P,x])", 0, "Renvoie a^n mod p, ou a^n mod un entier p et un polynome P en x.","123,456,789", "x+1,452,19,x^4+x+1,x", CAT_CATEGORY_ARIT | XCAS_ONLY}, - {"print(expr)", 0, "Afficher dans la console", 0, 0, CAT_CATEGORY_PROG}, - {"projection(obj1,obj2)", 0, "Projection sur obj1 de obj2", "line(y=x),point(2,3)", 0, CAT_CATEGORY_2D }, - {"pcoeff(p)", 0, "Polynome unitaire dont on donne la liste des racines (fonction reciproque de proot)", "[1,2,3]", 0, CAT_CATEGORY_POLYNOMIAL}, - {"peval(p,x)", 0, "Valeur d'un polynome en un point", "[1,2,3],4", 0, CAT_CATEGORY_POLYNOMIAL}, - {"proot(p)", 0, "Racines reelles et complexes approchees d'un polynome. Exemple proot([1,2.1,3,4.2]) ou proot(x^3+2.1*x^2+3x+4.2)", "[1.,2.1,3,4.2]","x^3+2.1*x^2+3x+4.2", CAT_CATEGORY_POLYNOMIAL|(CAT_CATEGORY_SOLVE<<8)}, - {"purge(x)", 0, "Purge le contenu de la variable x. Raccourci SHIFT-FORMAT", 0, 0, CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_SOFUS<<8) | XCAS_ONLY}, - {"pyramid(A,B,C)", 0, "Tetraedre d'arete AB avec une face dans le plan ABC", "[0,0,0],[3,0,0],[0,1,0]", "[0,0,0],[3,0,0],[0,3,0],[0,0,4]", CAT_CATEGORY_3D}, - {"python(f)", 0, "Affiche la fonction f en syntaxe Python.", 0, 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"python_compat(0|1|2|4)", 0, "python_compat(0) syntaxe Xcas, python_compat(1) syntaxe Python avec ^ interprete comme puissance, python_compat(2) ^ interprete comme ou exclusif bit a bit", "0", "1", CAT_CATEGORY_PROG | XCAS_ONLY}, - {"qr(A)", 0, "Factorisation A=Q*R avec Q orthogonale et R triangulaire superieure", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX | XCAS_ONLY}, - {"quadric(equation)", 0, "Quadrique donnee par une equation (ou 9 points)", "x^2-y^2+z^2", "x^2+x*y+y^2+z^2-3", CAT_CATEGORY_3D}, - {"quartile1(l)", 0, "1er quartile", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"quartile3(l)", 0, "3eme quartile", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"quo(p,q,x)", 0, "Quotient de division euclidienne polynomiale en x.", 0, 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"quote(x)", 0, "Renvoie l'expression x non evaluee.", 0, 0, CAT_CATEGORY_ALGEBRA | XCAS_ONLY}, - {"rayon(objet)", 0, "Rayon d'un cercle ou d'une sphere", "circle(0,1)", "sphere([0,0,0],[1,1,1])", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"rand()", "rand()", "Reel aleatoire entre 0 et 1", 0, 0, CAT_CATEGORY_PROBA}, - {"randint(a,b)", 0, "Entier aleatoire entre a et b. En Xcas, avec un seul argument n, entier entre 1 et n.", "5,20", "6", CAT_CATEGORY_PROBA}, - {"ranm(n,m,[loi,parametres])", 0, "Matrice aleatoire a coefficients entiers ou selon une loi de probabilites (ranv pour un vecteur). Exemples ranm(2,3), ranm(3,2,binomial,20,.3), ranm(4,2,normald,0,1)", "3,3","4,2,normald,0,1", CAT_CATEGORY_MATRIX}, - {"ranv(n,[loi,parametres])", 0, "Vecteur aleatoire", "4,normald,0,1", "10,30", CAT_CATEGORY_LINALG}, - {"ratnormal(x)", 0, "Ecrit sous forme d'une fraction irreductible.", "(x+1)/(x^2-1)^2", 0, CAT_CATEGORY_ALGEBRA | XCAS_ONLY}, - {"re(z)", 0, "Partie reelle (z.re en Python)", "1+i", 0, CAT_CATEGORY_COMPLEXNUM}, - {"read(\"filename\")", "read(\"", "Lire un fichier. Voir aussi write", 0, 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"rectangle_plein a,b", "rectangle_plein ", "Rectangle direct rempli depuis la tortue de cotes a et b (si b est omis, la tortue remplit un carre)", "#rectangle_plein 30", "#rectangle_plein(20,40)", CAT_CATEGORY_LOGO | XCAS_ONLY}, - {"recule n", "recule ", "La tortue recule de n pas, par defaut n=10", "#recule 30", 0, CAT_CATEGORY_LOGO}, - {"red", "red", "Option d'affichage", "#display=red", 0, CAT_CATEGORY_PROGCMD}, - {"reflection(obj1,obj2)", 0, "Symetrique de obj2", "line(y=x),cercle(1,1)", 0, CAT_CATEGORY_2D }, - {"rem(p,q,x)", 0, "Reste de division euclidienne polynomiale en x", 0, 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"repete(n,...)", "repete( ", "Repete plusieurs fois les instructions", "#repete(4,avance,tourne_gauche)", 0, CAT_CATEGORY_LOGO | XCAS_ONLY}, -#ifdef RELEASE - {"residue(f(z),z,z0)", 0, "Residu de l'expression en z0.", "1/(x^2+1),x,i", 0, CAT_CATEGORY_COMPLEXNUM | XCAS_ONLY}, -#endif - {"resultant(p,q,x)", 0, "Resultant en x des polynomes p et q.", "#P:=x^3+p*x+q;resultant(P,P',x);", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"revert(p[,x])", 0, "Developpement de Taylor reciproque, p doit etre nul en 0","x+x^2+x^4", 0, CAT_CATEGORY_CALCULUS | XCAS_ONLY}, - {"rgb(r,g,b)", 0, "couleur definie par niveau de rouge, vert, bleu entre 0 et 255", "255,0,255", 0, CAT_CATEGORY_PROGCMD}, - {"rhombus_point", "rhombus_point", "Option d'affichage", "#display=magenta+rhombus_point", 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"rond n", "rond ", "Cercle tangent a la tortue de rayon n. Utiliser rond n,theta pour un arc de cercle.", "#rond 30", "#rond(30,90)", CAT_CATEGORY_LOGO}, - {"rotation(centre,angle,objet)", 0, "Image de l'objet par la rotation de centre et angle donnes en argyment", "2-i,pi/2,circle(0,1)", "sphere([0,0,0],[1,1,1])", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"rref(M)","rref","Reduction d'une matrice par le pivot de Gauss.","[[1,2,3],[4,5,6]]",0,CAT_CATEGORY_MATRIX|(CAT_CATEGORY_LINALG<<8)}, - {"rsolve(equation,u(n),[init])", 0, "Expression d'une suite donnee par une recurrence.","u(n+1)=2*u(n)+3,u(n),u(0)=1", "([u(n+1)=3*v(n)+u(n),v(n+1)=v(n)+u(n)],[u(n),v(n)],[u(0)=1,v(0)=2]", CAT_CATEGORY_SOLVE | XCAS_ONLY}, - {"saute n", "saute ", "La tortue fait un saut de n pas, par defaut n=10", "#saute 30", 0, CAT_CATEGORY_LOGO}, - {"scatterplot(Xlist,Ylist)", 0, "Nuage de points (scatter en Python)", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS| (CAT_CATEGORY_PLOT<<8)}, - {"segment(A,B)", 0, "Segment", "1,2+i", "[1,2,1],[-1,3,2]", CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"seq(expr,var,a,b[,pas])", 0, "Liste de terme general donne.","j^2,j,1,10", "j^2,j,1,10,2", CAT_CATEGORY_LIST | XCAS_ONLY}, - {"si (test Xcas)", "si alors sinon fsi;", "Test.", "#f(x):=si x>0 alors x; sinon -x; fsi;", 0, CAT_CATEGORY_PROG | XCAS_ONLY}, - {"sign(x)", 0, "Renvoie -1 si x est negatif, 0 si x est nul et 1 si x est positif.", 0, 0, CAT_CATEGORY_REAL | XCAS_ONLY}, - {"similitude(centre,rapport,angle,objet)", 0, "Image de l'objet par similitude", "0,2,pi/2,circle(1,1)", 0, CAT_CATEGORY_2D }, - {"simplify(expr)", 0, "Renvoie en general expr sous forme simplifiee. Raccourci expr=>/", "sin(3x)/sin(x)", "ln(4)-ln(2)", CAT_CATEGORY_ALGEBRA | XCAS_ONLY}, - {"sin_regression(Xlist,Ylist)", 0, "Regression trigonometrique.", "[1,2,3,4,5,6,7,8,9,10,11,12,13,14],[0.1,0.5,0.8,1,0.7,0.5,0.05,-.5,-.75,-1,-.7,-.4,0.1,.5]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"sin_regression_plot(Xlist,Ylist)", 0, "Graphe d'une regression trigonometrique.", "#X,Y:=[1,2,3,4,5,6,7,8,9,10,11,12,13,14],[0.1,0.5,0.8,1,0.7,0.5,0.05,-.5,-.75,-1,-.7,-.4,0.1,.5];sin_regression_plot(X,Y);", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"solve()", 0, "Xcas: solve(equation,x) resolution exacte d'une equation en x (ou d'un systeme polynomial). Utiliser csolve pour les solutions complexes, linsolve pour un systeme lineaire. Python et Xcas: solve(A,b) resolution d'un systeme de Cramer A*x=b", "x^2-x-1=0,x", "[x^2-y^2=0,x^2-z^2=0],[x,y,z]", CAT_CATEGORY_SOLVE}, - {"sommets(objet)", 0, "Liste des sommets d'un polygone ou polyedre", "triangle(1,i,2)", "cube([0,0,0],[1,0,0],[0,1,0])", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"sorted(l)", 0, "Trie une liste.","[3/2,2,1,1/2,3,2,3/2]", "[[1,2],[2,3],[4,3]],(x,y)->when(x[1]==y[1],x[0]>y[0],x[1]>y[1]", CAT_CATEGORY_LIST}, - {"sphere(A,r)", 0, "Sphere de centre A et rayon r ou de diametre AB", "[0,0,0],1", "[0,0,0],[1,1,1]", CAT_CATEGORY_3D}, - {"square_point", "square_point", "Option d'affichage", "#display=cyan+square_point", 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY }, - {"star_point", "star_point", "Option d'affichage", "#display=magenta+star_point", 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"stddev(l)", 0, "Ecart-type d'une liste l", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS | XCAS_ONLY}, - {"sub(u,v)", 0, "En Python, soustrait des listes ou listes de listes u et v comme des vecteurs ou matrices.","[1,2,3],[0,1,3]", "[[1,2]],[[3,4]]", CAT_CATEGORY_LINALG}, - {"subst(a,b=c)", 0, "Remplace b par c dans a. Raccourci a(b=c). Pour faire plusieurs remplacements, saisir subst(expr,[b1,b2...],[c1,c2...])", "x^2,x=3", "x+y^2,[x,y],[1,2]", CAT_CATEGORY_ALGEBRA | XCAS_ONLY}, - {"sum(f,k,m,M)", 0, "Somme de l'expression f dependant de k pour k variant de m a M. Exemple sum(k^2,k,1,n)=>*. Raccourci ALPHA F3", "k,k,1,n", "k^2,k", CAT_CATEGORY_CALCULUS | XCAS_ONLY}, - {"svd(A)", 0, "Singular Value Decomposition, renvoie U orthogonale, S vecteur des valeurs singulières, Q orthogonale tels que A=U*diag(S)*tran(Q).", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX | XCAS_ONLY}, - {"tabvar(f,[x=a..b])", 0, "Tableau de variations de l'expression f, avec arguments optionnels la variable x dans l'intervalle a..b.", "sqrt(x^2+x+1)", "[cos(2t),sin(3t)],t", CAT_CATEGORY_CALCULUS | XCAS_ONLY}, - {"tantque (boucle Xcas)", "tantque faire ftantque;", "Boucle indefinie.", "#j:=13; tantque j!=1 faire j:=ifte(even(j),j/2,3j+1); print(j); ftantque;", 0, CAT_CATEGORY_PROG | XCAS_ONLY}, - {"taylor(f,x=a,n,[polynom])", 0, "Developpement de Taylor de l'expression f en x=a a l'ordre n, ajouter le parametre polynom pour enlever le terme de reste.","sin(x),x=0,5", "sin(x),x=0,5,polynom", CAT_CATEGORY_CALCULUS | XCAS_ONLY}, - {"tchebyshev1(n)", 0, "Polynome de Tchebyshev de 1ere espece: cos(n*x)=T_n(cos(x))", "10", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"tchebyshev2(n)", 0, "Polynome de Tchebyshev de 2eme espece: sin((n+1)*x)=sin(x)*U_n(cos(x))", "10", 0, CAT_CATEGORY_POLYNOMIAL | XCAS_ONLY}, - {"tcollect(expr)", 0, "Linearisation trigonometrique et regroupement.","sin(x)+cos(x)", 0, CAT_CATEGORY_TRIG | XCAS_ONLY}, - {"texpand(expr)", 0, "Developpe les fonctions trigonometriques, exp et ln.","sin(3x)", "ln(x*y)", CAT_CATEGORY_TRIG | XCAS_ONLY}, - {"time(cmd)", 0, "Temps pour effectuer une commande ou mise a l'heure de horloge","int(1/(x^4+1),x)","8,0", CAT_CATEGORY_PROG}, - {"tlin(expr)", 0, "Linearisation trigonometrique de l'expression.","sin(x)^3", 0, CAT_CATEGORY_TRIG | XCAS_ONLY}, - {"tourne_droite n", "tourne_droite ", "La tortue tourne de n degres, par defaut n=90", "#tourne_droite 45", 0, CAT_CATEGORY_LOGO}, - {"tourne_gauche n", "tourne_gauche ", "La tortue tourne de n degres, par defaut n=90", "#tourne_gauche 45", 0, CAT_CATEGORY_LOGO}, - {"trace(A)", 0, "Trace de la matrice A.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"transpose(A)", 0, "Transposee de la matrice A. Pour la transconjuguee utiliser trn(A) ou A^*.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"translation(vect,obj)", 0, "Translation par vect de obj", "[1,2],cercle(0,1)", 0, CAT_CATEGORY_2D }, - {"triangle(A,B,C)", 0, "Triangle donne par 3 sommets", "1+i,1-i,-1", "A,B,C", CAT_CATEGORY_2D}, - {"triangle_point", "triangle_point", "Option d'affichage", "#display=yellow+triangle_point", 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"trig2exp(expr)", 0, "Convertit les fonctions trigonometriques en exponentielles.","cos(x)^3", 0, CAT_CATEGORY_TRIG | XCAS_ONLY}, - {"trigcos(expr)", 0, "Exprime sin^2 et tan^2 avec cos^2.","sin(x)^4", 0, CAT_CATEGORY_TRIG | XCAS_ONLY}, - {"trigsin(expr)", 0, "Exprime cos^2 et tan^2 avec sin^2.","cos(x)^4", 0, CAT_CATEGORY_TRIG | XCAS_ONLY}, - {"trigtan(expr)", 0, "Exprime cos^2 et sin^2 avec tan^2.","cos(x)^4", 0, CAT_CATEGORY_TRIG | XCAS_ONLY}, - {"uniformd(a,b,x)", 0, "loi uniforme sur [a,b] de densite 1/(b-a)", 0, 0, CAT_CATEGORY_PROBA | XCAS_ONLY}, - {"v augmente_de n", " augmente_de ", "La variable v augmente de n, ou de n %", "#v:=3; v augmente_de 1", 0, CAT_CATEGORY_SOFUS | XCAS_ONLY}, - {"v diminue_de n", " diminue_de ", "La variable v diminue de n, ou de n %", "#v:=3; v diminue_de 1", 0, CAT_CATEGORY_SOFUS | XCAS_ONLY}, - {"v est_divise_par n", " est_divise_par ", "La variable v est divisee par n", "#v:=3; v est_divise_par 2", 0, CAT_CATEGORY_SOFUS | XCAS_ONLY}, - {"v est_eleve_puissance n", " est_eleve_puissance ", "La variable v est eleveee a la puissance n", "#v:=3; v est_eleve_puissance 2", 0, CAT_CATEGORY_SOFUS | XCAS_ONLY}, - {"v est_multiplie_par n", " est_multiplie_par ", "La variable v est multipliee par n", "#v:=3; v est_multiplie_par 2", 0, CAT_CATEGORY_SOFUS | XCAS_ONLY}, - {"vector(A,B)", 0, "vecteur AB", 0, 0, CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8)}, - {"volume(P)", 0, "volume d'un polyedre ou d'une sphere", 0, 0, (CAT_CATEGORY_3D )}, - //{"version", "version()", "Khicas 1.5.0, (c) B. Parisse et al. www-fourier.ujf-grenoble.fr/~parisse. License GPL version 2. Interface adaptee d'Eigenmath pour Casio, G. Maia, http://gbl08ma.com", 0, 0, CAT_CATEGORY_PROGCMD}, - {"write(\"filename\",var)", "write(\"", "Sauvegarde une ou plusieurs variables dans un fichier. Par exemple f(x):=x^2; write(\"func_f\",f).", 0, 0, CAT_CATEGORY_PROGCMD | XCAS_ONLY}, - {"yellow", "yellow", "Option d'affichage", "#display=yellow", 0, CAT_CATEGORY_PROGCMD}, - {"|", "|", "Ou logique", "#1|2", 0, CAT_CATEGORY_PROGCMD}, - {"~", "~", "Complement", "#~7", 0, CAT_CATEGORY_PROGCMD}, - }; - -const catalogFunc completeCaten[] = { // list of all functions (including some not in any category) - {" loop for", "for ", "Defined loop.", "#\nfor ", 0, CAT_CATEGORY_PROG}, - {" loop in list", "for in", "Loop on all elements of a list.", "#\nfor in", 0, CAT_CATEGORY_PROG}, - {" loop while", "while ", "Undefined loop.", "#\nwhile ", 0, CAT_CATEGORY_PROG}, - {" test if", "if ", "Test", "#\nif ", 0, CAT_CATEGORY_PROG}, - {" test else", "else ", "Test false case", 0, 0, CAT_CATEGORY_PROG}, - {" function def", "f(x):=", "Definition of function.", "#\nf(x):=", 0, CAT_CATEGORY_PROG}, - {" local j,k;", "local ", "Local variables declaration (Xcas)", 0, 0, CAT_CATEGORY_PROG}, - {" range(a,b)", 0, "In range [a,b) (a included, b excluded)", "# in range(1,10)", 0, CAT_CATEGORY_PROG}, - {" return res", "return ", "Leaves current function and returns res.", 0, 0, CAT_CATEGORY_PROG}, - {" edit list ", "list ", "List creation wizzard.", 0, 0, CAT_CATEGORY_LIST}, - {" edit matrix ", "matrix ", "Matrix creation wizzard.", 0, 0, CAT_CATEGORY_MATRIX}, - {" mksa(x)", 0, "Conversion to MKSA units", 0, 0, CAT_CATEGORY_PHYS | (CAT_CATEGORY_UNIT << 8) | XCAS_ONLY}, - {" ufactor(a,b)", 0, "Factorize unit b in a", "100_J,1_kW", 0, CAT_CATEGORY_PHYS | (CAT_CATEGORY_UNIT << 8) | XCAS_ONLY}, - {" usimplify(a)", 0, "Simplify unit", "100_l/10_cm^2", 0, CAT_CATEGORY_PHYS | (CAT_CATEGORY_UNIT << 8) | XCAS_ONLY}, - {"!", "!", "Logical not (prefix) or factorial of n (suffix).", "#7!", "~!b", CAT_CATEGORY_PROGCMD}, - {"#", "#", "Python comment, for Xcas comment type //. Shortcut ALPHA F2", 0, 0, CAT_CATEGORY_PROG}, - {"%", "%", "a % b means a modulo b", 0, 0, CAT_CATEGORY_ARIT | (CAT_CATEGORY_PROGCMD << 8)}, - {"&", "&", "Logical and or +", "#1&2", 0, CAT_CATEGORY_PROGCMD}, - {":=", ":=", "Set variable value. Shortcut SHIFT F1", "#a:=3", 0, CAT_CATEGORY_PROGCMD|(CAT_CATEGORY_SOFUS<<8)|XCAS_ONLY}, - {"<", "<", "Shortcut SHIFT F2", 0, 0, CAT_CATEGORY_PROGCMD}, - {"=>", "=>", "Store value in variable or conversion (touche ->). For example 5=>a or x^4-1=>* or (x+1)^2=>+ or sin(x)^2=>cos.", "#5=>a", "#15_ft=>_cm", CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_PHYS <<8) | (CAT_CATEGORY_UNIT << 16) | XCAS_ONLY}, - {">", ">", "Shortcut F2.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"\\", "\\", "\\ char", 0, 0, CAT_CATEGORY_PROGCMD}, - {"_", "_", "_ char, shortcut (-).", 0, 0, CAT_CATEGORY_PROGCMD}, - {"_(km/h)", "_(km/h)", "Speed kilometer per hour", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_(m/s)", "_(m/s)", "Speed meter/second", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_(m/s^2)", "_(m/s^2)", "Acceleration", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_(m^2/s)", "_(m^2/s)", "Viscosity", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_A", 0, "Ampere", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Bq", 0, "Becquerel", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_C", 0, "Coulomb", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Ci", 0, "Curie", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_F", 0, "Farad", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_F_", 0, "Faraday constant", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_G_", 0, "Gravitation force=_G_*m1*m2/r^2", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_H", 0, "Henry", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Hz", 0, "Hertz", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_J", 0, "Joule=kg*m^2/s^2", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_K", 0, "Temperature in Kelvin", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Kcal", 0, "Energy kilo-calorie", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_MeV", 0, "Energy mega-electron-Volt", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_N", 0, "Force Newton=kg*m/s^2", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_NA_", 0, "Avogadro constant", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_Ohm", 0, "Ohm", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_PSun_", 0, "Sun power", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_Pa", 0, "Pressure in Pascal=kg/m/s^2", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_REarth_", 0, "Earth radius", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_RSun_", 0, "Sun radius", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_R_", 0, "Boltzmann constant (per mol)", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_S", 0, "", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_StdP_", 0, "Standard pressure", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_StdT_", 0, "Standard temperature (0 degre Celsius in Kelvins)", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_Sv", 0, "Sievert", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_T", 0, "Tesla", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_V", 0, "Volt", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Vm_", 0, "Volume molaire", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_W", 0, "Watt=kg*m^2/s^3", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_Wb", 0, "Weber", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_alpha_", 0, "fine structure constant", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_c_", 0, "speed of light", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_cd", 0, "candela", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_cdf", "_cdf", "Suffix to get a cumulative distribution function. Type F2 for inverse cumulative distribution function _icdf suffix.", "#_icdf", 0, CAT_CATEGORY_PROBA|XCAS_ONLY}, - {"_d", 0, "day", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_deg", 0, "degree", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_eV", 0, "electron-Volt", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_epsilon0_", 0, "vacuum permittivity", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_ft", 0, "feet", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_g_", 0, "Earth gravity (ground)", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_grad", 0, "grades (angle unit(", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_h", 0, "Hour", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_h_", 0, "Planck constant", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_ha", 0, "hectare", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_hbar_", 0, "Planck constant/(2*pi)", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_inch", 0, "inches", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_kWh", 0, "kWh", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_k_", 0, "Boltzmann constant", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_kg", 0, "kilogram", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_l", 0, "liter", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_m", 0, "meter", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_mEarth_", 0, "Earth mass", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_m^2", 0, "Area in m^2", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_m^3", 0, "Volume in m^3", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_me_", 0, "electron mass", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_miUS", 0, "US miles", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_mn", 0, "minute", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_mp_", 0, "proton mass", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_mpme_", 0, "proton/electron mass-ratio", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_mu0_", 0, "", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_phi_", 0, "magnetic flux quantum", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_plot", "_plot", "Suffix for a regression graph.", "#X,Y:=[1,2,3,4,5],[0,1,3,4,4];polynomial_regression_plot(X,Y,2);scatterplot(X,Y)", 0, CAT_CATEGORY_STATS}, - {"_qe_", 0, "electron charge", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_qme_", 0, "_q_/_me_", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_rad", 0, "radians", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_rem", 0, "rem", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_s", 0, "second", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_sd_", 0, "Sideral day", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_syr_", 0, "Siderale year", 0, 0, CAT_CATEGORY_PHYS | XCAS_ONLY}, - {"_tr", 0, "tour (angle unit)", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"_yd", 0, "yards", 0, 0, CAT_CATEGORY_UNIT | XCAS_ONLY}, - {"a and b", " and ", "Logical and", 0, 0, CAT_CATEGORY_PROGCMD}, - {"a or b", " or ", "Logical or", 0, 0, CAT_CATEGORY_PROGCMD}, - {"abcuv(a,b,c)", 0, "Find 2 polynomial u,v such that a*u+b*v=c","x+1,x^2-2,x", 0, CAT_CATEGORY_POLYNOMIAL}, - {"abs(x)", 0, "Absolute value or norm of x x", "-3", "[1,2,3]", CAT_CATEGORY_COMPLEXNUM | (CAT_CATEGORY_REAL<<8)}, - {"altitude(A,B,C)", 0, "Altitude in triangle ABC from A", "1,i,2+i", 0,CAT_CATEGORY_2D}, - {"append", 0, "Adds an element at the end of a list","#l.append(x)", 0, CAT_CATEGORY_LIST}, - {"approx(x)", 0, "Approx. value x. Shortcut S-D", "pi", 0, CAT_CATEGORY_REAL}, - {"area(objet)", 0, "Algebric area", "circle(0,1)", "triangle(-1,1+i,3)", CAT_CATEGORY_2D }, - {"arg(z)", 0, "Angle of complex z.", "1+i", 0, CAT_CATEGORY_COMPLEXNUM}, - {"asc(string)", 0, "List of ASCII codes os a string", "\"Hello\"", 0, CAT_CATEGORY_ARIT}, - {"assume(hyp)", 0, "Assumption on variable.", "x>1", "x>-1 and x<1", CAT_CATEGORY_PROGCMD|(CAT_CATEGORY_SOFUS<<8)}, - {"avance n", "avance ", "Turtle forward n steps, default n=10", "#avance 30", 0, CAT_CATEGORY_LOGO}, - {"axes", "axes", "Axes visible or not axes=1 or 0", "#axes=0", 0, CAT_CATEGORY_PROGCMD << 8|XCAS_ONLY}, - {"baisse_crayon ", "baisse_crayon ", "Turtle moves with the pen writing.", 0, 0, CAT_CATEGORY_LOGO}, - {"barplot(list)", 0, "Bar plot of 1-d statistic series data in list.", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS}, - {"barycenter([pnt,coeff],...)", 0, "Barycenter of a sequence of [point,coefficient]. Run isobarycenter if all coefficients are equal", "[1,1],[i,1],[2,3]", 0, CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"binomial(n,p,k)", 0, "binomial(n,p,k) probability to get k success with n trials where p is the probability of success of 1 trial. binomial_cdf(n,p,k) is the probability to get at most k successes. binomial_icdf(n,p,t) returns the smallest k such that binomial_cdf(n,p,k)>=t", "10,.5,4", 0, CAT_CATEGORY_PROBA}, - {"bisector(A,B,C)", 0, "Bisector of angle AB,AC", "1,i,2+i", 0,CAT_CATEGORY_2D}, - {"bitxor", "bitxor", "Exclusive or", "#bitxor(1,2)", 0, CAT_CATEGORY_PROGCMD}, - {"black", "black", "Display option", "#display=black", 0, CAT_CATEGORY_PROGCMD}, - {"blue", "blue", "Display option", "#display=blue", 0, CAT_CATEGORY_PROGCMD}, - {"camembert(list)", 0, "Camembert pie-chart of a 1-d statistical series.", "[[\"France\",6],[\"Germany\",12],[\"Switzerland\",5]]", 0, CAT_CATEGORY_STATS}, - {"cache_tortue ", "cache_tortue ", "Hide turtle (once the picture has been drawn).", 0, 0, CAT_CATEGORY_LOGO}, - {"ceil(x)", 0, "Smallest integer not less than x", "1.2", 0, CAT_CATEGORY_REAL}, - {"center(objet)", 0, "Circle or sphere center. For ellipse or hyperbola, returns center, one focus and a point on the conic. For a parabola, returns focus and vertex.", "circle(0,1)", "sphere([0,0,0],[1,1,1])", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"cfactor(p)", 0, "Factorization over C.", "x^4-1", 0, CAT_CATEGORY_ALGEBRA | (CAT_CATEGORY_COMPLEXNUM << 8)}, - {"char(liste)", 0, "Converts a list of ASCII codes to a string.", "[97,98,99]", 0, CAT_CATEGORY_ARIT}, - {"charpoly(M,x)", 0, "Characteristic polynomial of matrix M in variable x.", "[[1,2],[3,4]],x", 0, CAT_CATEGORY_MATRIX}, - {"circle(center,radius)", 0, "Circle", "2+i,3", "1-i,1+i", CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8)}, - {"circumcircle(A,B,C)", 0, "Circumcircle", "-1,2+i,3", 0, CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"clearscreen()", "clearscreen()", "Clear screen.", 0, 0, CAT_CATEGORY_PROGCMD|XCAS_ONLY}, - {"coeff(p,x,n)", 0, "Coefficient of x^n in polynomial p.", 0, 0, CAT_CATEGORY_POLYNOMIAL}, - {"comb(n,k)", 0, "Returns nCk", "10,4", 0, CAT_CATEGORY_PROBA}, - {"cond(A,[1,2,inf])", 0, "Nombre de condition d'une matrice par rapport a la norme specifiee (par defaut 1)", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"cone(A,v,theta,[h])", 0, " cone with vertex A, direction v, and with half_angle t [and with altitudes h and -h]", "[0,0,0],[0,0,1],pi/6", "[0,0,0],[0,0,1],pi/6,4", CAT_CATEGORY_3D}, - {"conic(expression)", 0, "Conic given by a polynomial equation of degree 2 or by 5 vertices", "x^2+x*y+y^2=5", "1,i,2+i,3-i,4+2i", CAT_CATEGORY_2D}, - {"coordinates(object)", 0, "Coordonnees (cartesian))", "point(1,2)", "point(1,2,3)", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"conj(z)", 0, "Complex conjugate of z.", "1+i", 0, CAT_CATEGORY_COMPLEXNUM}, - {"correlation(l1,l2)", 0, "Correlation of lists l1 and l2", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS}, - {"covariance(l1,l2)", 0, "Covariance of lists l1 and l2", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS}, - {"cpartfrac(p,x)", 0, "Partial fraction decomposition over C.", "1/(x^4-1)", 0, CAT_CATEGORY_ALGEBRA | (CAT_CATEGORY_COMPLEXNUM << 8)}, - {"crayon ", "crayon ", "Turtle drawing color", "#crayon red", 0, CAT_CATEGORY_LOGO}, - {"cross(u,v)", 0, "Cross product of vectors u and v.","[1,2,3],[0,1,3]", 0, CAT_CATEGORY_LINALG}, - {"csolve(equation,x)", 0, "Solve equation (or polynomial system) in exact mode over the complex numbers.","x^2+x+1=0", 0, CAT_CATEGORY_SOLVE| (CAT_CATEGORY_COMPLEXNUM << 8)}, - {"cube(A,B,C)", 0, "Cube of edge AB with one face in plane ABC", "[0,0,0],[1,0,0],[0,1,0]","[0,0,0],[0,2,sqrt(5)/2+3/2],[0,0,1]", CAT_CATEGORY_3D}, - {"curl(u,vars)", 0, "Curl of vector u.", "[2*x*y,x*z,y*z],[x,y,z]", 0, CAT_CATEGORY_LINALG}, - {"cyan", "cyan", "Display option", "#display=cyan", 0, CAT_CATEGORY_PROGCMD}, - {"cylinder(A,v,r,[h])", 0, "Cylinder of axis A,v and radius r [and optional altitude h]", "[0,0,0],[0,1,0],2", "[0,0,0],[0,1,0],2,3", CAT_CATEGORY_3D}, - {"debug(f(args))", 0, "Runs user function f in step by step mode.", 0, 0, CAT_CATEGORY_PROG}, - {"degree(p,x)", 0, "Degre of polynomial p in x.", "x^4-1", 0, CAT_CATEGORY_POLYNOMIAL}, - {"denom(x)", 0, "Denominator of expression x.", "3/4", 0, CAT_CATEGORY_POLYNOMIAL}, - {"desolve(equation,t,y)", 0, "Exact differential equation solving.", "desolve([y'+y=exp(x),y(0)=1])", "[y'=[[1,2],[2,1]]*y+[x,x+1],y(0)=[1,2]]", CAT_CATEGORY_SOLVE | (CAT_CATEGORY_CALCULUS << 8)}, - {"det(A)", 0, "Determinant of matrix A.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"diff(f,var,[n])", 0, "Derivative of expression f with respect to var (order n, n=1 by default), for example diff(sin(x),x) or diff(x^3,x,2). For derivation with respect to x, run f' (shortcut F3). For the gradient of f, var is the list of variables.", "sin(x),x", "sin(x^2),x,3", CAT_CATEGORY_CALCULUS}, - {"display", "display", "Display option", "#display=red", 0, CAT_CATEGORY_PROGCMD}, - {"disque n", "disque ", "Filled circle tangent to the turtle, radius n. Run disque n,theta for a filled arc of circle, theta in degrees, or disque n,theta,segment for a segment of circle.", "#disque 30", "#disque(30,90)", CAT_CATEGORY_LOGO}, - {"dodecahedron(A,B,C)", 0, "Dodecahedron of edge AB with one face in plane ABC", "[0,0,0],[0,2,sqrt(5)/2+3/2],[0,0,1]", 0, CAT_CATEGORY_3D}, - {"dot(a,b)", 0, "Dot product of 2 vectors. Shortcut: *", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_LINALG}, - {"draw_arc(x1,y1,rx,ry,theta1,theta2,c)", 0, "Pixelised arc of ellipse.", "100,100,60,80,0,pi,magenta", 0, CAT_CATEGORY_PROGCMD}, - {"draw_circle(x1,y1,r,c)", 0, "Pixelised circle. Option: filled", "100,100,60,cyan+filled", 0, CAT_CATEGORY_PROGCMD}, - {"draw_line(x1,y1,x2,y2,c)", 0, "Pixelised line.", "100,50,300,200,blue", 0, CAT_CATEGORY_PROGCMD}, - {"draw_pixel(x,y,color)", 0, "Colors pixel x,y. Run draw_pixel() to synchronise screen.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"draw_polygon([[x1,y1],...],c)", 0, "Pixelised polygon.", "[[100,50],[30,20],[60,70]],red+filled", 0, CAT_CATEGORY_PROGCMD}, - {"draw_rectangle(x,y,w,h,c)", 0, "Rectangle.", "100,50,30,20,red+filled", 0, CAT_CATEGORY_PROGCMD}, - {"draw_string(s,x,y,c)", 0, "Draw string s at pixel x,y", "\"Bonjour\",80,60", 0, CAT_CATEGORY_PROGCMD}, -#ifndef TURTLETAB - {"ecris ", "ecris ", "Write at turtle position", "#ecris \"hello\"", 0, CAT_CATEGORY_LOGO}, -#endif - {"efface", "efface", "Reset turtle", 0, 0, CAT_CATEGORY_LOGO}, - {"egcd(A,B)", 0, "Find polynomials U,V,D such that A*U+B*V=D=gcd(A,B)","x^2+3x+1,x^2-5x-1", 0, CAT_CATEGORY_POLYNOMIAL}, - {"elif test", "elif ", "Test cascade", 0, 0, CAT_CATEGORY_PROG}, - {"ellipse(F1,F2,M)", 0, "Ellipse given by 2 focus and one point", "-1,1,2", 0, CAT_CATEGORY_2D}, - {"eigenvals(A)", 0, "Eigenvalues of matrix A.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX |XCAS_ONLY}, - {"eigenvects(A)", 0, "Eigenvectors of matrix A.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"equation(object)", 0, "Cartesian equation. Run parameq for parametric equation", "circle(0,1)", "ellipse(-1,1,3)", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"erf(x)", 0, "Error function of x.", "1.2", 0, CAT_CATEGORY_PROBA}, - {"erfc(x)", 0, "Complementary error function of x.", "1.2", 0, CAT_CATEGORY_PROBA}, - {"euler(n)",0,"Euler indicatrix: number of integers < n coprime with n","25",0,CAT_CATEGORY_ARIT}, - {"eval(f)", 0, "Evals f.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"evalc(z)", 0, "Write z=x+i*y.", "1/(1+i*sqrt(3))", 0, CAT_CATEGORY_COMPLEXNUM}, - {"exact(x)", 0, "Converts x to a rational. Shortcut shift S-D", "1.2", 0, CAT_CATEGORY_REAL}, - {"exp2trig(expr)", 0, "Convert complex exponentials to sin/cos", "exp(i*x)", 0, CAT_CATEGORY_TRIG}, - {"exponential_regression(Xlist,Ylist)", 0, "Exponential regression.", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS}, - {"exponential_regression_plot(Xlist,Ylist)", 0, "Exponential regression plot.", "#X,Y:=[1,2,3,4,5],[0,1,3,4,4];exponential_regression_plot(X,Y);scatterplot(X,Y)", 0, CAT_CATEGORY_STATS}, - {"exponentiald(lambda,x)", 0, "Exponential distribution law of parameter lambda. exponentiald_cdf(lambda,x) probability that \"exponential distribution <=x\" e.g. exponentiald_cdf(2,3). exponentiald_icdf(lambda,t) returns x such that \"exponential distribution <=x\" has probability t, e.g, exponentiald_icdf(2,0.95) ", "5.1,3.4", 0, CAT_CATEGORY_PROBA}, - {"extend", 0, "Merge 2 lists. Note that + does not merge lists, it adds vectors","#l1.extend(l2)", 0, CAT_CATEGORY_LIST}, - {"factor(p,[x])", 0, "Factors polynomial p (run ifactor for an integer). Shortcut: p=>*", "x^4-1", "x^6+1,sqrt(3)", CAT_CATEGORY_ALGEBRA| (CAT_CATEGORY_POLYNOMIAL << 8)}, - {"filled", "filled", "Display option", 0, 0, CAT_CATEGORY_PROGCMD}, - {"float(x)", 0, "Converts x to a floating point value.", "pi", 0, CAT_CATEGORY_REAL}, - {"floor(x)", 0, "Largest integer not greater than x", "pi", 0, CAT_CATEGORY_REAL}, - {"fourier_an(f,x,T,n,a)", 0, "Cosine Fourier coefficients of f", "x^2,x,2*pi,n,-pi", 0, CAT_CATEGORY_CALCULUS}, - {"fourier_bn(f,x,T,n,a)", 0, "Sine Fourier coefficients of f", "x^2,x,2*pi,n,-pi", 0, CAT_CATEGORY_CALCULUS}, - {"fourier_cn(f,x,T,n,a)", 0, "Exponential Fourier coefficients of f", "x^2,x,2*pi,n,-pi", 0, CAT_CATEGORY_CALCULUS}, - {"from math/... import *", "from math import *", "Access to math or to random functions ([random]) or turtle with English commandnames [turtle]. Math import is not required in KhiCAS", "#from random import *", "#from turtle import *", CAT_CATEGORY_PROG}, - {"fsolve(equation,x=a..b)", 0, "Approx equation solving in interval a..b.","cos(x)=x,x=0..1", "cos(x)-x,x=0.0", CAT_CATEGORY_SOLVE}, - // {"function f(x):...", "function f(x) local y; ffunction:;", "Function definition.", "#function f(x) local y; y:=x^2; return y; ffunction:;", 0, CAT_CATEGORY_PROG}, - {"gauss(q)", 0, "Quadratic form reduction", "x^2+x*y+x*z+y^2+z^2,[x,y,z]", 0, CAT_CATEGORY_LINALG}, - {"gcd(a,b,...)", 0, "Greatest common divisor. See also iegcd and egcd for extended GCD.", "23,13", "x^2-1,x^3-1", CAT_CATEGORY_ARIT | (CAT_CATEGORY_POLYNOMIAL << 8)}, - {"gl_x", "gl_x", "Display settings X gl_x=xmin..xmax", "#gl_x=0..2", 0, CAT_CATEGORY_PROGCMD}, - {"gl_y", "gl_y", "Display settings Y gl_y=ymin..ymax", "#gl_y=-1..1", 0, CAT_CATEGORY_PROGCMD}, - {"gramschmidt(M)", 0, "Gram-Schmidt orthonormalization (line vectors or linearly independent set of vectors)", "[[1,2,3],[4,5,6]]", "[1,1+x],(p,q)->integrate(p*q,x,-1,1)", CAT_CATEGORY_LINALG}, - {"green", "green", "Display option", "#display=green", 0, CAT_CATEGORY_PROGCMD}, - {"halftan(expr)", 0, "Convert cos, sin, tan with tan(angle/2).","cos(x)", 0, CAT_CATEGORY_TRIG}, - {"hermite(n)", 0, "n-th Hermite polynomial", "10", 0, CAT_CATEGORY_POLYNOMIAL}, - {"hilbert(n)", 0, "Hilbert matrix of order n.", "4", 0, CAT_CATEGORY_MATRIX}, - {"histogram(list,min,size)", 0, "Histogram of data in list, classes begin at min of size size.","ranv(100,uniformd,0,1),0,0.1", 0, CAT_CATEGORY_STATS}, - {"homothety(center,ratio,object)", 0, "Image of object by homothety of ratio", "0,2,circle(1,1)", 0, CAT_CATEGORY_2D }, - {"hyperbola(F1,F2,M)", 0, "Hyperbola given by 2 focus and one point", "-2-i,2+i,1", 0, CAT_CATEGORY_2D}, - {"iabcuv(a,b,c)", 0, "Find 2 integers u,v such that a*u+b*v=c","23,13,15", 0, CAT_CATEGORY_ARIT}, - {"ichinrem([a,m],[b,n])", 0,"Integer chinese remainder of a mod m and b mod n.", "[3,13],[2,7]", 0, CAT_CATEGORY_ARIT}, - {"icosahedron(A,B,C)", 0, "Icosahedron with center A, vertex B and such that the plane ABC contains one vertex among the 5 nearest vertices from B ", "[0,0,0],[sqrt(5),0,0],[1,2,0]", 0, CAT_CATEGORY_3D}, - {"idivis(n)", 0, "Returns the list of divisors of an integer n.", "10", 0, CAT_CATEGORY_ARIT}, - {"idn(n)", 0, "Identity matrix of order n", "4", 0, CAT_CATEGORY_MATRIX}, - {"iegcd(a,b)", 0, "Find integers u,v,d such that a*u+b*v=d=gcd(a,b)","23,13", 0, CAT_CATEGORY_ARIT}, - {"ifactor(n)", 0, "Factorization of an integer (not too large!). Shortcut n=>*", 0, 0, CAT_CATEGORY_ARIT}, - {"ilaplace(f,s,x)", 0, "Inverse Laplace transform of f", "s/(s^2+1),s,x", 0, CAT_CATEGORY_CALCULUS}, - {"im(z)", 0, "Imaginary part.", "1+i", 0, CAT_CATEGORY_COMPLEXNUM}, - {"incircle(A,B,C)", 0, "Incircle", "-1,2+i,3", 0, CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"inf", "inf", "Plus infinity. -inf for minus infinity and infinity for unsigned/complex infinity. Shortcut shift INS.", "oo", 0, CAT_CATEGORY_CALCULUS}, - {"input()", "input()", "Read a string from keyboard", 0, 0, CAT_CATEGORY_PROG}, - {"integrate(f,x,[a,b])", 0, "Antiderivative of f with respect to x, like integrate(x*sin(x),x). For definite integral enter optional arguments a and b, like integrate(x*sin(x),x,0,pi). Shortcut SHIFT F3.", "x*sin(x),x", "cos(x)/(1+x^4),x,0,inf", CAT_CATEGORY_CALCULUS}, - {"interp(X,Y)", 0, "Lagrange interpolation at points (xi,yi) where X is the list of xi and Y of yi. If interp is passed as 3rd argument, returns the divided differences list.", "[1,2,3,4,5],[0,1,3,4,4]", "[1,2,3,4,5],[0,1,3,4,4],interp", CAT_CATEGORY_POLYNOMIAL}, - {"inter(A,B)", 0, "Intersections list. Run single_inter if intersection is unique.", "line(y=x),circle(0,1)", 0, CAT_CATEGORY_3D | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"inv(A)", 0, "Inverse of A.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"iquo(a,b)", 0, "Integer quotient of a and b.", "23,13", 0, CAT_CATEGORY_ARIT}, - {"irem(a,b)", 0,"Integer remainder of a and b.", "23,13", 0, CAT_CATEGORY_ARIT}, - {"isprime(n)", 0, "Returns 1 if n is prime, 0 otherwise.", "11", "10", CAT_CATEGORY_ARIT}, - {"jordan(A)", 0, "Jordan normal form of matrix A, returns P and D such that P^-1*A*P=D", "[[1,2],[3,4]]", "[[1,1,-1,2,-1],[2,0,1,-4,-1],[0,1,1,1,1],[0,1,2,0,1],[0,0,-3,3,-1]]", CAT_CATEGORY_MATRIX}, - {"laguerre(n,a,x)", 0, "n-ieme Laguerre polynomial (default a=0).", "10", 0, CAT_CATEGORY_POLYNOMIAL}, - {"laplace(f,x,s)", 0, "Laplace transform of f","sin(x),x,s", 0, CAT_CATEGORY_CALCULUS}, - {"lcm(a,b,...)", 0, "Least common multiple.", "23,13", "x^2-1,x^3-1", CAT_CATEGORY_ARIT | (CAT_CATEGORY_POLYNOMIAL << 8)}, - {"lcoeff(p,x)", 0, "Leading coefficient of polynomial p in x.", "x^4-1", 0, CAT_CATEGORY_POLYNOMIAL}, - {"legendre(n)", 0, "n-the Legendre polynomial.", "10", "10,t", CAT_CATEGORY_POLYNOMIAL}, -#ifdef RELEASE - {"len(l)", 0, "Size of a list.", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_LIST}, -#endif - {"leve_crayon ", "leve_crayon ", "Turtle moves without trace.", 0, 0, CAT_CATEGORY_LOGO}, - {"limit(f,x=a)", 0, "Limit of f at x = a. Add 1 or -1 for unidirectional limits, e.g. limit(sin(x)/x,x=0) or limit(abs(x)/x,x=0,1). Shortcut: SHIFT MIXEDFRAC", "sin(x)/x,x=0", "exp(-1/x),x=0,1", CAT_CATEGORY_CALCULUS}, - {"line(equation)", 0, "Line of equation", "y=2x+1", "[0,0,0],[1,-2,3]", CAT_CATEGORY_PROGCMD |(CAT_CATEGORY_2D << 8)|(CAT_CATEGORY_2D << 16)}, - {"line_width_", "line_width_", "Width prefix (2 to 8)", 0, 0, CAT_CATEGORY_PROGCMD}, - {"linear_regression(Xlist,Ylist)", 0, "Linear regression.", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS}, - {"linear_regression_plot(Xlist,Ylist)", 0, "Linear regression plot.", "#X,Y:=[1,2,3,4,5],[0,1,3,4,4];linear_regression_plot(X,Y);scatterplot(X,Y)", 0, CAT_CATEGORY_STATS}, - {"linetan(expr,x,x0)", 0, "Tangent to the graph at x=x0.", "sin(x),x,pi/2", 0, CAT_CATEGORY_PLOT}, - {"linsolve([eq1,eq2,..],[x,y,..])", 0, "Linear system solving. May use the output of lu for O(n^2) solving (see example 2).","[x+y=1,x-y=2],[x,y]", "#p,l,u:=lu([[1,2],[3,4]]); linsolve(p,l,u,[5,6])", CAT_CATEGORY_SOLVE | (CAT_CATEGORY_LINALG <<8) | (CAT_CATEGORY_MATRIX << 16)}, - {"logarithmic_regression(Xlist,Ylist)", 0, "Logarithmic egression.", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS}, - {"logarithmic_regression_plot(Xlist,Ylist)", 0, "Logarithmic regression plot.", "#X,Y:=[1,2,3,4,5],[0,1,3,4,4];logarithmic_regression_plot(X,Y);scatterplot(X,Y)", 0, CAT_CATEGORY_STATS}, - {"lu(A)", 0, "LU decomposition LU of matrix A, P*A=L*U", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"magenta", "magenta", "Display option", "#display=magenta", 0, CAT_CATEGORY_PROGCMD}, - {"map(f,l)", 0, "Maps f on element of list l.","lambda x:x*x,[1,2,3]", 0, CAT_CATEGORY_LIST}, - {"matpow(A,n)", 0, "Returns matrix A^n", "[[1,2],[3,4]],n","#assume(n>=1);matpow([[0,2],[0,4]],n)", CAT_CATEGORY_MATRIX}, - {"matrix(r,c,func)", 0, "Matrix from a defining function.", "2,3,(j,k)->j^k", 0, CAT_CATEGORY_MATRIX}, - {"mean(l)", 0, "Arithmetic mean of list l", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS}, - {"median(l)", 0, "Median", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS}, - {"median_line(A,B,C)", 0, "Median line of triangle ABC from vertex A", "1,i,2+i", 0,CAT_CATEGORY_2D}, - {"midpoint(A,B)", 0, "Midpoint of segment AB", "1,i", 0,CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8)}, - {"montre_tortue ", "montre_tortue ", "Displays the turtle", 0, 0, CAT_CATEGORY_LOGO}, - {"mult_c_conjugate", 0, "Multiplier par le conjugue complexe.", "1+2*i", 0, (CAT_CATEGORY_COMPLEXNUM << 8)}, - {"mult_conjugate", 0, "Multiplier par le conjugue (sqrt).", "sqrt(2)-sqrt(3)", 0, CAT_CATEGORY_ALGEBRA}, - {"normald([mu,sigma],x)", 0, "Normal distribution probability density, by default mu=0 and sigma=1. normald_cdf([mu,sigma],x) probability that \"normal distribution <=x\" e.g. normald_cdf(1.96). normald_icdf([mu,sigma],t) returns x such that \"normal distribution <=x\" has probability t, e.g. normald_icdf(0.975) ", "1.2", 0, CAT_CATEGORY_PROBA}, - {"not(x)", 0, "Logical not.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"numer(x)", 0, "Numerator of x.", "3/4", 0, CAT_CATEGORY_POLYNOMIAL}, - {"octahedron(A,B,C)", 0, "Octahedron of edge AB with one face in plane ABC", "[0,0,0],[3,0,0],[0,1,0]", 0, CAT_CATEGORY_3D}, - {"odesolve(f(t,y),[t,y],[t0,y0],t1)", 0, "Approx. solution of differential equation y'=f(t,y) and y(t0)=y0, value for t=t1 (add curve to get intermediate values of y)", "sin(t*y),[t,y],[0,1],2", "0..pi,(t,v)->{[-v[1],v[0]]},[0,1]", CAT_CATEGORY_SOLVE}, - {"parabola(F,A)", 0, "Parabola given by focus and vertex", "-2-i,2+i", 0, CAT_CATEGORY_2D}, - {"parameq(object)", 0, "Parametric equations. Run equation for cartesian equation", "circle(0,1)", "ellipse(-1,1,3)", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"partfrac(p,x)", 0, "Partial fraction expansion. Shortcut p=>+", "1/(x^4-1)", 0, CAT_CATEGORY_ALGEBRA}, - {"pas_de_cote n", "pas_de_cote ", "Turtle side jump from n steps, by default n=10", "#pas_de_cote 30", 0, CAT_CATEGORY_LOGO}, - {"perpen_bisector(A,B)", 0, "Perpendicular bisector of segment AB", "1,i", 0,CAT_CATEGORY_2D}, - {"plane(equation)", 0, "Plane given by equation or by 3 points", "z=x+y-1", "[0,0,0],[1,0,0],[0,1,0]", CAT_CATEGORY_3D | XCAS_ONLY}, - {"plot(expr,x)", 0, "Plot an expression. For example plot(sin(x)), plot(ln(x),x.0,5), plot(x^2-y^2), plot(x^2-y^2<1), plot(x^2-y^2=1)", "ln(x),x,0,5", "1/x,x=1..5,xstep=1", (CAT_CATEGORY_PLOT << 8) | (CAT_CATEGORY_3D)}, -#ifdef RELEASE - {"plotarea(expr,x=a..b,[n,meth])", 0, "Area under curve with specified quadrature.", "1/x,x=1..3,2,trapezoid", 0, CAT_CATEGORY_PLOT}, -#endif - {"plotcontour(expr,[x=xm..xM,y=ym..yM],levels)", 0, "Levels of expr.", "x^2+2y^2,[x=-2..2,y=-2..2],[1,2]", 0, CAT_CATEGORY_PLOT}, - {"plotfield(f(t,y),[t=tmin..tmax,y=ymin..ymax])", 0, "Plot field of differential equation y'=f(t,y), an optionally one solution by adding plotode=[t0,y0]", "sin(t*y),[t=-3..3,y=-3..3],plotode=[0,1]", 0, CAT_CATEGORY_PLOT}, - {"plotfunc(expr,[x,y])", 0, "Xcas: graph of a 3d function", "x^2-y^2,[x,y]","x^2-y^2,[x=-2..2,y=-2..2],nstep=700", CAT_CATEGORY_PLOT | (CAT_CATEGORY_3D << 8) | XCAS_ONLY }, - {"plotlist(list)", 0, "Plot a list", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_PLOT}, - {"plotode(f(t,y),[t=tmin..tmax,y],[t0,y0])", 0, "Plot solution of differential equation y'=f(t,y), y(t0)=y0.", "sin(t*y),[t=-3..3,y],[0,1]", 0, CAT_CATEGORY_PLOT}, - {"plotparam([x,y],t)", 0, "Parametric plot. For example plotparam([sin(3t),cos(2t)],t,0,pi) or plotparam(exp(i*t),t,0,pi)", "[sin(3t),cos(2t)],t,0,pi", "[t^2,t^3],t=-1..1,tstep=0.1", CAT_CATEGORY_PLOT}, - {"plotpolar(r,theta)", 0, "Polar plot.","cos(3*x),x,0,pi", "1/(1+cos(x)),x=0..pi,xstep=0.05", CAT_CATEGORY_PLOT}, - {"plotseq(f(x),x=[u0,m,M],n)", 0, "Plot f(x) on [m,M] and n terms of the sequence defined by u_{n+1}=f(u_n) and u0.","sqrt(2+x),x=[6,0,7],5", 0, CAT_CATEGORY_PLOT}, - {"plus_point", "plus_point", "Display option", "#display=blue+plus_point", 0, CAT_CATEGORY_PROGCMD}, - {"point(x,y[,z])", 0, "Point", "1,2", "1,2,3", CAT_CATEGORY_PLOT | (CAT_CATEGORY_2D << 8)}, - {"polygon(list)", 0, "Closed polygon given by a list of vertices.", "1-i,2+i,3,3-2i", 0, CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8) }, - {"polygonscatterplot(Xlist,Ylist)", 0, "Plot points and polygonal line.", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS}, - {"polyhedron(A,B,C,D,...)", 0, "Convex polyhedron of vertices in A,B,C,D,...", "[0,0,0],[0,5,0],[0,0,5],[1,2,6]", 0, CAT_CATEGORY_3D}, - {"polynomial_regression(Xlist,Ylist,n)", 0, "Polynomial regression, degree <= n.", "[1,2,3,4,5],[0,1,3,4,4],2", 0, CAT_CATEGORY_STATS}, - {"polynomial_regression_plot(Xlist,Ylist,n)", 0, "Polynomial regression plot, degree <= n.", "#X,Y:=[1,2,3,4,5],[0,1,3,4,4];polynomial_regression_plot(X,Y,2);scatterplot(X,Y)", 0, CAT_CATEGORY_STATS}, - //{"pour", "pour j de 1 jusque faire fpour;", "For loop.","#pour j de 1 jusque 10 faire print(j,j^2); fpour;", 0, CAT_CATEGORY_PROG}, - {"power_regression(Xlist,Ylist,n)", 0, "Power regression.", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS}, - {"power_regression_plot(Xlist,Ylist,n)", 0, "Power regression graph", "#X,Y:=[1,2,3,4,5],[0,1,3,4,4];power_regression_plot(X,Y);scatterplot(X,Y)", 0, CAT_CATEGORY_STATS}, - {"powmod(a,n,p)", 0, "Returns a^n mod p.","123,456,789", 0, CAT_CATEGORY_ARIT}, - {"print(expr)", 0, "Print expr in console", 0, 0, CAT_CATEGORY_PROG}, - {"projection(obj1,obj2)", 0, "Projection on obj1 of obj2", "line(y=x),point(2,3)", 0, CAT_CATEGORY_2D }, - {"proot(p)", 0, "Returns real and complex roots, of polynomial p. Exemple proot([1,2.1,3,4.2]) or proot(x^3+2.1*x^2+3x+4.2)", "x^3+2.1*x^2+3x+4.2", 0, CAT_CATEGORY_POLYNOMIAL}, - {"purge(x)", 0, "Clear assigned variable x. Shortcut SHIFT-FORMAT", 0, 0, CAT_CATEGORY_PROGCMD|(CAT_CATEGORY_SOFUS<<8)}, - {"python(f)", 0, "Displays f in Python syntax.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"python_compat(0|1|2)", 0, "python_compat(0) Xcas syntax, python_compat(1) Python syntax with ^ interpreted as power, python_compat(2) ^ as bit xor", "0", "1", CAT_CATEGORY_PROG}, - {"qr(A)", 0, "A=Q*R factorization with Q orthogonal and R upper triangular", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"quadric(equation)", 0, "Quadric given by equation (or 9 points)", "x^2-y^2+z^2", "x^2+x*y+y^2+z^2-3", CAT_CATEGORY_3D}, - {"quartile1(l)", 0, "1st quartile", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS}, - {"quartile3(l)", 0, "3rd quartile", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS}, - {"quo(p,q,x)", 0, "Quotient of synthetic division of polynomials p and q (variable x).", 0, 0, CAT_CATEGORY_POLYNOMIAL}, - {"quote(x)", 0, "Returns expression x unevaluated.", 0, 0, CAT_CATEGORY_ALGEBRA}, - {"radius(objet)", 0, "Radius of a circle or sphere", "circle(0,1)", "sphere([0,0,0],[1,1,1])", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"rand()", "rand()", "Random real between 0 and 1", 0, 0, CAT_CATEGORY_PROBA}, - {"randint(a,b)", 0, "Random integer between a and b. With 1 argument in Xcas, random integer between 1 and n.", "5,25", "6", CAT_CATEGORY_PROBA}, - {"ranm(n,m,[loi,parametres])", 0, "Random matrix with integer coefficients or according to a probability law (ranv for a vector). Examples ranm(2,3), ranm(3,2,binomial,20,.3), ranm(4,2,normald,0,1)", "3,3","4,2,normald,0,1", CAT_CATEGORY_MATRIX}, - {"ranv(n,[loi,parametres])", 0, "Random vector.", "10","4,normald,0,1", CAT_CATEGORY_LINALG}, - {"ratnormal(x)", 0, "Puts everything over a common denominator.", 0, 0, CAT_CATEGORY_ALGEBRA}, - {"re(z)", 0, "Real part.", "1+i", 0, CAT_CATEGORY_COMPLEXNUM}, - {"read(\"filename\")", "read(\"", "Read a file.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"rectangle_plein a,b", "rectangle_plein ", "Direct filled rectangle from turtle position, if b is omitted b==a", "#rectangle_plein 30","#rectangle_plein 20,40", CAT_CATEGORY_LOGO}, - {"recule n", "recule ", "Turtle backward n steps, n=10 by default", "#recule 30", 0, CAT_CATEGORY_LOGO}, - {"red", "red", "Display option", "#display=red", 0, CAT_CATEGORY_PROGCMD}, - {"reflection(obj1,obj2)", 0, "Reflection or symmetrical of obj2", "line(y=x),cercle(1,1)", 0, CAT_CATEGORY_2D }, - {"rem(p,q,x)", 0, "Remainder of synthetic division of polynomials p and q (variable x)", 0, 0, CAT_CATEGORY_POLYNOMIAL}, -#ifdef RELEASE - {"residue(f(z),z,z0)", 0, "Residue of an expression at z0.", "1/(x^2+1),x,i", 0, CAT_CATEGORY_COMPLEXNUM}, -#endif - {"resultant(p,q,x)", 0, "Resultant in x of polynomials p and q.", "#P:=x^3+p*x+q;resultant(P,P',x);", 0, CAT_CATEGORY_POLYNOMIAL}, - {"revert(p[,x])", 0, "Revert Taylor series","x+x^2+x^4", 0, CAT_CATEGORY_CALCULUS}, - {"rgb(r,g,b)", 0, "color defined from red, green, blue from 0 to 255", "255,0,255", 0, CAT_CATEGORY_PROGCMD}, - {"rhombus_point", "rhombus_point", "Display option", "#display=magenta+rhombus_point", 0, CAT_CATEGORY_PROGCMD}, - {"rond n", "rond ", "Circle tangent to the turtle, radius n. Run rond n,theta for an arc of circle of theta degrees", 0, 0, CAT_CATEGORY_LOGO}, - {"rotation(center,angle,objcet)", 0, "Image of object by rotation", "2-i,pi/2,circle(0,1)", "sphere([0,0,0],[1,1,1])", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - {"rsolve(equation,u(n),[init])", 0, "Solve a recurrence relation.","u(n+1)=2*u(n)+3,u(n),u(0)=1", "([u(n+1)=3*v(n)+u(n),v(n+1)=v(n)+u(n)],[u(n),v(n)],[u(0)=1,v(0)=2]", CAT_CATEGORY_SOLVE}, - {"saute n", "saute ", "Turtle jumps n steps, by default n=10", "#saute 30", 0, CAT_CATEGORY_LOGO}, - {"scatterplot(Xlist,Ylist)", 0, "Draws points", "[1,2,3,4,5],[0,1,3,4,4]", 0, CAT_CATEGORY_STATS}, - {"segment(A,B)", 0, "Segment", "1,2+i", "[1,2,1],[-1,3,2]", CAT_CATEGORY_PROGCMD | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"seq(expr,var,a,b)", 0, "Generates a list from an expression.","j^2,j,1,10", 0, CAT_CATEGORY_PROGCMD}, - //{"si", "si alors sinon fsi;", "Test.", "#f(x):=si x>0 alors x; sinon -x; fsi;// valeur absolue", 0, CAT_CATEGORY_PROG}, - {"sign(x)", 0, "Returns -1 if x is negative, 0 if x is zero and 1 if x is positive.", 0, 0, CAT_CATEGORY_REAL|XCAS_ONLY}, - {"similarity(center,ratio,angle,object)", 0, "Image of object by similarity", "0,2,pi/2,circle(1,1)", 0, CAT_CATEGORY_2D }, - {"simplify(expr)", 0, "Returns x in a simpler form. Shortcut expr=>/", "sin(3x)/sin(x)", 0, CAT_CATEGORY_ALGEBRA}, - {"single_inter(A,B)", 0, "First intersection. Run inter for a list of intersections.", "line(y=x),line(x+y=3)", 0, CAT_CATEGORY_3D | (CAT_CATEGORY_2D << 8) | XCAS_ONLY}, - {"solve(equation,x)", 0, "Exact solving of equation w.r.t. x (or of a polynomial system). Run csolve for complex solutions, linsolve for a linear system. Shortcut SHIFT XthetaT", "x^2-x-1=0,x", "[x^2-y^2=0,x^2-z^2=0],[x,y,z]", CAT_CATEGORY_SOLVE}, - {"sorted(l)", 0, "Sorts a list.","[3/2,2,1,1/2,3,2,3/2]", "[[1,2],[2,3],[4,3]],(x,y)->when(x[1]==y[1],x[0]>y[0],x[1]>y[1]", CAT_CATEGORY_LIST}, - {"sphere(A,r)", 0, "Sphere of center A and radius r or diameter AB", "[0,0,0],1", "[0,0,0],[1,1,1]", CAT_CATEGORY_3D}, - {"square_point", "square_point", "Display option", "#display=cyan+square_point", 0, CAT_CATEGORY_PROGCMD}, - {"star_point", "star_point", "Display option", "#display=magenta+star_point", 0, CAT_CATEGORY_PROGCMD}, - {"stddev(l)", 0, "Standard deviation of list l", "[3/2,2,1,1/2,3,2,3/2]", 0, CAT_CATEGORY_STATS}, - {"subst(a,b=c)", 0, "Substitutes b for c in a. Shortcut a(b=c).", "x^2,x=3", 0, CAT_CATEGORY_ALGEBRA}, - {"sum(f,k,m,M)", 0, "Summation of expression f for k from m to M. Exemple sum(k^2,k,1,n)=>*. Shortcut ALPHA F3", "k,k,1,n", 0, CAT_CATEGORY_CALCULUS}, - {"svd(A)", 0, "Singular Value Decomposition, returns U orthogonal, S vector of singular values, Q orthogonal such that A=U*diag(S)*tran(Q).", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"tabvar(f,[x=a..b])", 0, "Table of variations of expression f, optional arguments variable x in interval a..b", "sqrt(x^2+x+1)", "[cos(t),sin(3t)],t", CAT_CATEGORY_CALCULUS}, - //{"tantque", "tantque faire ftantque;", "While loop.", "#j:=13; tantque j!=1 faire j:=when(even(j),j/2,3j+1); print(j); ftantque;", 0, CAT_CATEGORY_PROG}, - {"taylor(f,x=a,n,[polynom])", 0, "Taylor expansion of f of x at a order n, add parameter polynom to remove remainder term.","sin(x),x=0,5", "sin(x),x=0,5,polynom", CAT_CATEGORY_CALCULUS}, - {"tchebyshev1(n)", 0, "Tchebyshev polynomial 1st kind: cos(n*x)=T_n(cos(x))", "10", 0, CAT_CATEGORY_POLYNOMIAL}, - {"tchebyshev2(n)", 0, "Tchebyshev polynomial 2nd kind: sin((n+1)*x)=sin(x)*U_n(cos(x))", "10", 0, CAT_CATEGORY_POLYNOMIAL}, - {"tcollect(expr)", 0, "Linearize and collect trig functions.","sin(x)+cos(x)", 0, CAT_CATEGORY_TRIG}, - {"texpand(expr)", 0, "Expand trigonometric, exp and ln functions.","sin(3x)", 0, CAT_CATEGORY_TRIG}, - {"time(cmd)", 0, "Time to run a command or set the clock","int(1/(x^4+1),x)","8,0", CAT_CATEGORY_PROG}, - {"tlin(expr)", 0, "Trigonometric linearization of expr.","sin(x)^3", 0, CAT_CATEGORY_TRIG}, - {"tourne_droite n", "tourne_droite ", "Turtle turns right n degrees, n=90 by default", 0, 0, CAT_CATEGORY_LOGO}, - {"tourne_gauche n", "tourne_gauche ", "Turtle turns left n degrees, n=90 by default", 0, 0, CAT_CATEGORY_LOGO}, - {"trace(A)", 0, "Trace of the matrix A.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"transpose(A)", 0, "Transposes matrix A. Transconjugate command is trn(A) or A^*.", "[[1,2],[3,4]]", 0, CAT_CATEGORY_MATRIX}, - {"translation(vect,obj)", 0, "Translate by vect obj", "[1,2],cercle(0,1)", 0, CAT_CATEGORY_2D }, - {"triangle(A,B,C)", 0, "Triangle given by 3 vertices", "1+i,1-i,-1", "A,B,C", CAT_CATEGORY_2D}, - {"triangle_point", "triangle_point", "Display option", "#display=yellow+triangle_point", 0, CAT_CATEGORY_PROGCMD}, - {"trig2exp(expr)", 0, "Convert complex exponentials to trigonometric functions","cos(x)^3", 0, CAT_CATEGORY_TRIG}, - {"trigcos(expr)", 0, "Convert sin^2 and tan^2 to cos^2.","sin(x)^4", 0, CAT_CATEGORY_TRIG}, - {"trigsin(expr)", 0, "Convert cos^2 and tan^2 to sin^2.","cos(x)^4", 0, CAT_CATEGORY_TRIG}, - {"trigtan(expr)", 0, "Convert cos^2 and sin^2 to tan^2.","cos(x)^4", 0, CAT_CATEGORY_TRIG}, - {"uniformd(a,b,x)", "uniformd", "uniform law on [a,b] of density 1/(b-a)", 0, 0, CAT_CATEGORY_PROBA}, - {"vertices(objet)", 0, "List of vertices of a polygon or polyhedra", "triangle(1,i,2)", "cube([0,0,0],[1,0,0],[0,1,0])", CAT_CATEGORY_2D | (CAT_CATEGORY_3D << 8) }, - //{"version", "version()", "Khicas 1.5.0, (c) B. Parisse et al. www-fourier.ujf-grenoble.fr/~parisse\nLicense GPL version 2. Interface adapted from Eigenmath for Casio, G. Maia, http://gbl08ma.com. Do not use if CAS calculators are forbidden.", 0, 0, CAT_CATEGORY_PROGCMD}, - {"write(\"filename\",var)", "write(\"", "Save 1 or more variables in a file. For example f(x):=x^2; write(\"func_f\",f).", 0, 0, CAT_CATEGORY_PROGCMD}, - {"yellow", "yellow", "Display option", "#display=yellow", 0, CAT_CATEGORY_PROGCMD}, - {"|", "|", "Logical or", "#1|2", 0, CAT_CATEGORY_PROGCMD}, - {"~", "~", "Complement", "#~7", 0, CAT_CATEGORY_PROGCMD}, -}; - - const char aide_khicas_string[]="Aide Khicas"; -#ifdef NUMWORKS - const char shortcuts_fr_string[]="Raccourcis clavier (shell et editeur)\nshift-/: %\nalpha shift \": '\nshift--: \\\nshift-ans: completion\nshift-*: factor\nshift-+: normal\nshift-1 a 6: selon bandeau en bas\nshift-7: matrices\nshift-8: complexes\nshift-9:arithmetique entiere\nshift-0: probas\nshift-.: reels\nshift-10^: polynomes\nvar: liste des variables\nans: figure tortue (editeur)\n\nshift-x^y (sto) renvoie =>\n=>+: partfrac\n=>*: factor\n=>sin/cos/tan\n=>=>: solve\n\nShell:\nshift-5: Editeur 2d ou graphique ou texte selon objet\nshift-6: editeur texte\n+ ou - modifie un parametre en surbrillance\n\nEditeur d'expressions\nshift-cut: defaire/refaire (1 fois)\npave directionnel: deplace la selection dans l'arborescence de l'expression\nshift-droit/gauche echange selection avec argument a droite ou a gauche\nalpha-droit/gauche dans une somme ou un produit: augmente la selection avec argument droit ou gauche\nshift-4: Editer selection, shift-5: taille police + ou - grande\nEXE: evaluer la selection\nshift-6: valeur approchee\nBackspace: supprime l'operateur racine de la selection\n\nEditeur de scripts\nEXE: passage a la ligne\nshift-CUT: documentation\nshift COPY (ou shift et deplacement curseur simultanement): marque le debut de la selection, deplacer le curseur vers la fin puis Backspace pour effacer ou shift-COPY pour copier sans effacer. shift-PASTE pour coller.\nHome-6 recherche seule: entrer un mot puis EXE puis EXE. Taper EXE pour l'occurence suivante, Back pour annuler.\nHome-6 remplacer: entrer un mot puis EXE puis le remplacement et EXE. Taper EXE ou Back pour remplacer ou non et passer a l'occurence suivante, AC pour annuler\nOK: tester syntaxe\n\nRaccourcis Graphes:\n+ - zoom\n(-): zoomout selon y\n*: autoscale\n/: orthonormalisation\nOPTN: axes on/off"; - const char shortcuts_en_string[]="Keyboard shortcuts (shell and editor)\nshift-/: %\nalpha shift \": '\nshift--: \\\nshift ans: completion\nshift-*: factor\nshift-+: normal\nshift-1 to 6: cf. screen bottom\nshift-7: matrices\nshift-8: complexes\nshift-9:arithmetic\nshift-0: proba\nshift-.: reals\nshift-10^: polynomials\nvar: variables list\nans: turtle screen (editor)\n\nshift-x^y (sto) returns =>\n=>+: partfrac\n=>*: factor\n=>sin/cos/tan\n=>=>: solve\n\nShell:\nshift-5: 2d editor or graph or text\nshift-6: text edit\n+ ou - modifies selected slider\n\nExpressions editor\nshift-cut: undo/redo (1 fois)\nkeypad: move selection inside expression tree\nshift-right/left exchange selection with right or left argument\nalpha-right/left: inside a sum or product: increase selection with right or left argument\nshift-4: Edit selection, shift-5: change fontsize\nEXE: eval selection\nshift-6: approx value\nBackspace: suppress selection's rootnode operator\n\nScript Editor\nEXE: newline\nshift-CUT: documentation\nshift-COPY: marks selection begin, move the cursor to the end, then hit Backspace to erase or shift-COPY to copy (no erase). shift-PASTE to paste.\nHome-6 search: enter a word then EXE then again EXE. Type EXE for next occurence, Back to cancel.\nHome-6 replace: enter a word then EXE then replacement word then EXE. Type EXE or Back to replace or ignore and go to next occurence, AC to cancel\nOK: test syntax\n\nGraph shortcuts:\n+ - zoom\n(-): zoomout along y\n*: autoscale\n/: orthonormalization\nOPTN: axes on/off"; -#else - const char shortcuts_fr_string[]="Raccourcis clavier (shell et editeur)\nlivre: aide/complete\ntab: complete (shell)/indente (editeur)\nshift-/: %\nshift *: '\nctrl-/: \\\nshift-1 a 6: selon bandeau en bas\nshift-7: matrices\nshift-8: complexes\nshift-9:arithmetique\nshift-0: probas\nshift-.: reels\nctrl P: programme\nvar: liste des variables\nans (shift (-)): figure tortue (editeur)\n\nctrl-var (sto) renvoie =>\n=>+: partfrac\n=>*: factor\n=>sin/cos/tan\n=>=>: solve\n\nShell:\nshift-5: Editeur 2d ou graphique ou texte selon objet\nshift-4: editeur texte\n+ ou - modifie un parametre en surbrillance\n\nEditeur d'expressions\nctrl z: defaire/refaire (1 fois)\npave directionnel: deplace la selection dans l'arborescence de l'expression\nshift-droit/gauche echange selection avec argument a droite ou a gauche\nctrl droit/gauche dans une somme ou un produit: augmente la selection avec argument droit ou gauche\nshift-4: Editer selection, shift-5: taille police + ou - grande\nenter: evaluer la selection\nshift-6: valeur approchee\nDel: supprime l'operateur racine de la selection\n\nEditeur de scripts\nenter: passage a la ligne\nctrl z: defaire/refaire (1 fois)\nctrl c ou shift et touche curseur simultanement: marque le debut de la selection, deplacer le curseur vers la fin puis Del pour effacer ou ctrl c pour copier sans effacer. ctrl v pour coller.\ndoc-6 recherche seule: entrer un mot puis enter puis enter. Taper enter pour l'occurence suivante, esc pour annuler.\ndoc-6 remplacer: entrer un mot puis enter puis le remplacement et enter. Taper enter ou esc pour remplacer ou non et passer a l'occurence suivante, ctrl del pour annuler\nvalidation (a droite de U): tester syntaxe\n\nRaccourcis Graphes:\n+ - zoom\n(-): zoomout selon y\n*: autoscale\n/: orthonormalisation\nOPTN: axes on/off"; - const char shortcuts_en_string[]="Keyboard shortcuts (shell and editor)\nbook: help or completion\ntab: completion (shell), indent (editor)\nshift-/: %\nalpha shift *: '\nctrl-/: \\\nshift-1 a 6: see at bottom\nshift-7: matrices\nshift-8: complexes\nshift-9:arithmetic\nshift-0: probas\nshift-.: reals\nctrl P: program\nvar: variables list\n ans (shift (-)): turtle screen (editor)\n\nctrl var (sto) returns =>\n=>+: partfrac\n=>*: factor\n=>sin/cos/tan\n=>=>: solve\n\nShell:\nshift-5: 2d editor or graph or text\nshift-4: text edit\n+ ou - modifies selected slider\n\nExpressions editor\nctrl z: undo/redo (1 fois)\nkeypad: move selection inside expression tree\nshift-right/left exchange selection with right or left argument\nalpha-right/left: inside a sum or product: increase selection with right or left argument\nshift-4: Edit selection, shift-5: change fontsize\nenter: eval selection\nshift-6: approx value\nDel: suppress selection's rootnode operator\n\nScript Editor\nenter: newline\nctrl z: undo/redo (1 time)\nctrl c or shift + cursor key simultaneously: marks selection begin, move the cursor to the end, then hit Del to erase or ctrl c to copy (no erase). ctrl v to paste.\ndoc-6 search: enter a word then enter then again enter. Type enter for next occurence, esc to cancel.\ndoc-6 replace: enter a word then enter then replacement word then enter. Type enter or esc to replace or ignore and go to next occurence, AC to cancel\nOK: test syntax\n\nGraph shortcuts:\n+ - zoom\n(-): zoomout along y\n*: autoscale\n/: orthonormalization\nOPTN: axes on/off"; -#endif - - const char apropos_fr_string[]="Giac/Xcas 1.6.0, (c) 2020 B. Parisse et R. De Graeve, www-fourier.univ-grenoble-alpes.fr/~parisse.\nKhicas, interface pour calculatrices par B. Parisse, license GPL version 2, adaptee de l'interface d'Eigenmath pour Casio, G. Maia (http://gbl08ma.com), Mike Smith, Nemhardy, LePhenixNoir, ...\nPortage sur Numworks par Damien Nicolet. Remerciements a Jean-Baptiste Boric et Maxime Friess\nPortage sur Nspire grace a Fabian Vogt (firebird-emu, ndless...).\nTable periodique d'apres Maxime Friess\nRemerciements au site tiplanet, en particulier Xavier Andreani, Adrien Bertrand, Lionel Debroux"; - - const char apropos_en_string[]="Giac/Xcas 1.6.0, (c) 2020 B. Parisse et R. De Graeve, www-fourier.univ-grenoble-alpes.fr/~parisse.\nKhicas, calculators interface by B. Parisse, GPL license version 2, adapted from Eigenmath for Casio, G. Maia (http://gbl08ma.com), Mike Smith, Nemhardy, LePhenixNoir, ...\nPorted on Numworks by Damien Nicolet. Thanks to Jean-Baptiste Boric and Maxime Friess\nPorted on Nspire thanks to Fabian Vogt (firebird-emu, ndless...)\nPeriodic table by Maxime Friess\nThanks to tiplanet, especially Xavier Andreani, Adrien Bertrand, Lionel Debroux"; - - const int CAT_COMPLETE_COUNT_FR=sizeof(completeCatfr)/sizeof(catalogFunc); - const int CAT_COMPLETE_COUNT_EN=sizeof(completeCaten)/sizeof(catalogFunc); - - std::string insert_string(int index){ - std::string s; - const catalogFunc * completeCat=(lang==1)?completeCatfr:completeCaten; - if (completeCat[index].insert) - s=completeCat[index].insert; - else { - s=completeCat[index].name; - int pos=s.find('('); - if (pos>=0 && pos=2?as.examples[1].c_str():0; - c.category=-1; - } - int showCatalog(char* insertText,int preselect,int menupos,GIAC_CONTEXT) { - // returns 0 on failure (user exit) and 1 on success (user chose a option) - MenuItem menuitems[CAT_CATEGORY_LOGO+1]; - menuitems[CAT_CATEGORY_ALL].text = (char*)((lang==1)?"Tout":"All"); - menuitems[CAT_CATEGORY_ALGEBRA].text = (char*)((lang==1)?"Algebre":"Algebra"); - menuitems[CAT_CATEGORY_LINALG].text = (char*)((lang==1)?"Algebre lineaire":"Linear algebra"); - menuitems[CAT_CATEGORY_CALCULUS].text = (char*)((lang==1)?"Analyse":"Calculus"); - menuitems[CAT_CATEGORY_ARIT].text = (char*)"Arithmetic, crypto"; - menuitems[CAT_CATEGORY_COMPLEXNUM].text = (char*)"Complexes"; - menuitems[CAT_CATEGORY_PLOT].text = (char*)((lang==1)?"Courbes":"Curves"); - menuitems[CAT_CATEGORY_POLYNOMIAL].text = (char*)((lang==1)?"Polynomes":"Polynomials"); - menuitems[CAT_CATEGORY_PROBA].text = (char*)((lang==1)?"Probabilites":"Probabilities"); - menuitems[CAT_CATEGORY_PROGCMD].text = (char*)((lang==1)?"Programmes cmds (0)":"Program cmds (0)"); - menuitems[CAT_CATEGORY_REAL].text = (char*)((lang==1)?"Reels (e^)":"Reals"); - menuitems[CAT_CATEGORY_SOLVE].text = (char*)((lang==1)?"Resoudre (ln)":"Solve (ln)"); - menuitems[CAT_CATEGORY_STATS].text = (char*)((lang==1)?"Statistiques (log)":"Statistics (log)"); - menuitems[CAT_CATEGORY_TRIG].text = (char*)((lang==1)?"Trigonometrie (i)":"Trigonometry (i)"); - menuitems[CAT_CATEGORY_OPTIONS].text = (char*)"Options (,)"; - menuitems[CAT_CATEGORY_LIST].text = (char*)((lang==1)?"Listes (x^y)":"Lists (x^y)"); - menuitems[CAT_CATEGORY_MATRIX].text = (char*)"Matrices (sin)"; - menuitems[CAT_CATEGORY_PROG].text = (char*)((lang==1)?"Programmes (cos)":"Programs"); - menuitems[CAT_CATEGORY_SOFUS].text = (char*)((lang==1)?"Modifier variables (tan)":"Change variables (tan)"); - menuitems[CAT_CATEGORY_PHYS].text = (char*)((lang==1)?"Constantes physique (pi)":"Physics constants (pi)"); - menuitems[CAT_CATEGORY_UNIT].text = (char*)((lang==1)?"Unites physiques (sqrt)":"Units (sqrt)"); - menuitems[CAT_CATEGORY_2D].text = (char*)((lang==1)?"Geometrie (x^2)":"Geometry (x^2)"); - menuitems[CAT_CATEGORY_3D].text = (char*)((lang==1)?"3D (()":"3D (()"); - menuitems[CAT_CATEGORY_LOGO].text = (char*)((lang==1)?"Tortue ())":"Turtle ())"); - - Menu menu; - menu.items=menuitems; - menu.numitems=sizeof(menuitems)/sizeof(MenuItem); - menu.scrollout=1; - menu.title = (char*)((lang==1)?"Liste de commandes":"Commands list"); - //puts("catalog 1"); - while(1) { - if (preselect) - menu.selection=preselect; - else { - if (menupos>0) - menu.selection=menupos; - int sres = doMenu(&menu); - if (sres != MENU_RETURN_SELECTION && sres!=KEY_CTRL_EXE) - return 0; - } - // puts("catalog 3"); - if(doCatalogMenu(insertText, menuitems[menu.selection-1].text, menu.selection-1,contextptr)) - return 1; - if (preselect) - return 0; - } - return 0; - } - - int showCatalog(char * text,int nmenu,GIAC_CONTEXT){ - return showCatalog(text,0,nmenu,contextptr); - } - - bool isalphanum(char c){ - return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'); - } - - string remove_accents(const string & s){ - string r; - for (int i=0;i0;--l){ - if (!isalphanum(buf[l-1]) && buf[l-1]!='_') - break; - } - // cmdname in buf+l - const char * cmdname=buf+l,*cmdnameorig=cmdname; - l=strlen(cmdname); - // search in catalog: dichotomy would be more efficient - // but leading spaces cmdnames would be missed - int nfunc=(lang==1)?CAT_COMPLETE_COUNT_FR:CAT_COMPLETE_COUNT_EN;//sizeof(completeCat)/sizeof(catalogFunc); -#if defined NSPIRE_NEWLIB || defined NUMWORKS // should match static_help[] in help.cc - int iii=nfunc; // no search in completeCat, directly in static_help.h - //if (xcas_python_eval) iii=0; -#else - int iii=0; -#endif - const catalogFunc * completeCat=(lang==1)?completeCatfr:completeCaten; - for (;iii0 && (completeCat[iii].category & XCAS_ONLY) ) - continue; - const char * name=completeCat[iii].name; - while (*name==' ') - ++name; - int j=0; - for (;j0 && fexamples[i]==';' && fexamples[i-1]!=' '){ - strcpy(fbuf,fexamples); - fbuf[i]=0; - fexamples=fbuf; - frelated=fbuf+i+1; - while (*frelated==' ') - ++frelated; - for (++i;iexample:fexamples; - const char * example2=catf?catf->example2:frelated; - if (exec){ - if (!fsyntax){ - cmdname=example; - example=example2; - } - } - else { - xcas::textArea text; - text.editable=false; - text.clipline=-1; - text.title = (char*)((lang==1)?"Aide sur la commande":"Help on command"); - text.allowF1=true; - text.python=false; - std::vector & elem=text.elements; - elem = std::vector (example2?5:4); - elem[0].s = catf?catf->name:cmdname; - elem[0].newLine = 0; - elem[1].lineSpacing = 0; - if (fsyntax){ - elem[1].newLine = 1; - elem[1].s=(lang==1?"Syntaxe: ":"Syntax: ")+elem[0].s+"("+(strlen(fsyntax)?fsyntax:"arg")+")"; - } - else { - elem[1].newLine = 0; - elem[1].s=elem[0].s; - } - if (cf.size()) - elem[0].s += " (cf. "+cf+")"; - if (elem[0].s.size()<16) - elem[0].s=string(16-elem[0].s.size()/2,' ')+elem[0].s; - //elem[0].color = COLOR_BLUE; - elem[2].newLine = 1; - elem[2].lineSpacing = 1; - elem[2].minimini=1; - std::string autoexample; - if (catf && catf->desc==0){ - // if (token==T_UNARY_OP || token==T_UNARY_OP_38) - elem[2].s=elem[0].s+"(args)"; - } - else { -#ifdef NUMWORKS - elem[2].s = remove_accents(catf?catf->desc:fhowto); -#else - elem[2].s = catf?catf->desc:fhowto; -#endif - } -#ifdef NSPIRE_NEWLIB - std::string ex("tab: "); -#else - std::string ex("Ans: "); -#endif - elem[3].newLine = 1; - elem[3].lineSpacing = 0; - //elem[2].minimini=1; - if (example){ - if (example[0]=='#') - ex += example+1; - else { - if (iii==nfunc) - ex += fexamples; - else { - ex += insert_string(iii); - ex += example; - ex += ")"; - } - } - elem[3].s = ex; - if (example2){ -#ifdef NSPIRE_NEWLIB - string ex2="ret: "; -#else - string ex2="EXE: "; -#endif - if (example2[0]=='#') - ex2 += example2+1; - else { - if (iii==nfunc) - ex2 += example2; - else { - ex2 += insert_string(iii); - ex2 += example2; - ex2 += ")"; - } - } - elem[4].newLine = 1; - // elem[3].lineSpacing = 0; - //elem[3].minimini=1; - elem[4].s=ex2; - } - } - else { - if (autoexample.size()) - elem[3].s=ex+autoexample; - else - elem.pop_back(); - } - exec=doTextArea(&text,contextptr); - } - if (exec==KEY_SHUTDOWN) - return ""; - if (exec==MENU_RETURN_SELECTION){ - while (*cmdname && *cmdname==*cmdnameorig){ - ++cmdname; ++cmdnameorig; - } - return cmdname; - } - if (exec == KEY_CHAR_ANS || exec==KEY_BOOK || exec=='\t' || exec==KEY_CTRL_EXE) { - reset_kbd(); - std::string s; - const char * example=0; - if (exec==KEY_CHAR_ANS || exec==KEY_BOOK || exec=='\t') - example=catf?catf->example:fexamples; - else - example=catf?catf->example2:frelated; - if (example){ - while (*example && *example==*cmdnameorig){ - ++example; ++cmdnameorig; - } - while (*cmdnameorig){ - ++back; - ++cmdnameorig; - } - if (example[0]=='#') - s=example+1; - else { - s += example; - //if (catf && s[s.size()-1]!=')') s += ")"; - } - } - if (python_compat(contextptr)<0 || (python_compat(contextptr) & 4)){ - // replace := by = - for (int i=1;ifirst:(lexer_tab_int_values_begin+curmi)->keyword; -#ifdef MICROPY_LIB - if (xcas_python_eval==1 && xcas::find_color(text,contextptr)!=3){ - ++cur; - continue; - } -#endif - menuitems[curmi].text = (char*) text; - menuitems[curmi].isfolder = allcmds; // assumes allcmds>allopts - menuitems[curmi].token=isall?((builtin_lexer_functions_begin()+curmi)->second.subtype+256):((lexer_tab_int_values_begin+curmi)->subtype+(lexer_tab_int_values_begin+curmi)->return_value*256); - // menuitems[curmi].token=isall?find_or_make_symbol(text,g,0,false,contextptr):((lexer_tab_int_values_begin+curmi)->subtype+(lexer_tab_int_values_begin+curmi)->return_value*256); - for (;i=0){ - size_t st=strlen(text),j=tmp?0:st; - for (;j=100) - lock_alpha(); //SetSetupSetting( (unsigned int)0x14, 0x88); - // DisplayStatusArea(); - menu.scrollout=1; - menu.title = (char *) title; - menu.type = MENUTYPE_FKEYS; - menu.height = 11; - while(1) { - drawRectangle(0,200,LCD_WIDTH_PX,22,giac::_WHITE); -#ifdef NSPIRE_NEWLIB - PrintMini(0,200,(category==CAT_CATEGORY_ALL?"menu: help | ret: ex1 | tab: ex2":"menu: help | ret ex1 | tab ex2"),4,33333,giac::_WHITE); -#else - PrintMini(0,200,(category==CAT_CATEGORY_ALL?"Toolbox help | Ans ex1 | EXE ex2":"Toolbox help | EXE ex1 | Ans ex2"),4,33333,giac::_WHITE); -#endif - int sres = 0; - if (curmi==0){ - do_confirm(lang==1?"Commandes seulement en mode Xcas":"Commands only in Xcas mode"); - sres=MENU_RETURN_EXIT; - } - else - sres=doMenu(&menu); - if (sres==KEY_CTRL_F4 && category!=CAT_CATEGORY_ALL){ - break; - } - if(sres == MENU_RETURN_EXIT){ - reset_kbd(); -#ifdef MENUITEM_MALLOC - free(menuitems); -#endif - return sres; - } - int index=menuitems[menu.selection-1].isfolder; - if(sres == KEY_CTRL_CATALOG || sres==KEY_BOOK) { - const char * example=index & elem=text.elements; - elem = std::vector (example2?4:3); - elem[0].s = index=0 && tab[i]) - g=string2gen(tab[i],false); - return g; - } -#endif -#ifdef MICROPY_LIB - if (xcas_python_eval==1){ - micropy_ck_eval(""); - const char ** tab=(const char **)mp_vars(); - const char **ptr=tab; - for (;*ptr;) - ++ptr; - // del at end should not be sorted - if (ptr-tab>=1 && strcmp(*(ptr-1),"del ")==0) - --ptr; - qsort(tab,ptr-tab,sizeof(char *),trialpha); - if (tab){ - int i=select_item(tab,"VARS",true); - gen g=undef; - if (i>=0 && tab[i]) - g=string2gen(tab[i],false); - free(tab); - return g; - } - } -#endif - gen g(_VARS(0,contextptr)); - if (g.type!=_VECT - //|| g._VECTptr->empty() - ){ - confirm((lang==1)?"Pas de variables. Exemples pour en creer":"No variables. Examples to create",(lang==1)?"a=1 ou f(x):=sin(x^2)":"a=1 or f(x):=sin(x^2)",true); - return undef; - } - vecteur & v=*g._VECTptr; - MenuItem smallmenuitems[v.size()+3]; - vector vs(v.size()+1); - int i,total=0; - const char typ[]="idzDcpiveSfEsFRmuMwgPF"; - for (i=0;iin_eval(0,v[i],w,contextptr,true); -#if 1 - vector vi(9); - tailles(w,vi); - total += vi[8]; - if (vi[8]<400) - vs[i]+=":="+w.print(contextptr); - else { - vs[i] += " ~"; - vs[i] += giac::print_INT_(vi[8]); - vs[i] += ','; - vs[i] += typ[w.type]; - } -#else - if (taille(w,50)<50) - vs[i]+=": "+w.print(contextptr); -#endif - } - smallmenuitems[i].text=(char *) vs[i].c_str(); - } - total += - // giac::syms().capacity()*(sizeof(string)+sizeof(giac::gen)+8)+sizeof(giac::sym_string_tab) + - giac::turtle_stack().capacity()*sizeof(giac::logo_turtle) + - // sizeof(giac::context)+contextptr->tabptr->capacity()*(sizeof(const char *)+sizeof(giac::gen)+8)+ - bytesize(giac::history_in(contextptr))+bytesize(giac::history_out(contextptr)); - vs[i]="purge(~"+giac::print_INT_(total)+')'; - smallmenuitems[i].text=(char *)vs[i].c_str(); - smallmenuitems[i+1].text=(char *)"assume("; - smallmenuitems[i+2].text=(char *)"restart"; - Menu smallmenu; - smallmenu.numitems=v.size()+3; - smallmenu.items=smallmenuitems; - smallmenu.height=12; - smallmenu.scrollbar=1; - smallmenu.scrollout=1; - string vars="Variables"; -#if defined NUMWORKS && defined DEVICE - vars += ", free >= "; - vars += print_INT_(_heap_size-((int)_heap_ptr-(int)_heap_base)); -#endif - smallmenu.title = (char*) vars.c_str(); - //MsgBoxPush(5); - int sres = doMenu(&smallmenu); - //MsgBoxPop(); - if (sres==KEY_CTRL_DEL && smallmenu.selection<=v.size()) - return symbolic(at_purge,v[smallmenu.selection-1]); - if (sres!=MENU_RETURN_SELECTION && sres!=KEY_CTRL_EXE) - return undef; - if (smallmenu.selection==1+v.size()) - return string2gen("purge(",false); - if (smallmenu.selection==2+v.size()) - return string2gen("assume(",false); - if (smallmenu.selection==3+v.size()) - return string2gen("restart",false); - return v[smallmenu.selection-1]; - } - - const char * keytostring(int key,int keyflag,bool py,const giac::context * contextptr){ - const int textsize=512; - static char text[textsize]; - if (key>=0x20 && key<=0x7e){ - text[0]=key; - text[1]=0; - return text; - } - switch (key){ - case KEY_CHAR_PLUS: - return "+"; - case KEY_CHAR_MINUS: - return "-"; - case KEY_CHAR_PMINUS: - return "_"; - case KEY_CHAR_MULT: - return "*"; - case KEY_CHAR_FRAC: - return py?"\\":"solve("; - case KEY_CHAR_DIV: - return "/"; - case KEY_CHAR_POW: - return "^"; - case KEY_CHAR_ROOT: - return "sqrt("; - case KEY_CHAR_SQUARE: - return py?"**2":"^2"; - case KEY_CHAR_CUBEROOT: - return py?"**(1/3)":"^(1/3)"; - case KEY_CHAR_POWROOT: - return py?"**(1/":"^(1/"; - case KEY_CHAR_RECIP: - return py?"**-1":"^-1"; - case KEY_CHAR_THETA: - return "arg("; - case KEY_CHAR_VALR: - return "abs("; - case KEY_CHAR_ANGLE: - return "polar_complex("; - case KEY_CTRL_XTT: - return xthetat?"t":"x"; - case KEY_CHAR_LN: - return "ln("; - case KEY_CHAR_LOG: - return "log10("; - case KEY_CHAR_EXPN10: - return "10^"; - case KEY_CHAR_EXPN: - return "exp("; - case KEY_CHAR_SIN: - return "sin("; - case KEY_CHAR_COS: - return "cos("; - case KEY_CHAR_TAN: - return "tan("; - case KEY_CHAR_ASIN: - return "asin("; - case KEY_CHAR_ACOS: - return "acos("; - case KEY_CHAR_ATAN: - return "atan("; - case KEY_CTRL_MIXEDFRAC: - return "limit("; - case KEY_CTRL_FRACCNVRT: - return "exact("; - // case KEY_CTRL_FORMAT: return "purge("; - case KEY_CTRL_FD: - return "approx("; - case KEY_CHAR_STORE: - // if (keyflag==1) return "inf"; - return "=>"; - case KEY_CHAR_IMGNRY: - return "i"; - case KEY_CHAR_PI: - return "pi"; - case KEY_CTRL_VARS: { - giac::gen var=select_var(contextptr); - if (!giac::is_undef(var)){ - strcpy(text,(var.type==giac::_STRNG?*var._STRNGptr:var.print(contextptr)).c_str()); - return text; - } - return "";//"VARS()"; - } - case KEY_CHAR_EXP: - return "e"; - case KEY_CHAR_ANS: - return "ans()"; - case KEY_CHAR_CROCHETS: - return "[]"; - case KEY_CHAR_ACCOLADES: - return "{}"; - case KEY_CTRL_INS: - return ":="; - case KEY_CHAR_MAT:{ - const char * ptr=xcas::input_matrix(false,contextptr); if (ptr) return ptr; - if (showCatalog(text,17,contextptr)) return text; - return ""; - } - case KEY_CHAR_LIST: { - const char * ptr=xcas::input_matrix(true,contextptr); if (ptr) return ptr; - if (showCatalog(text,16,contextptr)) return text; - return ""; - } - case KEY_CTRL_PRGM: - // open functions catalog, prgm submenu - if(showCatalog(text,18,contextptr)) - return text; - return ""; - case KEY_CTRL_CATALOG: case KEY_BOOK: - if(showCatalog(text,0,contextptr)) - return text; - return ""; - case KEY_CTRL_F4: - if(showCatalog(text,0,contextptr)) - return text; - return ""; - case KEY_CTRL_OPTN: - if(showCatalog(text,15,contextptr)) - return text; - return ""; - case KEY_CTRL_QUIT: - if(showCatalog(text,20,contextptr)) - return text; - return ""; - case KEY_CTRL_PASTE: - return paste_clipboard(); - case KEY_CHAR_DQUATE: - return "\""; - case KEY_CHAR_FACTOR: - return "factor("; - case KEY_CHAR_NORMAL: - return "normal("; - } - return 0; - } - - const char * keytostring(int key,int keyflag,GIAC_CONTEXT){ - return keytostring(key,keyflag,python_compat(contextptr),contextptr); - } - - bool stringtodouble(const string & s1,double & d){ - gen g(s1,context0); - g=evalf(g,1,context0); - if (g.type!=_DOUBLE_){ - confirm("Invalid value",s1.c_str()); - return false; - } - d=g._DOUBLE_val; - return true; - } - - bool inputdouble(const char * msg1,double & d,GIAC_CONTEXT){ - int di=d; - string s1; - if (di==d) - s1=print_INT_(di); - else - s1=print_DOUBLE_(d,3); - inputline(msg1,((lang==1)?"Nouvelle valeur? ":"New value? "),s1,false,65,contextptr); - return stringtodouble(s1,d); - } - - bool inputdouble(const char * msg1,double & d,int ypos,GIAC_CONTEXT){ - int di=d; - string s1; - if (di==d) - s1=print_INT_(di); - else - s1=print_DOUBLE_(d,3); - inputline(msg1,((lang==1)?"Nouvelle valeur? ":"New value? "),s1,false,ypos,contextptr); - return stringtodouble(s1,d); - } - - int inputline(const char * msg1,const char * msg2,string & s,bool numeric,int ypos,GIAC_CONTEXT){ - //s=msg2; - int pos=s.size(),beg=0; - for (;;){ - int X1=print_msg12(msg1,msg2,ypos-30); - int textX=X1,textY=ypos; - drawRectangle(textX,textY,LCD_WIDTH_PX-textX-4,18,COLOR_WHITE); - if (pos-beg>36) - beg=pos-12; - if (int(s.size())-beg<36) - beg=giac::giacmax(0,int(s.size())-36); - if (beg>pos) - beg=pos; - textX=X1; -#if 0 - os_draw_string_(textX,textY,(s.substr(beg,pos-beg)+"|"+s.substr(pos,s.size()-pos)).c_str()); -#else - textX=os_draw_string_(textX,textY+2,s.substr(beg,pos-beg).c_str()); - os_draw_string_(textX,textY+2,s.substr(pos,s.size()-pos).c_str()); - drawRectangle(textX,textY+4,2,13,COLOR_BLACK); // cursor - // PrintMini(0,58," | | | | A<>a | ",4); -#endif - int key; - GetKey(&key); - if (key==KEY_SHUTDOWN) - return key; - // if (!giac::freeze) set_xcas_status(); - if (key==KEY_CTRL_EXE || key==KEY_CTRL_OK) - return KEY_CTRL_EXE; - if (key>=32 && key<128){ - if (!numeric || key=='-' || (key>='0' && key<='9')){ - s.insert(s.begin()+pos,char(key)); - ++pos; - } - continue; - } - if (key==KEY_CHAR_ACCOLADES || key==KEY_CHAR_CROCHETS){ - s.insert(s.begin()+pos,key==KEY_CHAR_ACCOLADES?'}':']'); - s.insert(s.begin()+pos,key==KEY_CHAR_ACCOLADES?'{':'['); - ++pos; - continue; - } - if (key==KEY_CTRL_DEL){ - if (pos){ - s.erase(s.begin()+pos-1); - --pos; - } - continue; - } - if (key==KEY_CTRL_AC){ - if (s=="") - return KEY_CTRL_EXIT; - s=""; - pos=0; - continue; - } - if (key==KEY_CTRL_EXIT) - return key; - if (key==KEY_CTRL_RIGHT){ - if (pos & turtle_stack(){ - static std::vector * ans = 0; - if (!ans){ - // initialize from python app storage - ans=new std::vector(1,(*turtleptr)); - - } - return *ans; - } - - logo_turtle vecteur2turtle(const vecteur & v){ - int s=int(v.size()); - if (s>=5 && v[0].type==_DOUBLE_ && v[1].type==_DOUBLE_ && v[2].type==_DOUBLE_ && v[3].type==_INT_ && v[4].type==_INT_ ){ - logo_turtle t; - t.x=v[0]._DOUBLE_val; - t.y=v[1]._DOUBLE_val; - t.theta=v[2]._DOUBLE_val; - int i=v[3].val; - t.mark=(i%2)!=0; - i=i >> 1; - t.visible=(i%2)!=0; - i=i >> 1; - t.direct = (i%2)!=0; - i=i >> 1; - t.turtle_width = i & 0xff; - i=i >> 8; - t.color = i; - t.radius = v[4].val; - if (s>5 && v[5].type==_INT_) - t.s=v[5].val; - else - t.s=-1; - return t; - } -#ifndef NO_STDEXCEPT - setsizeerr(gettext("vecteur2turtle")); // FIXME -#endif - return logo_turtle(); - } - - static int turtle_status(const logo_turtle & turtle){ - int status= (turtle.color << 11) | ( (turtle.turtle_width & 0xff) << 3) ; - if (turtle.direct) - status += 4; - if (turtle.visible) - status += 2; - if (turtle.mark) - status += 1; - return status; - } - -#if defined NUMWORKS && defined DEVICE - bool ck_turtle_size(){ - vector & v=turtle_stack(); - if (v.size()=2 && v[0].type==_DOUBLE_ && v[1].type==_DOUBLE_){ - vecteur w(v); - int s=int(w.size()); - if (s==2) - w.push_back(double((*turtleptr).theta)); - if (s<4) - w.push_back(turtle_status((*turtleptr))); - if (s<5) - w.push_back(0); - if (w[2].type==_DOUBLE_ && w[3].type==_INT_ && w[4].type==_INT_){ - (*turtleptr)=vecteur2turtle(w); - if (!ck_turtle_size()) - return false; -#ifdef TURTLETAB - turtle_stack_push_back(*turtleptr); -#else - turtle_stack().push_back((*turtleptr)); -#endif - return true; - } - } - return false; - } - - gen turtle2gen(const logo_turtle & turtle){ - return gen(makevecteur(turtle.x,turtle.y,double(turtle.theta),turtle_status(turtle),turtle.radius,turtle.s),_LOGO__VECT); - } - - gen turtle_state(GIAC_CONTEXT){ - return turtle2gen((*turtleptr)); - } - - static gen update_turtle_state(bool clrstring,GIAC_CONTEXT){ -#if defined NUMWORKS && defined DEVICE - if (!ck_turtle_size()){ - if (ctrl_c || interrupted) - return undef; - ctrl_c=true; interrupted=true; - return gensizeerr("Not enough memory"); - } -#else -#ifdef TURTLETAB - if (turtle_stack_size>=MAX_LOGO) - return gensizeerr("Not enough memory"); -#else - if (turtle_stack().size()>=MAX_LOGO){ - ctrl_c=true; interrupted=true; - return gensizeerr("Not enough memory"); - } -#endif -#endif - if (clrstring) - (*turtleptr).s=-1; - (*turtleptr).theta = (*turtleptr).theta - floor((*turtleptr).theta/360)*360; - bool push=true; - if (push){ -#ifdef TURTLETAB - turtle_stack_push_back((*turtleptr)); -#else - if (!turtle_stack().empty()){ - logo_turtle & t=turtle_stack().back(); - if (t.equal_except_nomark(*turtleptr)){ - t.theta=turtleptr->theta; - t.mark=turtleptr->mark; - t.visible=turtleptr->visible; - t.color=turtleptr->color; - push=false; - } - } - turtle_stack().push_back((*turtleptr)); -#endif - } - gen res=turtle_state(contextptr); -#if defined EMCC || defined (EMCC2) // should directly interact with canvas - return gen(turtlevect2vecteur(turtle_stack()),_LOGO__VECT); -#endif - return res; - } - - int turtle_speed=0; - gen _speed(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - if (g.type==_VECT && g._VECTptr->empty()) - return turtle_speed; - if (g.type!=_INT_) - return gensizeerr(contextptr); - int i=g.val; - if (i<0) i=0; - if (i>1000) i=1000; - turtle_speed=i; - return i; - } - static const char _speed_s []="speed"; - static define_unary_function_eval2 (__speed,&_speed,_speed_s,&printastifunction); - define_unary_function_ptr5( at_speed ,alias_at_speed,&__speed,0,T_LOGO); - - gen _avance(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - double i; - if (g.type!=_INT_){ - if (g.type==_VECT) - i=turtle_length; - else { - gen g1=evalf_double(g,1,contextptr); - if (g1.type==_DOUBLE_) - i=g1._DOUBLE_val; - else - return gensizeerr(contextptr); - } - } - else - i=g.val; - (*turtleptr).x += i * std::cos((*turtleptr).theta*deg2rad_d); - (*turtleptr).y += i * std::sin((*turtleptr).theta*deg2rad_d) ; - (*turtleptr).radius = 0; - return update_turtle_state(true,contextptr); - } - static const char _avance_s []="avance"; - static define_unary_function_eval2 (__avance,&_avance,_avance_s,&printastifunction); - define_unary_function_ptr5( at_avance ,alias_at_avance,&__avance,0,T_LOGO); - - static const char _forward_s []="forward"; - static define_unary_function_eval (__forward,&_avance,_forward_s); - define_unary_function_ptr5( at_forward ,alias_at_forward,&__forward,0,true); - - gen _recule(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - if (g.type==_VECT) - return _avance(-turtle_length,contextptr); - return _avance(-g,contextptr); - } - static const char _recule_s []="recule"; - static define_unary_function_eval2 (__recule,&_recule,_recule_s,&printastifunction); - define_unary_function_ptr5( at_recule ,alias_at_recule,&__recule,0,T_LOGO); - - gen _towards(const gen & g,GIAC_CONTEXT){ - // logo instruction - if (g.type!=_VECT || g._VECTptr->size()!=2) - return gensizeerr(contextptr); - gen z=g._VECTptr->front()-(*turtleptr).x+cst_i*(g._VECTptr->back()-(*turtleptr).y); - int m=get_mode_set_radian(contextptr); - z=arg(z,contextptr); - angle_mode(m,contextptr); - return 180/M_PI*z; - } - static const char _towards_s []="towards"; - static define_unary_function_eval2 (__towards,&_towards,_towards_s,&printastifunction); - define_unary_function_ptr5( at_towards ,alias_at_towards,&__towards,0,T_LOGO); - - static const char _backward_s []="backward"; - static define_unary_function_eval (__backward,&_recule,_backward_s); - define_unary_function_ptr5( at_backward ,alias_at_backward,&__backward,0,true); - - gen _position(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - if (g.type!=_VECT) - return makevecteur((*turtleptr).x,(*turtleptr).y); - // return turtle_state(); - vecteur v = *g._VECTptr; - int s=int(v.size()); - if (!s) - return makevecteur((*turtleptr).x,(*turtleptr).y); - v[0]=evalf_double(v[0],1,contextptr); - if (s>1) - v[1]=evalf_double(v[1],1,contextptr); - if (s>2) - v[2]=evalf_double(v[2],1,contextptr); - if (set_turtle_state(v,contextptr)) - return update_turtle_state(true,contextptr); - return zero; - } - static const char _position_s []="position"; - static define_unary_function_eval2 (__position,&_position,_position_s,&printastifunction); - define_unary_function_ptr5( at_position ,alias_at_position,&__position,0,T_LOGO); - - gen _cap(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - gen gg=evalf_double(g,1,contextptr); - if (gg.type!=_DOUBLE_) - return double((*turtleptr).theta); - (*turtleptr).theta=gg._DOUBLE_val; - (*turtleptr).radius = 0; - return update_turtle_state(true,contextptr); - } - static const char _cap_s []="cap"; - static define_unary_function_eval2 (__cap,&_cap,_cap_s,&printastifunction); - define_unary_function_ptr5( at_cap ,alias_at_cap,&__cap,0,T_LOGO); - - static const char _heading_s []="heading"; - static define_unary_function_eval (__heading,&_cap,_heading_s); - define_unary_function_ptr5( at_heading ,alias_at_heading,&__heading,0,true); - - - gen _tourne_droite(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - if (g.type!=_INT_){ - if (g.type==_VECT) - (*turtleptr).theta -= 90; - else { - gen g1=evalf_double(g,1,contextptr); - if (g1.type==_DOUBLE_) - (*turtleptr).theta -= g1._DOUBLE_val; - else - return gensizeerr(contextptr); - } - } - else - (*turtleptr).theta -= g.val; - (*turtleptr).radius = 0; - return update_turtle_state(true,contextptr); - } - static const char _tourne_droite_s []="tourne_droite"; - static define_unary_function_eval2 (__tourne_droite,&_tourne_droite,_tourne_droite_s,&printastifunction); - define_unary_function_ptr5( at_tourne_droite ,alias_at_tourne_droite,&__tourne_droite,0,T_LOGO); - - gen _tourne_gauche(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - if (g.type==_VECT){ - (*turtleptr).theta += 90; - (*turtleptr).radius = 0; - return update_turtle_state(true,contextptr); - } - return _tourne_droite(-g,contextptr); - } - static const char _tourne_gauche_s []="tourne_gauche"; - static define_unary_function_eval2 (__tourne_gauche,&_tourne_gauche,_tourne_gauche_s,&printastifunction); - define_unary_function_ptr5( at_tourne_gauche ,alias_at_tourne_gauche,&__tourne_gauche,0,T_LOGO); - - gen _leve_crayon(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - (*turtleptr).mark = false; - (*turtleptr).radius = 0; - return update_turtle_state(true,contextptr); - } - static const char _leve_crayon_s []="leve_crayon"; - static define_unary_function_eval2 (__leve_crayon,&_leve_crayon,_leve_crayon_s,&printastifunction); - define_unary_function_ptr5( at_leve_crayon ,alias_at_leve_crayon,&__leve_crayon,0,T_LOGO); - - static const char _penup_s []="penup"; - static define_unary_function_eval (__penup,&_leve_crayon,_penup_s); - define_unary_function_ptr5( at_penup ,alias_at_penup,&__penup,0,T_LOGO); - - gen _baisse_crayon(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - (*turtleptr).mark = true; - (*turtleptr).radius = 0; - return update_turtle_state(true,contextptr); - } - static const char _baisse_crayon_s []="baisse_crayon"; - static define_unary_function_eval2 (__baisse_crayon,&_baisse_crayon,_baisse_crayon_s,&printastifunction); - define_unary_function_ptr5( at_baisse_crayon ,alias_at_baisse_crayon,&__baisse_crayon,0,T_LOGO); - - static const char _pendown_s []="pendown"; - static define_unary_function_eval (__pendown,&_baisse_crayon,_pendown_s); - define_unary_function_ptr5( at_pendown ,alias_at_pendown,&__pendown,0,T_LOGO); - - vector * ecrisptr=0; - vector & ecristab(){ - if (!ecrisptr) - ecrisptr=new vector; - return * ecrisptr; - } - gen _ecris(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; -#if 0 //def TURTLETAB - return gensizeerr("String support does not work with static turtle table"); -#endif - // logo instruction - (*turtleptr).radius=14; - if (g.type==_VECT){ - vecteur & v =*g._VECTptr; - int s=int(v.size()); - if (s==2 && v[1].type==_INT_){ - (*turtleptr).radius=absint(v[1].val); - (*turtleptr).s=ecristab().size(); - ecristab().push_back(gen2string(v.front())); - return update_turtle_state(false,contextptr); - } - if (s==4 && v[1].type==_INT_ && v[2].type==_INT_ && v[3].type==_INT_){ - logo_turtle t=(*turtleptr); - _leve_crayon(0,contextptr); - _position(makevecteur(v[2],v[3]),contextptr); - (*turtleptr).radius=absint(v[1].val); - (*turtleptr).s=ecristab().size(); - ecristab().push_back(gen2string(v.front())); - update_turtle_state(false,contextptr); - (*turtleptr)=t; - return update_turtle_state(true,contextptr); - } - } - (*turtleptr).s=ecristab().size(); - ecristab().push_back(gen2string(g)); - return update_turtle_state(false,contextptr); - } - static const char _ecris_s []="ecris"; - static define_unary_function_eval2 (__ecris,&_ecris,_ecris_s,&printastifunction); - define_unary_function_ptr5( at_ecris ,alias_at_ecris,&__ecris,0,T_LOGO); - - gen _signe(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - return _ecris(makevecteur(g,20,10,10),contextptr); - } - static const char _signe_s []="signe"; - static define_unary_function_eval2 (__signe,&_signe,_signe_s,&printastifunction); - define_unary_function_ptr5( at_signe ,alias_at_signe,&__signe,0,T_LOGO); - - gen _saute(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - _leve_crayon(0,contextptr); - _avance(g,contextptr); - return _baisse_crayon(0,contextptr); - } - static const char _saute_s []="saute"; - static define_unary_function_eval2 (__saute,&_saute,_saute_s,&printastifunction); - define_unary_function_ptr5( at_saute ,alias_at_saute,&__saute,0,T_LOGO); - - static const char _jump_s []="jump"; - static define_unary_function_eval2 (__jump,&_saute,_jump_s,&printastifunction); - define_unary_function_ptr5( at_jump ,alias_at_jump,&__jump,0,T_LOGO); - - gen _pas_de_cote(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - _leve_crayon(0,contextptr); - _tourne_droite(-90,contextptr); - _avance(g,contextptr); - _tourne_droite(90,contextptr); - return _baisse_crayon(0,contextptr); - } - static const char _pas_de_cote_s []="pas_de_cote"; - static define_unary_function_eval2 (__pas_de_cote,&_pas_de_cote,_pas_de_cote_s,&printastifunction); - define_unary_function_ptr5( at_pas_de_cote ,alias_at_pas_de_cote,&__pas_de_cote,0,T_LOGO); - - static const char _skip_s []="skip"; - static define_unary_function_eval2 (__skip,&_pas_de_cote,_skip_s,&printastifunction); - define_unary_function_ptr5( at_skip ,alias_at_skip,&__skip,0,T_LOGO); - - gen _cache_tortue(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - (*turtleptr).visible=false; - (*turtleptr).radius = 0; - return update_turtle_state(true,contextptr); - } - static const char _cache_tortue_s []="cache_tortue"; - static define_unary_function_eval2 (__cache_tortue,&_cache_tortue,_cache_tortue_s,&printastifunction); - define_unary_function_ptr5( at_cache_tortue ,alias_at_cache_tortue,&__cache_tortue,0,T_LOGO); - - static const char _hideturtle_s []="hideturtle"; - static define_unary_function_eval (__hideturtle,&_cache_tortue,_hideturtle_s); - define_unary_function_ptr5( at_hideturtle ,alias_at_hideturtle,&__hideturtle,0,true); - - gen _montre_tortue(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - (*turtleptr).visible=true; - (*turtleptr).radius = 0; - return update_turtle_state(true,contextptr); - } - static const char _montre_tortue_s []="montre_tortue"; - static define_unary_function_eval2 (__montre_tortue,&_montre_tortue,_montre_tortue_s,&printastifunction); - define_unary_function_ptr5( at_montre_tortue ,alias_at_montre_tortue,&__montre_tortue,0,T_LOGO); - - static const char _showturtle_s []="showturtle"; - static define_unary_function_eval (__showturtle,&_montre_tortue,_showturtle_s); - define_unary_function_ptr5( at_showturtle ,alias_at_showturtle,&__showturtle,0,true); - - - gen _repete(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - if (g.type!=_VECT || g._VECTptr->size()<2) - return gensizeerr(contextptr); - // logo instruction - vecteur v = *g._VECTptr; - v[0]=eval(v[0],contextptr); - if (v.front().type!=_INT_) - return gentypeerr(contextptr); - gen prog=vecteur(v.begin()+1,v.end()); - int i=absint(v.front().val); - gen res; - for (int j=0;jsize()==3) - return _crayon(_rgb(g,contextptr),contextptr); - if (g.type!=_INT_){ - gen res=(*turtleptr).color; - res.subtype=_INT_COLOR; - return res; - } - if (g.val<0){ - if (g.val<-64) - return (*turtleptr).turtle_width; - (*turtleptr).turtle_width=-g.val; - } - else - (*turtleptr).color=g.val; - (*turtleptr).radius = 0; - return update_turtle_state(true,contextptr); - } - static const char _crayon_s []="crayon"; - static define_unary_function_eval2 (__crayon,&_crayon,_crayon_s,&printastifunction); - define_unary_function_ptr5( at_crayon ,alias_at_crayon,&__crayon,0,T_LOGO); - - static const char _pencolor_s []="pencolor"; - static define_unary_function_eval (__pencolor,&_crayon,_pencolor_s); - define_unary_function_ptr5( at_pencolor ,alias_at_pencolor,&__pencolor,0,T_LOGO); - - gen _efface_logo(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - if (g.type==_INT_){ - _crayon(int(FL_WHITE),contextptr); - _recule(g,contextptr); - return _crayon(0,contextptr); - } - // logo instruction - (*turtleptr) = logo_turtle(); -#ifdef TURTLETAB - turtle_stack_size=0; -#else - turtle_stack().clear(); -#endif - ecristab().clear(); - if (g.type==_VECT && g._VECTptr->size()==2){ - vecteur v = *g._VECTptr; - int s=int(v.size()); - v[0]=evalf_double(v[0],1,contextptr); - if (s>1) - v[1]=evalf_double(v[1],1,contextptr); - (*turtleptr).mark = false; // leve_crayon - (*turtleptr).radius = 0; - update_turtle_state(true,contextptr); - set_turtle_state(v,contextptr); // baisse_crayon - update_turtle_state(true,contextptr); - (*turtleptr).mark = true; - (*turtleptr).radius = 0; - } - return update_turtle_state(true,contextptr); - } - static const char _efface_logo_s []="efface"; - static define_unary_function_eval2 (__efface_logo,&_efface_logo,_efface_logo_s,&printastifunction); - define_unary_function_ptr5( at_efface_logo ,alias_at_efface_logo,&__efface_logo,0,T_LOGO); - - static const char _efface_s []="efface"; - static define_unary_function_eval2 (__efface,&_efface_logo,_efface_s,&printastifunction); - define_unary_function_ptr5( at_efface ,alias_at_efface,&__efface,0,T_LOGO); - - static const char _reset_s []="reset"; - static define_unary_function_eval2 (__reset,&_efface_logo,_reset_s,&printastifunction); - define_unary_function_ptr5( at_reset ,alias_at_reset,&__reset,0,T_LOGO); - - static const char _clearscreen_s []="clearscreen"; - static define_unary_function_eval2 (__clearscreen,&_efface_logo,_clearscreen_s,&printastifunction); - define_unary_function_ptr5( at_clearscreen ,alias_at_clearscreen,&__clearscreen,0,T_LOGO); - - gen _debut_enregistrement(const gen &g,GIAC_CONTEXT){ - return undef; - } - static const char _debut_enregistrement_s []="debut_enregistrement"; - static define_unary_function_eval2 (__debut_enregistrement,&_debut_enregistrement,_debut_enregistrement_s,&printastifunction); - define_unary_function_ptr5( at_debut_enregistrement ,alias_at_debut_enregistrement,&__debut_enregistrement,0,T_LOGO); - - static const char _fin_enregistrement_s []="fin_enregistrement"; - static define_unary_function_eval2 (__fin_enregistrement,&_debut_enregistrement,_fin_enregistrement_s,&printastifunction); - define_unary_function_ptr5( at_fin_enregistrement ,alias_at_fin_enregistrement,&__fin_enregistrement,0,T_LOGO); - - static const char _turtle_stack_s []="turtle_stack"; - static define_unary_function_eval2 (__turtle_stack,&_debut_enregistrement,_turtle_stack_s,&printastifunction); - define_unary_function_ptr5( at_turtle_stack ,alias_at_turtle_stack,&__turtle_stack,0,T_LOGO); - - gen _vers(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - if (g.type!=_VECT || g._VECTptr->size()!=2) - return gensizeerr(contextptr); - gen x=evalf_double(g._VECTptr->front(),1,contextptr), - y=evalf_double(g._VECTptr->back(),1,contextptr); - if (x.type!=_DOUBLE_ || y.type!=_DOUBLE_) - return gensizeerr(contextptr); - double xv=x._DOUBLE_val,yv=y._DOUBLE_val,xt=(*turtleptr).x,yt=(*turtleptr).y; - double theta=atan2(yv-yt,xv-xt); - return _cap(theta*180/M_PI,contextptr); - } - static const char _vers_s []="vers"; - static define_unary_function_eval2 (__vers,&_vers,_vers_s,&printastifunction); - define_unary_function_ptr5( at_vers ,alias_at_vers,&__vers,0,T_LOGO); - - static int find_radius(const gen & g,int & r,int & theta2,bool & direct){ - int radius; - direct=true; - theta2 = 360 ; - // logo instruction - if (g.type==_VECT && !g._VECTptr->empty()){ - vecteur v = *g._VECTptr; - bool seg=false; - if (v.back()==at_segment){ - v.pop_back(); - seg=true; - } - if (v.size()<2) - return RAND_MAX; // setdimerr(contextptr); - if (v[0].type==_INT_) - r=v[0].val; - else { - gen v0=evalf_double(v[0],1,context0); - if (v0.type==_DOUBLE_) - r=int(v0._DOUBLE_val+0.5); - else - return RAND_MAX; // setsizeerr(contextptr); - } - if (r<0){ - r=-r; - direct=false; - } - int theta1; - if (v[1].type==_DOUBLE_) - theta1=int(v[1]._DOUBLE_val+0.5); - else { - if (v[1].type==_INT_) - theta1=v[1].val; - else return RAND_MAX; // setsizeerr(contextptr); - } - while (theta1<0) - theta1 += 360; - if (v.size()>=3){ - if (v[2].type==_DOUBLE_) - theta2 = int(v[2]._DOUBLE_val+0.5); - else { - if (v[2].type==_INT_) - theta2 = v[2].val; - else return RAND_MAX; // setsizeerr(contextptr); - } - while (theta2<0) - theta2 += 360; - radius = giacmin(r,512) | (giacmin(theta1,360) << 9) | (giacmin(theta2,360) << 18 ) | (seg?(1<<28):0); - } - else {// angle 1=0 - theta2 = theta1; - if (theta2<0) - theta2 += 360; - radius = giacmin(r,512) | (giacmin(theta2,360) << 18 ) | (seg?(1<<28):0); - } - return radius; - } - radius = 10; - if (g.type==_INT_) - radius= (r=g.val); - if (g.type==_DOUBLE_) - radius= (r=int(g._DOUBLE_val)); - if (radius<=0){ - radius = -radius; - direct=false; - } - radius = giacmin(radius,512 )+(360 << 18) ; // 2nd angle = 360 degrees - return radius; - } - - static void turtle_move(int r,int theta2,GIAC_CONTEXT){ - double theta0; - if ((*turtleptr).direct) - theta0=(*turtleptr).theta-90; - else { - theta0=(*turtleptr).theta+90; - theta2=-theta2; - } - (*turtleptr).x += r*(std::cos(M_PI/180*(theta2+theta0))-std::cos(M_PI/180*theta0)); - (*turtleptr).y += r*(std::sin(M_PI/180*(theta2+theta0))-std::sin(M_PI/180*theta0)); - (*turtleptr).theta = (*turtleptr).theta+theta2 ; - if ((*turtleptr).theta<0) - (*turtleptr).theta += 360; - if ((*turtleptr).theta>360) - (*turtleptr).theta -= 360; - } - - gen _rond(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - int r,theta2,tmpr; - tmpr=find_radius(g,r,theta2,(*turtleptr).direct); - if (tmpr==RAND_MAX) - return gensizeerr(contextptr); - (*turtleptr).radius=tmpr; - turtle_move(r,theta2,contextptr); - return update_turtle_state(true,contextptr); - } - static const char _rond_s []="rond"; - static define_unary_function_eval2 (__rond,&_rond,_rond_s,&printastifunction); - define_unary_function_ptr5( at_rond ,alias_at_rond,&__rond,0,T_LOGO); - - gen _disque(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - int r,theta2,tmpr=find_radius(g,r,theta2,(*turtleptr).direct); - if (tmpr==RAND_MAX) - return gensizeerr(contextptr); - (*turtleptr).radius=tmpr; - turtle_move(r,theta2,contextptr); - (*turtleptr).radius += 1 << 27; - return update_turtle_state(true,contextptr); - } - static const char _disque_s []="disque"; - static define_unary_function_eval2 (__disque,&_disque,_disque_s,&printastifunction); - define_unary_function_ptr5( at_disque ,alias_at_disque,&__disque,0,T_LOGO); - - gen _disque_centre(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - int r,theta2; - bool direct; - int radius=find_radius(g,r,theta2,direct); - if (radius==RAND_MAX) - return gensizeerr(contextptr); - r=absint(r); - _saute(r,contextptr); - _tourne_gauche(direct?90:-90,contextptr); - (*turtleptr).radius = radius; - (*turtleptr).direct=direct; - turtle_move(r,theta2,contextptr); - (*turtleptr).radius += 1 << 27; - update_turtle_state(true,contextptr); - _tourne_droite(direct?90:-90,contextptr); - return _saute(-r,contextptr); - } - static const char _disque_centre_s []="disque_centre"; - static define_unary_function_eval2 (__disque_centre,&_disque_centre,_disque_centre_s,&printastifunction); - define_unary_function_ptr5( at_disque_centre ,alias_at_disque_centre,&__disque_centre,0,T_LOGO); - - gen _polygone_rempli(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - static int turtle_fill_begin=-1,turtle_fill_color=-1; - if (g.type==_VECT && g._VECTptr->size()==3){ - turtle_fill_color=_rgb(g,contextptr).val; - return change_subtype(turtle_fill_color,_INT_COLOR); - } - if (g.type==_VECT && !g._VECTptr->empty() && g._VECTptr->front().type==_INT_){ - if (g._VECTptr->front().val>=0) - turtle_fill_color= g._VECTptr->front().val; - return change_subtype(turtle_fill_color,_INT_COLOR); - } - if (g.type==_INT_ - //&& g.subtype==_INT_COLOR - ){ - if (g.val<-1 && g.val>-1024){ - (*turtleptr).radius=-absint(g.val); - if ((*turtleptr).radius<-1) - return update_turtle_state(true,contextptr); - } - turtle_fill_color= g.val; - return g; - } - if (g.type!=_VECT && is_zero(g)){ // 0.0 - turtle_fill_begin=turtle_stack().size(); - return 1; - } - if (g.type==_VECT && g._VECTptr->empty()){ - if (turtle_fill_begin<0){ - if (g.subtype==0) - turtle_fill_begin=turtle_stack().size(); - else - return gensizeerr(); - return 1; - } - int c=turtleptr->color; - if (turtle_fill_color>=0) - _crayon(turtle_fill_color,contextptr); - int n=turtle_stack().size()- turtle_fill_begin; - turtle_fill_begin=-1; - turtleptr->radius=-absint(n); - gen res=update_turtle_state(true,contextptr); - if (turtle_fill_color>=0){ - turtleptr->radius=0; - _crayon(c,contextptr); - } - return res; - } - return gensizeerr(gettext("Integer argument >= 2")); - } - static const char _polygone_rempli_s []="polygone_rempli"; - static define_unary_function_eval2 (__polygone_rempli,&_polygone_rempli,_polygone_rempli_s,&printastifunction); - define_unary_function_ptr5( at_polygone_rempli ,alias_at_polygone_rempli,&__polygone_rempli,0,T_LOGO); - - gen _rectangle_plein(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - gen gx=g,gy=g; - if (g.type==_VECT && g._VECTptr->size()==2){ - gx=g._VECTptr->front(); - gy=g._VECTptr->back(); - } - for (int i=0;i<2;++i){ - _avance(gx,contextptr); - _tourne_droite(-90,contextptr); - _avance(gy,contextptr); - _tourne_droite(-90,contextptr); - } - //for (int i=0;isize()>=2){ - vecteur & v=*g._VECTptr; - gx=v.front(); - gy=v[1]; - gtheta=90; - if (v.size()>2) - gtheta=v[2]; - } - logo_turtle t=(*turtleptr); - _avance(gx,contextptr); - double save_x=(*turtleptr).x,save_y=(*turtleptr).y; - _recule(gx,contextptr); - _tourne_gauche(gtheta,contextptr); - _avance(gy,contextptr); - (*turtleptr).x=save_x; - (*turtleptr).y=save_y; - update_turtle_state(true,contextptr); - (*turtleptr)=t; - (*turtleptr).radius=0; - update_turtle_state(true,contextptr); - return _polygone_rempli(-3,contextptr); - } - static const char _triangle_plein_s []="triangle_plein"; - static define_unary_function_eval2 (__triangle_plein,&_triangle_plein,_triangle_plein_s,&printastifunction); - define_unary_function_ptr5( at_triangle_plein ,alias_at_triangle_plein,&__triangle_plein,0,T_LOGO); - - gen _dessine_tortue(const gen & g,GIAC_CONTEXT){ - if ( g.type==_STRNG && g.subtype==-1) return g; - // logo instruction - /* - _triangle_plein(makevecteur(17,5)); - _tourne_droite(90); - _triangle_plein(makevecteur(5,17)); - return _tourne_droite(-90); - */ - double save_x=(*turtleptr).x,save_y=(*turtleptr).y; - _tourne_droite(90,contextptr); - _avance(5,contextptr); - _tourne_gauche(106,contextptr); - _avance(18,contextptr); - _tourne_gauche(148,contextptr); - _avance(18,contextptr); - _tourne_gauche(106,contextptr); - _avance(5,contextptr); - (*turtleptr).x=save_x; (*turtleptr).y=save_y; - gen res(_tourne_gauche(90,contextptr)); - if (is_one(g)) - return res; - return _polygone_rempli(-9,contextptr); - } - static const char _dessine_tortue_s []="dessine_tortue"; - static define_unary_function_eval2 (__dessine_tortue,&_dessine_tortue,_dessine_tortue_s,&printastifunction); - define_unary_function_ptr5( at_dessine_tortue ,alias_at_dessine_tortue,&__dessine_tortue,0,T_LOGO); - -#ifndef NO_NAMESPACE_GIAC -} // namespace giac -#endif // ndef NO_NAMESPACE_GIAC - - -#ifndef NO_NAMESPACE_XCAS -namespace xcas { -#endif // ndef NO_NAMESPACE_XCAS - void drawRectangle(int x,int y,int w,int h,int c){ - draw_rectangle(x,y,w,h,c,context0); - } - void draw_rectangle(int x,int y,int w,int h,int c){ - draw_rectangle(x,y,w,h,c,context0); - } - void draw_line(int x0,int y0,int x1,int y1,int c){ - if (x0==x1){ - if (y0<=y1) - draw_rectangle(x0,y0,1,y1-y0+1,c); - else - draw_rectangle(x0,y1,1,y0-y1+1,c); - } - else { - if (y0==y1){ - if (x0<=x1) - draw_rectangle(x0,y0,x1-x0+1,1,c); - else - draw_rectangle(x1,y0,x0-x1+1,1,c); - } - else - draw_line(x0,y0,x1,y1,c,context0); - } - } - void draw_circle(int xc,int yc,int r,int color,bool q1,bool q2,bool q3,bool q4){ - draw_circle(xc,yc,r,color,q1,q2,q3,q4,context0); - } - void draw_filled_circle(int xc,int yc,int r,int color,bool left,bool right){ - draw_filled_circle(xc,yc,r,color,left,right,context0); - } - void draw_polygon(std::vector< std::vector > & v1,int color){ - draw_polygon(v1,color,context0); - } - void draw_filled_polygon(std::vector< vector > &L,int xmin,int xmax,int ymin,int ymax,int color){ - draw_filled_polygon(L,xmin,xmax,ymin,ymax,color,context0); - } - void draw_arc(int xc,int yc,int rx,int ry,int color,double theta1, double theta2){ - draw_arc(xc,yc,rx,ry,color,theta1,theta2,giac::context0); - } - void draw_filled_arc(int x,int y,int rx,int ry,int theta1_deg,int theta2_deg,int color,int xmin,int xmax,int ymin,int ymax,bool segment){ - draw_filled_arc(x,y,rx,ry,theta1_deg,theta2_deg,color,xmin,xmax,ymin,ymax,segment,context0); - } - - - unsigned max_prettyprint_equation=256; - - // make a free copy of g - gen Equation_copy(const gen & g){ - if (g.type==_EQW) - return *g._EQWptr; - if (g.type!=_VECT) - return g; - vecteur & v = *g._VECTptr; - const_iterateur it=v.begin(),itend=v.end(); - vecteur res; - res.reserve(itend-it); - for (;it!=itend;++it) - res.push_back(Equation_copy(*it)); - return gen(res,g.subtype); - } - - // matrix/list select - bool do_select(gen & eql,bool select,gen & value){ - if (eql.type==_VECT && !eql._VECTptr->empty()){ - vecteur & v=*eql._VECTptr; - size_t s=v.size(); - if (v[s-1].type!=_EQW) - return false; - v[s-1]._EQWptr->selected=select; - gen sommet=v[s-1]._EQWptr->g; - --s; - vecteur args(s); - for (size_t i=0;ig; - } - gen va=s==1?args[0]:gen(args,_SEQ__VECT); - if (sommet.type==_FUNC) - va=symbolic(*sommet._FUNCptr,va); - else - va=sommet(va,context0); - //cout << "va " << va << endl; - value=*v[s]._EQWptr; - value._EQWptr->g=va; - //cout << "value " << value << endl; - return true; - } - if (eql.type!=_EQW) - return false; - eql._EQWptr->selected=select; - value=eql; - return true; - } - - bool Equation_box_sizes(const gen & g,int & l,int & h,int & x,int & y,attributs & attr,bool & selected){ - if (g.type==_EQW){ - eqwdata & w=*g._EQWptr; - x=w.x; - y=w.y; - l=w.dx; - h=w.dy; - selected=w.selected; - attr=w.eqw_attributs; - //cout << g << endl; - return true; - } - else { - if (g.type!=_VECT || g._VECTptr->empty() ){ - l=0; - h=0; - x=0; - y=0; - attr=attributs(0,0,0); - selected=false; - return true; - } - gen & g1=g._VECTptr->back(); - Equation_box_sizes(g1,l,h,x,y,attr,selected); - return false; - } - } - - // return true if g has some selection inside, gsel points to the selection - bool Equation_adjust_xy(gen & g,int & xleft,int & ytop,int & xright,int & ybottom,gen * & gsel,gen * & gselparent,int &gselpos,std::vector * goto_ptr){ - gsel=0; - gselparent=0; - gselpos=0; - int x,y,w,h; - attributs f(0,0,0); - bool selected; - Equation_box_sizes(g,w,h,x,y,f,selected); - if ( (g.type==_EQW__VECT) || selected ){ // terminal or selected - xleft=x; - ybottom=y; - if (selected){ // g is selected - ytop=y+h; - xright=x+w; - gsel = &g; - //cout << "adjust " << *gsel << endl; - return true; - } - else { // no selection - xright=x; - ytop=y; - return false; - } - } - if (g.type!=_VECT) - return false; - // last not selected, recurse - iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end()-1; - for (;it!=itend;++it){ - if (Equation_adjust_xy(*it,xleft,ytop,xright,ybottom,gsel,gselparent,gselpos,goto_ptr)){ - if (goto_ptr){ - goto_ptr->push_back(it-g._VECTptr->begin()); - //cout << g << ":" << *goto_ptr << endl; - } - if (gsel==&*it){ - // check next siblings - - gselparent= &g; - gselpos=it-g._VECTptr->begin(); - //cout << "gselparent " << g << endl; - } - return true; - } - } - return false; - } - - // select or deselect part of the current eqution - // This is done *in place* - void Equation_select(gen & g,bool select){ - if (g.type==_EQW){ - eqwdata & e=*g._EQWptr; - e.selected=select; - } - if (g.type!=_VECT) - return; - vecteur & v=*g._VECTptr; - iterateur it=v.begin(),itend=v.end(); - for (;it!=itend;++it) - Equation_select(*it,select); - } - - // decrease selection (like HP49 eqw Down key) - int eqw_select_down(gen & g){ - int xleft,ytop,xright,ybottom,gselpos; - int newxleft,newytop,newxright,newybottom; - gen * gsel,*gselparent; - if (Equation_adjust_xy(g,xleft,ytop,xright,ybottom,gsel,gselparent,gselpos)){ - //cout << "select down before " << *gsel << endl; - if (gsel->type==_VECT && !gsel->_VECTptr->empty()){ - Equation_select(*gsel,false); - Equation_select(gsel->_VECTptr->front(),true); - //cout << "select down after " << *gsel << endl; - Equation_adjust_xy(g,newxleft,newytop,newxright,newybottom,gsel,gselparent,gselpos); - return newytop-ytop; - } - } - return 0; - } - - int eqw_select_up(gen & g){ - int xleft,ytop,xright,ybottom,gselpos; - int newxleft,newytop,newxright,newybottom; - gen * gsel,*gselparent; - if (Equation_adjust_xy(g,xleft,ytop,xright,ybottom,gsel,gselparent,gselpos) && gselparent){ - Equation_select(*gselparent,true); - //cout << "gselparent " << *gselparent << endl; - Equation_adjust_xy(g,newxleft,newytop,newxright,newybottom,gsel,gselparent,gselpos); - return newytop-ytop; - } - return false; - } - - // exchange==0 move selection to left or right sibling, ==2 add left or right - // sibling, ==1 exchange selection with left or right sibling - int eqw_select_leftright(Equation & eq,bool left,int exchange,GIAC_CONTEXT){ - gen & g=eq.data; - int xleft,ytop,xright,ybottom,gselpos; - int newxleft,newytop,newxright,newybottom; - gen * gsel,*gselparent; - vector goto_sel; - if (Equation_adjust_xy(g,xleft,ytop,xright,ybottom,gsel,gselparent,gselpos,&goto_sel) && gselparent && gselparent->type==_VECT){ - vecteur & gselv=*gselparent->_VECTptr; - int n=gselv.size()-1,gselpos_orig=gselpos; - if (n<1) return 0; - if (left) { - if (gselpos==0) - gselpos=n-1; - else - gselpos--; - } - else { - if (gselpos==n-1) - gselpos=0; - else - gselpos++; - } - if (exchange==1){ // exchange gselpos_orig and gselpos - swapgen(gselv[gselpos],gselv[gselpos_orig]); - gsel=&gselv[gselpos_orig]; - gen value; - if (xcas::do_select(*gsel,true,value) && value.type==_EQW) - replace_selection(eq,value._EQWptr->g,gsel,&goto_sel,contextptr); - } - else { - // increase selection to next sibling possible for + and * only - if (n>2 && exchange==2 && gselv[n].type==_EQW && (gselv[n]._EQWptr->g==at_plus || gselv[n]._EQWptr->g==at_prod)){ - gen value1, value2,tmp; - if (gselpos_origg==at_plus?value1._EQWptr->g+value2._EQWptr->g:value1._EQWptr->g*value2._EQWptr->g; - gselv.erase(gselv.begin()+gselpos_orig); - replace_selection(eq,tmp,&gselv[gselpos],&goto_sel,contextptr); - } - } - else { - Equation_select(*gselparent,false); - gen & tmp=(*gselparent->_VECTptr)[gselpos]; - Equation_select(tmp,true); - } - } - Equation_adjust_xy(g,newxleft,newytop,newxright,newybottom,gsel,gselparent,gselpos); - return newxleft-xleft; - } - return 0; - } - - bool eqw_select(const gen & eq,int l,int c,bool select,gen & value){ - value=undef; - if (l<0 || eq.type!=_VECT || eq._VECTptr->size()<=l) - return false; - gen & eql=(*eq._VECTptr)[l]; - if (c<0) - return do_select(eql,select,value); - if (eql.type!=_VECT || eql._VECTptr->size()<=c) - return false; - gen & eqlc=(*eql._VECTptr)[c]; - return do_select(eqlc,select,value); - } - - gen Equation_compute_size(const gen & g,const attributs & a,int windowhsize,GIAC_CONTEXT); - - // void Bdisp_MMPrint(int x, int y, const char* string, int mode_flags, int xlimit, int P6, int P7, int color, int back_color, int writeflag, int P11); - // void PrintCXY(int x, int y, const char *cptr, int mode_flags, int P5, int color, int back_color, int P8, int P9) - // void PrintMini( int* x, int* y, const char* string, int mode_flags, unsigned int xlimit, int P6, int P7, int color, int back_color, int writeflag, int P11) - void text_print(int fontsize,const char * s,int x,int y,int c=COLOR_BLACK,int bg=COLOR_WHITE,int mode=0){ - // *logptr(contextptr) << x << " " << y << " " << fontsize << " " << s << endl; return; - c=(unsigned short) c; - if (mode==4 && c==COLOR_BLACK && bg==COLOR_WHITE){ - bg=color_gris; - mode=0; - } - if (x>LCD_WIDTH_PX) return; - int ss=strlen(s); - if (ss==1 && s[0]==0x1e){ // arrow for limit - if (mode==4) - c=bg; - draw_line(x,y-4,x+fontsize/2,y-4,c); - draw_line(x,y-3,x+fontsize/2,y-3,c); - draw_line(x+fontsize/2-4,y,x+fontsize/2,y-4,c); - draw_line(x+fontsize/2-3,y,x+fontsize/2+1,y-4,c); - draw_line(x+fontsize/2-4,y-7,x+fontsize/2,y-3,c); - draw_line(x+fontsize/2-3,y-7,x+fontsize/2+1,y-3,c); - return; - } - if (ss==2 && strcmp(s,"pi")==0){ - if (mode==4){ - drawRectangle(x,y+2-fontsize,fontsize,fontsize,c); - c=bg; - } - draw_line(x+fontsize/3-1,y+1,x+fontsize/3,y+6-fontsize,c); - draw_line(x+fontsize/3-2,y+1,x+fontsize/3-1,y+6-fontsize,c); - draw_line(x+2*fontsize/3,y+1,x+2*fontsize/3,y+6-fontsize,c); - draw_line(x+2*fontsize/3+1,y+1,x+2*fontsize/3+1,y+6-fontsize,c); - draw_line(x+2,y+6-fontsize,x+fontsize,y+6-fontsize,c); - draw_line(x+2,y+5-fontsize,x+fontsize,y+5-fontsize,c); - return; - } - if (fontsize>=16 && ss==2 && s[0]==char(0xe5) && (s[1]==char(0xea) || s[1]==char(0xeb))) // special handling for increasing and decreasing in tabvar output - fontsize=18; - if (fontsize>=18){ - y -= 16;// status area shift - os_draw_string(x,y,mode==4?bg:c,mode==4?c:bg,s); - // PrintMini(&x,&y,(unsigned char *)s,mode,0xffffffff,0,0,c,bg,1,0); - return; - } - y -= 12; - x=os_draw_string_small(x,y,mode==4?bg:c,mode==4?c:bg,s);// PrintMiniMini( &x, &y, (unsigned char *)s, mode,c, 0 ); - return; - } - - int text_width(int fontsize,const char * s){ -#ifdef NSPIRE_NEWLIB - int x=0; - if (fontsize>=18) - x=os_draw_string(0,0,0,1,s,true); - else - x=os_draw_string_small(0,0,0,1,s,true); - return x; -#else - if (fontsize>=18) - return strlen(s)*11; - return strlen(s)*7; -#endif - } - - void fl_arc(int x,int y,int rx,int ry,int theta1_deg,int theta2_deg,int c=COLOR_BLACK){ - rx/=2; - ry/=2; - // *logptr(contextptr) << "theta " << theta1_deg << " " << theta2_deg << endl; - if (ry==rx){ - if (theta2_deg-theta1_deg==360){ - draw_circle(x+rx,y+rx,rx,c); - return; - } - if (theta1_deg==0 && theta2_deg==180){ - draw_circle(x+rx,y+rx,rx,c,true,true,false,false); - return; - } - if (theta1_deg==180 && theta2_deg==360){ - draw_circle(x+rx,y+rx,rx,c,false,false,true,true); - return; - } - } - // *logptr(contextptr) << "draw_arc" << theta1_deg*M_PI/180. << " " << theta2_deg*M_PI/180. << endl; - draw_arc(x+rx,y+ry,rx,ry,c,theta1_deg*M_PI/180.,theta2_deg*M_PI/180.,context0); - } - - void fl_pie(int x,int y,int rx,int ry,int theta1_deg,int theta2_deg,int c=COLOR_BLACK,bool segment=false){ - //cout << "fl_pie " << theta1_deg << " " << theta2_deg << " " << c << endl; - if (!segment && ry==rx){ - if (theta2_deg-theta1_deg>=360){ - rx/=2; - draw_filled_circle(x+rx,y+rx,rx,c); - return; - } - if (theta1_deg==-90 && theta2_deg==90){ - rx/=2; - draw_filled_circle(x+rx,y+rx,rx,c,false,true); - return; - } - if (theta1_deg==90 && theta2_deg==270){ - rx/=2; - draw_filled_circle(x+rx,y+rx,rx,c,true,false); - return; - } - } - // approximation by a filled polygon - // points: (x,y), (x+rx*cos(theta)/2,y+ry*sin(theta)/2) theta=theta1..theta2 - while (theta2_deg=360){ - theta1_deg=0; - theta2_deg=360; - } - int N0=theta2_deg-theta1_deg+1; - // reduce N if rx or ry is small - double red=double(rx)/LCD_WIDTH_PX*double(ry)/LCD_HEIGHT_PX; - if (red>1) red=1; - if (red<0.1) red=0.1; - int N=red*N0; - if (N<5) - N=N0>5?5:N0; - if (N<2) - N=2; - vector< vector > v(segment?N+1:N+2,vector(2)); - x += rx/2; - y += ry/2; - int i=0; - if (!segment){ - v[0][0]=x; - v[0][1]=y; - ++i; - } - double theta=theta1_deg*M_PI/180; - double thetastep=(theta2_deg-theta1_deg)*M_PI/(180*(N-1)); - for (;iempty()) - return eqwdata(0,0,0,0,attributs(0,0,0),undef); - return Equation_total_size(g._VECTptr->back()); - } - - // find smallest value of y and height - void Equation_y_dy(const gen & g,int & y,int & dy){ - y=0; dy=0; - if (g.type==_EQW){ - y=g._EQWptr->y; - dy=g._EQWptr->dy; - } - if (g.type==_VECT){ - iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end(); - for (;it!=itend;++it){ - int Y,dY; - Equation_y_dy(*it,Y,dY); - // Y, Y+dY and y,y+dy - int ymax=giacmax(y+dy,Y+dY); - if (Yx += deltax; - g._EQWptr->y += deltay; - g._EQWptr->baseline += deltay; - return ; - } - if (g.type!=_VECT) - setsizeerr(); - vecteur & v=*g._VECTptr; - iterateur it=v.begin(),itend=v.end(); - for (;it!=itend;++it) - Equation_translate(*it,deltax,deltay); - } - - gen Equation_change_attributs(const gen & g,const attributs & newa){ - if (g.type==_EQW){ - gen res(*g._EQWptr); - res._EQWptr->eqw_attributs = newa; - return res; - } - if (g.type!=_VECT) - return gensizeerr(); - vecteur v=*g._VECTptr; - iterateur it=v.begin(),itend=v.end(); - for (;it!=itend;++it) - *it=Equation_change_attributs(*it,newa); - return gen(v,g.subtype); - } - - vecteur Equation_subsizes(const gen & arg,const attributs & a,int windowhsize,GIAC_CONTEXT){ - vecteur v; - if ( (arg.type==_VECT) && ( (arg.subtype==_SEQ__VECT) - // || (!ckmatrix(arg)) - ) ){ - const_iterateur it=arg._VECTptr->begin(),itend=arg._VECTptr->end(); - for (;it!=itend;++it) - v.push_back(Equation_compute_size(*it,a,windowhsize,contextptr)); - } - else { - v.push_back(Equation_compute_size(arg,a,windowhsize,contextptr)); - } - return v; - } - - // vertical merge with same baseline - // for vertical merge of hp,yp at top (like ^) add fontsize to yp - // at bottom (like lower bound of int) subtract fontsize from yp - void Equation_vertical_adjust(int hp,int yp,int & h,int & y){ - int yf=min(y,yp); - h=max(y+h,yp+hp)-yf; - y=yf; - } - - gen Equation_compute_symb_size(const gen & g,const attributs & a,int windowhsize,GIAC_CONTEXT){ - if (g.type!=_SYMB) - return Equation_compute_size(g,a,windowhsize,contextptr); - unary_function_ptr & u=g._SYMBptr->sommet; - gen arg=g._SYMBptr->feuille,rootof_value; - if (u==at_makevector){ - vecteur v(1,arg); - if (arg.type==_VECT) - v=*arg._VECTptr; - iterateur it=v.begin(),itend=v.end(); - for (;it!=itend;++it){ - if ( (it->type==_SYMB) && (it->_SYMBptr->sommet==at_makevector) ) - *it=_makevector(it->_SYMBptr->feuille,contextptr); - } - return Equation_compute_size(v,a,windowhsize,contextptr); - } - if (u==at_makesuite){ - if (arg.type==_VECT) - return Equation_compute_size(gen(*arg._VECTptr,_SEQ__VECT),a,windowhsize,contextptr); - else - return Equation_compute_size(arg,a,windowhsize,contextptr); - } - if (u==at_sqrt) - return Equation_compute_size(symb_pow(arg,plus_one_half),a,windowhsize,contextptr); - if (u==at_division){ - if (arg.type!=_VECT || arg._VECTptr->size()!=2) - return Equation_compute_size(arg,a,windowhsize,contextptr); - gen tmp=Tfraction(arg._VECTptr->front(),arg._VECTptr->back()); - return Equation_compute_size(tmp,a,windowhsize,contextptr); - } - if (u==at_prod){ - gen n,d; - if (rewrite_prod_inv(arg,n,d)){ - if (n.is_symb_of_sommet(at_neg)) - return Equation_compute_size(symbolic(at_neg,Tfraction(-n,d)),a,windowhsize,contextptr); - return Equation_compute_size(Tfraction(n,d),a,windowhsize,contextptr); - } - } - if (u==at_inv){ - if ( (is_integer(arg) && is_positive(-arg,contextptr)) - || (arg.is_symb_of_sommet(at_neg))) - return Equation_compute_size(symbolic(at_neg,Tfraction(plus_one,-arg)),a,windowhsize,contextptr); - return Equation_compute_size(Tfraction(plus_one,arg),a,windowhsize,contextptr); - } - if (u==at_expr && arg.type==_VECT && arg.subtype==_SEQ__VECT && arg._VECTptr->size()==2 && arg._VECTptr->back().type==_INT_){ - gen varg1=Equation_compute_size(arg._VECTptr->front(),a,windowhsize,contextptr); - eqwdata vv(Equation_total_size(varg1)); - gen varg2=eqwdata(0,0,0,0,a,arg._VECTptr->back()); - vecteur v12(makevecteur(varg1,varg2)); - v12.push_back(eqwdata(vv.dx,vv.dy,0,vv.y,a,at_expr,0)); - return gen(v12,_SEQ__VECT); - } - int llp=int(text_width(a.fontsize,("(")))-1; - int lrp=llp; - int lc=int(text_width(a.fontsize,(","))); - string us=u.ptr()->s; - int ls=int(text_width(a.fontsize,(us.c_str()))); - // if (isalpha(u.ptr()->s[0])) ls += 1; - if (u==at_abs) - ls = 2; - // special cases first int, sigma, /, ^ - // and if printed as printsommetasoperator - // otherwise print with usual functional notation - int x=0; - int h=a.fontsize; - int y=0; -#if 1 - if ((u==at_integrate) || (u==at_sum) ){ // Int - int s=1; - if (arg.type==_VECT) - s=arg._VECTptr->size(); - else - arg=vecteur(1,arg); - // s==1 -> general case - if ( (s==1) || (s==2) ){ // int f(x) dx and sum f(n) n - vecteur v(Equation_subsizes(gen(*arg._VECTptr,_SEQ__VECT),a,windowhsize,contextptr)); - eqwdata vv(Equation_total_size(v[0])); - if (s==1){ - x=a.fontsize; - Equation_translate(v[0],x,0); - x += int(text_width(a.fontsize,(" dx"))); - } - if (s==2){ - if (u==at_integrate){ - x=a.fontsize; - Equation_translate(v[0],x,0); - x += vv.dx+int(text_width(a.fontsize,(" d"))); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - vv=Equation_total_size(v[1]); - Equation_translate(v[1],x,0); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - } - else { - Equation_vertical_adjust(vv.dy,vv.y,h,y); - eqwdata v1=Equation_total_size(v[1]); - x=max((int)a.fontsize,(int)v1.dx)+2*a.fontsize/3; // var name size - Equation_translate(v[1],0,-v1.dy-v1.y); - Equation_vertical_adjust(v1.dy,-v1.dy,h,y); - Equation_translate(v[0],x,0); - x += vv.dx; // add function size - } - } - if (u==at_integrate){ - x += vv.dx; - if (h==a.fontsize) - h+=2*a.fontsize/3; - if (y==0){ - y=-2*a.fontsize/3; - h+=2*a.fontsize/3; - } - } - v.push_back(eqwdata(x,h,0,y,a,u,0)); - return gen(v,_SEQ__VECT); - } - if (s>=3){ // int _a^b f(x) dx - vecteur & intarg=*arg._VECTptr; - gen tmp_l,tmp_u,tmp_f,tmp_x; - attributs aa(a); - if (a.fontsize>=10) - aa.fontsize -= 2; - tmp_f=Equation_compute_size(intarg[0],a,windowhsize,contextptr); - tmp_x=Equation_compute_size(intarg[1],a,windowhsize,contextptr); - tmp_l=Equation_compute_size(intarg[2],aa,windowhsize,contextptr); - if (s==4) - tmp_u=Equation_compute_size(intarg[3],aa,windowhsize,contextptr); - x=a.fontsize+(u==at_integrate?-2:+4); - eqwdata vv(Equation_total_size(tmp_l)); - Equation_translate(tmp_l,x,-vv.y-vv.dy); - vv=Equation_total_size(tmp_l); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - int lx = vv.dx; - if (s==4){ - vv=Equation_total_size(tmp_u); - Equation_translate(tmp_u,x,a.fontsize-3-vv.y); - vv=Equation_total_size(tmp_u); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - } - x += max(lx,(int)vv.dx); - Equation_translate(tmp_f,x,0); - vv=Equation_total_size(tmp_f); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - if (u==at_integrate){ - x += vv.dx+int(text_width(a.fontsize,(" d"))); - Equation_translate(tmp_x,x,0); - vv=Equation_total_size(tmp_x); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - x += vv.dx; - } - else { - x += vv.dx; - Equation_vertical_adjust(vv.dy,vv.y,h,y); - vv=Equation_total_size(tmp_x); - x=max(x,(int)vv.dx)+a.fontsize/3; - Equation_translate(tmp_x,0,-vv.dy-vv.y); - //Equation_translate(tmp_l,0,-1); - if (s==4) Equation_translate(tmp_u,-2,0); - Equation_vertical_adjust(vv.dy,-vv.dy,h,y); - } - vecteur res(makevecteur(tmp_f,tmp_x,tmp_l)); - if (s==4) - res.push_back(tmp_u); - res.push_back(eqwdata(x,h,0,y,a,u,0)); - return gen(res,_SEQ__VECT); - } - } - if (u==at_limit && arg.type==_VECT){ // limit - vecteur limarg=*arg._VECTptr; - int s=limarg.size(); - if (s==2 && limarg[1].is_symb_of_sommet(at_equal)){ - limarg.push_back(limarg[1]._SYMBptr->feuille[1]); - limarg[1]=limarg[1]._SYMBptr->feuille[0]; - ++s; - } - if (s>=3){ - gen tmp_l,tmp_f,tmp_x,tmp_dir; - attributs aa(a); - if (a.fontsize>=10) - aa.fontsize -= 2; - tmp_f=Equation_compute_size(limarg[0],a,windowhsize,contextptr); - tmp_x=Equation_compute_size(limarg[1],aa,windowhsize,contextptr); - tmp_l=Equation_compute_size(limarg[2],aa,windowhsize,contextptr); - if (s==4) - tmp_dir=Equation_compute_size(limarg[3],aa,windowhsize,contextptr); - eqwdata vf(Equation_total_size(tmp_f)); - eqwdata vx(Equation_total_size(tmp_x)); - eqwdata vl(Equation_total_size(tmp_l)); - eqwdata vdir(Equation_total_size(tmp_dir)); - int sous=max(vx.dy,vl.dy); - if (s==4) - Equation_translate(tmp_f,vx.dx+vl.dx+vdir.dx+a.fontsize+4,0); - else - Equation_translate(tmp_f,vx.dx+vl.dx+a.fontsize+2,0); - Equation_translate(tmp_x,0,-sous-vl.y); - Equation_translate(tmp_l,vx.dx+a.fontsize+2,-sous-vl.y); - if (s==4) - Equation_translate(tmp_dir,vx.dx+vl.dx+a.fontsize+4,-sous-vl.y); - h=vf.dy; - y=vf.y; - vl=Equation_total_size(tmp_l); - Equation_vertical_adjust(vl.dy,vl.y,h,y); - vecteur res(makevecteur(tmp_f,tmp_x,tmp_l)); - if (s==4){ - res.push_back(tmp_dir); - res.push_back(eqwdata(vf.dx+vx.dx+a.fontsize+4+vl.dx+vdir.dx,h,0,y,a,u,0)); - } - else - res.push_back(eqwdata(vf.dx+vx.dx+a.fontsize+2+vl.dx,h,0,y,a,u,0)); - return gen(res,_SEQ__VECT); - } - } -#endif - if ( (u==at_of || u==at_at) && arg.type==_VECT && arg._VECTptr->size()==2 ){ - // user function, function in 1st arg, arguments in 2nd arg - gen varg1=Equation_compute_size(arg._VECTptr->front(),a,windowhsize,contextptr); - eqwdata vv=Equation_total_size(varg1); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - gen arg2=arg._VECTptr->back(); - if (u==at_at && xcas_mode(contextptr)!=0){ - if (arg2.type==_VECT) - arg2=gen(addvecteur(*arg2._VECTptr,vecteur(arg2._VECTptr->size(),plus_one)),_SEQ__VECT); - else - arg2=arg2+plus_one; - } - gen varg2=Equation_compute_size(arg2,a,windowhsize,contextptr); - Equation_translate(varg2,vv.dx+llp,0); - vv=Equation_total_size(varg2); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - vecteur res(makevecteur(varg1,varg2)); - res.push_back(eqwdata(vv.dx+vv.x+lrp,h,0,y,a,u,0)); - return gen(res,_SEQ__VECT); - } - if (u==at_pow){ - // first arg not translated - gen varg=Equation_compute_size(arg._VECTptr->front(),a,windowhsize,contextptr); - eqwdata vv=Equation_total_size(varg); - // 1/2 ->sqrt, otherwise as exponent - if (arg._VECTptr->back()==plus_one_half){ - Equation_translate(varg,a.fontsize,0); - vecteur res(1,varg); - res.push_back(eqwdata(vv.dx+a.fontsize,vv.dy+4,vv.x,vv.y,a,at_sqrt,0)); - return gen(res,_SEQ__VECT); - } - bool needpar=vv.g.type==_FUNC || vv.g.is_symb_of_sommet(at_pow) || need_parenthesis(vv.g); - if (needpar) - x=llp; - Equation_translate(varg,x,0); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - vecteur res(1,varg); - // 2nd arg translated - if (needpar) - x+=vv.dx+lrp; - else - x+=vv.dx+1; - int arg1dy=vv.dy,arg1y=vv.y; - if (a.fontsize>=16){ - attributs aa(a); - aa.fontsize -= 2; - varg=Equation_compute_size(arg._VECTptr->back(),aa,windowhsize,contextptr); - } - else - varg=Equation_compute_size(arg._VECTptr->back(),a,windowhsize,contextptr); - vv=Equation_total_size(varg); - Equation_translate(varg,x,arg1y+(3*arg1dy)/4-vv.y); - res.push_back(varg); - vv=Equation_total_size(varg); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - x += vv.dx; - res.push_back(eqwdata(x,h,0,y,a,u,0)); - return gen(res,_SEQ__VECT); - } - if (u==at_factorial){ - vecteur v; - gen varg=Equation_compute_size(arg,a,windowhsize,contextptr); - eqwdata vv=Equation_total_size(varg); - bool paren=need_parenthesis(vv.g) || vv.g==at_prod || vv.g==at_division || vv.g==at_pow; - if (paren) - x+=llp; - Equation_translate(varg,x,0); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - v.push_back(varg); - x += vv.dx; - if (paren) - x+=lrp; - varg=eqwdata(x+4,h,0,y,a,u,0); - v.push_back(varg); - return gen(v,_SEQ__VECT); - } - if (u==at_sto){ // A:=B, *it -> B - gen varg=Equation_compute_size(arg._VECTptr->back(),a,windowhsize,contextptr); - eqwdata vv=Equation_total_size(varg); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - Equation_translate(varg,x,0); - vecteur v(2); - v[1]=varg; - x+=vv.dx; - x+=ls+3; - // first arg not translated - varg=Equation_compute_size(arg._VECTptr->front(),a,windowhsize,contextptr); - vv=Equation_total_size(varg); - if (need_parenthesis(vv.g)) - x+=llp; - Equation_translate(varg,x,0); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - v[0]=varg; - x += vv.dx; - if (need_parenthesis(vv.g)) - x+=lrp; - v.push_back(eqwdata(x,h,0,y,a,u,0)); - return gen(v,_SEQ__VECT); - } - if (u==at_program && arg._VECTptr->back().type!=_VECT && !arg._VECTptr->back().is_symb_of_sommet(at_local) ){ - gen varg=Equation_compute_size(arg._VECTptr->front(),a,windowhsize,contextptr); - eqwdata vv=Equation_total_size(varg); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - Equation_translate(varg,x,0); - vecteur v(2); - v[0]=varg; - x+=vv.dx; - x+=int(text_width(a.fontsize,("->")))+3; - varg=Equation_compute_size(arg._VECTptr->back(),a,windowhsize,contextptr); - vv=Equation_total_size(varg); - Equation_translate(varg,x,0); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - v[1]=varg; - x += vv.dx; - v.push_back(eqwdata(x,h,0,y,a,u,0)); - return gen(v,_SEQ__VECT); - } - bool binaryop= (u.ptr()->printsommet==&printsommetasoperator) || binary_op(u); - if ( u!=at_sto && u.ptr()->printsommet!=NULL && !binaryop ){ - gen tmp=string2gen(g.print(contextptr),false); - return Equation_compute_size(symbolic(at_expr,makesequence(tmp,xcas_mode(contextptr))),a,windowhsize,contextptr); - } - vecteur v; - if (!binaryop || arg.type!=_VECT) - v=Equation_subsizes(arg,a,windowhsize,contextptr); - else - v=Equation_subsizes(gen(*arg._VECTptr,_SEQ__VECT),a,windowhsize,contextptr); - iterateur it=v.begin(),itend=v.end(); - if ( it==itend || (itend-it==1) ){ - gen gtmp; - if (it==itend) - gtmp=Equation_compute_size(gen(vecteur(0),_SEQ__VECT),a,windowhsize,contextptr); - else - gtmp=*it; - // unary op, shift arg position horizontally - eqwdata vv=Equation_total_size(gtmp); - bool paren = u!=at_neg || (vv.g!=at_prod && need_parenthesis(vv.g)) ; - x=ls+(paren?llp:0); - gen tmp=gtmp; Equation_translate(tmp,x,0); - x=x+vv.dx+(paren?lrp:0); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - return gen(makevecteur(tmp,eqwdata(x,h,0,y,a,u,0)),_EQW__VECT); - } - if (binaryop){ // op (default with par) - int currenth=h,largeur=0; - iterateur itprec=v.begin(); - h=0; - if (u==at_plus){ // op without parenthesis - if (it->type==_VECT && !it->_VECTptr->empty() && it->_VECTptr->back().type==_EQW && it->_VECTptr->back()._EQWptr->g==at_equal) - ; - else { - llp=0; - lrp=0; - } - } - for (;;){ - eqwdata vv=Equation_total_size(*it); - if (need_parenthesis(vv.g)) - x+=llp; - if (u==at_plus && it!=v.begin() && - ( - (it->type==_VECT && it->_VECTptr->back().type==_EQW && it->_VECTptr->back()._EQWptr->g==at_neg) - || - ( it->type==_EQW && (is_integer(it->_EQWptr->g) || it->_EQWptr->g.type==_DOUBLE_) && is_strictly_positive(-it->_EQWptr->g,contextptr) ) - ) - ) - x -= ls; -#if 0 // - if (x>windowhsize-vv.dx && x>windowhsize/2 && (itend-it)*vv.dx>windowhsize/2){ - largeur=max(x,largeur); - x=0; - if (need_parenthesis(vv.g)) - x+=llp; - h+=currenth; - Equation_translate(*it,x,0); - for (iterateur kt=v.begin();kt!=itprec;++kt) - Equation_translate(*kt,0,currenth); - if (y){ - for (iterateur kt=itprec;kt!=it;++kt) - Equation_translate(*kt,0,-y); - } - itprec=it; - currenth=vv.dy; - y=vv.y; - } - else -#endif - { - Equation_translate(*it,x,0); - vv=Equation_total_size(*it); - Equation_vertical_adjust(vv.dy,vv.y,currenth,y); - } - x+=vv.dx; - if (need_parenthesis(vv.g)) - x+=lrp; - ++it; - if (it==itend){ - for (iterateur kt=v.begin();kt!=itprec;++kt) - Equation_translate(*kt,0,currenth+y); - h+=currenth; - v.push_back(eqwdata(max(x,largeur),h,0,y,a,u,0)); - //cout << v << endl; - return gen(v,_SEQ__VECT); - } - x += ls+3; - } - } - // normal printing - x=ls+llp; - for (;;){ - eqwdata vv=Equation_total_size(*it); - Equation_translate(*it,x,0); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - x+=vv.dx; - ++it; - if (it==itend){ - x+=lrp; - v.push_back(eqwdata(x,h,0,y,a,u,0)); - return gen(v,_SEQ__VECT); - } - x+=lc; - } - } - - // windowhsize is used for g of type HIST__VECT (history) right justify answers - // Returns either a eqwdata type object (terminal) or a vector - // (of subtype _EQW__VECT or _HIST__VECT) - gen Equation_compute_size(const gen & g,const attributs & a,int windowhsize,GIAC_CONTEXT){ - /***************** - * FRACTIONS * - *****************/ - if (g.type==_FRAC){ - if (is_integer(g._FRACptr->num) && is_positive(-g._FRACptr->num,contextptr)) - return Equation_compute_size(symbolic(at_neg,fraction(-g._FRACptr->num,g._FRACptr->den)),a,windowhsize,contextptr); - gen v1=Equation_compute_size(g._FRACptr->num,a,windowhsize,contextptr); - eqwdata vv1=Equation_total_size(v1); - gen v2=Equation_compute_size(g._FRACptr->den,a,windowhsize,contextptr); - eqwdata vv2=Equation_total_size(v2); - // Center the fraction - int w1=vv1.dx,w2=vv2.dx; - int w=max(w1,w2)+6; - vecteur v(3); - v[0]=v1; Equation_translate(v[0],(w-w1)/2,11-vv1.y); - v[1]=v2; Equation_translate(v[1],(w-w2)/2,5-vv2.dy-vv2.y); - v[2]=eqwdata(w,a.fontsize/2+vv1.dy+vv2.dy+1,0,(a.fontsize<=14?4:3)-vv2.dy,a,at_division,0); - return gen(v,_SEQ__VECT); - } - /*************** - * VECTORS * - ***************/ - if ( (g.type==_VECT) && !g._VECTptr->empty() ){ - vecteur v; - const_iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end(); - int x=0,y=0,h=a.fontsize; - /*************** - * MATRICE * - ***************/ - bool gmat=ckmatrix(g); - vector V; int p=0; - if (!gmat && is_mod_vecteur(*g._VECTptr,V,p) && p!=0){ - gen gm=makemodquoted(unmod(g),p); - return Equation_compute_size(gm,a,windowhsize,contextptr); - } - vector< vector > M; - if (gmat && is_mod_matrice(*g._VECTptr,M,p) && p!=0){ - gen gm=makemodquoted(unmod(g),p); - return Equation_compute_size(gm,a,windowhsize,contextptr); - } - if (gmat && g.subtype!=_SEQ__VECT && g.subtype!=_SET__VECT && g.subtype!=_POLY1__VECT && g._VECTptr->front().subtype!=_SEQ__VECT){ - gen mkvect(at_makevector); - mkvect.subtype=_SEQ__VECT; - gen mkmat(at_makevector); - mkmat.subtype=_MATRIX__VECT; - int nrows,ncols; - mdims(*g._VECTptr,nrows,ncols); - if (ncols){ - vecteur all_sizes; - all_sizes.reserve(nrows); - vector row_heights(nrows),row_bases(nrows),col_widths(ncols); - // vertical gluing - for (int i=0;it!=itend;++it,++i){ - gen tmpg=*it; - tmpg.subtype=_SEQ__VECT; - vecteur tmp(Equation_subsizes(tmpg,a,max(windowhsize/ncols-a.fontsize,230),contextptr)); - int h=a.fontsize,y=0; - const_iterateur jt=tmp.begin(),jtend=tmp.end(); - for (int j=0;jt!=jtend;++jt,++j){ - eqwdata w(Equation_total_size(*jt)); - Equation_vertical_adjust(w.dy,w.y,h,y); - col_widths[j]=max(col_widths[j],(int)w.dx); - } - if (i) - row_heights[i]=row_heights[i-1]+h+a.fontsize/2; - else - row_heights[i]=h; - row_bases[i]=y; - all_sizes.push_back(tmp); - } - // accumulate col widths - col_widths.front() +=(3*a.fontsize)/2; - vector::iterator iit=col_widths.begin()+1,iitend=col_widths.end(); - for (;iit!=iitend;++iit) - *iit += *(iit-1)+a.fontsize; - // translate each cell - it=all_sizes.begin(); - itend=all_sizes.end(); - int h,y,prev_h=0; - for (int i=0;it!=itend;++it,++i){ - h=row_heights[i]; - y=row_bases[i]; - iterateur jt=it->_VECTptr->begin(),jtend=it->_VECTptr->end(); - for (int j=0;jt!=jtend;++jt,++j){ - eqwdata w(Equation_total_size(*jt)); - if (j) - Equation_translate(*jt,col_widths[j-1]-w.x,-h-y); - else - Equation_translate(*jt,-w.x+a.fontsize/2,-h-y); - } - it->_VECTptr->push_back(eqwdata(col_widths.back(),h-prev_h,0,-h,a,mkvect,0)); - prev_h=h; - } - all_sizes.push_back(eqwdata(col_widths.back(),row_heights.back(),0,-row_heights.back(),a,mkmat,-row_heights.back()/2)); - gen all_sizesg=all_sizes; Equation_translate(all_sizesg,0,row_heights.back()/2); return all_sizesg; - } - } // end matrices - /************************* - * SEQUENCES/VECTORS * - *************************/ - // horizontal gluing - if (g.subtype!=_PRINT__VECT) x += a.fontsize/2; - int ncols=itend-it; - //ncols=min(ncols,5); - for (;it!=itend;++it){ - gen cur_size=Equation_compute_size(*it,a, - max(windowhsize/ncols-a.fontsize, -#ifdef IPAQ - 200 -#else - 480 -#endif - ),contextptr); - eqwdata tmp=Equation_total_size(cur_size); - Equation_translate(cur_size,x-tmp.x,0); v.push_back(cur_size); - x=x+tmp.dx+((g.subtype==_PRINT__VECT)?2:a.fontsize); - Equation_vertical_adjust(tmp.dy,tmp.y,h,y); - } - gen mkvect(at_makevector); - if (g.subtype==_SEQ__VECT) - mkvect=at_makesuite; - else - mkvect.subtype=g.subtype; - v.push_back(eqwdata(x,h,0,y,a,mkvect,0)); - return gen(v,_EQW__VECT); - } // end sequences - if (g.type==_MOD){ - int x=0; - int h=a.fontsize; - int y=0; - int py=python_compat(contextptr); - int modsize=int(text_width(a.fontsize,(py?" mod":"%")))+4; - bool paren=is_positive(-*g._MODptr,contextptr); - int llp=int(text_width(a.fontsize,("("))); - int lrp=int(text_width(a.fontsize,(")"))); - gen varg1=Equation_compute_size(*g._MODptr,a,windowhsize,contextptr); - if (paren) Equation_translate(varg1,llp,0); - eqwdata vv=Equation_total_size(varg1); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - gen arg2=*(g._MODptr+1); - gen varg2=Equation_compute_size(arg2,a,windowhsize,contextptr); - if (paren) - Equation_translate(varg2,vv.dx+modsize+lrp,0); - else - Equation_translate(varg2,vv.dx+modsize,0); - vv=Equation_total_size(varg2); - Equation_vertical_adjust(vv.dy,vv.y,h,y); - vecteur res(makevecteur(varg1,varg2)); - res.push_back(eqwdata(vv.dx+vv.x,h,0,y,a,at_normalmod,0)); - return gen(res,_SEQ__VECT); - } - if (g.type!=_SYMB){ - string s=g.type==_STRNG?*g._STRNGptr:g.print(contextptr); - //if (g==cst_pi) s=char(129); - if (s.size()>2000) - s=s.substr(0,2000)+"..."; - int i=int(text_width(a.fontsize,(s.c_str()))); - gen tmp=eqwdata(i,a.fontsize,0,0,a,g); - return tmp; - } - /********************** - * SYMBOLIC HANDLING * - **********************/ - return Equation_compute_symb_size(g,a,windowhsize,contextptr); - // return Equation_compute_symb_size(aplatir_fois_plus(g),a,windowhsize,contextptr); - // aplatir_fois_plus is a problem for Equation_replace_selection - // because it will modify the structure of the data - } - - void Equation_draw(const eqwdata & e,int x,int y,int rightx,int lowery,Equation * eq,GIAC_CONTEXT){ - if ( (e.dx+e.xrightx) || (e.y>y) || e.y+e.dy2000) - s=s.substr(0,2000)+"..."; - // cerr << s.size() << endl; - text_print(fontsize,s.c_str(),eq->x()+e.x-x,eq->y()+y-e.y,text_color,background,e.selected?4:0); - return; - } - - inline void check_fl_rectf(int x,int y,int w,int h,int imin,int jmin,int di,int dj,int delta_i,int delta_j,int c){ - drawRectangle(x+delta_i,y+delta_j,w,h,c); - //fl_rectf(x+delta_i,y+delta_j,w,h,c); - } - - void Equation_draw(const gen & g,int x,int y,int rightx,int lowery,Equation * equat,GIAC_CONTEXT){ - int eqx=equat->x(),eqy=equat->y(); - if (g.type==_EQW){ // terminal - eqwdata & e=*g._EQWptr; - Equation_draw(e,x,y,rightx,lowery,equat,contextptr); - } - if (g.type!=_VECT) - return; - vecteur & v=*g._VECTptr; - if (v.empty()) - return; - gen tmp=v.back(); - if (tmp.type!=_EQW){ - cout << "EQW error:" << v << endl; - return; - } - eqwdata & w=*tmp._EQWptr; - if ( (w.dx+w.x-x<0) || (w.x>rightx) || (w.y>y) || (w.y+w.dyback().type !=_EQW || arg2._VECTptr->back()._EQWptr->g!=at_makesuite){ // Yes (if not _EQW it's a sequence with parent) - eqwdata varg2=Equation_total_size(arg2); - x0=varg2.x; - y0=varg2.y; - y1=y0+varg2.dy; - fontsize=varg2.eqw_attributs.fontsize; - int pfontsize=max(fontsize,(fontsize+(varg2.baseline-varg2.y))/2); - if (x0=0){ - draw_line(eqx+x0-x+1,eqy+y-y0+1,eqx+x0-x+1,eqy+y-y1+1,draw_line_color); - draw_line(eqx+x0-x+decal,eqy+y-y0+1,eqx+x0-x+decal,eqy+y-y1+1,draw_line_color); - draw_line(eqx+x0-x+1,eqy+y-y0+1,eqx+x0-x+fontsize/4,eqy+y-y0+1,draw_line_color); - draw_line(eqx+x0-x+1,eqy+y-y1+1,eqx+x0-x+fontsize/4,eqy+y-y1+1,draw_line_color); - } - x0 += w.dx ; - if (eqx+x0-x-1",eqx+tmp.x+tmp.dx-x,eqy+y-tmp.baseline,text_color,background,mode); - return; - } -#if 1 - if (u==at_sum){ - if (x02){ // draw the = - eqwdata ptmp=Equation_total_size(v[1]); - if (ptmp.x+ptmp.dx 1 draw the d - eqwdata ptmp=Equation_total_size(v[1]); - if (ptmp.x=4){ - if (x0=5){ - arg2=v[2]; // 3rd arg of lim, the point, draw a comma after if dir. - if (arg2.type==_EQW){ - eqwdata & varg2=*arg2._EQWptr; - if (varg2.x+varg2.dxprintsommet==&printsommetasoperator || binary_op(u) ){ - if (u==at_normalmod && python_compat(contextptr)) - opstring=" mod"; - else - opstring=u.ptr()->s; - } - else { - if (u==at_sto) - opstring=":="; - parenthesis=false; - } - // int yy=y0; // y0 is the lower coordinate of the whole eqwdata - // int opsize=int(text_width(fontsize,(opstring.c_str())))+3; - it=v.begin(); - itend=v.end()-1; - // Reminder: here tmp is the 1st arg eqwdata, w the whole eqwdata - if ( (itend-it==1) && ( (u==at_neg) - || (u==at_plus) // uncommented for +infinity - ) ){ - if ( (u==at_neg &&need_parenthesis(tmp.g) && tmp.g!=at_prod)){ - if (tmp.x-lpsizes,eqx+w.x-x,eqy+y-w.baseline,text_color,background,mode); - } - return; - } - // write first open parenthesis - if (u==at_plus && tmp.g!=at_equal) - parenthesis=false; - else { - if (parenthesis && need_parenthesis(tmp.g)){ - if (w.xprintsommet==&printsommetasoperator || u==at_sto || binary_op(u)) - return; - else - break; - } - // write operator - if (u==at_prod){ - // text_print(fontsize,".",eqx+xx+3,eqy+y-tmp.baseline-fontsize/3); - text_print(fontsize,opstring.c_str(),eqx+xx+1,eqy+y-tmp.baseline,text_color,background,mode); - } - else { - gen tmpgen; - if (u==at_plus && ( - (it->type==_VECT && it->_VECTptr->back().type==_EQW && it->_VECTptr->back()._EQWptr->g==at_neg) - || - ( it->type==_EQW && (is_integer(it->_EQWptr->g) || it->_EQWptr->g.type==_DOUBLE_) && is_strictly_positive(-it->_EQWptr->g,contextptr) ) - ) - ) - ; - else { - if (xx+1s; - s += '('; - text_print(fontsize,s.c_str(),eqx+w.x-x,eqy+y-w.baseline,text_color,background,mode); - } - if (w.x+w.dx-rpsize * gotoptr,GIAC_CONTEXT){ - int xleft,ytop,xright,ybottom,gselpos; gen *gselparent; - vector goto_sel; - eq.undodata=Equation_copy(eq.data); - if (gotoptr==0){ - if (xcas::Equation_adjust_xy(eq.data,xleft,ytop,xright,ybottom,gsel,gselparent,gselpos,&goto_sel) && gsel) - gotoptr=&goto_sel; - else - return; - } - *gsel=xcas::Equation_compute_size(tmp,eq.attr,LCD_WIDTH_PX,contextptr); - gen value; - xcas::do_select(eq.data,true,value); - if (value.type==_EQW) - eq.data=xcas::Equation_compute_size(value._EQWptr->g,eq.attr,LCD_WIDTH_PX,contextptr); - //cout << "new value " << value << " " << eq.data << " " << *gotoptr << endl; - xcas::Equation_select(eq.data,false); - gen * gptr=&eq.data; - for (int i=gotoptr->size()-1;i>=0;--i){ - int pos=(*gotoptr)[i]; - if (gptr->type==_VECT &&gptr->_VECTptr->size()>pos) - gptr=&(*gptr->_VECTptr)[pos]; - } - xcas::Equation_select(*gptr,true); - //cout << "new sel " << *gptr << endl; - } - - void display(Equation & eq,int x,int y,GIAC_CONTEXT){ - // Equation_draw(eq.data,x,y,LCD_WIDTH_PX,0,&eq,contextptr); - int xleft,ytop,xright,ybottom,gselpos; gen * gsel,*gselparent; - eqwdata eqdata=Equation_total_size(eq.data); - if ( (eqdata.dx>LCD_WIDTH_PX || eqdata.dy>LCD_HEIGHT_PX-STATUS_AREA_PX) && Equation_adjust_xy(eq.data,xleft,ytop,xright,ybottom,gsel,gselparent,gselpos)){ - if (x=xleft && x+LCD_WIDTH_PX>=xright){ - if (xright-x=ytop && y+LCD_HEIGHT_PX>=ybottom){ - if (ybottom-y=-1e-12 && s+t<=1+1e-12; -#else - double as_x = x-x0; - double as_y = y-y0; - bool s_01 = (x1-x0)*as_y-(y1-y0)*as_x>0; // dot product P0P1.P0P>0 - if ( (x2-x0)*as_y-(y2-y0)*as_x>0 == s_01) - return false; - if ((x2-x1)*(y-y1)-(y2-y1)*(x-x1) > 0 != s_01) - return false; - return true; -#endif - } - - /* 3d rotation handling */ - void normalize(double & a,double &b,double &c){ - double n=std::sqrt(a*a+b*b+c*c); - a /= n; - b /= n; - c /= n; - } - - inline int Min(int i,int j) {return i>j?j:i;} - - inline int Max(int i,int j) {return i>j?i:j;} - - quaternion_double::quaternion_double(double theta_x,double theta_y,double theta_z) { - *this=euler_deg_to_quaternion_double(theta_x,theta_y,theta_z); - } - - quaternion_double euler_deg_to_quaternion_double(double a,double b,double c){ - double phi=a*M_PI/180, theta=b*M_PI/180, psi=c*M_PI/180; - double c1 = std::cos(phi/2); - double s1 = std::sin(phi/2); - double c2 = std::cos(theta/2); - double s2 = std::sin(theta/2); - double c3 = std::cos(psi/2); - double s3 = std::sin(psi/2); - double c1c2 = c1*c2; - double s1s2 = s1*s2; - double w =c1c2*c3 - s1s2*s3; - double x =c1c2*s3 + s1s2*c3; - double y =s1*c2*c3 + c1*s2*s3; - double z =c1*s2*c3 - s1*c2*s3; - return quaternion_double(w,x,y,z); - } - - void quaternion_double_to_euler_deg(const quaternion_double & q,double & phi,double & theta, double & psi){ - double test = q.x*q.y + q.z*q.w; - if (test > 0.499) { // singularity at north pole - phi = 2 * atan2(q.x,q.w) * 180/M_PI; - theta = 90; - psi = 0; - return; - } - if (test < -0.499) { // singularity at south pole - phi = -2 * atan2(q.x,q.w) * 180/M_PI; - theta = - 90; - psi = 0; - return; - } - double sqx = q.x*q.x; - double sqy = q.y*q.y; - double sqz = q.z*q.z; - phi = atan2(2*q.y*q.w-2*q.x*q.z , 1 - 2*sqy - 2*sqz) * 180/M_PI; - theta = asin(2*test) * 180/M_PI; - psi = atan2(2*q.x*q.w-2*q.y*q.z , 1 - 2*sqx - 2*sqz) * 180/M_PI; - } - - quaternion_double operator * (const quaternion_double & q1,const quaternion_double & q2){ - double z=q1.w*q2.z+q2.w*q1.z+q1.x*q2.y-q2.x*q1.y; - double x=q1.w*q2.x+q2.w*q1.x+q1.y*q2.z-q2.y*q1.z; - double y=q1.w*q2.y+q2.w*q1.y+q1.z*q2.x-q2.z*q1.x; - double w=q1.w*q2.w-q1.x*q2.x-q1.y*q2.y-q1.z*q2.z; - return quaternion_double(w,x,y,z); - } - - // q must be a unit - void get_axis_angle_deg(const quaternion_double & q,double &x,double &y,double & z, double &theta){ - double scale=1-q.w*q.w; - if (scale>1e-6){ - scale=std::sqrt(scale); - theta=2*std::acos(q.w)*180/M_PI; - x=q.x/scale; - y=q.y/scale; - z=q.z/scale; - } - else { - x=0; y=0; z=1; - theta=0; - } - } - - quaternion_double rotation_2_quaternion_double(double x, double y, double z,double theta){ - double t=theta*M_PI/180; - double qx,qy,qz,qw,s=std::sin(t/2),c=std::cos(t/2); - qx=x*s; - qy=y*s; - qz=z*s; - qw=c; - double n=std::sqrt(qx*qx+qy*qy+qz*qz+qw*qw); - return quaternion_double(qw/n,qx/n,qy/n,qz/n); - } - - // image of (x,y,z) by rotation around axis r(rx,ry,rz) of angle theta - void rotate(double rx,double ry,double rz,double theta,double x,double y,double z,double & X,double & Y,double & Z){ - /* - quaternion_double q=rotation_2_quaternion_double(rx,ry,rz,theta); - quaternion_double qx(x,y,z,0); - quaternion_double qX=conj(q)*qx*q; - */ - // r(rx,ry,rz) the axis, v(x,y,z) projects on w=a*r with a such that - // w.r=a*r.r=v.r - double r2=rx*rx+ry*ry+rz*rz; - double r=std::sqrt(r2); - double a=(rx*x+ry*y+rz*z)/r2; - // v=w+V, w remains stable, V=v-w=v-a*r rotates - // Rv=w+RV, where RV=cos(theta)*V+sin(theta)*(r cross V)/sqrt(r2) - double Vx=x-a*rx,Vy=y-a*ry,Vz=z-a*rz; - // cross product of k with V - double kVx=ry*Vz-rz*Vy, kVy=rz*Vx-rx*Vz,kVz=rx*Vy-ry*Vx; - double c=std::cos(theta),s=std::sin(theta); - X=a*rx+c*Vx+s*kVx/r; - Y=a*ry+c*Vy+s*kVy/r; - Z=a*rz+c*Vz+s*kVz/r; - } - - int diffuse(int color_orig,double diffusionz){ - if (diffusionz<1.1) - return color_orig; - int color=rgb565to888(color_orig); - int r=(color&0xff0000)>>16,g=(color & 0xff00)>>8,b=192; - double attenuate=(.3*(diffusionz-1)); - attenuate=1.0/(1+attenuate*attenuate); - r*=attenuate; g*=attenuate; b*=attenuate; - return rgb888to565((r<<16)|(g<<8)|b); - } - - void glinter1(double z,double dz, - double *zmin,double *zmax,double ZMIN,double ZMAX, - int ih,int lcdz, - int upcolor,int downcolor,int diffusionz,int diffusionz_limit,bool interval - ){ - if (ZMIN*zmax+lcdz) - *zmax=*zmin=z; - bool diffus=diffusionz=LCD_HEIGHT_PX) { - // return; - z=LCD_HEIGHT_PX-1; intervalonly=true; - } - deltaz=diffus?1:diffusionz; - if (z>*zmax+deltaz){ - if (diffus){ - drawRectangle(ih,*zmax,1,std::ceil(z-*zmax),diffuse(downcolor,diffusionz)); - if (!intervalonly) - os_set_pixel(ih,z,downcolor); - } - else { - drawRectangle(ih,*zmax,1,std::ceil(z-*zmax),_BLACK); - // draw interval - int nstep=int(z-*zmax)/diffusionz; - double zstep=(z-*zmax)/nstep; - for (double zz=*zmax+zstep;zz<=z;zz+=zstep) - os_set_pixel(ih,zz,downcolor); - } - *zmax=z; - return; - } - else if (z<*zmin-deltaz){ - if (diffus){ - drawRectangle(ih,z,1,std::ceil(*zmin-z),diffuse(upcolor,diffusionz)); - if (!intervalonly) - os_set_pixel(ih,z,upcolor); - } - else { - drawRectangle(ih,z,1,std::ceil(*zmin-z),_BLACK); - // draw interval - int nstep=int(*zmin-z)/diffusionz; - double zstep=(z-*zmin)/nstep; // zstep<0 - for (double zz=*zmin+zstep;zz>=z;zz+=zstep) - os_set_pixel(ih,zz,upcolor); - } - *zmin=z; - return; - } - } // end if interval - if (z>=0 && z<=LCD_HEIGHT_PX){ - int color=-1; - if (diffus){ - if (z<=*zmin){ - // mark all points with diffuse color from upcolor - drawRectangle(ih,z,1,std::ceil(*zmin-z),diffuse(upcolor,std::min(double(diffusionz),std::max(-dz,1.0)))); - color=upcolor; - *zmin=z; - } - if (z>=*zmax){ - // mark all points with diffuse color from downcolor - drawRectangle(ih,*zmax,1,std::ceil(z-*zmax),diffuse(downcolor,std::min(double(diffusionz),std::max(dz,1.0)))); - *zmax=z; - } - return; - } - if (z>*zmax){ // mark only 1 point - color=downcolor; - drawRectangle(ih,*zmax+1,1,z-*zmax-1,_BLACK); - *zmax=z; - } - if (z<*zmin){ // mark 1 point - color=upcolor; - drawRectangle(ih,z+1,1,*zmin-z-1,_BLACK); - *zmin=z; - } - if (color>=0) os_set_pixel(ih,z,color); - } - } - - void glinter(double a,double b,double c, - double xscale,double xc,double yscale,double yc, - double *zmin,double *zmax,double ZMIN,double ZMAX, - int i,int horiz,int j,int w,int h,int lcdz, - int upcolor,int downcolor,int diffusionz,int diffusionz_limit,bool interval - ){ - double dz=lcdz*(a+b)*yscale-1; - //if (dz<-10 || dz>10) cout << "dz=" << dz << "\n"; - // plane equation solved - if (//0 - h==1 && w==1 - ){ - int ih=i+horiz; - double x = yscale*j-xscale*i + xc; - // if (x*zmax+lcdz) - *zmax=*zmin=z; - if (0 && (*zmax<50 || *zmin<50 || z<50)) - cout << *zmax << " "; // debug - bool diffus=diffusionz=LCD_HEIGHT_PX) { - // return; - z=LCD_HEIGHT_PX-1; intervalonly=true; - } - deltaz=diffus?1:diffusionz; - if (z>*zmax+deltaz){ - if (diffus){ - drawRectangle(ih,*zmax,1,std::ceil(z-*zmax),diffuse(downcolor,diffusionz)); - if (!intervalonly) - os_set_pixel(ih,z,downcolor); - } - else { - drawRectangle(ih,*zmax,1,std::ceil(z-*zmax),_BLACK); - // draw interval - int nstep=int(z-*zmax)/diffusionz; - double zstep=(z-*zmax)/nstep; - for (double zz=*zmax+zstep;zz<=z;zz+=zstep) - os_set_pixel(ih,zz,downcolor); - } - *zmax=z; - return; - } - else if (z<*zmin-deltaz){ - if (diffus){ - drawRectangle(ih,z,1,std::ceil(*zmin-z),diffuse(upcolor,diffusionz)); - if (!intervalonly) - os_set_pixel(ih,z,upcolor); - } - else { - drawRectangle(ih,z,1,std::ceil(*zmin-z),_BLACK); - // draw interval - int nstep=int(*zmin-z)/diffusionz; - double zstep=(z-*zmin)/nstep; // zstep<0 - for (double zz=*zmin+zstep;zz>=z;zz+=zstep) - os_set_pixel(ih,zz,upcolor); - } - *zmin=z; - return; - } - } // end if interval - if (z>=0 && z<=LCD_HEIGHT_PX){ - int color=-1; - if (diffus){ - if (z<=*zmin){ - // mark all points with diffuse color from upcolor - drawRectangle(ih,z,1,std::ceil(*zmin-z),diffuse(upcolor,std::min(double(diffusionz),std::max(-dz,1.0)))); - color=upcolor; - *zmin=z; - } - if (z>=*zmax){ - // mark all points with diffuse color from downcolor - drawRectangle(ih,*zmax,1,std::ceil(z-*zmax),diffuse(downcolor,std::min(double(diffusionz),std::max(dz,1.0)))); - *zmax=z; - } - return; - } - if (z>=*zmax){ // mark only 1 point - color=downcolor; - // drawRectangle(ih,*zmax,1,z-*zmax,color); - // drawRectangle(ih,*zmax,1,z-*zmax,_BLACK); - *zmax=z; - } - if (z<=*zmin){ // mark 1 point - color=upcolor; - //drawRectangle(ih,z,1,*zmin-z,color); - //drawRectangle(ih,z,1,*zmin-z,_BLACK); - *zmin=z; - } - if (color>=0) os_set_pixel(ih,z,color); - } - return; // end h==1 and w==1 - } - for (int I=i;I=LCD_HEIGHT_PX) { - z=LCD_HEIGHT_PX-1; intervalonly=true; - } - } - if (i==0) - ; // cout << "i=" << i << " j=" << j << ", zmin=" << *zmin << " z=" << z << " zmax=" << *zmax << " dz=" << dz << ", a=" << a << " b=" << b << " c=" << c <<"\n"; - if (*zmax<*zmin || z<*zmin-lcdz || z>*zmax+lcdz) - *zmax=*zmin=z; - int deltaz=(diffusionz*zmax+deltaz){ - if (//0 - diffusionz=z;zz+=zstep) - os_set_pixel(ih,zz,upcolor); - } - if (intervalonly){ - *zmin=z; - continue; - } - } - if (//x-(h-1)*yscale>xmin && y-(h-1)*yscale>ymin && - z>=0 && z+(h-1)*dz>=0 && z<=LCD_HEIGHT_PX && z+(h-1)*dz<=LCD_HEIGHT_PX - ){ - int color=-1; - if ( (h>1 || diffusionz0 && z>=*zmax){ - // mark all points with downcolor - *zmax=z+(h-1)*dz; - color=downcolor; - if (diffusionz>=diffusionz_limit && dz>diffusionz){ - drawRectangle(ih,z,1,std::ceil(*zmax-z),_BLACK); - // draw interval - int nstep=int(std::ceil((*zmax-z)/diffusionz)); - double zstep=(*zmax-z)/nstep; - for (int i=0;i<=nstep;++i) - os_set_pixel(ih,z+i*zstep,color); - continue; - } - } - if ( (h>1 || diffusionz=diffusionz_limit && dz<-diffusionz){ - drawRectangle(ih,z,1,std::ceil(z-*zmin),_BLACK); - // draw interval - int nstep=int(std::ceil((z-*zmin)/diffusionz)); - double zstep=(*zmin-z)/nstep; - for (int i=0;i<=nstep;++i) - os_set_pixel(ih,z+i*zstep,color); - continue; - } - } - if (color>=0){ - if (diffusionz0) - drawRectangle(ih,z,1,std::ceil(h*dz),diffuse(color,std::min(double(diffusionz),std::max(dz,1.0)))); - else - drawRectangle(ih,z-std::ceil(-h*dz),1,std::ceil(-h*dz),diffuse(color,std::min(double(diffusionz),std::max(-dz,1.0)))); - continue; - } - if (dz>1) - drawRectangle(ih,z,1,std::ceil(h*dz),_BLACK); - os_set_pixel(ih,z,color); - if (h==1) continue; - z += dz; - os_set_pixel(ih,z,color); - if (h==2) continue; - z += dz; - os_set_pixel(ih,z,color); - if (h==3) continue; - z += dz; - os_set_pixel(ih,z,color); - if (h==4) continue; - z += dz; - os_set_pixel(ih,z,color); - if (h==5) continue; - z += dz; - os_set_pixel(ih,z,color); - if (h==6) continue; - z += dz; - os_set_pixel(ih,z,color); - if (h==7) continue; - z += dz; - os_set_pixel(ih,z,color); - if (h==8) continue; - z += dz; - os_set_pixel(ih,z,color); - continue; - } - if (dz<=0 && z>=*zmax && z+(h-1)*dz>=*zmin){ // mark only 1 point - *zmax=z; - color=downcolor; - } - if (dz>=0 && z<=*zmin && z+(h-1)*dz<=*zmax){ // mark 1 point - *zmin=z; - color=upcolor; - } - if (color>=0){ - os_set_pixel(ih,z,color); - continue; - } - } - for (int J=0;J=xmin && y>=ymin - ;++J,z+=dz,x-=yscale,y-=yscale){ - int color=-1; - if (z>*zmax){ - drawRectangle(i,*zmax,1,z-*zmax,_BLACK); - *zmax=z; - color=downcolor; - } - if (z<*zmin){ - drawRectangle(i,z,1,*zmin-z,_BLACK); - *zmin=z; - color=upcolor; - } - if (z<=-0.5 || z>=LCD_HEIGHT_PX) - continue; - if (color>=0) - os_set_pixel(ih,z,color); // drawRectangle(i,z,w,h,color); - } - } - } - - void find_abc(double x1,double x2,double x3, - double y1,double y2,double y3, - double z1,double z2,double z3, - double &a,double &b,double &c){ - // solve([a*x1+b*y1+c=z1,a*x2+b*y2+c=z2,a*x3+b*y3+c=z3],[a,b,c]) - // double d=(x1*y2-x1*y3-x2*y1+x2*y3+x3*y1-x3*y2); - double d=(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2)); - if (d==0) return; - d=1/d; - double z12=z2-z1,z23=z3-z2,z31=z1-z3; - //double a=(-y1*z2+y1*z3+y2*z1-y2*z3-y3*z1+y3*z2)/d; - a=d*(y1*z23+y2*z31+y3*z12); - // double b=(x1*z2-x1*z3-x2*z1+x2*z3+x3*z1-x3*z2)/d; - b=-d*(x1*z23+x2*z31+x3*z12); - //double c=(x1*y2*z3-x1*y3*z2-x2*y1*z3+x2*y3*z1+x3*y1*z2-x3*y2*z1)/d; - c=d*(x1*(y2*z3-y3*z2)+x2*(y3*z1-y1*z3)+x3*(y1*z2-y2*z1)); - } - - void glinter(double x1,double x2,double x3, - double y1,double y2,double y3, - double z1,double z2,double z3, - double xscale,double xc,double yscale,double yc, - double *zmin,double *zmax,double ZMIN,double ZMAX, - int i,int horiz,int j,int w,int h,int lcdz, - int upcolor,int downcolor,int diffusionz,int diffusionz_limit,bool interval - ){ - double a,b,c; - find_abc(x1,x2,x3,y1,y2,y3,z1,z2,z3,a,b,c); - glinter(a,b,c,xscale,xc,yscale,yc,zmin,zmax,ZMIN,ZMAX,i,horiz,j,w,h,lcdz,upcolor,downcolor,diffusionz,diffusionz_limit,interval); - } - - void update12(bool & found,bool &found2, - double x1,double x2,double x3,double y1,double y2,double y3,double z1,double z2,double z3, - int upcolor,int downcolor,int downupcolor,int downdowncolor, - double & curx1, double &curx2, double &curx3, double &cury1, double &cury2, double &cury3, double &curz1, double &curz2, double &curz3, - double &cur2x1, double &cur2x2, double &cur2x3, double &cur2y1, double &cur2y2, double &cur2y3, double &cur2z1, double &cur2z2, double &cur2z3, - int & u,int & d,int & du,int & dd){ - if (found){ - if (z1+z2+z3 & v,double x,double y){ - int n=0; - for (int i=1;i0) // on vertical edge - return false; - continue; - } - if (x==prevx) - continue; - if ((x-prevx)*(curx-x)<0) - continue; - //double Y=cury+m*(x-curx); - double Y=cury+(cur.y-prev.y)/(cur.x-prev.x)*(x-curx); - if (Y>=y) - ++n; - } - if (n%2) - return true; - return false; - } -#else - bool inside(const vector & v,double x,double y){ - int n=0; - for (int i=1;i0) - ++n; - continue; - } - if (x==prevx || (x-prevx)*(curx-x)<0) - continue; - double Y=cury+m*(x-curx); - if (Y>=y) - ++n; - } - if (n%2) - return true; - return false; - } -#endif - - // intersect plane x-y=xy with line m+t*v - // m.x+t*v.x-m.y-t*v.y=-xy - double intersect(const double3 & m,const double3 & v,double xy){ - return (-xy+m.y-m.x)/(v.x-v.y); - } - - // returns true if filled, false otherwise - bool get_colors(gen attr,int & upcolor,int & downcolor,int & downupcolor,int & downdowncolor){ - if (attr.is_symb_of_sommet(at_pnt)){ - attr=attr[1]; - } - if (attr.type==_INT_ && (attr.val & 0xffff)!=0){ - upcolor=attr.val &0xffff; - int color=rgb565to888(upcolor); - int r=(color&0xff0000)>>16,g=(color & 0xff00)>>8,b=192; - r >>= 2; - g >>= 2; - downcolor=rgb888to565((r<<16)|(g<<8)|b); - r >>= 1; - g >>= 1; - downupcolor=rgb888to565((r<<16)|(g<<8)|b); - r >>= 2; - g >>= 2; - downdowncolor=rgb888to565((r<<16)|(g<<8)|b); - } - if (attr.type==_INT_) - return attr.val & 0x40000000; - return false; - } - -#define ABC3D - - // 2d coordinates of m+t*v - void grmtv2ij(const Graph2d & gr,const double3 & m,const double3 & v,double t,int & i,int & j){ - double x=m.x+t*v.x; - double y=m.y+t*v.y; - double z=m.z+t*v.z; - gr.XYZ2ij(double3(x,y,z),i,j); - } - - struct hypertriangle_t { - int4 * colorptr; // hypersurface color - double xmin,xmax,ymin,ymax; // minmax values intersection with plane y-x=Cte - double a,b,c; // plane equation of triangle - double zG; // altitude for gravity center - } ; // data struct for hypesurface triangulation cache - -#define HYPERQUAD -#ifdef HYPERQUAD - - void compute(double yx,double3 * cur,hypertriangle_t & res){ - double xmin=1e307,xmax=-1e307,ymin=1e307,ymax=-1e307; - for (int l=0;l<4;++l){ - int prev=l==0?3:l-1; - double3 & d3=cur[prev]; - double x0=d3.x,y0=d3.y,x1=cur[l].x,y1=cur[l].y; - double yx0=y0-x0,yx1=y1-x1,m=yx1-yx0; - if (m==0){ - if (yx==yx1){ - if (x0>xmax) xmax=x0; if (x0xmax) xmax=x1; if (x1ymax) ymax=y0; if (y0ymax) ymax=y1; if (y1=0 && t<=1){ - double X=x0+t*(x1-x0),Y=y0+t*(y1-y0); - if (X>xmax) xmax=X; if (Xymax) ymax=Y; if (Yxmax) xmax=x0; if (x0xmax) xmax=x1; if (x1ymax) ymax=y0; if (y0ymax) ymax=y1; if (y1=0 && t<=1){ - double X=x0+t*(x1-x0),Y=y0+t*(y1-y0); - if (X>xmax) xmax=X; if (Xymax) ymax=Y; if (Y & hypertriangles,double x,double y, - bool & found,bool &found2, - double3 & curabc1,double & curz1, - double3 & curabc2,double & curz2, - int & upcolor,int & downcolor,int & downupcolor,int & downdowncolor){ - vector::const_iterator it=hypertriangles.begin(),itend=hypertriangles.end(); - for (;it!=itend;++it){ - if (xxmin){ - ++it; - if (it==itend) break; - if (xxmin){ - ++it; - if (it==itend) break; - if (xxmin){ - ++it; - if (it==itend) break; - } - } - } - else if (x>it->xmax){ - ++it; - if (it==itend) break; - if (x>it->xmax){ - ++it; - if (it==itend) break; - if (x>it->xmax){ - ++it; - if (it==itend) break; - } - } - } - const hypertriangle_t & cur=*it; - if (xcur.xmax || ycur.ymax) - continue; - if (!found || cur.zG>curz1){ - if (found){ - found2=true; - curabc2=curabc1; - curz2=curz1; - } - found=true; - curabc1.x=cur.a; curabc1.y=cur.b; curabc1.z=cur.c; - curz1=cur.zG; - upcolor=cur.colorptr->u; downcolor=cur.colorptr->d; - continue; - } - if (cur.zG>curz2){ - found2=true; - curabc2.x=cur.a; curabc2.y=cur.b; curabc2.z=cur.c; - curz2=cur.zG; - downupcolor=cur.colorptr->du; downdowncolor=cur.colorptr->dd; - continue; - } - } // end loop on k - } - - // hpersurface encoded as a matrix - // with lines containing 3 coordinates per point - bool Graph2d::glsurface(int w,int h,int lcdz,GIAC_CONTEXT, - int upcolor_,int downcolor_,int downupcolor_,int downdowncolor_) { - if (w>9) w=9; if (w<1) w=1; - if (h>9) h=9; if (h<1) h=1; - // save zmin/zmax on the stack (4K required) - const int jmintabsize=512; - ALLOCA(short int,jmintab,jmintabsize*sizeof(short int)); - ALLOCA(short int,jmaxtab,jmintabsize*sizeof(short int)); - // short int *jmintab=(short int *)alloca(jmintabsize*sizeof(short int)), * jmaxtab=(short int *)alloca(jmintabsize*sizeof(short int)); // assumes LCD_WIDTH_PX<=jmintabsize - for (int i=0;i >::const_iterator > hypv; // 3 iterateurs per hypersurface - int upcolor,downcolor,downupcolor,downdowncolor; - for (int i=0;iimax) imax=itmp; - itmp=segments_x2[i]; - if (itmpimax) imax=itmp; - } - double xmin=-1,ymin=-1,xmax=1,ymax=1,xscale=0.6*(xmax-xmin)/horiz,yscale=0.6*(ymax-ymin)/vert,x,y,z,xc=(xmin+xmax)/2,yc=(ymin+ymax)/2; - drawRectangle(0,0,imin,LCD_HEIGHT_PX,COLOR_BLACK); // clear - drawRectangle(imax,0,LCD_WIDTH_PX-imax,LCD_HEIGHT_PX,COLOR_BLACK); // clear - sync_screen(); - int count=0; - vector polyedrei; polyedrei.reserve(polyedrev.size()); // cache for polyedres polygons edges - vector polyedrexmin,polyedrexmax,polyedreymin,polyedreymax; - polyedrexmin.reserve(polyedrev.size());polyedrexmax.reserve(polyedrev.size()); - polyedreymin.reserve(polyedrev.size());polyedreymax.reserve(polyedrev.size()); - vector hypertriangles; - for (int i=imin-horiz;i=0 ){ - double y=segments_y1[k]+segments_m[k]*(ih-segments_x1[k]); - if (y<=jmin) - jmin=std::floor(y); - if (y>=jmax) - jmax=std::ceil(y); - } - } - if (jmin>jmax) continue; - if (jmin<0) jmin=0; - if (jmax>LCD_HEIGHT_PX) jmax=LCD_HEIGHT_PX; - jmin -= LCD_HEIGHT_PX/2; - jmax -= LCD_HEIGHT_PX/2; - // optimization caches for this vertical - double yx=2*xscale*(i+(w-1)/2.0)+yc-xc; - // poledrev indices for yx, and xmin/xmax/ymin/ymax values - // (xmin/xmax should be enough, except limit cases) - polyedrei.clear(); polyedrexmin.clear(); polyedrexmax.clear(); polyedreymin.clear(); polyedreymax.clear(); - for (int k=0;kfacemax) - continue; - polyedrei.push_back(k); - vector & cur=polyedrev[k]; - double xmin=1e307,xmax=-1e307,ymin=1e307,ymax=-1e307; - for (int l=0;lxmax) xmax=x0; if (x0xmax) xmax=x1; if (x1ymax) ymax=y0; if (y0ymax) ymax=y1; if (y1=0 && t<=1){ - double X=x0+t*(x1-x0),Y=y0+t*(y1-y0); - if (X>xmax) xmax=X; if (Xymax) ymax=Y; if (Y >::const_iterator sbeg=hypv[k],send=hypv[k+1],sprec,scur; - vector::const_iterator itprec,itcur,itprecend; - for (sprec=sbeg,scur=sprec+1;scurbegin(); - itprecend=sprec->end(); - itcur=scur->begin(); - double yx1,yx2=*(itprec+1)-*itprec,yx3,yx4=*(itcur+1)-*itcur; - for (itprec+=3,itcur+=3;itprecyx1 && yx>yx2 && yx>yx3 && yx>yx4){ - for (;;){ - // per iteration: 2 incr, 1 test, 2 read, 2 comp, && , test - itprec+=3;itcur+=3; - if (itprec(yx2=*(itprec+1)-*itprec) && yx>(yx4=*(itcur+1)-*itcur)){ - itprec+=3;itcur+=3; - if (itprec(yx2=*(itprec+1)-*itprec) && yx>(yx4=*(itcur+1)-*itcur)){ - itprec+=3;itcur+=3; - if (itprec(yx2=*(itprec+1)-*itprec) && yx>(yx4=*(itcur+1)-*itcur)){ - itprec+=3;itcur+=3; - if (itprec(yx2=*(itprec+1)-*itprec) && yx>(yx4=*(itcur+1)-*itcur)){ - continue; - } - } - } - } - break; - } - if (yx>yx2 && yx>yx4) continue; - } - // found one quad intersecting plane - double x1=*(itprec-3),x2=*(itprec),x3=*(itcur-3),x4=*(itcur); - double y1=*(itprec-2),y2=*(itprec+1),y3=*(itcur-2),y4=*(itcur+1); - double z1=*(itprec-1),z2=*(itprec+2),z3=*(itcur-1),z4=*(itcur+2); - yx1=y1-x1; yx2=y2-x2; yx3=y3-x3; yx4=y4-x4; -#ifdef HYPERQUAD - tri[0]=double3(x1,y1,z1); - tri[1]=double3(x2,y2,z2); - tri[2]=double3(x4,y4,z4); - tri[3]=double3(x3,y3,z3); - double x123=(x1+x2+x3+x4)/4,y123=(y1+y2+y3+y4)/4,z123=(z1+z2+z3+z4)/4,X,Y,Z; - double xy123=x123+y123; - if (xy123hyperxymax) hyperxymax=xy123; - do_transform(invtransform,x123,y123,z123,X,Y,Z); - if (Z>=window_zmin && Z<=window_zmax && X>=window_xmin && X<=window_xmax && Y>=window_ymin && Y<=window_ymax ){ - hypertriangle_t res; res.colorptr=&hyp_color[k]; - compute(yx,tri,res); - hypertriangles.push_back(res); - } -#else // HYPERQUAD - tri[1]=double3(x2,y2,z2); - tri[2]=double3(x3,y3,z3); - if ( (yx>yx1 && yx>yx2 && yx>yx3) || - (yxhyperxymax) hyperxymax=xy123; - do_transform(invtransform,x123,y123,z123,X,Y,Z); - if (Z>=window_zmin && Z<=window_zmax && X>=window_xmin && X<=window_xmax && Y>=window_ymin && Y<=window_ymax ){ - tri[0]=double3(x1,y1,z1); - hypertriangle_t res; res.colorptr=&hyp_color[k]; - compute(yx,tri,res); - hypertriangles.push_back(res); - } - } - if ( (yx>yx4 && yx>yx2 && yx>yx3) || - (yxhyperxymax) hyperxymax=xy423; - do_transform(invtransform,x423,y423,z423,X,Y,Z); - if (Z>=window_zmin && Z<=window_zmax && X>=window_xmin && X<=window_xmax && Y>=window_ymin && Y<=window_ymax ){ - tri[0]=double3(x4,y4,z4); - hypertriangle_t res; res.colorptr=&hyp_color[k]; - compute(yx,tri,res); - hypertriangles.push_back(res); - } - } -#endif // HYPERQUAD - } - } - } - vector spheres(sphere_centerv.size()); // is plane y-x=yx intersecting sphere - for (int k=0;k=0; - } - double zmin[10]={220.220,220,220,220,220,220,220,220,220}, - zmax[10]={0,0,0,0,0,0,0,0,0,0}, - zmin2[10]={220.220,220,220,220,220,220,220,220,220}, - zmax2[10]={0,0,0,0,0,0,0,0,0,0} ; // initialize for these vertical lines -#ifdef ABC3D - double3 curabc1,curabc2; - double curz1=-1e306,curz2=1e306; -#else - double curx1,curx2,curx3,cury1,cury2,cury3,curz1=-1e306,curz2=-1e306,curz3=-1e306; - double cur2x1,cur2x2,cur2x3,cur2y1,cur2y2,cur2y3,cur2z1=-1e306,cur2z2=-1e306,cur2z3=-1e306; -#endif - int u,d,du,dd; - // loop earlier if there are only hypersurfaces - bool only_hypertri=true; - for (int ki=0;kijmin) - jmin=effjmin-1; - x = yscale*(jmax-(h-1)/2.0)-xscale*(i+(w-1)/2.0) + xc; - y = yscale*(jmax-(h-1)/2.0)+xscale*(i+(w-1)/2.0) + yc; - for (int j=jmax;j>=jmin;j-=h,x-=yscale*h,y-=yscale*h){ - bool found=false,found2=false; - update_hypertri(hypertriangles,x,y,found,found2,curabc1,curz1,curabc2,curz2,upcolor,downcolor,downupcolor,downdowncolor); - if (!found) continue; - if (h==1 && w==1){ - if (found2 && !hide2nd){ - double dz=lcdz*(curabc2.x+curabc2.y)*yscale-1; - // if (y=jmin;j-=h,x-=yscale*h,y-=yscale*h){ - if (0 && i==-35 && j==-44) - u=0; // debug - // x = yscale*(j-(h-1)/2.0)-xscale*(i+(w-1)/2.0) + xc; - // y = yscale*(j-(h-1)/2.0)+xscale*(i+(w-1)/2.0) + yc; - bool found=false,found2=false; - update_hypertri(hypertriangles,x,y,found,found2,curabc1,curz1,curabc2,curz2,upcolor,downcolor,downupcolor,downdowncolor); - for (int ki=0;ki & cur=polyedrev[k]; - if ( -#if 1 - x>=polyedrexmin[ki] && x<=polyedrexmax[ki] && y>=polyedreymin[ki] && y<=polyedreymax[ki] -#else - inside(cur,x,y) -#endif - ){ - const double3 & abc=polyedre_abcv[k]; - const int4 & color=polyedre_color[k]; - // std::cout << k << " " << x << " " << y << " " << color.u << "\n"; - double a=abc.x,b=abc.y,c=abc.z; - z=a*x+b*y+c; - bool is_clipped=polyedre_faceisclipped[k]; - if (!is_clipped){ - double X,Y,Z; - do_transform(invtransform,x,y,z,X,Y,Z); - is_clipped=X>=window_xmin && X<=window_xmax && Y>=window_ymin && Y<=window_ymax && Z>=window_zmin && Z<=window_zmax; - } - if (is_clipped){ -#ifdef ABC3D - update12(found,found2, - a,b,c,z, - color.u,color.d,color.du,color.dd, - curabc1.x,curabc1.y,curabc1.z,curz1, - curabc2.x,curabc2.y,curabc2.z,curz2, - upcolor,downcolor,downupcolor,downdowncolor); -#else - update12(found,found2, - x-.5,x-.5,x+1,y+0.866,y-0.866,y,z-.5*a+.866*b,z-.5*a-.866*b,z+a,color.u,color.d,color.du,color.dd, - curx1,curx2,curx3,cury1,cury2,cury3,curz1,curz2,curz3, - cur2x1,cur2x2,cur2x3,cur2y1,cur2y2,cur2y3,cur2z1,cur2z2,cur2z3, - upcolor,downcolor,downupcolor,downdowncolor); -#endif - } - } // end if inside(cur,x,y) - } - for (int k=0;k0){ - sol1=(-b-delta)/2/a; - sol2=2*C/(-b-delta); // (-b+delta)/2/a; - } - else { - sol1=2*C/(-b+delta);//(-b-delta)/2/a; - sol2=(-b+delta)/2/a; - } - double v2=sol1; - z=v2+c.z; - bool is_clipped=sphere_isclipped[k]; - if (!is_clipped){ - double X,Y,Z; - do_transform(invtransform,x,y,z,X,Y,Z); - is_clipped=X>=window_xmin && X<=window_xmax && Y>=window_ymin && Y<=window_ymax && Z>=window_zmin && Z<=window_zmax; - } - if (is_clipped){ - double w0=v0*m0[0]._DOUBLE_val+v1*m1[0]._DOUBLE_val+v2*m2[0]._DOUBLE_val; - double w1=v0*m0[1]._DOUBLE_val+v1*m1[1]._DOUBLE_val+v2*m2[1]._DOUBLE_val; - double w2=v0*m0[2]._DOUBLE_val+v1*m1[2]._DOUBLE_val+v2*m2[2]._DOUBLE_val; -#ifdef ABC3D - double a=-w0/w2,b=-w1/w2,c=z-(a*x+b*y); - update12(found,found2, - a,b,c,z, - color.u,color.d,color.du,color.dd, - curabc1.x,curabc1.y,curabc1.z,curz1, - curabc2.x,curabc2.y,curabc2.z,curz2, - upcolor,downcolor,downupcolor,downdowncolor); -#else - update12(found,found2, - //x-w2,x,x,y,y,y-w2,z+w0,z,z+w1, - x-0.5,x-.5,x+1,y+.866,y-.866,y,z+.5*w0/w2-.866*w1/w2,z+.5*w0/w2+.866*w1/w2,z-w0/w2, - color.u,color.d,color.du,color.dd, - curx1,curx2,curx3,cury1,cury2,cury3,curz1,curz2,curz3, - cur2x1,cur2x2,cur2x3,cur2y1,cur2y2,cur2y3,cur2z1,cur2z2,cur2z3, - upcolor,downcolor,downupcolor,downdowncolor); -#endif - } - if (delta<=0) continue; // delta==0, twice the same point - v2=sol2; - z=v2+c.z; - is_clipped=sphere_isclipped[k]; - if (!is_clipped){ - double X,Y,Z; - do_transform(invtransform,x,y,z,X,Y,Z); - is_clipped=X>=window_xmin && X<=window_xmax && Y>=window_ymin && Y<=window_ymax && Z>=window_zmin && Z<=window_zmax; - } - if (is_clipped){ - double w0=v0*m0[0]._DOUBLE_val+v1*m1[0]._DOUBLE_val+v2*m2[0]._DOUBLE_val; - double w1=v0*m0[1]._DOUBLE_val+v1*m1[1]._DOUBLE_val+v2*m2[1]._DOUBLE_val; - double w2=v0*m0[2]._DOUBLE_val+v1*m1[2]._DOUBLE_val+v2*m2[2]._DOUBLE_val; -#ifdef ABC3D - double a=-w0/w2,b=-w1/w2,c=z-(a*x+b*y); - update12(found,found2, - a,b,c,z, - color.u,color.d,color.du,color.dd, - curabc1.x,curabc1.y,curabc1.z,curz1, - curabc2.x,curabc2.y,curabc2.z,curz2, - upcolor,downcolor,downupcolor,downdowncolor); -#else - update12(found,found2, - //x-w2,x,x,y,y,y-w2,z+w0,z,z+w1, - x-0.5,x-.5,x+1,y+.866,y-.866,y,z+.5*w0/w2-.866*w1/w2,z+.5*w0/w2+.866*w1/w2,z-w0/w2, - color.u,color.d,color.du,color.dd, - curx1,curx2,curx3,cury1,cury2,cury3,curz1,curz2,curz3, - cur2x1,cur2x2,cur2x3,cur2y1,cur2y2,cur2y3,cur2z1,cur2z2,cur2z3, - upcolor,downcolor,downupcolor,downdowncolor); -#endif - } - } // end hypersphere loop - for (int k=0;k=window_xmin && X<=window_xmax && Y>=window_ymin && Y<=window_ymax && Z>=window_zmin && Z<=window_zmax) -#ifdef ABC3D - update12(found,found2, - abc.x,abc.y,abc.z,z, - color.u,color.d,color.du,color.dd, - curabc1.x,curabc1.y,curabc1.z,curz1, - curabc2.x,curabc2.y,curabc2.z,curz2, - upcolor,downcolor,downupcolor,downdowncolor); -#else - update12(found,found2, - x-1,x,x,y,y,y+1,z-abc.x,z,z+abc.y,color.u,color.d,color.du,color.dd, - curx1,curx2,curx3,cury1,cury2,cury3,curz1,curz2,curz3, - cur2x1,cur2x2,cur2x3,cur2y1,cur2y2,cur2y3,cur2z1,cur2z2,cur2z3, - upcolor,downcolor,downupcolor,downdowncolor); -#endif - } // end hyperplan loop - if (found){ -#ifdef ABC3D - if (found2){ - if (!hide2nd) - glinter(curabc2.x,curabc2.y,curabc2.z,xscale,xc,yscale,yc,zmin2,zmax2,zmin[0],zmax[0],i,horiz,j,w,h,lcdz,downupcolor,downdowncolor,diffusionz,diffusionz_limit,interval); - glinter(curabc1.x,curabc1.y,curabc1.z,xscale,xc,yscale,yc,zmin,zmax,1e307,-1e307,i,horiz,j,w,h,lcdz,upcolor,downcolor,diffusionz,diffusionz_limit,interval); - } - else - glinter(curabc1.x,curabc1.y,curabc1.z,xscale,xc,yscale,yc,zmin,zmax,1e307,-1e307,i,horiz,j,w,h,lcdz,upcolor,downcolor,diffusionz,diffusionz_limit,interval); -#else - if (found2){ - if (!hide2nd) - glinter(cur2x1,cur2x2,cur2x3,cur2y1,cur2y2,cur2y3,cur2z1,cur2z2,cur2z3,xscale,xc,yscale,yc,zmin2,zmax2,zmin[0],zmax[0],i,horiz,j,w,h,lcdz,downupcolor,downdowncolor,diffusionz,diffusionz_limit,interval); - glinter(curx1,curx2,curx3,cury1,cury2,cury3,curz1,curz2,curz3,xscale,xc,yscale,yc,zmin,zmax,1e307,-1e307,i,horiz,j,w,h,lcdz,upcolor,downcolor,diffusionz,diffusionz_limit,interval); - } - else - glinter(curx1,curx2,curx3,cury1,cury2,cury3,curz1,curz2,curz3,xscale,xc,yscale,yc,zmin,zmax,1e307,-1e307,i,horiz,j,w,h,lcdz,upcolor,downcolor,diffusionz,diffusionz_limit,interval); -#endif - } - else { - //std::cout << "not inside " << i << " " << j << " " << x << " " << y << "\n"; - } - } // end pixel vertical loop on j - } // end else only_hypertri - // update jmintab/jmaxtab - if (i+horiz+w & cur=curvev[j]; - int s=cur.size(); - if (s<2) continue; - int4 color=curve_color[j]; - double xy=yc-xc+xscale*2*i; - for (int l=0;l1) - continue; - double dt=2*xscale/(v.y-v.x); // di==1 - double x1=m.x+t1*v.x; - double y1=m.y+t1*v.y; - double z1=m.z+t1*v.z; - double X1,Y1,Z1; - do_transform(invtransform,x1,y1,z1,X1,Y1,Z1); - if (X1window_xmax || Y1window_ymax || Z1window_zmax) - continue; - z1=LCD_HEIGHT_PX/2-lcdz*z1+(x1+y1)/2/yscale; - double dz=-dt*v.z*lcdz+dt*(v.x+v.y)/2/yscale; - int horiz=LCD_WIDTH_PX/2; - for (int k=0;kZ2) std::swap(Z1,Z2); - // line [ (i+k,Z1), (i+k,Z2) ] - if (Z2zmax[k]){ - drawRectangle(i+horiz+k,Z1,1,std::ceil(Z2-Z1),color.d); - continue; - } - drawRectangle(i+horiz+k,Z1,1,std::ceil(Z2-Z1),color.du); - if (Z1zmax[k]) - drawRectangle(i+horiz+k,zmax[k],1,std::ceil(Z2-zmax[k]),color.d); - } - } // end l loop on curve discretization - } // end loop on curves -#ifdef OLD_LINE_RENDERING - for (int j=0;j=0, for segments between 0 and 1 - if (linetypev[j]==_HALFLINE__VECT && t1<0) - continue; - if (linetypev[j]==_GROUP__VECT && (t1<0 || t1>1)) - continue; - double dt=2*xscale/(v.y-v.x); // di==1 - double x1=m.x+t1*v.x; - double y1=m.y+t1*v.y; - double z1=m.z+t1*v.z; - double X1,Y1,Z1; - do_transform(invtransform,x1,y1,z1,X1,Y1,Z1); - // int dbgi,dbgj; xyz2ij(double3(x1,y1,z1),dbgi,dbgj); - /// double x2=x1+dt*v.x,y2=y1+dt*v.y,z2=z1+dt*v.z; - if (X1window_xmax || Y1window_ymax || Z1window_zmax) - continue; - z1=LCD_HEIGHT_PX/2-lcdz*z1+(x1+y1)/2/yscale; - double dz=-dt*v.z*lcdz+dt*(v.x+v.y)/2/yscale; - int horiz=LCD_WIDTH_PX/2; - for (int k=0;kZ2) std::swap(Z1,Z2); - // line [ (i+k,Z1), (i+k,Z2) ] - if (Z2zmax[k]){ - drawRectangle(i+horiz+k,Z1,1,std::ceil(Z2-Z1),color.d); - continue; - } - drawRectangle(i+horiz+k,Z1,1,std::ceil(Z2-Z1),color.du); - if (Z1zmax[k]) - drawRectangle(i+horiz+k,zmax[k],1,std::ceil(Z2-zmax[k]),color.d); - } - } // end lines rendering -#endif - // points rendering - for (int j=0;j=i+horiz+w) - continue; - const int4 & c=point_color[j]; - int k=m.x-i-horiz,color=-1; - double mz=LCD_HEIGHT_PX/2-lcdz*m.z; - double dz=(zmax[k]-zmin[k])*1e-3; - if (mz>=zmax[k]-dz) - color=c.u; - else if (mz<=zmin[k]+dz) - color=c.u; // c.d? - else color=color_gris;//c.du; - drawRectangle(m.x,m.y,3,3,color); - if (points[j]){ - // int dx=RAND_MAX+os_draw_string(-RAND_MAX,0,color,0,points[j],false); // fake print - int dx=os_draw_string_small(0,0,color,0,points[j],true); // fake print - os_draw_string_small(m.x-dx,m.y,color,0,points[j],false); - } - } // end points rendering - } // end pixel horizontal loop on i -#ifndef OLD_LINE_RENDERING - // new line rendering - for (int j=0;j