+ Fixes
[opsoft.git] / silentbob / sblib / Sblib.cxx
blobf3494eedec2f4181203c8460d7d6f800a25accc5
1 /*
2 * (c) Oleg Puchinin 2006,2007
3 * graycardinalster@gmail.com
5 */
7 #include <gclib/gclib.h>
8 #include <env.h>
9 #include <bob_flags.h>
10 #include <head.h>
11 #include <wit.h>
12 #include <dbg.h>
13 #include <string.h>
14 #include <sys/wait.h>
15 #include <errno.h>
16 #include <the_tt.h>
18 struct env_t *ENV;
20 char * __bice_get (char *optname)
22 char * value;
23 value = ENV->settings->get (optname);
24 if (! value)
25 value = getenv (optname);
26 return value;
29 EHash * bob_init_compile_env ()
31 EHash * compile_env;
32 char *cc;
33 char *cxx;
34 char *cflags;
35 char *cxxflags;
36 char *opts;
37 char *include;
38 char *libs;
39 char *ldflags;
41 compile_env = new EHash;
43 cc = __bice_get ((char *) "CC");
44 cxx = __bice_get ((char *) "CXX");
45 cflags = __bice_get ((char *) "CFLAGS");
46 cxxflags = __bice_get ((char *) "CXXFLAGS");
47 opts = __bice_get ((char *) "OPTS");
48 include = __bice_get ((char *) "INCLUDE");
49 libs = __bice_get ((char *) "LIBS");
50 ldflags = __bice_get ((char *) "LDFLAGS");
52 if (! cc)
53 cc = (char *) "gcc";
54 if (! cxx)
55 cxx = (char *) "g++";
56 if (! cflags)
57 cflags = (char *) "-O3 -Wall -pipe";
58 if (! cxxflags)
59 cxxflags = cflags;
60 if (! opts)
61 opts = (char *) "";
62 if (! include)
63 include = (char *) "";
64 if (! libs)
65 libs = (char *) "";
66 if (! ldflags)
67 ldflags = (char *) "";
69 if (SB_FLGET (SB_FLVERBOSE)) {
70 printf ("C compiler: %s\n", cc);
71 printf ("C++ compiler: %s\n", cxx);
72 printf ("C flags: %s\n", cflags);
73 printf ("C++ flags: %s\n", cxxflags);
74 printf ("OPTS: %s\n", opts);
75 printf ("INCLUDE: %s\n", include);
76 printf ("LIBS: %s\n", libs);
77 printf ("LDFLAGS: %s\n", ldflags);
80 compile_env->set ((char *) "CC", strdup (cc));
81 compile_env->set ((char *) "CXX", strdup (cxx));
82 compile_env->set ((char *) "CFLAGS", strdup (cflags));
83 compile_env->set ((char *) "CXXFLAGS", strdup (cxxflags));
84 compile_env->set ((char *) "OPTS", strdup (opts));
85 compile_env->set ((char *) "INCLUDE", strdup (include));
86 compile_env->set ((char *) "LIBS", strdup (libs));
87 compile_env->set ((char *) "LDFLAGS", strdup (ldflags));
89 return compile_env;
92 int sb_prname (char *arg)
94 int i_cmd = 0;
95 char * d_ptr;
96 d_ptr = arg + strlen (arg);
97 d_ptr--;
99 while (*d_ptr != '\\' &&
100 d_ptr > arg)
101 d_ptr--;
103 if (*d_ptr == '\\')
104 d_ptr++;
106 if (EQ (d_ptr, "bob_perl"))
107 ENV->language = strdup ("Perl");
108 else if (EQ (d_ptr, "bob_python"))
109 ENV->language = strdup ("Python");
110 else if (EQ (d_ptr, "bob_ruby"))
111 ENV->language = strdup ("Ruby");
113 if (EQ (d_ptr, "tags"))
114 i_cmd = cmd_tags;
115 else if (EQ (d_ptr, "the_tt"))
116 i_cmd = cmd_the_tt;
117 else if (EQ (d_ptr, "gc_indent"))
118 i_cmd = cmd_indent;
119 else if (EQ (d_ptr, "structs"))
120 i_cmd = cmd_give_structs;
122 return i_cmd;
125 // SilentBob --tags
126 void tags (DArray * d_names, char * d_file_output)
128 struct fdump_param_t d_param;
129 EArray * d_tags;
130 struct d_tag_t * d_tag;
131 int a, i, n_names;
133 if (! d_names)
134 return;
136 n_names = d_names->get_size ();
138 for (i = 0; i < n_names; i++) {
139 d_tags = got_tag (d_names->get (i));
140 if (d_tags == NULL) {
141 if (d_tags->get_size () == 0) {
142 fprintf (ENV->d_stream_dbg, "Tag not found : %s\n",
143 d_names->get (i));
144 fflush (ENV->d_stream_dbg);
145 delete d_tags;
146 continue;
150 if (! d_tags)
151 continue;
153 if(! d_tags->get_size ()) {
154 delete d_tags;
155 d_tags = NULL;
156 continue;
159 fault (! d_tags);
161 for (a = 0; a < d_tags->get_size (); a++) {
162 d_tag = (d_tag_t *) d_tags->get (a);
164 fault (! d_tag);
166 if (! d_file_output)
167 printf ("// file %s line %i\n",
168 d_tag->d_file, d_tag->d_line);
170 memset (&d_param, 0, sizeof (struct fdump_param_t));
171 d_param.n_trip = 0;
172 d_param.d_file_name = d_tag->d_file;
173 d_param.d_line = d_tag->d_line;
174 d_param.linear = true;
175 d_param.d_file_output = d_file_output;
176 if (d_tag->d_type == OT::Function)
177 d_param.b_force_block = true;
179 nogui_fdump (&d_param);
180 if (! d_file_output)
181 fputc ('\n', stdout);
183 DROP (d_tag);
186 if (d_tags) {
187 d_tags->drop ();
188 delete d_tags;
192 fflush (stdout);
195 void bug_longmacro ()
197 printf ("Too big macro."
198 "If your macro have more than 300 lines, please "
199 "contact <graycardinal@pisem.net>\n"
200 "Program stopped.\n");
202 exit (0);
205 void bug_nosuch_tag (char * f_name)
207 printf ("Tag \"%s\" not found. Broken \"tags\" file ? "
208 "Try \"silent-bob --make-ctags\".\n", f_name);
211 void bug_nocalltags ()
213 printf ("File \"call_tags\" not found. "
214 "Try \"silent-bob --call-tags [-L] <files>\"\n");
215 exit (1);
218 void bug_system ()
220 printf ("Can't make tags file. Maybe you do not have write permissions ?\n");
221 exit (1);
224 void bug_fork ()
226 perror ("fork");
227 exit (1);
230 void bug_plugin (char *name)
232 fprintf (stderr, "Can't load plugin (%s)\n", name);
235 void bug_notsupported ()
237 printf ("SilentBob (or language plugin)"
238 " don't support this feature !\n");
241 bool bob_tag (char *d_str, char * d_name, d_tag_t * d_tag)
243 char m_buf[256];
244 char *d_file;
245 char *S;
247 strcpy (m_buf, d_str);
248 d_str = m_buf;
250 strncpy (d_tag->d_name, d_name, 255);
251 d_tag->d_name[255] = 0;
252 S = strchr (d_str, '\t');
253 if (! S)
254 return false;
256 S++;
257 d_file = S;
258 S = strchr (d_file, '\t');
259 if (! S)
260 return false;
262 *S = 0;
263 strncpy (d_tag->d_file, d_file, 255);
264 d_tag->d_file[255] = 0;
266 S++;
268 if (if_digit (S))
269 d_tag->d_line = atoi (S);
270 else
271 return false;
273 return true;
276 char * cts (struct c_word * d_word)
278 char * S;
280 if (d_word == NULL)
281 return NULL;
283 S = d_word->S;
284 if (!strncmp (S, "else ", 5))
285 S += 5;
287 if (d_word->ch != '(')
288 return NULL;
290 while (!strncmp (S, "do ", 3))
291 S += 3;
293 if (!strncmp (S, "return ", 7))
294 S += 7;
296 if (ENV->d_cops->sfind (S) != -1)
297 return NULL;
299 if (words_count (S) != 1)
300 return NULL;
302 return S;
305 bool def_test (char * d_op)
307 char * S = d_op;
308 ++S;
309 while (*S == ' ' || *S == '\t')
310 ++S;
312 if (! strncmp (S, "define", 6))
313 return true;
314 return false;
317 int find_cfiles ()
319 find_one_ext ((char *) "*.h");
320 find_one_ext ("*.hpp");
321 find_one_ext ("*.cpp");
322 find_one_ext ("*.c");
323 find_one_ext ("*.cc");
324 find_one_ext ("*.cxx");
325 return 0;
328 int sblib_find (const char * path, const char * name, const char * f_outname)
330 int devnull;
331 int fd;
332 int pid;
333 int status = -1;
335 pid = fork ();
336 if (pid == 0) {
337 devnull = open ("/dev/null", O_WRONLY, 0600);
338 fd = open (f_outname, O_WRONLY, 0600);
339 if (fd == -1) {
340 fd = open (f_outname, O_WRONLY | O_CREAT, 0600);
341 if (fd == -1) {
342 close (devnull);
343 return -1;
345 } else
346 lseek (fd, 0, SEEK_END);
347 dup2 (devnull, 2);
348 dup2 (fd, 1);
349 execlp ("find", path, "-name", name, NULL);
350 } else if (pid > 0) {
351 waitpid (pid, &status, 0);
352 return status;
355 return status;
358 # define TMP_FILE_NAME (char *) "./silent_bob.tmp"
359 struct tt_state_t * get_onett_tag (char * f_name, char ** d_tt_buf)
361 DArray d_array;
362 tt_state_t * Ret = NULL;
363 char * S;
365 if (d_tt_buf)
366 *d_tt_buf = NULL;
368 d_array.add (f_name);
369 Ret = CNEW (tt_state_t, 1);
371 unlink (TMP_FILE_NAME);
372 tags (&d_array, TMP_FILE_NAME);
374 while( 1 ) {
375 if (access (TMP_FILE_NAME, R_OK) != 0)
376 break;
378 Ret->fileName = strdup (TMP_FILE_NAME);
379 S = THE_TT::do_tt_file (Ret);
381 if (S == NULL)
382 break;
384 if (Ret->mmaped)
385 munmap (Ret->fileData, Ret->fileDataSize);
387 if (Ret->fd)
388 close (Ret->fd);
390 if (d_tt_buf)
391 *d_tt_buf = S;
393 unlink (TMP_FILE_NAME);
394 return Ret;
397 DROP (Ret);
398 unlink (TMP_FILE_NAME);
399 return NULL;
402 void globalsPrint (tt_state_t * tt, char * d_out, int d_found_type)
404 int t_line;
405 char * S;
407 if (SB_FLGET (SB_FLSIMULATE))
408 return;
410 if (d_found_type & OT::Other)
411 return;
413 t_line = tt->attachment[ENV->t_op_no].pair_line+1;
414 t_line += ww_begin_line (tt, d_out,
415 tt->attachment[ENV->t_op_no].offset);
417 if (SB_FLGET(SB_FLTAGSTYLE))
418 mk_tag (d_out, tt->fileName,
419 t_line, d_found_type);
420 else {
421 if (d_found_type & OT::Class) {
422 S = strchr (d_out, ':');
423 if (S) {
424 *S = '\0';
425 if (S[-1] == ' ')
426 S[-1] = '\0';
429 printf ("%s\t\t//file %s //line %i\n", d_out,
430 tt->fileName, t_line);
434 #define NOT_VALID 0
435 #define CALL_BACK 1
436 #define VALID 2
438 EArray * got_tag (char * d_tag)
440 struct d_tag_t *d_new_tag;
441 char d_buf[256];
442 EArray * d_ret;
443 int d_len;
444 char *S;
445 int i;
447 d_ret = new EArray;
449 if (ENV->d_tags_file == NULL) {
450 ENV->d_tags_file = new EArray;
451 ENV->d_tags_file->from_file ((char *) "./tags");
454 snprintf (d_buf, 255, "%s\t", d_tag);
455 d_len = strlen (d_buf);
457 if (ENV->d_tags_file->get_size () == 0)
458 return d_ret;
460 i = ENV->d_tags_file->snfind_fast (d_buf, strlen (d_buf));
462 if (i == -1) {
463 fprintf (ENV->d_stream_dbg, "\tENV->d_tags_file->snfind_fast == -1"); LN;
464 return d_ret;
467 d_len = strlen (d_buf);
468 do {
469 i++;
470 S = ENV->d_tags_file->get (i);
471 if (! S)
472 break;
473 } while (! strncmp (S, d_buf, d_len));
474 --i;
476 while (true) {
477 S = ENV->d_tags_file->get (i);
478 fprintf (ENV->d_stream_dbg, "\ttag : %s\n", S); fflush (ENV->d_stream_dbg);
480 d_new_tag = CNEW (d_tag_t, 1);
481 memset (d_new_tag, 0, sizeof (d_tag_t));
482 if (strstr (S, ";\tf"))
483 d_new_tag->d_type = OT::Function;
485 if (bob_tag (S, d_tag, d_new_tag) == false) {
486 DROP (d_new_tag);
487 fprintf (ENV->d_stream_dbg, "\tBAD tag : %s\n", S);
488 return d_ret;
491 d_ret->add ((long) d_new_tag);
493 i--;
494 if (i < 0)
495 break;
497 S = ENV->d_tags_file->get (i);
498 if (strncmp (S, d_tag, strlen (d_tag)))
499 break;
502 return d_ret;
505 char * macro_name (char * d_op, char * d_macro_name)
507 char *d_begin;
508 char *S;
509 char m_buf[256];
511 strncpy (m_buf, d_op, 255);
512 m_buf[255] = 0;
514 S = strstr (m_buf, "define");
516 if (! S)
517 return NULL;
519 S = strchr (S, ' ');
520 if (! S)
521 return NULL;
523 while (*S == ' ')
524 S++;
526 d_begin = S;
527 S = strchr (d_begin, ' ');
528 if (S)
529 *S = 0;
531 S = strchr (d_begin, '(');
532 if (S)
533 *S = 0;
535 strcpy (d_macro_name, d_begin);
536 return d_macro_name;
539 void mk_tag_macro (char * d_op, char * d_file, int t_line)
541 char S[256];
543 if (! macro_name (d_op, S))
544 return;
546 printf ("%s\t%s\t%i\n", S, d_file, t_line);
549 void mk_tag (char * d_op, char * d_file, int line, int d_found_type)
551 char * d_format = (char *) "%s\t%s\t%i\n";
552 char * S;
554 if (d_found_type & OT::Define) {
555 mk_tag_macro (d_op, d_file, line);
556 return;
559 if (d_found_type & OT::Class) {
560 S = strchr (d_op, ':');
561 if (S)
562 *S = 0;
565 S = ww_last_word (d_op);
566 if (! S || !(*S) || (*S == ' '))
567 return;
569 if (*S == 's') {
570 if (! strncmp (S, "static", 6))
571 return;
572 if (! strncmp (S, "struct", 6))
573 return;
576 if (*S == 'u' && !strncmp (S, "union", 5))
577 return;
578 if (*S == 'e' && !strncmp (S, "enum", 4))
579 return;
581 if (d_found_type & OT::Function)
582 d_format = (char *) "%s\t%s\t%i\t;\tf\n";
583 else if (d_found_type & OT::Class)
584 d_format = (char *) "%s\t%s\t%i\t;\tc\n";
585 else if (d_found_type & OT::Struct)
586 d_format = (char *) "%s\t%s\t%i\t;\ts\n";
588 printf (d_format, S, d_file, line);
591 DArray * mk_tag_structtail_split (char *S)
593 bool b_macro = false;
594 char * d_old = NULL;
595 int brace_depth = 0;
596 DArray * d_array;
598 d_array = new DArray (128);
599 if (! d_array)
600 return NULL;
602 d_old = S;
604 while (true) {
605 if (*S == '\"' || *S == '\'') {
606 S = sstrend (S);
607 if (S == NULL || *S == '\0')
608 break;
611 if (*S == '(')
612 brace_depth++;
614 if (*S == ')') {
615 brace_depth--;
616 if (! brace_depth) {
617 S++;
618 break;
622 if (*S == 0) {
623 if (! b_macro)
624 d_array->add (d_old);
625 break;
628 if (brace_depth) {
629 S++;
630 continue;
633 if (S[1] == '(') {
634 b_macro = true;
635 S++;
636 continue;
639 if (*S == ' ' || *S == ',') {
640 *S = 0;
641 S++;
642 b_macro = false;
643 while (*S == ' ' || *S == '*')
644 S++;
645 if (! b_macro)
646 d_array->add (d_old);
647 d_old = S;
649 continue;
651 S++;
654 return d_array;
657 void mk_tag_structtail (char * S, char * d_file, int t_line)
659 char *w;
660 DArray * d_array;
661 int i;
663 d_array = mk_tag_structtail_split (S);
664 if (! d_array)
665 return;
667 for (i = 0; i < d_array->get_size (); i++) {
668 w = ww_last_word (d_array->get (i));
669 if (! w || !(*w) || *w == ' ')
670 continue;
671 printf ("%s\t%s\t%i\n", w, d_file, t_line);
674 delete d_array;
677 void mk_tags (char *f_name, DArray *d_in)
679 DHeapSort * heap;
680 DArray * d_array = NULL;
681 char *S;
682 FILE * my_file;
683 int d_size;
684 int i;
686 if (d_in == NULL) {
687 d_array = new DArray (1024);
688 d_array->from_file (ENV->tmp_tags);
689 } else
690 d_array = d_in;
692 d_size = d_array->get_size ();
693 heap = new DHeapSort (d_size);
695 for (i = 0; i < d_size; ++i)
696 heap->add (d_array->get (i));
698 my_file = fopen (f_name, "w");
699 if (my_file == NULL) {
700 fprintf (stderr, "file %s:\n", f_name);
701 perror ("fopen");
702 return;
705 fprintf (my_file, "!_TAG_FILE_FORMAT\t2\n");
706 fprintf (my_file, "!_TAG_FILE_SORTED\t1\n");
707 fprintf (my_file, "!_TAG_PROGRAM_AUTHOR\tOleg Puchinin (graycardinalster@gmail.com)\n");
708 fprintf (my_file, "!_TAG_PROGRAM_NAME\tSilent Bob\n");
709 fprintf (my_file, "!_TAG_PROGRAM_URL\thttp://sf.net/projects/silentbob\n");
710 fprintf (my_file, "!_TAG_PROGRAM_VERSION\t1.6\n");
712 while ((S = heap->extract_min ()) && S)
713 fprintf (my_file, "%s", S);
715 if (d_in == NULL) {
716 d_array->foreach (free);
717 delete d_array;
720 fclose (my_file);
721 delete heap;
724 char * name2obj (char * name)
726 char *S;
727 char m_buf[512];
728 if (! name)
729 return NULL;
730 strcpy (m_buf, name);
731 S = rindex (m_buf, '.');
732 if (! S)
733 return NULL;
734 strcpy (S, ".o");
735 return strdup (m_buf);
737 bool b_in_comment;
739 bool brace_count (char * d_str, int * d_count, bool b_force_block) // "nice"
741 bool Ret = false;
743 if (! d_str || ! d_count)
744 return false;
746 while (*d_str != 0) {
747 if (!strncmp (d_str, "/*", 2)) {
748 b_in_comment = true;
749 d_str += 2;
750 continue;
753 if (b_in_comment) {
754 if (strncmp (d_str, "*/", 2)) {
755 d_str ++;
756 continue;
757 } else {
758 d_str += 2;
759 b_in_comment = false;
760 continue;
764 if (!strncmp (d_str, "//", 2))
765 break;
767 if (*d_str == '\"' || *d_str == '\'') {
768 d_str = sstrend (d_str);
769 if (d_str == NULL || *d_str == 0) {
770 assert (true, "HimTeh 4");
771 break;
775 if (*d_str == '{') {
776 Ret = true;
777 (*d_count)++;
780 if (*d_str == '}') {
781 Ret = true;
782 (*d_count)--;
785 if (*d_str == ';' && *d_count == 0 && !b_force_block) {
786 Ret = true;
787 break;
789 d_str++;
792 return Ret;
795 void nogui_fdump (struct fdump_param_t * d_param)
797 int d_count = 0;
798 DArray d_array;
799 FILE * d_file;
800 int d_size;
801 char * S;
802 int i,a;
804 if (!d_array.from_file (d_param->d_file_name))
805 return;
807 if (d_param->d_file_output == NULL)
808 d_file = stdout;
809 else
810 d_file = fopen (d_param->d_file_output, "w");
812 if (! d_file)
813 return;
815 if (! d_param->linear) {
816 for (a = 0; a < d_param->n_trip; a++)
817 fprintf (d_file, "\t");
818 fprintf (d_file, "//<***>\n");
821 i = d_param->d_line-1;
822 d_size = d_array.get_size ();
823 b_in_comment = false;
825 if (d_array.get (i)[0] != '#') {
826 while (i < d_size) {
827 if (!d_param->linear) {
828 for (a = 0; a < d_param->n_trip; a++)
829 fprintf (d_file, "\t");
831 fprintf (d_file, "%s", d_array.get(i));
833 if (brace_count (d_array.get(i), &d_count, d_param->b_force_block) && !d_count)
834 break;
836 if (!d_count && ((i - d_param->d_line) > 2) && !d_param->b_force_block)
837 break;
839 i++;
841 } else {
842 do {
843 S = d_array.get (i);
844 fprintf (d_file, "%s", S);
845 S = &S[strlen (S)-2];
846 while ((*S == ' ') || (*S == '\t'))
847 S--;
849 if (*S != '\\')
850 break;
851 i++;
852 } while (i < d_size);
855 if (!d_param->linear) {
856 for (a = 0; a < d_param->n_trip; a++)
857 fprintf (d_file, "\t");
858 fprintf (d_file, "//</***>\n");
861 if (d_param->d_file_output != NULL)
862 fclose (d_file);
864 d_array.foreach (free);
868 /* code for "linear" functionality, */
869 void nogui_tagsdump (char * f_name, int n_trip) {
870 DArray * d_tags;
871 d_tag_t * d_tag;
872 struct fdump_param_t d_param;
873 int a,i;
875 d_tags = got_tag (f_name);
877 assert (d_tags->get_size () == 0, "HimTeh 1");
878 for (i = 0; i < d_tags->get_size (); i++) {
879 d_tag = (d_tag_t *) d_tags->get (i);
880 if (i != 0)
881 fputc ('\n', stdout);
883 if (!SB_FLGET(SB_FLLINEAR)) {
884 for (a = 0; a < n_trip; a++)
885 fputc ('\t', stdout);
888 printf ("// file %s line %i\n", d_tag->d_file, d_tag->d_line);
890 memset (&d_param, 0, sizeof (struct fdump_param_t));
891 d_param.n_trip = n_trip;
892 d_param.d_file_name = d_tag->d_file;
893 d_param.d_line = d_tag->d_line;
894 d_param.linear = SB_FLGET (SB_FLLINEAR);
895 if (d_tag->d_type & OT::Function)
896 d_param.b_force_block = true;
897 nogui_fdump (&d_param);
900 d_tags->foreach (free);
901 delete d_tags;
902 printf ("\n");
905 void opMacro (char ** d_ptr, char ** d_out, char ch)
907 char *macro_start;
908 char * d_my;
909 int n = 0;
911 d_my = *d_out;
912 macro_start = *d_out;
913 while (true) {
914 if (ch == '\n')
915 n++;
917 if ((ch == '\n') && (d_my[strlen (d_my) - 1] != '\\'))
918 break;
920 // if (n > 300)
921 // break;
923 ch = t_op (d_ptr, d_out);
924 ENV->t_op_no++;
925 if (ch == 0)
926 break;
927 d_my = *d_out;
931 int remove_tmp_files ()
933 char m_buf[512];
934 int i = 0;
936 for (i = 0; i < ENV->max_proc; ++i) {
937 sprintf (m_buf, "%s%i", ENV->tmp_files, i);
938 unlink (m_buf);
941 unlink (ENV->tmp_files);
942 unlink (ENV->tmp_tags);
943 return ENV->max_proc;
946 void setParam (char *opt)
948 char m_buf[512];
949 char *S;
951 if (! opt)
952 return;
953 strcpy (m_buf, opt);
954 S = index (m_buf, '=');
955 if (! S)
956 return;
958 *S = '\0';
959 ++S;
960 strip2 (m_buf);
961 strip (S);
962 ENV->settings->set (m_buf, strdup (S));
965 int split_tmp_files ()
967 FILE * f_tmpfiles;
968 FILE ** proc_files;
969 char m_buf[512];
970 int i = 0;
972 f_tmpfiles = fopen (ENV->tmp_files, "r");
973 if (! f_tmpfiles)
974 return -1;
976 proc_files = CNEW (FILE *, ENV->max_proc);
977 memset (proc_files, 0, sizeof (FILE *) * ENV->max_proc);
978 errno = 0;
979 for (i = 0; i < ENV->max_proc; ++i) {
980 sprintf (m_buf, "%s%i", ENV->tmp_files, i);
981 unlink (m_buf);
982 proc_files[i] = fopen (m_buf, "w");
983 if (! proc_files[i]) {
984 perror ("fopen");
985 return -1;
989 i = 0;
990 while (fgets (m_buf, 512, f_tmpfiles)) {
991 fprintf (proc_files[i], "%s", m_buf);
992 if (++i >= ENV->max_proc)
993 i = 0;
996 for (i = 0; i < ENV->max_proc; ++i)
997 fclose (proc_files[i]);
999 return ENV->max_proc;
1002 DArray * split_to_words (char * d_op)
1004 DArray * d_Ret = new DArray (16);
1005 char * d_old = strdup (d_op);
1006 bool b_done = false;
1007 char * S = d_old;
1008 char * d_end;
1009 char ch;
1011 if (d_Ret == NULL || d_old == NULL)
1012 return NULL;
1014 while (true) {
1015 b_done = false;
1016 d_end = S;
1018 if (*d_end == ' ')
1019 d_end++;
1021 while (*d_end) {
1022 if (!(if_abc(d_end) ||
1023 if_digit (d_end) ||
1024 *d_end == '_' ||
1025 *d_end == ' ') )
1026 break;
1027 d_end ++;
1030 if (! *d_end) {
1031 ch = 0;
1032 b_done = true;
1033 goto split_to_words_L1;
1036 ch = *d_end;
1037 if (d_end[-1] == ' ')
1038 d_end[-1] = 0;
1039 else
1040 *d_end = 0;
1042 while (*S && *S == ' ')
1043 S++;
1045 split_to_words_L1:
1046 d_Ret->add (LPCHAR(new_cword (S, ch)));
1048 if (b_done)
1049 break;
1051 if (ch == '\"' || ch == '\'') {
1052 *d_end = ch;
1053 d_end = sstrend (d_end);
1054 assert (d_end == NULL, "Lena 1");
1055 if (*d_end == '\0' || *(++d_end) == '\0')
1056 break;
1059 S = d_end + 1;
1062 DROP (d_old);
1063 return d_Ret;
1066 char * sstrend (char * d_ptr)
1068 bool t_instring = false;
1069 int d_slash_count;
1070 char ch_last;
1071 char *d_old;
1072 unsigned limit = 1024;
1074 if (! d_ptr)
1075 return (char *) 0;
1077 if (!(*d_ptr))
1078 return (char *) 0;
1080 ch_last = *d_ptr;
1081 d_old = d_ptr;
1082 limit--;
1083 while (*d_ptr && (limit > 0)) {
1084 if (*d_ptr == '\'' || *d_ptr == '\"') {
1085 if (t_instring && *d_ptr != ch_last) {
1086 d_ptr++;
1087 continue; // Mmm...
1090 if (t_instring) {
1091 if (d_ptr[-1] == '\\') {
1092 d_slash_count = 1;
1093 while (d_ptr [-(d_slash_count)] == '\\')
1094 d_slash_count++;
1096 if (d_slash_count & 1)
1097 t_instring = false;
1098 } else {
1099 d_ptr++;
1100 t_instring = false;
1101 continue;
1103 } else {
1104 ch_last = *d_ptr;
1105 t_instring = true;
1109 if (t_instring) {
1110 d_ptr++;
1111 continue;
1112 } else
1113 break;
1116 d_ptr --;
1118 if (*d_ptr == 0)
1119 return 0;
1121 return d_ptr;
1124 char * sstrkill (char *OP)
1126 char *S;
1127 char *tail;
1129 if (! OP)
1130 return NULL;
1132 S = OP;
1133 while (*S) {
1134 if (*S == '\"' || *S == '\'') {
1135 tail = sstrend (S);
1136 if (! tail)
1137 break;
1139 if (*tail == '\0' ||*(tail+1) == '\0') {
1140 *S = '\0';
1141 break;
1144 ++S;
1145 strcpy (S, tail);
1147 ++S;
1150 return OP;
1153 int words_count (char *S)
1155 bool b_begin = true;
1156 int d_ret = 0;
1158 if (S == 0)
1159 return 0;
1161 while (*S) {
1162 if (*S == ' ') {
1163 b_begin = true;
1164 S++;
1165 continue;
1168 if (b_begin) {
1169 if (if_abc (S) ||
1170 (*S == '_') ||
1171 (*S == '*') ||
1172 (*S == '&')) {
1173 S++;
1174 d_ret ++;
1175 b_begin = false;
1176 continue;
1177 } else
1178 break;
1179 } else {
1180 if (!(if_abc (S) || (*S == '_')
1181 || (*S == '*') || (if_digit (S))))
1182 break;
1185 S++;
1186 b_begin = false;
1189 return d_ret;
1192 int ww_begin_line (struct tt_state_t * d_tt_state, char *d_out, int d_offset)
1194 char *S = &d_tt_state->fileData [d_offset] - 1;
1195 char * d_end = &d_out[strlen (d_out)] - 1;
1196 int Ret = 0;
1198 while (d_end > d_out) {
1199 if (*d_end == ' ' || *d_end == '\t') {
1200 while ((S >= d_tt_state->fileData) && (*S == ' ' || *S == '\t'))
1201 --S;
1203 if (S < d_tt_state->fileData)
1204 return Ret;
1206 while ((d_end >= d_out) && (*d_end == ' ' || *d_end == '\t'))
1207 --d_end;
1209 if (d_end <= d_out)
1210 return Ret;
1212 continue;
1215 if (*S == '\n')
1216 --Ret;
1218 if (*S == *d_end)
1219 --d_end;
1221 --S;
1224 return Ret;
1227 char * ww_begin_offset (struct tt_state_t * d_tt_state, char *d_out, int d_offset)
1229 char *S = &d_tt_state->fileData [d_offset] - 1;
1230 char * d_real = &d_out[strlen (d_out)] - 1;
1232 while (d_real != d_out) {
1233 if (*d_real == ' ' || *d_real == '\t') {
1234 while (*S == ' ' || *S == '\t')
1235 S--;
1237 while ((*d_real == ' ' || *d_real == '\t')
1238 && (d_real != d_out))
1239 --d_real;
1241 continue;
1244 if (*S == *d_real)
1245 --d_real;
1247 --S;
1250 return S;
1253 char * ww_last_word (char *d_op)
1255 char * S = d_op;
1256 char * d_word;
1258 while (*S) {
1259 if (*S == '(' || *S == '=' || *S == '[')
1260 break;
1261 S++;
1264 if (S[-1] == ' ')
1265 S--;
1267 *S = 0;
1268 d_word = d_op;
1269 while (true) {
1270 S = strchr (d_word, ' ');
1271 if (S == NULL)
1272 break;
1273 d_word = S+1;
1276 while (*d_word == '*' ||
1277 *d_word == '&' ||
1278 *d_word == ' ')
1279 d_word++;
1281 return d_word;
1284 bool validOption (char *Name)
1286 char *S;
1287 if (! Name)
1288 return false;
1290 S = ENV->listOptions->first ();
1291 while (S) {
1292 if (EQ (Name, S))
1293 return true;
1294 S = ENV->listOptions->next ();
1296 return false;
1299 int lastPluginID = 0;
1300 int newPluginID ()
1302 return ++lastPluginID;