Subversion Repositories wimsdev

Rev

Rev 15775 | 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. /* non existent strings should not compare */
  62. int my_strcmp(char *a, char *b) {return (a && b)? strcmp(a,b):1; }
  63.  
  64. /* variable substitution. buffer p must have MAX_LINELEN */
  65. void subst(char *p)
  66. {
  67.   char *pp, *pe, nbuf[MAX_NAMELEN];
  68.   int i;
  69.  
  70.   for(pp=p;pp-p<MAX_LINELEN && *pp; pp++) {
  71.     if(*pp=='$') {
  72.       string_modify(p,pp,pp+1,"&#36;");
  73.       pp+=3;
  74.       continue;
  75.     }
  76.     if(*pp=='!' && isalnum(*(pp+1))) {
  77.       string_modify(p,pp,pp+1,"&#33;");
  78.       pp+=3; continue;
  79.     }
  80.     if(*pp!='\\') continue;
  81.     if(*(pp+1)=='\\') {
  82.       pp++; continue;
  83.     }
  84.     if(!isalpha(*(pp+1))) continue;
  85.     for(pe=pp+1;isalnum(*pe) || *pe=='_'; pe++);
  86.     if(pe-pp>=MAX_NAMELEN) continue;
  87.     memmove(nbuf,pp+1,pe-pp-1);nbuf[pe-pp-1]=0;
  88.     for(i=varcnt-1;i>=1 && my_strcmp(nbuf,param[i].name)!=0;i--);
  89.     if(i>=1) {
  90.       if(deftag) param[i].save=1;
  91.       if(*pe=='[') {
  92.         char *pt, tbuf[MAX_LINELEN+1], vbuf[MAX_LINELEN+20];
  93.         int l;
  94.         pt=find_matching(pe+1,']'); if(pt!=NULL && pt-pe<MAX_LINELEN) {
  95.           pe++; memmove(tbuf,pe,pt-pe); tbuf[pt-pe]=0; pe=pt+1;
  96.           subst(tbuf);
  97.           for(pt=strchr(tbuf,'\\');pt;pt=strchr(pt,'\\'))
  98.             string_modify(tbuf,pt,pt+1,"$m_");
  99.           snprintf(vbuf,sizeof(vbuf),"$(val%d[%s])",i,tbuf);
  100.           l=strlen(vbuf);
  101.           string_modify(p,pp,pe,"%s",vbuf);
  102.           pp+=l-1;continue;
  103.         }
  104.       }
  105.       string_modify(p,pp,pe,"$val%d",i);
  106.     }
  107.     else if(wordchr(mdef,nbuf)!=NULL) string_modify(p,pp,pp+1,"$m_");
  108.   }
  109. }
  110.  
  111. void repsubst(char *p)
  112. {
  113.   char *p1;
  114.   for(p1=strstr(p,"\\reply"); p1!=NULL; p1=strstr(p1+1,"\\reply")) {
  115.     if(p1>p && *(p1-1)=='\\') continue;
  116.     string_modify(p,p1,p1+strlen("\\reply"),"$m_reply");
  117.   }
  118.   for(p1=strstr(p,"\\result"); p1!=NULL; p1=strstr(p1+1,"\\result")) {
  119.     if(p1>p && *(p1-1)=='\\') continue;
  120.     string_modify(p,p1,p1+strlen("\\result"),"$m_result");
  121.   }
  122.   for(p1=strstr(p,"\\choice"); p1!=NULL; p1=strstr(p1+1,"\\choice")) {
  123.     if(p1>p && *(p1-1)=='\\') continue;
  124.     string_modify(p,p1,p1+strlen("\\choice"),"$m_choice");
  125.   }
  126.   for(p1=strstr(p,"\\step"); p1!=NULL; p1=strstr(p1+1,"\\step")) {
  127.     if(p1>p && *(p1-1)=='\\') continue;
  128.     string_modify(p,p1,p1+strlen("\\step"),"$m_step");
  129.   }
  130.   for(p1=strstr(p,"\\sc_reply"); p1!=NULL; p1=strstr(p1+1,"\\sc_reply")) {
  131.     if(p1>p && *(p1-1)=='\\') continue;
  132.     string_modify(p,p1,p1+strlen("\\sc_reply"),"$m_sc_reply");
  133.   }
  134.   for(p1=strstr(p,"\\sc_choice"); p1!=NULL; p1=strstr(p1+1,"\\sc_choice")) {
  135.     if(p1>p && *(p1-1)=='\\') continue;
  136.     string_modify(p,p1,p1+strlen("\\sc_choice"),"$m_sc_choice");
  137.   }
  138.   for(p1=strstr(p,"\\reply_"); p1!=NULL; p1=strstr(p1+1,"\\reply_")) {
  139.     if(p1>p && *(p1-1)=='\\') continue;
  140.     string_modify(p,p1,p1+strlen("\\reply_"),"$m_reply_");
  141.   }
  142. }
  143.  
  144.  
  145. /* find matching parenthesis.
  146.  * The entrance point should be after the opening
  147.  * parenthesis.
  148.  * Returns NULL if unmatched.
  149.  */
  150. char *find_matching2(char *p, char c)
  151. {
  152.   char *pp, *pp2, *ppar,*pbrk, *pbrc;
  153.   int parenth, brak, brace;
  154.   if(c=='|') {
  155.     for(pp=p;*pp!=0;pp++) {
  156.       pp2=pp;
  157.       switch(*pp) {
  158.         case '|': return pp;
  159.         case '(': {
  160.           pp=find_matching(pp+1,')');
  161.           if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;}
  162.           break;
  163.         }
  164.         case '[': {
  165.           pp=find_matching(pp+1,']');
  166.           if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;}
  167.           break;
  168.         }
  169.         case '{': {
  170.           pp=find_matching(pp+1,'}');
  171.           if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;}
  172.           break;
  173.         }
  174.         case ')':
  175.         case ']':
  176.         case '}': badpar=pp; return NULL;
  177.  
  178.         default: break;
  179.       }
  180.     }
  181.     return NULL;
  182.   }
  183.   parenth=brak=brace=0; ppar=pbrc=pbrk=NULL;
  184.   for(pp=p; *pp!=0; pp++) {
  185.     switch(*pp) {
  186.       case '[': if(brak==0) pbrk=pp; brak++; break;
  187.       case ']': brak--; break;
  188.       case '(': if(parenth==0) ppar=pp; parenth++; break;
  189.       case ')': parenth--; break;
  190.       case '{': if(brace==0) pbrc=pp; brace++; break;
  191.       case '}': brace--; break;
  192.       default: continue;
  193.     }
  194.     if(parenth<0 || brak<0 || brace<0) {
  195.       if(badpar==NULL) {
  196.         if(parenth>0) badpar=ppar;
  197.         if(brace>0) badpar=pbrc;
  198.         if(brak>0) badpar=pbrk;
  199.       }
  200.       if(parenth>0 || brak>0 || brace>0) return NULL;
  201.       if(*pp!=c) {
  202.         if(badpar==NULL) badpar=pp;
  203.         return NULL;
  204.       }
  205.       else break;
  206.     }
  207.   }
  208.   if(*pp!=c) return NULL;
  209.   return pp;
  210. }
  211.  
  212. /* Check whether parentheses are balanced in a given string.
  213.  * Returns 0 if OK.
  214.  * style=0: simple check. style<>0: strong check.
  215.  */
  216. int checkparentheses(char *p, int style)
  217. {
  218.   int i,j,k;
  219.   j=strlen(p);
  220.   if(j>=MAX_FILELEN) return 65535;
  221.   if(style!=0) {
  222.     char *pp, *pe, c;
  223.     for(pp=p;pp<p+j;pp++) {
  224.       switch (*pp) {
  225.         case ')':
  226.         case ']':
  227.         case '}': {badpar=pp; return -1;}
  228.         case '(': c=')'; goto find;
  229.         case '[': c=']'; goto find;
  230.         case '{': c='}';
  231.         find: {
  232.           pe=find_matching2(pp+1,c);
  233.           if(pe==NULL) {
  234.             if(badpar==NULL) badpar=pp;
  235.             return 1;
  236.           }
  237.           else pp=pe;
  238.         }
  239.         default: break;
  240.       }
  241.     }
  242.     return 0;
  243.   }
  244.   for(i=k=0;i<j && k>=0;i++) {
  245.     if(*(p+i)=='(') k++;
  246.     if(*(p+i)==')') k--;
  247.   }
  248.   return k;
  249. }
  250.