Subversion Repositories wimsdev

Rev

Rev 11123 | Rev 12247 | 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. /* line input / output / translation routines
  18.  * and error routines
  19.  */
  20.  
  21. #include "../Lib/libwims.h"
  22. #include "oef2wims.h"
  23.  
  24. /* critical error situation */
  25. void oef_error(char *s)
  26. {
  27.     /* fputs(s,stderr); */
  28.     if(badpar!=NULL) {
  29.      char *p; int i,t,v;
  30.      char buf[128];
  31.      for(p=inpbuf,t=1;p<badpar;p++) if(*p=='\n') t++;
  32.      for(p=badpar-1;p>=inpbuf && *p!='\n'; p--);
  33.      p++; v=badpar-p+1;
  34.      snprintf(buf,sizeof(buf),"%s",p);
  35.      for(i=0,p=buf;i<3 && *p;p++) if(*p=='\n') i++;
  36.      *p=0;
  37.      printf("\nERROR %s '%c' at line %d col %d.\n",
  38.            s,*badpar,t,v);
  39.      for(i=1;i<v;i++) putchar(' ');
  40.      printf("!\n%s\n",buf);
  41.     }
  42.     else printf("\nERROR %s\n",s);
  43.     exit(1);
  44. }
  45.  
  46. char *substit(char *p)
  47. {
  48.     char *pp;
  49.     while((pp=strchr(p,'$'))!=NULL) *pp=' ';
  50.     return p;
  51. }
  52.  
  53. /* replace newline by tab */
  54. void replace_newline(char *p)
  55. {
  56.     for(;*p;p++) {
  57.      if(*p=='   ') *p=' ';
  58.      if(*p=='\n') *p='  ';
  59.     }
  60. }
  61.  
  62. /* variable substitution. buffer p must have MAX_LINELEN */
  63. void subst(char *p)
  64. {
  65.     char *pp, *pe, nbuf[MAX_NAMELEN];
  66.     int i;
  67.  
  68.     for(pp=p;pp-p<MAX_LINELEN && *pp; pp++) {
  69.      if(*pp=='$') {
  70.          string_modify(p,pp,pp+1,"&#36;");
  71.          pp+=3;
  72.          continue;
  73.      }
  74.      if(*pp=='!' && isalnum(*(pp+1))) {
  75.          string_modify(p,pp,pp+1,"&#33;");
  76.          pp+=3; continue;
  77.      }
  78.      if(*pp!='\\') continue;
  79.      if(*(pp+1)=='\\') {
  80.          pp++; continue;
  81.      }
  82.      if(!isalpha(*(pp+1))) continue;
  83.      for(pe=pp+1;isalnum(*pe) || *pe=='_'; pe++);
  84.      if(pe-pp>=MAX_NAMELEN) continue;
  85.      memmove(nbuf,pp+1,pe-pp-1);nbuf[pe-pp-1]=0;
  86.      for(i=varcnt-1;i>=1 && strcmp(nbuf,param[i].name)!=0;i--);
  87.      if(i>=1) {
  88.          if(deftag) param[i].save=1;
  89.          if(*pe=='[') {
  90.           char *pt, tbuf[MAX_LINELEN+1], vbuf[MAX_LINELEN+1];
  91.           int l;
  92.           pt=find_matching(pe+1,']'); if(pt!=NULL && pt-pe<MAX_LINELEN) {
  93.               pe++; memmove(tbuf,pe,pt-pe); tbuf[pt-pe]=0; pe=pt+1;
  94.               subst(tbuf);
  95.               for(pt=strchr(tbuf,'\\');pt;pt=strchr(pt,'\\'))
  96.                 string_modify(tbuf,pt,pt+1,"$m_");
  97.               snprintf(vbuf,sizeof(vbuf),"$(val%d[%s])",i,tbuf);
  98.               l=strlen(vbuf);
  99.               string_modify(p,pp,pe,"%s",vbuf);
  100.               pp+=l-1;continue;
  101.           }
  102.          }
  103.          string_modify(p,pp,pe,"$val%d",i);
  104.      }
  105.      else if(wordchr(mdef,nbuf)!=NULL) string_modify(p,pp,pp+1,"$m_");
  106.     }
  107. }
  108.  
  109. void repsubst(char *p)
  110. {
  111.     char *p1;
  112.     for(p1=strstr(p,"\\reply"); p1!=NULL; p1=strstr(p1+1,"\\reply")) {
  113.      if(p1>p && *(p1-1)=='\\') continue;
  114.      string_modify(p,p1,p1+strlen("\\reply"),"$m_reply");
  115.     }
  116.     for(p1=strstr(p,"\\result"); p1!=NULL; p1=strstr(p1+1,"\\result")) {
  117.      if(p1>p && *(p1-1)=='\\') continue;
  118.      string_modify(p,p1,p1+strlen("\\result"),"$m_result");
  119.     }
  120.     for(p1=strstr(p,"\\choice"); p1!=NULL; p1=strstr(p1+1,"\\choice")) {
  121.      if(p1>p && *(p1-1)=='\\') continue;
  122.      string_modify(p,p1,p1+strlen("\\choice"),"$m_choice");
  123.     }
  124.     for(p1=strstr(p,"\\step"); p1!=NULL; p1=strstr(p1+1,"\\step")) {
  125.      if(p1>p && *(p1-1)=='\\') continue;
  126.      string_modify(p,p1,p1+strlen("\\step"),"$m_step");
  127.     }
  128.     for(p1=strstr(p,"\\sc_reply"); p1!=NULL; p1=strstr(p1+1,"\\sc_reply")) {
  129.      if(p1>p && *(p1-1)=='\\') continue;
  130.      string_modify(p,p1,p1+strlen("\\sc_reply"),"$m_sc_reply");
  131.     }
  132.     for(p1=strstr(p,"\\sc_choice"); p1!=NULL; p1=strstr(p1+1,"\\sc_choice")) {
  133.      if(p1>p && *(p1-1)=='\\') continue;
  134.      string_modify(p,p1,p1+strlen("\\sc_choice"),"$m_sc_choice");
  135.     }
  136.     for(p1=strstr(p,"\\reply_"); p1!=NULL; p1=strstr(p1+1,"\\reply_")) {
  137.      if(p1>p && *(p1-1)=='\\') continue;
  138.      string_modify(p,p1,p1+strlen("\\reply_"),"$m_reply_");
  139.     }
  140. }
  141.  
  142.  
  143. /* find matching parenthesis.
  144.  * The entrance point should be after the opening
  145.  * parenthesis.
  146.  * Returns NULL if unmatched.
  147.  */
  148. char *find_matching2(char *p, char c)
  149. {
  150.     char *pp, *pp2, *ppar,*pbrk, *pbrc;
  151.     int parenth, brak, brace;
  152.     if(c=='|') {
  153.      for(pp=p;*pp!=0;pp++) {
  154.          pp2=pp;
  155.          switch(*pp) {
  156.           case '|': return pp;
  157.           case '(': {
  158.               pp=find_matching(pp+1,')');
  159.               if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;}
  160.               break;
  161.           }
  162.           case '[': {
  163.               pp=find_matching(pp+1,']');
  164.               if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;}
  165.               break;
  166.           }
  167.           case '{': {
  168.               pp=find_matching(pp+1,'}');
  169.               if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;}
  170.               break;
  171.           }
  172.           case ')':
  173.           case ']':
  174.           case '}': badpar=pp; return NULL;
  175.  
  176.           default: break;
  177.          }
  178.      }
  179.      return NULL;
  180.     }
  181.     parenth=brak=brace=0; ppar=pbrc=pbrk=NULL;
  182.     for(pp=p; *pp!=0; pp++) {
  183.      switch(*pp) {
  184.          case '[': if(brak==0) pbrk=pp; brak++; break;
  185.          case ']': brak--; break;
  186.          case '(': if(parenth==0) ppar=pp; parenth++; break;
  187.          case ')': parenth--; break;
  188.          case '{': if(brace==0) pbrc=pp; brace++; break;
  189.          case '}': brace--; break;
  190.          default: continue;
  191.      }
  192.      if(parenth<0 || brak<0 || brace<0) {
  193.          if(badpar==NULL) {
  194.           if(parenth>0) badpar=ppar;
  195.           if(brace>0) badpar=pbrc;
  196.           if(brak>0) badpar=pbrk;
  197.          }
  198.          if(parenth>0 || brak>0 || brace>0) return NULL;
  199.          if(*pp!=c) {
  200.           if(badpar==NULL) badpar=pp;
  201.           return NULL;
  202.          }
  203.          else break;
  204.      }
  205.     }
  206.     if(*pp!=c) return NULL;
  207.     return pp;
  208. }
  209.  
  210. /* Check whether parentheses are balanced in a given string.
  211.  * Returns 0 if OK.
  212.  * style=0: simple check. style<>0: strong check.
  213.  */
  214. int checkparentheses(char *p, int style)
  215. {
  216.     int i,j,k;
  217.     j=strlen(p);
  218.     if(j>=MAX_FILELEN) return 65535;
  219.     if(style!=0) {
  220.      char *pp, *pe, c;
  221.      for(pp=p;pp<p+j;pp++) {
  222.          switch (*pp) {
  223.           case ')':
  224.           case ']':
  225.           case '}': {badpar=pp; return -1;}
  226.           case '(': c=')'; goto find;
  227.           case '[': c=']'; goto find;
  228.           case '{': c='}';
  229.           find: {
  230.               pe=find_matching2(pp+1,c);
  231.               if(pe==NULL) {
  232.                if(badpar==NULL) badpar=pp;
  233.                return 1;
  234.               }
  235.               else pp=pe;
  236.           }
  237.           default: break;
  238.          }
  239.      }
  240.      return 0;
  241.     }
  242.     for(i=k=0;i<j && k>=0;i++) {
  243.      if(*(p+i)=='(') k++;
  244.     if(*(p+i)==')') k--;
  245.     }
  246.     return k;
  247. }
  248.  
  249.