1 /*    e_trans.cpp
2  *
3  *    Copyright (c) 1994-1996, Marko Macek
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9 
10 #include "c_history.h"
11 #include "i_modelview.h"
12 #include "i_view.h"
13 #include "o_buflist.h"
14 #include "s_util.h"
15 
16 #include <ctype.h>
17 
18 // FLAW: NULL characters can not be translated, need escaping
ParseTrans(unsigned char * S,unsigned char * D,TransTable tab)19 int ParseTrans(unsigned char *S, unsigned char *D, TransTable tab) {
20     unsigned char Dest[512];
21     unsigned char A, B;
22     unsigned int i;
23 
24     if (S == 0 || D == 0)
25         return 0;
26 
27     strncpy((char *)Dest, (char *)D, sizeof(Dest) - 1); Dest[sizeof(Dest) - 1] = 0;
28     D = Dest;
29 
30     // no translation
31     for (i = 0; i < 256; i++)
32         tab[i] = (unsigned char)i;
33 
34     while (*S && *D) {
35         if (S[0] && S[1] == '-' && S[2]) {
36             if (S[0] <= S[2]) {
37                 A = (*S)++;
38                 if (S[0] >= S[2])
39                     S += 2;
40             } else {
41                 A = (*S)--;
42                 if (S[0] <= S[2])
43                     S += 2;
44             }
45         } else {
46             A = *S++;
47         }
48         if (D[0] && D[1] == '-' && D[2]) {
49             if (D[0] <= D[2]) {
50                 B = (*D)++;
51                 if (D[0] >= D[2])
52                     D += 2;
53             } else {
54                 B = (*D)--;
55                 if (D[0] <= D[2])
56                     D += 2;
57             }
58         } else {
59             B = *D++;
60         }
61         tab[A] = B;
62     }
63     if (*S != *D) // one was too short
64         return 0;
65     return 1;
66 }
67 
MakeTrans(TransTable tab,int What)68 int MakeTrans(TransTable tab, int What) {
69     int i;
70 
71     // no translation
72     for (i = 0; i <= 255; i++)
73         tab[i] = (unsigned char)i;
74 
75     switch (What) {
76     case ccToggle:
77     case ccUp:
78         for (i = 33; i <= 255; i++)
79             if (isalpha(i) && (toupper(i) != i))
80                 tab[i] = (unsigned char) toupper(i);
81         if (What != ccToggle)
82             break;
83     case ccDown:
84         for (i = 33; i <= 255; i++)
85             if (isalpha(i) && (i == tab[i]) && (tolower(i) != i))
86                 tab[i] = (unsigned char) tolower(i);
87         break;
88     default:
89         return 0;
90     }
91     return 1;
92 }
93 
BlockTrans(TransTable tab)94 int EBuffer::BlockTrans(TransTable tab) {
95     int L, I, B, E;
96     PELine LL;
97 
98     if (CheckBlock() == 0) return 0;
99     if (RCount == 0) return 0;
100 
101     for (L = BB.Row; L <= BE.Row; L++) {
102         LL = RLine(L);
103         B = 0;
104         E = 0;
105         switch (BlockMode) {
106         case bmLine:
107             if (L == BE.Row)
108                 E = 0;
109             else
110                 E = LL->Count;
111             break;
112         case bmColumn:
113             if (L == BE.Row)
114                 E = 0;
115             else {
116                 B = CharOffset(LL, BB.Col);
117                 E = CharOffset(LL, BE.Col);
118             }
119             break;
120         case bmStream:
121             if (L == BB.Row && L == BE.Row) {
122                 B = CharOffset(LL, BB.Col);
123                 E = CharOffset(LL, BE.Col);
124             } else if (L == BB.Row) {
125                 B = CharOffset(LL, BB.Col);
126                 E = LL->Count;
127             } else if (L == BE.Row) {
128                 B = 0;
129                 E = CharOffset(LL, BE.Col);
130             } else {
131                 B = 0;
132                 E = LL->Count;
133             }
134             break;
135         }
136         if (B > LL->Count)
137             B = LL->Count;
138         if (E > LL->Count)
139             E = LL->Count;
140         if (E > B) {
141             if (ChgChars(L, B, E - B, 0) == 0) return 0;
142             for (I = B; I < E; I++)
143                 LL->Chars[I] = tab[(unsigned char)LL->Chars[I]];
144         }
145     }
146     Draw(BB.Row, BE.Row);
147     return 1;
148 }
149 
CharTrans(TransTable tab)150 int EBuffer::CharTrans(TransTable tab) {
151     PELine L = VLine(CP.Row);
152     unsigned int P = CharOffset(L, CP.Col);
153 
154     if (P >= (unsigned int)L->Count) return 0;
155     if (ChgChars(CP.Row, P, 1, 0) == 0) return 0;
156     L->Chars[P] = tab[(unsigned char)L->Chars[P]];
157     return 1;
158 }
159 
LineTrans(TransTable tab)160 int EBuffer::LineTrans(TransTable tab) {
161     PELine L = VLine(CP.Row);
162     int I;
163 
164     if (L->Count > 0) {
165         if (ChgChars(CP.Row, 0, L->Count, 0) == 0) return 0;
166         for (I = 0; I < L->Count; I++)
167             L->Chars[I] = tab[(unsigned char)L->Chars[I]];
168     }
169     return 1;
170 }
171 
CharCaseUp()172 int EBuffer::CharCaseUp() {
173     TransTable tab;
174 
175     MakeTrans(tab, ccUp);
176     return CharTrans(tab);
177 }
178 
CharCaseDown()179 int EBuffer::CharCaseDown() {
180     TransTable tab;
181 
182     MakeTrans(tab, ccDown);
183     return CharTrans(tab);
184 }
185 
CharCaseToggle()186 int EBuffer::CharCaseToggle() {
187     TransTable tab;
188 
189     MakeTrans(tab, ccToggle);
190     return CharTrans(tab);
191 }
192 
LineCaseUp()193 int EBuffer::LineCaseUp() {
194     TransTable tab;
195 
196     MakeTrans(tab, ccUp);
197     return LineTrans(tab);
198 }
199 
LineCaseDown()200 int EBuffer::LineCaseDown() {
201     TransTable tab;
202 
203     MakeTrans(tab, ccDown);
204     return LineTrans(tab);
205 }
206 
LineCaseToggle()207 int EBuffer::LineCaseToggle()  {
208     TransTable tab;
209 
210     MakeTrans(tab, ccToggle);
211     return LineTrans(tab);
212 }
213 
BlockCaseUp()214 int EBuffer::BlockCaseUp() {
215     TransTable tab;
216 
217     MakeTrans(tab, ccUp);
218     return BlockTrans(tab);
219 }
220 
BlockCaseDown()221 int EBuffer::BlockCaseDown() {
222     TransTable tab;
223 
224     MakeTrans(tab, ccDown);
225     return BlockTrans(tab);
226 }
227 
BlockCaseToggle()228 int EBuffer::BlockCaseToggle() {
229     TransTable tab;
230 
231     MakeTrans(tab, ccToggle);
232     return BlockTrans(tab);
233 }
234 
GetTrans(ExState & State,TransTable tab)235 int EBuffer::GetTrans(ExState &State, TransTable tab) {
236     unsigned char TrS[512] = "";
237     unsigned char TrD[512] = "";
238 
239     if (State.GetStrParam(View, (char *)TrS, sizeof(TrS)) == 0)
240         if (View->MView->Win->GetStr("Trans From", sizeof(TrS), (char *)TrS, HIST_TRANS) == 0)
241             return 0;
242     if (State.GetStrParam(View, (char *)TrD, sizeof(TrD)) == 0)
243         if (View->MView->Win->GetStr("Trans To", sizeof(TrS), (char *)TrD, HIST_TRANS) == 0)
244             return 0;
245     if (ParseTrans(TrS, TrD, tab) == 0) {
246         Msg(S_ERROR, "Bad Trans Arguments %s %s.", TrS, TrD);
247         return 0;
248     }
249     return 1;
250 }
251 
CharTrans(ExState & State)252 int EBuffer::CharTrans(ExState &State) {
253     TransTable tab;
254 
255     if (GetTrans(State, tab) == 0)
256         return 0;
257     return CharTrans(tab);
258 }
259 
LineTrans(ExState & State)260 int EBuffer::LineTrans(ExState &State) {
261     TransTable tab;
262 
263     if (GetTrans(State, tab) == 0)
264         return 0;
265     return LineTrans(tab);
266 }
267 
BlockTrans(ExState & State)268 int EBuffer::BlockTrans(ExState &State) {
269     TransTable tab;
270 
271     if (GetTrans(State, tab) == 0)
272         return 0;
273     return BlockTrans(tab);
274 }
275