Subversion Repositories wimsdev

Rev

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