/*
* Copyright (c) 2012, NTT Multimedia Communications Laboratories, Inc. and Koushik Sen
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package tests;
/* -*- Last-Edit: Mon Dec 7 10:31:51 1992 by Tarak S. Goradia; -*-
* ported to Java
* */
import janala.Main;
public class Replace {
final int MYMAX = 20;
final int MAXSTR = 100;
final int MAXPAT = 100;
final char ENDSTR = '\0';
final char ESCAPE = '@';
final char CLOSURE = '*';
final char BOL = '%';
final char EOL = '$';
final char ANY = '?';
final char CCL = '[';
final char CCLEND = ']';
final char NEGATE = '^';
final char NCCL = '!';
final char LITCHAR = 'c';
final int DITTO = -1;
final char DASH = '-';
final char TAB = 9;
final char NEWLINE = 10;
final int CLOSIZE = 1;
// typedef char character;
// typedef char string[MAXSTR];
boolean getline(char[] s, int maxsize) {
char[] result;
int i;
char c;
for(i=0;i<MYMAX-1;i++) {
c = Main.readChar('a');
Main.MakeSymbolic(c);
s[i] = c;
}
s[i] = '\0';
return true;
}
boolean addstr(char c, char[] outset, int[] j, int maxset)
{
boolean result;
if (j[0] >= maxset)
result = false;
else {
outset[j[0]] = c;
j[0] = j[0] + 1;
result = true;
}
return result;
}
char esc(char[] s, int[] i) {
char result;
if (s[i[0]] != ESCAPE)
result = s[i[0]];
else
if (s[i[0] + 1] == ENDSTR)
result = ESCAPE;
else
{
i[0] = i[0] + 1;
if (s[i[0]] == 'n')
result = NEWLINE;
else
if (s[i[0]] == 't')
result = TAB;
else
result = s[i[0]];
}
return result;
}
void dodash(char delim, char[] src, int[] i, char[] dest, int[] j, int maxset)
{
int k;
boolean junk;
char escjunk;
while ((src[i[0]] != delim) && (src[i[0]] != ENDSTR))
{
if (src[i[0] - 1] == ESCAPE) {
escjunk = esc(src, i);
junk = addstr(escjunk, dest, j, maxset);
} else
if (src[i[0]] != DASH)
junk = addstr(src[i[0]], dest, j, maxset);
else if (j[0] <= 1 || src[i[0] + 1] == ENDSTR)
junk = addstr(DASH, dest, j, maxset);
else if ((isalnum(src[i[0] - 1])) && (isalnum(src[i[0] + 1]))
&& (src[i[0] - 1] <= src[i[0] + 1]))
{
for (k = src[i[0]-1]+1; k<=src[i[0]+1]; k++)
{
junk = addstr((char)k, dest, j, maxset);
}
i[0] = i[0] + 1;
}
else
junk = addstr(DASH, dest, j, maxset);
i[0] = i[0] + 1;
}
}
private boolean isalnum(char c) {
return ((c >='a' && c <='z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'));
}
boolean getccl(char[] arg, int[] i, char[] pat, int[] j) {
int jstart;
boolean junk;
i[0] = i[0] + 1;
if (arg[i[0]] == NEGATE) {
junk = addstr(NCCL, pat, j, MAXPAT);
i[0] = i[0] + 1;
} else
junk = addstr(CCL, pat, j, MAXPAT);
jstart = j[0];
junk = addstr((char)0, pat, j, MAXPAT);
dodash(CCLEND, arg, i, pat, j, MAXPAT);
pat[jstart] = (char)(j[0] - jstart - 1);
return (arg[i[0]] == CCLEND);
}
void stclose(char[] pat, int[] j, int lastj) {
int[] jt = new int[1];
int jp;
boolean junk;
for (jp = j[0] - 1; jp >= lastj ; jp--)
{
jt[0] = jp + CLOSIZE;
junk = addstr(pat[jp], pat, jt, MAXPAT);
}
j[0] = j[0] + CLOSIZE;
pat[lastj] = CLOSURE;
}
boolean in_set_2(char c) {
return (c == BOL || c == EOL || c == CLOSURE);
}
boolean in_pat_set(char c){
return ( c == LITCHAR || c == BOL || c == EOL || c == ANY
|| c == CCL || c == NCCL || c == CLOSURE);
}
int makepat(char[] arg, int start, char delim, char[] pat) {
int result;
int lastj, lj;
boolean done, junk;
boolean getres;
char escjunk;
int[] j = new int[1];
j[0] = 0;
int[] i = new int[1];
i[0] = start;
lastj = 0;
done = false;
while ((!done) && (arg[i[0]] != delim) && (arg[i[0]] != ENDSTR)) {
lj = j[0];
if ((arg[i[0]] == ANY))
junk = addstr(ANY, pat, j, MAXPAT);
else if ((arg[i[0]] == BOL) && (i[0] == start))
junk = addstr(BOL, pat, j, MAXPAT);
else if ((arg[i[0]] == EOL) && (arg[i[0]+1] == delim))
junk = addstr(EOL, pat, j, MAXPAT);
else if ((arg[i[0]] == CCL))
{
getres = getccl(arg, i, pat, j);
done = (getres == false);
}
else if ((arg[i[0]] == CLOSURE) && (i[0] > start))
{
lj = lastj;
if (in_set_2(pat[lj]))
done = true;
else
stclose(pat, j, lastj);
}
else
{
junk = addstr(LITCHAR, pat, j, MAXPAT);
escjunk = esc(arg, i);
junk = addstr(escjunk, pat, j, MAXPAT);
}
lastj = lj;
if ((!done))
i[0] = i[0] + 1;
}
junk = addstr(ENDSTR, pat, j, MAXPAT);
if ((done) || (arg[i[0]] != delim))
result = 0;
else
if ((!junk))
result = 0;
else
result = i[0];
return result;
}
boolean getpat(char[] arg, char[] pat) {
int makeres;
makeres = makepat(arg, 0, ENDSTR, pat);
return (makeres > 0);
}
int makesub(char[] arg, int from, char delim, char[] sub) {
int result;
int[] i = new int[1];
boolean junk;
char escjunk;
int[] j = new int[1];
j[0] = 0;
i[0] = from;
while ((arg[i[0]] != delim) && (arg[i[0]] != ENDSTR)) {
if ((arg[i[0]] == ('&')))
junk = addstr((char)DITTO, sub, j, MAXPAT);
else {
escjunk = esc(arg, i);
junk = addstr(escjunk, sub, j, MAXPAT);
}
i[0] = i[0] + 1;
}
if (arg[i[0]] != delim)
result = 0;
else {
junk = addstr(ENDSTR, sub, j, MAXPAT);
if ((!junk))
result = 0;
else
result = i[0];
}
return result;
}
boolean getsub(char[] arg, char[] sub) {
int makeres;
makeres = makesub(arg, 0, ENDSTR, sub);
return (makeres > 0);
}
boolean locate(char c, char[] pat, int offset) {
int i;
boolean flag;
flag = false;
i = offset + pat[offset];
while ((i > offset))
{
if (c == pat[i]) {
flag = true;
i = offset;
} else
i = i - 1;
}
return flag;
}
boolean omatch(char[] lin, int[] i, char[] pat, int j) {
char advance;
boolean result;
advance = (char)-1;
if ((lin[i[0]] == ENDSTR))
result = false;
else
{
if (!in_pat_set(pat[j]))
{
System.err.print("in omatch: can't happen\n");
System.exit(0);
} else {
if(pat[j]==LITCHAR) {
if (lin[i[0]] == pat[j + 1])
advance = 1;
} else if(pat[j]==BOL) {
if (i[0] == 0)
advance = 0;
} else if (pat[j]==ANY) {
if (lin[i[0]] != NEWLINE)
advance = 1;
} else if (pat[j]==EOL) {
if (lin[i[0]] == NEWLINE)
advance = 0;
} else if (pat[j]==CCL) {
if (locate(lin[i[0]], pat, j + 1))
advance = 1;
} else if (pat[j]==NCCL) {
if ((lin[i[0]] != NEWLINE) && (!locate(lin[i[0]], pat, j+1)))
advance = 1;
} else {
Caseerror(pat[j]);
}
}
}
if ((advance >= 0))
{
i[0] = i[0] + advance;
result = true;
} else
result = false;
return result;
}
int patsize(char[] pat, int n) {
int size=0;
if (!in_pat_set(pat[n])) {
System.err.print("in patsize: can't happen\n");
System.exit(0);
} else
if(pat[n] == LITCHAR) {
size = 2;
} else if (pat[n]==BOL || pat[n]== EOL || pat[n] ==ANY) {
size = 1;
} else if (pat[n]==CCL || pat[n] == NCCL) {
size = pat[n + 1] + 2;
} else if (pat[n]==CLOSURE) {
size = CLOSIZE;
} else {
Caseerror(pat[n]);
}
return size;
}
int amatch(char[] lin, int offset, char[] pat, int j) {
int i, k=0;
boolean result, done;
int[] offseta = new int[1];
int[] ia = new int[1];
done = false;
while ((!done) && (pat[j] != ENDSTR))
if ((pat[j] == CLOSURE)) {
j = j + patsize(pat, j);
i = offset;
while ((!done) && (lin[i] != ENDSTR)) {
ia[0] = i;
result = omatch(lin, ia, pat, j);
i = ia[0];
if (!result)
done = true;
}
done = false;
while ((!done) && (i >= offset)) {
k = amatch(lin, i, pat, j + patsize(pat, j));
if ((k >= 0))
done = true;
else
i = i - 1;
}
offset = k;
done = true;
} else {
offseta[0] = offset;
result = omatch(lin, offseta, pat, j);
offset = offseta[0];
if ((!result)) {
offset = -1;
done = true;
} else
j = j + patsize(pat, j);
}
return offset;
}
void putsub(char[] lin, int s1, int s2, char[] sub) {
int i;
int j;
i = 0;
while ((sub[i] != ENDSTR)) {
if ((sub[i] == DITTO))
for (j = s1; j < s2; j++)
{
System.out.print(lin[j]);
}
else
{
System.out.print(sub[i]);
}
i = i + 1;
}
}
void subline(char[] lin, char[] pat, char[] sub) {
int i, lastm, m;
lastm = -1;
i = 0;
while ((lin[i] != ENDSTR))
{
m = amatch(lin, i, pat, 0);
if ((m >= 0) && (lastm != m)) {
putsub(lin, i, m, sub);
lastm = m;
}
if ((m == -1) || (m == i)) {
System.out.print(lin[i]);
i = i + 1;
} else
i = m;
}
}
void change(char[] pat, char[] sub) {
char[] line = new char[MAXSTR];
boolean result;
result = getline(line, MAXSTR);
if ((result)) {
subline(line, pat, sub);
}
}
void main()
{
char[] pat = new char[MAXSTR];
char[] sub = new char[MAXSTR];
boolean result;
char c;
char[] input1 = new char[MAXSTR];
char[] input2 = new char[MAXSTR];
int i;
for(i=0;i<MYMAX-1;i++) {
c = Main.readChar('a');
Main.MakeSymbolic(c);
input1[i] = c;
}
input1[i] = '\0';
for(i=0;i<MYMAX-1;i++) {
c = Main.readChar('a');
Main.MakeSymbolic(c);
input2[i] = c;
}
input2[i] = '\0';
result = getpat(input1, pat);
if (!result)
{
System.out.print("change: illegal \"from\" pattern\n");
System.exit(0);
}
result = getsub(input2, sub);
if (!result)
{
System.out.print("change: illegal \"to\" string\n");
System.exit(0);
}
change(pat, sub);
}
void Caseerror(int n) {
System.out.println("Missing case limb: line"+n);
System.exit(0);
}
public static void main(String[] args) {
(new Replace()).main();
}
}