Back to index

wims  3.65+svn20090927
math.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 
00018        /* Subroutines to manipulate math expressions */
00019 
00020 
00021        /* Points to the start of a mathematics variable (or number) */
00022 char *find_mathvar_start(char *p)
00023 {
00024     int i;
00025     for(i=0;!isalnum(*p) && *p!='.' && *p!=0 && i<MAX_LINELEN; p++,i++);
00026     return p;
00027 }
00028 
00029        /* Points to the end of a mathematics variable (or number) */
00030 char *find_mathvar_end(char *p)
00031 {
00032     int i; char *pp;
00033     if(!isalnum(*p) && *p!='.') return p;
00034     if(isalpha(*p)) {
00035        for(i=0; *p!=0 && (isalnum(*p) || *p=='.' || *p=='\'')
00036            && i<MAX_LINELEN;p++,i++);
00037        return p;
00038     }
00039     else {
00040        int t=0;
00041        expon:
00042        for(i=0; (isdigit(*p) || *p=='.') && i<MAX_LINELEN;p++,i++);
00043        pp=p; if(t) return pp;
00044        while(isspace(*p)) p++;
00045        if(*p=='e' || *p=='E'){
00046            t=1; p++; while(isspace(*p)) p++;
00047            if(isdigit(*p)) goto expon;
00048            if((*p=='-' || *p=='+') && isdigit(*(p+1))) {
00049               p++; goto expon;
00050            }
00051        }
00052        return pp;
00053     }
00054 }
00055 
00056        /* list variable (function) names in an expression.
00057         * buffer is modified to contain the list. */
00058 void mathvarlist(char *p)
00059 {
00060     char buf[MAX_LINELEN+1], *pb, *pe, *pp;
00061     char *l[10240];
00062     int i,j,len, nofn=0;
00063 
00064     pb=find_word_start(p);pe=find_word_end(pb);
00065     if(pe-pb==strlen("nofn") && memcmp(pb,"nofn",strlen("nofn"))==0) {
00066        nofn=1; pb=find_word_start(pe);
00067     }
00068     snprintf(buf,sizeof(buf),"%s",pb);
00069     len=strlen(buf);
00070     for(i=0,pb=buf;pb<buf+len;pb++) {
00071        if(!isalpha(*pb)) continue;
00072        if(pb>buf && isalnum(*(pb-1))) {
00073            pb=find_mathvar_end(pb); continue;
00074        }
00075        pe=find_mathvar_end(pb); pp=find_word_start(pe);
00076        if(nofn && *pp=='(') {
00077            pb=pe; continue;
00078        }
00079        *pe=0;
00080        if(i<10240) {
00081            for(j=0;j<i;j++) if(strcmp(pb,l[j])==0) goto nextp;
00082            l[i++]=pb;
00083        }
00084        nextp:
00085        pb=pe;
00086     }
00087     for(*p=0,j=0;j<i;j++) {
00088        strcat(p,l[j]);
00089        if(j<i-1) strcat(p,",");
00090     }
00091 }
00092