Back to index

wims  3.65+svn20090927
Classes | Defines | Enumerations | Functions | Variables
translator.c File Reference
#include "../wims.h"
#include "suffix.c"

Go to the source code of this file.

Classes

struct  entry

Defines

#define entrylim   32768
#define diclim   2*1024*1024
#define sourcelim   16*1024*1024

Enumerations

enum  { unk_delete, unk_leave, unk_replace }

Functions

void * xmalloc (size_t n)
void escape (void)
char * find_word_end (char *p)
char * find_word_start (char *p)
char * strip_trailing_spaces (char *p)
int compare (int i1, const char *s2)
int search_list (struct entry *list, int items, size_t item_size, const char *str)
void string_modify (char *start, char *bad_beg, char *bad_end, char *good,...)
void singlespace (char *p)
void prepare_dic (void)
void translate (void)
void switches (void)
int main ()

Variables

char * inpbuf
char outbuf [2 *(MAX_LINELEN+1)]
char * dicbuf
struct entry entry [entrylim]
int entrycount
int has_digits = 0
int unknown_type = unk_delete
int nocase = 0
int leaveline = 0
int fromfile = 0
char * unknown
char unkbuf [1024]

Class Documentation

struct entry

Definition at line 37 of file dicsort.c.

Class Members
int earlier
int olen
unsigned char * original
char * original
unsigned char * replace
char * replace

Define Documentation

#define diclim   2*1024*1024

Definition at line 25 of file translator.c.

#define entrylim   32768

Definition at line 23 of file translator.c.

#define sourcelim   16*1024*1024

Definition at line 27 of file translator.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
unk_delete 
unk_leave 
unk_replace 

Definition at line 41 of file translator.c.


Function Documentation

int compare ( int  i1,
const char *  s2 
)

Definition at line 89 of file translator.c.

{
    int k;
    if(nocase) k=strncasecmp(entry[i1].original,s2,entry[i1].olen);
    else k=strncmp(entry[i1].original,s2,entry[i1].olen);
    if(k==0 && (isalnum(*(s2+entry[i1].olen)) || (*(s2+entry[i1].olen)&128)!=0)) return -1;
    else return k;
}
void escape ( void  )

Definition at line 59 of file translator.c.

{
    printf("%s",inpbuf); exit(0);
}

Here is the caller graph for this function:

char* find_word_end ( char *  p)

Definition at line 65 of file translator.c.

{
    int i;
    for(i=0;!isspace(*p) && *p!=0 && i<MAX_LINELEN; p++,i++);
    return p;
}
char* find_word_start ( char *  p)

Definition at line 73 of file translator.c.

{
    int i;
    for(i=0; isspace(*p) && i<MAX_LINELEN; p++,i++);
    return p;
}
int main ( void  )

Definition at line 285 of file translator.c.

{
    char c, *p1, *p2, *s;
    unsigned int l;

    switches();
    if(!fromfile) {
       s=getenv("wims_exec_parm");
       if(s==NULL || *s==0) return 0;     /* Nothing to translate */
       l=strlen(s); if(l<=0 || l>sourcelim) return 0; /* too long */
       inpbuf=xmalloc(l+16); memmove(inpbuf,s,l+1);
    }
    else {
       FILE *f;
       s=getenv("translator_input"); if(s==NULL || *s==0) return 0;
       f=fopen(s,"r"); if(f==NULL) return 0; /* no file */
       fseek(f,0,SEEK_END); l=ftell(f); fseek(f,0,SEEK_SET);
       if(l<=0 || l>sourcelim) return 0; /* too long */
       inpbuf=xmalloc(l+16); fread(inpbuf,1,l,f); fclose(f); inpbuf[l]=0;
    }
    p1=inpbuf; prepare_dic();
    if(leaveline) c='\n'; else c=' ';
    do {
       l=strlen(p1);
       if(l>MAX_LINELEN-1024) l=MAX_LINELEN-1024; p2=p1+l;
       if(*p2) {
           while(p2>p1 && *p2!=c) p2--;
       }
       if(p2<=p1) return 0;
       memmove(outbuf,p1,p2-p1); outbuf[p2-p1]=0;
       singlespace(outbuf);
       s=getenv("w_suffix_dictionary");
       if(s!=NULL && *s!=0) suffix(outbuf,s);
       translate();
       if(*p2==c) {printf("%c",c); p1=++p2;}
    }
    while(*p2);
    return 0;
}

