Subversion Repositories wimsdev

Rev

Rev 7688 | Rev 8135 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17.  
  18. enum {pt_int, pt_rat, pt_real, pt_complex, pt_func, pt_text, pt_matrix};
  19. int prepcnt;
  20. int ex_statement=0, ex_hint=0, ex_help=0, ex_solution=0, ex_latex=0;
  21. char vbuf_statement[MAX_LINELEN+1];
  22. char vbuf_hint[MAX_LINELEN+1];
  23. char vbuf_help[MAX_LINELEN+1];
  24. char vbuf_solution[MAX_LINELEN+1];
  25. char vbuf_latex[MAX_LINELEN+1];
  26. const size_t MAX_KEY_LEN=128;
  27.  
  28. #include "sp.c"
  29.  
  30. /* empty processor, template. */
  31. void empty(char *p[MAX_PARM]) {}
  32.  
  33. void p_author(char *p[MAX_PARM])
  34. {
  35.     p[0]=find_word_start(p[0]);
  36.     if(strlen(p[0])>128) p[0][128]=0;
  37.     fprintf(outf,"author=%s\n",p[0]);
  38. }
  39.  
  40. static void p_keyword(char *p[MAX_PARM], const char *key)
  41. {
  42.     p[0]=find_word_start(p[0]);
  43.     if(strlen(p[0])>MAX_KEY_LEN) p[0][MAX_KEY_LEN]=0;
  44.     fprintf(outf,"%s=%s\n", key, p[0]);
  45. }
  46.  
  47. void p_title_ca(char *p[MAX_PARM]) { p_keyword(p, "title_ca"); }
  48. void p_title_cn(char *p[MAX_PARM]) { p_keyword(p, "title_cn"); }
  49. void p_title_en(char *p[MAX_PARM]) { p_keyword(p, "title_en"); }
  50. void p_title_es(char *p[MAX_PARM]) { p_keyword(p, "title_es"); }
  51. void p_title_fr(char *p[MAX_PARM]) { p_keyword(p, "title_fr"); }
  52. void p_title_it(char *p[MAX_PARM]) { p_keyword(p, "title_it"); }
  53. void p_title_nl(char *p[MAX_PARM]) { p_keyword(p, "title_nl"); }
  54. void p_title_si(char *p[MAX_PARM]) { p_keyword(p, "title_si"); }
  55.  
  56. void p_email(char *p[MAX_PARM])
  57. {
  58.     p[0]=find_word_start(p[0]);
  59.     if(strlen(p[0])>128) p[0][128]=0;
  60.     fprintf(outf,"email=%s\n",p[0]);
  61. }
  62.  
  63. void p_computeanswer(char *p[MAX_PARM])
  64. {
  65.     p[0]=find_word_start(p[0]);
  66.     *find_word_end(p[0])=0;
  67.     if(strcasecmp(p[0],"yes"))
  68.       fprintf(outf,"computeanswer=no\n");
  69.     else fprintf(outf,"computeanswer=%s\n",p[0]);
  70. }
  71.  
  72. void p_precision(char *p[MAX_PARM])
  73. {
  74.     int pr;
  75.     pr=atoi(p[0]);
  76.     if(pr<0 || pr>100000000) return;
  77.     fprintf(outf,"precision=%d\n",pr);
  78. }
  79.  
  80. /* ajout de bpr */
  81. void p_css(char *p[MAX_PARM])
  82. {
  83.     char vbuf_css[MAX_LINELEN+1];
  84.     if(p==NULL) return;
  85.     snprintf(vbuf_css,sizeof(vbuf_css),"%s",p[0]); subst(vbuf_css);
  86.     fprintf(outf,"oefcss=%s\n",vbuf_css);
  87. }
  88.  
  89. void p_credits(char *p[MAX_PARM])
  90. {
  91.     char vbuf_credits[MAX_LINELEN+1];
  92.     if(p==NULL) return;
  93.     snprintf(vbuf_credits,sizeof(vbuf_credits),"%s",p[0]);
  94.     subst(vbuf_credits);
  95.     singlespace(vbuf_credits);
  96.     fprintf(outf,"credits=%s\n\n", vbuf_credits);
  97. }
  98.  
  99. /* */
  100.  
  101. void p_wims(char *p[MAX_PARM])
  102. {
  103.     char vbuf[MAX_LINELEN+1];
  104.     snprintf(vbuf,sizeof(vbuf),"%s",p[0]); subst(vbuf);
  105. /* the second condition could be removed?
  106.  * To be very careful! */
  107.     if(strchr(vbuf,'=')==NULL || strchr(vbuf,'!')!=NULL) return;
  108.     fprintf(outf,"%s\n",vbuf);
  109. }
  110.  
  111. void p_mdef(char *p[MAX_PARM])
  112. {
  113.     char vbuf[MAX_LINELEN+1];
  114.     if(wordchr(mdef,p[0])==NULL) return;
  115.     snprintf(vbuf,sizeof(vbuf),"%s",p[1]); subst(vbuf);
  116. /* the second condition could be removed?
  117.  * To be very careful! */
  118.     if(strchr(vbuf,'!')!=NULL) return;
  119.     fprintf(outf,"m_%s=%s\n",p[0],vbuf);
  120. }
  121.  
  122. void p_range(char *p[MAX_PARM])
  123. {
  124.     double left, right;
  125.     char *pp;
  126.     pp=strstr(p[0],"..");
  127.     if(pp==NULL) return;
  128.     *pp=0;pp+=strlen("..");
  129.     left=atof(p[0]); right=atof(pp);
  130.     if(left>=right-1E-50 || left<-1E50 || right>1E50) return;
  131.     fprintf(outf,"leftrange=%f\nrightrange=%f\n",left,right);
  132. }
  133.  
  134. void p_language(char *p[MAX_PARM])
  135. {
  136.     p[0]=find_word_start(p[0]);
  137.     *find_word_end(p[0])=0;
  138.     if(strlen(p[0])==2) fprintf(outf,"language=%s\n",p[0]);
  139. }
  140.  
  141. void p_statement(char *p[MAX_PARM])
  142. {
  143.     if(ex_statement<0) return;
  144.     if(ex_statement>0 || p==NULL) {
  145.       out_exec(vbuf_statement,"question");
  146.       ex_statement=-1; return;
  147.     }
  148.     if(p==NULL) return;
  149.     snprintf(vbuf_statement,sizeof(vbuf_statement),"%s",p[0]);
  150.     subst(vbuf_statement);
  151.     if(strcmp(format,"html")!=0) {
  152.       fprintf(outf,"question=!nosubst %s\n",vbuf_statement);
  153.       ex_statement=-1;
  154.     }
  155.     else {
  156.       fprintf(outf,"question=%s\n",executed_str);
  157.       ex_statement=1;
  158.     }
  159. }
  160.  
  161. void p_hint(char *p[MAX_PARM])
  162. {
  163.     if(ex_hint<0) return;
  164.     if(ex_hint>0 || p==NULL) {
  165.       out_exec(vbuf_hint,"hint");
  166.       ex_hint=-1; return;
  167.     }
  168.     snprintf(vbuf_hint,sizeof(vbuf_hint),"%s",p[0]); subst(vbuf_hint);
  169.     if(strchr(vbuf_hint,'\\')!=NULL) {
  170.       fprintf(outf,"hint=%s\n",executed_str);
  171.       ex_hint=1;
  172.     }
  173.     else {
  174.       singlespace(vbuf_hint);
  175.       fprintf(outf,"hint=!nosubst %s\n\n", vbuf_hint);
  176.     }
  177. }
  178.  
  179. void p_help(char *p[MAX_PARM])
  180. {
  181.     if(ex_help<0) return;
  182.     if(ex_help>0 || p==NULL) {
  183.       out_exec(vbuf_help,"help");
  184.       ex_help=-1; return;
  185.     }
  186.     snprintf(vbuf_help,sizeof(vbuf_help),"%s",p[0]); subst(vbuf_help);
  187.     if(strchr(vbuf_help,'\\')!=NULL) {
  188.       fprintf(outf,"help=%s\n",executed_str);
  189.       ex_help=1;
  190.     }
  191.     else {
  192.       singlespace(vbuf_help);
  193.       fprintf(outf,"help=!nosubst %s\n\n", vbuf_help);
  194.     }
  195. }
  196.  
  197. void p_solution(char *p[MAX_PARM])
  198. {
  199.     if(ex_solution<0) return;
  200.     if(ex_solution>0 || p==NULL) {
  201.       out_exec(vbuf_solution,"solution");
  202.       ex_solution=-1; return;
  203.     }
  204.     snprintf(vbuf_solution,sizeof(vbuf_solution),"%s",p[0]);
  205.     subst(vbuf_solution);
  206.     if(strchr(vbuf_solution,'\\')!=NULL) {
  207.       fprintf(outf,"solution=%s\n",executed_str);
  208.       ex_solution=1;
  209.     }
  210.     else {
  211.       singlespace(vbuf_solution);
  212.       fprintf(outf,"solution=!nosubst %s\n\n", vbuf_solution);
  213.     }
  214. }
  215.  
  216. void p_latex(char *p[MAX_PARM])
  217. {
  218.     if(ex_latex<0) return;
  219.     if(ex_latex>0 || p==NULL) {
  220.       out_exec(vbuf_latex,"latex");
  221.       ex_latex=-1; return;
  222.     }
  223.     snprintf(vbuf_latex,sizeof(vbuf_latex),"%s",p[0]);
  224.     subst(vbuf_latex);
  225.       singlespace(vbuf_latex);
  226.       fprintf(outf,"latex=!nosubst %s\n\n", vbuf_latex);
  227. }
  228.  
  229. enum {typ_default, typ_num, typ_func, typ_units, typ_text,
  230.       typ_formal,typ_matrix,typ_vector,typ_set,typ_equation,
  231.       typ_case, typ_nocase, typ_atext, typ_wlist, typ_comp,
  232.       typ_algexp, typ_litexp, typ_menu, typ_coord, typ_fill,
  233.       typ_raw, typ_symtext,
  234.       typ_java, typ_src, typ_chem
  235. };
  236.  
  237. struct {
  238.     char *name;
  239.     int  type;
  240.     char *def;
  241. } anstype[]={
  242.       {"algexp", typ_algexp, "algexp"},
  243.       {"aset",  typ_set, "aset"},
  244.       {"atext",  typ_atext, "atext"},
  245.       {"case",  typ_case, "case"},
  246.       {"checkbox", typ_menu, "checkbox"},
  247.       {"chemeq",        typ_chem,       "chemeq"},
  248.       {"chset",  typ_atext, "chset"},
  249.       {"click",  typ_menu, "click"},
  250.       {"clickfill", typ_fill, "clickfill"},
  251.       {"code",  typ_src, "code"},
  252.       {"compose", typ_comp, "compose"},
  253.       {"coord",  typ_coord, "coord"},
  254.       {"coordinates", typ_coord, "coord"},
  255.       {"corresp", typ_comp, "correspond"},
  256.       {"correspond", typ_comp, "correspond"},
  257.       {"default", typ_default, "default"},
  258.       {"dragfill", typ_fill, "dragfill"},
  259.       {"equation", typ_equation, "equation"},
  260.       {"expalg", typ_algexp, "algexp"},
  261.       {"formal", typ_formal, "formal"},
  262.       {"fset",  typ_set, "fset"},
  263.       {"function", typ_func, "function"},
  264.       {"imgcomp", typ_comp, "imgcomp"},
  265.       {"javacurve", typ_java, "javacurve"},
  266.       {"link",  typ_menu, "click"},
  267.       {"litexp", typ_litexp, "litexp"},
  268.       {"mark",  typ_menu, "mark"},
  269.       {"matrix", typ_matrix, "matrix"},
  270.       {"menu",  typ_menu, "menu"},
  271.       {"nocase", typ_nocase, "nocase"},
  272.       {"number", typ_num, "numeric"},
  273.       {"numeric", typ_num, "numeric"},
  274.       {"numexp", typ_algexp, "numexp"},
  275.       {"radio",  typ_menu, "radio"},
  276.       {"range",  typ_func, "range"},
  277.       {"ranges", typ_func, "range"},
  278.       {"raw",  typ_raw, "raw"},
  279.       {"reorder", typ_comp, "reorder"},
  280.       {"select", typ_menu, "menu"},
  281.       {"set",  typ_set, "set"},
  282.       {"sigunits", typ_units, "sigunits"},
  283.       {"symtext", typ_symtext, "symtext"},
  284.       {"text",  typ_text, "case"},
  285.       {"textcomp", typ_comp, "textcomp"},
  286.       {"unit",  typ_units, "units"},
  287.       {"units",  typ_units, "units"},
  288.       {"vector", typ_vector, "vector"},
  289.       {"wlist",  typ_wlist, "wlist"},
  290.       {"wordcomp", typ_comp, "textcomp"}
  291. };
  292.  
  293. #define anstype_no (sizeof(anstype)/sizeof(anstype[0]))
  294.  
  295. void p_answer(char *p[MAX_PARM])
  296. {
  297.     char *pp, vbuf[MAX_LINELEN+1],nbuf[MAX_LINELEN+1];
  298.     int i,j,k,typ;
  299.  
  300. /* look for type definition */
  301.     typ=typ_default;
  302.     for(i=0;i<5;i++) {
  303.       if(p[i]==NULL || p[i][0]==0) continue;
  304.       p[i]=find_word_start(p[i]);
  305.       if(strncasecmp(p[i],"type",strlen("type"))==0) {
  306.           char *tt;
  307.           tt=find_word_start(p[i]+strlen("type"));
  308.           if(*tt=='=') {
  309.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  310.             tt=find_word_start(tt+1); *find_word_end(tt)=0;
  311.             k=search_list(anstype,anstype_no,sizeof(anstype[0]),tt);
  312. /* unknown type is now substituted */
  313.             if(k>=0) {
  314.                 fprintf(outf,"replytype%d=%s\n",
  315.                       answercnt,anstype[k].def);
  316.                 typ=anstype[k].type;
  317.             }
  318.             else {
  319.                 snprintf(nbuf,sizeof(nbuf),"%s",tt); subst(nbuf);
  320.                 fprintf(outf,"replytype%d=%s\n\n",answercnt,nbuf);
  321.             }
  322.           }
  323.           continue;
  324.       }
  325.       if(strncasecmp(p[i],"option",strlen("option"))==0) {
  326.           char *tt, *tv;
  327.           tt=p[i]+strlen("option");
  328.           if(*tt=='s' || *tt=='S') tt++;
  329.           tt=find_word_start(tt);
  330.           if(*tt=='=') {
  331.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  332.             snprintf(nbuf,sizeof(nbuf),"%s",tt+1); subst(nbuf);
  333.             for(tv=nbuf; *tv; tv++) if(*tv==',' || *tv==';') *tv=' ';
  334.             strip_trailing_spaces(nbuf);
  335.             fprintf(outf,"replyoption%d=%s \n",answercnt,
  336.                   find_word_start(nbuf));
  337.           }
  338.           continue;
  339.       }
  340.       if(strncasecmp(p[i],"weight",strlen("weight"))==0) {
  341.           char *tt;
  342.           tt=p[i]+strlen("weight");
  343.           tt=find_word_start(tt);
  344.           if(*tt=='=') {
  345.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  346.             snprintf(nbuf,sizeof(nbuf),"%s",tt+1); subst(nbuf);
  347.             strip_trailing_spaces(nbuf);
  348.             fprintf(outf,"replyweight%d=%s \n",answercnt,
  349.                   find_word_start(nbuf));
  350.           }
  351.           continue;
  352.       }
  353.     }
  354.     p[0]=find_word_start(p[0]);
  355.     strncpy(nbuf,p[0],MAX_LINELEN); nbuf[MAX_LINELEN]=0; subst(nbuf);
  356.     nbuf[MAX_PROMPTLEN]=0;
  357.     strip_trailing_spaces(nbuf); pp=nbuf+strlen(nbuf)-1;
  358.     if(*pp=='=') *pp=0;
  359.     p[1]=find_word_start(p[1]);
  360.     if(*p[1]=='\\' && (isalnum(*(p[1]+1)) || *(p[1]+1)=='_')) {
  361. /* check for analyzed answers */
  362.       int i,n; char *pt;
  363.       strncpy(vbuf,p[1]+1,MAX_LINELEN); vbuf[MAX_LINELEN]=0;
  364.       pt=strchr(vbuf,';'); if(pt!=NULL) *pt=0;
  365.       strip_trailing_spaces(vbuf); n=strlen(vbuf);
  366.       if(n>=MAX_NAMELEN) goto normal;
  367.       for(i=0;i<n && (isalnum(vbuf[i]) || vbuf[i]=='_');i++);
  368.       if(i<n) goto normal;
  369.       for(i=varcnt-1;i>=1 && strcmp(vbuf,param[i].name)!=0;i--);
  370.       if(i<1) { /* unused name; the answer should be analyzed */
  371.           char *pm;
  372.           pm=xmalloc(MAX_NAMELEN+2);
  373.           ovlstrcpy(pm,vbuf); param[varcnt].name=pm;
  374.           if(pt) {
  375.             *pt=';';
  376.             ovlstrcpy(vbuf,pt); subst(vbuf); pt=vbuf;
  377.           }
  378.           else pt="";
  379.           param[varcnt].type=pt_real;
  380.           param[varcnt].save=1;
  381.           fprintf(outf,"replyname%d=%s\nreplygood%d=?analyze %d%s\n",
  382.                 answercnt,nbuf,answercnt,varcnt,pt);
  383.           condans++; answercnt++; varcnt++; return;
  384.       }
  385.     }
  386.     normal:
  387.     strncpy(vbuf,p[1],MAX_LINELEN); vbuf[MAX_LINELEN]=0;
  388.     subst(vbuf);
  389.     switch(typ) {
  390.       default:
  391.       case typ_default: {
  392.           fprintf(outf,"replyname%d=%s\nreplygood%d=%s\n",
  393.                 answercnt,nbuf,answercnt,vbuf);
  394.           break;
  395.       }
  396.       case typ_num: {
  397.           fprintf(outf,"replyname%d=%s\nreplygood%d=$[%s]\n",
  398.                 answercnt,nbuf,answercnt,vbuf);
  399.           break;
  400.       }
  401.       case typ_equation:
  402.       case typ_func: {
  403.           fprintf(outf,"replyname%d=%s\nreplygood%d=!rawmath %s\n",
  404.                 answercnt,nbuf,answercnt,vbuf);
  405.           break;
  406.       }
  407.       case typ_units: {
  408.           fprintf(outf,"replyname%d=%s\nreplygood%d=%s\n",
  409.                 answercnt,nbuf,answercnt,vbuf);
  410.           break;
  411.       }
  412.     }
  413.     answercnt++;
  414. }
  415.  
  416. void p_choice(char *p[MAX_PARM])
  417. {
  418.     int i,j;
  419.     char buf1[MAX_LINELEN+1],buf2[MAX_LINELEN+1],nbuf[MAX_LINELEN+1];
  420.     for(i=0;i<5;i++) {
  421.       if(p[i]==NULL || p[i][0]==0) continue;
  422.       p[i]=find_word_start(p[i]);
  423.       if(strncasecmp(p[i],"option",strlen("option"))==0) {
  424.           char *tt, *tv;
  425.           tt=p[i]+strlen("option");
  426.           if(*tt=='s' || *tt=='S') tt++;
  427.           tt=find_word_start(tt);
  428.           if(*tt=='=') {
  429.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  430.             snprintf(nbuf,sizeof(nbuf),"%s",tt+1); subst(nbuf);
  431.             for(tv=nbuf; *tv; tv++) if(*tv==',' || *tv==';') *tv=' ';
  432.             strip_trailing_spaces(nbuf);
  433.             fprintf(outf,"choiceoption%d=%s \n",choicecnt,
  434.                   find_word_start(nbuf));
  435.           }
  436.           continue;
  437.       }
  438.       if(strncasecmp(p[i],"weight",strlen("weight"))==0) {
  439.           char *tt;
  440.           tt=p[i]+strlen("weight");
  441.           tt=find_word_start(tt);
  442.           if(*tt=='=') {
  443.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  444.             snprintf(nbuf,sizeof(nbuf),"%s",tt+1); subst(nbuf);
  445.             strip_trailing_spaces(nbuf);
  446.             fprintf(outf,"choiceweight%d=%s \n",choicecnt,
  447.                   find_word_start(nbuf));
  448.           }
  449.           continue;
  450.       }
  451.     }
  452.     p[0]=find_word_start(p[0]);
  453.     snprintf(buf1,sizeof(buf1),"%s",p[1]); subst(buf1);
  454.     snprintf(buf2,sizeof(buf2),"%s",p[2]); subst(buf2);
  455.     snprintf(nbuf,sizeof(nbuf),"%s",p[0]); subst(nbuf);
  456.     nbuf[MAX_PROMPTLEN]=0;
  457.     fprintf(outf,"choicename%d=%s\nchoicegood%d=%s\nchoicebad%d=%s\n",
  458.           choicecnt,nbuf,choicecnt,buf1,choicecnt,buf2);
  459.     choicecnt++;
  460. }
  461.  
  462. void putval(char *p, int n, int ptype)
  463. {
  464.     switch(ptype) {
  465.       case pt_int: {
  466.           fprintf(outf,"val%d=$[rint(%s)]\n",n,p);
  467.           break;
  468.       }
  469.       case pt_real: {
  470.           fprintf(outf,"val%d=$[%s]\n",n,p);
  471.           break;
  472.       }
  473.       case pt_func: {
  474.           fprintf(outf,"val%d=!rawmath %s\n",n,p);
  475.           break;
  476.       }
  477.       case pt_complex: {
  478.           fprintf(outf,"t_=!rawmath %s\nt_=!exec pari print($t_)\n\
  479. val%d=!mathsubst I=i in $t_\n",p,n);
  480.           break;
  481.       }
  482.       case pt_matrix: {
  483.           fprintf(outf,"tmp=!trim %s\n\
  484. val%d=!translate internal $     \\\n$ to ;; in $tmp\n",p,n);
  485.           break;
  486.       }
  487.       case pt_rat: {
  488.           fprintf(outf,"t_=!rawmath %s\n\
  489. val%d=!exec pari print($t_)\n",p,n);
  490.           break;
  491.       }
  492.       default: {
  493.           fprintf(outf,"val%d=%s\n",n,p);
  494.           break;
  495.       }
  496.     }
  497. }
  498.  
  499. void parm(char *p[MAX_PARM], int ptype)
  500. {
  501.     char *pp, *p2;
  502.     char vbuf[MAX_LINELEN+1];
  503.     int i;
  504.  
  505.     p[0]=find_word_start(p[0]);
  506.     if(*p[0]=='\\') p[0]++;
  507. /* bad name */
  508.     if(!isalpha(*p[0])) return;
  509.     strip_trailing_spaces(p[0]);
  510.     for(pp=p[0];*pp;pp++) if(!isalnum(*pp) && *pp!='_') {
  511. /* bad name and security risk */
  512.       if(!isspace(*pp)) return;
  513.       ovlstrcpy(pp,pp+1); pp--;
  514.     }
  515.     for(i=1;i<varcnt && strcmp(p[0],param[i].name)!=0;i++);
  516.     p[1]=find_word_start(p[1]);
  517.     snprintf(vbuf,sizeof(vbuf),"%s",p[1]); subst(vbuf);
  518.     if(deftag) repsubst(vbuf);
  519.     if((pp=strparchr(vbuf,'?'))!=NULL && pp[1]!='?') {
  520.       char buf[MAX_LINELEN+1];
  521.       if(check_compare(vbuf)==0) goto noif;
  522.       p2=strparchr(pp,':'); *pp++=0; if(p2!=NULL) *p2++=0;
  523.       snprintf(buf,sizeof(buf),"%s",vbuf);
  524.       prepcnt=0; parmprep(buf,ptype);
  525.       fprintf(outf,"\n!ifval %s\n",buf);
  526.       snprintf(buf,sizeof(buf),"%s",pp);
  527.       parmprep(buf,ptype); putval(buf,i,ptype);
  528.       if(p2!=NULL) {
  529.           fprintf(outf,"!else\n");
  530.           snprintf(buf,sizeof(buf),"%s",p2);
  531.           parmprep(buf,ptype); putval(buf,i,ptype);
  532.       }
  533.       fprintf(outf,"!endif\n");
  534.     }
  535.     else {
  536. noif:
  537.       prepcnt=0; parmprep(vbuf, ptype);
  538.       putval(vbuf,i,ptype);
  539.     }
  540.     if(i>=varcnt && i<MAX_PARAM) {
  541.       param[varcnt].name=p[0];
  542.       param[varcnt].type=ptype;
  543.       param[varcnt].save=0;
  544.       varcnt++;
  545.     }
  546. }
  547.  
  548. void p_int(char *p[MAX_PARM]) {parm(p,pt_int);}
  549. void p_rational(char *p[MAX_PARM]) {parm(p,pt_rat);}
  550. void p_real(char *p[MAX_PARM]) {parm(p,pt_real);}
  551. void p_complex(char *p[MAX_PARM]) {parm(p,pt_complex);}
  552. void p_func(char *p[MAX_PARM]) {parm(p,pt_func);}
  553. void p_text(char *p[MAX_PARM]) {parm(p,pt_text);}
  554. void p_matrix(char *p[MAX_PARM]) {parm(p,pt_matrix);}
  555.  
  556. void p_parm(char *p[MAX_PARM])
  557. {
  558.     parm(p,pt_real);
  559. }
  560.  
  561. void p_if(char *p[MAX_PARM])
  562. {
  563.     char vbuf[MAX_LINELEN+1];
  564.     snprintf(vbuf,sizeof(vbuf),"%s",p[0]); subst(vbuf);
  565.     if(deftag) repsubst(vbuf);
  566.     prepcnt=0; parmprep(vbuf, pt_real);
  567.     fprintf(outf,"!if %s \n",vbuf);
  568. }
  569.  
  570. void p_else(char *p[MAX_PARM])
  571. {
  572.     fprintf(outf,"!else\n");
  573. }
  574.  
  575. void p_endif(char *p[MAX_PARM])
  576. {
  577.     fprintf(outf,"!endif\n");
  578. }
  579.  
  580.  
  581. void p_while(char *p[MAX_PARM])
  582. {
  583.     char vbuf[MAX_LINELEN+1];
  584.     snprintf(vbuf,sizeof(vbuf),"%s",p[0]); subst(vbuf);
  585.     if(deftag) repsubst(vbuf);
  586.     prepcnt=0; parmprep(vbuf, pt_real);
  587.     fprintf(outf,"!while %s \n",vbuf);
  588. }
  589.  
  590. void p_endwhile(char *p[MAX_PARM])
  591. {
  592.     fprintf(outf,"!endwhile\n");
  593. }
  594.  
  595. void p_for(char *p[MAX_PARM])
  596. {
  597.     char *p1, *p2, buf[256];
  598.     char vbuf[MAX_LINELEN+1];
  599.     int i;
  600.  
  601.     p1=find_word_start(p[0]);
  602.     if(!isalpha(*p1)) return;
  603.     for(p2=p1; isalnum(*p2); p2++);
  604.     if(p2-p1>64) return;
  605.     memmove(buf,p1,p2-p1); buf[p2-p1]=0;
  606.     for(i=1;i<varcnt && strcmp(buf,param[i].name)!=0;i++);
  607.     if(i>=varcnt && i<MAX_PARAM) {
  608.       param[varcnt].name=p1;
  609.       param[varcnt].type=pt_real;
  610.       param[varcnt].save=0;
  611.       varcnt++;
  612.     }
  613.     snprintf(vbuf,sizeof(vbuf),"%s",p2); subst(vbuf); *p2=0;
  614.     if(deftag) repsubst(vbuf);
  615.     prepcnt=0; parmprep(vbuf, pt_real);
  616.     fprintf(outf,"!for val%d %s \n", i, vbuf);
  617. }
  618.  
  619. void p_next(char *p[MAX_PARM])
  620. {
  621.     fprintf(outf,"!next\n");
  622. }
  623.  
  624. void p_plot(char *p[MAX_PARM])
  625. {
  626.     int i, f, xr, yr;
  627.     char *pp, *p2;
  628.     char buf[MAX_LINELEN+1];
  629.     f=xr=yr=-1;
  630.     for(i=0;i<3;i++) {
  631.       if(*p[i]==0) continue;
  632.       if((pp=strchr(p[i],'='))==NULL) f=i;
  633.       else {
  634.           *pp=0; pp++;
  635.           p2=find_word_start(p[i]);
  636.           if(*p2=='x' || *p2=='X') xr=i;
  637.           else if (*p2=='y' || *p2=='Y') yr=i;
  638.           ovlstrcpy(p[i],pp);
  639.       }
  640.     }
  641. /*    if(xr>=0 && (pp=strstr(p[xr],".."))!=NULL) {
  642.  
  643.     }
  644. */    if(f<0) return;
  645.     ovlstrcpy(buf, p[f]);
  646.     prepcnt=0; parmprep(buf,pt_func);
  647.     fprintf(outf,"plot_fn=!rawmath %s\n",buf);
  648.  
  649. }
  650.  
  651. void p_condition(char *p[MAX_PARM])
  652. {
  653.     int i,j;
  654.     char buf1[MAX_LINELEN+1],buf2[MAX_LINELEN+1];
  655.     for(i=0;i<5;i++) {
  656.       if(p[i]==NULL || p[i][0]==0) continue;
  657.       p[i]=find_word_start(p[i]);
  658.       if(strncasecmp(p[i],"option",strlen("option"))==0) {
  659.           char *tt, *tv;
  660.           tt=p[i]+strlen("option");
  661.           if(*tt=='s' || *tt=='S') tt++;
  662.           tt=find_word_start(tt);
  663.           if(*tt=='=') {
  664.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  665.             snprintf(buf1,sizeof(buf1),"%s",tt+1); subst(buf1);
  666.             for(tv=buf1; *tv; tv++) if(*tv==',' || *tv==';') *tv=' ';
  667.             strip_trailing_spaces(buf1);
  668.             fprintf(outf,"condoption%d=%s \n",conditioncnt,
  669.                   find_word_start(buf1));
  670.           }
  671.           continue;
  672.       }
  673.       if(strncasecmp(p[i],"weight",strlen("weight"))==0) {
  674.           char *tt;
  675.           tt=p[i]+strlen("weight");
  676.           tt=find_word_start(tt);
  677.           if(*tt=='=') {
  678.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  679.             snprintf(buf1,sizeof(buf1),"%s",tt+1); subst(buf1);
  680.             strip_trailing_spaces(buf1);
  681.             fprintf(outf,"condweight%d=%s \n",conditioncnt,
  682.                   find_word_start(buf1));
  683.           }
  684.           continue;
  685.       }
  686.     }
  687.     if(p[1][0]==0) {p[1]=p[0]; p[0]="";}
  688.     snprintf(buf1,sizeof(buf1),"%s",p[0]); subst(buf1);
  689.     snprintf(buf2,sizeof(buf2),"%s",p[1]); subst(buf2);
  690.     prepcnt=0; parmprep(buf2, pt_real);
  691.     repsubst(buf2);
  692.     fprintf(outf,"\n!ifval %s\n condtest%d=1\n!else\n condtest%d=0\n!endif\n\
  693. condname%d=%s\n", buf2,conditioncnt,conditioncnt,conditioncnt,buf1);
  694.     conditioncnt++;
  695. }
  696.  
  697. void p_conditions(char *p[MAX_PARM])
  698. {
  699.     char buf[MAX_LINELEN+1];
  700.     snprintf(buf,sizeof(buf),"%s",p[0]); subst(buf);
  701.     prepcnt=0; parmprep(buf, pt_real);
  702.     repsubst(buf);
  703.     fprintf(outf,"\ncondlist=%s\n",buf);
  704. }
  705.  
  706. void p_feedback(char *p[MAX_PARM])
  707. {
  708.     char buf1[MAX_LINELEN+1],buf2[MAX_LINELEN+1];
  709.     char *cmpstr="ifval";
  710.  
  711.     snprintf(buf1,sizeof(buf1),"%s",p[0]); subst(buf1);
  712.     snprintf(buf2,sizeof(buf2),"%s",p[1]); subst(buf2);
  713.     repsubst(buf1); repsubst(buf2);
  714.     if(strstr(buf1,"$m_choice")!=NULL) cmpstr="if";
  715.     prepcnt=0; setpre="!set "; parmprep(buf1, pt_real); setpre="";
  716.     fprintf(outf,"!%s %s\n <div class='oef_feedbacks'>",cmpstr, buf1);
  717.     out_exec(buf2,NULL);
  718.     fprintf(outf,"</div>\n!endif\n");
  719. }
  720.  
  721. /* definition of steps */
  722. void p_steps(char *p[MAX_PARM])
  723. {
  724.     char vbuf[MAX_LINELEN+1];
  725.     char *pp, *p2;
  726.  
  727.     snprintf(vbuf,sizeof(vbuf),"%s",find_word_start(p[0])); subst(vbuf);
  728.     strip_trailing_spaces(vbuf);
  729.     if(vbuf[0]==0) return;
  730.     if((pp=strparchr(vbuf,'?'))!=NULL && pp[1]!='?') {
  731.       char buf[MAX_LINELEN+1];
  732.       if(check_compare(vbuf)==0) goto noif;
  733.       p2=strparchr(pp,':'); *pp++=0; if(p2!=NULL) *p2++=0;
  734.       snprintf(buf,sizeof(buf),"%s",vbuf);
  735.       prepcnt=0; parmprep(buf,pt_text);
  736.       fprintf(outf,"\n!ifval %s \n",buf);
  737.       snprintf(buf,sizeof(buf),"%s",pp);
  738.       parmprep(buf,pt_text);
  739.       fprintf(outf,"oefsteps=%s \n",buf);
  740.       if(p2!=NULL) {
  741.           fprintf(outf,"!else\n");
  742.           snprintf(buf,sizeof(buf),"%s",p2);
  743.           parmprep(buf,pt_text);
  744.           fprintf(outf,"oefsteps=%s \n",buf);
  745.       }
  746.       fprintf(outf,"!endif\n");
  747.     }
  748.     else {
  749. noif:
  750.       prepcnt=0; parmprep(vbuf, pt_text);
  751.       fprintf(outf,"oefsteps=%s \nnextstep=!nosubst %s \n",vbuf,vbuf);
  752.     }
  753.     fprintf(outf,"!readproc oef/steps.proc\n");
  754. }
  755.  
  756. /* dynamic steps */
  757. void p_nextstep(char *p[MAX_PARM])
  758. {
  759.     fprintf(outf,"dynsteps=yes\n");
  760.     p_steps(p);
  761. }
  762.  
  763.