Very old versions for history.
[opsoft_archive.git] / silentbob / silentbob-1.1 / src / plugins / the_fly.cpp
blobea4aff957e6c0ae4095e4418e5229820680abc5f
1 /*
2 * (c) Oleg Puchinin 2006.
3 * graycardinalster@gmail.com
5 * Oleg, "THE FLY", and BUGS.
6 *
7 * "THE FLY" - "THE TT" analog for Perl code.
8 * 1 May 2006 - started.
9 * 26/06/06 - v1.0-rc1.
11 * RUS, KOI8-r.
12 * îÅ "ôô". "íÕÈÁ". ;)
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <ctype.h>
20 #include <dlib.h>
21 #include "../mod.h"
22 #include "../head.h"
23 #include "../dbg.h"
24 #include "../the_tt.h"
25 #include "the_fly.hpp"
27 namespace THE_FLY {
29 char * t_map;
30 char * t_new;
31 char pch;
32 int i;
33 int ii;
34 int t_size;
35 int spaces;
36 int nlines;
37 int t_op_no;
38 pair_t * d_attachment = NULL;
40 #define T t_map[i]
42 inline void t_attach ()
44 t_op_no++;
45 d_attachment[t_op_no].pair_op = t_op_no;
46 d_attachment[t_op_no].pair_line = nlines;
47 d_attachment[t_op_no].offset = i;
50 inline void TN (char ch) {
51 t_new[ii] = ch;
52 ++ii;
53 if ((i && t_map[i-1] != '\\') && (ch == '{' || ch == '}' || ch == ';'))
54 t_attach ();
57 inline char * fly_fw (char * word)
59 char * Ret;
60 char *S = word;
61 while (true) {
62 if (!if_abc (S) &&
63 !if_digit (S) &&
64 *S != '_' &&
65 *S != '*')
66 break;
67 ++S;
69 Ret = CNEW (char, S - word + 1);
70 memcpy (Ret, word, S - word);
71 Ret[S-word] = '\0';
72 return Ret;
75 void fly_skip ()
77 char * word = NULL;
78 char * S = NULL;
79 char * ptrn = NULL;
81 word = &t_map[i+2];
82 if (*word == '\'' || *word == '\"')
83 ++word;
85 word = fly_fw (word);
86 if (! word)
87 return;
89 ptrn = CNEW (char, strlen (word)+3);
90 sprintf (ptrn, "\n%s\n", word);
91 S = (char *) memmem (&t_map[i+2], t_size-i-2, ptrn, strlen (ptrn));
92 assert (! S, "fly_skip fail !");
93 if (! S) {
94 i = t_size;
95 goto out;
98 nlines += Dsyms (&t_map[i+2], S, '\n');
99 nlines+=2;
100 i += S - &t_map[i] + strlen (ptrn) + 1;
102 out:
103 DROP (ptrn);
104 DROP (word);
107 void doc_skip ()
109 char *S;
110 char * ptrn = "\n=cut\n";
112 S = (char *) memmem (&t_map[i], t_size-i, ptrn, 6);
113 if (! S) {
114 i = t_size;
115 return;
118 nlines += Dsyms (&t_map[i], S, '\n');
119 ++nlines;
120 i += S - &t_map[i] + 4;
123 void regexp_skip ()
125 char ss;
126 int count;
127 char * ptr;
128 int old;
130 count = 1;
131 old = i;
132 switch (T) {
133 case 't':
134 i+=2;
135 break;
136 case 's':
137 ++i;
138 count = 2;
139 break;
140 case 'm':
141 ++i;
142 break;
145 ss = T;
146 if (ss == '{')
147 ss = '}';
148 ++i;
149 ptr = &t_map[i];
150 while (true) {
151 for (; i < t_size; ++i) {
152 if (T == '\n')
153 break;
155 if (t_map[i] == ss && !(ww_nsyms_r (ptr, &t_map[i-1], '\\') % 2))
156 break;
159 if (T == '\n')
160 break;
162 assert (i >= t_size, "Sibadi 2006.2");
163 if (i >= t_size)
164 break;
166 if (--count == 0)
167 break;
168 ++i;
171 if (T == '\n') {
172 i = old;
173 TN(T);
177 bool regexp_test ()
179 char * ptr;
180 char ch = T;
181 char ss;
183 if (isalnum (pch) || pch == '_' || pch == ')')
184 return false;
186 if (! (ch == '/' || ch == 's' || ch == 'm' || !strncmp (&t_map[i], "tr", 2)))
187 return false;
189 ptr = &t_map[i];
190 ++ptr;
191 switch (ch) {
192 case 't':
193 ++ptr;
194 case 's':
195 case 'm':
196 ss = *ptr;
197 if (! (ss == '/' || ss == '?' || ss == '#'
198 || ss == '!' || ss == '&' || ss == '|' || ss == '{'))
199 return false;
200 break;
203 return true;
206 inline void tt_skip ()
208 while (T != '\n' && i < t_size)
209 ++i;
210 --i;
213 int fly_for_buffers (char * d_input, int size, char * d_output)
215 char ch;
216 char * S;
218 i = 0;
219 ii = 0;
220 t_size = size;
221 t_map = d_input;
222 t_new = d_output;
223 spaces = 0;
224 nlines = 0;
225 pch = 'a';
226 t_op_no = 0;
228 i = 0;
229 if (T == '#') {
230 tt_skip ();
231 ++i;
234 for (; i < size; i++) {
235 ch = T;
236 if (ch == '\n')
237 ++nlines;
239 if (regexp_test ()) {
240 regexp_skip ();
241 continue;
244 if (if_digit (&t_map[i]) || if_abc (&t_map[i])) {
245 spaces = 0;
246 goto abc;
249 if ((ch == '\'' || ch == '\"') && t_map[i-1] != '$' && t_map[i-1] != '\\') {
250 if (ch == '\'' && (isalnum (t_map[i-1]) || t_map[i-1] == '&'))
251 goto abc;
253 S = sstrend (&t_map[i]);
254 assert (S == NULL, "\n\nSibadi 2006\n\n");
255 nlines += Dsyms (&t_map[i], S, '\n');
256 i += S - &t_map[i];
257 pch = ch;
258 TN (ch);
259 TN (ch);
260 continue;
263 if (ch == '\n' || ch == ' ' || ch == '\t') {
264 if (spaces == 0) {
265 TN (' ');
266 spaces++;
267 continue;
268 } else
269 continue;
272 if (ch == '<' && t_map[i+1] == '<') {
273 fly_skip ();
274 if (i >= t_size) {
275 TN ('\0');
276 break;
278 TN (';');
279 TN (' ');
280 spaces = 0;
281 pch = ch;
282 continue;
285 if (ch == ';' || ch == '}' || ch == ')' ||
286 ch == '{' || ch == '(') {
287 if (! spaces)
288 TN (' ');
289 TN (ch);
290 TN (' ');
291 spaces = 1;
292 pch = ch;
293 continue;
296 if (ch == '=' && t_map[i-1] == '\n') {
297 doc_skip ();
298 pch = ch;
299 continue;
302 if (ch == '#' && t_map[i-1] != '$') {
303 tt_skip ();
304 pch = ch;
305 continue;
308 abc:
309 pch = ch;
310 TN(T);
313 TN('\0');
314 return ii;
317 char * fly_for_file (struct tt_state_t * tt)
319 if (! tt)
320 return NULL;
322 if (access (tt->d_file_name, R_OK) != F_OK) {
323 fprintf (stderr, "No such file %s\n", tt->d_file_name);
324 return NULL;
327 tt_map (tt);
329 tt->d_output = CNEW (char, 1024*1024);
330 tt->d_output[0] = 0;
331 d_attachment = (pair_t *) CNEW (char, 1024*1024);
333 tt->d_attachment = d_attachment;
334 tt->d_output_size = fly_for_buffers (tt->d_file_in, tt->d_filein_size, tt->d_output);
335 return tt->d_output;
338 } // namespace THE_FLY