Here is the call graph for this function:

void prepare_dic ( void  )

Definition at line 174 of file translator.c.

{
    int i,l;
    FILE *dicf;
    char *fname, *p1, *p2, *pp, buf[1024];
    long int flen;
    fname=getenv("w_dictionary");
    if(fname==NULL || *fname==0 || *fname=='/' || strstr(fname,"..")) {
       p1=getenv("w_module"); if(p1 && strncmp(p1,"classes/",strlen("classes/"))==0) {
           p1=getenv("w_wims_class"); p2=getenv("w_wims_home");
           if(p1 && p2) {
              snprintf(buf,sizeof(buf),"%s/log/classes/%s/",p2,p1);
              if(strncmp(fname,buf,strlen(buf))!=0) escape();
           }
           else escape();
       }
       else {
           p1=getenv("untrust"); if(p1 && strstr(p1,"yes")) escape();
       }
    }
    dicf=fopen(fname,"r"); if(dicf==NULL) escape();
    fseek(dicf,0,SEEK_END);flen=ftell(dicf); fseek(dicf,0,SEEK_SET);
    if(flen>diclim) escape();
    dicbuf=xmalloc(flen+16);flen=fread(dicbuf,1,flen,dicf);
    fclose(dicf);
    if(flen>0 && flen<diclim) dicbuf[flen]=0;
    else escape();
    for(i=0,p1=dicbuf;p1!=NULL && *p1!=0 && i<entrylim;p1=p2) {
       p2=strchr(p1+1,'\n'); if(p2>p1) *p2++=0;
       pp=strchr(p1,':'); if(pp==NULL) continue;
       *pp++=0;
       strip_trailing_spaces(p1); strip_trailing_spaces(pp);
       singlespace(p1);
       p1=find_word_start(p1); pp=find_word_start(pp);
       if(*p1==0) continue;
       if(has_digits==0) {
           char *p;
           for(p=p1;*p!=0 && p<pp && !isdigit(*p);p++);
           if(isdigit(*p)) has_digits=1;
       }
       entry[i].original=p1; entry[i].replace=pp; 
       entry[i].olen=l=strlen(p1); entry[i].earlier=-1;
       if(i>0) {
           int l1,l2;
           l1=entry[i-1].earlier; if(l1>=0) l2=entry[l1].olen;
           else {l2=entry[i-1].olen;l1=i-1;}
           if(l>l2 && isspace(p1[l2])
              && strncmp(entry[l1].original,p1,l2)==0) 
             entry[i].earlier=entry[i-1].earlier=l1;
       }
       i++;
    }
    entrycount=i; if(entrycount<=0) escape();
}

Here is the call graph for this function:

int search_list ( struct entry list,
int  items,
size_t  item_size,
const char *  str 
)

Definition at line 100 of file translator.c.

{
    int i1,i2,j,k,t,t1;
    unsigned char c;

    if(items<=0) return -1;
    j=0; c=str[0];
    k=list[0].original[0]-c; if(k==0) k=compare(0,str);
    if(k==0) goto more; if(k>0) return -1;
    j=items-1; k=list[j].original[0]-c; if(k==0) k=compare(j,str);
    if(k==0) return j;
    if(k>0) for(i1=0,i2=j;i2>i1+1;) {
       j=i1+(i2-i1)/2;
       k=list[j].original[0]-c; if(k==0) k=compare(j,str);
       if(k==0) goto more;
       if(k>0) {i2=j; continue;}
       if(k<0) {i1=j; continue;}   
    }
    if(k>0) {j--;k=compare(j,str);}
    more:
    if((t=list[j].earlier)<0) {
       if(k==0) return j; else return -1;
    }
    if(compare(t,str)!=0) return -1;
    for(j=t1=t,k=0;j<items && list[j].earlier==t1 && (k=compare(j,str))<=0; j++) {
       if(k==0) t=j;
    }
    return t;
}

Here is the call graph for this function:

void singlespace ( char *  p)

Definition at line 145 of file translator.c.

