10 return (access(fn,F_OK)!=-1);
18 #define ENTER endl<<endl<<endl
23 if(getpid()!=pid)
return;
26 script <<
"&q;" << endl <<
"&x;" <<
ENTER;
27 string istr = script.str();
28 write(P2C[1], istr.c_str(), istr.length());
30 waitpid(fpid, &st, WUNTRACED);
41 if (pipe(P2C)==-1 || pipe(C2P)==-1) {
42 throw Error(
"pipe failed in Fermat::Init.");
47 if(setpgid(0,0))
throw Error(
"setpgid failed in Fermat::Init.");
54 execlp(fer_path.c_str(), fer_path.c_str(), NULL);
63 script <<
"&(_d=90000);" << endl;
64 script <<
"&d" << endl <<
"0;" << endl;
65 script <<
"&(_t=0);" << endl;
66 script <<
"&(t=0);" << endl;
67 script <<
"&(_s=0);" << endl;
68 script <<
"&(_o=1000);" << endl;
69 script <<
"&(M=' ');" << endl;
71 string istr = script.str();
72 write(P2C[1], istr.c_str(), istr.length());
79 for(
int i=0; i<n+1; i++) buffer[i] =
'\0';
80 nio = read(C2P[0], buffer, n);
81 if(nio>0) ostr += buffer;
82 else throw Error(ostr);
84 if(cpos!=string::npos) {
85 const char* WhiteSpace =
" \t\v\r\n";
86 auto lpos = ostr.find_last_not_of(WhiteSpace);
87 if(ostr[lpos]!=
'0') read(C2P[0], buffer, n);
94 string_replace_all(ostr,
"*** Fermat Warning. Early exit from mod_multivar_Chinese.",
"");
95 if(ostr.find(
"***")!=string::npos) {
96 cout <<
"Fermat script: " << endl << istr << endl << endl;
97 throw Error(ostr.c_str());
103 if(exited)
throw Error(
"Fermat has already exited.");
104 if(getpid() != pid)
throw Error(
"Fermat: can not Execute on child process.");
105 ostringstream script;
106 script << expr << endl;
108 string istr = script.str();
109 write(P2C[1], istr.c_str(), istr.length());
116 for(
int i=0; i<n+1; i++) buffer[i] =
'\0';
117 nio = read(C2P[0], buffer, n);
118 if(nio>0) ostr += buffer;
119 else throw Error(ostr);
121 if(cpos!=string::npos) {
122 const char* WhiteSpace =
" \t\v\r\n";
123 auto lpos = ostr.find_last_not_of(WhiteSpace);
124 if(ostr[lpos]!=
'0') read(C2P[0], buffer, n);
132 if(ostr.find(
"***")!=string::npos) {
133 cout << endl << expr << endl << endl;
134 throw Error(ostr.c_str());
145 if(getpid()!=pid)
return;
146 if(inited && !exited) {
147 string exit_cmd =
"\n.end\n" +
Prompt +
"\n";
148 write(io[0][1], exit_cmd.c_str(), exit_cmd.length());
150 read(io[1][0], buffer, 8);
152 waitpid(fpid, &st, WUNTRACED);
163 if (pipe(io[0])==-1 || pipe(io[1])==-1 || pipe(stdo)==-1) {
166 throw Error(
"pipe failed in Form::Init.");
171 if(setpgid(0,0))
throw Error(
"setpgid failed in Form::Init.");
177 auto cpid = getpid();
179 oss <<
"init-" << cpid <<
".frm";
182 ofs.open(oss.str().c_str(), ios::out);
186 throw Error(
"failed to open init.frm file!");
188 ofs <<
"Off Statistics;" << endl;
189 ofs <<
"#ifndef `PIPES_'" << endl;
190 ofs <<
" #message \"No pipes found\";" << endl;
191 ofs <<
" .end;" << endl;
192 ofs <<
"#endif" << endl;
193 ofs <<
"#if (`PIPES_' <= 0)" << endl;
194 ofs <<
" #message \"No pipes found\";" << endl;
195 ofs <<
" .end;" << endl;
196 ofs <<
"#endif" << endl;
197 ofs <<
"#procedure put(mexp)" << endl;
198 ofs <<
" Format Nospaces;" << endl;
199 ofs <<
" ON NoSpacesInNumbers;" << endl;
200 ofs <<
" #write \""<<
Sentinel<<
"\\n\"" << endl;
201 ofs <<
" #toexternal \"%E\", `mexp'" << endl;
202 ofs <<
" #toexternal \""<<
Sentinel<<
"\"" << endl;
203 ofs <<
" #toexternal \"\\n\"" << endl;
204 ofs <<
"#endprocedure" << endl;
205 ofs <<
"#setexternal `PIPE1_';" << endl;
206 ofs <<
"#toexternal \"OK\"" << endl;
207 ofs <<
"Local [o]=0;" << endl;
208 ofs <<
".sort" << endl;
209 ofs <<
"Format Mathematica;" << endl;
210 ofs <<
"#prompt \"" <<
Prompt <<
"\"" << endl;
211 ofs <<
"#fromexternal-" << endl;
212 ofs <<
".end" << endl;
215 execlp(form_path.c_str(), form_path.c_str(),
217 (to_string(io[0][0])+
","+to_string(io[1][1])).c_str(),
218 "-M", (
"init-"+to_string(cpid)).c_str(),
228 read(io[1][0], buffer,
sizeof(buffer));
229 char* p = strstr(buffer,
"\n");
233 cout <<
"the return is: <|" << buffer <<
"|>" << endl;
234 throw Error(
"Init Failed: Expect a Line break!");
236 sprintf(p,
",%d\n\n", fpid);
237 write(io[0][1], buffer, strlen(buffer));
238 read(io[1][0], buffer,
sizeof(buffer));
239 p = strstr(buffer,
"OK");
240 if(p==NULL || p!=buffer) {
243 throw Error(
"Init Failed: Expect OK!");
247 oss <<
"init-" << fpid <<
".frm";
248 if(
file_exists(oss.str().c_str())) remove(oss.str().c_str());
256 for(
int i=0; i<n+1; i++) buffer[i] =
'\0';
257 nio = read(stdo[0], buffer, n);
258 if(nio>0) estr += buffer;
260 if(cpos!=string::npos)
break;
261 cpos = estr.find(
"-->");
262 if(cpos!=string::npos) {
272 if(exited)
throw Error(
"Form has already exited.");
273 if(getpid() != pid)
throw Error(
"Form: can not Execute on child process.");
274 string istr = script;
275 istr +=
"\n.sort\n#call put(";
277 istr +=
")\n.sort\n";
280 write(io[0][1], istr.c_str(), istr.length());
289 for(
int i=0; i<n+1; i++) buffer[i] =
'\0';
290 nio = read(stdo[0], buffer, n);
291 if(nio>0) estr += buffer;
292 auto cpos = estr.find(
"-->");
293 if(cpos!=string::npos) {
299 if(cpos!=string::npos)
break;
303 for(
int i=0; i<n+1; i++) buffer[i] =
'\0';
304 nio = read(io[1][0], buffer, n);
305 if(nio>0) ostr += buffer;
309 for(
int i=0; i<n+1; i++) buffer[i] =
'\0';
310 nio = read(stdo[0], buffer, n);
316 throw Error(estr.c_str());
319 if(cpos!=string::npos) {
320 ostr.replace(cpos,
Sentinel.length(),
"");
bool file_exists(const char *fn)
class used to wrap error message
void Init(string fer_path="fer64")
bool file_exists(string fn)
void string_replace_all(string &str, const string &from, const string &to)
void string_trim(string &str)