Back to index

wims  3.65+svn20090927
lines.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017        /* line input / output / translation routines
00018         * and error routines */
00019 #include <stdarg.h>
00020 
00021        /* critical error situation */
00022 void error(char *s)
00023 {
00024     /* fputs(s,stderr); */
00025     if(badpar!=NULL) {
00026        char *p; int i,t,v;
00027        char buf[128];
00028        for(p=inpbuf,t=1;p<badpar;p++) if(*p=='\n') t++;
00029        for(p=badpar-1;p>=inpbuf && *p!='\n'; p--);
00030        p++; v=badpar-p+1;
00031        snprintf(buf,sizeof(buf),"%s",p);
00032        for(i=0,p=buf;i<3 && *p;p++) if(*p=='\n') i++;
00033        *p=0;
00034        printf("\nERROR %s '%c' at line %d col %d.\n",
00035                s,*badpar,t,v);
00036        for(i=1;i<v;i++) putchar(' ');
00037        printf("!\n%s\n",buf);
00038        
00039     }
00040     else printf("\nERROR %s\n",s);
00041     exit(1);
00042 }
00043 
00044 char *substit(char *p)
00045 {
00046     char *pp;
00047     while((pp=strchr(p,'$'))!=NULL) *pp=' ';
00048     return p;
00049 }
00050 
00051        /* replace newline by tab */
00052 void replace_newline(char *p)
00053 {
00054     for(;*p;p++) {
00055        if(*p=='      ') *p=' ';
00056        if(*p=='\n') *p='    ';
00057     }
00058 }
00059 
00060        /* variable substitution. buffer p must have MAX_LINELEN */
00061 void subst(char *p)
00062 {
00063     char *pp, *pe, nbuf[MAX_NAMELEN];
00064     int i;
00065 
00066     for(pp=p;pp-p<MAX_LINELEN && *pp; pp++) {
00067        if(*pp=='$') {
00068            string_modify(p,pp,pp+1,"&#36;");
00069            pp+=3;
00070            continue;
00071        }
00072        if(*pp=='!' && isalnum(*(pp+1))) {
00073            string_modify(p,pp,pp+1,"&#33;");
00074            pp+=3; continue;
00075        }
00076        if(*pp!='\\') continue;
00077        if(*(pp+1)=='\\') {
00078            pp++; continue;
00079        }
00080        if(!isalpha(*(pp+1))) continue;
00081        for(pe=pp+1;isalnum(*pe) || *pe=='_'; pe++);
00082        if(pe-pp>=MAX_NAMELEN) continue;
00083        memmove(nbuf,pp+1,pe-pp-1);nbuf[pe-pp-1]=0;
00084        for(i=varcnt-1;i>=1 && strcmp(nbuf,param[i].name)!=0;i--);
00085        if(i>=1) {
00086            if(deftag) param[i].save=1;
00087            if(*pe=='[') {
00088               char *pt, tbuf[MAX_LINELEN+1], vbuf[MAX_LINELEN+1];
00089               int l;
00090               pt=find_matching(pe+1,']'); if(pt!=NULL && pt-pe<MAX_LINELEN) {
00091                   pe++; memmove(tbuf,pe,pt-pe); tbuf[pt-pe]=0; pe=pt+1;
00092                   subst(tbuf);
00093                   for(pt=strchr(tbuf,'\\');pt;pt=strchr(pt,'\\'))
00094                     string_modify(tbuf,pt,pt+1,"$m_");
00095                   snprintf(vbuf,sizeof(vbuf),"$(val%d[%s])",i,tbuf);
00096                   l=strlen(vbuf);
00097                   string_modify(p,pp,pe,"%s",vbuf);
00098                   pp+=l-1;continue;
00099               }
00100            }
00101            string_modify(p,pp,pe,"$val%d",i);
00102        }
00103        else if(wordchr(mdef,nbuf)!=NULL) string_modify(p,pp,pp+1,"$m_");
00104     }
00105 }
00106 
00107 void repsubst(char *p)
00108 {
00109     char *p1;
00110     for(p1=strstr(p,"\\reply"); p1!=NULL; p1=strstr(p1+1,"\\reply")) {
00111        if(p1>p && *(p1-1)=='\\') continue;
00112        string_modify(p,p1,p1+strlen("\\reply"),"$m_reply");
00113     }
00114     for(p1=strstr(p,"\\result"); p1!=NULL; p1=strstr(p1+1,"\\result")) {
00115        if(p1>p && *(p1-1)=='\\') continue;
00116        string_modify(p,p1,p1+strlen("\\result"),"$m_result");
00117     }
00118     for(p1=strstr(p,"\\choice"); p1!=NULL; p1=strstr(p1+1,"\\choice")) {
00119        if(p1>p && *(p1-1)=='\\') continue;
00120        string_modify(p,p1,p1+strlen("\\choice"),"$m_choice");
00121     }
00122     for(p1=strstr(p,"\\step"); p1!=NULL; p1=strstr(p1+1,"\\step")) {
00123        if(p1>p && *(p1-1)=='\\') continue;
00124        string_modify(p,p1,p1+strlen("\\step"),"$m_step");
00125     }
00126     for(p1=strstr(p,"\\sc_reply"); p1!=NULL; p1=strstr(p1+1,"\\sc_reply")) {
00127        if(p1>p && *(p1-1)=='\\') continue;
00128        string_modify(p,p1,p1+strlen("\\sc_reply"),"$m_sc_reply");
00129     }
00130     for(p1=strstr(p,"\\sc_choice"); p1!=NULL; p1=strstr(p1+1,"\\sc_choice")) {
00131        if(p1>p && *(p1-1)=='\\') continue;
00132        string_modify(p,p1,p1+strlen("\\sc_choice"),"$m_sc_choice");
00133     }
00134 }
00135 
00136        /* find matching parenthesis.
00137         * The entrance point should be after the opening 
00138         * parenthesis.
00139         * Returns NULL if unmatched. */
00140 char *find_matching2(char *p, char c)
00141 {
00142     char *pp, *pp2, *ppar,*pbrk, *pbrc;
00143     int parenth, brak, brace;
00144     if(c=='|') {
00145        for(pp=p;*pp!=0;pp++) {
00146            pp2=pp;
00147            switch(*pp) {
00148               case '|': return pp;
00149               case '(': {
00150                   pp=find_matching(pp+1,')');
00151                   if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;}
00152                   break;
00153               }
00154               case '[': {
00155                   pp=find_matching(pp+1,']');
00156                   if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;}
00157                   break;
00158               }
00159               case '{': {
00160                   pp=find_matching(pp+1,'}');
00161                   if(pp==NULL) {if(badpar==NULL) badpar=pp2; return NULL;}
00162                   break;
00163               }
00164               case ')':
00165               case ']':
00166               case '}': badpar=pp; return NULL;
00167               
00168               default: break;
00169            }
00170        }
00171        return NULL;
00172     }
00173     parenth=brak=brace=0; ppar=pbrc=pbrk=NULL;
00174     for(pp=p; *pp!=0; pp++) {
00175        switch(*pp) {
00176            case '[': if(brak==0) pbrk=pp; brak++; break;
00177            case ']': brak--; break;
00178            case '(': if(parenth==0) ppar=pp; parenth++; break;
00179            case ')': parenth--; break;
00180            case '{': if(brace==0) pbrc=pp; brace++; break;
00181            case '}': brace--; break;
00182            default: continue;
00183        }
00184        if(parenth<0 || brak<0 || brace<0) {
00185            if(badpar==NULL) {
00186               if(parenth>0) badpar=ppar;
00187               if(brace>0) badpar=pbrc;
00188               if(brak>0) badpar=pbrk;
00189            }
00190            if(parenth>0 || brak>0 || brace>0) return NULL;
00191            if(*pp!=c) {
00192               if(badpar==NULL) badpar=pp; return NULL;
00193            }
00194            else break;
00195        }
00196     }
00197     if(*pp!=c) return NULL;
00198     return pp;
00199 }
00200 
00201        /* Check whether parentheses are balanced in a given string.
00202         * Returns 0 if OK. */
00203        /* style=0: simple check. style<>0: strong check. */
00204 int checkparentheses(char *p, int style)
00205 {
00206     int i,j,k;
00207     j=strlen(p);
00208     if(j>=MAX_FILELEN) return 65535;
00209     if(style!=0) {
00210        char *pp, *pe, c;
00211        for(pp=p;pp<p+j;pp++) {
00212            switch (*pp) {
00213               case ')':
00214               case ']':
00215               case '}': {badpar=pp; return -1;}
00216               case '(': c=')'; goto find;
00217               case '[': c=']'; goto find;
00218               case '{': c='}';
00219               find: {
00220                   pe=find_matching2(pp+1,c);
00221                   if(pe==NULL) {
00222                      if(badpar==NULL) badpar=pp;
00223                      return 1;
00224                   }
00225                   else pp=pe;
00226               }
00227               default: break;
00228            }
00229        }
00230        return 0;
00231     }
00232     for(i=k=0;i<j && k>=0;i++) {
00233        if(*(p+i)=='(') k++;
00234        if(*(p+i)==')') k--;
00235     }
00236     return k;
00237 }
00238