// -*- mode:C++ ; compile-command: "g++ -I.. -g -c help.cc -Wall" -*- //#define _SCL_SECURE_NO_WARNINGS #include "giacPCH.h" #include "path.h" /* * Copyright (C) 2000,14 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 . */ using namespace std; #include #include "gen.h" #include "help.h" #include #include "global.h" #ifdef HAVE_UNISTD_H #include #endif #if defined VISUALC || defined BESTA_OS #define opendir FindFirstFile #define readdir FindNextFile #define closedir FindClose #define DIR WIN32_FIND_DATA #define GNUWINCE 1 #else // VISUALC or BESTA_OS #ifdef HAVE_SYS_PARAM_H #include #endif #if !defined BESTA_OS && !defined NSPIRE && !defined NUMWORKS // test should always return true #include #endif #endif // VISUALC or BESTA_OS #include "input_lexer.h" #ifndef NO_NAMESPACE_GIAC namespace giac { #endif // ndef NO_NAMESPACE_GIAC const int HELP_LANGUAGES=4; struct static_help_t { const char * cmd_name; const char * cmd_howto[HELP_LANGUAGES]; const char * cmd_syntax; const char * cmd_related; const char * cmd_examples; }; const static_help_t static_help[]={ #if !defined RTOS_THREADX && !defined BESTA_OS && !defined GIAC_HAS_STO_38 #include "static_help.h" #else { "", { "", "", "", ""}, "", "", "" }, #endif }; const int static_help_size=sizeof(static_help)/sizeof(static_help_t); struct static_help_sort { static_help_sort() {} inline bool operator () (const static_help_t & a ,const static_help_t & b){ return strcmp(a.cmd_name, b.cmd_name) < 0; } }; inline int mon_max(int a,int b){ if (a>b) return a; else return b; } bool seconddec (const pair & a,const pair & b){ return a.second>b.second; } // NB: cmd_name may be localized but related is not localized bool has_static_help(const char * cmd_name,int lang,const char * & howto,const char * & syntax,const char * & related,const char * & examples){ #ifdef GIAC_HAS_STO_38 const char nullstring[]=" "; #else const char nullstring[]=""; #endif if (lang<=0) lang=2; if (lang>HELP_LANGUAGES) lang=2; string s=unlocalize(cmd_name); int l=int(s.size()); if ( (l>2) && (s[0]=='\'') && (s[l-1]=='\'') ) s=s.substr(1,l-2); static_help_t h={s.c_str(),{0,0,0,0},0,0,0}; std::pair p=equal_range(static_help,static_help+static_help_size,h,static_help_sort()); if (p.first!=p.second && p.first!=static_help+static_help_size){ howto=p.first->cmd_howto[lang-1]; if (!howto) howto=p.first->cmd_howto[1]; syntax=p.first->cmd_syntax; if (!syntax) syntax=nullstring; related=p.first->cmd_related; if (!related) related=nullstring; examples=p.first->cmd_examples; if (!examples) examples=nullstring; return true; } #ifdef EMCC // Find closest string syntax=nullstring; related=nullstring; static string res; res=""; int best_score=0,cur_score; vector< pair > best_j; for (int j=0;jbest_score){ best_score=cur_score; vector< pair > tmp; for (unsigned k=0;k=best_score-6) tmp.push_back(best_j[k]); } best_j=tmp; best_j.push_back(pair(j,cur_score)); continue; } if (cur_score>=mon_max(best_score-6,0)){ best_j.push_back(pair(j,cur_score)); } } if (best_score>0){ sort(best_j.begin(),best_j.end(),seconddec); vector< pair >::iterator it=best_j.begin(),itend=best_j.end(); for (int k=1;(k<10) && (it!=itend);++k,++it){ res = res+static_help[it->first].cmd_name; res = res+","; } if (!res.empty()) res=res.substr(0,res.size()-1); } static string syn; syn = gettext("Best match has score ") + printint(best_score) + "\n"; howto = syn.c_str(); examples = res.c_str(); return true; #else return false; #endif } static std::string output_quote(const string s){ string res; int ss=int(s.size()); for (int i=0;i & v,const vector & langv){ #ifndef NSPIRE ofstream of("static_help.h"); vector::iterator it=v.begin(),itend=v.end(); for (;it!=itend;){ of << "{"; of << '"' << output_quote(it->cmd_name) << '"' << ","; std::vector & blabla = it->blabla; sort(blabla.begin(),blabla.end()); int bs=int(blabla.size()); of << "{"; for (int i=0;isyntax) << '"' << ',' ; std::vector & examples = it->examples; bs=int(examples.size()); if (bs){ of << '"'; for (int i=0;i & related = it->related; bs=int(related.size()); if (bs){ of << '"'; for (int i=0;icmd_name; ofw << 'L' << '"' << output_quote(cmd) << '"' << ","; if (cmd.size()>16) cmd=cmd.substr(0,16); ofwindex << "{NULL,NULL, " << 'L' << '"' << output_quote(cmd) << '"' << ", HIDVoid }" ; std::vector & blabla = it->blabla; sort(blabla.begin(),blabla.end()); int bs=int(blabla.size()); ofw << "{"; for (int i=0;icmd_name) << '(' << output_quote(it->syntax) << ')' << '"' << ',' ; std::vector & examples = it->examples; bs=int(examples.size()); if (bs>=1){ ofw << 'L' << '"'; ofw << output_quote(examples[0]) ; ofw << '"' << ','; if (bs>=2){ ofw << 'L' << '"'; ofw << output_quote(examples[1]) ; ofw << '"' << ','; } else ofw << 0 << ","; } else ofw << 0 << "," << 0 << ","; std::vector & related = it->related; bs=int(related.size()); if (bs>=1){ ofw << 'L' << '"'; ofw << output_quote(related[0].chaine) ; ofw << '"' << ','; if (bs>=2){ ofw << 'L' << '"'; ofw << output_quote(related[1].chaine) ; ofw << '"' << ','; } else ofw << 0 << ","; } else ofw << 0 << "," << 0 << ","; ofw << "}"; ++it; if (it==itend) break; ofw << "," << endl; ofwindex << "," << endl; } ofw << endl; ofwindex << "};" << endl; #endif return true; } bool operator < (const indexed_string & is1,const indexed_string & is2){ if (is1.index!=is2.index) return is1.index-1;--length,i/=10) s[length]=i%10+'0'; #if defined VISUALC || defined BESTA_OS string res=s; delete [] s; return res; #else return s; #endif } inline int max(int a,int b,int c){ if (a>=b){ if (a>=c) return a; else return c; } if (b>=c) return b; else return c; } int score(const string & s,const string & t){ int ls=int(s.size()),lt=int(t.size()); if (!ls) return -1; vector cur_l, new_l(lt+1,0); for (int j=0;j<=lt;++j) cur_l.push_back(-j); vector::iterator newbeg=new_l.begin(),newend=new_l.end(),newit=newbeg; vector::iterator curbeg=cur_l.begin(),curit;//curend=cur_l.end(), for (int i=0;i & current_synonymes){ current_synonymes.clear(); // parse curren_aide.cmd_name for synonyms string s=cmd_name,s1; int i; for (;;){ // cout << s << endl; i=int(s.find(' ')); if (i<=0){ if (!s.empty()) current_synonymes.push_back(localized_string(0,s)); break; } s1=s.substr(0,i); current_synonymes.push_back(localized_string(0,s1)); /* add also keyword translations of s1 multimap::iterator it=back_lexer_localization_map().find(s1),backend=back_lexer_localization_map().end(),itend=back_lexer_localization_map().upper_bound(s1); if (it!=backend){ for (;it!=itend;++it){ current_synonymes.push_back(it->second); } } */ s=s.substr(i+1,s.size()-i-1); } // end for (;;) } vector readhelp(const char * f_name,int & count,bool warn){ vector v(1); readhelp(v,f_name,count,warn); return v; } // FIXME: aide_cas may end with synonyms (# cmd synonym1 ...) void readhelp(vector & v,const char * f_name,int & count,bool warn){ count=0; #ifndef NSPIRE if (access(f_name,R_OK)){ if (warn) std::cerr << "Help file " << f_name << " not found" << endl; return ; } // v.reserve(1600); ifstream f(f_name); char fs[HELP_MAXLENSIZE+1]; vector current_blabla; vector current_related; vector current_examples; aide current_aide; vector vposition; int vpositions; string current_line; vector current_synonymes; while (f){ f.getline(fs,HELP_MAXLENSIZE,'\n'); if (!fs[0]) continue; current_line=fs; if (fs[0]=='#'){ current_aide.blabla=current_blabla; current_aide.examples=current_examples; current_aide.related=current_related; if (!current_aide.cmd_name.empty()){ find_synonymes(current_aide.cmd_name,current_synonymes); current_aide.synonymes=current_synonymes; vector::const_iterator it=current_synonymes.begin(),itend=current_synonymes.end(); vpositions=int(vposition.size()); for (int pos=0;it!=itend;++it,++pos){ current_aide.cmd_name=it->chaine; if (pos2?current_line.substr(2,current_line.size()-2):""; // search if cmd_name is already present in v // if so set vposition, current_blabla/examples/related accordingly find_synonymes(current_aide.cmd_name,current_synonymes); vector::const_iterator itbeg=current_synonymes.begin(),itend=current_synonymes.end(),it; vector::iterator itpos; for (it=itbeg;it!=itend;++it){ itpos=lower_bound(v.begin(),v.end(),current_aide,alpha_order); if (itpos!=v.end()){ // --itpos; if (itpos->cmd_name==it->chaine){ // already documented current_synonymes=itpos->synonymes; current_blabla=itpos->blabla; current_examples=itpos->examples; current_related=itpos->related; vposition.push_back(int(itpos-v.begin())); } } } continue; } // look for space int l=int(current_line.find_first_of(' ')); if ( (l==1) && (current_line[0]=='0') ){ int cs=int(current_line.size()); while (l'9')){ n=0; break; } else n=10*n+(current_line[i]-int('0')); } if (!positif) n=-n; if (n>0) current_blabla.push_back(localized_string(n,current_line.substr(l+1,current_line.size()-l))); else { if (n<0) current_related.push_back(indexed_string(-n,current_line.substr(l+1,current_line.size()-l))); else current_examples.push_back(current_line); } } // end reading help from file if (!current_aide.cmd_name.empty()){ current_aide.synonymes=vector(1,localized_string(0,current_aide.cmd_name)); current_aide.blabla=current_blabla; current_aide.examples=current_examples; current_aide.related=current_related; v.push_back(current_aide); count++; } sort(v.begin(),v.end(),alpha_order); if (debug_infolevel==-2){ vector langv; langv.push_back(1); langv.push_back(2); // langv.push_back(3); // langv.push_back(4); output_static_help(v,langv); } #endif } static aide add_synonyme_name_to_examples(const aide & a){ aide res(a); std::vector::iterator it=res.examples.begin(),itend=res.examples.end(); for (;it!=itend;++it){ if (!it->empty() && (*it)[0]==' ') continue; // look for a ( unsigned i=unsigned(it->find('(')); if (i>0 && isize()){ // check whether the beginning of the string is in synonyms string cmd=it->substr(0,i); std::vector::const_iterator jt=res.synonymes.begin(),jtend=res.synonymes.end(); for (;jt!=jtend;++jt){ if (jt->chaine==cmd) break; } if (jt!=jtend) // Yes, replace it *it=res.cmd_name+it->substr(i,it->size()-i); else *it=res.cmd_name+'('+*it+')'; } else *it=res.cmd_name+'('+*it+')'; } return res; } aide helpon(const string & demande,const vector & v,int language,int count,bool with_op){ aide result; string current(demande); if (with_op) result.syntax = gettext("No help available for ") +current +"\n"; else result.syntax="NULL"; if (!count){ return result; } for (int i=1;;++i){ if (i==count){ if (!with_op) return result; // Find closest string int best_score=0,cur_score; vector< pair > best_j; for (int j=1;jbest_score){ best_score=cur_score; vector< pair > tmp; for (unsigned k=0;k=best_score-6) tmp.push_back(best_j[k]); } best_j=tmp; best_j.push_back(pair(j,cur_score)); continue; } if (cur_score>=mon_max(best_score-6,0)){ best_j.push_back(pair(j,cur_score)); } } if (best_score>0){ sort(best_j.begin(),best_j.end(),seconddec); vector< pair >::iterator it=best_j.begin(),itend=best_j.end(); for (int k=1;(k<10) && (it!=itend);++k,++it) result.related.push_back(indexed_string(k,v[it->first].cmd_name)); } result.syntax += gettext("Best match has score ") + printint(best_score) + "\n"; result.cmd_name = current; return result; } if (current==v[i].cmd_name){ result=v[i]; if (!with_op) return add_synonyme_name_to_examples(result); result.syntax= current + "(" +result.syntax +")\n"; return add_synonyme_name_to_examples(result); } } // end for i } string writehelp(const aide & cur_aide,int language){ string result=cur_aide.syntax; vector::const_iterator it=cur_aide.blabla.begin(),itend=cur_aide.blabla.end(); for (;it!=itend;++it){ if (it->language==language){ result += it->chaine +'\n' ; break; } } vector::const_iterator iti=cur_aide.related.begin(),itiend=cur_aide.related.end(); if (itiend!=iti){ result += gettext("See also: "); for (;iti!=itiend;++iti){ result += printint(iti->index) + "/ " + iti->chaine + " "; } result += '\n' ; } vector::const_iterator its=cur_aide.examples.begin(),itsend=cur_aide.examples.end(); for (int i=1;its!=itsend;++its,++i){ string current = "Ex" + printint(i)+':'+*its ; result += current +'\n' ; // system(current.c_str()); } return result; } #if !defined(NSPIRE_NEWLIB) || !defined(RTOS_THREADX) && !defined(EMCC) &&!defined(NSPIRE) multimap html_mtt,html_mall; std::vector html_vtt,html_vall; // WARNING rebuilding caches works with old version of hevea (1.10) but not with hevea 2.29 // find index nodes in file file static bool find_index(const std::string & current_dir,const std::string & file,multimap&mtt,multimap&mall,bool is_index=false,bool warn=false){ if (access(file.c_str(),R_OK)) return false; ifstream i(file.c_str()); // Skip navigation panel #if defined VISUALC || defined BESTA_OS || defined FREERTOS char * buf=new char[BUFFER_SIZE+1]; #else char buf[BUFFER_SIZE+1]; #endif for (;i && !i.eof();){ i.getline(buf,BUFFER_SIZE,'\n'); string s(buf),stmp; if (s=="") // latex2html? break; int t=int(s.size()); if (t>24 && ((stmp=s.substr(t-24,24))=="
  • " || stmp=="
  • ")){ // hevea file contains index for (;i && !i.eof(); ){ i.getline(buf,BUFFER_SIZE,'\n'); s=buf; t=int(s.size()); if (t>29 && ((stmp=s.substr(0,29))=="
  • " || stmp=="
  • ")){ s=s.substr(29,s.size()-29); t=int(s.size()); if (!t || s[0]=='<') // skip index words with special color/font continue; int endcmd=int(s.find("<")); // position of end of commandname if (endcmd>2 && endcmd hrefs; for (;;){ t=int(s.size()); endcmd=int(s.find("=t){ endcmd=int(s.find("=t) break; } s=s.substr(endcmd+9,s.size()-endcmd-9); t=int(s.size()); endcmd=int(s.find("\"")); if (endcmd<0 || endcmd+2>=t) break; string link=s.substr(0,endcmd); if (link[0]=='#') link = file + link; else link = current_dir + link; s=s.substr(endcmd+2,s.size()-endcmd-2); t=int(s.size()); if (t<3) break; if (s.substr(0,3)=="" || (t>30 && s.substr(0,29)=="::const_iterator it=hrefs.begin(),itend=hrefs.end(); for (;it!=itend;++it){ if (it==hrefs.begin()) mtt.insert(pair(cmdname,*it)); mall.insert(pair(cmdname,*it)); } } // if (endcmd>2 && endcmd29 &&... } // for (;i && !i.eof();) end of file #if defined VISUALC || defined BESTA_OS || defined FREERTOS delete [] buf; #endif return true; } // end hevea file with index // latex2html only? if (t>14 && s.substr(t-14,14)=="Index "){ // look in the corresponding index file instead int t1=int(s.find("HREF"))+6; if (t1>=0 && t1> tmp; int l=int(tmp.size()); string tts; if (is_index){ if (l<13) continue; int tmpl=0; if (tmp.substr(0,8)=="") tmpl=8; if (tmp.substr(0,12)=="
    ") tmpl=12; if (!tmpl) continue; int l1=int(tmp.find("")); if (l1<=tmpl || l1>=l) continue; tts=tmp.substr(tmpl,l1-tmpl); } else { if (l<2 || tmp.substr(l-2,2)!="4 && tmp.substr(s-4,4)=="
    "){ // no found, truncate tmp to the first found int l=int(tmp.find("")); if (l0) tmp=tmp.substr(0,l); s=int(tmp.size()); break; } if (s>8 && tmp.substr(s-8,8)==""){ // Find backward the first occurence of 0;--l){ if (tmp[l]=='<' && tmp[l+1]=='A') break; } if (l){ tmp=tmp.substr(l,s-l); s -= l; } break; } } // cerr << tmp << endl; // analysis, search for HREF int href=int(tmp.find("HREF=\"")); if (href<0 || href+6>=s) continue; string hrefs(current_dir); int hrefend=0; for (int j=href+6;j(tts,hrefs)); mall.insert(pair(tts,hrefs)); } else { // search for TT int tt=int(tmp.find("")),ttend=tt; if (tt>=0 && tt+6(tts,hrefs)); mall.insert(pair(tts,hrefs)); tmp=tmp.substr(0,tt)+tmp.substr(ttend,tmp.size()-ttend); } // add href for all normal words s=int(tmp.size()); int j=hrefend+1; for (;jj && pos(tmpins,hrefs)); } if (pos==-1){ string tmpins(tmp.substr(j,s-j)); mall.insert(pair(tmpins,hrefs)); break; } j=pos+1; } } // end else is_index } return false; } static const string subdir_strings[]={"cascmd","casgeo","casrouge","cassim","castor","tutoriel","casinter","casexo","cascas"}; static const int subdir_taille=sizeof(subdir_strings)/sizeof(string); static int equalposcomp(const string * tab,const string & s){ int i=int(s.size())-1; for (;i>=0;--i){ if (s[i]=='/') break; } ++i; string t=s.substr(i,s.size()-i); i=int(t.size())-1; for (;i>=0;--i){ if (t[i]=='_') t=t.substr(0,i); } for (i=0;id_name); // cerr << s << endl; int t=s.size(); if (s[t-1]=='\\'){ return s!="." && s!=".."; } if (t<9) return 0; if (s[t-1]=='l'){ s=s.substr(0,t-1); --t; } if (t>9) s=s.substr(t-9,9); return s=="index.htm"; } #else // __APPLE_CC__ == 5666 on Mac OS X 10.6, 5658 on geogebra build system OS X 10.8 // should check __APPLE__ OS X version instead! #if ( defined(__MAC_OS_X_VERSION_MAX_ALLOWED)&& __MAC_OS_X_VERSION_MAX_ALLOWED< 1080 ) || ( defined(__IPHONE_OS_VERSION_MAX_ALLOWED)&& __IPHONE_OS_VERSION_MAX_ALLOWED< 60100 ) || defined(__OpenBSD__) || ( defined(__FreeBSD_version)&& __FreeBSD_version<800501) static int dir_select (struct dirent *d){ #else static int dir_select (const struct dirent *d){ #endif string s(d->d_name); if (d->d_type==DT_DIR || equalposcomp(subdir_strings,s)){ return s!="." && s!=".."; } int t=s.size(); if (t<9) return 0; if (s[t-1]=='l'){ s=s.substr(0,t-1); --t; } if (t>9) s=s.substr(t-9,9); return s=="index.htm"; } #endif #endif // visualc void find_all_index(const std::string & subdir,multimap & mtt,multimap & mall){ #if defined GNUWINCE || defined __MINGW_H || defined __ANDROID__ || defined EMCC || defined NSPIRE_NEWLIB return; #else // cerr << "HTML help Scanning " << subdir << endl; DIR *dp; struct dirent *ep; dp = opendir (subdir.c_str()); if (dp != NULL){ string s; int t; while ( (ep = readdir (dp)) ){ s=ep->d_name; t=s.size(); if (t>5 && s.substr(t-4,4)=="html") html_vall.push_back(subdir+s); } closedir (dp); } struct dirent **eps; int n; #if defined APPLE_SMART || defined NO_SCANDIR n =-1; #else n = scandir (subdir.c_str(), &eps, dir_select, alphasort); #endif if (n >= 0){ bool index_done=false; int cnt; for (cnt = -1; cnt < n; ++cnt){ string s; if (cnt==-1) s="index.html"; else s=eps[cnt]->d_name; s= subdir+s; #ifdef WIN32 int t=s.size(); if (s[t-1]=='\\') find_all_index(s+"/",mtt,mall); else { if (!index_done) index_done=find_index(subdir,s,mtt,mall); } #else unsigned char type=cnt>=0?eps[cnt]->d_type:0; if (type==DT_DIR || equalposcomp(subdir_strings,s)) find_all_index(s+"/",mtt,mall); else { if (!index_done) index_done=find_index(subdir,s,mtt,mall); } #endif } } #endif // GNUWINCE } // Return all HTML nodes refered to s in mtt std::vector html_help(multimap & mtt,const std::string & s){ vector v; multimap::const_iterator it=mtt.lower_bound(s),itend=mtt.upper_bound(s); for (;it!=itend;++it){ v.push_back(it->second); } return v; } string xcasroot_dir(const char * arg){ string xcasroot; if (getenv("XCAS_ROOT")){ xcasroot=string(getenv("XCAS_ROOT")); if (xcasroot.empty()) xcasroot="/"; if (xcasroot[xcasroot.size()-1]!='/') xcasroot+='/'; } else { xcasroot=arg; int xcasroot_size=int(xcasroot.size())-1; for (;xcasroot_size>=0;--xcasroot_size){ if (xcasroot[xcasroot_size]=='/') break; } if (xcasroot_size>0) xcasroot=xcasroot.substr(0,xcasroot_size)+"/"; else { if (access("/usr/bin/xcas",R_OK)==0) xcasroot="/usr/bin/"; else { #ifdef __APPLE__ if (access("/Applications/usr/bin/xcas",R_OK)==0) xcasroot="/Applications/usr/bin"; #else if (access("/usr/local/bin/xcas",R_OK)==0) xcasroot="/usr/local/bin/"; #endif else xcasroot="./"; } } } // ofstream of("/tmp/xcasroot"); // of << xcasroot << endl; return xcasroot; } // extern int debug_infolevel; static bool get_index_from_cache(const char * filename, multimap & multi,bool verbose){ #if defined VISUALC || defined BESTA_OS || defined FREERTOS char * buf = new char[BUFFER_SIZE]; #else char buf[BUFFER_SIZE]; #endif ifstream if_mtt(filename); int n=0; while (if_mtt && !if_mtt.eof()){ if_mtt.getline(buf,BUFFER_SIZE,char(0xa4)); // was '¤', utf8 not compatible, octal \244 if (!if_mtt || if_mtt.eof()){ if (verbose) cerr << "// Read " << n << " entries from cache " << filename << endl; #if defined VISUALC || defined BESTA_OS || defined FREERTOS delete [] buf; #endif return true; } string first(buf); if_mtt.getline(buf,BUFFER_SIZE,char(0xa4)); if (!if_mtt || if_mtt.eof()){ #if defined VISUALC || defined BESTA_OS || defined FREERTOS delete [] buf; #endif return false; } multi.insert(pair(first,buf)); if (!(n%100)){ // check every 100 links if link exists first=buf; int l=int(first.size()),j; char ch=0; for (j=l-1;j>=0;--j){ ch=first[j]; if (ch=='#' || ch=='/') break; } if (j>0 && ch=='#') first=first.substr(0,j); if (access(first.c_str(),R_OK)){ multi.clear(); cerr << "Wrong cache! " << filename << endl; if_mtt.close(); #if !defined RTOS_THREADX && !defined BESTA_OS && !defined FREERTOS if (unlink(filename)==-1) cerr << "You don't have write permissions on " << filename <<".\nYou must ask someone who has write permissions to remove " << filename << endl; else cerr << "Cache file "<< filename << " has been deleted" << endl; #endif #if defined VISUALC || defined BESTA_OS || defined FREERTOS delete [] buf; #endif return false; } } ++n; if_mtt.getline(buf,BUFFER_SIZE,'\n'); } if (verbose) cerr << "// Read " << n << " entries from cache " << filename ; #if defined VISUALC || defined BESTA_OS || defined FREERTOS delete [] buf; #endif return true; } static bool get_index_from_cache(const char * filename, vector & multi,bool verbose){ #if defined VISUALC || defined BESTA_OS || defined FREERTOS char * buf = new char[BUFFER_SIZE]; #else char buf[BUFFER_SIZE]; #endif ifstream if_mtt(filename); int n=0; while (if_mtt && !if_mtt.eof()){ if_mtt.getline(buf,BUFFER_SIZE,char(0xa4)); if (!if_mtt || if_mtt.eof()){ #if defined VISUALC || defined BESTA_OS || defined FREERTOS delete [] buf; #endif if (verbose) cerr << "// Read " << n << " entries from cache " << filename << endl; return true; } multi.push_back(buf); ++n; if_mtt.getline(buf,BUFFER_SIZE,'\n'); } #if defined VISUALC || defined BESTA_OS || defined FREERTOS delete [] buf; #endif if (verbose) cerr << "// Read " << n << " entries from cache " << filename ; return true; } string html_help_init(const char * arg,int language,bool verbose,bool force_rebuild){ string xcasroot=xcasroot_dir(arg); // HTML online help string html_help_dir=xcasroot+"doc/"; if (access(html_help_dir.c_str(),R_OK)){ #ifdef __APPLE__ if (!access("/Applications/usr/bin/icas",R_OK)) html_help_dir="/Applications/usr/share/giac/doc/"; #else if (!access("/usr/bin/xcas",R_OK)) html_help_dir="/usr/share/giac/doc/"; #endif else { if (!access("/usr/local/bin/xcas",R_OK)) html_help_dir="/usr/local/share/giac/doc/"; } } if (access(html_help_dir.c_str(),R_OK) && xcasroot.size()>4 && xcasroot.substr(xcasroot.size()-4,4)=="bin/") html_help_dir=xcasroot.substr(0,xcasroot.size()-4)+"share/giac/doc/"; if (access(html_help_dir.c_str(),R_OK)) cerr << "Unable to open HTML doc directory " << html_help_dir << endl; html_help_dir += find_lang_prefix(language); #ifdef WIN32 string html_help_dir_save=html_help_dir; html_help_dir +="cascmd_"+find_lang_prefix(giac::language(context0)); // temporary workaround, for win archive copy doc/fr/html_vall to doc/fr/cascmd_fr/html_vall and change path #endif html_mtt.clear(); html_mall.clear(); html_vall.clear(); // Get indices from file cache if it exists if (!force_rebuild && !access((html_help_dir+"html_mtt").c_str(),R_OK) && !access((html_help_dir+"html_mall").c_str(),R_OK) && !access((html_help_dir+"html_vall").c_str(),R_OK)){ if (get_index_from_cache((html_help_dir+"html_mtt").c_str(),html_mtt,verbose)&& get_index_from_cache((html_help_dir+"html_mall").c_str(),html_mall,verbose)&& get_index_from_cache((html_help_dir+"html_vall").c_str(),html_vall,verbose) ) return html_help_dir; } find_all_index(html_help_dir,html_mtt,html_mall); #ifdef WIN32 for (unsigned i=0;i::const_iterator it=html_mtt.begin(),itend=html_mtt.end(); for (;it!=itend;++it) of_mtt << it->first << char(0xa4) << it->second << char(0xa4) << endl; of_mtt.close(); ofstream of_mall((html_help_dir+"html_mall").c_str()); it=html_mall.begin();itend=html_mall.end(); for (;it!=itend;++it) of_mall << it->first << char(0xa4) << it->second << char(0xa4) << endl; of_mall.close(); ofstream of_vall((html_help_dir+"html_vall").c_str()); vector::const_iterator st=html_vall.begin(),stend=html_vall.end(); for (;st!=stend;++st) of_vall << *st << char(0xa4) << endl; of_vall.close(); /* if (debug_infolevel){ vector::const_iterator it=html_vall.begin(),itend=html_vall.end(); for (;it!=itend;++it) cerr << *it << endl; } */ return html_help_dir; } static bool multigrep(FILE * f,const string & s){ int l=int(s.size()); // find spaces string tmp; vector vs; for (int i=0;i='A' && c<='F') code = code*base + c-'A'+10; if (c>='a' && c<='f') code = code*base + c-'a'+10; if (c>='0' && c<='9') code = code*base + c-'0'; } } else{ switch (code){ case 0xe8: case 0xe9: case 0xea: c='e'; break; case 0xe0: case 0xe2: c='a'; break; case 0xf4: c='o'; break; case 0xf9: case 0xfb: c='u'; break; case 0xe7: c='c'; break; case 238: c='i'; break; } break; } } } } if (c==' '){ if (!tmp.empty()){ // search tmp in vs unsigned tmpl=unsigned(tmp.size()),tmpvs; for (int i=0;i='0' && ch<='9') return true; if (ch>='a' && ch<='z') return true; if (ch>='A' && ch<='Z') return true; if (unsigned(ch)>128) return true; if (ch=='_' || ch=='.' || ch=='~') return true; /* char * ptr=otherchars; for (;*ptr;++ptr){ if (ch==*ptr) return true; } */ return false; } std::string unlocalize(const std::string & s){ std::string res,tmp; int ss=int(s.size()); std::map::const_iterator it,itend=lexer_localization_map().end(); int mode=0; // 1 if inside a string for (int i=0;;++i){ char ch=s[i]; if (mode){ if (ch=='"'){ if (res.empty() || res[res.size()-1]!='\\') mode=0; } res += ch; if (i==ss) break; continue; } if (isecond; // it is -> we must translate to giac res += tmp; tmp = ""; if (ch=='"'){ if (res.empty() || res[res.size()-1]!='\\') mode=1; } if (i::const_iterator it0,it,itend,backend=back_lexer_localization_map().end(); for (int i=0;;++i){ char ch=s[i]; if (mode){ if (ch=='"'){ if (res.empty() || res[res.size()-1]!='\\') mode=0; } res += ch; if (i==ss) break; continue; } if (isecond.language==language){ tmp = it->second.chaine; break; } } if (it==itend) tmp = it0->second.chaine; } res += tmp; tmp = ""; if (ch=='"'){ if (res.empty() || res[res.size()-1]!='\\') mode=1; } if (i