Subversion Repositories wimsdev

Rev

Rev 11132 | Rev 15775 | 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.