{
    char *pp, *p2;
    for(pp=p;*pp;pp++) {
       if(!isspace(*pp)) continue;
       if(leaveline) {
           if(*pp==13) strcpy(pp,pp+1);
           if(*pp=='\n') {
              pp++;
              gopt: for(p2=pp; isspace(*p2) && *p2!='\n'; p2++);
              if(p2>pp) strcpy(pp,p2); pp--;
           }
           else {
              pp++; if(!isspace(*pp) || *pp=='\n') continue;
              goto gopt;
           }
       }
       else {
           if(*pp!=' ') *pp=' ';
           pp++; if(!isspace(*pp)) continue;
           for(p2=pp;isspace(*p2);p2++);
           strcpy(pp,p2); pp--;
       }
    }
}
void string_modify ( char *  start,
char *  bad_beg,
char *  bad_end,
char *  good,
  ... 
)

Definition at line 131 of file translator.c.

{
    char buf[MAX_LINELEN+1];
    va_list vp;
    
    va_start(vp,good);
    vsnprintf(buf,sizeof(buf),good,vp); va_end(vp);
    if(strlen(start)-(bad_end-bad_beg)+strlen(buf)>=2*MAX_LINELEN)
      return; /* this is an error situation. */
    strcat(buf,bad_end);
    strcpy(bad_beg,buf);
}
char* strip_trailing_spaces ( char *  p)

Definition at line 81 of file translator.c.

{
    char *pp;
    if(*p==0) return p;
    for(pp=p+strlen(p)-1; pp>=p && isspace(*pp); *(pp--)=0);
    return pp;
}
void switches ( void  )

Definition at line 269 of file translator.c.

{
    char *sw;
    unknown=getenv("w_translator_unknown");
    if(unknown==NULL) unknown="";
    snprintf(unkbuf,sizeof(unkbuf),"%s",find_word_start(unknown));
    *find_word_end(unkbuf)=0;
    if(strcasecmp(unkbuf,"leave")==0) unknown_type=unk_leave;
    else if(unkbuf[0]!=0) unknown_type=unk_replace;
    sw=getenv("w_translator_switch");
    if(sw==NULL) return;
    if(strstr(sw,"leaveline")) leaveline=1;
    if(strstr(sw,"nocase")) nocase=1;
    if(strstr(sw,"file")) fromfile=1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void translate ( void  )

Definition at line 230 of file translator.c.

{
    char *p1, *p2, *pp;
    int t;

    for(p1=find_word_start(outbuf);
       p1!=NULL && p1-outbuf<MAX_LINELEN && *p1!=0;
       p1=p2) {
       p2=find_word_end(p1);
       for(pp=p1;pp<p2 && 
           ((!has_digits && isalpha(*pp)) ||
            (has_digits && isalnum(*pp)) || (*pp&128)!=0 ||
            strchr("_",*pp)!=NULL);pp++);
       p2=find_word_start(p2);
       if(pp==p1 || 
          (has_digits==0 && isdigit(*pp)) || 
          (*pp!=0 && !isspace(*pp) && strchr(",.?!/;",*pp)==NULL)) continue;
       t=search_list(entry,entrycount,sizeof(entry[0]),p1);
       if(t<0) {
           switch(unknown_type) {
              case unk_leave: break;
              case unk_delete: {
                  strcpy(p1,find_word_start(pp)); p2=p1;
                  break;
              }
              case unk_replace: {
                  string_modify(outbuf,p1,pp,unkbuf);
                  p2=find_word_start(p1+strlen(unkbuf));
              }
           }
           continue;
       }
       string_modify(outbuf,p1,p1+strlen(entry[t].original),
                    entry[t].replace);
       p2=find_word_start(p1+strlen(entry[t].replace));
    }
    outbuf[MAX_LINELEN]=0; printf("%s",outbuf);
}

Here is the call graph for this function:

void* xmalloc ( size_t  n)

Definition at line 50 of file translator.c.

{
    void *p;
    p=malloc(n);
    if(p==NULL) exit(1);
    return p;
}

Variable Documentation

char* dicbuf

Definition at line 34 of file translator.c.

struct entry entry[entrylim]

Definition at line 39 of file translator.c.

int fromfile = 0

Definition at line 47 of file translator.c.

int has_digits = 0

Definition at line 45 of file translator.c.

char* inpbuf

Definition at line 33 of file translator.c.

int leaveline = 0

Definition at line 47 of file translator.c.

int nocase = 0

Definition at line 47 of file translator.c.

char outbuf[2 *(MAX_LINELEN+1)]

Definition at line 33 of file translator.c.

char unkbuf[1024]

Definition at line 48 of file translator.c.

char* unknown

Definition at line 48 of file translator.c.

Definition at line 46 of file translator.c.