1 /* @source biosed application
2 **
3 ** Replace or delete sequence sections
4 **
5 ** @author Copyright (C) Alan Bleasby (ableasby@hgmp.mrc.ac.uk)
6 ** @@
7 **
8 ** This program is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU General Public License
10 ** as published by the Free Software Foundation; either version 2
11 ** of the License, or (at your option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program; if not, write to the Free Software
20 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21 ******************************************************************************/
22 
23 #include "emboss.h"
24 
25 
26 static void biosed_replace(AjPStr *substr,
27 			   const AjPStr target, const AjPStr replace,
28 			   ajint targetpos, ajint begin);
29 static void biosed_delete(AjPStr *substr, const AjPStr target,
30 			   ajint targetpos, ajint begin);
31 
32 
33 
34 
35 /* @prog biosed ***************************************************************
36 **
37 ** Replace or delete sequence sections
38 **
39 ******************************************************************************/
40 
main(int argc,char ** argv)41 int main(int argc, char **argv)
42 {
43     AjPSeq       seq = NULL;
44     AjPSeqall    seqall;
45     AjPStr	 target;
46     AjPStr	 replace;
47     AjBool       delete;
48     AjPSeqout    outseq;
49     ajint        targetpos;
50 
51     AjPStr       substr = NULL;
52     AjPStr       str    = NULL;
53 
54     ajint        begin;
55     ajint        end;
56 
57     const char *p = NULL;
58 
59     embInit("biosed", argc, argv);
60 
61     seqall  = ajAcdGetSeqall("sequence");
62     delete  = ajAcdGetToggle("delete");
63     target  = ajAcdGetString("targetregion");
64     targetpos  = ajAcdGetInt("position");
65     replace = ajAcdGetString("replace");
66     outseq  = ajAcdGetSeqout("outseq");
67 
68     substr = ajStrNew();
69     str    = ajStrNew();
70 
71     ajStrFmtUpper(&target);
72     ajStrFmtUpper(&replace);
73 
74     while(ajSeqallNext(seqall,&seq))
75     {
76 	begin = ajSeqallGetseqBegin(seqall);
77 	end   = ajSeqallGetseqEnd(seqall);
78 
79 	p = ajSeqGetSeqC(seq);
80 	ajStrAssignSubC(&substr,p,begin-1,end-1);
81 	ajStrFmtUpper(&substr);
82 
83 	if(!delete)
84 	    biosed_replace(&substr,target,replace,targetpos, begin);
85 	else
86 	    biosed_delete(&substr,target,targetpos, begin);
87 
88 	ajSeqAssignSeqS(seq,substr);
89 	ajSeqoutWriteSeq(outseq,seq);
90     }
91 
92     ajStrDel(&substr);
93     ajStrDel(&str);
94     ajSeqoutClose(outseq);
95 
96     ajSeqoutDel(&outseq);
97 
98     ajSeqallDel(&seqall);
99     ajSeqDel(&seq);
100     ajStrDel(&replace);
101     ajStrDel(&target);
102 
103     embExit();
104 
105     return 0;
106 }
107 
108 
109 
110 
111 /* @funcstatic biosed_replace *************************************************
112 **
113 ** Generic (unoptimised) replacement of all matching string subsections
114 **
115 ** @param [w] substr [AjPStr *] sequence
116 ** @param [r] target [const AjPStr] target pattern
117 ** @param [r] replace [const AjPStr] replacement subsequence
118 ** @param [r] targetpos [ajint] target position
119 ** @param [r] begin [ajint] first base of sequence
120 **
121 ** @return [void]
122 ** @@
123 ******************************************************************************/
124 
biosed_replace(AjPStr * substr,const AjPStr target,const AjPStr replace,ajint targetpos,ajint begin)125 static void biosed_replace(AjPStr *substr,
126 			   const AjPStr target, const AjPStr replace,
127 			   ajint targetpos, ajint begin)
128 {
129     AjPStr str = NULL;
130     AjPStr tmp = NULL;
131 
132     ajint  tlen;
133     ajint  end = 0;
134 
135     const char   *p = NULL;
136     const char   *q  = NULL;
137     const char   *v;
138 
139     str = ajStrNew();
140     tmp = ajStrNew();
141     p   = ajStrGetPtr(*substr);
142     v   = ajStrGetPtr(target);
143 
144     tlen = ajStrGetLen(target);
145 
146     if(targetpos)
147     {
148 	q = p;
149 	p += (targetpos - begin);
150 	end = (ajint)(p - q) - 1;
151 	if(ajCharPrefixS(p, target)) {
152 	    if(end > -1)
153 	    {
154 		ajStrAssignSubC(&tmp,q,0,end);
155 		ajStrAppendS(&str,tmp);
156 	    }
157 	    p += tlen;
158 	    ajStrAppendS(&str,replace);
159 	    ajStrAppendC(&str,p);
160 	    ajStrAssignS(substr,str);
161 	}
162     }
163     else {
164 	while((q=strstr(p,v)))
165 	{
166 	    end = (ajint)(q-p) - 1;
167 
168 	    if(end > -1)
169 	    {
170 		ajStrAssignSubC(&tmp,p,0,end);
171 		ajStrAppendS(&str,tmp);
172 	    }
173 
174 	    ajStrAppendS(&str,replace);
175 	    p = q+tlen;
176 	}
177 	ajStrAppendC(&str,p);
178 	ajStrAssignS(substr,str);
179     }
180 
181     ajStrDel(&str);
182     ajStrDel(&tmp);
183 
184     return;
185 }
186 
187 
188 
189 
190 /* @funcstatic biosed_delete **************************************************
191 **
192 ** Generic (unoptimised) delete of all matching string subsections
193 **
194 ** @param [w] substr [AjPStr*] sequence
195 ** @param [r] target [const AjPStr] target pattern
196 ** @param [r] targetpos [ajint] target position
197 ** @param [r] begin [ajint] first base of sequence
198 **
199 ** @return [void]
200 ** @@
201 ******************************************************************************/
202 
biosed_delete(AjPStr * substr,const AjPStr target,ajint targetpos,ajint begin)203 static void biosed_delete(AjPStr *substr, const AjPStr target,
204 			   ajint targetpos, ajint begin)
205 {
206     AjPStr str = NULL;
207     char   *p  = NULL;
208     char   *q  = NULL;
209     const char   *v  = NULL;
210     char   *t  = NULL;
211     ajint  tlen = 0;
212     AjPStr tmp = NULL;
213     ajint end;
214 
215     str = ajStrNew();
216     tmp = ajStrNew();
217     ajStrAssignS(&str,*substr);
218     p = ajStrGetuniquePtr(&str);
219     v = ajStrGetPtr(target);
220     tlen = ajStrGetLen(target);
221 
222     if(targetpos)
223     {
224 	q = p;
225 	p += (targetpos - begin);
226 	end = (ajint)(p - q) - 1;
227 	if(ajCharPrefixS(p, target))
228 	{
229 	    if(end > -1)
230 	    {
231 		ajStrAssignSubC(&tmp,q,0,end);
232 	    }
233 	    p += tlen;
234 	    ajStrAppendC(&tmp,p);
235 	    ajStrAssignS(substr,tmp);
236 	}
237     }
238     else
239     {
240 	while((q=strstr(p,v)))
241 	{
242 	    t = q + tlen;
243 	    p = t;
244 	    while((*q++=*p++));
245 	    p = t-1;
246 	}
247 	ajStrAssignC(substr,ajStrGetPtr(str));
248     }
249     ajStrDel(&str);
250     ajStrDel(&tmp);
251 
252     return;
253 }
254