Very old versions for history.
[opsoft_archive.git] / silentbob / silent_bob-1.2 / src / sblib / the_tt.cpp
blobd2554423faa93873a2036d4444ece212effa41c9
1 /*
2 * (c) Oleg Puchinin 2006
3 * graycardinalster@gmail.com
4 *
5 */
7 /*
8 * "Oleg, THE_TT and BUGs"
9 *
10 * 01/01/06 00:00 - Started...
11 * January 2006 - string BUG fixed.
12 * "//" BUG fixed. It's work currently ?!
14 * January 2006, last day. added operator to line conversion.
15 * February 2006 - operator to line conversion work properly.
16 * February 2006 - "macro BUG" fixed.
17 * March 2006 - "Style BUG" fixed (?).
18 **/
20 #include "../head.h"
21 #include <sys/mman.h>
22 #include "../the_tt.h"
24 extern FILE * d_stream_dbg;
26 namespace THE_TT {
28 #define IF(arg) if (t_map[i] == arg)
29 #define IF2(arga, argb) if (t_map[i] == arga && t_map[i+1] == argb)
30 #define is_space(arg) (arg == ' ' || arg == '\t' || arg == '\n')
31 #define IF_breaker if (t_map[i]==';' || t_map[i] == '}' || t_map[i] == '{')
32 #define T t_map[i]
33 #define T2 t_map[i+1]
34 #define Toff(arg) t_map[i+arg]
35 #define ATTACH t_attach ();
37 int i;
38 int ii;
39 int t_size;
40 char * t_map;
41 char * t_new;
42 int t_input_line;
43 int t_op_no;
44 int brace_depth = 0; // for '()'
45 int block_depth = 0; // for '{}'
46 bool b_make_attachment;
47 bool t_in_macro;
48 pair_t * d_attachment = NULL;
50 char * tt_out_buf = NULL;
51 int tt_outbuf_size = 0;
53 inline void t_attach ()
55 t_op_no++;
56 d_attachment[t_op_no].pair_op = t_op_no;
57 d_attachment[t_op_no].pair_line = t_input_line;
58 d_attachment[t_op_no].offset = i;
59 brace_depth = 0; // Paranoid
62 inline void TN (char arg)
64 t_new[ii] = arg;
65 ++ii;
66 if (arg == '\n' ||
67 arg == '{' || arg == '}' ||
68 (arg == ';' && !brace_depth)) {
70 if (arg == '\n') {
71 --t_input_line;
72 ATTACH;
73 ++t_input_line;
74 } else
75 ATTACH;
79 #define TNs(arg) do { t_new[ii] = arg; ++ii; } while (0)
81 inline void tt_comment ()
83 while (i < t_size) {
84 IF2('*', '/')
85 break;
86 IF ('\n') {
87 t_input_line++;
89 i++;
91 i++;
94 inline void tt_skip ()
96 while (T != '\n' && i < t_size)
97 ++i;
98 --i;
101 // NOTE: you _must_ allocate d_input and d_output before call this.
102 int the_tt_for_buffers (char * d_input,
103 int t_new_size,
104 char * d_output)
106 unsigned int t_spaces = 1;
107 bool b_mustlined = false;
108 bool b_instring = false;
109 bool b_newline = true;
110 int d_slash_count = 0;
111 bool b_lined = true;
112 char ch_last = 0;
114 i = 0;
115 ii = 0;
116 b_lined = true;
117 b_mustlined = false;
118 b_newline = true;
119 t_size = t_new_size;
120 t_map = d_input;
121 t_new = d_output;
122 t_input_line = 0;
123 t_op_no = 0;
124 brace_depth = 0;
125 block_depth = 0;
127 if (t_map[0] == '\n') {
128 ++i; // "mmap BUG" fixed :))
129 ++t_input_line;
132 if (Toff (t_size-1) == '\n')
133 t_size--; // mmap'ed TT not work without this !
135 for (; i < t_size; ++i) {
136 if (if_abc (&t_map[i]) || if_digit (&t_map[i])) {
137 b_lined = false;
138 t_spaces = 0;
139 goto abc;
142 IF ('\n')
143 ++t_input_line;
145 if (T == '\'' || T == '\"') {
146 if (b_instring && ch_last != T) {
147 TN(T);
148 continue;
151 if (b_instring) {
152 if (Toff(-1) != '\\') // Normal skip \" and... \\" :)
153 b_instring = false;
154 else {
155 d_slash_count = 1;
156 while (Toff (-(d_slash_count)) == '\\') // Yes, I'm don't like this.
157 d_slash_count++;
159 if (d_slash_count & 1)
160 b_instring = false;
162 } else {
163 ch_last = T;
164 b_instring = true;
168 if (b_instring) {
169 if (T != '\n')
170 TNs (T);
171 else {
172 if (Toff(-1) == '\\')
173 --ii;
175 continue;
178 if (T == '\n') {
179 if (Toff(-1) == '\\') {
180 if (t_in_macro)
181 TN(T);
182 else
183 ii--;
184 continue;
185 } else
186 t_in_macro = false;
189 IF2('/','/') {
190 tt_skip ();
191 continue;
194 IF2('/', '*') {
195 tt_comment ();
196 continue;
199 if (T == '(')
200 ++brace_depth;
202 if (T == ')')
203 --brace_depth;
205 if (brace_depth < 0)
206 brace_depth = 0;
208 if (is_space (T)) {
209 if (T == '\n') {
210 b_newline = true;
211 if (Toff(1) == '#' && !b_lined) {
212 TN ('\n');
213 ++t_spaces;
214 b_lined = true;
215 b_mustlined = false;
216 continue;
219 if (b_mustlined) {
220 TN('\n');
221 ++t_spaces;
222 if (!(Toff (-1) == '\\')) {
223 b_mustlined = false;
224 b_lined = true;
228 if (t_spaces == 0 && !b_lined) {
229 ++t_spaces;
230 TN(' ');
232 continue;
233 } else {
234 ++t_spaces;
235 if (t_spaces == 1)
236 TN(' ');
238 continue;
241 b_lined = false;
242 if (T == '(' && t_spaces == 0 && b_mustlined == 0) {
243 ++t_spaces; // No space after '('.
244 TN(' ');
245 TN('(');
246 continue;
249 if (T == ')' && t_spaces == 0) {
250 ++t_spaces;
251 TN(')');
252 TN(' ');
253 continue;
256 t_spaces = 0;
257 IF_breaker {
258 TN(T);
259 TN(' ');
260 ++t_spaces;
261 continue;
264 IF('#' && b_newline) {
265 TN ('#');
266 t_in_macro = true;
267 b_mustlined = true;
268 continue;
271 IF (0x0D)
272 continue;
274 abc:
275 b_newline = false;
276 // TN(T);
277 TNs(T);
278 } // for
280 return ii;
283 char * do_tt_file (tt_state_t * d_tt_state)
285 char * t_output = NULL;
286 char * f_name;
287 int t_Ret;
289 d_attachment = NULL;
291 if (! d_tt_state)
292 return 0;
294 f_name = d_tt_state->d_file_name;
296 if (EQ(f_name, "-")) {
297 d_tt_state->d_file_in = Dread_to_eof (fileno (stdin), &d_tt_state->d_filein_size);
298 if (d_tt_state->d_filein_size <= 0)
299 exit (1);
300 } else
301 tt_map (d_tt_state);
303 t_size = d_tt_state->d_filein_size;
305 t_output = CNEW (char, t_size<<1); // Paranoid.
306 if (t_output == NULL) {
307 perror ("no such memory");
308 return NULL;
310 /**/
312 if (t_size < 4096)
313 d_attachment = CNEW (pair_t, 4096);
314 else
315 d_attachment = CNEW (pair_t, t_size>>1);
317 d_tt_state->d_attachment = d_attachment;
319 t_Ret = the_tt_for_buffers (d_tt_state->d_file_in, t_size, t_output);
320 t_output[t_Ret] = 0; // Required.
321 d_tt_state->d_output_size = t_Ret;
322 d_tt_state->d_output = t_output;
324 return t_output;
327 // $ silent_bob --the-tt
328 int the_tt_main (char * f_name)
330 char * t_output;
331 tt_state_t * d_tt_state;
333 d_tt_state = CNEW (tt_state_t, 1);
334 memset (d_tt_state, 0, sizeof (tt_state_t));
335 d_tt_state->d_file_name = f_name;
336 t_output = do_tt_file (d_tt_state);
338 if (! SB_FLGET (SB_FLSIMULATE))
339 write (fileno (stdout), t_output, d_tt_state->d_output_size);
341 free_tt_state (d_tt_state);
342 return EXIT_SUCCESS;
345 } // namespace THE_TT
347 void free_tt_state (struct tt_state_t * S)
349 if (S->b_mmap)
350 munmap (S->d_file_in, S->d_filein_size);
351 else
352 DROP (S->d_file_in);
354 if (S->d_fd)
355 close (S->d_fd);
357 DROP (S->d_output);
358 DROP (S->d_attachment);
359 DROP (S);
362 int tt_map (tt_state_t *tt)
364 tt->b_mmap = true;
365 tt->d_file_in = DFMAP (tt->d_file_name, &tt->d_fd, &tt->d_filein_size);
367 if (tt->d_file_in == NULL) {
368 tt->d_filein_size = fsize (tt->d_file_name);
369 tt->b_mmap = false;
370 tt->d_file_in = CNEW (char, tt->d_filein_size);
371 if (Dfnread (tt->d_file_name, tt->d_file_in, tt->d_filein_size) < 0)
372 DROP (tt->d_file_in);
375 if (! tt->d_file_in) {
376 fprintf (stderr, "can't open/mmap file %s\n", tt->d_file_name);
377 perror ("open/mmap");
378 return -1;
381 return 0;