8 changed files with 11 additions and 1654 deletions
-
10ChangeLog
-
2src/frontend/numparam/Makefile.am
-
89src/frontend/numparam/downgrad.txt
-
29src/frontend/numparam/general.h
-
420src/frontend/numparam/mystring.c
-
1src/frontend/numparam/numparam.h
-
996src/frontend/numparam/washprog.c
-
118src/frontend/numparam/xpressn.c
@ -1,89 +0,0 @@ |
|||
! downgrad.txt, Use with 'washprog.c' |
|||
! opcodes: x=exclusion, m=macro, w=wordsubst s= general subst |
|||
! Macros to keep: Cconst Hi Lo Str Strbig Use ...? |
|||
|
|||
w Proc void |
|||
w Begin { |
|||
w EndProc ;} |
|||
w Func "" |
|||
w EndFunc ;} |
|||
w If "if (" |
|||
w Then ") {" |
|||
w Else ";} else {" |
|||
w ElsIf ";} else if (" |
|||
w EndIf ;} |
|||
w While "while (" |
|||
w Do ") {" |
|||
w Done ;} |
|||
w Repeat "do {" |
|||
w Until ";} while ( !(" |
|||
w EndRep )); |
|||
w For "for (" |
|||
w Switch "switch (" |
|||
w CaseOne ") { case" |
|||
w Case "; break; } case" |
|||
w AndCase ":; case" |
|||
w Is :{ |
|||
w Default "; break;} default: {" |
|||
w EndSw ";break;} }" |
|||
|
|||
m Const(1,2) "const short 1 = 2;" |
|||
|
|||
m Record(1) "typedef struct _t1 {" |
|||
m RecPtr(1) "typedef struct _t1 *" |
|||
m EndRec(1) "} 1;" |
|||
m Addr(1) &1 |
|||
|
|||
w False 0 |
|||
w True 1 |
|||
w Not ! |
|||
w And && |
|||
w Or || |
|||
w Div / |
|||
w Mod % |
|||
|
|||
w Shl << |
|||
w Shr >> |
|||
w AND & |
|||
w OR | |
|||
w XOR \^ |
|||
w NOT ~ |
|||
w AT * |
|||
|
|||
m Inc(1) 1++ |
|||
m Dec(1) 1-- |
|||
w Null NULL |
|||
w Void void |
|||
m Table(1) "[1]= {" |
|||
w EndTab }; |
|||
|
|||
m chr(1) (char)(1) |
|||
m Zero(1) (!(1)) |
|||
m NotZ(1) (1) |
|||
|
|||
w Pointer "void *" |
|||
w Pfile "FILE *" |
|||
|
|||
w Char "unsigned char" |
|||
w Byte "unsigned char" |
|||
w Bool "unsigned char" |
|||
w Word "unsigned short" |
|||
w Pchar "char *" |
|||
|
|||
w Intern static |
|||
w Extern extern |
|||
m Tarray(1,2,3) "typedef 2 1[3];" |
|||
m Tarray\2(1,2,3,4) "typedef 2 1[3][4];" |
|||
m Darray(1,2,3) "2 1[3];" |
|||
|
|||
m Cconst(1,2) "typedef enum {1 = 2} _n1;" |
|||
!m Str(1,2) "char 2[1+03]={00,00,(char)1}" |
|||
!m Strbig(1,2) "char 2[1+04]={00, (char)Hi(1), (char)Lo(1)}" |
|||
|
|||
w Aconst(1,2,3) "2 1[3] ={" |
|||
w EndAco "};" |
|||
m Sini(1) "sini(1,sizeof(1)-04)" |
|||
m New(1) "(1 *)new(sizeof(1))" |
|||
m Dispose(1) "dispose((void *)1)" |
|||
m NewArr(1,2) "(1 *)new(sizeof(1)*2)" |
|||
|
|||
@ -1,996 +0,0 @@ |
|||
/* washprog.c Copyright (C) 2002 Georg Post |
|||
* |
|||
* This file is part of Numparam, see: readme.txt |
|||
* Free software under the terms of the GNU Lesser General Public License |
|||
*/ |
|||
|
|||
/**** washprog: trivial text substitution utility. ****/ |
|||
|
|||
/* history: this was an exercise to make an 'intersection' language |
|||
of C and Java, that would look like Basic. A complete failure, of course. |
|||
|
|||
Now only used to clean my Basic/Pascal-contaminated C code. |
|||
With the rules file below, it destroys all those macros of mine for |
|||
quiche eaters, which seem offensive to C aficionados. |
|||
|
|||
Standard rules file needed : downgrad.txt |
|||
|
|||
Typical command line: ./washprog -r downgrad washprog.c |
|||
|
|||
There is no printf. Console Output/Input primitives are as follows: |
|||
wc ws wr wn wi wln rln |
|||
The bare-bones string(=Pchar) manipulation library is this: |
|||
pscopy streq str length upcase scopy sadd saddn cadd pos |
|||
|
|||
Format of substitution rules: |
|||
|
|||
s <string> <string> substitute. use "" around string if spaces inside. |
|||
w <string> <string> first string must be a whole word only |
|||
m <macro1> <macro2> macro substitution with args 1 2 3 ... |
|||
u <macro1> <macro2> macro with atomic args, no punctuation "(;,:)" inside. |
|||
x <strng1> <strng2> exclude text section from strng1 to strng2. |
|||
a <mac1> <mac2> dynamically add a new macro rule, if table space left. |
|||
|
|||
string: may contain special chars: ^A ... ^Z \n \" |
|||
macro1: string with "placeholders" 1 2 ... 9, in this order |
|||
macro2: may contain the "arguments" anywhere |
|||
non-arg digits in macro2 are prefixed 0 |
|||
|
|||
Heavy use of 3 string operations: |
|||
- pscopy() substring extraction. |
|||
- comparison: match(). |
|||
- spos() substring search |
|||
|
|||
added : special postprocessing for C to place the ; and } : |
|||
1. any ';' following a ';' or '}' is wiped out. |
|||
2. any ';' preceding a '}' is wiped out. |
|||
3. any remaining ';' on start of line is shifted to end of preceding one. |
|||
*/ |
|||
|
|||
#include <stdio.h> /* NULL FILE fopen feof fgets fclose fputs fputc gets */ |
|||
#include "general.h" |
|||
Cconst(Llen, 15000) |
|||
Cconst(nsub, 100+1) /*max nbr of substitution rules */ |
|||
Cconst(nargs, 11) /*max number of macro args + 1*/ |
|||
Cconst(wild,'æ') /* wildcard character in patterns */ |
|||
Cconst(joker,1) /* one-character placeholder */ |
|||
Cconst( Recursion, True) /* 20 % slower, re-substitute inside macro args */ |
|||
|
|||
Tarray(macargs, string, nargs) /* 0..9 macro copy args, 10: a wildcard */ |
|||
|
|||
/* global vars */ |
|||
int isr; /* nb of substitution rules */ |
|||
Bool cMode; /* a scanning options: c language mode */ |
|||
int lookmax; /* input lookahead max size */ |
|||
Pfile fout; /* file filled by: echoOut macroOut translate traduire */ |
|||
|
|||
Tarray(str40, char, 44) |
|||
Tarray(str80, char, 84) |
|||
Darray(search, str40, nsub) |
|||
Darray(replace, str80, nsub) |
|||
Str(nsub, srule); |
|||
Str(nsub, wildcard); |
|||
|
|||
/********* trivial io ***/ |
|||
|
|||
Proc wsf( Pchar s, int fmt) |
|||
Begin |
|||
int k; |
|||
For k=1; k<=fmt-length(s); Inc(k) Do |
|||
wc(' ') |
|||
Done |
|||
ws(s) |
|||
EndProc |
|||
|
|||
Proc wcf(char c, int fmt) |
|||
Begin |
|||
int k; |
|||
For k=1; k<=fmt-1; Inc(k) Do |
|||
wc(' ') |
|||
Done |
|||
wc(c) |
|||
EndProc |
|||
|
|||
Proc wif(long i, int fmt) |
|||
Begin /*default fmt=1*/ |
|||
Str(30, s); |
|||
nadd(s,i); |
|||
wsf(s,fmt) |
|||
EndProc |
|||
|
|||
Proc rln(Pchar s) /* 78 column limit */ |
|||
Begin |
|||
int i; Bool done; char c; |
|||
int max=maxlen(s); |
|||
If max>78 Then max=78 EndIf |
|||
i=0; done=False; |
|||
scopy(s,""); |
|||
While Not done Do |
|||
c=fgetc(stdin); |
|||
If (c>=' ') And (c<='~') And (i<max) Then |
|||
cadd(s,c); Inc(i) |
|||
EndIf |
|||
done= (c=='\n') Or (c==Cr) |
|||
Done |
|||
EndProc |
|||
|
|||
/*****************/ |
|||
|
|||
Proc saddn( Pchar s, Pchar t, int n) |
|||
Begin |
|||
Strbig(Llen,u); |
|||
int lt= length(t); |
|||
If lt<= n Then |
|||
sadd(s,t) |
|||
Else |
|||
pscopy(u,t,1,n); |
|||
sadd(s,u) |
|||
EndIf |
|||
EndProc |
|||
|
|||
Proc allocdata(void) |
|||
Begin /* prevent any string overflow */ |
|||
int i; |
|||
For i=0; i<nsub; Inc(i) Do |
|||
Sini(search[i]); |
|||
Sini(replace[i]) |
|||
Done |
|||
EndProc |
|||
|
|||
Proc setOptions(Pchar s) |
|||
/* command-line options c-mode and/or lookahead buffer size */ |
|||
Begin |
|||
int j,k; |
|||
Bool num; |
|||
int z; |
|||
char c; |
|||
/*-StartProc-*/ |
|||
ws("Options: "); |
|||
For j=1; j<length(s); Inc(j) Do /*scan for option setting chars */ |
|||
If s[j]=='C' Then |
|||
cMode=True; ws("cMode ") |
|||
EndIf |
|||
If s[j]=='L' Then /*redefine max lookahead length */ |
|||
z=0; |
|||
k= (int)(j+1); |
|||
Repeat |
|||
Inc(k); c=s[k]; |
|||
num= (c>='0') And (c<='9'); |
|||
If num Then z= (int)( 10*z+ c - '0') EndIf |
|||
Until Not num EndRep |
|||
If (z>lookmax) And (z<255) Then |
|||
lookmax= z |
|||
EndIf |
|||
ws("Lookahead="); wi(lookmax); |
|||
EndIf |
|||
Done |
|||
wln(); |
|||
EndProc |
|||
|
|||
/******** matching routines *******/ |
|||
|
|||
Proc copySpace(Pchar s, Pchar t, int a, int b) /* a,b>0 ! Pascal indexing */ |
|||
Begin |
|||
/*echo any "nontrivial" whitespace t-->s */ |
|||
int lt,i,k, comment; |
|||
Bool leader; |
|||
char c; |
|||
/*-StartProc-*/ |
|||
scopy(s,""); |
|||
leader=False; /*leader space on new line...*/ |
|||
k=0; |
|||
comment=0; /* for C type whitespaces 1 And 2*/ |
|||
lt= length(t); |
|||
If b>lt Then b=lt EndIf |
|||
For i=(int)(a-1); i<b; Inc(i) Do |
|||
c=t[i]; |
|||
If (c>0) And (c<' ') Then leader=True EndIf |
|||
If cMode And (c=='/') And (t[i+1]=='*') Then comment=1 EndIf |
|||
If ((c>0) And (c<' ')) Or (leader And (c==' ')) Or (comment>0) Then |
|||
cadd(s,c); Inc(k); |
|||
EndIf |
|||
If (comment==1) And (c=='/') And (t[i-1]=='*') Then comment=0 EndIf |
|||
Done |
|||
EndProc |
|||
|
|||
Func int skipCwhite(Pchar t, int j, int lt) /* assume C indexing */ |
|||
Begin |
|||
/* skip any C And C++ type whitespace in t, from j to lt */ |
|||
/* returns j-1 If current char is no white at all! */ |
|||
char c; |
|||
int comment; /*types 1 And 2! */ |
|||
/*t[j] may already be '/' ? */ comment=0; |
|||
c=t[j]; /*If c>' ', we are done! */ |
|||
If (c>0) And (c<=' ') Then |
|||
Repeat |
|||
If (comment==0) And (c=='/') Then |
|||
If t[j+1]=='*' Then |
|||
comment=1 |
|||
ElsIf t[j+1]=='/' Then |
|||
comment=2 |
|||
EndIf |
|||
ElsIf (comment==1) And (c=='/') And (t[j-1]=='*') Then |
|||
comment=0 |
|||
ElsIf (comment==2) And (c==Lf) Then |
|||
comment=0 |
|||
EndIf |
|||
Inc(j); c=t[j]; |
|||
Until (j>lt) Or ((comment==0) And (c>' ')) EndRep |
|||
EndIf |
|||
return (int)(j-1); /* return last white-matching char position */ |
|||
EndProc |
|||
|
|||
Func Bool simple(Pchar s) |
|||
Begin /* check if no strange punctuations inside s */ |
|||
char c; |
|||
int i,ls; |
|||
Bool found; |
|||
/*-StartProc-*/ |
|||
ls=length(s); |
|||
i=0; |
|||
Repeat c=s[i]; |
|||
found=(c=='(') Or (c==')') Or (c==',') Or (c==';') Or (c==':'); |
|||
Inc(i); |
|||
Until found Or (i>=ls) EndRep |
|||
return Not found; |
|||
EndFunc |
|||
|
|||
Func Bool match(Pchar s, Pchar t, int n, int tstart) |
|||
Begin |
|||
/* test if t starts with substring s. |
|||
returns 0 If tstart is out of range. But n may be 0 ? |
|||
options: Singlechar wildcards "?" |
|||
*/ |
|||
int i,j,lt; |
|||
Bool ok; |
|||
/*-StartProc-*/ |
|||
i=0; j=tstart; |
|||
lt= length(t); |
|||
ok=(tstart<lt); |
|||
While ok And (i<n) Do |
|||
ok= (j<lt) And ((s[i]==t[j]) Or (s[i]==joker)); |
|||
Inc(i); Inc(j); |
|||
Done |
|||
return ok |
|||
EndFunc |
|||
|
|||
/* Func int posi(Pchar sub, Pchar s) |
|||
Begin re-defines Turbo Pos, result Pascal compatible |
|||
int a,b,k; |
|||
Bool ok; |
|||
-StartProc- |
|||
ok=False; |
|||
a=length(sub); |
|||
b=(int)(length(s)-a); |
|||
k=0; |
|||
If a>0 Then Else return 0 |
|||
While (k<=b) And (Not ok) Do |
|||
ok=match(sub,s, a,k); remark we must start at k=0 ! |
|||
Inc(k); |
|||
Done |
|||
EndIf |
|||
If ok Then |
|||
return k |
|||
Else |
|||
return 0 |
|||
EndIf |
|||
EndFunc */ |
|||
|
|||
Func int matchwhite(Pchar s, Pchar t, int n, int tstart) |
|||
Begin |
|||
/* like match, but any whitespace in t matches space in s*/ |
|||
int i,j,lt; Bool ok; |
|||
/*-StartProc-*/ |
|||
i=0; j=tstart; |
|||
lt= length(t); |
|||
ok=(tstart<lt); |
|||
While ok And (i<n) Do |
|||
If s[i]==' ' Then /* always Ok, skip space in t */ |
|||
If cMode Then |
|||
j=skipCwhite(t,j,lt) |
|||
Else |
|||
While (j<=lt) And (t[j]<=' ') And (t[j]>0) Do Inc(j) Done |
|||
Dec(j); |
|||
EndIf |
|||
Repeat |
|||
Inc(j) |
|||
Until (j>=lt) Or (t[j]>' ') EndRep /*skip space in t*/ |
|||
Dec(j); |
|||
Else |
|||
ok= (j<=lt) And ((s[i]==t[j]) Or (s[i]==joker)); |
|||
EndIf |
|||
Inc(i); Inc(j); |
|||
Done |
|||
If ok Then |
|||
return (int)(j-tstart) |
|||
Else |
|||
return (int)0 |
|||
EndIf |
|||
EndFunc |
|||
|
|||
Func int posizero(Pchar sub, Pchar s) |
|||
Begin /*another Pos */ |
|||
/* substring search. like posi, but reject quotes & bracketed stuff */ |
|||
int a,b,k; |
|||
Bool ok; |
|||
int blevel; |
|||
char c; |
|||
/*-StartProc-*/ |
|||
ok=False; |
|||
a=length(sub); |
|||
b=(int)(length(s)-a); |
|||
k=0; blevel=0; |
|||
If a>0 Then /*Else return 0*/ |
|||
While (k<=b) And (Not ok) Do |
|||
ok= (matchwhite(sub,s, a,k)>0); |
|||
If (k<=b) And (Not ok) Then |
|||
c=s[k]; |
|||
If (c==')') Or (c==']') Or (c=='}') Then |
|||
If c!=sub[0] Then Dec(blevel) EndIf /*negative level: fail!*/ |
|||
If blevel<0 Then k=b EndIf |
|||
ElsIf (c=='\'') Or (c=='\"') Then /*skip quote */ |
|||
Repeat Inc(k) |
|||
Until (k>=b) Or (s[k]==c) EndRep |
|||
ElsIf (c=='(') Or (c=='[') Or (c=='{') Then /*skip block*/ |
|||
Inc(blevel); /*counts the bracketing level */ |
|||
Repeat |
|||
Inc(k); c=s[k]; |
|||
If (c=='(') Or (c=='[') Or (c=='{') Then |
|||
Inc(blevel) |
|||
ElsIf (c==')') Or (c==']') Or (c=='}') Then |
|||
Dec(blevel) |
|||
EndIf |
|||
Until (k>=b) Or (blevel==0) EndRep |
|||
EndIf |
|||
EndIf |
|||
Inc(k); |
|||
Done |
|||
EndIf |
|||
If ok Then |
|||
return k |
|||
Else |
|||
return 0 |
|||
EndIf |
|||
EndFunc |
|||
|
|||
Func int isMacro(Pchar s, char option, Pchar t, int tstart, |
|||
string maccopy[] ) |
|||
/* s= macro template, t=buffer, maccopy = arg Array |
|||
return value: number of characters matched, |
|||
restrictive option: 'u' |
|||
macro substitution args 1 2 3 ...9. |
|||
sample: bla1tra2gla3vla matches "bla ME tra YOU gla HIM vla" |
|||
substitute 1 by maccopy[1] etc |
|||
*/ |
|||
Begin |
|||
Darray(ps, int, nargs+1) |
|||
Word j,k,dk,ls, lst, lmt, jmax, pj; |
|||
Bool ok; |
|||
char arg; |
|||
Strbig(Llen,u); |
|||
Str(40,st); |
|||
/* returns >0 If comparison Ok == length of compared Pchar */ |
|||
/*-StartProc-*/ k=0; |
|||
ok= (s[0]==t[tstart]); /* intcut: how much does it accelerate ? some % */ |
|||
If ok Then |
|||
ps[0]=0; |
|||
ps[nargs]=0; /*only 1..9 are valid data, 10 filler templates*/ |
|||
j=0; |
|||
Repeat |
|||
Inc(j); arg= (char)(j+'0'); |
|||
ps[j]= cpos(arg,s); |
|||
Until (j>=nargs) Or (ps[j]==0) EndRep |
|||
ls= length(s); |
|||
ps[j]=(int)(ls+1); /*For last template chunk*/ |
|||
jmax=j; j=1; |
|||
k=0; lmt=0; |
|||
Repeat |
|||
pscopy(st,s, (Word)(ps[j-1]+1), (Word)(ps[j]-ps[j-1]-1) ); |
|||
/*j-th template Pchar*/ lst=length(st); |
|||
If j==1 Then |
|||
If option=='u' Then |
|||
lmt= matchwhite(st,t,lst,tstart); |
|||
ok=(lmt>0) /*length of match in t*/ |
|||
Else |
|||
ok= match(st,t,lst,tstart) |
|||
EndIf |
|||
If ok Then |
|||
pscopy(u,t, (Word)(tstart+1), (Word)255); |
|||
pj=1 |
|||
Else |
|||
pj=0 |
|||
EndIf |
|||
Else |
|||
If option=='u' Then |
|||
pj= posizero(st,u); |
|||
If pj>0 Then lmt= matchwhite(st,u, lst, (int)(pj-1)) EndIf |
|||
Else |
|||
pj= posi(st,u) |
|||
EndIf /* qs[j]= k+pj; is position in t*/ |
|||
ok=(pj>0); |
|||
EndIf |
|||
If ok Then |
|||
If option=='u' Then |
|||
If j==1 Then scopy(maccopy[0],"") EndIf |
|||
saddn(maccopy[j-1],u, (Word)(pj-1)); |
|||
dk= (Word)(pj+lmt); |
|||
copySpace(maccopy[j], t, |
|||
(Word)(tstart+k+pj), (Word)(tstart+k+dk)); |
|||
/* space in t[k+pj...k+dk] goes into maccopy[j] as a prefix. */ |
|||
Else |
|||
pscopy(maccopy[j-1],u, (Word)1, (Word)(pj-1)); |
|||
/*the stuff preceding the marker*/ |
|||
dk= (Word)(pj+lst); /* start of unexplored part */ |
|||
EndIf |
|||
pscopy(u,u, (Word)dk, (Word)length(u)); /*shift in the rest*/ |
|||
k= (Word)(k+dk-1); |
|||
EndIf |
|||
Inc(j) |
|||
Until (j>jmax) Or (Not ok) EndRep |
|||
EndIf |
|||
If Not ok Then k=0 EndIf |
|||
return k |
|||
EndFunc |
|||
|
|||
Func int similar(Pchar s, char wilds, Pchar t, |
|||
int tstart, string maccopy[] ) |
|||
/* try to match s with t, then save the wildcard parts ins maccopy[] */ |
|||
/* s=template, t=buffer, wilds= number of wildcards, maccopy=substitute */ |
|||
/* return value: number of characters matched */ |
|||
Begin |
|||
Word j,k,ps,ls; |
|||
Bool ok; |
|||
char endc; |
|||
Strbig(Llen,u); |
|||
/* returns >0 if comparison Ok = length of compared string */ |
|||
/* char comparison, s may have wildcard regions with "æ" BUT 1 valid End */ |
|||
/*-StartProc-*/ |
|||
ls=length(s); |
|||
k=0; |
|||
If wilds==wild Then |
|||
ps= cpos(wild,s) |
|||
Else |
|||
ps=0 |
|||
EndIf |
|||
If ps==0 Then |
|||
If match(s,t,ls,tstart) Then |
|||
k=ls; |
|||
ps= cpos(joker,s); /*save joker's substitute*/ |
|||
If ps>0 Then |
|||
maccopy[nargs][0]=t[ps-1+tstart] |
|||
EndIf |
|||
Else |
|||
k=0 |
|||
EndIf |
|||
Else |
|||
k= (Word)(ps-1); |
|||
While s[k]==wild Do Inc(k) Done |
|||
endc=s[k]; /*End char to detect, at length */ |
|||
ok= match(s,t, (int)(ps-1), tstart); |
|||
If ok Then |
|||
pscopy(u,t, (Word)(ps+tstart), (Word)255); |
|||
j= cpos(endc, u); |
|||
ok=(j>0); |
|||
If ok Then |
|||
k= (Word)(ps+j-1); |
|||
pscopy(maccopy[nargs],t, (Word)(ps+tstart), (Word)(j-1)); |
|||
EndIf |
|||
EndIf |
|||
If Not ok Then k=0 EndIf |
|||
EndIf |
|||
return k |
|||
EndProc |
|||
|
|||
Func int addSubList(Pchar s, int isr) |
|||
/* add the rule s to the Rule list at isr */ |
|||
Begin |
|||
int j,ls; |
|||
char c,d,endc; |
|||
Bool start,stop; |
|||
/*-StartProc-*/ |
|||
ls=length(s); /* must kill the Newline */ |
|||
endc=' '; |
|||
While (ls>0) And (s[ls]<' ') Do Dec(ls) Done; |
|||
s[ls+1]=' '; |
|||
s[ls+2]=0; /* add a space */ |
|||
If s[0]=='o' Then |
|||
setOptions(s) |
|||
ElsIf (isr<nsub) And (cpos(s[0],"swmuxa") >0) Then |
|||
j=1; |
|||
Inc(isr); |
|||
scopy(search[isr],""); scopy(replace[isr],""); |
|||
srule[isr]=(s[0]); |
|||
wildcard[isr]=0; |
|||
/*init search*/ |
|||
start=True; stop=False; |
|||
d=0; |
|||
While Not stop Do |
|||
Inc(j); c=s[j]; |
|||
If start Then |
|||
If c !=' ' Then |
|||
start=False; |
|||
If c=='\"' Then endc=c Else endc=' ' EndIf |
|||
EndIf |
|||
Else |
|||
stop=(c==endc) |
|||
EndIf |
|||
If Not (start Or (c==endc)) Then |
|||
If c=='?' Then |
|||
c=joker |
|||
ElsIf (c=='^') And (s[j+1]>= ' ') Then |
|||
Inc(j); c=s[j]; |
|||
If (c>='@') And (c<='_') Then |
|||
c= (char)(c-'@') |
|||
EndIf |
|||
ElsIf (c=='\\') And (s[j+1]>= ' ') Then |
|||
Inc(j); c=s[j]; |
|||
If c=='n' Then c= Cr; d=Lf EndIf |
|||
EndIf |
|||
cadd(search[isr],c); |
|||
If (c==wild) Or (c==joker) Then |
|||
wildcard[isr]=c |
|||
EndIf |
|||
If d!=0 Then |
|||
cadd(search[isr],d); |
|||
d=0 |
|||
EndIf |
|||
EndIf |
|||
Done |
|||
If endc!=' ' Then Inc(j) EndIf |
|||
/*init replace*/ |
|||
start=True; stop=False; |
|||
d=0; |
|||
While Not stop Do |
|||
Inc(j); c=s[j]; |
|||
If start Then |
|||
If c!=' ' Then |
|||
start=False; |
|||
If c=='\"' Then endc=c Else endc=' ' EndIf |
|||
EndIf |
|||
Else |
|||
stop=(c==endc) |
|||
EndIf |
|||
If Not (start Or (c==endc)) Then |
|||
If c=='?' Then |
|||
c=joker |
|||
ElsIf (c=='^') And (s[j+1]>= ' ') Then |
|||
Inc(j); c=s[j]; |
|||
If (c>='@') And (c<='Z') Then c= (char)(c-'@') EndIf |
|||
ElsIf (c=='\\') And (s[j+1]>= ' ') Then |
|||
Inc(j); c=s[j]; /*echo next char */ |
|||
If c=='n' Then c=Cr; d=Lf EndIf |
|||
EndIf |
|||
cadd(replace[isr],c); |
|||
If d!=0 Then |
|||
cadd(replace[isr],d); |
|||
d=0 |
|||
EndIf |
|||
EndIf |
|||
Done |
|||
If endc !=' ' Then Inc(j) EndIf |
|||
EndIf |
|||
If isr>=nsub Then |
|||
ws("No more room for rules."); wln() |
|||
EndIf |
|||
return isr |
|||
EndFunc |
|||
|
|||
Func Bool getSubList(Pchar slist) |
|||
/* read the search and substitution rule list */ |
|||
Begin |
|||
Strbig(Llen,s); |
|||
Pfile f; |
|||
Bool done, ok; |
|||
/*-StartProc-*/ |
|||
cMode=False; |
|||
lookmax= 80; /* or 250: handle 4 full lines maximum ? */ |
|||
If Zero(slist[0]) Then |
|||
scopy(slist, "slist.txt") |
|||
EndIf |
|||
f=fopen(slist,"rb"); |
|||
isr=0; |
|||
done= (f == Null); |
|||
ok= Not done; |
|||
While Not done Do |
|||
fgets(s,(int)80,f); |
|||
isr=addSubList(s,isr); |
|||
done= feof(f) |
|||
Done |
|||
If f != Null Then fclose(f) EndIf |
|||
ws("Number of rules: "); |
|||
wi(isr); wln(); |
|||
return ok |
|||
EndFunc |
|||
|
|||
Func Bool nonAlfa(char c) |
|||
Begin |
|||
return ((c<'a') Or (c>'z')) And ((c<'A') Or (c>'Z')) |
|||
EndFunc |
|||
|
|||
/********** optional output postprocessor **************/ |
|||
|
|||
/* the main translator calls these: |
|||
washinit to reset the postprocessor |
|||
washchar to output a char |
|||
washstring to output a string |
|||
washflush to terminate |
|||
*/ |
|||
|
|||
/* C reformatter, keeping an eye on the following (modulo whitespace): |
|||
; } Lf. |
|||
|
|||
This is just a state machine, handling 3 rules using an output buffer obf. |
|||
<white> means space excluding \n, and <white2>, space including newlines. |
|||
Wanted: regular-expression scripts or tricks to do the same or better... |
|||
|
|||
Rule1: <white>Lf<white>; --> ;<white>Lf<white> states 2 3 |
|||
Rule2: ;<white2>; --> ;<white2> state 1 |
|||
Rule3: }<white2>; --> }<white2> state 1 |
|||
*/ |
|||
|
|||
Bool washmore= True; /* flag that activates the postprocessor */ |
|||
Strbig(Llen,obf); /* output buffer */ |
|||
int iobf=0; /* its index */ |
|||
int wstate=0; /* output state machine */ |
|||
|
|||
Proc washinit(void) |
|||
Begin |
|||
iobf=0; |
|||
wstate=0 |
|||
EndProc |
|||
|
|||
Proc washchar(char c) |
|||
Begin /* state machine receives one character */ |
|||
int i; |
|||
If Not washmore Then /* never leave state 0 */ |
|||
fputc(c, fout) |
|||
ElsIf wstate==0 Then /* buffer empty */ |
|||
If (c==';') Or (c=='}') Then |
|||
iobf=0; obf[iobf]=c; |
|||
Inc(iobf); wstate=1 |
|||
ElsIf c<=' ' Then |
|||
iobf=0; obf[iobf]=c; |
|||
Inc(iobf); |
|||
If c==Lf Then wstate=3 Else wstate=2 EndIf |
|||
Else |
|||
fputc(c, fout) |
|||
EndIf |
|||
ElsIf wstate==1 Then |
|||
If c <= ' ' Then |
|||
obf[iobf]=c; Inc(iobf) |
|||
Else |
|||
If c != ';' Then |
|||
obf[iobf]=c; Inc(iobf) |
|||
EndIf |
|||
For i=0; i<iobf; Inc(i) Do |
|||
fputc(obf[i], fout) |
|||
Done |
|||
iobf=0; |
|||
wstate=0 |
|||
EndIf |
|||
ElsIf wstate==2 Then |
|||
obf[iobf]=c; Inc(iobf); |
|||
If c==Lf Then |
|||
wstate=3 |
|||
ElsIf c<=' ' Then /* keep state */ |
|||
Else |
|||
For i=0; i<iobf; Inc(i) Do |
|||
fputc(obf[i], fout) |
|||
Done |
|||
iobf=0; |
|||
wstate=0 |
|||
EndIf |
|||
ElsIf wstate==3 Then |
|||
obf[iobf]=c; Inc(iobf); |
|||
If c<=' ' Then /* keep state */ |
|||
Else |
|||
If c==';' Then |
|||
Dec(iobf); fputc(c, fout) |
|||
EndIf |
|||
For i=0; i<iobf; Inc(i) Do |
|||
fputc(obf[i], fout) |
|||
Done |
|||
iobf=0; |
|||
wstate=0 |
|||
EndIf |
|||
EndIf |
|||
EndProc |
|||
|
|||
Proc washflush(void) |
|||
Begin |
|||
int i; |
|||
If NotZ(wstate) Then |
|||
For i=0; i<iobf; Inc(i) Do |
|||
fputc(obf[i], fout) |
|||
Done |
|||
iobf=0; |
|||
wstate=0 |
|||
EndIf |
|||
EndProc |
|||
|
|||
Proc washstring( Pchar s) |
|||
Begin |
|||
int i; |
|||
For i=0; i<length(s); Inc(i) Do |
|||
washchar(s[i]) |
|||
Done |
|||
EndProc |
|||
|
|||
/************* main part of translation filter ***********/ |
|||
|
|||
Proc translate(Pchar bf); /* recursion */ |
|||
|
|||
Proc echoOut(Pchar r, char isWild, string mac[] ) |
|||
Begin |
|||
int u; |
|||
Strbig(Llen,s); |
|||
/*-StartProc-*/ |
|||
If isWild !=0 Then |
|||
u= cpos(isWild,r) |
|||
Else |
|||
u=0 |
|||
EndIf |
|||
If u==0 Then |
|||
washstring(r) |
|||
Else /*substitute with wildcard*/ |
|||
pscopy(s,r, (Word)1, (Word)(u-1)); washstring(s); |
|||
If isWild==joker Then |
|||
washchar(mac[nargs][0]) |
|||
ElsIf Recursion Then |
|||
translate(mac[nargs]) |
|||
Else |
|||
washstring(mac[nargs]) |
|||
EndIf |
|||
scopy(mac[nargs], ""); |
|||
pscopy(s,r, (Word)(u+1), (Word)40); |
|||
washstring(s); |
|||
EndIf |
|||
EndProc |
|||
|
|||
Proc macroOut(Pchar r, string mac[] ) |
|||
Begin |
|||
/* substitutes "1"..."9", uses "0" as escape character*/ |
|||
char c; |
|||
int i,j; |
|||
Bool escape; |
|||
/*-StartProc-*/ |
|||
escape=False; |
|||
For i=0; i<length(r); Inc(i) Do |
|||
c=r[i]; |
|||
j= (int)(c-'0'); |
|||
If j==0 Then |
|||
escape=True /*And skip*/ |
|||
ElsIf ((j>0) And (j<nargs)) And (Not escape) Then |
|||
If Recursion Then |
|||
translate(mac[j]) |
|||
Else |
|||
washstring(mac[j]) |
|||
EndIf |
|||
Else |
|||
washchar(c); |
|||
escape=False |
|||
EndIf |
|||
Done |
|||
EndProc |
|||
|
|||
Proc makeNewRule(Pchar r, string mac[] ) |
|||
Begin |
|||
/* substitutes "1"..."9", uses "0" as escape character*/ |
|||
char c; |
|||
int i,j; |
|||
Bool escape; |
|||
Strbig(Llen,s); |
|||
/*-StartProc-*/ |
|||
escape=False; |
|||
For i=0; i<length(r); Inc(i) Do |
|||
c=r[i]; |
|||
j= (int)(c-'0'); |
|||
If j==0 Then |
|||
escape=True /*And skip*/ |
|||
ElsIf ((j>0) And (j<nargs)) And (Not escape) Then |
|||
sadd(s,mac[j]) |
|||
Else |
|||
cadd(s,c); escape=False |
|||
EndIf |
|||
Done |
|||
isr= addSubList(s,isr) |
|||
EndProc |
|||
|
|||
Proc translate(Pchar bff) |
|||
Begin /*light version, inside recursion only */ |
|||
Bool done; |
|||
Strbig(Llen,bf); |
|||
Darray(mac, string, nargs) |
|||
Bool ok; |
|||
int i,sm; |
|||
char lastBf1; |
|||
Word nbrep; |
|||
/*-StartProc-*/ |
|||
For i=0; i<nargs; Inc(i) Do |
|||
Sini(mac[i]) |
|||
Done |
|||
nbrep=0; |
|||
done= Zero(bff[0]); |
|||
lastBf1=' '; |
|||
If Not done Then scopy(bf,bff) EndIf |
|||
While Not done Do |
|||
i=1; |
|||
ok=False; sm=0; |
|||
While (i<=isr) And (Not ok) Do /*search For 1st match*/ |
|||
If (srule[i]=='m') Or (srule[i]=='u') Then |
|||
If alfa(lastBf1) And (alfa(search[i][0])) Then |
|||
sm=0 /*inside word*/ |
|||
Else |
|||
sm= isMacro(search[i], srule[i], bf, (int)0,mac) |
|||
EndIf |
|||
Else |
|||
sm=similar(search[i],wildcard[i],bf, (int)0, mac) |
|||
EndIf |
|||
ok=sm>0; |
|||
If ok And (srule[i]=='w') Then |
|||
ok=nonAlfa(lastBf1) And nonAlfa(bf[sm]) |
|||
EndIf |
|||
If Not ok Then Inc(i) EndIf |
|||
Done |
|||
If ok Then |
|||
If (srule[i]=='m') Or (srule[i]=='u') Then |
|||
macroOut(replace[i], mac) |
|||
Else |
|||
echoOut(replace[i],wildcard[i], mac) |
|||
EndIf |
|||
lastBf1=bf[sm-1]; pscopy(bf,bf, (Word)(sm+1), (Word)255); |
|||
Inc(nbrep); |
|||
Else |
|||
lastBf1=bf[0]; |
|||
washchar(lastBf1); |
|||
pscopy(bf,bf, (Word)2, (Word)255); |
|||
EndIf |
|||
done= Zero(bf[0]) |
|||
Done |
|||
EndProc |
|||
|
|||
Proc translator( Pchar fname) |
|||
/* checks list of possible substitution rules sequentially. |
|||
Does the first that matches. Option: recursion. |
|||
BUG: is very slow. |
|||
*/ |
|||
Begin |
|||
Strbig(Llen, outname); Strbig(Llen,bf); |
|||
Bool done; |
|||
Darray( mac, string, nargs) |
|||
Pfile fin; |
|||
Bool ok; |
|||
int i,sm, exclusion, idot; |
|||
char c,lastBf1; |
|||
Word nbrep,nline; |
|||
/*-StartProc-*/ |
|||
For i=0; i<nargs; Inc(i) Do |
|||
Sini(mac[i]) |
|||
Done |
|||
nbrep=0; |
|||
nline=0; |
|||
exclusion=0; /* will be >0 if an exclusion rule is active */ |
|||
fin=fopen( fname, "rb"); |
|||
scopy(outname, fname); |
|||
idot= cpos('.',outname); |
|||
If idot <= 8 Then /* room for underbar prefix, even in Ms-dos */ |
|||
cins(outname,'_') |
|||
ElsIf NotZ(outname[0]) Then /* just erase first char */ |
|||
outname[0] = '_' |
|||
Else |
|||
scopy(outname,"washprog.out") |
|||
EndIf |
|||
fout=fopen( outname,"wb"); |
|||
washinit(); |
|||
done= (fin == Null) Or (fout == Null); |
|||
scopy(bf,""); |
|||
lastBf1=' '; |
|||
/* lookmax=80; handle a line maximum ! */ |
|||
While Not done Do |
|||
c=' '; |
|||
While (c !=0) And (length(bf)<lookmax) Do /*refill buffer*/ |
|||
If Not feof(fin) Then |
|||
c=fgetc(fin); |
|||
If (c== Cr) Or (c== Lf) Then |
|||
Inc(nline); |
|||
If odd(nline) Then wc('.') EndIf |
|||
If (nline Mod 150)==0 Then wln() EndIf |
|||
EndIf |
|||
If (c==0) Or feof(fin) Then c=' ' EndIf /*== space*/ |
|||
Else |
|||
c=0 |
|||
EndIf |
|||
If NotZ(c) Then cadd(bf,c) EndIf |
|||
Done |
|||
ok=False; |
|||
sm=0; i=0; |
|||
If exclusion>0 Then |
|||
i=exclusion; |
|||
sm=similar(replace[i], (char)0, bf, (int)0, mac); |
|||
ok= sm>0 |
|||
EndIf |
|||
If Zero(exclusion) Then |
|||
i=1; |
|||
While (i<=isr) And (Not ok) Do /*search for 1st match*/ |
|||
If (srule[i]=='m') Or (srule[i]=='u') Or (srule[i]=='a') Then |
|||
If alfa(lastBf1) And (alfa(search[i][0])) Then |
|||
sm=0 /*inside word*/ |
|||
Else |
|||
sm= isMacro(search[i], srule[i], bf, (int)0,mac) |
|||
EndIf |
|||
Else |
|||
sm=similar(search[i],wildcard[i],bf, (int)0, mac) |
|||
EndIf |
|||
ok=sm>0; |
|||
If ok And (srule[i]=='w') Then |
|||
ok=nonAlfa(lastBf1) And nonAlfa(bf[sm]) |
|||
EndIf |
|||
If Not ok Then Inc(i) EndIf |
|||
Done |
|||
EndIf |
|||
If ok Then |
|||
If (srule[i]=='m') Or (srule[i]=='u') Then |
|||
macroOut(replace[i], mac) |
|||
ElsIf srule[i]=='x' Then |
|||
If Zero(exclusion) Then |
|||
exclusion=i |
|||
Else |
|||
exclusion=0 |
|||
EndIf |
|||
ElsIf srule[i]=='a' Then |
|||
makeNewRule(replace[i],mac) |
|||
Else |
|||
echoOut(replace[i],wildcard[i],mac) |
|||
EndIf |
|||
lastBf1=bf[sm-1]; pscopy(bf,bf, (Word)(sm+1), (Word)lookmax); |
|||
Inc(nbrep); |
|||
Else |
|||
lastBf1=bf[0]; |
|||
If Zero(exclusion) Then washchar(lastBf1) EndIf; |
|||
pscopy(bf,bf, (Word)2, (Word)lookmax); |
|||
/*avoid this time-consuming buffer shuffling ?*/ |
|||
EndIf |
|||
done= Zero(bf[0]); |
|||
Done |
|||
If fout !=Null Then |
|||
washflush(); |
|||
fputc('\n', fout); |
|||
fclose(fout) |
|||
EndIf |
|||
If fin !=Null Then fclose(fin) EndIf |
|||
ws("Lines: "); wi(nline); |
|||
ws(" Replacements: "); |
|||
wi(nbrep); wln(); |
|||
EndProc |
|||
|
|||
Func int main( int argc, Pchar argv[]) |
|||
Begin |
|||
Str(80,dico); |
|||
int istart= 1; |
|||
Bool ok= True; |
|||
/*-StartProc-*/ |
|||
allocdata(); |
|||
scopy(dico,"downgrad"); /* default rules file */ |
|||
ws(" washprog: A text substitution utility"); wln(); |
|||
If (argc>2) And steq(argv[1],"-r") Then |
|||
scopy(dico,argv[2]); |
|||
istart= 3; |
|||
/* |
|||
Else |
|||
ws("Dictionary file (.TXT automatic): "); |
|||
rln(dico); |
|||
*/ |
|||
EndIf |
|||
If spos(".txt",dico) <=0 Then |
|||
sadd(dico,".txt") |
|||
EndIf |
|||
ok= getSubList(dico); /*list of substitution rules */ |
|||
While ok And (istart< argc) Do |
|||
If argv[istart][0] != '_' Then /* leading underbar not accepted */ |
|||
translator( argv[istart]) |
|||
EndIf |
|||
Inc(istart) |
|||
Done |
|||
return 0 |
|||
EndFunc |
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue