+ Fixes
[opsoft.git] / silentbob / src / cgrep.cxx
blob8d54dccfc831600c0f97533efc604114e67c6ad1
1 /*
2 * (c) Oleg Puchinin 2006
3 * graycardinalster@gmail.com
5 */
7 #include <head.h>
8 #include <structs.h>
9 #include <the_tt.h>
10 #include <dbg.h>
12 namespace cgrep {
14 /// смещение (в строках) строки str в буфере d_buf.
15 int stringOffset (char ** d_buf, char *str)
17 char * S;
18 int len = strlen (str);
19 int fix = 0;;
21 S = *d_buf;
22 while (true) {
23 if (! strncmp (S, str, len))
24 break;
25 if (*S == '\n')
26 fix--;
27 --S;
30 *d_buf = S;
31 return fix;
34 int fixPosition (tt_state_t *tt, int t_op_no, DArray * exp)
36 int fix = 0;
37 char * d_buf;
38 int i;
40 if (! tt || ! exp)
41 return 0;
43 d_buf = tt->fileData + tt->attachment[t_op_no].offset - 1;
44 for (i = exp->get_size () - 1; i >= 0; --i)
45 fix += stringOffset (&d_buf, exp->get (i));
47 return fix;
50 void print (tt_state_t * tt, DArray * d_array, DArray * d_lines)
52 int line;
53 line = tt->attachment[ENV->t_op_no].pair_line + 1;
54 line += fixPosition (tt, ENV->t_op_no, d_array);
55 if (SB_FLGET (SB_FLTAGSTYLE))
56 printf ("%s\t%s\t+%i\n", ENV->cgrep_exp,
57 tt->fileName, line);
58 else
59 printf ("%s +%i: %s", tt->fileName, line, d_lines->get (line-1));
60 fflush (stdout);
63 bool scan (char *S, DArray * d_array)
65 char * one;
66 int size;
67 int i;
69 size = d_array->get_size ();
70 for (i = 0; i < size; i++) {
71 one = d_array->get (i);
72 S = strstr (S, one);
73 if (! S)
74 break;
75 S += strlen (one);
78 if (i == size)
79 return true;
80 return false;
83 int file (char * fileName)
85 char * d_ptr, *d_out;
86 DArray * d_array;
87 DArray * d_lines = NULL;
88 tt_state_t * tt;
89 char ch;
91 if (ENV->cgrep_exp == NULL)
92 return -1;
94 tt = CNEW (tt_state_t, 1);
95 memset (tt, 0, sizeof (tt_state_t));
96 tt->fileName = strdup (fileName);
98 if (THE_TT::do_tt_file (tt) == NULL) {
99 free_tt_state (tt);
100 return -1; // broken file
103 d_out = tt->result;
104 d_ptr = tt->result;
105 ENV->t_op_no = 0;
107 d_array = Dsplit (ENV->cgrep_exp, (char *) ",");
108 if (d_array == NULL)
109 return -2;
111 if (! SB_FLGET (SB_FLTAGSTYLE)) {
112 d_lines = new DArray (1024);
113 d_lines->from_file (tt->fileName);
116 while (true) {
117 ch = t_op (&d_ptr, &d_out);
118 ENV->t_op_no++;
119 if (! ch)
120 break;
121 if (! scan (d_out, d_array))
122 continue;
123 print (tt, d_array, d_lines);
126 if (d_lines) {
127 d_lines->foreach (free);
128 delete d_lines;
131 free_tt_state (tt);
132 return 0;
135 int thread (int N)
137 char m_buf[512];
138 FILE * m_file;
140 sprintf (m_buf, "%s%i", ENV->tmp_files, N);
141 m_file = fopen (m_buf, "r");
142 if (! m_file)
143 exit (-1);
145 while (fgets (m_buf, 512, m_file)) {
146 chomp (m_buf);
147 file (m_buf);
150 fclose (m_file);
151 exit (0);
152 return 0;
155 int cgrep (EArray * d_files)
157 __djob_t * j;
158 int i;
160 if (! d_files)
161 return -1;
163 if (strchr (ENV->cgrep_exp, ' ') ||
164 strchr (ENV->cgrep_exp, '\t')) {
165 fprintf (stderr, "You can't use spaces and tabs in expression.\n");
166 return -1;
169 if (ENV->max_proc == 1) {
170 for (i = 0; i < d_files->get_size (); ++i)
171 file (d_files->get (i));
172 return 0;
175 d_files->strings_to_file (ENV->tmp_files);
176 split_tmp_files ();
177 for (i = 0; i < ENV->max_proc; ++i) {
178 j = ENV->proc_list->fork ();
179 if (j->child)
180 thread (i);
183 while ((j = ENV->proc_list->wait_all ()) && j)
184 Dexec_done (j);
186 remove_tmp_files ();
187 return 0;
190 } // namespace cgrep