Back to index

wims  3.65+svn20090927
mup.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018        /* Interface MuPAD to wims */
00019 
00020 /*************** Customization: change values hereafter ****************/
00021 
00022        /* limit of input/output file sizes */
00023 #define fsizelim 2621440
00024        /* String to tell the program to quit. */
00025 #define quitstring "\nquit;\n"
00026        /* The way to print a string in the program. */
00027 #define stringprinter "print(\"%s\");\n"
00028 
00029        /* default path setups */
00030 char *nameofcmd="/usr/local/lib/mupad/share/bin/mupad";
00031 int precision=20;    /* default */
00032 
00033 #define libpath "lib"
00034 #define helppath "doc/ascii"
00035 #define homepage "http://www.mupad.de/"
00036 
00037 char header[]="log:=ln;Pi:=PI;pi:=PI;e:=E;euler:=EULER;Euler:=EULER;\n\
00038 log10:=proc(x) begin ln(x)/ln(10); end_proc: lg:=log10;\n\
00039 log2:=proc(x) begin ln(x)/ln(2); end_proc: \n\
00040 i:=I;sgn:=sign;ch:=cosh;sh:=sinh;th:=tanh;\n\
00041 arcsin:=asin;arccos:=acos;tg:=tan;arctan:=atan;arctg:=atan;\n\
00042 Argch:=acosh;Argsh:=asinh;Argth:=atanh;argch:=acosh;argsh:=asinh;argth:=atanh;\n\
00043 cotan:=cot;ctg:=cot;rint:=round;factorial:=fact;\n\
00044 PRETTYPRINT:=PRETTY_PRINT;\n";
00045 
00046 struct {
00047     char *wname;    char *defaultval;    char *setname;
00048 } setups[]={
00049        {"w_mup_precision",  "20",  "DIGITS"},
00050        {"w_mup_prettyprint",   "FALSE","PRETTY_PRINT"},
00051        {"w_mup_textwidth",  "1024","TEXTWIDTH"},
00052        {"w_mupad_precision",       "20",  "DIGITS"},
00053        {"w_mupad_prettyprint",   "FALSE","PRETTY_PRINT"},
00054        {"w_mupad_textwidth",       "1024","TEXTWIDTH"}
00055 };
00056 
00057        /* names which are not allowed */
00058 char *illegal[]={
00059       "manual","help",
00060       "fclose","fopen","fprint","fread","ftextinput",
00061       "input","pathname","protocol",
00062       "read","system","write"
00063 };
00064 
00065        /* name parts which are not allowed */
00066 char *illpart[]={
00067     "plot", "PATH"
00068 };
00069 
00070 /***************** Nothing should need change hereafter *****************/
00071 
00072 #define progname "mupad"
00073 #include "common.h"
00074 #include "common.c"
00075 
00076 int patch_tex;
00077 
00078        /* verify illegal strings in parms. */
00079 void check_parm(char *p)
00080 {
00081     char *pp, *p3;
00082     
00083        /* the character ! allows escaping into operating system */
00084     for(pp=strchr(p,'!');pp!=NULL; pp=strchr(pp+1,'!')) {
00085        if(pp<=p) {
00086            bad: fprintf(stderr,"Illegal under WIMS.\n");  exit(1);
00087        }
00088        for(p3=pp-1;p3>=p && isspace(*p3); p3--);
00089        if(p3<p || *p3=='(' || *p3==';' || *p3=='[') goto bad;
00090     }
00091     find_illegal(p);
00092 }
00093 
00094        /* process and print gp output */
00095 void output(char *p)
00096 {
00097     int n;
00098     char *pp, *pe, *p2, *p3;
00099     pp=strstr(p,"\n>>"); if(pp==NULL) return;
00100     pp++;
00101     while(pp-1!=NULL) {
00102        pe=strstr(pp,"\n>>");
00103        if(pe>=pp) *pe=0;
00104        p2=strchr(pp,'\n');
00105        if(p2==NULL) p2=pp+strlen(pp); else p2++;
00106        pp=p2;
00107        n=strlen(pp); if(n==0) {pp=pe+1; continue;}
00108               /* take off warning and error messages,
00109                * and make every output one-line */
00110        p2=pp; do {
00111            p3=strchr(p2,'\n');
00112              /* patch for stupidities in mupad tex output */
00113            if(p3>pp && *(p3-1)=='\\' && (p3==pp+1 || *(p3-2)!='\\')) {
00114               strcpy(p3-1,p3+1); continue;
00115            }
00116            if(p3!=NULL) *p3=0;
00117            if(strstr(p2,"Warning")!=NULL || strstr(p2,"Error")!=NULL) {
00118               fprintf(stderr,"%s\n",p2);
00119               if(p3!=NULL) {
00120                   memmove(p2,p3+1,strlen(p3+1)+1); continue;
00121               }
00122               else {
00123                   *p2=0; break;
00124               }
00125            }
00126            if(p3!=NULL) {
00127               *p3=' '; p2=p3+1;
00128            }
00129        }
00130        while(p3!=NULL);
00131        
00132        /* translating array to pmatrix; should be done in script. */
00133        for(p3=strstr(pp,"\\begin{array}"); p3!=NULL; p3=strstr(p3,"\\begin{array}")) {
00134            memmove  (p3,"\\pmatrix{       ",strlen("\\begin{array}"));
00135            p3+=strlen  ("\\begin{array}");
00136            while(*p3!='}') *p3++=' '; *p3=' ';
00137        }
00138        for(p3=strstr(pp,"\\end{array}"); p3!=NULL; p3=strstr(p3,"\\end{array}")) {
00139            memmove  (p3,"}             ",strlen("\\end{array}"));
00140        }
00141              
00142        if(*pp=='[' && *(pp+strlen(pp)-1)==']') {
00143            *(pp+strlen(pp)-1)=0; pp++;
00144        }
00145        /* patch latex output of \sqrt[n] */
00146        for(p3=strstr(pp,"\\sqrt["); p3!=NULL; p3=strstr(p3+1,"\\sqrt[")) {
00147            char *p4;
00148            memmove(p3,"\\ROOT{",strlen("\\ROOT{"));
00149            p4=strchr(p3,']'); if(p4!=NULL) *p4='}';
00150        }
00151        /* patch of the superscript bug of mupad tex generation. */
00152        if(patch_tex) {
00153            char *p4, *p5, c;
00154            while((p4=strchr(pp,'^'))!=NULL) {
00155               c=*(p4+1);
00156               if(c=='{') {
00157                   *(p4+1)=0; printf("%s%c",pp,c);
00158                   pp=p4+2;continue;
00159               }
00160               if(c=='(') {
00161                   p5=find_matching(p4+2,')');
00162                   if(p5!=NULL) {
00163                      *(p4+1)='{'; *p5=0;
00164                      printf("%s}",pp);pp=p5+1;
00165                   }
00166                   else {
00167                      *(p4+1)=0; printf("%s",pp); pp=p4+2;
00168                   }
00169                   continue;
00170               }
00171               *(p4+1)=0; p4+=2;
00172               printf("%s{%c",pp,c);
00173               while(isdigit(*p4) || *p4=='.') printf("%c",*p4++);
00174               printf("}");pp=p4;
00175            }
00176        }
00177        puts(find_word_start(pp)); pp=pe+1;
00178     }
00179 }
00180 
00181 void about(void)
00182 {
00183     char *p, *pp;
00184 
00185     prepabout(quitstring,outputfname,NULL);
00186     if(readabout()>0) {
00187         for(p=aboutbuf;*p!=0 && memcmp(p,"MuPAD",5)!=0;
00188            p=find_word_start(find_word_end(p)));
00189        if(*p!=0) {
00190            pp=find_word_start(find_word_end(p));
00191            pp=find_word_end(pp); *pp=0;
00192            printf("<A HREF=\"%s\">%s</A>",homepage,p);
00193        }
00194     }
00195 }
00196 
00197 char *dynsetup(char *ptr, char *end)
00198 {
00199     int i;
00200     char *p, *pp;
00201     for(i=0;i<SETUP_NO;i++) {
00202        p=getenv(setups[i].wname);
00203        if(p!=NULL) for(pp=p;*pp;pp++) if(!isspace(*pp) && !isalnum(*pp)) p="";
00204        if(p==NULL || *p==0) p=setups[i].defaultval;
00205        snprintf(ptr,end-ptr,"%s:=%s;\n",setups[i].setname,p);
00206        ptr+=strlen(ptr);
00207        if(strstr(setups[i].wname,"mupad_precision")!=NULL)
00208          precision=atoi(p);
00209        if(precision<0) precision=-precision;
00210     }
00211     return ptr;
00212 }
00213 
00214 int main(int argc,char *argv[])
00215 {
00216     char *p;
00217     
00218     p=getenv("w_mupad_tex_patch");
00219     if(p!=NULL && *p!=0) patch_tex=1; else patch_tex=0;
00220     prepare1();
00221     run();
00222     if(!isabout) setenv("w_mupad_tex_patch","",1);
00223     return 0;    
00224 }
00225